@auto-engineer/generate-react-client 1.63.0 → 1.65.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 +45 -0
- package/dist/starter/.storybook/main.ts +17 -22
- package/dist/starter/.storybook/manager-head.html +31 -31
- package/dist/starter/.storybook/manager.ts +133 -133
- package/dist/starter/.storybook/preview-head.html +12 -12
- package/dist/starter/.storybook/preview.tsx +79 -79
- package/dist/starter/biome.json +126 -0
- package/dist/starter/codegen.ts +11 -11
- package/dist/starter/components.json +27 -27
- package/dist/starter/package.json +86 -80
- package/dist/starter/public/mockServiceWorker.js +261 -261
- package/dist/starter/scripts/build-component-db.ts +17 -20
- package/dist/starter/src/App.tsx +15 -17
- package/dist/starter/src/components/ui/Accordion.stories.tsx +35 -35
- package/dist/starter/src/components/ui/Accordion.tsx +33 -33
- package/dist/starter/src/components/ui/Alert.stories.tsx +15 -15
- package/dist/starter/src/components/ui/Alert.tsx +32 -32
- package/dist/starter/src/components/ui/AlertDialog.stories.tsx +50 -50
- package/dist/starter/src/components/ui/AlertDialog.tsx +114 -115
- package/dist/starter/src/components/ui/AspectRatio.stories.tsx +20 -20
- package/dist/starter/src/components/ui/AspectRatio.tsx +1 -1
- package/dist/starter/src/components/ui/Avatar.stories.tsx +27 -27
- package/dist/starter/src/components/ui/Avatar.tsx +63 -63
- package/dist/starter/src/components/ui/Badge.stories.tsx +14 -14
- package/dist/starter/src/components/ui/Badge.tsx +27 -27
- package/dist/starter/src/components/ui/Breadcrumb.stories.tsx +38 -38
- package/dist/starter/src/components/ui/Breadcrumb.tsx +63 -62
- package/dist/starter/src/components/ui/Button.stories.tsx +55 -55
- package/dist/starter/src/components/ui/Button.tsx +49 -49
- package/dist/starter/src/components/ui/ButtonGroup.stories.tsx +17 -17
- package/dist/starter/src/components/ui/ButtonGroup.tsx +52 -53
- package/dist/starter/src/components/ui/Calendar.stories.tsx +20 -19
- package/dist/starter/src/components/ui/Calendar.tsx +142 -143
- package/dist/starter/src/components/ui/Card.stories.tsx +29 -29
- package/dist/starter/src/components/ui/Card.tsx +31 -31
- package/dist/starter/src/components/ui/Carousel.stories.tsx +41 -41
- package/dist/starter/src/components/ui/Carousel.tsx +171 -172
- package/dist/starter/src/components/ui/Chart.stories.tsx +21 -21
- package/dist/starter/src/components/ui/Chart.tsx +244 -247
- package/dist/starter/src/components/ui/Checkbox.stories.tsx +11 -11
- package/dist/starter/src/components/ui/Checkbox.tsx +18 -18
- package/dist/starter/src/components/ui/Collapsible.stories.tsx +40 -40
- package/dist/starter/src/components/ui/Collapsible.tsx +3 -3
- package/dist/starter/src/components/ui/Combobox.stories.tsx +48 -48
- package/dist/starter/src/components/ui/Combobox.tsx +204 -205
- package/dist/starter/src/components/ui/Command.stories.tsx +55 -55
- package/dist/starter/src/components/ui/Command.tsx +102 -103
- package/dist/starter/src/components/ui/ContextMenu.stories.tsx +52 -52
- package/dist/starter/src/components/ui/ContextMenu.tsx +151 -151
- package/dist/starter/src/components/ui/DesignSystem-Colors.stories.tsx +92 -92
- package/dist/starter/src/components/ui/DesignSystem-Layout.stories.tsx +139 -139
- package/dist/starter/src/components/ui/DesignSystem-Overview.stories.tsx +676 -657
- package/dist/starter/src/components/ui/DesignSystem-Typography.stories.tsx +59 -59
- package/dist/starter/src/components/ui/Dialog.stories.tsx +56 -56
- package/dist/starter/src/components/ui/Dialog.tsx +97 -98
- package/dist/starter/src/components/ui/Direction.stories.tsx +20 -20
- package/dist/starter/src/components/ui/Direction.tsx +7 -7
- package/dist/starter/src/components/ui/Drawer.stories.tsx +54 -54
- package/dist/starter/src/components/ui/Drawer.tsx +70 -70
- package/dist/starter/src/components/ui/DropdownMenu.stories.tsx +58 -58
- package/dist/starter/src/components/ui/DropdownMenu.tsx +157 -157
- package/dist/starter/src/components/ui/Empty.stories.tsx +22 -22
- package/dist/starter/src/components/ui/Empty.tsx +58 -58
- package/dist/starter/src/components/ui/Field.stories.tsx +31 -31
- package/dist/starter/src/components/ui/Field.tsx +180 -181
- package/dist/starter/src/components/ui/Form.stories.tsx +29 -29
- package/dist/starter/src/components/ui/Form.tsx +93 -96
- package/dist/starter/src/components/ui/HoverCard.stories.tsx +34 -34
- package/dist/starter/src/components/ui/HoverCard.tsx +21 -21
- package/dist/starter/src/components/ui/Input.stories.tsx +18 -18
- package/dist/starter/src/components/ui/Input.tsx +14 -14
- package/dist/starter/src/components/ui/InputGroup.stories.tsx +34 -34
- package/dist/starter/src/components/ui/InputGroup.tsx +110 -111
- package/dist/starter/src/components/ui/InputOTP.stories.tsx +28 -28
- package/dist/starter/src/components/ui/InputOTP.tsx +43 -43
- package/dist/starter/src/components/ui/Item.stories.tsx +45 -45
- package/dist/starter/src/components/ui/Item.tsx +113 -114
- package/dist/starter/src/components/ui/Kbd.stories.tsx +31 -31
- package/dist/starter/src/components/ui/Kbd.tsx +11 -11
- package/dist/starter/src/components/ui/Label.stories.tsx +62 -62
- package/dist/starter/src/components/ui/Label.tsx +26 -25
- package/dist/starter/src/components/ui/Menubar.stories.tsx +62 -62
- package/dist/starter/src/components/ui/Menubar.tsx +173 -173
- package/dist/starter/src/components/ui/NativeSelect.stories.tsx +26 -26
- package/dist/starter/src/components/ui/NativeSelect.tsx +29 -29
- package/dist/starter/src/components/ui/NavigationMenu.stories.tsx +64 -64
- package/dist/starter/src/components/ui/NavigationMenu.tsx +103 -103
- package/dist/starter/src/components/ui/Pagination.stories.tsx +61 -61
- package/dist/starter/src/components/ui/Pagination.tsx +69 -71
- package/dist/starter/src/components/ui/Popover.stories.tsx +38 -38
- package/dist/starter/src/components/ui/Popover.tsx +25 -25
- package/dist/starter/src/components/ui/Progress.stories.tsx +9 -9
- package/dist/starter/src/components/ui/Progress.tsx +14 -14
- package/dist/starter/src/components/ui/RadioGroup.stories.tsx +35 -35
- package/dist/starter/src/components/ui/RadioGroup.tsx +19 -19
- package/dist/starter/src/components/ui/Resizable.stories.tsx +54 -54
- package/dist/starter/src/components/ui/Resizable.tsx +29 -29
- package/dist/starter/src/components/ui/ScrollArea.stories.tsx +27 -27
- package/dist/starter/src/components/ui/ScrollArea.tsx +34 -34
- package/dist/starter/src/components/ui/Select.stories.tsx +43 -43
- package/dist/starter/src/components/ui/Select.tsx +120 -120
- package/dist/starter/src/components/ui/Separator.stories.tsx +27 -27
- package/dist/starter/src/components/ui/Separator.tsx +17 -17
- package/dist/starter/src/components/ui/Sheet.stories.tsx +53 -53
- package/dist/starter/src/components/ui/Sheet.tsx +69 -69
- package/dist/starter/src/components/ui/Sidebar.stories.tsx +77 -77
- package/dist/starter/src/components/ui/Sidebar.tsx +563 -564
- package/dist/starter/src/components/ui/Skeleton.stories.tsx +25 -25
- package/dist/starter/src/components/ui/Skeleton.tsx +1 -1
- package/dist/starter/src/components/ui/Slider.stories.tsx +5 -5
- package/dist/starter/src/components/ui/Slider.tsx +45 -44
- package/dist/starter/src/components/ui/Sonner.stories.tsx +32 -32
- package/dist/starter/src/components/ui/Sonner.tsx +23 -23
- package/dist/starter/src/components/ui/Spinner.stories.tsx +8 -8
- package/dist/starter/src/components/ui/Spinner.tsx +1 -1
- package/dist/starter/src/components/ui/Switch.stories.tsx +16 -17
- package/dist/starter/src/components/ui/Switch.tsx +24 -24
- package/dist/starter/src/components/ui/Table.stories.tsx +50 -50
- package/dist/starter/src/components/ui/Table.tsx +45 -45
- package/dist/starter/src/components/ui/Tabs.stories.tsx +39 -39
- package/dist/starter/src/components/ui/Tabs.tsx +47 -47
- package/dist/starter/src/components/ui/Textarea.stories.tsx +9 -9
- package/dist/starter/src/components/ui/Textarea.tsx +11 -11
- package/dist/starter/src/components/ui/Toast.stories.tsx +77 -77
- package/dist/starter/src/components/ui/Toast.tsx +75 -75
- package/dist/starter/src/components/ui/Toaster.tsx +17 -19
- package/dist/starter/src/components/ui/Toggle.stories.tsx +20 -20
- package/dist/starter/src/components/ui/Toggle.tsx +26 -26
- package/dist/starter/src/components/ui/ToggleGroup.stories.tsx +41 -41
- package/dist/starter/src/components/ui/ToggleGroup.tsx +61 -62
- package/dist/starter/src/components/ui/Tooltip.stories.tsx +26 -26
- package/dist/starter/src/components/ui/Tooltip.tsx +24 -24
- package/dist/starter/src/gql/execute.ts +1 -1
- package/dist/starter/src/gql/fragment-masking.ts +1 -1
- package/dist/starter/src/gql/graphql.ts +3 -0
- package/dist/starter/src/hooks/use-mobile.ts +11 -11
- package/dist/starter/src/hooks/use-toast.ts +135 -135
- package/dist/starter/src/index.css +105 -105
- package/dist/starter/src/lib/utils.ts +1 -1
- package/dist/starter/src/main.tsx +4 -1
- package/dist/starter/tsconfig.app.json +24 -24
- package/dist/starter/tsconfig.json +8 -8
- package/dist/starter/vite.config.ts +38 -37
- package/package.json +3 -3
|
@@ -1,168 +1,167 @@
|
|
|
1
|
-
import * as React from 'react';
|
|
2
1
|
import { cva, type VariantProps } from 'class-variance-authority';
|
|
3
2
|
import { Slot } from 'radix-ui';
|
|
4
|
-
|
|
5
|
-
import { cn } from '@/lib/utils';
|
|
3
|
+
import type * as React from 'react';
|
|
6
4
|
import { Separator } from '@/components/ui/Separator';
|
|
5
|
+
import { cn } from '@/lib/utils';
|
|
7
6
|
|
|
8
7
|
/** Container for a list of Item components. Provides list semantics for accessibility. */
|
|
9
8
|
function ItemGroup({ className, ...props }: React.ComponentProps<'div'>) {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
9
|
+
return (
|
|
10
|
+
<div role="list" data-slot="item-group" className={cn('group/item-group flex flex-col', className)} {...props} />
|
|
11
|
+
);
|
|
13
12
|
}
|
|
14
13
|
|
|
15
14
|
/** Horizontal divider between items in an ItemGroup. */
|
|
16
15
|
function ItemSeparator({ className, ...props }: React.ComponentProps<typeof Separator>) {
|
|
17
|
-
|
|
16
|
+
return <Separator data-slot="item-separator" orientation="horizontal" className={cn('my-0', className)} {...props} />;
|
|
18
17
|
}
|
|
19
18
|
|
|
20
19
|
const itemVariants = cva(
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
20
|
+
'group/item flex items-center border border-transparent text-sm rounded-md transition-colors [a]:hover:bg-accent/50 [a]:transition-colors duration-100 flex-wrap outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px]',
|
|
21
|
+
{
|
|
22
|
+
variants: {
|
|
23
|
+
variant: {
|
|
24
|
+
default: 'bg-transparent',
|
|
25
|
+
outline: 'border-border',
|
|
26
|
+
muted: 'bg-muted/50',
|
|
27
|
+
},
|
|
28
|
+
size: {
|
|
29
|
+
default: 'p-4 gap-4 ',
|
|
30
|
+
sm: 'py-3 px-4 gap-2.5',
|
|
31
|
+
},
|
|
32
|
+
},
|
|
33
|
+
defaultVariants: {
|
|
34
|
+
variant: 'default',
|
|
35
|
+
size: 'default',
|
|
36
|
+
},
|
|
37
|
+
},
|
|
39
38
|
);
|
|
40
39
|
|
|
41
40
|
/** A flexible list item for displaying structured content like notifications, settings rows, or search results. Compose with ItemMedia, ItemContent, ItemTitle, ItemDescription, and ItemActions. */
|
|
42
41
|
function Item({
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
42
|
+
className,
|
|
43
|
+
variant = 'default',
|
|
44
|
+
size = 'default',
|
|
45
|
+
asChild = false,
|
|
46
|
+
...props
|
|
48
47
|
}: React.ComponentProps<'div'> & VariantProps<typeof itemVariants> & { asChild?: boolean }) {
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
48
|
+
const Comp = asChild ? Slot.Root : 'div';
|
|
49
|
+
return (
|
|
50
|
+
<Comp
|
|
51
|
+
data-slot="item"
|
|
52
|
+
data-variant={variant}
|
|
53
|
+
data-size={size}
|
|
54
|
+
className={cn(itemVariants({ variant, size, className }))}
|
|
55
|
+
{...props}
|
|
56
|
+
/>
|
|
57
|
+
);
|
|
59
58
|
}
|
|
60
59
|
|
|
61
60
|
const itemMediaVariants = cva(
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
61
|
+
'flex shrink-0 items-center justify-center gap-2 group-has-[[data-slot=item-description]]/item:self-start [&_svg]:pointer-events-none group-has-[[data-slot=item-description]]/item:translate-y-0.5',
|
|
62
|
+
{
|
|
63
|
+
variants: {
|
|
64
|
+
variant: {
|
|
65
|
+
default: 'bg-transparent',
|
|
66
|
+
icon: "size-8 border rounded-sm bg-muted [&_svg:not([class*='size-'])]:size-4",
|
|
67
|
+
image: 'size-10 rounded-sm overflow-hidden [&_img]:size-full [&_img]:object-cover',
|
|
68
|
+
},
|
|
69
|
+
},
|
|
70
|
+
defaultVariants: {
|
|
71
|
+
variant: 'default',
|
|
72
|
+
},
|
|
73
|
+
},
|
|
75
74
|
);
|
|
76
75
|
|
|
77
76
|
/** Container for an icon, avatar, or image at the start of an Item. Use variant="icon" for styled icon backgrounds or variant="image" for thumbnails. */
|
|
78
77
|
function ItemMedia({
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
78
|
+
className,
|
|
79
|
+
variant = 'default',
|
|
80
|
+
...props
|
|
82
81
|
}: React.ComponentProps<'div'> & VariantProps<typeof itemMediaVariants>) {
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
82
|
+
return (
|
|
83
|
+
<div
|
|
84
|
+
data-slot="item-media"
|
|
85
|
+
data-variant={variant}
|
|
86
|
+
className={cn(itemMediaVariants({ variant, className }))}
|
|
87
|
+
{...props}
|
|
88
|
+
/>
|
|
89
|
+
);
|
|
91
90
|
}
|
|
92
91
|
|
|
93
92
|
/** Main content area of an Item, containing title and description. */
|
|
94
93
|
function ItemContent({ className, ...props }: React.ComponentProps<'div'>) {
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
94
|
+
return (
|
|
95
|
+
<div
|
|
96
|
+
data-slot="item-content"
|
|
97
|
+
className={cn('flex flex-1 flex-col gap-1 [&+[data-slot=item-content]]:flex-none', className)}
|
|
98
|
+
{...props}
|
|
99
|
+
/>
|
|
100
|
+
);
|
|
102
101
|
}
|
|
103
102
|
|
|
104
103
|
/** Primary text label for an Item. */
|
|
105
104
|
function ItemTitle({ className, ...props }: React.ComponentProps<'div'>) {
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
105
|
+
return (
|
|
106
|
+
<div
|
|
107
|
+
data-slot="item-title"
|
|
108
|
+
className={cn('flex w-fit items-center gap-2 text-sm leading-snug font-medium', className)}
|
|
109
|
+
{...props}
|
|
110
|
+
/>
|
|
111
|
+
);
|
|
113
112
|
}
|
|
114
113
|
|
|
115
114
|
/** Secondary text below the title, limited to 2 lines. */
|
|
116
115
|
function ItemDescription({ className, ...props }: React.ComponentProps<'p'>) {
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
116
|
+
return (
|
|
117
|
+
<p
|
|
118
|
+
data-slot="item-description"
|
|
119
|
+
className={cn(
|
|
120
|
+
'text-muted-foreground line-clamp-2 text-sm leading-normal font-normal text-balance',
|
|
121
|
+
'[&>a:hover]:text-primary [&>a]:underline [&>a]:underline-offset-4',
|
|
122
|
+
className,
|
|
123
|
+
)}
|
|
124
|
+
{...props}
|
|
125
|
+
/>
|
|
126
|
+
);
|
|
128
127
|
}
|
|
129
128
|
|
|
130
129
|
/** Container for action buttons at the end of an Item. */
|
|
131
130
|
function ItemActions({ className, ...props }: React.ComponentProps<'div'>) {
|
|
132
|
-
|
|
131
|
+
return <div data-slot="item-actions" className={cn('flex items-center gap-2', className)} {...props} />;
|
|
133
132
|
}
|
|
134
133
|
|
|
135
134
|
/** Full-width header row spanning the top of an Item, with space-between layout. */
|
|
136
135
|
function ItemHeader({ className, ...props }: React.ComponentProps<'div'>) {
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
136
|
+
return (
|
|
137
|
+
<div
|
|
138
|
+
data-slot="item-header"
|
|
139
|
+
className={cn('flex basis-full items-center justify-between gap-2', className)}
|
|
140
|
+
{...props}
|
|
141
|
+
/>
|
|
142
|
+
);
|
|
144
143
|
}
|
|
145
144
|
|
|
146
145
|
/** Full-width footer row spanning the bottom of an Item, with space-between layout. */
|
|
147
146
|
function ItemFooter({ className, ...props }: React.ComponentProps<'div'>) {
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
147
|
+
return (
|
|
148
|
+
<div
|
|
149
|
+
data-slot="item-footer"
|
|
150
|
+
className={cn('flex basis-full items-center justify-between gap-2', className)}
|
|
151
|
+
{...props}
|
|
152
|
+
/>
|
|
153
|
+
);
|
|
155
154
|
}
|
|
156
155
|
|
|
157
156
|
export {
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
157
|
+
Item,
|
|
158
|
+
ItemMedia,
|
|
159
|
+
ItemContent,
|
|
160
|
+
ItemActions,
|
|
161
|
+
ItemGroup,
|
|
162
|
+
ItemSeparator,
|
|
163
|
+
ItemTitle,
|
|
164
|
+
ItemDescription,
|
|
165
|
+
ItemHeader,
|
|
166
|
+
ItemFooter,
|
|
168
167
|
};
|
|
@@ -2,12 +2,12 @@ import type { Meta, StoryObj } from '@storybook/react-vite';
|
|
|
2
2
|
import { Kbd } from './Kbd';
|
|
3
3
|
|
|
4
4
|
const meta: Meta<typeof Kbd> = {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
5
|
+
title: 'UI Components/Kbd',
|
|
6
|
+
component: Kbd,
|
|
7
|
+
parameters: {
|
|
8
|
+
layout: 'centered',
|
|
9
|
+
},
|
|
10
|
+
tags: ['autodocs'],
|
|
11
11
|
};
|
|
12
12
|
|
|
13
13
|
export default meta;
|
|
@@ -15,45 +15,45 @@ type Story = StoryObj<typeof meta>;
|
|
|
15
15
|
|
|
16
16
|
/** Shows a single keyboard key shortcut. */
|
|
17
17
|
export const Default: Story = {
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
18
|
+
args: {
|
|
19
|
+
children: '⌘K',
|
|
20
|
+
},
|
|
21
21
|
};
|
|
22
22
|
|
|
23
23
|
/** Shows a key with a text label like "Ctrl". */
|
|
24
24
|
export const WithText: Story = {
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
25
|
+
args: {
|
|
26
|
+
children: 'Ctrl',
|
|
27
|
+
},
|
|
28
28
|
};
|
|
29
29
|
|
|
30
30
|
/** Shows a key with an arrow symbol. */
|
|
31
31
|
export const ArrowKeys: Story = {
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
32
|
+
args: {
|
|
33
|
+
children: '→',
|
|
34
|
+
},
|
|
35
35
|
};
|
|
36
36
|
|
|
37
37
|
/** Shows two keys composed together to represent a shortcut combination. */
|
|
38
38
|
export const Multiple: Story = {
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
39
|
+
render: () => (
|
|
40
|
+
<div className="flex gap-2 items-center">
|
|
41
|
+
<Kbd>⌘</Kbd>
|
|
42
|
+
<span>+</span>
|
|
43
|
+
<Kbd>K</Kbd>
|
|
44
|
+
</div>
|
|
45
|
+
),
|
|
46
46
|
};
|
|
47
47
|
|
|
48
48
|
/** Shows a three-key combination shortcut. */
|
|
49
49
|
export const Combination: Story = {
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
50
|
+
render: () => (
|
|
51
|
+
<div className="flex gap-2 items-center">
|
|
52
|
+
<Kbd>Ctrl</Kbd>
|
|
53
|
+
<span>+</span>
|
|
54
|
+
<Kbd>Shift</Kbd>
|
|
55
|
+
<span>+</span>
|
|
56
|
+
<Kbd>P</Kbd>
|
|
57
|
+
</div>
|
|
58
|
+
),
|
|
59
59
|
};
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import React from 'react';
|
|
1
|
+
import type React from 'react';
|
|
2
2
|
import { cn } from '@/lib/utils';
|
|
3
3
|
|
|
4
4
|
interface KbdProps {
|
|
5
|
-
|
|
6
|
-
|
|
5
|
+
children: React.ReactNode;
|
|
6
|
+
className?: string;
|
|
7
7
|
}
|
|
8
8
|
|
|
9
9
|
/**
|
|
@@ -11,12 +11,12 @@ interface KbdProps {
|
|
|
11
11
|
* Use to display keyboard shortcuts or key combinations in documentation and UI hints.
|
|
12
12
|
*/
|
|
13
13
|
export function Kbd({ children, className }: KbdProps) {
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
14
|
+
return (
|
|
15
|
+
<kbd
|
|
16
|
+
data-slot="kbd"
|
|
17
|
+
className={cn('border border-border rounded bg-muted px-1.5 py-0.5 text-xs font-medium', className)}
|
|
18
|
+
>
|
|
19
|
+
{children}
|
|
20
|
+
</kbd>
|
|
21
|
+
);
|
|
22
22
|
}
|
|
@@ -2,27 +2,27 @@ import type { Meta, StoryObj } from '@storybook/react-vite';
|
|
|
2
2
|
import { Label } from './Label';
|
|
3
3
|
|
|
4
4
|
const meta: Meta<typeof Label> = {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
5
|
+
title: 'UI Components/Label',
|
|
6
|
+
component: Label,
|
|
7
|
+
parameters: {
|
|
8
|
+
layout: 'centered',
|
|
9
|
+
},
|
|
10
|
+
tags: ['autodocs'],
|
|
11
|
+
argTypes: {
|
|
12
|
+
variant: {
|
|
13
|
+
control: { type: 'radio' },
|
|
14
|
+
options: ['default', 'required'],
|
|
15
|
+
},
|
|
16
|
+
required: {
|
|
17
|
+
control: { type: 'boolean' },
|
|
18
|
+
},
|
|
19
|
+
htmlFor: {
|
|
20
|
+
control: { type: 'text' },
|
|
21
|
+
},
|
|
22
|
+
children: {
|
|
23
|
+
control: { type: 'text' },
|
|
24
|
+
},
|
|
25
|
+
},
|
|
26
26
|
};
|
|
27
27
|
|
|
28
28
|
export default meta;
|
|
@@ -30,61 +30,61 @@ type Story = StoryObj<typeof meta>;
|
|
|
30
30
|
|
|
31
31
|
/** Shows a basic label associated with a form field. */
|
|
32
32
|
export const Default: Story = {
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
33
|
+
args: {
|
|
34
|
+
children: 'Email address',
|
|
35
|
+
htmlFor: 'email',
|
|
36
|
+
},
|
|
37
37
|
};
|
|
38
38
|
|
|
39
39
|
/** Shows the label with the required prop, which appends a red asterisk. */
|
|
40
40
|
export const Required: Story = {
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
41
|
+
args: {
|
|
42
|
+
children: 'Email address',
|
|
43
|
+
htmlFor: 'email',
|
|
44
|
+
required: true,
|
|
45
|
+
},
|
|
46
46
|
};
|
|
47
47
|
|
|
48
48
|
/** Shows the label using the "required" variant prop directly. */
|
|
49
49
|
export const RequiredVariant: Story = {
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
50
|
+
args: {
|
|
51
|
+
children: 'Email address',
|
|
52
|
+
htmlFor: 'email',
|
|
53
|
+
variant: 'required',
|
|
54
|
+
},
|
|
55
55
|
};
|
|
56
56
|
|
|
57
57
|
/** Shows the label paired with a text input in a form layout. */
|
|
58
58
|
export const WithForm: Story = {
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
59
|
+
render: (_args) => (
|
|
60
|
+
<div className="space-y-2">
|
|
61
|
+
<Label htmlFor="example-input" required>
|
|
62
|
+
Example Field
|
|
63
|
+
</Label>
|
|
64
|
+
<input
|
|
65
|
+
id="example-input"
|
|
66
|
+
type="text"
|
|
67
|
+
className="flex h-10 w-full rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background file:border-0 file:bg-transparent file:text-sm file:font-medium 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"
|
|
68
|
+
placeholder="Enter value..."
|
|
69
|
+
/>
|
|
70
|
+
</div>
|
|
71
|
+
),
|
|
72
72
|
};
|
|
73
73
|
|
|
74
74
|
/** Demonstrates the dimmed appearance when the associated input is disabled. */
|
|
75
75
|
export const DisabledField: Story = {
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
76
|
+
render: (_args) => (
|
|
77
|
+
<div className="space-y-2">
|
|
78
|
+
<Label htmlFor="disabled-input" required>
|
|
79
|
+
Disabled Field
|
|
80
|
+
</Label>
|
|
81
|
+
<input
|
|
82
|
+
id="disabled-input"
|
|
83
|
+
type="text"
|
|
84
|
+
disabled
|
|
85
|
+
className="flex h-10 w-full rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background file:border-0 file:bg-transparent file:text-sm file:font-medium 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"
|
|
86
|
+
placeholder="Disabled input..."
|
|
87
|
+
/>
|
|
88
|
+
</div>
|
|
89
|
+
),
|
|
90
90
|
};
|
|
@@ -1,26 +1,26 @@
|
|
|
1
|
-
import * as React from 'react';
|
|
2
1
|
import { cva, type VariantProps } from 'class-variance-authority';
|
|
2
|
+
import * as React from 'react';
|
|
3
3
|
import { cn } from '@/lib/utils';
|
|
4
4
|
|
|
5
5
|
const labelVariants = cva(
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
6
|
+
'text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70',
|
|
7
|
+
{
|
|
8
|
+
variants: {
|
|
9
|
+
variant: {
|
|
10
|
+
default: 'text-foreground',
|
|
11
|
+
required: "text-foreground after:content-['*'] after:ml-1 after:text-destructive",
|
|
12
|
+
},
|
|
13
|
+
},
|
|
14
|
+
defaultVariants: {
|
|
15
|
+
variant: 'default',
|
|
16
|
+
},
|
|
17
|
+
},
|
|
18
18
|
);
|
|
19
19
|
|
|
20
20
|
export interface LabelProps extends React.LabelHTMLAttributes<HTMLLabelElement>, VariantProps<typeof labelVariants> {
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
21
|
+
htmlFor?: string;
|
|
22
|
+
required?: boolean;
|
|
23
|
+
children?: React.ReactNode;
|
|
24
24
|
}
|
|
25
25
|
|
|
26
26
|
/**
|
|
@@ -28,16 +28,17 @@ export interface LabelProps extends React.LabelHTMLAttributes<HTMLLabelElement>,
|
|
|
28
28
|
* Supports a "required" variant that appends a red asterisk, and automatically dims when its peer input is disabled.
|
|
29
29
|
*/
|
|
30
30
|
const Label = React.forwardRef<HTMLLabelElement, LabelProps>(({ className, variant, required, ...props }, ref) => {
|
|
31
|
-
|
|
31
|
+
const effectiveVariant = required ? 'required' : variant || 'default';
|
|
32
32
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
33
|
+
return (
|
|
34
|
+
// biome-ignore lint/a11y/noLabelWithoutControl: Label is a generic component - htmlFor is provided by consumers
|
|
35
|
+
<label
|
|
36
|
+
ref={ref}
|
|
37
|
+
data-slot="label"
|
|
38
|
+
className={cn(labelVariants({ variant: effectiveVariant }), className)}
|
|
39
|
+
{...props}
|
|
40
|
+
/>
|
|
41
|
+
);
|
|
41
42
|
});
|
|
42
43
|
Label.displayName = 'Label';
|
|
43
44
|
|