Skip to content

Commit 30f2923

Browse files
committed
[Fix]: #2021 add map mode for NAV
1 parent 0e5aa97 commit 30f2923

File tree

1 file changed

+111
-23
lines changed
  • client/packages/lowcoder/src/comps/comps/navComp

1 file changed

+111
-23
lines changed

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

Lines changed: 111 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
import { NameConfig, NameConfigHidden, withExposingConfigs } from "comps/generators/withExposing";
2+
import { MultiCompBuilder } from "comps/generators/multi";
23
import { UICompBuilder, withDefault } from "comps/generators";
34
import { Section, sectionNames } from "lowcoder-design";
45
import styled from "styled-components";
56
import { clickEvent, eventHandlerControl } from "comps/controls/eventHandlerControl";
6-
import { StringControl } from "comps/controls/codeControl";
7+
import { BoolCodeControl, StringControl } from "comps/controls/codeControl";
78
import { alignWithJustifyControl } from "comps/controls/alignControl";
89
import { navListComp } from "./navItemComp";
910
import { menuPropertyView } from "./components/MenuItemList";
@@ -22,6 +23,9 @@ import { trans } from "i18n";
2223

2324
import { useContext } from "react";
2425
import { EditorContext } from "comps/editorState";
26+
import { dropdownControl } from "comps/controls/dropdownControl";
27+
import { controlItem } from "lowcoder-design";
28+
import { mapOptionsControl } from "comps/controls/optionsControl";
2529

2630
type IProps = {
2731
$justify: boolean;
@@ -137,35 +141,50 @@ const childrenMap = {
137141
horizontalAlignment: alignWithJustifyControl(),
138142
style: migrateOldData(styleControl(NavigationStyle, 'style'), fixOldStyleData),
139143
animationStyle: styleControl(AnimationStyle, 'animationStyle'),
140-
items: withDefault(navListComp(), [
141-
{
142-
label: trans("menuItem") + " 1",
143-
},
144-
]),
144+
items: withDefault(createNavItemsControl(), {
145+
optionType: "manual",
146+
manual: [
147+
{
148+
label: trans("menuItem") + " 1",
149+
},
150+
],
151+
}),
145152
};
146153

147154
const NavCompBase = new UICompBuilder(childrenMap, (props) => {
148155
const data = props.items;
149156
const items = (
150157
<>
151-
{data.map((menuItem, idx) => {
152-
const { hidden, label, items, active, onEvent } = menuItem.getView();
158+
{data.map((menuItem: any, idx: number) => {
159+
const isCompItem = typeof menuItem?.getView === "function";
160+
const view = isCompItem ? menuItem.getView() : menuItem;
161+
const hidden = !!view?.hidden;
153162
if (hidden) {
154163
return null;
155164
}
165+
166+
const label = view?.label;
167+
const active = !!view?.active;
168+
const onEvent = view?.onEvent;
169+
const subItems = isCompItem ? view?.items : [];
170+
156171
const subMenuItems: Array<{ key: string; label: string }> = [];
157172
const subMenuSelectedKeys: Array<string> = [];
158-
items.forEach((subItem, originalIndex) => {
159-
if (subItem.children.hidden.getView()) {
160-
return;
161-
}
162-
const key = originalIndex + "";
163-
subItem.children.active.getView() && subMenuSelectedKeys.push(key);
164-
subMenuItems.push({
165-
key: key,
166-
label: subItem.children.label.getView(),
173+
174+
if (Array.isArray(subItems)) {
175+
subItems.forEach((subItem: any, originalIndex: number) => {
176+
if (subItem.children.hidden.getView()) {
177+
return;
178+
}
179+
const key = originalIndex + "";
180+
subItem.children.active.getView() && subMenuSelectedKeys.push(key);
181+
subMenuItems.push({
182+
key: key,
183+
label: subItem.children.label.getView(),
184+
});
167185
});
168-
});
186+
}
187+
169188
const item = (
170189
<Item
171190
key={idx}
@@ -180,18 +199,19 @@ const NavCompBase = new UICompBuilder(childrenMap, (props) => {
180199
$textTransform={props.style.textTransform}
181200
$textDecoration={props.style.textDecoration}
182201
$margin={props.style.margin}
183-
onClick={() => onEvent("click")}
202+
onClick={() => onEvent && onEvent("click")}
184203
>
185204
{label}
186-
{items.length > 0 && <DownOutlined />}
205+
{Array.isArray(subItems) && subItems.length > 0 && <DownOutlined />}
187206
</Item>
188207
);
189208
if (subMenuItems.length > 0) {
190209
const subMenu = (
191210
<StyledMenu
192211
onClick={(e) => {
193-
const { onEvent: onSubEvent } = items[Number(e.key)]?.getView();
194-
onSubEvent("click");
212+
const subItem = subItems[Number(e.key)];
213+
const onSubEvent = subItem?.getView()?.onEvent;
214+
onSubEvent && onSubEvent("click");
195215
}}
196216
selectedKeys={subMenuSelectedKeys}
197217
items={subMenuItems}
@@ -237,7 +257,7 @@ const NavCompBase = new UICompBuilder(childrenMap, (props) => {
237257
return (
238258
<>
239259
<Section name={sectionNames.basic}>
240-
{menuPropertyView(children.items)}
260+
{children.items.propertyView()}
241261
</Section>
242262

243263
{(useContext(EditorContext).editorModeStatus === "logic" || useContext(EditorContext).editorModeStatus === "both") && (
@@ -285,3 +305,71 @@ export const NavComp = withExposingConfigs(NavCompBase, [
285305
NameConfigHidden,
286306
new NameConfig("items", trans("navigation.itemsDesc")),
287307
]);
308+
309+
// ----------------------------------------
310+
// Nav Items Control (Manual / Map modes)
311+
// ----------------------------------------
312+
function createNavItemsControl() {
313+
const OptionTypes = [
314+
{ label: trans("prop.manual"), value: "manual" },
315+
{ label: trans("prop.map"), value: "map" },
316+
] as const;
317+
318+
// Variant used in Map mode
319+
const NavMapOption = new MultiCompBuilder(
320+
{
321+
label: StringControl,
322+
hidden: BoolCodeControl,
323+
active: BoolCodeControl,
324+
onEvent: eventHandlerControl([clickEvent]),
325+
},
326+
(props) => props
327+
)
328+
.setPropertyViewFn((children) => (
329+
<>
330+
{children.label.propertyView({ label: trans("label"), placeholder: "{{item}}" })}
331+
{children.active.propertyView({ label: trans("navItemComp.active") })}
332+
{children.hidden.propertyView({ label: trans("hidden") })}
333+
{children.onEvent.propertyView({ inline: true })}
334+
</>
335+
))
336+
.build();
337+
338+
const TmpNavItemsControl = new MultiCompBuilder(
339+
{
340+
optionType: dropdownControl(OptionTypes, "manual"),
341+
manual: navListComp(),
342+
mapData: mapOptionsControl(NavMapOption),
343+
},
344+
(props) => {
345+
return props.optionType === "manual" ? props.manual : props.mapData;
346+
}
347+
)
348+
.setPropertyViewFn(() => {
349+
throw new Error("Method not implemented.");
350+
})
351+
.build();
352+
353+
return class NavItemsControl extends TmpNavItemsControl {
354+
exposingNode() {
355+
return this.children.optionType.getView() === "manual"
356+
? (this.children.manual as any).exposingNode()
357+
: (this.children.mapData as any).exposingNode();
358+
}
359+
360+
propertyView() {
361+
const isManual = this.children.optionType.getView() === "manual";
362+
const content = isManual
363+
? menuPropertyView(this.children.manual as any)
364+
: this.children.mapData.getPropertyView();
365+
366+
return controlItem(
367+
{ searchChild: true },
368+
<>
369+
{this.children.optionType.propertyView({ radioButton: true, type: "oneline" })}
370+
{content}
371+
</>
372+
);
373+
}
374+
};
375+
}

0 commit comments

Comments
 (0)