@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.
- package/dist/config/native_tools.json +15 -3
- package/dist/main.js +0 -1
- 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,143 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import * as DropdownMenuPrimitive from '@radix-ui/react-dropdown-menu';
|
|
3
|
+
import { Check, ChevronRight, Circle } from 'lucide-react';
|
|
4
|
+
import { cn } from '@/lib/utils';
|
|
5
|
+
|
|
6
|
+
const DropdownMenu = DropdownMenuPrimitive.Root;
|
|
7
|
+
const DropdownMenuTrigger = DropdownMenuPrimitive.Trigger;
|
|
8
|
+
const DropdownMenuGroup = DropdownMenuPrimitive.Group;
|
|
9
|
+
const DropdownMenuPortal = DropdownMenuPrimitive.Portal;
|
|
10
|
+
const DropdownMenuSub = DropdownMenuPrimitive.Sub;
|
|
11
|
+
const DropdownMenuRadioGroup = DropdownMenuPrimitive.RadioGroup;
|
|
12
|
+
|
|
13
|
+
const DropdownMenuSubTrigger = React.forwardRef(({ className, inset, children, ...props }, ref) => (
|
|
14
|
+
<DropdownMenuPrimitive.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 data-[state=open]:bg-accent',
|
|
18
|
+
inset && 'pl-8',
|
|
19
|
+
className
|
|
20
|
+
)}
|
|
21
|
+
{...props}
|
|
22
|
+
>
|
|
23
|
+
{children}
|
|
24
|
+
<ChevronRight className="ml-auto h-4 w-4" />
|
|
25
|
+
</DropdownMenuPrimitive.SubTrigger>
|
|
26
|
+
));
|
|
27
|
+
DropdownMenuSubTrigger.displayName = DropdownMenuPrimitive.SubTrigger.displayName;
|
|
28
|
+
|
|
29
|
+
const DropdownMenuSubContent = React.forwardRef(({ className, ...props }, ref) => (
|
|
30
|
+
<DropdownMenuPrimitive.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-lg',
|
|
34
|
+
className
|
|
35
|
+
)}
|
|
36
|
+
{...props}
|
|
37
|
+
/>
|
|
38
|
+
));
|
|
39
|
+
DropdownMenuSubContent.displayName = DropdownMenuPrimitive.SubContent.displayName;
|
|
40
|
+
|
|
41
|
+
const DropdownMenuContent = React.forwardRef(({ className, sideOffset = 4, ...props }, ref) => (
|
|
42
|
+
<DropdownMenuPrimitive.Portal>
|
|
43
|
+
<DropdownMenuPrimitive.Content
|
|
44
|
+
ref={ref}
|
|
45
|
+
sideOffset={sideOffset}
|
|
46
|
+
className={cn(
|
|
47
|
+
'z-50 min-w-[8rem] overflow-hidden rounded-md border bg-popover p-1 text-popover-foreground shadow-md',
|
|
48
|
+
className
|
|
49
|
+
)}
|
|
50
|
+
{...props}
|
|
51
|
+
/>
|
|
52
|
+
</DropdownMenuPrimitive.Portal>
|
|
53
|
+
));
|
|
54
|
+
DropdownMenuContent.displayName = DropdownMenuPrimitive.Content.displayName;
|
|
55
|
+
|
|
56
|
+
const DropdownMenuItem = React.forwardRef(({ className, inset, ...props }, ref) => (
|
|
57
|
+
<DropdownMenuPrimitive.Item
|
|
58
|
+
ref={ref}
|
|
59
|
+
className={cn(
|
|
60
|
+
'relative flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none transition-colors focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50',
|
|
61
|
+
inset && 'pl-8',
|
|
62
|
+
className
|
|
63
|
+
)}
|
|
64
|
+
{...props}
|
|
65
|
+
/>
|
|
66
|
+
));
|
|
67
|
+
DropdownMenuItem.displayName = DropdownMenuPrimitive.Item.displayName;
|
|
68
|
+
|
|
69
|
+
const DropdownMenuCheckboxItem = React.forwardRef(({ className, children, checked, ...props }, ref) => (
|
|
70
|
+
<DropdownMenuPrimitive.CheckboxItem
|
|
71
|
+
ref={ref}
|
|
72
|
+
className={cn(
|
|
73
|
+
'relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none transition-colors focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50',
|
|
74
|
+
className
|
|
75
|
+
)}
|
|
76
|
+
checked={checked}
|
|
77
|
+
{...props}
|
|
78
|
+
>
|
|
79
|
+
<span className="absolute left-2 flex h-3.5 w-3.5 items-center justify-center">
|
|
80
|
+
<DropdownMenuPrimitive.ItemIndicator>
|
|
81
|
+
<Check className="h-4 w-4" />
|
|
82
|
+
</DropdownMenuPrimitive.ItemIndicator>
|
|
83
|
+
</span>
|
|
84
|
+
{children}
|
|
85
|
+
</DropdownMenuPrimitive.CheckboxItem>
|
|
86
|
+
));
|
|
87
|
+
DropdownMenuCheckboxItem.displayName = DropdownMenuPrimitive.CheckboxItem.displayName;
|
|
88
|
+
|
|
89
|
+
const DropdownMenuRadioItem = React.forwardRef(({ className, children, ...props }, ref) => (
|
|
90
|
+
<DropdownMenuPrimitive.RadioItem
|
|
91
|
+
ref={ref}
|
|
92
|
+
className={cn(
|
|
93
|
+
'relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none transition-colors focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50',
|
|
94
|
+
className
|
|
95
|
+
)}
|
|
96
|
+
{...props}
|
|
97
|
+
>
|
|
98
|
+
<span className="absolute left-2 flex h-3.5 w-3.5 items-center justify-center">
|
|
99
|
+
<DropdownMenuPrimitive.ItemIndicator>
|
|
100
|
+
<Circle className="h-2 w-2 fill-current" />
|
|
101
|
+
</DropdownMenuPrimitive.ItemIndicator>
|
|
102
|
+
</span>
|
|
103
|
+
{children}
|
|
104
|
+
</DropdownMenuPrimitive.RadioItem>
|
|
105
|
+
));
|
|
106
|
+
DropdownMenuRadioItem.displayName = DropdownMenuPrimitive.RadioItem.displayName;
|
|
107
|
+
|
|
108
|
+
const DropdownMenuLabel = React.forwardRef(({ className, inset, ...props }, ref) => (
|
|
109
|
+
<DropdownMenuPrimitive.Label
|
|
110
|
+
ref={ref}
|
|
111
|
+
className={cn('px-2 py-1.5 text-sm font-semibold', inset && 'pl-8', className)}
|
|
112
|
+
{...props}
|
|
113
|
+
/>
|
|
114
|
+
));
|
|
115
|
+
DropdownMenuLabel.displayName = DropdownMenuPrimitive.Label.displayName;
|
|
116
|
+
|
|
117
|
+
const DropdownMenuSeparator = React.forwardRef(({ className, ...props }, ref) => (
|
|
118
|
+
<DropdownMenuPrimitive.Separator ref={ref} className={cn('-mx-1 my-1 h-px bg-muted', className)} {...props} />
|
|
119
|
+
));
|
|
120
|
+
DropdownMenuSeparator.displayName = DropdownMenuPrimitive.Separator.displayName;
|
|
121
|
+
|
|
122
|
+
const DropdownMenuShortcut = ({ className, ...props }) => {
|
|
123
|
+
return <span className={cn('ml-auto text-xs tracking-widest opacity-60', className)} {...props} />;
|
|
124
|
+
};
|
|
125
|
+
DropdownMenuShortcut.displayName = 'DropdownMenuShortcut';
|
|
126
|
+
|
|
127
|
+
export {
|
|
128
|
+
DropdownMenu,
|
|
129
|
+
DropdownMenuTrigger,
|
|
130
|
+
DropdownMenuContent,
|
|
131
|
+
DropdownMenuItem,
|
|
132
|
+
DropdownMenuCheckboxItem,
|
|
133
|
+
DropdownMenuRadioItem,
|
|
134
|
+
DropdownMenuLabel,
|
|
135
|
+
DropdownMenuSeparator,
|
|
136
|
+
DropdownMenuShortcut,
|
|
137
|
+
DropdownMenuGroup,
|
|
138
|
+
DropdownMenuPortal,
|
|
139
|
+
DropdownMenuSub,
|
|
140
|
+
DropdownMenuSubContent,
|
|
141
|
+
DropdownMenuSubTrigger,
|
|
142
|
+
DropdownMenuRadioGroup,
|
|
143
|
+
};
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { Slot } from '@radix-ui/react-slot';
|
|
3
|
+
import { Controller, FormProvider, useFormContext } from 'react-hook-form';
|
|
4
|
+
import { cn } from '@/lib/utils';
|
|
5
|
+
import { Label } from '@/components/ui/label';
|
|
6
|
+
|
|
7
|
+
const Form = FormProvider;
|
|
8
|
+
|
|
9
|
+
const FormFieldContext = React.createContext({});
|
|
10
|
+
|
|
11
|
+
const FormField = ({ name, ...props }) => {
|
|
12
|
+
return (
|
|
13
|
+
<FormFieldContext.Provider value={{ name }}>
|
|
14
|
+
<Controller name={name} {...props} />
|
|
15
|
+
</FormFieldContext.Provider>
|
|
16
|
+
);
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
const useFormField = () => {
|
|
20
|
+
const fieldContext = React.useContext(FormFieldContext);
|
|
21
|
+
const itemContext = React.useContext(FormItemContext);
|
|
22
|
+
const { getFieldState, formState } = useFormContext();
|
|
23
|
+
const fieldState = getFieldState(fieldContext.name, formState);
|
|
24
|
+
if (!fieldContext) throw new Error('useFormField should be used within <FormField>');
|
|
25
|
+
const { id } = itemContext;
|
|
26
|
+
return {
|
|
27
|
+
id,
|
|
28
|
+
name: fieldContext.name,
|
|
29
|
+
formItemId: `${id}-form-item`,
|
|
30
|
+
formDescriptionId: `${id}-form-item-description`,
|
|
31
|
+
formMessageId: `${id}-form-item-message`,
|
|
32
|
+
...fieldState,
|
|
33
|
+
};
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
const FormItemContext = React.createContext({});
|
|
37
|
+
|
|
38
|
+
const FormItem = React.forwardRef(({ className, ...props }, ref) => {
|
|
39
|
+
const id = React.useId();
|
|
40
|
+
return (
|
|
41
|
+
<FormItemContext.Provider value={{ id }}>
|
|
42
|
+
<div ref={ref} className={cn('space-y-2', className)} {...props} />
|
|
43
|
+
</FormItemContext.Provider>
|
|
44
|
+
);
|
|
45
|
+
});
|
|
46
|
+
FormItem.displayName = 'FormItem';
|
|
47
|
+
|
|
48
|
+
const FormLabel = React.forwardRef(({ className, ...props }, ref) => {
|
|
49
|
+
const { error, formItemId } = useFormField();
|
|
50
|
+
return <Label ref={ref} className={cn(error && 'text-destructive', className)} htmlFor={formItemId} {...props} />;
|
|
51
|
+
});
|
|
52
|
+
FormLabel.displayName = 'FormLabel';
|
|
53
|
+
|
|
54
|
+
const FormControl = React.forwardRef(({ ...props }, ref) => {
|
|
55
|
+
const { error, formItemId, formDescriptionId, formMessageId } = useFormField();
|
|
56
|
+
return (
|
|
57
|
+
<Slot
|
|
58
|
+
ref={ref}
|
|
59
|
+
id={formItemId}
|
|
60
|
+
aria-describedby={!error ? `${formDescriptionId}` : `${formDescriptionId} ${formMessageId}`}
|
|
61
|
+
aria-invalid={!!error}
|
|
62
|
+
{...props}
|
|
63
|
+
/>
|
|
64
|
+
);
|
|
65
|
+
});
|
|
66
|
+
FormControl.displayName = 'FormControl';
|
|
67
|
+
|
|
68
|
+
const FormDescription = React.forwardRef(({ className, ...props }, ref) => {
|
|
69
|
+
const { formDescriptionId } = useFormField();
|
|
70
|
+
return (
|
|
71
|
+
<p ref={ref} id={formDescriptionId} className={cn('text-sm text-muted-foreground', className)} {...props} />
|
|
72
|
+
);
|
|
73
|
+
});
|
|
74
|
+
FormDescription.displayName = 'FormDescription';
|
|
75
|
+
|
|
76
|
+
const FormMessage = React.forwardRef(({ className, children, ...props }, ref) => {
|
|
77
|
+
const { error, formMessageId } = useFormField();
|
|
78
|
+
const body = error ? String(error?.message) : children;
|
|
79
|
+
if (!body) return null;
|
|
80
|
+
return (
|
|
81
|
+
<p ref={ref} id={formMessageId} className={cn('text-sm font-medium text-destructive', className)} {...props}>
|
|
82
|
+
{body}
|
|
83
|
+
</p>
|
|
84
|
+
);
|
|
85
|
+
});
|
|
86
|
+
FormMessage.displayName = 'FormMessage';
|
|
87
|
+
|
|
88
|
+
export { useFormField, Form, FormItem, FormLabel, FormControl, FormDescription, FormMessage, FormField };
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import * as HoverCardPrimitive from '@radix-ui/react-hover-card';
|
|
3
|
+
import { cn } from '@/lib/utils';
|
|
4
|
+
|
|
5
|
+
const HoverCard = HoverCardPrimitive.Root;
|
|
6
|
+
const HoverCardTrigger = HoverCardPrimitive.Trigger;
|
|
7
|
+
|
|
8
|
+
const HoverCardContent = React.forwardRef(({ className, align = 'center', sideOffset = 4, ...props }, ref) => (
|
|
9
|
+
<HoverCardPrimitive.Content
|
|
10
|
+
ref={ref}
|
|
11
|
+
align={align}
|
|
12
|
+
sideOffset={sideOffset}
|
|
13
|
+
className={cn(
|
|
14
|
+
'z-50 w-64 rounded-md border bg-popover p-4 text-popover-foreground shadow-md outline-none',
|
|
15
|
+
className
|
|
16
|
+
)}
|
|
17
|
+
{...props}
|
|
18
|
+
/>
|
|
19
|
+
));
|
|
20
|
+
HoverCardContent.displayName = HoverCardPrimitive.Content.displayName;
|
|
21
|
+
|
|
22
|
+
export { HoverCard, HoverCardTrigger, HoverCardContent };
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { OTPInput } from 'input-otp';
|
|
3
|
+
import { Dot } from 'lucide-react';
|
|
4
|
+
import { cn } from '@/lib/utils';
|
|
5
|
+
|
|
6
|
+
const InputOTP = React.forwardRef(({ className, containerClassName, maxLength = 6, ...props }, ref) => (
|
|
7
|
+
<OTPInput
|
|
8
|
+
ref={ref}
|
|
9
|
+
maxLength={maxLength}
|
|
10
|
+
containerClassName={cn('flex items-center gap-2 has-[:disabled]:opacity-50', containerClassName)}
|
|
11
|
+
className={cn('disabled:cursor-not-allowed', className)}
|
|
12
|
+
render={({ slots }) => (
|
|
13
|
+
<div className="flex">
|
|
14
|
+
{slots.map((slot, idx) => (
|
|
15
|
+
<div
|
|
16
|
+
key={idx}
|
|
17
|
+
className={cn(
|
|
18
|
+
'relative flex h-10 w-10 items-center justify-center border-y border-r border-input text-sm transition-all first:rounded-l-md first:border-l last:rounded-r-md',
|
|
19
|
+
slot.isActive && 'z-10 ring-2 ring-ring ring-offset-background'
|
|
20
|
+
)}
|
|
21
|
+
>
|
|
22
|
+
{slot.char ?? slot.placeholderChar}
|
|
23
|
+
{slot.hasFakeCaret && (
|
|
24
|
+
<div className="pointer-events-none absolute inset-0 flex items-center justify-center">
|
|
25
|
+
<div className="h-4 w-px animate-pulse bg-foreground" />
|
|
26
|
+
</div>
|
|
27
|
+
)}
|
|
28
|
+
</div>
|
|
29
|
+
))}
|
|
30
|
+
</div>
|
|
31
|
+
)}
|
|
32
|
+
{...props}
|
|
33
|
+
/>
|
|
34
|
+
));
|
|
35
|
+
InputOTP.displayName = 'InputOTP';
|
|
36
|
+
|
|
37
|
+
const InputOTPGroup = React.forwardRef(({ className, ...props }, ref) => (
|
|
38
|
+
<div ref={ref} className={cn('flex items-center', className)} {...props} />
|
|
39
|
+
));
|
|
40
|
+
InputOTPGroup.displayName = 'InputOTPGroup';
|
|
41
|
+
|
|
42
|
+
const InputOTPSeparator = React.forwardRef(({ ...props }, ref) => (
|
|
43
|
+
<div ref={ref} role="separator" {...props}>
|
|
44
|
+
<Dot />
|
|
45
|
+
</div>
|
|
46
|
+
));
|
|
47
|
+
InputOTPSeparator.displayName = 'InputOTPSeparator';
|
|
48
|
+
|
|
49
|
+
export { InputOTP, InputOTPGroup, InputOTPSeparator };
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { cn } from '@/lib/utils';
|
|
3
|
+
|
|
4
|
+
const Input = React.forwardRef(({ className, type, ...props }, ref) => {
|
|
5
|
+
return (
|
|
6
|
+
<input
|
|
7
|
+
type={type}
|
|
8
|
+
className={cn(
|
|
9
|
+
'flex h-10 w-full rounded-md border border-input bg-background px-3 py-2 text-base ring-offset-background file:border-0 file:bg-transparent file:text-sm file:font-medium file:text-foreground placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 md:text-sm',
|
|
10
|
+
className
|
|
11
|
+
)}
|
|
12
|
+
ref={ref}
|
|
13
|
+
{...props}
|
|
14
|
+
/>
|
|
15
|
+
);
|
|
16
|
+
});
|
|
17
|
+
Input.displayName = 'Input';
|
|
18
|
+
|
|
19
|
+
export { Input };
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import * as LabelPrimitive from '@radix-ui/react-label';
|
|
3
|
+
import { cva } from 'class-variance-authority';
|
|
4
|
+
import { cn } from '@/lib/utils';
|
|
5
|
+
|
|
6
|
+
const labelVariants = cva(
|
|
7
|
+
'text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70'
|
|
8
|
+
);
|
|
9
|
+
|
|
10
|
+
const Label = React.forwardRef(({ className, ...props }, ref) => (
|
|
11
|
+
<LabelPrimitive.Root ref={ref} className={cn(labelVariants(), className)} {...props} />
|
|
12
|
+
));
|
|
13
|
+
Label.displayName = LabelPrimitive.Root.displayName;
|
|
14
|
+
|
|
15
|
+
export { Label };
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import * as MenubarPrimitive from '@radix-ui/react-menubar';
|
|
3
|
+
import { Check, ChevronRight, Circle } from 'lucide-react';
|
|
4
|
+
import { cn } from '@/lib/utils';
|
|
5
|
+
|
|
6
|
+
const MenubarMenu = MenubarPrimitive.Menu;
|
|
7
|
+
const MenubarGroup = MenubarPrimitive.Group;
|
|
8
|
+
const MenubarPortal = MenubarPrimitive.Portal;
|
|
9
|
+
const MenubarSub = MenubarPrimitive.Sub;
|
|
10
|
+
const MenubarRadioGroup = MenubarPrimitive.RadioGroup;
|
|
11
|
+
|
|
12
|
+
const Menubar = React.forwardRef(({ className, ...props }, ref) => (
|
|
13
|
+
<MenubarPrimitive.Root
|
|
14
|
+
ref={ref}
|
|
15
|
+
className={cn('flex h-10 items-center space-x-1 rounded-md border bg-background p-1', className)}
|
|
16
|
+
{...props}
|
|
17
|
+
/>
|
|
18
|
+
));
|
|
19
|
+
Menubar.displayName = MenubarPrimitive.Root.displayName;
|
|
20
|
+
|
|
21
|
+
const MenubarTrigger = React.forwardRef(({ className, ...props }, ref) => (
|
|
22
|
+
<MenubarPrimitive.Trigger
|
|
23
|
+
ref={ref}
|
|
24
|
+
className={cn(
|
|
25
|
+
'flex cursor-default select-none items-center rounded-sm px-3 py-1.5 text-sm font-medium outline-none focus:bg-accent focus:text-accent-foreground data-[state=open]:bg-accent data-[state=open]:text-accent-foreground',
|
|
26
|
+
className
|
|
27
|
+
)}
|
|
28
|
+
{...props}
|
|
29
|
+
/>
|
|
30
|
+
));
|
|
31
|
+
MenubarTrigger.displayName = MenubarPrimitive.Trigger.displayName;
|
|
32
|
+
|
|
33
|
+
const MenubarSubTrigger = React.forwardRef(({ className, inset, children, ...props }, ref) => (
|
|
34
|
+
<MenubarPrimitive.SubTrigger
|
|
35
|
+
ref={ref}
|
|
36
|
+
className={cn(
|
|
37
|
+
'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',
|
|
38
|
+
inset && 'pl-8',
|
|
39
|
+
className
|
|
40
|
+
)}
|
|
41
|
+
{...props}
|
|
42
|
+
>
|
|
43
|
+
{children}
|
|
44
|
+
<ChevronRight className="ml-auto h-4 w-4" />
|
|
45
|
+
</MenubarPrimitive.SubTrigger>
|
|
46
|
+
));
|
|
47
|
+
MenubarSubTrigger.displayName = MenubarPrimitive.SubTrigger.displayName;
|
|
48
|
+
|
|
49
|
+
const MenubarSubContent = React.forwardRef(({ className, ...props }, ref) => (
|
|
50
|
+
<MenubarPrimitive.SubContent
|
|
51
|
+
ref={ref}
|
|
52
|
+
className={cn(
|
|
53
|
+
'z-50 min-w-[8rem] overflow-hidden rounded-md border bg-popover p-1 text-popover-foreground shadow-lg',
|
|
54
|
+
className
|
|
55
|
+
)}
|
|
56
|
+
{...props}
|
|
57
|
+
/>
|
|
58
|
+
));
|
|
59
|
+
MenubarSubContent.displayName = MenubarPrimitive.SubContent.displayName;
|
|
60
|
+
|
|
61
|
+
const MenubarContent = React.forwardRef(({ className, align = 'start', alignOffset = -4, sideOffset = 8, ...props }, ref) => (
|
|
62
|
+
<MenubarPrimitive.Portal>
|
|
63
|
+
<MenubarPrimitive.Content
|
|
64
|
+
ref={ref}
|
|
65
|
+
align={align}
|
|
66
|
+
alignOffset={alignOffset}
|
|
67
|
+
sideOffset={sideOffset}
|
|
68
|
+
className={cn(
|
|
69
|
+
'z-50 min-w-[12rem] overflow-hidden rounded-md border bg-popover p-1 text-popover-foreground shadow-md',
|
|
70
|
+
className
|
|
71
|
+
)}
|
|
72
|
+
{...props}
|
|
73
|
+
/>
|
|
74
|
+
</MenubarPrimitive.Portal>
|
|
75
|
+
));
|
|
76
|
+
MenubarContent.displayName = MenubarPrimitive.Content.displayName;
|
|
77
|
+
|
|
78
|
+
const MenubarItem = React.forwardRef(({ className, inset, ...props }, ref) => (
|
|
79
|
+
<MenubarPrimitive.Item
|
|
80
|
+
ref={ref}
|
|
81
|
+
className={cn(
|
|
82
|
+
'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',
|
|
83
|
+
inset && 'pl-8',
|
|
84
|
+
className
|
|
85
|
+
)}
|
|
86
|
+
{...props}
|
|
87
|
+
/>
|
|
88
|
+
));
|
|
89
|
+
MenubarItem.displayName = MenubarPrimitive.Item.displayName;
|
|
90
|
+
|
|
91
|
+
const MenubarCheckboxItem = React.forwardRef(({ className, children, checked, ...props }, ref) => (
|
|
92
|
+
<MenubarPrimitive.CheckboxItem
|
|
93
|
+
ref={ref}
|
|
94
|
+
className={cn(
|
|
95
|
+
'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',
|
|
96
|
+
className
|
|
97
|
+
)}
|
|
98
|
+
checked={checked}
|
|
99
|
+
{...props}
|
|
100
|
+
>
|
|
101
|
+
<span className="absolute left-2 flex h-3.5 w-3.5 items-center justify-center">
|
|
102
|
+
<MenubarPrimitive.ItemIndicator>
|
|
103
|
+
<Check className="h-4 w-4" />
|
|
104
|
+
</MenubarPrimitive.ItemIndicator>
|
|
105
|
+
</span>
|
|
106
|
+
{children}
|
|
107
|
+
</MenubarPrimitive.CheckboxItem>
|
|
108
|
+
));
|
|
109
|
+
MenubarCheckboxItem.displayName = MenubarPrimitive.CheckboxItem.displayName;
|
|
110
|
+
|
|
111
|
+
const MenubarRadioItem = React.forwardRef(({ className, children, ...props }, ref) => (
|
|
112
|
+
<MenubarPrimitive.RadioItem
|
|
113
|
+
ref={ref}
|
|
114
|
+
className={cn(
|
|
115
|
+
'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',
|
|
116
|
+
className
|
|
117
|
+
)}
|
|
118
|
+
{...props}
|
|
119
|
+
>
|
|
120
|
+
<span className="absolute left-2 flex h-3.5 w-3.5 items-center justify-center">
|
|
121
|
+
<MenubarPrimitive.ItemIndicator>
|
|
122
|
+
<Circle className="h-2 w-2 fill-current" />
|
|
123
|
+
</MenubarPrimitive.ItemIndicator>
|
|
124
|
+
</span>
|
|
125
|
+
{children}
|
|
126
|
+
</MenubarPrimitive.RadioItem>
|
|
127
|
+
));
|
|
128
|
+
MenubarRadioItem.displayName = MenubarPrimitive.RadioItem.displayName;
|
|
129
|
+
|
|
130
|
+
const MenubarLabel = React.forwardRef(({ className, inset, ...props }, ref) => (
|
|
131
|
+
<MenubarPrimitive.Label ref={ref} className={cn('px-2 py-1.5 text-sm font-semibold', inset && 'pl-8', className)} {...props} />
|
|
132
|
+
));
|
|
133
|
+
MenubarLabel.displayName = MenubarPrimitive.Label.displayName;
|
|
134
|
+
|
|
135
|
+
const MenubarSeparator = React.forwardRef(({ className, ...props }, ref) => (
|
|
136
|
+
<MenubarPrimitive.Separator ref={ref} className={cn('-mx-1 my-1 h-px bg-muted', className)} {...props} />
|
|
137
|
+
));
|
|
138
|
+
MenubarSeparator.displayName = MenubarPrimitive.Separator.displayName;
|
|
139
|
+
|
|
140
|
+
const MenubarShortcut = ({ className, ...props }) => {
|
|
141
|
+
return <span className={cn('ml-auto text-xs tracking-widest text-muted-foreground', className)} {...props} />;
|
|
142
|
+
};
|
|
143
|
+
|
|
144
|
+
export {
|
|
145
|
+
Menubar,
|
|
146
|
+
MenubarMenu,
|
|
147
|
+
MenubarTrigger,
|
|
148
|
+
MenubarContent,
|
|
149
|
+
MenubarItem,
|
|
150
|
+
MenubarSeparator,
|
|
151
|
+
MenubarLabel,
|
|
152
|
+
MenubarCheckboxItem,
|
|
153
|
+
MenubarRadioGroup,
|
|
154
|
+
MenubarRadioItem,
|
|
155
|
+
MenubarPortal,
|
|
156
|
+
MenubarSubContent,
|
|
157
|
+
MenubarSubTrigger,
|
|
158
|
+
MenubarGroup,
|
|
159
|
+
MenubarSub,
|
|
160
|
+
MenubarShortcut,
|
|
161
|
+
};
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import * as NavigationMenuPrimitive from '@radix-ui/react-navigation-menu';
|
|
3
|
+
import { cva } from 'class-variance-authority';
|
|
4
|
+
import { ChevronDown } from 'lucide-react';
|
|
5
|
+
import { cn } from '@/lib/utils';
|
|
6
|
+
|
|
7
|
+
const NavigationMenu = React.forwardRef(({ className, children, ...props }, ref) => (
|
|
8
|
+
<NavigationMenuPrimitive.Root
|
|
9
|
+
ref={ref}
|
|
10
|
+
className={cn('relative z-10 flex max-w-max flex-1 items-center justify-center', className)}
|
|
11
|
+
{...props}
|
|
12
|
+
>
|
|
13
|
+
{children}
|
|
14
|
+
<NavigationMenuViewport />
|
|
15
|
+
</NavigationMenuPrimitive.Root>
|
|
16
|
+
));
|
|
17
|
+
NavigationMenu.displayName = NavigationMenuPrimitive.Root.displayName;
|
|
18
|
+
|
|
19
|
+
const NavigationMenuList = React.forwardRef(({ className, ...props }, ref) => (
|
|
20
|
+
<NavigationMenuPrimitive.List
|
|
21
|
+
ref={ref}
|
|
22
|
+
className={cn('group flex flex-1 list-none items-center justify-center space-x-1', className)}
|
|
23
|
+
{...props}
|
|
24
|
+
/>
|
|
25
|
+
));
|
|
26
|
+
NavigationMenuList.displayName = NavigationMenuPrimitive.List.displayName;
|
|
27
|
+
|
|
28
|
+
const NavigationMenuItem = NavigationMenuPrimitive.Item;
|
|
29
|
+
|
|
30
|
+
const navigationMenuTriggerStyle = cva(
|
|
31
|
+
'group inline-flex h-10 w-max items-center justify-center rounded-md bg-background px-4 py-2 text-sm font-medium transition-colors hover:bg-accent hover:text-accent-foreground focus:bg-accent focus:text-accent-foreground focus:outline-none disabled:pointer-events-none disabled:opacity-50 data-[active]:bg-accent/50 data-[state=open]:bg-accent/50'
|
|
32
|
+
);
|
|
33
|
+
|
|
34
|
+
const NavigationMenuTrigger = React.forwardRef(({ className, children, ...props }, ref) => (
|
|
35
|
+
<NavigationMenuPrimitive.Trigger
|
|
36
|
+
ref={ref}
|
|
37
|
+
className={cn(navigationMenuTriggerStyle(), 'group', className)}
|
|
38
|
+
{...props}
|
|
39
|
+
>
|
|
40
|
+
{children}{' '}
|
|
41
|
+
<ChevronDown
|
|
42
|
+
className="relative top-[1px] ml-1 h-3 w-3 transition duration-200 group-data-[state=open]:rotate-180"
|
|
43
|
+
aria-hidden="true"
|
|
44
|
+
/>
|
|
45
|
+
</NavigationMenuPrimitive.Trigger>
|
|
46
|
+
));
|
|
47
|
+
NavigationMenuTrigger.displayName = NavigationMenuPrimitive.Trigger.displayName;
|
|
48
|
+
|
|
49
|
+
const NavigationMenuContent = React.forwardRef(({ className, ...props }, ref) => (
|
|
50
|
+
<NavigationMenuPrimitive.Content
|
|
51
|
+
ref={ref}
|
|
52
|
+
className={cn('left-0 top-0 w-full p-2 md:absolute md:w-auto', className)}
|
|
53
|
+
{...props}
|
|
54
|
+
/>
|
|
55
|
+
));
|
|
56
|
+
NavigationMenuContent.displayName = NavigationMenuPrimitive.Content.displayName;
|
|
57
|
+
|
|
58
|
+
const NavigationMenuLink = NavigationMenuPrimitive.Link;
|
|
59
|
+
|
|
60
|
+
const NavigationMenuViewport = React.forwardRef(({ className, ...props }, ref) => (
|
|
61
|
+
<div className={cn('absolute left-0 top-full flex justify-center')}>
|
|
62
|
+
<NavigationMenuPrimitive.Viewport
|
|
63
|
+
className={cn(
|
|
64
|
+
'origin-top-center relative mt-1.5 h-[var(--radix-navigation-menu-viewport-height)] w-full overflow-hidden rounded-md border bg-popover text-popover-foreground shadow-lg md:w-[var(--radix-navigation-menu-viewport-width)]',
|
|
65
|
+
className
|
|
66
|
+
)}
|
|
67
|
+
ref={ref}
|
|
68
|
+
{...props}
|
|
69
|
+
/>
|
|
70
|
+
</div>
|
|
71
|
+
));
|
|
72
|
+
NavigationMenuViewport.displayName = NavigationMenuPrimitive.Viewport.displayName;
|
|
73
|
+
|
|
74
|
+
const NavigationMenuIndicator = React.forwardRef(({ className, ...props }, ref) => (
|
|
75
|
+
<NavigationMenuPrimitive.Indicator
|
|
76
|
+
ref={ref}
|
|
77
|
+
className={cn('top-full z-[1] flex h-1.5 items-end justify-center overflow-hidden', className)}
|
|
78
|
+
{...props}
|
|
79
|
+
>
|
|
80
|
+
<div className="relative top-[60%] h-2 w-2 rotate-45 rounded-tl-sm bg-border shadow-md" />
|
|
81
|
+
</NavigationMenuPrimitive.Indicator>
|
|
82
|
+
));
|
|
83
|
+
NavigationMenuIndicator.displayName = NavigationMenuPrimitive.Indicator.displayName;
|
|
84
|
+
|
|
85
|
+
export {
|
|
86
|
+
navigationMenuTriggerStyle,
|
|
87
|
+
NavigationMenu,
|
|
88
|
+
NavigationMenuList,
|
|
89
|
+
NavigationMenuItem,
|
|
90
|
+
NavigationMenuContent,
|
|
91
|
+
NavigationMenuTrigger,
|
|
92
|
+
NavigationMenuLink,
|
|
93
|
+
NavigationMenuIndicator,
|
|
94
|
+
NavigationMenuViewport,
|
|
95
|
+
};
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { ChevronLeft, ChevronRight, MoreHorizontal } from 'lucide-react';
|
|
3
|
+
import { cn } from '@/lib/utils';
|
|
4
|
+
import { buttonVariants } from '@/components/ui/button';
|
|
5
|
+
|
|
6
|
+
const Pagination = ({ className, ...props }) => (
|
|
7
|
+
<nav
|
|
8
|
+
role="navigation"
|
|
9
|
+
aria-label="pagination"
|
|
10
|
+
className={cn('mx-auto flex w-full justify-center', className)}
|
|
11
|
+
{...props}
|
|
12
|
+
/>
|
|
13
|
+
);
|
|
14
|
+
Pagination.displayName = 'Pagination';
|
|
15
|
+
|
|
16
|
+
const PaginationContent = React.forwardRef(({ className, ...props }, ref) => (
|
|
17
|
+
<ul ref={ref} className={cn('flex flex-row items-center gap-1', className)} {...props} />
|
|
18
|
+
));
|
|
19
|
+
PaginationContent.displayName = 'PaginationContent';
|
|
20
|
+
|
|
21
|
+
const PaginationItem = React.forwardRef(({ className, ...props }, ref) => (
|
|
22
|
+
<li ref={ref} className={cn('', className)} {...props} />
|
|
23
|
+
));
|
|
24
|
+
PaginationItem.displayName = 'PaginationItem';
|
|
25
|
+
|
|
26
|
+
const PaginationLink = ({ className, isActive, size = 'icon', ...props }) => (
|
|
27
|
+
<a
|
|
28
|
+
aria-current={isActive ? 'page' : undefined}
|
|
29
|
+
className={cn(
|
|
30
|
+
buttonVariants({
|
|
31
|
+
variant: isActive ? 'outline' : 'ghost',
|
|
32
|
+
size,
|
|
33
|
+
}),
|
|
34
|
+
className
|
|
35
|
+
)}
|
|
36
|
+
{...props}
|
|
37
|
+
/>
|
|
38
|
+
);
|
|
39
|
+
PaginationLink.displayName = 'PaginationLink';
|
|
40
|
+
|
|
41
|
+
const PaginationPrevious = ({ className, ...props }) => (
|
|
42
|
+
<PaginationLink aria-label="Go to previous page" size="default" className={cn('gap-1 pl-2.5', className)} {...props}>
|
|
43
|
+
<ChevronLeft className="h-4 w-4" />
|
|
44
|
+
<span>Previous</span>
|
|
45
|
+
</PaginationLink>
|
|
46
|
+
);
|
|
47
|
+
PaginationPrevious.displayName = 'PaginationPrevious';
|
|
48
|
+
|
|
49
|
+
const PaginationNext = ({ className, ...props }) => (
|
|
50
|
+
<PaginationLink aria-label="Go to next page" size="default" className={cn('gap-1 pr-2.5', className)} {...props}>
|
|
51
|
+
<span>Next</span>
|
|
52
|
+
<ChevronRight className="h-4 w-4" />
|
|
53
|
+
</PaginationLink>
|
|
54
|
+
);
|
|
55
|
+
PaginationNext.displayName = 'PaginationNext';
|
|
56
|
+
|
|
57
|
+
const PaginationEllipsis = ({ className, ...props }) => (
|
|
58
|
+
<span
|
|
59
|
+
aria-hidden
|
|
60
|
+
className={cn('flex h-9 w-9 items-center justify-center', className)}
|
|
61
|
+
{...props}
|
|
62
|
+
>
|
|
63
|
+
<MoreHorizontal className="h-4 w-4" />
|
|
64
|
+
<span className="sr-only">More pages</span>
|
|
65
|
+
</span>
|
|
66
|
+
);
|
|
67
|
+
PaginationEllipsis.displayName = 'PaginationEllipsis';
|
|
68
|
+
|
|
69
|
+
export {
|
|
70
|
+
Pagination,
|
|
71
|
+
PaginationContent,
|
|
72
|
+
PaginationEllipsis,
|
|
73
|
+
PaginationItem,
|
|
74
|
+
PaginationLink,
|
|
75
|
+
PaginationNext,
|
|
76
|
+
PaginationPrevious,
|
|
77
|
+
};
|