Skip to content

Commit c2c88ec

Browse files
optimise shared components
1 parent 9cac3cf commit c2c88ec

File tree

4 files changed

+224
-142
lines changed

4 files changed

+224
-142
lines changed
Lines changed: 103 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { useContext, useEffect, useState } from "react";
1+
import React, { useContext, useEffect, useState, useCallback, useMemo } from "react";
22
import styled from "styled-components";
33
import { PointIcon, SearchOutlinedIcon } from "lowcoder-design/src/icons";
44
import type { EditPopoverItemType } from 'lowcoder-design/src/components/popover';
@@ -72,89 +72,100 @@ interface Iprops {
7272
search?: { searchText: string; setSearchText: (t: string) => void };
7373
}
7474

75-
export const CompName = (props: Iprops) => {
75+
export const CompName = React.memo((props: Iprops) => {
7676
const [error, setError] = useState<string | undefined>(undefined);
7777
const [editing, setEditing] = useState(false);
7878
const [upgrading, setUpgrading] = useState(false);
79+
const [showSearch, setShowSearch] = useState<boolean>(false);
80+
7981
const editorState = useContext(EditorContext);
80-
const selectedComp = values(editorState.selectedComps())[0];
81-
const compType = selectedComp.children.compType.getView() as UICompType;
82-
const compInfo = parseCompType(compType);
83-
const docUrl = getComponentDocUrl(compType);
84-
const playgroundUrl = getComponentPlaygroundUrl(compType);
85-
86-
const items: EditPopoverItemType[] = [];
87-
88-
// Falk: TODO - Implement upgrade for individual Version functionality
89-
const handleUpgrade = async () => {
90-
if (upgrading) {
91-
return;
92-
}
82+
const selectedComp = useMemo(() => values(editorState.selectedComps())[0], [editorState]);
83+
const compType = useMemo(() => selectedComp.children.compType.getView() as UICompType, [selectedComp]);
84+
const compInfo = useMemo(() => parseCompType(compType), [compType]);
85+
const docUrl = useMemo(() => getComponentDocUrl(compType), [compType]);
86+
const playgroundUrl = useMemo(() => getComponentPlaygroundUrl(compType), [compType]);
87+
88+
// Cleanup on unmount
89+
useEffect(() => {
90+
return () => {
91+
setError(undefined);
92+
setEditing(false);
93+
setUpgrading(false);
94+
setShowSearch(false);
95+
};
96+
}, []);
97+
98+
// Reset search when name changes
99+
useEffect(() => {
100+
setShowSearch(false);
101+
}, [props.name]);
102+
103+
const handleUpgrade = useCallback(async () => {
104+
if (upgrading) return;
93105
setUpgrading(true);
94-
await GridCompOperator.upgradeCurrentComp(editorState);
95-
setUpgrading(false);
96-
};
97-
98-
if (docUrl) {
99-
items.push({
100-
text: trans("comp.menuViewDocs"),
101-
onClick: () => {
102-
window.open(docUrl, "_blank");
103-
},
104-
});
105-
}
106+
try {
107+
await GridCompOperator.upgradeCurrentComp(editorState);
108+
} finally {
109+
setUpgrading(false);
110+
}
111+
}, [upgrading, editorState]);
106112

107-
if (playgroundUrl) {
108-
items.push({
109-
text: trans("comp.menuViewPlayground"),
110-
onClick: () => {
111-
window.open(playgroundUrl, "_blank");
112-
},
113-
});
114-
}
113+
const handleRename = useCallback((value: string) => {
114+
if (editorState.rename(props.name, value)) {
115+
editorState.setSelectedCompNames(new Set([value]));
116+
setError(undefined);
117+
}
118+
}, [editorState, props.name]);
115119

120+
const handleSearchChange = useCallback((e: React.ChangeEvent<HTMLInputElement>) => {
121+
props.search?.setSearchText(e.target.value);
122+
}, [props.search]);
116123

117-
if (compInfo.isRemote) {
118-
// Falk: Displaying the current version of the component
119-
items.push({
120-
text: trans("history.currentVersion") + ": " + compInfo.packageVersion,
121-
onClick: () => {
122-
},
123-
});
124-
// items.push({
125-
// text: trans("history.currentVersion") + ": " + compInfo.packageVersion,
126-
// onClick: () => {
127-
128-
// },
129-
// });
130-
131-
items.push({
132-
text: trans("comp.menuUpgradeToLatest"),
133-
onClick: () => {
134-
handleUpgrade();
135-
},
136-
137-
});
138-
}
124+
const handleSearchToggle = useCallback(() => {
125+
setShowSearch(prev => !prev);
126+
props.search?.setSearchText("");
127+
}, [props.search]);
139128

140-
const [showSearch, setShowSearch] = useState<boolean>(false);
141-
const { search } = props;
142-
useEffect(() => {
143-
setShowSearch(false);
144-
}, [props.name]);
145-
const compName = (
146-
<CompDiv $width={props.width} $hasSearch={!!search} $showSearch={showSearch}>
129+
const items = useMemo<EditPopoverItemType[]>(() => {
130+
const menuItems: EditPopoverItemType[] = [];
131+
132+
if (docUrl) {
133+
menuItems.push({
134+
text: trans("comp.menuViewDocs"),
135+
onClick: () => window.open(docUrl, "_blank"),
136+
});
137+
}
138+
139+
if (playgroundUrl) {
140+
menuItems.push({
141+
text: trans("comp.menuViewPlayground"),
142+
onClick: () => window.open(playgroundUrl, "_blank"),
143+
});
144+
}
145+
146+
if (compInfo.isRemote) {
147+
menuItems.push({
148+
text: trans("history.currentVersion") + ": " + compInfo.packageVersion,
149+
onClick: () => {},
150+
});
151+
152+
menuItems.push({
153+
text: trans("comp.menuUpgradeToLatest"),
154+
onClick: handleUpgrade,
155+
});
156+
}
157+
158+
return menuItems;
159+
}, [docUrl, playgroundUrl, compInfo, handleUpgrade]);
160+
161+
const compName = useMemo(() => (
162+
<CompDiv $width={props.width} $hasSearch={!!props.search} $showSearch={showSearch}>
147163
<div>
148164
<EditText
149165
text={props.name}
150-
onFinish={(value) => {
151-
if (editorState.rename(props.name, value)) {
152-
editorState.setSelectedCompNames(new Set([value]));
153-
setError(undefined);
154-
}
155-
}}
166+
onFinish={handleRename}
156167
onChange={(value) => setError(editorState.checkRename(props.name, value))}
157-
onEditStateChange={(editing) => setEditing(editing)}
168+
onEditStateChange={setEditing}
158169
/>
159170
<PopupCard
160171
editorFocus={!!error && editing}
@@ -163,16 +174,13 @@ export const CompName = (props: Iprops) => {
163174
hasError={!!error}
164175
/>
165176
</div>
166-
{!!search && (
177+
{!!props.search && (
167178
<SearchIcon
168-
onClick={() => {
169-
setShowSearch(!showSearch);
170-
search?.setSearchText("");
171-
}}
179+
onClick={handleSearchToggle}
172180
style={{ color: showSearch ? "#315EFB" : "#8B8FA3" }}
173181
/>
174182
)}
175-
{ compType === "module" ? (
183+
{compType === "module" ? (
176184
<EditPopover
177185
items={items}
178186
edit={() => GridCompOperator.editComp(editorState)}
@@ -189,19 +197,32 @@ export const CompName = (props: Iprops) => {
189197
</EditPopover>
190198
)}
191199
</CompDiv>
192-
);
200+
), [
201+
props.width,
202+
props.search,
203+
props.name,
204+
showSearch,
205+
error,
206+
editing,
207+
compType,
208+
items,
209+
editorState,
210+
handleRename,
211+
handleSearchToggle
212+
]);
213+
193214
return (
194215
<div>
195216
{compName}
196-
{search && showSearch && (
217+
{props.search && showSearch && (
197218
<Search
198219
placeholder={trans("comp.searchProp")}
199-
value={search.searchText}
200-
onChange={(e) => search.setSearchText(e.target.value)}
220+
value={props.search.searchText}
221+
onChange={handleSearchChange}
201222
allowClear={true}
202223
style={{ padding: "0 16px", margin: "0 0 4px 0" }}
203224
/>
204225
)}
205226
</div>
206227
);
207-
};
228+
});

client/packages/lowcoder/src/components/Tabs.tsx

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { default as AntdTabs } from "antd/es/tabs";
22
import { GreyTextColor, TabActiveColor } from "constants/style";
3-
import { ReactNode } from "react";
3+
import { ReactNode, memo } from "react";
44
import styled from "styled-components";
55

66
export const Tabs = styled(AntdTabs)`
@@ -52,12 +52,14 @@ interface TabTitleProps {
5252
text: ReactNode;
5353
}
5454

55-
export const TabTitle = function TabTitle(props: TabTitleProps) {
55+
export const TabTitle = memo(function TabTitle(props: TabTitleProps) {
5656
const { icon, text } = props;
5757
return (
5858
<TabTitleWrapper>
5959
{icon && <IconWrapper>{icon}</IconWrapper>}
6060
{text}
6161
</TabTitleWrapper>
6262
);
63-
};
63+
});
64+
65+
TabTitle.displayName = 'TabTitle';

0 commit comments

Comments
 (0)