@auto-engineer/generate-react-client 1.64.0 → 1.66.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 +140 -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/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +3 -3
|
@@ -1,12 +1,11 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
|
|
3
|
-
import * as React from 'react';
|
|
4
3
|
import { Combobox as ComboboxPrimitive } from '@base-ui/react';
|
|
5
4
|
import { CheckIcon, ChevronDownIcon, XIcon } from 'lucide-react';
|
|
6
|
-
|
|
7
|
-
import { cn } from '@/lib/utils';
|
|
5
|
+
import * as React from 'react';
|
|
8
6
|
import { Button } from '@/components/ui/Button';
|
|
9
7
|
import { InputGroup, InputGroupAddon, InputGroupButton, InputGroupInput } from '@/components/ui/InputGroup';
|
|
8
|
+
import { cn } from '@/lib/utils';
|
|
10
9
|
|
|
11
10
|
/**
|
|
12
11
|
* An autocomplete input that combines a text field with a filterable dropdown list.
|
|
@@ -20,277 +19,277 @@ const Combobox = ComboboxPrimitive.Root;
|
|
|
20
19
|
|
|
21
20
|
/** Renders the display text for the currently selected combobox value. */
|
|
22
21
|
function ComboboxValue({ ...props }: ComboboxPrimitive.Value.Props) {
|
|
23
|
-
|
|
22
|
+
return <ComboboxPrimitive.Value data-slot="combobox-value" {...props} />;
|
|
24
23
|
}
|
|
25
24
|
|
|
26
25
|
/** Button that toggles the combobox dropdown open/closed. Renders a chevron icon automatically. */
|
|
27
26
|
function ComboboxTrigger({ className, children, ...props }: ComboboxPrimitive.Trigger.Props) {
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
27
|
+
return (
|
|
28
|
+
<ComboboxPrimitive.Trigger
|
|
29
|
+
data-slot="combobox-trigger"
|
|
30
|
+
className={cn("[&_svg:not([class*='size-'])]:size-4", className)}
|
|
31
|
+
{...props}
|
|
32
|
+
>
|
|
33
|
+
{children}
|
|
34
|
+
<ChevronDownIcon data-slot="combobox-trigger-icon" className="text-muted-foreground pointer-events-none size-4" />
|
|
35
|
+
</ComboboxPrimitive.Trigger>
|
|
36
|
+
);
|
|
38
37
|
}
|
|
39
38
|
|
|
40
39
|
/** Button that clears the current combobox selection. Renders an X icon. */
|
|
41
40
|
function ComboboxClear({ className, ...props }: ComboboxPrimitive.Clear.Props) {
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
41
|
+
return (
|
|
42
|
+
<ComboboxPrimitive.Clear
|
|
43
|
+
data-slot="combobox-clear"
|
|
44
|
+
render={<InputGroupButton variant="ghost" size="icon-xs" />}
|
|
45
|
+
className={cn(className)}
|
|
46
|
+
{...props}
|
|
47
|
+
>
|
|
48
|
+
<XIcon className="pointer-events-none" />
|
|
49
|
+
</ComboboxPrimitive.Clear>
|
|
50
|
+
);
|
|
52
51
|
}
|
|
53
52
|
|
|
54
53
|
/**
|
|
55
54
|
* Text input for filtering combobox options, wrapped in an InputGroup with optional trigger and clear buttons.
|
|
56
55
|
*/
|
|
57
56
|
function ComboboxInput({
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
57
|
+
className,
|
|
58
|
+
children,
|
|
59
|
+
disabled = false,
|
|
60
|
+
/** Whether to show the dropdown toggle chevron button. */
|
|
61
|
+
showTrigger = true,
|
|
62
|
+
/** Whether to show a clear button when a value is selected. */
|
|
63
|
+
showClear = false,
|
|
64
|
+
...props
|
|
66
65
|
}: ComboboxPrimitive.Input.Props & {
|
|
67
|
-
|
|
68
|
-
|
|
66
|
+
showTrigger?: boolean;
|
|
67
|
+
showClear?: boolean;
|
|
69
68
|
}) {
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
69
|
+
return (
|
|
70
|
+
<InputGroup className={cn('w-auto', className)}>
|
|
71
|
+
<ComboboxPrimitive.Input render={<InputGroupInput disabled={disabled} />} {...props} />
|
|
72
|
+
<InputGroupAddon align="inline-end">
|
|
73
|
+
{showTrigger && (
|
|
74
|
+
<InputGroupButton
|
|
75
|
+
size="icon-xs"
|
|
76
|
+
variant="ghost"
|
|
77
|
+
asChild
|
|
78
|
+
data-slot="input-group-button"
|
|
79
|
+
className="group-has-data-[slot=combobox-clear]/input-group:hidden data-pressed:bg-transparent"
|
|
80
|
+
disabled={disabled}
|
|
81
|
+
>
|
|
82
|
+
<ComboboxTrigger />
|
|
83
|
+
</InputGroupButton>
|
|
84
|
+
)}
|
|
85
|
+
{showClear && <ComboboxClear disabled={disabled} />}
|
|
86
|
+
</InputGroupAddon>
|
|
87
|
+
{children}
|
|
88
|
+
</InputGroup>
|
|
89
|
+
);
|
|
91
90
|
}
|
|
92
91
|
|
|
93
92
|
/** Positioned popover that contains the combobox dropdown list. Portals to the document body. */
|
|
94
93
|
function ComboboxContent({
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
94
|
+
className,
|
|
95
|
+
side = 'bottom',
|
|
96
|
+
sideOffset = 6,
|
|
97
|
+
align = 'start',
|
|
98
|
+
alignOffset = 0,
|
|
99
|
+
anchor,
|
|
100
|
+
...props
|
|
102
101
|
}: ComboboxPrimitive.Popup.Props &
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
102
|
+
Pick<ComboboxPrimitive.Positioner.Props, 'side' | 'align' | 'sideOffset' | 'alignOffset' | 'anchor'>) {
|
|
103
|
+
return (
|
|
104
|
+
<ComboboxPrimitive.Portal>
|
|
105
|
+
<ComboboxPrimitive.Positioner
|
|
106
|
+
side={side}
|
|
107
|
+
sideOffset={sideOffset}
|
|
108
|
+
align={align}
|
|
109
|
+
alignOffset={alignOffset}
|
|
110
|
+
anchor={anchor}
|
|
111
|
+
className="isolate z-50"
|
|
112
|
+
>
|
|
113
|
+
<ComboboxPrimitive.Popup
|
|
114
|
+
data-slot="combobox-content"
|
|
115
|
+
data-chips={!!anchor}
|
|
116
|
+
className={cn(
|
|
117
|
+
'bg-popover text-popover-foreground data-open:animate-in data-closed:animate-out data-closed:fade-out-0 data-open:fade-in-0 data-closed:zoom-out-95 data-open:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 ring-foreground/10 *:data-[slot=input-group]:bg-input/30 *:data-[slot=input-group]:border-input/30 group/combobox-content relative max-h-96 w-(--anchor-width) max-w-(--available-width) min-w-[calc(var(--anchor-width)+--spacing(7))] origin-(--transform-origin) overflow-hidden rounded-md shadow-md ring-1 duration-100 data-[chips=true]:min-w-(--anchor-width) *:data-[slot=input-group]:m-1 *:data-[slot=input-group]:mb-0 *:data-[slot=input-group]:h-8 *:data-[slot=input-group]:shadow-none',
|
|
118
|
+
className,
|
|
119
|
+
)}
|
|
120
|
+
{...props}
|
|
121
|
+
/>
|
|
122
|
+
</ComboboxPrimitive.Positioner>
|
|
123
|
+
</ComboboxPrimitive.Portal>
|
|
124
|
+
);
|
|
126
125
|
}
|
|
127
126
|
|
|
128
127
|
/** Scrollable container for combobox option items. */
|
|
129
128
|
function ComboboxList({ className, ...props }: ComboboxPrimitive.List.Props) {
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
129
|
+
return (
|
|
130
|
+
<ComboboxPrimitive.List
|
|
131
|
+
data-slot="combobox-list"
|
|
132
|
+
className={cn(
|
|
133
|
+
'max-h-[min(calc(--spacing(96)---spacing(9)),calc(var(--available-height)---spacing(9)))] scroll-py-1 overflow-y-auto p-1 data-empty:p-0',
|
|
134
|
+
className,
|
|
135
|
+
)}
|
|
136
|
+
{...props}
|
|
137
|
+
/>
|
|
138
|
+
);
|
|
140
139
|
}
|
|
141
140
|
|
|
142
141
|
/** A selectable option within the combobox list. Shows a check indicator when selected. */
|
|
143
142
|
function ComboboxItem({ className, children, ...props }: ComboboxPrimitive.Item.Props) {
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
143
|
+
return (
|
|
144
|
+
<ComboboxPrimitive.Item
|
|
145
|
+
data-slot="combobox-item"
|
|
146
|
+
className={cn(
|
|
147
|
+
"data-highlighted:bg-accent data-highlighted:text-accent-foreground relative flex w-full cursor-default items-center gap-2 rounded-sm py-1.5 pr-8 pl-2 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
|
|
148
|
+
className,
|
|
149
|
+
)}
|
|
150
|
+
{...props}
|
|
151
|
+
>
|
|
152
|
+
{children}
|
|
153
|
+
<ComboboxPrimitive.ItemIndicator
|
|
154
|
+
data-slot="combobox-item-indicator"
|
|
155
|
+
render={<span className="pointer-events-none absolute right-2 flex size-4 items-center justify-center" />}
|
|
156
|
+
>
|
|
157
|
+
<CheckIcon className="pointer-events-none size-4 pointer-coarse:size-5" />
|
|
158
|
+
</ComboboxPrimitive.ItemIndicator>
|
|
159
|
+
</ComboboxPrimitive.Item>
|
|
160
|
+
);
|
|
162
161
|
}
|
|
163
162
|
|
|
164
163
|
/** Groups related combobox items together, typically with a ComboboxLabel. */
|
|
165
164
|
function ComboboxGroup({ className, ...props }: ComboboxPrimitive.Group.Props) {
|
|
166
|
-
|
|
165
|
+
return <ComboboxPrimitive.Group data-slot="combobox-group" className={cn(className)} {...props} />;
|
|
167
166
|
}
|
|
168
167
|
|
|
169
168
|
/** Non-interactive label heading for a ComboboxGroup. */
|
|
170
169
|
function ComboboxLabel({ className, ...props }: ComboboxPrimitive.GroupLabel.Props) {
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
170
|
+
return (
|
|
171
|
+
<ComboboxPrimitive.GroupLabel
|
|
172
|
+
data-slot="combobox-label"
|
|
173
|
+
className={cn(
|
|
174
|
+
'text-muted-foreground px-2 py-1.5 text-xs pointer-coarse:px-3 pointer-coarse:py-2 pointer-coarse:text-sm',
|
|
175
|
+
className,
|
|
176
|
+
)}
|
|
177
|
+
{...props}
|
|
178
|
+
/>
|
|
179
|
+
);
|
|
181
180
|
}
|
|
182
181
|
|
|
183
182
|
/** Provides the collection of items for virtual scrolling or dynamic option sets. */
|
|
184
183
|
function ComboboxCollection({ ...props }: ComboboxPrimitive.Collection.Props) {
|
|
185
|
-
|
|
184
|
+
return <ComboboxPrimitive.Collection data-slot="combobox-collection" {...props} />;
|
|
186
185
|
}
|
|
187
186
|
|
|
188
187
|
/** Displayed when no combobox items match the current filter query. */
|
|
189
188
|
function ComboboxEmpty({ className, ...props }: ComboboxPrimitive.Empty.Props) {
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
189
|
+
return (
|
|
190
|
+
<ComboboxPrimitive.Empty
|
|
191
|
+
data-slot="combobox-empty"
|
|
192
|
+
className={cn(
|
|
193
|
+
'text-muted-foreground hidden w-full justify-center py-2 text-center text-sm group-data-empty/combobox-content:flex',
|
|
194
|
+
className,
|
|
195
|
+
)}
|
|
196
|
+
{...props}
|
|
197
|
+
/>
|
|
198
|
+
);
|
|
200
199
|
}
|
|
201
200
|
|
|
202
201
|
/** Visual divider between groups of combobox items. */
|
|
203
202
|
function ComboboxSeparator({ className, ...props }: ComboboxPrimitive.Separator.Props) {
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
203
|
+
return (
|
|
204
|
+
<ComboboxPrimitive.Separator
|
|
205
|
+
data-slot="combobox-separator"
|
|
206
|
+
className={cn('bg-border -mx-1 my-1 h-px', className)}
|
|
207
|
+
{...props}
|
|
208
|
+
/>
|
|
209
|
+
);
|
|
211
210
|
}
|
|
212
211
|
|
|
213
212
|
/** Container for multi-select chips, styled as a form input. Use with ComboboxChip and ComboboxChipsInput. */
|
|
214
213
|
function ComboboxChips({
|
|
215
|
-
|
|
216
|
-
|
|
214
|
+
className,
|
|
215
|
+
...props
|
|
217
216
|
}: React.ComponentPropsWithRef<typeof ComboboxPrimitive.Chips> & ComboboxPrimitive.Chips.Props) {
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
217
|
+
return (
|
|
218
|
+
<ComboboxPrimitive.Chips
|
|
219
|
+
data-slot="combobox-chips"
|
|
220
|
+
className={cn(
|
|
221
|
+
'dark:bg-input/30 border-input focus-within:border-ring focus-within:ring-ring/50 has-aria-invalid:ring-destructive/20 dark:has-aria-invalid:ring-destructive/40 has-aria-invalid:border-destructive dark:has-aria-invalid:border-destructive/50 flex min-h-9 flex-wrap items-center gap-1.5 rounded-md border bg-transparent bg-clip-padding px-2.5 py-1.5 text-sm shadow-xs transition-[color,box-shadow] focus-within:ring-[3px] has-aria-invalid:ring-[3px] has-data-[slot=combobox-chip]:px-1.5',
|
|
222
|
+
className,
|
|
223
|
+
)}
|
|
224
|
+
{...props}
|
|
225
|
+
/>
|
|
226
|
+
);
|
|
228
227
|
}
|
|
229
228
|
|
|
230
229
|
/** Individual chip representing a selected value in multi-select mode. Optionally includes a remove button. */
|
|
231
230
|
function ComboboxChip({
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
231
|
+
className,
|
|
232
|
+
children,
|
|
233
|
+
/** Whether to show the remove (X) button on the chip. */
|
|
234
|
+
showRemove = true,
|
|
235
|
+
...props
|
|
237
236
|
}: ComboboxPrimitive.Chip.Props & {
|
|
238
|
-
|
|
237
|
+
showRemove?: boolean;
|
|
239
238
|
}) {
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
239
|
+
return (
|
|
240
|
+
<ComboboxPrimitive.Chip
|
|
241
|
+
data-slot="combobox-chip"
|
|
242
|
+
className={cn(
|
|
243
|
+
'bg-muted text-foreground flex h-[calc(--spacing(5.5))] w-fit items-center justify-center gap-1 rounded-sm px-1.5 text-xs font-medium whitespace-nowrap has-disabled:pointer-events-none has-disabled:cursor-not-allowed has-disabled:opacity-50 has-data-[slot=combobox-chip-remove]:pr-0',
|
|
244
|
+
className,
|
|
245
|
+
)}
|
|
246
|
+
{...props}
|
|
247
|
+
>
|
|
248
|
+
{children}
|
|
249
|
+
{showRemove && (
|
|
250
|
+
<ComboboxPrimitive.ChipRemove
|
|
251
|
+
render={<Button variant="ghost" size="icon-xs" />}
|
|
252
|
+
className="-ml-1 opacity-50 hover:opacity-100"
|
|
253
|
+
data-slot="combobox-chip-remove"
|
|
254
|
+
>
|
|
255
|
+
<XIcon className="pointer-events-none" />
|
|
256
|
+
</ComboboxPrimitive.ChipRemove>
|
|
257
|
+
)}
|
|
258
|
+
</ComboboxPrimitive.Chip>
|
|
259
|
+
);
|
|
261
260
|
}
|
|
262
261
|
|
|
263
262
|
/** Inline text input rendered alongside chips for multi-select filtering. */
|
|
264
263
|
function ComboboxChipsInput({ className, children, ...props }: ComboboxPrimitive.Input.Props) {
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
264
|
+
return (
|
|
265
|
+
<ComboboxPrimitive.Input
|
|
266
|
+
data-slot="combobox-chip-input"
|
|
267
|
+
className={cn('min-w-16 flex-1 outline-none', className)}
|
|
268
|
+
{...props}
|
|
269
|
+
/>
|
|
270
|
+
);
|
|
272
271
|
}
|
|
273
272
|
|
|
274
273
|
/** Returns a ref to use as the anchor element for positioning the combobox popup (e.g. for chips layout). */
|
|
275
274
|
function useComboboxAnchor() {
|
|
276
|
-
|
|
275
|
+
return React.useRef<HTMLDivElement | null>(null);
|
|
277
276
|
}
|
|
278
277
|
|
|
279
278
|
export {
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
279
|
+
Combobox,
|
|
280
|
+
ComboboxInput,
|
|
281
|
+
ComboboxContent,
|
|
282
|
+
ComboboxList,
|
|
283
|
+
ComboboxItem,
|
|
284
|
+
ComboboxGroup,
|
|
285
|
+
ComboboxLabel,
|
|
286
|
+
ComboboxCollection,
|
|
287
|
+
ComboboxEmpty,
|
|
288
|
+
ComboboxSeparator,
|
|
289
|
+
ComboboxChips,
|
|
290
|
+
ComboboxChip,
|
|
291
|
+
ComboboxChipsInput,
|
|
292
|
+
ComboboxTrigger,
|
|
293
|
+
ComboboxValue,
|
|
294
|
+
useComboboxAnchor,
|
|
296
295
|
};
|
|
@@ -1,71 +1,71 @@
|
|
|
1
1
|
import type { Meta, StoryObj } from '@storybook/react-vite';
|
|
2
|
+
import { CalendarIcon, CreditCardIcon, MailIcon, SettingsIcon, UserIcon } from 'lucide-react';
|
|
2
3
|
import {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
4
|
+
Command,
|
|
5
|
+
CommandEmpty,
|
|
6
|
+
CommandGroup,
|
|
7
|
+
CommandInput,
|
|
8
|
+
CommandItem,
|
|
9
|
+
CommandList,
|
|
10
|
+
CommandSeparator,
|
|
11
|
+
CommandShortcut,
|
|
11
12
|
} from '@/components/ui/Command';
|
|
12
|
-
import { CalendarIcon, MailIcon, SettingsIcon, UserIcon, CreditCardIcon } from 'lucide-react';
|
|
13
13
|
|
|
14
14
|
const meta: Meta<typeof Command> = {
|
|
15
|
-
|
|
16
|
-
|
|
15
|
+
title: 'UI Components/Command',
|
|
16
|
+
component: Command,
|
|
17
17
|
};
|
|
18
18
|
export default meta;
|
|
19
19
|
type Story = StoryObj<typeof Command>;
|
|
20
20
|
|
|
21
21
|
/** Shows the command palette with grouped items, icons, keyboard shortcuts, and a search input. */
|
|
22
22
|
export const Default: Story = {
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
23
|
+
render: () => (
|
|
24
|
+
<Command className="rounded-lg border shadow-md md:min-w-[450px]">
|
|
25
|
+
<CommandInput placeholder="Type a command or search..." />
|
|
26
|
+
<CommandList>
|
|
27
|
+
<CommandEmpty>No results found.</CommandEmpty>
|
|
28
|
+
<CommandGroup heading="Suggestions">
|
|
29
|
+
<CommandItem>
|
|
30
|
+
<CalendarIcon />
|
|
31
|
+
<span>Calendar</span>
|
|
32
|
+
</CommandItem>
|
|
33
|
+
<CommandItem>
|
|
34
|
+
<MailIcon />
|
|
35
|
+
<span>Mail</span>
|
|
36
|
+
</CommandItem>
|
|
37
|
+
</CommandGroup>
|
|
38
|
+
<CommandSeparator />
|
|
39
|
+
<CommandGroup heading="Settings">
|
|
40
|
+
<CommandItem>
|
|
41
|
+
<UserIcon />
|
|
42
|
+
<span>Profile</span>
|
|
43
|
+
<CommandShortcut>Ctrl+P</CommandShortcut>
|
|
44
|
+
</CommandItem>
|
|
45
|
+
<CommandItem>
|
|
46
|
+
<CreditCardIcon />
|
|
47
|
+
<span>Billing</span>
|
|
48
|
+
<CommandShortcut>Ctrl+B</CommandShortcut>
|
|
49
|
+
</CommandItem>
|
|
50
|
+
<CommandItem>
|
|
51
|
+
<SettingsIcon />
|
|
52
|
+
<span>Settings</span>
|
|
53
|
+
<CommandShortcut>Ctrl+S</CommandShortcut>
|
|
54
|
+
</CommandItem>
|
|
55
|
+
</CommandGroup>
|
|
56
|
+
</CommandList>
|
|
57
|
+
</Command>
|
|
58
|
+
),
|
|
59
59
|
};
|
|
60
60
|
|
|
61
61
|
/** Shows the empty state when no items match the search query. */
|
|
62
62
|
export const WithNoResults: Story = {
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
63
|
+
render: () => (
|
|
64
|
+
<Command className="rounded-lg border shadow-md md:min-w-[450px]">
|
|
65
|
+
<CommandInput placeholder="Search..." />
|
|
66
|
+
<CommandList>
|
|
67
|
+
<CommandEmpty>No results found.</CommandEmpty>
|
|
68
|
+
</CommandList>
|
|
69
|
+
</Command>
|
|
70
|
+
),
|
|
71
71
|
};
|