Skip to content

Commit e1c4f27

Browse files
fix view loading issue in json mode + added styling
1 parent 78142a4 commit e1c4f27

File tree

2 files changed

+114
-54
lines changed

2 files changed

+114
-54
lines changed

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

Lines changed: 111 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,11 @@ import { manualOptionsControl } from "comps/controls/optionsControl";
55
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, useMemo, useState } from "react";
8+
import React, { Suspense, useContext, useEffect, 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";
12-
import { ConstructorToComp } from "lowcoder-core";
12+
import { ConstructorToComp, ConstructorToDataType } from "lowcoder-core";
1313
import { CanvasContainer } from "comps/comps/gridLayoutComp/canvasView";
1414
import { CanvasContainerID } from "constants/domLocators";
1515
import { EditorContainer, EmptyContent } from "pages/common/styledComponent";
@@ -18,17 +18,15 @@ import { ExternalEditorContext } from "util/context/ExternalEditorContext";
1818
import { default as Skeleton } from "antd/es/skeleton";
1919
import { hiddenPropertyView } from "comps/utils/propertyUtils";
2020
import { dropdownControl } from "@lowcoder-ee/comps/controls/dropdownControl";
21-
import { DataOption, DataOptionType, ModeOptions, jsonMenuItems, menuItemStyleOptions, mobileNavJsonMenuItems } from "./navLayoutConstants";
21+
import { DataOption, DataOptionType, ModeOptions, menuItemStyleOptions, mobileNavJsonMenuItems } from "./navLayoutConstants";
2222
import { styleControl } from "@lowcoder-ee/comps/controls/styleControl";
23-
import { NavLayoutItemActiveStyle, NavLayoutItemHoverStyle, NavLayoutItemStyle, NavLayoutStyle } from "@lowcoder-ee/comps/controls/styleControlConstants";
23+
import { NavLayoutItemActiveStyle, NavLayoutItemActiveStyleType, NavLayoutItemHoverStyle, NavLayoutItemHoverStyleType, NavLayoutItemStyle, NavLayoutItemStyleType, NavLayoutStyle, NavLayoutStyleType, defaultTheme } from "@lowcoder-ee/comps/controls/styleControlConstants";
2424
import Segmented from "antd/es/segmented";
2525
import { controlItem } from "components/control";
26-
import { MenuItemNode } from "./navLayout";
2726
import { check } from "@lowcoder-ee/util/convertUtils";
2827
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";
28+
import { isEmpty } from "lodash";
29+
import { ThemeContext } from "@lowcoder-ee/comps/utils/themeContext";
3230

3331
const TabBar = React.lazy(() => import("antd-mobile/es/components/tab-bar"));
3432
const TabBarItem = React.lazy(() =>
@@ -55,9 +53,12 @@ const TabLayoutViewContainer = styled.div`
5553
height: calc(100% - ${TabBarHeight}px);
5654
`;
5755

58-
const TabBarWrapper = styled.div<{ $readOnly: boolean }>`
56+
const TabBarWrapper = styled.div<{
57+
$readOnly: boolean,
58+
$canvasBg: string,
59+
}>`
5960
max-width: inherit;
60-
background: white;
61+
background: ${(props) => (props.$canvasBg)};
6162
margin: 0 auto;
6263
position: fixed;
6364
bottom: 0;
@@ -73,6 +74,50 @@ const TabBarWrapper = styled.div<{ $readOnly: boolean }>`
7374
}
7475
`;
7576

77+
const StyledTabBar = styled(TabBar)<{
78+
$tabStyle: NavLayoutStyleType,
79+
$tabItemStyle: NavLayoutItemStyleType,
80+
$tabItemHoverStyle: NavLayoutItemHoverStyleType,
81+
$tabItemActiveStyle: NavLayoutItemActiveStyleType,
82+
}>`
83+
width: ${(props) => `calc(100% - ${props.$tabStyle.margin} - ${props.$tabStyle.margin})`};
84+
border: ${(props) => props.$tabStyle.border};
85+
background: ${(props) => props.$tabStyle.background};
86+
border-radius: ${(props) => props.$tabStyle.radius };
87+
margin: ${(props) => props.$tabStyle.margin };
88+
padding: ${(props) => props.$tabStyle.padding };
89+
90+
.adm-tab-bar-item:not(:last-child) {
91+
border-right: ${(props) => props.$tabStyle.border};
92+
}
93+
.adm-tab-bar-item-icon, .adm-tab-bar-item-title {
94+
color: ${(props) => props.$tabStyle.text};
95+
}
96+
97+
.adm-tab-bar-item {
98+
background-color: ${(props) => props.$tabItemStyle?.background};
99+
color: ${(props) => props.$tabItemStyle?.text};
100+
border-radius: ${(props) => props.$tabItemStyle?.radius} !important;
101+
border: ${(props) => `1px solid ${props.$tabItemStyle?.border}`};
102+
margin: ${(props) => props.$tabItemStyle?.margin};
103+
padding: ${(props) => props.$tabItemStyle?.padding};
104+
}
105+
106+
.adm-tab-bar-item:hover {
107+
background-color: ${(props) => props.$tabItemHoverStyle?.background} !important;
108+
color: ${(props) => props.$tabItemHoverStyle?.text} !important;
109+
border: ${(props) => `1px solid ${props.$tabItemHoverStyle?.border}`};
110+
}
111+
112+
.adm-tab-bar-item.adm-tab-bar-item-active {
113+
background-color: ${(props) => props.$tabItemActiveStyle.background};
114+
// border: ${(props) => `1px solid ${props.$tabItemActiveStyle.border}`};
115+
.adm-tab-bar-item-icon, .adm-tab-bar-item-title {
116+
color: ${(props) => props.$tabItemActiveStyle.text};
117+
}
118+
}
119+
`;
120+
76121
const defaultStyle = {
77122
radius: '0px',
78123
margin: '0px',
@@ -97,6 +142,11 @@ type TabBarProps = {
97142
selectedKey: string;
98143
onChange: (key: string) => void;
99144
readOnly: boolean;
145+
canvasBg: string;
146+
tabStyle: NavLayoutStyleType;
147+
tabItemStyle: NavLayoutItemStyleType;
148+
tabItemHoverStyle: NavLayoutItemHoverStyleType;
149+
tabItemActiveStyle: NavLayoutItemActiveStyleType;
100150
};
101151

102152
function checkDataNodes(value: any, key?: string): JsonItemNode[] | undefined {
@@ -115,25 +165,33 @@ function convertTreeData(data: any) {
115165
}
116166

117167
function TabBarView(props: TabBarProps) {
118-
console.log(props);
168+
const {
169+
canvasBg, tabStyle, tabItemStyle, tabItemHoverStyle, tabItemActiveStyle,
170+
} = props;
119171
return (
120172
<Suspense fallback={<Skeleton />}>
121-
<TabBarWrapper $readOnly={props.readOnly}>
122-
<TabBar
173+
<TabBarWrapper
174+
$readOnly={props.readOnly}
175+
$canvasBg={canvasBg}
176+
>
177+
<StyledTabBar
123178
onChange={(key: string) => {
124179
if (key) {
125180
props.onChange(key);
126181
}
127182
}}
128-
style={{ width: "100%" }}
129183
activeKey={props.selectedKey}
184+
$tabStyle={tabStyle}
185+
$tabItemStyle={tabItemStyle}
186+
$tabItemHoverStyle={tabItemHoverStyle}
187+
$tabItemActiveStyle={tabItemActiveStyle}
130188
>
131189
{props.tabs.map((tab) => {
132190
return (
133191
<TabBarItem key={tab.key} icon={tab.icon} title={tab.title} />
134192
);
135193
})}
136-
</TabBar>
194+
</StyledTabBar>
137195
</TabBarWrapper>
138196
</Suspense>
139197
);
@@ -187,8 +245,10 @@ let MobileTabLayoutTmp = (function () {
187245
},
188246
],
189247
}),
248+
jsonTabs: manualOptionsControl(TabOptionComp, {
249+
initOptions: [],
250+
}),
190251
backgroundImage: withDefault(StringControl, ""),
191-
mode: dropdownControl(ModeOptions, "inline"),
192252
navStyle: withDefault(styleControl(NavLayoutStyle), defaultStyle),
193253
navItemStyle: withDefault(styleControl(NavLayoutItemStyle), defaultStyle),
194254
navItemHoverStyle: withDefault(styleControl(NavLayoutItemHoverStyle), {}),
@@ -206,7 +266,6 @@ let MobileTabLayoutTmp = (function () {
206266
radioButton: true,
207267
type: "oneline",
208268
})}
209-
{/* {children.tabs.propertyView({})} */}
210269
{
211270
children.dataOptionType.getView() === DataOption.Manual
212271
? children.tabs.propertyView({})
@@ -216,10 +275,6 @@ let MobileTabLayoutTmp = (function () {
216275
}
217276
</Section>
218277
<Section name={sectionNames.layout}>
219-
{ children.mode.propertyView({
220-
label: trans("labelProp.position"),
221-
radioButton: true
222-
})}
223278
{children.backgroundImage.propertyView({
224279
label: `Background Image`,
225280
placeholder: 'https://temp.im/350x400',
@@ -256,47 +311,40 @@ let MobileTabLayoutTmp = (function () {
256311
MobileTabLayoutTmp = withViewFn(MobileTabLayoutTmp, (comp) => {
257312
const [tabIndex, setTabIndex] = useState(0);
258313
const { readOnly } = useContext(ExternalEditorContext);
259-
const tabs = comp.children.tabs.getView();
260-
const navMode = comp.children.mode.getView();
261314
const navStyle = comp.children.navStyle.getView();
262315
const navItemStyle = comp.children.navItemStyle.getView();
263316
const navItemHoverStyle = comp.children.navItemHoverStyle.getView();
264317
const navItemActiveStyle = comp.children.navItemActiveStyle.getView();
265318
const backgroundImage = comp.children.backgroundImage.getView();
266319
const jsonItems = comp.children.jsonItems.getView();
267320
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());
321+
const bgColor = (useContext(ThemeContext)?.theme || defaultTheme).canvas;
322+
323+
useEffect(() => {
324+
comp.children.jsonTabs.dispatchChangeValueAction({
325+
manual: jsonItems as unknown as Array<ConstructorToDataType<typeof TabOptionComp>>
326+
});
327+
}, [jsonItems]);
328+
273329
const tabViews = useMemo(() => {
274330
if (dataOptionType === DataOption.Manual) {
275331
return (comp.children.tabs.children.manual.getView() as unknown as Array<
276332
ConstructorToComp<typeof TabOptionComp>
277333
>
278334
).filter((tab) => !tab.children.hidden.getView());
279335
}
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);
336+
if (dataOptionType === DataOption.Json) {
337+
return (comp.children.jsonTabs.children.manual.getView() as unknown as Array<
338+
ConstructorToComp<typeof TabOptionComp>
339+
>
340+
).filter((tab) => !tab.children.hidden.getView());
341+
}
342+
return [];
343+
}, [dataOptionType, jsonItems, comp.children.tabs, comp.children.jsonTabs])
296344

297345
const appView = useMemo(() => {
298346
const currentTab = tabViews[tabIndex];
299-
347+
300348
return (currentTab &&
301349
currentTab.children.app.getAppId() &&
302350
currentTab.children.app.getView()) || (
@@ -305,7 +353,12 @@ MobileTabLayoutTmp = withViewFn(MobileTabLayoutTmp, (comp) => {
305353
style={{ height: "100%", backgroundColor: "white" }}
306354
/>
307355
)
308-
}, [tabIndex]);
356+
}, [tabIndex, tabViews, dataOptionType]);
357+
358+
let backgroundStyle = navStyle.background;
359+
if(!isEmpty(backgroundImage)) {
360+
backgroundStyle = `center / cover url('${backgroundImage}') no-repeat, ${backgroundStyle}`;
361+
}
309362

310363
const tabBarView = (
311364
<TabBarView
@@ -319,11 +372,21 @@ MobileTabLayoutTmp = withViewFn(MobileTabLayoutTmp, (comp) => {
319372
selectedKey={tabIndex + ""}
320373
onChange={(key) => setTabIndex(Number(key))}
321374
readOnly={!!readOnly}
375+
canvasBg={bgColor}
376+
tabStyle={{
377+
border: `1px solid ${navStyle.border}`,
378+
radius: navStyle.radius,
379+
text: navStyle.text,
380+
margin: navStyle.margin,
381+
padding: navStyle.padding,
382+
background: backgroundStyle,
383+
}}
384+
tabItemStyle={navItemStyle}
385+
tabItemHoverStyle={navItemHoverStyle}
386+
tabItemActiveStyle={navItemActiveStyle}
322387
/>
323388
);
324389

325-
//console.log("appView", appView);
326-
327390
if (readOnly) {
328391
return (
329392
<TabLayoutViewContainer>

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

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -79,28 +79,25 @@ export const jsonMenuItems = [
7979
export const mobileNavJsonMenuItems = [
8080
{
8181
label: "Option 1",
82-
// key: 'option-1',
8382
icon: "https://cdn-icons-png.flaticon.com/128/149/149338.png",
8483
app: {
85-
appId: ""
84+
appId: "",
8685
},
8786
hidden: false,
8887
},
8988
{
9089
label: "Option 2",
91-
// key: 'option-2',
9290
icon: "https://cdn-icons-png.flaticon.com/128/149/149206.png",
9391
app: {
94-
appId: ""
92+
appId: "",
9593
},
9694
hidden: false,
9795
},
9896
{
9997
label: "Option 2",
100-
// key: 'option-2',
10198
icon: "https://cdn-icons-png.flaticon.com/128/149/149206.png",
10299
app: {
103-
appId: ""
100+
appId: "",
104101
},
105102
hidden: true,
106103
}

0 commit comments

Comments
 (0)