Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit1ceefdb

Browse files
committed
add navigation component burger mode
1 parent2a82955 commit1ceefdb

File tree

1 file changed

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

1 file changed

+176
-23
lines changed

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

Lines changed: 176 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -5,26 +5,34 @@ import { Section, sectionNames } from "lowcoder-design";
55
importstyledfrom"styled-components";
66
import{clickEvent,eventHandlerControl}from"comps/controls/eventHandlerControl";
77
import{BoolCodeControl,StringControl}from"comps/controls/codeControl";
8+
import{dropdownControl}from"comps/controls/dropdownControl";
89
import{alignWithJustifyControl}from"comps/controls/alignControl";
910
import{navListComp}from"./navItemComp";
1011
import{menuPropertyView}from"./components/MenuItemList";
1112
import{defaultasDownOutlined}from"@ant-design/icons/DownOutlined";
13+
import{defaultasMenuOutlined}from"@ant-design/icons/MenuOutlined";
1214
import{defaultasDropdown}from"antd/es/dropdown";
1315
import{defaultasMenu,MenuProps}from"antd/es/menu";
16+
import{defaultasDrawer}from"antd/es/drawer";
1417
import{migrateOldData}from"comps/generators/simpleGenerators";
1518
import{styleControl}from"comps/controls/styleControl";
1619
import{
1720
AnimationStyle,
1821
AnimationStyleType,
1922
NavigationStyle,
23+
HamburgerButtonStyle,
24+
DrawerContainerStyle,
25+
NavLayoutItemStyle,
26+
NavLayoutItemHoverStyle,
27+
NavLayoutItemActiveStyle,
2028
}from"comps/controls/styleControlConstants";
2129
import{hiddenPropertyView,showDataLoadingIndicatorsPropertyView}from"comps/utils/propertyUtils";
2230
import{trans}from"i18n";
2331

24-
import{useContext}from"react";
32+
import{useContext,useState}from"react";
2533
import{EditorContext}from"comps/editorState";
26-
import{controlItem}from"lowcoder-design";
2734
import{createNavItemsControl}from"./components/NavItemsControl";
35+
import{Layers}from"constants/Layers";
2836

2937
typeIProps={
3038
$justify:boolean;
@@ -34,6 +42,7 @@ type IProps = {
3442
$borderRadius:string;
3543
$borderStyle:string;
3644
$animationStyle:AnimationStyleType;
45+
$orientation:"horizontal"|"vertical";
3746
};
3847

3948
constWrapper=styled("div")<
@@ -45,18 +54,21 @@ ${props=>props.$animationStyle}
4554
box-sizing: border-box;
4655
border:${(props)=>props.$borderWidth ?`${props.$borderWidth}` :'1px'}${props=>props.$borderStyle}${(props)=>props.$borderColor};
4756
background:${(props)=>props.$bgColor};
57+
position: relative;
4858
`;
4959

50-
constNavInner=styled("div")<Pick<IProps,"$justify">>`
60+
constNavInner=styled("div")<Pick<IProps,"$justify"|"$orientation">>`
5161
// margin: 0 -16px;
5262
height: 100%;
5363
display: flex;
54-
justify-content:${(props)=>(props.$justify ?"space-between" :"left")};
64+
flex-direction:${(props)=>(props.$orientation==="vertical" ?"column" :"row")};
65+
justify-content:${(props)=>(props.$orientation==="vertical" ?"flex-start" :(props.$justify ?"space-between" :"left"))};
5566
`;
5667

5768
constItem=styled.div<{
5869
$active:boolean;
5970
$activeColor:string;
71+
$hoverColor:string;
6072
$color:string;
6173
$fontFamily:string;
6274
$fontStyle:string;
@@ -66,12 +78,22 @@ const Item = styled.div<{
6678
$padding:string;
6779
$textTransform:string;
6880
$textDecoration:string;
81+
$bg?:string;
82+
$hoverBg?:string;
83+
$activeBg?:string;
84+
$border?:string;
85+
$hoverBorder?:string;
86+
$activeBorder?:string;
87+
$radius?:string;
6988
$disabled?:boolean;
7089
}>`
7190
height: 30px;
7291
line-height: 30px;
7392
padding:${(props)=>props.$padding ?props.$padding :'0 16px'};
7493
color:${(props)=>props.$disabled ?`${props.$color}80` :(props.$active ?props.$activeColor :props.$color)};
94+
background-color:${(props)=>(props.$active ?(props.$activeBg||'transparent') :(props.$bg||'transparent'))};
95+
border:${(props)=>props.$border ?`1px solid${props.$border}` :'1px solid transparent'};
96+
border-radius:${(props)=>props.$radius ?props.$radius :'0px'};
7597
font-weight:${(props)=>(props.$textWeight ?props.$textWeight :500)};
7698
font-family:${(props)=>(props.$fontFamily ?props.$fontFamily :'sans-serif')};
7799
font-style:${(props)=>(props.$fontStyle ?props.$fontStyle :'normal')};
@@ -81,7 +103,9 @@ const Item = styled.div<{
81103
margin:${(props)=>props.$margin ?props.$margin :'0px'};
82104
83105
&:hover {
84-
color:${(props)=>props.$disabled ?(props.$active ?props.$activeColor :props.$color) :props.$activeColor};
106+
color:${(props)=>props.$disabled ?(props.$active ?props.$activeColor :props.$color) :(props.$hoverColor||props.$activeColor)};
107+
background-color:${(props)=>props.$disabled ?(props.$active ?(props.$activeBg||'transparent') :(props.$bg||'transparent')) :(props.$hoverBg||props.$activeBg||props.$bg||'transparent')};
108+
border:${(props)=>props.$hoverBorder ?`1px solid${props.$hoverBorder}` :(props.$activeBorder ?`1px solid${props.$activeBorder}` :(props.$border ?`1px solid${props.$border}` :'1px solid transparent'))};
85109
cursor:${(props)=>props.$disabled ?'not-allowed' :'pointer'};
86110
}
87111
@@ -101,10 +125,10 @@ const LogoWrapper = styled.div`
101125
}
102126
`;
103127

104-
constItemList=styled.div<{$align:string}>`
128+
constItemList=styled.div<{$align:string,$orientation?:string}>`
105129
flex: 1;
106130
display: flex;
107-
flex-direction: row;
131+
flex-direction:${(props)=>(props.$orientation==="vertical" ?"column" :"row")};
108132
justify-content:${(props)=>props.$align};
109133
`;
110134

@@ -114,6 +138,37 @@ const StyledMenu = styled(Menu) <MenuProps>`
114138
}
115139
`;
116140

141+
constFloatingHamburgerButton=styled.button<{
142+
$size:string;
143+
$position:string;// top-right | top-left | bottom-right | bottom-left
144+
$zIndex:number;
145+
$background?:string;
146+
$borderColor?:string;
147+
$radius?:string;
148+
$margin?:string;
149+
$padding?:string;
150+
$borderWidth?:string;
151+
$iconColor?:string;
152+
}>`
153+
position: fixed;
154+
${(props)=>(props.$position.includes('bottom') ?'bottom: 16px;' :'top: 16px;')}
155+
${(props)=>(props.$position.includes('right') ?'right: 16px;' :'left: 16px;')}
156+
width:${(props)=>props.$size};
157+
height:${(props)=>props.$size};
158+
border-radius:${(props)=>props.$radius||'50%'};
159+
border:${(props)=>props.$borderWidth||'1px'} solid${(props)=>props.$borderColor||'rgba(0,0,0,0.1)'};
160+
background:${(props)=>props.$background||'white'};
161+
margin:${(props)=>props.$margin||'0px'};
162+
padding:${(props)=>props.$padding||'0px'};
163+
display: flex;
164+
align-items: center;
165+
justify-content: center;
166+
z-index:${(props)=>props.$zIndex};
167+
cursor: pointer;
168+
box-shadow: 0 6px 16px rgba(0,0,0,0.15);
169+
color:${(props)=>props.$iconColor||'inherit'};
170+
`;
171+
117172
constlogoEventHandlers=[clickEvent];
118173

119174
// Compatible with historical style data 2022-8-26
@@ -154,8 +209,33 @@ function fixOldItemsData(oldData: any) {
154209
constchildrenMap={
155210
logoUrl:StringControl,
156211
logoEvent:withDefault(eventHandlerControl(logoEventHandlers),[{name:"click"}]),
212+
orientation:dropdownControl([
213+
{label:"Horizontal",value:"horizontal"},
214+
{label:"Vertical",value:"vertical"},
215+
],"horizontal"),
216+
displayMode:dropdownControl([
217+
{label:"Bar",value:"bar"},
218+
{label:"Hamburger",value:"hamburger"},
219+
],"bar"),
220+
hamburgerPosition:dropdownControl([
221+
{label:"Top Right",value:"top-right"},
222+
{label:"Top Left",value:"top-left"},
223+
{label:"Bottom Right",value:"bottom-right"},
224+
{label:"Bottom Left",value:"bottom-left"},
225+
],"top-right"),
226+
hamburgerSize:withDefault(StringControl,"56px"),
227+
drawerPlacement:dropdownControl([
228+
{label:"Left",value:"left"},
229+
{label:"Right",value:"right"},
230+
],"right"),
231+
shadowOverlay:withDefault(BoolCodeControl,true),
157232
horizontalAlignment:alignWithJustifyControl(),
158233
style:migrateOldData(styleControl(NavigationStyle,'style'),fixOldStyleData),
234+
navItemStyle:styleControl(NavLayoutItemStyle,'navItemStyle'),
235+
navItemHoverStyle:styleControl(NavLayoutItemHoverStyle,'navItemHoverStyle'),
236+
navItemActiveStyle:styleControl(NavLayoutItemActiveStyle,'navItemActiveStyle'),
237+
hamburgerButtonStyle:styleControl(HamburgerButtonStyle,'hamburgerButtonStyle'),
238+
drawerContainerStyle:styleControl(DrawerContainerStyle,'drawerContainerStyle'),
159239
animationStyle:styleControl(AnimationStyle,'animationStyle'),
160240
items:withDefault(migrateOldData(createNavItemsControl(),fixOldItemsData),{
161241
optionType:"manual",
@@ -168,6 +248,7 @@ const childrenMap = {
168248
};
169249

170250
constNavCompBase=newUICompBuilder(childrenMap,(props)=>{
251+
const[drawerVisible,setDrawerVisible]=useState(false);
171252
constdata=props.items;
172253
constitems=(
173254
<>
@@ -207,16 +288,24 @@ const NavCompBase = new UICompBuilder(childrenMap, (props) => {
207288
<Item
208289
key={idx}
209290
$active={active||subMenuSelectedKeys.length>0}
210-
$color={props.style.text}
211-
$activeColor={props.style.accent}
291+
$color={(props.navItemStyle&&props.navItemStyle.text)||props.style.text}
292+
$hoverColor={(props.navItemHoverStyle&&props.navItemHoverStyle.text)||props.style.accent}
293+
$activeColor={(props.navItemActiveStyle&&props.navItemActiveStyle.text)||props.style.accent}
212294
$fontFamily={props.style.fontFamily}
213295
$fontStyle={props.style.fontStyle}
214296
$textWeight={props.style.textWeight}
215297
$textSize={props.style.textSize}
216-
$padding={props.style.padding}
298+
$padding={(props.navItemStyle&&props.navItemStyle.padding)||props.style.padding}
217299
$textTransform={props.style.textTransform}
218300
$textDecoration={props.style.textDecoration}
219-
$margin={props.style.margin}
301+
$margin={(props.navItemStyle&&props.navItemStyle.margin)||props.style.margin}
302+
$bg={(props.navItemStyle&&props.navItemStyle.background)||undefined}
303+
$hoverBg={(props.navItemHoverStyle&&props.navItemHoverStyle.background)||undefined}
304+
$activeBg={(props.navItemActiveStyle&&props.navItemActiveStyle.background)||undefined}
305+
$border={(props.navItemStyle&&props.navItemStyle.border)||undefined}
306+
$hoverBorder={(props.navItemHoverStyle&&props.navItemHoverStyle.border)||undefined}
307+
$activeBorder={(props.navItemActiveStyle&&props.navItemActiveStyle.border)||undefined}
308+
$radius={(props.navItemStyle&&props.navItemStyle.radius)||undefined}
220309
$disabled={disabled}
221310
onClick={()=>{if(!disabled&&onEvent)onEvent("click");}}
222311
>
@@ -255,6 +344,8 @@ const NavCompBase = new UICompBuilder(childrenMap, (props) => {
255344
);
256345

257346
constjustify=props.horizontalAlignment==="justify";
347+
constisVertical=props.orientation==="vertical";
348+
constisHamburger=props.displayMode==="hamburger";
258349

259350
return(
260351
<Wrapper
@@ -265,14 +356,46 @@ const NavCompBase = new UICompBuilder(childrenMap, (props) => {
265356
$borderWidth={props.style.borderWidth}
266357
$borderRadius={props.style.radius}
267358
>
268-
<NavInner$justify={justify}>
269-
{props.logoUrl&&(
270-
<LogoWrapperonClick={()=>props.logoEvent("click")}>
271-
<imgsrc={props.logoUrl}alt="LOGO"/>
272-
</LogoWrapper>
273-
)}
274-
{!justify ?<ItemList$align={props.horizontalAlignment}>{items}</ItemList> :items}
275-
</NavInner>
359+
{!isHamburger&&(
360+
<NavInner$justify={justify}$orientation={isVertical ?"vertical" :"horizontal"}>
361+
{props.logoUrl&&(
362+
<LogoWrapperonClick={()=>props.logoEvent("click")}>
363+
<imgsrc={props.logoUrl}alt="LOGO"/>
364+
</LogoWrapper>
365+
)}
366+
{!justify ?<ItemList$align={props.horizontalAlignment}$orientation={isVertical ?"vertical" :"horizontal"}>{items}</ItemList> :items}
367+
</NavInner>
368+
)}
369+
{isHamburger&&(
370+
<>
371+
<FloatingHamburgerButton
372+
$size={props.hamburgerSize||"56px"}
373+
$position={props.hamburgerPosition||"top-right"}
374+
$zIndex={Layers.tabBar+1}
375+
$background={props.hamburgerButtonStyle?.background}
376+
$borderColor={props.hamburgerButtonStyle?.border}
377+
$radius={props.hamburgerButtonStyle?.radius}
378+
$margin={props.hamburgerButtonStyle?.margin}
379+
$padding={props.hamburgerButtonStyle?.padding}
380+
$borderWidth={props.hamburgerButtonStyle?.borderWidth}
381+
$iconColor={props.hamburgerButtonStyle?.iconFill}
382+
onClick={()=>setDrawerVisible(true)}
383+
>
384+
<MenuOutlined/>
385+
</FloatingHamburgerButton>
386+
<Drawer
387+
placement={(props.drawerPlacementasany)||"right"}
388+
closable={true}
389+
onClose={()=>setDrawerVisible(false)}
390+
open={drawerVisible}
391+
mask={props.shadowOverlay}
392+
styles={{body:{padding:"8px",background:props.drawerContainerStyle?.background}}}
393+
destroyOnClose
394+
>
395+
<ItemList$align={"flex-start"}$orientation={"vertical"}>{items}</ItemList>
396+
</Drawer>
397+
</>
398+
)}
276399
</Wrapper>
277400
);
278401
})
@@ -292,10 +415,21 @@ const NavCompBase = new UICompBuilder(childrenMap, (props) => {
292415

293416
{(useContext(EditorContext).editorModeStatus==="layout"||useContext(EditorContext).editorModeStatus==="both")&&(
294417
<Sectionname={sectionNames.layout}>
295-
{children.horizontalAlignment.propertyView({
296-
label:trans("navigation.horizontalAlignment"),
297-
radioButton:true,
298-
})}
418+
{children.orientation.propertyView({label:"Orientation",radioButton:true})}
419+
{children.displayMode.propertyView({label:"Display Mode",radioButton:true})}
420+
{children.displayMode.getView()==='hamburger' ?(
421+
[
422+
children.hamburgerPosition.propertyView({label:"Hamburger Position"}),
423+
children.hamburgerSize.propertyView({label:"Hamburger Size"}),
424+
children.drawerPlacement.propertyView({label:"Drawer Placement",radioButton:true}),
425+
children.shadowOverlay.propertyView({label:"Shadow Overlay"}),
426+
]
427+
) :(
428+
children.horizontalAlignment.propertyView({
429+
label:trans("navigation.horizontalAlignment"),
430+
radioButton:true,
431+
})
432+
)}
299433
{hiddenPropertyView(children)}
300434
</Section>
301435
)}
@@ -313,6 +447,25 @@ const NavCompBase = new UICompBuilder(childrenMap, (props) => {
313447
<Sectionname={sectionNames.style}>
314448
{children.style.getPropertyView()}
315449
</Section>
450+
<Sectionname={"Item Style"}>
451+
{children.navItemStyle.getPropertyView()}
452+
</Section>
453+
<Sectionname={"Item Hover Style"}>
454+
{children.navItemHoverStyle.getPropertyView()}
455+
</Section>
456+
<Sectionname={"Item Active Style"}>
457+
{children.navItemActiveStyle.getPropertyView()}
458+
</Section>
459+
{children.displayMode.getView()==='hamburger'&&(
460+
<>
461+
<Sectionname={"Hamburger Button Style"}>
462+
{children.hamburgerButtonStyle.getPropertyView()}
463+
</Section>
464+
<Sectionname={"Drawer Container Style"}>
465+
{children.drawerContainerStyle.getPropertyView()}
466+
</Section>
467+
</>
468+
)}
316469
<Sectionname={sectionNames.animationStyle}hasTooltip={true}>
317470
{children.animationStyle.getPropertyView()}
318471
</Section>

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp