@dt-dds/react-sidebar 1.0.0-beta.1
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/CHANGELOG.md +7 -0
- package/LICENSE.md +21 -0
- package/README.md +184 -0
- package/dist/index.d.mts +93 -0
- package/dist/index.d.ts +93 -0
- package/dist/index.js +1541 -0
- package/dist/index.mjs +1528 -0
- package/package.json +59 -0
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,1528 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __defProps = Object.defineProperties;
|
|
3
|
+
var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
|
|
4
|
+
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __propIsEnum = Object.prototype.propertyIsEnumerable;
|
|
7
|
+
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
8
|
+
var __spreadValues = (a, b) => {
|
|
9
|
+
for (var prop in b || (b = {}))
|
|
10
|
+
if (__hasOwnProp.call(b, prop))
|
|
11
|
+
__defNormalProp(a, prop, b[prop]);
|
|
12
|
+
if (__getOwnPropSymbols)
|
|
13
|
+
for (var prop of __getOwnPropSymbols(b)) {
|
|
14
|
+
if (__propIsEnum.call(b, prop))
|
|
15
|
+
__defNormalProp(a, prop, b[prop]);
|
|
16
|
+
}
|
|
17
|
+
return a;
|
|
18
|
+
};
|
|
19
|
+
var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
|
|
20
|
+
var __objRest = (source, exclude) => {
|
|
21
|
+
var target = {};
|
|
22
|
+
for (var prop in source)
|
|
23
|
+
if (__hasOwnProp.call(source, prop) && exclude.indexOf(prop) < 0)
|
|
24
|
+
target[prop] = source[prop];
|
|
25
|
+
if (source != null && __getOwnPropSymbols)
|
|
26
|
+
for (var prop of __getOwnPropSymbols(source)) {
|
|
27
|
+
if (exclude.indexOf(prop) < 0 && __propIsEnum.call(source, prop))
|
|
28
|
+
target[prop] = source[prop];
|
|
29
|
+
}
|
|
30
|
+
return target;
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
// src/Sidebar.tsx
|
|
34
|
+
import {
|
|
35
|
+
useMemo as useMemo5,
|
|
36
|
+
useCallback as useCallback4,
|
|
37
|
+
useState as useState5,
|
|
38
|
+
useEffect as useEffect4,
|
|
39
|
+
useRef as useRef3
|
|
40
|
+
} from "react";
|
|
41
|
+
import { useTheme as useTheme2 } from "@emotion/react";
|
|
42
|
+
import { useMedia } from "@dt-dds/react-core";
|
|
43
|
+
|
|
44
|
+
// src/components/SidebarBackdrop/SidebarBackdrop.tsx
|
|
45
|
+
import { useCallback } from "react";
|
|
46
|
+
|
|
47
|
+
// src/components/SidebarBackdrop/SidebarBackdrop.styled.ts
|
|
48
|
+
import styled from "@emotion/styled";
|
|
49
|
+
import { BACKDROP_Z_INDEX } from "@dt-dds/react-core";
|
|
50
|
+
import { hexToRgba } from "@dt-dds/themes";
|
|
51
|
+
var SidebarBackdropStyled = styled.div`
|
|
52
|
+
${({ theme, isOpen }) => {
|
|
53
|
+
if (!isOpen) {
|
|
54
|
+
return "display: none;";
|
|
55
|
+
}
|
|
56
|
+
return `
|
|
57
|
+
position: fixed;
|
|
58
|
+
width: 100%;
|
|
59
|
+
height: 100%;
|
|
60
|
+
top: 0;
|
|
61
|
+
right: 0;
|
|
62
|
+
bottom: 0;
|
|
63
|
+
left: 0;
|
|
64
|
+
background: ${hexToRgba(theme.palette.surface.dark, 0.2)};
|
|
65
|
+
z-index: ${BACKDROP_Z_INDEX};
|
|
66
|
+
overflow: hidden;
|
|
67
|
+
`;
|
|
68
|
+
}}
|
|
69
|
+
`;
|
|
70
|
+
|
|
71
|
+
// src/components/SidebarBackdrop/SidebarBackdrop.tsx
|
|
72
|
+
import { jsx } from "react/jsx-runtime";
|
|
73
|
+
var SidebarBackdrop = ({
|
|
74
|
+
isOpen,
|
|
75
|
+
onBackdropClick,
|
|
76
|
+
children,
|
|
77
|
+
dataTestId
|
|
78
|
+
}) => {
|
|
79
|
+
const handleBackdropClick = useCallback(
|
|
80
|
+
(event) => {
|
|
81
|
+
if (event.target === event.currentTarget && onBackdropClick) {
|
|
82
|
+
onBackdropClick();
|
|
83
|
+
}
|
|
84
|
+
},
|
|
85
|
+
[onBackdropClick]
|
|
86
|
+
);
|
|
87
|
+
if (!isOpen) {
|
|
88
|
+
return null;
|
|
89
|
+
}
|
|
90
|
+
return /* @__PURE__ */ jsx(
|
|
91
|
+
SidebarBackdropStyled,
|
|
92
|
+
{
|
|
93
|
+
"data-testid": dataTestId != null ? dataTestId : "sidebar-backdrop",
|
|
94
|
+
isOpen,
|
|
95
|
+
onClick: handleBackdropClick,
|
|
96
|
+
children
|
|
97
|
+
}
|
|
98
|
+
);
|
|
99
|
+
};
|
|
100
|
+
SidebarBackdrop.displayName = "Sidebar.Backdrop";
|
|
101
|
+
|
|
102
|
+
// src/components/SidebarDivider/SidebarDivider.tsx
|
|
103
|
+
import {
|
|
104
|
+
withResponsive
|
|
105
|
+
} from "@dt-dds/react-core";
|
|
106
|
+
|
|
107
|
+
// src/components/SidebarDivider/SidebarDivider.styled.ts
|
|
108
|
+
import styled2 from "@emotion/styled";
|
|
109
|
+
var SidebarDividerStyled = styled2.hr`
|
|
110
|
+
${({ theme }) => `
|
|
111
|
+
height: 1px;
|
|
112
|
+
margin: ${theme.spacing.spacing_0};
|
|
113
|
+
border: none;
|
|
114
|
+
background-color: ${theme.palette.border.default};
|
|
115
|
+
`}
|
|
116
|
+
`;
|
|
117
|
+
|
|
118
|
+
// src/components/SidebarDivider/SidebarDivider.tsx
|
|
119
|
+
import { jsx as jsx2 } from "react/jsx-runtime";
|
|
120
|
+
var SidebarDividerBase = (_a) => {
|
|
121
|
+
var _b = _a, {
|
|
122
|
+
dataTestId,
|
|
123
|
+
style
|
|
124
|
+
} = _b, rest = __objRest(_b, [
|
|
125
|
+
"dataTestId",
|
|
126
|
+
"style"
|
|
127
|
+
]);
|
|
128
|
+
return /* @__PURE__ */ jsx2(
|
|
129
|
+
SidebarDividerStyled,
|
|
130
|
+
__spreadValues({
|
|
131
|
+
"data-testid": dataTestId != null ? dataTestId : "sidebar-divider",
|
|
132
|
+
style
|
|
133
|
+
}, rest)
|
|
134
|
+
);
|
|
135
|
+
};
|
|
136
|
+
SidebarDividerBase.displayName = "Sidebar.Divider";
|
|
137
|
+
var SidebarDivider = withResponsive(SidebarDividerBase);
|
|
138
|
+
|
|
139
|
+
// src/components/SidebarSection/SidebarSection.tsx
|
|
140
|
+
import { useMemo } from "react";
|
|
141
|
+
import { useTheme } from "@emotion/react";
|
|
142
|
+
import { Typography as Typography2 } from "@dt-dds/react-typography";
|
|
143
|
+
|
|
144
|
+
// src/components/SidebarSection/SidebarSectionRoot.styled.ts
|
|
145
|
+
import styled3 from "@emotion/styled";
|
|
146
|
+
|
|
147
|
+
// src/constants/index.ts
|
|
148
|
+
var SIDEBAR_WIDTH = 250;
|
|
149
|
+
var SIDEBAR_WIDTH_MAX_TEXT_LENGTH = 170;
|
|
150
|
+
var SIDEBAR_WIDTH_MINI = 70;
|
|
151
|
+
var SIDEBAR_HEADER_HEIGHT = 64;
|
|
152
|
+
var SIDEBAR_HEADER_HEIGHT_MOBILE = 72;
|
|
153
|
+
var SIDEBAR_DEFAULT_OFFSET_TOP = 0;
|
|
154
|
+
var SIDEBAR_DEFAULT_OFFSET_POSITION = 0;
|
|
155
|
+
var SIDEBAR_DEFAULT_PLACEMENT = "left";
|
|
156
|
+
var SIDEBAR_MOBILE_PLACEMENT = "right";
|
|
157
|
+
var SIDEBAR_BACKDROP_SHOW_DELAY = 50;
|
|
158
|
+
var SIDEBAR_BACKDROP_HIDE_DELAY = 200;
|
|
159
|
+
var SIDEBAR_DEFAULT_TRANSITION = "all 0.2s ease-in-out";
|
|
160
|
+
|
|
161
|
+
// src/components/SidebarSection/SidebarSectionRoot.styled.ts
|
|
162
|
+
var SidebarSectionRoot = styled3.section`
|
|
163
|
+
${({ theme, variant, isSidebarCollapsed, firstItemHasIcon }) => {
|
|
164
|
+
const shouldHide = isSidebarCollapsed && !firstItemHasIcon;
|
|
165
|
+
return `
|
|
166
|
+
display: ${shouldHide ? "none" : "flex"};
|
|
167
|
+
flex-direction: column;
|
|
168
|
+
margin: 0;
|
|
169
|
+
padding: ${theme.spacing.spacing_50} ${theme.spacing.spacing_0};
|
|
170
|
+
|
|
171
|
+
ul {
|
|
172
|
+
display: flex;
|
|
173
|
+
flex-direction: column;
|
|
174
|
+
list-style-type: none;
|
|
175
|
+
margin: 0;
|
|
176
|
+
padding: 0;
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
${variant === "header" && `
|
|
180
|
+
height: ${SIDEBAR_HEADER_HEIGHT}px;
|
|
181
|
+
justify-content: center;
|
|
182
|
+
overflow: hidden;
|
|
183
|
+
|
|
184
|
+
@media (min-width: ${theme.breakpoints.mq3}px) {
|
|
185
|
+
height: ${SIDEBAR_HEADER_HEIGHT_MOBILE}px;
|
|
186
|
+
}
|
|
187
|
+
`}
|
|
188
|
+
`;
|
|
189
|
+
}}
|
|
190
|
+
`;
|
|
191
|
+
|
|
192
|
+
// src/context/SidebarContext.tsx
|
|
193
|
+
import { createContext, useContext } from "react";
|
|
194
|
+
import { jsx as jsx3 } from "react/jsx-runtime";
|
|
195
|
+
var SidebarContext = createContext(null);
|
|
196
|
+
var SidebarContextProvider = ({
|
|
197
|
+
value,
|
|
198
|
+
children
|
|
199
|
+
}) => {
|
|
200
|
+
return /* @__PURE__ */ jsx3(SidebarContext.Provider, { value, children });
|
|
201
|
+
};
|
|
202
|
+
var useSidebarContext = () => {
|
|
203
|
+
const context = useContext(SidebarContext);
|
|
204
|
+
if (!context) {
|
|
205
|
+
throw new Error("Sidebar compound components must be used within Sidebar");
|
|
206
|
+
}
|
|
207
|
+
return context;
|
|
208
|
+
};
|
|
209
|
+
|
|
210
|
+
// src/context/SectionContext.tsx
|
|
211
|
+
import { createContext as createContext2, useContext as useContext2 } from "react";
|
|
212
|
+
var SectionContext = createContext2(null);
|
|
213
|
+
var useSectionContext = () => {
|
|
214
|
+
var _a;
|
|
215
|
+
const context = useContext2(SectionContext);
|
|
216
|
+
return (_a = context == null ? void 0 : context.variant) != null ? _a : "default";
|
|
217
|
+
};
|
|
218
|
+
|
|
219
|
+
// src/context/SubListContext.tsx
|
|
220
|
+
import { createContext as createContext3, useContext as useContext3 } from "react";
|
|
221
|
+
var SubListContext = createContext3(null);
|
|
222
|
+
var useSubListContext = () => {
|
|
223
|
+
var _a;
|
|
224
|
+
const context = useContext3(SubListContext);
|
|
225
|
+
return (_a = context == null ? void 0 : context.isNested) != null ? _a : false;
|
|
226
|
+
};
|
|
227
|
+
|
|
228
|
+
// src/utils/sidebarUtils.ts
|
|
229
|
+
import {
|
|
230
|
+
Children,
|
|
231
|
+
isValidElement,
|
|
232
|
+
Fragment
|
|
233
|
+
} from "react";
|
|
234
|
+
var calculateSidebarWidth = (isMobile, isExpanded) => {
|
|
235
|
+
if (isMobile || isExpanded) {
|
|
236
|
+
return SIDEBAR_WIDTH;
|
|
237
|
+
}
|
|
238
|
+
return SIDEBAR_WIDTH_MINI;
|
|
239
|
+
};
|
|
240
|
+
var calculateSidebarPosition = (isMobile, isExpanded) => {
|
|
241
|
+
if (isMobile) {
|
|
242
|
+
return isExpanded ? SIDEBAR_DEFAULT_OFFSET_POSITION : -SIDEBAR_WIDTH;
|
|
243
|
+
}
|
|
244
|
+
return SIDEBAR_DEFAULT_OFFSET_POSITION;
|
|
245
|
+
};
|
|
246
|
+
var isSidebarItemElement = (child) => {
|
|
247
|
+
if (!isValidElement(child)) return false;
|
|
248
|
+
const componentType = child.type;
|
|
249
|
+
if ((componentType == null ? void 0 : componentType.displayName) === "SidebarItem") return true;
|
|
250
|
+
if (typeof child.type === "function" && child.type.name === "SidebarItem")
|
|
251
|
+
return true;
|
|
252
|
+
return false;
|
|
253
|
+
};
|
|
254
|
+
var isSidebarSubList = (child) => {
|
|
255
|
+
if (!isValidElement(child)) return false;
|
|
256
|
+
const componentType = child.type;
|
|
257
|
+
if ((componentType == null ? void 0 : componentType.displayName) === "SidebarSubList") return true;
|
|
258
|
+
if (typeof child.type === "function" && child.type.name === "SidebarSubList")
|
|
259
|
+
return true;
|
|
260
|
+
return false;
|
|
261
|
+
};
|
|
262
|
+
var findDirectSidebarItems = (node) => {
|
|
263
|
+
var _a, _b;
|
|
264
|
+
const items = [];
|
|
265
|
+
if (!isValidElement(node)) return items;
|
|
266
|
+
if (isSidebarItemElement(node)) {
|
|
267
|
+
items.push(node);
|
|
268
|
+
return items;
|
|
269
|
+
}
|
|
270
|
+
if (node.type === Fragment && ((_a = node.props) == null ? void 0 : _a.children)) {
|
|
271
|
+
const fragmentChildren = Children.toArray(node.props.children);
|
|
272
|
+
fragmentChildren.forEach((child) => {
|
|
273
|
+
if (isValidElement(child) && isSidebarItemElement(child)) {
|
|
274
|
+
items.push(child);
|
|
275
|
+
}
|
|
276
|
+
});
|
|
277
|
+
return items;
|
|
278
|
+
}
|
|
279
|
+
if ((_b = node.props) == null ? void 0 : _b.children) {
|
|
280
|
+
const children = Children.toArray(node.props.children);
|
|
281
|
+
children.forEach((child) => {
|
|
282
|
+
if (isValidElement(child) && isSidebarItemElement(child)) {
|
|
283
|
+
items.push(child);
|
|
284
|
+
}
|
|
285
|
+
});
|
|
286
|
+
}
|
|
287
|
+
return items;
|
|
288
|
+
};
|
|
289
|
+
var isIconElement = (child) => {
|
|
290
|
+
if (!isValidElement(child)) return false;
|
|
291
|
+
const componentType = child.type;
|
|
292
|
+
if ((componentType == null ? void 0 : componentType.displayName) === "Icon" || (componentType == null ? void 0 : componentType.displayName) === "IconButton" || (componentType == null ? void 0 : componentType.displayName) === "SidebarToggle")
|
|
293
|
+
return true;
|
|
294
|
+
if (typeof child.type === "function" && (child.type.name === "Icon" || child.type.name === "IconButton" || child.type.name === "SidebarToggle"))
|
|
295
|
+
return true;
|
|
296
|
+
if (typeof child.type === "string" && child.type === "i") return true;
|
|
297
|
+
return false;
|
|
298
|
+
};
|
|
299
|
+
var isSidebarToggleElement = (child) => {
|
|
300
|
+
if (!isValidElement(child)) return false;
|
|
301
|
+
const componentType = child.type;
|
|
302
|
+
if ((componentType == null ? void 0 : componentType.displayName) === "SidebarToggle") return true;
|
|
303
|
+
if (typeof child.type === "function" && child.type.name === "SidebarToggle")
|
|
304
|
+
return true;
|
|
305
|
+
return false;
|
|
306
|
+
};
|
|
307
|
+
var extractIconsFromNode = (node, icons = []) => {
|
|
308
|
+
var _a, _b;
|
|
309
|
+
if (!isValidElement(node)) return icons;
|
|
310
|
+
if (isIconElement(node)) {
|
|
311
|
+
icons.push(node);
|
|
312
|
+
return icons;
|
|
313
|
+
}
|
|
314
|
+
if (isSidebarSubList(node)) return icons;
|
|
315
|
+
if (isSidebarItemElement(node)) return icons;
|
|
316
|
+
if (node.type === Fragment && ((_a = node.props) == null ? void 0 : _a.children)) {
|
|
317
|
+
const fragmentChildren = Children.toArray(node.props.children);
|
|
318
|
+
fragmentChildren.forEach((child) => extractIconsFromNode(child, icons));
|
|
319
|
+
return icons;
|
|
320
|
+
}
|
|
321
|
+
const nodeChildren = (_b = node.props) == null ? void 0 : _b.children;
|
|
322
|
+
if (nodeChildren !== void 0 && nodeChildren !== null) {
|
|
323
|
+
const nestedChildren = Children.toArray(nodeChildren);
|
|
324
|
+
nestedChildren.forEach((child) => extractIconsFromNode(child, icons));
|
|
325
|
+
}
|
|
326
|
+
return icons;
|
|
327
|
+
};
|
|
328
|
+
var extractIconsFromChildren = (children) => {
|
|
329
|
+
const icons = [];
|
|
330
|
+
const childrenArray = Children.toArray(children);
|
|
331
|
+
childrenArray.forEach((child) => {
|
|
332
|
+
extractIconsFromNode(child, icons);
|
|
333
|
+
});
|
|
334
|
+
return icons;
|
|
335
|
+
};
|
|
336
|
+
var hasIconInChildren = (children) => {
|
|
337
|
+
return extractIconsFromChildren(children).length > 0;
|
|
338
|
+
};
|
|
339
|
+
var hasFirstItemIcon = (children) => {
|
|
340
|
+
const childrenArray = Children.toArray(children);
|
|
341
|
+
return childrenArray.some((child) => {
|
|
342
|
+
const directItems = findDirectSidebarItems(child);
|
|
343
|
+
return directItems.some((item) => {
|
|
344
|
+
if (isValidElement(item)) {
|
|
345
|
+
const itemChildren = item.props.children || [];
|
|
346
|
+
return hasIconInChildren(itemChildren);
|
|
347
|
+
}
|
|
348
|
+
return false;
|
|
349
|
+
});
|
|
350
|
+
});
|
|
351
|
+
};
|
|
352
|
+
|
|
353
|
+
// src/utils/urlUtils.ts
|
|
354
|
+
var getCurrentPath = () => {
|
|
355
|
+
if (typeof window === "undefined") return "";
|
|
356
|
+
return window.location.pathname;
|
|
357
|
+
};
|
|
358
|
+
var getHrefPath = (href) => {
|
|
359
|
+
try {
|
|
360
|
+
return new URL(
|
|
361
|
+
href,
|
|
362
|
+
typeof window !== "undefined" ? window.location.origin : "http://localhost"
|
|
363
|
+
).pathname;
|
|
364
|
+
} catch (e) {
|
|
365
|
+
return href.startsWith("/") ? href : `/${href}`;
|
|
366
|
+
}
|
|
367
|
+
};
|
|
368
|
+
var isCurrentUrl = (href, currentPath) => {
|
|
369
|
+
if (!href) return false;
|
|
370
|
+
const pathToCompare = currentPath != null ? currentPath : getCurrentPath();
|
|
371
|
+
const hrefPath = getHrefPath(href);
|
|
372
|
+
return hrefPath ? pathToCompare === hrefPath : false;
|
|
373
|
+
};
|
|
374
|
+
|
|
375
|
+
// src/utils/sidebarItemUtils.ts
|
|
376
|
+
import { Children as Children2, Fragment as Fragment2, isValidElement as isValidElement2 } from "react";
|
|
377
|
+
var isLinkElement = (child) => {
|
|
378
|
+
if (!isValidElement2(child)) return false;
|
|
379
|
+
return child.type === "a" || "href" in (child.props || {});
|
|
380
|
+
};
|
|
381
|
+
var findSubListInChildren = (node) => {
|
|
382
|
+
if (!isValidElement2(node)) return false;
|
|
383
|
+
if (isSidebarSubList(node)) return true;
|
|
384
|
+
if (node.type === Fragment2 && node.props.children) {
|
|
385
|
+
return Children2.toArray(node.props.children).some(findSubListInChildren);
|
|
386
|
+
}
|
|
387
|
+
return false;
|
|
388
|
+
};
|
|
389
|
+
var flattenChildren = (children) => {
|
|
390
|
+
return Children2.toArray(children).flatMap((child) => {
|
|
391
|
+
if (isValidElement2(child) && child.type === Fragment2 && child.props.children) {
|
|
392
|
+
return flattenChildren(child.props.children);
|
|
393
|
+
}
|
|
394
|
+
return [child];
|
|
395
|
+
});
|
|
396
|
+
};
|
|
397
|
+
var partitionChildren = (children) => {
|
|
398
|
+
const allChildren = flattenChildren(children);
|
|
399
|
+
return allChildren.reduce(
|
|
400
|
+
(acc, child) => {
|
|
401
|
+
if (findSubListInChildren(child)) {
|
|
402
|
+
acc.subList.push(child);
|
|
403
|
+
} else {
|
|
404
|
+
acc.otherChildren.push(child);
|
|
405
|
+
}
|
|
406
|
+
return acc;
|
|
407
|
+
},
|
|
408
|
+
{ subList: [], otherChildren: [] }
|
|
409
|
+
);
|
|
410
|
+
};
|
|
411
|
+
var containsActiveSidebarItem = (node, currentPath, isCurrentUrl2) => {
|
|
412
|
+
var _a;
|
|
413
|
+
if (!isValidElement2(node)) return false;
|
|
414
|
+
if (isSidebarItemElement(node)) {
|
|
415
|
+
return isCurrentUrl2(node.props.href, currentPath);
|
|
416
|
+
}
|
|
417
|
+
if (!((_a = node.props) == null ? void 0 : _a.children)) return false;
|
|
418
|
+
return Children2.toArray(node.props.children).some(
|
|
419
|
+
(childNode) => containsActiveSidebarItem(childNode, currentPath, isCurrentUrl2)
|
|
420
|
+
);
|
|
421
|
+
};
|
|
422
|
+
var isLinkTarget = (target) => {
|
|
423
|
+
if (!(target instanceof HTMLElement)) return false;
|
|
424
|
+
return !!target.closest("a");
|
|
425
|
+
};
|
|
426
|
+
|
|
427
|
+
// src/utils/sidebarItemRenderers.tsx
|
|
428
|
+
import { Children as Children4, cloneElement, isValidElement as isValidElement4 } from "react";
|
|
429
|
+
|
|
430
|
+
// src/utils/sidebarItemContent.tsx
|
|
431
|
+
import { Children as Children3, isValidElement as isValidElement3 } from "react";
|
|
432
|
+
import { Tooltip } from "@dt-dds/react-tooltip";
|
|
433
|
+
|
|
434
|
+
// src/components/SidebarItem/SidebarItem.styled.ts
|
|
435
|
+
import styled4 from "@emotion/styled";
|
|
436
|
+
import { Typography } from "@dt-dds/react-typography";
|
|
437
|
+
var SidebarItemStyled = styled4.li`
|
|
438
|
+
margin: 0;
|
|
439
|
+
padding: 0;
|
|
440
|
+
list-style: none;
|
|
441
|
+
`;
|
|
442
|
+
var SidebarItemHeaderStyled = styled4.div`
|
|
443
|
+
${({
|
|
444
|
+
theme,
|
|
445
|
+
isActive,
|
|
446
|
+
isSidebarCollapsed,
|
|
447
|
+
isInteractive = true,
|
|
448
|
+
isNested = false,
|
|
449
|
+
sectionVariant
|
|
450
|
+
}) => {
|
|
451
|
+
const padding = isNested ? `${theme.spacing.spacing_30} ${theme.spacing.spacing_80}` : `${theme.spacing.spacing_30} ${theme.spacing.spacing_60}`;
|
|
452
|
+
const paddingRight = `${isSidebarCollapsed ? "auto" : theme.spacing.spacing_30}`;
|
|
453
|
+
const justifyContent = `${isSidebarCollapsed ? "center" : "space-between"}`;
|
|
454
|
+
return `
|
|
455
|
+
cursor: ${isInteractive ? "pointer" : "default"};
|
|
456
|
+
display: flex;
|
|
457
|
+
align-items: center;
|
|
458
|
+
padding: ${padding};
|
|
459
|
+
padding-right: ${paddingRight};
|
|
460
|
+
color: ${isActive ? theme.palette.accent.default : theme.palette.content.default};
|
|
461
|
+
justify-content: ${justifyContent};
|
|
462
|
+
|
|
463
|
+
&[role="button"] {
|
|
464
|
+
justify-content: ${justifyContent};
|
|
465
|
+
}
|
|
466
|
+
|
|
467
|
+
${sectionVariant === "default" && `
|
|
468
|
+
transition: ${SIDEBAR_DEFAULT_TRANSITION};
|
|
469
|
+
|
|
470
|
+
&:hover,
|
|
471
|
+
&:focus-visible,
|
|
472
|
+
&:active {
|
|
473
|
+
background-color: ${theme.palette.accent.light};
|
|
474
|
+
}
|
|
475
|
+
`}
|
|
476
|
+
`;
|
|
477
|
+
}}
|
|
478
|
+
`;
|
|
479
|
+
var SidebarItemBodyStyled = styled4.div`
|
|
480
|
+
${({ isExpanded, isSidebarJustExpanded }) => {
|
|
481
|
+
const shouldDelay = isSidebarJustExpanded && isExpanded;
|
|
482
|
+
return `
|
|
483
|
+
display: grid;
|
|
484
|
+
grid-template-rows: ${isExpanded ? "1fr" : "0fr"};
|
|
485
|
+
transition: ${SIDEBAR_DEFAULT_TRANSITION};
|
|
486
|
+
overflow: hidden;
|
|
487
|
+
|
|
488
|
+
& > * {
|
|
489
|
+
min-height: 0;
|
|
490
|
+
opacity: ${shouldDelay ? "0" : isExpanded ? "1" : "0"};
|
|
491
|
+
visibility: ${shouldDelay ? "hidden" : isExpanded ? "visible" : "hidden"};
|
|
492
|
+
${shouldDelay ? `
|
|
493
|
+
transition: none;
|
|
494
|
+
animation: fadeInDelayed 0s ease-in-out 0s forwards;
|
|
495
|
+
@keyframes fadeInDelayed {
|
|
496
|
+
from {
|
|
497
|
+
opacity: 0;
|
|
498
|
+
visibility: hidden;
|
|
499
|
+
}
|
|
500
|
+
to {
|
|
501
|
+
opacity: 1;
|
|
502
|
+
visibility: visible;
|
|
503
|
+
}
|
|
504
|
+
}
|
|
505
|
+
` : `
|
|
506
|
+
transition: ${SIDEBAR_DEFAULT_TRANSITION};
|
|
507
|
+
`}
|
|
508
|
+
}
|
|
509
|
+
`;
|
|
510
|
+
}}
|
|
511
|
+
`;
|
|
512
|
+
var defaultSidebarItemLinkStyles = ({
|
|
513
|
+
theme,
|
|
514
|
+
isActive,
|
|
515
|
+
isSidebarCollapsed,
|
|
516
|
+
sectionVariant
|
|
517
|
+
}) => `
|
|
518
|
+
display: flex;
|
|
519
|
+
align-items: center;
|
|
520
|
+
width: ${isSidebarCollapsed ? "auto" : "100%"};
|
|
521
|
+
gap: ${theme.spacing.spacing_40};
|
|
522
|
+
color: inherit;
|
|
523
|
+
text-decoration: none;
|
|
524
|
+
cursor: pointer;
|
|
525
|
+
transition: ${SIDEBAR_DEFAULT_TRANSITION};
|
|
526
|
+
|
|
527
|
+
${sectionVariant === "header" ? `
|
|
528
|
+
justify-content: space-between;
|
|
529
|
+
flex-direction: row-reverse;
|
|
530
|
+
|
|
531
|
+
&:has(> :only-child:not(button)) {
|
|
532
|
+
flex-direction: row;
|
|
533
|
+
}
|
|
534
|
+
|
|
535
|
+
svg,
|
|
536
|
+
img {
|
|
537
|
+
max-height: 24px;
|
|
538
|
+
width: auto;
|
|
539
|
+
}
|
|
540
|
+
` : ""}
|
|
541
|
+
${isSidebarCollapsed ? `
|
|
542
|
+
justify-content: center;
|
|
543
|
+
padding: ${theme.spacing.spacing_10};
|
|
544
|
+
` : ""}
|
|
545
|
+
|
|
546
|
+
> i:first-of-type {
|
|
547
|
+
opacity: 1;
|
|
548
|
+
visibility: visible;
|
|
549
|
+
color: ${isActive ? theme.palette.accent.default : theme.palette.content.dark};
|
|
550
|
+
|
|
551
|
+
transition: ${SIDEBAR_DEFAULT_TRANSITION};
|
|
552
|
+
}
|
|
553
|
+
|
|
554
|
+
&:hover,
|
|
555
|
+
&:focus-visible,
|
|
556
|
+
&:active,
|
|
557
|
+
&:hover > i:first-of-type {
|
|
558
|
+
color: ${theme.palette.accent.default};
|
|
559
|
+
}
|
|
560
|
+
`;
|
|
561
|
+
var SidebarItemLinkStyled = styled4(Typography)`
|
|
562
|
+
${({
|
|
563
|
+
theme,
|
|
564
|
+
isActive,
|
|
565
|
+
isSidebarCollapsed,
|
|
566
|
+
isDynamicLink,
|
|
567
|
+
isNested,
|
|
568
|
+
sectionVariant
|
|
569
|
+
}) => isDynamicLink ? `
|
|
570
|
+
> a,
|
|
571
|
+
> *[href] {
|
|
572
|
+
${defaultSidebarItemLinkStyles({
|
|
573
|
+
theme,
|
|
574
|
+
isActive,
|
|
575
|
+
isSidebarCollapsed,
|
|
576
|
+
isNested,
|
|
577
|
+
sectionVariant
|
|
578
|
+
})}
|
|
579
|
+
}
|
|
580
|
+
` : defaultSidebarItemLinkStyles({
|
|
581
|
+
theme,
|
|
582
|
+
isActive,
|
|
583
|
+
isSidebarCollapsed,
|
|
584
|
+
isNested,
|
|
585
|
+
sectionVariant
|
|
586
|
+
})}
|
|
587
|
+
`;
|
|
588
|
+
var SidebarItemTextContent = styled4.span`
|
|
589
|
+
${({ isSidebarCollapsed }) => `
|
|
590
|
+
max-width: ${SIDEBAR_WIDTH_MAX_TEXT_LENGTH}px;
|
|
591
|
+
opacity: ${isSidebarCollapsed ? "0" : "1"};
|
|
592
|
+
visibility: ${isSidebarCollapsed ? "hidden" : "visible"};
|
|
593
|
+
white-space: nowrap;
|
|
594
|
+
overflow: hidden;
|
|
595
|
+
text-overflow: ellipsis;
|
|
596
|
+
`}
|
|
597
|
+
`;
|
|
598
|
+
|
|
599
|
+
// src/utils/sidebarItemContent.tsx
|
|
600
|
+
import { jsx as jsx4, jsxs } from "react/jsx-runtime";
|
|
601
|
+
var extractTextContent = (children) => {
|
|
602
|
+
const directString = children.find(
|
|
603
|
+
(child) => typeof child === "string"
|
|
604
|
+
);
|
|
605
|
+
if (directString) {
|
|
606
|
+
return directString;
|
|
607
|
+
}
|
|
608
|
+
for (const child of children) {
|
|
609
|
+
if (isSidebarToggleElement(child)) return "Expand sidebar";
|
|
610
|
+
if (isValidElement3(child) && child.props.children) {
|
|
611
|
+
const nestedChildren = Children3.toArray(child.props.children);
|
|
612
|
+
const nestedString = nestedChildren.find(
|
|
613
|
+
(nested) => typeof nested === "string"
|
|
614
|
+
);
|
|
615
|
+
if (nestedString) {
|
|
616
|
+
return nestedString;
|
|
617
|
+
}
|
|
618
|
+
}
|
|
619
|
+
}
|
|
620
|
+
return void 0;
|
|
621
|
+
};
|
|
622
|
+
var partitionIconAndContent = (children) => {
|
|
623
|
+
const childrenArray = Children3.toArray(children);
|
|
624
|
+
const firstIconIndex = childrenArray.findIndex(isIconElement);
|
|
625
|
+
if (firstIconIndex === -1) {
|
|
626
|
+
return { firstIcon: null, textContent: childrenArray };
|
|
627
|
+
}
|
|
628
|
+
const firstIcon = childrenArray[firstIconIndex];
|
|
629
|
+
const textContent = [
|
|
630
|
+
...childrenArray.slice(0, firstIconIndex),
|
|
631
|
+
...childrenArray.slice(firstIconIndex + 1)
|
|
632
|
+
];
|
|
633
|
+
return { firstIcon, textContent };
|
|
634
|
+
};
|
|
635
|
+
var wrapTextContent = (textContent, isSidebarCollapsed) => textContent.length > 0 ? /* @__PURE__ */ jsx4(SidebarItemTextContent, { isSidebarCollapsed, children: textContent }) : null;
|
|
636
|
+
var wrapWithTooltip = (content, tooltipText) => tooltipText ? /* @__PURE__ */ jsxs(Tooltip, { children: [
|
|
637
|
+
content,
|
|
638
|
+
/* @__PURE__ */ jsx4(Tooltip.Content, { background: "full", direction: "right", children: tooltipText })
|
|
639
|
+
] }) : content;
|
|
640
|
+
var createLinkWrapperProps = (isActive, isSidebarCollapsed, isNested, sectionVariant) => ({
|
|
641
|
+
isActive,
|
|
642
|
+
isSidebarCollapsed,
|
|
643
|
+
isNested,
|
|
644
|
+
sectionVariant
|
|
645
|
+
});
|
|
646
|
+
var createLinkStyledProps = (href, isActive, isSidebarCollapsed, isNested, sectionVariant) => __spreadValues({
|
|
647
|
+
href,
|
|
648
|
+
isActive,
|
|
649
|
+
isSidebarCollapsed,
|
|
650
|
+
isNested,
|
|
651
|
+
sectionVariant
|
|
652
|
+
}, href && isActive && { "aria-current": "page" });
|
|
653
|
+
|
|
654
|
+
// src/utils/sidebarItemRenderers.tsx
|
|
655
|
+
import { Fragment as Fragment3, jsx as jsx5, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
656
|
+
var renderCollapsed = (content, href, isActive, isSidebarCollapsed, isNested, sectionVariant) => {
|
|
657
|
+
const childrenArray = Children4.toArray(content);
|
|
658
|
+
const hasLinkChild = childrenArray.some(isLinkElement);
|
|
659
|
+
if (hasLinkChild) {
|
|
660
|
+
const linkElement = childrenArray.find(isLinkElement);
|
|
661
|
+
if (!linkElement || !isValidElement4(linkElement)) {
|
|
662
|
+
return null;
|
|
663
|
+
}
|
|
664
|
+
const linkChildren = linkElement.props.children;
|
|
665
|
+
if (linkChildren === void 0 || linkChildren === null) {
|
|
666
|
+
return null;
|
|
667
|
+
}
|
|
668
|
+
const iconOnlyContent2 = extractIconsFromChildren(linkChildren);
|
|
669
|
+
if (iconOnlyContent2.length === 0) {
|
|
670
|
+
return null;
|
|
671
|
+
}
|
|
672
|
+
const clonedLink = cloneElement(
|
|
673
|
+
linkElement,
|
|
674
|
+
isActive ? { "aria-current": "page" } : {},
|
|
675
|
+
iconOnlyContent2
|
|
676
|
+
);
|
|
677
|
+
const tooltipText2 = extractTextContent(Children4.toArray(linkChildren));
|
|
678
|
+
const color2 = isActive ? "accent.default" : "content.dark";
|
|
679
|
+
const fontStyles2 = isActive && !isNested ? "bodyLgBold" : "bodyLgRegular";
|
|
680
|
+
const wrappedLink = /* @__PURE__ */ jsx5(
|
|
681
|
+
SidebarItemLinkStyled,
|
|
682
|
+
__spreadProps(__spreadValues({
|
|
683
|
+
color: color2,
|
|
684
|
+
element: "span",
|
|
685
|
+
fontStyles: fontStyles2,
|
|
686
|
+
isDynamicLink: true
|
|
687
|
+
}, createLinkWrapperProps(
|
|
688
|
+
isActive,
|
|
689
|
+
isSidebarCollapsed,
|
|
690
|
+
isNested,
|
|
691
|
+
sectionVariant
|
|
692
|
+
)), {
|
|
693
|
+
children: clonedLink
|
|
694
|
+
})
|
|
695
|
+
);
|
|
696
|
+
return wrapWithTooltip(wrappedLink, tooltipText2);
|
|
697
|
+
}
|
|
698
|
+
const iconOnlyContent = childrenArray.filter(isIconElement);
|
|
699
|
+
if (iconOnlyContent.length === 0) {
|
|
700
|
+
return null;
|
|
701
|
+
}
|
|
702
|
+
const tooltipText = extractTextContent(childrenArray);
|
|
703
|
+
const element = href ? "a" : "span";
|
|
704
|
+
const color = isActive ? "accent.default" : "content.dark";
|
|
705
|
+
const fontStyles = isActive && !isNested ? "bodyLgBold" : "bodyLgRegular";
|
|
706
|
+
const styledLink = /* @__PURE__ */ jsx5(
|
|
707
|
+
SidebarItemLinkStyled,
|
|
708
|
+
__spreadProps(__spreadValues({
|
|
709
|
+
color,
|
|
710
|
+
element,
|
|
711
|
+
fontStyles,
|
|
712
|
+
isDynamicLink: false
|
|
713
|
+
}, createLinkStyledProps(
|
|
714
|
+
href,
|
|
715
|
+
isActive,
|
|
716
|
+
isSidebarCollapsed,
|
|
717
|
+
isNested,
|
|
718
|
+
sectionVariant
|
|
719
|
+
)), {
|
|
720
|
+
children: iconOnlyContent
|
|
721
|
+
})
|
|
722
|
+
);
|
|
723
|
+
return wrapWithTooltip(styledLink, tooltipText);
|
|
724
|
+
};
|
|
725
|
+
var renderExpanded = (content, href, isActive, isSidebarCollapsed, isNested, sectionVariant) => {
|
|
726
|
+
const childrenArray = Children4.toArray(content);
|
|
727
|
+
const hasLinkChild = childrenArray.some(isLinkElement);
|
|
728
|
+
const color = isActive ? "accent.default" : "content.dark";
|
|
729
|
+
const footerFontStyles = sectionVariant === "footer" ? "bodyLgBold" : "bodyLgRegular";
|
|
730
|
+
const fontStyles = isActive && !isNested ? "bodyLgBold" : footerFontStyles;
|
|
731
|
+
if (hasLinkChild) {
|
|
732
|
+
const linkElement = childrenArray.find(isLinkElement);
|
|
733
|
+
if (!linkElement || !isValidElement4(linkElement)) {
|
|
734
|
+
const { firstIcon: firstIcon3, textContent: textContent3 } = partitionIconAndContent(content);
|
|
735
|
+
const wrappedTextContent3 = wrapTextContent(
|
|
736
|
+
textContent3,
|
|
737
|
+
isSidebarCollapsed
|
|
738
|
+
);
|
|
739
|
+
const element2 = href ? "a" : "span";
|
|
740
|
+
return /* @__PURE__ */ jsxs2(
|
|
741
|
+
SidebarItemLinkStyled,
|
|
742
|
+
__spreadProps(__spreadValues({
|
|
743
|
+
color,
|
|
744
|
+
element: element2,
|
|
745
|
+
fontStyles,
|
|
746
|
+
isDynamicLink: false
|
|
747
|
+
}, createLinkStyledProps(
|
|
748
|
+
href,
|
|
749
|
+
isActive,
|
|
750
|
+
isSidebarCollapsed,
|
|
751
|
+
isNested,
|
|
752
|
+
sectionVariant
|
|
753
|
+
)), {
|
|
754
|
+
children: [
|
|
755
|
+
firstIcon3,
|
|
756
|
+
wrappedTextContent3
|
|
757
|
+
]
|
|
758
|
+
})
|
|
759
|
+
);
|
|
760
|
+
}
|
|
761
|
+
const nonLinkChildren = childrenArray.filter(
|
|
762
|
+
(child) => !isLinkElement(child)
|
|
763
|
+
);
|
|
764
|
+
const linkChildren = Children4.toArray(linkElement.props.children);
|
|
765
|
+
const { firstIcon: firstIcon2, textContent: textContent2 } = partitionIconAndContent(linkChildren);
|
|
766
|
+
const wrappedTextContent2 = wrapTextContent(textContent2, isSidebarCollapsed);
|
|
767
|
+
const structuredLinkChildren = /* @__PURE__ */ jsxs2(Fragment3, { children: [
|
|
768
|
+
firstIcon2,
|
|
769
|
+
wrappedTextContent2
|
|
770
|
+
] });
|
|
771
|
+
const clonedLink = cloneElement(
|
|
772
|
+
linkElement,
|
|
773
|
+
isActive ? { "aria-current": "page" } : {},
|
|
774
|
+
structuredLinkChildren
|
|
775
|
+
);
|
|
776
|
+
return /* @__PURE__ */ jsxs2(
|
|
777
|
+
SidebarItemLinkStyled,
|
|
778
|
+
__spreadProps(__spreadValues({
|
|
779
|
+
color,
|
|
780
|
+
element: "span",
|
|
781
|
+
fontStyles,
|
|
782
|
+
isDynamicLink: true
|
|
783
|
+
}, createLinkWrapperProps(
|
|
784
|
+
isActive,
|
|
785
|
+
isSidebarCollapsed,
|
|
786
|
+
isNested,
|
|
787
|
+
sectionVariant
|
|
788
|
+
)), {
|
|
789
|
+
children: [
|
|
790
|
+
clonedLink,
|
|
791
|
+
nonLinkChildren
|
|
792
|
+
]
|
|
793
|
+
})
|
|
794
|
+
);
|
|
795
|
+
}
|
|
796
|
+
const { firstIcon, textContent } = partitionIconAndContent(content);
|
|
797
|
+
const wrappedTextContent = wrapTextContent(textContent, isSidebarCollapsed);
|
|
798
|
+
const element = href ? "a" : "span";
|
|
799
|
+
return /* @__PURE__ */ jsxs2(
|
|
800
|
+
SidebarItemLinkStyled,
|
|
801
|
+
__spreadProps(__spreadValues({
|
|
802
|
+
color,
|
|
803
|
+
element,
|
|
804
|
+
fontStyles,
|
|
805
|
+
isDynamicLink: false
|
|
806
|
+
}, createLinkStyledProps(
|
|
807
|
+
href,
|
|
808
|
+
isActive,
|
|
809
|
+
isSidebarCollapsed,
|
|
810
|
+
isNested,
|
|
811
|
+
sectionVariant
|
|
812
|
+
)), {
|
|
813
|
+
children: [
|
|
814
|
+
firstIcon,
|
|
815
|
+
wrappedTextContent
|
|
816
|
+
]
|
|
817
|
+
})
|
|
818
|
+
);
|
|
819
|
+
};
|
|
820
|
+
var renderContent = (content, href, isActive, isSidebarCollapsed, isNested, sectionVariant) => {
|
|
821
|
+
if (isSidebarCollapsed) {
|
|
822
|
+
return renderCollapsed(
|
|
823
|
+
content,
|
|
824
|
+
href,
|
|
825
|
+
isActive,
|
|
826
|
+
isSidebarCollapsed,
|
|
827
|
+
isNested,
|
|
828
|
+
sectionVariant
|
|
829
|
+
);
|
|
830
|
+
}
|
|
831
|
+
return renderExpanded(
|
|
832
|
+
content,
|
|
833
|
+
href,
|
|
834
|
+
isActive,
|
|
835
|
+
isSidebarCollapsed,
|
|
836
|
+
isNested,
|
|
837
|
+
sectionVariant
|
|
838
|
+
);
|
|
839
|
+
};
|
|
840
|
+
|
|
841
|
+
// src/components/SidebarSection/SidebarSection.tsx
|
|
842
|
+
import { jsx as jsx6, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
843
|
+
var SidebarSection = (_a) => {
|
|
844
|
+
var _b = _a, {
|
|
845
|
+
title,
|
|
846
|
+
children,
|
|
847
|
+
dataTestId,
|
|
848
|
+
style
|
|
849
|
+
} = _b, rest = __objRest(_b, [
|
|
850
|
+
"title",
|
|
851
|
+
"children",
|
|
852
|
+
"dataTestId",
|
|
853
|
+
"style"
|
|
854
|
+
]);
|
|
855
|
+
const theme = useTheme();
|
|
856
|
+
const { isExpanded, isMobile } = useSidebarContext();
|
|
857
|
+
const isSidebarCollapsed = !isMobile && !isExpanded;
|
|
858
|
+
const shouldShowTitle = title && !isSidebarCollapsed;
|
|
859
|
+
const firstItemHasIcon = useMemo(
|
|
860
|
+
() => hasFirstItemIcon(children),
|
|
861
|
+
[children]
|
|
862
|
+
);
|
|
863
|
+
return /* @__PURE__ */ jsx6(SectionContext.Provider, { value: { variant: "default" }, children: /* @__PURE__ */ jsxs3(
|
|
864
|
+
SidebarSectionRoot,
|
|
865
|
+
__spreadProps(__spreadValues({
|
|
866
|
+
as: "nav",
|
|
867
|
+
"data-testid": dataTestId != null ? dataTestId : "sidebar-section",
|
|
868
|
+
firstItemHasIcon,
|
|
869
|
+
isSidebarCollapsed,
|
|
870
|
+
style,
|
|
871
|
+
variant: "default"
|
|
872
|
+
}, rest), {
|
|
873
|
+
children: [
|
|
874
|
+
shouldShowTitle ? /* @__PURE__ */ jsx6(
|
|
875
|
+
Typography2,
|
|
876
|
+
{
|
|
877
|
+
color: "content.dark",
|
|
878
|
+
element: "h2",
|
|
879
|
+
fontStyles: "bodySmBold",
|
|
880
|
+
style: {
|
|
881
|
+
padding: `${theme.spacing.spacing_50} ${theme.spacing.spacing_60}`,
|
|
882
|
+
whiteSpace: "nowrap",
|
|
883
|
+
overflow: "hidden",
|
|
884
|
+
textTransform: "uppercase"
|
|
885
|
+
},
|
|
886
|
+
children: title
|
|
887
|
+
}
|
|
888
|
+
) : null,
|
|
889
|
+
/* @__PURE__ */ jsx6("ul", { children })
|
|
890
|
+
]
|
|
891
|
+
})
|
|
892
|
+
) });
|
|
893
|
+
};
|
|
894
|
+
SidebarSection.displayName = "Sidebar.Section";
|
|
895
|
+
|
|
896
|
+
// src/components/SidebarSection/SidebarHeader.tsx
|
|
897
|
+
import { useMemo as useMemo2 } from "react";
|
|
898
|
+
import {
|
|
899
|
+
withResponsive as withResponsive2
|
|
900
|
+
} from "@dt-dds/react-core";
|
|
901
|
+
import { jsx as jsx7 } from "react/jsx-runtime";
|
|
902
|
+
var SidebarHeaderBase = (_a) => {
|
|
903
|
+
var _b = _a, {
|
|
904
|
+
children,
|
|
905
|
+
dataTestId,
|
|
906
|
+
style
|
|
907
|
+
} = _b, rest = __objRest(_b, [
|
|
908
|
+
"children",
|
|
909
|
+
"dataTestId",
|
|
910
|
+
"style"
|
|
911
|
+
]);
|
|
912
|
+
const { isExpanded, isMobile } = useSidebarContext();
|
|
913
|
+
const isSidebarCollapsed = !isMobile && !isExpanded;
|
|
914
|
+
const firstItemHasIcon = useMemo2(
|
|
915
|
+
() => hasFirstItemIcon(children),
|
|
916
|
+
[children]
|
|
917
|
+
);
|
|
918
|
+
return /* @__PURE__ */ jsx7(SectionContext.Provider, { value: { variant: "header" }, children: /* @__PURE__ */ jsx7(
|
|
919
|
+
SidebarSectionRoot,
|
|
920
|
+
__spreadProps(__spreadValues({
|
|
921
|
+
as: "header",
|
|
922
|
+
"data-testid": dataTestId != null ? dataTestId : "sidebar-header",
|
|
923
|
+
firstItemHasIcon,
|
|
924
|
+
isSidebarCollapsed,
|
|
925
|
+
style,
|
|
926
|
+
variant: "header"
|
|
927
|
+
}, rest), {
|
|
928
|
+
children: /* @__PURE__ */ jsx7("ul", { children })
|
|
929
|
+
})
|
|
930
|
+
) });
|
|
931
|
+
};
|
|
932
|
+
SidebarHeaderBase.displayName = "Sidebar.Header";
|
|
933
|
+
var SidebarHeader = withResponsive2(SidebarHeaderBase);
|
|
934
|
+
|
|
935
|
+
// src/components/SidebarSection/SidebarFooter.tsx
|
|
936
|
+
import { useMemo as useMemo3 } from "react";
|
|
937
|
+
import {
|
|
938
|
+
withResponsive as withResponsive3
|
|
939
|
+
} from "@dt-dds/react-core";
|
|
940
|
+
import { jsx as jsx8 } from "react/jsx-runtime";
|
|
941
|
+
var SidebarFooterBase = (_a) => {
|
|
942
|
+
var _b = _a, {
|
|
943
|
+
children,
|
|
944
|
+
dataTestId,
|
|
945
|
+
style
|
|
946
|
+
} = _b, rest = __objRest(_b, [
|
|
947
|
+
"children",
|
|
948
|
+
"dataTestId",
|
|
949
|
+
"style"
|
|
950
|
+
]);
|
|
951
|
+
const { isExpanded, isMobile } = useSidebarContext();
|
|
952
|
+
const isSidebarCollapsed = !isMobile && !isExpanded;
|
|
953
|
+
const firstItemHasIcon = useMemo3(
|
|
954
|
+
() => hasFirstItemIcon(children),
|
|
955
|
+
[children]
|
|
956
|
+
);
|
|
957
|
+
return /* @__PURE__ */ jsx8(SectionContext.Provider, { value: { variant: "footer" }, children: /* @__PURE__ */ jsx8(
|
|
958
|
+
SidebarSectionRoot,
|
|
959
|
+
__spreadProps(__spreadValues({
|
|
960
|
+
as: "footer",
|
|
961
|
+
"data-testid": dataTestId != null ? dataTestId : "sidebar-footer",
|
|
962
|
+
firstItemHasIcon,
|
|
963
|
+
isSidebarCollapsed,
|
|
964
|
+
style,
|
|
965
|
+
variant: "footer"
|
|
966
|
+
}, rest), {
|
|
967
|
+
children: /* @__PURE__ */ jsx8("ul", { children })
|
|
968
|
+
})
|
|
969
|
+
) });
|
|
970
|
+
};
|
|
971
|
+
SidebarFooterBase.displayName = "Sidebar.Footer";
|
|
972
|
+
var SidebarFooter = withResponsive3(SidebarFooterBase);
|
|
973
|
+
|
|
974
|
+
// src/components/SidebarItem/SidebarItem.tsx
|
|
975
|
+
import {
|
|
976
|
+
useState as useState4,
|
|
977
|
+
useMemo as useMemo4,
|
|
978
|
+
useId,
|
|
979
|
+
useEffect as useEffect3,
|
|
980
|
+
useRef as useRef2
|
|
981
|
+
} from "react";
|
|
982
|
+
import { Icon } from "@dt-dds/react-icon";
|
|
983
|
+
import { IconButton } from "@dt-dds/react-icon-button";
|
|
984
|
+
|
|
985
|
+
// src/hooks/useSidebar.tsx
|
|
986
|
+
import { useState, useCallback as useCallback2 } from "react";
|
|
987
|
+
var useSidebar = (options = {}) => {
|
|
988
|
+
const { isExpanded: initialExpanded = false } = options;
|
|
989
|
+
const [isExpanded, setIsExpanded] = useState(initialExpanded);
|
|
990
|
+
const toggleSidebar = useCallback2(() => {
|
|
991
|
+
setIsExpanded((prev) => !prev);
|
|
992
|
+
}, []);
|
|
993
|
+
return {
|
|
994
|
+
isExpanded,
|
|
995
|
+
setIsExpanded,
|
|
996
|
+
toggleSidebar
|
|
997
|
+
};
|
|
998
|
+
};
|
|
999
|
+
|
|
1000
|
+
// src/hooks/useLocationPath.ts
|
|
1001
|
+
import { useEffect, useState as useState2 } from "react";
|
|
1002
|
+
var useLocationPath = () => {
|
|
1003
|
+
const [path, setPath] = useState2(() => getCurrentPath());
|
|
1004
|
+
useEffect(() => {
|
|
1005
|
+
if (typeof window === "undefined") return;
|
|
1006
|
+
const handleLocationChange = () => {
|
|
1007
|
+
setPath(getCurrentPath());
|
|
1008
|
+
};
|
|
1009
|
+
window.addEventListener("popstate", handleLocationChange);
|
|
1010
|
+
window.addEventListener("hashchange", handleLocationChange);
|
|
1011
|
+
return () => {
|
|
1012
|
+
window.removeEventListener("popstate", handleLocationChange);
|
|
1013
|
+
window.removeEventListener("hashchange", handleLocationChange);
|
|
1014
|
+
};
|
|
1015
|
+
}, []);
|
|
1016
|
+
return path;
|
|
1017
|
+
};
|
|
1018
|
+
|
|
1019
|
+
// src/hooks/useDisclosureState.ts
|
|
1020
|
+
import { useCallback as useCallback3, useEffect as useEffect2, useRef, useState as useState3 } from "react";
|
|
1021
|
+
var shouldTriggerAutoExpand = (isControlled, shouldAutoExpand, autoExpandKey, lastKey) => !isControlled && shouldAutoExpand && !!autoExpandKey && lastKey !== autoExpandKey;
|
|
1022
|
+
var useDisclosureState = ({
|
|
1023
|
+
controlledExpanded,
|
|
1024
|
+
defaultExpanded,
|
|
1025
|
+
onToggle,
|
|
1026
|
+
shouldAutoExpand,
|
|
1027
|
+
autoExpandKey
|
|
1028
|
+
}) => {
|
|
1029
|
+
const isControlled = controlledExpanded !== void 0;
|
|
1030
|
+
const [internalExpanded, setInternalExpanded] = useState3(
|
|
1031
|
+
() => defaultExpanded
|
|
1032
|
+
);
|
|
1033
|
+
const lastAutoExpandKey = useRef(
|
|
1034
|
+
shouldAutoExpand ? autoExpandKey : null
|
|
1035
|
+
);
|
|
1036
|
+
useEffect2(() => {
|
|
1037
|
+
const shouldTrigger = shouldTriggerAutoExpand(
|
|
1038
|
+
isControlled,
|
|
1039
|
+
shouldAutoExpand,
|
|
1040
|
+
autoExpandKey,
|
|
1041
|
+
lastAutoExpandKey.current
|
|
1042
|
+
);
|
|
1043
|
+
if (!shouldAutoExpand) {
|
|
1044
|
+
lastAutoExpandKey.current = null;
|
|
1045
|
+
return;
|
|
1046
|
+
}
|
|
1047
|
+
if (shouldTrigger) {
|
|
1048
|
+
setInternalExpanded(true);
|
|
1049
|
+
lastAutoExpandKey.current = autoExpandKey;
|
|
1050
|
+
}
|
|
1051
|
+
}, [autoExpandKey, isControlled, shouldAutoExpand]);
|
|
1052
|
+
const expanded = isControlled ? controlledExpanded : internalExpanded;
|
|
1053
|
+
const toggle = useCallback3(() => {
|
|
1054
|
+
const next = !expanded;
|
|
1055
|
+
if (!isControlled) {
|
|
1056
|
+
setInternalExpanded(next);
|
|
1057
|
+
}
|
|
1058
|
+
onToggle == null ? void 0 : onToggle(next);
|
|
1059
|
+
}, [expanded, isControlled, onToggle]);
|
|
1060
|
+
return {
|
|
1061
|
+
expanded: !!expanded,
|
|
1062
|
+
toggle
|
|
1063
|
+
};
|
|
1064
|
+
};
|
|
1065
|
+
|
|
1066
|
+
// src/components/SidebarItem/SidebarItem.tsx
|
|
1067
|
+
import { jsx as jsx9, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
1068
|
+
var SidebarItem = (_a) => {
|
|
1069
|
+
var _b = _a, {
|
|
1070
|
+
href,
|
|
1071
|
+
defaultExpanded = false,
|
|
1072
|
+
expanded: controlledExpanded,
|
|
1073
|
+
onToggle,
|
|
1074
|
+
children,
|
|
1075
|
+
dataTestId,
|
|
1076
|
+
style
|
|
1077
|
+
} = _b, rest = __objRest(_b, [
|
|
1078
|
+
"href",
|
|
1079
|
+
"defaultExpanded",
|
|
1080
|
+
"expanded",
|
|
1081
|
+
"onToggle",
|
|
1082
|
+
"children",
|
|
1083
|
+
"dataTestId",
|
|
1084
|
+
"style"
|
|
1085
|
+
]);
|
|
1086
|
+
const { isExpanded: isSidebarExpanded, isMobile } = useSidebarContext();
|
|
1087
|
+
const sectionVariant = useSectionContext();
|
|
1088
|
+
const isNested = useSubListContext();
|
|
1089
|
+
const collapseToIcons = !isMobile && !isSidebarExpanded;
|
|
1090
|
+
const [isSidebarJustExpanded, setIsSidebarJustExpanded] = useState4(false);
|
|
1091
|
+
const prevCollapseToIcons = useRef2(collapseToIcons);
|
|
1092
|
+
useEffect3(() => {
|
|
1093
|
+
if (prevCollapseToIcons.current && !collapseToIcons) {
|
|
1094
|
+
setIsSidebarJustExpanded(true);
|
|
1095
|
+
const timeout = setTimeout(() => {
|
|
1096
|
+
setIsSidebarJustExpanded(false);
|
|
1097
|
+
}, 1e3);
|
|
1098
|
+
return () => clearTimeout(timeout);
|
|
1099
|
+
}
|
|
1100
|
+
prevCollapseToIcons.current = collapseToIcons;
|
|
1101
|
+
}, [collapseToIcons]);
|
|
1102
|
+
const { subList, otherChildren } = useMemo4(
|
|
1103
|
+
() => partitionChildren(children),
|
|
1104
|
+
[children]
|
|
1105
|
+
);
|
|
1106
|
+
const currentPath = useLocationPath();
|
|
1107
|
+
const isActive = useMemo4(
|
|
1108
|
+
() => isCurrentUrl(href, currentPath),
|
|
1109
|
+
[href, currentPath]
|
|
1110
|
+
);
|
|
1111
|
+
const hasActiveDescendant = useMemo4(() => {
|
|
1112
|
+
if (!subList.length) return false;
|
|
1113
|
+
return subList.some(
|
|
1114
|
+
(node) => containsActiveSidebarItem(node, currentPath, isCurrentUrl)
|
|
1115
|
+
);
|
|
1116
|
+
}, [subList, currentPath]);
|
|
1117
|
+
const shouldAutoExpand = isActive && subList.length > 0 || hasActiveDescendant;
|
|
1118
|
+
const autoExpandKey = shouldAutoExpand ? [href != null ? href : "", currentPath, String(hasActiveDescendant)].join("|") : null;
|
|
1119
|
+
const { expanded, toggle } = useDisclosureState({
|
|
1120
|
+
controlledExpanded,
|
|
1121
|
+
defaultExpanded: defaultExpanded || shouldAutoExpand,
|
|
1122
|
+
onToggle,
|
|
1123
|
+
shouldAutoExpand,
|
|
1124
|
+
autoExpandKey
|
|
1125
|
+
});
|
|
1126
|
+
const submenuId = useId();
|
|
1127
|
+
const headerId = useId();
|
|
1128
|
+
const showDisclosure = subList.length > 0 && !collapseToIcons;
|
|
1129
|
+
const handleKeyDown = (event) => {
|
|
1130
|
+
if (isLinkTarget(event.target)) {
|
|
1131
|
+
return;
|
|
1132
|
+
}
|
|
1133
|
+
if (event.key === "Enter" || event.key === " ") {
|
|
1134
|
+
event.preventDefault();
|
|
1135
|
+
toggle();
|
|
1136
|
+
}
|
|
1137
|
+
};
|
|
1138
|
+
const handleHeaderClick = (event) => {
|
|
1139
|
+
if (isLinkTarget(event.target)) {
|
|
1140
|
+
return;
|
|
1141
|
+
}
|
|
1142
|
+
toggle();
|
|
1143
|
+
};
|
|
1144
|
+
const handleToggleButtonClick = (event) => {
|
|
1145
|
+
event.stopPropagation();
|
|
1146
|
+
toggle();
|
|
1147
|
+
};
|
|
1148
|
+
const handleToggleButtonKeyDown = (event) => {
|
|
1149
|
+
if (event.key === "Enter" || event.key === " ") {
|
|
1150
|
+
event.preventDefault();
|
|
1151
|
+
event.stopPropagation();
|
|
1152
|
+
toggle();
|
|
1153
|
+
}
|
|
1154
|
+
};
|
|
1155
|
+
if (subList.length > 0) {
|
|
1156
|
+
const toggleIconCode = expanded ? "keyboard_arrow_up" : "keyboard_arrow_down";
|
|
1157
|
+
const headerContent2 = renderContent(
|
|
1158
|
+
otherChildren,
|
|
1159
|
+
href,
|
|
1160
|
+
isActive,
|
|
1161
|
+
collapseToIcons,
|
|
1162
|
+
isNested,
|
|
1163
|
+
sectionVariant
|
|
1164
|
+
);
|
|
1165
|
+
if (collapseToIcons && !headerContent2) {
|
|
1166
|
+
return null;
|
|
1167
|
+
}
|
|
1168
|
+
return /* @__PURE__ */ jsxs4(
|
|
1169
|
+
SidebarItemStyled,
|
|
1170
|
+
__spreadProps(__spreadValues({
|
|
1171
|
+
as: "li",
|
|
1172
|
+
"data-testid": dataTestId != null ? dataTestId : "sidebar-item",
|
|
1173
|
+
style
|
|
1174
|
+
}, rest), {
|
|
1175
|
+
children: [
|
|
1176
|
+
/* @__PURE__ */ jsxs4(
|
|
1177
|
+
SidebarItemHeaderStyled,
|
|
1178
|
+
{
|
|
1179
|
+
"aria-controls": showDisclosure ? submenuId : void 0,
|
|
1180
|
+
"aria-expanded": showDisclosure ? expanded : void 0,
|
|
1181
|
+
id: `header-${headerId}`,
|
|
1182
|
+
isActive,
|
|
1183
|
+
isInteractive: showDisclosure,
|
|
1184
|
+
isNested,
|
|
1185
|
+
isSidebarCollapsed: collapseToIcons,
|
|
1186
|
+
onClick: showDisclosure ? handleHeaderClick : void 0,
|
|
1187
|
+
onKeyDown: showDisclosure ? handleKeyDown : void 0,
|
|
1188
|
+
role: showDisclosure ? "button" : void 0,
|
|
1189
|
+
sectionVariant,
|
|
1190
|
+
tabIndex: showDisclosure ? 0 : void 0,
|
|
1191
|
+
children: [
|
|
1192
|
+
headerContent2,
|
|
1193
|
+
showDisclosure ? /* @__PURE__ */ jsx9(
|
|
1194
|
+
IconButton,
|
|
1195
|
+
{
|
|
1196
|
+
"aria-controls": submenuId,
|
|
1197
|
+
"aria-expanded": expanded,
|
|
1198
|
+
"aria-label": expanded ? "Collapse submenu" : "Expand submenu",
|
|
1199
|
+
onClick: handleToggleButtonClick,
|
|
1200
|
+
onKeyDown: handleToggleButtonKeyDown,
|
|
1201
|
+
style: {
|
|
1202
|
+
display: "flex",
|
|
1203
|
+
width: collapseToIcons ? "auto" : "100%",
|
|
1204
|
+
height: "auto",
|
|
1205
|
+
justifyContent: "flex-end",
|
|
1206
|
+
whiteSpace: "nowrap"
|
|
1207
|
+
},
|
|
1208
|
+
children: /* @__PURE__ */ jsx9(Icon, { code: toggleIconCode })
|
|
1209
|
+
}
|
|
1210
|
+
) : null
|
|
1211
|
+
]
|
|
1212
|
+
}
|
|
1213
|
+
),
|
|
1214
|
+
showDisclosure ? /* @__PURE__ */ jsx9(
|
|
1215
|
+
SidebarItemBodyStyled,
|
|
1216
|
+
{
|
|
1217
|
+
"aria-hidden": !expanded,
|
|
1218
|
+
"aria-labelledby": headerId,
|
|
1219
|
+
id: submenuId,
|
|
1220
|
+
isExpanded: expanded,
|
|
1221
|
+
isSidebarJustExpanded,
|
|
1222
|
+
children: /* @__PURE__ */ jsx9("div", { children: subList })
|
|
1223
|
+
}
|
|
1224
|
+
) : null
|
|
1225
|
+
]
|
|
1226
|
+
})
|
|
1227
|
+
);
|
|
1228
|
+
}
|
|
1229
|
+
const headerContent = renderContent(
|
|
1230
|
+
children,
|
|
1231
|
+
href,
|
|
1232
|
+
isActive,
|
|
1233
|
+
collapseToIcons,
|
|
1234
|
+
isNested,
|
|
1235
|
+
sectionVariant
|
|
1236
|
+
);
|
|
1237
|
+
if (collapseToIcons && !headerContent) {
|
|
1238
|
+
return null;
|
|
1239
|
+
}
|
|
1240
|
+
return /* @__PURE__ */ jsx9(
|
|
1241
|
+
SidebarItemStyled,
|
|
1242
|
+
__spreadProps(__spreadValues({
|
|
1243
|
+
as: "li",
|
|
1244
|
+
"data-testid": dataTestId != null ? dataTestId : "sidebar-item",
|
|
1245
|
+
style
|
|
1246
|
+
}, rest), {
|
|
1247
|
+
children: /* @__PURE__ */ jsx9(
|
|
1248
|
+
SidebarItemHeaderStyled,
|
|
1249
|
+
{
|
|
1250
|
+
isActive,
|
|
1251
|
+
isInteractive: false,
|
|
1252
|
+
isNested,
|
|
1253
|
+
isSidebarCollapsed: collapseToIcons,
|
|
1254
|
+
sectionVariant,
|
|
1255
|
+
children: headerContent
|
|
1256
|
+
}
|
|
1257
|
+
)
|
|
1258
|
+
})
|
|
1259
|
+
);
|
|
1260
|
+
};
|
|
1261
|
+
SidebarItem.displayName = "SidebarItem";
|
|
1262
|
+
|
|
1263
|
+
// src/components/SidebarSubList/SidebarSubList.styled.ts
|
|
1264
|
+
import styled5 from "@emotion/styled";
|
|
1265
|
+
var SidebarSubListStyled = styled5.ul`
|
|
1266
|
+
margin: 0;
|
|
1267
|
+
padding: 0;
|
|
1268
|
+
list-style: none;
|
|
1269
|
+
display: flex;
|
|
1270
|
+
flex-direction: column;
|
|
1271
|
+
`;
|
|
1272
|
+
|
|
1273
|
+
// src/components/SidebarSubList/SidebarSubList.tsx
|
|
1274
|
+
import { jsx as jsx10 } from "react/jsx-runtime";
|
|
1275
|
+
var SidebarSubList = (_a) => {
|
|
1276
|
+
var _b = _a, {
|
|
1277
|
+
children,
|
|
1278
|
+
dataTestId,
|
|
1279
|
+
style
|
|
1280
|
+
} = _b, rest = __objRest(_b, [
|
|
1281
|
+
"children",
|
|
1282
|
+
"dataTestId",
|
|
1283
|
+
"style"
|
|
1284
|
+
]);
|
|
1285
|
+
useSidebarContext();
|
|
1286
|
+
return /* @__PURE__ */ jsx10(SubListContext.Provider, { value: { isNested: true }, children: /* @__PURE__ */ jsx10(
|
|
1287
|
+
SidebarSubListStyled,
|
|
1288
|
+
__spreadProps(__spreadValues({
|
|
1289
|
+
as: "ul",
|
|
1290
|
+
"data-testid": dataTestId != null ? dataTestId : "sidebar-sub-list",
|
|
1291
|
+
style
|
|
1292
|
+
}, rest), {
|
|
1293
|
+
children
|
|
1294
|
+
})
|
|
1295
|
+
) });
|
|
1296
|
+
};
|
|
1297
|
+
SidebarSubList.displayName = "SidebarSubList";
|
|
1298
|
+
|
|
1299
|
+
// src/components/SidebarContent/SidebarContent.styled.ts
|
|
1300
|
+
import styled6 from "@emotion/styled";
|
|
1301
|
+
var SidebarContentStyled = styled6.div`
|
|
1302
|
+
${({ theme, isSidebarCollapsed }) => {
|
|
1303
|
+
return `
|
|
1304
|
+
position: relative;
|
|
1305
|
+
display: block;
|
|
1306
|
+
flex: 1 1 auto;
|
|
1307
|
+
overflow-x: hidden;
|
|
1308
|
+
overflow-y: overlay;
|
|
1309
|
+
scrollbar-width: ${isSidebarCollapsed ? "none" : "thin"};
|
|
1310
|
+
scrollbar-color: ${theme.palette.border.default} transparent;
|
|
1311
|
+
`;
|
|
1312
|
+
}}
|
|
1313
|
+
`;
|
|
1314
|
+
|
|
1315
|
+
// src/components/SidebarContent/SidebarContent.tsx
|
|
1316
|
+
import { jsx as jsx11 } from "react/jsx-runtime";
|
|
1317
|
+
var SidebarContent = (_a) => {
|
|
1318
|
+
var _b = _a, {
|
|
1319
|
+
children,
|
|
1320
|
+
dataTestId,
|
|
1321
|
+
style
|
|
1322
|
+
} = _b, rest = __objRest(_b, [
|
|
1323
|
+
"children",
|
|
1324
|
+
"dataTestId",
|
|
1325
|
+
"style"
|
|
1326
|
+
]);
|
|
1327
|
+
const { isExpanded, isMobile } = useSidebarContext();
|
|
1328
|
+
const isSidebarCollapsed = !isMobile && !isExpanded;
|
|
1329
|
+
return /* @__PURE__ */ jsx11(
|
|
1330
|
+
SidebarContentStyled,
|
|
1331
|
+
__spreadProps(__spreadValues({
|
|
1332
|
+
"data-testid": dataTestId != null ? dataTestId : "sidebar-content",
|
|
1333
|
+
isSidebarCollapsed,
|
|
1334
|
+
style
|
|
1335
|
+
}, rest), {
|
|
1336
|
+
children
|
|
1337
|
+
})
|
|
1338
|
+
);
|
|
1339
|
+
};
|
|
1340
|
+
SidebarContent.displayName = "Sidebar.Content";
|
|
1341
|
+
|
|
1342
|
+
// src/components/SidebarToggle/SidebarToggle.tsx
|
|
1343
|
+
import { Icon as Icon2 } from "@dt-dds/react-icon";
|
|
1344
|
+
|
|
1345
|
+
// src/components/SidebarToggle/SidebarToggle.styled.ts
|
|
1346
|
+
import styled7 from "@emotion/styled";
|
|
1347
|
+
import { IconButton as IconButton2 } from "@dt-dds/react-icon-button";
|
|
1348
|
+
var SidebarToggleStyled = styled7(IconButton2)`
|
|
1349
|
+
${({ isSidebarCollapsed }) => `
|
|
1350
|
+
display: flex;
|
|
1351
|
+
align-items: center;
|
|
1352
|
+
justify-content: center;
|
|
1353
|
+
|
|
1354
|
+
> i {
|
|
1355
|
+
transform: ${isSidebarCollapsed ? "rotate(180deg)" : ""};
|
|
1356
|
+
}
|
|
1357
|
+
`}
|
|
1358
|
+
`;
|
|
1359
|
+
|
|
1360
|
+
// src/components/SidebarToggle/SidebarToggle.tsx
|
|
1361
|
+
import { jsx as jsx12 } from "react/jsx-runtime";
|
|
1362
|
+
var SidebarToggle = ({ onClick }) => {
|
|
1363
|
+
const { isExpanded, isMobile, onToggle } = useSidebarContext();
|
|
1364
|
+
const isSidebarCollapsed = !isMobile && !isExpanded;
|
|
1365
|
+
const handleClick = onClick != null ? onClick : onToggle;
|
|
1366
|
+
return /* @__PURE__ */ jsx12(
|
|
1367
|
+
SidebarToggleStyled,
|
|
1368
|
+
{
|
|
1369
|
+
"aria-expanded": !isSidebarCollapsed,
|
|
1370
|
+
"aria-label": "Toggle sidebar navigation",
|
|
1371
|
+
isSidebarCollapsed,
|
|
1372
|
+
onClick: handleClick,
|
|
1373
|
+
children: /* @__PURE__ */ jsx12(Icon2, { code: "menu_open" })
|
|
1374
|
+
}
|
|
1375
|
+
);
|
|
1376
|
+
};
|
|
1377
|
+
SidebarToggle.displayName = "Sidebar.Toggle";
|
|
1378
|
+
|
|
1379
|
+
// src/Sidebar.styled.ts
|
|
1380
|
+
import styled8 from "@emotion/styled";
|
|
1381
|
+
var SidebarStyled = styled8.aside`
|
|
1382
|
+
${({ theme, isExpanded, isMobile, offsetTop, placement }) => {
|
|
1383
|
+
const height = isMobile ? SIDEBAR_DEFAULT_OFFSET_TOP : offsetTop;
|
|
1384
|
+
const width = calculateSidebarWidth(isMobile, isExpanded);
|
|
1385
|
+
const sidebarPositionValue = calculateSidebarPosition(isMobile, isExpanded);
|
|
1386
|
+
const transitionAnimation = SIDEBAR_DEFAULT_TRANSITION;
|
|
1387
|
+
return `
|
|
1388
|
+
position: fixed;
|
|
1389
|
+
display: flex;
|
|
1390
|
+
flex-direction: column;
|
|
1391
|
+
height: calc(100% - ${height}px);
|
|
1392
|
+
width: ${width}px;
|
|
1393
|
+
background-color: ${theme.palette.surface.contrast};
|
|
1394
|
+
overflow: hidden;
|
|
1395
|
+
top: ${offsetTop}px;
|
|
1396
|
+
transition: ${transitionAnimation};
|
|
1397
|
+
${placement}: ${sidebarPositionValue}px;
|
|
1398
|
+
|
|
1399
|
+
${placement === "right" ? `border-left: 1px solid ${theme.palette.border.default};` : `border-right: 1px solid ${theme.palette.border.default};`}
|
|
1400
|
+
`;
|
|
1401
|
+
}}
|
|
1402
|
+
`;
|
|
1403
|
+
|
|
1404
|
+
// src/Sidebar.tsx
|
|
1405
|
+
import { jsx as jsx13 } from "react/jsx-runtime";
|
|
1406
|
+
var Sidebar = (_a) => {
|
|
1407
|
+
var _b = _a, {
|
|
1408
|
+
dataTestId,
|
|
1409
|
+
offsetTop = 0,
|
|
1410
|
+
children,
|
|
1411
|
+
ariaLabel,
|
|
1412
|
+
style,
|
|
1413
|
+
isExpanded,
|
|
1414
|
+
placement = SIDEBAR_DEFAULT_PLACEMENT,
|
|
1415
|
+
onToggle
|
|
1416
|
+
} = _b, rest = __objRest(_b, [
|
|
1417
|
+
"dataTestId",
|
|
1418
|
+
"offsetTop",
|
|
1419
|
+
"children",
|
|
1420
|
+
"ariaLabel",
|
|
1421
|
+
"style",
|
|
1422
|
+
"isExpanded",
|
|
1423
|
+
"placement",
|
|
1424
|
+
"onToggle"
|
|
1425
|
+
]);
|
|
1426
|
+
const theme = useTheme2();
|
|
1427
|
+
const isMobile = useMedia(`(max-width: ${theme.breakpoints.mq3}px)`);
|
|
1428
|
+
const [isBackdropVisible, setIsBackdropVisible] = useState5(false);
|
|
1429
|
+
const [shouldShowSidebar, setShouldShowSidebar] = useState5(
|
|
1430
|
+
!isMobile && isExpanded
|
|
1431
|
+
);
|
|
1432
|
+
const timeoutRef = useRef3(null);
|
|
1433
|
+
useEffect4(() => {
|
|
1434
|
+
if (timeoutRef.current !== null) {
|
|
1435
|
+
window.clearTimeout(timeoutRef.current);
|
|
1436
|
+
timeoutRef.current = null;
|
|
1437
|
+
}
|
|
1438
|
+
if (!isMobile) {
|
|
1439
|
+
setIsBackdropVisible(false);
|
|
1440
|
+
setShouldShowSidebar(isExpanded);
|
|
1441
|
+
return;
|
|
1442
|
+
}
|
|
1443
|
+
if (isExpanded) {
|
|
1444
|
+
setIsBackdropVisible(true);
|
|
1445
|
+
timeoutRef.current = window.setTimeout(() => {
|
|
1446
|
+
setShouldShowSidebar(true);
|
|
1447
|
+
}, SIDEBAR_BACKDROP_SHOW_DELAY);
|
|
1448
|
+
} else {
|
|
1449
|
+
setShouldShowSidebar(false);
|
|
1450
|
+
timeoutRef.current = window.setTimeout(() => {
|
|
1451
|
+
setIsBackdropVisible(false);
|
|
1452
|
+
}, SIDEBAR_BACKDROP_HIDE_DELAY);
|
|
1453
|
+
}
|
|
1454
|
+
return () => {
|
|
1455
|
+
if (timeoutRef.current !== null) {
|
|
1456
|
+
window.clearTimeout(timeoutRef.current);
|
|
1457
|
+
}
|
|
1458
|
+
};
|
|
1459
|
+
}, [isExpanded, isMobile]);
|
|
1460
|
+
useEffect4(() => {
|
|
1461
|
+
if (!isMobile || !isExpanded) return;
|
|
1462
|
+
const handleEscapeKey = (event) => {
|
|
1463
|
+
if (event.key === "Escape") {
|
|
1464
|
+
onToggle == null ? void 0 : onToggle(false);
|
|
1465
|
+
}
|
|
1466
|
+
};
|
|
1467
|
+
document.addEventListener("keydown", handleEscapeKey);
|
|
1468
|
+
return () => document.removeEventListener("keydown", handleEscapeKey);
|
|
1469
|
+
}, [isMobile, isExpanded, onToggle]);
|
|
1470
|
+
const handleToggle = useCallback4(() => {
|
|
1471
|
+
onToggle == null ? void 0 : onToggle(!isExpanded);
|
|
1472
|
+
}, [onToggle, isExpanded]);
|
|
1473
|
+
const contextValue = useMemo5(
|
|
1474
|
+
() => ({
|
|
1475
|
+
isExpanded,
|
|
1476
|
+
isMobile,
|
|
1477
|
+
onToggle: handleToggle
|
|
1478
|
+
}),
|
|
1479
|
+
[isExpanded, isMobile, handleToggle]
|
|
1480
|
+
);
|
|
1481
|
+
return /* @__PURE__ */ jsx13(SidebarContextProvider, { value: contextValue, children: isMobile ? /* @__PURE__ */ jsx13(
|
|
1482
|
+
SidebarBackdrop,
|
|
1483
|
+
{
|
|
1484
|
+
dataTestId: "mobile-backdrop",
|
|
1485
|
+
isOpen: isBackdropVisible,
|
|
1486
|
+
onBackdropClick: handleToggle,
|
|
1487
|
+
children: /* @__PURE__ */ jsx13(
|
|
1488
|
+
SidebarStyled,
|
|
1489
|
+
__spreadProps(__spreadValues({
|
|
1490
|
+
"aria-label": ariaLabel,
|
|
1491
|
+
"data-testid": dataTestId,
|
|
1492
|
+
isExpanded: shouldShowSidebar,
|
|
1493
|
+
isMobile,
|
|
1494
|
+
offsetTop: SIDEBAR_DEFAULT_OFFSET_TOP,
|
|
1495
|
+
placement: SIDEBAR_MOBILE_PLACEMENT,
|
|
1496
|
+
style
|
|
1497
|
+
}, rest), {
|
|
1498
|
+
children
|
|
1499
|
+
})
|
|
1500
|
+
)
|
|
1501
|
+
}
|
|
1502
|
+
) : /* @__PURE__ */ jsx13(
|
|
1503
|
+
SidebarStyled,
|
|
1504
|
+
__spreadProps(__spreadValues({
|
|
1505
|
+
"aria-label": ariaLabel,
|
|
1506
|
+
"data-testid": dataTestId,
|
|
1507
|
+
isExpanded,
|
|
1508
|
+
isMobile,
|
|
1509
|
+
offsetTop,
|
|
1510
|
+
placement,
|
|
1511
|
+
style
|
|
1512
|
+
}, rest), {
|
|
1513
|
+
children
|
|
1514
|
+
})
|
|
1515
|
+
) });
|
|
1516
|
+
};
|
|
1517
|
+
Sidebar.Content = SidebarContent;
|
|
1518
|
+
Sidebar.Divider = SidebarDivider;
|
|
1519
|
+
Sidebar.Section = SidebarSection;
|
|
1520
|
+
Sidebar.Item = SidebarItem;
|
|
1521
|
+
Sidebar.SubList = SidebarSubList;
|
|
1522
|
+
Sidebar.Header = SidebarHeader;
|
|
1523
|
+
Sidebar.Footer = SidebarFooter;
|
|
1524
|
+
Sidebar.Toggle = SidebarToggle;
|
|
1525
|
+
export {
|
|
1526
|
+
Sidebar,
|
|
1527
|
+
useSidebar
|
|
1528
|
+
};
|