Skip to content

Commit 78142a4

Browse files
mobile nav layout options + styling
1 parent dea9f65 commit 78142a4

File tree

2 files changed

+182
-21
lines changed

2 files changed

+182
-21
lines changed

client/packages/lowcoder/src/comps/comps/layout/mobileTabLayout.tsx

Lines changed: 152 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
1-
import { MultiCompBuilder, withViewFn } from "comps/generators";
1+
import { MultiCompBuilder, withDefault, withViewFn } from "comps/generators";
22
import { trans } from "i18n";
3-
import { Section } from "components/Section";
3+
import { Section, sectionNames } from "components/Section";
44
import { manualOptionsControl } from "comps/controls/optionsControl";
5-
import { BoolCodeControl, StringControl } from "comps/controls/codeControl";
5+
import { BoolCodeControl, StringControl, jsonControl } from "comps/controls/codeControl";
66
import { IconControl } from "comps/controls/iconControl";
77
import styled from "styled-components";
8-
import React, { Suspense, useContext, useState } from "react";
8+
import React, { Suspense, useContext, useMemo, useState } from "react";
99
import { registerLayoutMap } from "comps/comps/uiComp";
1010
import { AppSelectComp } from "comps/comps/layout/appSelectComp";
1111
import { NameAndExposingInfo } from "comps/utils/exposingTypes";
@@ -17,6 +17,18 @@ import { Layers } from "constants/Layers";
1717
import { ExternalEditorContext } from "util/context/ExternalEditorContext";
1818
import { default as Skeleton } from "antd/es/skeleton";
1919
import { hiddenPropertyView } from "comps/utils/propertyUtils";
20+
import { dropdownControl } from "@lowcoder-ee/comps/controls/dropdownControl";
21+
import { DataOption, DataOptionType, ModeOptions, jsonMenuItems, menuItemStyleOptions, mobileNavJsonMenuItems } from "./navLayoutConstants";
22+
import { styleControl } from "@lowcoder-ee/comps/controls/styleControl";
23+
import { NavLayoutItemActiveStyle, NavLayoutItemHoverStyle, NavLayoutItemStyle, NavLayoutStyle } from "@lowcoder-ee/comps/controls/styleControlConstants";
24+
import Segmented from "antd/es/segmented";
25+
import { controlItem } from "components/control";
26+
import { MenuItemNode } from "./navLayout";
27+
import { check } from "@lowcoder-ee/util/convertUtils";
28+
import { JSONObject } from "@lowcoder-ee/util/jsonTypes";
29+
import { getCompContainer, useCompContainer, useCompInstance } from "@lowcoder-ee/comps/utils/useCompInstance";
30+
import { ModuleComp } from "../moduleComp/moduleComp";
31+
import { evalAndReduceWithExposing } from "comps/utils";
2032

2133
const TabBar = React.lazy(() => import("antd-mobile/es/components/tab-bar"));
2234
const TabBarItem = React.lazy(() =>
@@ -61,6 +73,21 @@ const TabBarWrapper = styled.div<{ $readOnly: boolean }>`
6173
}
6274
`;
6375

76+
const defaultStyle = {
77+
radius: '0px',
78+
margin: '0px',
79+
padding: '0px',
80+
}
81+
82+
type MenuItemStyleOptionValue = "normal" | "hover" | "active";
83+
84+
type JsonItemNode = {
85+
label: string;
86+
hidden?: boolean;
87+
icon?: any;
88+
app?: JSONObject,
89+
}
90+
6491
type TabBarProps = {
6592
tabs: Array<{
6693
title: string;
@@ -72,7 +99,23 @@ type TabBarProps = {
7299
readOnly: boolean;
73100
};
74101

102+
function checkDataNodes(value: any, key?: string): JsonItemNode[] | undefined {
103+
return check(value, ["array", "undefined"], key, (node, k) => {
104+
check(node, ["object"], k);
105+
check(node["label"], ["string"], "label");
106+
check(node["hidden"], ["boolean", "undefined"], "hidden");
107+
check(node["icon"], ["string", "undefined"], "icon");
108+
check(node["app"], ["object", "undefined"], "app");
109+
return node;
110+
});
111+
}
112+
113+
function convertTreeData(data: any) {
114+
return data === "" ? [] : checkDataNodes(data) ?? [];
115+
}
116+
75117
function TabBarView(props: TabBarProps) {
118+
console.log(props);
76119
return (
77120
<Suspense fallback={<Skeleton />}>
78121
<TabBarWrapper $readOnly={props.readOnly}>
@@ -126,6 +169,8 @@ const TabOptionComp = (function () {
126169

127170
let MobileTabLayoutTmp = (function () {
128171
const childrenMap = {
172+
dataOptionType: dropdownControl(DataOptionType, DataOption.Manual),
173+
jsonItems: jsonControl<JsonItemNode[]>(convertTreeData, mobileNavJsonMenuItems),
129174
tabs: manualOptionsControl(TabOptionComp, {
130175
initOptions: [
131176
{
@@ -142,17 +187,67 @@ let MobileTabLayoutTmp = (function () {
142187
},
143188
],
144189
}),
190+
backgroundImage: withDefault(StringControl, ""),
191+
mode: dropdownControl(ModeOptions, "inline"),
192+
navStyle: withDefault(styleControl(NavLayoutStyle), defaultStyle),
193+
navItemStyle: withDefault(styleControl(NavLayoutItemStyle), defaultStyle),
194+
navItemHoverStyle: withDefault(styleControl(NavLayoutItemHoverStyle), {}),
195+
navItemActiveStyle: withDefault(styleControl(NavLayoutItemActiveStyle), {}),
145196
};
146197
return new MultiCompBuilder(childrenMap, (props) => {
147198
return null;
148199
})
149200
.setPropertyViewFn((children) => {
201+
const [styleSegment, setStyleSegment] = useState('normal')
150202
return (
151-
<>
203+
<div style={{overflowY: 'auto'}}>
152204
<Section name={trans("aggregation.tabBar")}>
153-
{children.tabs.propertyView({})}
205+
{children.dataOptionType.propertyView({
206+
radioButton: true,
207+
type: "oneline",
208+
})}
209+
{/* {children.tabs.propertyView({})} */}
210+
{
211+
children.dataOptionType.getView() === DataOption.Manual
212+
? children.tabs.propertyView({})
213+
: children.jsonItems.propertyView({
214+
label: "Json Data",
215+
})
216+
}
154217
</Section>
155-
</>
218+
<Section name={sectionNames.layout}>
219+
{ children.mode.propertyView({
220+
label: trans("labelProp.position"),
221+
radioButton: true
222+
})}
223+
{children.backgroundImage.propertyView({
224+
label: `Background Image`,
225+
placeholder: 'https://temp.im/350x400',
226+
})}
227+
</Section>
228+
<Section name={trans("navLayout.navStyle")}>
229+
{ children.navStyle.getPropertyView() }
230+
</Section>
231+
<Section name={trans("navLayout.navItemStyle")}>
232+
{controlItem({}, (
233+
<Segmented
234+
block
235+
options={menuItemStyleOptions}
236+
value={styleSegment}
237+
onChange={(k) => setStyleSegment(k as MenuItemStyleOptionValue)}
238+
/>
239+
))}
240+
{styleSegment === 'normal' && (
241+
children.navItemStyle.getPropertyView()
242+
)}
243+
{styleSegment === 'hover' && (
244+
children.navItemHoverStyle.getPropertyView()
245+
)}
246+
{styleSegment === 'active' && (
247+
children.navItemActiveStyle.getPropertyView()
248+
)}
249+
</Section>
250+
</div>
156251
);
157252
})
158253
.build();
@@ -161,20 +256,56 @@ let MobileTabLayoutTmp = (function () {
161256
MobileTabLayoutTmp = withViewFn(MobileTabLayoutTmp, (comp) => {
162257
const [tabIndex, setTabIndex] = useState(0);
163258
const { readOnly } = useContext(ExternalEditorContext);
164-
const tabViews = (
165-
comp.children.tabs.children.manual.getView() as unknown as Array<
166-
ConstructorToComp<typeof TabOptionComp>
167-
>
168-
).filter((tab) => !tab.children.hidden.getView());
169-
const currentTab = tabViews[tabIndex];
170-
const appView = (currentTab &&
171-
currentTab.children.app.getAppId() &&
172-
currentTab.children.app.getView()) || (
173-
<EmptyContent
174-
text={readOnly ? "" : trans("aggregation.emptyTabTooltip")}
175-
style={{ height: "100%", backgroundColor: "white" }}
176-
/>
177-
);
259+
const tabs = comp.children.tabs.getView();
260+
const navMode = comp.children.mode.getView();
261+
const navStyle = comp.children.navStyle.getView();
262+
const navItemStyle = comp.children.navItemStyle.getView();
263+
const navItemHoverStyle = comp.children.navItemHoverStyle.getView();
264+
const navItemActiveStyle = comp.children.navItemActiveStyle.getView();
265+
const backgroundImage = comp.children.backgroundImage.getView();
266+
const jsonItems = comp.children.jsonItems.getView();
267+
const dataOptionType = comp.children.dataOptionType.getView();
268+
// const tabViews = (
269+
// comp.children.tabs.children.manual.getView() as unknown as Array<
270+
// ConstructorToComp<typeof TabOptionComp>
271+
// >
272+
// ).filter((tab) => !tab.children.hidden.getView());
273+
const tabViews = useMemo(() => {
274+
if (dataOptionType === DataOption.Manual) {
275+
return (comp.children.tabs.children.manual.getView() as unknown as Array<
276+
ConstructorToComp<typeof TabOptionComp>
277+
>
278+
).filter((tab) => !tab.children.hidden.getView());
279+
}
280+
return jsonItems.filter(item => !Boolean(item.hidden)).map((item) => {
281+
const container = getCompContainer({
282+
Comp: TabOptionComp,
283+
initialValue: {
284+
...item,
285+
}
286+
})
287+
if (container) {
288+
container.initialized = true;
289+
container.comp = evalAndReduceWithExposing(container.comp);
290+
}
291+
return container!.comp as unknown as ConstructorToComp<typeof TabOptionComp>
292+
})
293+
}, [dataOptionType])
294+
295+
console.log(tabViews);
296+
297+
const appView = useMemo(() => {
298+
const currentTab = tabViews[tabIndex];
299+
300+
return (currentTab &&
301+
currentTab.children.app.getAppId() &&
302+
currentTab.children.app.getView()) || (
303+
<EmptyContent
304+
text={readOnly ? "" : trans("aggregation.emptyTabTooltip")}
305+
style={{ height: "100%", backgroundColor: "white" }}
306+
/>
307+
)
308+
}, [tabIndex]);
178309

179310
const tabBarView = (
180311
<TabBarView

client/packages/lowcoder/src/comps/comps/layout/navLayoutConstants.ts

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,4 +74,34 @@ export const jsonMenuItems = [
7474
newTab: true,
7575
},
7676
}
77+
]
78+
79+
export const mobileNavJsonMenuItems = [
80+
{
81+
label: "Option 1",
82+
// key: 'option-1',
83+
icon: "https://cdn-icons-png.flaticon.com/128/149/149338.png",
84+
app: {
85+
appId: ""
86+
},
87+
hidden: false,
88+
},
89+
{
90+
label: "Option 2",
91+
// key: 'option-2',
92+
icon: "https://cdn-icons-png.flaticon.com/128/149/149206.png",
93+
app: {
94+
appId: ""
95+
},
96+
hidden: false,
97+
},
98+
{
99+
label: "Option 2",
100+
// key: 'option-2',
101+
icon: "https://cdn-icons-png.flaticon.com/128/149/149206.png",
102+
app: {
103+
appId: ""
104+
},
105+
hidden: true,
106+
}
77107
]

0 commit comments

Comments
 (0)