@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/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
+ };