@nomad-e/bluma-cli 0.14.1 → 0.16.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (64) hide show
  1. package/dist/config/native_tools.json +15 -3
  2. package/dist/main.js +0 -1
  3. package/dist/scaffold/.eslintrc.json +3 -0
  4. package/dist/scaffold/app/globals.css +46 -0
  5. package/dist/scaffold/app/layout.tsx +19 -0
  6. package/dist/scaffold/app/page.tsx +124 -0
  7. package/dist/scaffold/components/ui/README.md +12 -0
  8. package/dist/scaffold/components/ui/accordion.jsx +42 -0
  9. package/dist/scaffold/components/ui/alert-dialog.jsx +80 -0
  10. package/dist/scaffold/components/ui/alert.jsx +33 -0
  11. package/dist/scaffold/components/ui/aspect-ratio.jsx +5 -0
  12. package/dist/scaffold/components/ui/avatar.jsx +28 -0
  13. package/dist/scaffold/components/ui/badge.jsx +24 -0
  14. package/dist/scaffold/components/ui/breadcrumb.jsx +72 -0
  15. package/dist/scaffold/components/ui/button.jsx +40 -0
  16. package/dist/scaffold/components/ui/calendar.jsx +56 -0
  17. package/dist/scaffold/components/ui/card.jsx +38 -0
  18. package/dist/scaffold/components/ui/carousel.jsx +168 -0
  19. package/dist/scaffold/components/ui/chart.jsx +76 -0
  20. package/dist/scaffold/components/ui/checkbox.jsx +22 -0
  21. package/dist/scaffold/components/ui/collapsible.jsx +7 -0
  22. package/dist/scaffold/components/ui/command.jsx +100 -0
  23. package/dist/scaffold/components/ui/context-menu.jsx +137 -0
  24. package/dist/scaffold/components/ui/dialog.jsx +72 -0
  25. package/dist/scaffold/components/ui/drawer.jsx +68 -0
  26. package/dist/scaffold/components/ui/dropdown-menu.jsx +143 -0
  27. package/dist/scaffold/components/ui/form.jsx +88 -0
  28. package/dist/scaffold/components/ui/hover-card.jsx +22 -0
  29. package/dist/scaffold/components/ui/input-otp.jsx +49 -0
  30. package/dist/scaffold/components/ui/input.jsx +19 -0
  31. package/dist/scaffold/components/ui/label.jsx +15 -0
  32. package/dist/scaffold/components/ui/menubar.jsx +161 -0
  33. package/dist/scaffold/components/ui/navigation-menu.jsx +95 -0
  34. package/dist/scaffold/components/ui/pagination.jsx +77 -0
  35. package/dist/scaffold/components/ui/popover.jsx +25 -0
  36. package/dist/scaffold/components/ui/progress.jsx +19 -0
  37. package/dist/scaffold/components/ui/radio-group.jsx +29 -0
  38. package/dist/scaffold/components/ui/resizable.jsx +27 -0
  39. package/dist/scaffold/components/ui/scroll-area.jsx +31 -0
  40. package/dist/scaffold/components/ui/select.jsx +117 -0
  41. package/dist/scaffold/components/ui/separator.jsx +22 -0
  42. package/dist/scaffold/components/ui/sheet.jsx +81 -0
  43. package/dist/scaffold/components/ui/skeleton.jsx +7 -0
  44. package/dist/scaffold/components/ui/slider.jsx +19 -0
  45. package/dist/scaffold/components/ui/sonner.jsx +22 -0
  46. package/dist/scaffold/components/ui/switch.jsx +23 -0
  47. package/dist/scaffold/components/ui/table.jsx +61 -0
  48. package/dist/scaffold/components/ui/tabs.jsx +43 -0
  49. package/dist/scaffold/components/ui/textarea.jsx +18 -0
  50. package/dist/scaffold/components/ui/toast.jsx +85 -0
  51. package/dist/scaffold/components/ui/toaster.jsx +33 -0
  52. package/dist/scaffold/components/ui/toggle-group.jsx +41 -0
  53. package/dist/scaffold/components/ui/toggle.jsx +30 -0
  54. package/dist/scaffold/components/ui/tooltip.jsx +22 -0
  55. package/dist/scaffold/hooks/use-toast.ts +101 -0
  56. package/dist/scaffold/lib/utils.ts +6 -0
  57. package/dist/scaffold/next.config.js +5 -0
  58. package/dist/scaffold/next.config.mjs +15 -0
  59. package/dist/scaffold/next.config.ts +19 -0
  60. package/dist/scaffold/package.json +70 -0
  61. package/dist/scaffold/postcss.config.js +6 -0
  62. package/dist/scaffold/tailwind.config.ts +57 -0
  63. package/dist/scaffold/tsconfig.json +20 -0
  64. package/package.json +1 -1
@@ -0,0 +1,168 @@
1
+ import * as React from 'react';
2
+ import useEmblaCarousel from 'embla-carousel-react';
3
+ import { ArrowLeft, ArrowRight } from 'lucide-react';
4
+ import { cn } from '@/lib/utils';
5
+ import { Button } from '@/components/ui/button';
6
+
7
+ const CarouselContext = React.createContext(null);
8
+
9
+ function useCarousel() {
10
+ const ctx = React.useContext(CarouselContext);
11
+ if (!ctx) throw new Error('useCarousel must be within <Carousel />');
12
+ return ctx;
13
+ }
14
+
15
+ const Carousel = React.forwardRef(
16
+ ({ orientation = 'horizontal', opts, setApi, plugins, className, children, ...props }, ref) => {
17
+ const [carouselRef, api] = useEmblaCarousel(
18
+ { ...opts, axis: orientation === 'horizontal' ? 'x' : 'y' },
19
+ plugins
20
+ );
21
+ const [canScrollPrev, setCanScrollPrev] = React.useState(false);
22
+ const [canScrollNext, setCanScrollNext] = React.useState(false);
23
+
24
+ const onSelect = React.useCallback((emblaApi) => {
25
+ if (!emblaApi) return;
26
+ setCanScrollPrev(emblaApi.canScrollPrev());
27
+ setCanScrollNext(emblaApi.canScrollNext());
28
+ }, []);
29
+
30
+ const scrollPrev = React.useCallback(() => api?.scrollPrev(), [api]);
31
+ const scrollNext = React.useCallback(() => api?.scrollNext(), [api]);
32
+
33
+ const handleKeyDown = React.useCallback(
34
+ (event) => {
35
+ if (event.key === 'ArrowLeft') {
36
+ event.preventDefault();
37
+ scrollPrev();
38
+ } else if (event.key === 'ArrowRight') {
39
+ event.preventDefault();
40
+ scrollNext();
41
+ }
42
+ },
43
+ [scrollPrev, scrollNext]
44
+ );
45
+
46
+ React.useEffect(() => {
47
+ if (!api || !setApi) return;
48
+ setApi(api);
49
+ }, [api, setApi]);
50
+
51
+ React.useEffect(() => {
52
+ if (!api) return;
53
+ onSelect(api);
54
+ api.on('reInit', onSelect);
55
+ api.on('select', onSelect);
56
+ return () => {
57
+ api?.off('select', onSelect);
58
+ };
59
+ }, [api, onSelect]);
60
+
61
+ return (
62
+ <CarouselContext.Provider
63
+ value={{
64
+ carouselRef,
65
+ api,
66
+ opts,
67
+ orientation: orientation || 'horizontal',
68
+ scrollPrev,
69
+ scrollNext,
70
+ canScrollPrev,
71
+ canScrollNext,
72
+ }}
73
+ >
74
+ <div
75
+ ref={ref}
76
+ onKeyDownCapture={handleKeyDown}
77
+ className={cn('relative', className)}
78
+ role="region"
79
+ aria-roledescription="carousel"
80
+ {...props}
81
+ >
82
+ {children}
83
+ </div>
84
+ </CarouselContext.Provider>
85
+ );
86
+ }
87
+ );
88
+ Carousel.displayName = 'Carousel';
89
+
90
+ const CarouselContent = React.forwardRef(({ className, ...props }, ref) => {
91
+ const { carouselRef, orientation } = useCarousel();
92
+ return (
93
+ <div ref={carouselRef} className="overflow-hidden">
94
+ <div
95
+ ref={ref}
96
+ className={cn('flex', orientation === 'horizontal' ? '-ml-4' : '-mt-4 flex-col', className)}
97
+ {...props}
98
+ />
99
+ </div>
100
+ );
101
+ });
102
+ CarouselContent.displayName = 'CarouselContent';
103
+
104
+ const CarouselItem = React.forwardRef(({ className, ...props }, ref) => {
105
+ const { orientation } = useCarousel();
106
+ return (
107
+ <div
108
+ ref={ref}
109
+ role="group"
110
+ aria-roledescription="slide"
111
+ className={cn('min-w-0 shrink-0 grow-0 basis-full', orientation === 'horizontal' ? 'pl-4' : 'pt-4', className)}
112
+ {...props}
113
+ />
114
+ );
115
+ });
116
+ CarouselItem.displayName = 'CarouselItem';
117
+
118
+ const CarouselPrevious = React.forwardRef(({ className, variant = 'outline', size = 'icon', ...props }, ref) => {
119
+ const { orientation, scrollPrev, canScrollPrev } = useCarousel();
120
+ return (
121
+ <Button
122
+ ref={ref}
123
+ variant={variant}
124
+ size={size}
125
+ className={cn(
126
+ 'absolute h-8 w-8 rounded-full',
127
+ orientation === 'horizontal'
128
+ ? '-left-12 top-1/2 -translate-y-1/2'
129
+ : '-top-12 left-1/2 -translate-x-1/2 rotate-90',
130
+ className
131
+ )}
132
+ disabled={!canScrollPrev}
133
+ onClick={scrollPrev}
134
+ {...props}
135
+ >
136
+ <ArrowLeft className="h-4 w-4" />
137
+ <span className="sr-only">Previous slide</span>
138
+ </Button>
139
+ );
140
+ });
141
+ CarouselPrevious.displayName = 'CarouselPrevious';
142
+
143
+ const CarouselNext = React.forwardRef(({ className, variant = 'outline', size = 'icon', ...props }, ref) => {
144
+ const { orientation, scrollNext, canScrollNext } = useCarousel();
145
+ return (
146
+ <Button
147
+ ref={ref}
148
+ variant={variant}
149
+ size={size}
150
+ className={cn(
151
+ 'absolute h-8 w-8 rounded-full',
152
+ orientation === 'horizontal'
153
+ ? '-right-12 top-1/2 -translate-y-1/2'
154
+ : '-bottom-12 left-1/2 -translate-x-1/2 rotate-90',
155
+ className
156
+ )}
157
+ disabled={!canScrollNext}
158
+ onClick={scrollNext}
159
+ {...props}
160
+ >
161
+ <ArrowRight className="h-4 w-4" />
162
+ <span className="sr-only">Next slide</span>
163
+ </Button>
164
+ );
165
+ });
166
+ CarouselNext.displayName = 'CarouselNext';
167
+
168
+ export { Carousel, CarouselContent, CarouselItem, CarouselPrevious, CarouselNext, useCarousel };
@@ -0,0 +1,76 @@
1
+ import * as React from 'react';
2
+ import * as RechartsPrimitive from 'recharts';
3
+ import { cn } from '@/lib/utils';
4
+
5
+ const ChartContainer = React.forwardRef(({ id, className, children, ...props }, ref) => {
6
+ const uniqueId = React.useId();
7
+ const chartId = `chart-${id || uniqueId.replace(/:/g, '')}`;
8
+ return (
9
+ <div
10
+ data-chart={chartId}
11
+ ref={ref}
12
+ className={cn(
13
+ 'flex aspect-video justify-center text-xs [&_.recharts-cartesian-grid_line]:stroke-border/50 [&_.recharts-curve.recharts-tooltip-cursor]:stroke-border [&_.recharts-dot]:stroke-transparent [&_.recharts-layer]:outline-none [&_.recharts-sector]:outline-none [&_.recharts-surface]:outline-none',
14
+ className
15
+ )}
16
+ {...props}
17
+ >
18
+ <RechartsPrimitive.ResponsiveContainer width="100%" height="100%">
19
+ {children}
20
+ </RechartsPrimitive.ResponsiveContainer>
21
+ </div>
22
+ );
23
+ });
24
+ ChartContainer.displayName = 'Chart';
25
+
26
+ const ChartTooltip = RechartsPrimitive.Tooltip;
27
+
28
+ const ChartTooltipContent = React.forwardRef(({ active, payload, className, label, ...props }, ref) => {
29
+ if (!active || !payload?.length) return null;
30
+ return (
31
+ <div
32
+ ref={ref}
33
+ className={cn('grid min-w-[8rem] items-start gap-1.5 rounded-lg border border-border/50 bg-background px-2.5 py-1.5 text-xs shadow-xl', className)}
34
+ {...props}
35
+ >
36
+ {label != null && <div className="font-medium">{label}</div>}
37
+ <div className="grid gap-1.5">
38
+ {payload.map((item, i) => (
39
+ <div key={i} className="flex items-center gap-2">
40
+ <div
41
+ className="h-2.5 w-2.5 shrink-0 rounded-[2px]"
42
+ style={{ backgroundColor: item.color }}
43
+ />
44
+ <span className="text-muted-foreground">{item.name}</span>
45
+ <span className="ml-auto font-mono font-medium">{item.value}</span>
46
+ </div>
47
+ ))}
48
+ </div>
49
+ </div>
50
+ );
51
+ });
52
+ ChartTooltipContent.displayName = 'ChartTooltip';
53
+
54
+ export {
55
+ ChartContainer,
56
+ ChartTooltip,
57
+ ChartTooltipContent,
58
+ };
59
+
60
+ export {
61
+ Area,
62
+ AreaChart,
63
+ Bar,
64
+ BarChart,
65
+ CartesianGrid,
66
+ Cell,
67
+ Legend,
68
+ Line,
69
+ LineChart,
70
+ Pie,
71
+ PieChart,
72
+ ResponsiveContainer,
73
+ Tooltip,
74
+ XAxis,
75
+ YAxis,
76
+ } from 'recharts';
@@ -0,0 +1,22 @@
1
+ import * as React from 'react';
2
+ import * as CheckboxPrimitive from '@radix-ui/react-checkbox';
3
+ import { Check } from 'lucide-react';
4
+ import { cn } from '@/lib/utils';
5
+
6
+ const Checkbox = React.forwardRef(({ className, ...props }, ref) => (
7
+ <CheckboxPrimitive.Root
8
+ ref={ref}
9
+ className={cn(
10
+ 'peer h-4 w-4 shrink-0 rounded-sm border border-primary ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 data-[state=checked]:bg-primary data-[state=checked]:text-primary-foreground',
11
+ className
12
+ )}
13
+ {...props}
14
+ >
15
+ <CheckboxPrimitive.Indicator className={cn('flex items-center justify-center text-current')}>
16
+ <Check className="h-4 w-4" />
17
+ </CheckboxPrimitive.Indicator>
18
+ </CheckboxPrimitive.Root>
19
+ ));
20
+ Checkbox.displayName = CheckboxPrimitive.Root.displayName;
21
+
22
+ export { Checkbox };
@@ -0,0 +1,7 @@
1
+ import * as CollapsiblePrimitive from '@radix-ui/react-collapsible';
2
+
3
+ const Collapsible = CollapsiblePrimitive.Root;
4
+ const CollapsibleTrigger = CollapsiblePrimitive.CollapsibleTrigger;
5
+ const CollapsibleContent = CollapsiblePrimitive.CollapsibleContent;
6
+
7
+ export { Collapsible, CollapsibleTrigger, CollapsibleContent };
@@ -0,0 +1,100 @@
1
+ import * as React from 'react';
2
+ import { Command as Cmdk } from 'cmdk';
3
+ import { Search } from 'lucide-react';
4
+ import { cn } from '@/lib/utils';
5
+ import { Dialog, DialogContent } from '@/components/ui/dialog';
6
+
7
+ const Command = React.forwardRef(({ className, ...props }, ref) => (
8
+ <Cmdk
9
+ ref={ref}
10
+ className={cn(
11
+ 'flex h-full w-full flex-col overflow-hidden rounded-md bg-popover text-popover-foreground',
12
+ className
13
+ )}
14
+ {...props}
15
+ />
16
+ ));
17
+ Command.displayName = Cmdk.displayName;
18
+
19
+ const CommandDialog = ({ children, ...props }) => {
20
+ return (
21
+ <Dialog {...props}>
22
+ <DialogContent className="overflow-hidden p-0 shadow-lg">
23
+ <Command className="[&_[cmdk-group-heading]]:px-2 [&_[cmdk-group-heading]]:font-medium [&_[cmdk-group-heading]]:text-muted-foreground [&_[cmdk-group]]:px-2 [&_[cmdk-input-wrapper]_svg]:h-5 [&_[cmdk-input-wrapper]_svg]:w-5 [&_[cmdk-input]]:h-12 [&_[cmdk-item]]:px-2 [&_[cmdk-item]]:py-3 [&_[cmdk-item]_svg]:h-5 [&_[cmdk-item]_svg]:w-5">
24
+ {children}
25
+ </Command>
26
+ </DialogContent>
27
+ </Dialog>
28
+ );
29
+ };
30
+
31
+ const CommandInput = React.forwardRef(({ className, ...props }, ref) => (
32
+ <div className="flex items-center border-b px-3" cmdk-input-wrapper="">
33
+ <Search className="mr-2 h-4 w-4 shrink-0 opacity-50" />
34
+ <Cmdk.Input
35
+ ref={ref}
36
+ className={cn(
37
+ 'flex h-11 w-full rounded-md bg-transparent py-3 text-sm outline-none placeholder:text-muted-foreground disabled:cursor-not-allowed disabled:opacity-50',
38
+ className
39
+ )}
40
+ {...props}
41
+ />
42
+ </div>
43
+ ));
44
+ CommandInput.displayName = Cmdk.Input.displayName;
45
+
46
+ const CommandList = React.forwardRef(({ className, ...props }, ref) => (
47
+ <Cmdk.List ref={ref} className={cn('max-h-[300px] overflow-y-auto overflow-x-hidden', className)} {...props} />
48
+ ));
49
+ CommandList.displayName = Cmdk.List.displayName;
50
+
51
+ const CommandEmpty = React.forwardRef((props, ref) => (
52
+ <Cmdk.Empty ref={ref} className="py-6 text-center text-sm" {...props} />
53
+ ));
54
+ CommandEmpty.displayName = Cmdk.Empty.displayName;
55
+
56
+ const CommandGroup = React.forwardRef(({ className, ...props }, ref) => (
57
+ <Cmdk.Group
58
+ ref={ref}
59
+ className={cn(
60
+ 'overflow-hidden p-1 text-foreground [&_[cmdk-group-heading]]:px-2 [&_[cmdk-group-heading]]:py-1.5 [&_[cmdk-group-heading]]:text-xs [&_[cmdk-group-heading]]:font-medium [&_[cmdk-group-heading]]:text-muted-foreground',
61
+ className
62
+ )}
63
+ {...props}
64
+ />
65
+ ));
66
+ CommandGroup.displayName = Cmdk.Group.displayName;
67
+
68
+ const CommandSeparator = React.forwardRef(({ className, ...props }, ref) => (
69
+ <Cmdk.Separator ref={ref} className={cn('-mx-1 h-px bg-border', className)} {...props} />
70
+ ));
71
+ CommandSeparator.displayName = Cmdk.Separator.displayName;
72
+
73
+ const CommandItem = React.forwardRef(({ className, ...props }, ref) => (
74
+ <Cmdk.Item
75
+ ref={ref}
76
+ className={cn(
77
+ "relative flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none data-[disabled=true]:pointer-events-none data-[selected='true']:bg-accent data-[selected=true]:text-accent-foreground data-[disabled=true]:opacity-50",
78
+ className
79
+ )}
80
+ {...props}
81
+ />
82
+ ));
83
+ CommandItem.displayName = Cmdk.Item.displayName;
84
+
85
+ const CommandShortcut = ({ className, ...props }) => {
86
+ return <span className={cn('ml-auto text-xs tracking-widest text-muted-foreground', className)} {...props} />;
87
+ };
88
+ CommandShortcut.displayName = 'CommandShortcut';
89
+
90
+ export {
91
+ Command,
92
+ CommandDialog,
93
+ CommandInput,
94
+ CommandList,
95
+ CommandEmpty,
96
+ CommandGroup,
97
+ CommandItem,
98
+ CommandShortcut,
99
+ CommandSeparator,
100
+ };
@@ -0,0 +1,137 @@
1
+ import * as React from 'react';
2
+ import * as ContextMenuPrimitive from '@radix-ui/react-context-menu';
3
+ import { Check, ChevronRight, Circle } from 'lucide-react';
4
+ import { cn } from '@/lib/utils';
5
+
6
+ const ContextMenu = ContextMenuPrimitive.Root;
7
+ const ContextMenuTrigger = ContextMenuPrimitive.Trigger;
8
+ const ContextMenuGroup = ContextMenuPrimitive.Group;
9
+ const ContextMenuPortal = ContextMenuPrimitive.Portal;
10
+ const ContextMenuSub = ContextMenuPrimitive.Sub;
11
+ const ContextMenuRadioGroup = ContextMenuPrimitive.RadioGroup;
12
+
13
+ const ContextMenuSubTrigger = React.forwardRef(({ className, inset, children, ...props }, ref) => (
14
+ <ContextMenuPrimitive.SubTrigger
15
+ ref={ref}
16
+ className={cn(
17
+ 'flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none focus:bg-accent focus:text-accent-foreground data-[state=open]:bg-accent data-[state=open]:text-accent-foreground',
18
+ inset && 'pl-8',
19
+ className
20
+ )}
21
+ {...props}
22
+ >
23
+ {children}
24
+ <ChevronRight className="ml-auto h-4 w-4" />
25
+ </ContextMenuPrimitive.SubTrigger>
26
+ ));
27
+ ContextMenuSubTrigger.displayName = ContextMenuPrimitive.SubTrigger.displayName;
28
+
29
+ const ContextMenuSubContent = React.forwardRef(({ className, ...props }, ref) => (
30
+ <ContextMenuPrimitive.SubContent
31
+ ref={ref}
32
+ className={cn(
33
+ 'z-50 min-w-[8rem] overflow-hidden rounded-md border bg-popover p-1 text-popover-foreground shadow-md',
34
+ className
35
+ )}
36
+ {...props}
37
+ />
38
+ ));
39
+ ContextMenuSubContent.displayName = ContextMenuPrimitive.SubContent.displayName;
40
+
41
+ const ContextMenuContent = React.forwardRef(({ className, ...props }, ref) => (
42
+ <ContextMenuPrimitive.Portal>
43
+ <ContextMenuPrimitive.Content
44
+ ref={ref}
45
+ className={cn(
46
+ 'z-50 min-w-[8rem] overflow-hidden rounded-md border bg-popover p-1 text-popover-foreground shadow-md',
47
+ className
48
+ )}
49
+ {...props}
50
+ />
51
+ </ContextMenuPrimitive.Portal>
52
+ ));
53
+ ContextMenuContent.displayName = ContextMenuPrimitive.Content.displayName;
54
+
55
+ const ContextMenuItem = React.forwardRef(({ className, inset, ...props }, ref) => (
56
+ <ContextMenuPrimitive.Item
57
+ ref={ref}
58
+ className={cn(
59
+ 'relative flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50',
60
+ inset && 'pl-8',
61
+ className
62
+ )}
63
+ {...props}
64
+ />
65
+ ));
66
+ ContextMenuItem.displayName = ContextMenuPrimitive.Item.displayName;
67
+
68
+ const ContextMenuCheckboxItem = React.forwardRef(({ className, children, checked, ...props }, ref) => (
69
+ <ContextMenuPrimitive.CheckboxItem
70
+ ref={ref}
71
+ className={cn(
72
+ 'relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50',
73
+ className
74
+ )}
75
+ checked={checked}
76
+ {...props}
77
+ >
78
+ <span className="absolute left-2 flex h-3.5 w-3.5 items-center justify-center">
79
+ <ContextMenuPrimitive.ItemIndicator>
80
+ <Check className="h-4 w-4" />
81
+ </ContextMenuPrimitive.ItemIndicator>
82
+ </span>
83
+ {children}
84
+ </ContextMenuPrimitive.CheckboxItem>
85
+ ));
86
+ ContextMenuCheckboxItem.displayName = ContextMenuPrimitive.CheckboxItem.displayName;
87
+
88
+ const ContextMenuRadioItem = React.forwardRef(({ className, children, ...props }, ref) => (
89
+ <ContextMenuPrimitive.RadioItem
90
+ ref={ref}
91
+ className={cn(
92
+ 'relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50',
93
+ className
94
+ )}
95
+ {...props}
96
+ >
97
+ <span className="absolute left-2 flex h-3.5 w-3.5 items-center justify-center">
98
+ <ContextMenuPrimitive.ItemIndicator>
99
+ <Circle className="h-2 w-2 fill-current" />
100
+ </ContextMenuPrimitive.ItemIndicator>
101
+ </span>
102
+ {children}
103
+ </ContextMenuPrimitive.RadioItem>
104
+ ));
105
+ ContextMenuRadioItem.displayName = ContextMenuPrimitive.RadioItem.displayName;
106
+
107
+ const ContextMenuLabel = React.forwardRef(({ className, inset, ...props }, ref) => (
108
+ <ContextMenuPrimitive.Label ref={ref} className={cn('px-2 py-1.5 text-sm font-semibold', inset && 'pl-8', className)} {...props} />
109
+ ));
110
+ ContextMenuLabel.displayName = ContextMenuPrimitive.Label.displayName;
111
+
112
+ const ContextMenuSeparator = React.forwardRef(({ className, ...props }, ref) => (
113
+ <ContextMenuPrimitive.Separator ref={ref} className={cn('-mx-1 my-1 h-px bg-muted', className)} {...props} />
114
+ ));
115
+ ContextMenuSeparator.displayName = ContextMenuPrimitive.Separator.displayName;
116
+
117
+ const ContextMenuShortcut = ({ className, ...props }) => {
118
+ return <span className={cn('ml-auto text-xs tracking-widest opacity-60', className)} {...props} />;
119
+ };
120
+
121
+ export {
122
+ ContextMenu,
123
+ ContextMenuTrigger,
124
+ ContextMenuContent,
125
+ ContextMenuItem,
126
+ ContextMenuCheckboxItem,
127
+ ContextMenuRadioItem,
128
+ ContextMenuLabel,
129
+ ContextMenuSeparator,
130
+ ContextMenuShortcut,
131
+ ContextMenuGroup,
132
+ ContextMenuPortal,
133
+ ContextMenuSub,
134
+ ContextMenuSubContent,
135
+ ContextMenuSubTrigger,
136
+ ContextMenuRadioGroup,
137
+ };
@@ -0,0 +1,72 @@
1
+ import * as React from 'react';
2
+ import * as DialogPrimitive from '@radix-ui/react-dialog';
3
+ import { X } from 'lucide-react';
4
+ import { cn } from '@/lib/utils';
5
+
6
+ const Dialog = DialogPrimitive.Root;
7
+ const DialogTrigger = DialogPrimitive.Trigger;
8
+ const DialogPortal = DialogPrimitive.Portal;
9
+ const DialogClose = DialogPrimitive.Close;
10
+
11
+ const DialogOverlay = React.forwardRef(({ className, ...props }, ref) => (
12
+ <DialogPrimitive.Overlay
13
+ ref={ref}
14
+ className={cn('fixed inset-0 z-50 bg-black/80', className)}
15
+ {...props}
16
+ />
17
+ ));
18
+ DialogOverlay.displayName = DialogPrimitive.Overlay.displayName;
19
+
20
+ const DialogContent = React.forwardRef(({ className, children, ...props }, ref) => (
21
+ <DialogPortal>
22
+ <DialogOverlay />
23
+ <DialogPrimitive.Content
24
+ ref={ref}
25
+ className={cn(
26
+ 'fixed left-[50%] top-[50%] z-50 grid w-full max-w-lg translate-x-[-50%] translate-y-[-50%] gap-4 border bg-background p-6 shadow-lg sm:rounded-lg',
27
+ className
28
+ )}
29
+ {...props}
30
+ >
31
+ {children}
32
+ <DialogPrimitive.Close className="absolute right-4 top-4 rounded-sm opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:pointer-events-none data-[state=open]:bg-accent data-[state=open]:text-muted-foreground">
33
+ <X className="h-4 w-4" />
34
+ <span className="sr-only">Close</span>
35
+ </DialogPrimitive.Close>
36
+ </DialogPrimitive.Content>
37
+ </DialogPortal>
38
+ ));
39
+ DialogContent.displayName = DialogPrimitive.Content.displayName;
40
+
41
+ const DialogHeader = ({ className, ...props }) => (
42
+ <div className={cn('flex flex-col space-y-1.5 text-center sm:text-left', className)} {...props} />
43
+ );
44
+ DialogHeader.displayName = 'DialogHeader';
45
+
46
+ const DialogFooter = ({ className, ...props }) => (
47
+ <div className={cn('flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2', className)} {...props} />
48
+ );
49
+ DialogFooter.displayName = 'DialogFooter';
50
+
51
+ const DialogTitle = React.forwardRef(({ className, ...props }, ref) => (
52
+ <DialogPrimitive.Title ref={ref} className={cn('text-lg font-semibold leading-none tracking-tight', className)} {...props} />
53
+ ));
54
+ DialogTitle.displayName = DialogPrimitive.Title.displayName;
55
+
56
+ const DialogDescription = React.forwardRef(({ className, ...props }, ref) => (
57
+ <DialogPrimitive.Description ref={ref} className={cn('text-sm text-muted-foreground', className)} {...props} />
58
+ ));
59
+ DialogDescription.displayName = DialogPrimitive.Description.displayName;
60
+
61
+ export {
62
+ Dialog,
63
+ DialogPortal,
64
+ DialogOverlay,
65
+ DialogClose,
66
+ DialogTrigger,
67
+ DialogContent,
68
+ DialogHeader,
69
+ DialogFooter,
70
+ DialogTitle,
71
+ DialogDescription,
72
+ };
@@ -0,0 +1,68 @@
1
+ import * as React from 'react';
2
+ import { Drawer as Vaul } from 'vaul';
3
+ import { cn } from '@/lib/utils';
4
+
5
+ function Drawer({ shouldScaleBackground = true, ...props }) {
6
+ return <Vaul.Root shouldScaleBackground={shouldScaleBackground} {...props} />;
7
+ }
8
+ Drawer.displayName = 'Drawer';
9
+
10
+ const DrawerTrigger = Vaul.Trigger;
11
+ const DrawerPortal = Vaul.Portal;
12
+ const DrawerClose = Vaul.Close;
13
+
14
+ const DrawerOverlay = React.forwardRef(({ className, ...props }, ref) => (
15
+ <Vaul.Overlay ref={ref} className={cn('fixed inset-0 z-50 bg-black/80', className)} {...props} />
16
+ ));
17
+ DrawerOverlay.displayName = Vaul.Overlay.displayName;
18
+
19
+ const DrawerContent = React.forwardRef(({ className, children, ...props }, ref) => (
20
+ <DrawerPortal>
21
+ <DrawerOverlay />
22
+ <Vaul.Content
23
+ ref={ref}
24
+ className={cn(
25
+ 'fixed inset-x-0 bottom-0 z-50 mt-24 flex h-auto flex-col rounded-t-[10px] border bg-background',
26
+ className
27
+ )}
28
+ {...props}
29
+ >
30
+ <Vaul.Handle className="mx-auto mt-4 h-2 w-[100px] rounded-full bg-muted" />
31
+ {children}
32
+ </Vaul.Content>
33
+ </DrawerPortal>
34
+ ));
35
+ DrawerContent.displayName = 'DrawerContent';
36
+
37
+ const DrawerHeader = ({ className, ...props }) => (
38
+ <div className={cn('grid gap-1.5 p-4 text-center sm:text-left', className)} {...props} />
39
+ );
40
+ DrawerHeader.displayName = 'DrawerHeader';
41
+
42
+ const DrawerFooter = ({ className, ...props }) => (
43
+ <div className={cn('mt-auto flex flex-col gap-2 p-4', className)} {...props} />
44
+ );
45
+ DrawerFooter.displayName = 'DrawerFooter';
46
+
47
+ const DrawerTitle = React.forwardRef(({ className, ...props }, ref) => (
48
+ <Vaul.Title ref={ref} className={cn('text-lg font-semibold leading-none tracking-tight', className)} {...props} />
49
+ ));
50
+ DrawerTitle.displayName = 'DrawerTitle';
51
+
52
+ const DrawerDescription = React.forwardRef(({ className, ...props }, ref) => (
53
+ <Vaul.Description ref={ref} className={cn('text-sm text-muted-foreground', className)} {...props} />
54
+ ));
55
+ DrawerDescription.displayName = 'DrawerDescription';
56
+
57
+ export {
58
+ Drawer,
59
+ DrawerPortal,
60
+ DrawerOverlay,
61
+ DrawerTrigger,
62
+ DrawerClose,
63
+ DrawerContent,
64
+ DrawerHeader,
65
+ DrawerFooter,
66
+ DrawerTitle,
67
+ DrawerDescription,
68
+ };