create-auto-app 1.34.0 → 1.36.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.
Files changed (156) hide show
  1. package/package.json +2 -2
  2. package/templates/typical/.gitignore +1 -1
  3. package/templates/typical/auto.config.ts +85 -80
  4. package/templates/typical/client/.gitignore +0 -4
  5. package/templates/typical/client/.storybook/main.ts +0 -66
  6. package/templates/typical/client/.storybook/manager-head.html +0 -154
  7. package/templates/typical/client/.storybook/manager.ts +0 -164
  8. package/templates/typical/client/.storybook/preview-head.html +0 -31
  9. package/templates/typical/client/.storybook/preview.tsx +0 -120
  10. package/templates/typical/client/codegen.ts +0 -17
  11. package/templates/typical/client/components.json +0 -29
  12. package/templates/typical/client/index.html +0 -12
  13. package/templates/typical/client/package.json +0 -69
  14. package/templates/typical/client/pnpm-lock.yaml +0 -7868
  15. package/templates/typical/client/public/blank.svg +0 -1
  16. package/templates/typical/client/public/mockServiceWorker.js +0 -336
  17. package/templates/typical/client/src/App.tsx +0 -29
  18. package/templates/typical/client/src/components/.gitkeep +0 -0
  19. package/templates/typical/client/src/components/ui/Accordion.stories.tsx +0 -49
  20. package/templates/typical/client/src/components/ui/Accordion.tsx +0 -55
  21. package/templates/typical/client/src/components/ui/Alert.stories.tsx +0 -29
  22. package/templates/typical/client/src/components/ui/Alert.tsx +0 -56
  23. package/templates/typical/client/src/components/ui/AlertDialog.stories.tsx +0 -67
  24. package/templates/typical/client/src/components/ui/AlertDialog.tsx +0 -178
  25. package/templates/typical/client/src/components/ui/AspectRatio.stories.tsx +0 -35
  26. package/templates/typical/client/src/components/ui/AspectRatio.tsx +0 -13
  27. package/templates/typical/client/src/components/ui/Avatar.stories.tsx +0 -45
  28. package/templates/typical/client/src/components/ui/Avatar.tsx +0 -98
  29. package/templates/typical/client/src/components/ui/Badge.stories.tsx +0 -41
  30. package/templates/typical/client/src/components/ui/Badge.tsx +0 -45
  31. package/templates/typical/client/src/components/ui/Breadcrumb.stories.tsx +0 -54
  32. package/templates/typical/client/src/components/ui/Breadcrumb.tsx +0 -104
  33. package/templates/typical/client/src/components/ui/Button.stories.tsx +0 -102
  34. package/templates/typical/client/src/components/ui/Button.tsx +0 -67
  35. package/templates/typical/client/src/components/ui/ButtonGroup.stories.tsx +0 -32
  36. package/templates/typical/client/src/components/ui/ButtonGroup.tsx +0 -81
  37. package/templates/typical/client/src/components/ui/Calendar.stories.tsx +0 -40
  38. package/templates/typical/client/src/components/ui/Calendar.tsx +0 -165
  39. package/templates/typical/client/src/components/ui/Card.stories.tsx +0 -44
  40. package/templates/typical/client/src/components/ui/Card.tsx +0 -66
  41. package/templates/typical/client/src/components/ui/Carousel.stories.tsx +0 -56
  42. package/templates/typical/client/src/components/ui/Carousel.tsx +0 -225
  43. package/templates/typical/client/src/components/ui/Chart.stories.tsx +0 -39
  44. package/templates/typical/client/src/components/ui/Chart.tsx +0 -305
  45. package/templates/typical/client/src/components/ui/Checkbox.stories.tsx +0 -35
  46. package/templates/typical/client/src/components/ui/Checkbox.tsx +0 -30
  47. package/templates/typical/client/src/components/ui/Collapsible.stories.tsx +0 -58
  48. package/templates/typical/client/src/components/ui/Collapsible.tsx +0 -18
  49. package/templates/typical/client/src/components/ui/Combobox.stories.tsx +0 -75
  50. package/templates/typical/client/src/components/ui/Combobox.tsx +0 -296
  51. package/templates/typical/client/src/components/ui/Command.stories.tsx +0 -71
  52. package/templates/typical/client/src/components/ui/Command.tsx +0 -157
  53. package/templates/typical/client/src/components/ui/ContextMenu.stories.tsx +0 -68
  54. package/templates/typical/client/src/components/ui/ContextMenu.tsx +0 -231
  55. package/templates/typical/client/src/components/ui/DesignSystem-Colors.mdx +0 -68
  56. package/templates/typical/client/src/components/ui/DesignSystem-Colors.stories.tsx +0 -117
  57. package/templates/typical/client/src/components/ui/DesignSystem-Layout.mdx +0 -64
  58. package/templates/typical/client/src/components/ui/DesignSystem-Layout.stories.tsx +0 -167
  59. package/templates/typical/client/src/components/ui/DesignSystem-Overview.stories.tsx +0 -748
  60. package/templates/typical/client/src/components/ui/DesignSystem-Typography.mdx +0 -31
  61. package/templates/typical/client/src/components/ui/DesignSystem-Typography.stories.tsx +0 -80
  62. package/templates/typical/client/src/components/ui/Dialog.stories.tsx +0 -74
  63. package/templates/typical/client/src/components/ui/Dialog.tsx +0 -154
  64. package/templates/typical/client/src/components/ui/Direction.stories.tsx +0 -38
  65. package/templates/typical/client/src/components/ui/Direction.tsx +0 -24
  66. package/templates/typical/client/src/components/ui/Drawer.stories.tsx +0 -70
  67. package/templates/typical/client/src/components/ui/Drawer.tsx +0 -124
  68. package/templates/typical/client/src/components/ui/DropdownMenu.stories.tsx +0 -74
  69. package/templates/typical/client/src/components/ui/DropdownMenu.tsx +0 -239
  70. package/templates/typical/client/src/components/ui/Empty.stories.tsx +0 -37
  71. package/templates/typical/client/src/components/ui/Empty.tsx +0 -98
  72. package/templates/typical/client/src/components/ui/Field.stories.tsx +0 -50
  73. package/templates/typical/client/src/components/ui/Field.tsx +0 -251
  74. package/templates/typical/client/src/components/ui/Form.stories.tsx +0 -45
  75. package/templates/typical/client/src/components/ui/Form.tsx +0 -148
  76. package/templates/typical/client/src/components/ui/HoverCard.stories.tsx +0 -49
  77. package/templates/typical/client/src/components/ui/HoverCard.tsx +0 -39
  78. package/templates/typical/client/src/components/ui/Input.stories.tsx +0 -42
  79. package/templates/typical/client/src/components/ui/Input.tsx +0 -22
  80. package/templates/typical/client/src/components/ui/InputGroup.stories.tsx +0 -53
  81. package/templates/typical/client/src/components/ui/InputGroup.tsx +0 -153
  82. package/templates/typical/client/src/components/ui/InputOTP.stories.tsx +0 -42
  83. package/templates/typical/client/src/components/ui/InputOTP.tsx +0 -72
  84. package/templates/typical/client/src/components/ui/Item.stories.tsx +0 -64
  85. package/templates/typical/client/src/components/ui/Item.tsx +0 -168
  86. package/templates/typical/client/src/components/ui/Kbd.stories.tsx +0 -59
  87. package/templates/typical/client/src/components/ui/Kbd.tsx +0 -22
  88. package/templates/typical/client/src/components/ui/Label.stories.tsx +0 -90
  89. package/templates/typical/client/src/components/ui/Label.tsx +0 -44
  90. package/templates/typical/client/src/components/ui/Menubar.stories.tsx +0 -78
  91. package/templates/typical/client/src/components/ui/Menubar.tsx +0 -251
  92. package/templates/typical/client/src/components/ui/NativeSelect.stories.tsx +0 -45
  93. package/templates/typical/client/src/components/ui/NativeSelect.tsx +0 -50
  94. package/templates/typical/client/src/components/ui/NavigationMenu.stories.tsx +0 -80
  95. package/templates/typical/client/src/components/ui/NavigationMenu.tsx +0 -152
  96. package/templates/typical/client/src/components/ui/Pagination.stories.tsx +0 -77
  97. package/templates/typical/client/src/components/ui/Pagination.tsx +0 -108
  98. package/templates/typical/client/src/components/ui/Popover.stories.tsx +0 -53
  99. package/templates/typical/client/src/components/ui/Popover.tsx +0 -57
  100. package/templates/typical/client/src/components/ui/Progress.stories.tsx +0 -32
  101. package/templates/typical/client/src/components/ui/Progress.tsx +0 -25
  102. package/templates/typical/client/src/components/ui/RadioGroup.stories.tsx +0 -50
  103. package/templates/typical/client/src/components/ui/RadioGroup.tsx +0 -36
  104. package/templates/typical/client/src/components/ui/Resizable.stories.tsx +0 -72
  105. package/templates/typical/client/src/components/ui/Resizable.tsx +0 -54
  106. package/templates/typical/client/src/components/ui/ScrollArea.stories.tsx +0 -45
  107. package/templates/typical/client/src/components/ui/ScrollArea.tsx +0 -51
  108. package/templates/typical/client/src/components/ui/Select.stories.tsx +0 -59
  109. package/templates/typical/client/src/components/ui/Select.tsx +0 -171
  110. package/templates/typical/client/src/components/ui/Separator.stories.tsx +0 -42
  111. package/templates/typical/client/src/components/ui/Separator.tsx +0 -27
  112. package/templates/typical/client/src/components/ui/Sheet.stories.tsx +0 -68
  113. package/templates/typical/client/src/components/ui/Sheet.tsx +0 -115
  114. package/templates/typical/client/src/components/ui/Sidebar.stories.tsx +0 -96
  115. package/templates/typical/client/src/components/ui/Sidebar.tsx +0 -695
  116. package/templates/typical/client/src/components/ui/Skeleton.stories.tsx +0 -40
  117. package/templates/typical/client/src/components/ui/Skeleton.tsx +0 -11
  118. package/templates/typical/client/src/components/ui/Slider.stories.tsx +0 -24
  119. package/templates/typical/client/src/components/ui/Slider.tsx +0 -55
  120. package/templates/typical/client/src/components/ui/Sonner.stories.tsx +0 -45
  121. package/templates/typical/client/src/components/ui/Sonner.tsx +0 -38
  122. package/templates/typical/client/src/components/ui/Spinner.stories.tsx +0 -26
  123. package/templates/typical/client/src/components/ui/Spinner.tsx +0 -13
  124. package/templates/typical/client/src/components/ui/Switch.stories.tsx +0 -39
  125. package/templates/typical/client/src/components/ui/Switch.tsx +0 -35
  126. package/templates/typical/client/src/components/ui/Table.stories.tsx +0 -67
  127. package/templates/typical/client/src/components/ui/Table.tsx +0 -86
  128. package/templates/typical/client/src/components/ui/Tabs.stories.tsx +0 -53
  129. package/templates/typical/client/src/components/ui/Tabs.tsx +0 -75
  130. package/templates/typical/client/src/components/ui/Textarea.stories.tsx +0 -27
  131. package/templates/typical/client/src/components/ui/Textarea.tsx +0 -22
  132. package/templates/typical/client/src/components/ui/Toast.stories.tsx +0 -116
  133. package/templates/typical/client/src/components/ui/Toast.tsx +0 -123
  134. package/templates/typical/client/src/components/ui/Toaster.tsx +0 -32
  135. package/templates/typical/client/src/components/ui/Toggle.stories.tsx +0 -44
  136. package/templates/typical/client/src/components/ui/Toggle.tsx +0 -42
  137. package/templates/typical/client/src/components/ui/ToggleGroup.stories.tsx +0 -61
  138. package/templates/typical/client/src/components/ui/ToggleGroup.tsx +0 -83
  139. package/templates/typical/client/src/components/ui/Tooltip.stories.tsx +0 -42
  140. package/templates/typical/client/src/components/ui/Tooltip.tsx +0 -48
  141. package/templates/typical/client/src/gql/execute.ts +0 -11
  142. package/templates/typical/client/src/gql/fragment-masking.ts +0 -83
  143. package/templates/typical/client/src/gql/gql.ts +0 -9
  144. package/templates/typical/client/src/gql/graphql.ts +0 -182
  145. package/templates/typical/client/src/gql/index.ts +0 -2
  146. package/templates/typical/client/src/graphql/mutations.ts +0 -0
  147. package/templates/typical/client/src/graphql/queries.ts +0 -0
  148. package/templates/typical/client/src/hooks/.gitkeep +0 -0
  149. package/templates/typical/client/src/hooks/use-mobile.ts +0 -19
  150. package/templates/typical/client/src/hooks/use-toast.ts +0 -186
  151. package/templates/typical/client/src/index.css +0 -121
  152. package/templates/typical/client/src/lib/utils.ts +0 -6
  153. package/templates/typical/client/src/main.tsx +0 -5
  154. package/templates/typical/client/tsconfig.app.json +0 -26
  155. package/templates/typical/client/tsconfig.json +0 -10
  156. package/templates/typical/client/vite.config.ts +0 -50
@@ -1,18 +0,0 @@
1
- import { Collapsible as CollapsiblePrimitive } from 'radix-ui';
2
-
3
- /** A disclosure widget that toggles content visibility. Compose with CollapsibleTrigger and CollapsibleContent. */
4
- function Collapsible({ ...props }: React.ComponentProps<typeof CollapsiblePrimitive.Root>) {
5
- return <CollapsiblePrimitive.Root data-slot="collapsible" {...props} />;
6
- }
7
-
8
- /** The interactive element that toggles the CollapsibleContent open or closed. */
9
- function CollapsibleTrigger({ ...props }: React.ComponentProps<typeof CollapsiblePrimitive.CollapsibleTrigger>) {
10
- return <CollapsiblePrimitive.CollapsibleTrigger data-slot="collapsible-trigger" {...props} />;
11
- }
12
-
13
- /** The content region that is shown or hidden when the Collapsible is toggled. */
14
- function CollapsibleContent({ ...props }: React.ComponentProps<typeof CollapsiblePrimitive.CollapsibleContent>) {
15
- return <CollapsiblePrimitive.CollapsibleContent data-slot="collapsible-content" {...props} />;
16
- }
17
-
18
- export { Collapsible, CollapsibleTrigger, CollapsibleContent };
@@ -1,75 +0,0 @@
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: 'UI Components/Combobox',
62
- component: ComboboxInput,
63
- };
64
- export default meta;
65
- type Story = StoryObj;
66
-
67
- /** Shows a searchable combobox with type-ahead filtering of framework options. */
68
- export const Default: Story = {
69
- render: () => <SearchableCombobox />,
70
- };
71
-
72
- /** Demonstrates the combobox with a clear button that resets the selection. */
73
- export const WithClear: Story = {
74
- render: () => <ClearableCombobox />,
75
- };
@@ -1,296 +0,0 @@
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
- /**
12
- * An autocomplete input that combines a text field with a filterable dropdown list.
13
- * Built on Base UI Combobox primitive. Supports single and multi-select with chips,
14
- * custom filtering, grouped options, and clearable selections.
15
- *
16
- * Compose with ComboboxInput, ComboboxContent, ComboboxList, and ComboboxItem.
17
- * For multi-select, use ComboboxChips, ComboboxChip, and ComboboxChipsInput.
18
- */
19
- const Combobox = ComboboxPrimitive.Root;
20
-
21
- /** Renders the display text for the currently selected combobox value. */
22
- function ComboboxValue({ ...props }: ComboboxPrimitive.Value.Props) {
23
- return <ComboboxPrimitive.Value data-slot="combobox-value" {...props} />;
24
- }
25
-
26
- /** Button that toggles the combobox dropdown open/closed. Renders a chevron icon automatically. */
27
- function ComboboxTrigger({ className, children, ...props }: ComboboxPrimitive.Trigger.Props) {
28
- return (
29
- <ComboboxPrimitive.Trigger
30
- data-slot="combobox-trigger"
31
- className={cn("[&_svg:not([class*='size-'])]:size-4", className)}
32
- {...props}
33
- >
34
- {children}
35
- <ChevronDownIcon data-slot="combobox-trigger-icon" className="text-muted-foreground pointer-events-none size-4" />
36
- </ComboboxPrimitive.Trigger>
37
- );
38
- }
39
-
40
- /** Button that clears the current combobox selection. Renders an X icon. */
41
- function ComboboxClear({ className, ...props }: ComboboxPrimitive.Clear.Props) {
42
- return (
43
- <ComboboxPrimitive.Clear
44
- data-slot="combobox-clear"
45
- render={<InputGroupButton variant="ghost" size="icon-xs" />}
46
- className={cn(className)}
47
- {...props}
48
- >
49
- <XIcon className="pointer-events-none" />
50
- </ComboboxPrimitive.Clear>
51
- );
52
- }
53
-
54
- /**
55
- * Text input for filtering combobox options, wrapped in an InputGroup with optional trigger and clear buttons.
56
- */
57
- function ComboboxInput({
58
- className,
59
- children,
60
- disabled = false,
61
- /** Whether to show the dropdown toggle chevron button. */
62
- showTrigger = true,
63
- /** Whether to show a clear button when a value is selected. */
64
- showClear = false,
65
- ...props
66
- }: ComboboxPrimitive.Input.Props & {
67
- showTrigger?: boolean;
68
- showClear?: boolean;
69
- }) {
70
- return (
71
- <InputGroup className={cn('w-auto', className)}>
72
- <ComboboxPrimitive.Input render={<InputGroupInput disabled={disabled} />} {...props} />
73
- <InputGroupAddon align="inline-end">
74
- {showTrigger && (
75
- <InputGroupButton
76
- size="icon-xs"
77
- variant="ghost"
78
- asChild
79
- data-slot="input-group-button"
80
- className="group-has-data-[slot=combobox-clear]/input-group:hidden data-pressed:bg-transparent"
81
- disabled={disabled}
82
- >
83
- <ComboboxTrigger />
84
- </InputGroupButton>
85
- )}
86
- {showClear && <ComboboxClear disabled={disabled} />}
87
- </InputGroupAddon>
88
- {children}
89
- </InputGroup>
90
- );
91
- }
92
-
93
- /** Positioned popover that contains the combobox dropdown list. Portals to the document body. */
94
- function ComboboxContent({
95
- className,
96
- side = 'bottom',
97
- sideOffset = 6,
98
- align = 'start',
99
- alignOffset = 0,
100
- anchor,
101
- ...props
102
- }: ComboboxPrimitive.Popup.Props &
103
- Pick<ComboboxPrimitive.Positioner.Props, 'side' | 'align' | 'sideOffset' | 'alignOffset' | 'anchor'>) {
104
- return (
105
- <ComboboxPrimitive.Portal>
106
- <ComboboxPrimitive.Positioner
107
- side={side}
108
- sideOffset={sideOffset}
109
- align={align}
110
- alignOffset={alignOffset}
111
- anchor={anchor}
112
- className="isolate z-50"
113
- >
114
- <ComboboxPrimitive.Popup
115
- data-slot="combobox-content"
116
- data-chips={!!anchor}
117
- className={cn(
118
- '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',
119
- className,
120
- )}
121
- {...props}
122
- />
123
- </ComboboxPrimitive.Positioner>
124
- </ComboboxPrimitive.Portal>
125
- );
126
- }
127
-
128
- /** Scrollable container for combobox option items. */
129
- function ComboboxList({ className, ...props }: ComboboxPrimitive.List.Props) {
130
- return (
131
- <ComboboxPrimitive.List
132
- data-slot="combobox-list"
133
- className={cn(
134
- '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',
135
- className,
136
- )}
137
- {...props}
138
- />
139
- );
140
- }
141
-
142
- /** A selectable option within the combobox list. Shows a check indicator when selected. */
143
- function ComboboxItem({ className, children, ...props }: ComboboxPrimitive.Item.Props) {
144
- return (
145
- <ComboboxPrimitive.Item
146
- data-slot="combobox-item"
147
- className={cn(
148
- "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",
149
- className,
150
- )}
151
- {...props}
152
- >
153
- {children}
154
- <ComboboxPrimitive.ItemIndicator
155
- data-slot="combobox-item-indicator"
156
- render={<span className="pointer-events-none absolute right-2 flex size-4 items-center justify-center" />}
157
- >
158
- <CheckIcon className="pointer-events-none size-4 pointer-coarse:size-5" />
159
- </ComboboxPrimitive.ItemIndicator>
160
- </ComboboxPrimitive.Item>
161
- );
162
- }
163
-
164
- /** Groups related combobox items together, typically with a ComboboxLabel. */
165
- function ComboboxGroup({ className, ...props }: ComboboxPrimitive.Group.Props) {
166
- return <ComboboxPrimitive.Group data-slot="combobox-group" className={cn(className)} {...props} />;
167
- }
168
-
169
- /** Non-interactive label heading for a ComboboxGroup. */
170
- function ComboboxLabel({ className, ...props }: ComboboxPrimitive.GroupLabel.Props) {
171
- return (
172
- <ComboboxPrimitive.GroupLabel
173
- data-slot="combobox-label"
174
- className={cn(
175
- 'text-muted-foreground px-2 py-1.5 text-xs pointer-coarse:px-3 pointer-coarse:py-2 pointer-coarse:text-sm',
176
- className,
177
- )}
178
- {...props}
179
- />
180
- );
181
- }
182
-
183
- /** Provides the collection of items for virtual scrolling or dynamic option sets. */
184
- function ComboboxCollection({ ...props }: ComboboxPrimitive.Collection.Props) {
185
- return <ComboboxPrimitive.Collection data-slot="combobox-collection" {...props} />;
186
- }
187
-
188
- /** Displayed when no combobox items match the current filter query. */
189
- function ComboboxEmpty({ className, ...props }: ComboboxPrimitive.Empty.Props) {
190
- return (
191
- <ComboboxPrimitive.Empty
192
- data-slot="combobox-empty"
193
- className={cn(
194
- 'text-muted-foreground hidden w-full justify-center py-2 text-center text-sm group-data-empty/combobox-content:flex',
195
- className,
196
- )}
197
- {...props}
198
- />
199
- );
200
- }
201
-
202
- /** Visual divider between groups of combobox items. */
203
- function ComboboxSeparator({ className, ...props }: ComboboxPrimitive.Separator.Props) {
204
- return (
205
- <ComboboxPrimitive.Separator
206
- data-slot="combobox-separator"
207
- className={cn('bg-border -mx-1 my-1 h-px', className)}
208
- {...props}
209
- />
210
- );
211
- }
212
-
213
- /** Container for multi-select chips, styled as a form input. Use with ComboboxChip and ComboboxChipsInput. */
214
- function ComboboxChips({
215
- className,
216
- ...props
217
- }: React.ComponentPropsWithRef<typeof ComboboxPrimitive.Chips> & ComboboxPrimitive.Chips.Props) {
218
- return (
219
- <ComboboxPrimitive.Chips
220
- data-slot="combobox-chips"
221
- className={cn(
222
- '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',
223
- className,
224
- )}
225
- {...props}
226
- />
227
- );
228
- }
229
-
230
- /** Individual chip representing a selected value in multi-select mode. Optionally includes a remove button. */
231
- function ComboboxChip({
232
- className,
233
- children,
234
- /** Whether to show the remove (X) button on the chip. */
235
- showRemove = true,
236
- ...props
237
- }: ComboboxPrimitive.Chip.Props & {
238
- showRemove?: boolean;
239
- }) {
240
- return (
241
- <ComboboxPrimitive.Chip
242
- data-slot="combobox-chip"
243
- className={cn(
244
- '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',
245
- className,
246
- )}
247
- {...props}
248
- >
249
- {children}
250
- {showRemove && (
251
- <ComboboxPrimitive.ChipRemove
252
- render={<Button variant="ghost" size="icon-xs" />}
253
- className="-ml-1 opacity-50 hover:opacity-100"
254
- data-slot="combobox-chip-remove"
255
- >
256
- <XIcon className="pointer-events-none" />
257
- </ComboboxPrimitive.ChipRemove>
258
- )}
259
- </ComboboxPrimitive.Chip>
260
- );
261
- }
262
-
263
- /** Inline text input rendered alongside chips for multi-select filtering. */
264
- function ComboboxChipsInput({ className, children, ...props }: ComboboxPrimitive.Input.Props) {
265
- return (
266
- <ComboboxPrimitive.Input
267
- data-slot="combobox-chip-input"
268
- className={cn('min-w-16 flex-1 outline-none', className)}
269
- {...props}
270
- />
271
- );
272
- }
273
-
274
- /** Returns a ref to use as the anchor element for positioning the combobox popup (e.g. for chips layout). */
275
- function useComboboxAnchor() {
276
- return React.useRef<HTMLDivElement | null>(null);
277
- }
278
-
279
- export {
280
- Combobox,
281
- ComboboxInput,
282
- ComboboxContent,
283
- ComboboxList,
284
- ComboboxItem,
285
- ComboboxGroup,
286
- ComboboxLabel,
287
- ComboboxCollection,
288
- ComboboxEmpty,
289
- ComboboxSeparator,
290
- ComboboxChips,
291
- ComboboxChip,
292
- ComboboxChipsInput,
293
- ComboboxTrigger,
294
- ComboboxValue,
295
- useComboboxAnchor,
296
- };
@@ -1,71 +0,0 @@
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: 'UI Components/Command',
16
- component: Command,
17
- };
18
- export default meta;
19
- type Story = StoryObj<typeof Command>;
20
-
21
- /** Shows the command palette with grouped items, icons, keyboard shortcuts, and a search input. */
22
- export const Default: Story = {
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
- };
60
-
61
- /** Shows the empty state when no items match the search query. */
62
- export const WithNoResults: Story = {
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
- };
@@ -1,157 +0,0 @@
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
- /**
11
- * A command palette / search interface for filtering and selecting from a list of actions or items.
12
- * Built on cmdk with keyboard navigation, grouping, and search filtering.
13
- *
14
- * Compose with CommandInput, CommandList, CommandGroup, CommandItem, and CommandEmpty.
15
- */
16
- function Command({ className, ...props }: React.ComponentProps<typeof CommandPrimitive>) {
17
- return (
18
- <CommandPrimitive
19
- data-slot="command"
20
- className={cn(
21
- 'bg-popover text-popover-foreground flex h-full w-full flex-col overflow-hidden rounded-md',
22
- className,
23
- )}
24
- {...props}
25
- />
26
- );
27
- }
28
-
29
- /**
30
- * Wraps Command in a modal Dialog for use as a keyboard-triggered command palette (e.g. Ctrl+K).
31
- * Provides accessible title and description via screen-reader-only DialogHeader.
32
- */
33
- function CommandDialog({
34
- /** Accessible title for screen readers. */
35
- title = 'Command Palette',
36
- /** Accessible description for screen readers. */
37
- description = 'Search for a command to run...',
38
- children,
39
- className,
40
- /** Whether to show the X close button. */
41
- showCloseButton = true,
42
- ...props
43
- }: React.ComponentProps<typeof Dialog> & {
44
- title?: string;
45
- description?: string;
46
- className?: string;
47
- showCloseButton?: boolean;
48
- }) {
49
- return (
50
- <Dialog {...props}>
51
- <DialogHeader className="sr-only">
52
- <DialogTitle>{title}</DialogTitle>
53
- <DialogDescription>{description}</DialogDescription>
54
- </DialogHeader>
55
- <DialogContent className={cn('overflow-hidden p-0', className)} showCloseButton={showCloseButton}>
56
- <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">
57
- {children}
58
- </Command>
59
- </DialogContent>
60
- </Dialog>
61
- );
62
- }
63
-
64
- /** Search input with a built-in search icon for filtering command items. */
65
- function CommandInput({ className, ...props }: React.ComponentProps<typeof CommandPrimitive.Input>) {
66
- return (
67
- <div data-slot="command-input-wrapper" className="flex h-9 items-center gap-2 border-b px-3">
68
- <SearchIcon className="size-4 shrink-0 opacity-50" />
69
- <CommandPrimitive.Input
70
- data-slot="command-input"
71
- className={cn(
72
- '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',
73
- className,
74
- )}
75
- {...props}
76
- />
77
- </div>
78
- );
79
- }
80
-
81
- /** Scrollable container for command results. */
82
- function CommandList({ className, ...props }: React.ComponentProps<typeof CommandPrimitive.List>) {
83
- return (
84
- <CommandPrimitive.List
85
- data-slot="command-list"
86
- className={cn('max-h-[300px] scroll-py-1 overflow-x-hidden overflow-y-auto', className)}
87
- {...props}
88
- />
89
- );
90
- }
91
-
92
- /** Displayed when no command items match the search query. */
93
- function CommandEmpty({ ...props }: React.ComponentProps<typeof CommandPrimitive.Empty>) {
94
- return <CommandPrimitive.Empty data-slot="command-empty" className="py-6 text-center text-sm" {...props} />;
95
- }
96
-
97
- /** Groups related command items under a heading label. */
98
- function CommandGroup({ className, ...props }: React.ComponentProps<typeof CommandPrimitive.Group>) {
99
- return (
100
- <CommandPrimitive.Group
101
- data-slot="command-group"
102
- className={cn(
103
- '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',
104
- className,
105
- )}
106
- {...props}
107
- />
108
- );
109
- }
110
-
111
- /** Visual divider between command groups. */
112
- function CommandSeparator({ className, ...props }: React.ComponentProps<typeof CommandPrimitive.Separator>) {
113
- return (
114
- <CommandPrimitive.Separator
115
- data-slot="command-separator"
116
- className={cn('bg-border -mx-1 h-px', className)}
117
- {...props}
118
- />
119
- );
120
- }
121
-
122
- /** A selectable action or item within a command list. Supports icons and keyboard shortcuts via CommandShortcut. */
123
- function CommandItem({ className, ...props }: React.ComponentProps<typeof CommandPrimitive.Item>) {
124
- return (
125
- <CommandPrimitive.Item
126
- data-slot="command-item"
127
- className={cn(
128
- "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",
129
- className,
130
- )}
131
- {...props}
132
- />
133
- );
134
- }
135
-
136
- /** Displays a keyboard shortcut hint aligned to the right side of a CommandItem. */
137
- function CommandShortcut({ className, ...props }: React.ComponentProps<'span'>) {
138
- return (
139
- <span
140
- data-slot="command-shortcut"
141
- className={cn('text-muted-foreground ml-auto text-xs tracking-widest', className)}
142
- {...props}
143
- />
144
- );
145
- }
146
-
147
- export {
148
- Command,
149
- CommandDialog,
150
- CommandInput,
151
- CommandList,
152
- CommandEmpty,
153
- CommandGroup,
154
- CommandItem,
155
- CommandShortcut,
156
- CommandSeparator,
157
- };
@@ -1,68 +0,0 @@
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: 'UI Components/ContextMenu',
16
- component: ContextMenu,
17
- };
18
- export default meta;
19
- type Story = StoryObj<typeof ContextMenu>;
20
-
21
- /** Shows a context menu with shortcuts, submenus, separators, and a destructive action. */
22
- export const Default: Story = {
23
- render: () => (
24
- <ContextMenu>
25
- <ContextMenuTrigger className="flex h-[150px] w-[300px] items-center justify-center rounded-md border border-dashed text-sm">
26
- Right click here
27
- </ContextMenuTrigger>
28
- <ContextMenuContent className="w-64">
29
- <ContextMenuItem>
30
- Back <ContextMenuShortcut>Ctrl+[</ContextMenuShortcut>
31
- </ContextMenuItem>
32
- <ContextMenuItem>
33
- Forward <ContextMenuShortcut>Ctrl+]</ContextMenuShortcut>
34
- </ContextMenuItem>
35
- <ContextMenuItem>
36
- Reload <ContextMenuShortcut>Ctrl+R</ContextMenuShortcut>
37
- </ContextMenuItem>
38
- <ContextMenuSeparator />
39
- <ContextMenuSub>
40
- <ContextMenuSubTrigger>More Tools</ContextMenuSubTrigger>
41
- <ContextMenuSubContent className="w-48">
42
- <ContextMenuItem>Save Page As...</ContextMenuItem>
43
- <ContextMenuItem>Create Shortcut...</ContextMenuItem>
44
- <ContextMenuItem>Developer Tools</ContextMenuItem>
45
- </ContextMenuSubContent>
46
- </ContextMenuSub>
47
- <ContextMenuSeparator />
48
- <ContextMenuItem variant="destructive">Delete</ContextMenuItem>
49
- </ContextMenuContent>
50
- </ContextMenu>
51
- ),
52
- };
53
-
54
- /** Shows a minimal context menu with basic cut/copy/paste actions. */
55
- export const Simple: Story = {
56
- render: () => (
57
- <ContextMenu>
58
- <ContextMenuTrigger className="flex h-[150px] w-[300px] items-center justify-center rounded-md border border-dashed text-sm">
59
- Right click here
60
- </ContextMenuTrigger>
61
- <ContextMenuContent>
62
- <ContextMenuItem>Cut</ContextMenuItem>
63
- <ContextMenuItem>Copy</ContextMenuItem>
64
- <ContextMenuItem>Paste</ContextMenuItem>
65
- </ContextMenuContent>
66
- </ContextMenu>
67
- ),
68
- };