@thecb/components 11.2.13 → 11.2.14-beta.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs.js +9 -22
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.esm.js +9 -22
- package/dist/index.esm.js.map +1 -1
- package/package.json +1 -1
- package/src/components/atoms/.DS_Store +0 -0
- package/src/components/molecules/nav-menu/LinkMenu.js +258 -0
- package/src/components/molecules/nav-menu/NavLinks.js +138 -0
- package/src/components/molecules/nav-menu/NavMenuMobile.js +14 -21
- package/src/components/molecules/nav-menu/NavMenuMobile.mdx +9 -0
- package/src/components/molecules/nav-menu/NavMenuMobile.stories.js +124 -0
package/package.json
CHANGED
|
Binary file
|
|
@@ -0,0 +1,258 @@
|
|
|
1
|
+
import React, {
|
|
2
|
+
useCallback,
|
|
3
|
+
useContext,
|
|
4
|
+
useEffect,
|
|
5
|
+
useRef,
|
|
6
|
+
useState
|
|
7
|
+
} from "react";
|
|
8
|
+
import { test } from "ramda";
|
|
9
|
+
import {
|
|
10
|
+
Box,
|
|
11
|
+
Cluster,
|
|
12
|
+
constants,
|
|
13
|
+
Stack,
|
|
14
|
+
Paragraph,
|
|
15
|
+
ExternalLink,
|
|
16
|
+
InternalLink,
|
|
17
|
+
Switcher,
|
|
18
|
+
withWindowSize
|
|
19
|
+
} from "@thecb/components";
|
|
20
|
+
import { ThemeContext } from "styled-components";
|
|
21
|
+
import { URL_TEST } from "../../../constants/regex_constants";
|
|
22
|
+
import HeaderItem from "./HeaderItem";
|
|
23
|
+
import RightArrowIcon from "../../icons/RightArrowIcon";
|
|
24
|
+
import NavLabel from "./NavLabel";
|
|
25
|
+
import NavLink, { NavLinkLevels } from "./NavLink";
|
|
26
|
+
import { getCallToActionInfo } from "../../../util/dataAdapters";
|
|
27
|
+
|
|
28
|
+
const KEY_ARROW_DOWN = 40;
|
|
29
|
+
const KEY_ARROW_UP = 38;
|
|
30
|
+
const KEY_TAB = 9;
|
|
31
|
+
|
|
32
|
+
const Link = ({ url, id, onSetRef, children }) => {
|
|
33
|
+
return test(URL_TEST, url) ? (
|
|
34
|
+
<ExternalLink href={url} ref={element => onSetRef(id, element)}>
|
|
35
|
+
{children}
|
|
36
|
+
</ExternalLink>
|
|
37
|
+
) : (
|
|
38
|
+
<InternalLink to={url} ref={element => onSetRef(id, element)}>
|
|
39
|
+
{children}
|
|
40
|
+
</InternalLink>
|
|
41
|
+
);
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
const LinkMenu = ({
|
|
45
|
+
link,
|
|
46
|
+
onChangeMenu,
|
|
47
|
+
hamburgerMenuStyle,
|
|
48
|
+
kbNavUsed,
|
|
49
|
+
themeValues
|
|
50
|
+
}) => {
|
|
51
|
+
const { isMobile } = useContext(ThemeContext);
|
|
52
|
+
const linkElements = useRef({});
|
|
53
|
+
const [focusLink, setFocusLink] = useState(-1);
|
|
54
|
+
|
|
55
|
+
const setElementFocus = key => {
|
|
56
|
+
if (kbNavUsed) {
|
|
57
|
+
linkElements.current[key].focus();
|
|
58
|
+
}
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
const handleSetRef = useCallback((id, element) => {
|
|
62
|
+
return (linkElements.current[id] = element);
|
|
63
|
+
}, []);
|
|
64
|
+
|
|
65
|
+
useEffect(() => {
|
|
66
|
+
const ref1Key = Object.keys(linkElements.current)[0];
|
|
67
|
+
setElementFocus(ref1Key);
|
|
68
|
+
setFocusLink(0);
|
|
69
|
+
}, []);
|
|
70
|
+
|
|
71
|
+
const SmallLink = ({ text, showArrow = false }) => (
|
|
72
|
+
<Cluster justify="flex-start" align="center">
|
|
73
|
+
<Paragraph variant={isMobile ? "p" : "pS"} color={themeValues.linkColor}>
|
|
74
|
+
{text}
|
|
75
|
+
</Paragraph>
|
|
76
|
+
{showArrow && <RightArrowIcon size={18} color={themeValues.linkColor} />}
|
|
77
|
+
</Cluster>
|
|
78
|
+
);
|
|
79
|
+
|
|
80
|
+
const handleKeyDown = event => {
|
|
81
|
+
switch (event.keyCode) {
|
|
82
|
+
case KEY_TAB:
|
|
83
|
+
event.preventDefault();
|
|
84
|
+
onChangeMenu(event.shiftKey ? "previous" : "next");
|
|
85
|
+
break;
|
|
86
|
+
case KEY_ARROW_DOWN:
|
|
87
|
+
case KEY_ARROW_UP:
|
|
88
|
+
event.preventDefault();
|
|
89
|
+
const increment = event.keyCode === KEY_ARROW_DOWN ? 1 : -1;
|
|
90
|
+
const length = Object.keys(linkElements.current).length;
|
|
91
|
+
const newFocus = (focusLink + (increment % length) + length) % length;
|
|
92
|
+
const newFocusKey = Object.keys(linkElements.current)[newFocus];
|
|
93
|
+
setFocusLink(newFocus);
|
|
94
|
+
setElementFocus(newFocusKey);
|
|
95
|
+
break;
|
|
96
|
+
default:
|
|
97
|
+
break;
|
|
98
|
+
}
|
|
99
|
+
};
|
|
100
|
+
|
|
101
|
+
const renderSubLinkSectionName = subLink => {
|
|
102
|
+
const { ctaUrl: subLinkUrl } = getCallToActionInfo(
|
|
103
|
+
subLink.callToActionLink,
|
|
104
|
+
"",
|
|
105
|
+
subLink.nameUrl
|
|
106
|
+
);
|
|
107
|
+
if (hamburgerMenuStyle) {
|
|
108
|
+
return subLinkUrl ? (
|
|
109
|
+
<NavLink
|
|
110
|
+
url={subLinkUrl}
|
|
111
|
+
label={subLink.name}
|
|
112
|
+
themeValues={themeValues}
|
|
113
|
+
navLevel={NavLinkLevels.SUB_MENU}
|
|
114
|
+
/>
|
|
115
|
+
) : (
|
|
116
|
+
<NavLabel text={subLink.name} themeValues={themeValues} navLevel={1} />
|
|
117
|
+
);
|
|
118
|
+
} else {
|
|
119
|
+
return subLinkUrl ? (
|
|
120
|
+
<Link url={subLinkUrl} id={subLink.id} onSetRef={handleSetRef}>
|
|
121
|
+
<HeaderItem
|
|
122
|
+
name={subLink?.name}
|
|
123
|
+
showArrow={!hamburgerMenuStyle}
|
|
124
|
+
themeValues={themeValues}
|
|
125
|
+
/>
|
|
126
|
+
</Link>
|
|
127
|
+
) : (
|
|
128
|
+
<HeaderItem
|
|
129
|
+
name={subLink?.name}
|
|
130
|
+
showArrow={false}
|
|
131
|
+
themeValues={themeValues}
|
|
132
|
+
/>
|
|
133
|
+
);
|
|
134
|
+
}
|
|
135
|
+
};
|
|
136
|
+
|
|
137
|
+
const renderSubLinkLink = (smallLink, index) => {
|
|
138
|
+
if (hamburgerMenuStyle) {
|
|
139
|
+
return (
|
|
140
|
+
<NavLink
|
|
141
|
+
key={`navlink-${index}`}
|
|
142
|
+
url={smallLink.externalUrl}
|
|
143
|
+
label={smallLink.text}
|
|
144
|
+
themeValues={themeValues}
|
|
145
|
+
navLevel={NavLinkLevels.DETAIL}
|
|
146
|
+
/>
|
|
147
|
+
);
|
|
148
|
+
} else {
|
|
149
|
+
return (
|
|
150
|
+
<Box padding={"0"} key={`link-${index}`}>
|
|
151
|
+
<Link
|
|
152
|
+
url={smallLink.externalUrl}
|
|
153
|
+
id={smallLink.id}
|
|
154
|
+
onSetRef={handleSetRef}
|
|
155
|
+
>
|
|
156
|
+
<SmallLink text={smallLink.text} />
|
|
157
|
+
</Link>
|
|
158
|
+
</Box>
|
|
159
|
+
);
|
|
160
|
+
}
|
|
161
|
+
};
|
|
162
|
+
|
|
163
|
+
const { ctaUrl } = getCallToActionInfo(
|
|
164
|
+
link.callToActionLink,
|
|
165
|
+
"",
|
|
166
|
+
link.nameUrl
|
|
167
|
+
);
|
|
168
|
+
|
|
169
|
+
return (
|
|
170
|
+
<Box
|
|
171
|
+
padding={hamburgerMenuStyle ? "16px 0" : "0"}
|
|
172
|
+
background={
|
|
173
|
+
hamburgerMenuStyle ? constants.colors.ATHENS_GREY : "transparent"
|
|
174
|
+
}
|
|
175
|
+
onKeyDown={handleKeyDown}
|
|
176
|
+
extraStyles={
|
|
177
|
+
hamburgerMenuStyle ? "margin-left: 16px; margin-right: 16px;" : ""
|
|
178
|
+
}
|
|
179
|
+
>
|
|
180
|
+
<Switcher breakpoint="45rem" largeChild="1" largeChildSize="2">
|
|
181
|
+
{hamburgerMenuStyle ? (
|
|
182
|
+
<Box padding={hamburgerMenuStyle ? "0 16px 16px" : 0}>
|
|
183
|
+
<Paragraph variant="pS" color={constants.colors.CHARADE_GREY}>
|
|
184
|
+
{link?.description}
|
|
185
|
+
</Paragraph>
|
|
186
|
+
</Box>
|
|
187
|
+
) : (
|
|
188
|
+
<Box key="title-desc" padding={"0 16px 0 4px"}>
|
|
189
|
+
<Stack childGap="8px">
|
|
190
|
+
<Box padding="0">
|
|
191
|
+
{ctaUrl ? (
|
|
192
|
+
<Box padding="0">
|
|
193
|
+
<Link url={ctaUrl} id={link.id} onSetRef={handleSetRef}>
|
|
194
|
+
<HeaderItem
|
|
195
|
+
name={link?.name}
|
|
196
|
+
showArrow={!hamburgerMenuStyle}
|
|
197
|
+
themeValues={themeValues}
|
|
198
|
+
/>
|
|
199
|
+
</Link>
|
|
200
|
+
</Box>
|
|
201
|
+
) : (
|
|
202
|
+
<HeaderItem
|
|
203
|
+
name={link?.name}
|
|
204
|
+
showArrow={ctaUrl !== ""}
|
|
205
|
+
themeValues={themeValues}
|
|
206
|
+
/>
|
|
207
|
+
)}
|
|
208
|
+
</Box>
|
|
209
|
+
<Box padding={"16px 24px 16px 0"}>
|
|
210
|
+
<Paragraph variant="pS">{link?.description}</Paragraph>
|
|
211
|
+
</Box>
|
|
212
|
+
</Stack>
|
|
213
|
+
</Box>
|
|
214
|
+
)}
|
|
215
|
+
{link?.linkLists?.map((subLink, index) => (
|
|
216
|
+
<Box
|
|
217
|
+
padding={hamburgerMenuStyle ? "0" : "0 24px"}
|
|
218
|
+
key={`subLink-${index}`}
|
|
219
|
+
>
|
|
220
|
+
<Stack childGap={"1rem"}>
|
|
221
|
+
{renderSubLinkSectionName(subLink)}
|
|
222
|
+
{subLink?.links?.map((smallLink, index) =>
|
|
223
|
+
renderSubLinkLink(smallLink, index)
|
|
224
|
+
)}
|
|
225
|
+
</Stack>
|
|
226
|
+
</Box>
|
|
227
|
+
))}
|
|
228
|
+
<Box padding={hamburgerMenuStyle ? "16px 0" : "0 24px"}>
|
|
229
|
+
<Stack childGap={"1rem"}>
|
|
230
|
+
<Box padding={"0"}>
|
|
231
|
+
{hamburgerMenuStyle ? (
|
|
232
|
+
<NavLabel
|
|
233
|
+
text={"Featured Services"}
|
|
234
|
+
themeValues={themeValues}
|
|
235
|
+
navLevel={1}
|
|
236
|
+
/>
|
|
237
|
+
) : (
|
|
238
|
+
<HeaderItem
|
|
239
|
+
name="Featured Services"
|
|
240
|
+
showArrow={false}
|
|
241
|
+
themeValues={themeValues}
|
|
242
|
+
color={themeValues.linkColor}
|
|
243
|
+
weight={constants.fontWeights.FONT_WEIGHT_SEMIBOLD}
|
|
244
|
+
variant="p"
|
|
245
|
+
/>
|
|
246
|
+
)}
|
|
247
|
+
</Box>
|
|
248
|
+
{link?.featuredLinks?.links?.map((featuredLink, index) =>
|
|
249
|
+
renderSubLinkLink(featuredLink, index)
|
|
250
|
+
)}
|
|
251
|
+
</Stack>
|
|
252
|
+
</Box>
|
|
253
|
+
</Switcher>
|
|
254
|
+
</Box>
|
|
255
|
+
);
|
|
256
|
+
};
|
|
257
|
+
|
|
258
|
+
export default withWindowSize(LinkMenu);
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
import React, { useContext } from "react";
|
|
2
|
+
import { Box, Cover, Heading, Motion, withWindowSize } from "@thecb/components";
|
|
3
|
+
import { ThemeContext } from "styled-components";
|
|
4
|
+
import LinkMenu from "./LinkMenu";
|
|
5
|
+
import HamburgerNavSection from "./HamburgerNavSection";
|
|
6
|
+
import { borderWrapper } from "./style";
|
|
7
|
+
|
|
8
|
+
const NavLinks = ({
|
|
9
|
+
navigation,
|
|
10
|
+
hamburgerMenuStyle,
|
|
11
|
+
themeValues,
|
|
12
|
+
navMenuOpen,
|
|
13
|
+
hamburgerOpenSection,
|
|
14
|
+
selectedNavMenu,
|
|
15
|
+
setSearchMenuOpen,
|
|
16
|
+
setSelectedMenu,
|
|
17
|
+
setNavMenuOpen,
|
|
18
|
+
setIsAnimating,
|
|
19
|
+
setKeyboardNavUsed,
|
|
20
|
+
setHamburgerOpenSection
|
|
21
|
+
}) => {
|
|
22
|
+
const { isMobile } = useContext(ThemeContext);
|
|
23
|
+
const selectMenu = (index, kbNavUsed) => {
|
|
24
|
+
setKeyboardNavUsed(kbNavUsed);
|
|
25
|
+
if (navMenuOpen !== true) {
|
|
26
|
+
setSearchMenuOpen(false);
|
|
27
|
+
setSelectedMenu(index);
|
|
28
|
+
setNavMenuOpen(true);
|
|
29
|
+
setIsAnimating(true);
|
|
30
|
+
setTimeout(() => {
|
|
31
|
+
setIsAnimating(false);
|
|
32
|
+
}, 600);
|
|
33
|
+
} else if (selectedNavMenu !== index) {
|
|
34
|
+
setSelectedMenu(index);
|
|
35
|
+
setSearchMenuOpen(false);
|
|
36
|
+
}
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
return (
|
|
40
|
+
<>
|
|
41
|
+
{navigation?.sections?.map((link, index) => {
|
|
42
|
+
debugger;
|
|
43
|
+
return (
|
|
44
|
+
<Box
|
|
45
|
+
padding="0"
|
|
46
|
+
key={`nav-link-${index}`}
|
|
47
|
+
extraStyles={!hamburgerMenuStyle && `height: 102px;`}
|
|
48
|
+
>
|
|
49
|
+
<Cover
|
|
50
|
+
singleChild
|
|
51
|
+
minHeight={isMobile ? "0%" : "100%"}
|
|
52
|
+
key={`section-${index}`}
|
|
53
|
+
>
|
|
54
|
+
{hamburgerMenuStyle ? (
|
|
55
|
+
<HamburgerNavSection
|
|
56
|
+
link={link}
|
|
57
|
+
toggleSection={() => {
|
|
58
|
+
link?.id === hamburgerOpenSection
|
|
59
|
+
? setHamburgerOpenSection("")
|
|
60
|
+
: setHamburgerOpenSection(link?.id);
|
|
61
|
+
}}
|
|
62
|
+
isOpen={hamburgerOpenSection === link?.id}
|
|
63
|
+
name={link?.name}
|
|
64
|
+
themeValues={themeValues}
|
|
65
|
+
>
|
|
66
|
+
<Motion
|
|
67
|
+
padding="0"
|
|
68
|
+
transition={{ duration: 0.3 }}
|
|
69
|
+
positionTransition
|
|
70
|
+
extraStyles={`transform-origin: 100% 0;`}
|
|
71
|
+
>
|
|
72
|
+
<LinkMenu
|
|
73
|
+
key={link.id}
|
|
74
|
+
link={link}
|
|
75
|
+
hamburgerMenuStyle={hamburgerMenuStyle}
|
|
76
|
+
themeValues={themeValues}
|
|
77
|
+
kbNavUsed={false}
|
|
78
|
+
onChangeMenu={() => {
|
|
79
|
+
setNavMenuOpen(false);
|
|
80
|
+
setSelectedMenu(100);
|
|
81
|
+
}}
|
|
82
|
+
/>
|
|
83
|
+
</Motion>
|
|
84
|
+
</HamburgerNavSection>
|
|
85
|
+
) : (
|
|
86
|
+
<Box
|
|
87
|
+
padding="0"
|
|
88
|
+
as="button"
|
|
89
|
+
background="transparent"
|
|
90
|
+
tabIndex="0"
|
|
91
|
+
onClick={() => {
|
|
92
|
+
setSearchMenuOpen(false);
|
|
93
|
+
setSelectedMenu(index);
|
|
94
|
+
setNavMenuOpen(!navMenuOpen);
|
|
95
|
+
setIsAnimating(true);
|
|
96
|
+
setTimeout(() => {
|
|
97
|
+
setIsAnimating(false);
|
|
98
|
+
}, 600);
|
|
99
|
+
}}
|
|
100
|
+
onMouseEnter={() => selectMenu(index, false)}
|
|
101
|
+
onFocus={() => selectMenu(index, true)}
|
|
102
|
+
>
|
|
103
|
+
<Box padding="0 1.5rem">
|
|
104
|
+
<Heading
|
|
105
|
+
variant="h6"
|
|
106
|
+
color={isMobile ? "#FFFFFF" : themeValues.linkColor}
|
|
107
|
+
extraStyles={
|
|
108
|
+
isMobile ? "font-size: 14px;" : `font-size: 16px;`
|
|
109
|
+
}
|
|
110
|
+
>
|
|
111
|
+
{link?.name}
|
|
112
|
+
</Heading>
|
|
113
|
+
</Box>
|
|
114
|
+
</Box>
|
|
115
|
+
)}
|
|
116
|
+
{!hamburgerMenuStyle && (
|
|
117
|
+
<Motion
|
|
118
|
+
padding="0"
|
|
119
|
+
minWidth="100%"
|
|
120
|
+
variants={borderWrapper}
|
|
121
|
+
animate={navMenuOpen ? "open" : "closed"}
|
|
122
|
+
layoutTransition
|
|
123
|
+
extraStyles={`border-bottom: 3px solid ${
|
|
124
|
+
selectedNavMenu === index
|
|
125
|
+
? `${themeValues.linkColor}`
|
|
126
|
+
: `transparent`
|
|
127
|
+
}`}
|
|
128
|
+
/>
|
|
129
|
+
)}
|
|
130
|
+
</Cover>
|
|
131
|
+
</Box>
|
|
132
|
+
);
|
|
133
|
+
})}
|
|
134
|
+
</>
|
|
135
|
+
);
|
|
136
|
+
};
|
|
137
|
+
|
|
138
|
+
export default NavLinks;
|
|
@@ -4,33 +4,20 @@ import { Box, Motion } from "../../atoms/layouts";
|
|
|
4
4
|
import { fallbackValues } from "./NavMenu.theme.js";
|
|
5
5
|
import { themeComponent } from "../../../util/themeUtils";
|
|
6
6
|
|
|
7
|
+
// Use transforms (x) rather than left/right
|
|
7
8
|
const menuVariants = {
|
|
8
9
|
invisible: {
|
|
9
|
-
|
|
10
|
-
right: "100vw",
|
|
10
|
+
x: "-100vw",
|
|
11
11
|
transition: {
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
duration: 500
|
|
15
|
-
},
|
|
16
|
-
left: {
|
|
17
|
-
ease: "easeOut",
|
|
18
|
-
duration: 500
|
|
19
|
-
}
|
|
12
|
+
ease: "easeOut",
|
|
13
|
+
duration: 0.5
|
|
20
14
|
}
|
|
21
15
|
},
|
|
22
16
|
visible: {
|
|
23
|
-
|
|
24
|
-
right: "0",
|
|
17
|
+
x: "0",
|
|
25
18
|
transition: {
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
duration: 500
|
|
29
|
-
},
|
|
30
|
-
right: {
|
|
31
|
-
ease: "easeIn",
|
|
32
|
-
duration: 500
|
|
33
|
-
}
|
|
19
|
+
ease: "easeIn",
|
|
20
|
+
duration: 0.5
|
|
34
21
|
}
|
|
35
22
|
}
|
|
36
23
|
};
|
|
@@ -38,6 +25,8 @@ const menuVariants = {
|
|
|
38
25
|
const ImposterMenu = styled(Motion)`
|
|
39
26
|
position: fixed;
|
|
40
27
|
top: ${({ headerSize }) => headerSize};
|
|
28
|
+
left: 0;
|
|
29
|
+
right: 0;
|
|
41
30
|
`;
|
|
42
31
|
|
|
43
32
|
const NavMenuMobile = ({
|
|
@@ -58,7 +47,11 @@ const NavMenuMobile = ({
|
|
|
58
47
|
<Box
|
|
59
48
|
width="100vw"
|
|
60
49
|
padding="1rem 0.5rem"
|
|
61
|
-
extraStyles={`
|
|
50
|
+
extraStyles={`
|
|
51
|
+
position: relative;
|
|
52
|
+
max-width: 400px;
|
|
53
|
+
height: calc(100vh - 72px);
|
|
54
|
+
`}
|
|
62
55
|
background={themeValues.backgroundColor}
|
|
63
56
|
>
|
|
64
57
|
{menuContent}
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
import React, { useState } from "react";
|
|
2
|
+
import NavMenuMobile from "./NavMenuMobile";
|
|
3
|
+
// import { Box, Button } from "../../layouts";
|
|
4
|
+
import { Box } from "../../atoms/layouts";
|
|
5
|
+
import { ButtonWithAction } from "../../atoms";
|
|
6
|
+
|
|
7
|
+
import { fallbackValues } from "./NavMenu.theme";
|
|
8
|
+
|
|
9
|
+
export default {
|
|
10
|
+
title: "Molecules/NavMenuMobile",
|
|
11
|
+
component: NavMenuMobile,
|
|
12
|
+
tags: ["!autodocs"],
|
|
13
|
+
parameters: {
|
|
14
|
+
layout: "centered",
|
|
15
|
+
controls: { expanded: true }
|
|
16
|
+
},
|
|
17
|
+
args: {
|
|
18
|
+
id: "nav-menu-mobile",
|
|
19
|
+
menuContent: (
|
|
20
|
+
<Box>
|
|
21
|
+
<p>Menu Item 1</p>
|
|
22
|
+
<p>Menu Item 2</p>
|
|
23
|
+
<p>Menu Item 3</p>
|
|
24
|
+
</Box>
|
|
25
|
+
),
|
|
26
|
+
visible: false,
|
|
27
|
+
headerSize: "72px",
|
|
28
|
+
themeValues: fallbackValues
|
|
29
|
+
},
|
|
30
|
+
argTypes: {
|
|
31
|
+
id: {
|
|
32
|
+
description: "Unique identifier for the menu",
|
|
33
|
+
table: {
|
|
34
|
+
type: { summary: "string" },
|
|
35
|
+
defaultValue: { summary: "nav-menu-mobile" }
|
|
36
|
+
}
|
|
37
|
+
},
|
|
38
|
+
menuContent: {
|
|
39
|
+
description: "Content to display inside the menu",
|
|
40
|
+
table: {
|
|
41
|
+
type: { summary: "ReactNode" },
|
|
42
|
+
defaultValue: { summary: "undefined" }
|
|
43
|
+
}
|
|
44
|
+
},
|
|
45
|
+
visible: {
|
|
46
|
+
description: "Whether the menu is visible",
|
|
47
|
+
table: {
|
|
48
|
+
type: { summary: "boolean" },
|
|
49
|
+
defaultValue: { summary: false }
|
|
50
|
+
}
|
|
51
|
+
},
|
|
52
|
+
headerSize: {
|
|
53
|
+
description: "Height of the header, used to position the menu",
|
|
54
|
+
table: {
|
|
55
|
+
type: { summary: "string" },
|
|
56
|
+
defaultValue: { summary: "72px" }
|
|
57
|
+
}
|
|
58
|
+
},
|
|
59
|
+
themeValues: {
|
|
60
|
+
description: "Theme values for styling the menu",
|
|
61
|
+
table: {
|
|
62
|
+
type: { summary: "object" },
|
|
63
|
+
defaultValue: { summary: "fallbackValues" }
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
export const ProfileMenu = {
|
|
70
|
+
args: {
|
|
71
|
+
id: "profile-menu",
|
|
72
|
+
menuContent: (
|
|
73
|
+
<Box>
|
|
74
|
+
<p>Profile Item 1</p>
|
|
75
|
+
<p>Profile Item 2</p>
|
|
76
|
+
<p>Profile Item 3</p>
|
|
77
|
+
</Box>
|
|
78
|
+
),
|
|
79
|
+
visible: false,
|
|
80
|
+
headerSize: "72px",
|
|
81
|
+
themeValues: fallbackValues
|
|
82
|
+
},
|
|
83
|
+
render: args => {
|
|
84
|
+
const [visible, setVisible] = useState(false);
|
|
85
|
+
|
|
86
|
+
const toggleMenu = () => {
|
|
87
|
+
setVisible(prev => !prev);
|
|
88
|
+
};
|
|
89
|
+
|
|
90
|
+
return (
|
|
91
|
+
<Box>
|
|
92
|
+
<ButtonWithAction onClick={toggleMenu}>
|
|
93
|
+
{visible ? "Hide Menu" : "Show Menu"}
|
|
94
|
+
</ButtonWithAction>
|
|
95
|
+
<NavMenuMobile {...args} visible={visible} />
|
|
96
|
+
</Box>
|
|
97
|
+
);
|
|
98
|
+
}
|
|
99
|
+
};
|
|
100
|
+
|
|
101
|
+
export const DefaultMenu = {
|
|
102
|
+
args: {
|
|
103
|
+
visible: true
|
|
104
|
+
}
|
|
105
|
+
};
|
|
106
|
+
|
|
107
|
+
export const InteractiveMenu = {
|
|
108
|
+
render: args => {
|
|
109
|
+
const [visible, setVisible] = useState(false);
|
|
110
|
+
|
|
111
|
+
const toggleMenu = () => {
|
|
112
|
+
setVisible(prev => !prev);
|
|
113
|
+
};
|
|
114
|
+
|
|
115
|
+
return (
|
|
116
|
+
<Box>
|
|
117
|
+
<ButtonWithAction onClick={toggleMenu}>
|
|
118
|
+
{visible ? "Hide Menu" : "Show Menu"}
|
|
119
|
+
</ButtonWithAction>
|
|
120
|
+
<NavMenuMobile {...args} visible={visible} />
|
|
121
|
+
</Box>
|
|
122
|
+
);
|
|
123
|
+
}
|
|
124
|
+
};
|