@codefast/ui 0.3.16-canary.2 → 0.4.0-canary.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (289) hide show
  1. package/CHANGELOG.md +81 -0
  2. package/README.md +28 -17
  3. package/dist/components/accordion.d.mts +7 -22
  4. package/dist/components/accordion.mjs +26 -29
  5. package/dist/components/alert-dialog.d.mts +27 -26
  6. package/dist/components/alert-dialog.mjs +53 -45
  7. package/dist/components/alert.d.mts +14 -14
  8. package/dist/components/alert.mjs +17 -28
  9. package/dist/components/aspect-ratio.d.mts +2 -2
  10. package/dist/components/aspect-ratio.mjs +2 -3
  11. package/dist/components/avatar.d.mts +41 -5
  12. package/dist/components/avatar.mjs +40 -10
  13. package/dist/components/badge.d.mts +3 -15
  14. package/dist/components/badge.mjs +6 -48
  15. package/dist/components/breadcrumb.d.mts +1 -0
  16. package/dist/components/breadcrumb.mjs +11 -10
  17. package/dist/components/button-group.d.mts +3 -13
  18. package/dist/components/button-group.mjs +9 -31
  19. package/dist/components/button.d.mts +3 -26
  20. package/dist/components/button.mjs +9 -79
  21. package/dist/components/calendar.d.mts +6 -2
  22. package/dist/components/calendar.mjs +41 -44
  23. package/dist/components/card.d.mts +4 -2
  24. package/dist/components/card.mjs +9 -9
  25. package/dist/components/carousel.d.mts +16 -5
  26. package/dist/components/carousel.mjs +24 -11
  27. package/dist/components/chart.d.mts +9 -6
  28. package/dist/components/chart.mjs +21 -15
  29. package/dist/components/checkbox-cards.mjs +4 -4
  30. package/dist/components/checkbox-group.mjs +3 -4
  31. package/dist/components/checkbox.d.mts +2 -2
  32. package/dist/components/checkbox.mjs +6 -7
  33. package/dist/components/collapsible.d.mts +4 -4
  34. package/dist/components/collapsible.mjs +4 -5
  35. package/dist/components/command.d.mts +11 -1
  36. package/dist/components/command.mjs +35 -32
  37. package/dist/components/context-menu.d.mts +22 -15
  38. package/dist/components/context-menu.mjs +44 -39
  39. package/dist/components/dialog.d.mts +19 -23
  40. package/dist/components/dialog.mjs +48 -47
  41. package/dist/components/direction.d.mts +24 -0
  42. package/dist/components/direction.mjs +18 -0
  43. package/dist/components/drawer.d.mts +3 -21
  44. package/dist/components/drawer.mjs +19 -27
  45. package/dist/components/dropdown-menu.d.mts +22 -15
  46. package/dist/components/dropdown-menu.mjs +41 -37
  47. package/dist/components/empty.d.mts +3 -13
  48. package/dist/components/empty.mjs +8 -23
  49. package/dist/components/field.d.mts +3 -14
  50. package/dist/components/field.mjs +14 -44
  51. package/dist/components/form.d.mts +7 -10
  52. package/dist/components/form.mjs +6 -7
  53. package/dist/components/hover-card.d.mts +5 -5
  54. package/dist/components/hover-card.mjs +14 -12
  55. package/dist/components/input-group.d.mts +4 -31
  56. package/dist/components/input-group.mjs +14 -96
  57. package/dist/components/input-number.d.mts +3 -1
  58. package/dist/components/input-number.mjs +50 -28
  59. package/dist/components/input-otp.mjs +9 -7
  60. package/dist/components/input-password.mjs +1 -4
  61. package/dist/components/input-search.mjs +3 -5
  62. package/dist/components/input.mjs +1 -2
  63. package/dist/components/item.d.mts +4 -29
  64. package/dist/components/item.mjs +12 -65
  65. package/dist/components/kbd.mjs +1 -1
  66. package/dist/components/label.d.mts +2 -2
  67. package/dist/components/label.mjs +3 -4
  68. package/dist/components/menubar.d.mts +22 -16
  69. package/dist/components/menubar.mjs +54 -47
  70. package/dist/components/native-select.d.mts +5 -1
  71. package/dist/components/native-select.mjs +9 -6
  72. package/dist/components/navigation-menu.d.mts +30 -13
  73. package/dist/components/navigation-menu.mjs +35 -32
  74. package/dist/components/pagination.d.mts +7 -1
  75. package/dist/components/pagination.mjs +27 -12
  76. package/dist/components/popover.d.mts +40 -7
  77. package/dist/components/popover.mjs +46 -14
  78. package/dist/components/progress-circle.d.mts +3 -47
  79. package/dist/components/progress-circle.mjs +2 -48
  80. package/dist/components/progress.d.mts +2 -2
  81. package/dist/components/progress.mjs +5 -6
  82. package/dist/components/radio-cards.d.mts +3 -3
  83. package/dist/components/radio-cards.mjs +11 -11
  84. package/dist/components/radio-group.d.mts +3 -3
  85. package/dist/components/radio-group.mjs +9 -9
  86. package/dist/components/radio.mjs +2 -3
  87. package/dist/components/resizable.mjs +3 -8
  88. package/dist/components/scroll-area.d.mts +8 -24
  89. package/dist/components/scroll-area.mjs +16 -70
  90. package/dist/components/select.d.mts +14 -14
  91. package/dist/components/select.mjs +47 -47
  92. package/dist/components/separator.d.mts +4 -19
  93. package/dist/components/separator.mjs +6 -27
  94. package/dist/components/sheet.d.mts +18 -31
  95. package/dist/components/sheet.mjs +46 -87
  96. package/dist/components/sidebar.d.mts +3 -19
  97. package/dist/components/sidebar.mjs +48 -84
  98. package/dist/components/skeleton.mjs +1 -1
  99. package/dist/components/slider.d.mts +2 -2
  100. package/dist/components/slider.mjs +9 -11
  101. package/dist/components/sonner.mjs +11 -3
  102. package/dist/components/spinner.mjs +6 -7
  103. package/dist/components/switch.d.mts +5 -2
  104. package/dist/components/switch.mjs +7 -7
  105. package/dist/components/table.mjs +10 -10
  106. package/dist/components/tabs.d.mts +8 -5
  107. package/dist/components/tabs.mjs +18 -12
  108. package/dist/components/textarea.mjs +1 -1
  109. package/dist/components/toggle-group.d.mts +11 -7
  110. package/dist/components/toggle-group.mjs +20 -21
  111. package/dist/components/toggle.d.mts +4 -24
  112. package/dist/components/toggle.mjs +6 -45
  113. package/dist/components/tooltip.d.mts +7 -6
  114. package/dist/components/tooltip.mjs +19 -17
  115. package/dist/hooks/use-animated-value.mjs +0 -1
  116. package/dist/hooks/use-copy-to-clipboard.mjs +0 -1
  117. package/dist/hooks/use-is-mobile.mjs +0 -1
  118. package/dist/hooks/use-media-query.mjs +0 -1
  119. package/dist/hooks/use-mutation-observer.mjs +0 -1
  120. package/dist/hooks/use-pagination.mjs +0 -1
  121. package/dist/index.d.mts +38 -21
  122. package/dist/index.mjs +40 -23
  123. package/dist/lib/utils.d.mts +1 -12
  124. package/dist/lib/utils.mjs +1 -9
  125. package/dist/primitives/checkbox-group.d.mts +9 -11
  126. package/dist/primitives/checkbox-group.mjs +14 -19
  127. package/dist/primitives/input-number.d.mts +3 -4
  128. package/dist/primitives/input-number.mjs +3 -5
  129. package/dist/primitives/input.d.mts +4 -5
  130. package/dist/primitives/input.mjs +2 -3
  131. package/dist/primitives/progress-circle.d.mts +3 -4
  132. package/dist/primitives/progress-circle.mjs +2 -3
  133. package/dist/variants/alert.d.mts +18 -0
  134. package/dist/variants/alert.mjs +15 -0
  135. package/dist/variants/badge.d.mts +22 -0
  136. package/dist/variants/badge.mjs +19 -0
  137. package/dist/variants/button-group.d.mts +18 -0
  138. package/dist/variants/button-group.mjs +15 -0
  139. package/dist/variants/button.d.mts +32 -0
  140. package/dist/variants/button.mjs +34 -0
  141. package/dist/variants/empty.d.mts +18 -0
  142. package/dist/variants/empty.mjs +15 -0
  143. package/dist/variants/field.d.mts +19 -0
  144. package/dist/variants/field.mjs +16 -0
  145. package/dist/variants/input-group.d.mts +43 -0
  146. package/dist/variants/input-group.mjs +34 -0
  147. package/dist/variants/input-number.d.mts +45 -0
  148. package/dist/variants/input-number.mjs +40 -0
  149. package/dist/variants/item.d.mts +38 -0
  150. package/dist/variants/item.mjs +38 -0
  151. package/dist/variants/navigation-menu.d.mts +13 -0
  152. package/dist/variants/navigation-menu.mjs +8 -0
  153. package/dist/variants/progress-circle.d.mts +52 -0
  154. package/dist/variants/progress-circle.mjs +45 -0
  155. package/dist/variants/scroll-area.d.mts +24 -0
  156. package/dist/variants/scroll-area.mjs +58 -0
  157. package/dist/variants/separator.d.mts +23 -0
  158. package/dist/variants/separator.mjs +25 -0
  159. package/dist/variants/sheet.d.mts +20 -0
  160. package/dist/variants/sheet.mjs +17 -0
  161. package/dist/variants/sidebar.d.mts +23 -0
  162. package/dist/variants/sidebar.mjs +25 -0
  163. package/dist/variants/tabs.d.mts +18 -0
  164. package/dist/variants/tabs.mjs +15 -0
  165. package/dist/variants/toggle.d.mts +23 -0
  166. package/dist/variants/toggle.mjs +25 -0
  167. package/package.json +186 -55
  168. package/src/components/accordion.tsx +114 -0
  169. package/src/components/alert-dialog.tsx +298 -0
  170. package/src/components/alert.tsx +94 -0
  171. package/src/components/aspect-ratio.tsx +25 -0
  172. package/src/components/avatar.tsx +171 -0
  173. package/src/components/badge.tsx +35 -0
  174. package/src/components/breadcrumb.tsx +191 -0
  175. package/src/components/button-group.tsx +97 -0
  176. package/src/components/button.tsx +55 -0
  177. package/src/components/calendar.tsx +222 -0
  178. package/src/components/card.tsx +169 -0
  179. package/src/components/carousel.tsx +349 -0
  180. package/src/components/chart.tsx +536 -0
  181. package/src/components/checkbox-cards.tsx +72 -0
  182. package/src/components/checkbox-group.tsx +60 -0
  183. package/src/components/checkbox.tsx +44 -0
  184. package/src/components/collapsible.tsx +57 -0
  185. package/src/components/command.tsx +298 -0
  186. package/src/components/context-menu.tsx +410 -0
  187. package/src/components/dialog.tsx +243 -0
  188. package/src/components/direction.tsx +32 -0
  189. package/src/components/drawer.tsx +209 -0
  190. package/src/components/dropdown-menu.tsx +419 -0
  191. package/src/components/empty.tsx +155 -0
  192. package/src/components/field.tsx +329 -0
  193. package/src/components/form.tsx +258 -0
  194. package/src/components/hover-card.tsx +93 -0
  195. package/src/components/input-group.tsx +185 -0
  196. package/src/components/input-number.tsx +141 -0
  197. package/src/components/input-otp.tsx +132 -0
  198. package/src/components/input-password.tsx +50 -0
  199. package/src/components/input-search.tsx +81 -0
  200. package/src/components/input.tsx +36 -0
  201. package/src/components/item.tsx +266 -0
  202. package/src/components/kbd.tsx +47 -0
  203. package/src/components/label.tsx +36 -0
  204. package/src/components/menubar.tsx +440 -0
  205. package/src/components/native-select.tsx +87 -0
  206. package/src/components/navigation-menu.tsx +235 -0
  207. package/src/components/pagination.tsx +198 -0
  208. package/src/components/popover.tsx +170 -0
  209. package/src/components/progress-circle.tsx +185 -0
  210. package/src/components/progress.tsx +41 -0
  211. package/src/components/radio-cards.tsx +66 -0
  212. package/src/components/radio-group.tsx +59 -0
  213. package/src/components/radio.tsx +40 -0
  214. package/src/components/resizable.tsx +78 -0
  215. package/src/components/scroll-area.tsx +95 -0
  216. package/src/components/select.tsx +296 -0
  217. package/src/components/separator.tsx +60 -0
  218. package/src/components/sheet.tsx +241 -0
  219. package/src/components/sidebar.tsx +926 -0
  220. package/src/components/skeleton.tsx +35 -0
  221. package/src/components/slider.tsx +66 -0
  222. package/src/components/sonner.tsx +57 -0
  223. package/src/components/spinner.tsx +66 -0
  224. package/src/components/switch.tsx +44 -0
  225. package/src/components/table.tsx +183 -0
  226. package/src/components/tabs.tsx +110 -0
  227. package/src/components/textarea.tsx +35 -0
  228. package/src/components/toggle-group.tsx +137 -0
  229. package/src/components/toggle.tsx +30 -0
  230. package/src/components/tooltip.tsx +115 -0
  231. package/src/css/foundation/base.css +50 -0
  232. package/src/css/foundation/motion.css +36 -0
  233. package/src/css/foundation/source.css +3 -0
  234. package/src/css/foundation/tokens.css +71 -0
  235. package/src/css/foundation/variants.css +113 -0
  236. package/src/css/preset.css +5 -195
  237. package/src/css/style.css +1 -1
  238. package/src/css/{amber.css → themes/amber.css} +59 -22
  239. package/src/css/{blue.css → themes/blue.css} +59 -22
  240. package/src/css/{cyan.css → themes/cyan.css} +59 -22
  241. package/src/css/{emerald.css → themes/emerald.css} +59 -22
  242. package/src/css/{fuchsia.css → themes/fuchsia.css} +59 -22
  243. package/src/css/{gray.css → themes/gray.css} +59 -22
  244. package/src/css/{green.css → themes/green.css} +59 -22
  245. package/src/css/{indigo.css → themes/indigo.css} +59 -22
  246. package/src/css/{lime.css → themes/lime.css} +59 -22
  247. package/src/css/{neutral.css → themes/neutral.css} +59 -22
  248. package/src/css/{orange.css → themes/orange.css} +59 -22
  249. package/src/css/{pink.css → themes/pink.css} +59 -22
  250. package/src/css/{purple.css → themes/purple.css} +59 -22
  251. package/src/css/{red.css → themes/red.css} +59 -22
  252. package/src/css/{rose.css → themes/rose.css} +59 -22
  253. package/src/css/{sky.css → themes/sky.css} +59 -22
  254. package/src/css/{slate.css → themes/slate.css} +59 -22
  255. package/src/css/{stone.css → themes/stone.css} +59 -22
  256. package/src/css/{teal.css → themes/teal.css} +59 -22
  257. package/src/css/{violet.css → themes/violet.css} +59 -22
  258. package/src/css/{yellow.css → themes/yellow.css} +59 -22
  259. package/src/css/{zinc.css → themes/zinc.css} +59 -22
  260. package/src/hooks/use-animated-value.ts +91 -0
  261. package/src/hooks/use-copy-to-clipboard.ts +58 -0
  262. package/src/hooks/use-is-mobile.ts +25 -0
  263. package/src/hooks/use-media-query.ts +69 -0
  264. package/src/hooks/use-mutation-observer.ts +51 -0
  265. package/src/hooks/use-pagination.ts +164 -0
  266. package/src/index.ts +679 -0
  267. package/src/lib/utils.ts +5 -0
  268. package/src/primitives/checkbox-group.tsx +346 -0
  269. package/src/primitives/input-number.tsx +967 -0
  270. package/src/primitives/input.tsx +227 -0
  271. package/src/primitives/progress-circle.tsx +507 -0
  272. package/src/variants/alert.ts +34 -0
  273. package/src/variants/badge.ts +39 -0
  274. package/src/variants/button-group.ts +36 -0
  275. package/src/variants/button.ts +56 -0
  276. package/src/variants/empty.ts +34 -0
  277. package/src/variants/field.ts +37 -0
  278. package/src/variants/input-group.ts +80 -0
  279. package/src/variants/input-number.ts +65 -0
  280. package/src/variants/item.ts +68 -0
  281. package/src/variants/navigation-menu.ts +25 -0
  282. package/src/variants/progress-circle.ts +46 -0
  283. package/src/variants/scroll-area.ts +73 -0
  284. package/src/variants/separator.ts +40 -0
  285. package/src/variants/sheet.ts +37 -0
  286. package/src/variants/sidebar.ts +41 -0
  287. package/src/variants/tabs.ts +34 -0
  288. package/src/variants/toggle.ts +40 -0
  289. package/dist/node_modules/.pnpm/clsx@2.1.1/node_modules/clsx/clsx.d.mts +0 -6
@@ -0,0 +1,926 @@
1
+ import { PanelLeftIcon } from "lucide-react";
2
+ import { Slot } from "radix-ui";
3
+ import { Context } from "radix-ui/internal";
4
+ import type { ComponentProps, CSSProperties, Dispatch, JSX, SetStateAction } from "react";
5
+ import { useCallback, useEffect, useState } from "react";
6
+
7
+ import { Button } from "#/components/button";
8
+ import { Input } from "#/components/input";
9
+ import { Separator } from "#/components/separator";
10
+ import { Sheet, SheetContent, SheetDescription, SheetHeader, SheetTitle } from "#/components/sheet";
11
+ import { Skeleton } from "#/components/skeleton";
12
+ import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "#/components/tooltip";
13
+ import { useIsMobile } from "#/hooks/use-is-mobile";
14
+ import { cn } from "#/lib/utils";
15
+ import type { SidebarMenuButtonVariants } from "#/variants/sidebar";
16
+ import { sidebarMenuButtonVariants } from "#/variants/sidebar";
17
+
18
+ const SIDEBAR_COOKIE_NAME = "sidebar_state";
19
+ const SIDEBAR_COOKIE_MAX_AGE = 60 * 60 * 24 * 7;
20
+ const SIDEBAR_WIDTH = "16rem";
21
+ const SIDEBAR_WIDTH_MOBILE = "18rem";
22
+ const SIDEBAR_WIDTH_ICON = "3.0625rem";
23
+ const SIDEBAR_KEYBOARD_SHORTCUT = "b";
24
+
25
+ interface SidebarContextValue {
26
+ isMobile: boolean;
27
+ open: boolean;
28
+ openMobile: boolean;
29
+ setOpen: (open: boolean) => void;
30
+ setOpenMobile: Dispatch<SetStateAction<boolean>>;
31
+ state: "collapsed" | "expanded";
32
+ toggleSidebar: () => void;
33
+ }
34
+
35
+ /* -----------------------------------------------------------------------------
36
+ * Context: SidebarProvider
37
+ * -------------------------------------------------------------------------- */
38
+
39
+ const SIDEBAR_PROVIDER_NAME = "SidebarProvider";
40
+
41
+ const [SidebarContextProvider, useSidebar] = Context.createContext<SidebarContextValue>(SIDEBAR_PROVIDER_NAME);
42
+
43
+ /* -----------------------------------------------------------------------------
44
+ * Component: SidebarProvider
45
+ * -------------------------------------------------------------------------- */
46
+
47
+ /**
48
+ * @since 0.3.16-canary.0
49
+ */
50
+ interface SidebarProviderProps extends ComponentProps<"div"> {
51
+ defaultOpen?: boolean;
52
+ onOpenChange?: (open: boolean) => void;
53
+ open?: boolean;
54
+ }
55
+
56
+ /**
57
+ * @since 0.3.16-canary.0
58
+ */
59
+ function SidebarProvider({
60
+ children,
61
+ className,
62
+ defaultOpen = true,
63
+ onOpenChange: setOpenProperty,
64
+ open: openProperty,
65
+ style,
66
+ ...props
67
+ }: SidebarProviderProps): JSX.Element {
68
+ const isMobile = useIsMobile();
69
+ const [openMobile, setOpenMobile] = useState(false);
70
+
71
+ // This is the internal state of the sidebar.
72
+ // We use openProp and setOpenProp for control from outside the component.
73
+ const [isOpen, setIsOpen] = useState(defaultOpen);
74
+ const open = openProperty ?? isOpen;
75
+ const setOpen = useCallback(
76
+ (value: ((value: boolean) => boolean) | boolean) => {
77
+ const openState = typeof value === "function" ? value(open) : value;
78
+
79
+ if (setOpenProperty) {
80
+ setOpenProperty(openState);
81
+ } else {
82
+ setIsOpen(openState);
83
+ }
84
+
85
+ //
86
+ document.cookie = `${SIDEBAR_COOKIE_NAME}=${openState.toString()}; path=/; max-age=${SIDEBAR_COOKIE_MAX_AGE.toString()}`;
87
+ },
88
+ [setOpenProperty, open],
89
+ );
90
+
91
+ // Helper to toggle the sidebar.
92
+ const toggleSidebar = useCallback(() => {
93
+ if (isMobile) {
94
+ setOpenMobile((currentValue) => !currentValue);
95
+ } else {
96
+ setOpen((currentValue) => !currentValue);
97
+ }
98
+ }, [isMobile, setOpen]);
99
+
100
+ // Adds a keyboard shortcut to toggle the sidebar.
101
+ useEffect(() => {
102
+ const handleKeyDown: (event: KeyboardEvent) => void = (event: KeyboardEvent) => {
103
+ if (event.key === SIDEBAR_KEYBOARD_SHORTCUT && (event.metaKey || event.ctrlKey)) {
104
+ event.preventDefault();
105
+ toggleSidebar();
106
+ }
107
+ };
108
+
109
+ window.addEventListener("keydown", handleKeyDown);
110
+
111
+ return (): void => {
112
+ window.removeEventListener("keydown", handleKeyDown);
113
+ };
114
+ }, [toggleSidebar]);
115
+
116
+ // We add a state so that we can do data-state="expanded" or "collapsed".
117
+ // This makes it easier to style the sidebar with Tailwind classes.
118
+ const state = open ? "expanded" : "collapsed";
119
+
120
+ return (
121
+ <SidebarContextProvider
122
+ isMobile={isMobile}
123
+ open={open}
124
+ openMobile={openMobile}
125
+ setOpen={setOpen}
126
+ setOpenMobile={setOpenMobile}
127
+ state={state}
128
+ toggleSidebar={toggleSidebar}
129
+ >
130
+ <TooltipProvider delayDuration={0}>
131
+ <div
132
+ className={cn("group/sidebar-wrapper flex min-h-svh w-full has-data-[variant=inset]:bg-sidebar", className)}
133
+ data-slot="sidebar-wrapper"
134
+ style={
135
+ {
136
+ "--sidebar-width": SIDEBAR_WIDTH,
137
+ "--sidebar-width-icon": SIDEBAR_WIDTH_ICON,
138
+ ...style,
139
+ } as CSSProperties
140
+ }
141
+ {...props}
142
+ >
143
+ {children}
144
+ </div>
145
+ </TooltipProvider>
146
+ </SidebarContextProvider>
147
+ );
148
+ }
149
+
150
+ /* -----------------------------------------------------------------------------
151
+ * Component: Sidebar
152
+ * -------------------------------------------------------------------------- */
153
+
154
+ const SIDEBAR_NAME = "Sidebar";
155
+
156
+ /**
157
+ * @since 0.3.16-canary.0
158
+ */
159
+ interface SidebarProps extends ComponentProps<"div"> {
160
+ collapsible?: "icon" | "none" | "offcanvas";
161
+ side?: "left" | "right";
162
+ variant?: "floating" | "inset" | "sidebar";
163
+ }
164
+
165
+ /**
166
+ * @since 0.3.16-canary.0
167
+ */
168
+ function Sidebar({
169
+ children,
170
+ className,
171
+ collapsible = "offcanvas",
172
+ side = "left",
173
+ variant = "sidebar",
174
+ ...props
175
+ }: SidebarProps): JSX.Element {
176
+ const { isMobile, openMobile, setOpenMobile, state } = useSidebar(SIDEBAR_NAME);
177
+
178
+ if (collapsible === "none") {
179
+ return (
180
+ <div
181
+ className={cn("flex h-full w-(--sidebar-width) flex-col bg-sidebar text-sidebar-foreground", className)}
182
+ data-slot="sidebar"
183
+ {...props}
184
+ >
185
+ {children}
186
+ </div>
187
+ );
188
+ }
189
+
190
+ if (isMobile) {
191
+ return (
192
+ <Sheet open={openMobile} onOpenChange={setOpenMobile} {...props}>
193
+ <SheetContent
194
+ className="w-(--sidebar-width) bg-sidebar p-0 text-sidebar-foreground [&>button]:hidden"
195
+ data-mobile="true"
196
+ data-sidebar="sidebar"
197
+ data-slot="sidebar"
198
+ side={side}
199
+ style={
200
+ {
201
+ "--sidebar-width": SIDEBAR_WIDTH_MOBILE,
202
+ } as CSSProperties
203
+ }
204
+ >
205
+ <SheetHeader className="sr-only">
206
+ <SheetTitle>Sidebar</SheetTitle>
207
+ <SheetDescription>Displays the mobile sidebar.</SheetDescription>
208
+ </SheetHeader>
209
+ <div className="flex h-full w-full flex-col">{children}</div>
210
+ </SheetContent>
211
+ </Sheet>
212
+ );
213
+ }
214
+
215
+ return (
216
+ <div
217
+ className={cn("group peer hidden text-sidebar-foreground md:block", className)}
218
+ data-collapsible={state === "collapsed" ? collapsible : ""}
219
+ data-side={side}
220
+ data-slot="sidebar"
221
+ data-state={state}
222
+ data-variant={variant}
223
+ >
224
+ {/* This is what handles the sidebar gap on desktop */}
225
+ <div
226
+ className={cn(
227
+ "relative w-(--sidebar-width) bg-transparent transition-[width] duration-200 ease-gentle group-data-[collapsible=offcanvas]:w-0 group-data-side-right:rotate-180",
228
+ variant === "floating" || variant === "inset"
229
+ ? "group-data-[collapsible=icon]:w-[calc(var(--sidebar-width-icon)+(--spacing(4)))]"
230
+ : "group-data-[collapsible=icon]:w-(--sidebar-width-icon)",
231
+ )}
232
+ data-slot="sidebar-gap"
233
+ />
234
+ <div
235
+ className={cn(
236
+ "fixed inset-y-0 z-10 hidden h-svh w-(--sidebar-width) transition-[left,right,width] duration-200 ease-gentle md:flex data-side-right:right-0 data-side-right:group-data-[collapsible=offcanvas]:right-[calc(var(--sidebar-width)*-1)] data-side-left:left-0 data-side-left:group-data-[collapsible=offcanvas]:left-[calc(var(--sidebar-width)*-1)]",
237
+ variant === "floating" || variant === "inset"
238
+ ? "p-2 group-data-[collapsible=icon]:w-[calc(var(--sidebar-width-icon)+(--spacing(4))+2px)]"
239
+ : "group-data-[collapsible=icon]:w-(--sidebar-width-icon) group-data-side-right:border-l group-data-side-left:border-r",
240
+ className,
241
+ )}
242
+ data-side={side}
243
+ data-slot="sidebar-container"
244
+ {...props}
245
+ >
246
+ <div
247
+ className="flex size-full flex-col bg-sidebar group-data-[variant=floating]:rounded-lg group-data-[variant=floating]:shadow-sm group-data-[variant=floating]:ring-1 group-data-[variant=floating]:ring-sidebar-border"
248
+ data-sidebar="sidebar"
249
+ data-slot="sidebar-inner"
250
+ >
251
+ {children}
252
+ </div>
253
+ </div>
254
+ </div>
255
+ );
256
+ }
257
+
258
+ /* -----------------------------------------------------------------------------
259
+ * Component: SidebarTrigger
260
+ * -------------------------------------------------------------------------- */
261
+
262
+ const SIDEBAR_TRIGGER_NAME = "SidebarTrigger";
263
+
264
+ /**
265
+ * @since 0.3.16-canary.0
266
+ */
267
+ type SidebarTriggerProps = ComponentProps<typeof Button>;
268
+
269
+ /**
270
+ * @since 0.3.16-canary.0
271
+ */
272
+ function SidebarTrigger({ onClick, ...props }: SidebarTriggerProps): JSX.Element {
273
+ const { toggleSidebar } = useSidebar(SIDEBAR_TRIGGER_NAME);
274
+
275
+ return (
276
+ <Button
277
+ data-sidebar="trigger"
278
+ data-slot="sidebar-trigger"
279
+ size="icon-sm"
280
+ variant="ghost"
281
+ onClick={(event) => {
282
+ onClick?.(event);
283
+ toggleSidebar();
284
+ }}
285
+ {...props}
286
+ >
287
+ <PanelLeftIcon className="rtl:rotate-180" />
288
+ <span className="sr-only">Toggle Sidebar</span>
289
+ </Button>
290
+ );
291
+ }
292
+
293
+ /* -----------------------------------------------------------------------------
294
+ * Component: SidebarRail
295
+ * -------------------------------------------------------------------------- */
296
+
297
+ const SIDEBAR_RAIL_NAME = "SidebarRail";
298
+
299
+ /**
300
+ * @since 0.3.16-canary.0
301
+ */
302
+ type SidebarRailProps = ComponentProps<"button">;
303
+
304
+ /**
305
+ * @since 0.3.16-canary.0
306
+ */
307
+ function SidebarRail({ className, ...props }: SidebarRailProps): JSX.Element {
308
+ const { toggleSidebar } = useSidebar(SIDEBAR_RAIL_NAME);
309
+
310
+ return (
311
+ <button
312
+ className={cn(
313
+ "absolute inset-y-0 z-20 hidden w-4 transition-all ease-gentle group-data-[collapsible=offcanvas]:translate-x-0 group-data-side-right:left-0 group-data-side-left:-right-4 after:absolute after:inset-y-0 after:inset-s-1/2 after:w-0.5 group-data-[collapsible=offcanvas]:after:left-full hover:group-data-[collapsible=offcanvas]:bg-sidebar hover:after:bg-sidebar-border in-data-side-right:cursor-e-resize in-data-side-left:cursor-w-resize sm:flex ltr:-translate-x-1/2 rtl:-translate-x-1/2 [[data-side=left][data-collapsible=offcanvas]_&]:-right-2 [[data-side=left][data-state=collapsed]_&]:cursor-e-resize [[data-side=right][data-collapsible=offcanvas]_&]:-left-2 [[data-side=right][data-state=collapsed]_&]:cursor-w-resize",
314
+ className,
315
+ )}
316
+ data-sidebar="rail"
317
+ data-slot="sidebar-rail"
318
+ title="Toggle Sidebar"
319
+ type="button"
320
+ onClick={toggleSidebar}
321
+ {...props}
322
+ />
323
+ );
324
+ }
325
+
326
+ /* -----------------------------------------------------------------------------
327
+ * Component: SidebarInset
328
+ * -------------------------------------------------------------------------- */
329
+
330
+ /**
331
+ * @since 0.3.16-canary.0
332
+ */
333
+ type SidebarInsetProps = ComponentProps<"main">;
334
+
335
+ /**
336
+ * @since 0.3.16-canary.0
337
+ */
338
+ function SidebarInset({ className, ...props }: SidebarInsetProps): JSX.Element {
339
+ return (
340
+ <main
341
+ className={cn(
342
+ "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-collapsed:ml-2",
343
+ className,
344
+ )}
345
+ data-slot="sidebar-inset"
346
+ {...props}
347
+ />
348
+ );
349
+ }
350
+
351
+ /* -----------------------------------------------------------------------------
352
+ * Component: SidebarInput
353
+ * -------------------------------------------------------------------------- */
354
+
355
+ /**
356
+ * @since 0.3.16-canary.0
357
+ */
358
+ type SidebarInputProps = ComponentProps<typeof Input>;
359
+
360
+ /**
361
+ * @since 0.3.16-canary.0
362
+ */
363
+ function SidebarInput({ className, ...props }: SidebarInputProps): JSX.Element {
364
+ return (
365
+ <Input
366
+ className={cn("h-8 w-full bg-background shadow-none", className)}
367
+ data-sidebar="input"
368
+ data-slot="sidebar-input"
369
+ {...props}
370
+ />
371
+ );
372
+ }
373
+
374
+ /* -----------------------------------------------------------------------------
375
+ * Component: SidebarHeader
376
+ * -------------------------------------------------------------------------- */
377
+
378
+ /**
379
+ * @since 0.3.16-canary.0
380
+ */
381
+ type SidebarHeaderProps = ComponentProps<"div">;
382
+
383
+ /**
384
+ * @since 0.3.16-canary.0
385
+ */
386
+ function SidebarHeader({ className, ...props }: SidebarHeaderProps): JSX.Element {
387
+ return (
388
+ <div
389
+ className={cn("flex flex-col gap-2 p-2", className)}
390
+ data-sidebar="header"
391
+ data-slot="sidebar-header"
392
+ {...props}
393
+ />
394
+ );
395
+ }
396
+
397
+ /* -----------------------------------------------------------------------------
398
+ * Component: SidebarFooter
399
+ * -------------------------------------------------------------------------- */
400
+
401
+ /**
402
+ * @since 0.3.16-canary.0
403
+ */
404
+ type SidebarFooterProps = ComponentProps<"div">;
405
+
406
+ /**
407
+ * @since 0.3.16-canary.0
408
+ */
409
+ function SidebarFooter({ className, ...props }: SidebarFooterProps): JSX.Element {
410
+ return (
411
+ <div
412
+ className={cn("flex flex-col gap-2 p-2", className)}
413
+ data-sidebar="footer"
414
+ data-slot="sidebar-footer"
415
+ {...props}
416
+ />
417
+ );
418
+ }
419
+
420
+ /* -----------------------------------------------------------------------------
421
+ * Component: SidebarSeparator
422
+ * -------------------------------------------------------------------------- */
423
+
424
+ /**
425
+ * @since 0.3.16-canary.0
426
+ */
427
+ type SidebarSeparatorProps = ComponentProps<typeof Separator>;
428
+
429
+ /**
430
+ * @since 0.3.16-canary.0
431
+ */
432
+ function SidebarSeparator({ className, ...props }: SidebarSeparatorProps): JSX.Element {
433
+ return (
434
+ <Separator
435
+ className={cn("mx-2 w-auto bg-sidebar-border", className)}
436
+ data-sidebar="separator"
437
+ data-slot="sidebar-separator"
438
+ {...props}
439
+ />
440
+ );
441
+ }
442
+
443
+ /* -----------------------------------------------------------------------------
444
+ * Component: SidebarContent
445
+ * -------------------------------------------------------------------------- */
446
+
447
+ /**
448
+ * @since 0.3.16-canary.0
449
+ */
450
+ type SidebarContentProps = ComponentProps<"div">;
451
+
452
+ /**
453
+ * @since 0.3.16-canary.0
454
+ */
455
+ function SidebarContent({ className, ...props }: SidebarContentProps): JSX.Element {
456
+ return (
457
+ <div
458
+ className={cn(
459
+ "flex min-h-0 flex-1 scrollbar-none flex-col gap-2 overflow-auto group-data-[collapsible=icon]:overflow-hidden",
460
+ className,
461
+ )}
462
+ data-sidebar="content"
463
+ data-slot="sidebar-content"
464
+ {...props}
465
+ />
466
+ );
467
+ }
468
+
469
+ /* -----------------------------------------------------------------------------
470
+ * Component: SidebarGroup
471
+ * -------------------------------------------------------------------------- */
472
+
473
+ /**
474
+ * @since 0.3.16-canary.0
475
+ */
476
+ type SidebarGroupProps = ComponentProps<"div">;
477
+
478
+ /**
479
+ * @since 0.3.16-canary.0
480
+ */
481
+ function SidebarGroup({ className, ...props }: SidebarGroupProps): JSX.Element {
482
+ return (
483
+ <div
484
+ className={cn("relative flex w-full min-w-0 flex-col p-2", className)}
485
+ data-sidebar="group"
486
+ data-slot="sidebar-group"
487
+ {...props}
488
+ />
489
+ );
490
+ }
491
+
492
+ /* -----------------------------------------------------------------------------
493
+ * Component: SidebarGroupLabel
494
+ * -------------------------------------------------------------------------- */
495
+
496
+ /**
497
+ * @since 0.3.16-canary.0
498
+ */
499
+ interface SidebarGroupLabelProps extends ComponentProps<"div"> {
500
+ asChild?: boolean;
501
+ }
502
+
503
+ /**
504
+ * @since 0.3.16-canary.0
505
+ */
506
+ function SidebarGroupLabel({ asChild = false, className, ...props }: SidebarGroupLabelProps): JSX.Element {
507
+ const Component = asChild ? Slot.Root : "div";
508
+
509
+ return (
510
+ <Component
511
+ className={cn(
512
+ "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-gentle group-data-[collapsible=icon]:-mt-8 group-data-[collapsible=icon]:opacity-0 focus-visible:ring-2 [&>svg]:size-4 [&>svg]:shrink-0",
513
+ className,
514
+ )}
515
+ data-sidebar="group-label"
516
+ data-slot="sidebar-group-label"
517
+ {...props}
518
+ />
519
+ );
520
+ }
521
+
522
+ /* -----------------------------------------------------------------------------
523
+ * Component: SidebarGroupAction
524
+ * -------------------------------------------------------------------------- */
525
+
526
+ /**
527
+ * @since 0.3.16-canary.0
528
+ */
529
+ interface SidebarGroupActionProps extends ComponentProps<"button"> {
530
+ asChild?: boolean;
531
+ }
532
+
533
+ /**
534
+ * @since 0.3.16-canary.0
535
+ */
536
+ function SidebarGroupAction({ asChild = false, className, ...props }: SidebarGroupActionProps): JSX.Element {
537
+ const Component = asChild ? Slot.Root : "button";
538
+
539
+ return (
540
+ <Component
541
+ className={cn(
542
+ "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",
543
+ className,
544
+ )}
545
+ data-sidebar="group-action"
546
+ data-slot="sidebar-group-action"
547
+ {...props}
548
+ />
549
+ );
550
+ }
551
+
552
+ /* -----------------------------------------------------------------------------
553
+ * Component: SidebarGroupContent
554
+ * -------------------------------------------------------------------------- */
555
+
556
+ /**
557
+ * @since 0.3.16-canary.0
558
+ */
559
+ type SidebarGroupContentProps = ComponentProps<"div">;
560
+
561
+ /**
562
+ * @since 0.3.16-canary.0
563
+ */
564
+ function SidebarGroupContent({ className, ...props }: SidebarGroupContentProps): JSX.Element {
565
+ return (
566
+ <div
567
+ className={cn("w-full text-sm", className)}
568
+ data-sidebar="group-content"
569
+ data-slot="sidebar-group-content"
570
+ {...props}
571
+ />
572
+ );
573
+ }
574
+
575
+ /* -----------------------------------------------------------------------------
576
+ * Component: SidebarMenu
577
+ * -------------------------------------------------------------------------- */
578
+
579
+ /**
580
+ * @since 0.3.16-canary.0
581
+ */
582
+ type SidebarMenuProps = ComponentProps<"ul">;
583
+
584
+ /**
585
+ * @since 0.3.16-canary.0
586
+ */
587
+ function SidebarMenu({ className, ...props }: SidebarMenuProps): JSX.Element {
588
+ return (
589
+ <ul
590
+ className={cn("flex w-full min-w-0 flex-col gap-1", className)}
591
+ data-sidebar="menu"
592
+ data-slot="sidebar-menu"
593
+ {...props}
594
+ />
595
+ );
596
+ }
597
+
598
+ /* -----------------------------------------------------------------------------
599
+ * Component: SidebarMenuItem
600
+ * -------------------------------------------------------------------------- */
601
+
602
+ /**
603
+ * @since 0.3.16-canary.0
604
+ */
605
+ type SidebarMenuItemProps = ComponentProps<"li">;
606
+
607
+ /**
608
+ * @since 0.3.16-canary.0
609
+ */
610
+ function SidebarMenuItem({ className, ...props }: SidebarMenuItemProps): JSX.Element {
611
+ return (
612
+ <li
613
+ className={cn("group/menu-item relative", className)}
614
+ data-sidebar="menu-item"
615
+ data-slot="sidebar-menu-item"
616
+ {...props}
617
+ />
618
+ );
619
+ }
620
+
621
+ /* -----------------------------------------------------------------------------
622
+ * Component: SidebarMenuButton
623
+ * -------------------------------------------------------------------------- */
624
+
625
+ const SIDEBAR_MENU_BUTTON_NAME = "SidebarMenuButton";
626
+
627
+ /**
628
+ * @since 0.3.16-canary.0
629
+ */
630
+ interface SidebarMenuButtonProps extends ComponentProps<"button">, SidebarMenuButtonVariants {
631
+ asChild?: boolean;
632
+ isActive?: boolean;
633
+ tooltip?: ComponentProps<typeof TooltipContent> | string;
634
+ }
635
+
636
+ /**
637
+ * @since 0.3.16-canary.0
638
+ */
639
+ function SidebarMenuButton({
640
+ asChild = false,
641
+ className,
642
+ isActive = false,
643
+ size = "default",
644
+ tooltip,
645
+ variant = "default",
646
+ ...props
647
+ }: SidebarMenuButtonProps): JSX.Element {
648
+ const Component = asChild ? Slot.Root : "button";
649
+ const { isMobile, state } = useSidebar(SIDEBAR_MENU_BUTTON_NAME);
650
+
651
+ const button = (
652
+ <Component
653
+ className={sidebarMenuButtonVariants({ size, variant, className })}
654
+ data-active={isActive}
655
+ data-sidebar="menu-button"
656
+ data-size={size}
657
+ data-slot="sidebar-menu-button"
658
+ {...props}
659
+ />
660
+ );
661
+
662
+ if (!tooltip) {
663
+ return button;
664
+ }
665
+
666
+ if (typeof tooltip === "string") {
667
+ tooltip = {
668
+ children: tooltip,
669
+ };
670
+ }
671
+
672
+ return (
673
+ <Tooltip>
674
+ <TooltipTrigger asChild>{button}</TooltipTrigger>
675
+ <TooltipContent align="center" hidden={state !== "collapsed" || isMobile} side="right" {...tooltip} />
676
+ </Tooltip>
677
+ );
678
+ }
679
+
680
+ /* -----------------------------------------------------------------------------
681
+ * Component: SidebarMenuAction
682
+ * -------------------------------------------------------------------------- */
683
+
684
+ /**
685
+ * @since 0.3.16-canary.0
686
+ */
687
+ interface SidebarMenuActionProps extends ComponentProps<"button"> {
688
+ asChild?: boolean;
689
+ showOnHover?: boolean;
690
+ }
691
+
692
+ /**
693
+ * @since 0.3.16-canary.0
694
+ */
695
+ function SidebarMenuAction({
696
+ asChild = false,
697
+ className,
698
+ showOnHover = false,
699
+ ...props
700
+ }: SidebarMenuActionProps): JSX.Element {
701
+ const Component = asChild ? Slot.Root : "button";
702
+
703
+ return (
704
+ <Component
705
+ className={cn(
706
+ "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",
707
+ showOnHover &&
708
+ "group-focus-within/menu-item:opacity-100 group-hover/menu-item:opacity-100 peer-data-active/menu-button:text-sidebar-accent-foreground aria-expanded:opacity-100 md:opacity-0",
709
+ className,
710
+ )}
711
+ data-sidebar="menu-action"
712
+ data-slot="sidebar-menu-action"
713
+ {...props}
714
+ />
715
+ );
716
+ }
717
+
718
+ /* -----------------------------------------------------------------------------
719
+ * Component: SidebarMenuBadge
720
+ * -------------------------------------------------------------------------- */
721
+
722
+ /**
723
+ * @since 0.3.16-canary.0
724
+ */
725
+ type SidebarMenuBadgeProps = ComponentProps<"div">;
726
+
727
+ /**
728
+ * @since 0.3.16-canary.0
729
+ */
730
+ function SidebarMenuBadge({ className, ...props }: SidebarMenuBadgeProps): JSX.Element {
731
+ return (
732
+ <div
733
+ className={cn(
734
+ "pointer-events-none absolute right-1 flex h-5 min-w-5 items-center justify-center rounded-md px-1 text-xs font-medium text-sidebar-foreground tabular-nums select-none group-data-[collapsible=icon]:hidden peer-hover/menu-button:text-sidebar-accent-foreground peer-data-[size=default]/menu-button:top-1.5 peer-data-[size=lg]/menu-button:top-2.5 peer-data-[size=sm]/menu-button:top-1 peer-data-active/menu-button:text-sidebar-accent-foreground",
735
+ className,
736
+ )}
737
+ data-sidebar="menu-badge"
738
+ data-slot="sidebar-menu-badge"
739
+ {...props}
740
+ />
741
+ );
742
+ }
743
+
744
+ /* -----------------------------------------------------------------------------
745
+ * Component: SidebarMenuSkeleton
746
+ * -------------------------------------------------------------------------- */
747
+
748
+ /**
749
+ * @since 0.3.16-canary.0
750
+ */
751
+ interface SidebarMenuSkeletonProps extends ComponentProps<"div"> {
752
+ showIcon?: boolean;
753
+ }
754
+
755
+ /**
756
+ * @since 0.3.16-canary.0
757
+ */
758
+ function SidebarMenuSkeleton({ className, showIcon = false, ...props }: SidebarMenuSkeletonProps): JSX.Element {
759
+ // Random width between 50 to 90% - use useState with lazy initializer to avoid calling Math.random during render
760
+ const [width] = useState(() => `${String(Math.floor(Math.random() * 40) + 50)}%`);
761
+
762
+ return (
763
+ <div
764
+ className={cn("flex h-8 items-center gap-2 rounded-md px-2", className)}
765
+ data-sidebar="menu-skeleton"
766
+ data-slot="sidebar-menu-skeleton"
767
+ {...props}
768
+ >
769
+ {showIcon ? <Skeleton className="size-4 rounded-md" data-sidebar="menu-skeleton-icon" /> : null}
770
+ <Skeleton
771
+ className="h-4 max-w-(--skeleton-width) flex-1"
772
+ data-sidebar="menu-skeleton-text"
773
+ style={
774
+ {
775
+ "--skeleton-width": width,
776
+ } as CSSProperties
777
+ }
778
+ />
779
+ </div>
780
+ );
781
+ }
782
+
783
+ /* -----------------------------------------------------------------------------
784
+ * Component: SidebarMenuSub
785
+ * -------------------------------------------------------------------------- */
786
+
787
+ /**
788
+ * @since 0.3.16-canary.0
789
+ */
790
+ type SidebarMenuSubProps = ComponentProps<"ul">;
791
+
792
+ /**
793
+ * @since 0.3.16-canary.0
794
+ */
795
+ function SidebarMenuSub({ className, ...props }: SidebarMenuSubProps): JSX.Element {
796
+ return (
797
+ <ul
798
+ className={cn(
799
+ "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",
800
+ className,
801
+ )}
802
+ data-sidebar="menu-sub"
803
+ data-slot="sidebar-menu-sub"
804
+ {...props}
805
+ />
806
+ );
807
+ }
808
+
809
+ /* -----------------------------------------------------------------------------
810
+ * Component: SidebarMenuSubItem
811
+ * -------------------------------------------------------------------------- */
812
+
813
+ /**
814
+ * @since 0.3.16-canary.0
815
+ */
816
+ type SidebarMenuSubItemProps = ComponentProps<"li">;
817
+
818
+ /**
819
+ * @since 0.3.16-canary.0
820
+ */
821
+ function SidebarMenuSubItem({ className, ...props }: SidebarMenuSubItemProps): JSX.Element {
822
+ return (
823
+ <li
824
+ className={cn("group/menu-sub-item relative", className)}
825
+ data-sidebar="menu-sub-item"
826
+ data-slot="sidebar-menu-sub-item"
827
+ {...props}
828
+ />
829
+ );
830
+ }
831
+
832
+ /* -----------------------------------------------------------------------------
833
+ * Component: SidebarMenuSubButton
834
+ * -------------------------------------------------------------------------- */
835
+
836
+ /**
837
+ * @since 0.3.16-canary.0
838
+ */
839
+ interface SidebarMenuSubButtonProps extends ComponentProps<"a"> {
840
+ asChild?: boolean;
841
+ isActive?: boolean;
842
+ size?: "md" | "sm";
843
+ }
844
+
845
+ /**
846
+ * @since 0.3.16-canary.0
847
+ */
848
+ function SidebarMenuSubButton({
849
+ asChild = false,
850
+ className,
851
+ isActive = false,
852
+ size = "md",
853
+ ...props
854
+ }: SidebarMenuSubButtonProps): JSX.Element {
855
+ const Component = asChild ? Slot.Root : "a";
856
+
857
+ return (
858
+ <Component
859
+ className={cn(
860
+ "flex h-7 min-w-0 -translate-x-px items-center gap-2 overflow-hidden rounded-md px-2 text-sidebar-foreground ring-sidebar-ring outline-hidden group-data-[collapsible=icon]:hidden hover:bg-sidebar-accent hover:text-sidebar-accent-foreground focus-visible:ring-2 active:bg-sidebar-accent active:text-sidebar-accent-foreground disabled:pointer-events-none disabled:opacity-50 aria-disabled:pointer-events-none aria-disabled:opacity-50 data-[size=md]:text-sm data-[size=sm]:text-xs data-active:bg-sidebar-accent data-active:text-sidebar-accent-foreground [&>span:last-child]:truncate [&>svg]:size-4 [&>svg]:shrink-0 [&>svg]:text-sidebar-accent-foreground",
861
+ className,
862
+ )}
863
+ data-active={isActive}
864
+ data-sidebar="menu-sub-button"
865
+ data-size={size}
866
+ data-slot="sidebar-menu-sub-button"
867
+ {...props}
868
+ />
869
+ );
870
+ }
871
+
872
+ /* -----------------------------------------------------------------------------
873
+ * Exports
874
+ * -------------------------------------------------------------------------- */
875
+
876
+ export {
877
+ Sidebar,
878
+ SidebarContent,
879
+ SidebarFooter,
880
+ SidebarGroup,
881
+ SidebarGroupAction,
882
+ SidebarGroupContent,
883
+ SidebarGroupLabel,
884
+ SidebarHeader,
885
+ SidebarInput,
886
+ SidebarInset,
887
+ SidebarMenu,
888
+ SidebarMenuAction,
889
+ SidebarMenuBadge,
890
+ SidebarMenuButton,
891
+ SidebarMenuItem,
892
+ SidebarMenuSkeleton,
893
+ SidebarMenuSub,
894
+ SidebarMenuSubButton,
895
+ SidebarMenuSubItem,
896
+ SidebarProvider,
897
+ SidebarRail,
898
+ SidebarSeparator,
899
+ SidebarTrigger,
900
+ useSidebar,
901
+ };
902
+ export type {
903
+ SidebarContentProps,
904
+ SidebarFooterProps,
905
+ SidebarGroupActionProps,
906
+ SidebarGroupContentProps,
907
+ SidebarGroupLabelProps,
908
+ SidebarGroupProps,
909
+ SidebarHeaderProps,
910
+ SidebarInputProps,
911
+ SidebarInsetProps,
912
+ SidebarMenuActionProps,
913
+ SidebarMenuBadgeProps,
914
+ SidebarMenuButtonProps,
915
+ SidebarMenuItemProps,
916
+ SidebarMenuProps,
917
+ SidebarMenuSkeletonProps,
918
+ SidebarMenuSubButtonProps,
919
+ SidebarMenuSubItemProps,
920
+ SidebarMenuSubProps,
921
+ SidebarProps,
922
+ SidebarProviderProps,
923
+ SidebarRailProps,
924
+ SidebarSeparatorProps,
925
+ SidebarTriggerProps,
926
+ };