@nomad-e/bluma-cli 0.15.0 → 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.
- package/dist/main.js +305 -400
- package/dist/scaffold/.eslintrc.json +3 -0
- package/dist/scaffold/app/globals.css +46 -0
- package/dist/scaffold/app/layout.tsx +19 -0
- package/dist/scaffold/app/page.tsx +124 -0
- package/dist/scaffold/components/ui/README.md +12 -0
- package/dist/scaffold/components/ui/accordion.jsx +42 -0
- package/dist/scaffold/components/ui/alert-dialog.jsx +80 -0
- package/dist/scaffold/components/ui/alert.jsx +33 -0
- package/dist/scaffold/components/ui/aspect-ratio.jsx +5 -0
- package/dist/scaffold/components/ui/avatar.jsx +28 -0
- package/dist/scaffold/components/ui/badge.jsx +24 -0
- package/dist/scaffold/components/ui/breadcrumb.jsx +72 -0
- package/dist/scaffold/components/ui/button.jsx +40 -0
- package/dist/scaffold/components/ui/calendar.jsx +56 -0
- package/dist/scaffold/components/ui/card.jsx +38 -0
- package/dist/scaffold/components/ui/carousel.jsx +168 -0
- package/dist/scaffold/components/ui/chart.jsx +76 -0
- package/dist/scaffold/components/ui/checkbox.jsx +22 -0
- package/dist/scaffold/components/ui/collapsible.jsx +7 -0
- package/dist/scaffold/components/ui/command.jsx +100 -0
- package/dist/scaffold/components/ui/context-menu.jsx +137 -0
- package/dist/scaffold/components/ui/dialog.jsx +72 -0
- package/dist/scaffold/components/ui/drawer.jsx +68 -0
- package/dist/scaffold/components/ui/dropdown-menu.jsx +143 -0
- package/dist/scaffold/components/ui/form.jsx +88 -0
- package/dist/scaffold/components/ui/hover-card.jsx +22 -0
- package/dist/scaffold/components/ui/input-otp.jsx +49 -0
- package/dist/scaffold/components/ui/input.jsx +19 -0
- package/dist/scaffold/components/ui/label.jsx +15 -0
- package/dist/scaffold/components/ui/menubar.jsx +161 -0
- package/dist/scaffold/components/ui/navigation-menu.jsx +95 -0
- package/dist/scaffold/components/ui/pagination.jsx +77 -0
- package/dist/scaffold/components/ui/popover.jsx +25 -0
- package/dist/scaffold/components/ui/progress.jsx +19 -0
- package/dist/scaffold/components/ui/radio-group.jsx +29 -0
- package/dist/scaffold/components/ui/resizable.jsx +27 -0
- package/dist/scaffold/components/ui/scroll-area.jsx +31 -0
- package/dist/scaffold/components/ui/select.jsx +117 -0
- package/dist/scaffold/components/ui/separator.jsx +22 -0
- package/dist/scaffold/components/ui/sheet.jsx +81 -0
- package/dist/scaffold/components/ui/skeleton.jsx +7 -0
- package/dist/scaffold/components/ui/slider.jsx +19 -0
- package/dist/scaffold/components/ui/sonner.jsx +22 -0
- package/dist/scaffold/components/ui/switch.jsx +23 -0
- package/dist/scaffold/components/ui/table.jsx +61 -0
- package/dist/scaffold/components/ui/tabs.jsx +43 -0
- package/dist/scaffold/components/ui/textarea.jsx +18 -0
- package/dist/scaffold/components/ui/toast.jsx +85 -0
- package/dist/scaffold/components/ui/toaster.jsx +33 -0
- package/dist/scaffold/components/ui/toggle-group.jsx +41 -0
- package/dist/scaffold/components/ui/toggle.jsx +30 -0
- package/dist/scaffold/components/ui/tooltip.jsx +22 -0
- package/dist/scaffold/hooks/use-toast.ts +101 -0
- package/dist/scaffold/lib/utils.ts +6 -0
- package/dist/scaffold/next.config.js +5 -0
- package/dist/scaffold/next.config.mjs +15 -0
- package/dist/scaffold/next.config.ts +19 -0
- package/dist/scaffold/package.json +70 -0
- package/dist/scaffold/postcss.config.js +6 -0
- package/dist/scaffold/tailwind.config.ts +57 -0
- package/dist/scaffold/tsconfig.json +20 -0
- 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
|
+
};
|