@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.
- package/LICENSE +21 -0
- package/LICENSE.beui +21 -0
- package/LICENSE.fluid-functionalism +21 -0
- package/LICENSE.motion-primitives +21 -0
- package/LICENSE.sileo +21 -0
- package/README.md +608 -2
- package/dist/base.css +994 -0
- package/dist/blocks/sidebar-app/index.d.ts +34 -0
- package/dist/blocks/sidebar-app/index.js +34 -0
- package/dist/components/badge/index.d.ts +59 -0
- package/dist/components/badge/index.js +18 -0
- package/dist/components/button/index.d.ts +59 -0
- package/dist/components/button/index.js +16 -0
- package/dist/components/card/index.d.ts +141 -0
- package/dist/components/card/index.js +44 -0
- package/dist/components/inputs/checkbox-group/index.d.ts +50 -0
- package/dist/components/inputs/checkbox-group/index.js +23 -0
- package/dist/components/inputs/color-picker/index.d.ts +137 -0
- package/dist/components/inputs/color-picker/index.js +37 -0
- package/dist/components/inputs/combobox/index.d.ts +161 -0
- package/dist/components/inputs/combobox/index.js +41 -0
- package/dist/components/inputs/date-time/calendar/index.d.ts +45 -0
- package/dist/components/inputs/date-time/calendar/index.js +20 -0
- package/dist/components/inputs/date-time/date-picker/index.d.ts +82 -0
- package/dist/components/inputs/date-time/date-picker/index.js +34 -0
- package/dist/components/inputs/date-time/date-range-picker/index.d.ts +64 -0
- package/dist/components/inputs/date-time/date-range-picker/index.js +33 -0
- package/dist/components/inputs/date-time/duration-picker/index.d.ts +57 -0
- package/dist/components/inputs/date-time/duration-picker/index.js +33 -0
- package/dist/components/inputs/date-time/month-picker/index.d.ts +57 -0
- package/dist/components/inputs/date-time/month-picker/index.js +32 -0
- package/dist/components/inputs/date-time/time-picker/index.d.ts +59 -0
- package/dist/components/inputs/date-time/time-picker/index.js +33 -0
- package/dist/components/inputs/input/index.d.ts +84 -0
- package/dist/components/inputs/input/index.js +20 -0
- package/dist/components/inputs/input-copy/index.d.ts +44 -0
- package/dist/components/inputs/input-copy/index.js +18 -0
- package/dist/components/inputs/input-message/index.d.ts +125 -0
- package/dist/components/inputs/input-message/index.js +27 -0
- package/dist/components/inputs/radio-group/index.d.ts +58 -0
- package/dist/components/inputs/radio-group/index.js +22 -0
- package/dist/components/inputs/search/index.d.ts +83 -0
- package/dist/components/inputs/search/index.js +28 -0
- package/dist/components/inputs/select/index.d.ts +105 -0
- package/dist/components/inputs/select/index.js +37 -0
- package/dist/components/inputs/slider/index.d.ts +108 -0
- package/dist/components/inputs/slider/index.js +16 -0
- package/dist/components/inputs/switch/index.d.ts +43 -0
- package/dist/components/inputs/switch/index.js +16 -0
- package/dist/components/navigation/accordion/index.d.ts +117 -0
- package/dist/components/navigation/accordion/index.js +30 -0
- package/dist/components/navigation/sidebar/index.d.ts +388 -0
- package/dist/components/navigation/sidebar/index.js +101 -0
- package/dist/components/navigation/tabs/index.d.ts +70 -0
- package/dist/components/navigation/tabs/index.js +25 -0
- package/dist/components/navigation/tabs-subtle/index.d.ts +73 -0
- package/dist/components/navigation/tabs-subtle/index.js +23 -0
- package/dist/components/overlays/alert-dialog/index.d.ts +67 -0
- package/dist/components/overlays/alert-dialog/index.js +24 -0
- package/dist/components/overlays/command/index.d.ts +121 -0
- package/dist/components/overlays/command/index.js +39 -0
- package/dist/components/overlays/context-menu/index.d.ts +97 -0
- package/dist/components/overlays/context-menu/index.js +32 -0
- package/dist/components/overlays/dialog/index.d.ts +130 -0
- package/dist/components/overlays/dialog/index.js +39 -0
- package/dist/components/overlays/dropdown/index.d.ts +222 -0
- package/dist/components/overlays/dropdown/index.js +47 -0
- package/dist/components/overlays/popover/index.d.ts +87 -0
- package/dist/components/overlays/popover/index.js +28 -0
- package/dist/components/overlays/preview-card/index.d.ts +75 -0
- package/dist/components/overlays/preview-card/index.js +21 -0
- package/dist/components/overlays/sheet/index.d.ts +67 -0
- package/dist/components/overlays/sheet/index.js +26 -0
- package/dist/components/overlays/toast/index.d.ts +107 -0
- package/dist/components/overlays/toast/index.js +23 -0
- package/dist/components/overlays/tooltip/index.d.ts +75 -0
- package/dist/components/overlays/tooltip/index.js +19 -0
- package/dist/components/table/index.d.ts +44 -0
- package/dist/components/table/index.js +28 -0
- package/dist/components/thinking-indicator/index.d.ts +32 -0
- package/dist/components/thinking-indicator/index.js +15 -0
- package/dist/index.d.ts +3926 -0
- package/dist/index.js +513 -0
- package/dist/preset.d.ts +104 -0
- package/dist/preset.js +124 -0
- package/dist/primitives/code/index.d.ts +23 -0
- package/dist/primitives/code/index.js +12 -0
- package/dist/primitives/craft/index.d.ts +31 -0
- package/dist/primitives/craft/index.js +13 -0
- package/dist/primitives/fluid-hover/index.d.ts +233 -0
- package/dist/primitives/fluid-hover/index.js +27 -0
- package/dist/primitives/morph/index.d.ts +127 -0
- package/dist/primitives/morph/index.js +21 -0
- package/dist/primitives/motion/index.d.ts +115 -0
- package/dist/primitives/motion/index.js +20 -0
- package/dist/primitives/scroll-area/index.d.ts +41 -0
- package/dist/primitives/scroll-area/index.js +13 -0
- package/dist/primitives/sizes/index.d.ts +128 -0
- package/dist/primitives/sizes/index.js +22 -0
- package/dist/primitives/surface/index.d.ts +69 -0
- package/dist/primitives/surface/index.js +18 -0
- package/dist/shared/components-0f0as45n.js +17 -0
- package/dist/shared/components-40j34hdb.js +986 -0
- package/dist/shared/components-4hh0gm0v.js +292 -0
- package/dist/shared/components-4xxddc44.js +15 -0
- package/dist/shared/components-4xxtggzp.js +110 -0
- package/dist/shared/components-54nf2x99.js +293 -0
- package/dist/shared/components-5pkcfprd.js +232 -0
- package/dist/shared/components-5vxtcp88.js +9 -0
- package/dist/shared/components-5zry9te1.js +152 -0
- package/dist/shared/components-61ckf42z.js +220 -0
- package/dist/shared/components-6hzwfmfd.js +58 -0
- package/dist/shared/components-6phwsry6.js +361 -0
- package/dist/shared/components-6t6nr33r.js +86 -0
- package/dist/shared/components-6y1th6k4.js +111 -0
- package/dist/shared/components-74c20v2f.js +32 -0
- package/dist/shared/components-7cqq1sqy.js +193 -0
- package/dist/shared/components-7gv95yfy.js +496 -0
- package/dist/shared/components-7nww01w4.js +375 -0
- package/dist/shared/components-7zp99w5d.js +62 -0
- package/dist/shared/components-8hk9ve3r.js +1200 -0
- package/dist/shared/components-8hzbsfbd.js +123 -0
- package/dist/shared/components-9p8s8n5q.js +171 -0
- package/dist/shared/components-aaq3yk4f.js +304 -0
- package/dist/shared/components-bf2d9k02.js +484 -0
- package/dist/shared/components-bkvb6nem.js +63 -0
- package/dist/shared/components-brnzrp2t.js +262 -0
- package/dist/shared/components-csxz9f52.js +42 -0
- package/dist/shared/components-de8xsm9y.js +22 -0
- package/dist/shared/components-dg0w8g5p.js +26 -0
- package/dist/shared/components-dphg9gjr.js +42 -0
- package/dist/shared/components-e46kf6cp.js +298 -0
- package/dist/shared/components-ed7cmssr.js +105 -0
- package/dist/shared/components-ess3ch6w.js +137 -0
- package/dist/shared/components-gjfrycb5.js +984 -0
- package/dist/shared/components-gndm6am4.js +128 -0
- package/dist/shared/components-hjkrv00c.js +191 -0
- package/dist/shared/components-hzfp4tjb.js +270 -0
- package/dist/shared/components-j65qt1mq.js +719 -0
- package/dist/shared/components-jw16snbn.js +19 -0
- package/dist/shared/components-jxgznftn.js +146 -0
- package/dist/shared/components-kf2ehztc.js +216 -0
- package/dist/shared/components-kpbcms10.js +9 -0
- package/dist/shared/components-m5br529r.js +141 -0
- package/dist/shared/components-nn6xezy2.js +1828 -0
- package/dist/shared/components-nnnd2xef.js +9 -0
- package/dist/shared/components-p2vmyfe1.js +345 -0
- package/dist/shared/components-peg09pzs.js +79 -0
- package/dist/shared/components-r22vtgqc.js +45 -0
- package/dist/shared/components-r2gke5p6.js +1759 -0
- package/dist/shared/components-r43mqnd6.js +160 -0
- package/dist/shared/components-r4jt6hgd.js +58 -0
- package/dist/shared/components-rc63qsy6.js +159 -0
- package/dist/shared/components-s3yfvfkr.js +149 -0
- package/dist/shared/components-s5pkbjx1.js +445 -0
- package/dist/shared/components-tad5h7ta.js +346 -0
- package/dist/shared/components-taxmgbnh.js +120 -0
- package/dist/shared/components-tm88ghva.js +215 -0
- package/dist/shared/components-v7es8aan.js +144 -0
- package/dist/shared/components-vb033rns.js +28 -0
- package/dist/shared/components-vc1k7yv2.js +30 -0
- package/dist/shared/components-vktws5r6.js +667 -0
- package/dist/shared/components-x2xyckd5.js +198 -0
- package/dist/shared/components-x3rz4cyn.js +61 -0
- package/dist/shared/components-xszag63d.js +141 -0
- package/dist/shared/components-y3cqdrgy.js +291 -0
- package/dist/shared/components-zvb11ker.js +288 -0
- package/dist/shared/components-zx2hr57f.js +124 -0
- package/dist/styles.css +1949 -0
- package/dist/tailwind.css +219 -0
- package/dist/tokens.css +345 -0
- 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 };
|