beez-ui 0.9.1 → 0.11.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,40 +1,121 @@
1
1
  "use client";
2
2
  import { c as _c } from "react/compiler-runtime";
3
+ /**
4
+ * Animated application sidebar adapted from beui.dev/components/motion/animated-sidebar: the rail
5
+ * morphs its width with a spring, labels fade out of the icon rail, a shared pill follows the
6
+ * hovered and active items, submenus unfold with a stagger, and small screens get a focus-trapped
7
+ * sheet. Links route through the `BeezUIProvider` adapter and the open state keeps the
8
+ * `sidebar_state` cookie contract read by server entrypoints.
9
+ */
3
10
  import * as React from "react";
4
- import { cva } from "class-variance-authority";
11
+ import { ChevronRight, PanelLeftIcon } from "lucide-react";
5
12
  import { Slot } from "radix-ui";
13
+ import { AnimatePresence, motion } from "motion/react";
14
+ import { createPortal } from "react-dom";
15
+ import { useIsHydrated } from "../hooks/use-is-hydrated.js";
6
16
  import { useIsMobile } from "../hooks/use-mobile.js";
7
- import { useSidebarPersistence, saveSidebarPreference } from "../hooks/use-sidebar-persistence.js";
8
- import { GlideSlot } from "../motion/glide-slot.js";
9
- import { MotionSlot } from "../motion/motion-slot.js";
10
- import { MOTION_EASE_DRAWER } from "../motion/tokens.js";
11
- import { cn } from "../lib/utils.js";
17
+ import { usePrefersReducedMotion } from "../hooks/use-prefers-reduced-motion.js";
18
+ import { saveSidebarCookie, saveSidebarPreference, useSidebarPersistence } from "../hooks/use-sidebar-persistence.js";
12
19
  import { SIDEBAR_COOKIE_MAX_AGE, SIDEBAR_COOKIE_NAME } from "../constants/sidebar.js";
13
- import { Button } from "./button.js";
14
- import { Input } from "./input.js";
15
- import { Separator } from "./separator.js";
16
- import { Sheet, SheetContent, SheetDescription, SheetHeader, SheetTitle } from "./sheet.js";
17
- import { Skeleton } from "./skeleton.js";
18
- import { Tooltip, TooltipContent, TooltipTrigger } from "./tooltip.js";
19
- import { PanelLeftIcon } from "lucide-react";
20
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
20
+ import { cn } from "../lib/utils.js";
21
+ import { MotionSlot } from "../motion/motion-slot.js";
22
+ import { SharedLayoutBg } from "../motion/shared-layout-bg.js";
23
+ import { MOTION_EASE, MOTION_EASE_DRAWER, MOTION_LIST_ITEM_DISTANCE, MOTION_TIMING, SPRING_LAYOUT } from "../motion/tokens.js";
24
+ import { Link } from "./link.js";
25
+ import { SidebarPanelContext } from "./sidebar-panel-context.js";
26
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
27
+ import { createElement as _createElement } from "react";
21
28
  const SIDEBAR_WIDTH = "16rem";
29
+ const SIDEBAR_WIDTH_ICON = "4.25rem";
22
30
  const SIDEBAR_WIDTH_MOBILE = "18rem";
23
- const SIDEBAR_WIDTH_ICON = "3rem";
24
31
  const SIDEBAR_KEYBOARD_SHORTCUT = "b";
25
- /** Drawer curve shared by the collapse transitions: quick start, long gentle settle. */
26
- const SIDEBAR_EASE = `cubic-bezier(${MOTION_EASE_DRAWER.join(", ")})`;
27
- const SIDEBAR_MENU_SKELETON_TEXT_WIDTH = "70%";
28
- function subscribeToClientMount() {
29
- return () => {};
30
- }
31
- function getClientMountSnapshot() {
32
- return true;
33
- }
34
- function getServerMountSnapshot() {
35
- return false;
36
- }
32
+ const EXTERNAL_LINK_TARGET = "_blank";
33
+ const EXTERNAL_LINK_REL = "noreferrer noopener";
34
+ /** Distance, in pixels, labels and chevrons drift while fading out of the icon rail. */
35
+ const SIDEBAR_LABEL_DRIFT_PX = 4;
36
+ /** Chevron rotation, in degrees, of an expanded group. */
37
+ const SIDEBAR_CHEVRON_EXPANDED_DEGREES = 90;
38
+ /** Blur, in pixels, submenu items shed as they unfold. */
39
+ const SIDEBAR_SUBMENU_ITEM_BLUR_PX = 3;
40
+ const PANEL_TRANSITION = {
41
+ duration: .36,
42
+ ease: MOTION_EASE_DRAWER
43
+ };
44
+ /**
45
+ * The desktop rail settles at a hard zero-width boundary. Keep the spring critically damped so it
46
+ * cannot overshoot, pause against that boundary, and then snap back during the final frame.
47
+ */
48
+ const SIDEBAR_MORPH_TRANSITION = {
49
+ type: "spring",
50
+ stiffness: 380,
51
+ damping: 35,
52
+ mass: .75
53
+ };
54
+ const LABEL_ENTER_TRANSITION = {
55
+ duration: MOTION_TIMING.message,
56
+ delay: .08,
57
+ ease: MOTION_EASE
58
+ };
59
+ const LABEL_EXIT_TRANSITION = {
60
+ duration: MOTION_TIMING.exit,
61
+ ease: MOTION_EASE
62
+ };
63
+ const REDUCED_TRANSITION = {
64
+ duration: .16,
65
+ ease: MOTION_EASE
66
+ };
67
+ const INSTANT_TRANSITION = { duration: 0 };
68
+ const SUBMENU_VARIANTS = {
69
+ closed: {
70
+ opacity: 0,
71
+ clipPath: "inset(0 0 100% 0 round 8px)",
72
+ transition: {
73
+ duration: MOTION_TIMING.fast,
74
+ ease: MOTION_EASE,
75
+ staggerChildren: .025,
76
+ staggerDirection: -1
77
+ }
78
+ },
79
+ open: {
80
+ opacity: 1,
81
+ clipPath: "inset(0 0 0% 0 round 8px)",
82
+ transition: {
83
+ duration: MOTION_TIMING.message,
84
+ delayChildren: MOTION_TIMING.listStagger,
85
+ ease: MOTION_EASE,
86
+ staggerChildren: .045
87
+ }
88
+ }
89
+ };
90
+ const SUBMENU_ITEM_VARIANTS = {
91
+ closed: {
92
+ opacity: 0,
93
+ y: -MOTION_LIST_ITEM_DISTANCE,
94
+ filter: `blur(${SIDEBAR_SUBMENU_ITEM_BLUR_PX}px)`
95
+ },
96
+ open: {
97
+ opacity: 1,
98
+ y: 0,
99
+ filter: "blur(0px)",
100
+ transition: {
101
+ duration: MOTION_TIMING.enter,
102
+ ease: MOTION_EASE
103
+ }
104
+ }
105
+ };
106
+ const FOCUSABLE_SELECTOR = [
107
+ "a[href]",
108
+ "button:not([disabled])",
109
+ "input:not([disabled])",
110
+ "select:not([disabled])",
111
+ "textarea:not([disabled])",
112
+ "[tabindex]:not([tabindex='-1'])"
113
+ ].join(",");
37
114
  const SidebarContext = React.createContext(null);
115
+ /**
116
+ * Reads the sidebar state shared by `SidebarProvider`.
117
+ * @returns Open state for desktop and mobile, viewport and motion flags, and state setters.
118
+ */
38
119
  function useSidebar() {
39
120
  const context = React.use(SidebarContext);
40
121
  if (!context) {
@@ -42,502 +123,929 @@ function useSidebar() {
42
123
  }
43
124
  return context;
44
125
  }
126
+ /**
127
+ * Reads the state of the enclosing `Sidebar` panel, so product content can adapt to the icon rail
128
+ * without depending on its DOM attributes.
129
+ * @returns Whether the panel is collapsed to its icon rail (always false in the mobile sheet), its
130
+ * collapse mode and its side.
131
+ */
132
+ function useSidebarPanel() {
133
+ const context = React.use(SidebarPanelContext);
134
+ if (!context) {
135
+ throw new Error("useSidebarPanel must be used within a Sidebar.");
136
+ }
137
+ return context;
138
+ }
139
+ /**
140
+ * Owns the open state of the sidebar, the ⌘B / Ctrl+B shortcut and the layout wrapper.
141
+ * @param props - Controlled or default state for both viewports, persistence options and wrapper attributes.
142
+ * @returns The wrapper that lays out the sidebar next to its inset.
143
+ */
45
144
  function SidebarProvider(t0) {
46
- const $ = _c(38);
145
+ const $ = _c(57);
47
146
  let children;
48
147
  let className;
148
+ let onOpenChange;
149
+ let onOpenMobileChange;
150
+ let openMobileProp;
49
151
  let openProp;
50
152
  let props;
51
- let setOpenProp;
52
153
  let storageKey;
53
154
  let style;
54
155
  let t1;
156
+ let t2;
157
+ let t3;
158
+ let t4;
55
159
  if ($[0] !== t0) {
56
- ({defaultOpen: t1, storageKey, open: openProp, onOpenChange: setOpenProp, className, style, children, ...props} = t0);
160
+ ({children, open: openProp, defaultOpen: t1, onOpenChange, openMobile: openMobileProp, defaultOpenMobile: t2, onOpenMobileChange, storageKey, cookieName: t3, cookieMaxAge: t4, className, style, ...props} = t0);
57
161
  $[0] = t0;
58
162
  $[1] = children;
59
163
  $[2] = className;
60
- $[3] = openProp;
61
- $[4] = props;
62
- $[5] = setOpenProp;
63
- $[6] = storageKey;
64
- $[7] = style;
65
- $[8] = t1;
164
+ $[3] = onOpenChange;
165
+ $[4] = onOpenMobileChange;
166
+ $[5] = openMobileProp;
167
+ $[6] = openProp;
168
+ $[7] = props;
169
+ $[8] = storageKey;
170
+ $[9] = style;
171
+ $[10] = t1;
172
+ $[11] = t2;
173
+ $[12] = t3;
174
+ $[13] = t4;
66
175
  } else {
67
176
  children = $[1];
68
177
  className = $[2];
69
- openProp = $[3];
70
- props = $[4];
71
- setOpenProp = $[5];
72
- storageKey = $[6];
73
- style = $[7];
74
- t1 = $[8];
178
+ onOpenChange = $[3];
179
+ onOpenMobileChange = $[4];
180
+ openMobileProp = $[5];
181
+ openProp = $[6];
182
+ props = $[7];
183
+ storageKey = $[8];
184
+ style = $[9];
185
+ t1 = $[10];
186
+ t2 = $[11];
187
+ t3 = $[12];
188
+ t4 = $[13];
75
189
  }
76
190
  const defaultOpen = t1 === undefined ? true : t1;
77
- const isMobile = useIsMobile();
78
- const [openMobile, setOpenMobile] = React.useState(false);
79
- const [_open, _setOpen] = React.useState(null);
191
+ const defaultOpenMobile = t2 === undefined ? false : t2;
192
+ const cookieName = t3 === undefined ? SIDEBAR_COOKIE_NAME : t3;
193
+ const cookieMaxAge = t4 === undefined ? SIDEBAR_COOKIE_MAX_AGE : t4;
194
+ const [internalOpen, setInternalOpen] = React.useState(null);
195
+ const [internalOpenMobile, setInternalOpenMobile] = React.useState(defaultOpenMobile);
80
196
  const persistedOpen = useSidebarPersistence(storageKey);
81
- const open = openProp ?? _open ?? persistedOpen ?? defaultOpen;
82
- let t2;
83
- if ($[9] !== open || $[10] !== setOpenProp || $[11] !== storageKey) {
84
- t2 = (value) => {
85
- const openState = typeof value === "function" ? value(open) : value;
86
- if (setOpenProp) {
87
- setOpenProp(openState);
88
- } else {
89
- _setOpen(openState);
197
+ const isMobile = useIsMobile();
198
+ const reduce = usePrefersReducedMotion();
199
+ const generatedId = React.useId();
200
+ const triggerRef = React.useRef(null);
201
+ const open = openProp ?? internalOpen ?? persistedOpen ?? defaultOpen;
202
+ const openMobile = openMobileProp ?? internalOpenMobile;
203
+ const state = open ? "expanded" : "collapsed";
204
+ const mobileWidth = style?.["--sidebar-width-mobile"] ?? SIDEBAR_WIDTH_MOBILE;
205
+ let t5;
206
+ if ($[14] !== cookieMaxAge || $[15] !== cookieName || $[16] !== onOpenChange || $[17] !== openProp || $[18] !== storageKey) {
207
+ t5 = (nextOpen) => {
208
+ if (openProp === undefined) {
209
+ setInternalOpen(nextOpen);
90
210
  }
91
- saveSidebarPreference(storageKey, openState);
92
- try {
93
- document.cookie = `${SIDEBAR_COOKIE_NAME}=${openState}; path=/; max-age=${SIDEBAR_COOKIE_MAX_AGE}; SameSite=Lax`;
94
- } catch {}
211
+ onOpenChange?.(nextOpen);
212
+ saveSidebarPreference(storageKey, nextOpen);
213
+ saveSidebarCookie(nextOpen, cookieName, cookieMaxAge);
95
214
  };
96
- $[9] = open;
97
- $[10] = setOpenProp;
98
- $[11] = storageKey;
99
- $[12] = t2;
215
+ $[14] = cookieMaxAge;
216
+ $[15] = cookieName;
217
+ $[16] = onOpenChange;
218
+ $[17] = openProp;
219
+ $[18] = storageKey;
220
+ $[19] = t5;
100
221
  } else {
101
- t2 = $[12];
222
+ t5 = $[19];
102
223
  }
103
- const setOpen = t2;
104
- let t3;
105
- if ($[13] !== isMobile || $[14] !== setOpen) {
106
- t3 = () => isMobile ? setOpenMobile(_temp) : setOpen(_temp2);
107
- $[13] = isMobile;
108
- $[14] = setOpen;
109
- $[15] = t3;
224
+ const setOpen = t5;
225
+ let t6;
226
+ if ($[20] !== onOpenMobileChange || $[21] !== openMobileProp) {
227
+ t6 = (nextOpen_0) => {
228
+ if (openMobileProp === undefined) {
229
+ setInternalOpenMobile(nextOpen_0);
230
+ }
231
+ onOpenMobileChange?.(nextOpen_0);
232
+ };
233
+ $[20] = onOpenMobileChange;
234
+ $[21] = openMobileProp;
235
+ $[22] = t6;
110
236
  } else {
111
- t3 = $[15];
237
+ t6 = $[22];
112
238
  }
113
- const toggleSidebar = t3;
114
- let t4;
115
- let t5;
116
- if ($[16] !== toggleSidebar) {
117
- t4 = () => {
118
- const handleKeyDown = (event) => {
119
- if (event.key === SIDEBAR_KEYBOARD_SHORTCUT && (event.metaKey || event.ctrlKey)) {
239
+ const setOpenMobile = t6;
240
+ let t7;
241
+ if ($[23] !== isMobile || $[24] !== open || $[25] !== openMobile || $[26] !== setOpen || $[27] !== setOpenMobile) {
242
+ t7 = () => {
243
+ if (isMobile) {
244
+ setOpenMobile(!openMobile);
245
+ } else {
246
+ setOpen(!open);
247
+ }
248
+ };
249
+ $[23] = isMobile;
250
+ $[24] = open;
251
+ $[25] = openMobile;
252
+ $[26] = setOpen;
253
+ $[27] = setOpenMobile;
254
+ $[28] = t7;
255
+ } else {
256
+ t7 = $[28];
257
+ }
258
+ const toggleSidebar = t7;
259
+ let t8;
260
+ let t9;
261
+ if ($[29] !== toggleSidebar) {
262
+ t8 = () => {
263
+ const handleShortcut = (event) => {
264
+ if (event.key.toLowerCase() === SIDEBAR_KEYBOARD_SHORTCUT && (event.metaKey || event.ctrlKey)) {
120
265
  event.preventDefault();
121
266
  toggleSidebar();
122
267
  }
123
268
  };
124
- window.addEventListener("keydown", handleKeyDown);
125
- return () => window.removeEventListener("keydown", handleKeyDown);
269
+ window.addEventListener("keydown", handleShortcut);
270
+ return () => window.removeEventListener("keydown", handleShortcut);
126
271
  };
127
- t5 = [toggleSidebar];
128
- $[16] = toggleSidebar;
129
- $[17] = t4;
130
- $[18] = t5;
272
+ t9 = [toggleSidebar];
273
+ $[29] = toggleSidebar;
274
+ $[30] = t8;
275
+ $[31] = t9;
131
276
  } else {
132
- t4 = $[17];
133
- t5 = $[18];
277
+ t8 = $[30];
278
+ t9 = $[31];
134
279
  }
135
- React.useEffect(t4, t5);
136
- const state = open ? "expanded" : "collapsed";
137
- let t6;
138
- if ($[19] !== isMobile || $[20] !== open || $[21] !== openMobile || $[22] !== setOpen || $[23] !== state || $[24] !== toggleSidebar) {
139
- t6 = {
140
- state,
141
- open,
142
- setOpen,
280
+ React.useEffect(t8, t9);
281
+ const t10 = `${generatedId}-active`;
282
+ let t11;
283
+ if ($[32] !== isMobile || $[33] !== mobileWidth || $[34] !== open || $[35] !== openMobile || $[36] !== reduce || $[37] !== setOpen || $[38] !== setOpenMobile || $[39] !== state || $[40] !== t10 || $[41] !== toggleSidebar) {
284
+ t11 = {
143
285
  isMobile,
286
+ layoutId: t10,
287
+ mobileWidth,
288
+ open,
144
289
  openMobile,
290
+ reduce,
291
+ setOpen,
145
292
  setOpenMobile,
146
- toggleSidebar
293
+ state,
294
+ toggleSidebar,
295
+ triggerRef
147
296
  };
148
- $[19] = isMobile;
149
- $[20] = open;
150
- $[21] = openMobile;
151
- $[22] = setOpen;
152
- $[23] = state;
153
- $[24] = toggleSidebar;
154
- $[25] = t6;
155
- } else {
156
- t6 = $[25];
157
- }
158
- const contextValue = t6;
159
- let t7;
160
- if ($[26] !== style) {
161
- t7 = {
297
+ $[32] = isMobile;
298
+ $[33] = mobileWidth;
299
+ $[34] = open;
300
+ $[35] = openMobile;
301
+ $[36] = reduce;
302
+ $[37] = setOpen;
303
+ $[38] = setOpenMobile;
304
+ $[39] = state;
305
+ $[40] = t10;
306
+ $[41] = toggleSidebar;
307
+ $[42] = t11;
308
+ } else {
309
+ t11 = $[42];
310
+ }
311
+ const contextValue = t11;
312
+ let t12;
313
+ if ($[43] !== mobileWidth || $[44] !== style) {
314
+ t12 = {
162
315
  "--sidebar-width": SIDEBAR_WIDTH,
163
316
  "--sidebar-width-icon": SIDEBAR_WIDTH_ICON,
164
- "--sidebar-ease": SIDEBAR_EASE,
317
+ "--sidebar-width-mobile": mobileWidth,
165
318
  ...style
166
319
  };
167
- $[26] = style;
168
- $[27] = t7;
320
+ $[43] = mobileWidth;
321
+ $[44] = style;
322
+ $[45] = t12;
169
323
  } else {
170
- t7 = $[27];
324
+ t12 = $[45];
171
325
  }
172
- const t8 = t7;
173
- let t9;
174
- if ($[28] !== className) {
175
- t9 = cn("group/sidebar-wrapper flex min-h-svh w-full has-data-[variant=inset]:bg-sidebar", className);
176
- $[28] = className;
177
- $[29] = t9;
326
+ let t13;
327
+ if ($[46] !== className) {
328
+ t13 = cn("group/sidebar-wrapper flex min-h-svh w-full min-w-0 has-data-[variant=inset]:bg-sidebar", className);
329
+ $[46] = className;
330
+ $[47] = t13;
178
331
  } else {
179
- t9 = $[29];
332
+ t13 = $[47];
180
333
  }
181
- let t10;
182
- if ($[30] !== children || $[31] !== props || $[32] !== t8 || $[33] !== t9) {
183
- t10 = /* @__PURE__ */ _jsx("div", {
184
- "data-slot": "sidebar-wrapper",
185
- style: t8,
186
- className: t9,
334
+ let t14;
335
+ if ($[48] !== children || $[49] !== props || $[50] !== state || $[51] !== t12 || $[52] !== t13) {
336
+ t14 = /* @__PURE__ */ _jsx("div", {
187
337
  ...props,
338
+ "data-slot": "sidebar-wrapper",
339
+ "data-state": state,
340
+ style: t12,
341
+ className: t13,
188
342
  children
189
343
  });
190
- $[30] = children;
191
- $[31] = props;
192
- $[32] = t8;
193
- $[33] = t9;
194
- $[34] = t10;
344
+ $[48] = children;
345
+ $[49] = props;
346
+ $[50] = state;
347
+ $[51] = t12;
348
+ $[52] = t13;
349
+ $[53] = t14;
350
+ } else {
351
+ t14 = $[53];
352
+ }
353
+ let t15;
354
+ if ($[54] !== contextValue || $[55] !== t14) {
355
+ t15 = /* @__PURE__ */ _jsx(SidebarContext.Provider, {
356
+ value: contextValue,
357
+ children: t14
358
+ });
359
+ $[54] = contextValue;
360
+ $[55] = t14;
361
+ $[56] = t15;
362
+ } else {
363
+ t15 = $[56];
364
+ }
365
+ return t15;
366
+ }
367
+ /** Small-screen sheet: locks page scroll, traps focus and hands it back to the trigger on close. */
368
+ function MobileSidebar(t0) {
369
+ const $ = _c(54);
370
+ const { ariaLabel, children, className, side } = t0;
371
+ const context = useSidebar();
372
+ const isHydrated = useIsHydrated();
373
+ const panelRef = React.useRef(null);
374
+ const [hidden, setHidden] = React.useState(!context.openMobile);
375
+ const openMobileRef = React.useRef(context.openMobile);
376
+ const { mobileWidth, openMobile, reduce, setOpenMobile, triggerRef } = context;
377
+ let t1;
378
+ let t2;
379
+ if ($[0] !== openMobile) {
380
+ t1 = () => {
381
+ openMobileRef.current = openMobile;
382
+ if (openMobile) {
383
+ setHidden(false);
384
+ }
385
+ };
386
+ t2 = [openMobile];
387
+ $[0] = openMobile;
388
+ $[1] = t1;
389
+ $[2] = t2;
390
+ } else {
391
+ t1 = $[1];
392
+ t2 = $[2];
393
+ }
394
+ React.useEffect(t1, t2);
395
+ let t3;
396
+ let t4;
397
+ if ($[3] !== openMobile || $[4] !== triggerRef) {
398
+ t3 = () => {
399
+ if (!openMobile) {
400
+ return;
401
+ }
402
+ const body = document.body;
403
+ const scrollY = window.scrollY;
404
+ const previousBodyStyles = {
405
+ left: body.style.left,
406
+ overflow: body.style.overflow,
407
+ position: body.style.position,
408
+ right: body.style.right,
409
+ top: body.style.top
410
+ };
411
+ body.style.position = "fixed";
412
+ body.style.top = `-${scrollY}px`;
413
+ body.style.left = "0";
414
+ body.style.right = "0";
415
+ body.style.overflow = "hidden";
416
+ const restoreTriggerFocus = () => triggerRef.current?.focus({ preventScroll: true });
417
+ const focusFrame = requestAnimationFrame(() => {
418
+ const firstFocusable = panelRef.current?.querySelector(FOCUSABLE_SELECTOR);
419
+ (firstFocusable ?? panelRef.current)?.focus({ preventScroll: true });
420
+ });
421
+ return () => {
422
+ cancelAnimationFrame(focusFrame);
423
+ body.style.position = previousBodyStyles.position;
424
+ body.style.top = previousBodyStyles.top;
425
+ body.style.left = previousBodyStyles.left;
426
+ body.style.right = previousBodyStyles.right;
427
+ body.style.overflow = previousBodyStyles.overflow;
428
+ window.scrollTo(0, scrollY);
429
+ restoreTriggerFocus();
430
+ };
431
+ };
432
+ t4 = [openMobile, triggerRef];
433
+ $[3] = openMobile;
434
+ $[4] = triggerRef;
435
+ $[5] = t3;
436
+ $[6] = t4;
437
+ } else {
438
+ t3 = $[5];
439
+ t4 = $[6];
440
+ }
441
+ React.useEffect(t3, t4);
442
+ if (!isHydrated) {
443
+ return null;
444
+ }
445
+ const closedOffset = side === "left" ? "-100%" : "100%";
446
+ const transition = reduce ? REDUCED_TRANSITION : PANEL_TRANSITION;
447
+ let t5;
448
+ if ($[7] !== setOpenMobile) {
449
+ t5 = (event) => {
450
+ if (event.key === "Escape") {
451
+ event.preventDefault();
452
+ setOpenMobile(false);
453
+ return;
454
+ }
455
+ if (event.key !== "Tab") {
456
+ return;
457
+ }
458
+ const focusable = panelRef.current ? Array.from(panelRef.current.querySelectorAll(FOCUSABLE_SELECTOR)) : [];
459
+ if (focusable.length === 0) {
460
+ event.preventDefault();
461
+ panelRef.current?.focus();
462
+ return;
463
+ }
464
+ const firstFocusable_0 = focusable[0];
465
+ const lastFocusable = focusable[focusable.length - 1];
466
+ if (event.shiftKey && document.activeElement === firstFocusable_0) {
467
+ event.preventDefault();
468
+ lastFocusable.focus();
469
+ } else {
470
+ if (!event.shiftKey && document.activeElement === lastFocusable) {
471
+ event.preventDefault();
472
+ firstFocusable_0.focus();
473
+ }
474
+ }
475
+ };
476
+ $[7] = setOpenMobile;
477
+ $[8] = t5;
478
+ } else {
479
+ t5 = $[8];
480
+ }
481
+ const trapFocus = t5;
482
+ const t6 = hidden && !openMobile ? "invisible" : "visible";
483
+ let t7;
484
+ if ($[9] !== t6) {
485
+ t7 = cn("pointer-events-none fixed top-0 left-0 z-50 size-0 md:hidden", t6);
486
+ $[9] = t6;
487
+ $[10] = t7;
488
+ } else {
489
+ t7 = $[10];
490
+ }
491
+ const t8 = openMobile ? 0 : -1;
492
+ const t9 = openMobile ? 1 : 0;
493
+ let t10;
494
+ if ($[11] !== t9) {
495
+ t10 = { opacity: t9 };
496
+ $[11] = t9;
497
+ $[12] = t10;
195
498
  } else {
196
- t10 = $[34];
499
+ t10 = $[12];
197
500
  }
198
501
  let t11;
199
- if ($[35] !== contextValue || $[36] !== t10) {
200
- t11 = /* @__PURE__ */ _jsx(SidebarContext.Provider, {
201
- value: contextValue,
202
- children: t10
502
+ if ($[13] !== setOpenMobile) {
503
+ t11 = () => setOpenMobile(false);
504
+ $[13] = setOpenMobile;
505
+ $[14] = t11;
506
+ } else {
507
+ t11 = $[14];
508
+ }
509
+ const t12 = openMobile ? "pointer-events-auto" : "pointer-events-none";
510
+ let t13;
511
+ if ($[15] !== t12) {
512
+ t13 = cn("fixed inset-0 bg-black/40", t12);
513
+ $[15] = t12;
514
+ $[16] = t13;
515
+ } else {
516
+ t13 = $[16];
517
+ }
518
+ let t14;
519
+ if ($[17] !== t10 || $[18] !== t11 || $[19] !== t13 || $[20] !== t8 || $[21] !== transition) {
520
+ t14 = /* @__PURE__ */ _jsx(motion.button, {
521
+ type: "button",
522
+ "aria-label": "Close sidebar",
523
+ "data-slot": "sidebar-overlay",
524
+ tabIndex: t8,
525
+ initial: false,
526
+ animate: t10,
527
+ transition,
528
+ onClick: t11,
529
+ className: t13
203
530
  });
204
- $[35] = contextValue;
205
- $[36] = t10;
206
- $[37] = t11;
531
+ $[17] = t10;
532
+ $[18] = t11;
533
+ $[19] = t13;
534
+ $[20] = t8;
535
+ $[21] = transition;
536
+ $[22] = t14;
537
+ } else {
538
+ t14 = $[22];
539
+ }
540
+ const t15 = !openMobile;
541
+ const t16 = !openMobile;
542
+ const t17 = openMobile ? "expanded" : "collapsed";
543
+ const t18 = reduce ? openMobile ? 1 : 0 : 1;
544
+ const t19 = reduce ? 0 : openMobile ? "0%" : closedOffset;
545
+ let t20;
546
+ if ($[23] !== t18 || $[24] !== t19) {
547
+ t20 = {
548
+ opacity: t18,
549
+ x: t19
550
+ };
551
+ $[23] = t18;
552
+ $[24] = t19;
553
+ $[25] = t20;
207
554
  } else {
208
- t11 = $[37];
555
+ t20 = $[25];
209
556
  }
210
- return t11;
211
- }
212
- function _temp2(open_1) {
213
- return !open_1;
214
- }
215
- function _temp(open_0) {
216
- return !open_0;
557
+ let t21;
558
+ if ($[26] === Symbol.for("react.memo_cache_sentinel")) {
559
+ t21 = () => {
560
+ if (!openMobileRef.current) {
561
+ setHidden(true);
562
+ }
563
+ };
564
+ $[26] = t21;
565
+ } else {
566
+ t21 = $[26];
567
+ }
568
+ let t22;
569
+ if ($[27] !== mobileWidth) {
570
+ t22 = { "--sidebar-width-mobile": mobileWidth };
571
+ $[27] = mobileWidth;
572
+ $[28] = t22;
573
+ } else {
574
+ t22 = $[28];
575
+ }
576
+ const t23 = t22;
577
+ const t24 = side === "left" ? "left-0 border-r" : "right-0 border-l";
578
+ const t25 = !openMobile && "pointer-events-none";
579
+ let t26;
580
+ if ($[29] !== className || $[30] !== t24 || $[31] !== t25) {
581
+ t26 = cn("pointer-events-auto fixed inset-y-0 flex h-dvh w-(--sidebar-width-mobile) max-w-[88vw] flex-col overflow-hidden outline-none", "border-sidebar-border bg-sidebar text-sidebar-foreground shadow-2xl will-change-transform", t24, t25, className);
582
+ $[29] = className;
583
+ $[30] = t24;
584
+ $[31] = t25;
585
+ $[32] = t26;
586
+ } else {
587
+ t26 = $[32];
588
+ }
589
+ let t27;
590
+ if ($[33] !== side) {
591
+ t27 = {
592
+ collapsed: false,
593
+ collapsible: "none",
594
+ side
595
+ };
596
+ $[33] = side;
597
+ $[34] = t27;
598
+ } else {
599
+ t27 = $[34];
600
+ }
601
+ let t28;
602
+ if ($[35] !== children || $[36] !== t27) {
603
+ t28 = /* @__PURE__ */ _jsx(SidebarPanelContext.Provider, {
604
+ value: t27,
605
+ children
606
+ });
607
+ $[35] = children;
608
+ $[36] = t27;
609
+ $[37] = t28;
610
+ } else {
611
+ t28 = $[37];
612
+ }
613
+ let t29;
614
+ if ($[38] !== ariaLabel || $[39] !== side || $[40] !== t15 || $[41] !== t16 || $[42] !== t17 || $[43] !== t20 || $[44] !== t23 || $[45] !== t26 || $[46] !== t28 || $[47] !== transition || $[48] !== trapFocus) {
615
+ t29 = /* @__PURE__ */ _jsx(motion.div, {
616
+ ref: panelRef,
617
+ role: "dialog",
618
+ "aria-modal": "true",
619
+ "aria-label": ariaLabel,
620
+ "aria-hidden": t15,
621
+ inert: t16,
622
+ tabIndex: -1,
623
+ "data-slot": "sidebar",
624
+ "data-mobile": "true",
625
+ "data-state": t17,
626
+ "data-side": side,
627
+ initial: false,
628
+ animate: t20,
629
+ transition,
630
+ onAnimationComplete: t21,
631
+ onKeyDown: trapFocus,
632
+ style: t23,
633
+ className: t26,
634
+ children: t28
635
+ });
636
+ $[38] = ariaLabel;
637
+ $[39] = side;
638
+ $[40] = t15;
639
+ $[41] = t16;
640
+ $[42] = t17;
641
+ $[43] = t20;
642
+ $[44] = t23;
643
+ $[45] = t26;
644
+ $[46] = t28;
645
+ $[47] = transition;
646
+ $[48] = trapFocus;
647
+ $[49] = t29;
648
+ } else {
649
+ t29 = $[49];
650
+ }
651
+ let t30;
652
+ if ($[50] !== t14 || $[51] !== t29 || $[52] !== t7) {
653
+ t30 = createPortal(/* @__PURE__ */ _jsxs("div", {
654
+ className: t7,
655
+ children: [t14, t29]
656
+ }), document.body);
657
+ $[50] = t14;
658
+ $[51] = t29;
659
+ $[52] = t7;
660
+ $[53] = t30;
661
+ } else {
662
+ t30 = $[53];
663
+ }
664
+ return t30;
217
665
  }
666
+ /**
667
+ * Renders the sidebar: a width-morphing rail on desktop and a sheet on small screens.
668
+ * @param props - Side, variant, collapse mode, accessible name and panel classes.
669
+ * @returns The desktop rail, the mobile sheet portal, or an always-expanded panel.
670
+ */
218
671
  function Sidebar(t0) {
219
- const $ = _c(48);
672
+ const $ = _c(55);
220
673
  let children;
221
674
  let className;
222
- let dir;
675
+ let panelClassName;
223
676
  let props;
677
+ let style;
224
678
  let t1;
225
679
  let t2;
226
680
  let t3;
681
+ let t4;
227
682
  if ($[0] !== t0) {
228
- ({side: t1, variant: t2, collapsible: t3, className, children, dir, ...props} = t0);
683
+ ({side: t1, variant: t2, collapsible: t3, ariaLabel: t4, children, className, panelClassName, style, ...props} = t0);
229
684
  $[0] = t0;
230
685
  $[1] = children;
231
686
  $[2] = className;
232
- $[3] = dir;
687
+ $[3] = panelClassName;
233
688
  $[4] = props;
234
- $[5] = t1;
235
- $[6] = t2;
236
- $[7] = t3;
689
+ $[5] = style;
690
+ $[6] = t1;
691
+ $[7] = t2;
692
+ $[8] = t3;
693
+ $[9] = t4;
237
694
  } else {
238
695
  children = $[1];
239
696
  className = $[2];
240
- dir = $[3];
697
+ panelClassName = $[3];
241
698
  props = $[4];
242
- t1 = $[5];
243
- t2 = $[6];
244
- t3 = $[7];
699
+ style = $[5];
700
+ t1 = $[6];
701
+ t2 = $[7];
702
+ t3 = $[8];
703
+ t4 = $[9];
245
704
  }
246
705
  const side = t1 === undefined ? "left" : t1;
247
706
  const variant = t2 === undefined ? "sidebar" : t2;
248
- const collapsible = t3 === undefined ? "offcanvas" : t3;
249
- const { isMobile, state, openMobile, setOpenMobile } = useSidebar();
250
- if (collapsible === "none") {
251
- let t4;
252
- if ($[8] !== className) {
253
- t4 = cn("flex h-full w-(--sidebar-width) flex-col bg-sidebar text-sidebar-foreground", className);
254
- $[8] = className;
255
- $[9] = t4;
256
- } else {
257
- t4 = $[9];
258
- }
707
+ const collapsible = t3 === undefined ? "icon" : t3;
708
+ const ariaLabel = t4 === undefined ? "Sidebar" : t4;
709
+ const context = useSidebar();
710
+ const collapsed = collapsible !== "none" && !context.open;
711
+ const offcanvas = collapsed && collapsible === "offcanvas";
712
+ const width = offcanvas ? "0px" : collapsed ? "var(--sidebar-width-icon)" : "var(--sidebar-width)";
713
+ if (context.isMobile && collapsible !== "none") {
259
714
  let t5;
260
- if ($[10] !== children || $[11] !== props || $[12] !== t4) {
261
- t5 = /* @__PURE__ */ _jsx("div", {
262
- "data-slot": "sidebar",
263
- className: t4,
264
- ...props,
715
+ if ($[10] !== ariaLabel || $[11] !== children || $[12] !== className || $[13] !== side) {
716
+ t5 = /* @__PURE__ */ _jsx(MobileSidebar, {
717
+ ariaLabel,
718
+ className,
719
+ side,
265
720
  children
266
721
  });
267
- $[10] = children;
268
- $[11] = props;
269
- $[12] = t4;
270
- $[13] = t5;
722
+ $[10] = ariaLabel;
723
+ $[11] = children;
724
+ $[12] = className;
725
+ $[13] = side;
726
+ $[14] = t5;
271
727
  } else {
272
- t5 = $[13];
728
+ t5 = $[14];
273
729
  }
274
730
  return t5;
275
731
  }
276
- if (isMobile) {
277
- let t4;
278
- if ($[14] === Symbol.for("react.memo_cache_sentinel")) {
279
- t4 = { "--sidebar-width": SIDEBAR_WIDTH_MOBILE };
280
- $[14] = t4;
281
- } else {
282
- t4 = $[14];
283
- }
284
- let t5;
285
- if ($[15] === Symbol.for("react.memo_cache_sentinel")) {
286
- t5 = /* @__PURE__ */ _jsxs(SheetHeader, {
287
- className: "sr-only",
288
- children: [/* @__PURE__ */ _jsx(SheetTitle, { children: "Sidebar" }), /* @__PURE__ */ _jsx(SheetDescription, { children: "Displays the mobile sidebar." })]
289
- });
290
- $[15] = t5;
291
- } else {
292
- t5 = $[15];
293
- }
294
- let t6;
295
- if ($[16] !== children) {
296
- t6 = /* @__PURE__ */ _jsx("div", {
297
- className: "flex h-full w-full flex-col",
298
- children
299
- });
300
- $[16] = children;
301
- $[17] = t6;
302
- } else {
303
- t6 = $[17];
304
- }
305
- let t7;
306
- if ($[18] !== dir || $[19] !== side || $[20] !== t6) {
307
- t7 = /* @__PURE__ */ _jsxs(SheetContent, {
308
- dir,
309
- "data-sidebar": "sidebar",
310
- "data-slot": "sidebar",
311
- "data-mobile": "true",
312
- className: "w-(--sidebar-width) bg-sidebar p-0 text-sidebar-foreground [&>button]:hidden",
313
- style: t4,
314
- side,
315
- children: [t5, t6]
316
- });
317
- $[18] = dir;
318
- $[19] = side;
319
- $[20] = t6;
320
- $[21] = t7;
321
- } else {
322
- t7 = $[21];
323
- }
324
- let t8;
325
- if ($[22] !== openMobile || $[23] !== props || $[24] !== setOpenMobile || $[25] !== t7) {
326
- t8 = /* @__PURE__ */ _jsx(Sheet, {
327
- open: openMobile,
328
- onOpenChange: setOpenMobile,
329
- ...props,
330
- children: t7
331
- });
332
- $[22] = openMobile;
333
- $[23] = props;
334
- $[24] = setOpenMobile;
335
- $[25] = t7;
336
- $[26] = t8;
337
- } else {
338
- t8 = $[26];
339
- }
340
- return t8;
341
- }
342
- const t4 = state === "collapsed" ? collapsible : "";
343
- const t5 = variant === "floating" || variant === "inset" ? "group-data-[collapsible=icon]:w-[calc(var(--sidebar-width-icon)+(--spacing(4)))]" : "group-data-[collapsible=icon]:w-(--sidebar-width-icon)";
732
+ const t5 = collapsed ? "collapsed" : "expanded";
344
733
  let t6;
345
- if ($[27] !== t5) {
346
- t6 = cn("relative w-(--sidebar-width) bg-transparent transition-[width] duration-300 ease-(--sidebar-ease)", "group-data-[collapsible=offcanvas]:w-0", "group-data-[side=right]:rotate-180", t5);
347
- $[27] = t5;
348
- $[28] = t6;
349
- } else {
350
- t6 = $[28];
351
- }
352
- let t7;
353
- if ($[29] !== t6) {
354
- t7 = /* @__PURE__ */ _jsx("div", {
355
- "data-slot": "sidebar-gap",
356
- className: t6
357
- });
358
- $[29] = t6;
359
- $[30] = t7;
734
+ if ($[15] !== width) {
735
+ t6 = { width };
736
+ $[15] = width;
737
+ $[16] = t6;
360
738
  } else {
361
- t7 = $[30];
739
+ t6 = $[16];
362
740
  }
363
- const t8 = variant === "floating" || variant === "inset" ? "p-2 group-data-[collapsible=icon]:w-[calc(var(--sidebar-width-icon)+(--spacing(4))+2px)]" : "group-data-[collapsible=icon]:w-(--sidebar-width-icon) group-data-[side=left]:border-r group-data-[side=right]:border-l";
364
- let t9;
365
- if ($[31] !== className || $[32] !== t8) {
366
- t9 = cn("fixed inset-y-0 z-10 hidden h-svh w-(--sidebar-width) transition-[left,right,width] duration-300 ease-(--sidebar-ease) data-[side=left]:left-0 data-[side=left]:group-data-[collapsible=offcanvas]:left-[calc(var(--sidebar-width)*-1)] data-[side=right]:right-0 data-[side=right]:group-data-[collapsible=offcanvas]:right-[calc(var(--sidebar-width)*-1)] md:flex", t8, className);
367
- $[31] = className;
368
- $[32] = t8;
369
- $[33] = t9;
741
+ const t7 = context.reduce ? INSTANT_TRANSITION : SIDEBAR_MORPH_TRANSITION;
742
+ const t8 = collapsible === "none" ? "block" : "hidden md:block";
743
+ const t9 = side === "right" && "order-last";
744
+ let t10;
745
+ if ($[17] !== className || $[18] !== t8 || $[19] !== t9) {
746
+ t10 = cn("group/sidebar peer relative h-auto shrink-0 text-sidebar-foreground will-change-[width]", t8, t9, className);
747
+ $[17] = className;
748
+ $[18] = t8;
749
+ $[19] = t9;
750
+ $[20] = t10;
751
+ } else {
752
+ t10 = $[20];
753
+ }
754
+ const t11 = offcanvas ? 0 : 1;
755
+ const t12 = offcanvas ? side === "left" ? "-100%" : "100%" : "0%";
756
+ let t13;
757
+ if ($[21] !== t11 || $[22] !== t12) {
758
+ t13 = {
759
+ opacity: t11,
760
+ x: t12
761
+ };
762
+ $[21] = t11;
763
+ $[22] = t12;
764
+ $[23] = t13;
765
+ } else {
766
+ t13 = $[23];
767
+ }
768
+ const t14 = context.reduce ? REDUCED_TRANSITION : PANEL_TRANSITION;
769
+ const t15 = collapsible === "offcanvas" && "w-(--sidebar-width)";
770
+ const t16 = collapsible === "none" && "h-auto";
771
+ const t17 = variant === "sidebar" && (side === "left" ? "border-r border-sidebar-border" : "border-l border-sidebar-border");
772
+ const t18 = variant === "floating" && "m-2 h-[calc(100svh-1rem)] rounded-2xl border border-sidebar-border shadow-sm";
773
+ const t19 = variant === "inset" && "m-2 h-[calc(100svh-1rem)] rounded-2xl";
774
+ let t20;
775
+ if ($[24] !== panelClassName || $[25] !== t15 || $[26] !== t16 || $[27] !== t17 || $[28] !== t18 || $[29] !== t19) {
776
+ t20 = cn("sticky top-0 flex h-svh w-full flex-col overflow-hidden bg-sidebar", t15, t16, t17, t18, t19, panelClassName);
777
+ $[24] = panelClassName;
778
+ $[25] = t15;
779
+ $[26] = t16;
780
+ $[27] = t17;
781
+ $[28] = t18;
782
+ $[29] = t19;
783
+ $[30] = t20;
784
+ } else {
785
+ t20 = $[30];
786
+ }
787
+ let t21;
788
+ if ($[31] !== collapsed || $[32] !== collapsible || $[33] !== side) {
789
+ t21 = {
790
+ collapsed,
791
+ collapsible,
792
+ side
793
+ };
794
+ $[31] = collapsed;
795
+ $[32] = collapsible;
796
+ $[33] = side;
797
+ $[34] = t21;
370
798
  } else {
371
- t9 = $[33];
799
+ t21 = $[34];
372
800
  }
373
- let t10;
374
- if ($[34] !== children) {
375
- t10 = /* @__PURE__ */ _jsx("div", {
376
- "data-sidebar": "sidebar",
377
- "data-slot": "sidebar-inner",
378
- className: "flex size-full flex-col bg-sidebar group-data-[variant=floating]:rounded-lg group-data-[variant=floating]:shadow-sm group-data-[variant=floating]:ring-1 group-data-[variant=floating]:ring-sidebar-border",
801
+ let t22;
802
+ if ($[35] !== children || $[36] !== t21) {
803
+ t22 = /* @__PURE__ */ _jsx(SidebarPanelContext.Provider, {
804
+ value: t21,
379
805
  children
380
806
  });
381
- $[34] = children;
382
- $[35] = t10;
383
- } else {
384
- t10 = $[35];
385
- }
386
- let t11;
387
- if ($[36] !== props || $[37] !== side || $[38] !== t10 || $[39] !== t9) {
388
- t11 = /* @__PURE__ */ _jsx("div", {
389
- "data-slot": "sidebar-container",
390
- "data-side": side,
391
- className: t9,
392
- ...props,
393
- children: t10
807
+ $[35] = children;
808
+ $[36] = t21;
809
+ $[37] = t22;
810
+ } else {
811
+ t22 = $[37];
812
+ }
813
+ let t23;
814
+ if ($[38] !== t13 || $[39] !== t14 || $[40] !== t20 || $[41] !== t22) {
815
+ t23 = /* @__PURE__ */ _jsx(motion.div, {
816
+ initial: false,
817
+ animate: t13,
818
+ transition: t14,
819
+ "data-slot": "sidebar-inner",
820
+ className: t20,
821
+ children: t22
394
822
  });
395
- $[36] = props;
396
- $[37] = side;
397
- $[38] = t10;
398
- $[39] = t9;
399
- $[40] = t11;
823
+ $[38] = t13;
824
+ $[39] = t14;
825
+ $[40] = t20;
826
+ $[41] = t22;
827
+ $[42] = t23;
400
828
  } else {
401
- t11 = $[40];
829
+ t23 = $[42];
402
830
  }
403
- let t12;
404
- if ($[41] !== side || $[42] !== state || $[43] !== t11 || $[44] !== t4 || $[45] !== t7 || $[46] !== variant) {
405
- t12 = /* @__PURE__ */ _jsxs("div", {
406
- className: "group peer hidden text-sidebar-foreground md:block",
407
- "data-state": state,
408
- "data-collapsible": t4,
831
+ let t24;
832
+ if ($[43] !== ariaLabel || $[44] !== collapsible || $[45] !== props || $[46] !== side || $[47] !== style || $[48] !== t10 || $[49] !== t23 || $[50] !== t5 || $[51] !== t6 || $[52] !== t7 || $[53] !== variant) {
833
+ t24 = /* @__PURE__ */ _jsx(motion.aside, {
834
+ ...props,
835
+ initial: false,
836
+ "aria-label": ariaLabel,
837
+ "data-slot": "sidebar",
838
+ "data-state": t5,
839
+ "data-collapsible": collapsible,
409
840
  "data-variant": variant,
410
841
  "data-side": side,
411
- "data-slot": "sidebar",
412
- children: [t7, t11]
842
+ animate: t6,
843
+ transition: t7,
844
+ style,
845
+ className: t10,
846
+ children: t23
413
847
  });
414
- $[41] = side;
415
- $[42] = state;
416
- $[43] = t11;
417
- $[44] = t4;
418
- $[45] = t7;
419
- $[46] = variant;
420
- $[47] = t12;
421
- } else {
422
- t12 = $[47];
423
- }
424
- return t12;
848
+ $[43] = ariaLabel;
849
+ $[44] = collapsible;
850
+ $[45] = props;
851
+ $[46] = side;
852
+ $[47] = style;
853
+ $[48] = t10;
854
+ $[49] = t23;
855
+ $[50] = t5;
856
+ $[51] = t6;
857
+ $[52] = t7;
858
+ $[53] = variant;
859
+ $[54] = t24;
860
+ } else {
861
+ t24 = $[54];
862
+ }
863
+ return t24;
864
+ }
865
+ /**
866
+ * Button that toggles the desktop rail or the mobile sheet; shows a panel icon unless given children.
867
+ * @param props - Native button attributes.
868
+ * @returns The toggle button.
869
+ */
870
+ function SidebarTrigger({ children, className, onClick, ref, type = "button", ...props }) {
871
+ const context = useSidebar();
872
+ const expanded = context.isMobile ? context.openMobile : context.open;
873
+ return /* @__PURE__ */ _jsx("button", {
874
+ ...props,
875
+ ref: (node) => {
876
+ context.triggerRef.current = node;
877
+ if (typeof ref === "function") return ref(node);
878
+ if (ref) ref.current = node;
879
+ },
880
+ type,
881
+ "aria-label": props["aria-label"] ?? "Toggle sidebar",
882
+ "aria-expanded": expanded,
883
+ "data-slot": "sidebar-trigger",
884
+ "data-state": expanded ? "expanded" : "collapsed",
885
+ onClick: (event) => {
886
+ onClick?.(event);
887
+ if (!event.defaultPrevented) context.toggleSidebar();
888
+ },
889
+ className: cn("inline-flex size-10 shrink-0 items-center justify-center rounded-xl outline-none [&_svg]:size-4", "focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background", className),
890
+ children: children ?? /* @__PURE__ */ _jsx(PanelLeftIcon, { "aria-hidden": "true" })
891
+ });
425
892
  }
426
- function SidebarTrigger(t0) {
427
- const $ = _c(15);
893
+ /**
894
+ * Button that closes the sidebar on the current viewport.
895
+ * @param props - Native button attributes; the content is the consumer's icon or text.
896
+ * @returns The close button.
897
+ */
898
+ function SidebarClose(t0) {
899
+ const $ = _c(16);
428
900
  let className;
429
901
  let onClick;
430
902
  let props;
903
+ let t1;
431
904
  if ($[0] !== t0) {
432
- ({className, onClick, ...props} = t0);
905
+ ({className, onClick, type: t1, ...props} = t0);
433
906
  $[0] = t0;
434
907
  $[1] = className;
435
908
  $[2] = onClick;
436
909
  $[3] = props;
910
+ $[4] = t1;
437
911
  } else {
438
912
  className = $[1];
439
913
  onClick = $[2];
440
914
  props = $[3];
915
+ t1 = $[4];
441
916
  }
442
- const { toggleSidebar } = useSidebar();
443
- let t1;
444
- if ($[4] !== className) {
445
- t1 = cn(className);
446
- $[4] = className;
447
- $[5] = t1;
448
- } else {
449
- t1 = $[5];
450
- }
451
- let t2;
452
- if ($[6] !== onClick || $[7] !== toggleSidebar) {
453
- t2 = (event) => {
917
+ const type = t1 === undefined ? "button" : t1;
918
+ const context = useSidebar();
919
+ const t2 = props["aria-label"] ?? "Close sidebar";
920
+ let t3;
921
+ if ($[5] !== context || $[6] !== onClick) {
922
+ t3 = (event) => {
454
923
  onClick?.(event);
455
- toggleSidebar();
924
+ if (event.defaultPrevented) {
925
+ return;
926
+ }
927
+ if (context.isMobile) {
928
+ context.setOpenMobile(false);
929
+ } else {
930
+ context.setOpen(false);
931
+ }
456
932
  };
933
+ $[5] = context;
457
934
  $[6] = onClick;
458
- $[7] = toggleSidebar;
459
- $[8] = t2;
935
+ $[7] = t3;
460
936
  } else {
461
- t2 = $[8];
937
+ t3 = $[7];
462
938
  }
463
- let t3;
464
939
  let t4;
465
- if ($[9] === Symbol.for("react.memo_cache_sentinel")) {
466
- t3 = /* @__PURE__ */ _jsx(PanelLeftIcon, {});
467
- t4 = /* @__PURE__ */ _jsx("span", {
468
- className: "sr-only",
469
- children: "Toggle Sidebar"
470
- });
471
- $[9] = t3;
472
- $[10] = t4;
940
+ if ($[8] !== className) {
941
+ t4 = cn("inline-flex size-10 shrink-0 items-center justify-center rounded-xl outline-none", "focus-visible:ring-2 focus-visible:ring-ring", className);
942
+ $[8] = className;
943
+ $[9] = t4;
473
944
  } else {
474
- t3 = $[9];
475
- t4 = $[10];
945
+ t4 = $[9];
476
946
  }
477
947
  let t5;
478
- if ($[11] !== props || $[12] !== t1 || $[13] !== t2) {
479
- t5 = /* @__PURE__ */ _jsxs(Button, {
480
- "data-sidebar": "trigger",
481
- "data-slot": "sidebar-trigger",
482
- variant: "ghost",
483
- size: "icon-sm",
484
- className: t1,
485
- onClick: t2,
948
+ if ($[10] !== props || $[11] !== t2 || $[12] !== t3 || $[13] !== t4 || $[14] !== type) {
949
+ t5 = /* @__PURE__ */ _jsx("button", {
486
950
  ...props,
487
- children: [t3, t4]
951
+ type,
952
+ "aria-label": t2,
953
+ "data-slot": "sidebar-close",
954
+ onClick: t3,
955
+ className: t4
488
956
  });
489
- $[11] = props;
490
- $[12] = t1;
491
- $[13] = t2;
492
- $[14] = t5;
957
+ $[10] = props;
958
+ $[11] = t2;
959
+ $[12] = t3;
960
+ $[13] = t4;
961
+ $[14] = type;
962
+ $[15] = t5;
493
963
  } else {
494
- t5 = $[14];
964
+ t5 = $[15];
495
965
  }
496
966
  return t5;
497
967
  }
968
+ /**
969
+ * Thin hit area on the sidebar edge that toggles it with the pointer.
970
+ * @param props - Native button attributes.
971
+ * @returns The rail button, outside the tab order.
972
+ */
498
973
  function SidebarRail(t0) {
499
- const $ = _c(9);
974
+ const $ = _c(17);
500
975
  let className;
976
+ let onClick;
501
977
  let props;
978
+ let t1;
502
979
  if ($[0] !== t0) {
503
- ({className, ...props} = t0);
980
+ ({className, onClick, type: t1, ...props} = t0);
504
981
  $[0] = t0;
505
982
  $[1] = className;
506
- $[2] = props;
983
+ $[2] = onClick;
984
+ $[3] = props;
985
+ $[4] = t1;
507
986
  } else {
508
987
  className = $[1];
509
- props = $[2];
988
+ onClick = $[2];
989
+ props = $[3];
990
+ t1 = $[4];
510
991
  }
511
- const { toggleSidebar } = useSidebar();
512
- let t1;
513
- if ($[3] !== className) {
514
- t1 = cn("absolute inset-y-0 z-20 hidden w-4 transition-all duration-300 ease-(--sidebar-ease) group-data-[side=left]:-right-4 group-data-[side=right]:left-0 after:absolute after:inset-y-0 after:start-1/2 after:w-[2px] hover:after:bg-sidebar-border sm:flex ltr:-translate-x-1/2 rtl:-translate-x-1/2", "in-data-[side=left]:cursor-w-resize in-data-[side=right]:cursor-e-resize", "[[data-side=left][data-state=collapsed]_&]:cursor-e-resize [[data-side=right][data-state=collapsed]_&]:cursor-w-resize", "group-data-[collapsible=offcanvas]:translate-x-0 group-data-[collapsible=offcanvas]:after:left-full hover:group-data-[collapsible=offcanvas]:bg-sidebar", "[[data-side=left][data-collapsible=offcanvas]_&]:-right-2", "[[data-side=right][data-collapsible=offcanvas]_&]:-left-2", className);
515
- $[3] = className;
516
- $[4] = t1;
992
+ const type = t1 === undefined ? "button" : t1;
993
+ const context = useSidebar();
994
+ const panel = useSidebarPanel();
995
+ const t2 = panel.side;
996
+ const t3 = props["aria-label"] ?? "Toggle sidebar";
997
+ let t4;
998
+ if ($[5] !== context || $[6] !== onClick) {
999
+ t4 = (event) => {
1000
+ onClick?.(event);
1001
+ if (!event.defaultPrevented) {
1002
+ context.toggleSidebar();
1003
+ }
1004
+ };
1005
+ $[5] = context;
1006
+ $[6] = onClick;
1007
+ $[7] = t4;
517
1008
  } else {
518
- t1 = $[4];
1009
+ t4 = $[7];
519
1010
  }
520
- let t2;
521
- if ($[5] !== props || $[6] !== t1 || $[7] !== toggleSidebar) {
522
- t2 = /* @__PURE__ */ _jsx("button", {
523
- "data-sidebar": "rail",
1011
+ let t5;
1012
+ if ($[8] !== className) {
1013
+ t5 = cn("absolute inset-y-0 z-20 hidden w-4 -translate-x-1/2 outline-none md:block", "after:absolute after:inset-y-0 after:left-1/2 after:w-px after:bg-transparent after:transition-colors hover:after:bg-sidebar-border", "data-[side=left]:left-full data-[side=right]:right-0 data-[side=right]:translate-x-1/2", className);
1014
+ $[8] = className;
1015
+ $[9] = t5;
1016
+ } else {
1017
+ t5 = $[9];
1018
+ }
1019
+ let t6;
1020
+ if ($[10] !== panel.side || $[11] !== props || $[12] !== t3 || $[13] !== t4 || $[14] !== t5 || $[15] !== type) {
1021
+ t6 = /* @__PURE__ */ _jsx("button", {
1022
+ ...props,
1023
+ type,
524
1024
  "data-slot": "sidebar-rail",
525
- "aria-label": "Toggle Sidebar",
1025
+ "data-side": t2,
1026
+ "aria-label": t3,
1027
+ title: "Toggle sidebar",
526
1028
  tabIndex: -1,
527
- onClick: toggleSidebar,
528
- title: "Toggle Sidebar",
529
- className: t1,
530
- ...props
1029
+ onClick: t4,
1030
+ className: t5
531
1031
  });
532
- $[5] = props;
533
- $[6] = t1;
534
- $[7] = toggleSidebar;
535
- $[8] = t2;
1032
+ $[10] = panel.side;
1033
+ $[11] = props;
1034
+ $[12] = t3;
1035
+ $[13] = t4;
1036
+ $[14] = t5;
1037
+ $[15] = type;
1038
+ $[16] = t6;
536
1039
  } else {
537
- t2 = $[8];
1040
+ t6 = $[16];
538
1041
  }
539
- return t2;
1042
+ return t6;
540
1043
  }
1044
+ /**
1045
+ * Main content area laid out next to the sidebar.
1046
+ * @param props - Motion-enabled `main` attributes.
1047
+ * @returns The content landmark.
1048
+ */
541
1049
  function SidebarInset(t0) {
542
1050
  const $ = _c(8);
543
1051
  let className;
@@ -553,7 +1061,7 @@ function SidebarInset(t0) {
553
1061
  }
554
1062
  let t1;
555
1063
  if ($[3] !== className) {
556
- t1 = cn("relative flex w-full flex-1 flex-col bg-background md:peer-data-[variant=inset]:m-2 md:peer-data-[variant=inset]:ml-0 md:peer-data-[variant=inset]:rounded-xl md:peer-data-[variant=inset]:shadow-sm md:peer-data-[variant=inset]:peer-data-[state=collapsed]:ml-2", className);
1064
+ t1 = cn("relative flex min-h-svh min-w-0 flex-1 flex-col bg-background", "md:peer-data-[variant=inset]:m-2 md:peer-data-[variant=inset]:ml-0 md:peer-data-[variant=inset]:rounded-2xl md:peer-data-[variant=inset]:shadow-sm", className);
557
1065
  $[3] = className;
558
1066
  $[4] = t1;
559
1067
  } else {
@@ -561,10 +1069,10 @@ function SidebarInset(t0) {
561
1069
  }
562
1070
  let t2;
563
1071
  if ($[5] !== props || $[6] !== t1) {
564
- t2 = /* @__PURE__ */ _jsx("main", {
1072
+ t2 = /* @__PURE__ */ _jsx(motion.main, {
1073
+ ...props,
565
1074
  "data-slot": "sidebar-inset",
566
- className: t1,
567
- ...props
1075
+ className: t1
568
1076
  });
569
1077
  $[5] = props;
570
1078
  $[6] = t1;
@@ -574,7 +1082,7 @@ function SidebarInset(t0) {
574
1082
  }
575
1083
  return t2;
576
1084
  }
577
- function SidebarInput(t0) {
1085
+ function SidebarHeader(t0) {
578
1086
  const $ = _c(8);
579
1087
  let className;
580
1088
  let props;
@@ -589,7 +1097,7 @@ function SidebarInput(t0) {
589
1097
  }
590
1098
  let t1;
591
1099
  if ($[3] !== className) {
592
- t1 = cn("h-8 w-full bg-background shadow-none", className);
1100
+ t1 = cn("flex shrink-0 flex-col gap-2 p-3", className);
593
1101
  $[3] = className;
594
1102
  $[4] = t1;
595
1103
  } else {
@@ -597,11 +1105,10 @@ function SidebarInput(t0) {
597
1105
  }
598
1106
  let t2;
599
1107
  if ($[5] !== props || $[6] !== t1) {
600
- t2 = /* @__PURE__ */ _jsx(Input, {
601
- "data-slot": "sidebar-input",
602
- "data-sidebar": "input",
603
- className: t1,
604
- ...props
1108
+ t2 = /* @__PURE__ */ _jsx("div", {
1109
+ ...props,
1110
+ "data-slot": "sidebar-header",
1111
+ className: t1
605
1112
  });
606
1113
  $[5] = props;
607
1114
  $[6] = t1;
@@ -611,7 +1118,7 @@ function SidebarInput(t0) {
611
1118
  }
612
1119
  return t2;
613
1120
  }
614
- function SidebarHeader(t0) {
1121
+ function SidebarContent(t0) {
615
1122
  const $ = _c(8);
616
1123
  let className;
617
1124
  let props;
@@ -626,7 +1133,7 @@ function SidebarHeader(t0) {
626
1133
  }
627
1134
  let t1;
628
1135
  if ($[3] !== className) {
629
- t1 = cn("flex flex-col gap-2 p-2", className);
1136
+ t1 = cn("flex min-h-0 flex-1 flex-col gap-2 overflow-x-hidden overflow-y-auto overscroll-contain px-2 py-2", className);
630
1137
  $[3] = className;
631
1138
  $[4] = t1;
632
1139
  } else {
@@ -635,10 +1142,9 @@ function SidebarHeader(t0) {
635
1142
  let t2;
636
1143
  if ($[5] !== props || $[6] !== t1) {
637
1144
  t2 = /* @__PURE__ */ _jsx("div", {
638
- "data-slot": "sidebar-header",
639
- "data-sidebar": "header",
640
- className: t1,
641
- ...props
1145
+ ...props,
1146
+ "data-slot": "sidebar-content",
1147
+ className: t1
642
1148
  });
643
1149
  $[5] = props;
644
1150
  $[6] = t1;
@@ -663,7 +1169,7 @@ function SidebarFooter(t0) {
663
1169
  }
664
1170
  let t1;
665
1171
  if ($[3] !== className) {
666
- t1 = cn("flex flex-col gap-2 p-2", className);
1172
+ t1 = cn("flex shrink-0 flex-col gap-2 border-t border-sidebar-border p-3 pb-[max(0.75rem,env(safe-area-inset-bottom))]", className);
667
1173
  $[3] = className;
668
1174
  $[4] = t1;
669
1175
  } else {
@@ -672,10 +1178,9 @@ function SidebarFooter(t0) {
672
1178
  let t2;
673
1179
  if ($[5] !== props || $[6] !== t1) {
674
1180
  t2 = /* @__PURE__ */ _jsx("div", {
1181
+ ...props,
675
1182
  "data-slot": "sidebar-footer",
676
- "data-sidebar": "footer",
677
- className: t1,
678
- ...props
1183
+ className: t1
679
1184
  });
680
1185
  $[5] = props;
681
1186
  $[6] = t1;
@@ -685,79 +1190,143 @@ function SidebarFooter(t0) {
685
1190
  }
686
1191
  return t2;
687
1192
  }
688
- function SidebarSeparator(t0) {
689
- const $ = _c(8);
690
- let className;
1193
+ /**
1194
+ * Product text that only makes sense in the expanded sidebar, such as a workspace name or an empty
1195
+ * state: it leaves the layout while the panel is the icon rail and always shows in the mobile sheet.
1196
+ * @param props - Span attributes, or `asChild` to keep the child element.
1197
+ * @returns The content, or nothing in the icon rail.
1198
+ */
1199
+ function SidebarLabel(t0) {
1200
+ const $ = _c(6);
691
1201
  let props;
1202
+ let t1;
692
1203
  if ($[0] !== t0) {
693
- ({className, ...props} = t0);
1204
+ ({asChild: t1, ...props} = t0);
694
1205
  $[0] = t0;
695
- $[1] = className;
696
- $[2] = props;
1206
+ $[1] = props;
1207
+ $[2] = t1;
697
1208
  } else {
698
- className = $[1];
699
- props = $[2];
1209
+ props = $[1];
1210
+ t1 = $[2];
700
1211
  }
701
- let t1;
702
- if ($[3] !== className) {
703
- t1 = cn("mx-2 w-auto bg-sidebar-border", className);
704
- $[3] = className;
705
- $[4] = t1;
706
- } else {
707
- t1 = $[4];
1212
+ const asChild = t1 === undefined ? false : t1;
1213
+ const { collapsed } = useSidebarPanel();
1214
+ if (collapsed) {
1215
+ return null;
708
1216
  }
1217
+ const Component = asChild ? Slot.Root : "span";
709
1218
  let t2;
710
- if ($[5] !== props || $[6] !== t1) {
711
- t2 = /* @__PURE__ */ _jsx(Separator, {
712
- "data-slot": "sidebar-separator",
713
- "data-sidebar": "separator",
714
- className: t1,
1219
+ if ($[3] !== Component || $[4] !== props) {
1220
+ t2 = /* @__PURE__ */ _jsx(Component, {
1221
+ "data-slot": "sidebar-label",
715
1222
  ...props
716
1223
  });
717
- $[5] = props;
718
- $[6] = t1;
719
- $[7] = t2;
1224
+ $[3] = Component;
1225
+ $[4] = props;
1226
+ $[5] = t2;
720
1227
  } else {
721
- t2 = $[7];
1228
+ t2 = $[5];
722
1229
  }
723
1230
  return t2;
724
1231
  }
725
- function SidebarContent(t0) {
726
- const $ = _c(8);
1232
+ /**
1233
+ * Header row that identifies the workspace, often the trigger of a workspace switcher. It forwards
1234
+ * its props and ref to the `button`, so it works as `DropdownMenuTrigger asChild`, and keeps its tile
1235
+ * on the menu icon column while the label and trailing content leave in the icon rail.
1236
+ * @param props - Tile, label, trailing content and native button attributes.
1237
+ * @returns The brand button.
1238
+ */
1239
+ function SidebarBrandButton(t0) {
1240
+ const $ = _c(23);
1241
+ let children;
727
1242
  let className;
1243
+ let icon;
728
1244
  let props;
1245
+ let t1;
1246
+ let trailing;
729
1247
  if ($[0] !== t0) {
730
- ({className, ...props} = t0);
1248
+ ({icon, trailing, children, className, type: t1, ...props} = t0);
731
1249
  $[0] = t0;
732
- $[1] = className;
733
- $[2] = props;
1250
+ $[1] = children;
1251
+ $[2] = className;
1252
+ $[3] = icon;
1253
+ $[4] = props;
1254
+ $[5] = t1;
1255
+ $[6] = trailing;
734
1256
  } else {
735
- className = $[1];
736
- props = $[2];
1257
+ children = $[1];
1258
+ className = $[2];
1259
+ icon = $[3];
1260
+ props = $[4];
1261
+ t1 = $[5];
1262
+ trailing = $[6];
737
1263
  }
738
- let t1;
739
- if ($[3] !== className) {
740
- t1 = cn("no-scrollbar flex min-h-0 flex-1 flex-col gap-2 overflow-auto group-data-[collapsible=icon]:overflow-hidden", className);
741
- $[3] = className;
742
- $[4] = t1;
1264
+ const type = t1 === undefined ? "button" : t1;
1265
+ const { collapsed } = useSidebarPanel();
1266
+ const textLabel = typeof children === "string" ? children : undefined;
1267
+ const t2 = collapsed ? textLabel : undefined;
1268
+ const t3 = collapsed ? textLabel : undefined;
1269
+ let t4;
1270
+ if ($[7] !== className) {
1271
+ t4 = cn("flex min-h-10 w-full min-w-0 items-center gap-3 rounded-xl px-2 py-1.5 text-left text-sm font-semibold text-sidebar-foreground outline-none transition-colors", "hover:bg-sidebar-accent/70 focus-visible:bg-sidebar-accent/70 focus-visible:ring-2 focus-visible:ring-sidebar-ring data-[state=open]:bg-sidebar-accent/70", "disabled:cursor-not-allowed disabled:opacity-40", className);
1272
+ $[7] = className;
1273
+ $[8] = t4;
743
1274
  } else {
744
- t1 = $[4];
1275
+ t4 = $[8];
745
1276
  }
746
- let t2;
747
- if ($[5] !== props || $[6] !== t1) {
748
- t2 = /* @__PURE__ */ _jsx("div", {
749
- "data-slot": "sidebar-content",
750
- "data-sidebar": "content",
751
- className: t1,
752
- ...props
1277
+ let t5;
1278
+ if ($[9] !== icon) {
1279
+ t5 = /* @__PURE__ */ _jsx("span", {
1280
+ "aria-hidden": "true",
1281
+ "data-slot": "sidebar-brand-icon",
1282
+ className: "grid size-7 shrink-0 place-items-center overflow-hidden rounded-lg [&>img]:size-full [&>img]:object-cover",
1283
+ children: icon
753
1284
  });
754
- $[5] = props;
755
- $[6] = t1;
756
- $[7] = t2;
1285
+ $[9] = icon;
1286
+ $[10] = t5;
757
1287
  } else {
758
- t2 = $[7];
1288
+ t5 = $[10];
759
1289
  }
760
- return t2;
1290
+ let t6;
1291
+ if ($[11] !== children || $[12] !== collapsed || $[13] !== trailing) {
1292
+ t6 = collapsed ? null : /* @__PURE__ */ _jsxs(_Fragment, { children: [/* @__PURE__ */ _jsx("span", {
1293
+ className: "min-w-0 flex-1 truncate",
1294
+ children
1295
+ }), trailing ? /* @__PURE__ */ _jsx("span", {
1296
+ "aria-hidden": "true",
1297
+ className: "grid size-4 shrink-0 place-items-center text-sidebar-foreground/70 [&_svg]:size-3.5",
1298
+ children: trailing
1299
+ }) : null] });
1300
+ $[11] = children;
1301
+ $[12] = collapsed;
1302
+ $[13] = trailing;
1303
+ $[14] = t6;
1304
+ } else {
1305
+ t6 = $[14];
1306
+ }
1307
+ let t7;
1308
+ if ($[15] !== props || $[16] !== t2 || $[17] !== t3 || $[18] !== t4 || $[19] !== t5 || $[20] !== t6 || $[21] !== type) {
1309
+ t7 = /* @__PURE__ */ _jsxs("button", {
1310
+ "aria-label": t2,
1311
+ title: t3,
1312
+ ...props,
1313
+ type,
1314
+ "data-slot": "sidebar-brand-button",
1315
+ className: t4,
1316
+ children: [t5, t6]
1317
+ });
1318
+ $[15] = props;
1319
+ $[16] = t2;
1320
+ $[17] = t3;
1321
+ $[18] = t4;
1322
+ $[19] = t5;
1323
+ $[20] = t6;
1324
+ $[21] = type;
1325
+ $[22] = t7;
1326
+ } else {
1327
+ t7 = $[22];
1328
+ }
1329
+ return t7;
761
1330
  }
762
1331
  function SidebarGroup(t0) {
763
1332
  const $ = _c(8);
@@ -774,7 +1343,7 @@ function SidebarGroup(t0) {
774
1343
  }
775
1344
  let t1;
776
1345
  if ($[3] !== className) {
777
- t1 = cn("relative flex w-full min-w-0 flex-col p-2", className);
1346
+ t1 = cn("flex w-full min-w-0 flex-col px-1 py-1.5", className);
778
1347
  $[3] = className;
779
1348
  $[4] = t1;
780
1349
  } else {
@@ -783,10 +1352,9 @@ function SidebarGroup(t0) {
783
1352
  let t2;
784
1353
  if ($[5] !== props || $[6] !== t1) {
785
1354
  t2 = /* @__PURE__ */ _jsx("div", {
1355
+ ...props,
786
1356
  "data-slot": "sidebar-group",
787
- "data-sidebar": "group",
788
- className: t1,
789
- ...props
1357
+ className: t1
790
1358
  });
791
1359
  $[5] = props;
792
1360
  $[6] = t1;
@@ -796,84 +1364,40 @@ function SidebarGroup(t0) {
796
1364
  }
797
1365
  return t2;
798
1366
  }
1367
+ /** Section heading that fades out of the icon rail and is hidden from assistive technology there. */
799
1368
  function SidebarGroupLabel(t0) {
800
1369
  const $ = _c(10);
801
1370
  let className;
802
1371
  let props;
803
- let t1;
804
1372
  if ($[0] !== t0) {
805
- ({className, asChild: t1, ...props} = t0);
1373
+ ({className, ...props} = t0);
806
1374
  $[0] = t0;
807
1375
  $[1] = className;
808
1376
  $[2] = props;
809
- $[3] = t1;
810
1377
  } else {
811
1378
  className = $[1];
812
1379
  props = $[2];
813
- t1 = $[3];
814
1380
  }
815
- const asChild = t1 === undefined ? false : t1;
816
- const Comp = asChild ? Slot.Root : "div";
1381
+ const { collapsed } = useSidebarPanel();
1382
+ const t1 = collapsed ? "opacity-0" : "opacity-100";
817
1383
  let t2;
818
- if ($[4] !== className) {
819
- t2 = cn("flex h-8 shrink-0 items-center rounded-md px-2 text-xs font-medium text-sidebar-foreground/70 ring-sidebar-ring outline-hidden transition-[margin,opacity] duration-300 ease-(--sidebar-ease) group-data-[collapsible=icon]:-mt-8 group-data-[collapsible=icon]:opacity-0 focus-visible:ring-2 [&>svg]:size-4 [&>svg]:shrink-0", className);
820
- $[4] = className;
1384
+ if ($[3] !== className || $[4] !== t1) {
1385
+ t2 = cn("mb-1 h-7 overflow-hidden px-2 text-[10px] font-medium tracking-[0.14em] text-sidebar-foreground/70 uppercase transition-opacity", t1, className);
1386
+ $[3] = className;
1387
+ $[4] = t1;
821
1388
  $[5] = t2;
822
1389
  } else {
823
1390
  t2 = $[5];
824
1391
  }
825
1392
  let t3;
826
- if ($[6] !== Comp || $[7] !== props || $[8] !== t2) {
827
- t3 = /* @__PURE__ */ _jsx(Comp, {
1393
+ if ($[6] !== collapsed || $[7] !== props || $[8] !== t2) {
1394
+ t3 = /* @__PURE__ */ _jsx("div", {
1395
+ ...props,
1396
+ "aria-hidden": collapsed,
828
1397
  "data-slot": "sidebar-group-label",
829
- "data-sidebar": "group-label",
830
- className: t2,
831
- ...props
1398
+ className: t2
832
1399
  });
833
- $[6] = Comp;
834
- $[7] = props;
835
- $[8] = t2;
836
- $[9] = t3;
837
- } else {
838
- t3 = $[9];
839
- }
840
- return t3;
841
- }
842
- function SidebarGroupAction(t0) {
843
- const $ = _c(10);
844
- let className;
845
- let props;
846
- let t1;
847
- if ($[0] !== t0) {
848
- ({className, asChild: t1, ...props} = t0);
849
- $[0] = t0;
850
- $[1] = className;
851
- $[2] = props;
852
- $[3] = t1;
853
- } else {
854
- className = $[1];
855
- props = $[2];
856
- t1 = $[3];
857
- }
858
- const asChild = t1 === undefined ? false : t1;
859
- const Comp = asChild ? Slot.Root : "button";
860
- let t2;
861
- if ($[4] !== className) {
862
- t2 = cn("absolute top-3.5 right-3 flex aspect-square w-5 items-center justify-center rounded-md p-0 text-sidebar-foreground ring-sidebar-ring outline-hidden transition-transform group-data-[collapsible=icon]:hidden after:absolute after:-inset-2 hover:bg-sidebar-accent hover:text-sidebar-accent-foreground focus-visible:ring-2 md:after:hidden [&>svg]:size-4 [&>svg]:shrink-0", className);
863
- $[4] = className;
864
- $[5] = t2;
865
- } else {
866
- t2 = $[5];
867
- }
868
- let t3;
869
- if ($[6] !== Comp || $[7] !== props || $[8] !== t2) {
870
- t3 = /* @__PURE__ */ _jsx(Comp, {
871
- "data-slot": "sidebar-group-action",
872
- "data-sidebar": "group-action",
873
- className: t2,
874
- ...props
875
- });
876
- $[6] = Comp;
1400
+ $[6] = collapsed;
877
1401
  $[7] = props;
878
1402
  $[8] = t2;
879
1403
  $[9] = t3;
@@ -897,7 +1421,7 @@ function SidebarGroupContent(t0) {
897
1421
  }
898
1422
  let t1;
899
1423
  if ($[3] !== className) {
900
- t1 = cn("w-full text-sm", className);
1424
+ t1 = cn("w-full min-w-0", className);
901
1425
  $[3] = className;
902
1426
  $[4] = t1;
903
1427
  } else {
@@ -906,10 +1430,9 @@ function SidebarGroupContent(t0) {
906
1430
  let t2;
907
1431
  if ($[5] !== props || $[6] !== t1) {
908
1432
  t2 = /* @__PURE__ */ _jsx("div", {
1433
+ ...props,
909
1434
  "data-slot": "sidebar-group-content",
910
- "data-sidebar": "group-content",
911
- className: t1,
912
- ...props
1435
+ className: t1
913
1436
  });
914
1437
  $[5] = props;
915
1438
  $[6] = t1;
@@ -919,6 +1442,7 @@ function SidebarGroupContent(t0) {
919
1442
  }
920
1443
  return t2;
921
1444
  }
1445
+ /** Menu list whose items share a hover pill that glides between them. */
922
1446
  function SidebarMenu(t0) {
923
1447
  const $ = _c(8);
924
1448
  let className;
@@ -934,7 +1458,7 @@ function SidebarMenu(t0) {
934
1458
  }
935
1459
  let t1;
936
1460
  if ($[3] !== className) {
937
- t1 = cn("flex w-full min-w-0 flex-col gap-1", className);
1461
+ t1 = cn("flex w-full min-w-0 list-none flex-col gap-0.5", className);
938
1462
  $[3] = className;
939
1463
  $[4] = t1;
940
1464
  } else {
@@ -942,14 +1466,13 @@ function SidebarMenu(t0) {
942
1466
  }
943
1467
  let t2;
944
1468
  if ($[5] !== props || $[6] !== t1) {
945
- t2 = /* @__PURE__ */ _jsx(GlideSlot, {
946
- preset: "sidebar",
947
- children: /* @__PURE__ */ _jsx("ul", {
948
- "data-slot": "sidebar-menu",
949
- "data-sidebar": "menu",
950
- className: t1,
951
- ...props
952
- })
1469
+ t2 = /* @__PURE__ */ _jsx(SharedLayoutBg, {
1470
+ ...props,
1471
+ inset: 0,
1472
+ pillClassName: "rounded-xl bg-sidebar-accent/70",
1473
+ pillContainerClassName: "inset-y-auto top-0 h-9",
1474
+ "data-slot": "sidebar-menu",
1475
+ className: t1
953
1476
  });
954
1477
  $[5] = props;
955
1478
  $[6] = t1;
@@ -974,7 +1497,7 @@ function SidebarMenuItem(t0) {
974
1497
  }
975
1498
  let t1;
976
1499
  if ($[3] !== className) {
977
- t1 = cn("group/menu-item relative", className);
1500
+ t1 = cn("relative", className);
978
1501
  $[3] = className;
979
1502
  $[4] = t1;
980
1503
  } else {
@@ -982,11 +1505,12 @@ function SidebarMenuItem(t0) {
982
1505
  }
983
1506
  let t2;
984
1507
  if ($[5] !== props || $[6] !== t1) {
985
- t2 = /* @__PURE__ */ _jsx("li", {
1508
+ t2 = /* @__PURE__ */ _jsx(motion.li, {
1509
+ ...props,
1510
+ layout: "position",
1511
+ transition: SPRING_LAYOUT,
986
1512
  "data-slot": "sidebar-menu-item",
987
- "data-sidebar": "menu-item",
988
- className: t1,
989
- ...props
1513
+ className: t1
990
1514
  });
991
1515
  $[5] = props;
992
1516
  $[6] = t1;
@@ -996,195 +1520,70 @@ function SidebarMenuItem(t0) {
996
1520
  }
997
1521
  return t2;
998
1522
  }
999
- const sidebarMenuButtonVariants = cva("peer/menu-button group/menu-button flex w-full items-center gap-2 overflow-hidden rounded-md p-2 text-left text-sm ring-sidebar-ring outline-hidden transition-[width,height,padding] group-has-data-[sidebar=menu-action]/menu-item:pr-8 group-data-[collapsible=icon]:size-8! group-data-[collapsible=icon]:p-2! hover:bg-sidebar-accent hover:text-sidebar-accent-foreground focus-visible:ring-2 active:bg-sidebar-accent active:text-sidebar-accent-foreground disabled:pointer-events-none disabled:opacity-50 aria-disabled:pointer-events-none aria-disabled:opacity-50 data-open:hover:bg-sidebar-accent data-open:hover:text-sidebar-accent-foreground data-active:bg-sidebar-accent data-active:font-medium data-active:text-sidebar-accent-foreground [&_svg]:size-4 [&_svg]:shrink-0 [&>span:last-child]:truncate", {
1000
- variants: {
1001
- variant: {
1002
- default: "hover:bg-sidebar-accent hover:text-sidebar-accent-foreground",
1003
- outline: "bg-background shadow-[0_0_0_1px_var(--sidebar-border)] hover:bg-sidebar-accent hover:text-sidebar-accent-foreground hover:shadow-[0_0_0_1px_var(--sidebar-accent)]"
1004
- },
1005
- size: {
1006
- default: "h-8 text-sm",
1007
- sm: "h-7 text-xs",
1008
- lg: "h-12 text-sm group-data-[collapsible=icon]:p-0!"
1009
- }
1010
- },
1011
- defaultVariants: {
1012
- variant: "default",
1013
- size: "default"
1014
- }
1015
- });
1016
- function SidebarMenuButton(t0) {
1017
- const $ = _c(28);
1523
+ /**
1524
+ * Nested list that unfolds with a clip and staggered items.
1525
+ * @param props - Open state and motion-enabled list attributes.
1526
+ * @returns The submenu while open and the sidebar is expanded.
1527
+ */
1528
+ function SidebarMenuSub(t0) {
1529
+ const $ = _c(14);
1530
+ let children;
1018
1531
  let className;
1532
+ let open;
1019
1533
  let props;
1020
- let t1;
1021
- let t2;
1022
- let t3;
1023
- let t4;
1024
- let tooltip;
1025
1534
  if ($[0] !== t0) {
1026
- ({asChild: t1, isActive: t2, variant: t3, size: t4, tooltip, className, ...props} = t0);
1535
+ ({open, children, className, ...props} = t0);
1027
1536
  $[0] = t0;
1028
- $[1] = className;
1029
- $[2] = props;
1030
- $[3] = t1;
1031
- $[4] = t2;
1032
- $[5] = t3;
1033
- $[6] = t4;
1034
- $[7] = tooltip;
1035
- } else {
1036
- className = $[1];
1037
- props = $[2];
1038
- t1 = $[3];
1039
- t2 = $[4];
1040
- t3 = $[5];
1041
- t4 = $[6];
1042
- tooltip = $[7];
1043
- }
1044
- const asChild = t1 === undefined ? false : t1;
1045
- const isActive = t2 === undefined ? false : t2;
1046
- const variant = t3 === undefined ? "default" : t3;
1047
- const size = t4 === undefined ? "default" : t4;
1048
- const Comp = asChild ? Slot.Root : "button";
1049
- const { isMobile, state } = useSidebar();
1050
- const hasMounted = React.useSyncExternalStore(subscribeToClientMount, getClientMountSnapshot, getServerMountSnapshot);
1051
- let t5;
1052
- if ($[8] !== className || $[9] !== size || $[10] !== variant) {
1053
- t5 = cn(sidebarMenuButtonVariants({
1054
- variant,
1055
- size
1056
- }), className);
1057
- $[8] = className;
1058
- $[9] = size;
1059
- $[10] = variant;
1060
- $[11] = t5;
1061
- } else {
1062
- t5 = $[11];
1063
- }
1064
- let t6;
1065
- if ($[12] !== Comp || $[13] !== isActive || $[14] !== props || $[15] !== size || $[16] !== t5) {
1066
- t6 = /* @__PURE__ */ _jsx(MotionSlot, {
1067
- kind: "subtle-press",
1068
- children: /* @__PURE__ */ _jsx(Comp, {
1069
- "data-slot": "sidebar-menu-button",
1070
- "data-sidebar": "menu-button",
1071
- "data-size": size,
1072
- "data-active": isActive,
1073
- className: t5,
1074
- ...props
1075
- })
1076
- });
1077
- $[12] = Comp;
1078
- $[13] = isActive;
1079
- $[14] = props;
1080
- $[15] = size;
1081
- $[16] = t5;
1082
- $[17] = t6;
1083
- } else {
1084
- t6 = $[17];
1085
- }
1086
- const button = t6;
1087
- if (!tooltip || !hasMounted) {
1088
- return button;
1089
- }
1090
- if (typeof tooltip === "string") {
1091
- let t7;
1092
- if ($[18] !== tooltip) {
1093
- t7 = { children: tooltip };
1094
- $[18] = tooltip;
1095
- $[19] = t7;
1096
- } else {
1097
- t7 = $[19];
1098
- }
1099
- tooltip = t7;
1100
- }
1101
- let t7;
1102
- if ($[20] !== button) {
1103
- t7 = /* @__PURE__ */ _jsx(TooltipTrigger, {
1104
- asChild: true,
1105
- children: button
1106
- });
1107
- $[20] = button;
1108
- $[21] = t7;
1109
- } else {
1110
- t7 = $[21];
1111
- }
1112
- const t8 = state !== "collapsed" || isMobile;
1113
- let t9;
1114
- if ($[22] !== t8 || $[23] !== tooltip) {
1115
- t9 = /* @__PURE__ */ _jsx(TooltipContent, {
1116
- side: "right",
1117
- align: "center",
1118
- hidden: t8,
1119
- ...tooltip
1120
- });
1121
- $[22] = t8;
1122
- $[23] = tooltip;
1123
- $[24] = t9;
1124
- } else {
1125
- t9 = $[24];
1126
- }
1127
- let t10;
1128
- if ($[25] !== t7 || $[26] !== t9) {
1129
- t10 = /* @__PURE__ */ _jsxs(Tooltip, { children: [t7, t9] });
1130
- $[25] = t7;
1131
- $[26] = t9;
1132
- $[27] = t10;
1537
+ $[1] = children;
1538
+ $[2] = className;
1539
+ $[3] = open;
1540
+ $[4] = props;
1133
1541
  } else {
1134
- t10 = $[27];
1542
+ children = $[1];
1543
+ className = $[2];
1544
+ open = $[3];
1545
+ props = $[4];
1135
1546
  }
1136
- return t10;
1137
- }
1138
- function SidebarMenuAction(t0) {
1139
- const $ = _c(12);
1140
- let className;
1141
- let props;
1547
+ const context = useSidebar();
1548
+ const panel = useSidebarPanel();
1142
1549
  let t1;
1143
- let t2;
1144
- if ($[0] !== t0) {
1145
- ({className, asChild: t1, showOnHover: t2, ...props} = t0);
1146
- $[0] = t0;
1147
- $[1] = className;
1148
- $[2] = props;
1149
- $[3] = t1;
1150
- $[4] = t2;
1151
- } else {
1152
- className = $[1];
1153
- props = $[2];
1154
- t1 = $[3];
1155
- t2 = $[4];
1156
- }
1157
- const asChild = t1 === undefined ? false : t1;
1158
- const showOnHover = t2 === undefined ? false : t2;
1159
- const Comp = asChild ? Slot.Root : "button";
1160
- const t3 = showOnHover && "group-focus-within/menu-item:opacity-100 group-hover/menu-item:opacity-100 peer-data-active/menu-button:text-sidebar-accent-foreground aria-expanded:opacity-100 md:opacity-0";
1161
- let t4;
1162
- if ($[5] !== className || $[6] !== t3) {
1163
- t4 = cn("absolute top-1.5 right-1 flex aspect-square w-5 items-center justify-center rounded-md p-0 text-sidebar-foreground ring-sidebar-ring outline-hidden transition-transform group-data-[collapsible=icon]:hidden peer-hover/menu-button:text-sidebar-accent-foreground peer-data-[size=default]/menu-button:top-1.5 peer-data-[size=lg]/menu-button:top-2.5 peer-data-[size=sm]/menu-button:top-1 after:absolute after:-inset-2 hover:bg-sidebar-accent hover:text-sidebar-accent-foreground focus-visible:ring-2 md:after:hidden [&>svg]:size-4 [&>svg]:shrink-0", t3, className);
1164
- $[5] = className;
1165
- $[6] = t3;
1166
- $[7] = t4;
1550
+ if ($[5] !== children || $[6] !== className || $[7] !== context || $[8] !== open || $[9] !== panel || $[10] !== props) {
1551
+ t1 = open && !panel.collapsed ? /* @__PURE__ */ _createElement(motion.ul, {
1552
+ ...props,
1553
+ key: "sidebar-submenu",
1554
+ variants: context.reduce ? undefined : SUBMENU_VARIANTS,
1555
+ initial: context.reduce ? false : "closed",
1556
+ animate: context.reduce ? { opacity: 1 } : "open",
1557
+ exit: context.reduce ? { opacity: 0 } : "closed",
1558
+ transition: context.reduce ? { duration: MOTION_TIMING.exit } : undefined,
1559
+ "data-slot": "sidebar-menu-sub",
1560
+ className: cn("relative mt-1 ml-5 flex min-w-0 flex-col gap-0.5 border-l border-sidebar-border pl-3", className)
1561
+ }, children) : null;
1562
+ $[5] = children;
1563
+ $[6] = className;
1564
+ $[7] = context;
1565
+ $[8] = open;
1566
+ $[9] = panel;
1567
+ $[10] = props;
1568
+ $[11] = t1;
1167
1569
  } else {
1168
- t4 = $[7];
1570
+ t1 = $[11];
1169
1571
  }
1170
- let t5;
1171
- if ($[8] !== Comp || $[9] !== props || $[10] !== t4) {
1172
- t5 = /* @__PURE__ */ _jsx(Comp, {
1173
- "data-slot": "sidebar-menu-action",
1174
- "data-sidebar": "menu-action",
1175
- className: t4,
1176
- ...props
1572
+ let t2;
1573
+ if ($[12] !== t1) {
1574
+ t2 = /* @__PURE__ */ _jsx(AnimatePresence, {
1575
+ initial: false,
1576
+ mode: "popLayout",
1577
+ children: t1
1177
1578
  });
1178
- $[8] = Comp;
1179
- $[9] = props;
1180
- $[10] = t4;
1181
- $[11] = t5;
1579
+ $[12] = t1;
1580
+ $[13] = t2;
1182
1581
  } else {
1183
- t5 = $[11];
1582
+ t2 = $[13];
1184
1583
  }
1185
- return t5;
1584
+ return t2;
1186
1585
  }
1187
- function SidebarMenuBadge(t0) {
1586
+ function SidebarMenuSubItem(t0) {
1188
1587
  const $ = _c(8);
1189
1588
  let className;
1190
1589
  let props;
@@ -1199,7 +1598,7 @@ function SidebarMenuBadge(t0) {
1199
1598
  }
1200
1599
  let t1;
1201
1600
  if ($[3] !== className) {
1202
- t1 = cn("pointer-events-none absolute right-1 flex h-5 min-w-5 items-center justify-center rounded-md px-1 text-xs font-medium text-sidebar-foreground tabular-nums select-none group-data-[collapsible=icon]:hidden peer-hover/menu-button:text-sidebar-accent-foreground peer-data-[size=default]/menu-button:top-1.5 peer-data-[size=lg]/menu-button:top-2.5 peer-data-[size=sm]/menu-button:top-1 peer-data-active/menu-button:text-sidebar-accent-foreground", className);
1601
+ t1 = cn("relative min-w-0", className);
1203
1602
  $[3] = className;
1204
1603
  $[4] = t1;
1205
1604
  } else {
@@ -1207,11 +1606,11 @@ function SidebarMenuBadge(t0) {
1207
1606
  }
1208
1607
  let t2;
1209
1608
  if ($[5] !== props || $[6] !== t1) {
1210
- t2 = /* @__PURE__ */ _jsx("div", {
1211
- "data-slot": "sidebar-menu-badge",
1212
- "data-sidebar": "menu-badge",
1213
- className: t1,
1214
- ...props
1609
+ t2 = /* @__PURE__ */ _jsx(motion.li, {
1610
+ ...props,
1611
+ variants: SUBMENU_ITEM_VARIANTS,
1612
+ "data-slot": "sidebar-menu-sub-item",
1613
+ className: t1
1215
1614
  });
1216
1615
  $[5] = props;
1217
1616
  $[6] = t1;
@@ -1221,208 +1620,379 @@ function SidebarMenuBadge(t0) {
1221
1620
  }
1222
1621
  return t2;
1223
1622
  }
1224
- function SidebarMenuSkeleton(t0) {
1225
- const $ = _c(14);
1226
- let className;
1227
- let props;
1228
- let t1;
1229
- if ($[0] !== t0) {
1230
- ({className, showIcon: t1, ...props} = t0);
1231
- $[0] = t0;
1232
- $[1] = className;
1233
- $[2] = props;
1234
- $[3] = t1;
1235
- } else {
1236
- className = $[1];
1237
- props = $[2];
1238
- t1 = $[3];
1239
- }
1240
- const showIcon = t1 === undefined ? false : t1;
1623
+ /** Renders a menu action as a routed link or a button, both with the subtle press feedback. */
1624
+ function SidebarPressable(t0) {
1625
+ const $ = _c(19);
1626
+ const { slot, href, disabled, target, rel, isActive, ariaExpanded, ariaLabel, title, className, children, onClick } = t0;
1627
+ const t1 = isActive ? "page" : undefined;
1241
1628
  let t2;
1242
- if ($[4] !== className) {
1243
- t2 = cn("flex h-8 items-center gap-2 rounded-md px-2", className);
1244
- $[4] = className;
1245
- $[5] = t2;
1629
+ if ($[0] !== ariaExpanded || $[1] !== ariaLabel || $[2] !== className || $[3] !== isActive || $[4] !== onClick || $[5] !== slot || $[6] !== t1 || $[7] !== title) {
1630
+ t2 = {
1631
+ "data-slot": slot,
1632
+ "data-active": isActive,
1633
+ "aria-current": t1,
1634
+ "aria-expanded": ariaExpanded,
1635
+ "aria-label": ariaLabel,
1636
+ title,
1637
+ className,
1638
+ onClick
1639
+ };
1640
+ $[0] = ariaExpanded;
1641
+ $[1] = ariaLabel;
1642
+ $[2] = className;
1643
+ $[3] = isActive;
1644
+ $[4] = onClick;
1645
+ $[5] = slot;
1646
+ $[6] = t1;
1647
+ $[7] = title;
1648
+ $[8] = t2;
1246
1649
  } else {
1247
- t2 = $[5];
1650
+ t2 = $[8];
1248
1651
  }
1652
+ const sharedProps = t2;
1249
1653
  let t3;
1250
- if ($[6] !== showIcon) {
1251
- t3 = showIcon && /* @__PURE__ */ _jsx(Skeleton, {
1252
- className: "size-4 rounded-md",
1253
- "data-sidebar": "menu-skeleton-icon"
1654
+ if ($[9] !== children || $[10] !== disabled || $[11] !== href || $[12] !== rel || $[13] !== sharedProps || $[14] !== target) {
1655
+ t3 = href ? /* @__PURE__ */ _jsx(Link, {
1656
+ ...sharedProps,
1657
+ href,
1658
+ target,
1659
+ rel: rel ?? (target === EXTERNAL_LINK_TARGET ? EXTERNAL_LINK_REL : undefined),
1660
+ "aria-disabled": disabled || undefined,
1661
+ tabIndex: disabled ? -1 : undefined,
1662
+ children
1663
+ }) : /* @__PURE__ */ _jsx("button", {
1664
+ ...sharedProps,
1665
+ type: "button",
1666
+ disabled,
1667
+ children
1254
1668
  });
1255
- $[6] = showIcon;
1256
- $[7] = t3;
1669
+ $[9] = children;
1670
+ $[10] = disabled;
1671
+ $[11] = href;
1672
+ $[12] = rel;
1673
+ $[13] = sharedProps;
1674
+ $[14] = target;
1675
+ $[15] = t3;
1257
1676
  } else {
1258
- t3 = $[7];
1677
+ t3 = $[15];
1259
1678
  }
1679
+ const element = t3;
1260
1680
  let t4;
1261
- if ($[8] === Symbol.for("react.memo_cache_sentinel")) {
1262
- t4 = { "--skeleton-width": SIDEBAR_MENU_SKELETON_TEXT_WIDTH };
1263
- $[8] = t4;
1264
- } else {
1265
- t4 = $[8];
1266
- }
1267
- let t5;
1268
- if ($[9] === Symbol.for("react.memo_cache_sentinel")) {
1269
- t5 = /* @__PURE__ */ _jsx(Skeleton, {
1270
- className: "h-4 max-w-(--skeleton-width) flex-1",
1271
- "data-sidebar": "menu-skeleton-text",
1272
- style: t4
1273
- });
1274
- $[9] = t5;
1275
- } else {
1276
- t5 = $[9];
1277
- }
1278
- let t6;
1279
- if ($[10] !== props || $[11] !== t2 || $[12] !== t3) {
1280
- t6 = /* @__PURE__ */ _jsxs("div", {
1281
- "data-slot": "sidebar-menu-skeleton",
1282
- "data-sidebar": "menu-skeleton",
1283
- className: t2,
1284
- ...props,
1285
- children: [t3, t5]
1681
+ if ($[16] !== disabled || $[17] !== element) {
1682
+ t4 = disabled ? element : /* @__PURE__ */ _jsx(MotionSlot, {
1683
+ kind: "subtle-press",
1684
+ children: element
1286
1685
  });
1287
- $[10] = props;
1288
- $[11] = t2;
1289
- $[12] = t3;
1290
- $[13] = t6;
1686
+ $[16] = disabled;
1687
+ $[17] = element;
1688
+ $[18] = t4;
1291
1689
  } else {
1292
- t6 = $[13];
1690
+ t4 = $[18];
1293
1691
  }
1294
- return t6;
1692
+ return t4;
1295
1693
  }
1296
- function SidebarMenuSub(t0) {
1297
- const $ = _c(8);
1298
- let className;
1299
- let props;
1300
- if ($[0] !== t0) {
1301
- ({className, ...props} = t0);
1302
- $[0] = t0;
1303
- $[1] = className;
1304
- $[2] = props;
1694
+ /**
1695
+ * Submenu entry; shows a dot when no icon is given.
1696
+ * @param props - Label, icon, link or select handler, active and disabled state.
1697
+ * @returns The submenu link or button.
1698
+ */
1699
+ function SidebarMenuSubButton(t0) {
1700
+ const $ = _c(25);
1701
+ const { children, icon, href, isActive: t1, disabled: t2, closeOnSelect: t3, target, rel, onSelect, className } = t0;
1702
+ const isActive = t1 === undefined ? false : t1;
1703
+ const disabled = t2 === undefined ? false : t2;
1704
+ const closeOnSelect = t3 === undefined ? true : t3;
1705
+ const context = useSidebar();
1706
+ let t4;
1707
+ if ($[0] !== closeOnSelect || $[1] !== context || $[2] !== disabled || $[3] !== onSelect) {
1708
+ t4 = (event) => {
1709
+ if (disabled) {
1710
+ event.preventDefault();
1711
+ return;
1712
+ }
1713
+ onSelect?.();
1714
+ if (context.isMobile && closeOnSelect) {
1715
+ context.setOpenMobile(false);
1716
+ }
1717
+ };
1718
+ $[0] = closeOnSelect;
1719
+ $[1] = context;
1720
+ $[2] = disabled;
1721
+ $[3] = onSelect;
1722
+ $[4] = t4;
1305
1723
  } else {
1306
- className = $[1];
1307
- props = $[2];
1724
+ t4 = $[4];
1308
1725
  }
1309
- let t1;
1310
- if ($[3] !== className) {
1311
- t1 = cn("mx-3.5 flex min-w-0 translate-x-px flex-col gap-1 border-l border-sidebar-border px-2.5 py-0.5 group-data-[collapsible=icon]:hidden", className);
1312
- $[3] = className;
1313
- $[4] = t1;
1726
+ const select = t4;
1727
+ const t5 = isActive && "bg-sidebar-accent/70 text-sidebar-accent-foreground";
1728
+ const t6 = disabled && "cursor-not-allowed opacity-40";
1729
+ let t7;
1730
+ if ($[5] !== className || $[6] !== t5 || $[7] !== t6) {
1731
+ t7 = cn("flex min-h-8 w-full min-w-0 items-center gap-2 rounded-lg px-2 text-left text-xs outline-none", "text-sidebar-foreground/70 transition-colors hover:bg-sidebar-accent/60 hover:text-sidebar-accent-foreground", "focus-visible:bg-sidebar-accent/70 focus-visible:ring-2 focus-visible:ring-sidebar-ring", t5, t6, className);
1732
+ $[5] = className;
1733
+ $[6] = t5;
1734
+ $[7] = t6;
1735
+ $[8] = t7;
1314
1736
  } else {
1315
- t1 = $[4];
1737
+ t7 = $[8];
1316
1738
  }
1317
- let t2;
1318
- if ($[5] !== props || $[6] !== t1) {
1319
- t2 = /* @__PURE__ */ _jsx("ul", {
1320
- "data-slot": "sidebar-menu-sub",
1321
- "data-sidebar": "menu-sub",
1322
- className: t1,
1323
- ...props
1324
- });
1325
- $[5] = props;
1326
- $[6] = t1;
1327
- $[7] = t2;
1739
+ let t8;
1740
+ if ($[9] !== icon) {
1741
+ t8 = icon ?? /* @__PURE__ */ _jsx("span", { className: "size-1 rounded-full bg-current" });
1742
+ $[9] = icon;
1743
+ $[10] = t8;
1328
1744
  } else {
1329
- t2 = $[7];
1745
+ t8 = $[10];
1330
1746
  }
1331
- return t2;
1332
- }
1333
- function SidebarMenuSubItem(t0) {
1334
- const $ = _c(8);
1335
- let className;
1336
- let props;
1337
- if ($[0] !== t0) {
1338
- ({className, ...props} = t0);
1339
- $[0] = t0;
1340
- $[1] = className;
1341
- $[2] = props;
1747
+ let t9;
1748
+ if ($[11] !== t8) {
1749
+ t9 = /* @__PURE__ */ _jsx("span", {
1750
+ "aria-hidden": "true",
1751
+ className: "grid size-4 shrink-0 place-items-center",
1752
+ children: t8
1753
+ });
1754
+ $[11] = t8;
1755
+ $[12] = t9;
1342
1756
  } else {
1343
- className = $[1];
1344
- props = $[2];
1757
+ t9 = $[12];
1345
1758
  }
1346
- let t1;
1347
- if ($[3] !== className) {
1348
- t1 = cn("group/menu-sub-item relative", className);
1349
- $[3] = className;
1350
- $[4] = t1;
1759
+ let t10;
1760
+ if ($[13] !== children) {
1761
+ t10 = /* @__PURE__ */ _jsx("span", {
1762
+ className: "min-w-0 flex-1 truncate",
1763
+ children
1764
+ });
1765
+ $[13] = children;
1766
+ $[14] = t10;
1351
1767
  } else {
1352
- t1 = $[4];
1768
+ t10 = $[14];
1353
1769
  }
1354
- let t2;
1355
- if ($[5] !== props || $[6] !== t1) {
1356
- t2 = /* @__PURE__ */ _jsx("li", {
1357
- "data-slot": "sidebar-menu-sub-item",
1358
- "data-sidebar": "menu-sub-item",
1359
- className: t1,
1360
- ...props
1770
+ let t11;
1771
+ if ($[15] !== disabled || $[16] !== href || $[17] !== isActive || $[18] !== rel || $[19] !== select || $[20] !== t10 || $[21] !== t7 || $[22] !== t9 || $[23] !== target) {
1772
+ t11 = /* @__PURE__ */ _jsxs(SidebarPressable, {
1773
+ slot: "sidebar-menu-sub-button",
1774
+ href,
1775
+ disabled,
1776
+ target,
1777
+ rel,
1778
+ isActive,
1779
+ onClick: select,
1780
+ className: t7,
1781
+ children: [t9, t10]
1361
1782
  });
1362
- $[5] = props;
1363
- $[6] = t1;
1364
- $[7] = t2;
1783
+ $[15] = disabled;
1784
+ $[16] = href;
1785
+ $[17] = isActive;
1786
+ $[18] = rel;
1787
+ $[19] = select;
1788
+ $[20] = t10;
1789
+ $[21] = t7;
1790
+ $[22] = t9;
1791
+ $[23] = target;
1792
+ $[24] = t11;
1365
1793
  } else {
1366
- t2 = $[7];
1794
+ t11 = $[24];
1367
1795
  }
1368
- return t2;
1796
+ return t11;
1369
1797
  }
1370
- function SidebarMenuSubButton(t0) {
1371
- const $ = _c(14);
1372
- let className;
1373
- let props;
1374
- let t1;
1375
- let t2;
1798
+ /**
1799
+ * Top-level menu entry: the active one carries a pill that glides between entries, and the label
1800
+ * fades out of the icon rail, leaving a string label as accessible name and native tooltip.
1801
+ * @param props - Label, icon, badge, link or select handler, submenu and active state.
1802
+ * @returns The menu link or button.
1803
+ */
1804
+ function SidebarMenuButton(t0) {
1805
+ const $ = _c(50);
1806
+ const { children, icon, badge, href, isActive: t1, ariaExpanded, disabled: t2, closeOnSelect, target, rel, onSelect, className } = t0;
1807
+ const isActive = t1 === undefined ? false : t1;
1808
+ const disabled = t2 === undefined ? false : t2;
1809
+ const context = useSidebar();
1810
+ const panel = useSidebarPanel();
1811
+ const textLabel = typeof children === "string" ? children : undefined;
1812
+ const collapsedLabel = panel.collapsed ? textLabel : undefined;
1376
1813
  let t3;
1377
- if ($[0] !== t0) {
1378
- ({asChild: t1, size: t2, isActive: t3, className, ...props} = t0);
1379
- $[0] = t0;
1380
- $[1] = className;
1381
- $[2] = props;
1382
- $[3] = t1;
1383
- $[4] = t2;
1384
- $[5] = t3;
1814
+ if ($[0] !== ariaExpanded || $[1] !== closeOnSelect || $[2] !== context || $[3] !== disabled || $[4] !== onSelect || $[5] !== panel.collapsed) {
1815
+ t3 = (event) => {
1816
+ if (disabled) {
1817
+ event.preventDefault();
1818
+ return;
1819
+ }
1820
+ onSelect?.();
1821
+ const shouldCloseOnSelect = closeOnSelect ?? ariaExpanded === undefined;
1822
+ if (context.isMobile && shouldCloseOnSelect) {
1823
+ context.setOpenMobile(false);
1824
+ }
1825
+ if (ariaExpanded !== undefined && panel.collapsed && !context.isMobile) {
1826
+ context.setOpen(true);
1827
+ }
1828
+ };
1829
+ $[0] = ariaExpanded;
1830
+ $[1] = closeOnSelect;
1831
+ $[2] = context;
1832
+ $[3] = disabled;
1833
+ $[4] = onSelect;
1834
+ $[5] = panel.collapsed;
1835
+ $[6] = t3;
1385
1836
  } else {
1386
- className = $[1];
1387
- props = $[2];
1388
- t1 = $[3];
1389
- t2 = $[4];
1390
- t3 = $[5];
1837
+ t3 = $[6];
1391
1838
  }
1392
- const asChild = t1 === undefined ? false : t1;
1393
- const size = t2 === undefined ? "md" : t2;
1394
- const isActive = t3 === undefined ? false : t3;
1395
- const Comp = asChild ? Slot.Root : "a";
1396
- let t4;
1397
- if ($[6] !== className) {
1398
- t4 = cn("flex h-7 min-w-0 -translate-x-px items-center gap-2 overflow-hidden rounded-md px-2 text-sidebar-foreground ring-sidebar-ring outline-hidden group-data-[collapsible=icon]:hidden hover:bg-sidebar-accent hover:text-sidebar-accent-foreground focus-visible:ring-2 active:bg-sidebar-accent active:text-sidebar-accent-foreground disabled:pointer-events-none disabled:opacity-50 aria-disabled:pointer-events-none aria-disabled:opacity-50 data-[size=md]:text-sm data-[size=sm]:text-xs data-active:bg-sidebar-accent data-active:text-sidebar-accent-foreground [&>span:last-child]:truncate [&>svg]:size-4 [&>svg]:shrink-0 [&>svg]:text-sidebar-accent-foreground", className);
1399
- $[6] = className;
1400
- $[7] = t4;
1839
+ const select = t3;
1840
+ const t4 = isActive && "text-sidebar-accent-foreground";
1841
+ const t5 = disabled && "cursor-not-allowed opacity-40";
1842
+ let t6;
1843
+ if ($[7] !== className || $[8] !== t4 || $[9] !== t5) {
1844
+ t6 = cn("relative flex min-h-9 w-full min-w-0 items-center gap-2.5 overflow-hidden rounded-xl px-3 text-left text-sm font-medium outline-none", "text-sidebar-foreground/70 transition-colors hover:text-sidebar-accent-foreground", "focus-visible:bg-sidebar-accent/70 focus-visible:ring-2 focus-visible:ring-sidebar-ring", t4, t5, className);
1845
+ $[7] = className;
1846
+ $[8] = t4;
1847
+ $[9] = t5;
1848
+ $[10] = t6;
1401
1849
  } else {
1402
- t4 = $[7];
1850
+ t6 = $[10];
1403
1851
  }
1404
- let t5;
1405
- if ($[8] !== Comp || $[9] !== isActive || $[10] !== props || $[11] !== size || $[12] !== t4) {
1406
- t5 = /* @__PURE__ */ _jsx(MotionSlot, {
1407
- kind: "subtle-press",
1408
- children: /* @__PURE__ */ _jsx(Comp, {
1409
- "data-slot": "sidebar-menu-sub-button",
1410
- "data-sidebar": "menu-sub-button",
1411
- "data-size": size,
1412
- "data-active": isActive,
1413
- className: t4,
1414
- ...props
1415
- })
1416
- });
1417
- $[8] = Comp;
1418
- $[9] = isActive;
1419
- $[10] = props;
1420
- $[11] = size;
1421
- $[12] = t4;
1422
- $[13] = t5;
1852
+ let t7;
1853
+ if ($[11] !== context.layoutId || $[12] !== context.reduce || $[13] !== isActive) {
1854
+ t7 = isActive ? /* @__PURE__ */ _jsx(motion.span, {
1855
+ "data-slot": "sidebar-menu-active-indicator",
1856
+ layoutId: context.layoutId,
1857
+ transition: context.reduce ? INSTANT_TRANSITION : SPRING_LAYOUT,
1858
+ className: "absolute inset-0 rounded-xl bg-sidebar-accent"
1859
+ }) : null;
1860
+ $[11] = context.layoutId;
1861
+ $[12] = context.reduce;
1862
+ $[13] = isActive;
1863
+ $[14] = t7;
1423
1864
  } else {
1424
- t5 = $[13];
1865
+ t7 = $[14];
1425
1866
  }
1426
- return t5;
1867
+ let t8;
1868
+ if ($[15] !== icon) {
1869
+ t8 = icon ? /* @__PURE__ */ _jsx("span", {
1870
+ "aria-hidden": "true",
1871
+ className: "relative z-10 grid size-5 shrink-0 place-items-center [&_svg]:size-4",
1872
+ children: icon
1873
+ }) : null;
1874
+ $[15] = icon;
1875
+ $[16] = t8;
1876
+ } else {
1877
+ t8 = $[16];
1878
+ }
1879
+ const t9 = panel.collapsed ? 0 : 1;
1880
+ const t10 = panel.collapsed ? -SIDEBAR_LABEL_DRIFT_PX : 0;
1881
+ let t11;
1882
+ if ($[17] !== t10 || $[18] !== t9) {
1883
+ t11 = {
1884
+ opacity: t9,
1885
+ x: t10
1886
+ };
1887
+ $[17] = t10;
1888
+ $[18] = t9;
1889
+ $[19] = t11;
1890
+ } else {
1891
+ t11 = $[19];
1892
+ }
1893
+ const t12 = context.reduce ? REDUCED_TRANSITION : panel.collapsed ? LABEL_EXIT_TRANSITION : LABEL_ENTER_TRANSITION;
1894
+ const t13 = panel.collapsed;
1895
+ const t14 = panel.collapsed && "pointer-events-none";
1896
+ let t15;
1897
+ if ($[20] !== t14) {
1898
+ t15 = cn("relative z-10 min-w-0 flex-1 truncate", t14);
1899
+ $[20] = t14;
1900
+ $[21] = t15;
1901
+ } else {
1902
+ t15 = $[21];
1903
+ }
1904
+ let t16;
1905
+ if ($[22] !== children || $[23] !== panel.collapsed || $[24] !== t11 || $[25] !== t12 || $[26] !== t15) {
1906
+ t16 = /* @__PURE__ */ _jsx(motion.span, {
1907
+ initial: false,
1908
+ animate: t11,
1909
+ transition: t12,
1910
+ "aria-hidden": t13,
1911
+ className: t15,
1912
+ children
1913
+ });
1914
+ $[22] = children;
1915
+ $[23] = panel.collapsed;
1916
+ $[24] = t11;
1917
+ $[25] = t12;
1918
+ $[26] = t15;
1919
+ $[27] = t16;
1920
+ } else {
1921
+ t16 = $[27];
1922
+ }
1923
+ let t17;
1924
+ if ($[28] !== badge || $[29] !== panel.collapsed) {
1925
+ t17 = badge && !panel.collapsed ? /* @__PURE__ */ _jsx("span", {
1926
+ className: "relative z-10 shrink-0 text-xs text-sidebar-foreground/70",
1927
+ children: badge
1928
+ }) : null;
1929
+ $[28] = badge;
1930
+ $[29] = panel.collapsed;
1931
+ $[30] = t17;
1932
+ } else {
1933
+ t17 = $[30];
1934
+ }
1935
+ let t18;
1936
+ if ($[31] !== ariaExpanded || $[32] !== context.reduce || $[33] !== panel.collapsed) {
1937
+ t18 = ariaExpanded !== undefined ? /* @__PURE__ */ _jsx(motion.span, {
1938
+ "aria-hidden": "true",
1939
+ initial: false,
1940
+ animate: {
1941
+ opacity: panel.collapsed ? 0 : 1,
1942
+ rotate: ariaExpanded ? SIDEBAR_CHEVRON_EXPANDED_DEGREES : 0,
1943
+ x: panel.collapsed ? SIDEBAR_LABEL_DRIFT_PX : 0
1944
+ },
1945
+ transition: context.reduce ? INSTANT_TRANSITION : SPRING_LAYOUT,
1946
+ className: "relative z-10 grid size-4 shrink-0 place-items-center text-sidebar-foreground/70",
1947
+ children: /* @__PURE__ */ _jsx(ChevronRight, { className: "size-3.5" })
1948
+ }) : null;
1949
+ $[31] = ariaExpanded;
1950
+ $[32] = context.reduce;
1951
+ $[33] = panel.collapsed;
1952
+ $[34] = t18;
1953
+ } else {
1954
+ t18 = $[34];
1955
+ }
1956
+ let t19;
1957
+ if ($[35] !== ariaExpanded || $[36] !== collapsedLabel || $[37] !== disabled || $[38] !== href || $[39] !== isActive || $[40] !== rel || $[41] !== select || $[42] !== t16 || $[43] !== t17 || $[44] !== t18 || $[45] !== t6 || $[46] !== t7 || $[47] !== t8 || $[48] !== target) {
1958
+ t19 = /* @__PURE__ */ _jsxs(SidebarPressable, {
1959
+ slot: "sidebar-menu-button",
1960
+ href,
1961
+ disabled,
1962
+ target,
1963
+ rel,
1964
+ isActive,
1965
+ ariaExpanded,
1966
+ ariaLabel: collapsedLabel,
1967
+ title: collapsedLabel,
1968
+ onClick: select,
1969
+ className: t6,
1970
+ children: [
1971
+ t7,
1972
+ t8,
1973
+ t16,
1974
+ t17,
1975
+ t18
1976
+ ]
1977
+ });
1978
+ $[35] = ariaExpanded;
1979
+ $[36] = collapsedLabel;
1980
+ $[37] = disabled;
1981
+ $[38] = href;
1982
+ $[39] = isActive;
1983
+ $[40] = rel;
1984
+ $[41] = select;
1985
+ $[42] = t16;
1986
+ $[43] = t17;
1987
+ $[44] = t18;
1988
+ $[45] = t6;
1989
+ $[46] = t7;
1990
+ $[47] = t8;
1991
+ $[48] = target;
1992
+ $[49] = t19;
1993
+ } else {
1994
+ t19 = $[49];
1995
+ }
1996
+ return t19;
1427
1997
  }
1428
- export { Sidebar, SidebarContent, SidebarFooter, SidebarGroup, SidebarGroupAction, SidebarGroupContent, SidebarGroupLabel, SidebarHeader, SidebarInput, SidebarInset, SidebarMenu, SidebarMenuAction, SidebarMenuBadge, SidebarMenuButton, SidebarMenuItem, SidebarMenuSkeleton, SidebarMenuSub, SidebarMenuSubButton, SidebarMenuSubItem, SidebarProvider, SidebarRail, SidebarSeparator, SidebarTrigger, useSidebar };
1998
+ export { Sidebar, SidebarBrandButton, SidebarClose, SidebarContent, SidebarFooter, SidebarGroup, SidebarGroupContent, SidebarGroupLabel, SidebarHeader, SidebarInset, SidebarLabel, SidebarMenu, SidebarMenuButton, SidebarMenuItem, SidebarMenuSub, SidebarMenuSubButton, SidebarMenuSubItem, SidebarProvider, SidebarRail, SidebarTrigger, useSidebar, useSidebarPanel };