@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.
Files changed (63) hide show
  1. package/dist/main.js +305 -400
  2. package/dist/scaffold/.eslintrc.json +3 -0
  3. package/dist/scaffold/app/globals.css +46 -0
  4. package/dist/scaffold/app/layout.tsx +19 -0
  5. package/dist/scaffold/app/page.tsx +124 -0
  6. package/dist/scaffold/components/ui/README.md +12 -0
  7. package/dist/scaffold/components/ui/accordion.jsx +42 -0
  8. package/dist/scaffold/components/ui/alert-dialog.jsx +80 -0
  9. package/dist/scaffold/components/ui/alert.jsx +33 -0
  10. package/dist/scaffold/components/ui/aspect-ratio.jsx +5 -0
  11. package/dist/scaffold/components/ui/avatar.jsx +28 -0
  12. package/dist/scaffold/components/ui/badge.jsx +24 -0
  13. package/dist/scaffold/components/ui/breadcrumb.jsx +72 -0
  14. package/dist/scaffold/components/ui/button.jsx +40 -0
  15. package/dist/scaffold/components/ui/calendar.jsx +56 -0
  16. package/dist/scaffold/components/ui/card.jsx +38 -0
  17. package/dist/scaffold/components/ui/carousel.jsx +168 -0
  18. package/dist/scaffold/components/ui/chart.jsx +76 -0
  19. package/dist/scaffold/components/ui/checkbox.jsx +22 -0
  20. package/dist/scaffold/components/ui/collapsible.jsx +7 -0
  21. package/dist/scaffold/components/ui/command.jsx +100 -0
  22. package/dist/scaffold/components/ui/context-menu.jsx +137 -0
  23. package/dist/scaffold/components/ui/dialog.jsx +72 -0
  24. package/dist/scaffold/components/ui/drawer.jsx +68 -0
  25. package/dist/scaffold/components/ui/dropdown-menu.jsx +143 -0
  26. package/dist/scaffold/components/ui/form.jsx +88 -0
  27. package/dist/scaffold/components/ui/hover-card.jsx +22 -0
  28. package/dist/scaffold/components/ui/input-otp.jsx +49 -0
  29. package/dist/scaffold/components/ui/input.jsx +19 -0
  30. package/dist/scaffold/components/ui/label.jsx +15 -0
  31. package/dist/scaffold/components/ui/menubar.jsx +161 -0
  32. package/dist/scaffold/components/ui/navigation-menu.jsx +95 -0
  33. package/dist/scaffold/components/ui/pagination.jsx +77 -0
  34. package/dist/scaffold/components/ui/popover.jsx +25 -0
  35. package/dist/scaffold/components/ui/progress.jsx +19 -0
  36. package/dist/scaffold/components/ui/radio-group.jsx +29 -0
  37. package/dist/scaffold/components/ui/resizable.jsx +27 -0
  38. package/dist/scaffold/components/ui/scroll-area.jsx +31 -0
  39. package/dist/scaffold/components/ui/select.jsx +117 -0
  40. package/dist/scaffold/components/ui/separator.jsx +22 -0
  41. package/dist/scaffold/components/ui/sheet.jsx +81 -0
  42. package/dist/scaffold/components/ui/skeleton.jsx +7 -0
  43. package/dist/scaffold/components/ui/slider.jsx +19 -0
  44. package/dist/scaffold/components/ui/sonner.jsx +22 -0
  45. package/dist/scaffold/components/ui/switch.jsx +23 -0
  46. package/dist/scaffold/components/ui/table.jsx +61 -0
  47. package/dist/scaffold/components/ui/tabs.jsx +43 -0
  48. package/dist/scaffold/components/ui/textarea.jsx +18 -0
  49. package/dist/scaffold/components/ui/toast.jsx +85 -0
  50. package/dist/scaffold/components/ui/toaster.jsx +33 -0
  51. package/dist/scaffold/components/ui/toggle-group.jsx +41 -0
  52. package/dist/scaffold/components/ui/toggle.jsx +30 -0
  53. package/dist/scaffold/components/ui/tooltip.jsx +22 -0
  54. package/dist/scaffold/hooks/use-toast.ts +101 -0
  55. package/dist/scaffold/lib/utils.ts +6 -0
  56. package/dist/scaffold/next.config.js +5 -0
  57. package/dist/scaffold/next.config.mjs +15 -0
  58. package/dist/scaffold/next.config.ts +19 -0
  59. package/dist/scaffold/package.json +70 -0
  60. package/dist/scaffold/postcss.config.js +6 -0
  61. package/dist/scaffold/tailwind.config.ts +57 -0
  62. package/dist/scaffold/tsconfig.json +20 -0
  63. 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
+ };