@inui/design-system 0.0.0-stage → 1.22.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/README.md +360 -2
- package/dist/components/ui/accordion.d.ts +44 -0
- package/dist/components/ui/accordion.d.ts.map +1 -0
- package/dist/components/ui/accordion.js +86 -0
- package/dist/components/ui/accordion.js.map +1 -0
- package/dist/components/ui/ai-avatar.d.ts +46 -0
- package/dist/components/ui/ai-avatar.d.ts.map +1 -0
- package/dist/components/ui/ai-avatar.js +43 -0
- package/dist/components/ui/ai-avatar.js.map +1 -0
- package/dist/components/ui/ai-label.d.ts +118 -0
- package/dist/components/ui/ai-label.d.ts.map +1 -0
- package/dist/components/ui/ai-label.js +184 -0
- package/dist/components/ui/ai-label.js.map +1 -0
- package/dist/components/ui/ai-sparkle.d.ts +91 -0
- package/dist/components/ui/ai-sparkle.d.ts.map +1 -0
- package/dist/components/ui/ai-sparkle.js +200 -0
- package/dist/components/ui/ai-sparkle.js.map +1 -0
- package/dist/components/ui/alert-dialog.d.ts +79 -0
- package/dist/components/ui/alert-dialog.d.ts.map +1 -0
- package/dist/components/ui/alert-dialog.js +147 -0
- package/dist/components/ui/alert-dialog.js.map +1 -0
- package/dist/components/ui/alert.d.ts +71 -0
- package/dist/components/ui/alert.d.ts.map +1 -0
- package/dist/components/ui/alert.js +108 -0
- package/dist/components/ui/alert.js.map +1 -0
- package/dist/components/ui/aspect-ratio.d.ts +30 -0
- package/dist/components/ui/aspect-ratio.d.ts.map +1 -0
- package/dist/components/ui/aspect-ratio.js +40 -0
- package/dist/components/ui/aspect-ratio.js.map +1 -0
- package/dist/components/ui/attachment.d.ts +74 -0
- package/dist/components/ui/attachment.d.ts.map +1 -0
- package/dist/components/ui/attachment.js +142 -0
- package/dist/components/ui/attachment.js.map +1 -0
- package/dist/components/ui/avatar.d.ts +82 -0
- package/dist/components/ui/avatar.d.ts.map +1 -0
- package/dist/components/ui/avatar.js +123 -0
- package/dist/components/ui/avatar.js.map +1 -0
- package/dist/components/ui/badge.d.ts +130 -0
- package/dist/components/ui/badge.d.ts.map +1 -0
- package/dist/components/ui/badge.js +226 -0
- package/dist/components/ui/badge.js.map +1 -0
- package/dist/components/ui/breadcrumb.d.ts +43 -0
- package/dist/components/ui/breadcrumb.d.ts.map +1 -0
- package/dist/components/ui/breadcrumb.js +98 -0
- package/dist/components/ui/breadcrumb.js.map +1 -0
- package/dist/components/ui/browser-tabs.d.ts +218 -0
- package/dist/components/ui/browser-tabs.d.ts.map +1 -0
- package/dist/components/ui/browser-tabs.js +528 -0
- package/dist/components/ui/browser-tabs.js.map +1 -0
- package/dist/components/ui/bubble.d.ts +80 -0
- package/dist/components/ui/bubble.d.ts.map +1 -0
- package/dist/components/ui/bubble.js +235 -0
- package/dist/components/ui/bubble.js.map +1 -0
- package/dist/components/ui/button-group.d.ts +60 -0
- package/dist/components/ui/button-group.d.ts.map +1 -0
- package/dist/components/ui/button-group.js +89 -0
- package/dist/components/ui/button-group.js.map +1 -0
- package/dist/components/ui/button.d.ts +157 -0
- package/dist/components/ui/button.d.ts.map +1 -0
- package/dist/components/ui/button.js +144 -0
- package/dist/components/ui/button.js.map +1 -0
- package/dist/components/ui/calendar.d.ts +57 -0
- package/dist/components/ui/calendar.d.ts.map +1 -0
- package/dist/components/ui/calendar.js +163 -0
- package/dist/components/ui/calendar.js.map +1 -0
- package/dist/components/ui/card.d.ts +96 -0
- package/dist/components/ui/card.d.ts.map +1 -0
- package/dist/components/ui/card.js +131 -0
- package/dist/components/ui/card.js.map +1 -0
- package/dist/components/ui/carousel.d.ts +86 -0
- package/dist/components/ui/carousel.d.ts.map +1 -0
- package/dist/components/ui/carousel.js +207 -0
- package/dist/components/ui/carousel.js.map +1 -0
- package/dist/components/ui/checkbox.d.ts +54 -0
- package/dist/components/ui/checkbox.d.ts.map +1 -0
- package/dist/components/ui/checkbox.js +78 -0
- package/dist/components/ui/checkbox.js.map +1 -0
- package/dist/components/ui/collapsible.d.ts +45 -0
- package/dist/components/ui/collapsible.d.ts.map +1 -0
- package/dist/components/ui/collapsible.js +65 -0
- package/dist/components/ui/collapsible.js.map +1 -0
- package/dist/components/ui/combobox.d.ts +111 -0
- package/dist/components/ui/combobox.d.ts.map +1 -0
- package/dist/components/ui/combobox.js +264 -0
- package/dist/components/ui/combobox.js.map +1 -0
- package/dist/components/ui/command.d.ts +71 -0
- package/dist/components/ui/command.d.ts.map +1 -0
- package/dist/components/ui/command.js +133 -0
- package/dist/components/ui/command.js.map +1 -0
- package/dist/components/ui/context-menu.d.ts +70 -0
- package/dist/components/ui/context-menu.d.ts.map +1 -0
- package/dist/components/ui/context-menu.js +163 -0
- package/dist/components/ui/context-menu.js.map +1 -0
- package/dist/components/ui/count-badge.d.ts +40 -0
- package/dist/components/ui/count-badge.d.ts.map +1 -0
- package/dist/components/ui/count-badge.js +43 -0
- package/dist/components/ui/count-badge.js.map +1 -0
- package/dist/components/ui/data-table.d.ts +1026 -0
- package/dist/components/ui/data-table.d.ts.map +1 -0
- package/dist/components/ui/data-table.js +3423 -0
- package/dist/components/ui/data-table.js.map +1 -0
- package/dist/components/ui/dialog.d.ts +73 -0
- package/dist/components/ui/dialog.d.ts.map +1 -0
- package/dist/components/ui/dialog.js +145 -0
- package/dist/components/ui/dialog.js.map +1 -0
- package/dist/components/ui/direction.d.ts +35 -0
- package/dist/components/ui/direction.d.ts.map +1 -0
- package/dist/components/ui/direction.js +35 -0
- package/dist/components/ui/direction.js.map +1 -0
- package/dist/components/ui/drawer.d.ts +53 -0
- package/dist/components/ui/drawer.d.ts.map +1 -0
- package/dist/components/ui/drawer.js +115 -0
- package/dist/components/ui/drawer.js.map +1 -0
- package/dist/components/ui/dropdown-menu.d.ts +75 -0
- package/dist/components/ui/dropdown-menu.d.ts.map +1 -0
- package/dist/components/ui/dropdown-menu.js +173 -0
- package/dist/components/ui/dropdown-menu.js.map +1 -0
- package/dist/components/ui/dropzone.d.ts +141 -0
- package/dist/components/ui/dropzone.d.ts.map +1 -0
- package/dist/components/ui/dropzone.js +257 -0
- package/dist/components/ui/dropzone.js.map +1 -0
- package/dist/components/ui/empty.d.ts +94 -0
- package/dist/components/ui/empty.d.ts.map +1 -0
- package/dist/components/ui/empty.js +149 -0
- package/dist/components/ui/empty.js.map +1 -0
- package/dist/components/ui/field.d.ts +122 -0
- package/dist/components/ui/field.d.ts.map +1 -0
- package/dist/components/ui/field.js +254 -0
- package/dist/components/ui/field.js.map +1 -0
- package/dist/components/ui/hover-card.d.ts +51 -0
- package/dist/components/ui/hover-card.d.ts.map +1 -0
- package/dist/components/ui/hover-card.js +101 -0
- package/dist/components/ui/hover-card.js.map +1 -0
- package/dist/components/ui/input-group.d.ts +62 -0
- package/dist/components/ui/input-group.d.ts.map +1 -0
- package/dist/components/ui/input-group.js +115 -0
- package/dist/components/ui/input-group.js.map +1 -0
- package/dist/components/ui/input-otp.d.ts +52 -0
- package/dist/components/ui/input-otp.d.ts.map +1 -0
- package/dist/components/ui/input-otp.js +89 -0
- package/dist/components/ui/input-otp.js.map +1 -0
- package/dist/components/ui/input.d.ts +47 -0
- package/dist/components/ui/input.d.ts.map +1 -0
- package/dist/components/ui/input.js +47 -0
- package/dist/components/ui/input.js.map +1 -0
- package/dist/components/ui/item.d.ts +74 -0
- package/dist/components/ui/item.d.ts.map +1 -0
- package/dist/components/ui/item.js +176 -0
- package/dist/components/ui/item.js.map +1 -0
- package/dist/components/ui/kbd.d.ts +41 -0
- package/dist/components/ui/kbd.d.ts.map +1 -0
- package/dist/components/ui/kbd.js +58 -0
- package/dist/components/ui/kbd.js.map +1 -0
- package/dist/components/ui/key-value-pair.d.ts +56 -0
- package/dist/components/ui/key-value-pair.d.ts.map +1 -0
- package/dist/components/ui/key-value-pair.js +110 -0
- package/dist/components/ui/key-value-pair.js.map +1 -0
- package/dist/components/ui/label.d.ts +83 -0
- package/dist/components/ui/label.d.ts.map +1 -0
- package/dist/components/ui/label.js +85 -0
- package/dist/components/ui/label.js.map +1 -0
- package/dist/components/ui/marker.d.ts +54 -0
- package/dist/components/ui/marker.d.ts.map +1 -0
- package/dist/components/ui/marker.js +79 -0
- package/dist/components/ui/marker.js.map +1 -0
- package/dist/components/ui/menubar.d.ts +72 -0
- package/dist/components/ui/menubar.d.ts.map +1 -0
- package/dist/components/ui/menubar.js +174 -0
- package/dist/components/ui/menubar.js.map +1 -0
- package/dist/components/ui/message-scroller.d.ts +53 -0
- package/dist/components/ui/message-scroller.d.ts.map +1 -0
- package/dist/components/ui/message-scroller.js +95 -0
- package/dist/components/ui/message-scroller.js.map +1 -0
- package/dist/components/ui/message.d.ts +63 -0
- package/dist/components/ui/message.d.ts.map +1 -0
- package/dist/components/ui/message.js +92 -0
- package/dist/components/ui/message.js.map +1 -0
- package/dist/components/ui/meta-list.d.ts +55 -0
- package/dist/components/ui/meta-list.d.ts.map +1 -0
- package/dist/components/ui/meta-list.js +75 -0
- package/dist/components/ui/meta-list.js.map +1 -0
- package/dist/components/ui/native-select.d.ts +51 -0
- package/dist/components/ui/native-select.d.ts.map +1 -0
- package/dist/components/ui/native-select.js +75 -0
- package/dist/components/ui/native-select.js.map +1 -0
- package/dist/components/ui/navigation-menu.d.ts +56 -0
- package/dist/components/ui/navigation-menu.d.ts.map +1 -0
- package/dist/components/ui/navigation-menu.js +116 -0
- package/dist/components/ui/navigation-menu.js.map +1 -0
- package/dist/components/ui/page-header.d.ts +223 -0
- package/dist/components/ui/page-header.d.ts.map +1 -0
- package/dist/components/ui/page-header.js +233 -0
- package/dist/components/ui/page-header.js.map +1 -0
- package/dist/components/ui/pagination.d.ts +68 -0
- package/dist/components/ui/pagination.d.ts.map +1 -0
- package/dist/components/ui/pagination.js +145 -0
- package/dist/components/ui/pagination.js.map +1 -0
- package/dist/components/ui/popover.d.ts +61 -0
- package/dist/components/ui/popover.d.ts.map +1 -0
- package/dist/components/ui/popover.js +144 -0
- package/dist/components/ui/popover.js.map +1 -0
- package/dist/components/ui/progress.d.ts +35 -0
- package/dist/components/ui/progress.d.ts.map +1 -0
- package/dist/components/ui/progress.js +46 -0
- package/dist/components/ui/progress.js.map +1 -0
- package/dist/components/ui/questionnaire.d.ts +92 -0
- package/dist/components/ui/questionnaire.d.ts.map +1 -0
- package/dist/components/ui/questionnaire.js +277 -0
- package/dist/components/ui/questionnaire.js.map +1 -0
- package/dist/components/ui/radio-group.d.ts +50 -0
- package/dist/components/ui/radio-group.d.ts.map +1 -0
- package/dist/components/ui/radio-group.js +65 -0
- package/dist/components/ui/radio-group.js.map +1 -0
- package/dist/components/ui/resizable.d.ts +44 -0
- package/dist/components/ui/resizable.d.ts.map +1 -0
- package/dist/components/ui/resizable.js +73 -0
- package/dist/components/ui/resizable.js.map +1 -0
- package/dist/components/ui/scroll-area.d.ts +55 -0
- package/dist/components/ui/scroll-area.d.ts.map +1 -0
- package/dist/components/ui/scroll-area.js +72 -0
- package/dist/components/ui/scroll-area.js.map +1 -0
- package/dist/components/ui/select.d.ts +274 -0
- package/dist/components/ui/select.d.ts.map +1 -0
- package/dist/components/ui/select.js +609 -0
- package/dist/components/ui/select.js.map +1 -0
- package/dist/components/ui/separator.d.ts +31 -0
- package/dist/components/ui/separator.d.ts.map +1 -0
- package/dist/components/ui/separator.js +38 -0
- package/dist/components/ui/separator.js.map +1 -0
- package/dist/components/ui/sheet.d.ts +59 -0
- package/dist/components/ui/sheet.d.ts.map +1 -0
- package/dist/components/ui/sheet.js +128 -0
- package/dist/components/ui/sheet.js.map +1 -0
- package/dist/components/ui/sidebar.d.ts +166 -0
- package/dist/components/ui/sidebar.d.ts.map +1 -0
- package/dist/components/ui/sidebar.js +512 -0
- package/dist/components/ui/sidebar.js.map +1 -0
- package/dist/components/ui/skeleton.d.ts +35 -0
- package/dist/components/ui/skeleton.d.ts.map +1 -0
- package/dist/components/ui/skeleton.js +46 -0
- package/dist/components/ui/skeleton.js.map +1 -0
- package/dist/components/ui/slider.d.ts +39 -0
- package/dist/components/ui/slider.d.ts.map +1 -0
- package/dist/components/ui/slider.js +75 -0
- package/dist/components/ui/slider.js.map +1 -0
- package/dist/components/ui/sonner.d.ts +56 -0
- package/dist/components/ui/sonner.d.ts.map +1 -0
- package/dist/components/ui/sonner.js +96 -0
- package/dist/components/ui/sonner.js.map +1 -0
- package/dist/components/ui/spinner.d.ts +37 -0
- package/dist/components/ui/spinner.d.ts.map +1 -0
- package/dist/components/ui/spinner.js +51 -0
- package/dist/components/ui/spinner.js.map +1 -0
- package/dist/components/ui/stepper.d.ts +84 -0
- package/dist/components/ui/stepper.d.ts.map +1 -0
- package/dist/components/ui/stepper.js +145 -0
- package/dist/components/ui/stepper.js.map +1 -0
- package/dist/components/ui/switch.d.ts +36 -0
- package/dist/components/ui/switch.d.ts.map +1 -0
- package/dist/components/ui/switch.js +44 -0
- package/dist/components/ui/switch.js.map +1 -0
- package/dist/components/ui/table.d.ts +80 -0
- package/dist/components/ui/table.d.ts.map +1 -0
- package/dist/components/ui/table.js +130 -0
- package/dist/components/ui/table.js.map +1 -0
- package/dist/components/ui/tabs.d.ts +87 -0
- package/dist/components/ui/tabs.d.ts.map +1 -0
- package/dist/components/ui/tabs.js +128 -0
- package/dist/components/ui/tabs.js.map +1 -0
- package/dist/components/ui/textarea.d.ts +35 -0
- package/dist/components/ui/textarea.d.ts.map +1 -0
- package/dist/components/ui/textarea.js +38 -0
- package/dist/components/ui/textarea.js.map +1 -0
- package/dist/components/ui/time-picker.d.ts +58 -0
- package/dist/components/ui/time-picker.d.ts.map +1 -0
- package/dist/components/ui/time-picker.js +188 -0
- package/dist/components/ui/time-picker.js.map +1 -0
- package/dist/components/ui/toggle-group.d.ts +52 -0
- package/dist/components/ui/toggle-group.d.ts.map +1 -0
- package/dist/components/ui/toggle-group.js +94 -0
- package/dist/components/ui/toggle-group.js.map +1 -0
- package/dist/components/ui/toggle.d.ts +50 -0
- package/dist/components/ui/toggle.d.ts.map +1 -0
- package/dist/components/ui/toggle.js +70 -0
- package/dist/components/ui/toggle.js.map +1 -0
- package/dist/components/ui/tooltip.d.ts +51 -0
- package/dist/components/ui/tooltip.d.ts.map +1 -0
- package/dist/components/ui/tooltip.js +78 -0
- package/dist/components/ui/tooltip.js.map +1 -0
- package/dist/hooks/use-dark-mode.d.ts +2 -0
- package/dist/hooks/use-dark-mode.d.ts.map +1 -0
- package/dist/hooks/use-dark-mode.js +36 -0
- package/dist/hooks/use-dark-mode.js.map +1 -0
- package/dist/hooks/use-mobile.d.ts +2 -0
- package/dist/hooks/use-mobile.d.ts.map +1 -0
- package/dist/hooks/use-mobile.js +20 -0
- package/dist/hooks/use-mobile.js.map +1 -0
- package/dist/index.d.ts +88 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +77 -0
- package/dist/lib/scope.d.ts +64 -0
- package/dist/lib/scope.d.ts.map +1 -0
- package/dist/lib/scope.js +74 -0
- package/dist/lib/scope.js.map +1 -0
- package/dist/lib/utils.d.ts +3 -0
- package/dist/lib/utils.d.ts.map +1 -0
- package/dist/lib/utils.js +11 -0
- package/dist/lib/utils.js.map +1 -0
- package/dist/styles.css +2 -0
- package/dist/theme-tokens.css +537 -0
- package/dist/theme.css +417 -0
- package/package.json +103 -3
|
@@ -0,0 +1,512 @@
|
|
|
1
|
+
import { cn } from "../../lib/utils.js";
|
|
2
|
+
import { useIsMobile } from "../../hooks/use-mobile.js";
|
|
3
|
+
import { Button } from "./button.js";
|
|
4
|
+
import { Input } from "./input.js";
|
|
5
|
+
import { Tooltip as Tooltip$1, TooltipContent, TooltipTrigger } from "./tooltip.js";
|
|
6
|
+
import { Separator as Separator$1 } from "./separator.js";
|
|
7
|
+
import { Collapsible as Collapsible$1, CollapsibleContent, CollapsibleTrigger } from "./collapsible.js";
|
|
8
|
+
import { Skeleton } from "./skeleton.js";
|
|
9
|
+
import { Sheet, SheetContent, SheetDescription, SheetHeader, SheetTitle } from "./sheet.js";
|
|
10
|
+
import * as React from "react";
|
|
11
|
+
import { Slot } from "radix-ui";
|
|
12
|
+
import { ChevronDownIcon, PanelLeftIcon } from "lucide-react";
|
|
13
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
14
|
+
import { cva } from "class-variance-authority";
|
|
15
|
+
//#region src/components/ui/sidebar.tsx
|
|
16
|
+
/**
|
|
17
|
+
* Sidebar — full application side-navigation shell.
|
|
18
|
+
*
|
|
19
|
+
* Includes SidebarMenuCollapsible, an animated, disclosable nav "folder"
|
|
20
|
+
* that pairs SidebarMenuButton with Collapsible (see its own doc comment above
|
|
21
|
+
* its definition). Composed from many sub-exports; see the WHEN TO USE /
|
|
22
|
+
* KEY RULES block at the end of this file for the family as a whole.
|
|
23
|
+
*/
|
|
24
|
+
var SIDEBAR_COOKIE_NAME = "sidebar_state";
|
|
25
|
+
var SIDEBAR_COOKIE_MAX_AGE = 604800;
|
|
26
|
+
var SIDEBAR_WIDTH = "16rem";
|
|
27
|
+
var SIDEBAR_WIDTH_MOBILE = "18rem";
|
|
28
|
+
var SIDEBAR_WIDTH_ICON = "3rem";
|
|
29
|
+
var SIDEBAR_KEYBOARD_SHORTCUT = "b";
|
|
30
|
+
var SidebarContext = React.createContext(null);
|
|
31
|
+
function useSidebar() {
|
|
32
|
+
const context = React.useContext(SidebarContext);
|
|
33
|
+
if (!context) throw new Error("useSidebar must be used within a SidebarProvider.");
|
|
34
|
+
return context;
|
|
35
|
+
}
|
|
36
|
+
function SidebarProvider({ defaultOpen = true, open: openProp, onOpenChange: setOpenProp, className, style, children, ...props }) {
|
|
37
|
+
const isMobile = useIsMobile();
|
|
38
|
+
const [openMobile, setOpenMobile] = React.useState(false);
|
|
39
|
+
const contentId = React.useId();
|
|
40
|
+
const [_open, _setOpen] = React.useState(defaultOpen);
|
|
41
|
+
const open = openProp ?? _open;
|
|
42
|
+
const setOpen = React.useCallback((value) => {
|
|
43
|
+
const openState = typeof value === "function" ? value(open) : value;
|
|
44
|
+
if (setOpenProp) setOpenProp(openState);
|
|
45
|
+
else _setOpen(openState);
|
|
46
|
+
document.cookie = `${SIDEBAR_COOKIE_NAME}=${openState}; path=/; max-age=${SIDEBAR_COOKIE_MAX_AGE}`;
|
|
47
|
+
}, [setOpenProp, open]);
|
|
48
|
+
const toggleSidebar = React.useCallback(() => {
|
|
49
|
+
return isMobile ? setOpenMobile((open) => !open) : setOpen((open) => !open);
|
|
50
|
+
}, [
|
|
51
|
+
isMobile,
|
|
52
|
+
setOpen,
|
|
53
|
+
setOpenMobile
|
|
54
|
+
]);
|
|
55
|
+
React.useEffect(() => {
|
|
56
|
+
const handleKeyDown = (event) => {
|
|
57
|
+
if (event.key === SIDEBAR_KEYBOARD_SHORTCUT && (event.metaKey || event.ctrlKey)) {
|
|
58
|
+
event.preventDefault();
|
|
59
|
+
toggleSidebar();
|
|
60
|
+
}
|
|
61
|
+
};
|
|
62
|
+
window.addEventListener("keydown", handleKeyDown);
|
|
63
|
+
return () => window.removeEventListener("keydown", handleKeyDown);
|
|
64
|
+
}, [toggleSidebar]);
|
|
65
|
+
const state = open ? "expanded" : "collapsed";
|
|
66
|
+
const contextValue = React.useMemo(() => ({
|
|
67
|
+
state,
|
|
68
|
+
open,
|
|
69
|
+
setOpen,
|
|
70
|
+
isMobile,
|
|
71
|
+
openMobile,
|
|
72
|
+
setOpenMobile,
|
|
73
|
+
toggleSidebar,
|
|
74
|
+
contentId
|
|
75
|
+
}), [
|
|
76
|
+
state,
|
|
77
|
+
open,
|
|
78
|
+
setOpen,
|
|
79
|
+
isMobile,
|
|
80
|
+
openMobile,
|
|
81
|
+
setOpenMobile,
|
|
82
|
+
toggleSidebar,
|
|
83
|
+
contentId
|
|
84
|
+
]);
|
|
85
|
+
return /* @__PURE__ */ jsx(SidebarContext.Provider, {
|
|
86
|
+
value: contextValue,
|
|
87
|
+
children: /* @__PURE__ */ jsx("div", {
|
|
88
|
+
"data-slot": "sidebar-wrapper",
|
|
89
|
+
style: {
|
|
90
|
+
"--sidebar-width": SIDEBAR_WIDTH,
|
|
91
|
+
"--sidebar-width-icon": SIDEBAR_WIDTH_ICON,
|
|
92
|
+
...style
|
|
93
|
+
},
|
|
94
|
+
className: cn("group/sidebar-wrapper flex min-h-svh w-full has-data-[variant=inset]:bg-sidebar", className),
|
|
95
|
+
...props,
|
|
96
|
+
children
|
|
97
|
+
})
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
function Sidebar({ side = "left", variant = "sidebar", collapsible = "offcanvas", className, children, dir, ...props }) {
|
|
101
|
+
const { isMobile, state, openMobile, setOpenMobile, contentId } = useSidebar();
|
|
102
|
+
if (collapsible === "none") return /* @__PURE__ */ jsx("div", {
|
|
103
|
+
id: contentId,
|
|
104
|
+
"data-slot": "sidebar",
|
|
105
|
+
className: cn("flex h-full w-(--sidebar-width) flex-col bg-sidebar text-sidebar-foreground", className),
|
|
106
|
+
...props,
|
|
107
|
+
children
|
|
108
|
+
});
|
|
109
|
+
if (isMobile) return /* @__PURE__ */ jsx(Sheet, {
|
|
110
|
+
open: openMobile,
|
|
111
|
+
onOpenChange: setOpenMobile,
|
|
112
|
+
...props,
|
|
113
|
+
children: /* @__PURE__ */ jsxs(SheetContent, {
|
|
114
|
+
id: contentId,
|
|
115
|
+
dir,
|
|
116
|
+
"data-sidebar": "sidebar",
|
|
117
|
+
"data-slot": "sidebar",
|
|
118
|
+
"data-mobile": "true",
|
|
119
|
+
className: "w-(--sidebar-width) bg-sidebar p-0 text-sidebar-foreground [&>button]:hidden",
|
|
120
|
+
style: { "--sidebar-width": SIDEBAR_WIDTH_MOBILE },
|
|
121
|
+
side,
|
|
122
|
+
children: [/* @__PURE__ */ jsxs(SheetHeader, {
|
|
123
|
+
className: "sr-only",
|
|
124
|
+
children: [/* @__PURE__ */ jsx(SheetTitle, { children: "Sidebar" }), /* @__PURE__ */ jsx(SheetDescription, { children: "Displays the mobile sidebar." })]
|
|
125
|
+
}), /* @__PURE__ */ jsx("div", {
|
|
126
|
+
className: "flex h-full w-full flex-col",
|
|
127
|
+
children
|
|
128
|
+
})]
|
|
129
|
+
})
|
|
130
|
+
});
|
|
131
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
132
|
+
className: "group peer hidden text-sidebar-foreground md:block",
|
|
133
|
+
"data-state": state,
|
|
134
|
+
"data-collapsible": state === "collapsed" ? collapsible : "",
|
|
135
|
+
"data-variant": variant,
|
|
136
|
+
"data-side": side,
|
|
137
|
+
"data-slot": "sidebar",
|
|
138
|
+
children: [/* @__PURE__ */ jsx("div", {
|
|
139
|
+
"data-slot": "sidebar-gap",
|
|
140
|
+
className: cn("relative w-(--sidebar-width) bg-transparent transition-[width] duration-200 ease-linear", "group-data-[collapsible=offcanvas]:w-0", "group-data-[side=right]:rotate-180", variant === "floating" || variant === "inset" ? "group-data-[collapsible=icon]:w-[calc(var(--sidebar-width-icon)+(--spacing(4)))]" : "group-data-[collapsible=icon]:w-(--sidebar-width-icon)")
|
|
141
|
+
}), /* @__PURE__ */ jsx("div", {
|
|
142
|
+
id: contentId,
|
|
143
|
+
"data-slot": "sidebar-container",
|
|
144
|
+
"data-side": side,
|
|
145
|
+
inert: collapsible === "offcanvas" && state === "collapsed",
|
|
146
|
+
className: cn("fixed inset-y-0 z-10 hidden h-svh w-(--sidebar-width) transition-[left,right,width] duration-200 ease-linear data-[side=left]:left-0 data-[side=left]:group-data-[collapsible=offcanvas]:left-[calc(var(--sidebar-width)*-1)] data-[side=right]:right-0 data-[side=right]:group-data-[collapsible=offcanvas]:right-[calc(var(--sidebar-width)*-1)] md:flex", variant === "floating" || variant === "inset" ? "p-2 group-data-[collapsible=icon]:w-[calc(var(--sidebar-width-icon)+(--spacing(4))+2px)]" : "group-data-[collapsible=icon]:w-(--sidebar-width-icon) group-data-[side=left]:border-r group-data-[side=right]:border-l", className),
|
|
147
|
+
...props,
|
|
148
|
+
children: /* @__PURE__ */ jsx("div", {
|
|
149
|
+
"data-sidebar": "sidebar",
|
|
150
|
+
"data-slot": "sidebar-inner",
|
|
151
|
+
className: "flex size-full flex-col bg-sidebar group-data-[variant=floating]:rounded-xl group-data-[variant=floating]:shadow-sm group-data-[variant=floating]:ring-1 group-data-[variant=floating]:ring-sidebar-border",
|
|
152
|
+
children
|
|
153
|
+
})
|
|
154
|
+
})]
|
|
155
|
+
});
|
|
156
|
+
}
|
|
157
|
+
function SidebarTrigger({ className, onClick, ...props }) {
|
|
158
|
+
const { toggleSidebar, state, contentId } = useSidebar();
|
|
159
|
+
return /* @__PURE__ */ jsxs(Button, {
|
|
160
|
+
"data-sidebar": "trigger",
|
|
161
|
+
"data-slot": "sidebar-trigger",
|
|
162
|
+
variant: "ghost",
|
|
163
|
+
size: "sm",
|
|
164
|
+
iconOnly: true,
|
|
165
|
+
"aria-label": "Toggle Sidebar",
|
|
166
|
+
"aria-expanded": state === "expanded",
|
|
167
|
+
"aria-controls": contentId,
|
|
168
|
+
className: cn(className),
|
|
169
|
+
onClick: (event) => {
|
|
170
|
+
onClick?.(event);
|
|
171
|
+
toggleSidebar();
|
|
172
|
+
},
|
|
173
|
+
...props,
|
|
174
|
+
children: [/* @__PURE__ */ jsx(PanelLeftIcon, {}), /* @__PURE__ */ jsx("span", {
|
|
175
|
+
className: "sr-only",
|
|
176
|
+
children: "Toggle Sidebar"
|
|
177
|
+
})]
|
|
178
|
+
});
|
|
179
|
+
}
|
|
180
|
+
function SidebarRail({ className, ...props }) {
|
|
181
|
+
const { toggleSidebar } = useSidebar();
|
|
182
|
+
return /* @__PURE__ */ jsx("button", {
|
|
183
|
+
"data-sidebar": "rail",
|
|
184
|
+
"data-slot": "sidebar-rail",
|
|
185
|
+
"aria-label": "Toggle Sidebar",
|
|
186
|
+
tabIndex: -1,
|
|
187
|
+
onClick: toggleSidebar,
|
|
188
|
+
title: "Toggle Sidebar",
|
|
189
|
+
className: cn("absolute inset-y-0 z-20 hidden w-4 transition-colors ease-linear group-data-[side=left]:-right-4 group-data-[side=right]:left-0 after:absolute after:inset-y-0 after:start-1/2 after:w-[2px] hover:after:bg-sidebar-border sm:flex ltr:-translate-x-1/2 rtl:-translate-x-1/2", "in-data-[side=left]:cursor-w-resize in-data-[side=right]:cursor-e-resize", "[[data-side=left][data-state=collapsed]_&]:cursor-e-resize [[data-side=right][data-state=collapsed]_&]:cursor-w-resize", "group-data-[collapsible=offcanvas]:translate-x-0 group-data-[collapsible=offcanvas]:after:left-full hover:group-data-[collapsible=offcanvas]:bg-sidebar", "[[data-side=left][data-collapsible=offcanvas]_&]:-right-2", "[[data-side=right][data-collapsible=offcanvas]_&]:-left-2", className),
|
|
190
|
+
...props
|
|
191
|
+
});
|
|
192
|
+
}
|
|
193
|
+
function SidebarInset({ className, ...props }) {
|
|
194
|
+
return /* @__PURE__ */ jsx("main", {
|
|
195
|
+
"data-slot": "sidebar-inset",
|
|
196
|
+
className: cn("relative flex w-full flex-1 flex-col bg-background md:peer-data-[variant=inset]:m-2 md:peer-data-[variant=inset]:ml-0 md:peer-data-[variant=inset]:rounded-xl md:peer-data-[variant=inset]:shadow-sm md:peer-data-[variant=inset]:peer-data-[state=collapsed]:ml-2", className),
|
|
197
|
+
...props
|
|
198
|
+
});
|
|
199
|
+
}
|
|
200
|
+
function SidebarInput({ className, ...props }) {
|
|
201
|
+
return /* @__PURE__ */ jsx(Input, {
|
|
202
|
+
"data-slot": "sidebar-input",
|
|
203
|
+
"data-sidebar": "input",
|
|
204
|
+
className: cn("h-8 w-full bg-background shadow-none", className),
|
|
205
|
+
...props
|
|
206
|
+
});
|
|
207
|
+
}
|
|
208
|
+
function SidebarHeader({ className, ...props }) {
|
|
209
|
+
return /* @__PURE__ */ jsx("div", {
|
|
210
|
+
"data-slot": "sidebar-header",
|
|
211
|
+
"data-sidebar": "header",
|
|
212
|
+
className: cn("flex flex-col gap-2 p-2", className),
|
|
213
|
+
...props
|
|
214
|
+
});
|
|
215
|
+
}
|
|
216
|
+
function SidebarFooter({ className, ...props }) {
|
|
217
|
+
return /* @__PURE__ */ jsx("div", {
|
|
218
|
+
"data-slot": "sidebar-footer",
|
|
219
|
+
"data-sidebar": "footer",
|
|
220
|
+
className: cn("flex flex-col gap-2 p-2", className),
|
|
221
|
+
...props
|
|
222
|
+
});
|
|
223
|
+
}
|
|
224
|
+
function SidebarSeparator({ className, ...props }) {
|
|
225
|
+
return /* @__PURE__ */ jsx(Separator$1, {
|
|
226
|
+
"data-slot": "sidebar-separator",
|
|
227
|
+
"data-sidebar": "separator",
|
|
228
|
+
className: cn("mx-2 w-auto bg-sidebar-border", className),
|
|
229
|
+
...props
|
|
230
|
+
});
|
|
231
|
+
}
|
|
232
|
+
function SidebarContent({ className, ...props }) {
|
|
233
|
+
return /* @__PURE__ */ jsx("div", {
|
|
234
|
+
"data-slot": "sidebar-content",
|
|
235
|
+
"data-sidebar": "content",
|
|
236
|
+
className: cn("no-scrollbar flex min-h-0 flex-1 flex-col gap-0 overflow-auto group-data-[collapsible=icon]:overflow-hidden", className),
|
|
237
|
+
...props
|
|
238
|
+
});
|
|
239
|
+
}
|
|
240
|
+
function SidebarGroup({ className, ...props }) {
|
|
241
|
+
return /* @__PURE__ */ jsx("div", {
|
|
242
|
+
"data-slot": "sidebar-group",
|
|
243
|
+
"data-sidebar": "group",
|
|
244
|
+
className: cn("relative flex w-full min-w-0 flex-col p-2", className),
|
|
245
|
+
...props
|
|
246
|
+
});
|
|
247
|
+
}
|
|
248
|
+
function SidebarGroupLabel({ className, asChild = false, ...props }) {
|
|
249
|
+
const Comp = asChild ? Slot.Root : "div";
|
|
250
|
+
return /* @__PURE__ */ jsx(Comp, {
|
|
251
|
+
"data-slot": "sidebar-group-label",
|
|
252
|
+
"data-sidebar": "group-label",
|
|
253
|
+
className: cn("flex h-8 shrink-0 items-center rounded-md px-2 text-xs font-medium text-sidebar-foreground/70 ring-sidebar-ring outline-hidden transition-[margin,opacity] duration-200 ease-linear group-data-[collapsible=icon]:-mt-8 group-data-[collapsible=icon]:opacity-0 focus-visible:ring-2 [&>svg]:size-4 [&>svg]:shrink-0", className),
|
|
254
|
+
...props
|
|
255
|
+
});
|
|
256
|
+
}
|
|
257
|
+
function SidebarGroupAction({ className, asChild = false, ...props }) {
|
|
258
|
+
const Comp = asChild ? Slot.Root : "button";
|
|
259
|
+
return /* @__PURE__ */ jsx(Comp, {
|
|
260
|
+
"data-slot": "sidebar-group-action",
|
|
261
|
+
"data-sidebar": "group-action",
|
|
262
|
+
className: cn("absolute top-3.5 right-3 flex aspect-square w-5 items-center justify-center rounded-md p-0 text-sidebar-foreground ring-sidebar-ring outline-hidden transition-transform group-data-[collapsible=icon]:hidden after:absolute after:-inset-2 hover:bg-sidebar-accent hover:text-sidebar-accent-foreground focus-visible:ring-2 md:after:hidden [&>svg]:size-4 [&>svg]:shrink-0", className),
|
|
263
|
+
...props
|
|
264
|
+
});
|
|
265
|
+
}
|
|
266
|
+
function SidebarGroupContent({ className, ...props }) {
|
|
267
|
+
return /* @__PURE__ */ jsx("div", {
|
|
268
|
+
"data-slot": "sidebar-group-content",
|
|
269
|
+
"data-sidebar": "group-content",
|
|
270
|
+
className: cn("w-full text-sm", className),
|
|
271
|
+
...props
|
|
272
|
+
});
|
|
273
|
+
}
|
|
274
|
+
function SidebarMenu({ className, ...props }) {
|
|
275
|
+
return /* @__PURE__ */ jsx("ul", {
|
|
276
|
+
"data-slot": "sidebar-menu",
|
|
277
|
+
"data-sidebar": "menu",
|
|
278
|
+
className: cn("flex w-full min-w-0 flex-col gap-0", className),
|
|
279
|
+
...props
|
|
280
|
+
});
|
|
281
|
+
}
|
|
282
|
+
function SidebarMenuItem({ className, ...props }) {
|
|
283
|
+
return /* @__PURE__ */ jsx("li", {
|
|
284
|
+
"data-slot": "sidebar-menu-item",
|
|
285
|
+
"data-sidebar": "menu-item",
|
|
286
|
+
className: cn("group/menu-item relative", className),
|
|
287
|
+
...props
|
|
288
|
+
});
|
|
289
|
+
}
|
|
290
|
+
var sidebarMenuButtonVariants = cva("peer/menu-button group/menu-button flex w-full items-center gap-2 overflow-hidden rounded-md p-2 text-left text-sm ring-sidebar-ring outline-hidden transition-[width,height,padding] group-has-data-[sidebar=menu-action]/menu-item:pr-8 group-data-[collapsible=icon]:size-8! group-data-[collapsible=icon]:p-2! hover:bg-sidebar-accent hover:text-sidebar-accent-foreground focus-visible:ring-2 active:bg-sidebar-accent active:text-sidebar-accent-foreground disabled:pointer-events-none disabled:opacity-50 aria-disabled:pointer-events-none aria-disabled:opacity-50 data-[active=true]:bg-sidebar-primary/10 data-[active=true]:font-medium data-[active=true]:text-sidebar-primary data-[state=open]:hover:bg-sidebar-accent data-[state=open]:hover:text-sidebar-accent-foreground [&_svg]:size-4 [&_svg]:shrink-0 [&>span:last-child]:truncate", {
|
|
291
|
+
variants: {
|
|
292
|
+
variant: {
|
|
293
|
+
default: "hover:bg-sidebar-accent hover:text-sidebar-accent-foreground",
|
|
294
|
+
outline: "bg-background shadow-[0_0_0_1px_var(--sidebar-border)] hover:bg-sidebar-accent hover:text-sidebar-accent-foreground hover:shadow-[0_0_0_1px_var(--sidebar-accent)]"
|
|
295
|
+
},
|
|
296
|
+
size: {
|
|
297
|
+
default: "h-8 text-sm",
|
|
298
|
+
sm: "h-7 text-xs",
|
|
299
|
+
lg: "h-12 text-sm group-data-[collapsible=icon]:p-0!"
|
|
300
|
+
}
|
|
301
|
+
},
|
|
302
|
+
defaultVariants: {
|
|
303
|
+
variant: "default",
|
|
304
|
+
size: "default"
|
|
305
|
+
}
|
|
306
|
+
});
|
|
307
|
+
function SidebarMenuButton({ asChild = false, isActive = false, variant = "default", size = "default", tooltip, className, ...props }) {
|
|
308
|
+
const Comp = asChild ? Slot.Root : "button";
|
|
309
|
+
const { isMobile, state } = useSidebar();
|
|
310
|
+
const button = /* @__PURE__ */ jsx(Comp, {
|
|
311
|
+
"data-slot": "sidebar-menu-button",
|
|
312
|
+
"data-sidebar": "menu-button",
|
|
313
|
+
"data-size": size,
|
|
314
|
+
"data-active": isActive,
|
|
315
|
+
"aria-current": isActive ? "page" : void 0,
|
|
316
|
+
className: cn(sidebarMenuButtonVariants({
|
|
317
|
+
variant,
|
|
318
|
+
size
|
|
319
|
+
}), className),
|
|
320
|
+
...props
|
|
321
|
+
});
|
|
322
|
+
if (!tooltip) return button;
|
|
323
|
+
if (typeof tooltip === "string") tooltip = { children: tooltip };
|
|
324
|
+
return /* @__PURE__ */ jsxs(Tooltip$1, { children: [/* @__PURE__ */ jsx(TooltipTrigger, {
|
|
325
|
+
asChild: true,
|
|
326
|
+
children: button
|
|
327
|
+
}), /* @__PURE__ */ jsx(TooltipContent, {
|
|
328
|
+
side: "right",
|
|
329
|
+
align: "center",
|
|
330
|
+
hidden: state !== "collapsed" || isMobile,
|
|
331
|
+
...tooltip
|
|
332
|
+
})] });
|
|
333
|
+
}
|
|
334
|
+
function SidebarMenuAction({ className, asChild = false, showOnHover = false, ...props }) {
|
|
335
|
+
const Comp = asChild ? Slot.Root : "button";
|
|
336
|
+
return /* @__PURE__ */ jsx(Comp, {
|
|
337
|
+
"data-slot": "sidebar-menu-action",
|
|
338
|
+
"data-sidebar": "menu-action",
|
|
339
|
+
className: cn("absolute top-1.5 right-1 flex aspect-square w-5 items-center justify-center rounded-md p-0 text-sidebar-foreground ring-sidebar-ring outline-hidden transition-transform group-data-[collapsible=icon]:hidden peer-hover/menu-button:text-sidebar-accent-foreground peer-data-[size=default]/menu-button:top-1.5 peer-data-[size=lg]/menu-button:top-2.5 peer-data-[size=sm]/menu-button:top-1 after:absolute after:-inset-2 hover:bg-sidebar-accent hover:text-sidebar-accent-foreground focus-visible:ring-2 md:after:hidden [&>svg]:size-4 [&>svg]:shrink-0", showOnHover && "group-focus-within/menu-item:opacity-100 group-hover/menu-item:opacity-100 peer-data-[active=true]/menu-button:text-sidebar-primary aria-expanded:opacity-100 md:opacity-0", className),
|
|
340
|
+
...props
|
|
341
|
+
});
|
|
342
|
+
}
|
|
343
|
+
function SidebarMenuBadge({ className, ...props }) {
|
|
344
|
+
return /* @__PURE__ */ jsx("div", {
|
|
345
|
+
"data-slot": "sidebar-menu-badge",
|
|
346
|
+
"data-sidebar": "menu-badge",
|
|
347
|
+
className: cn("pointer-events-none absolute right-1 flex h-5 min-w-5 items-center justify-center rounded-md px-1 text-xs font-medium text-sidebar-foreground tabular-nums select-none group-data-[collapsible=icon]:hidden peer-hover/menu-button:text-sidebar-accent-foreground peer-data-[active=true]/menu-button:text-sidebar-primary peer-data-[size=default]/menu-button:top-1.5 peer-data-[size=lg]/menu-button:top-2.5 peer-data-[size=sm]/menu-button:top-1", className),
|
|
348
|
+
...props
|
|
349
|
+
});
|
|
350
|
+
}
|
|
351
|
+
function SidebarMenuSkeleton({ className, showIcon = false, ...props }) {
|
|
352
|
+
const [width] = React.useState(() => {
|
|
353
|
+
return `${Math.floor(Math.random() * 40) + 50}%`;
|
|
354
|
+
});
|
|
355
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
356
|
+
"data-slot": "sidebar-menu-skeleton",
|
|
357
|
+
"data-sidebar": "menu-skeleton",
|
|
358
|
+
className: cn("flex h-8 items-center gap-2 rounded-md px-2", className),
|
|
359
|
+
...props,
|
|
360
|
+
children: [showIcon && /* @__PURE__ */ jsx(Skeleton, {
|
|
361
|
+
className: "size-4 rounded-md",
|
|
362
|
+
"data-sidebar": "menu-skeleton-icon"
|
|
363
|
+
}), /* @__PURE__ */ jsx(Skeleton, {
|
|
364
|
+
className: "h-4 max-w-(--skeleton-width) flex-1",
|
|
365
|
+
"data-sidebar": "menu-skeleton-text",
|
|
366
|
+
style: { "--skeleton-width": width }
|
|
367
|
+
})]
|
|
368
|
+
});
|
|
369
|
+
}
|
|
370
|
+
function SidebarMenuSub({ className, ...props }) {
|
|
371
|
+
return /* @__PURE__ */ jsx("ul", {
|
|
372
|
+
"data-slot": "sidebar-menu-sub",
|
|
373
|
+
"data-sidebar": "menu-sub",
|
|
374
|
+
className: cn("mx-3.5 flex min-w-0 translate-x-px flex-col gap-1 border-l border-sidebar-border px-2.5 py-0.5 group-data-[collapsible=icon]:hidden", className),
|
|
375
|
+
...props
|
|
376
|
+
});
|
|
377
|
+
}
|
|
378
|
+
function SidebarMenuSubItem({ className, ...props }) {
|
|
379
|
+
return /* @__PURE__ */ jsx("li", {
|
|
380
|
+
"data-slot": "sidebar-menu-sub-item",
|
|
381
|
+
"data-sidebar": "menu-sub-item",
|
|
382
|
+
className: cn("group/menu-sub-item relative", className),
|
|
383
|
+
...props
|
|
384
|
+
});
|
|
385
|
+
}
|
|
386
|
+
function SidebarMenuSubButton({ asChild = false, size = "md", isActive = false, className, ...props }) {
|
|
387
|
+
const Comp = asChild ? Slot.Root : "a";
|
|
388
|
+
return /* @__PURE__ */ jsx(Comp, {
|
|
389
|
+
"data-slot": "sidebar-menu-sub-button",
|
|
390
|
+
"data-sidebar": "menu-sub-button",
|
|
391
|
+
"data-size": size,
|
|
392
|
+
"data-active": isActive,
|
|
393
|
+
"aria-current": isActive ? "page" : void 0,
|
|
394
|
+
className: cn("flex h-7 min-w-0 -translate-x-px items-center gap-2 overflow-hidden rounded-md px-2 text-sidebar-foreground ring-sidebar-ring outline-hidden group-data-[collapsible=icon]:hidden hover:bg-sidebar-accent hover:text-sidebar-accent-foreground focus-visible:ring-2 active:bg-sidebar-accent active:text-sidebar-accent-foreground disabled:pointer-events-none disabled:opacity-50 aria-disabled:pointer-events-none aria-disabled:opacity-50 data-[active=true]:bg-sidebar-primary/10 data-[active=true]:font-medium data-[active=true]:text-sidebar-primary data-[size=md]:text-sm data-[size=sm]:text-xs [&>span:last-child]:truncate [&>svg]:size-4 [&>svg]:shrink-0", className),
|
|
395
|
+
...props
|
|
396
|
+
});
|
|
397
|
+
}
|
|
398
|
+
/**
|
|
399
|
+
* A SidebarMenuButton that discloses a set of child rows underneath it
|
|
400
|
+
* instead of navigating — a "folder" of related destinations in the rail.
|
|
401
|
+
*
|
|
402
|
+
* SidebarMenuSub is a static indented list with no disclosure state of its
|
|
403
|
+
* own; this pairs it with Collapsible so opening/closing actually animates,
|
|
404
|
+
* and flattens the indent to 0 once the sidebar collapses to icon-only
|
|
405
|
+
* (`group-data-[collapsible=icon]`), matching how every other menu row in
|
|
406
|
+
* this family already collapses.
|
|
407
|
+
*
|
|
408
|
+
* `open`/`onOpenChange` are owned by the caller, same as SidebarMenuButton's
|
|
409
|
+
* `isActive` — this component holds no state of its own, so multiple
|
|
410
|
+
* instances of the same rail (e.g. a docked sidebar and its own hover
|
|
411
|
+
* overlay) can share one open/closed answer instead of disagreeing.
|
|
412
|
+
*/
|
|
413
|
+
function SidebarMenuCollapsible({ icon, label, children, open, onOpenChange, isActive = false, className, ...props }) {
|
|
414
|
+
return /* @__PURE__ */ jsxs(Collapsible$1, {
|
|
415
|
+
open,
|
|
416
|
+
onOpenChange,
|
|
417
|
+
children: [/* @__PURE__ */ jsx(CollapsibleTrigger, {
|
|
418
|
+
asChild: true,
|
|
419
|
+
children: /* @__PURE__ */ jsxs(SidebarMenuButton, {
|
|
420
|
+
"data-slot": "sidebar-menu-collapsible-trigger",
|
|
421
|
+
isActive,
|
|
422
|
+
className: cn(!isActive && "bg-transparent", className),
|
|
423
|
+
...props,
|
|
424
|
+
children: [
|
|
425
|
+
icon,
|
|
426
|
+
/* @__PURE__ */ jsx("span", {
|
|
427
|
+
className: "min-w-0 flex-1 truncate",
|
|
428
|
+
children: label
|
|
429
|
+
}),
|
|
430
|
+
/* @__PURE__ */ jsx(ChevronDownIcon, { className: cn("shrink-0 text-sidebar-foreground/70 transition-transform duration-150", open && "rotate-180") })
|
|
431
|
+
]
|
|
432
|
+
})
|
|
433
|
+
}), /* @__PURE__ */ jsx(CollapsibleContent, {
|
|
434
|
+
forceMount: true,
|
|
435
|
+
"data-slot": "sidebar-menu-collapsible-content",
|
|
436
|
+
className: cn("grid ease-out", open ? "visible grid-rows-[1fr] opacity-100 transition-opacity duration-150" : "invisible grid-rows-[0fr] opacity-0 transition-[grid-template-rows,opacity,visibility] duration-200"),
|
|
437
|
+
children: /* @__PURE__ */ jsx("div", {
|
|
438
|
+
className: "overflow-hidden",
|
|
439
|
+
children: /* @__PURE__ */ jsx("div", {
|
|
440
|
+
className: "mt-0.5 flex flex-col gap-0.5 pl-7 transition-[padding-left] duration-200 ease-linear group-data-[collapsible=icon]:pl-0",
|
|
441
|
+
children
|
|
442
|
+
})
|
|
443
|
+
})
|
|
444
|
+
})]
|
|
445
|
+
});
|
|
446
|
+
}
|
|
447
|
+
/**
|
|
448
|
+
* WHEN TO USE
|
|
449
|
+
* - Persistent primary navigation in an app-shell layout — the main way
|
|
450
|
+
* users move between top-level sections of the product.
|
|
451
|
+
*
|
|
452
|
+
* NOT WHEN
|
|
453
|
+
* - A temporary/dismissible panel — use Sheet (Sidebar itself renders as a
|
|
454
|
+
* Sheet on mobile automatically, but don't reach for Sidebar to build a
|
|
455
|
+
* one-off drawer).
|
|
456
|
+
* - Top-bar navigation — use NavigationMenu.
|
|
457
|
+
* - A plain, non-collapsible list with no app-shell chrome — use Item.
|
|
458
|
+
*
|
|
459
|
+
* KEY RULES
|
|
460
|
+
* - Requires SidebarProvider wrapping both the Sidebar and the SidebarInset
|
|
461
|
+
* content — it owns the open/collapsed state via context (`useSidebar`);
|
|
462
|
+
* Sidebar and SidebarInset don't work standalone.
|
|
463
|
+
* - `side`: "left" | "right". `variant`: "sidebar" (flush) | "floating"
|
|
464
|
+
* (rounded, ringed) | "inset" (content insets around it). `collapsible`:
|
|
465
|
+
* "offcanvas" (slides fully away) | "icon" (shrinks to icon rail) | "none"
|
|
466
|
+
* (always expanded, no collapse control).
|
|
467
|
+
* - Below the `md` breakpoint the sidebar always renders as a Sheet
|
|
468
|
+
* regardless of `collapsible`, via `useIsMobile` — don't special-case
|
|
469
|
+
* mobile yourself.
|
|
470
|
+
* - SidebarMenuButton's `isActive` and SidebarMenuCollapsible's `open` are
|
|
471
|
+
* both caller-owned — this file holds no "current route" state.
|
|
472
|
+
* - SidebarMenuSub is a static indented list; SidebarMenuCollapsible is the
|
|
473
|
+
* version with its own open/close disclosure and icon-collapse indent
|
|
474
|
+
* flattening — don't use Sub when you need a toggleable "folder".
|
|
475
|
+
* - Cmd/Ctrl+B toggles the sidebar globally (wired inside SidebarProvider).
|
|
476
|
+
*
|
|
477
|
+
* USAGE
|
|
478
|
+
* <SidebarProvider>
|
|
479
|
+
* <Sidebar>
|
|
480
|
+
* <SidebarHeader>...</SidebarHeader>
|
|
481
|
+
* <SidebarContent>
|
|
482
|
+
* <SidebarGroup>
|
|
483
|
+
* <SidebarGroupLabel>Platform</SidebarGroupLabel>
|
|
484
|
+
* <SidebarGroupContent>
|
|
485
|
+
* <SidebarMenu>
|
|
486
|
+
* <SidebarMenuItem>
|
|
487
|
+
* <SidebarMenuButton isActive>
|
|
488
|
+
* <HomeIcon />Overview
|
|
489
|
+
* </SidebarMenuButton>
|
|
490
|
+
* </SidebarMenuItem>
|
|
491
|
+
* <SidebarMenuItem>
|
|
492
|
+
* <SidebarMenuCollapsible
|
|
493
|
+
* icon={<FolderIcon />}
|
|
494
|
+
* label="Analytics"
|
|
495
|
+
* open={open}
|
|
496
|
+
* onOpenChange={setOpen}
|
|
497
|
+
* >
|
|
498
|
+
* <SidebarMenuButton><BarChartIcon />Cohort Builder</SidebarMenuButton>
|
|
499
|
+
* </SidebarMenuCollapsible>
|
|
500
|
+
* </SidebarMenuItem>
|
|
501
|
+
* </SidebarMenu>
|
|
502
|
+
* </SidebarGroupContent>
|
|
503
|
+
* </SidebarGroup>
|
|
504
|
+
* </SidebarContent>
|
|
505
|
+
* </Sidebar>
|
|
506
|
+
* <SidebarInset>{"<page content>"}</SidebarInset>
|
|
507
|
+
* </SidebarProvider>
|
|
508
|
+
*/
|
|
509
|
+
//#endregion
|
|
510
|
+
export { Sidebar, SidebarContent, SidebarFooter, SidebarGroup, SidebarGroupAction, SidebarGroupContent, SidebarGroupLabel, SidebarHeader, SidebarInput, SidebarInset, SidebarMenu, SidebarMenuAction, SidebarMenuBadge, SidebarMenuButton, SidebarMenuCollapsible, SidebarMenuItem, SidebarMenuSkeleton, SidebarMenuSub, SidebarMenuSubButton, SidebarMenuSubItem, SidebarProvider, SidebarRail, SidebarSeparator, SidebarTrigger, useSidebar };
|
|
511
|
+
|
|
512
|
+
//# sourceMappingURL=sidebar.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sidebar.js","names":[],"sources":["../../../src/components/ui/sidebar.tsx"],"sourcesContent":["/**\n * Sidebar — full application side-navigation shell.\n *\n * Includes SidebarMenuCollapsible, an animated, disclosable nav \"folder\"\n * that pairs SidebarMenuButton with Collapsible (see its own doc comment above\n * its definition). Composed from many sub-exports; see the WHEN TO USE /\n * KEY RULES block at the end of this file for the family as a whole.\n */\n\nimport * as React from \"react\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\nimport { Slot } from \"radix-ui\"\n\nimport { useIsMobile } from \"@/hooks/use-mobile\"\nimport { cn } from \"@/lib/utils\"\nimport { Button } from \"@/components/ui/button\"\nimport {\n Collapsible,\n CollapsibleContent,\n CollapsibleTrigger,\n} from \"@/components/ui/collapsible\"\nimport { Input } from \"@/components/ui/input\"\nimport { Separator } from \"@/components/ui/separator\"\nimport {\n Sheet,\n SheetContent,\n SheetDescription,\n SheetHeader,\n SheetTitle,\n} from \"@/components/ui/sheet\"\nimport { Skeleton } from \"@/components/ui/skeleton\"\nimport {\n Tooltip,\n TooltipContent,\n TooltipTrigger,\n} from \"@/components/ui/tooltip\"\nimport { ChevronDownIcon, PanelLeftIcon } from \"lucide-react\"\n\nconst SIDEBAR_COOKIE_NAME = \"sidebar_state\"\nconst SIDEBAR_COOKIE_MAX_AGE = 60 * 60 * 24 * 7\nconst SIDEBAR_WIDTH = \"16rem\"\nconst SIDEBAR_WIDTH_MOBILE = \"18rem\"\nconst SIDEBAR_WIDTH_ICON = \"3rem\"\nconst SIDEBAR_KEYBOARD_SHORTCUT = \"b\"\n\ntype SidebarContextProps = {\n state: \"expanded\" | \"collapsed\"\n open: boolean\n setOpen: (open: boolean) => void\n openMobile: boolean\n setOpenMobile: (open: boolean) => void\n isMobile: boolean\n toggleSidebar: () => void\n /** Shared with `Sidebar` (as its panel `id`) and `SidebarTrigger` (as `aria-controls`) so the trigger's open/closed toggle button points at a real target instead of just changing state with no reachable relationship. */\n contentId: string\n}\n\nconst SidebarContext = React.createContext<SidebarContextProps | null>(null)\n\nfunction useSidebar() {\n const context = React.useContext(SidebarContext)\n if (!context) {\n throw new Error(\"useSidebar must be used within a SidebarProvider.\")\n }\n\n return context\n}\n\nfunction SidebarProvider({\n defaultOpen = true,\n open: openProp,\n onOpenChange: setOpenProp,\n className,\n style,\n children,\n ...props\n}: React.ComponentProps<\"div\"> & {\n defaultOpen?: boolean\n open?: boolean\n onOpenChange?: (open: boolean) => void\n}) {\n const isMobile = useIsMobile()\n const [openMobile, setOpenMobile] = React.useState(false)\n const contentId = React.useId()\n\n // This is the internal state of the sidebar.\n // We use openProp and setOpenProp for control from outside the component.\n const [_open, _setOpen] = React.useState(defaultOpen)\n const open = openProp ?? _open\n const setOpen = React.useCallback(\n (value: boolean | ((value: boolean) => boolean)) => {\n const openState = typeof value === \"function\" ? value(open) : value\n if (setOpenProp) {\n setOpenProp(openState)\n } else {\n _setOpen(openState)\n }\n\n // This sets the cookie to keep the sidebar state.\n document.cookie = `${SIDEBAR_COOKIE_NAME}=${openState}; path=/; max-age=${SIDEBAR_COOKIE_MAX_AGE}`\n },\n [setOpenProp, open]\n )\n\n // Helper to toggle the sidebar.\n const toggleSidebar = React.useCallback(() => {\n return isMobile ? setOpenMobile((open) => !open) : setOpen((open) => !open)\n }, [isMobile, setOpen, setOpenMobile])\n\n // Adds a keyboard shortcut to toggle the sidebar.\n React.useEffect(() => {\n const handleKeyDown = (event: KeyboardEvent) => {\n if (\n event.key === SIDEBAR_KEYBOARD_SHORTCUT &&\n (event.metaKey || event.ctrlKey)\n ) {\n event.preventDefault()\n toggleSidebar()\n }\n }\n\n window.addEventListener(\"keydown\", handleKeyDown)\n return () => window.removeEventListener(\"keydown\", handleKeyDown)\n }, [toggleSidebar])\n\n // We add a state so that we can do data-state=\"expanded\" or \"collapsed\".\n // This makes it easier to style the sidebar with Tailwind classes.\n const state = open ? \"expanded\" : \"collapsed\"\n\n const contextValue = React.useMemo<SidebarContextProps>(\n () => ({\n state,\n open,\n setOpen,\n isMobile,\n openMobile,\n setOpenMobile,\n toggleSidebar,\n contentId,\n }),\n [\n state,\n open,\n setOpen,\n isMobile,\n openMobile,\n setOpenMobile,\n toggleSidebar,\n contentId,\n ]\n )\n\n return (\n <SidebarContext.Provider value={contextValue}>\n <div\n data-slot=\"sidebar-wrapper\"\n style={\n {\n \"--sidebar-width\": SIDEBAR_WIDTH,\n \"--sidebar-width-icon\": SIDEBAR_WIDTH_ICON,\n ...style,\n } as React.CSSProperties\n }\n className={cn(\n \"group/sidebar-wrapper flex min-h-svh w-full has-data-[variant=inset]:bg-sidebar\",\n className\n )}\n {...props}\n >\n {children}\n </div>\n </SidebarContext.Provider>\n )\n}\n\nfunction Sidebar({\n side = \"left\",\n variant = \"sidebar\",\n collapsible = \"offcanvas\",\n className,\n children,\n dir,\n ...props\n}: React.ComponentProps<\"div\"> & {\n side?: \"left\" | \"right\"\n variant?: \"sidebar\" | \"floating\" | \"inset\"\n collapsible?: \"offcanvas\" | \"icon\" | \"none\"\n}) {\n const { isMobile, state, openMobile, setOpenMobile, contentId } = useSidebar()\n\n if (collapsible === \"none\") {\n return (\n <div\n id={contentId}\n data-slot=\"sidebar\"\n className={cn(\n \"flex h-full w-(--sidebar-width) flex-col bg-sidebar text-sidebar-foreground\",\n className\n )}\n {...props}\n >\n {children}\n </div>\n )\n }\n\n if (isMobile) {\n return (\n <Sheet open={openMobile} onOpenChange={setOpenMobile} {...props}>\n <SheetContent\n id={contentId}\n dir={dir}\n data-sidebar=\"sidebar\"\n data-slot=\"sidebar\"\n data-mobile=\"true\"\n className=\"w-(--sidebar-width) bg-sidebar p-0 text-sidebar-foreground [&>button]:hidden\"\n style={\n {\n \"--sidebar-width\": SIDEBAR_WIDTH_MOBILE,\n } as React.CSSProperties\n }\n side={side}\n >\n <SheetHeader className=\"sr-only\">\n <SheetTitle>Sidebar</SheetTitle>\n <SheetDescription>Displays the mobile sidebar.</SheetDescription>\n </SheetHeader>\n <div className=\"flex h-full w-full flex-col\">{children}</div>\n </SheetContent>\n </Sheet>\n )\n }\n\n return (\n <div\n className=\"group peer hidden text-sidebar-foreground md:block\"\n data-state={state}\n data-collapsible={state === \"collapsed\" ? collapsible : \"\"}\n data-variant={variant}\n data-side={side}\n data-slot=\"sidebar\"\n >\n {/* This is what handles the sidebar gap on desktop */}\n <div\n data-slot=\"sidebar-gap\"\n className={cn(\n \"relative w-(--sidebar-width) bg-transparent transition-[width] duration-200 ease-linear\",\n \"group-data-[collapsible=offcanvas]:w-0\",\n \"group-data-[side=right]:rotate-180\",\n variant === \"floating\" || variant === \"inset\"\n ? \"group-data-[collapsible=icon]:w-[calc(var(--sidebar-width-icon)+(--spacing(4)))]\"\n : \"group-data-[collapsible=icon]:w-(--sidebar-width-icon)\"\n )}\n />\n <div\n id={contentId}\n data-slot=\"sidebar-container\"\n data-side={side}\n // Offcanvas collapse only ever moves this box off-screen via\n // `left`/`right` — a transform, not `display`/`aria-hidden` — so\n // without `inert` its contents stayed in the tab order and\n // accessibility tree while invisible: keyboard/AT users could tab\n // into and activate controls they can't see. `inert` removes both\n // at once (focusability and AT exposure) without touching the\n // transition itself. Only applies to the collapse mode that's\n // actually invisible when collapsed — \"icon\" mode stays visible\n // (shrunk, not hidden), so its content correctly stays reachable.\n inert={collapsible === \"offcanvas\" && state === \"collapsed\"}\n className={cn(\n \"fixed inset-y-0 z-10 hidden h-svh w-(--sidebar-width) transition-[left,right,width] duration-200 ease-linear data-[side=left]:left-0 data-[side=left]:group-data-[collapsible=offcanvas]:left-[calc(var(--sidebar-width)*-1)] data-[side=right]:right-0 data-[side=right]:group-data-[collapsible=offcanvas]:right-[calc(var(--sidebar-width)*-1)] md:flex\",\n // Adjust the padding for floating and inset variants.\n variant === \"floating\" || variant === \"inset\"\n ? \"p-2 group-data-[collapsible=icon]:w-[calc(var(--sidebar-width-icon)+(--spacing(4))+2px)]\"\n : \"group-data-[collapsible=icon]:w-(--sidebar-width-icon) group-data-[side=left]:border-r group-data-[side=right]:border-l\",\n className\n )}\n {...props}\n >\n <div\n data-sidebar=\"sidebar\"\n data-slot=\"sidebar-inner\"\n className=\"flex size-full flex-col bg-sidebar group-data-[variant=floating]:rounded-xl group-data-[variant=floating]:shadow-sm group-data-[variant=floating]:ring-1 group-data-[variant=floating]:ring-sidebar-border\"\n >\n {children}\n </div>\n </div>\n </div>\n )\n}\n\nfunction SidebarTrigger({\n className,\n onClick,\n ...props\n}: Omit<\n React.ComponentProps<typeof Button>,\n \"size\" | \"iconOnly\" | \"asChild\" | \"aria-label\" | \"variant\"\n>) {\n const { toggleSidebar, state, contentId } = useSidebar()\n\n return (\n <Button\n data-sidebar=\"trigger\"\n data-slot=\"sidebar-trigger\"\n variant=\"ghost\"\n size=\"sm\"\n iconOnly\n aria-label=\"Toggle Sidebar\"\n // Static label + no other state cue meant this button never told AT\n // whether activating it would open or close the panel, unlike every\n // other disclosure trigger in this library.\n aria-expanded={state === \"expanded\"}\n aria-controls={contentId}\n className={cn(className)}\n onClick={(event) => {\n onClick?.(event)\n toggleSidebar()\n }}\n {...props}\n >\n <PanelLeftIcon />\n <span className=\"sr-only\">Toggle Sidebar</span>\n </Button>\n )\n}\n\nfunction SidebarRail({ className, ...props }: React.ComponentProps<\"button\">) {\n const { toggleSidebar } = useSidebar()\n\n return (\n <button\n data-sidebar=\"rail\"\n data-slot=\"sidebar-rail\"\n aria-label=\"Toggle Sidebar\"\n tabIndex={-1}\n onClick={toggleSidebar}\n title=\"Toggle Sidebar\"\n className={cn(\n \"absolute inset-y-0 z-20 hidden w-4 transition-colors ease-linear group-data-[side=left]:-right-4 group-data-[side=right]:left-0 after:absolute after:inset-y-0 after:start-1/2 after:w-[2px] hover:after:bg-sidebar-border sm:flex ltr:-translate-x-1/2 rtl:-translate-x-1/2\",\n \"in-data-[side=left]:cursor-w-resize in-data-[side=right]:cursor-e-resize\",\n \"[[data-side=left][data-state=collapsed]_&]:cursor-e-resize [[data-side=right][data-state=collapsed]_&]:cursor-w-resize\",\n \"group-data-[collapsible=offcanvas]:translate-x-0 group-data-[collapsible=offcanvas]:after:left-full hover:group-data-[collapsible=offcanvas]:bg-sidebar\",\n \"[[data-side=left][data-collapsible=offcanvas]_&]:-right-2\",\n \"[[data-side=right][data-collapsible=offcanvas]_&]:-left-2\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction SidebarInset({ className, ...props }: React.ComponentProps<\"main\">) {\n return (\n <main\n data-slot=\"sidebar-inset\"\n className={cn(\n \"relative flex w-full flex-1 flex-col bg-background md:peer-data-[variant=inset]:m-2 md:peer-data-[variant=inset]:ml-0 md:peer-data-[variant=inset]:rounded-xl md:peer-data-[variant=inset]:shadow-sm md:peer-data-[variant=inset]:peer-data-[state=collapsed]:ml-2\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction SidebarInput({\n className,\n ...props\n}: React.ComponentProps<typeof Input>) {\n return (\n <Input\n data-slot=\"sidebar-input\"\n data-sidebar=\"input\"\n className={cn(\"h-8 w-full bg-background shadow-none\", className)}\n {...props}\n />\n )\n}\n\nfunction SidebarHeader({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"sidebar-header\"\n data-sidebar=\"header\"\n className={cn(\"flex flex-col gap-2 p-2\", className)}\n {...props}\n />\n )\n}\n\nfunction SidebarFooter({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"sidebar-footer\"\n data-sidebar=\"footer\"\n className={cn(\"flex flex-col gap-2 p-2\", className)}\n {...props}\n />\n )\n}\n\nfunction SidebarSeparator({\n className,\n ...props\n}: React.ComponentProps<typeof Separator>) {\n return (\n <Separator\n data-slot=\"sidebar-separator\"\n data-sidebar=\"separator\"\n className={cn(\"mx-2 w-auto bg-sidebar-border\", className)}\n {...props}\n />\n )\n}\n\nfunction SidebarContent({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"sidebar-content\"\n data-sidebar=\"content\"\n className={cn(\n \"no-scrollbar flex min-h-0 flex-1 flex-col gap-0 overflow-auto group-data-[collapsible=icon]:overflow-hidden\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction SidebarGroup({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"sidebar-group\"\n data-sidebar=\"group\"\n className={cn(\"relative flex w-full min-w-0 flex-col p-2\", className)}\n {...props}\n />\n )\n}\n\nfunction SidebarGroupLabel({\n className,\n asChild = false,\n ...props\n}: React.ComponentProps<\"div\"> & { asChild?: boolean }) {\n const Comp = asChild ? Slot.Root : \"div\"\n\n return (\n <Comp\n data-slot=\"sidebar-group-label\"\n data-sidebar=\"group-label\"\n className={cn(\n \"flex h-8 shrink-0 items-center rounded-md px-2 text-xs font-medium text-sidebar-foreground/70 ring-sidebar-ring outline-hidden transition-[margin,opacity] duration-200 ease-linear group-data-[collapsible=icon]:-mt-8 group-data-[collapsible=icon]:opacity-0 focus-visible:ring-2 [&>svg]:size-4 [&>svg]:shrink-0\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction SidebarGroupAction({\n className,\n asChild = false,\n ...props\n}: React.ComponentProps<\"button\"> & { asChild?: boolean }) {\n const Comp = asChild ? Slot.Root : \"button\"\n\n return (\n <Comp\n data-slot=\"sidebar-group-action\"\n data-sidebar=\"group-action\"\n className={cn(\n \"absolute top-3.5 right-3 flex aspect-square w-5 items-center justify-center rounded-md p-0 text-sidebar-foreground ring-sidebar-ring outline-hidden transition-transform group-data-[collapsible=icon]:hidden after:absolute after:-inset-2 hover:bg-sidebar-accent hover:text-sidebar-accent-foreground focus-visible:ring-2 md:after:hidden [&>svg]:size-4 [&>svg]:shrink-0\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction SidebarGroupContent({\n className,\n ...props\n}: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"sidebar-group-content\"\n data-sidebar=\"group-content\"\n className={cn(\"w-full text-sm\", className)}\n {...props}\n />\n )\n}\n\nfunction SidebarMenu({ className, ...props }: React.ComponentProps<\"ul\">) {\n return (\n <ul\n data-slot=\"sidebar-menu\"\n data-sidebar=\"menu\"\n className={cn(\"flex w-full min-w-0 flex-col gap-0\", className)}\n {...props}\n />\n )\n}\n\nfunction SidebarMenuItem({ className, ...props }: React.ComponentProps<\"li\">) {\n return (\n <li\n data-slot=\"sidebar-menu-item\"\n data-sidebar=\"menu-item\"\n className={cn(\"group/menu-item relative\", className)}\n {...props}\n />\n )\n}\n\nconst sidebarMenuButtonVariants = cva(\n // data-[state=open]: covers `asChild` wrapping a Radix trigger (a\n // DropdownMenuTrigger/CollapsibleTrigger) that sets its own real\n // data-state on this exact node — not a literal data-open this button\n // ever sets itself.\n \"peer/menu-button group/menu-button flex w-full items-center gap-2 overflow-hidden rounded-md p-2 text-left text-sm ring-sidebar-ring outline-hidden transition-[width,height,padding] group-has-data-[sidebar=menu-action]/menu-item:pr-8 group-data-[collapsible=icon]:size-8! group-data-[collapsible=icon]:p-2! hover:bg-sidebar-accent hover:text-sidebar-accent-foreground focus-visible:ring-2 active:bg-sidebar-accent active:text-sidebar-accent-foreground disabled:pointer-events-none disabled:opacity-50 aria-disabled:pointer-events-none aria-disabled:opacity-50 data-[active=true]:bg-sidebar-primary/10 data-[active=true]:font-medium data-[active=true]:text-sidebar-primary data-[state=open]:hover:bg-sidebar-accent data-[state=open]:hover:text-sidebar-accent-foreground [&_svg]:size-4 [&_svg]:shrink-0 [&>span:last-child]:truncate\",\n {\n variants: {\n variant: {\n default: \"hover:bg-sidebar-accent hover:text-sidebar-accent-foreground\",\n outline:\n \"bg-background shadow-[0_0_0_1px_var(--sidebar-border)] hover:bg-sidebar-accent hover:text-sidebar-accent-foreground hover:shadow-[0_0_0_1px_var(--sidebar-accent)]\",\n },\n size: {\n default: \"h-8 text-sm\",\n sm: \"h-7 text-xs\",\n lg: \"h-12 text-sm group-data-[collapsible=icon]:p-0!\",\n },\n },\n defaultVariants: {\n variant: \"default\",\n size: \"default\",\n },\n }\n)\n\nfunction SidebarMenuButton({\n asChild = false,\n isActive = false,\n variant = \"default\",\n size = \"default\",\n tooltip,\n className,\n ...props\n}: React.ComponentProps<\"button\"> & {\n asChild?: boolean\n isActive?: boolean\n tooltip?: string | React.ComponentProps<typeof TooltipContent>\n} & VariantProps<typeof sidebarMenuButtonVariants>) {\n const Comp = asChild ? Slot.Root : \"button\"\n const { isMobile, state } = useSidebar()\n\n const button = (\n <Comp\n data-slot=\"sidebar-menu-button\"\n data-sidebar=\"menu-button\"\n data-size={size}\n data-active={isActive}\n // data-active alone is a CSS hook — nothing AT-facing conveyed \"this\n // is the current page\" beyond color/weight. aria-current is the\n // actual state attribute; \"page\" fits this row's usual role (a nav\n // destination link), not \"true\", since these usually render as/wrap\n // a real page link via asChild.\n aria-current={isActive ? \"page\" : undefined}\n className={cn(sidebarMenuButtonVariants({ variant, size }), className)}\n {...props}\n />\n )\n\n if (!tooltip) {\n return button\n }\n\n if (typeof tooltip === \"string\") {\n tooltip = {\n children: tooltip,\n }\n }\n\n return (\n <Tooltip>\n <TooltipTrigger asChild>{button}</TooltipTrigger>\n <TooltipContent\n side=\"right\"\n align=\"center\"\n hidden={state !== \"collapsed\" || isMobile}\n {...tooltip}\n />\n </Tooltip>\n )\n}\n\nfunction SidebarMenuAction({\n className,\n asChild = false,\n showOnHover = false,\n ...props\n}: React.ComponentProps<\"button\"> & {\n asChild?: boolean\n showOnHover?: boolean\n}) {\n const Comp = asChild ? Slot.Root : \"button\"\n\n return (\n <Comp\n data-slot=\"sidebar-menu-action\"\n data-sidebar=\"menu-action\"\n className={cn(\n \"absolute top-1.5 right-1 flex aspect-square w-5 items-center justify-center rounded-md p-0 text-sidebar-foreground ring-sidebar-ring outline-hidden transition-transform group-data-[collapsible=icon]:hidden peer-hover/menu-button:text-sidebar-accent-foreground peer-data-[size=default]/menu-button:top-1.5 peer-data-[size=lg]/menu-button:top-2.5 peer-data-[size=sm]/menu-button:top-1 after:absolute after:-inset-2 hover:bg-sidebar-accent hover:text-sidebar-accent-foreground focus-visible:ring-2 md:after:hidden [&>svg]:size-4 [&>svg]:shrink-0\",\n showOnHover &&\n \"group-focus-within/menu-item:opacity-100 group-hover/menu-item:opacity-100 peer-data-[active=true]/menu-button:text-sidebar-primary aria-expanded:opacity-100 md:opacity-0\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction SidebarMenuBadge({\n className,\n ...props\n}: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"sidebar-menu-badge\"\n data-sidebar=\"menu-badge\"\n className={cn(\n \"pointer-events-none absolute right-1 flex h-5 min-w-5 items-center justify-center rounded-md px-1 text-xs font-medium text-sidebar-foreground tabular-nums select-none group-data-[collapsible=icon]:hidden peer-hover/menu-button:text-sidebar-accent-foreground peer-data-[active=true]/menu-button:text-sidebar-primary peer-data-[size=default]/menu-button:top-1.5 peer-data-[size=lg]/menu-button:top-2.5 peer-data-[size=sm]/menu-button:top-1\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction SidebarMenuSkeleton({\n className,\n showIcon = false,\n ...props\n}: React.ComponentProps<\"div\"> & {\n showIcon?: boolean\n}) {\n // Random width between 50 to 90%.\n const [width] = React.useState(() => {\n return `${Math.floor(Math.random() * 40) + 50}%`\n })\n\n return (\n <div\n data-slot=\"sidebar-menu-skeleton\"\n data-sidebar=\"menu-skeleton\"\n className={cn(\"flex h-8 items-center gap-2 rounded-md px-2\", className)}\n {...props}\n >\n {showIcon && (\n <Skeleton\n className=\"size-4 rounded-md\"\n data-sidebar=\"menu-skeleton-icon\"\n />\n )}\n <Skeleton\n className=\"h-4 max-w-(--skeleton-width) flex-1\"\n data-sidebar=\"menu-skeleton-text\"\n style={\n {\n \"--skeleton-width\": width,\n } as React.CSSProperties\n }\n />\n </div>\n )\n}\n\nfunction SidebarMenuSub({ className, ...props }: React.ComponentProps<\"ul\">) {\n return (\n <ul\n data-slot=\"sidebar-menu-sub\"\n data-sidebar=\"menu-sub\"\n className={cn(\n \"mx-3.5 flex min-w-0 translate-x-px flex-col gap-1 border-l border-sidebar-border px-2.5 py-0.5 group-data-[collapsible=icon]:hidden\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction SidebarMenuSubItem({\n className,\n ...props\n}: React.ComponentProps<\"li\">) {\n return (\n <li\n data-slot=\"sidebar-menu-sub-item\"\n data-sidebar=\"menu-sub-item\"\n className={cn(\"group/menu-sub-item relative\", className)}\n {...props}\n />\n )\n}\n\nfunction SidebarMenuSubButton({\n asChild = false,\n size = \"md\",\n isActive = false,\n className,\n ...props\n}: React.ComponentProps<\"a\"> & {\n asChild?: boolean\n size?: \"sm\" | \"md\"\n isActive?: boolean\n}) {\n const Comp = asChild ? Slot.Root : \"a\"\n\n return (\n <Comp\n data-slot=\"sidebar-menu-sub-button\"\n data-sidebar=\"menu-sub-button\"\n data-size={size}\n data-active={isActive}\n aria-current={isActive ? \"page\" : undefined}\n className={cn(\n \"flex h-7 min-w-0 -translate-x-px items-center gap-2 overflow-hidden rounded-md px-2 text-sidebar-foreground ring-sidebar-ring outline-hidden group-data-[collapsible=icon]:hidden hover:bg-sidebar-accent hover:text-sidebar-accent-foreground focus-visible:ring-2 active:bg-sidebar-accent active:text-sidebar-accent-foreground disabled:pointer-events-none disabled:opacity-50 aria-disabled:pointer-events-none aria-disabled:opacity-50 data-[active=true]:bg-sidebar-primary/10 data-[active=true]:font-medium data-[active=true]:text-sidebar-primary data-[size=md]:text-sm data-[size=sm]:text-xs [&>span:last-child]:truncate [&>svg]:size-4 [&>svg]:shrink-0\",\n className\n )}\n {...props}\n />\n )\n}\n\n/**\n * A SidebarMenuButton that discloses a set of child rows underneath it\n * instead of navigating — a \"folder\" of related destinations in the rail.\n *\n * SidebarMenuSub is a static indented list with no disclosure state of its\n * own; this pairs it with Collapsible so opening/closing actually animates,\n * and flattens the indent to 0 once the sidebar collapses to icon-only\n * (`group-data-[collapsible=icon]`), matching how every other menu row in\n * this family already collapses.\n *\n * `open`/`onOpenChange` are owned by the caller, same as SidebarMenuButton's\n * `isActive` — this component holds no state of its own, so multiple\n * instances of the same rail (e.g. a docked sidebar and its own hover\n * overlay) can share one open/closed answer instead of disagreeing.\n */\nfunction SidebarMenuCollapsible({\n icon,\n label,\n children,\n open,\n onOpenChange,\n isActive = false,\n className,\n ...props\n}: Omit<React.ComponentProps<typeof SidebarMenuButton>, \"children\"> & {\n icon?: React.ReactNode\n /** The trigger row's own text — distinct from `children`, which is the disclosed row list. */\n label: React.ReactNode\n /** Child rows, revealed when open. */\n children: React.ReactNode\n open: boolean\n onOpenChange: (open: boolean) => void\n}) {\n return (\n <Collapsible open={open} onOpenChange={onOpenChange}>\n <CollapsibleTrigger asChild>\n <SidebarMenuButton\n data-slot=\"sidebar-menu-collapsible-trigger\"\n isActive={isActive}\n className={cn(!isActive && \"bg-transparent\", className)}\n {...props}\n >\n {icon}\n <span className=\"min-w-0 flex-1 truncate\">{label}</span>\n <ChevronDownIcon\n className={cn(\n \"shrink-0 text-sidebar-foreground/70 transition-transform duration-150\",\n open && \"rotate-180\"\n )}\n />\n </SidebarMenuButton>\n </CollapsibleTrigger>\n {/* forceMount keeps this mounted through the collapse so the close\n direction animates too, instead of being ripped out of the DOM the\n instant it closes. Opening only transitions opacity (the height\n lands immediately, rows fade up); closing also transitions the grid\n track, since an instant height change on that side reads as a\n jerk. */}\n <CollapsibleContent\n forceMount\n data-slot=\"sidebar-menu-collapsible-content\"\n className={cn(\n \"grid ease-out\",\n open\n ? \"visible grid-rows-[1fr] opacity-100 transition-opacity duration-150\"\n : \"invisible grid-rows-[0fr] opacity-0 transition-[grid-template-rows,opacity,visibility] duration-200\"\n )}\n >\n <div className=\"overflow-hidden\">\n <div className=\"mt-0.5 flex flex-col gap-0.5 pl-7 transition-[padding-left] duration-200 ease-linear group-data-[collapsible=icon]:pl-0\">\n {children}\n </div>\n </div>\n </CollapsibleContent>\n </Collapsible>\n )\n}\n\nexport {\n Sidebar,\n SidebarContent,\n SidebarFooter,\n SidebarGroup,\n SidebarGroupAction,\n SidebarGroupContent,\n SidebarGroupLabel,\n SidebarHeader,\n SidebarInput,\n SidebarInset,\n SidebarMenu,\n SidebarMenuAction,\n SidebarMenuBadge,\n SidebarMenuButton,\n SidebarMenuCollapsible,\n SidebarMenuItem,\n SidebarMenuSkeleton,\n SidebarMenuSub,\n SidebarMenuSubButton,\n SidebarMenuSubItem,\n SidebarProvider,\n SidebarRail,\n SidebarSeparator,\n SidebarTrigger,\n useSidebar,\n}\n\n/**\n * WHEN TO USE\n * - Persistent primary navigation in an app-shell layout — the main way\n * users move between top-level sections of the product.\n *\n * NOT WHEN\n * - A temporary/dismissible panel — use Sheet (Sidebar itself renders as a\n * Sheet on mobile automatically, but don't reach for Sidebar to build a\n * one-off drawer).\n * - Top-bar navigation — use NavigationMenu.\n * - A plain, non-collapsible list with no app-shell chrome — use Item.\n *\n * KEY RULES\n * - Requires SidebarProvider wrapping both the Sidebar and the SidebarInset\n * content — it owns the open/collapsed state via context (`useSidebar`);\n * Sidebar and SidebarInset don't work standalone.\n * - `side`: \"left\" | \"right\". `variant`: \"sidebar\" (flush) | \"floating\"\n * (rounded, ringed) | \"inset\" (content insets around it). `collapsible`:\n * \"offcanvas\" (slides fully away) | \"icon\" (shrinks to icon rail) | \"none\"\n * (always expanded, no collapse control).\n * - Below the `md` breakpoint the sidebar always renders as a Sheet\n * regardless of `collapsible`, via `useIsMobile` — don't special-case\n * mobile yourself.\n * - SidebarMenuButton's `isActive` and SidebarMenuCollapsible's `open` are\n * both caller-owned — this file holds no \"current route\" state.\n * - SidebarMenuSub is a static indented list; SidebarMenuCollapsible is the\n * version with its own open/close disclosure and icon-collapse indent\n * flattening — don't use Sub when you need a toggleable \"folder\".\n * - Cmd/Ctrl+B toggles the sidebar globally (wired inside SidebarProvider).\n *\n * USAGE\n * <SidebarProvider>\n * <Sidebar>\n * <SidebarHeader>...</SidebarHeader>\n * <SidebarContent>\n * <SidebarGroup>\n * <SidebarGroupLabel>Platform</SidebarGroupLabel>\n * <SidebarGroupContent>\n * <SidebarMenu>\n * <SidebarMenuItem>\n * <SidebarMenuButton isActive>\n * <HomeIcon />Overview\n * </SidebarMenuButton>\n * </SidebarMenuItem>\n * <SidebarMenuItem>\n * <SidebarMenuCollapsible\n * icon={<FolderIcon />}\n * label=\"Analytics\"\n * open={open}\n * onOpenChange={setOpen}\n * >\n * <SidebarMenuButton><BarChartIcon />Cohort Builder</SidebarMenuButton>\n * </SidebarMenuCollapsible>\n * </SidebarMenuItem>\n * </SidebarMenu>\n * </SidebarGroupContent>\n * </SidebarGroup>\n * </SidebarContent>\n * </Sidebar>\n * <SidebarInset>{\"<page content>\"}</SidebarInset>\n * </SidebarProvider>\n */\n"],"mappings":"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"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Skeleton — pulsing placeholder block that mirrors the shape of content still loading.
|
|
3
|
+
*
|
|
4
|
+
* A single div with an `animate-pulse` background; no internal shape logic.
|
|
5
|
+
* All sizing/shape comes from
|
|
6
|
+
* utility classes passed via `className` (e.g. `h-4 w-48`, `size-12 rounded-full`).
|
|
7
|
+
*/
|
|
8
|
+
declare function Skeleton({ className, ...props }: React.ComponentProps<"div">): import("react").JSX.Element;
|
|
9
|
+
export { Skeleton };
|
|
10
|
+
/**
|
|
11
|
+
* WHEN TO USE
|
|
12
|
+
* - Initial data fetch for a region whose layout is already known — lists, cards, tables — so the placeholder mirrors the real content shape.
|
|
13
|
+
* - Composing multiple Skeletons together (e.g. an avatar circle plus two text lines) to approximate a specific card or row.
|
|
14
|
+
*
|
|
15
|
+
* NOT WHEN
|
|
16
|
+
* - Action-level feedback on a button or small control — use Spinner instead.
|
|
17
|
+
* - Loads short enough to flash (under ~300ms) — a flashing skeleton reads as a glitch, not loading.
|
|
18
|
+
* - The final layout isn't known yet — an inaccurate placeholder is worse than a generic spinner.
|
|
19
|
+
*
|
|
20
|
+
* KEY RULES
|
|
21
|
+
* - Skeleton has no default size — always pass explicit sizing via `className` (e.g. `h-4 w-48`, `size-12 rounded-full`) to match the real content.
|
|
22
|
+
* - Shape should mirror the content it stands in for: circles for avatars, matching line-heights/widths for text.
|
|
23
|
+
*
|
|
24
|
+
* USAGE
|
|
25
|
+
* <Skeleton className="h-4 w-48" />
|
|
26
|
+
*
|
|
27
|
+
* <div className="flex items-center gap-4">
|
|
28
|
+
* <Skeleton className="size-12 rounded-full" />
|
|
29
|
+
* <div className="grid flex-1 gap-2">
|
|
30
|
+
* <Skeleton className="h-4 w-full" />
|
|
31
|
+
* <Skeleton className="h-4 w-3/5" />
|
|
32
|
+
* </div>
|
|
33
|
+
* </div>
|
|
34
|
+
*/
|
|
35
|
+
//# sourceMappingURL=skeleton.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"skeleton.d.ts","sourceRoot":"","sources":["../../../src/components/ui/skeleton.tsx"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAIH,iBAAS,QAAQ,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,KAAK,CAAC,cAAc,CAAC,KAAK,CAAC,+BAQrE;AAED,OAAO,EAAE,QAAQ,EAAE,CAAA;AAEnB;;;;;;;;;;;;;;;;;;;;;;;;GAwBG"}
|