@justanarthur/modo-ui 0.0.0-stage → 0.1.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.
Files changed (172) hide show
  1. package/LICENSE +21 -0
  2. package/LICENSE.beui +21 -0
  3. package/LICENSE.fluid-functionalism +21 -0
  4. package/LICENSE.motion-primitives +21 -0
  5. package/LICENSE.sileo +21 -0
  6. package/README.md +608 -2
  7. package/dist/base.css +994 -0
  8. package/dist/blocks/sidebar-app/index.d.ts +34 -0
  9. package/dist/blocks/sidebar-app/index.js +34 -0
  10. package/dist/components/badge/index.d.ts +59 -0
  11. package/dist/components/badge/index.js +18 -0
  12. package/dist/components/button/index.d.ts +59 -0
  13. package/dist/components/button/index.js +16 -0
  14. package/dist/components/card/index.d.ts +141 -0
  15. package/dist/components/card/index.js +44 -0
  16. package/dist/components/inputs/checkbox-group/index.d.ts +50 -0
  17. package/dist/components/inputs/checkbox-group/index.js +23 -0
  18. package/dist/components/inputs/color-picker/index.d.ts +137 -0
  19. package/dist/components/inputs/color-picker/index.js +37 -0
  20. package/dist/components/inputs/combobox/index.d.ts +161 -0
  21. package/dist/components/inputs/combobox/index.js +41 -0
  22. package/dist/components/inputs/date-time/calendar/index.d.ts +45 -0
  23. package/dist/components/inputs/date-time/calendar/index.js +20 -0
  24. package/dist/components/inputs/date-time/date-picker/index.d.ts +82 -0
  25. package/dist/components/inputs/date-time/date-picker/index.js +34 -0
  26. package/dist/components/inputs/date-time/date-range-picker/index.d.ts +64 -0
  27. package/dist/components/inputs/date-time/date-range-picker/index.js +33 -0
  28. package/dist/components/inputs/date-time/duration-picker/index.d.ts +57 -0
  29. package/dist/components/inputs/date-time/duration-picker/index.js +33 -0
  30. package/dist/components/inputs/date-time/month-picker/index.d.ts +57 -0
  31. package/dist/components/inputs/date-time/month-picker/index.js +32 -0
  32. package/dist/components/inputs/date-time/time-picker/index.d.ts +59 -0
  33. package/dist/components/inputs/date-time/time-picker/index.js +33 -0
  34. package/dist/components/inputs/input/index.d.ts +84 -0
  35. package/dist/components/inputs/input/index.js +20 -0
  36. package/dist/components/inputs/input-copy/index.d.ts +44 -0
  37. package/dist/components/inputs/input-copy/index.js +18 -0
  38. package/dist/components/inputs/input-message/index.d.ts +125 -0
  39. package/dist/components/inputs/input-message/index.js +27 -0
  40. package/dist/components/inputs/radio-group/index.d.ts +58 -0
  41. package/dist/components/inputs/radio-group/index.js +22 -0
  42. package/dist/components/inputs/search/index.d.ts +83 -0
  43. package/dist/components/inputs/search/index.js +28 -0
  44. package/dist/components/inputs/select/index.d.ts +105 -0
  45. package/dist/components/inputs/select/index.js +37 -0
  46. package/dist/components/inputs/slider/index.d.ts +108 -0
  47. package/dist/components/inputs/slider/index.js +16 -0
  48. package/dist/components/inputs/switch/index.d.ts +43 -0
  49. package/dist/components/inputs/switch/index.js +16 -0
  50. package/dist/components/navigation/accordion/index.d.ts +117 -0
  51. package/dist/components/navigation/accordion/index.js +30 -0
  52. package/dist/components/navigation/sidebar/index.d.ts +388 -0
  53. package/dist/components/navigation/sidebar/index.js +101 -0
  54. package/dist/components/navigation/tabs/index.d.ts +70 -0
  55. package/dist/components/navigation/tabs/index.js +25 -0
  56. package/dist/components/navigation/tabs-subtle/index.d.ts +73 -0
  57. package/dist/components/navigation/tabs-subtle/index.js +23 -0
  58. package/dist/components/overlays/alert-dialog/index.d.ts +67 -0
  59. package/dist/components/overlays/alert-dialog/index.js +24 -0
  60. package/dist/components/overlays/command/index.d.ts +121 -0
  61. package/dist/components/overlays/command/index.js +39 -0
  62. package/dist/components/overlays/context-menu/index.d.ts +97 -0
  63. package/dist/components/overlays/context-menu/index.js +32 -0
  64. package/dist/components/overlays/dialog/index.d.ts +130 -0
  65. package/dist/components/overlays/dialog/index.js +39 -0
  66. package/dist/components/overlays/dropdown/index.d.ts +222 -0
  67. package/dist/components/overlays/dropdown/index.js +47 -0
  68. package/dist/components/overlays/popover/index.d.ts +87 -0
  69. package/dist/components/overlays/popover/index.js +28 -0
  70. package/dist/components/overlays/preview-card/index.d.ts +75 -0
  71. package/dist/components/overlays/preview-card/index.js +21 -0
  72. package/dist/components/overlays/sheet/index.d.ts +67 -0
  73. package/dist/components/overlays/sheet/index.js +26 -0
  74. package/dist/components/overlays/toast/index.d.ts +107 -0
  75. package/dist/components/overlays/toast/index.js +23 -0
  76. package/dist/components/overlays/tooltip/index.d.ts +75 -0
  77. package/dist/components/overlays/tooltip/index.js +19 -0
  78. package/dist/components/table/index.d.ts +44 -0
  79. package/dist/components/table/index.js +28 -0
  80. package/dist/components/thinking-indicator/index.d.ts +32 -0
  81. package/dist/components/thinking-indicator/index.js +15 -0
  82. package/dist/index.d.ts +3926 -0
  83. package/dist/index.js +513 -0
  84. package/dist/preset.d.ts +104 -0
  85. package/dist/preset.js +124 -0
  86. package/dist/primitives/code/index.d.ts +23 -0
  87. package/dist/primitives/code/index.js +12 -0
  88. package/dist/primitives/craft/index.d.ts +31 -0
  89. package/dist/primitives/craft/index.js +13 -0
  90. package/dist/primitives/fluid-hover/index.d.ts +233 -0
  91. package/dist/primitives/fluid-hover/index.js +27 -0
  92. package/dist/primitives/morph/index.d.ts +127 -0
  93. package/dist/primitives/morph/index.js +21 -0
  94. package/dist/primitives/motion/index.d.ts +115 -0
  95. package/dist/primitives/motion/index.js +20 -0
  96. package/dist/primitives/scroll-area/index.d.ts +41 -0
  97. package/dist/primitives/scroll-area/index.js +13 -0
  98. package/dist/primitives/sizes/index.d.ts +128 -0
  99. package/dist/primitives/sizes/index.js +22 -0
  100. package/dist/primitives/surface/index.d.ts +69 -0
  101. package/dist/primitives/surface/index.js +18 -0
  102. package/dist/shared/components-0f0as45n.js +17 -0
  103. package/dist/shared/components-40j34hdb.js +986 -0
  104. package/dist/shared/components-4hh0gm0v.js +292 -0
  105. package/dist/shared/components-4xxddc44.js +15 -0
  106. package/dist/shared/components-4xxtggzp.js +110 -0
  107. package/dist/shared/components-54nf2x99.js +293 -0
  108. package/dist/shared/components-5pkcfprd.js +232 -0
  109. package/dist/shared/components-5vxtcp88.js +9 -0
  110. package/dist/shared/components-5zry9te1.js +152 -0
  111. package/dist/shared/components-61ckf42z.js +220 -0
  112. package/dist/shared/components-6hzwfmfd.js +58 -0
  113. package/dist/shared/components-6phwsry6.js +361 -0
  114. package/dist/shared/components-6t6nr33r.js +86 -0
  115. package/dist/shared/components-6y1th6k4.js +111 -0
  116. package/dist/shared/components-74c20v2f.js +32 -0
  117. package/dist/shared/components-7cqq1sqy.js +193 -0
  118. package/dist/shared/components-7gv95yfy.js +496 -0
  119. package/dist/shared/components-7nww01w4.js +375 -0
  120. package/dist/shared/components-7zp99w5d.js +62 -0
  121. package/dist/shared/components-8hk9ve3r.js +1200 -0
  122. package/dist/shared/components-8hzbsfbd.js +123 -0
  123. package/dist/shared/components-9p8s8n5q.js +171 -0
  124. package/dist/shared/components-aaq3yk4f.js +304 -0
  125. package/dist/shared/components-bf2d9k02.js +484 -0
  126. package/dist/shared/components-bkvb6nem.js +63 -0
  127. package/dist/shared/components-brnzrp2t.js +262 -0
  128. package/dist/shared/components-csxz9f52.js +42 -0
  129. package/dist/shared/components-de8xsm9y.js +22 -0
  130. package/dist/shared/components-dg0w8g5p.js +26 -0
  131. package/dist/shared/components-dphg9gjr.js +42 -0
  132. package/dist/shared/components-e46kf6cp.js +298 -0
  133. package/dist/shared/components-ed7cmssr.js +105 -0
  134. package/dist/shared/components-ess3ch6w.js +137 -0
  135. package/dist/shared/components-gjfrycb5.js +984 -0
  136. package/dist/shared/components-gndm6am4.js +128 -0
  137. package/dist/shared/components-hjkrv00c.js +191 -0
  138. package/dist/shared/components-hzfp4tjb.js +270 -0
  139. package/dist/shared/components-j65qt1mq.js +719 -0
  140. package/dist/shared/components-jw16snbn.js +19 -0
  141. package/dist/shared/components-jxgznftn.js +146 -0
  142. package/dist/shared/components-kf2ehztc.js +216 -0
  143. package/dist/shared/components-kpbcms10.js +9 -0
  144. package/dist/shared/components-m5br529r.js +141 -0
  145. package/dist/shared/components-nn6xezy2.js +1828 -0
  146. package/dist/shared/components-nnnd2xef.js +9 -0
  147. package/dist/shared/components-p2vmyfe1.js +345 -0
  148. package/dist/shared/components-peg09pzs.js +79 -0
  149. package/dist/shared/components-r22vtgqc.js +45 -0
  150. package/dist/shared/components-r2gke5p6.js +1759 -0
  151. package/dist/shared/components-r43mqnd6.js +160 -0
  152. package/dist/shared/components-r4jt6hgd.js +58 -0
  153. package/dist/shared/components-rc63qsy6.js +159 -0
  154. package/dist/shared/components-s3yfvfkr.js +149 -0
  155. package/dist/shared/components-s5pkbjx1.js +445 -0
  156. package/dist/shared/components-tad5h7ta.js +346 -0
  157. package/dist/shared/components-taxmgbnh.js +120 -0
  158. package/dist/shared/components-tm88ghva.js +215 -0
  159. package/dist/shared/components-v7es8aan.js +144 -0
  160. package/dist/shared/components-vb033rns.js +28 -0
  161. package/dist/shared/components-vc1k7yv2.js +30 -0
  162. package/dist/shared/components-vktws5r6.js +667 -0
  163. package/dist/shared/components-x2xyckd5.js +198 -0
  164. package/dist/shared/components-x3rz4cyn.js +61 -0
  165. package/dist/shared/components-xszag63d.js +141 -0
  166. package/dist/shared/components-y3cqdrgy.js +291 -0
  167. package/dist/shared/components-zvb11ker.js +288 -0
  168. package/dist/shared/components-zx2hr57f.js +124 -0
  169. package/dist/styles.css +1949 -0
  170. package/dist/tailwind.css +219 -0
  171. package/dist/tokens.css +345 -0
  172. package/package.json +102 -3
@@ -0,0 +1,1828 @@
1
+ import {
2
+ useIsMobile
3
+ } from "./components-4xxddc44.js";
4
+ import {
5
+ Sheet
6
+ } from "./components-r43mqnd6.js";
7
+ import {
8
+ fieldVariants
9
+ } from "./components-de8xsm9y.js";
10
+ import {
11
+ Tooltip
12
+ } from "./components-gndm6am4.js";
13
+ import {
14
+ SizeProvider
15
+ } from "./components-vb033rns.js";
16
+ import {
17
+ Button
18
+ } from "./components-5pkcfprd.js";
19
+ import {
20
+ useIcon
21
+ } from "./components-m5br529r.js";
22
+ import {
23
+ ScrollArea
24
+ } from "./components-ed7cmssr.js";
25
+ import {
26
+ SurfaceProvider,
27
+ surfaceClasses,
28
+ useSurface
29
+ } from "./components-csxz9f52.js";
30
+ import {
31
+ FluidHoverHighlight
32
+ } from "./components-r22vtgqc.js";
33
+ import {
34
+ useFluidHover
35
+ } from "./components-e46kf6cp.js";
36
+ import {
37
+ useShape
38
+ } from "./components-7zp99w5d.js";
39
+ import {
40
+ useControllableState
41
+ } from "./components-dg0w8g5p.js";
42
+ import {
43
+ GooIndicator
44
+ } from "./components-kf2ehztc.js";
45
+ import {
46
+ exitFallbackMs,
47
+ spring
48
+ } from "./components-vc1k7yv2.js";
49
+ import {
50
+ useSize,
51
+ useSizeVariant
52
+ } from "./components-x3rz4cyn.js";
53
+ import {
54
+ cn
55
+ } from "./components-0f0as45n.js";
56
+
57
+ // components/navigation/sidebar/index.tsx
58
+ import {
59
+ forwardRef as forwardRef3,
60
+ useEffect as useEffect3,
61
+ useMemo as useMemo3
62
+ } from "react";
63
+
64
+ // components/navigation/sidebar/sidebar-core.tsx
65
+ import { motion, useReducedMotion } from "motion/react";
66
+ import {
67
+ Children,
68
+ cloneElement,
69
+ createContext,
70
+ forwardRef,
71
+ isValidElement,
72
+ useCallback,
73
+ useContext,
74
+ useEffect,
75
+ useId,
76
+ useLayoutEffect,
77
+ useMemo,
78
+ useRef,
79
+ useState
80
+ } from "react";
81
+ import { jsx, jsxs, Fragment } from "react/jsx-runtime";
82
+ var SIDEBAR_COOKIE_NAME = "sidebar_state";
83
+ var SIDEBAR_COOKIE_MAX_AGE = 60 * 60 * 24 * 7;
84
+ var SIDEBAR_WIDTH = "16rem";
85
+ var SIDEBAR_WIDTH_MOBILE = "18rem";
86
+ var SIDEBAR_KEYBOARD_SHORTCUT = "[";
87
+ var SIDEBAR_KEYBOARD_SHORTCUT_RIGHT = "]";
88
+ var SIDEBAR_MIN_WIDTH = 160;
89
+ var SIDEBAR_MAX_WIDTH = 360;
90
+ var SIDEBAR_COLLAPSE_SLOP = 56;
91
+ var SIDEBAR_HOVER_STRIP = 12;
92
+ var SIDEBAR_HOVER_TRIGGER_GAP = 24;
93
+ var mountedProviders = [];
94
+ var SidebarContext = createContext(null);
95
+ function useSidebar() {
96
+ const ctx = useContext(SidebarContext);
97
+ if (!ctx)
98
+ throw new Error("useSidebar must be used within a SidebarProvider");
99
+ return ctx;
100
+ }
101
+ function inHoverZone(event, side, frame, shell, triggers) {
102
+ if (!frame || !shell)
103
+ return false;
104
+ const bounds = frame.getBoundingClientRect();
105
+ if (event.clientY < bounds.top || event.clientY > bounds.bottom)
106
+ return false;
107
+ const box = shell.getBoundingClientRect();
108
+ const inner = side === "left" ? box.right : box.left;
109
+ let reach = SIDEBAR_HOVER_STRIP;
110
+ for (const trigger of triggers) {
111
+ const button = trigger.getBoundingClientRect();
112
+ const gap = side === "left" ? button.left - inner : inner - button.right;
113
+ if (gap >= 0 && gap <= SIDEBAR_HOVER_TRIGGER_GAP)
114
+ reach = Math.max(reach, gap + button.width);
115
+ }
116
+ return side === "left" ? event.clientX >= bounds.left && event.clientX < inner + reach : event.clientX <= bounds.right && event.clientX > inner - reach;
117
+ }
118
+ var SidebarProvider = forwardRef(({
119
+ defaultOpen = true,
120
+ open: openProp,
121
+ onOpenChange,
122
+ persist = true,
123
+ shortcut: shortcutProp,
124
+ mobileBreakpoint = 768,
125
+ openOnHover = false,
126
+ width: widthProp = SIDEBAR_WIDTH,
127
+ widthMobile = SIDEBAR_WIDTH_MOBILE,
128
+ className,
129
+ style,
130
+ children,
131
+ ...props
132
+ }, ref) => {
133
+ const isMobile = useIsMobile(mobileBreakpoint);
134
+ const [openMobile, setOpenMobile] = useState(false);
135
+ const [side, setSide] = useState("left");
136
+ const wrapperRef = useRef(null);
137
+ useEffect(() => {
138
+ const el = wrapperRef.current;
139
+ if (!el)
140
+ return;
141
+ mountedProviders.push(el);
142
+ return () => {
143
+ const i = mountedProviders.indexOf(el);
144
+ if (i !== -1)
145
+ mountedProviders.splice(i, 1);
146
+ };
147
+ }, []);
148
+ const registerSide = useCallback((next) => setSide(next), []);
149
+ const [width, setWidth] = useState(widthProp);
150
+ useEffect(() => setWidth(widthProp), [widthProp]);
151
+ const [isResizing, setIsResizing] = useState(false);
152
+ const shortcut = shortcutProp === undefined ? side === "right" ? SIDEBAR_KEYBOARD_SHORTCUT_RIGHT : SIDEBAR_KEYBOARD_SHORTCUT : shortcutProp;
153
+ const [internalOpen, setInternalOpen] = useState(defaultOpen);
154
+ const open = openProp ?? internalOpen;
155
+ const openRef = useRef(open);
156
+ openRef.current = open;
157
+ const setOpen = useCallback((value2) => {
158
+ const next = typeof value2 === "function" ? value2(openRef.current) : value2;
159
+ if (onOpenChange)
160
+ onOpenChange(next);
161
+ else
162
+ setInternalOpen(next);
163
+ if (persist) {
164
+ document.cookie = `${SIDEBAR_COOKIE_NAME}=${next}; path=/; max-age=${SIDEBAR_COOKIE_MAX_AGE}`;
165
+ }
166
+ }, [onOpenChange, persist]);
167
+ const toggleSidebar = useCallback(() => {
168
+ if (isMobile)
169
+ setOpenMobile((prev) => !prev);
170
+ else
171
+ setOpen((prev) => !prev);
172
+ }, [isMobile, setOpen]);
173
+ const [hoverOpen, setHoverOpen] = useState(false);
174
+ useEffect(() => {
175
+ if (open || !openOnHover)
176
+ setHoverOpen(false);
177
+ }, [open, openOnHover]);
178
+ const shellRef = useRef(null);
179
+ const triggers = useRef(new Set);
180
+ const registerTrigger = useCallback((node) => {
181
+ triggers.current.add(node);
182
+ return () => {
183
+ triggers.current.delete(node);
184
+ };
185
+ }, []);
186
+ useEffect(() => {
187
+ if (!openOnHover || open || isMobile || isResizing)
188
+ return;
189
+ let armed = false;
190
+ let close;
191
+ const onPointerMove = (event) => {
192
+ if (event.pointerType !== "mouse")
193
+ return;
194
+ if (!inHoverZone(event, side, wrapperRef.current, shellRef.current, triggers.current)) {
195
+ armed = true;
196
+ if (hoverOpen)
197
+ close ??= setTimeout(() => setHoverOpen(false), 300);
198
+ return;
199
+ }
200
+ clearTimeout(close);
201
+ close = undefined;
202
+ if (armed)
203
+ setHoverOpen(true);
204
+ };
205
+ document.addEventListener("pointermove", onPointerMove);
206
+ return () => {
207
+ document.removeEventListener("pointermove", onPointerMove);
208
+ clearTimeout(close);
209
+ };
210
+ }, [openOnHover, open, isMobile, isResizing, hoverOpen, side]);
211
+ useEffect(() => {
212
+ if (shortcut == null)
213
+ return;
214
+ const onKeyDown = (event) => {
215
+ if (event.key.toLowerCase() !== shortcut.toLowerCase())
216
+ return;
217
+ if (event.metaKey || event.ctrlKey || event.altKey)
218
+ return;
219
+ const target = event.target;
220
+ if (target.tagName === "INPUT" || target.tagName === "TEXTAREA" || target.tagName === "SELECT" || target.isContentEditable)
221
+ return;
222
+ const root = wrapperRef.current;
223
+ if (!root)
224
+ return;
225
+ if (root.contains(target)) {
226
+ if (mountedProviders.some((el) => el !== root && root.contains(el) && el.contains(target)))
227
+ return;
228
+ if (mountedProviders.some((el) => el !== root && target.contains(el)))
229
+ return;
230
+ } else {
231
+ const wrapped = mountedProviders.filter((el) => target.contains(el));
232
+ if (wrapped.length > 0) {
233
+ const outermost = wrapped.find((el) => !wrapped.some((other) => other !== el && other.contains(el)));
234
+ if (outermost !== root)
235
+ return;
236
+ } else {
237
+ if (mountedProviders.some((el) => el !== root && el.contains(target)))
238
+ return;
239
+ const outermost = mountedProviders.find((el) => !mountedProviders.some((other) => other !== el && other.contains(el)));
240
+ if (outermost !== root)
241
+ return;
242
+ }
243
+ }
244
+ event.preventDefault();
245
+ toggleSidebar();
246
+ };
247
+ window.addEventListener("keydown", onKeyDown);
248
+ return () => window.removeEventListener("keydown", onKeyDown);
249
+ }, [shortcut, toggleSidebar]);
250
+ const value = useMemo(() => ({
251
+ state: open || hoverOpen ? "expanded" : "collapsed",
252
+ open,
253
+ setOpen,
254
+ openMobile,
255
+ setOpenMobile,
256
+ isMobile,
257
+ toggleSidebar,
258
+ width,
259
+ setWidth,
260
+ widthMobile,
261
+ mobileBreakpoint,
262
+ side,
263
+ registerSide,
264
+ shortcut,
265
+ openOnHover,
266
+ hoverOpen,
267
+ setHoverOpen,
268
+ shellRef,
269
+ registerTrigger,
270
+ isResizing,
271
+ setIsResizing
272
+ }), [
273
+ open,
274
+ setOpen,
275
+ openMobile,
276
+ isMobile,
277
+ toggleSidebar,
278
+ width,
279
+ widthMobile,
280
+ mobileBreakpoint,
281
+ side,
282
+ registerSide,
283
+ shortcut,
284
+ openOnHover,
285
+ hoverOpen,
286
+ registerTrigger,
287
+ isResizing
288
+ ]);
289
+ return /* @__PURE__ */ jsx(SidebarContext.Provider, {
290
+ value,
291
+ children: /* @__PURE__ */ jsx("div", {
292
+ ref: (node) => {
293
+ wrapperRef.current = node;
294
+ if (typeof ref === "function")
295
+ ref(node);
296
+ else if (ref)
297
+ ref.current = node;
298
+ },
299
+ "data-slot": "sidebar-wrapper",
300
+ className: cn("group/sidebar-wrapper relative flex min-h-svh w-full", className),
301
+ style: {
302
+ "--sidebar-width": width,
303
+ "--sidebar-width-mobile": widthMobile,
304
+ ...style
305
+ },
306
+ ...props,
307
+ children
308
+ })
309
+ });
310
+ });
311
+ SidebarProvider.displayName = "SidebarProvider";
312
+ function composeRefs(...refs) {
313
+ return (node) => {
314
+ for (const r of refs) {
315
+ if (typeof r === "function")
316
+ r(node);
317
+ else if (r)
318
+ r.current = node;
319
+ }
320
+ };
321
+ }
322
+ function resolveSlotTemplate(render, asChild, children) {
323
+ if (render && isValidElement(render)) {
324
+ return { template: render, content: children };
325
+ }
326
+ if (asChild) {
327
+ const only = Children.toArray(children)[0];
328
+ if (isValidElement(only)) {
329
+ return {
330
+ template: only,
331
+ content: only.props.children
332
+ };
333
+ }
334
+ }
335
+ return { template: null, content: children };
336
+ }
337
+ function slotElement(template, DefaultTag, props, content) {
338
+ if (!template) {
339
+ const Tag = DefaultTag;
340
+ return /* @__PURE__ */ jsx(Tag, {
341
+ ...props,
342
+ children: content
343
+ });
344
+ }
345
+ const templateProps = template.props;
346
+ const merged = {
347
+ ...props,
348
+ ...templateProps,
349
+ className: cn(props.className, templateProps.className),
350
+ style: { ...props.style, ...templateProps.style }
351
+ };
352
+ for (const key of Object.keys(props)) {
353
+ if (!/^on[A-Z]/.test(key))
354
+ continue;
355
+ const ours = props[key];
356
+ const theirs = templateProps[key];
357
+ if (typeof ours === "function" && typeof theirs === "function") {
358
+ merged[key] = (...args) => {
359
+ theirs(...args);
360
+ ours(...args);
361
+ };
362
+ }
363
+ }
364
+ const templateRef = templateProps.ref ?? template.ref;
365
+ merged.ref = composeRefs(props.ref, templateRef);
366
+ return cloneElement(template, merged, content);
367
+ }
368
+ var BREAKPOINT_FADE_BASE = "transition-[opacity,display] ease-out [transition-behavior:allow-discrete] motion-reduce:transition-none";
369
+ var BREAKPOINT_HIDDEN = {
370
+ 640: "max-sm:hidden max-sm:opacity-0 max-sm:duration-moderate sm:duration-slow sm:starting:opacity-0",
371
+ 768: "max-md:hidden max-md:opacity-0 max-md:duration-moderate md:duration-slow md:starting:opacity-0",
372
+ 1024: "max-lg:hidden max-lg:opacity-0 max-lg:duration-moderate lg:duration-slow lg:starting:opacity-0",
373
+ 1280: "max-xl:hidden max-xl:opacity-0 max-xl:duration-moderate xl:duration-slow xl:starting:opacity-0"
374
+ };
375
+ var SidebarShell = forwardRef(({ side, variant, bordered = true, rail = true, railTooltipOpen, className, children, ...props }, ref) => {
376
+ const { open: kept, hoverOpen, width, mobileBreakpoint, isMobile, isResizing, shellRef } = useSidebar();
377
+ const open = kept || hoverOpen;
378
+ const shape = useShape();
379
+ const substrate = useSurface();
380
+ const floatingLevel = Math.min(substrate + 1, 8);
381
+ const reduceMotion = useReducedMotion() ?? false;
382
+ const [dragFlip, setDragFlip] = useState(false);
383
+ const prevOpenRef = useRef(open);
384
+ const openFlipped = prevOpenRef.current !== open;
385
+ useEffect(() => {
386
+ const flipped = prevOpenRef.current !== open;
387
+ prevOpenRef.current = open;
388
+ if (!isResizing) {
389
+ setDragFlip(false);
390
+ return;
391
+ }
392
+ if (!flipped)
393
+ return;
394
+ setDragFlip(true);
395
+ const id = setTimeout(() => setDragFlip(false), exitFallbackMs(spring.moderate));
396
+ return () => clearTimeout(id);
397
+ }, [open, isResizing]);
398
+ const widthTransition = reduceMotion ? { duration: 0 } : isResizing ? openFlipped || dragFlip ? open ? spring.moderate : spring.moderate.exit : { duration: 0 } : open ? spring.slow : spring.slow.exit;
399
+ return /* @__PURE__ */ jsx(motion.div, {
400
+ ref: (node) => {
401
+ shellRef.current = node;
402
+ if (typeof ref === "function")
403
+ ref(node);
404
+ else if (ref)
405
+ ref.current = node;
406
+ },
407
+ "data-slot": "sidebar",
408
+ "data-state": open ? "expanded" : "collapsed",
409
+ "data-collapsible": open ? "" : "offcanvas",
410
+ "data-variant": variant,
411
+ "data-side": side,
412
+ className: cn("peer shrink-0 sticky top-0 h-svh overflow-hidden", side === "right" && "order-last", variant === "inset" && "[--scroll-divider-inset:8px]", BREAKPOINT_FADE_BASE, BREAKPOINT_HIDDEN[mobileBreakpoint], !BREAKPOINT_HIDDEN[mobileBreakpoint] && isMobile && "hidden", className),
413
+ initial: false,
414
+ animate: { width: open ? width : "0rem" },
415
+ transition: widthTransition,
416
+ ...props,
417
+ children: /* @__PURE__ */ jsxs(motion.div, {
418
+ className: cn("absolute inset-y-0 flex h-full flex-col", side === "left" ? "left-0" : "right-0", variant === "floating" && "p-2", variant === "inset" && "py-2"),
419
+ style: { width },
420
+ initial: false,
421
+ animate: { x: open ? "0%" : side === "left" ? "-100%" : "100%" },
422
+ transition: widthTransition,
423
+ ...open || isResizing ? {} : { inert: "" },
424
+ children: [
425
+ variant === "floating" ? /* @__PURE__ */ jsx("div", {
426
+ "data-sidebar": "sidebar",
427
+ className: cn("flex h-full w-full min-h-0 flex-col", shape.container, surfaceClasses(floatingLevel, 3)),
428
+ children: /* @__PURE__ */ jsx(SurfaceProvider, {
429
+ value: floatingLevel,
430
+ children
431
+ })
432
+ }) : /* @__PURE__ */ jsx("div", {
433
+ "data-sidebar": "sidebar",
434
+ className: cn("flex h-full w-full min-h-0 flex-col", bordered && variant === "sidebar" && (side === "left" ? "border-r border-border" : "border-l border-border")),
435
+ children
436
+ }),
437
+ rail && /* @__PURE__ */ jsx(SidebarRail, {
438
+ tooltipOpen: railTooltipOpen,
439
+ className: cn(variant === "floating" && (side === "left" ? "right-1 after:right-[3.5px]" : "left-1 after:left-[3.5px]"), variant !== "sidebar" && "after:inset-y-2 after:[mask-image:linear-gradient(to_bottom,transparent_var(--rail-fade-start),black_var(--rail-fade-end),black_calc(100%-var(--rail-fade-end)),transparent_calc(100%-var(--rail-fade-start)))]"),
440
+ style: variant !== "sidebar" ? {
441
+ "--rail-fade-start": `${shape.bgRadius >= 20 ? 24 : 12}px`,
442
+ "--rail-fade-end": `${(shape.bgRadius >= 20 ? 24 : 12) + 24}px`
443
+ } : undefined
444
+ })
445
+ ]
446
+ })
447
+ });
448
+ });
449
+ SidebarShell.displayName = "SidebarShell";
450
+ function ShortcutKbd({ children }) {
451
+ return /* @__PURE__ */ jsx("kbd", {
452
+ className: "-my-1 flex h-4 min-w-4 items-center justify-center rounded border border-background/30 px-1 font-sans text-micro-compact text-background/80",
453
+ children
454
+ });
455
+ }
456
+ function useShortcutKey() {
457
+ const { side, shortcut } = useSidebar();
458
+ return shortcut ?? (side === "right" ? SIDEBAR_KEYBOARD_SHORTCUT_RIGHT : SIDEBAR_KEYBOARD_SHORTCUT);
459
+ }
460
+ var SidebarTrigger = forwardRef(({ onClick, size, children, ...props }, ref) => {
461
+ const { toggleSidebar, open, openMobile, isMobile, side, openOnHover, registerTrigger } = useSidebar();
462
+ const shortcutKey = useShortcutKey();
463
+ const hoverMode = openOnHover && !isMobile;
464
+ const TriggerIcon = useIcon(`panel-${side}${hoverMode && !open ? "-dashed" : ""}`);
465
+ const iconSize = useSizeVariant() === "compact" ? "icon-compact" : "icon";
466
+ const collapsed = isMobile ? !openMobile : !open;
467
+ const label = hoverMode ? open ? "Show sidebar on hover" : "Keep sidebar open" : collapsed ? "Expand sidebar" : "Collapse sidebar";
468
+ const node = useRef(null);
469
+ useEffect(() => node.current ? registerTrigger(node.current) : undefined, [registerTrigger]);
470
+ return /* @__PURE__ */ jsx(Tooltip, {
471
+ side: "bottom",
472
+ content: /* @__PURE__ */ jsxs("span", {
473
+ className: "flex items-center gap-1.5",
474
+ children: [
475
+ /* @__PURE__ */ jsx("span", {
476
+ className: "[text-box:trim-both_cap_alphabetic]",
477
+ children: label
478
+ }),
479
+ /* @__PURE__ */ jsx(ShortcutKbd, {
480
+ children: shortcutKey
481
+ })
482
+ ]
483
+ }),
484
+ children: /* @__PURE__ */ jsx(Button, {
485
+ ref: (element) => {
486
+ node.current = element;
487
+ if (typeof ref === "function")
488
+ ref(element);
489
+ else if (ref)
490
+ ref.current = element;
491
+ },
492
+ variant: "ghost",
493
+ size: size ?? iconSize,
494
+ "data-sidebar": "trigger",
495
+ "aria-label": hoverMode ? label : "Toggle Sidebar",
496
+ onClick: (event) => {
497
+ onClick?.(event);
498
+ toggleSidebar();
499
+ },
500
+ ...props,
501
+ children: children ?? /* @__PURE__ */ jsx(TriggerIcon, {})
502
+ })
503
+ });
504
+ });
505
+ SidebarTrigger.displayName = "SidebarTrigger";
506
+ var SidebarRail = forwardRef(({ className, tooltipOpen, ...props }, ref) => {
507
+ const { toggleSidebar, open, setOpen, setHoverOpen, setWidth, side, setIsResizing } = useSidebar();
508
+ const shortcutKey = useShortcutKey();
509
+ const railRef = useRef(null);
510
+ const dragRef = useRef(null);
511
+ const [dragging, setDragging] = useState(false);
512
+ const onPointerDown = (event) => {
513
+ const panel = railRef.current?.closest('[data-slot="sidebar"]');
514
+ if (!panel)
515
+ return;
516
+ dragRef.current = {
517
+ startX: event.clientX,
518
+ startWidth: panel.offsetWidth,
519
+ moved: false,
520
+ collapsed: false,
521
+ kept: open
522
+ };
523
+ event.currentTarget.setPointerCapture(event.pointerId);
524
+ };
525
+ const onPointerMove = (event) => {
526
+ const drag = dragRef.current;
527
+ if (!drag)
528
+ return;
529
+ const dx = event.clientX - drag.startX;
530
+ if (!drag.moved && Math.abs(dx) < 4)
531
+ return;
532
+ if (!drag.moved) {
533
+ drag.moved = true;
534
+ setDragging(true);
535
+ setIsResizing(true);
536
+ }
537
+ const delta = side === "left" ? dx : -dx;
538
+ const raw = drag.startWidth + delta;
539
+ if (raw < SIDEBAR_MIN_WIDTH - SIDEBAR_COLLAPSE_SLOP) {
540
+ if (!drag.collapsed) {
541
+ drag.collapsed = true;
542
+ setWidth(`${SIDEBAR_MIN_WIDTH}px`);
543
+ (drag.kept ? setOpen : setHoverOpen)(false);
544
+ }
545
+ return;
546
+ }
547
+ if (drag.collapsed) {
548
+ drag.collapsed = false;
549
+ (drag.kept ? setOpen : setHoverOpen)(true);
550
+ }
551
+ const next = Math.max(SIDEBAR_MIN_WIDTH, Math.min(SIDEBAR_MAX_WIDTH, raw));
552
+ setWidth(`${next}px`);
553
+ };
554
+ const onPointerUp = (event) => {
555
+ const drag = dragRef.current;
556
+ dragRef.current = null;
557
+ event.currentTarget.releasePointerCapture(event.pointerId);
558
+ setDragging(false);
559
+ setIsResizing(false);
560
+ if (drag && !drag.moved) {
561
+ if (drag.kept)
562
+ toggleSidebar();
563
+ else
564
+ setHoverOpen(false);
565
+ }
566
+ };
567
+ const onPointerCancel = () => {
568
+ dragRef.current = null;
569
+ setDragging(false);
570
+ setIsResizing(false);
571
+ };
572
+ return /* @__PURE__ */ jsx(Tooltip, {
573
+ side: side === "left" ? "right" : "left",
574
+ sideOffset: 8,
575
+ followCursor: "y",
576
+ forceOpen: dragging ? false : tooltipOpen,
577
+ content: /* @__PURE__ */ jsxs("span", {
578
+ className: "flex flex-col items-start gap-2",
579
+ children: [
580
+ /* @__PURE__ */ jsxs("span", {
581
+ className: "[text-box:trim-both_cap_alphabetic]",
582
+ children: [
583
+ /* @__PURE__ */ jsx("span", {
584
+ className: "weight-semibold",
585
+ children: "Drag"
586
+ }),
587
+ " to resize"
588
+ ]
589
+ }),
590
+ /* @__PURE__ */ jsxs("span", {
591
+ className: "flex items-center gap-1.5",
592
+ children: [
593
+ /* @__PURE__ */ jsxs("span", {
594
+ className: "[text-box:trim-both_cap_alphabetic]",
595
+ children: [
596
+ /* @__PURE__ */ jsx("span", {
597
+ className: "weight-semibold",
598
+ children: "Click"
599
+ }),
600
+ " to collapse"
601
+ ]
602
+ }),
603
+ /* @__PURE__ */ jsx(ShortcutKbd, {
604
+ children: shortcutKey
605
+ })
606
+ ]
607
+ })
608
+ ]
609
+ }),
610
+ children: /* @__PURE__ */ jsx("button", {
611
+ ref: (node) => {
612
+ railRef.current = node;
613
+ if (typeof ref === "function")
614
+ ref(node);
615
+ else if (ref)
616
+ ref.current = node;
617
+ },
618
+ type: "button",
619
+ "data-sidebar": "rail",
620
+ "aria-label": "Resize or collapse sidebar",
621
+ tabIndex: -1,
622
+ onPointerDown,
623
+ onPointerMove,
624
+ onPointerUp,
625
+ onPointerCancel,
626
+ className: cn("absolute inset-y-0 z-20 w-2 cursor-col-resize touch-none outline-none", side === "left" ? "right-0" : "left-0", "after:absolute after:inset-y-0 after:w-px after:bg-transparent hover:after:bg-foreground/25 after:transition-colors after:duration-fast", tooltipOpen && "after:bg-foreground/25", side === "left" ? "after:right-0" : "after:left-0", className),
627
+ ...props
628
+ })
629
+ });
630
+ });
631
+ SidebarRail.displayName = "SidebarRail";
632
+ var SidebarInset = forwardRef(({ className, ...props }, ref) => {
633
+ const shape = useShape();
634
+ return /* @__PURE__ */ jsx("main", {
635
+ ref,
636
+ "data-slot": "sidebar-inset",
637
+ className: cn("relative flex min-h-0 w-full min-w-0 flex-1 flex-col bg-background", "peer-data-[variant=inset]:m-2 peer-data-[variant=inset]:peer-data-[side=left]:ml-0 peer-data-[variant=inset]:peer-data-[side=right]:mr-0", "peer-data-[variant=inset]:peer-data-[state=collapsed]:peer-data-[side=left]:ml-2 peer-data-[variant=inset]:peer-data-[state=collapsed]:peer-data-[side=right]:mr-2", "transition-[margin] duration-fast", shape.bgRadius >= 20 ? "peer-data-[variant=inset]:rounded-3xl" : "peer-data-[variant=inset]:rounded-xl", "peer-data-[variant=inset]:bg-surface-2 peer-data-[variant=inset]:shadow-surface-2", className),
638
+ ...props
639
+ });
640
+ });
641
+ SidebarInset.displayName = "SidebarInset";
642
+ var SidebarInput = forwardRef(({ className, ...props }, ref) => {
643
+ const shape = useShape();
644
+ const size = useSize();
645
+ return /* @__PURE__ */ jsx("input", {
646
+ ref,
647
+ "data-sidebar": "input",
648
+ className: cn(fieldVariants(), "w-full px-3 text-foreground placeholder:text-muted-foreground outline-none", "focus-visible:ring-focus-ring", size.variant === "compact" ? "h-7" : "h-8", size.text, shape.input, className),
649
+ ...props
650
+ });
651
+ });
652
+ SidebarInput.displayName = "SidebarInput";
653
+ var SidebarHeader = forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx("div", {
654
+ ref,
655
+ "data-sidebar": "header",
656
+ className: cn("flex shrink-0 flex-col gap-2 p-2", className),
657
+ ...props
658
+ }));
659
+ SidebarHeader.displayName = "SidebarHeader";
660
+ var SidebarFooter = forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx("div", {
661
+ ref,
662
+ "data-sidebar": "footer",
663
+ className: cn("mt-auto flex shrink-0 flex-col gap-2 p-2", className),
664
+ ...props
665
+ }));
666
+ SidebarFooter.displayName = "SidebarFooter";
667
+ var SidebarSeparator = forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx("div", {
668
+ ref,
669
+ "data-sidebar": "separator",
670
+ role: "separator",
671
+ "aria-orientation": "horizontal",
672
+ className: cn("mx-2 h-px shrink-0 bg-border", className),
673
+ ...props
674
+ }));
675
+ SidebarSeparator.displayName = "SidebarSeparator";
676
+ var useIsoLayoutEffect = typeof window !== "undefined" ? useLayoutEffect : useEffect;
677
+ var SidebarGroupContext = createContext(null);
678
+ var SidebarGroup = forwardRef(({ className, collapsible = false, open: openProp, defaultOpen = true, onOpenChange, children, ...props }, ref) => {
679
+ const [uncontrolledOpen, setUncontrolledOpen] = useState(defaultOpen);
680
+ const open = openProp ?? uncontrolledOpen;
681
+ const contentId = useId();
682
+ const toggle = useCallback(() => {
683
+ const next = !(openProp ?? uncontrolledOpen);
684
+ setUncontrolledOpen(next);
685
+ onOpenChange?.(next);
686
+ }, [openProp, uncontrolledOpen, onOpenChange]);
687
+ const contentRef = useRef(null);
688
+ const [contentHeight, setContentHeight] = useState(null);
689
+ useIsoLayoutEffect(() => {
690
+ if (!collapsible)
691
+ return;
692
+ const el = contentRef.current;
693
+ if (!el || typeof ResizeObserver === "undefined")
694
+ return;
695
+ const measure = () => setContentHeight(el.offsetHeight);
696
+ measure();
697
+ const ro = new ResizeObserver(measure);
698
+ ro.observe(el);
699
+ return () => ro.disconnect();
700
+ }, [collapsible]);
701
+ const measured = contentHeight !== null;
702
+ const [settled, setSettled] = useState(open);
703
+ useEffect(() => {
704
+ if (!open)
705
+ setSettled(false);
706
+ }, [open]);
707
+ const prevOpenRef = useRef(open);
708
+ const togglingRef = useRef(false);
709
+ if (prevOpenRef.current !== open) {
710
+ prevOpenRef.current = open;
711
+ togglingRef.current = true;
712
+ }
713
+ const isHeaderAction = (k) => isValidElement(k) && (k.type === SidebarGroupAction || k.type === SidebarGroupActions);
714
+ let inner = children;
715
+ let actionsCount = 0;
716
+ if (collapsible) {
717
+ const kids = Children.toArray(children);
718
+ const labelIdx = kids.findIndex((k) => isValidElement(k) && k.type === SidebarGroupLabel);
719
+ if (labelIdx !== -1) {
720
+ const tail = kids.slice(labelIdx + 1);
721
+ const headerActions = tail.filter(isHeaderAction);
722
+ const rest = tail.filter((k) => !isHeaderAction(k));
723
+ actionsCount = headerActions.reduce((n, k) => n + (isValidElement(k) && k.type === SidebarGroupActions ? Children.count(k.props.children) : 1), 0);
724
+ inner = /* @__PURE__ */ jsxs(Fragment, {
725
+ children: [
726
+ kids.slice(0, labelIdx),
727
+ /* @__PURE__ */ jsxs("div", {
728
+ className: "group/group-header w-full",
729
+ children: [
730
+ kids[labelIdx],
731
+ headerActions
732
+ ]
733
+ }),
734
+ /* @__PURE__ */ jsx(motion.div, {
735
+ id: contentId,
736
+ "aria-hidden": open ? undefined : true,
737
+ className: cn(open && settled ? "overflow-visible" : "overflow-hidden", !measured && !open && "h-0"),
738
+ initial: false,
739
+ animate: measured ? { height: open ? contentHeight : 0, opacity: open ? 1 : 0 } : { opacity: open ? 1 : 0 },
740
+ transition: togglingRef.current ? open ? spring.moderate : spring.moderate.exit : { duration: 0 },
741
+ onAnimationComplete: () => {
742
+ togglingRef.current = false;
743
+ if (open)
744
+ setSettled(true);
745
+ },
746
+ children: /* @__PURE__ */ jsx("div", {
747
+ ref: contentRef,
748
+ className: "flex w-full min-w-0 flex-col",
749
+ ...open ? {} : { inert: "" },
750
+ children: rest
751
+ })
752
+ })
753
+ ]
754
+ });
755
+ }
756
+ }
757
+ const ctx = useMemo(() => ({ open, toggle, contentId, actionsCount }), [open, toggle, contentId, actionsCount]);
758
+ return /* @__PURE__ */ jsx("div", {
759
+ ref,
760
+ "data-sidebar": "group",
761
+ "data-state": collapsible ? open ? "open" : "closed" : undefined,
762
+ className: cn("relative flex w-full min-w-0 flex-col p-2", className),
763
+ ...props,
764
+ children: /* @__PURE__ */ jsx(SidebarGroupContext.Provider, {
765
+ value: collapsible ? ctx : null,
766
+ children: inner
767
+ })
768
+ });
769
+ });
770
+ SidebarGroup.displayName = "SidebarGroup";
771
+ var SidebarGroupLabel = forwardRef(({ className, render, asChild, children, ...props }, ref) => {
772
+ const sizeVariant = useSizeVariant();
773
+ const sizeClasses = useSize();
774
+ const group = useContext(SidebarGroupContext);
775
+ const shape = useShape();
776
+ const ChevronRightIcon = useIcon("chevron-right");
777
+ const { template, content } = resolveSlotTemplate(render, asChild, children);
778
+ const nodes = Children.toArray(content);
779
+ let textEnd = 0;
780
+ while (textEnd < nodes.length && (typeof nodes[textEnd] === "string" || typeof nodes[textEnd] === "number")) {
781
+ textEnd++;
782
+ }
783
+ const leadingText = nodes.slice(0, textEnd).join("");
784
+ const labelContent = leadingText ? /* @__PURE__ */ jsxs(Fragment, {
785
+ children: [
786
+ /* @__PURE__ */ jsx("span", {
787
+ className: "min-w-0 truncate",
788
+ children: leadingText
789
+ }),
790
+ nodes.slice(textEnd)
791
+ ]
792
+ }) : content;
793
+ if (group) {
794
+ return slotElement(template, "button", {
795
+ ref,
796
+ type: template ? undefined : "button",
797
+ "data-sidebar": "group-label",
798
+ "aria-expanded": group.open,
799
+ "aria-controls": group.contentId,
800
+ onClick: group.toggle,
801
+ style: group.actionsCount > 0 ? { "--group-actions-pad": `${group.actionsCount * 28 + 6}px` } : undefined,
802
+ className: cn("flex h-8 w-full shrink-0 cursor-pointer select-none items-center gap-2 px-2 text-left text-muted-foreground/70 outline-none", "transition-colors duration-fast hover:text-muted-foreground", group.actionsCount > 0 && "pr-[var(--group-actions-pad)]", "focus-visible:ring-1 focus-visible:ring-focus-ring", shape.item, sizeVariant === "compact" ? "text-caption-compact" : "text-caption", className),
803
+ ...props
804
+ }, /* @__PURE__ */ jsxs(Fragment, {
805
+ children: [
806
+ labelContent,
807
+ /* @__PURE__ */ jsx("span", {
808
+ className: cn("ml-auto flex h-6 shrink-0 items-center justify-center overflow-hidden", group.open ? "w-0 opacity-0 group-hover/group-header:w-6 group-hover/group-header:opacity-100 group-focus-within/group-header:w-6 group-focus-within/group-header:opacity-100 group-has-[[data-sidebar=group-action]:is([data-state=open],[data-popup-open],[aria-expanded=true])]/group-header:w-6 group-has-[[data-sidebar=group-action]:is([data-state=open],[data-popup-open],[aria-expanded=true])]/group-header:opacity-100 pointer-coarse:w-6 pointer-coarse:opacity-100" : "w-6 opacity-100"),
809
+ children: /* @__PURE__ */ jsx(motion.span, {
810
+ className: "inline-flex",
811
+ animate: { rotate: group.open ? 90 : 0 },
812
+ transition: spring.fast,
813
+ children: /* @__PURE__ */ jsx(ChevronRightIcon, {
814
+ size: sizeClasses.icon,
815
+ strokeWidth: 1.5,
816
+ className: "shrink-0"
817
+ })
818
+ })
819
+ })
820
+ ]
821
+ }));
822
+ }
823
+ return slotElement(template, "div", {
824
+ ref,
825
+ "data-sidebar": "group-label",
826
+ className: cn("flex h-8 shrink-0 items-center gap-2 px-2 text-muted-foreground/70 outline-none", sizeVariant === "compact" ? "text-caption-compact" : "text-caption", className),
827
+ ...props
828
+ }, labelContent);
829
+ });
830
+ SidebarGroupLabel.displayName = "SidebarGroupLabel";
831
+ var GroupActionsContext = createContext(false);
832
+ var SidebarGroupAction = forwardRef(({ className, render, asChild, children, ...props }, ref) => {
833
+ const shape = useShape();
834
+ const sizeClasses = useSize();
835
+ const inCluster = useContext(GroupActionsContext);
836
+ const { template, content } = resolveSlotTemplate(render, asChild, children);
837
+ return slotElement(template, "button", {
838
+ ref,
839
+ type: template ? undefined : "button",
840
+ "data-sidebar": "group-action",
841
+ className: cn(inCluster ? "relative flex size-6 items-center justify-center text-muted-foreground outline-none" : "absolute right-3.5 top-3 flex size-6 items-center justify-center text-muted-foreground outline-none", "hover:bg-hover hover:text-foreground transition-colors duration-fast", "focus-visible:ring-1 focus-visible:ring-focus-ring", "[&_svg]:size-[var(--icon-size)] [&_svg]:shrink-0 [&_svg]:stroke-[1.5] [&_svg]:transition-[stroke-width] [&_svg]:duration-fast hover:[&_svg]:stroke-[2]", shape.item, className),
842
+ ...props,
843
+ style: {
844
+ ...{ "--icon-size": `${sizeClasses.icon}px` },
845
+ ...props.style ?? {}
846
+ }
847
+ }, content);
848
+ });
849
+ SidebarGroupAction.displayName = "SidebarGroupAction";
850
+ var SidebarGroupActions = forwardRef(({ className, children, ...props }, ref) => {
851
+ return /* @__PURE__ */ jsx("div", {
852
+ ref,
853
+ "data-sidebar": "group-actions",
854
+ className: cn("absolute right-3.5 top-2 z-10 flex h-8 items-center gap-1", className),
855
+ ...props,
856
+ children: /* @__PURE__ */ jsx(GroupActionsContext.Provider, {
857
+ value: true,
858
+ children
859
+ })
860
+ });
861
+ });
862
+ SidebarGroupActions.displayName = "SidebarGroupActions";
863
+ var SidebarGroupContent = forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx("div", {
864
+ ref,
865
+ "data-sidebar": "group-content",
866
+ className: cn("w-full", className),
867
+ ...props
868
+ }));
869
+ SidebarGroupContent.displayName = "SidebarGroupContent";
870
+
871
+ // components/navigation/sidebar/sidebar-menu.tsx
872
+ import { cva } from "class-variance-authority";
873
+ import { AnimatePresence, motion as motion2 } from "motion/react";
874
+ import {
875
+ Children as Children2,
876
+ createContext as createContext2,
877
+ forwardRef as forwardRef2,
878
+ useCallback as useCallback2,
879
+ useContext as useContext2,
880
+ useEffect as useEffect2,
881
+ useId as useId2,
882
+ useLayoutEffect as useLayoutEffect2,
883
+ useMemo as useMemo2,
884
+ useRef as useRef2,
885
+ useState as useState2
886
+ } from "react";
887
+ import { jsx as jsx2, jsxs as jsxs2, Fragment as Fragment2 } from "react/jsx-runtime";
888
+ var useIsoLayoutEffect2 = typeof window !== "undefined" ? useLayoutEffect2 : useEffect2;
889
+ var MenuScopeContext = createContext2(null);
890
+ var SidebarSelection = createContext2(null);
891
+ var MenuItemContext = createContext2(null);
892
+ var MenuActionsClusterContext = createContext2(false);
893
+ function rowHidden(el) {
894
+ return el.closest('[data-sidebar="menu-sub"][data-state="closed"]') !== null;
895
+ }
896
+ var DISABLED_CONTROL = ':disabled, [aria-disabled="true"]';
897
+ function rowDisabled(el) {
898
+ return el.matches(DISABLED_CONTROL) || el.querySelector(`:scope > [data-sidebar="menu-button"]:is(${DISABLED_CONTROL}), :scope > [data-sidebar="menu-sub-button"]:is(${DISABLED_CONTROL})`) !== null;
899
+ }
900
+ function rowSkipped(el) {
901
+ return rowHidden(el) || rowDisabled(el);
902
+ }
903
+ var overlayGroupSeq = 0;
904
+ var overlayGroupIds = new WeakMap;
905
+ function overlayGroupId(el) {
906
+ let id = overlayGroupIds.get(el);
907
+ if (id === undefined) {
908
+ id = ++overlayGroupSeq;
909
+ overlayGroupIds.set(el, id);
910
+ }
911
+ return id;
912
+ }
913
+ function byDomOrder(a, b) {
914
+ return a.compareDocumentPosition(b) & Node.DOCUMENT_POSITION_FOLLOWING ? -1 : 1;
915
+ }
916
+ function sameElements(a, b) {
917
+ return a.length === b.length && a.every((el, i) => el === b[i]);
918
+ }
919
+ function useMenuScope(containerRef, { focusRing = true } = {}) {
920
+ const { activeIndex, setActiveIndex, itemRects, isMeasured, sessionRef, handlers, registerItem } = useFluidHover(containerRef, { isItemDisabled: rowSkipped });
921
+ const rowsRef = useRef2(new Set);
922
+ const rowButtonsRef = useRef2(new Map);
923
+ const activeMapRef = useRef2(new Map);
924
+ const [orderedRows, setOrderedRows] = useState2([]);
925
+ const orderedRowsRef = useRef2(orderedRows);
926
+ orderedRowsRef.current = orderedRows;
927
+ const registeredCountRef = useRef2(0);
928
+ const [activeRows, setActiveRows] = useState2([]);
929
+ const [focusedRowEl, setFocusedRowEl] = useState2(null);
930
+ const recomputeActive = useCallback2(() => {
931
+ const next = orderedRowsRef.current.filter((el) => activeMapRef.current.get(el) && !rowSkipped(el));
932
+ setActiveRows((prev) => sameElements(prev, next) ? prev : next);
933
+ }, []);
934
+ const rowButton = useCallback2((row) => rowButtonsRef.current.get(row) ?? row.querySelector(':scope > [data-sidebar="menu-button"], :scope > [data-sidebar="menu-sub-button"]'), []);
935
+ const syncRows = useCallback2(() => {
936
+ const sorted = [...rowsRef.current].sort(byDomOrder);
937
+ orderedRowsRef.current = sorted;
938
+ setOrderedRows((prev) => sameElements(prev, sorted) ? prev : sorted);
939
+ sorted.forEach((el, i) => registerItem(i, rowButton(el) ?? el));
940
+ for (let i = sorted.length;i < registeredCountRef.current; i++) {
941
+ registerItem(i, null);
942
+ }
943
+ registeredCountRef.current = sorted.length;
944
+ recomputeActive();
945
+ }, [registerItem, recomputeActive, rowButton]);
946
+ const registerRow = useCallback2((el) => {
947
+ rowsRef.current.add(el);
948
+ syncRows();
949
+ return () => {
950
+ rowsRef.current.delete(el);
951
+ rowButtonsRef.current.delete(el);
952
+ activeMapRef.current.delete(el);
953
+ syncRows();
954
+ };
955
+ }, [syncRows]);
956
+ const setRowButton = useCallback2((row, button) => {
957
+ if (button)
958
+ rowButtonsRef.current.set(row, button);
959
+ else
960
+ rowButtonsRef.current.delete(row);
961
+ syncRows();
962
+ }, [syncRows]);
963
+ const setRowActive = useCallback2((row, active) => {
964
+ activeMapRef.current.set(row, active);
965
+ recomputeActive();
966
+ }, [recomputeActive]);
967
+ const refreshVisibility = useCallback2(() => {
968
+ recomputeActive();
969
+ setActiveIndex((prev) => {
970
+ const row = prev !== null ? orderedRowsRef.current[prev] : undefined;
971
+ return row && rowSkipped(row) ? null : prev;
972
+ });
973
+ }, [recomputeActive, setActiveIndex]);
974
+ const overlayRect = useCallback2((row) => {
975
+ if (!row)
976
+ return null;
977
+ const idx = orderedRowsRef.current.indexOf(row);
978
+ const rect = idx === -1 ? null : itemRects[idx];
979
+ if (!rect)
980
+ return null;
981
+ const height = Math.min(rect.height, rowButton(row)?.offsetHeight ?? 48);
982
+ return { ...rect, height };
983
+ }, [itemRects, rowButton]);
984
+ const popupOpen = useCallback2(() => {
985
+ const container = containerRef.current;
986
+ if (!container)
987
+ return false;
988
+ const root = container.closest('[data-slot="sidebar-wrapper"]') ?? container;
989
+ return !!root.querySelector('[data-sidebar="menu-button"][data-state="open"], [data-sidebar="menu-button"][data-popup-open], [data-sidebar="menu-action"][data-state="open"], [data-sidebar="menu-action"][data-popup-open]');
990
+ }, [containerRef]);
991
+ const onMouseMove = useCallback2((e) => {
992
+ if (popupOpen())
993
+ return;
994
+ handlers.onMouseMove(e);
995
+ }, [popupOpen, handlers]);
996
+ const onFocus = useCallback2((e) => {
997
+ const target = e.target;
998
+ if (!target.closest('[data-sidebar="menu-button"],[data-sidebar="menu-sub-button"]'))
999
+ return;
1000
+ const row = target.closest('[data-sidebar="menu-item"],[data-sidebar="menu-sub-item"]');
1001
+ if (!row)
1002
+ return;
1003
+ const idx = orderedRowsRef.current.indexOf(row);
1004
+ if (idx === -1)
1005
+ return;
1006
+ setActiveIndex(idx);
1007
+ setFocusedRowEl(target.matches(":focus-visible") ? row : null);
1008
+ }, [setActiveIndex]);
1009
+ const onPointerDown = useCallback2(() => {
1010
+ setFocusedRowEl(null);
1011
+ }, []);
1012
+ const onBlur = useCallback2((e) => {
1013
+ if (containerRef.current?.contains(e.relatedTarget))
1014
+ return;
1015
+ setFocusedRowEl(null);
1016
+ setActiveIndex(null);
1017
+ }, [containerRef, setActiveIndex]);
1018
+ const onKeyDown = useCallback2((e) => {
1019
+ if (!["ArrowDown", "ArrowUp", "ArrowRight", "ArrowLeft", "Home", "End"].includes(e.key))
1020
+ return;
1021
+ const container = containerRef.current;
1022
+ if (!container)
1023
+ return;
1024
+ const items = Array.from(container.querySelectorAll('[data-sidebar="menu-button"], [data-sidebar="menu-sub-button"]')).filter((el) => !el.closest('[data-sidebar="menu-sub"][data-state="closed"]'));
1025
+ const currentIdx = items.indexOf(e.target);
1026
+ if (currentIdx === -1)
1027
+ return;
1028
+ e.preventDefault();
1029
+ e.stopPropagation();
1030
+ if (e.key === "Home")
1031
+ items[0]?.focus();
1032
+ else if (e.key === "End")
1033
+ items[items.length - 1]?.focus();
1034
+ else {
1035
+ const next = ["ArrowDown", "ArrowRight"].includes(e.key) ? (currentIdx + 1) % items.length : (currentIdx - 1 + items.length) % items.length;
1036
+ items[next]?.focus();
1037
+ }
1038
+ }, [containerRef]);
1039
+ const hoveredRowEl = activeIndex !== null ? orderedRows[activeIndex] ?? null : null;
1040
+ const value = useMemo2(() => ({
1041
+ registerRow,
1042
+ setRowButton,
1043
+ setRowActive,
1044
+ hoveredRowEl,
1045
+ activeRows,
1046
+ firstRowEl: orderedRows[0] ?? null,
1047
+ hasActive: activeRows.length > 0,
1048
+ refreshVisibility
1049
+ }), [registerRow, setRowButton, setRowActive, hoveredRowEl, activeRows, orderedRows, refreshVisibility]);
1050
+ const shape = useShape();
1051
+ const rowLevel = useCallback2((row) => row.closest('[data-sidebar="menu-sub"]') ?? containerRef.current, [containerRef]);
1052
+ const prevTargetsRef = useRef2({ hover: null, focus: null, actives: new Map });
1053
+ const levelOccurrence = new Map;
1054
+ const levelFirstActive = new Map;
1055
+ const activeRects = [];
1056
+ for (const row of activeRows) {
1057
+ const level = rowLevel(row);
1058
+ if (!level)
1059
+ continue;
1060
+ const levelId = overlayGroupId(level);
1061
+ const occurrence = levelOccurrence.get(levelId) ?? 0;
1062
+ levelOccurrence.set(levelId, occurrence + 1);
1063
+ if (!levelFirstActive.has(levelId))
1064
+ levelFirstActive.set(levelId, row);
1065
+ const rect = overlayRect(row);
1066
+ if (rect)
1067
+ activeRects.push({
1068
+ key: `${levelId}:${occurrence}`,
1069
+ rect,
1070
+ row,
1071
+ rowChanged: prevTargetsRef.current.actives.get(`${levelId}:${occurrence}`) !== row
1072
+ });
1073
+ }
1074
+ const hoverRect = overlayRect(hoveredRowEl);
1075
+ const focusRect = focusRing ? overlayRect(focusedRowEl) : null;
1076
+ const hoverRowChanged = prevTargetsRef.current.hover !== hoveredRowEl;
1077
+ const focusRowChanged = prevTargetsRef.current.focus !== focusedRowEl;
1078
+ useIsoLayoutEffect2(() => {
1079
+ prevTargetsRef.current = {
1080
+ hover: hoveredRowEl,
1081
+ focus: focusedRowEl,
1082
+ actives: new Map(activeRects.map(({ key, row }) => [key, row]))
1083
+ };
1084
+ });
1085
+ const hoveredLevel = hoveredRowEl ? rowLevel(hoveredRowEl) : null;
1086
+ const hoverAnchorRow = (hoveredLevel ? levelFirstActive.get(overlayGroupId(hoveredLevel)) : undefined) ?? levelFirstActive.values().next().value;
1087
+ const hoverAnchorRect = hoverAnchorRow ? overlayRect(hoverAnchorRow) : null;
1088
+ const overlays = isMeasured ? /* @__PURE__ */ jsxs2(Fragment2, {
1089
+ children: [
1090
+ /* @__PURE__ */ jsx2(AnimatePresence, {
1091
+ children: activeRects.map(({ key, rect, rowChanged }) => /* @__PURE__ */ jsx2(motion2.div, {
1092
+ className: "pointer-events-none absolute top-0 left-0",
1093
+ initial: false,
1094
+ animate: { opacity: 1 },
1095
+ exit: { opacity: 0, transition: spring.moderate.exit },
1096
+ children: /* @__PURE__ */ jsx2(GooIndicator, {
1097
+ rect,
1098
+ className: cn("bg-active", shape.bg),
1099
+ transition: rowChanged ? spring.moderate : false
1100
+ })
1101
+ }, key))
1102
+ }),
1103
+ /* @__PURE__ */ jsx2(FluidHoverHighlight, {
1104
+ rect: hoverRect,
1105
+ session: sessionRef.current,
1106
+ from: hoverAnchorRect,
1107
+ className: shape.bg,
1108
+ transition: hoverRowChanged ? undefined : false
1109
+ }),
1110
+ /* @__PURE__ */ jsx2(AnimatePresence, {
1111
+ children: focusRect && /* @__PURE__ */ jsx2(motion2.div, {
1112
+ className: `absolute ${shape.focusRing} pointer-events-none z-20 border border-focus-ring`,
1113
+ initial: false,
1114
+ animate: {
1115
+ left: focusRect.left - 2,
1116
+ top: focusRect.top - 2,
1117
+ width: focusRect.width + 4,
1118
+ height: focusRect.height + 4
1119
+ },
1120
+ exit: { opacity: 0, transition: spring.fast.exit },
1121
+ transition: focusRowChanged ? { ...spring.fast, opacity: { duration: 0.08 } } : { duration: 0 }
1122
+ })
1123
+ })
1124
+ ]
1125
+ }) : null;
1126
+ return {
1127
+ value,
1128
+ containerProps: {
1129
+ onMouseEnter: handlers.onMouseEnter,
1130
+ onMouseMove,
1131
+ onMouseLeave: handlers.onMouseLeave,
1132
+ onClick: handlers.onClick,
1133
+ onFocus,
1134
+ onBlur,
1135
+ onPointerDown,
1136
+ onKeyDown
1137
+ },
1138
+ overlays
1139
+ };
1140
+ }
1141
+ var SidebarMenu = forwardRef2(({ className, size, focusRing, children, ...props }, ref) => {
1142
+ const containerRef = useRef2(null);
1143
+ const { value, containerProps, overlays } = useMenuScope(containerRef, { focusRing });
1144
+ const content = /* @__PURE__ */ jsx2(MenuScopeContext.Provider, {
1145
+ value,
1146
+ children: /* @__PURE__ */ jsxs2("ul", {
1147
+ ref: (node) => {
1148
+ containerRef.current = node;
1149
+ if (typeof ref === "function")
1150
+ ref(node);
1151
+ else if (ref)
1152
+ ref.current = node;
1153
+ },
1154
+ "data-sidebar": "menu",
1155
+ className: cn("relative flex w-full min-w-0 flex-col select-none", className),
1156
+ ...containerProps,
1157
+ ...props,
1158
+ children: [
1159
+ overlays,
1160
+ children
1161
+ ]
1162
+ })
1163
+ });
1164
+ return size ? /* @__PURE__ */ jsx2(SizeProvider, {
1165
+ size,
1166
+ children: content
1167
+ }) : content;
1168
+ });
1169
+ SidebarMenu.displayName = "SidebarMenu";
1170
+ function useMenuRow(rowRef, isSubRow = false, sub) {
1171
+ const scope = useContext2(MenuScopeContext);
1172
+ const registerRow = scope?.registerRow;
1173
+ const setRowButton = scope?.setRowButton;
1174
+ const setRowActive = scope?.setRowActive;
1175
+ const activeFlagRef = useRef2(false);
1176
+ useIsoLayoutEffect2(() => {
1177
+ const el = rowRef.current;
1178
+ if (!el || !registerRow)
1179
+ return;
1180
+ return registerRow(el);
1181
+ }, [registerRow, rowRef]);
1182
+ const attachRow = useCallback2((node) => {
1183
+ rowRef.current = node;
1184
+ if (node && setRowActive)
1185
+ setRowActive(node, activeFlagRef.current);
1186
+ }, [setRowActive, rowRef]);
1187
+ const setActive = useCallback2((active) => {
1188
+ activeFlagRef.current = active;
1189
+ if (rowRef.current && setRowActive)
1190
+ setRowActive(rowRef.current, active);
1191
+ }, [setRowActive, rowRef]);
1192
+ const setButtonEl = useCallback2((el) => {
1193
+ if (rowRef.current && setRowButton)
1194
+ setRowButton(rowRef.current, el);
1195
+ }, [setRowButton, rowRef]);
1196
+ const isHovered = rowRef.current !== null && scope?.hoveredRowEl === rowRef.current;
1197
+ const isActiveRow = rowRef.current !== null && (scope?.activeRows.includes(rowRef.current) ?? false);
1198
+ const [trailing, setTrailing] = useState2({
1199
+ actionCount: 0,
1200
+ actionsShowOnHover: false,
1201
+ hasBadge: false
1202
+ });
1203
+ const setActions = useCallback2((count, showOnHover) => setTrailing((prev) => prev.actionCount === count && prev.actionsShowOnHover === showOnHover ? prev : { ...prev, actionCount: count, actionsShowOnHover: showOnHover }), []);
1204
+ const setHasBadge = useCallback2((hasBadge) => setTrailing((prev) => prev.hasBadge === hasBadge ? prev : { ...prev, hasBadge }), []);
1205
+ const [open, setOpen] = useControllableState(sub?.open, sub?.defaultOpen ?? false, sub?.onOpenChange);
1206
+ const subOpen = sub?.collapsible ? open : undefined;
1207
+ const toggleSub = useCallback2(() => setOpen((prev) => !prev), [setOpen]);
1208
+ return useMemo2(() => ({
1209
+ rowRef,
1210
+ attachRow,
1211
+ isHovered,
1212
+ isActiveRow,
1213
+ isSubRow,
1214
+ setActive,
1215
+ setButtonEl,
1216
+ ...trailing,
1217
+ setActions,
1218
+ setHasBadge,
1219
+ subOpen,
1220
+ toggleSub
1221
+ }), [
1222
+ rowRef,
1223
+ attachRow,
1224
+ isHovered,
1225
+ isActiveRow,
1226
+ isSubRow,
1227
+ setActive,
1228
+ setButtonEl,
1229
+ trailing,
1230
+ setActions,
1231
+ setHasBadge,
1232
+ subOpen,
1233
+ toggleSub
1234
+ ]);
1235
+ }
1236
+ var ROW_BASE_PAD = 8;
1237
+ var ROW_SLOT = 24;
1238
+ var ROW_GAP = 4;
1239
+ var ROW_BADGE_INSET = 8;
1240
+ var ROW_ACTION_INSET = 6;
1241
+ function rowGutter(actionCount, hasBadge) {
1242
+ if (!actionCount && !hasBadge)
1243
+ return ROW_BASE_PAD;
1244
+ const actionsWidth = actionCount ? actionCount * ROW_SLOT + (actionCount - 1) * ROW_GAP : 0;
1245
+ const runWidth = (hasBadge ? ROW_SLOT : 0) + actionsWidth + (hasBadge && actionCount ? ROW_GAP : 0);
1246
+ const inset = hasBadge ? ROW_BADGE_INSET : ROW_ACTION_INSET;
1247
+ return inset + runWidth + ROW_GAP;
1248
+ }
1249
+ var SidebarMenuItem = forwardRef2(({ collapsible, open, defaultOpen, onOpenChange, className, children, ...props }, ref) => {
1250
+ const rowRef = useRef2(null);
1251
+ const item = useMenuRow(rowRef, false, { collapsible, open, defaultOpen, onOpenChange });
1252
+ const { attachRow } = item;
1253
+ const refCb = useCallback2((node) => {
1254
+ attachRow(node);
1255
+ if (typeof ref === "function")
1256
+ ref(node);
1257
+ else if (ref)
1258
+ ref.current = node;
1259
+ }, [attachRow, ref]);
1260
+ return /* @__PURE__ */ jsx2(MenuItemContext.Provider, {
1261
+ value: item,
1262
+ children: /* @__PURE__ */ jsx2("li", {
1263
+ ref: refCb,
1264
+ "data-sidebar": "menu-item",
1265
+ className: cn("group/menu-item relative", className),
1266
+ ...props,
1267
+ children
1268
+ })
1269
+ });
1270
+ });
1271
+ SidebarMenuItem.displayName = "SidebarMenuItem";
1272
+ var SidebarMenuSubItem = forwardRef2(({ className, children, ...props }, ref) => {
1273
+ const rowRef = useRef2(null);
1274
+ const item = useMenuRow(rowRef, true);
1275
+ const { attachRow } = item;
1276
+ const refCb = useCallback2((node) => {
1277
+ attachRow(node);
1278
+ if (typeof ref === "function")
1279
+ ref(node);
1280
+ else if (ref)
1281
+ ref.current = node;
1282
+ }, [attachRow, ref]);
1283
+ return /* @__PURE__ */ jsx2(MenuItemContext.Provider, {
1284
+ value: item,
1285
+ children: /* @__PURE__ */ jsx2("li", {
1286
+ ref: refCb,
1287
+ "data-sidebar": "menu-sub-item",
1288
+ className: cn("group/menu-sub-item relative", className),
1289
+ ...props,
1290
+ children
1291
+ })
1292
+ });
1293
+ });
1294
+ SidebarMenuSubItem.displayName = "SidebarMenuSubItem";
1295
+ function MenuRowLabel({
1296
+ content,
1297
+ lit,
1298
+ emphasized,
1299
+ textClass
1300
+ }) {
1301
+ const nodes = Children2.toArray(content);
1302
+ const textParts = [];
1303
+ let i = 0;
1304
+ while (i < nodes.length && (typeof nodes[i] === "string" || typeof nodes[i] === "number")) {
1305
+ textParts.push(String(nodes[i]));
1306
+ i++;
1307
+ }
1308
+ const label = textParts.join("");
1309
+ const rest = nodes.slice(i);
1310
+ if (!label) {
1311
+ return /* @__PURE__ */ jsx2("span", {
1312
+ className: cn("flex min-w-0 flex-1 items-center gap-2 transition-colors duration-fast", lit ? "text-foreground" : "text-muted-foreground", textClass),
1313
+ children: content
1314
+ });
1315
+ }
1316
+ return /* @__PURE__ */ jsxs2(Fragment2, {
1317
+ children: [
1318
+ /* @__PURE__ */ jsxs2("span", {
1319
+ className: cn("inline-grid min-w-0 text-left", textClass),
1320
+ children: [
1321
+ /* @__PURE__ */ jsx2("span", {
1322
+ className: "col-start-1 row-start-1 invisible truncate pt-[0.25em] -mt-[0.25em] pb-[0.25em] -mb-[0.25em] weight-semibold [text-box:trim-both_cap_alphabetic]",
1323
+ "aria-hidden": "true",
1324
+ children: label
1325
+ }),
1326
+ /* @__PURE__ */ jsx2("span", {
1327
+ className: cn("col-start-1 row-start-1 truncate pt-[0.25em] -mt-[0.25em] pb-[0.25em] -mb-[0.25em] transition-[color,font-variation-settings] duration-fast [text-box:trim-both_cap_alphabetic]", lit ? "text-foreground" : "text-muted-foreground", emphasized ? "weight-semibold" : "weight-normal"),
1328
+ children: label
1329
+ })
1330
+ ]
1331
+ }),
1332
+ rest
1333
+ ]
1334
+ });
1335
+ }
1336
+ var sidebarMenuButtonVariants = cva("peer/menu-button relative z-10 flex w-full cursor-pointer select-none items-center gap-2 pl-2 text-left outline-none disabled:opacity-50 disabled:pointer-events-none transition-[padding] duration-fast pr-[var(--row-gutter)] group-hover/menu-item:pr-[var(--row-gutter-hover)] group-focus-within/menu-item:pr-[var(--row-gutter-hover)] group-hover/menu-sub-item:pr-[var(--row-gutter-hover)] group-focus-within/menu-sub-item:pr-[var(--row-gutter-hover)] group-has-[[data-sidebar=menu-action]:is([data-state=open],[data-popup-open],[aria-expanded=true])]/menu-item:pr-[var(--row-gutter-hover)] group-has-[[data-sidebar=menu-action]:is([data-state=open],[data-popup-open],[aria-expanded=true])]/menu-sub-item:pr-[var(--row-gutter-hover)]", {
1337
+ variants: {
1338
+ variant: {
1339
+ default: "",
1340
+ outline: "border border-border bg-background"
1341
+ }
1342
+ },
1343
+ defaultVariants: { variant: "default" }
1344
+ });
1345
+ var SidebarMenuButton = forwardRef2(({
1346
+ isActive = false,
1347
+ size = "default",
1348
+ variant,
1349
+ icon: Icon,
1350
+ status,
1351
+ dot,
1352
+ value,
1353
+ render,
1354
+ asChild,
1355
+ className,
1356
+ style,
1357
+ onClick,
1358
+ children,
1359
+ ...props
1360
+ }, ref) => {
1361
+ const scope = useContext2(MenuScopeContext);
1362
+ const item = useContext2(MenuItemContext);
1363
+ const selection = useContext2(SidebarSelection);
1364
+ const shape = useShape();
1365
+ const sizeClasses = useSize();
1366
+ const buttonRef = useRef2(null);
1367
+ const ChevronRightIcon = useIcon("chevron-right");
1368
+ const subOpen = item?.subOpen;
1369
+ const collapsible = subOpen !== undefined;
1370
+ const effectiveActive = isActive || (value === undefined ? status === "active" : selection?.value === value);
1371
+ const setActive = item?.setActive;
1372
+ useIsoLayoutEffect2(() => {
1373
+ setActive?.(effectiveActive);
1374
+ return () => setActive?.(false);
1375
+ }, [effectiveActive, setActive]);
1376
+ const setButtonEl = item?.setButtonEl;
1377
+ useIsoLayoutEffect2(() => {
1378
+ setButtonEl?.(buttonRef.current);
1379
+ return () => setButtonEl?.(null);
1380
+ }, [setButtonEl]);
1381
+ const resolvedDot = dot ?? (status ? status === "idle" ? "ring" : "filled" : undefined);
1382
+ const lit = effectiveActive || (item?.isHovered ?? false);
1383
+ const heightClass = size === "sm" ? "h-7" : size === "lg" ? "h-12" : sizeClasses.variant === "compact" ? "h-7" : "h-8";
1384
+ const textClass = size === "sm" ? "text-body-compact" : sizeClasses.text;
1385
+ const row = item?.rowRef.current ?? null;
1386
+ const tabIdx = effectiveActive ? 0 : scope?.hasActive ? -1 : row !== null && row === scope?.firstRowEl ? 0 : -1;
1387
+ const gutterHover = rowGutter(item?.actionCount ?? 0, item?.hasBadge ?? false);
1388
+ const gutterRest = item?.actionsShowOnHover ? rowGutter(0, item?.hasBadge ?? false) : gutterHover;
1389
+ const gutterVars = {
1390
+ "--row-gutter": `${gutterRest}px`,
1391
+ "--row-gutter-hover": `${gutterHover}px`
1392
+ };
1393
+ const { template, content } = resolveSlotTemplate(render, asChild, children);
1394
+ const inner = /* @__PURE__ */ jsxs2(Fragment2, {
1395
+ children: [
1396
+ Icon && /* @__PURE__ */ jsx2(Icon, {
1397
+ size: sizeClasses.icon,
1398
+ strokeWidth: lit ? 2 : 1.5,
1399
+ className: cn("shrink-0 transition-[color,stroke-width] duration-fast", lit ? "text-foreground" : "text-muted-foreground")
1400
+ }),
1401
+ !Icon && resolvedDot && /* @__PURE__ */ jsx2("span", {
1402
+ className: "flex shrink-0 items-center justify-center",
1403
+ style: { width: sizeClasses.icon, height: sizeClasses.icon },
1404
+ children: /* @__PURE__ */ jsx2("span", {
1405
+ className: cn("size-2 rounded-full transition-colors duration-fast", resolvedDot === "filled" ? lit ? "bg-foreground/60" : "bg-muted-foreground/50" : lit ? "border border-foreground/60" : "border border-muted-foreground/50")
1406
+ })
1407
+ }),
1408
+ /* @__PURE__ */ jsx2(MenuRowLabel, {
1409
+ content,
1410
+ lit,
1411
+ emphasized: effectiveActive,
1412
+ textClass
1413
+ }),
1414
+ status === "unread" && /* @__PURE__ */ jsx2("span", {
1415
+ className: "sr-only",
1416
+ children: ", unread"
1417
+ }),
1418
+ collapsible && /* @__PURE__ */ jsx2("span", {
1419
+ className: "ml-auto -mr-0.5 flex size-6 shrink-0 items-center justify-center",
1420
+ children: /* @__PURE__ */ jsx2(motion2.span, {
1421
+ className: "inline-flex",
1422
+ animate: { rotate: subOpen ? 90 : 0 },
1423
+ transition: spring.fast,
1424
+ children: /* @__PURE__ */ jsx2(ChevronRightIcon, {
1425
+ size: sizeClasses.icon,
1426
+ strokeWidth: 1.5,
1427
+ className: cn("text-muted-foreground transition-opacity duration-fast", subOpen ? "opacity-0 group-hover/parent-row:opacity-100 group-focus-within/parent-row:opacity-100" : "opacity-100")
1428
+ })
1429
+ })
1430
+ })
1431
+ ]
1432
+ });
1433
+ return slotElement(template, "button", {
1434
+ ref: (node) => {
1435
+ buttonRef.current = node;
1436
+ if (typeof ref === "function")
1437
+ ref(node);
1438
+ else if (ref)
1439
+ ref.current = node;
1440
+ },
1441
+ type: template ? undefined : "button",
1442
+ "data-sidebar": "menu-button",
1443
+ "data-size": size,
1444
+ "data-active": effectiveActive ? "true" : undefined,
1445
+ "data-status": status,
1446
+ "aria-current": effectiveActive ? "page" : undefined,
1447
+ "aria-expanded": subOpen,
1448
+ tabIndex: tabIdx,
1449
+ className: cn(sidebarMenuButtonVariants({ variant }), heightClass, shape.item, collapsible && "group/parent-row", className),
1450
+ onClick: (event) => {
1451
+ onClick?.(event);
1452
+ if (collapsible)
1453
+ item?.toggleSub();
1454
+ else if (value !== undefined)
1455
+ selection?.select(value);
1456
+ },
1457
+ ...props,
1458
+ style: {
1459
+ ...gutterVars,
1460
+ ...collapsible ? { "--row-gutter": "var(--row-gutter-hover)" } : {},
1461
+ ...style
1462
+ }
1463
+ }, inner);
1464
+ });
1465
+ SidebarMenuButton.displayName = "SidebarMenuButton";
1466
+ var SidebarMenuAction = forwardRef2(({ className, showOnHover = false, render, asChild, children, onClick, ...props }, ref) => {
1467
+ const shape = useShape();
1468
+ const sizeClasses = useSize();
1469
+ const item = useContext2(MenuItemContext);
1470
+ const inCluster = useContext2(MenuActionsClusterContext);
1471
+ const { template, content } = resolveSlotTemplate(render, asChild, children);
1472
+ const setActions = item?.setActions;
1473
+ useIsoLayoutEffect2(() => {
1474
+ if (inCluster || !setActions)
1475
+ return;
1476
+ setActions(1, showOnHover);
1477
+ return () => setActions(0, false);
1478
+ }, [inCluster, setActions, showOnHover]);
1479
+ return slotElement(template, "button", {
1480
+ ref,
1481
+ type: template ? undefined : "button",
1482
+ "data-sidebar": "menu-action",
1483
+ "data-show-on-hover": showOnHover ? "" : undefined,
1484
+ className: cn(inCluster ? "relative flex size-6 shrink-0 items-center justify-center text-muted-foreground outline-none" : "absolute right-1.5 z-10 flex size-6 items-center justify-center text-muted-foreground outline-none", !inCluster && (item?.isSubRow ? "group-has-[>[data-sidebar=menu-badge]]/menu-sub-item:right-8.5" : "group-has-[>[data-sidebar=menu-badge]]/menu-item:right-8.5"), !inCluster && (item?.isSubRow || sizeClasses.variant === "compact" ? "top-0.5" : "top-1"), "hover:bg-hover hover:text-foreground transition-[color,background-color,opacity] duration-fast", "focus-visible:ring-1 focus-visible:ring-focus-ring", "[&_svg]:size-[var(--icon-size)] [&_svg]:shrink-0 [&_svg]:stroke-[1.5] [&_svg]:transition-[stroke-width] [&_svg]:duration-fast hover:[&_svg]:stroke-[2]", shape.item, !inCluster && showOnHover && (item?.isSubRow ? "opacity-0 group-hover/menu-sub-item:opacity-100 group-focus-within/menu-sub-item:opacity-100 data-[state=open]:opacity-100 aria-expanded:opacity-100" : "opacity-0 peer-hover/menu-button:opacity-100 peer-focus-visible/menu-button:opacity-100 hover:opacity-100 focus-visible:opacity-100 data-[state=open]:opacity-100 aria-expanded:opacity-100"), className),
1485
+ onClick: (event) => {
1486
+ event.stopPropagation();
1487
+ onClick?.(event);
1488
+ },
1489
+ ...props,
1490
+ style: { ...{ "--icon-size": `${sizeClasses.icon}px` }, ...props.style ?? {} }
1491
+ }, content);
1492
+ });
1493
+ SidebarMenuAction.displayName = "SidebarMenuAction";
1494
+ var SidebarMenuActions = forwardRef2(({ className, showOnHover = false, children, ...props }, ref) => {
1495
+ const item = useContext2(MenuItemContext);
1496
+ const sizeClasses = useSize();
1497
+ const count = Children2.count(children);
1498
+ const setActions = item?.setActions;
1499
+ useIsoLayoutEffect2(() => {
1500
+ setActions?.(count, showOnHover);
1501
+ return () => setActions?.(0, false);
1502
+ }, [setActions, count, showOnHover]);
1503
+ return /* @__PURE__ */ jsx2("div", {
1504
+ ref,
1505
+ "data-sidebar": "menu-actions",
1506
+ className: cn("absolute right-1.5 z-10 flex items-center gap-1", item?.isSubRow ? "group-has-[>[data-sidebar=menu-badge]]/menu-sub-item:right-8.5" : "group-has-[>[data-sidebar=menu-badge]]/menu-item:right-8.5", item?.isSubRow || sizeClasses.variant === "compact" ? "top-0.5" : "top-1", showOnHover && (item?.isSubRow ? "opacity-0 transition-opacity duration-fast group-hover/menu-sub-item:opacity-100 group-focus-within/menu-sub-item:opacity-100 has-[[data-state=open]]:opacity-100 has-[[data-popup-open]]:opacity-100" : "opacity-0 transition-opacity duration-fast peer-hover/menu-button:opacity-100 peer-focus-visible/menu-button:opacity-100 hover:opacity-100 focus-within:opacity-100 has-[[data-state=open]]:opacity-100 has-[[data-popup-open]]:opacity-100"), className),
1507
+ ...props,
1508
+ children: /* @__PURE__ */ jsx2(MenuActionsClusterContext.Provider, {
1509
+ value: true,
1510
+ children
1511
+ })
1512
+ });
1513
+ });
1514
+ SidebarMenuActions.displayName = "SidebarMenuActions";
1515
+ var SidebarMenuBadge = forwardRef2(({ className, ...props }, ref) => {
1516
+ const item = useContext2(MenuItemContext);
1517
+ const sizeClasses = useSize();
1518
+ const lit = item?.isActiveRow ?? false;
1519
+ const setHasBadge = item?.setHasBadge;
1520
+ useIsoLayoutEffect2(() => {
1521
+ setHasBadge?.(true);
1522
+ return () => setHasBadge?.(false);
1523
+ }, [setHasBadge]);
1524
+ return /* @__PURE__ */ jsx2("div", {
1525
+ ref,
1526
+ "data-sidebar": "menu-badge",
1527
+ className: cn("pointer-events-none absolute right-2 z-10 flex h-5 min-w-5 items-center justify-center px-1 tabular-nums", sizeClasses.variant === "compact" ? "top-1 text-micro-compact" : "top-1.5 text-micro", "transition-[color,font-variation-settings] duration-fast", lit ? "text-foreground weight-semibold" : "text-muted-foreground weight-normal", className),
1528
+ ...props
1529
+ });
1530
+ });
1531
+ SidebarMenuBadge.displayName = "SidebarMenuBadge";
1532
+ var SKELETON_WIDTHS = ["62%", "74%", "55%", "82%", "68%"];
1533
+ var SidebarMenuSkeleton = forwardRef2(({ className, showIcon = false, ...props }, ref) => {
1534
+ const sizeClasses = useSize();
1535
+ const id = useId2();
1536
+ let sum = 0;
1537
+ for (let i = 0;i < id.length; i++)
1538
+ sum += id.charCodeAt(i);
1539
+ const width = SKELETON_WIDTHS[sum % SKELETON_WIDTHS.length];
1540
+ return /* @__PURE__ */ jsxs2("div", {
1541
+ ref,
1542
+ "data-sidebar": "menu-skeleton",
1543
+ className: cn("flex items-center gap-2 px-2", sizeClasses.variant === "compact" ? "h-7" : "h-8", className),
1544
+ ...props,
1545
+ children: [
1546
+ showIcon && /* @__PURE__ */ jsx2("div", {
1547
+ "data-sidebar": "menu-skeleton-icon",
1548
+ className: "size-4 shrink-0 animate-pulse rounded-md bg-hover"
1549
+ }),
1550
+ /* @__PURE__ */ jsx2("div", {
1551
+ "data-sidebar": "menu-skeleton-text",
1552
+ className: "h-4 flex-1 animate-pulse rounded-md bg-hover",
1553
+ style: { maxWidth: width }
1554
+ })
1555
+ ]
1556
+ });
1557
+ });
1558
+ SidebarMenuSkeleton.displayName = "SidebarMenuSkeleton";
1559
+ var SidebarMenuSub = forwardRef2(({ className, open: openProp, children, ...props }, ref) => {
1560
+ const containerRef = useRef2(null);
1561
+ const row = useContext2(MenuItemContext);
1562
+ const open = openProp ?? row?.subOpen ?? true;
1563
+ const scope = useContext2(MenuScopeContext);
1564
+ const refreshVisibility = scope?.refreshVisibility;
1565
+ useIsoLayoutEffect2(() => {
1566
+ refreshVisibility?.();
1567
+ }, [open, refreshVisibility]);
1568
+ const [contentHeight, setContentHeight] = useState2(null);
1569
+ useIsoLayoutEffect2(() => {
1570
+ const el = containerRef.current;
1571
+ if (!el || typeof ResizeObserver === "undefined")
1572
+ return;
1573
+ const measure = () => setContentHeight(el.offsetHeight);
1574
+ measure();
1575
+ const ro = new ResizeObserver(measure);
1576
+ ro.observe(el);
1577
+ return () => ro.disconnect();
1578
+ }, []);
1579
+ const measured = contentHeight !== null;
1580
+ const prevOpenRef = useRef2(open);
1581
+ const togglingRef = useRef2(false);
1582
+ if (prevOpenRef.current !== open) {
1583
+ prevOpenRef.current = open;
1584
+ togglingRef.current = true;
1585
+ }
1586
+ return /* @__PURE__ */ jsx2(motion2.div, {
1587
+ "data-slot": "sidebar-menu-sub-wrapper",
1588
+ className: cn("overflow-hidden", !measured && !open && "h-0"),
1589
+ initial: false,
1590
+ animate: measured ? { height: open ? contentHeight : 0, opacity: open ? 1 : 0 } : { opacity: open ? 1 : 0 },
1591
+ transition: togglingRef.current ? open ? spring.moderate : spring.moderate.exit : { duration: 0 },
1592
+ onAnimationComplete: () => {
1593
+ togglingRef.current = false;
1594
+ },
1595
+ children: /* @__PURE__ */ jsx2("ul", {
1596
+ ref: (node) => {
1597
+ containerRef.current = node;
1598
+ if (typeof ref === "function")
1599
+ ref(node);
1600
+ else if (ref)
1601
+ ref.current = node;
1602
+ },
1603
+ "data-sidebar": "menu-sub",
1604
+ "data-state": open ? "open" : "closed",
1605
+ "aria-hidden": open ? undefined : true,
1606
+ ...open ? {} : { inert: "" },
1607
+ className: cn("relative ml-[15px] flex min-w-0 flex-col border-l border-border pl-2 select-none", className),
1608
+ ...props,
1609
+ children
1610
+ })
1611
+ });
1612
+ });
1613
+ SidebarMenuSub.displayName = "SidebarMenuSub";
1614
+ var SidebarMenuSubButton = forwardRef2(({
1615
+ isActive: isActiveProp = false,
1616
+ size = "md",
1617
+ icon: Icon,
1618
+ value,
1619
+ render,
1620
+ asChild,
1621
+ className,
1622
+ onClick,
1623
+ children,
1624
+ ...props
1625
+ }, ref) => {
1626
+ const item = useContext2(MenuItemContext);
1627
+ const selection = useContext2(SidebarSelection);
1628
+ const isActive = isActiveProp || value !== undefined && selection?.value === value;
1629
+ const shape = useShape();
1630
+ const sizeClasses = useSize();
1631
+ const buttonRef = useRef2(null);
1632
+ const setActive = item?.setActive;
1633
+ useIsoLayoutEffect2(() => {
1634
+ setActive?.(isActive);
1635
+ return () => setActive?.(false);
1636
+ }, [isActive, setActive]);
1637
+ const setButtonEl = item?.setButtonEl;
1638
+ useIsoLayoutEffect2(() => {
1639
+ setButtonEl?.(buttonRef.current);
1640
+ return () => setButtonEl?.(null);
1641
+ }, [setButtonEl]);
1642
+ const lit = isActive || (item?.isHovered ?? false);
1643
+ const tabIdx = isActive ? 0 : -1;
1644
+ const gutterHover = rowGutter(item?.actionCount ?? 0, item?.hasBadge ?? false);
1645
+ const gutterRest = item?.actionsShowOnHover ? rowGutter(0, item?.hasBadge ?? false) : gutterHover;
1646
+ const gutterVars = {
1647
+ "--row-gutter": `${gutterRest}px`,
1648
+ "--row-gutter-hover": `${gutterHover}px`
1649
+ };
1650
+ const { template, content } = resolveSlotTemplate(render, asChild, children);
1651
+ const asButton = !template && value !== undefined && props.href === undefined;
1652
+ return slotElement(template, asButton ? "button" : "a", {
1653
+ type: asButton ? "button" : undefined,
1654
+ ref: (node) => {
1655
+ buttonRef.current = node;
1656
+ if (typeof ref === "function")
1657
+ ref(node);
1658
+ else if (ref)
1659
+ ref.current = node;
1660
+ },
1661
+ "data-sidebar": "menu-sub-button",
1662
+ "data-size": size,
1663
+ "data-active": isActive ? "true" : undefined,
1664
+ "aria-current": isActive ? "page" : undefined,
1665
+ tabIndex: tabIdx,
1666
+ className: cn("relative z-10 flex w-full cursor-pointer select-none items-center gap-2 pl-2 text-left outline-none", "transition-[padding] duration-fast pr-[var(--row-gutter)] group-hover/menu-sub-item:pr-[var(--row-gutter-hover)] group-focus-within/menu-sub-item:pr-[var(--row-gutter-hover)] group-has-[[data-sidebar=menu-action]:is([data-state=open],[data-popup-open],[aria-expanded=true])]/menu-sub-item:pr-[var(--row-gutter-hover)]", size === "sm" ? "h-6" : sizeClasses.variant === "compact" ? "h-6" : "h-7", shape.item, className),
1667
+ onClick: (event) => {
1668
+ onClick?.(event);
1669
+ if (value !== undefined)
1670
+ selection?.select(value);
1671
+ },
1672
+ ...props,
1673
+ style: { ...gutterVars, ...props.style ?? {} }
1674
+ }, /* @__PURE__ */ jsxs2(Fragment2, {
1675
+ children: [
1676
+ Icon && /* @__PURE__ */ jsx2(Icon, {
1677
+ size: sizeClasses.icon,
1678
+ strokeWidth: lit ? 2 : 1.5,
1679
+ className: cn("shrink-0 transition-[color,stroke-width] duration-fast", lit ? "text-foreground" : "text-muted-foreground")
1680
+ }),
1681
+ /* @__PURE__ */ jsx2(MenuRowLabel, {
1682
+ content,
1683
+ lit,
1684
+ emphasized: isActive,
1685
+ textClass: size === "sm" ? "text-body-compact" : sizeClasses.text
1686
+ })
1687
+ ]
1688
+ }));
1689
+ });
1690
+ SidebarMenuSubButton.displayName = "SidebarMenuSubButton";
1691
+
1692
+ // components/navigation/sidebar/index.tsx
1693
+ import { jsx as jsx3, jsxs as jsxs3, Fragment as Fragment3 } from "react/jsx-runtime";
1694
+ function SidebarSheet({ side, children }) {
1695
+ const { openMobile, setOpenMobile, widthMobile } = useSidebar();
1696
+ return /* @__PURE__ */ jsx3(Sheet, {
1697
+ side,
1698
+ open: openMobile,
1699
+ onOpenChange: setOpenMobile,
1700
+ children: /* @__PURE__ */ jsx3(Sheet.Content, {
1701
+ "aria-label": "Sidebar",
1702
+ "data-sidebar": "sidebar",
1703
+ "data-mobile": "true",
1704
+ "data-side": side,
1705
+ tier: "moderate",
1706
+ className: "gap-0 overflow-hidden p-0",
1707
+ style: { width: widthMobile },
1708
+ children
1709
+ })
1710
+ });
1711
+ }
1712
+ var Sidebar = forwardRef3(({
1713
+ side = "left",
1714
+ variant = "sidebar",
1715
+ collapsible = "offcanvas",
1716
+ bordered = true,
1717
+ rail = true,
1718
+ railTooltipOpen,
1719
+ value: valueProp,
1720
+ defaultValue,
1721
+ onValueChange,
1722
+ className,
1723
+ style,
1724
+ children: parts,
1725
+ ...props
1726
+ }, ref) => {
1727
+ const { isMobile, width, registerSide } = useSidebar();
1728
+ const [value, setValue] = useControllableState(valueProp, defaultValue, onValueChange);
1729
+ const selection = useMemo3(() => ({ value, select: setValue }), [value, setValue]);
1730
+ const children = /* @__PURE__ */ jsx3(SidebarSelection.Provider, {
1731
+ value: selection,
1732
+ children: parts
1733
+ });
1734
+ useEffect3(() => registerSide(side), [side, registerSide]);
1735
+ if (collapsible === "none") {
1736
+ return /* @__PURE__ */ jsx3("div", {
1737
+ ref,
1738
+ "data-slot": "sidebar",
1739
+ "data-variant": variant,
1740
+ "data-side": side,
1741
+ className: cn("peer sticky top-0 flex h-svh shrink-0 flex-col", side === "right" && "order-last", className),
1742
+ style: { width, ...style },
1743
+ ...props,
1744
+ children: /* @__PURE__ */ jsx3("div", {
1745
+ "data-sidebar": "sidebar",
1746
+ className: cn("flex h-full w-full min-h-0 flex-col", bordered && variant === "sidebar" && (side === "left" ? "border-r border-border" : "border-l border-border")),
1747
+ children
1748
+ })
1749
+ });
1750
+ }
1751
+ return /* @__PURE__ */ jsxs3(Fragment3, {
1752
+ children: [
1753
+ isMobile && /* @__PURE__ */ jsx3(SidebarSheet, {
1754
+ side,
1755
+ children
1756
+ }),
1757
+ /* @__PURE__ */ jsx3(SidebarShell, {
1758
+ ref,
1759
+ side,
1760
+ variant,
1761
+ bordered,
1762
+ rail,
1763
+ railTooltipOpen,
1764
+ className,
1765
+ style,
1766
+ ...props,
1767
+ children
1768
+ })
1769
+ ]
1770
+ });
1771
+ });
1772
+ Sidebar.displayName = "Sidebar";
1773
+ var SidebarContent = forwardRef3(({ className, viewportClassName, children, ...props }, ref) => {
1774
+ const { isMobile } = useSidebar();
1775
+ if (isMobile) {
1776
+ return /* @__PURE__ */ jsx3("div", {
1777
+ className: "scroll-divider [--scroll-divider-inset:8px] flex min-h-0 w-full flex-1 flex-col",
1778
+ children: /* @__PURE__ */ jsx3("div", {
1779
+ ref,
1780
+ "data-sidebar": "content",
1781
+ className: cn("scroll-fade flex min-h-0 w-full flex-1 flex-col overflow-y-auto", className),
1782
+ ...props,
1783
+ children
1784
+ })
1785
+ });
1786
+ }
1787
+ return /* @__PURE__ */ jsx3(ScrollArea, {
1788
+ className: cn("scroll-divider min-h-0 w-full flex-1", className),
1789
+ viewportClassName: cn("scroll-fade [&>div]:!block [&>div]:!min-w-0", viewportClassName),
1790
+ children: /* @__PURE__ */ jsx3("div", {
1791
+ ref,
1792
+ "data-sidebar": "content",
1793
+ className: "flex w-full min-w-0 flex-col",
1794
+ ...props,
1795
+ children
1796
+ })
1797
+ });
1798
+ });
1799
+ SidebarContent.displayName = "SidebarContent";
1800
+ Object.assign(Sidebar, {
1801
+ Provider: SidebarProvider,
1802
+ Trigger: SidebarTrigger,
1803
+ Rail: SidebarRail,
1804
+ Inset: SidebarInset,
1805
+ Input: SidebarInput,
1806
+ Header: SidebarHeader,
1807
+ Content: SidebarContent,
1808
+ Footer: SidebarFooter,
1809
+ Separator: SidebarSeparator,
1810
+ Group: SidebarGroup,
1811
+ GroupLabel: SidebarGroupLabel,
1812
+ GroupAction: SidebarGroupAction,
1813
+ GroupActions: SidebarGroupActions,
1814
+ GroupContent: SidebarGroupContent,
1815
+ Menu: SidebarMenu,
1816
+ MenuItem: SidebarMenuItem,
1817
+ MenuButton: SidebarMenuButton,
1818
+ MenuAction: SidebarMenuAction,
1819
+ MenuActions: SidebarMenuActions,
1820
+ MenuBadge: SidebarMenuBadge,
1821
+ MenuSkeleton: SidebarMenuSkeleton,
1822
+ MenuSub: SidebarMenuSub,
1823
+ MenuSubItem: SidebarMenuSubItem,
1824
+ MenuSubButton: SidebarMenuSubButton
1825
+ });
1826
+ var sidebar_default = Sidebar;
1827
+
1828
+ export { SIDEBAR_COOKIE_NAME, SIDEBAR_COOKIE_MAX_AGE, SIDEBAR_WIDTH, SIDEBAR_WIDTH_MOBILE, SIDEBAR_KEYBOARD_SHORTCUT, SIDEBAR_KEYBOARD_SHORTCUT_RIGHT, SIDEBAR_MIN_WIDTH, SIDEBAR_MAX_WIDTH, useSidebar, SidebarProvider, SidebarTrigger, SidebarRail, SidebarInset, SidebarInput, SidebarHeader, SidebarFooter, SidebarSeparator, SidebarGroup, SidebarGroupLabel, SidebarGroupAction, SidebarGroupActions, SidebarGroupContent, SidebarSelection, SidebarMenu, SidebarMenuItem, SidebarMenuSubItem, sidebarMenuButtonVariants, SidebarMenuButton, SidebarMenuAction, SidebarMenuActions, SidebarMenuBadge, SidebarMenuSkeleton, SidebarMenuSub, SidebarMenuSubButton, Sidebar, SidebarContent, sidebar_default };