Skip to content

Commit f33b807

Browse files
author
FalkWolsky
committed
WIP Introducing Step Component
1 parent 1a7bbf0 commit f33b807

File tree

10 files changed

+256
-11
lines changed

10 files changed

+256
-11
lines changed

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

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ import { EditorContext } from "comps/editorState";
1515

1616
// TODO: eventually to embedd in container so we have styling?
1717
// TODO: support different starter templates for different frameworks (react, ANT, Flutter, Angular, etc)
18-
// TODO: use modern version of ANTd
1918

2019
const defaultModel = {
2120
name: "{{currentUser.name}}",
Lines changed: 151 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,151 @@
1+
2+
import { default as AntdSteps } from "antd/es/steps";
3+
import { BoolCodeControl } from "comps/controls/codeControl";
4+
import { stringExposingStateControl } from "comps/controls/codeStateControl";
5+
import { ChangeEventHandlerControl } from "comps/controls/eventHandlerControl";
6+
import { LabelControl } from "comps/controls/labelControl";
7+
import { StepOptionControl } from "comps/controls/optionsControl";
8+
import { styleControl } from "comps/controls/styleControl";
9+
import { StepsStyle, StepsStyleType } from "comps/controls/styleControlConstants";
10+
import styled, { css } from "styled-components";
11+
import { UICompBuilder } from "../../generators";
12+
import { CommonNameConfig, NameConfig, withExposingConfigs } from "../../generators/withExposing";
13+
import { selectDivRefMethods, } from "./selectInputConstants";
14+
import { Section, sectionNames } from "lowcoder-design";
15+
import { hiddenPropertyView, disabledPropertyView } from "comps/utils/propertyUtils";
16+
import { trans } from "i18n";
17+
import { hasIcon } from "comps/utils";
18+
import { RefControl } from "comps/controls/refControl";
19+
20+
import { useContext, useState } from "react";
21+
import { EditorContext } from "comps/editorState";
22+
23+
24+
/* const getStyle = (style: StepsStyleType) => {
25+
return css`
26+
&.ant-segmented:not(.ant-segmented-disabled) {
27+
background-color: ${style.background};
28+
29+
&,
30+
.ant-segmented-item-selected,
31+
.ant-segmented-thumb,
32+
.ant-segmented-item:hover,
33+
.ant-segmented-item:focus {
34+
color: ${style.text};
35+
border-radius: ${style.radius};
36+
}
37+
.ant-segmented-item {
38+
padding: ${style.padding};
39+
}
40+
.ant-segmented-item-selected,
41+
.ant-segmented-thumb {
42+
background-color: ${style.indicatorBackground};
43+
}
44+
}
45+
46+
&.ant-segmented,
47+
.ant-segmented-item-selected {
48+
border-radius: ${style.radius};
49+
}
50+
&.ant-segmented, .ant-segmented-item-label {
51+
font-family:${style.fontFamily};
52+
font-style:${style.fontStyle};
53+
font-size:${style.textSize};
54+
font-weight:${style.textWeight};
55+
text-transform:${style.textTransform};
56+
text-decoration:${style.textDecoration};
57+
}
58+
`;
59+
}; */
60+
61+
// ${(props) => props.$style && getStyle(props.$style)}
62+
const Segmented = styled(AntdSteps)<{ $style: StepsStyleType }>`
63+
width: 100%;
64+
min-height: 24px;
65+
`;
66+
67+
const SegmentedWrapper = styled.div`
68+
width: 100%;
69+
min-height: 24px;
70+
`;
71+
72+
const StepsChildrenMap = {
73+
defaultValue: stringExposingStateControl("value"),
74+
value: stringExposingStateControl("value"),
75+
label: LabelControl,
76+
disabled: BoolCodeControl,
77+
onEvent: ChangeEventHandlerControl,
78+
options: StepOptionControl,
79+
style: styleControl(StepsStyle),
80+
viewRef: RefControl<HTMLDivElement>
81+
};
82+
83+
let StepControlBasicComp = (function () {
84+
return new UICompBuilder(StepsChildrenMap, (props) => {
85+
86+
const [current, setCurrent] = useState(0);
87+
88+
const onChange = (value: number) => {
89+
console.log('onChange:', value);
90+
setCurrent(value);
91+
};
92+
93+
return props.label({
94+
95+
style: props.style,
96+
97+
children: (
98+
<SegmentedWrapper ref={props.viewRef}>
99+
<AntdSteps
100+
type="navigation"
101+
size="default"
102+
current={current}
103+
onChange={onChange}
104+
items={props.options.map((option) => ({
105+
label: option.label,
106+
subTitle: option.subTitle,
107+
description: option.description,
108+
status: option.status as "error" | "finish" | "wait" | "process",
109+
disabled: option.disabled,
110+
icon: hasIcon(option.icon) && option.icon,
111+
}))}
112+
/>
113+
</SegmentedWrapper>
114+
),
115+
});
116+
})
117+
.setPropertyViewFn((children) => (
118+
<>
119+
<Section name={sectionNames.basic}>
120+
{children.options.propertyView({})}
121+
{children.defaultValue.propertyView({ label: trans("prop.defaultValue") })}
122+
</Section>
123+
124+
{["logic", "both"].includes(useContext(EditorContext).editorModeStatus) && (
125+
<>
126+
<Section name={sectionNames.interaction}>
127+
{children.onEvent.getPropertyView()}
128+
{disabledPropertyView(children)}
129+
{hiddenPropertyView(children)}
130+
</Section></>
131+
)}
132+
133+
{["layout", "both"].includes(useContext(EditorContext).editorModeStatus) && (
134+
children.label.getPropertyView()
135+
)}
136+
137+
{["layout", "both"].includes(useContext(EditorContext).editorModeStatus) && (
138+
<Section name={sectionNames.style}>
139+
{children.style.getPropertyView()}
140+
</Section>
141+
)}
142+
</>
143+
))
144+
.setExposeMethodConfigs(selectDivRefMethods)
145+
.build();
146+
})();
147+
148+
export const StepComp = withExposingConfigs(StepControlBasicComp, [
149+
// new NameConfig("label", trans("selectInput.valueDesc")),
150+
...CommonNameConfig,
151+
]);

client/packages/lowcoder/src/comps/controls/eventHandlerControl.tsx

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ import {
2020
QueryConfigItemWrapper,
2121
ValueFromOption,
2222
} from "lowcoder-design";
23-
import { Fragment, ReactNode, useContext, useEffect, useState } from "react";
23+
import { Fragment, ReactNode, useContext, useEffect, useState} from "react";
2424
import { memo } from "util/cacheUtils";
2525
import { EditorContext } from "../editorState";
2626
import { ActionSelectorControl } from "./actionSelector/actionSelectorControl";
@@ -142,18 +142,21 @@ const EventHandlerControlPropertyView = (props: {
142142
type?: "query";
143143
eventConfigs: EventConfigsType;
144144
}) => {
145+
146+
147+
const editorState = useContext(EditorContext);
148+
const [showNewCreate, setShowNewCreate] = useState(false);
149+
145150
const {
146151
dispatch,
147152
pushAction,
148153
deleteAction,
149154
inline = false,
150155
items,
151156
eventConfigs,
152-
type,
157+
type
153158
} = props;
154-
const editorState = useContext(EditorContext);
155-
const [showNewCreate, setShowNewCreate] = useState(false);
156-
159+
157160
useEffect(() => setShowNewCreate(false), [dispatch]);
158161

159162
const queryHandler = {
@@ -232,9 +235,8 @@ const EventHandlerControlPropertyView = (props: {
232235
);
233236
};
234237

235-
class EventHandlerControl<T extends EventConfigsType> extends list(
236-
SingleEventHandlerControl
237-
) {
238+
class EventHandlerControl<T extends EventConfigsType> extends list(SingleEventHandlerControl) {
239+
238240
@memo
239241
// @ts-ignore
240242
getView() {

client/packages/lowcoder/src/comps/controls/optionsControl.tsx

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -634,3 +634,39 @@ export const ColumnOptionControl = manualOptionsControl(ColumnOption, {
634634
autoIncField: "id",
635635
});
636636

637+
let StepOption = new MultiCompBuilder(
638+
{
639+
label: StringControl,
640+
subTitle: StringControl,
641+
description: StringControl,
642+
icon: IconControl,
643+
status: StringControl,
644+
disabled: BoolCodeControl,
645+
},
646+
(props) => props
647+
).build();
648+
649+
StepOption = class extends StepOption implements OptionCompProperty {
650+
propertyView(param: { autoMap?: boolean }) {
651+
return (
652+
<>
653+
{this.children.label.propertyView({ label: trans("stepOptionsControl.title") })}
654+
{this.children.subTitle.propertyView({ label: trans("stepOptionsControl.subTitle") })}
655+
{this.children.description.propertyView({ label: trans("stepOptionsControl.description") })}
656+
{this.children.icon.propertyView({ label: trans("button.icon") })}
657+
{this.children.status.propertyView({ label: trans("stepOptionsControl.status") })}
658+
{disabledPropertyView(this.children)}
659+
</>
660+
);
661+
}
662+
};
663+
664+
export const StepOptionControl = optionsControl(StepOption, {
665+
initOptions: [
666+
{ label: "Step 1", subTitle: "Initialization", description: "Initial setup of parameters.", icon: "solid/play", status: "complete", disabled: "false" },
667+
{ label: "Step 2", subTitle: "Execution", description: "Execution of the main process.", icon: "solid/person-running", status: "in_progress", disabled: "false" },
668+
{ label: "Step 3", subTitle: "Finalization", description: "Final steps to complete the process.", icon: "solid/circle-check", status: "pending", disabled: "true" },
669+
{ label: "Step 4", subTitle: "Completion", description: "Process completed successfully.", icon: "solid/stamp", status: "complete", disabled: "true" },
670+
],
671+
uniqField: "label",
672+
});

client/packages/lowcoder/src/comps/controls/styleControlConstants.tsx

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -963,6 +963,29 @@ export const SegmentStyle = [
963963
VALIDATE,
964964
] as const;
965965

966+
export const StepsStyle = [
967+
LABEL,
968+
...STYLING_FIELDS_SEQUENCE.filter((style) => ['border', 'borderWidth'].includes(style.name) === false),
969+
{
970+
name: "indicatorBackground",
971+
label: trans("style.indicatorBackground"),
972+
color: SURFACE_COLOR,
973+
},
974+
{
975+
name: "background",
976+
label: trans("style.background"),
977+
depName: "indicatorBackground",
978+
transformer: handleToSegmentBackground,
979+
},
980+
{
981+
name: "text",
982+
label: trans("text"),
983+
depName: "indicatorBackground",
984+
depType: DEP_TYPE.CONTRAST_TEXT,
985+
transformer: contrastText,
986+
},
987+
] as const;
988+
966989
const LinkTextStyle = [
967990
{
968991
name: "text",
@@ -1442,6 +1465,7 @@ export type CascaderStyleType = StyleConfigType<typeof CascaderStyle>;
14421465
export type CheckboxStyleType = StyleConfigType<typeof CheckboxStyle>;
14431466
export type RadioStyleType = StyleConfigType<typeof RadioStyle>;
14441467
export type SegmentStyleType = StyleConfigType<typeof SegmentStyle>;
1468+
export type StepsStyleType = StyleConfigType<typeof StepsStyle>;
14451469
export type TableStyleType = StyleConfigType<typeof TableStyle>;
14461470
export type TableHeaderStyleType = StyleConfigType<typeof TableHeaderStyle>;
14471471
export type TableToolbarStyleType = StyleConfigType<typeof TableToolbarStyle>;

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

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ import { CheckboxComp } from "./comps/selectInputComp/checkboxComp";
2929
import { MultiSelectComp } from "./comps/selectInputComp/multiSelectComp";
3030
import { RadioComp } from "./comps/selectInputComp/radioComp";
3131
import { SegmentedControlComp } from "./comps/selectInputComp/segmentedControl";
32+
import { StepComp } from "./comps/selectInputComp/stepControl";
3233
import { SelectComp } from "./comps/selectInputComp/selectComp";
3334
import { SwitchComp } from "./comps/switchComp";
3435
import { defaultTableData } from "./comps/tableComp/mockTableComp";
@@ -898,6 +899,22 @@ export var uiCompMap: Registry = {
898899
h: 6,
899900
},
900901
},
902+
step: {
903+
name: trans("uiComp.stepControlCompName"),
904+
enName: "Steps Control",
905+
description: trans("uiComp.stepControlCompDesc"),
906+
categories: ["forms"],
907+
icon: SegmentedCompIcon,
908+
keywords: trans("uiComp.stepControlCompKeywords"),
909+
lazyLoad: true,
910+
compName: 'StepComp',
911+
compPath: 'comps/selectInputComp/stepsControl',
912+
layoutInfo: {
913+
w: 6,
914+
h: 6,
915+
},
916+
},
917+
901918
rating: {
902919
name: trans("uiComp.ratingCompName"),
903920
enName: "Rating",

client/packages/lowcoder/src/comps/uiCompRegistry.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ export type UICompType =
7676
| "switch"
7777
| "select"
7878
| "multiSelect"
79+
| "step"
7980
| "cascader"
8081
| "checkbox"
8182
| "radio"

client/packages/lowcoder/src/i18n/locales/en.ts

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -276,7 +276,6 @@ export const en = {
276276
"slowdownTooltip": "Use debounce or throttle to control the frequency of action triggers. Time unit can be 'ms' (millisecond, default) or 's' (second).",
277277
"notHandledError": "Not Handled",
278278
"currentApp": "Current",
279-
280279
"inputEventHandlers": "Input Event Handlers",
281280
"inputEventHandlersDesc": "Event Handlers related to User Input",
282281
"buttonEventHandlers": "Button Event Handlers",
@@ -313,7 +312,6 @@ export const en = {
313312
"meetingEventHandlersDesc": "Event Handlers related to Meeting Events",
314313
"collaborationEventHandlers": "Collaboration Event Handlers",
315314
"collaborationEventHandlersDesc": "Event Handlers related to Collaboration Events",
316-
317315
},
318316
"event": {
319317
"submit": "Submit",
@@ -900,6 +898,10 @@ export const en = {
900898
"segmentedControlCompDesc": "A control with segmented options for quickly toggling between multiple choices.",
901899
"segmentedControlCompKeywords": "segmented, control, toggle, options",
902900

901+
"stepControlCompName": "Step Control",
902+
"stepControlCompDesc": "A control with step options to offer visual guided steps for applications like forms or wizards.",
903+
"stepControlCompKeywords": "steps, control, toggle, options",
904+
903905
"fileUploadCompName": "File Upload",
904906
"fileUploadCompDesc": "A component for uploading files, with support for drag-and-drop and file selection.",
905907
"fileUploadCompKeywords": "file, upload, drag and drop, select",
@@ -1252,6 +1254,12 @@ export const en = {
12521254
"viewDocs": "View Docs",
12531255
"tip": "The 'item' and 'i' Variables Represent the Value and Index of Each Item in the Data Array"
12541256
},
1257+
"stepOptionsControl": {
1258+
"title": "Step Title",
1259+
"subTitle": "Step Subtitle",
1260+
"description": "Step Description",
1261+
"status": "Step Status",
1262+
},
12551263
"radio": {
12561264
"options": "Options",
12571265
"horizontal": "Horizontal",

client/packages/lowcoder/src/i18n/locales/zh.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1180,6 +1180,12 @@ optionsControl: {
11801180
viewDocs: "查看文档",
11811181
tip: '“item”和“i”变量代表数据数组中每个项的值和索引',
11821182
},
1183+
"stepOptionsControl": {
1184+
"title": "步骤",
1185+
"subTitle": "子标题",
1186+
"description": "描述",
1187+
"status": "状态",
1188+
},
11831189
radio: {
11841190
options: "选项",
11851191
horizontal: "水平",

client/packages/lowcoder/src/pages/editor/editorConstants.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ export const CompStateIcon: {
6565
checkbox: <LeftCheckbox />,
6666
radio: <LeftRadio />,
6767
segmentedControl: <LeftSegmentedControl />,
68+
step: <LeftSegmentedControl />,
6869
file: <LeftFile />,
6970
date: <LeftDate />,
7071
dateRange: <LeftDate />,

0 commit comments

Comments
 (0)