@kopexa/sidebar 17.1.74 → 17.2.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.
@@ -0,0 +1,878 @@
1
+ "use client";
2
+ "use strict";
3
+ "use client";
4
+ var __defProp = Object.defineProperty;
5
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
6
+ var __getOwnPropNames = Object.getOwnPropertyNames;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
19
+ };
20
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
21
+
22
+ // src/v2/index.tsx
23
+ var v2_exports = {};
24
+ __export(v2_exports, {
25
+ AppShell: () => AppShell,
26
+ AppShellAside: () => AppShellAside,
27
+ AppShellHeader: () => AppShellHeader,
28
+ AppShellMain: () => AppShellMain,
29
+ AppShellPanelContent: () => AppShellPanelContent,
30
+ AppShellRoot: () => AppShellRoot,
31
+ SidebarV2: () => SidebarV2,
32
+ SidebarV2FromConfig: () => SidebarV2FromConfig,
33
+ SidebarV2Inset: () => SidebarV2Inset,
34
+ SidebarV2Panel: () => SidebarV2Panel,
35
+ SidebarV2PanelGroup: () => SidebarV2PanelGroup,
36
+ SidebarV2PanelItems: () => SidebarV2PanelItems,
37
+ SidebarV2PanelLabel: () => SidebarV2PanelLabel,
38
+ SidebarV2PanelLeaf: () => SidebarV2PanelLeaf,
39
+ SidebarV2Provider: () => SidebarV2Provider,
40
+ SidebarV2Rail: () => SidebarV2Rail,
41
+ SidebarV2RailItem: () => SidebarV2RailItem,
42
+ SidebarV2RailLink: () => SidebarV2RailLink,
43
+ SidebarV2RailSpacer: () => SidebarV2RailSpacer,
44
+ SidebarV2Trigger: () => SidebarV2Trigger,
45
+ SidebarV2Workspace: () => SidebarV2Workspace,
46
+ useSidebarV2: () => useSidebarV2
47
+ });
48
+ module.exports = __toCommonJS(v2_exports);
49
+
50
+ // src/v2/app-shell.tsx
51
+ var import_react2 = require("react");
52
+ var import_react_dom = require("react-dom");
53
+
54
+ // src/v2/context.tsx
55
+ var import_react_utils = require("@kopexa/react-utils");
56
+ var import_theme = require("@kopexa/theme");
57
+ var import_tooltip = require("@kopexa/tooltip");
58
+ var import_use_is_mobile = require("@kopexa/use-is-mobile");
59
+ var import_react = require("react");
60
+ var import_jsx_runtime = require("react/jsx-runtime");
61
+ var PIN_COOKIE = "kpx_sidebar_v2_pinned";
62
+ var PIN_COOKIE_MAX_AGE = 60 * 60 * 24 * 7;
63
+ var [Provider, useSidebarV2] = (0, import_react_utils.createContext)({
64
+ name: "SidebarV2Context",
65
+ errorMessage: "useSidebarV2 must be used within <SidebarV2> (the provider component)."
66
+ });
67
+ var defaultRenderLink = (props) => {
68
+ const { href, className, children, ...rest } = props;
69
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("a", { href, className, ...rest, children });
70
+ };
71
+ function SidebarV2Provider({
72
+ children,
73
+ tone = "dark",
74
+ flyoutTrigger = "click",
75
+ activeHref,
76
+ renderLink = defaultRenderLink,
77
+ pinned: pinnedProp,
78
+ onPinnedChange,
79
+ defaultPinned = true
80
+ }) {
81
+ const isMobile = (0, import_use_is_mobile.useIsMobile)();
82
+ const [drawerOpen, setDrawerOpen] = (0, import_react.useState)(false);
83
+ const [flyoutValue, setFlyoutValue] = (0, import_react.useState)(null);
84
+ const [selectedRail, setSelectedRail] = (0, import_react.useState)(null);
85
+ const [openGroup, setOpenGroup] = (0, import_react.useState)(null);
86
+ const [pinnedUncontrolled, setPinnedUncontrolled] = (0, import_react.useState)(defaultPinned);
87
+ const pinned = pinnedProp != null ? pinnedProp : pinnedUncontrolled;
88
+ const [panelHost, setPanelHost] = (0, import_react.useState)(null);
89
+ const [overrideCount, setOverrideCount] = (0, import_react.useState)(0);
90
+ const registerPanelOverride = (0, import_react.useCallback)(() => {
91
+ setOverrideCount((c) => c + 1);
92
+ return () => setOverrideCount((c) => c - 1);
93
+ }, []);
94
+ const panelOverrideActive = overrideCount > 0;
95
+ const navPreviewActive = pinned ? selectedRail !== null : flyoutValue !== null;
96
+ const styles = (0, import_react.useMemo)(() => (0, import_theme.sidebarV2)({ tone }), [tone]);
97
+ const setPinned = (0, import_react.useCallback)(
98
+ (value2) => {
99
+ onPinnedChange == null ? void 0 : onPinnedChange(value2);
100
+ if (pinnedProp === void 0) {
101
+ setPinnedUncontrolled(value2);
102
+ }
103
+ document.cookie = `${PIN_COOKIE}=${value2}; path=/; max-age=${PIN_COOKIE_MAX_AGE}`;
104
+ },
105
+ [onPinnedChange, pinnedProp]
106
+ );
107
+ const togglePin = (0, import_react.useCallback)(() => {
108
+ setPinned(!pinned);
109
+ setFlyoutValue(null);
110
+ }, [pinned, setPinned]);
111
+ const openFlyout = (0, import_react.useCallback)((value2) => {
112
+ setFlyoutValue((curr) => curr === value2 ? null : value2);
113
+ }, []);
114
+ const setFlyout = (0, import_react.useCallback)((value2) => {
115
+ setFlyoutValue(value2);
116
+ }, []);
117
+ const closeFlyout = (0, import_react.useCallback)(() => setFlyoutValue(null), []);
118
+ const resetPanelSelection = (0, import_react.useCallback)(() => {
119
+ setSelectedRail(null);
120
+ setFlyoutValue(null);
121
+ }, []);
122
+ const toggleGroup = (0, import_react.useCallback)((key) => {
123
+ setOpenGroup((curr) => curr === key ? null : key);
124
+ }, []);
125
+ const isActive = (0, import_react.useCallback)(
126
+ (href) => activeHref === href || href !== "/" && activeHref.startsWith(`${href}/`),
127
+ [activeHref]
128
+ );
129
+ const value = (0, import_react.useMemo)(
130
+ () => ({
131
+ tone,
132
+ styles,
133
+ pinned,
134
+ togglePin,
135
+ setPinned,
136
+ selectedRail,
137
+ setSelectedRail,
138
+ flyoutTrigger,
139
+ flyoutValue,
140
+ openFlyout,
141
+ setFlyout,
142
+ closeFlyout,
143
+ resetPanelSelection,
144
+ openGroup,
145
+ toggleGroup,
146
+ setOpenGroup,
147
+ activeHref,
148
+ isActive,
149
+ renderLink,
150
+ isMobile,
151
+ drawerOpen,
152
+ setDrawerOpen,
153
+ panelHost,
154
+ setPanelHost,
155
+ panelOverrideActive,
156
+ registerPanelOverride,
157
+ navPreviewActive
158
+ }),
159
+ [
160
+ tone,
161
+ styles,
162
+ pinned,
163
+ togglePin,
164
+ setPinned,
165
+ selectedRail,
166
+ flyoutTrigger,
167
+ flyoutValue,
168
+ openFlyout,
169
+ setFlyout,
170
+ closeFlyout,
171
+ resetPanelSelection,
172
+ openGroup,
173
+ toggleGroup,
174
+ activeHref,
175
+ isActive,
176
+ renderLink,
177
+ isMobile,
178
+ drawerOpen,
179
+ panelHost,
180
+ panelOverrideActive,
181
+ registerPanelOverride,
182
+ navPreviewActive
183
+ ]
184
+ );
185
+ (0, import_react.useEffect)(() => {
186
+ setDrawerOpen(false);
187
+ setFlyoutValue(null);
188
+ setSelectedRail(null);
189
+ setOpenGroup(null);
190
+ }, [activeHref]);
191
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Provider, { value, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_tooltip.TooltipProvider, { delayDuration: 0, children }) });
192
+ }
193
+
194
+ // src/v2/app-shell.tsx
195
+ var import_jsx_runtime2 = require("react/jsx-runtime");
196
+ var RAIL_WIDTH = "4rem";
197
+ var PANEL_WIDTH = "15rem";
198
+ function AppShellRoot({
199
+ className,
200
+ style,
201
+ children,
202
+ ...props
203
+ }) {
204
+ const { tone, styles } = useSidebarV2();
205
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
206
+ "div",
207
+ {
208
+ "data-slot": "app-shell",
209
+ "data-tone": tone,
210
+ className: styles.shell({ className }),
211
+ style: {
212
+ "--kpx-rail-width": RAIL_WIDTH,
213
+ "--kpx-panel-width": PANEL_WIDTH,
214
+ gridTemplateAreas: '"header header header header" "rail panel main aside"',
215
+ gridTemplateRows: "auto 1fr",
216
+ gridTemplateColumns: "auto auto 1fr auto",
217
+ ...style
218
+ },
219
+ ...props,
220
+ children
221
+ }
222
+ );
223
+ }
224
+ function AppShellHeader({
225
+ className,
226
+ style,
227
+ ...props
228
+ }) {
229
+ const { styles } = useSidebarV2();
230
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
231
+ "header",
232
+ {
233
+ "data-slot": "app-shell-header",
234
+ className: styles.header({ className }),
235
+ style: { gridArea: "header", ...style },
236
+ ...props
237
+ }
238
+ );
239
+ }
240
+ function AppShellMain({ className, style, ...props }) {
241
+ const { styles } = useSidebarV2();
242
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
243
+ "main",
244
+ {
245
+ "data-slot": "app-shell-main",
246
+ className: styles.main({ className }),
247
+ style: { gridArea: "main", ...style },
248
+ ...props
249
+ }
250
+ );
251
+ }
252
+ function AppShellAside({
253
+ className,
254
+ style,
255
+ ...props
256
+ }) {
257
+ const { styles } = useSidebarV2();
258
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
259
+ "aside",
260
+ {
261
+ "data-slot": "app-shell-aside",
262
+ className: styles.aside({ className }),
263
+ style: { gridArea: "aside", ...style },
264
+ ...props
265
+ }
266
+ );
267
+ }
268
+ function AppShellPanelContent({ children }) {
269
+ const { panelHost, registerPanelOverride, navPreviewActive } = useSidebarV2();
270
+ (0, import_react2.useEffect)(() => registerPanelOverride(), [registerPanelOverride]);
271
+ if (!panelHost || navPreviewActive) return null;
272
+ return (0, import_react_dom.createPortal)(children, panelHost);
273
+ }
274
+ var AppShell = AppShellRoot;
275
+ AppShell.Header = AppShellHeader;
276
+ AppShell.Main = AppShellMain;
277
+ AppShell.Aside = AppShellAside;
278
+ AppShell.PanelContent = AppShellPanelContent;
279
+
280
+ // src/v2/components.tsx
281
+ var import_button = require("@kopexa/button");
282
+ var import_icons = require("@kopexa/icons");
283
+ var import_shared_utils = require("@kopexa/shared-utils");
284
+ var import_theme2 = require("@kopexa/theme");
285
+ var import_tooltip2 = require("@kopexa/tooltip");
286
+ var import_react3 = require("react");
287
+
288
+ // src/v2/types.ts
289
+ function panelItemHasChildren(item) {
290
+ return "children" in item && Array.isArray(item.children);
291
+ }
292
+ function panelItemIsSection(item) {
293
+ return "section" in item;
294
+ }
295
+
296
+ // src/v2/components.tsx
297
+ var import_jsx_runtime3 = require("react/jsx-runtime");
298
+ function SidebarV2Inset({
299
+ className,
300
+ ...props
301
+ }) {
302
+ const { styles } = useSidebarV2();
303
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
304
+ "main",
305
+ {
306
+ "data-slot": "sidebar-v2-inset",
307
+ className: styles.inset({ className }),
308
+ ...props
309
+ }
310
+ );
311
+ }
312
+ function SidebarV2Rail({ className, ...props }) {
313
+ const { styles } = useSidebarV2();
314
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
315
+ "nav",
316
+ {
317
+ "data-slot": "sidebar-v2-rail",
318
+ className: styles.rail({ className }),
319
+ ...props
320
+ }
321
+ );
322
+ }
323
+ function SidebarV2RailSpacer() {
324
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { "aria-hidden": true, className: "flex-1" });
325
+ }
326
+ var SidebarV2Workspace = (0, import_react3.forwardRef)(({ name, role, logo, className, appearance = "rail", ...props }, ref) => {
327
+ const { styles } = useSidebarV2();
328
+ if (appearance === "bar") {
329
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
330
+ "button",
331
+ {
332
+ ref,
333
+ type: "button",
334
+ "data-slot": "sidebar-v2-workspace",
335
+ "aria-label": role ? `${name} \u2013 ${role}` : name,
336
+ className: styles.workspaceBar({ className }),
337
+ ...props,
338
+ children: [
339
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: styles.workspaceBarLogo(), children: logo != null ? logo : name.charAt(0).toUpperCase() }),
340
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("span", { className: styles.workspaceBarText(), children: [
341
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: styles.workspaceBarName(), children: name }),
342
+ role && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: styles.workspaceBarRole(), children: role })
343
+ ] }),
344
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_icons.ChevronDownIcon, { className: styles.workspaceBarChevron() })
345
+ ]
346
+ }
347
+ );
348
+ }
349
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
350
+ "button",
351
+ {
352
+ ref,
353
+ type: "button",
354
+ "data-slot": "sidebar-v2-workspace",
355
+ "aria-label": role ? `${name} \u2013 ${role}` : name,
356
+ className: styles.workspaceRail({ className }),
357
+ ...props,
358
+ children: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("span", { className: styles.workspaceRailLogo(), children: [
359
+ logo != null ? logo : name.charAt(0).toUpperCase(),
360
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_icons.ChevronDownIcon, { className: styles.workspaceRailChevron() })
361
+ ] })
362
+ }
363
+ );
364
+ });
365
+ SidebarV2Workspace.displayName = "SidebarV2Workspace";
366
+ function RailInner({
367
+ icon: Icon,
368
+ badge
369
+ }) {
370
+ const { styles } = useSidebarV2();
371
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_jsx_runtime3.Fragment, { children: [
372
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { "aria-hidden": true, className: styles.railIndicator() }),
373
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Icon, { className: styles.railIcon() }),
374
+ badge != null && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: styles.railBadge(), children: badge })
375
+ ] });
376
+ }
377
+ function SidebarV2RailLink({
378
+ icon,
379
+ label,
380
+ href,
381
+ badge
382
+ }) {
383
+ const { renderLink, isActive, resetPanelSelection, styles } = useSidebarV2();
384
+ const active = isActive(href);
385
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_tooltip2.Tooltip, { content: label, side: "right", children: renderLink({
386
+ href,
387
+ className: styles.railButton(),
388
+ "data-active": active,
389
+ "aria-current": active ? "page" : void 0,
390
+ "aria-label": label,
391
+ // Navigating to a destination link clears any open panel preview,
392
+ // even when the route doesn't change (e.g. already on it).
393
+ onClick: resetPanelSelection,
394
+ children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(RailInner, { icon, badge })
395
+ }) });
396
+ }
397
+ function SidebarV2RailItem({
398
+ icon,
399
+ label,
400
+ active,
401
+ hasPanel,
402
+ onClick,
403
+ onMouseEnter,
404
+ onMouseLeave,
405
+ badge
406
+ }) {
407
+ const { styles } = useSidebarV2();
408
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_tooltip2.Tooltip, { content: label, side: "right", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
409
+ "button",
410
+ {
411
+ type: "button",
412
+ "data-active": active,
413
+ "aria-label": label,
414
+ "aria-expanded": hasPanel ? active : void 0,
415
+ onClick,
416
+ onMouseEnter,
417
+ onMouseLeave,
418
+ className: styles.railButton(),
419
+ children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(RailInner, { icon, badge })
420
+ }
421
+ ) });
422
+ }
423
+ function SidebarV2Panel({
424
+ title,
425
+ subtitle,
426
+ floating,
427
+ hidePin,
428
+ action,
429
+ children,
430
+ className
431
+ }) {
432
+ const { togglePin, pinned, styles } = useSidebarV2();
433
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
434
+ "div",
435
+ {
436
+ "data-slot": "sidebar-v2-panel",
437
+ "data-floating": floating ? "true" : "false",
438
+ className: styles.panel({ className }),
439
+ children: [
440
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: styles.panelHeader(), children: [
441
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "min-w-0 flex-1", children: [
442
+ title && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: styles.panelTitle(), children: title }),
443
+ subtitle && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: styles.panelSubtitle(), children: subtitle })
444
+ ] }),
445
+ action != null ? action : !hidePin && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
446
+ import_tooltip2.Tooltip,
447
+ {
448
+ content: pinned ? "Panel l\xF6sen" : "Panel anheften",
449
+ side: "bottom",
450
+ children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
451
+ import_button.IconButton,
452
+ {
453
+ variant: "ghost",
454
+ size: "sm",
455
+ "aria-label": pinned ? "Panel l\xF6sen" : "Panel anheften",
456
+ onClick: togglePin,
457
+ className: styles.panelPin(),
458
+ children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_icons.PanelLeftIcon, { className: "size-4" })
459
+ }
460
+ )
461
+ }
462
+ )
463
+ ] }),
464
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: styles.panelBody(), children })
465
+ ]
466
+ }
467
+ );
468
+ }
469
+ function SidebarV2PanelLabel({
470
+ className,
471
+ ...props
472
+ }) {
473
+ const { styles } = useSidebarV2();
474
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
475
+ "div",
476
+ {
477
+ "data-slot": "sidebar-v2-panel-label",
478
+ className: styles.panelLabel({ className }),
479
+ ...props
480
+ }
481
+ );
482
+ }
483
+ function SidebarV2PanelLeaf({
484
+ item,
485
+ active: activeProp
486
+ }) {
487
+ const { renderLink, isActive, tone, styles } = useSidebarV2();
488
+ const light = tone === "light";
489
+ const Icon = item.icon;
490
+ const active = activeProp != null ? activeProp : isActive(item.href);
491
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_jsx_runtime3.Fragment, { children: renderLink({
492
+ href: item.href,
493
+ "data-active": active,
494
+ "aria-current": active ? "page" : void 0,
495
+ // Light tone uses the recipe's leaf slot (group/leaf + data-active);
496
+ // dark tone reuses the existing sidebarMenuButton recipe.
497
+ className: light ? styles.panelLeaf() : (0, import_theme2.sidebarMenuButton)({ size: "md" }),
498
+ children: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_jsx_runtime3.Fragment, { children: [
499
+ Icon && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Icon, { className: styles.panelLeafIcon() }),
500
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: styles.panelLeafLabel(), children: item.label }),
501
+ item.badge != null && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: styles.panelLeafBadge(), children: item.badge })
502
+ ] })
503
+ }) });
504
+ }
505
+ function SidebarV2PanelGroup({
506
+ item
507
+ }) {
508
+ var _a;
509
+ const { openGroup, toggleGroup, activeHref, renderLink, tone, styles } = useSidebarV2();
510
+ const light = tone === "light";
511
+ const Icon = item.icon;
512
+ const key = (_a = item.value) != null ? _a : item.label;
513
+ let bestChildHref = null;
514
+ let bestLen = -1;
515
+ for (const c of item.children) {
516
+ if (activeHref === c.href) {
517
+ bestChildHref = c.href;
518
+ break;
519
+ }
520
+ if (activeHref.startsWith(`${c.href}/`) && c.href.length > bestLen) {
521
+ bestChildHref = c.href;
522
+ bestLen = c.href.length;
523
+ }
524
+ }
525
+ const containsActive = bestChildHref !== null;
526
+ const open = openGroup === key || openGroup === null && containsActive;
527
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { children: [
528
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
529
+ "button",
530
+ {
531
+ type: "button",
532
+ "data-state": open ? "open" : "closed",
533
+ "data-contains-active": containsActive,
534
+ "aria-expanded": open,
535
+ onClick: () => toggleGroup(key),
536
+ className: (0, import_shared_utils.cn)(
537
+ light ? styles.panelLeaf() : (0, import_theme2.sidebarMenuButton)({ size: "md" }),
538
+ styles.panelGroupButton()
539
+ ),
540
+ children: [
541
+ Icon && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Icon, { className: styles.panelGroupIcon() }),
542
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: styles.panelGroupLabel(), children: item.label }),
543
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_icons.ChevronRightIcon, { className: styles.panelGroupChevron() })
544
+ ]
545
+ }
546
+ ),
547
+ open && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: styles.panelTree(), children: item.children.map((child) => {
548
+ const active = child.href === bestChildHref;
549
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { children: renderLink({
550
+ href: child.href,
551
+ "data-active": active,
552
+ "aria-current": active ? "page" : void 0,
553
+ className: styles.subItem(),
554
+ children: child.label
555
+ }) }, child.href);
556
+ }) })
557
+ ] });
558
+ }
559
+ function SidebarV2PanelItems({
560
+ items
561
+ }) {
562
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_jsx_runtime3.Fragment, { children: items.map((item, idx) => {
563
+ var _a;
564
+ if (panelItemIsSection(item)) {
565
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(SidebarV2PanelLabel, { children: item.section }, `section-${item.section}-${idx}`);
566
+ }
567
+ if (panelItemHasChildren(item)) {
568
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(SidebarV2PanelGroup, { item }, (_a = item.value) != null ? _a : item.label);
569
+ }
570
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(SidebarV2PanelLeaf, { item }, item.href);
571
+ }) });
572
+ }
573
+ function SidebarV2Trigger({
574
+ className,
575
+ ...props
576
+ }) {
577
+ const { setDrawerOpen, drawerOpen } = useSidebarV2();
578
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
579
+ import_button.IconButton,
580
+ {
581
+ variant: "ghost",
582
+ size: "md",
583
+ "aria-label": "Navigation \xF6ffnen",
584
+ onClick: () => setDrawerOpen(!drawerOpen),
585
+ className,
586
+ ...props,
587
+ children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_icons.PanelLeftIcon, { className: "size-5" })
588
+ }
589
+ );
590
+ }
591
+
592
+ // src/v2/from-config.tsx
593
+ var import_drawer = require("@kopexa/drawer");
594
+ var import_shared_utils2 = require("@kopexa/shared-utils");
595
+ var import_react4 = require("motion/react");
596
+ var import_react5 = require("react");
597
+ var import_jsx_runtime4 = require("react/jsx-runtime");
598
+ var RAIL_WIDTH2 = "4rem";
599
+ var PANEL_WIDTH2 = "15rem";
600
+ var railVars = {
601
+ "--kpx-rail-width": RAIL_WIDTH2,
602
+ "--kpx-panel-width": PANEL_WIDTH2
603
+ };
604
+ function entryValue(entry) {
605
+ var _a;
606
+ if (entry.type === "divider") return "divider";
607
+ return entry.type === "panel" ? (_a = entry.value) != null ? _a : entry.label : entry.label;
608
+ }
609
+ function SidebarV2FromConfig({
610
+ items,
611
+ header
612
+ }) {
613
+ var _a, _b, _c;
614
+ const {
615
+ pinned,
616
+ flyoutTrigger,
617
+ flyoutValue,
618
+ openFlyout,
619
+ setFlyout,
620
+ closeFlyout,
621
+ selectedRail,
622
+ setSelectedRail,
623
+ isActive,
624
+ isMobile,
625
+ drawerOpen,
626
+ setDrawerOpen,
627
+ setPanelHost,
628
+ panelOverrideActive,
629
+ navPreviewActive,
630
+ styles
631
+ } = useSidebarV2();
632
+ const hoverMode = flyoutTrigger === "hover" && !pinned && !isMobile;
633
+ const closeTimer = (0, import_react5.useRef)(null);
634
+ const cancelClose = (0, import_react5.useCallback)(() => {
635
+ if (closeTimer.current) clearTimeout(closeTimer.current);
636
+ closeTimer.current = null;
637
+ }, []);
638
+ const scheduleClose = (0, import_react5.useCallback)(() => {
639
+ cancelClose();
640
+ closeTimer.current = setTimeout(() => closeFlyout(), 160);
641
+ }, [cancelClose, closeFlyout]);
642
+ (0, import_react5.useEffect)(() => cancelClose, [cancelClose]);
643
+ (0, import_react5.useEffect)(() => {
644
+ if (pinned || isMobile || !flyoutValue) return;
645
+ const onPointerDown = (event) => {
646
+ const t = event.target;
647
+ if (!t) return;
648
+ if (t.closest('[data-slot="sidebar-v2-rail"]')) return;
649
+ if (t.closest('[data-floating="true"]')) return;
650
+ closeFlyout();
651
+ };
652
+ const onKeyDown = (event) => {
653
+ if (event.key === "Escape") closeFlyout();
654
+ };
655
+ document.addEventListener("pointerdown", onPointerDown);
656
+ document.addEventListener("keydown", onKeyDown);
657
+ return () => {
658
+ document.removeEventListener("pointerdown", onPointerDown);
659
+ document.removeEventListener("keydown", onKeyDown);
660
+ };
661
+ }, [pinned, isMobile, flyoutValue, closeFlyout]);
662
+ const panels = (0, import_react5.useMemo)(
663
+ () => items.filter(
664
+ (e) => e.type === "panel"
665
+ ),
666
+ [items]
667
+ );
668
+ const activeRailValue = (0, import_react5.useMemo)(() => {
669
+ const match = panels.find(
670
+ (p) => p.items.some((item) => {
671
+ if (panelItemIsSection(item)) return false;
672
+ return panelItemHasChildren(item) ? item.children.some((c) => isActive(c.href)) : isActive(item.href);
673
+ })
674
+ );
675
+ return match ? entryValue(match) : null;
676
+ }, [panels, isActive]);
677
+ const shownValue = pinned ? selectedRail != null ? selectedRail : activeRailValue : flyoutValue;
678
+ const shownPanel = (_a = panels.find((p) => entryValue(p) === shownValue)) != null ? _a : null;
679
+ const topEntries = items.filter((e) => e.slot !== "bottom");
680
+ const bottomEntries = items.filter((e) => e.slot === "bottom");
681
+ function renderRailEntry(entry, index) {
682
+ if (entry.type === "divider") {
683
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
684
+ "div",
685
+ {
686
+ "aria-hidden": true,
687
+ className: styles.railDivider()
688
+ },
689
+ `rail-divider-${index}`
690
+ );
691
+ }
692
+ const value = entryValue(entry);
693
+ if (entry.type === "link") {
694
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
695
+ SidebarV2RailLink,
696
+ {
697
+ icon: entry.icon,
698
+ label: entry.label,
699
+ href: entry.href,
700
+ badge: entry.badge
701
+ },
702
+ value
703
+ );
704
+ }
705
+ if (entry.type === "action") {
706
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
707
+ SidebarV2RailItem,
708
+ {
709
+ icon: entry.icon,
710
+ label: entry.label,
711
+ active: false,
712
+ onClick: entry.onSelect
713
+ },
714
+ value
715
+ );
716
+ }
717
+ const active = flyoutValue ? value === flyoutValue : value === (selectedRail != null ? selectedRail : activeRailValue);
718
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
719
+ SidebarV2RailItem,
720
+ {
721
+ icon: entry.icon,
722
+ label: entry.label,
723
+ active,
724
+ hasPanel: true,
725
+ onClick: () => {
726
+ if (pinned) setSelectedRail(value);
727
+ else openFlyout(value);
728
+ },
729
+ onMouseEnter: hoverMode ? () => {
730
+ cancelClose();
731
+ setFlyout(value);
732
+ } : void 0,
733
+ onMouseLeave: hoverMode ? scheduleClose : void 0
734
+ },
735
+ value
736
+ );
737
+ }
738
+ const railContent = /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_jsx_runtime4.Fragment, { children: [
739
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: styles.railScroll(), children: [
740
+ header && /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_jsx_runtime4.Fragment, { children: [
741
+ header,
742
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: styles.railHeaderDivider() })
743
+ ] }),
744
+ topEntries.map(renderRailEntry)
745
+ ] }),
746
+ bottomEntries.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: styles.railBottom(), children: bottomEntries.map(renderRailEntry) })
747
+ ] });
748
+ const navData = pinned && shownPanel && (navPreviewActive || !panelOverrideActive) ? shownPanel : null;
749
+ const [bufferedPanel, setBufferedPanel] = (0, import_react5.useState)(navData);
750
+ (0, import_react5.useEffect)(() => {
751
+ if (navData) {
752
+ setBufferedPanel(navData);
753
+ return;
754
+ }
755
+ const t = setTimeout(() => setBufferedPanel(null), 220);
756
+ return () => clearTimeout(t);
757
+ }, [navData]);
758
+ const navToRender = navData != null ? navData : bufferedPanel;
759
+ const renderNav = (!panelOverrideActive || navPreviewActive) && navToRender;
760
+ const panelContent = navToRender && renderNav ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
761
+ SidebarV2Panel,
762
+ {
763
+ title: (_b = navToRender.title) != null ? _b : navToRender.label,
764
+ subtitle: navToRender.subtitle,
765
+ children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(SidebarV2PanelItems, { items: navToRender.items })
766
+ },
767
+ entryValue(navToRender)
768
+ ) : null;
769
+ const docked = Boolean(navData) || panelOverrideActive;
770
+ const showFlyout = !pinned && Boolean(shownPanel);
771
+ if (isMobile) {
772
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
773
+ import_drawer.Drawer.Root,
774
+ {
775
+ open: drawerOpen,
776
+ onOpenChange: setDrawerOpen,
777
+ placement: "left",
778
+ children: /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_drawer.Drawer.Content, { className: styles.mobileDrawer(), children: [
779
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_drawer.Drawer.Header, { className: "sr-only", children: [
780
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_drawer.Drawer.Title, { children: "Navigation" }),
781
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_drawer.Drawer.Description, { children: "Hauptnavigation" })
782
+ ] }),
783
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "flex h-full", style: railVars, children: [
784
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(SidebarV2Rail, { children: railContent }),
785
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
786
+ "div",
787
+ {
788
+ ref: setPanelHost,
789
+ "data-slot": "sidebar-v2-panel-zone",
790
+ className: "flex min-h-0",
791
+ children: panelContent
792
+ }
793
+ )
794
+ ] })
795
+ ] })
796
+ }
797
+ );
798
+ }
799
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_jsx_runtime4.Fragment, { children: [
800
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(SidebarV2Rail, { style: { gridArea: "rail" }, children: railContent }),
801
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
802
+ "div",
803
+ {
804
+ ref: setPanelHost,
805
+ "data-slot": "sidebar-v2-panel-zone",
806
+ className: (0, import_shared_utils2.cn)(styles.panelZone(), pinned && "overflow-hidden"),
807
+ style: { gridArea: "panel", width: docked ? PANEL_WIDTH2 : "0px" },
808
+ children: [
809
+ panelContent,
810
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react4.AnimatePresence, { children: showFlyout && shownPanel && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
811
+ import_react4.motion.div,
812
+ {
813
+ "data-floating": "true",
814
+ className: styles.flyout(),
815
+ initial: { x: -14, opacity: 0 },
816
+ animate: { x: 0, opacity: 1 },
817
+ exit: { x: -14, opacity: 0 },
818
+ transition: { duration: 0.16, ease: "easeOut" },
819
+ onMouseEnter: hoverMode ? cancelClose : void 0,
820
+ onMouseLeave: hoverMode ? scheduleClose : void 0,
821
+ children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
822
+ SidebarV2Panel,
823
+ {
824
+ floating: true,
825
+ title: (_c = shownPanel.title) != null ? _c : shownPanel.label,
826
+ subtitle: shownPanel.subtitle,
827
+ children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(SidebarV2PanelItems, { items: shownPanel.items })
828
+ }
829
+ )
830
+ },
831
+ "sidebar-v2-flyout"
832
+ ) })
833
+ ]
834
+ }
835
+ )
836
+ ] });
837
+ }
838
+
839
+ // src/v2/index.tsx
840
+ var SidebarV2 = SidebarV2Provider;
841
+ SidebarV2.FromConfig = SidebarV2FromConfig;
842
+ SidebarV2.Inset = SidebarV2Inset;
843
+ SidebarV2.Trigger = SidebarV2Trigger;
844
+ SidebarV2.Rail = SidebarV2Rail;
845
+ SidebarV2.RailItem = SidebarV2RailItem;
846
+ SidebarV2.RailLink = SidebarV2RailLink;
847
+ SidebarV2.RailSpacer = SidebarV2RailSpacer;
848
+ SidebarV2.Workspace = SidebarV2Workspace;
849
+ SidebarV2.Panel = SidebarV2Panel;
850
+ SidebarV2.PanelItems = SidebarV2PanelItems;
851
+ SidebarV2.PanelLeaf = SidebarV2PanelLeaf;
852
+ SidebarV2.PanelGroup = SidebarV2PanelGroup;
853
+ SidebarV2.PanelLabel = SidebarV2PanelLabel;
854
+ // Annotate the CommonJS export names for ESM import in node:
855
+ 0 && (module.exports = {
856
+ AppShell,
857
+ AppShellAside,
858
+ AppShellHeader,
859
+ AppShellMain,
860
+ AppShellPanelContent,
861
+ AppShellRoot,
862
+ SidebarV2,
863
+ SidebarV2FromConfig,
864
+ SidebarV2Inset,
865
+ SidebarV2Panel,
866
+ SidebarV2PanelGroup,
867
+ SidebarV2PanelItems,
868
+ SidebarV2PanelLabel,
869
+ SidebarV2PanelLeaf,
870
+ SidebarV2Provider,
871
+ SidebarV2Rail,
872
+ SidebarV2RailItem,
873
+ SidebarV2RailLink,
874
+ SidebarV2RailSpacer,
875
+ SidebarV2Trigger,
876
+ SidebarV2Workspace,
877
+ useSidebarV2
878
+ });