Skip to content

Commit 7dcc4bc

Browse files
optimise button component
1 parent 147cf4c commit 7dcc4bc

File tree

1 file changed

+96
-77
lines changed

1 file changed

+96
-77
lines changed

client/packages/lowcoder/src/comps/comps/buttonComp/buttonComp.tsx

Lines changed: 96 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import { ButtonEventHandlerControl } from "comps/controls/eventHandlerControl";
44
import { IconControl } from "comps/controls/iconControl";
55
import { CompNameContext, EditorContext, EditorState } from "comps/editorState";
66
import { withDefault } from "comps/generators";
7-
import { UICompBuilder } from "comps/generators/uiCompBuilder";
7+
import { NewChildren, UICompBuilder } from "comps/generators/uiCompBuilder";
88
import {
99
disabledPropertyView,
1010
hiddenPropertyView,
@@ -24,9 +24,11 @@ import {
2424
} from "./buttonCompConstants";
2525
import { RefControl } from "comps/controls/refControl";
2626

27-
import React, { useContext, useEffect } from "react";
27+
import React, { useContext, useEffect, useCallback } from "react";
2828
import { AnimationStyle } from "@lowcoder-ee/comps/controls/styleControlConstants";
2929
import { styleControl } from "@lowcoder-ee/comps/controls/styleControl";
30+
import { RecordConstructorToComp } from "lowcoder-core";
31+
import { ToViewReturn } from "@lowcoder-ee/comps/generators/multi";
3032

3133
const FormLabel = styled(CommonBlueLabel)`
3234
font-size: 13px;
@@ -120,83 +122,100 @@ function submitForm(editorState: EditorState, formName: string) {
120122
}
121123
}
122124

123-
const ButtonTmpComp = (function () {
124-
const childrenMap = {
125-
text: withDefault(StringControl, trans("button.button")),
126-
type: dropdownControl(typeOptions, ""),
127-
onEvent: ButtonEventHandlerControl,
128-
disabled: BoolCodeControl,
129-
loading: BoolCodeControl,
130-
form: SelectFormControl,
131-
prefixIcon: IconControl,
132-
suffixIcon: IconControl,
133-
style: ButtonStyleControl,
134-
animationStyle: styleControl(AnimationStyle, 'animationStyle'),
135-
viewRef: RefControl<HTMLElement>,
136-
};
137-
return new UICompBuilder(childrenMap, (props) => {
138-
return(
139-
<ButtonCompWrapper $disabled={props.disabled}>
140-
<EditorContext.Consumer>
141-
{(editorState) => (
142-
<Button100
143-
ref={props.viewRef}
144-
$buttonStyle={props.style}
145-
loading={props.loading}
146-
disabled={
147-
props.disabled ||
148-
(!isDefault(props.type) && getForm(editorState, props.form)?.disableSubmit())
149-
}
150-
onClick={() =>
151-
isDefault(props.type) ? props.onEvent("click") : submitForm(editorState, props.form)
152-
}
153-
>
154-
{props.prefixIcon && <IconWrapper>{props.prefixIcon}</IconWrapper>}
155-
{
156-
props.text || (props.prefixIcon || props.suffixIcon ? undefined : " ") // Avoid button disappearing
157-
}
158-
{props.suffixIcon && <IconWrapper>{props.suffixIcon}</IconWrapper>}
159-
</Button100>
160-
)}
161-
</EditorContext.Consumer>
162-
</ButtonCompWrapper>
163-
);
164-
})
165-
.setPropertyViewFn((children) => (
166-
<>
167-
<Section name={sectionNames.basic}>
168-
{children.text.propertyView({ label: trans("text") })}
169-
</Section>
170-
171-
{(useContext(EditorContext).editorModeStatus === "logic" || useContext(EditorContext).editorModeStatus === "both") && (
172-
<><Section name={sectionNames.interaction}>
173-
{children.type.propertyView({ label: trans("prop.type"), radioButton: true })}
174-
{isDefault(children.type.getView())
175-
? [
176-
children.onEvent.getPropertyView(),
177-
disabledPropertyView(children),
178-
hiddenPropertyView(children),
179-
loadingPropertyView(children),
180-
]
181-
: children.form.getPropertyView()}
182-
</Section>
183-
</>
184-
)}
125+
const childrenMap = {
126+
text: withDefault(StringControl, trans("button.button")),
127+
type: dropdownControl(typeOptions, ""),
128+
onEvent: ButtonEventHandlerControl,
129+
disabled: BoolCodeControl,
130+
loading: BoolCodeControl,
131+
form: SelectFormControl,
132+
prefixIcon: IconControl,
133+
suffixIcon: IconControl,
134+
style: ButtonStyleControl,
135+
animationStyle: styleControl(AnimationStyle, 'animationStyle'),
136+
viewRef: RefControl<HTMLElement>,
137+
};
185138

186-
{(useContext(EditorContext).editorModeStatus === "layout" || useContext(EditorContext).editorModeStatus === "both") && (
187-
<>
188-
<Section name={sectionNames.layout}>
189-
{children.prefixIcon.propertyView({ label: trans("button.prefixIcon") })}
190-
{children.suffixIcon.propertyView({ label: trans("button.suffixIcon") })}
191-
</Section>
192-
<Section name={sectionNames.style}>{children.style.getPropertyView()}</Section>
193-
</>
139+
type ChildrenType = NewChildren<RecordConstructorToComp<typeof childrenMap>>;
140+
141+
const ButtonPropertyView = React.memo((props: {
142+
children: ChildrenType
143+
}) => {
144+
const { editorModeStatus } = useContext(EditorContext);
145+
return (
146+
<>
147+
<Section name={sectionNames.basic}>
148+
{props.children.text.propertyView({ label: trans("text") })}
149+
</Section>
150+
151+
{(editorModeStatus === "logic" || editorModeStatus === "both") && (
152+
<><Section name={sectionNames.interaction}>
153+
{props.children.type.propertyView({ label: trans("prop.type"), radioButton: true })}
154+
{isDefault(props.children.type.getView())
155+
? [
156+
props.children.onEvent.getPropertyView(),
157+
disabledPropertyView(props.children),
158+
hiddenPropertyView(props.children),
159+
loadingPropertyView(props.children),
160+
]
161+
: props.children.form.getPropertyView()}
162+
</Section>
163+
</>
164+
)}
165+
166+
{(editorModeStatus === "layout" || editorModeStatus === "both") && (
167+
<>
168+
<Section name={sectionNames.layout}>
169+
{props.children.prefixIcon.propertyView({ label: trans("button.prefixIcon") })}
170+
{props.children.suffixIcon.propertyView({ label: trans("button.suffixIcon") })}
171+
</Section>
172+
<Section name={sectionNames.style}>{props.children.style.getPropertyView()}</Section>
173+
</>
174+
)}
175+
</>
176+
);
177+
});
178+
179+
const ButtonView = React.memo((props: ToViewReturn<ChildrenType>) => {
180+
const editorState = useContext(EditorContext);
181+
182+
const handleClick = useCallback(() => {
183+
isDefault(props.type) ? props.onEvent("click") : submitForm(editorState, props.form);
184+
}, [props.type, props.onEvent, props.form, editorState]);
185+
186+
return (
187+
<ButtonCompWrapper $disabled={props.disabled}>
188+
<EditorContext.Consumer>
189+
{(editorState) => (
190+
<Button100
191+
ref={props.viewRef}
192+
$buttonStyle={props.style}
193+
loading={props.loading}
194+
disabled={
195+
props.disabled ||
196+
(!isDefault(props.type) && getForm(editorState, props.form)?.disableSubmit())
197+
}
198+
onClick={handleClick}
199+
>
200+
{props.prefixIcon && <IconWrapper>{props.prefixIcon}</IconWrapper>}
201+
{
202+
props.text || (props.prefixIcon || props.suffixIcon ? undefined : " ") // Avoid button disappearing
203+
}
204+
{props.suffixIcon && <IconWrapper>{props.suffixIcon}</IconWrapper>}
205+
</Button100>
194206
)}
195-
</>
196-
))
197-
.setExposeMethodConfigs(buttonRefMethods)
198-
.build();
199-
})();
207+
</EditorContext.Consumer>
208+
</ButtonCompWrapper>
209+
)
210+
});
211+
212+
const buttonViewFn = (props: ToViewReturn<ChildrenType>) => <ButtonView {...props} />
213+
const buttonPropertyViewFn = (children: ChildrenType) => <ButtonPropertyView children={children} />
214+
215+
const ButtonTmpComp = new UICompBuilder(childrenMap, buttonViewFn)
216+
.setPropertyViewFn(buttonPropertyViewFn)
217+
.setExposeMethodConfigs(buttonRefMethods)
218+
.build();
200219

201220
export const ButtonComp = withExposingConfigs(ButtonTmpComp, [
202221
new NameConfig("text", trans("button.textDesc")),

0 commit comments

Comments
 (0)