@auto-engineer/generate-react-client 1.12.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (154) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/LICENSE +10 -0
  3. package/dist/src/commands/generate-react-client.d.ts +21 -0
  4. package/dist/src/commands/generate-react-client.d.ts.map +1 -0
  5. package/dist/src/commands/generate-react-client.js +62 -0
  6. package/dist/src/commands/generate-react-client.js.map +1 -0
  7. package/dist/src/copy-starter.d.ts +2 -0
  8. package/dist/src/copy-starter.d.ts.map +1 -0
  9. package/dist/src/copy-starter.js +34 -0
  10. package/dist/src/copy-starter.js.map +1 -0
  11. package/dist/src/index.d.ts +10 -0
  12. package/dist/src/index.d.ts.map +1 -0
  13. package/dist/src/index.js +4 -0
  14. package/dist/src/index.js.map +1 -0
  15. package/dist/starter/.storybook/main.ts +33 -0
  16. package/dist/starter/.storybook/preview.tsx +35 -0
  17. package/dist/starter/components.json +29 -0
  18. package/dist/starter/index.html +12 -0
  19. package/dist/starter/package.json +60 -0
  20. package/dist/starter/pnpm-lock.yaml +5236 -0
  21. package/dist/starter/public/mockServiceWorker.js +336 -0
  22. package/dist/starter/src/App.tsx +15 -0
  23. package/dist/starter/src/components/.gitkeep +0 -0
  24. package/dist/starter/src/components/ui/Accordion.stories.tsx +47 -0
  25. package/dist/starter/src/components/ui/Accordion.tsx +51 -0
  26. package/dist/starter/src/components/ui/Alert.stories.tsx +27 -0
  27. package/dist/starter/src/components/ui/Alert.tsx +49 -0
  28. package/dist/starter/src/components/ui/AlertDialog.stories.tsx +65 -0
  29. package/dist/starter/src/components/ui/AlertDialog.tsx +163 -0
  30. package/dist/starter/src/components/ui/AspectRatio.stories.tsx +33 -0
  31. package/dist/starter/src/components/ui/AspectRatio.tsx +9 -0
  32. package/dist/starter/src/components/ui/Avatar.stories.tsx +42 -0
  33. package/dist/starter/src/components/ui/Avatar.tsx +87 -0
  34. package/dist/starter/src/components/ui/Badge.stories.tsx +36 -0
  35. package/dist/starter/src/components/ui/Badge.tsx +40 -0
  36. package/dist/starter/src/components/ui/Breadcrumb.stories.tsx +52 -0
  37. package/dist/starter/src/components/ui/Breadcrumb.tsx +92 -0
  38. package/dist/starter/src/components/ui/Button.stories.tsx +92 -0
  39. package/dist/starter/src/components/ui/Button.tsx +62 -0
  40. package/dist/starter/src/components/ui/ButtonGroup.stories.tsx +30 -0
  41. package/dist/starter/src/components/ui/ButtonGroup.tsx +75 -0
  42. package/dist/starter/src/components/ui/Calendar.stories.tsx +38 -0
  43. package/dist/starter/src/components/ui/Calendar.tsx +159 -0
  44. package/dist/starter/src/components/ui/Card.stories.tsx +42 -0
  45. package/dist/starter/src/components/ui/Card.tsx +56 -0
  46. package/dist/starter/src/components/ui/Carousel.stories.tsx +54 -0
  47. package/dist/starter/src/components/ui/Carousel.tsx +216 -0
  48. package/dist/starter/src/components/ui/Chart.stories.tsx +38 -0
  49. package/dist/starter/src/components/ui/Chart.tsx +296 -0
  50. package/dist/starter/src/components/ui/Checkbox.stories.tsx +31 -0
  51. package/dist/starter/src/components/ui/Checkbox.tsx +29 -0
  52. package/dist/starter/src/components/ui/Collapsible.stories.tsx +56 -0
  53. package/dist/starter/src/components/ui/Collapsible.tsx +15 -0
  54. package/dist/starter/src/components/ui/Combobox.stories.tsx +73 -0
  55. package/dist/starter/src/components/ui/Combobox.tsx +267 -0
  56. package/dist/starter/src/components/ui/Command.stories.tsx +69 -0
  57. package/dist/starter/src/components/ui/Command.tsx +137 -0
  58. package/dist/starter/src/components/ui/ContextMenu.stories.tsx +66 -0
  59. package/dist/starter/src/components/ui/ContextMenu.tsx +211 -0
  60. package/dist/starter/src/components/ui/DesignSystem-Colors.mdx +68 -0
  61. package/dist/starter/src/components/ui/DesignSystem-Colors.stories.tsx +116 -0
  62. package/dist/starter/src/components/ui/DesignSystem-Layout.mdx +64 -0
  63. package/dist/starter/src/components/ui/DesignSystem-Layout.stories.tsx +166 -0
  64. package/dist/starter/src/components/ui/DesignSystem-Typography.mdx +31 -0
  65. package/dist/starter/src/components/ui/DesignSystem-Typography.stories.tsx +79 -0
  66. package/dist/starter/src/components/ui/Dialog.stories.tsx +72 -0
  67. package/dist/starter/src/components/ui/Dialog.tsx +136 -0
  68. package/dist/starter/src/components/ui/Direction.stories.tsx +36 -0
  69. package/dist/starter/src/components/ui/Direction.tsx +18 -0
  70. package/dist/starter/src/components/ui/Drawer.stories.tsx +68 -0
  71. package/dist/starter/src/components/ui/Drawer.tsx +106 -0
  72. package/dist/starter/src/components/ui/DropdownMenu.stories.tsx +72 -0
  73. package/dist/starter/src/components/ui/DropdownMenu.tsx +219 -0
  74. package/dist/starter/src/components/ui/Empty.stories.tsx +35 -0
  75. package/dist/starter/src/components/ui/Empty.tsx +85 -0
  76. package/dist/starter/src/components/ui/Field.stories.tsx +47 -0
  77. package/dist/starter/src/components/ui/Field.tsx +226 -0
  78. package/dist/starter/src/components/ui/Form.stories.tsx +44 -0
  79. package/dist/starter/src/components/ui/Form.tsx +136 -0
  80. package/dist/starter/src/components/ui/HoverCard.stories.tsx +47 -0
  81. package/dist/starter/src/components/ui/HoverCard.tsx +36 -0
  82. package/dist/starter/src/components/ui/Input.stories.tsx +38 -0
  83. package/dist/starter/src/components/ui/Input.tsx +21 -0
  84. package/dist/starter/src/components/ui/InputGroup.stories.tsx +50 -0
  85. package/dist/starter/src/components/ui/InputGroup.tsx +147 -0
  86. package/dist/starter/src/components/ui/InputOTP.stories.tsx +40 -0
  87. package/dist/starter/src/components/ui/InputOTP.tsx +68 -0
  88. package/dist/starter/src/components/ui/Item.stories.tsx +61 -0
  89. package/dist/starter/src/components/ui/Item.tsx +158 -0
  90. package/dist/starter/src/components/ui/Kbd.stories.tsx +54 -0
  91. package/dist/starter/src/components/ui/Kbd.tsx +18 -0
  92. package/dist/starter/src/components/ui/Label.stories.tsx +85 -0
  93. package/dist/starter/src/components/ui/Label.tsx +40 -0
  94. package/dist/starter/src/components/ui/Menubar.stories.tsx +76 -0
  95. package/dist/starter/src/components/ui/Menubar.tsx +236 -0
  96. package/dist/starter/src/components/ui/NativeSelect.stories.tsx +42 -0
  97. package/dist/starter/src/components/ui/NativeSelect.tsx +44 -0
  98. package/dist/starter/src/components/ui/NavigationMenu.stories.tsx +78 -0
  99. package/dist/starter/src/components/ui/NavigationMenu.tsx +142 -0
  100. package/dist/starter/src/components/ui/Pagination.stories.tsx +75 -0
  101. package/dist/starter/src/components/ui/Pagination.tsx +100 -0
  102. package/dist/starter/src/components/ui/Popover.stories.tsx +51 -0
  103. package/dist/starter/src/components/ui/Popover.tsx +52 -0
  104. package/dist/starter/src/components/ui/Progress.stories.tsx +28 -0
  105. package/dist/starter/src/components/ui/Progress.tsx +24 -0
  106. package/dist/starter/src/components/ui/RadioGroup.stories.tsx +48 -0
  107. package/dist/starter/src/components/ui/RadioGroup.tsx +31 -0
  108. package/dist/starter/src/components/ui/Resizable.stories.tsx +69 -0
  109. package/dist/starter/src/components/ui/Resizable.tsx +47 -0
  110. package/dist/starter/src/components/ui/ScrollArea.stories.tsx +43 -0
  111. package/dist/starter/src/components/ui/ScrollArea.tsx +46 -0
  112. package/dist/starter/src/components/ui/Select.stories.tsx +57 -0
  113. package/dist/starter/src/components/ui/Select.tsx +162 -0
  114. package/dist/starter/src/components/ui/Separator.stories.tsx +40 -0
  115. package/dist/starter/src/components/ui/Separator.tsx +26 -0
  116. package/dist/starter/src/components/ui/Sheet.stories.tsx +66 -0
  117. package/dist/starter/src/components/ui/Sheet.tsx +107 -0
  118. package/dist/starter/src/components/ui/Sidebar.stories.tsx +94 -0
  119. package/dist/starter/src/components/ui/Sidebar.tsx +675 -0
  120. package/dist/starter/src/components/ui/Skeleton.stories.tsx +38 -0
  121. package/dist/starter/src/components/ui/Skeleton.tsx +7 -0
  122. package/dist/starter/src/components/ui/Slider.stories.tsx +21 -0
  123. package/dist/starter/src/components/ui/Slider.tsx +54 -0
  124. package/dist/starter/src/components/ui/Sonner.stories.tsx +44 -0
  125. package/dist/starter/src/components/ui/Sonner.tsx +34 -0
  126. package/dist/starter/src/components/ui/Spinner.stories.tsx +23 -0
  127. package/dist/starter/src/components/ui/Spinner.tsx +9 -0
  128. package/dist/starter/src/components/ui/Switch.stories.tsx +35 -0
  129. package/dist/starter/src/components/ui/Switch.tsx +33 -0
  130. package/dist/starter/src/components/ui/Table.stories.tsx +65 -0
  131. package/dist/starter/src/components/ui/Table.tsx +75 -0
  132. package/dist/starter/src/components/ui/Tabs.stories.tsx +51 -0
  133. package/dist/starter/src/components/ui/Tabs.tsx +69 -0
  134. package/dist/starter/src/components/ui/Textarea.stories.tsx +24 -0
  135. package/dist/starter/src/components/ui/Textarea.tsx +18 -0
  136. package/dist/starter/src/components/ui/Toast.stories.tsx +112 -0
  137. package/dist/starter/src/components/ui/Toast.tsx +114 -0
  138. package/dist/starter/src/components/ui/Toaster.tsx +28 -0
  139. package/dist/starter/src/components/ui/Toggle.stories.tsx +40 -0
  140. package/dist/starter/src/components/ui/Toggle.tsx +41 -0
  141. package/dist/starter/src/components/ui/ToggleGroup.stories.tsx +58 -0
  142. package/dist/starter/src/components/ui/ToggleGroup.tsx +80 -0
  143. package/dist/starter/src/components/ui/Tooltip.stories.tsx +40 -0
  144. package/dist/starter/src/components/ui/Tooltip.tsx +42 -0
  145. package/dist/starter/src/hooks/use-mobile.ts +19 -0
  146. package/dist/starter/src/hooks/use-toast.ts +186 -0
  147. package/dist/starter/src/index.css +123 -0
  148. package/dist/starter/src/lib/utils.ts +6 -0
  149. package/dist/starter/src/main.tsx +5 -0
  150. package/dist/starter/tsconfig.app.json +25 -0
  151. package/dist/starter/tsconfig.json +4 -0
  152. package/dist/starter/vite.config.ts +16 -0
  153. package/dist/tsconfig.tsbuildinfo +1 -0
  154. package/package.json +37 -0
@@ -0,0 +1,73 @@
1
+ import * as React from 'react';
2
+ import type { Meta, StoryObj } from '@storybook/react-vite';
3
+ import {
4
+ Combobox,
5
+ ComboboxInput,
6
+ ComboboxContent,
7
+ ComboboxList,
8
+ ComboboxItem,
9
+ ComboboxEmpty,
10
+ } from '@/components/ui/Combobox';
11
+
12
+ const frameworks = [
13
+ { value: 'react', label: 'React' },
14
+ { value: 'vue', label: 'Vue' },
15
+ { value: 'angular', label: 'Angular' },
16
+ { value: 'svelte', label: 'Svelte' },
17
+ { value: 'solid', label: 'SolidJS' },
18
+ ];
19
+
20
+ function SearchableCombobox() {
21
+ const [value, setValue] = React.useState<string | null>(null);
22
+
23
+ return (
24
+ <Combobox value={value} onValueChange={setValue}>
25
+ <ComboboxInput placeholder="Search frameworks..." />
26
+ <ComboboxContent>
27
+ <ComboboxList>
28
+ {frameworks.map((fw) => (
29
+ <ComboboxItem key={fw.value} value={fw.value}>
30
+ {fw.label}
31
+ </ComboboxItem>
32
+ ))}
33
+ <ComboboxEmpty>No framework found.</ComboboxEmpty>
34
+ </ComboboxList>
35
+ </ComboboxContent>
36
+ </Combobox>
37
+ );
38
+ }
39
+
40
+ function ClearableCombobox() {
41
+ const [value, setValue] = React.useState<string | null>(null);
42
+
43
+ return (
44
+ <Combobox value={value} onValueChange={setValue}>
45
+ <ComboboxInput placeholder="Pick a framework..." showClear />
46
+ <ComboboxContent>
47
+ <ComboboxList>
48
+ {frameworks.map((fw) => (
49
+ <ComboboxItem key={fw.value} value={fw.value}>
50
+ {fw.label}
51
+ </ComboboxItem>
52
+ ))}
53
+ <ComboboxEmpty>No framework found.</ComboboxEmpty>
54
+ </ComboboxList>
55
+ </ComboboxContent>
56
+ </Combobox>
57
+ );
58
+ }
59
+
60
+ const meta: Meta = {
61
+ title: 'Combobox',
62
+ component: ComboboxInput,
63
+ };
64
+ export default meta;
65
+ type Story = StoryObj;
66
+
67
+ export const Default: Story = {
68
+ render: () => <SearchableCombobox />,
69
+ };
70
+
71
+ export const WithClear: Story = {
72
+ render: () => <ClearableCombobox />,
73
+ };
@@ -0,0 +1,267 @@
1
+ 'use client';
2
+
3
+ import * as React from 'react';
4
+ import { Combobox as ComboboxPrimitive } from '@base-ui/react';
5
+ import { CheckIcon, ChevronDownIcon, XIcon } from 'lucide-react';
6
+
7
+ import { cn } from '@/lib/utils';
8
+ import { Button } from '@/components/ui/Button';
9
+ import { InputGroup, InputGroupAddon, InputGroupButton, InputGroupInput } from '@/components/ui/InputGroup';
10
+
11
+ const Combobox = ComboboxPrimitive.Root;
12
+
13
+ function ComboboxValue({ ...props }: ComboboxPrimitive.Value.Props) {
14
+ return <ComboboxPrimitive.Value data-slot="combobox-value" {...props} />;
15
+ }
16
+
17
+ function ComboboxTrigger({ className, children, ...props }: ComboboxPrimitive.Trigger.Props) {
18
+ return (
19
+ <ComboboxPrimitive.Trigger
20
+ data-slot="combobox-trigger"
21
+ className={cn("[&_svg:not([class*='size-'])]:size-4", className)}
22
+ {...props}
23
+ >
24
+ {children}
25
+ <ChevronDownIcon data-slot="combobox-trigger-icon" className="text-muted-foreground pointer-events-none size-4" />
26
+ </ComboboxPrimitive.Trigger>
27
+ );
28
+ }
29
+
30
+ function ComboboxClear({ className, ...props }: ComboboxPrimitive.Clear.Props) {
31
+ return (
32
+ <ComboboxPrimitive.Clear
33
+ data-slot="combobox-clear"
34
+ render={<InputGroupButton variant="ghost" size="icon-xs" />}
35
+ className={cn(className)}
36
+ {...props}
37
+ >
38
+ <XIcon className="pointer-events-none" />
39
+ </ComboboxPrimitive.Clear>
40
+ );
41
+ }
42
+
43
+ function ComboboxInput({
44
+ className,
45
+ children,
46
+ disabled = false,
47
+ showTrigger = true,
48
+ showClear = false,
49
+ ...props
50
+ }: ComboboxPrimitive.Input.Props & {
51
+ showTrigger?: boolean;
52
+ showClear?: boolean;
53
+ }) {
54
+ return (
55
+ <InputGroup className={cn('w-auto', className)}>
56
+ <ComboboxPrimitive.Input render={<InputGroupInput disabled={disabled} />} {...props} />
57
+ <InputGroupAddon align="inline-end">
58
+ {showTrigger && (
59
+ <InputGroupButton
60
+ size="icon-xs"
61
+ variant="ghost"
62
+ asChild
63
+ data-slot="input-group-button"
64
+ className="group-has-data-[slot=combobox-clear]/input-group:hidden data-pressed:bg-transparent"
65
+ disabled={disabled}
66
+ >
67
+ <ComboboxTrigger />
68
+ </InputGroupButton>
69
+ )}
70
+ {showClear && <ComboboxClear disabled={disabled} />}
71
+ </InputGroupAddon>
72
+ {children}
73
+ </InputGroup>
74
+ );
75
+ }
76
+
77
+ function ComboboxContent({
78
+ className,
79
+ side = 'bottom',
80
+ sideOffset = 6,
81
+ align = 'start',
82
+ alignOffset = 0,
83
+ anchor,
84
+ ...props
85
+ }: ComboboxPrimitive.Popup.Props &
86
+ Pick<ComboboxPrimitive.Positioner.Props, 'side' | 'align' | 'sideOffset' | 'alignOffset' | 'anchor'>) {
87
+ return (
88
+ <ComboboxPrimitive.Portal>
89
+ <ComboboxPrimitive.Positioner
90
+ side={side}
91
+ sideOffset={sideOffset}
92
+ align={align}
93
+ alignOffset={alignOffset}
94
+ anchor={anchor}
95
+ className="isolate z-50"
96
+ >
97
+ <ComboboxPrimitive.Popup
98
+ data-slot="combobox-content"
99
+ data-chips={!!anchor}
100
+ className={cn(
101
+ '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',
102
+ className,
103
+ )}
104
+ {...props}
105
+ />
106
+ </ComboboxPrimitive.Positioner>
107
+ </ComboboxPrimitive.Portal>
108
+ );
109
+ }
110
+
111
+ function ComboboxList({ className, ...props }: ComboboxPrimitive.List.Props) {
112
+ return (
113
+ <ComboboxPrimitive.List
114
+ data-slot="combobox-list"
115
+ className={cn(
116
+ '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',
117
+ className,
118
+ )}
119
+ {...props}
120
+ />
121
+ );
122
+ }
123
+
124
+ function ComboboxItem({ className, children, ...props }: ComboboxPrimitive.Item.Props) {
125
+ return (
126
+ <ComboboxPrimitive.Item
127
+ data-slot="combobox-item"
128
+ className={cn(
129
+ "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",
130
+ className,
131
+ )}
132
+ {...props}
133
+ >
134
+ {children}
135
+ <ComboboxPrimitive.ItemIndicator
136
+ data-slot="combobox-item-indicator"
137
+ render={<span className="pointer-events-none absolute right-2 flex size-4 items-center justify-center" />}
138
+ >
139
+ <CheckIcon className="pointer-events-none size-4 pointer-coarse:size-5" />
140
+ </ComboboxPrimitive.ItemIndicator>
141
+ </ComboboxPrimitive.Item>
142
+ );
143
+ }
144
+
145
+ function ComboboxGroup({ className, ...props }: ComboboxPrimitive.Group.Props) {
146
+ return <ComboboxPrimitive.Group data-slot="combobox-group" className={cn(className)} {...props} />;
147
+ }
148
+
149
+ function ComboboxLabel({ className, ...props }: ComboboxPrimitive.GroupLabel.Props) {
150
+ return (
151
+ <ComboboxPrimitive.GroupLabel
152
+ data-slot="combobox-label"
153
+ className={cn(
154
+ 'text-muted-foreground px-2 py-1.5 text-xs pointer-coarse:px-3 pointer-coarse:py-2 pointer-coarse:text-sm',
155
+ className,
156
+ )}
157
+ {...props}
158
+ />
159
+ );
160
+ }
161
+
162
+ function ComboboxCollection({ ...props }: ComboboxPrimitive.Collection.Props) {
163
+ return <ComboboxPrimitive.Collection data-slot="combobox-collection" {...props} />;
164
+ }
165
+
166
+ function ComboboxEmpty({ className, ...props }: ComboboxPrimitive.Empty.Props) {
167
+ return (
168
+ <ComboboxPrimitive.Empty
169
+ data-slot="combobox-empty"
170
+ className={cn(
171
+ 'text-muted-foreground hidden w-full justify-center py-2 text-center text-sm group-data-empty/combobox-content:flex',
172
+ className,
173
+ )}
174
+ {...props}
175
+ />
176
+ );
177
+ }
178
+
179
+ function ComboboxSeparator({ className, ...props }: ComboboxPrimitive.Separator.Props) {
180
+ return (
181
+ <ComboboxPrimitive.Separator
182
+ data-slot="combobox-separator"
183
+ className={cn('bg-border -mx-1 my-1 h-px', className)}
184
+ {...props}
185
+ />
186
+ );
187
+ }
188
+
189
+ function ComboboxChips({
190
+ className,
191
+ ...props
192
+ }: React.ComponentPropsWithRef<typeof ComboboxPrimitive.Chips> & ComboboxPrimitive.Chips.Props) {
193
+ return (
194
+ <ComboboxPrimitive.Chips
195
+ data-slot="combobox-chips"
196
+ className={cn(
197
+ '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',
198
+ className,
199
+ )}
200
+ {...props}
201
+ />
202
+ );
203
+ }
204
+
205
+ function ComboboxChip({
206
+ className,
207
+ children,
208
+ showRemove = true,
209
+ ...props
210
+ }: ComboboxPrimitive.Chip.Props & {
211
+ showRemove?: boolean;
212
+ }) {
213
+ return (
214
+ <ComboboxPrimitive.Chip
215
+ data-slot="combobox-chip"
216
+ className={cn(
217
+ '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',
218
+ className,
219
+ )}
220
+ {...props}
221
+ >
222
+ {children}
223
+ {showRemove && (
224
+ <ComboboxPrimitive.ChipRemove
225
+ render={<Button variant="ghost" size="icon-xs" />}
226
+ className="-ml-1 opacity-50 hover:opacity-100"
227
+ data-slot="combobox-chip-remove"
228
+ >
229
+ <XIcon className="pointer-events-none" />
230
+ </ComboboxPrimitive.ChipRemove>
231
+ )}
232
+ </ComboboxPrimitive.Chip>
233
+ );
234
+ }
235
+
236
+ function ComboboxChipsInput({ className, children, ...props }: ComboboxPrimitive.Input.Props) {
237
+ return (
238
+ <ComboboxPrimitive.Input
239
+ data-slot="combobox-chip-input"
240
+ className={cn('min-w-16 flex-1 outline-none', className)}
241
+ {...props}
242
+ />
243
+ );
244
+ }
245
+
246
+ function useComboboxAnchor() {
247
+ return React.useRef<HTMLDivElement | null>(null);
248
+ }
249
+
250
+ export {
251
+ Combobox,
252
+ ComboboxInput,
253
+ ComboboxContent,
254
+ ComboboxList,
255
+ ComboboxItem,
256
+ ComboboxGroup,
257
+ ComboboxLabel,
258
+ ComboboxCollection,
259
+ ComboboxEmpty,
260
+ ComboboxSeparator,
261
+ ComboboxChips,
262
+ ComboboxChip,
263
+ ComboboxChipsInput,
264
+ ComboboxTrigger,
265
+ ComboboxValue,
266
+ useComboboxAnchor,
267
+ };
@@ -0,0 +1,69 @@
1
+ import type { Meta, StoryObj } from '@storybook/react-vite';
2
+ import {
3
+ Command,
4
+ CommandInput,
5
+ CommandList,
6
+ CommandEmpty,
7
+ CommandGroup,
8
+ CommandItem,
9
+ CommandSeparator,
10
+ CommandShortcut,
11
+ } from '@/components/ui/Command';
12
+ import { CalendarIcon, MailIcon, SettingsIcon, UserIcon, CreditCardIcon } from 'lucide-react';
13
+
14
+ const meta: Meta<typeof Command> = {
15
+ title: 'Command',
16
+ component: Command,
17
+ };
18
+ export default meta;
19
+ type Story = StoryObj<typeof Command>;
20
+
21
+ export const Default: Story = {
22
+ render: () => (
23
+ <Command className="rounded-lg border shadow-md md:min-w-[450px]">
24
+ <CommandInput placeholder="Type a command or search..." />
25
+ <CommandList>
26
+ <CommandEmpty>No results found.</CommandEmpty>
27
+ <CommandGroup heading="Suggestions">
28
+ <CommandItem>
29
+ <CalendarIcon />
30
+ <span>Calendar</span>
31
+ </CommandItem>
32
+ <CommandItem>
33
+ <MailIcon />
34
+ <span>Mail</span>
35
+ </CommandItem>
36
+ </CommandGroup>
37
+ <CommandSeparator />
38
+ <CommandGroup heading="Settings">
39
+ <CommandItem>
40
+ <UserIcon />
41
+ <span>Profile</span>
42
+ <CommandShortcut>Ctrl+P</CommandShortcut>
43
+ </CommandItem>
44
+ <CommandItem>
45
+ <CreditCardIcon />
46
+ <span>Billing</span>
47
+ <CommandShortcut>Ctrl+B</CommandShortcut>
48
+ </CommandItem>
49
+ <CommandItem>
50
+ <SettingsIcon />
51
+ <span>Settings</span>
52
+ <CommandShortcut>Ctrl+S</CommandShortcut>
53
+ </CommandItem>
54
+ </CommandGroup>
55
+ </CommandList>
56
+ </Command>
57
+ ),
58
+ };
59
+
60
+ export const WithNoResults: Story = {
61
+ render: () => (
62
+ <Command className="rounded-lg border shadow-md md:min-w-[450px]">
63
+ <CommandInput placeholder="Search..." />
64
+ <CommandList>
65
+ <CommandEmpty>No results found.</CommandEmpty>
66
+ </CommandList>
67
+ </Command>
68
+ ),
69
+ };
@@ -0,0 +1,137 @@
1
+ 'use client';
2
+
3
+ import * as React from 'react';
4
+ import { Command as CommandPrimitive } from 'cmdk';
5
+ import { SearchIcon } from 'lucide-react';
6
+
7
+ import { cn } from '@/lib/utils';
8
+ import { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle } from '@/components/ui/Dialog';
9
+
10
+ function Command({ className, ...props }: React.ComponentProps<typeof CommandPrimitive>) {
11
+ return (
12
+ <CommandPrimitive
13
+ data-slot="command"
14
+ className={cn(
15
+ 'bg-popover text-popover-foreground flex h-full w-full flex-col overflow-hidden rounded-md',
16
+ className,
17
+ )}
18
+ {...props}
19
+ />
20
+ );
21
+ }
22
+
23
+ function CommandDialog({
24
+ title = 'Command Palette',
25
+ description = 'Search for a command to run...',
26
+ children,
27
+ className,
28
+ showCloseButton = true,
29
+ ...props
30
+ }: React.ComponentProps<typeof Dialog> & {
31
+ title?: string;
32
+ description?: string;
33
+ className?: string;
34
+ showCloseButton?: boolean;
35
+ }) {
36
+ return (
37
+ <Dialog {...props}>
38
+ <DialogHeader className="sr-only">
39
+ <DialogTitle>{title}</DialogTitle>
40
+ <DialogDescription>{description}</DialogDescription>
41
+ </DialogHeader>
42
+ <DialogContent className={cn('overflow-hidden p-0', className)} showCloseButton={showCloseButton}>
43
+ <Command className="[&_[cmdk-group-heading]]:text-muted-foreground **:data-[slot=command-input-wrapper]:h-12 [&_[cmdk-group-heading]]:px-2 [&_[cmdk-group-heading]]:font-medium [&_[cmdk-group]]:px-2 [&_[cmdk-group]:not([hidden])_~[cmdk-group]]:pt-0 [&_[cmdk-input-wrapper]_svg]:h-5 [&_[cmdk-input-wrapper]_svg]:w-5 [&_[cmdk-input]]:h-12 [&_[cmdk-item]]:px-2 [&_[cmdk-item]]:py-3 [&_[cmdk-item]_svg]:h-5 [&_[cmdk-item]_svg]:w-5">
44
+ {children}
45
+ </Command>
46
+ </DialogContent>
47
+ </Dialog>
48
+ );
49
+ }
50
+
51
+ function CommandInput({ className, ...props }: React.ComponentProps<typeof CommandPrimitive.Input>) {
52
+ return (
53
+ <div data-slot="command-input-wrapper" className="flex h-9 items-center gap-2 border-b px-3">
54
+ <SearchIcon className="size-4 shrink-0 opacity-50" />
55
+ <CommandPrimitive.Input
56
+ data-slot="command-input"
57
+ className={cn(
58
+ 'placeholder:text-muted-foreground flex h-10 w-full rounded-md bg-transparent py-3 text-sm outline-hidden disabled:cursor-not-allowed disabled:opacity-50',
59
+ className,
60
+ )}
61
+ {...props}
62
+ />
63
+ </div>
64
+ );
65
+ }
66
+
67
+ function CommandList({ className, ...props }: React.ComponentProps<typeof CommandPrimitive.List>) {
68
+ return (
69
+ <CommandPrimitive.List
70
+ data-slot="command-list"
71
+ className={cn('max-h-[300px] scroll-py-1 overflow-x-hidden overflow-y-auto', className)}
72
+ {...props}
73
+ />
74
+ );
75
+ }
76
+
77
+ function CommandEmpty({ ...props }: React.ComponentProps<typeof CommandPrimitive.Empty>) {
78
+ return <CommandPrimitive.Empty data-slot="command-empty" className="py-6 text-center text-sm" {...props} />;
79
+ }
80
+
81
+ function CommandGroup({ className, ...props }: React.ComponentProps<typeof CommandPrimitive.Group>) {
82
+ return (
83
+ <CommandPrimitive.Group
84
+ data-slot="command-group"
85
+ className={cn(
86
+ 'text-foreground [&_[cmdk-group-heading]]:text-muted-foreground overflow-hidden p-1 [&_[cmdk-group-heading]]:px-2 [&_[cmdk-group-heading]]:py-1.5 [&_[cmdk-group-heading]]:text-xs [&_[cmdk-group-heading]]:font-medium',
87
+ className,
88
+ )}
89
+ {...props}
90
+ />
91
+ );
92
+ }
93
+
94
+ function CommandSeparator({ className, ...props }: React.ComponentProps<typeof CommandPrimitive.Separator>) {
95
+ return (
96
+ <CommandPrimitive.Separator
97
+ data-slot="command-separator"
98
+ className={cn('bg-border -mx-1 h-px', className)}
99
+ {...props}
100
+ />
101
+ );
102
+ }
103
+
104
+ function CommandItem({ className, ...props }: React.ComponentProps<typeof CommandPrimitive.Item>) {
105
+ return (
106
+ <CommandPrimitive.Item
107
+ data-slot="command-item"
108
+ className={cn(
109
+ "data-[selected=true]:bg-accent data-[selected=true]:text-accent-foreground [&_svg:not([class*='text-'])]:text-muted-foreground relative flex cursor-default items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-hidden select-none data-[disabled=true]:pointer-events-none data-[disabled=true]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
110
+ className,
111
+ )}
112
+ {...props}
113
+ />
114
+ );
115
+ }
116
+
117
+ function CommandShortcut({ className, ...props }: React.ComponentProps<'span'>) {
118
+ return (
119
+ <span
120
+ data-slot="command-shortcut"
121
+ className={cn('text-muted-foreground ml-auto text-xs tracking-widest', className)}
122
+ {...props}
123
+ />
124
+ );
125
+ }
126
+
127
+ export {
128
+ Command,
129
+ CommandDialog,
130
+ CommandInput,
131
+ CommandList,
132
+ CommandEmpty,
133
+ CommandGroup,
134
+ CommandItem,
135
+ CommandShortcut,
136
+ CommandSeparator,
137
+ };
@@ -0,0 +1,66 @@
1
+ import type { Meta, StoryObj } from '@storybook/react-vite';
2
+ import {
3
+ ContextMenu,
4
+ ContextMenuTrigger,
5
+ ContextMenuContent,
6
+ ContextMenuItem,
7
+ ContextMenuSeparator,
8
+ ContextMenuSub,
9
+ ContextMenuSubTrigger,
10
+ ContextMenuSubContent,
11
+ ContextMenuShortcut,
12
+ } from '@/components/ui/ContextMenu';
13
+
14
+ const meta: Meta<typeof ContextMenu> = {
15
+ title: 'ContextMenu',
16
+ component: ContextMenu,
17
+ };
18
+ export default meta;
19
+ type Story = StoryObj<typeof ContextMenu>;
20
+
21
+ export const Default: Story = {
22
+ render: () => (
23
+ <ContextMenu>
24
+ <ContextMenuTrigger className="flex h-[150px] w-[300px] items-center justify-center rounded-md border border-dashed text-sm">
25
+ Right click here
26
+ </ContextMenuTrigger>
27
+ <ContextMenuContent className="w-64">
28
+ <ContextMenuItem>
29
+ Back <ContextMenuShortcut>Ctrl+[</ContextMenuShortcut>
30
+ </ContextMenuItem>
31
+ <ContextMenuItem>
32
+ Forward <ContextMenuShortcut>Ctrl+]</ContextMenuShortcut>
33
+ </ContextMenuItem>
34
+ <ContextMenuItem>
35
+ Reload <ContextMenuShortcut>Ctrl+R</ContextMenuShortcut>
36
+ </ContextMenuItem>
37
+ <ContextMenuSeparator />
38
+ <ContextMenuSub>
39
+ <ContextMenuSubTrigger>More Tools</ContextMenuSubTrigger>
40
+ <ContextMenuSubContent className="w-48">
41
+ <ContextMenuItem>Save Page As...</ContextMenuItem>
42
+ <ContextMenuItem>Create Shortcut...</ContextMenuItem>
43
+ <ContextMenuItem>Developer Tools</ContextMenuItem>
44
+ </ContextMenuSubContent>
45
+ </ContextMenuSub>
46
+ <ContextMenuSeparator />
47
+ <ContextMenuItem variant="destructive">Delete</ContextMenuItem>
48
+ </ContextMenuContent>
49
+ </ContextMenu>
50
+ ),
51
+ };
52
+
53
+ export const Simple: Story = {
54
+ render: () => (
55
+ <ContextMenu>
56
+ <ContextMenuTrigger className="flex h-[150px] w-[300px] items-center justify-center rounded-md border border-dashed text-sm">
57
+ Right click here
58
+ </ContextMenuTrigger>
59
+ <ContextMenuContent>
60
+ <ContextMenuItem>Cut</ContextMenuItem>
61
+ <ContextMenuItem>Copy</ContextMenuItem>
62
+ <ContextMenuItem>Paste</ContextMenuItem>
63
+ </ContextMenuContent>
64
+ </ContextMenu>
65
+ ),
66
+ };