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.
- package/dist/index.d.ts +1 -0
- package/dist/index.js +747 -0
- package/package.json +57 -0
- package/registry/components/accordion.json +26 -0
- package/registry/components/alert.json +25 -0
- package/registry/components/avatar.json +26 -0
- package/registry/components/badge.json +24 -0
- package/registry/components/breadcrumb.json +28 -0
- package/registry/components/button.json +25 -0
- package/registry/components/card.json +28 -0
- package/registry/components/checkbox.json +23 -0
- package/registry/components/command.json +31 -0
- package/registry/components/dialog.json +32 -0
- package/registry/components/divider.json +22 -0
- package/registry/components/dropdown-menu.json +36 -0
- package/registry/components/empty-state.json +21 -0
- package/registry/components/error-message.json +20 -0
- package/registry/components/field-group.json +20 -0
- package/registry/components/helper-text.json +20 -0
- package/registry/components/input.json +21 -0
- package/registry/components/label.json +20 -0
- package/registry/components/progress.json +22 -0
- package/registry/components/radio.json +23 -0
- package/registry/components/select.json +32 -0
- package/registry/components/spinner.json +20 -0
- package/registry/components/switch.json +22 -0
- package/registry/components/table.json +27 -0
- package/registry/components/tabs.json +25 -0
- package/registry/components/textarea.json +21 -0
- package/registry/components/theme-toggler.json +24 -0
- package/registry/components/toast.json +31 -0
- package/registry/components/tooltip.json +26 -0
- package/registry/components/use-theme.json +19 -0
- package/registry/components/utils.json +21 -0
- package/registry/registry.json +35 -0
- package/registry/source/accordion.tsx +55 -0
- package/registry/source/alert.tsx +102 -0
- package/registry/source/avatar.tsx +137 -0
- package/registry/source/badge.tsx +38 -0
- package/registry/source/breadcrumb.tsx +109 -0
- package/registry/source/button.tsx +58 -0
- package/registry/source/card.tsx +108 -0
- package/registry/source/checkbox.tsx +170 -0
- package/registry/source/command.tsx +195 -0
- package/registry/source/dialog.tsx +133 -0
- package/registry/source/divider.tsx +84 -0
- package/registry/source/dropdown-menu.tsx +209 -0
- package/registry/source/empty-state.tsx +88 -0
- package/registry/source/error-message.tsx +49 -0
- package/registry/source/field-group.tsx +53 -0
- package/registry/source/helper-text.tsx +40 -0
- package/registry/source/input.tsx +219 -0
- package/registry/source/label.tsx +60 -0
- package/registry/source/progress.tsx +84 -0
- package/registry/source/radio.tsx +161 -0
- package/registry/source/select.tsx +278 -0
- package/registry/source/spinner.tsx +84 -0
- package/registry/source/switch.tsx +104 -0
- package/registry/source/table.tsx +116 -0
- package/registry/source/tabs.tsx +55 -0
- package/registry/source/textarea.tsx +129 -0
- package/registry/source/theme-toggler.tsx +94 -0
- package/registry/source/toast.tsx +166 -0
- package/registry/source/tooltip.tsx +55 -0
- package/registry/source/use-theme.tsx +102 -0
- package/registry/source/utils.ts +13 -0
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import * as SeparatorPrimitive from '@radix-ui/react-separator';
|
|
3
|
+
import { cn } from '../../lib/utils';
|
|
4
|
+
|
|
5
|
+
export interface DividerProps
|
|
6
|
+
extends React.ComponentPropsWithoutRef<typeof SeparatorPrimitive.Root> {
|
|
7
|
+
label?: string;
|
|
8
|
+
labelPosition?: 'left' | 'center' | 'right';
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
const Divider = React.forwardRef<
|
|
12
|
+
React.ElementRef<typeof SeparatorPrimitive.Root>,
|
|
13
|
+
DividerProps
|
|
14
|
+
>(
|
|
15
|
+
(
|
|
16
|
+
{
|
|
17
|
+
className,
|
|
18
|
+
orientation = 'horizontal',
|
|
19
|
+
decorative = true,
|
|
20
|
+
label,
|
|
21
|
+
labelPosition = 'center',
|
|
22
|
+
...props
|
|
23
|
+
},
|
|
24
|
+
ref
|
|
25
|
+
) => {
|
|
26
|
+
if (!label) {
|
|
27
|
+
return (
|
|
28
|
+
<SeparatorPrimitive.Root
|
|
29
|
+
ref={ref}
|
|
30
|
+
decorative={decorative}
|
|
31
|
+
orientation={orientation}
|
|
32
|
+
className={cn(
|
|
33
|
+
'shrink-0 bg-semantic-border-default',
|
|
34
|
+
orientation === 'horizontal' ? 'h-[1px] w-full' : 'h-full w-[1px]',
|
|
35
|
+
className
|
|
36
|
+
)}
|
|
37
|
+
{...props}
|
|
38
|
+
/>
|
|
39
|
+
);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// Divider with label (only for horizontal)
|
|
43
|
+
if (orientation === 'vertical') {
|
|
44
|
+
return (
|
|
45
|
+
<SeparatorPrimitive.Root
|
|
46
|
+
ref={ref}
|
|
47
|
+
decorative={decorative}
|
|
48
|
+
orientation={orientation}
|
|
49
|
+
className={cn('h-full w-[1px] shrink-0 bg-semantic-border-default', className)}
|
|
50
|
+
{...props}
|
|
51
|
+
/>
|
|
52
|
+
);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
const labelPositionClasses = {
|
|
56
|
+
left: 'justify-start',
|
|
57
|
+
center: 'justify-center',
|
|
58
|
+
right: 'justify-end',
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
return (
|
|
62
|
+
<div className={cn('flex w-full items-center', labelPositionClasses[labelPosition])}>
|
|
63
|
+
{labelPosition !== 'left' && (
|
|
64
|
+
<SeparatorPrimitive.Root
|
|
65
|
+
decorative={decorative}
|
|
66
|
+
orientation={orientation}
|
|
67
|
+
className="h-[1px] flex-1 bg-semantic-border-default"
|
|
68
|
+
/>
|
|
69
|
+
)}
|
|
70
|
+
<span className="px-3 text-xs font-medium text-semantic-fg-secondary">{label}</span>
|
|
71
|
+
{labelPosition !== 'right' && (
|
|
72
|
+
<SeparatorPrimitive.Root
|
|
73
|
+
decorative={decorative}
|
|
74
|
+
orientation={orientation}
|
|
75
|
+
className="h-[1px] flex-1 bg-semantic-border-default"
|
|
76
|
+
/>
|
|
77
|
+
)}
|
|
78
|
+
</div>
|
|
79
|
+
);
|
|
80
|
+
}
|
|
81
|
+
);
|
|
82
|
+
Divider.displayName = 'Divider';
|
|
83
|
+
|
|
84
|
+
export { Divider };
|
|
@@ -0,0 +1,209 @@
|
|
|
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
|
+
|
|
8
|
+
const DropdownMenuTrigger = DropdownMenuPrimitive.Trigger;
|
|
9
|
+
|
|
10
|
+
const DropdownMenuGroup = DropdownMenuPrimitive.Group;
|
|
11
|
+
|
|
12
|
+
const DropdownMenuPortal = DropdownMenuPrimitive.Portal;
|
|
13
|
+
|
|
14
|
+
const DropdownMenuSub = DropdownMenuPrimitive.Sub;
|
|
15
|
+
|
|
16
|
+
const DropdownMenuRadioGroup = DropdownMenuPrimitive.RadioGroup;
|
|
17
|
+
|
|
18
|
+
const DropdownMenuSubTrigger = React.forwardRef<
|
|
19
|
+
React.ElementRef<typeof DropdownMenuPrimitive.SubTrigger>,
|
|
20
|
+
React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.SubTrigger> & {
|
|
21
|
+
inset?: boolean;
|
|
22
|
+
}
|
|
23
|
+
>(({ className, inset, children, ...props }, ref) => (
|
|
24
|
+
<DropdownMenuPrimitive.SubTrigger
|
|
25
|
+
ref={ref}
|
|
26
|
+
className={cn(
|
|
27
|
+
'flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none',
|
|
28
|
+
'focus:bg-semantic-bg-hover data-[state=open]:bg-semantic-bg-hover',
|
|
29
|
+
inset && 'pl-8',
|
|
30
|
+
className
|
|
31
|
+
)}
|
|
32
|
+
{...props}
|
|
33
|
+
>
|
|
34
|
+
{children}
|
|
35
|
+
<ChevronRight className="ml-auto h-4 w-4" />
|
|
36
|
+
</DropdownMenuPrimitive.SubTrigger>
|
|
37
|
+
));
|
|
38
|
+
DropdownMenuSubTrigger.displayName = 'DropdownMenuSubTrigger';
|
|
39
|
+
|
|
40
|
+
const DropdownMenuSubContent = React.forwardRef<
|
|
41
|
+
React.ElementRef<typeof DropdownMenuPrimitive.SubContent>,
|
|
42
|
+
React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.SubContent>
|
|
43
|
+
>(({ className, ...props }, ref) => (
|
|
44
|
+
<DropdownMenuPrimitive.SubContent
|
|
45
|
+
ref={ref}
|
|
46
|
+
className={cn(
|
|
47
|
+
'z-50 min-w-[8rem] overflow-hidden rounded-md border border-semantic-border-default bg-semantic-bg-elevated p-1 shadow-lg',
|
|
48
|
+
'data-[state=open]:animate-in data-[state=closed]:animate-out',
|
|
49
|
+
'data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0',
|
|
50
|
+
'data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95',
|
|
51
|
+
'data-[side=top]:slide-in-from-bottom-2 data-[side=bottom]:slide-in-from-top-2',
|
|
52
|
+
'data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2',
|
|
53
|
+
className
|
|
54
|
+
)}
|
|
55
|
+
{...props}
|
|
56
|
+
/>
|
|
57
|
+
));
|
|
58
|
+
DropdownMenuSubContent.displayName = 'DropdownMenuSubContent';
|
|
59
|
+
|
|
60
|
+
const DropdownMenuContent = React.forwardRef<
|
|
61
|
+
React.ElementRef<typeof DropdownMenuPrimitive.Content>,
|
|
62
|
+
React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Content>
|
|
63
|
+
>(({ className, sideOffset = 4, ...props }, ref) => (
|
|
64
|
+
<DropdownMenuPrimitive.Portal>
|
|
65
|
+
<DropdownMenuPrimitive.Content
|
|
66
|
+
ref={ref}
|
|
67
|
+
sideOffset={sideOffset}
|
|
68
|
+
className={cn(
|
|
69
|
+
'z-50 min-w-[8rem] overflow-hidden rounded-md border border-semantic-border-default bg-semantic-bg-elevated p-1 shadow-md',
|
|
70
|
+
'data-[state=open]:animate-in data-[state=closed]:animate-out',
|
|
71
|
+
'data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0',
|
|
72
|
+
'data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95',
|
|
73
|
+
'data-[side=top]:slide-in-from-bottom-2 data-[side=bottom]:slide-in-from-top-2',
|
|
74
|
+
'data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2',
|
|
75
|
+
className
|
|
76
|
+
)}
|
|
77
|
+
{...props}
|
|
78
|
+
/>
|
|
79
|
+
</DropdownMenuPrimitive.Portal>
|
|
80
|
+
));
|
|
81
|
+
DropdownMenuContent.displayName = 'DropdownMenuContent';
|
|
82
|
+
|
|
83
|
+
const DropdownMenuItem = React.forwardRef<
|
|
84
|
+
React.ElementRef<typeof DropdownMenuPrimitive.Item>,
|
|
85
|
+
React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Item> & {
|
|
86
|
+
inset?: boolean;
|
|
87
|
+
}
|
|
88
|
+
>(({ className, inset, ...props }, ref) => (
|
|
89
|
+
<DropdownMenuPrimitive.Item
|
|
90
|
+
ref={ref}
|
|
91
|
+
className={cn(
|
|
92
|
+
'relative flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none transition-colors',
|
|
93
|
+
'focus:bg-semantic-bg-hover focus:text-semantic-fg-primary',
|
|
94
|
+
'data-[disabled]:pointer-events-none data-[disabled]:opacity-50',
|
|
95
|
+
inset && 'pl-8',
|
|
96
|
+
className
|
|
97
|
+
)}
|
|
98
|
+
{...props}
|
|
99
|
+
/>
|
|
100
|
+
));
|
|
101
|
+
DropdownMenuItem.displayName = 'DropdownMenuItem';
|
|
102
|
+
|
|
103
|
+
const DropdownMenuCheckboxItem = React.forwardRef<
|
|
104
|
+
React.ElementRef<typeof DropdownMenuPrimitive.CheckboxItem>,
|
|
105
|
+
React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.CheckboxItem>
|
|
106
|
+
>(({ className, children, checked, ...props }, ref) => (
|
|
107
|
+
<DropdownMenuPrimitive.CheckboxItem
|
|
108
|
+
ref={ref}
|
|
109
|
+
className={cn(
|
|
110
|
+
'relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none transition-colors',
|
|
111
|
+
'focus:bg-semantic-bg-hover focus:text-semantic-fg-primary',
|
|
112
|
+
'data-[disabled]:pointer-events-none data-[disabled]:opacity-50',
|
|
113
|
+
className
|
|
114
|
+
)}
|
|
115
|
+
checked={checked}
|
|
116
|
+
{...props}
|
|
117
|
+
>
|
|
118
|
+
<span className="absolute left-2 flex h-3.5 w-3.5 items-center justify-center">
|
|
119
|
+
<DropdownMenuPrimitive.ItemIndicator>
|
|
120
|
+
<Check className="h-4 w-4" />
|
|
121
|
+
</DropdownMenuPrimitive.ItemIndicator>
|
|
122
|
+
</span>
|
|
123
|
+
{children}
|
|
124
|
+
</DropdownMenuPrimitive.CheckboxItem>
|
|
125
|
+
));
|
|
126
|
+
DropdownMenuCheckboxItem.displayName = 'DropdownMenuCheckboxItem';
|
|
127
|
+
|
|
128
|
+
const DropdownMenuRadioItem = React.forwardRef<
|
|
129
|
+
React.ElementRef<typeof DropdownMenuPrimitive.RadioItem>,
|
|
130
|
+
React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.RadioItem>
|
|
131
|
+
>(({ className, children, ...props }, ref) => (
|
|
132
|
+
<DropdownMenuPrimitive.RadioItem
|
|
133
|
+
ref={ref}
|
|
134
|
+
className={cn(
|
|
135
|
+
'relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none transition-colors',
|
|
136
|
+
'focus:bg-semantic-bg-hover focus:text-semantic-fg-primary',
|
|
137
|
+
'data-[disabled]:pointer-events-none data-[disabled]:opacity-50',
|
|
138
|
+
className
|
|
139
|
+
)}
|
|
140
|
+
{...props}
|
|
141
|
+
>
|
|
142
|
+
<span className="absolute left-2 flex h-3.5 w-3.5 items-center justify-center">
|
|
143
|
+
<DropdownMenuPrimitive.ItemIndicator>
|
|
144
|
+
<Circle className="h-2 w-2 fill-current" />
|
|
145
|
+
</DropdownMenuPrimitive.ItemIndicator>
|
|
146
|
+
</span>
|
|
147
|
+
{children}
|
|
148
|
+
</DropdownMenuPrimitive.RadioItem>
|
|
149
|
+
));
|
|
150
|
+
DropdownMenuRadioItem.displayName = 'DropdownMenuRadioItem';
|
|
151
|
+
|
|
152
|
+
const DropdownMenuLabel = React.forwardRef<
|
|
153
|
+
React.ElementRef<typeof DropdownMenuPrimitive.Label>,
|
|
154
|
+
React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Label> & {
|
|
155
|
+
inset?: boolean;
|
|
156
|
+
}
|
|
157
|
+
>(({ className, inset, ...props }, ref) => (
|
|
158
|
+
<DropdownMenuPrimitive.Label
|
|
159
|
+
ref={ref}
|
|
160
|
+
className={cn(
|
|
161
|
+
'px-2 py-1.5 text-sm font-semibold text-semantic-fg-primary',
|
|
162
|
+
inset && 'pl-8',
|
|
163
|
+
className
|
|
164
|
+
)}
|
|
165
|
+
{...props}
|
|
166
|
+
/>
|
|
167
|
+
));
|
|
168
|
+
DropdownMenuLabel.displayName = 'DropdownMenuLabel';
|
|
169
|
+
|
|
170
|
+
const DropdownMenuSeparator = React.forwardRef<
|
|
171
|
+
React.ElementRef<typeof DropdownMenuPrimitive.Separator>,
|
|
172
|
+
React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Separator>
|
|
173
|
+
>(({ className, ...props }, ref) => (
|
|
174
|
+
<DropdownMenuPrimitive.Separator
|
|
175
|
+
ref={ref}
|
|
176
|
+
className={cn('-mx-1 my-1 h-px bg-semantic-border-default', className)}
|
|
177
|
+
{...props}
|
|
178
|
+
/>
|
|
179
|
+
));
|
|
180
|
+
DropdownMenuSeparator.displayName = 'DropdownMenuSeparator';
|
|
181
|
+
|
|
182
|
+
const DropdownMenuShortcut = ({
|
|
183
|
+
className,
|
|
184
|
+
...props
|
|
185
|
+
}: React.HTMLAttributes<HTMLSpanElement>) => (
|
|
186
|
+
<span
|
|
187
|
+
className={cn('ml-auto text-xs tracking-widest text-semantic-fg-muted', className)}
|
|
188
|
+
{...props}
|
|
189
|
+
/>
|
|
190
|
+
);
|
|
191
|
+
DropdownMenuShortcut.displayName = 'DropdownMenuShortcut';
|
|
192
|
+
|
|
193
|
+
export {
|
|
194
|
+
DropdownMenu,
|
|
195
|
+
DropdownMenuTrigger,
|
|
196
|
+
DropdownMenuContent,
|
|
197
|
+
DropdownMenuItem,
|
|
198
|
+
DropdownMenuCheckboxItem,
|
|
199
|
+
DropdownMenuRadioItem,
|
|
200
|
+
DropdownMenuLabel,
|
|
201
|
+
DropdownMenuSeparator,
|
|
202
|
+
DropdownMenuShortcut,
|
|
203
|
+
DropdownMenuGroup,
|
|
204
|
+
DropdownMenuPortal,
|
|
205
|
+
DropdownMenuSub,
|
|
206
|
+
DropdownMenuSubContent,
|
|
207
|
+
DropdownMenuSubTrigger,
|
|
208
|
+
DropdownMenuRadioGroup,
|
|
209
|
+
};
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { cva, type VariantProps } from 'class-variance-authority';
|
|
3
|
+
import { cn } from '../../lib/utils';
|
|
4
|
+
|
|
5
|
+
const emptyStateVariants = cva(
|
|
6
|
+
'flex flex-col items-center justify-center text-center',
|
|
7
|
+
{
|
|
8
|
+
variants: {
|
|
9
|
+
variant: {
|
|
10
|
+
default: 'py-12 px-6',
|
|
11
|
+
minimal: 'py-8 px-4',
|
|
12
|
+
card: 'py-12 px-6 bg-semantic-bg-elevated border border-semantic-border-default rounded-lg shadow-sm',
|
|
13
|
+
},
|
|
14
|
+
},
|
|
15
|
+
defaultVariants: {
|
|
16
|
+
variant: 'default',
|
|
17
|
+
},
|
|
18
|
+
}
|
|
19
|
+
);
|
|
20
|
+
|
|
21
|
+
export interface EmptyStateProps
|
|
22
|
+
extends React.HTMLAttributes<HTMLDivElement>,
|
|
23
|
+
VariantProps<typeof emptyStateVariants> {
|
|
24
|
+
/** Icon element to display */
|
|
25
|
+
icon?: React.ReactNode;
|
|
26
|
+
/** Title text */
|
|
27
|
+
title: string;
|
|
28
|
+
/** Description text */
|
|
29
|
+
description?: string;
|
|
30
|
+
/** Action element (typically a Button) */
|
|
31
|
+
action?: React.ReactNode;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
const EmptyState = React.forwardRef<HTMLDivElement, EmptyStateProps>(
|
|
35
|
+
({ className, variant, icon, title, description, action, ...props }, ref) => {
|
|
36
|
+
return (
|
|
37
|
+
<div
|
|
38
|
+
ref={ref}
|
|
39
|
+
role="region"
|
|
40
|
+
aria-label={title}
|
|
41
|
+
className={cn(emptyStateVariants({ variant }), className)}
|
|
42
|
+
{...props}
|
|
43
|
+
>
|
|
44
|
+
{icon && (
|
|
45
|
+
<div
|
|
46
|
+
className={cn(
|
|
47
|
+
'mb-4 flex items-center justify-center text-semantic-fg-disabled',
|
|
48
|
+
variant === 'minimal' && 'mb-3'
|
|
49
|
+
)}
|
|
50
|
+
aria-hidden="true"
|
|
51
|
+
>
|
|
52
|
+
{icon}
|
|
53
|
+
</div>
|
|
54
|
+
)}
|
|
55
|
+
|
|
56
|
+
<h3
|
|
57
|
+
className={cn(
|
|
58
|
+
'font-semibold text-semantic-fg-primary',
|
|
59
|
+
variant === 'minimal' ? 'text-base' : 'text-lg'
|
|
60
|
+
)}
|
|
61
|
+
>
|
|
62
|
+
{title}
|
|
63
|
+
</h3>
|
|
64
|
+
|
|
65
|
+
{description && (
|
|
66
|
+
<p
|
|
67
|
+
className={cn(
|
|
68
|
+
'mt-2 max-w-sm text-semantic-fg-muted',
|
|
69
|
+
variant === 'minimal' ? 'text-xs' : 'text-sm'
|
|
70
|
+
)}
|
|
71
|
+
>
|
|
72
|
+
{description}
|
|
73
|
+
</p>
|
|
74
|
+
)}
|
|
75
|
+
|
|
76
|
+
{action && (
|
|
77
|
+
<div className={cn('mt-6', variant === 'minimal' && 'mt-4')}>
|
|
78
|
+
{action}
|
|
79
|
+
</div>
|
|
80
|
+
)}
|
|
81
|
+
</div>
|
|
82
|
+
);
|
|
83
|
+
}
|
|
84
|
+
);
|
|
85
|
+
|
|
86
|
+
EmptyState.displayName = 'EmptyState';
|
|
87
|
+
|
|
88
|
+
export { EmptyState, emptyStateVariants };
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { cva, type VariantProps } from 'class-variance-authority';
|
|
3
|
+
import { AlertCircle } from 'lucide-react';
|
|
4
|
+
import { cn } from '../../lib/utils';
|
|
5
|
+
|
|
6
|
+
const errorMessageVariants = cva(
|
|
7
|
+
'flex items-start gap-2 text-sm text-semantic-fg-error',
|
|
8
|
+
{
|
|
9
|
+
variants: {
|
|
10
|
+
size: {
|
|
11
|
+
sm: 'text-xs',
|
|
12
|
+
md: 'text-sm',
|
|
13
|
+
},
|
|
14
|
+
},
|
|
15
|
+
defaultVariants: {
|
|
16
|
+
size: 'md',
|
|
17
|
+
},
|
|
18
|
+
}
|
|
19
|
+
);
|
|
20
|
+
|
|
21
|
+
export interface ErrorMessageProps
|
|
22
|
+
extends React.HTMLAttributes<HTMLParagraphElement>,
|
|
23
|
+
VariantProps<typeof errorMessageVariants> {
|
|
24
|
+
/** Show error icon */
|
|
25
|
+
showIcon?: boolean;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
const ErrorMessage = React.forwardRef<HTMLParagraphElement, ErrorMessageProps>(
|
|
29
|
+
({ className, size, showIcon = true, children, ...props }, ref) => {
|
|
30
|
+
return (
|
|
31
|
+
<p
|
|
32
|
+
ref={ref}
|
|
33
|
+
className={cn(errorMessageVariants({ size }), className)}
|
|
34
|
+
role="alert"
|
|
35
|
+
aria-live="assertive"
|
|
36
|
+
{...props}
|
|
37
|
+
>
|
|
38
|
+
{showIcon && (
|
|
39
|
+
<AlertCircle className={cn('flex-shrink-0', size === 'sm' ? 'h-3 w-3' : 'h-4 w-4')} aria-hidden="true" />
|
|
40
|
+
)}
|
|
41
|
+
<span>{children}</span>
|
|
42
|
+
</p>
|
|
43
|
+
);
|
|
44
|
+
}
|
|
45
|
+
);
|
|
46
|
+
|
|
47
|
+
ErrorMessage.displayName = 'ErrorMessage';
|
|
48
|
+
|
|
49
|
+
export { ErrorMessage, errorMessageVariants };
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { cva, type VariantProps } from 'class-variance-authority';
|
|
3
|
+
import { cn } from '../../lib/utils';
|
|
4
|
+
|
|
5
|
+
const fieldGroupVariants = cva('space-y-2', {
|
|
6
|
+
variants: {
|
|
7
|
+
spacing: {
|
|
8
|
+
sm: 'space-y-1',
|
|
9
|
+
md: 'space-y-2',
|
|
10
|
+
lg: 'space-y-3',
|
|
11
|
+
},
|
|
12
|
+
},
|
|
13
|
+
defaultVariants: {
|
|
14
|
+
spacing: 'md',
|
|
15
|
+
},
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
export interface FieldGroupProps
|
|
19
|
+
extends React.HTMLAttributes<HTMLDivElement>,
|
|
20
|
+
VariantProps<typeof fieldGroupVariants> {
|
|
21
|
+
/** Field label element */
|
|
22
|
+
label?: React.ReactNode;
|
|
23
|
+
/** Helper text element */
|
|
24
|
+
helperText?: React.ReactNode;
|
|
25
|
+
/** Error message element */
|
|
26
|
+
error?: React.ReactNode;
|
|
27
|
+
/** The input/field element */
|
|
28
|
+
children: React.ReactNode;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
const FieldGroup = React.forwardRef<HTMLDivElement, FieldGroupProps>(
|
|
32
|
+
({ className, spacing, label, helperText, error, children, ...props }, ref) => {
|
|
33
|
+
const labelId = React.useId();
|
|
34
|
+
|
|
35
|
+
return (
|
|
36
|
+
<div
|
|
37
|
+
ref={ref}
|
|
38
|
+
role="group"
|
|
39
|
+
aria-labelledby={label ? labelId : undefined}
|
|
40
|
+
className={cn(fieldGroupVariants({ spacing }), className)}
|
|
41
|
+
{...props}
|
|
42
|
+
>
|
|
43
|
+
{label && <div id={labelId}>{label}</div>}
|
|
44
|
+
<div>{children}</div>
|
|
45
|
+
{error ? <div>{error}</div> : helperText ? <div>{helperText}</div> : null}
|
|
46
|
+
</div>
|
|
47
|
+
);
|
|
48
|
+
}
|
|
49
|
+
);
|
|
50
|
+
|
|
51
|
+
FieldGroup.displayName = 'FieldGroup';
|
|
52
|
+
|
|
53
|
+
export { FieldGroup, fieldGroupVariants };
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { cva, type VariantProps } from 'class-variance-authority';
|
|
3
|
+
import { cn } from '../../lib/utils';
|
|
4
|
+
|
|
5
|
+
const helperTextVariants = cva('text-sm', {
|
|
6
|
+
variants: {
|
|
7
|
+
variant: {
|
|
8
|
+
default: 'text-semantic-fg-secondary',
|
|
9
|
+
muted: 'text-semantic-fg-muted',
|
|
10
|
+
},
|
|
11
|
+
size: {
|
|
12
|
+
sm: 'text-xs',
|
|
13
|
+
md: 'text-sm',
|
|
14
|
+
},
|
|
15
|
+
},
|
|
16
|
+
defaultVariants: {
|
|
17
|
+
variant: 'default',
|
|
18
|
+
size: 'md',
|
|
19
|
+
},
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
export interface HelperTextProps
|
|
23
|
+
extends React.HTMLAttributes<HTMLParagraphElement>,
|
|
24
|
+
VariantProps<typeof helperTextVariants> {}
|
|
25
|
+
|
|
26
|
+
const HelperText = React.forwardRef<HTMLParagraphElement, HelperTextProps>(
|
|
27
|
+
({ className, variant, size, ...props }, ref) => {
|
|
28
|
+
return (
|
|
29
|
+
<p
|
|
30
|
+
ref={ref}
|
|
31
|
+
className={cn(helperTextVariants({ variant, size }), className)}
|
|
32
|
+
{...props}
|
|
33
|
+
/>
|
|
34
|
+
);
|
|
35
|
+
}
|
|
36
|
+
);
|
|
37
|
+
|
|
38
|
+
HelperText.displayName = 'HelperText';
|
|
39
|
+
|
|
40
|
+
export { HelperText, helperTextVariants };
|