@auto-engineer/generate-react-client 1.34.0 → 1.35.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/CHANGELOG.md +32 -0
- package/dist/starter/package.json +2 -1
- package/dist/starter/scripts/build-component-db.ts +157 -0
- package/dist/starter/src/components/ui/Accordion.stories.tsx +2 -0
- package/dist/starter/src/components/ui/Accordion.tsx +4 -0
- package/dist/starter/src/components/ui/Alert.stories.tsx +2 -0
- package/dist/starter/src/components/ui/Alert.tsx +7 -0
- package/dist/starter/src/components/ui/AlertDialog.stories.tsx +2 -0
- package/dist/starter/src/components/ui/AlertDialog.tsx +15 -0
- package/dist/starter/src/components/ui/AspectRatio.stories.tsx +2 -0
- package/dist/starter/src/components/ui/AspectRatio.tsx +4 -0
- package/dist/starter/src/components/ui/Avatar.stories.tsx +3 -0
- package/dist/starter/src/components/ui/Avatar.tsx +11 -0
- package/dist/starter/src/components/ui/Badge.stories.tsx +5 -0
- package/dist/starter/src/components/ui/Badge.tsx +5 -0
- package/dist/starter/src/components/ui/Breadcrumb.stories.tsx +2 -0
- package/dist/starter/src/components/ui/Breadcrumb.tsx +12 -0
- package/dist/starter/src/components/ui/Button.stories.tsx +10 -0
- package/dist/starter/src/components/ui/Button.tsx +5 -0
- package/dist/starter/src/components/ui/ButtonGroup.stories.tsx +2 -0
- package/dist/starter/src/components/ui/ButtonGroup.tsx +6 -0
- package/dist/starter/src/components/ui/Calendar.stories.tsx +2 -0
- package/dist/starter/src/components/ui/Calendar.tsx +6 -0
- package/dist/starter/src/components/ui/Card.stories.tsx +2 -0
- package/dist/starter/src/components/ui/Card.tsx +10 -0
- package/dist/starter/src/components/ui/Carousel.stories.tsx +2 -0
- package/dist/starter/src/components/ui/Carousel.tsx +9 -0
- package/dist/starter/src/components/ui/Chart.stories.tsx +1 -0
- package/dist/starter/src/components/ui/Chart.tsx +9 -0
- package/dist/starter/src/components/ui/Checkbox.stories.tsx +4 -0
- package/dist/starter/src/components/ui/Checkbox.tsx +1 -0
- package/dist/starter/src/components/ui/Collapsible.stories.tsx +2 -0
- package/dist/starter/src/components/ui/Collapsible.tsx +3 -0
- package/dist/starter/src/components/ui/Combobox.stories.tsx +2 -0
- package/dist/starter/src/components/ui/Combobox.tsx +29 -0
- package/dist/starter/src/components/ui/Command.stories.tsx +2 -0
- package/dist/starter/src/components/ui/Command.tsx +20 -0
- package/dist/starter/src/components/ui/ContextMenu.stories.tsx +2 -0
- package/dist/starter/src/components/ui/ContextMenu.tsx +20 -0
- package/dist/starter/src/components/ui/Dialog.stories.tsx +2 -0
- package/dist/starter/src/components/ui/Dialog.tsx +18 -0
- package/dist/starter/src/components/ui/Direction.stories.tsx +2 -0
- package/dist/starter/src/components/ui/Direction.tsx +6 -0
- package/dist/starter/src/components/ui/Drawer.stories.tsx +2 -0
- package/dist/starter/src/components/ui/Drawer.tsx +18 -0
- package/dist/starter/src/components/ui/DropdownMenu.stories.tsx +2 -0
- package/dist/starter/src/components/ui/DropdownMenu.tsx +20 -0
- package/dist/starter/src/components/ui/Empty.stories.tsx +2 -0
- package/dist/starter/src/components/ui/Empty.tsx +13 -0
- package/dist/starter/src/components/ui/Field.stories.tsx +3 -0
- package/dist/starter/src/components/ui/Field.tsx +25 -0
- package/dist/starter/src/components/ui/Form.stories.tsx +1 -0
- package/dist/starter/src/components/ui/Form.tsx +15 -3
- package/dist/starter/src/components/ui/HoverCard.stories.tsx +2 -0
- package/dist/starter/src/components/ui/HoverCard.tsx +3 -0
- package/dist/starter/src/components/ui/Input.stories.tsx +4 -0
- package/dist/starter/src/components/ui/Input.tsx +1 -0
- package/dist/starter/src/components/ui/InputGroup.stories.tsx +3 -0
- package/dist/starter/src/components/ui/InputGroup.tsx +6 -0
- package/dist/starter/src/components/ui/InputOTP.stories.tsx +2 -0
- package/dist/starter/src/components/ui/InputOTP.tsx +4 -0
- package/dist/starter/src/components/ui/Item.stories.tsx +3 -0
- package/dist/starter/src/components/ui/Item.tsx +10 -0
- package/dist/starter/src/components/ui/Kbd.stories.tsx +5 -0
- package/dist/starter/src/components/ui/Kbd.tsx +4 -0
- package/dist/starter/src/components/ui/Label.stories.tsx +5 -0
- package/dist/starter/src/components/ui/Label.tsx +4 -0
- package/dist/starter/src/components/ui/Menubar.stories.tsx +2 -0
- package/dist/starter/src/components/ui/Menubar.tsx +15 -0
- package/dist/starter/src/components/ui/NativeSelect.stories.tsx +3 -0
- package/dist/starter/src/components/ui/NativeSelect.tsx +6 -0
- package/dist/starter/src/components/ui/NavigationMenu.stories.tsx +2 -0
- package/dist/starter/src/components/ui/NavigationMenu.tsx +10 -0
- package/dist/starter/src/components/ui/Pagination.stories.tsx +2 -0
- package/dist/starter/src/components/ui/Pagination.tsx +8 -0
- package/dist/starter/src/components/ui/Popover.stories.tsx +2 -0
- package/dist/starter/src/components/ui/Popover.tsx +5 -0
- package/dist/starter/src/components/ui/Progress.stories.tsx +4 -0
- package/dist/starter/src/components/ui/Progress.tsx +1 -0
- package/dist/starter/src/components/ui/RadioGroup.stories.tsx +2 -0
- package/dist/starter/src/components/ui/RadioGroup.tsx +5 -0
- package/dist/starter/src/components/ui/Resizable.stories.tsx +3 -0
- package/dist/starter/src/components/ui/Resizable.tsx +7 -0
- package/dist/starter/src/components/ui/ScrollArea.stories.tsx +2 -0
- package/dist/starter/src/components/ui/ScrollArea.tsx +5 -0
- package/dist/starter/src/components/ui/Select.stories.tsx +2 -0
- package/dist/starter/src/components/ui/Select.tsx +9 -0
- package/dist/starter/src/components/ui/Separator.stories.tsx +2 -0
- package/dist/starter/src/components/ui/Separator.tsx +1 -0
- package/dist/starter/src/components/ui/Sheet.stories.tsx +2 -0
- package/dist/starter/src/components/ui/Sheet.tsx +8 -0
- package/dist/starter/src/components/ui/Sidebar.stories.tsx +2 -0
- package/dist/starter/src/components/ui/Sidebar.tsx +20 -0
- package/dist/starter/src/components/ui/Skeleton.stories.tsx +2 -0
- package/dist/starter/src/components/ui/Skeleton.tsx +4 -0
- package/dist/starter/src/components/ui/Slider.stories.tsx +3 -0
- package/dist/starter/src/components/ui/Slider.tsx +1 -0
- package/dist/starter/src/components/ui/Sonner.stories.tsx +1 -0
- package/dist/starter/src/components/ui/Sonner.tsx +4 -0
- package/dist/starter/src/components/ui/Spinner.stories.tsx +3 -0
- package/dist/starter/src/components/ui/Spinner.tsx +4 -0
- package/dist/starter/src/components/ui/Switch.stories.tsx +4 -0
- package/dist/starter/src/components/ui/Switch.tsx +2 -0
- package/dist/starter/src/components/ui/Table.stories.tsx +2 -0
- package/dist/starter/src/components/ui/Table.tsx +11 -0
- package/dist/starter/src/components/ui/Tabs.stories.tsx +2 -0
- package/dist/starter/src/components/ui/Tabs.tsx +6 -0
- package/dist/starter/src/components/ui/Textarea.stories.tsx +3 -0
- package/dist/starter/src/components/ui/Textarea.tsx +4 -0
- package/dist/starter/src/components/ui/Toast.stories.tsx +4 -0
- package/dist/starter/src/components/ui/Toast.tsx +9 -0
- package/dist/starter/src/components/ui/Toaster.tsx +4 -0
- package/dist/starter/src/components/ui/Toggle.stories.tsx +4 -0
- package/dist/starter/src/components/ui/Toggle.tsx +1 -0
- package/dist/starter/src/components/ui/ToggleGroup.stories.tsx +3 -0
- package/dist/starter/src/components/ui/ToggleGroup.tsx +3 -0
- package/dist/starter/src/components/ui/Tooltip.stories.tsx +2 -0
- package/dist/starter/src/components/ui/Tooltip.tsx +6 -0
- package/package.json +2 -2
|
@@ -6,30 +6,37 @@ import { ContextMenu as ContextMenuPrimitive } from 'radix-ui';
|
|
|
6
6
|
|
|
7
7
|
import { cn } from '@/lib/utils';
|
|
8
8
|
|
|
9
|
+
/** Right-click menu with keyboard navigation. Supports submenus, checkbox/radio items, separators, and shortcuts. */
|
|
9
10
|
function ContextMenu({ ...props }: React.ComponentProps<typeof ContextMenuPrimitive.Root>) {
|
|
10
11
|
return <ContextMenuPrimitive.Root data-slot="context-menu" {...props} />;
|
|
11
12
|
}
|
|
12
13
|
|
|
14
|
+
/** The element that opens the context menu on right-click. Wraps its children. */
|
|
13
15
|
function ContextMenuTrigger({ ...props }: React.ComponentProps<typeof ContextMenuPrimitive.Trigger>) {
|
|
14
16
|
return <ContextMenuPrimitive.Trigger data-slot="context-menu-trigger" {...props} />;
|
|
15
17
|
}
|
|
16
18
|
|
|
19
|
+
/** Groups related context menu items for accessibility. */
|
|
17
20
|
function ContextMenuGroup({ ...props }: React.ComponentProps<typeof ContextMenuPrimitive.Group>) {
|
|
18
21
|
return <ContextMenuPrimitive.Group data-slot="context-menu-group" {...props} />;
|
|
19
22
|
}
|
|
20
23
|
|
|
24
|
+
/** Renders context menu content into a React portal. */
|
|
21
25
|
function ContextMenuPortal({ ...props }: React.ComponentProps<typeof ContextMenuPrimitive.Portal>) {
|
|
22
26
|
return <ContextMenuPrimitive.Portal data-slot="context-menu-portal" {...props} />;
|
|
23
27
|
}
|
|
24
28
|
|
|
29
|
+
/** Container for a submenu within the context menu. */
|
|
25
30
|
function ContextMenuSub({ ...props }: React.ComponentProps<typeof ContextMenuPrimitive.Sub>) {
|
|
26
31
|
return <ContextMenuPrimitive.Sub data-slot="context-menu-sub" {...props} />;
|
|
27
32
|
}
|
|
28
33
|
|
|
34
|
+
/** Groups radio items for single-selection within the context menu. */
|
|
29
35
|
function ContextMenuRadioGroup({ ...props }: React.ComponentProps<typeof ContextMenuPrimitive.RadioGroup>) {
|
|
30
36
|
return <ContextMenuPrimitive.RadioGroup data-slot="context-menu-radio-group" {...props} />;
|
|
31
37
|
}
|
|
32
38
|
|
|
39
|
+
/** Menu item that opens a nested submenu on hover or keyboard navigation. Shows a chevron indicator. */
|
|
33
40
|
function ContextMenuSubTrigger({
|
|
34
41
|
className,
|
|
35
42
|
inset,
|
|
@@ -54,6 +61,7 @@ function ContextMenuSubTrigger({
|
|
|
54
61
|
);
|
|
55
62
|
}
|
|
56
63
|
|
|
64
|
+
/** Popup content for a nested submenu. */
|
|
57
65
|
function ContextMenuSubContent({ className, ...props }: React.ComponentProps<typeof ContextMenuPrimitive.SubContent>) {
|
|
58
66
|
return (
|
|
59
67
|
<ContextMenuPrimitive.SubContent
|
|
@@ -67,6 +75,7 @@ function ContextMenuSubContent({ className, ...props }: React.ComponentProps<typ
|
|
|
67
75
|
);
|
|
68
76
|
}
|
|
69
77
|
|
|
78
|
+
/** The positioned popup container for context menu items. Portals to the document body. */
|
|
70
79
|
function ContextMenuContent({ className, ...props }: React.ComponentProps<typeof ContextMenuPrimitive.Content>) {
|
|
71
80
|
return (
|
|
72
81
|
<ContextMenuPrimitive.Portal>
|
|
@@ -82,9 +91,15 @@ function ContextMenuContent({ className, ...props }: React.ComponentProps<typeof
|
|
|
82
91
|
);
|
|
83
92
|
}
|
|
84
93
|
|
|
94
|
+
/**
|
|
95
|
+
* A selectable action within the context menu.
|
|
96
|
+
* Use variant="destructive" for dangerous actions like delete.
|
|
97
|
+
*/
|
|
85
98
|
function ContextMenuItem({
|
|
86
99
|
className,
|
|
100
|
+
/** Adds left padding to align with items that have icons or indicators. */
|
|
87
101
|
inset,
|
|
102
|
+
/** Use "destructive" for dangerous actions. */
|
|
88
103
|
variant = 'default',
|
|
89
104
|
...props
|
|
90
105
|
}: React.ComponentProps<typeof ContextMenuPrimitive.Item> & {
|
|
@@ -105,6 +120,7 @@ function ContextMenuItem({
|
|
|
105
120
|
);
|
|
106
121
|
}
|
|
107
122
|
|
|
123
|
+
/** A toggleable checkbox item within the context menu. Shows a check indicator when active. */
|
|
108
124
|
function ContextMenuCheckboxItem({
|
|
109
125
|
className,
|
|
110
126
|
children,
|
|
@@ -131,6 +147,7 @@ function ContextMenuCheckboxItem({
|
|
|
131
147
|
);
|
|
132
148
|
}
|
|
133
149
|
|
|
150
|
+
/** A radio-selectable item within a ContextMenuRadioGroup. Shows a dot indicator when selected. */
|
|
134
151
|
function ContextMenuRadioItem({
|
|
135
152
|
className,
|
|
136
153
|
children,
|
|
@@ -155,6 +172,7 @@ function ContextMenuRadioItem({
|
|
|
155
172
|
);
|
|
156
173
|
}
|
|
157
174
|
|
|
175
|
+
/** Non-interactive label within a context menu, used for section headings. */
|
|
158
176
|
function ContextMenuLabel({
|
|
159
177
|
className,
|
|
160
178
|
inset,
|
|
@@ -172,6 +190,7 @@ function ContextMenuLabel({
|
|
|
172
190
|
);
|
|
173
191
|
}
|
|
174
192
|
|
|
193
|
+
/** Visual divider between groups of context menu items. */
|
|
175
194
|
function ContextMenuSeparator({ className, ...props }: React.ComponentProps<typeof ContextMenuPrimitive.Separator>) {
|
|
176
195
|
return (
|
|
177
196
|
<ContextMenuPrimitive.Separator
|
|
@@ -182,6 +201,7 @@ function ContextMenuSeparator({ className, ...props }: React.ComponentProps<type
|
|
|
182
201
|
);
|
|
183
202
|
}
|
|
184
203
|
|
|
204
|
+
/** Displays a keyboard shortcut hint aligned to the right side of a context menu item. */
|
|
185
205
|
function ContextMenuShortcut({ className, ...props }: React.ComponentProps<'span'>) {
|
|
186
206
|
return (
|
|
187
207
|
<span
|
|
@@ -19,6 +19,7 @@ const meta: Meta<typeof Dialog> = {
|
|
|
19
19
|
export default meta;
|
|
20
20
|
type Story = StoryObj<typeof Dialog>;
|
|
21
21
|
|
|
22
|
+
/** Shows a dialog with a form for editing profile information. */
|
|
22
23
|
export const Default: Story = {
|
|
23
24
|
render: () => (
|
|
24
25
|
<Dialog>
|
|
@@ -52,6 +53,7 @@ export const Default: Story = {
|
|
|
52
53
|
),
|
|
53
54
|
};
|
|
54
55
|
|
|
56
|
+
/** Shows a confirmation dialog with a footer close button and a destructive action. */
|
|
55
57
|
export const WithCloseButton: Story = {
|
|
56
58
|
render: () => (
|
|
57
59
|
<Dialog>
|
|
@@ -5,22 +5,27 @@ import { Dialog as DialogPrimitive } from 'radix-ui';
|
|
|
5
5
|
import { cn } from '@/lib/utils';
|
|
6
6
|
import { Button } from '@/components/ui/Button';
|
|
7
7
|
|
|
8
|
+
/** A modal overlay with focus trapping and scroll locking. Click outside or press Escape to close. */
|
|
8
9
|
function Dialog({ ...props }: React.ComponentProps<typeof DialogPrimitive.Root>) {
|
|
9
10
|
return <DialogPrimitive.Root data-slot="dialog" {...props} />;
|
|
10
11
|
}
|
|
11
12
|
|
|
13
|
+
/** Button or element that opens the dialog when clicked. */
|
|
12
14
|
function DialogTrigger({ ...props }: React.ComponentProps<typeof DialogPrimitive.Trigger>) {
|
|
13
15
|
return <DialogPrimitive.Trigger data-slot="dialog-trigger" {...props} />;
|
|
14
16
|
}
|
|
15
17
|
|
|
18
|
+
/** Renders dialog content into a React portal. */
|
|
16
19
|
function DialogPortal({ ...props }: React.ComponentProps<typeof DialogPrimitive.Portal>) {
|
|
17
20
|
return <DialogPrimitive.Portal data-slot="dialog-portal" {...props} />;
|
|
18
21
|
}
|
|
19
22
|
|
|
23
|
+
/** Programmatic close trigger for the dialog. */
|
|
20
24
|
function DialogClose({ ...props }: React.ComponentProps<typeof DialogPrimitive.Close>) {
|
|
21
25
|
return <DialogPrimitive.Close data-slot="dialog-close" {...props} />;
|
|
22
26
|
}
|
|
23
27
|
|
|
28
|
+
/** Semi-transparent backdrop behind the dialog that dims the page content. */
|
|
24
29
|
function DialogOverlay({ className, ...props }: React.ComponentProps<typeof DialogPrimitive.Overlay>) {
|
|
25
30
|
return (
|
|
26
31
|
<DialogPrimitive.Overlay
|
|
@@ -34,9 +39,14 @@ function DialogOverlay({ className, ...props }: React.ComponentProps<typeof Dial
|
|
|
34
39
|
);
|
|
35
40
|
}
|
|
36
41
|
|
|
42
|
+
/**
|
|
43
|
+
* The main dialog panel centered on screen with overlay backdrop.
|
|
44
|
+
* Set showCloseButton={false} to hide the top-right X button.
|
|
45
|
+
*/
|
|
37
46
|
function DialogContent({
|
|
38
47
|
className,
|
|
39
48
|
children,
|
|
49
|
+
/** Whether to render the close (X) button in the top-right corner. */
|
|
40
50
|
showCloseButton = true,
|
|
41
51
|
...props
|
|
42
52
|
}: React.ComponentProps<typeof DialogPrimitive.Content> & {
|
|
@@ -68,6 +78,7 @@ function DialogContent({
|
|
|
68
78
|
);
|
|
69
79
|
}
|
|
70
80
|
|
|
81
|
+
/** Container for DialogTitle and DialogDescription at the top of the dialog. */
|
|
71
82
|
function DialogHeader({ className, ...props }: React.ComponentProps<'div'>) {
|
|
72
83
|
return (
|
|
73
84
|
<div
|
|
@@ -78,8 +89,13 @@ function DialogHeader({ className, ...props }: React.ComponentProps<'div'>) {
|
|
|
78
89
|
);
|
|
79
90
|
}
|
|
80
91
|
|
|
92
|
+
/**
|
|
93
|
+
* Container for action buttons at the bottom of the dialog.
|
|
94
|
+
* Set showCloseButton to add an automatic "Close" button.
|
|
95
|
+
*/
|
|
81
96
|
function DialogFooter({
|
|
82
97
|
className,
|
|
98
|
+
/** Whether to append a "Close" button that dismisses the dialog. */
|
|
83
99
|
showCloseButton = false,
|
|
84
100
|
children,
|
|
85
101
|
...props
|
|
@@ -102,6 +118,7 @@ function DialogFooter({
|
|
|
102
118
|
);
|
|
103
119
|
}
|
|
104
120
|
|
|
121
|
+
/** Accessible title for the dialog. Required for screen reader support. */
|
|
105
122
|
function DialogTitle({ className, ...props }: React.ComponentProps<typeof DialogPrimitive.Title>) {
|
|
106
123
|
return (
|
|
107
124
|
<DialogPrimitive.Title
|
|
@@ -112,6 +129,7 @@ function DialogTitle({ className, ...props }: React.ComponentProps<typeof Dialog
|
|
|
112
129
|
);
|
|
113
130
|
}
|
|
114
131
|
|
|
132
|
+
/** Accessible description text for the dialog, displayed below the title. */
|
|
115
133
|
function DialogDescription({ className, ...props }: React.ComponentProps<typeof DialogPrimitive.Description>) {
|
|
116
134
|
return (
|
|
117
135
|
<DialogPrimitive.Description
|
|
@@ -13,6 +13,7 @@ function DirectionDisplay() {
|
|
|
13
13
|
return <p className="text-sm text-muted-foreground">Current direction: {direction ?? 'not set'}</p>;
|
|
14
14
|
}
|
|
15
15
|
|
|
16
|
+
/** Shows the DirectionProvider in left-to-right mode. */
|
|
16
17
|
export const LTR: Story = {
|
|
17
18
|
render: () => (
|
|
18
19
|
<DirectionProvider dir="ltr">
|
|
@@ -24,6 +25,7 @@ export const LTR: Story = {
|
|
|
24
25
|
),
|
|
25
26
|
};
|
|
26
27
|
|
|
28
|
+
/** Shows the DirectionProvider in right-to-left mode for internationalization support. */
|
|
27
29
|
export const RTL: Story = {
|
|
28
30
|
render: () => (
|
|
29
31
|
<DirectionProvider dir="rtl">
|
|
@@ -3,8 +3,13 @@
|
|
|
3
3
|
import * as React from 'react';
|
|
4
4
|
import { Direction } from 'radix-ui';
|
|
5
5
|
|
|
6
|
+
/**
|
|
7
|
+
* Provides text direction (LTR/RTL) context to all descendant Radix UI components.
|
|
8
|
+
* Accepts either `dir` or `direction` prop for convenience.
|
|
9
|
+
*/
|
|
6
10
|
function DirectionProvider({
|
|
7
11
|
dir,
|
|
12
|
+
/** Alias for `dir`. If both are provided, `direction` takes precedence. */
|
|
8
13
|
direction,
|
|
9
14
|
children,
|
|
10
15
|
}: React.ComponentProps<typeof Direction.DirectionProvider> & {
|
|
@@ -13,6 +18,7 @@ function DirectionProvider({
|
|
|
13
18
|
return <Direction.DirectionProvider dir={direction ?? dir}>{children}</Direction.DirectionProvider>;
|
|
14
19
|
}
|
|
15
20
|
|
|
21
|
+
/** Hook to read the current text direction from the nearest DirectionProvider. */
|
|
16
22
|
const useDirection = Direction.useDirection;
|
|
17
23
|
|
|
18
24
|
export { DirectionProvider, useDirection };
|
|
@@ -18,6 +18,7 @@ const meta: Meta<typeof Drawer> = {
|
|
|
18
18
|
export default meta;
|
|
19
19
|
type Story = StoryObj<typeof Drawer>;
|
|
20
20
|
|
|
21
|
+
/** Shows a bottom drawer with a title, description, body content, and action buttons. */
|
|
21
22
|
export const Default: Story = {
|
|
22
23
|
render: () => (
|
|
23
24
|
<Drawer>
|
|
@@ -43,6 +44,7 @@ export const Default: Story = {
|
|
|
43
44
|
),
|
|
44
45
|
};
|
|
45
46
|
|
|
47
|
+
/** Shows a drawer sliding in from the right side, useful for side panels and detail views. */
|
|
46
48
|
export const RightSide: Story = {
|
|
47
49
|
render: () => (
|
|
48
50
|
<Drawer direction="right">
|
|
@@ -3,22 +3,32 @@ import { Drawer as DrawerPrimitive } from 'vaul';
|
|
|
3
3
|
|
|
4
4
|
import { cn } from '@/lib/utils';
|
|
5
5
|
|
|
6
|
+
/**
|
|
7
|
+
* A panel that slides in from the edge of the screen, ideal for mobile-friendly interactions.
|
|
8
|
+
* Built on Vaul with swipe-to-dismiss gestures. Supports top, bottom, left, and right directions.
|
|
9
|
+
*
|
|
10
|
+
* Compose with DrawerTrigger, DrawerContent, DrawerHeader, DrawerTitle, DrawerDescription, and DrawerFooter.
|
|
11
|
+
*/
|
|
6
12
|
function Drawer({ ...props }: React.ComponentProps<typeof DrawerPrimitive.Root>) {
|
|
7
13
|
return <DrawerPrimitive.Root data-slot="drawer" {...props} />;
|
|
8
14
|
}
|
|
9
15
|
|
|
16
|
+
/** Button or element that opens the drawer when clicked. */
|
|
10
17
|
function DrawerTrigger({ ...props }: React.ComponentProps<typeof DrawerPrimitive.Trigger>) {
|
|
11
18
|
return <DrawerPrimitive.Trigger data-slot="drawer-trigger" {...props} />;
|
|
12
19
|
}
|
|
13
20
|
|
|
21
|
+
/** Renders drawer content into a React portal. */
|
|
14
22
|
function DrawerPortal({ ...props }: React.ComponentProps<typeof DrawerPrimitive.Portal>) {
|
|
15
23
|
return <DrawerPrimitive.Portal data-slot="drawer-portal" {...props} />;
|
|
16
24
|
}
|
|
17
25
|
|
|
26
|
+
/** Programmatic close trigger for the drawer. */
|
|
18
27
|
function DrawerClose({ ...props }: React.ComponentProps<typeof DrawerPrimitive.Close>) {
|
|
19
28
|
return <DrawerPrimitive.Close data-slot="drawer-close" {...props} />;
|
|
20
29
|
}
|
|
21
30
|
|
|
31
|
+
/** Semi-transparent backdrop behind the drawer that dims the page content. */
|
|
22
32
|
function DrawerOverlay({ className, ...props }: React.ComponentProps<typeof DrawerPrimitive.Overlay>) {
|
|
23
33
|
return (
|
|
24
34
|
<DrawerPrimitive.Overlay
|
|
@@ -32,6 +42,10 @@ function DrawerOverlay({ className, ...props }: React.ComponentProps<typeof Draw
|
|
|
32
42
|
);
|
|
33
43
|
}
|
|
34
44
|
|
|
45
|
+
/**
|
|
46
|
+
* The main drawer panel that slides in from the configured direction.
|
|
47
|
+
* Automatically shows a drag handle for bottom drawers.
|
|
48
|
+
*/
|
|
35
49
|
function DrawerContent({ className, children, ...props }: React.ComponentProps<typeof DrawerPrimitive.Content>) {
|
|
36
50
|
return (
|
|
37
51
|
<DrawerPortal data-slot="drawer-portal">
|
|
@@ -55,6 +69,7 @@ function DrawerContent({ className, children, ...props }: React.ComponentProps<t
|
|
|
55
69
|
);
|
|
56
70
|
}
|
|
57
71
|
|
|
72
|
+
/** Container for DrawerTitle and DrawerDescription at the top of the drawer. */
|
|
58
73
|
function DrawerHeader({ className, ...props }: React.ComponentProps<'div'>) {
|
|
59
74
|
return (
|
|
60
75
|
<div
|
|
@@ -68,10 +83,12 @@ function DrawerHeader({ className, ...props }: React.ComponentProps<'div'>) {
|
|
|
68
83
|
);
|
|
69
84
|
}
|
|
70
85
|
|
|
86
|
+
/** Container for action buttons at the bottom of the drawer. */
|
|
71
87
|
function DrawerFooter({ className, ...props }: React.ComponentProps<'div'>) {
|
|
72
88
|
return <div data-slot="drawer-footer" className={cn('mt-auto flex flex-col gap-2 p-4', className)} {...props} />;
|
|
73
89
|
}
|
|
74
90
|
|
|
91
|
+
/** Accessible title for the drawer. */
|
|
75
92
|
function DrawerTitle({ className, ...props }: React.ComponentProps<typeof DrawerPrimitive.Title>) {
|
|
76
93
|
return (
|
|
77
94
|
<DrawerPrimitive.Title
|
|
@@ -82,6 +99,7 @@ function DrawerTitle({ className, ...props }: React.ComponentProps<typeof Drawer
|
|
|
82
99
|
);
|
|
83
100
|
}
|
|
84
101
|
|
|
102
|
+
/** Accessible description text for the drawer, displayed below the title. */
|
|
85
103
|
function DrawerDescription({ className, ...props }: React.ComponentProps<typeof DrawerPrimitive.Description>) {
|
|
86
104
|
return (
|
|
87
105
|
<DrawerPrimitive.Description
|
|
@@ -19,6 +19,7 @@ const meta: Meta<typeof DropdownMenu> = {
|
|
|
19
19
|
export default meta;
|
|
20
20
|
type Story = StoryObj<typeof DropdownMenu>;
|
|
21
21
|
|
|
22
|
+
/** Shows a dropdown menu with grouped items, icons, keyboard shortcuts, and a destructive logout action. */
|
|
22
23
|
export const Default: Story = {
|
|
23
24
|
render: () => (
|
|
24
25
|
<DropdownMenu>
|
|
@@ -55,6 +56,7 @@ export const Default: Story = {
|
|
|
55
56
|
),
|
|
56
57
|
};
|
|
57
58
|
|
|
59
|
+
/** Shows a minimal dropdown menu with basic edit/duplicate/delete actions. */
|
|
58
60
|
export const Simple: Story = {
|
|
59
61
|
render: () => (
|
|
60
62
|
<DropdownMenu>
|
|
@@ -6,18 +6,22 @@ import { DropdownMenu as DropdownMenuPrimitive } from 'radix-ui';
|
|
|
6
6
|
|
|
7
7
|
import { cn } from '@/lib/utils';
|
|
8
8
|
|
|
9
|
+
/** Action menu triggered by a button click. Supports submenus, checkbox/radio items, and keyboard shortcuts. */
|
|
9
10
|
function DropdownMenu({ ...props }: React.ComponentProps<typeof DropdownMenuPrimitive.Root>) {
|
|
10
11
|
return <DropdownMenuPrimitive.Root data-slot="dropdown-menu" {...props} />;
|
|
11
12
|
}
|
|
12
13
|
|
|
14
|
+
/** Renders dropdown menu content into a React portal. */
|
|
13
15
|
function DropdownMenuPortal({ ...props }: React.ComponentProps<typeof DropdownMenuPrimitive.Portal>) {
|
|
14
16
|
return <DropdownMenuPrimitive.Portal data-slot="dropdown-menu-portal" {...props} />;
|
|
15
17
|
}
|
|
16
18
|
|
|
19
|
+
/** Button or element that toggles the dropdown menu open/closed. */
|
|
17
20
|
function DropdownMenuTrigger({ ...props }: React.ComponentProps<typeof DropdownMenuPrimitive.Trigger>) {
|
|
18
21
|
return <DropdownMenuPrimitive.Trigger data-slot="dropdown-menu-trigger" {...props} />;
|
|
19
22
|
}
|
|
20
23
|
|
|
24
|
+
/** The positioned popup container for dropdown menu items. Portals to the document body. */
|
|
21
25
|
function DropdownMenuContent({
|
|
22
26
|
className,
|
|
23
27
|
sideOffset = 4,
|
|
@@ -38,13 +42,20 @@ function DropdownMenuContent({
|
|
|
38
42
|
);
|
|
39
43
|
}
|
|
40
44
|
|
|
45
|
+
/** Groups related dropdown menu items for accessibility. */
|
|
41
46
|
function DropdownMenuGroup({ ...props }: React.ComponentProps<typeof DropdownMenuPrimitive.Group>) {
|
|
42
47
|
return <DropdownMenuPrimitive.Group data-slot="dropdown-menu-group" {...props} />;
|
|
43
48
|
}
|
|
44
49
|
|
|
50
|
+
/**
|
|
51
|
+
* A selectable action within the dropdown menu.
|
|
52
|
+
* Use variant="destructive" for dangerous actions like delete or logout.
|
|
53
|
+
*/
|
|
45
54
|
function DropdownMenuItem({
|
|
46
55
|
className,
|
|
56
|
+
/** Adds left padding to align with items that have icons or indicators. */
|
|
47
57
|
inset,
|
|
58
|
+
/** Use "destructive" for dangerous actions. */
|
|
48
59
|
variant = 'default',
|
|
49
60
|
...props
|
|
50
61
|
}: React.ComponentProps<typeof DropdownMenuPrimitive.Item> & {
|
|
@@ -65,6 +76,7 @@ function DropdownMenuItem({
|
|
|
65
76
|
);
|
|
66
77
|
}
|
|
67
78
|
|
|
79
|
+
/** A toggleable checkbox item within the dropdown menu. Shows a check indicator when active. */
|
|
68
80
|
function DropdownMenuCheckboxItem({
|
|
69
81
|
className,
|
|
70
82
|
children,
|
|
@@ -91,10 +103,12 @@ function DropdownMenuCheckboxItem({
|
|
|
91
103
|
);
|
|
92
104
|
}
|
|
93
105
|
|
|
106
|
+
/** Groups radio items for single-selection within the dropdown menu. */
|
|
94
107
|
function DropdownMenuRadioGroup({ ...props }: React.ComponentProps<typeof DropdownMenuPrimitive.RadioGroup>) {
|
|
95
108
|
return <DropdownMenuPrimitive.RadioGroup data-slot="dropdown-menu-radio-group" {...props} />;
|
|
96
109
|
}
|
|
97
110
|
|
|
111
|
+
/** A radio-selectable item within a DropdownMenuRadioGroup. Shows a dot indicator when selected. */
|
|
98
112
|
function DropdownMenuRadioItem({
|
|
99
113
|
className,
|
|
100
114
|
children,
|
|
@@ -119,6 +133,7 @@ function DropdownMenuRadioItem({
|
|
|
119
133
|
);
|
|
120
134
|
}
|
|
121
135
|
|
|
136
|
+
/** Non-interactive label within a dropdown menu, used for section headings. */
|
|
122
137
|
function DropdownMenuLabel({
|
|
123
138
|
className,
|
|
124
139
|
inset,
|
|
@@ -136,6 +151,7 @@ function DropdownMenuLabel({
|
|
|
136
151
|
);
|
|
137
152
|
}
|
|
138
153
|
|
|
154
|
+
/** Visual divider between groups of dropdown menu items. */
|
|
139
155
|
function DropdownMenuSeparator({ className, ...props }: React.ComponentProps<typeof DropdownMenuPrimitive.Separator>) {
|
|
140
156
|
return (
|
|
141
157
|
<DropdownMenuPrimitive.Separator
|
|
@@ -146,6 +162,7 @@ function DropdownMenuSeparator({ className, ...props }: React.ComponentProps<typ
|
|
|
146
162
|
);
|
|
147
163
|
}
|
|
148
164
|
|
|
165
|
+
/** Displays a keyboard shortcut hint aligned to the right side of a dropdown menu item. */
|
|
149
166
|
function DropdownMenuShortcut({ className, ...props }: React.ComponentProps<'span'>) {
|
|
150
167
|
return (
|
|
151
168
|
<span
|
|
@@ -156,10 +173,12 @@ function DropdownMenuShortcut({ className, ...props }: React.ComponentProps<'spa
|
|
|
156
173
|
);
|
|
157
174
|
}
|
|
158
175
|
|
|
176
|
+
/** Container for a submenu within the dropdown menu. */
|
|
159
177
|
function DropdownMenuSub({ ...props }: React.ComponentProps<typeof DropdownMenuPrimitive.Sub>) {
|
|
160
178
|
return <DropdownMenuPrimitive.Sub data-slot="dropdown-menu-sub" {...props} />;
|
|
161
179
|
}
|
|
162
180
|
|
|
181
|
+
/** Menu item that opens a nested submenu on hover or keyboard navigation. Shows a chevron indicator. */
|
|
163
182
|
function DropdownMenuSubTrigger({
|
|
164
183
|
className,
|
|
165
184
|
inset,
|
|
@@ -184,6 +203,7 @@ function DropdownMenuSubTrigger({
|
|
|
184
203
|
);
|
|
185
204
|
}
|
|
186
205
|
|
|
206
|
+
/** Popup content for a nested submenu. */
|
|
187
207
|
function DropdownMenuSubContent({
|
|
188
208
|
className,
|
|
189
209
|
...props
|
|
@@ -9,6 +9,7 @@ const meta: Meta<typeof Empty> = {
|
|
|
9
9
|
export default meta;
|
|
10
10
|
type Story = StoryObj<typeof Empty>;
|
|
11
11
|
|
|
12
|
+
/** Shows a basic empty state with a title and description text. */
|
|
12
13
|
export const Default: Story = {
|
|
13
14
|
render: () => (
|
|
14
15
|
<Empty>
|
|
@@ -20,6 +21,7 @@ export const Default: Story = {
|
|
|
20
21
|
),
|
|
21
22
|
};
|
|
22
23
|
|
|
24
|
+
/** Shows an empty state with a styled icon container above the title and description. */
|
|
23
25
|
export const WithIcon: Story = {
|
|
24
26
|
render: () => (
|
|
25
27
|
<Empty>
|
|
@@ -2,6 +2,11 @@ import { cva, type VariantProps } from 'class-variance-authority';
|
|
|
2
2
|
|
|
3
3
|
import { cn } from '@/lib/utils';
|
|
4
4
|
|
|
5
|
+
/**
|
|
6
|
+
* A placeholder component for empty states, such as no search results or empty inboxes.
|
|
7
|
+
* Compose with EmptyHeader, EmptyMedia, EmptyTitle, EmptyDescription, and EmptyContent
|
|
8
|
+
* to build structured empty state layouts with icons and call-to-action areas.
|
|
9
|
+
*/
|
|
5
10
|
function Empty({ className, ...props }: React.ComponentProps<'div'>) {
|
|
6
11
|
return (
|
|
7
12
|
<div
|
|
@@ -15,6 +20,7 @@ function Empty({ className, ...props }: React.ComponentProps<'div'>) {
|
|
|
15
20
|
);
|
|
16
21
|
}
|
|
17
22
|
|
|
23
|
+
/** Container for the title, description, and optional media in an empty state. */
|
|
18
24
|
function EmptyHeader({ className, ...props }: React.ComponentProps<'div'>) {
|
|
19
25
|
return (
|
|
20
26
|
<div
|
|
@@ -40,6 +46,10 @@ const emptyMediaVariants = cva(
|
|
|
40
46
|
},
|
|
41
47
|
);
|
|
42
48
|
|
|
49
|
+
/**
|
|
50
|
+
* Container for an icon or illustration in the empty state.
|
|
51
|
+
* Use variant="icon" for a styled icon container with a muted background.
|
|
52
|
+
*/
|
|
43
53
|
function EmptyMedia({
|
|
44
54
|
className,
|
|
45
55
|
variant = 'default',
|
|
@@ -55,10 +65,12 @@ function EmptyMedia({
|
|
|
55
65
|
);
|
|
56
66
|
}
|
|
57
67
|
|
|
68
|
+
/** Title text for the empty state message. */
|
|
58
69
|
function EmptyTitle({ className, ...props }: React.ComponentProps<'div'>) {
|
|
59
70
|
return <div data-slot="empty-title" className={cn('text-lg font-medium tracking-tight', className)} {...props} />;
|
|
60
71
|
}
|
|
61
72
|
|
|
73
|
+
/** Descriptive text explaining why the content is empty or what the user can do. */
|
|
62
74
|
function EmptyDescription({ className, ...props }: React.ComponentProps<'p'>) {
|
|
63
75
|
return (
|
|
64
76
|
<div
|
|
@@ -72,6 +84,7 @@ function EmptyDescription({ className, ...props }: React.ComponentProps<'p'>) {
|
|
|
72
84
|
);
|
|
73
85
|
}
|
|
74
86
|
|
|
87
|
+
/** Container for action buttons or additional content below the empty state message. */
|
|
75
88
|
function EmptyContent({ className, ...props }: React.ComponentProps<'div'>) {
|
|
76
89
|
return (
|
|
77
90
|
<div
|
|
@@ -9,6 +9,7 @@ const meta: Meta<typeof Field> = {
|
|
|
9
9
|
export default meta;
|
|
10
10
|
type Story = StoryObj<typeof Field>;
|
|
11
11
|
|
|
12
|
+
/** Shows a vertical form field with label, input, and helper description text. */
|
|
12
13
|
export const Default: Story = {
|
|
13
14
|
render: () => (
|
|
14
15
|
<Field>
|
|
@@ -21,6 +22,7 @@ export const Default: Story = {
|
|
|
21
22
|
),
|
|
22
23
|
};
|
|
23
24
|
|
|
25
|
+
/** Shows a field in an invalid state with error styling and a validation error message. */
|
|
24
26
|
export const WithError: Story = {
|
|
25
27
|
render: () => (
|
|
26
28
|
<Field data-invalid="true">
|
|
@@ -34,6 +36,7 @@ export const WithError: Story = {
|
|
|
34
36
|
),
|
|
35
37
|
};
|
|
36
38
|
|
|
39
|
+
/** Shows a field with horizontal orientation where the label and input are side by side. */
|
|
37
40
|
export const Horizontal: Story = {
|
|
38
41
|
render: () => (
|
|
39
42
|
<Field orientation="horizontal">
|
|
@@ -7,6 +7,10 @@ import { cn } from '@/lib/utils';
|
|
|
7
7
|
import { Label } from '@/components/ui/Label';
|
|
8
8
|
import { Separator } from '@/components/ui/Separator';
|
|
9
9
|
|
|
10
|
+
/**
|
|
11
|
+
* A semantic fieldset container for grouping related form fields.
|
|
12
|
+
* Use as a top-level wrapper around FieldGroup or multiple Field components.
|
|
13
|
+
*/
|
|
10
14
|
function FieldSet({ className, ...props }: React.ComponentProps<'fieldset'>) {
|
|
11
15
|
return (
|
|
12
16
|
<fieldset
|
|
@@ -21,6 +25,10 @@ function FieldSet({ className, ...props }: React.ComponentProps<'fieldset'>) {
|
|
|
21
25
|
);
|
|
22
26
|
}
|
|
23
27
|
|
|
28
|
+
/**
|
|
29
|
+
* A legend element for a FieldSet, displayed as the group heading.
|
|
30
|
+
* Use variant="label" for a smaller label-sized heading.
|
|
31
|
+
*/
|
|
24
32
|
function FieldLegend({
|
|
25
33
|
className,
|
|
26
34
|
variant = 'legend',
|
|
@@ -36,6 +44,7 @@ function FieldLegend({
|
|
|
36
44
|
);
|
|
37
45
|
}
|
|
38
46
|
|
|
47
|
+
/** Container for a group of Field components. Provides container query context for responsive layouts. */
|
|
39
48
|
function FieldGroup({ className, ...props }: React.ComponentProps<'div'>) {
|
|
40
49
|
return (
|
|
41
50
|
<div
|
|
@@ -70,8 +79,14 @@ const fieldVariants = cva('group/field flex w-full gap-3 data-[invalid=true]:tex
|
|
|
70
79
|
},
|
|
71
80
|
});
|
|
72
81
|
|
|
82
|
+
/**
|
|
83
|
+
* A form field wrapper that pairs a label with an input and optional description/error.
|
|
84
|
+
* Supports vertical, horizontal, and responsive orientations.
|
|
85
|
+
* Set data-invalid="true" to apply error styling.
|
|
86
|
+
*/
|
|
73
87
|
function Field({
|
|
74
88
|
className,
|
|
89
|
+
/** Layout direction: "vertical" stacks label above input, "horizontal" places them side by side, "responsive" switches at the md breakpoint. */
|
|
75
90
|
orientation = 'vertical',
|
|
76
91
|
...props
|
|
77
92
|
}: React.ComponentProps<'div'> & VariantProps<typeof fieldVariants>) {
|
|
@@ -86,6 +101,7 @@ function Field({
|
|
|
86
101
|
);
|
|
87
102
|
}
|
|
88
103
|
|
|
104
|
+
/** Container for the input element plus optional description and error within a Field. */
|
|
89
105
|
function FieldContent({ className, ...props }: React.ComponentProps<'div'>) {
|
|
90
106
|
return (
|
|
91
107
|
<div
|
|
@@ -96,6 +112,7 @@ function FieldContent({ className, ...props }: React.ComponentProps<'div'>) {
|
|
|
96
112
|
);
|
|
97
113
|
}
|
|
98
114
|
|
|
115
|
+
/** Label for a form field. Supports wrapping checkbox/radio inputs for card-style selection. */
|
|
99
116
|
function FieldLabel({ className, ...props }: React.ComponentProps<typeof Label>) {
|
|
100
117
|
return (
|
|
101
118
|
<Label
|
|
@@ -111,6 +128,7 @@ function FieldLabel({ className, ...props }: React.ComponentProps<typeof Label>)
|
|
|
111
128
|
);
|
|
112
129
|
}
|
|
113
130
|
|
|
131
|
+
/** Non-interactive title text for a field, used when a label association is not needed. */
|
|
114
132
|
function FieldTitle({ className, ...props }: React.ComponentProps<'div'>) {
|
|
115
133
|
return (
|
|
116
134
|
<div
|
|
@@ -124,6 +142,7 @@ function FieldTitle({ className, ...props }: React.ComponentProps<'div'>) {
|
|
|
124
142
|
);
|
|
125
143
|
}
|
|
126
144
|
|
|
145
|
+
/** Helper text displayed below the input to provide additional guidance. */
|
|
127
146
|
function FieldDescription({ className, ...props }: React.ComponentProps<'p'>) {
|
|
128
147
|
return (
|
|
129
148
|
<p
|
|
@@ -139,6 +158,7 @@ function FieldDescription({ className, ...props }: React.ComponentProps<'p'>) {
|
|
|
139
158
|
);
|
|
140
159
|
}
|
|
141
160
|
|
|
161
|
+
/** A visual separator between fields within a FieldGroup. Optionally displays centered text. */
|
|
142
162
|
function FieldSeparator({
|
|
143
163
|
children,
|
|
144
164
|
className,
|
|
@@ -166,9 +186,14 @@ function FieldSeparator({
|
|
|
166
186
|
);
|
|
167
187
|
}
|
|
168
188
|
|
|
189
|
+
/**
|
|
190
|
+
* Displays validation error messages for a form field.
|
|
191
|
+
* Accepts either children or an errors array; deduplicates and renders as a list if multiple.
|
|
192
|
+
*/
|
|
169
193
|
function FieldError({
|
|
170
194
|
className,
|
|
171
195
|
children,
|
|
196
|
+
/** Array of error objects with message strings. Automatically deduplicated. */
|
|
172
197
|
errors,
|
|
173
198
|
...props
|
|
174
199
|
}: React.ComponentProps<'div'> & {
|