@hobenakicoffee/libraries 1.28.0 → 1.29.1

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 (38) hide show
  1. package/package.json +5 -39
  2. package/src/nuqs/common.ts +12 -0
  3. package/src/nuqs/index.ts +2 -0
  4. package/src/nuqs/transactions.ts +31 -0
  5. package/src/components/ui/alert-dialog.tsx +0 -196
  6. package/src/components/ui/alert.tsx +0 -76
  7. package/src/components/ui/avatar.tsx +0 -110
  8. package/src/components/ui/badge.tsx +0 -49
  9. package/src/components/ui/breadcrumb.tsx +0 -122
  10. package/src/components/ui/button-group.tsx +0 -82
  11. package/src/components/ui/card.tsx +0 -100
  12. package/src/components/ui/chart.tsx +0 -364
  13. package/src/components/ui/checkbox.tsx +0 -30
  14. package/src/components/ui/dialog.tsx +0 -162
  15. package/src/components/ui/drawer.tsx +0 -126
  16. package/src/components/ui/dropdown-menu.tsx +0 -267
  17. package/src/components/ui/empty-minimal.tsx +0 -20
  18. package/src/components/ui/empty.tsx +0 -101
  19. package/src/components/ui/field.tsx +0 -235
  20. package/src/components/ui/input-group.tsx +0 -170
  21. package/src/components/ui/input-otp.tsx +0 -84
  22. package/src/components/ui/input.tsx +0 -37
  23. package/src/components/ui/item.tsx +0 -196
  24. package/src/components/ui/label.tsx +0 -19
  25. package/src/components/ui/popover.tsx +0 -87
  26. package/src/components/ui/radio-group.tsx +0 -47
  27. package/src/components/ui/select.tsx +0 -205
  28. package/src/components/ui/separator.tsx +0 -26
  29. package/src/components/ui/sheet.tsx +0 -141
  30. package/src/components/ui/sidebar.tsx +0 -699
  31. package/src/components/ui/skeleton.tsx +0 -13
  32. package/src/components/ui/sonner.tsx +0 -74
  33. package/src/components/ui/table.tsx +0 -114
  34. package/src/components/ui/tabs.tsx +0 -88
  35. package/src/components/ui/textarea.tsx +0 -35
  36. package/src/components/ui/toggle-group.tsx +0 -91
  37. package/src/components/ui/toggle.tsx +0 -44
  38. package/src/components/ui/tooltip.tsx +0 -59
@@ -1,699 +0,0 @@
1
- import { SidebarLeftIcon } from "@hugeicons/core-free-icons";
2
- import { HugeiconsIcon } from "@hugeicons/react";
3
- import { cva, type VariantProps } from "class-variance-authority";
4
- import { Slot } from "radix-ui";
5
- import {
6
- type ComponentProps,
7
- type CSSProperties,
8
- createContext,
9
- useCallback,
10
- useContext,
11
- useEffect,
12
- useMemo,
13
- useState,
14
- } from "react";
15
- import { Button } from "@/components/ui/button";
16
- import { Input } from "@/components/ui/input";
17
- import { Separator } from "@/components/ui/separator";
18
- import {
19
- Sheet,
20
- SheetContent,
21
- SheetDescription,
22
- SheetHeader,
23
- SheetTitle,
24
- } from "@/components/ui/sheet";
25
- import { Skeleton } from "@/components/ui/skeleton";
26
- import {
27
- Tooltip,
28
- TooltipContent,
29
- TooltipTrigger,
30
- } from "@/components/ui/tooltip";
31
- import { useIsMobile } from "@/hooks/use-mobile";
32
- import { cn } from "@/lib/utils";
33
-
34
- const SIDEBAR_COOKIE_NAME = "sidebar_state";
35
- const SIDEBAR_COOKIE_MAX_AGE = 60 * 60 * 24 * 7;
36
- const SIDEBAR_WIDTH = "16rem";
37
- const SIDEBAR_WIDTH_MOBILE = "18rem";
38
- const SIDEBAR_WIDTH_ICON = "3rem";
39
- const SIDEBAR_KEYBOARD_SHORTCUT = "b";
40
-
41
- type SidebarContextProps = {
42
- state: "expanded" | "collapsed";
43
- open: boolean;
44
- setOpen: (open: boolean) => void;
45
- openMobile: boolean;
46
- setOpenMobile: (open: boolean) => void;
47
- isMobile: boolean;
48
- toggleSidebar: () => void;
49
- };
50
-
51
- const SidebarContext = createContext<SidebarContextProps | null>(null);
52
-
53
- function useSidebar() {
54
- const context = useContext(SidebarContext);
55
- if (!context) {
56
- throw new Error("useSidebar must be used within a SidebarProvider.");
57
- }
58
-
59
- return context;
60
- }
61
-
62
- function SidebarProvider({
63
- defaultOpen = true,
64
- open: openProp,
65
- onOpenChange: setOpenProp,
66
- className,
67
- style,
68
- children,
69
- ...props
70
- }: ComponentProps<"div"> & {
71
- defaultOpen?: boolean;
72
- open?: boolean;
73
- onOpenChange?: (open: boolean) => void;
74
- }) {
75
- const isMobile = useIsMobile();
76
- const [openMobile, setOpenMobile] = useState(false);
77
-
78
- // This is the internal state of the sidebar.
79
- // We use openProp and setOpenProp for control from outside the component.
80
- const [_open, _setOpen] = useState(defaultOpen);
81
- const open = openProp ?? _open;
82
- const setOpen = useCallback(
83
- (value: boolean | ((value: boolean) => boolean)) => {
84
- const openState = typeof value === "function" ? value(open) : value;
85
- if (setOpenProp) {
86
- setOpenProp(openState);
87
- } else {
88
- _setOpen(openState);
89
- }
90
-
91
- // This sets the cookie to keep the sidebar state.
92
- // biome-ignore lint/suspicious/noDocumentCookie: <shadcn frontend cookie>
93
- document.cookie = `${SIDEBAR_COOKIE_NAME}=${openState}; path=/; max-age=${SIDEBAR_COOKIE_MAX_AGE}`;
94
- },
95
- [setOpenProp, open]
96
- );
97
-
98
- // Helper to toggle the sidebar.
99
- const toggleSidebar = useCallback(() => {
100
- return isMobile ? setOpenMobile((open) => !open) : setOpen((open) => !open);
101
- }, [isMobile, setOpen, setOpenMobile]);
102
-
103
- // Adds a keyboard shortcut to toggle the sidebar.
104
- useEffect(() => {
105
- const handleKeyDown = (event: KeyboardEvent) => {
106
- if (
107
- event.key === SIDEBAR_KEYBOARD_SHORTCUT &&
108
- (event.metaKey || event.ctrlKey)
109
- ) {
110
- event.preventDefault();
111
- toggleSidebar();
112
- }
113
- };
114
-
115
- window.addEventListener("keydown", handleKeyDown);
116
- return () => window.removeEventListener("keydown", handleKeyDown);
117
- }, [toggleSidebar]);
118
-
119
- // We add a state so that we can do data-state="expanded" or "collapsed".
120
- // This makes it easier to style the sidebar with Tailwind classes.
121
- const state = open ? "expanded" : "collapsed";
122
-
123
- const contextValue = useMemo<SidebarContextProps>(
124
- () => ({
125
- state,
126
- open,
127
- setOpen,
128
- isMobile,
129
- openMobile,
130
- setOpenMobile,
131
- toggleSidebar,
132
- }),
133
- [state, open, setOpen, isMobile, openMobile, setOpenMobile, toggleSidebar]
134
- );
135
-
136
- return (
137
- <SidebarContext.Provider value={contextValue}>
138
- <div
139
- className={cn(
140
- "group/sidebar-wrapper flex min-h-svh w-full has-data-[variant=inset]:bg-sidebar",
141
- className
142
- )}
143
- data-slot="sidebar-wrapper"
144
- style={
145
- {
146
- "--sidebar-width": SIDEBAR_WIDTH,
147
- "--sidebar-width-icon": SIDEBAR_WIDTH_ICON,
148
- ...style,
149
- } as CSSProperties
150
- }
151
- {...props}
152
- >
153
- {children}
154
- </div>
155
- </SidebarContext.Provider>
156
- );
157
- }
158
-
159
- function Sidebar({
160
- side = "left",
161
- variant = "sidebar",
162
- collapsible = "offCanvas",
163
- className,
164
- children,
165
- ...props
166
- }: ComponentProps<"div"> & {
167
- side?: "left" | "right";
168
- variant?: "sidebar" | "floating" | "inset";
169
- collapsible?: "offCanvas" | "icon" | "none";
170
- }) {
171
- const { isMobile, state, openMobile, setOpenMobile } = useSidebar();
172
-
173
- if (collapsible === "none") {
174
- return (
175
- <div
176
- className={cn(
177
- "flex h-full w-(--sidebar-width) flex-col bg-sidebar text-sidebar-foreground/70",
178
- className
179
- )}
180
- data-slot="sidebar"
181
- {...props}
182
- >
183
- {children}
184
- </div>
185
- );
186
- }
187
-
188
- if (isMobile) {
189
- return (
190
- <Sheet onOpenChange={setOpenMobile} open={openMobile} {...props}>
191
- <SheetContent
192
- className="w-(--sidebar-width) bg-sidebar p-0 text-sidebar-foreground/70 [&>button]:hidden"
193
- data-mobile="true"
194
- data-sidebar="sidebar"
195
- data-slot="sidebar"
196
- side={side}
197
- style={
198
- {
199
- "--sidebar-width": SIDEBAR_WIDTH_MOBILE,
200
- } as CSSProperties
201
- }
202
- >
203
- <SheetHeader className="sr-only">
204
- <SheetTitle>Sidebar</SheetTitle>
205
- <SheetDescription>Displays the mobile sidebar.</SheetDescription>
206
- </SheetHeader>
207
- <div className="flex h-full w-full flex-col">{children}</div>
208
- </SheetContent>
209
- </Sheet>
210
- );
211
- }
212
-
213
- return (
214
- <div
215
- className="group peer hidden border-r text-sidebar-foreground/70 lg:block"
216
- data-collapsible={state === "collapsed" ? collapsible : ""}
217
- data-side={side}
218
- data-slot="sidebar"
219
- data-state={state}
220
- data-variant={variant}
221
- >
222
- {/* This is what handles the sidebar gap on desktop */}
223
- <div
224
- className={cn(
225
- "relative w-(--sidebar-width) bg-transparent transition-[width] duration-200 ease-linear",
226
- "group-data-[collapsible=offCanvas]:w-0",
227
- "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-linear lg:flex",
237
- side === "left"
238
- ? "left-0 group-data-[collapsible=offCanvas]:left-[calc(var(--sidebar-width)*-1)]"
239
- : "right-0 group-data-[collapsible=offCanvas]:right-[calc(var(--sidebar-width)*-1)]",
240
- // Adjust the padding for floating and inset variants.
241
- variant === "floating" || variant === "inset"
242
- ? "p-2 group-data-[collapsible=icon]:w-[calc(var(--sidebar-width-icon)+(--spacing(4))+2px)]"
243
- : "group-data-[collapsible=icon]:w-(--sidebar-width-icon) group-data-[side=left]:border-r group-data-[side=right]:border-l",
244
- className
245
- )}
246
- data-slot="sidebar-container"
247
- {...props}
248
- >
249
- <div
250
- 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"
251
- data-sidebar="sidebar"
252
- data-slot="sidebar-inner"
253
- >
254
- {children}
255
- </div>
256
- </div>
257
- </div>
258
- );
259
- }
260
-
261
- function SidebarTrigger({
262
- className,
263
- onClick,
264
- ...props
265
- }: ComponentProps<typeof Button>) {
266
- const { toggleSidebar } = useSidebar();
267
-
268
- return (
269
- <Button
270
- className={cn("w-12 bg-background", className)}
271
- data-sidebar="trigger"
272
- data-slot="sidebar-trigger"
273
- onClick={(event) => {
274
- onClick?.(event);
275
- toggleSidebar();
276
- }}
277
- variant="outline"
278
- {...props}
279
- >
280
- <HugeiconsIcon icon={SidebarLeftIcon} strokeWidth={2} />
281
- <span className="sr-only">Toggle Sidebar</span>
282
- </Button>
283
- );
284
- }
285
-
286
- function SidebarRail({ className, ...props }: ComponentProps<"button">) {
287
- const { toggleSidebar } = useSidebar();
288
-
289
- return (
290
- <button
291
- aria-label="Toggle Sidebar"
292
- className={cn(
293
- "absolute inset-y-0 z-20 hidden w-4 -translate-x-1/2 transition-all ease-linear after:absolute after:inset-y-0 after:left-1/2 after:w-0.5 hover:after:bg-sidebar-border group-data-[side=left]:-right-4 group-data-[side=right]:left-0 sm:flex",
294
- "in-data-[side=left]:cursor-w-resize in-data-[side=right]:cursor-e-resize",
295
- "[[data-side=left][data-state=collapsed]_&]:cursor-e-resize [[data-side=right][data-state=collapsed]_&]:cursor-w-resize",
296
- "group-data-[collapsible=offCanvas]:translate-x-0 hover:group-data-[collapsible=offCanvas]:bg-sidebar group-data-[collapsible=offCanvas]:after:left-full",
297
- "[[data-side=left][data-collapsible=offCanvas]_&]:-right-2",
298
- "[[data-side=right][data-collapsible=offCanvas]_&]:-left-2",
299
- className
300
- )}
301
- data-sidebar="rail"
302
- data-slot="sidebar-rail"
303
- onClick={toggleSidebar}
304
- tabIndex={-1}
305
- title="Toggle Sidebar"
306
- {...props}
307
- />
308
- );
309
- }
310
-
311
- function SidebarInset({ className, ...props }: ComponentProps<"main">) {
312
- return (
313
- <main
314
- className={cn(
315
- "relative flex w-full flex-1 flex-col bg-primary/3",
316
- className
317
- )}
318
- data-slot="sidebar-inset"
319
- {...props}
320
- />
321
- );
322
- }
323
-
324
- function SidebarInput({ className, ...props }: ComponentProps<typeof Input>) {
325
- return (
326
- <Input
327
- className={cn("h-8 w-full bg-background shadow-none", className)}
328
- data-sidebar="input"
329
- data-slot="sidebar-input"
330
- {...props}
331
- />
332
- );
333
- }
334
-
335
- function SidebarHeader({ className, ...props }: ComponentProps<"div">) {
336
- return (
337
- <div
338
- className={cn("flex flex-col gap-2 p-2", className)}
339
- data-sidebar="header"
340
- data-slot="sidebar-header"
341
- {...props}
342
- />
343
- );
344
- }
345
-
346
- function SidebarFooter({ className, ...props }: ComponentProps<"div">) {
347
- return (
348
- <div
349
- className={cn("flex flex-col gap-2 p-2", className)}
350
- data-sidebar="footer"
351
- data-slot="sidebar-footer"
352
- {...props}
353
- />
354
- );
355
- }
356
-
357
- function SidebarSeparator({
358
- className,
359
- ...props
360
- }: ComponentProps<typeof Separator>) {
361
- return (
362
- <Separator
363
- className={cn("mx-2 w-auto bg-sidebar-border", className)}
364
- data-sidebar="separator"
365
- data-slot="sidebar-separator"
366
- {...props}
367
- />
368
- );
369
- }
370
-
371
- function SidebarContent({ className, ...props }: ComponentProps<"div">) {
372
- return (
373
- <div
374
- className={cn(
375
- "no-scrollbar flex min-h-0 flex-1 flex-col gap-2 overflow-auto group-data-[collapsible=icon]:overflow-hidden",
376
- className
377
- )}
378
- data-sidebar="content"
379
- data-slot="sidebar-content"
380
- {...props}
381
- />
382
- );
383
- }
384
-
385
- function SidebarGroup({ className, ...props }: ComponentProps<"div">) {
386
- return (
387
- <div
388
- className={cn("relative flex w-full min-w-0 flex-col p-2", className)}
389
- data-sidebar="group"
390
- data-slot="sidebar-group"
391
- {...props}
392
- />
393
- );
394
- }
395
-
396
- function SidebarGroupLabel({
397
- className,
398
- asChild = false,
399
- ...props
400
- }: ComponentProps<"div"> & { asChild?: boolean }) {
401
- const Comp = asChild ? Slot.Root : "div";
402
-
403
- return (
404
- <Comp
405
- className={cn(
406
- "ml-2 flex h-8 shrink-0 items-center rounded-md px-2 font-medium text-sidebar-foreground/50 text-sm outline-hidden ring-sidebar-ring transition-[margin,opacity] duration-200 ease-linear focus-visible:ring-2 group-data-[collapsible=icon]:-mt-8 group-data-[collapsible=icon]:opacity-0 [&>svg]:size-4 [&>svg]:shrink-0",
407
- className
408
- )}
409
- data-sidebar="group-label"
410
- data-slot="sidebar-group-label"
411
- {...props}
412
- />
413
- );
414
- }
415
-
416
- function SidebarGroupAction({
417
- className,
418
- asChild = false,
419
- ...props
420
- }: ComponentProps<"button"> & { asChild?: boolean }) {
421
- const Comp = asChild ? Slot.Root : "button";
422
-
423
- return (
424
- <Comp
425
- className={cn(
426
- "absolute top-3.5 right-3 flex aspect-square w-5 items-center justify-center rounded-md p-0 text-sidebar-foreground/70 outline-hidden ring-sidebar-ring transition-transform after:absolute after:-inset-2 hover:bg-sidebar-accent hover:text-sidebar-accent-foreground focus-visible:ring-2 group-data-[collapsible=icon]:hidden lg:after:hidden [&>svg]:size-4 [&>svg]:shrink-0",
427
- className
428
- )}
429
- data-sidebar="group-action"
430
- data-slot="sidebar-group-action"
431
- {...props}
432
- />
433
- );
434
- }
435
-
436
- function SidebarGroupContent({ className, ...props }: ComponentProps<"div">) {
437
- return (
438
- <div
439
- className={cn("w-full text-base", className)}
440
- data-sidebar="group-content"
441
- data-slot="sidebar-group-content"
442
- {...props}
443
- />
444
- );
445
- }
446
-
447
- function SidebarMenu({ className, ...props }: ComponentProps<"ul">) {
448
- return (
449
- <ul
450
- className={cn("flex w-full min-w-0 flex-col gap-1", className)}
451
- data-sidebar="menu"
452
- data-slot="sidebar-menu"
453
- {...props}
454
- />
455
- );
456
- }
457
-
458
- function SidebarMenuItem({ className, ...props }: ComponentProps<"li">) {
459
- return (
460
- <li
461
- className={cn("group/menu-item relative", className)}
462
- data-sidebar="menu-item"
463
- data-slot="sidebar-menu-item"
464
- {...props}
465
- />
466
- );
467
- }
468
-
469
- const sidebarMenuButtonVariants = cva(
470
- "peer/menu-button flex w-full items-center gap-3 overflow-hidden rounded-xl px-4 py-3 text-left font-medium text-base outline-hidden ring-sidebar-ring transition-[width,height,padding] 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 group-has-data-[sidebar=menu-action]/menu-item:pr-8 aria-disabled:pointer-events-none aria-disabled:opacity-50 data-active:bg-sidebar-accent data-active:font-medium data-active:text-sidebar-accent-foreground data-open:hover:bg-sidebar-accent data-open:hover:text-sidebar-accent-foreground group-data-[collapsible=icon]:size-8! group-data-[collapsible=icon]:p-4! [&>span:last-child]:truncate [&_svg]:size-4 [&_svg]:shrink-0",
471
- {
472
- variants: {
473
- variant: {
474
- default:
475
- "hover:bg-muted hover:text-sidebar-accent data-active:hover:bg-sidebar-accent data-active:hover:text-sidebar-accent-foreground",
476
- outline:
477
- "bg-background shadow-[0_0_0_1px_hsl(var(--sidebar-border))] hover:bg-sidebar-accent hover:text-sidebar-accent-foreground hover:shadow-[0_0_0_1px_hsl(var(--sidebar-accent))]",
478
- },
479
- size: {
480
- default: "h-13 text-base",
481
- sm: "h-7 text-xs",
482
- lg: "h-16 text-base group-data-[collapsible=icon]:p-0!",
483
- },
484
- },
485
- defaultVariants: {
486
- variant: "default",
487
- size: "default",
488
- },
489
- }
490
- );
491
-
492
- function SidebarMenuButton({
493
- asChild = false,
494
- isActive = false,
495
- variant = "default",
496
- size = "default",
497
- tooltip,
498
- className,
499
- ...props
500
- }: ComponentProps<"button"> & {
501
- asChild?: boolean;
502
- isActive?: boolean;
503
- tooltip?: string | ComponentProps<typeof TooltipContent>;
504
- } & VariantProps<typeof sidebarMenuButtonVariants>) {
505
- const Comp = asChild ? Slot.Root : "button";
506
- const { isMobile, state, setOpenMobile } = useSidebar();
507
-
508
- const button = (
509
- <Comp
510
- className={cn(sidebarMenuButtonVariants({ variant, size }), className)}
511
- data-active={isActive}
512
- data-sidebar="menu-button"
513
- data-size={size}
514
- data-slot="sidebar-menu-button"
515
- onClick={() => setOpenMobile(false)}
516
- {...props}
517
- />
518
- );
519
-
520
- if (!tooltip) {
521
- return button;
522
- }
523
-
524
- if (typeof tooltip === "string") {
525
- tooltip = {
526
- children: tooltip,
527
- };
528
- }
529
-
530
- return (
531
- <Tooltip>
532
- <TooltipTrigger asChild>{button}</TooltipTrigger>
533
- <TooltipContent
534
- align="center"
535
- hidden={state !== "collapsed" || isMobile}
536
- side="right"
537
- {...tooltip}
538
- />
539
- </Tooltip>
540
- );
541
- }
542
-
543
- function SidebarMenuAction({
544
- className,
545
- asChild = false,
546
- showOnHover = false,
547
- ...props
548
- }: ComponentProps<"button"> & {
549
- asChild?: boolean;
550
- showOnHover?: boolean;
551
- }) {
552
- const Comp = asChild ? Slot.Root : "button";
553
-
554
- return (
555
- <Comp
556
- className={cn(
557
- "absolute top-1.5 right-1 flex aspect-square w-5 items-center justify-center rounded-md p-0 text-sidebar-foreground/70 outline-hidden ring-sidebar-ring transition-transform after:absolute after:-inset-2 hover:bg-sidebar-accent hover:text-sidebar-accent-foreground focus-visible:ring-2 peer-hover/menu-button:text-sidebar-accent-foreground group-data-[collapsible=icon]:hidden 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 lg:after:hidden [&>svg]:size-4 [&>svg]:shrink-0",
558
- showOnHover &&
559
- "group-focus-within/menu-item:opacity-100 group-hover/menu-item:opacity-100 data-open:opacity-100 peer-data-active/menu-button:text-sidebar-accent-foreground lg:opacity-0",
560
- className
561
- )}
562
- data-sidebar="menu-action"
563
- data-slot="sidebar-menu-action"
564
- {...props}
565
- />
566
- );
567
- }
568
-
569
- function SidebarMenuBadge({ className, ...props }: ComponentProps<"div">) {
570
- return (
571
- <div
572
- className={cn(
573
- "pointer-events-none absolute right-1 flex h-5 min-w-5 select-none items-center justify-center rounded-md px-1 font-medium text-sidebar-foreground/70 text-xs tabular-nums peer-hover/menu-button:text-sidebar-accent-foreground group-data-[collapsible=icon]:hidden 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",
574
- className
575
- )}
576
- data-sidebar="menu-badge"
577
- data-slot="sidebar-menu-badge"
578
- {...props}
579
- />
580
- );
581
- }
582
-
583
- function SidebarMenuSkeleton({
584
- className,
585
- showIcon = false,
586
- ...props
587
- }: ComponentProps<"div"> & {
588
- showIcon?: boolean;
589
- }) {
590
- // Random width between 50 to 90%.
591
- const [width] = useState(() => {
592
- return `${Math.floor(Math.random() * 40) + 50}%`;
593
- });
594
-
595
- return (
596
- <div
597
- className={cn("flex h-8 items-center gap-2 rounded-md px-2", className)}
598
- data-sidebar="menu-skeleton"
599
- data-slot="sidebar-menu-skeleton"
600
- {...props}
601
- >
602
- {showIcon && (
603
- <Skeleton
604
- className="size-4 rounded-md"
605
- data-sidebar="menu-skeleton-icon"
606
- />
607
- )}
608
- <Skeleton
609
- className="h-4 max-w-(--skeleton-width) flex-1"
610
- data-sidebar="menu-skeleton-text"
611
- style={
612
- {
613
- "--skeleton-width": width,
614
- } as CSSProperties
615
- }
616
- />
617
- </div>
618
- );
619
- }
620
-
621
- function SidebarMenuSub({ className, ...props }: ComponentProps<"ul">) {
622
- return (
623
- <ul
624
- className={cn(
625
- "mx-3.5 flex min-w-0 translate-x-px flex-col gap-1 border-sidebar-border border-l px-2.5 py-0.5 group-data-[collapsible=icon]:hidden",
626
- className
627
- )}
628
- data-sidebar="menu-sub"
629
- data-slot="sidebar-menu-sub"
630
- {...props}
631
- />
632
- );
633
- }
634
-
635
- function SidebarMenuSubItem({ className, ...props }: ComponentProps<"li">) {
636
- return (
637
- <li
638
- className={cn("group/menu-sub-item relative", className)}
639
- data-sidebar="menu-sub-item"
640
- data-slot="sidebar-menu-sub-item"
641
- {...props}
642
- />
643
- );
644
- }
645
-
646
- function SidebarMenuSubButton({
647
- asChild = false,
648
- size = "md",
649
- isActive = false,
650
- className,
651
- ...props
652
- }: ComponentProps<"a"> & {
653
- asChild?: boolean;
654
- size?: "sm" | "md";
655
- isActive?: boolean;
656
- }) {
657
- const Comp = asChild ? Slot.Root : "a";
658
-
659
- return (
660
- <Comp
661
- className={cn(
662
- "flex h-7 min-w-0 -translate-x-px items-center gap-2 overflow-hidden rounded-md px-2 text-sidebar-foreground/70 outline-hidden ring-sidebar-ring 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:bg-sidebar-accent data-[size=md]:text-base data-[size=sm]:text-xs data-active:text-sidebar-accent-foreground group-data-[collapsible=icon]:hidden [&>span:last-child]:truncate [&>svg]:size-4 [&>svg]:shrink-0 [&>svg]:text-sidebar-accent-foreground",
663
- className
664
- )}
665
- data-active={isActive}
666
- data-sidebar="menu-sub-button"
667
- data-size={size}
668
- data-slot="sidebar-menu-sub-button"
669
- {...props}
670
- />
671
- );
672
- }
673
-
674
- export {
675
- Sidebar,
676
- SidebarContent,
677
- SidebarFooter,
678
- SidebarGroup,
679
- SidebarGroupAction,
680
- SidebarGroupContent,
681
- SidebarGroupLabel,
682
- SidebarHeader,
683
- SidebarInput,
684
- SidebarInset,
685
- SidebarMenu,
686
- SidebarMenuAction,
687
- SidebarMenuBadge,
688
- SidebarMenuButton,
689
- SidebarMenuItem,
690
- SidebarMenuSkeleton,
691
- SidebarMenuSub,
692
- SidebarMenuSubButton,
693
- SidebarMenuSubItem,
694
- SidebarProvider,
695
- SidebarRail,
696
- SidebarSeparator,
697
- SidebarTrigger,
698
- useSidebar,
699
- };
@@ -1,13 +0,0 @@
1
- import { cn } from "@/lib/utils";
2
-
3
- function Skeleton({ className, ...props }: React.ComponentProps<"div">) {
4
- return (
5
- <div
6
- className={cn("animate-pulse rounded-md bg-muted", className)}
7
- data-slot="skeleton"
8
- {...props}
9
- />
10
- );
11
- }
12
-
13
- export { Skeleton };