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