@@ -2,7 +2,7 @@ import { MultiCompBuilder, withDefault, withViewFn } from "comps/generators";
22import { trans } from "i18n" ;
33import { Section , sectionNames } from "components/Section" ;
44import { manualOptionsControl } from "comps/controls/optionsControl" ;
5- import { BoolCodeControl , StringControl , jsonControl } from "comps/controls/codeControl" ;
5+ import { BoolCodeControl , StringControl , jsonControl , NumberControl } from "comps/controls/codeControl" ;
66import { IconControl } from "comps/controls/iconControl" ;
77import styled from "styled-components" ;
88import React , { Suspense , useContext , useEffect , useMemo , useState } from "react" ;
@@ -27,6 +27,9 @@ import { check } from "@lowcoder-ee/util/convertUtils";
2727import { JSONObject } from "@lowcoder-ee/util/jsonTypes" ;
2828import { isEmpty } from "lodash" ;
2929import { ThemeContext } from "@lowcoder-ee/comps/utils/themeContext" ;
30+ import { AlignCenter } from "lowcoder-design" ;
31+ import { AlignLeft } from "lowcoder-design" ;
32+ import { AlignRight } from "lowcoder-design" ;
3033
3134const TabBar = React . lazy ( ( ) => import ( "antd-mobile/es/components/tab-bar" ) ) ;
3235const TabBarItem = React . lazy ( ( ) =>
@@ -35,8 +38,6 @@ const TabBarItem = React.lazy(() =>
3538 } ) )
3639) ;
3740
38- const TabBarHeight = 56 ;
39- const MaxWidth = 450 ;
4041const AppViewContainer = styled . div `
4142 position: absolute;
4243 width: 100%;
@@ -46,16 +47,25 @@ const AppViewContainer = styled.div`
4647 height: 100%;
4748` ;
4849
49- const TabLayoutViewContainer = styled . div `
50+ const TabLayoutViewContainer = styled . div < {
51+ maxWidth : number ;
52+ tabBarHeight : string ;
53+ // verticalAlignment: string;
54+ } > `
5055 margin: 0 auto;
51- max-width: ${ MaxWidth } px;
56+ max-width: ${ ( props ) => props . maxWidth } px;
5257 position: relative;
53- height: calc(100% - ${ TabBarHeight } px);
58+ height: calc(100% - ${ ( props ) => props . tabBarHeight } );
59+ display: flex;
60+ flex-direction: column;
5461` ;
5562
5663const TabBarWrapper = styled . div < {
5764 $readOnly : boolean ,
5865 $canvasBg : string ,
66+ $tabBarHeight : string ,
67+ $maxWidth : number ,
68+ $verticalAlignment : string ;
5969} > `
6070 max-width: inherit;
6171 background: ${ ( props ) => ( props . $canvasBg ) } ;
@@ -64,35 +74,46 @@ const TabBarWrapper = styled.div<{
6474 bottom: 0;
6575 left: 0;
6676 right: 0;
67- width: ${ ( props ) => ( props . $readOnly ? "100%" : "418px" ) } ;
77+ width: ${ ( props ) => props . $readOnly ? "100%" : ` ${ props . $maxWidth - 30 } px` } ;
6878 z-index: ${ Layers . tabBar } ;
6979 padding-bottom: env(safe-area-inset-bottom, 0);
7080
7181 .adm-tab-bar-wrap {
7282 overflow: auto;
73- height: ${ TabBarHeight } px;
83+ height: ${ ( props ) => props . $tabBarHeight } ;
84+ display: flex;
85+ flex-wrap: wrap;
86+ align-content: ${ ( props ) => props . $verticalAlignment } ;
7487 }
7588` ;
7689
7790const StyledTabBar = styled ( TabBar ) < {
91+ $showSeparator : boolean ,
7892 $tabStyle : NavLayoutStyleType ,
7993 $tabItemStyle : NavLayoutItemStyleType ,
8094 $tabItemHoverStyle : NavLayoutItemHoverStyleType ,
8195 $tabItemActiveStyle : NavLayoutItemActiveStyleType ,
96+ $navIconSize : string ;
8297} > `
8398 width: ${ ( props ) => `calc(100% - ${ props . $tabStyle . margin } - ${ props . $tabStyle . margin } )` } ;
8499 border: ${ ( props ) => props . $tabStyle . border } ;
85100 background: ${ ( props ) => props . $tabStyle . background } ;
86101 border-radius: ${ ( props ) => props . $tabStyle . radius } ;
87102 margin: ${ ( props ) => props . $tabStyle . margin } ;
88103 padding: ${ ( props ) => props . $tabStyle . padding } ;
89-
104+
105+ ${ ( props ) => props . $showSeparator ? `
90106 .adm-tab-bar-item:not(:last-child) {
91- border-right: ${ ( props ) => props . $tabStyle . border } ;
107+ border-right: ${ props . $tabStyle . border } ;
92108 }
109+ ` : '' }
110+
93111 .adm-tab-bar-item-icon, .adm-tab-bar-item-title {
94112 color: ${ ( props ) => props . $tabStyle . text } ;
95113 }
114+ .adm-tab-bar-item-icon, {
115+ font-size: ${ ( props ) => props . $navIconSize } ;
116+ }
96117
97118 .adm-tab-bar-item {
98119 background-color: ${ ( props ) => props . $tabItemStyle ?. background } ;
@@ -124,6 +145,22 @@ const defaultStyle = {
124145 padding : '0px' ,
125146}
126147
148+ const AlignTop = styled ( AlignLeft ) `
149+ transform: rotate(90deg);
150+ ` ;
151+ const AlignBottom = styled ( AlignRight ) `
152+ transform: rotate(90deg);
153+ ` ;
154+ const AlignVerticalCenter = styled ( AlignCenter ) `
155+ transform: rotate(90deg);
156+ ` ;
157+
158+ const VerticalAlignmentOptions = [
159+ { label : < AlignTop /> , value : "flex-start" } ,
160+ { label : < AlignVerticalCenter /> , value : "stretch" } ,
161+ { label : < AlignBottom /> , value : "flex-end" } ,
162+ ] as const ;
163+
127164type MenuItemStyleOptionValue = "normal" | "hover" | "active" ;
128165
129166type JsonItemNode = {
@@ -164,7 +201,14 @@ function convertTreeData(data: any) {
164201 return data === "" ? [ ] : checkDataNodes ( data ) ?? [ ] ;
165202}
166203
167- function TabBarView ( props : TabBarProps ) {
204+ function TabBarView ( props : TabBarProps & {
205+ tabBarHeight : string ;
206+ maxWidth : number ;
207+ verticalAlignment : string ;
208+ showSeparator : boolean ;
209+ navIconSize : string ;
210+ }
211+ ) {
168212 const {
169213 canvasBg, tabStyle, tabItemStyle, tabItemHoverStyle, tabItemActiveStyle,
170214 } = props ;
@@ -173,6 +217,9 @@ function TabBarView(props: TabBarProps) {
173217 < TabBarWrapper
174218 $readOnly = { props . readOnly }
175219 $canvasBg = { canvasBg }
220+ $tabBarHeight = { props . tabBarHeight }
221+ $maxWidth = { props . maxWidth }
222+ $verticalAlignment = { props . verticalAlignment }
176223 >
177224 < StyledTabBar
178225 onChange = { ( key : string ) => {
@@ -185,6 +232,8 @@ function TabBarView(props: TabBarProps) {
185232 $tabItemStyle = { tabItemStyle }
186233 $tabItemHoverStyle = { tabItemHoverStyle }
187234 $tabItemActiveStyle = { tabItemActiveStyle }
235+ $showSeparator = { props . showSeparator }
236+ $navIconSize = { props . navIconSize }
188237 >
189238 { props . tabs . map ( ( tab ) => {
190239 return (
@@ -249,6 +298,11 @@ let MobileTabLayoutTmp = (function () {
249298 initOptions : [ ] ,
250299 } ) ,
251300 backgroundImage : withDefault ( StringControl , "" ) ,
301+ tabBarHeight : withDefault ( StringControl , "56px" ) ,
302+ navIconSize : withDefault ( StringControl , "32px" ) ,
303+ maxWidth : withDefault ( NumberControl , 450 ) ,
304+ verticalAlignment : dropdownControl ( VerticalAlignmentOptions , "stretch" ) ,
305+ showSeparator : withDefault ( BoolCodeControl , true ) ,
252306 navStyle : withDefault ( styleControl ( NavLayoutStyle ) , defaultStyle ) ,
253307 navItemStyle : withDefault ( styleControl ( NavLayoutItemStyle ) , defaultStyle ) ,
254308 navItemHoverStyle : withDefault ( styleControl ( NavLayoutItemHoverStyle ) , { } ) ,
@@ -279,6 +333,13 @@ let MobileTabLayoutTmp = (function () {
279333 label : `Background Image` ,
280334 placeholder : 'https://temp.im/350x400' ,
281335 } ) }
336+ { children . showSeparator . propertyView ( { label : trans ( "navLayout.mobileNavVerticalShowSeparator" ) } ) }
337+ { children . tabBarHeight . propertyView ( { label : trans ( "navLayout.mobileNavBarHeight" ) } ) }
338+ { children . navIconSize . propertyView ( { label : trans ( "navLayout.mobileNavIconSize" ) } ) }
339+ { children . maxWidth . propertyView ( { label : trans ( "navLayout.mobileNavVerticalMaxWidth" ) } ) }
340+ { children . verticalAlignment . propertyView (
341+ { label : trans ( "navLayout.mobileNavVerticalOrientation" ) , radioButton : true }
342+ ) }
282343 </ Section >
283344 < Section name = { trans ( "navLayout.navStyle" ) } >
284345 { children . navStyle . getPropertyView ( ) }
@@ -318,6 +379,11 @@ MobileTabLayoutTmp = withViewFn(MobileTabLayoutTmp, (comp) => {
318379 const backgroundImage = comp . children . backgroundImage . getView ( ) ;
319380 const jsonItems = comp . children . jsonItems . getView ( ) ;
320381 const dataOptionType = comp . children . dataOptionType . getView ( ) ;
382+ const tabBarHeight = comp . children . tabBarHeight . getView ( ) ;
383+ const navIconSize = comp . children . navIconSize . getView ( ) ;
384+ const maxWidth = comp . children . maxWidth . getView ( ) ;
385+ const verticalAlignment = comp . children . verticalAlignment . getView ( ) ;
386+ const showSeparator = comp . children . showSeparator . getView ( ) ;
321387 const bgColor = ( useContext ( ThemeContext ) ?. theme || defaultTheme ) . canvas ;
322388
323389 useEffect ( ( ) => {
@@ -384,20 +450,25 @@ MobileTabLayoutTmp = withViewFn(MobileTabLayoutTmp, (comp) => {
384450 tabItemStyle = { navItemStyle }
385451 tabItemHoverStyle = { navItemHoverStyle }
386452 tabItemActiveStyle = { navItemActiveStyle }
453+ tabBarHeight = { tabBarHeight }
454+ navIconSize = { navIconSize }
455+ maxWidth = { maxWidth }
456+ verticalAlignment = { verticalAlignment }
457+ showSeparator = { showSeparator }
387458 />
388459 ) ;
389460
390461 if ( readOnly ) {
391462 return (
392- < TabLayoutViewContainer >
463+ < TabLayoutViewContainer maxWidth = { maxWidth } tabBarHeight = { tabBarHeight } >
393464 < AppViewContainer > { appView } </ AppViewContainer >
394465 { tabBarView }
395466 </ TabLayoutViewContainer >
396467 ) ;
397468 }
398469
399470 return (
400- < CanvasContainer $maxWidth = { MaxWidth } id = { CanvasContainerID } >
471+ < CanvasContainer $maxWidth = { maxWidth } id = { CanvasContainerID } >
401472 < EditorContainer > { appView } </ EditorContainer >
402473 { tabBarView }
403474 </ CanvasContainer >
0 commit comments