apex-design-cli 1.0.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 (66) hide show
  1. package/dist/index.d.ts +1 -0
  2. package/dist/index.js +747 -0
  3. package/package.json +57 -0
  4. package/registry/components/accordion.json +26 -0
  5. package/registry/components/alert.json +25 -0
  6. package/registry/components/avatar.json +26 -0
  7. package/registry/components/badge.json +24 -0
  8. package/registry/components/breadcrumb.json +28 -0
  9. package/registry/components/button.json +25 -0
  10. package/registry/components/card.json +28 -0
  11. package/registry/components/checkbox.json +23 -0
  12. package/registry/components/command.json +31 -0
  13. package/registry/components/dialog.json +32 -0
  14. package/registry/components/divider.json +22 -0
  15. package/registry/components/dropdown-menu.json +36 -0
  16. package/registry/components/empty-state.json +21 -0
  17. package/registry/components/error-message.json +20 -0
  18. package/registry/components/field-group.json +20 -0
  19. package/registry/components/helper-text.json +20 -0
  20. package/registry/components/input.json +21 -0
  21. package/registry/components/label.json +20 -0
  22. package/registry/components/progress.json +22 -0
  23. package/registry/components/radio.json +23 -0
  24. package/registry/components/select.json +32 -0
  25. package/registry/components/spinner.json +20 -0
  26. package/registry/components/switch.json +22 -0
  27. package/registry/components/table.json +27 -0
  28. package/registry/components/tabs.json +25 -0
  29. package/registry/components/textarea.json +21 -0
  30. package/registry/components/theme-toggler.json +24 -0
  31. package/registry/components/toast.json +31 -0
  32. package/registry/components/tooltip.json +26 -0
  33. package/registry/components/use-theme.json +19 -0
  34. package/registry/components/utils.json +21 -0
  35. package/registry/registry.json +35 -0
  36. package/registry/source/accordion.tsx +55 -0
  37. package/registry/source/alert.tsx +102 -0
  38. package/registry/source/avatar.tsx +137 -0
  39. package/registry/source/badge.tsx +38 -0
  40. package/registry/source/breadcrumb.tsx +109 -0
  41. package/registry/source/button.tsx +58 -0
  42. package/registry/source/card.tsx +108 -0
  43. package/registry/source/checkbox.tsx +170 -0
  44. package/registry/source/command.tsx +195 -0
  45. package/registry/source/dialog.tsx +133 -0
  46. package/registry/source/divider.tsx +84 -0
  47. package/registry/source/dropdown-menu.tsx +209 -0
  48. package/registry/source/empty-state.tsx +88 -0
  49. package/registry/source/error-message.tsx +49 -0
  50. package/registry/source/field-group.tsx +53 -0
  51. package/registry/source/helper-text.tsx +40 -0
  52. package/registry/source/input.tsx +219 -0
  53. package/registry/source/label.tsx +60 -0
  54. package/registry/source/progress.tsx +84 -0
  55. package/registry/source/radio.tsx +161 -0
  56. package/registry/source/select.tsx +278 -0
  57. package/registry/source/spinner.tsx +84 -0
  58. package/registry/source/switch.tsx +104 -0
  59. package/registry/source/table.tsx +116 -0
  60. package/registry/source/tabs.tsx +55 -0
  61. package/registry/source/textarea.tsx +129 -0
  62. package/registry/source/theme-toggler.tsx +94 -0
  63. package/registry/source/toast.tsx +166 -0
  64. package/registry/source/tooltip.tsx +55 -0
  65. package/registry/source/use-theme.tsx +102 -0
  66. package/registry/source/utils.ts +13 -0
@@ -0,0 +1,58 @@
1
+ import * as React from 'react';
2
+ import { cva, type VariantProps } from 'class-variance-authority';
3
+ import { Loader2 } from 'lucide-react';
4
+ import { cn } from '../../lib/utils';
5
+
6
+ const buttonVariants = cva(
7
+ 'inline-flex items-center justify-center rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-semantic-focus focus-visible:ring-offset-2 ring-offset-semantic-offset disabled:pointer-events-none',
8
+ {
9
+ variants: {
10
+ variant: {
11
+ primary: 'bg-semantic-action-primary text-semantic-fg-inverse hover:bg-semantic-action-primary-hover disabled:bg-semantic-action-primary-disabled-bg disabled:text-semantic-action-primary-disabled-fg',
12
+ secondary: 'bg-semantic-bg-sunken text-semantic-fg-primary hover:bg-semantic-bg-hover disabled:bg-semantic-bg-disabled disabled:text-semantic-fg-disabled',
13
+ outline: 'border border-semantic-border-strong bg-semantic-bg-elevated hover:bg-semantic-bg-hover hover:text-semantic-fg-primary disabled:border-semantic-border-default disabled:text-semantic-fg-disabled',
14
+ ghost: 'hover:bg-semantic-bg-hover hover:text-semantic-fg-primary disabled:text-semantic-fg-disabled',
15
+ danger: 'bg-semantic-action-danger text-semantic-fg-inverse hover:bg-semantic-action-danger-hover disabled:bg-semantic-action-danger-disabled-bg disabled:text-semantic-action-danger-disabled-fg',
16
+ },
17
+ size: {
18
+ sm: 'h-9 px-3',
19
+ md: 'h-10 px-4 py-2',
20
+ lg: 'h-11 px-8',
21
+ },
22
+ },
23
+ defaultVariants: {
24
+ variant: 'primary',
25
+ size: 'md',
26
+ },
27
+ }
28
+ );
29
+
30
+ export interface ButtonProps
31
+ extends React.ButtonHTMLAttributes<HTMLButtonElement>,
32
+ VariantProps<typeof buttonVariants> {
33
+ isLoading?: boolean;
34
+ leftIcon?: React.ReactNode;
35
+ rightIcon?: React.ReactNode;
36
+ }
37
+
38
+ const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(
39
+ ({ className, variant, size, isLoading, leftIcon, rightIcon, children, disabled, ...props }, ref) => {
40
+ return (
41
+ <button
42
+ className={cn(buttonVariants({ variant, size, className }))}
43
+ ref={ref}
44
+ disabled={isLoading || disabled}
45
+ aria-busy={isLoading || undefined}
46
+ {...props}
47
+ >
48
+ {isLoading && <Loader2 className="mr-2 h-4 w-4 animate-spin" aria-hidden="true" />}
49
+ {!isLoading && leftIcon && <span className="mr-2" aria-hidden="true">{leftIcon}</span>}
50
+ {children}
51
+ {!isLoading && rightIcon && <span className="ml-2" aria-hidden="true">{rightIcon}</span>}
52
+ </button>
53
+ );
54
+ }
55
+ );
56
+ Button.displayName = 'Button';
57
+
58
+ export { Button, buttonVariants };
@@ -0,0 +1,108 @@
1
+ import * as React from 'react';
2
+ import { cva, type VariantProps } from 'class-variance-authority';
3
+ import { cn } from '../../lib/utils';
4
+
5
+ const cardVariants = cva(
6
+ 'rounded-lg border bg-semantic-bg-elevated text-semantic-fg-primary shadow-sm',
7
+ {
8
+ variants: {
9
+ variant: {
10
+ default: 'border-semantic-border-default',
11
+ elevated: 'border-transparent shadow-md',
12
+ outlined: 'border-semantic-border-strong shadow-none',
13
+ },
14
+ padding: {
15
+ none: '',
16
+ sm: 'p-4',
17
+ md: 'p-6',
18
+ lg: 'p-8',
19
+ },
20
+ },
21
+ defaultVariants: {
22
+ variant: 'default',
23
+ padding: 'md',
24
+ },
25
+ }
26
+ );
27
+
28
+ export interface CardProps
29
+ extends React.HTMLAttributes<HTMLDivElement>,
30
+ VariantProps<typeof cardVariants> {
31
+ hover?: boolean;
32
+ }
33
+
34
+ const Card = React.forwardRef<HTMLDivElement, CardProps>(
35
+ ({ className, variant, padding, hover, ...props }, ref) => (
36
+ <div
37
+ ref={ref}
38
+ className={cn(
39
+ cardVariants({ variant, padding }),
40
+ hover && 'transition-shadow hover:shadow-lg',
41
+ className
42
+ )}
43
+ {...props}
44
+ />
45
+ )
46
+ );
47
+ Card.displayName = 'Card';
48
+
49
+ const CardHeader = React.forwardRef<
50
+ HTMLDivElement,
51
+ React.HTMLAttributes<HTMLDivElement>
52
+ >(({ className, ...props }, ref) => (
53
+ <div
54
+ ref={ref}
55
+ className={cn('flex flex-col space-y-2', className)}
56
+ {...props}
57
+ />
58
+ ));
59
+ CardHeader.displayName = 'CardHeader';
60
+
61
+ const CardTitle = React.forwardRef<
62
+ HTMLParagraphElement,
63
+ React.HTMLAttributes<HTMLHeadingElement>
64
+ >(({ className, ...props }, ref) => (
65
+ <h3
66
+ ref={ref}
67
+ className={cn(
68
+ 'text-lg font-semibold leading-tight tracking-tight text-semantic-fg-primary',
69
+ className
70
+ )}
71
+ {...props}
72
+ />
73
+ ));
74
+ CardTitle.displayName = 'CardTitle';
75
+
76
+ const CardDescription = React.forwardRef<
77
+ HTMLParagraphElement,
78
+ React.HTMLAttributes<HTMLParagraphElement>
79
+ >(({ className, ...props }, ref) => (
80
+ <p
81
+ ref={ref}
82
+ className={cn('text-sm leading-relaxed text-semantic-fg-secondary', className)}
83
+ {...props}
84
+ />
85
+ ));
86
+ CardDescription.displayName = 'CardDescription';
87
+
88
+ const CardContent = React.forwardRef<
89
+ HTMLDivElement,
90
+ React.HTMLAttributes<HTMLDivElement>
91
+ >(({ className, ...props }, ref) => (
92
+ <div ref={ref} className={cn('pt-4', className)} {...props} />
93
+ ));
94
+ CardContent.displayName = 'CardContent';
95
+
96
+ const CardFooter = React.forwardRef<
97
+ HTMLDivElement,
98
+ React.HTMLAttributes<HTMLDivElement>
99
+ >(({ className, ...props }, ref) => (
100
+ <div
101
+ ref={ref}
102
+ className={cn('flex items-center gap-2 pt-4', className)}
103
+ {...props}
104
+ />
105
+ ));
106
+ CardFooter.displayName = 'CardFooter';
107
+
108
+ export { Card, CardHeader, CardFooter, CardTitle, CardDescription, CardContent, cardVariants };
@@ -0,0 +1,170 @@
1
+ import * as React from 'react';
2
+ import * as CheckboxPrimitive from '@radix-ui/react-checkbox';
3
+ import { Check, Minus } from 'lucide-react';
4
+ import { cn } from '../../lib/utils';
5
+
6
+ // ===================
7
+ // CHECKBOX PRIMITIVE
8
+ // ===================
9
+
10
+ const CheckboxRoot = React.forwardRef<
11
+ React.ElementRef<typeof CheckboxPrimitive.Root>,
12
+ React.ComponentPropsWithoutRef<typeof CheckboxPrimitive.Root> & {
13
+ error?: boolean;
14
+ size?: 'sm' | 'md' | 'lg';
15
+ }
16
+ >(({ className, error = false, size = 'md', ...props }, ref) => {
17
+ const sizeClasses = {
18
+ sm: 'h-4 w-4',
19
+ md: 'h-5 w-5',
20
+ lg: 'h-6 w-6',
21
+ };
22
+
23
+ const iconSizes = {
24
+ sm: 12,
25
+ md: 16,
26
+ lg: 20,
27
+ };
28
+
29
+ return (
30
+ <CheckboxPrimitive.Root
31
+ ref={ref}
32
+ className={cn(
33
+ 'peer shrink-0 rounded border-2 ring-offset-semantic-offset transition-colors',
34
+ 'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-semantic-focus focus-visible:ring-offset-2',
35
+ 'disabled:cursor-not-allowed disabled:opacity-50',
36
+ 'data-[state=checked]:bg-semantic-control-bg-checked data-[state=checked]:text-semantic-fg-inverse data-[state=checked]:border-semantic-control-bg-checked',
37
+ 'data-[state=indeterminate]:bg-semantic-control-bg-checked data-[state=indeterminate]:text-semantic-fg-inverse data-[state=indeterminate]:border-semantic-control-bg-checked',
38
+ error
39
+ ? 'border-semantic-control-border-error data-[state=checked]:bg-semantic-action-danger data-[state=checked]:border-semantic-action-danger'
40
+ : 'border-semantic-control-border hover:border-semantic-control-border-hover',
41
+ sizeClasses[size],
42
+ className
43
+ )}
44
+ {...props}
45
+ >
46
+ <CheckboxPrimitive.Indicator className="flex items-center justify-center text-current">
47
+ {props.checked === 'indeterminate' ? (
48
+ <Minus size={iconSizes[size]} strokeWidth={3} />
49
+ ) : (
50
+ <Check size={iconSizes[size]} strokeWidth={3} />
51
+ )}
52
+ </CheckboxPrimitive.Indicator>
53
+ </CheckboxPrimitive.Root>
54
+ );
55
+ });
56
+ CheckboxRoot.displayName = CheckboxPrimitive.Root.displayName;
57
+
58
+ // ===================
59
+ // CHECKBOX WITH LABEL (Componente completo)
60
+ // ===================
61
+
62
+ export interface CheckboxProps
63
+ extends Omit<React.ComponentPropsWithoutRef<typeof CheckboxPrimitive.Root>, 'type'> {
64
+ /** Label text */
65
+ label?: string;
66
+ /** Helper text shown below checkbox */
67
+ helperText?: string;
68
+ /** Error message shown when error={true} */
69
+ errorMessage?: string;
70
+ /** Error state */
71
+ error?: boolean;
72
+ /** Checkbox size */
73
+ size?: 'sm' | 'md' | 'lg';
74
+ /** Additional CSS classes for the container */
75
+ containerClassName?: string;
76
+ }
77
+
78
+ const Checkbox = React.forwardRef<
79
+ React.ElementRef<typeof CheckboxPrimitive.Root>,
80
+ CheckboxProps
81
+ >(
82
+ (
83
+ {
84
+ className,
85
+ label,
86
+ helperText,
87
+ errorMessage,
88
+ error = false,
89
+ size = 'md',
90
+ id,
91
+ containerClassName,
92
+ ...props
93
+ },
94
+ ref
95
+ ) => {
96
+ const checkboxId = id || React.useId();
97
+ const helperTextId = `${checkboxId}-helper`;
98
+ const errorMessageId = `${checkboxId}-error`;
99
+
100
+ return (
101
+ <div className={cn('flex flex-col', containerClassName)}>
102
+ <div className="flex items-start gap-2">
103
+ <CheckboxRoot
104
+ ref={ref}
105
+ id={checkboxId}
106
+ error={error}
107
+ size={size}
108
+ className={className}
109
+ aria-invalid={error ? 'true' : 'false'}
110
+ aria-describedby={
111
+ error && errorMessage
112
+ ? errorMessageId
113
+ : helperText
114
+ ? helperTextId
115
+ : undefined
116
+ }
117
+ {...props}
118
+ />
119
+
120
+ {label && (
121
+ <label
122
+ htmlFor={checkboxId}
123
+ className={cn(
124
+ 'cursor-pointer select-none font-medium leading-none',
125
+ 'peer-disabled:cursor-not-allowed peer-disabled:opacity-70',
126
+ size === 'sm' ? 'text-sm' : size === 'lg' ? 'text-lg' : 'text-base',
127
+ error ? 'text-semantic-fg-error' : 'text-semantic-fg-primary'
128
+ )}
129
+ >
130
+ {label}
131
+ </label>
132
+ )}
133
+ </div>
134
+
135
+ {!error && helperText && (
136
+ <p
137
+ id={helperTextId}
138
+ className={cn(
139
+ 'text-sm text-semantic-fg-secondary',
140
+ size === 'sm' ? 'ml-6' : size === 'lg' ? 'ml-8' : 'ml-7',
141
+ 'mt-1.5'
142
+ )}
143
+ >
144
+ {helperText}
145
+ </p>
146
+ )}
147
+
148
+ {error && errorMessage && (
149
+ <p
150
+ id={errorMessageId}
151
+ className={cn(
152
+ 'text-sm text-semantic-fg-error',
153
+ size === 'sm' ? 'ml-6' : size === 'lg' ? 'ml-8' : 'ml-7',
154
+ 'mt-1.5'
155
+ )}
156
+ >
157
+ {errorMessage}
158
+ </p>
159
+ )}
160
+ </div>
161
+ );
162
+ }
163
+ );
164
+ Checkbox.displayName = 'Checkbox';
165
+
166
+ // ===================
167
+ // EXPORTS
168
+ // ===================
169
+
170
+ export { Checkbox, CheckboxRoot };
@@ -0,0 +1,195 @@
1
+ import * as React from 'react';
2
+ import { Command as CommandPrimitive } from 'cmdk';
3
+ import { Search } from 'lucide-react';
4
+ import { cn } from '../../lib/utils';
5
+
6
+ const Command = React.forwardRef<
7
+ React.ElementRef<typeof CommandPrimitive>,
8
+ React.ComponentPropsWithoutRef<typeof CommandPrimitive>
9
+ >(({ className, ...props }, ref) => (
10
+ <CommandPrimitive
11
+ ref={ref}
12
+ className={cn(
13
+ 'flex h-full w-full flex-col overflow-hidden rounded-md',
14
+ 'bg-semantic-bg-elevated',
15
+ className
16
+ )}
17
+ {...props}
18
+ />
19
+ ));
20
+ Command.displayName = 'Command';
21
+
22
+ interface CommandDialogProps {
23
+ open?: boolean;
24
+ onOpenChange?: (open: boolean) => void;
25
+ children?: React.ReactNode;
26
+ }
27
+
28
+ const CommandDialog = ({ open, onOpenChange, children }: CommandDialogProps) => {
29
+ const [isOpen, setIsOpen] = React.useState(open ?? false);
30
+
31
+ const handleOpenChange = React.useCallback(
32
+ (value: boolean) => {
33
+ setIsOpen(value);
34
+ onOpenChange?.(value);
35
+ },
36
+ [onOpenChange]
37
+ );
38
+
39
+ React.useEffect(() => {
40
+ if (open !== undefined) {
41
+ setIsOpen(open);
42
+ }
43
+ }, [open]);
44
+
45
+ React.useEffect(() => {
46
+ const down = (e: KeyboardEvent) => {
47
+ if (e.key === 'k' && (e.metaKey || e.ctrlKey)) {
48
+ e.preventDefault();
49
+ handleOpenChange(!isOpen);
50
+ }
51
+ };
52
+
53
+ document.addEventListener('keydown', down);
54
+ return () => document.removeEventListener('keydown', down);
55
+ }, [isOpen, handleOpenChange]);
56
+
57
+ if (!isOpen) return null;
58
+
59
+ return (
60
+ <div className="fixed inset-0 z-50">
61
+ {/* Backdrop */}
62
+ <div
63
+ className="fixed inset-0 bg-semantic-bg-overlay backdrop-blur-sm"
64
+ onClick={() => handleOpenChange(false)}
65
+ />
66
+ {/* Dialog */}
67
+ <div className="fixed left-1/2 top-1/2 z-50 w-full max-w-lg -translate-x-1/2 -translate-y-1/2 p-4">
68
+ <Command
69
+ className={cn(
70
+ 'rounded-lg border border-semantic-border-default shadow-2xl',
71
+ )}
72
+ >
73
+ {children}
74
+ </Command>
75
+ </div>
76
+ </div>
77
+ );
78
+ };
79
+
80
+ const CommandInput = React.forwardRef<
81
+ React.ElementRef<typeof CommandPrimitive.Input>,
82
+ React.ComponentPropsWithoutRef<typeof CommandPrimitive.Input>
83
+ >(({ className, ...props }, ref) => (
84
+ <div className="flex items-center border-b border-semantic-border-default px-3">
85
+ <Search className="mr-2 h-4 w-4 shrink-0 text-semantic-fg-muted" aria-hidden="true" />
86
+ <CommandPrimitive.Input
87
+ ref={ref}
88
+ className={cn(
89
+ 'flex h-11 w-full rounded-md bg-transparent py-3 text-sm outline-none',
90
+ 'placeholder:text-semantic-control-placeholder',
91
+ 'disabled:cursor-not-allowed disabled:text-semantic-fg-disabled',
92
+ className
93
+ )}
94
+ {...props}
95
+ />
96
+ </div>
97
+ ));
98
+ CommandInput.displayName = 'CommandInput';
99
+
100
+ const CommandList = React.forwardRef<
101
+ React.ElementRef<typeof CommandPrimitive.List>,
102
+ React.ComponentPropsWithoutRef<typeof CommandPrimitive.List>
103
+ >(({ className, ...props }, ref) => (
104
+ <CommandPrimitive.List
105
+ ref={ref}
106
+ className={cn('max-h-[300px] overflow-y-auto overflow-x-hidden', className)}
107
+ {...props}
108
+ />
109
+ ));
110
+ CommandList.displayName = 'CommandList';
111
+
112
+ const CommandEmpty = React.forwardRef<
113
+ React.ElementRef<typeof CommandPrimitive.Empty>,
114
+ React.ComponentPropsWithoutRef<typeof CommandPrimitive.Empty>
115
+ >((props, ref) => (
116
+ <CommandPrimitive.Empty
117
+ ref={ref}
118
+ className="py-6 text-center text-sm text-semantic-fg-muted"
119
+ {...props}
120
+ />
121
+ ));
122
+ CommandEmpty.displayName = 'CommandEmpty';
123
+
124
+ const CommandGroup = React.forwardRef<
125
+ React.ElementRef<typeof CommandPrimitive.Group>,
126
+ React.ComponentPropsWithoutRef<typeof CommandPrimitive.Group>
127
+ >(({ className, ...props }, ref) => (
128
+ <CommandPrimitive.Group
129
+ ref={ref}
130
+ className={cn(
131
+ 'overflow-hidden p-1',
132
+ '[&_[cmdk-group-heading]]:px-2 [&_[cmdk-group-heading]]:py-1.5',
133
+ '[&_[cmdk-group-heading]]:text-xs [&_[cmdk-group-heading]]:font-medium',
134
+ '[&_[cmdk-group-heading]]:text-semantic-fg-muted',
135
+ className
136
+ )}
137
+ {...props}
138
+ />
139
+ ));
140
+ CommandGroup.displayName = 'CommandGroup';
141
+
142
+ const CommandSeparator = React.forwardRef<
143
+ React.ElementRef<typeof CommandPrimitive.Separator>,
144
+ React.ComponentPropsWithoutRef<typeof CommandPrimitive.Separator>
145
+ >(({ className, ...props }, ref) => (
146
+ <CommandPrimitive.Separator
147
+ ref={ref}
148
+ className={cn('-mx-1 h-px bg-semantic-border-default', className)}
149
+ {...props}
150
+ />
151
+ ));
152
+ CommandSeparator.displayName = 'CommandSeparator';
153
+
154
+ const CommandItem = React.forwardRef<
155
+ React.ElementRef<typeof CommandPrimitive.Item>,
156
+ React.ComponentPropsWithoutRef<typeof CommandPrimitive.Item>
157
+ >(({ className, ...props }, ref) => (
158
+ <CommandPrimitive.Item
159
+ ref={ref}
160
+ className={cn(
161
+ 'relative flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none',
162
+ 'data-[selected=true]:bg-semantic-bg-selected data-[selected=true]:text-semantic-fg-primary',
163
+ 'data-[disabled=true]:pointer-events-none data-[disabled=true]:text-semantic-fg-disabled',
164
+ className
165
+ )}
166
+ {...props}
167
+ />
168
+ ));
169
+ CommandItem.displayName = 'CommandItem';
170
+
171
+ const CommandShortcut = ({
172
+ className,
173
+ ...props
174
+ }: React.HTMLAttributes<HTMLSpanElement>) => (
175
+ <span
176
+ className={cn(
177
+ 'ml-auto text-xs tracking-widest text-semantic-fg-muted',
178
+ className
179
+ )}
180
+ {...props}
181
+ />
182
+ );
183
+ CommandShortcut.displayName = 'CommandShortcut';
184
+
185
+ export {
186
+ Command,
187
+ CommandDialog,
188
+ CommandInput,
189
+ CommandList,
190
+ CommandEmpty,
191
+ CommandGroup,
192
+ CommandItem,
193
+ CommandSeparator,
194
+ CommandShortcut,
195
+ };
@@ -0,0 +1,133 @@
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
+
8
+ const DialogTrigger = DialogPrimitive.Trigger;
9
+
10
+ const DialogPortal = DialogPrimitive.Portal;
11
+
12
+ const DialogClose = DialogPrimitive.Close;
13
+
14
+ const DialogOverlay = React.forwardRef<
15
+ React.ElementRef<typeof DialogPrimitive.Overlay>,
16
+ React.ComponentPropsWithoutRef<typeof DialogPrimitive.Overlay>
17
+ >(({ className, ...props }, ref) => (
18
+ <DialogPrimitive.Overlay
19
+ ref={ref}
20
+ className={cn(
21
+ 'fixed inset-0 z-50 bg-semantic-bg-overlay backdrop-blur-sm',
22
+ 'data-[state=open]:animate-in data-[state=closed]:animate-out',
23
+ 'data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0',
24
+ className
25
+ )}
26
+ {...props}
27
+ />
28
+ ));
29
+ DialogOverlay.displayName = DialogPrimitive.Overlay.displayName;
30
+
31
+ const DialogContent = React.forwardRef<
32
+ React.ElementRef<typeof DialogPrimitive.Content>,
33
+ React.ComponentPropsWithoutRef<typeof DialogPrimitive.Content> & {
34
+ showClose?: boolean;
35
+ }
36
+ >(({ className, children, showClose = true, ...props }, ref) => (
37
+ <DialogPortal>
38
+ <DialogOverlay />
39
+ <DialogPrimitive.Content
40
+ ref={ref}
41
+ className={cn(
42
+ 'fixed left-[50%] top-[50%] z-50 grid w-full max-w-lg translate-x-[-50%] translate-y-[-50%] gap-4',
43
+ 'border border-semantic-border-default bg-semantic-bg-elevated p-6 shadow-lg duration-200',
44
+ 'data-[state=open]:animate-in data-[state=closed]:animate-out',
45
+ 'data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0',
46
+ 'data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95',
47
+ 'data-[state=closed]:slide-out-to-left-1/2 data-[state=closed]:slide-out-to-top-[48%]',
48
+ 'data-[state=open]:slide-in-from-left-1/2 data-[state=open]:slide-in-from-top-[48%]',
49
+ 'rounded-lg',
50
+ 'sm:rounded-lg',
51
+ className
52
+ )}
53
+ {...props}
54
+ >
55
+ {children}
56
+ {showClose && (
57
+ <DialogPrimitive.Close className="absolute right-4 top-4 rounded-sm opacity-70 ring-offset-semantic-offset transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-semantic-focus focus:ring-offset-2 disabled:pointer-events-none data-[state=open]:bg-semantic-bg-hover data-[state=open]:text-semantic-fg-secondary">
58
+ <X className="h-4 w-4" />
59
+ <span className="sr-only">Close</span>
60
+ </DialogPrimitive.Close>
61
+ )}
62
+ </DialogPrimitive.Content>
63
+ </DialogPortal>
64
+ ));
65
+ DialogContent.displayName = DialogPrimitive.Content.displayName;
66
+
67
+ const DialogHeader = ({
68
+ className,
69
+ ...props
70
+ }: React.HTMLAttributes<HTMLDivElement>) => (
71
+ <div
72
+ className={cn(
73
+ 'flex flex-col space-y-1.5 text-center sm:text-left',
74
+ className
75
+ )}
76
+ {...props}
77
+ />
78
+ );
79
+ DialogHeader.displayName = 'DialogHeader';
80
+
81
+ const DialogFooter = ({
82
+ className,
83
+ ...props
84
+ }: React.HTMLAttributes<HTMLDivElement>) => (
85
+ <div
86
+ className={cn(
87
+ 'flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2',
88
+ className
89
+ )}
90
+ {...props}
91
+ />
92
+ );
93
+ DialogFooter.displayName = 'DialogFooter';
94
+
95
+ const DialogTitle = React.forwardRef<
96
+ React.ElementRef<typeof DialogPrimitive.Title>,
97
+ React.ComponentPropsWithoutRef<typeof DialogPrimitive.Title>
98
+ >(({ className, ...props }, ref) => (
99
+ <DialogPrimitive.Title
100
+ ref={ref}
101
+ className={cn(
102
+ 'text-lg font-semibold leading-none tracking-tight text-semantic-fg-primary',
103
+ className
104
+ )}
105
+ {...props}
106
+ />
107
+ ));
108
+ DialogTitle.displayName = DialogPrimitive.Title.displayName;
109
+
110
+ const DialogDescription = React.forwardRef<
111
+ React.ElementRef<typeof DialogPrimitive.Description>,
112
+ React.ComponentPropsWithoutRef<typeof DialogPrimitive.Description>
113
+ >(({ className, ...props }, ref) => (
114
+ <DialogPrimitive.Description
115
+ ref={ref}
116
+ className={cn('text-sm text-semantic-fg-secondary', className)}
117
+ {...props}
118
+ />
119
+ ));
120
+ DialogDescription.displayName = DialogPrimitive.Description.displayName;
121
+
122
+ export {
123
+ Dialog,
124
+ DialogPortal,
125
+ DialogOverlay,
126
+ DialogClose,
127
+ DialogTrigger,
128
+ DialogContent,
129
+ DialogHeader,
130
+ DialogFooter,
131
+ DialogTitle,
132
+ DialogDescription,
133
+ };