11import { NameConfig , NameConfigHidden , withExposingConfigs } from "comps/generators/withExposing" ;
2+ import { MultiCompBuilder } from "comps/generators/multi" ;
23import { UICompBuilder , withDefault } from "comps/generators" ;
34import { Section , sectionNames } from "lowcoder-design" ;
45import styled from "styled-components" ;
56import { clickEvent , eventHandlerControl } from "comps/controls/eventHandlerControl" ;
6- import { StringControl } from "comps/controls/codeControl" ;
7+ import { BoolCodeControl , StringControl } from "comps/controls/codeControl" ;
78import { alignWithJustifyControl } from "comps/controls/alignControl" ;
89import { navListComp } from "./navItemComp" ;
910import { menuPropertyView } from "./components/MenuItemList" ;
@@ -22,6 +23,9 @@ import { trans } from "i18n";
2223
2324import { useContext } from "react" ;
2425import { 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
2630type 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
147154const 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