@auto-engineer/generate-react-client 1.64.0 → 1.65.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (144) hide show
  1. package/CHANGELOG.md +21 -0
  2. package/dist/starter/.storybook/main.ts +17 -22
  3. package/dist/starter/.storybook/manager-head.html +31 -31
  4. package/dist/starter/.storybook/manager.ts +133 -133
  5. package/dist/starter/.storybook/preview-head.html +12 -12
  6. package/dist/starter/.storybook/preview.tsx +79 -79
  7. package/dist/starter/biome.json +126 -0
  8. package/dist/starter/codegen.ts +11 -11
  9. package/dist/starter/components.json +27 -27
  10. package/dist/starter/package.json +86 -80
  11. package/dist/starter/public/mockServiceWorker.js +261 -261
  12. package/dist/starter/scripts/build-component-db.ts +17 -20
  13. package/dist/starter/src/App.tsx +15 -17
  14. package/dist/starter/src/components/ui/Accordion.stories.tsx +35 -35
  15. package/dist/starter/src/components/ui/Accordion.tsx +33 -33
  16. package/dist/starter/src/components/ui/Alert.stories.tsx +15 -15
  17. package/dist/starter/src/components/ui/Alert.tsx +32 -32
  18. package/dist/starter/src/components/ui/AlertDialog.stories.tsx +50 -50
  19. package/dist/starter/src/components/ui/AlertDialog.tsx +114 -115
  20. package/dist/starter/src/components/ui/AspectRatio.stories.tsx +20 -20
  21. package/dist/starter/src/components/ui/AspectRatio.tsx +1 -1
  22. package/dist/starter/src/components/ui/Avatar.stories.tsx +27 -27
  23. package/dist/starter/src/components/ui/Avatar.tsx +63 -63
  24. package/dist/starter/src/components/ui/Badge.stories.tsx +14 -14
  25. package/dist/starter/src/components/ui/Badge.tsx +27 -27
  26. package/dist/starter/src/components/ui/Breadcrumb.stories.tsx +38 -38
  27. package/dist/starter/src/components/ui/Breadcrumb.tsx +63 -62
  28. package/dist/starter/src/components/ui/Button.stories.tsx +55 -55
  29. package/dist/starter/src/components/ui/Button.tsx +49 -49
  30. package/dist/starter/src/components/ui/ButtonGroup.stories.tsx +17 -17
  31. package/dist/starter/src/components/ui/ButtonGroup.tsx +52 -53
  32. package/dist/starter/src/components/ui/Calendar.stories.tsx +20 -19
  33. package/dist/starter/src/components/ui/Calendar.tsx +142 -143
  34. package/dist/starter/src/components/ui/Card.stories.tsx +29 -29
  35. package/dist/starter/src/components/ui/Card.tsx +31 -31
  36. package/dist/starter/src/components/ui/Carousel.stories.tsx +41 -41
  37. package/dist/starter/src/components/ui/Carousel.tsx +171 -172
  38. package/dist/starter/src/components/ui/Chart.stories.tsx +21 -21
  39. package/dist/starter/src/components/ui/Chart.tsx +244 -247
  40. package/dist/starter/src/components/ui/Checkbox.stories.tsx +11 -11
  41. package/dist/starter/src/components/ui/Checkbox.tsx +18 -18
  42. package/dist/starter/src/components/ui/Collapsible.stories.tsx +40 -40
  43. package/dist/starter/src/components/ui/Collapsible.tsx +3 -3
  44. package/dist/starter/src/components/ui/Combobox.stories.tsx +48 -48
  45. package/dist/starter/src/components/ui/Combobox.tsx +204 -205
  46. package/dist/starter/src/components/ui/Command.stories.tsx +55 -55
  47. package/dist/starter/src/components/ui/Command.tsx +102 -103
  48. package/dist/starter/src/components/ui/ContextMenu.stories.tsx +52 -52
  49. package/dist/starter/src/components/ui/ContextMenu.tsx +151 -151
  50. package/dist/starter/src/components/ui/DesignSystem-Colors.stories.tsx +92 -92
  51. package/dist/starter/src/components/ui/DesignSystem-Layout.stories.tsx +139 -139
  52. package/dist/starter/src/components/ui/DesignSystem-Overview.stories.tsx +676 -657
  53. package/dist/starter/src/components/ui/DesignSystem-Typography.stories.tsx +59 -59
  54. package/dist/starter/src/components/ui/Dialog.stories.tsx +56 -56
  55. package/dist/starter/src/components/ui/Dialog.tsx +97 -98
  56. package/dist/starter/src/components/ui/Direction.stories.tsx +20 -20
  57. package/dist/starter/src/components/ui/Direction.tsx +7 -7
  58. package/dist/starter/src/components/ui/Drawer.stories.tsx +54 -54
  59. package/dist/starter/src/components/ui/Drawer.tsx +70 -70
  60. package/dist/starter/src/components/ui/DropdownMenu.stories.tsx +58 -58
  61. package/dist/starter/src/components/ui/DropdownMenu.tsx +157 -157
  62. package/dist/starter/src/components/ui/Empty.stories.tsx +22 -22
  63. package/dist/starter/src/components/ui/Empty.tsx +58 -58
  64. package/dist/starter/src/components/ui/Field.stories.tsx +31 -31
  65. package/dist/starter/src/components/ui/Field.tsx +180 -181
  66. package/dist/starter/src/components/ui/Form.stories.tsx +29 -29
  67. package/dist/starter/src/components/ui/Form.tsx +93 -96
  68. package/dist/starter/src/components/ui/HoverCard.stories.tsx +34 -34
  69. package/dist/starter/src/components/ui/HoverCard.tsx +21 -21
  70. package/dist/starter/src/components/ui/Input.stories.tsx +18 -18
  71. package/dist/starter/src/components/ui/Input.tsx +14 -14
  72. package/dist/starter/src/components/ui/InputGroup.stories.tsx +34 -34
  73. package/dist/starter/src/components/ui/InputGroup.tsx +110 -111
  74. package/dist/starter/src/components/ui/InputOTP.stories.tsx +28 -28
  75. package/dist/starter/src/components/ui/InputOTP.tsx +43 -43
  76. package/dist/starter/src/components/ui/Item.stories.tsx +45 -45
  77. package/dist/starter/src/components/ui/Item.tsx +113 -114
  78. package/dist/starter/src/components/ui/Kbd.stories.tsx +31 -31
  79. package/dist/starter/src/components/ui/Kbd.tsx +11 -11
  80. package/dist/starter/src/components/ui/Label.stories.tsx +62 -62
  81. package/dist/starter/src/components/ui/Label.tsx +26 -25
  82. package/dist/starter/src/components/ui/Menubar.stories.tsx +62 -62
  83. package/dist/starter/src/components/ui/Menubar.tsx +173 -173
  84. package/dist/starter/src/components/ui/NativeSelect.stories.tsx +26 -26
  85. package/dist/starter/src/components/ui/NativeSelect.tsx +29 -29
  86. package/dist/starter/src/components/ui/NavigationMenu.stories.tsx +64 -64
  87. package/dist/starter/src/components/ui/NavigationMenu.tsx +103 -103
  88. package/dist/starter/src/components/ui/Pagination.stories.tsx +61 -61
  89. package/dist/starter/src/components/ui/Pagination.tsx +69 -71
  90. package/dist/starter/src/components/ui/Popover.stories.tsx +38 -38
  91. package/dist/starter/src/components/ui/Popover.tsx +25 -25
  92. package/dist/starter/src/components/ui/Progress.stories.tsx +9 -9
  93. package/dist/starter/src/components/ui/Progress.tsx +14 -14
  94. package/dist/starter/src/components/ui/RadioGroup.stories.tsx +35 -35
  95. package/dist/starter/src/components/ui/RadioGroup.tsx +19 -19
  96. package/dist/starter/src/components/ui/Resizable.stories.tsx +54 -54
  97. package/dist/starter/src/components/ui/Resizable.tsx +29 -29
  98. package/dist/starter/src/components/ui/ScrollArea.stories.tsx +27 -27
  99. package/dist/starter/src/components/ui/ScrollArea.tsx +34 -34
  100. package/dist/starter/src/components/ui/Select.stories.tsx +43 -43
  101. package/dist/starter/src/components/ui/Select.tsx +120 -120
  102. package/dist/starter/src/components/ui/Separator.stories.tsx +27 -27
  103. package/dist/starter/src/components/ui/Separator.tsx +17 -17
  104. package/dist/starter/src/components/ui/Sheet.stories.tsx +53 -53
  105. package/dist/starter/src/components/ui/Sheet.tsx +69 -69
  106. package/dist/starter/src/components/ui/Sidebar.stories.tsx +77 -77
  107. package/dist/starter/src/components/ui/Sidebar.tsx +563 -564
  108. package/dist/starter/src/components/ui/Skeleton.stories.tsx +25 -25
  109. package/dist/starter/src/components/ui/Skeleton.tsx +1 -1
  110. package/dist/starter/src/components/ui/Slider.stories.tsx +5 -5
  111. package/dist/starter/src/components/ui/Slider.tsx +45 -44
  112. package/dist/starter/src/components/ui/Sonner.stories.tsx +32 -32
  113. package/dist/starter/src/components/ui/Sonner.tsx +23 -23
  114. package/dist/starter/src/components/ui/Spinner.stories.tsx +8 -8
  115. package/dist/starter/src/components/ui/Spinner.tsx +1 -1
  116. package/dist/starter/src/components/ui/Switch.stories.tsx +16 -17
  117. package/dist/starter/src/components/ui/Switch.tsx +24 -24
  118. package/dist/starter/src/components/ui/Table.stories.tsx +50 -50
  119. package/dist/starter/src/components/ui/Table.tsx +45 -45
  120. package/dist/starter/src/components/ui/Tabs.stories.tsx +39 -39
  121. package/dist/starter/src/components/ui/Tabs.tsx +47 -47
  122. package/dist/starter/src/components/ui/Textarea.stories.tsx +9 -9
  123. package/dist/starter/src/components/ui/Textarea.tsx +11 -11
  124. package/dist/starter/src/components/ui/Toast.stories.tsx +77 -77
  125. package/dist/starter/src/components/ui/Toast.tsx +75 -75
  126. package/dist/starter/src/components/ui/Toaster.tsx +17 -19
  127. package/dist/starter/src/components/ui/Toggle.stories.tsx +20 -20
  128. package/dist/starter/src/components/ui/Toggle.tsx +26 -26
  129. package/dist/starter/src/components/ui/ToggleGroup.stories.tsx +41 -41
  130. package/dist/starter/src/components/ui/ToggleGroup.tsx +61 -62
  131. package/dist/starter/src/components/ui/Tooltip.stories.tsx +26 -26
  132. package/dist/starter/src/components/ui/Tooltip.tsx +24 -24
  133. package/dist/starter/src/gql/execute.ts +1 -1
  134. package/dist/starter/src/gql/fragment-masking.ts +1 -1
  135. package/dist/starter/src/gql/graphql.ts +3 -0
  136. package/dist/starter/src/hooks/use-mobile.ts +11 -11
  137. package/dist/starter/src/hooks/use-toast.ts +135 -135
  138. package/dist/starter/src/index.css +105 -105
  139. package/dist/starter/src/lib/utils.ts +1 -1
  140. package/dist/starter/src/main.tsx +4 -1
  141. package/dist/starter/tsconfig.app.json +24 -24
  142. package/dist/starter/tsconfig.json +8 -8
  143. package/dist/starter/vite.config.ts +38 -37
  144. package/package.json +3 -3
@@ -1,50 +1,50 @@
1
1
  'use client';
2
2
 
3
- import * as React from 'react';
4
3
  import { CheckIcon, ChevronRightIcon, CircleIcon } from 'lucide-react';
5
4
  import { DropdownMenu as DropdownMenuPrimitive } from 'radix-ui';
5
+ import type * as React from 'react';
6
6
 
7
7
  import { cn } from '@/lib/utils';
8
8
 
9
9
  /** Action menu triggered by a button click. Supports submenus, checkbox/radio items, and keyboard shortcuts. */
10
10
  function DropdownMenu({ ...props }: React.ComponentProps<typeof DropdownMenuPrimitive.Root>) {
11
- return <DropdownMenuPrimitive.Root data-slot="dropdown-menu" {...props} />;
11
+ return <DropdownMenuPrimitive.Root data-slot="dropdown-menu" {...props} />;
12
12
  }
13
13
 
14
14
  /** Renders dropdown menu content into a React portal. */
15
15
  function DropdownMenuPortal({ ...props }: React.ComponentProps<typeof DropdownMenuPrimitive.Portal>) {
16
- return <DropdownMenuPrimitive.Portal data-slot="dropdown-menu-portal" {...props} />;
16
+ return <DropdownMenuPrimitive.Portal data-slot="dropdown-menu-portal" {...props} />;
17
17
  }
18
18
 
19
19
  /** Button or element that toggles the dropdown menu open/closed. */
20
20
  function DropdownMenuTrigger({ ...props }: React.ComponentProps<typeof DropdownMenuPrimitive.Trigger>) {
21
- return <DropdownMenuPrimitive.Trigger data-slot="dropdown-menu-trigger" {...props} />;
21
+ return <DropdownMenuPrimitive.Trigger data-slot="dropdown-menu-trigger" {...props} />;
22
22
  }
23
23
 
24
24
  /** The positioned popup container for dropdown menu items. Portals to the document body. */
25
25
  function DropdownMenuContent({
26
- className,
27
- sideOffset = 4,
28
- ...props
26
+ className,
27
+ sideOffset = 4,
28
+ ...props
29
29
  }: React.ComponentProps<typeof DropdownMenuPrimitive.Content>) {
30
- return (
31
- <DropdownMenuPrimitive.Portal>
32
- <DropdownMenuPrimitive.Content
33
- data-slot="dropdown-menu-content"
34
- sideOffset={sideOffset}
35
- className={cn(
36
- 'bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=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 z-50 max-h-(--radix-dropdown-menu-content-available-height) min-w-[8rem] origin-(--radix-dropdown-menu-content-transform-origin) overflow-x-hidden overflow-y-auto rounded-md border p-1 shadow-md',
37
- className,
38
- )}
39
- {...props}
40
- />
41
- </DropdownMenuPrimitive.Portal>
42
- );
30
+ return (
31
+ <DropdownMenuPrimitive.Portal>
32
+ <DropdownMenuPrimitive.Content
33
+ data-slot="dropdown-menu-content"
34
+ sideOffset={sideOffset}
35
+ className={cn(
36
+ 'bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=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 z-50 max-h-(--radix-dropdown-menu-content-available-height) min-w-[8rem] origin-(--radix-dropdown-menu-content-transform-origin) overflow-x-hidden overflow-y-auto rounded-md border p-1 shadow-md',
37
+ className,
38
+ )}
39
+ {...props}
40
+ />
41
+ </DropdownMenuPrimitive.Portal>
42
+ );
43
43
  }
44
44
 
45
45
  /** Groups related dropdown menu items for accessibility. */
46
46
  function DropdownMenuGroup({ ...props }: React.ComponentProps<typeof DropdownMenuPrimitive.Group>) {
47
- return <DropdownMenuPrimitive.Group data-slot="dropdown-menu-group" {...props} />;
47
+ return <DropdownMenuPrimitive.Group data-slot="dropdown-menu-group" {...props} />;
48
48
  }
49
49
 
50
50
  /**
@@ -52,188 +52,188 @@ function DropdownMenuGroup({ ...props }: React.ComponentProps<typeof DropdownMen
52
52
  * Use variant="destructive" for dangerous actions like delete or logout.
53
53
  */
54
54
  function DropdownMenuItem({
55
- className,
56
- /** Adds left padding to align with items that have icons or indicators. */
57
- inset,
58
- /** Use "destructive" for dangerous actions. */
59
- variant = 'default',
60
- ...props
55
+ className,
56
+ /** Adds left padding to align with items that have icons or indicators. */
57
+ inset,
58
+ /** Use "destructive" for dangerous actions. */
59
+ variant = 'default',
60
+ ...props
61
61
  }: React.ComponentProps<typeof DropdownMenuPrimitive.Item> & {
62
- inset?: boolean;
63
- variant?: 'default' | 'destructive';
62
+ inset?: boolean;
63
+ variant?: 'default' | 'destructive';
64
64
  }) {
65
- return (
66
- <DropdownMenuPrimitive.Item
67
- data-slot="dropdown-menu-item"
68
- data-inset={inset}
69
- data-variant={variant}
70
- className={cn(
71
- "focus:bg-accent focus:text-accent-foreground data-[variant=destructive]:text-destructive data-[variant=destructive]:focus:bg-destructive/10 dark:data-[variant=destructive]:focus:bg-destructive/20 data-[variant=destructive]:focus:text-destructive data-[variant=destructive]:*:[svg]:!text-destructive [&_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]:pointer-events-none data-[disabled]:opacity-50 data-[inset]:pl-8 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
72
- className,
73
- )}
74
- {...props}
75
- />
76
- );
65
+ return (
66
+ <DropdownMenuPrimitive.Item
67
+ data-slot="dropdown-menu-item"
68
+ data-inset={inset}
69
+ data-variant={variant}
70
+ className={cn(
71
+ "focus:bg-accent focus:text-accent-foreground data-[variant=destructive]:text-destructive data-[variant=destructive]:focus:bg-destructive/10 dark:data-[variant=destructive]:focus:bg-destructive/20 data-[variant=destructive]:focus:text-destructive data-[variant=destructive]:*:[svg]:!text-destructive [&_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]:pointer-events-none data-[disabled]:opacity-50 data-[inset]:pl-8 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
72
+ className,
73
+ )}
74
+ {...props}
75
+ />
76
+ );
77
77
  }
78
78
 
79
79
  /** A toggleable checkbox item within the dropdown menu. Shows a check indicator when active. */
80
80
  function DropdownMenuCheckboxItem({
81
- className,
82
- children,
83
- checked,
84
- ...props
81
+ className,
82
+ children,
83
+ checked,
84
+ ...props
85
85
  }: React.ComponentProps<typeof DropdownMenuPrimitive.CheckboxItem>) {
86
- return (
87
- <DropdownMenuPrimitive.CheckboxItem
88
- data-slot="dropdown-menu-checkbox-item"
89
- className={cn(
90
- "focus:bg-accent focus:text-accent-foreground relative flex cursor-default items-center gap-2 rounded-sm py-1.5 pr-2 pl-8 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",
91
- className,
92
- )}
93
- checked={checked}
94
- {...props}
95
- >
96
- <span className="pointer-events-none absolute left-2 flex size-3.5 items-center justify-center">
97
- <DropdownMenuPrimitive.ItemIndicator>
98
- <CheckIcon className="size-4" />
99
- </DropdownMenuPrimitive.ItemIndicator>
100
- </span>
101
- {children}
102
- </DropdownMenuPrimitive.CheckboxItem>
103
- );
86
+ return (
87
+ <DropdownMenuPrimitive.CheckboxItem
88
+ data-slot="dropdown-menu-checkbox-item"
89
+ className={cn(
90
+ "focus:bg-accent focus:text-accent-foreground relative flex cursor-default items-center gap-2 rounded-sm py-1.5 pr-2 pl-8 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",
91
+ className,
92
+ )}
93
+ checked={checked}
94
+ {...props}
95
+ >
96
+ <span className="pointer-events-none absolute left-2 flex size-3.5 items-center justify-center">
97
+ <DropdownMenuPrimitive.ItemIndicator>
98
+ <CheckIcon className="size-4" />
99
+ </DropdownMenuPrimitive.ItemIndicator>
100
+ </span>
101
+ {children}
102
+ </DropdownMenuPrimitive.CheckboxItem>
103
+ );
104
104
  }
105
105
 
106
106
  /** Groups radio items for single-selection within the dropdown menu. */
107
107
  function DropdownMenuRadioGroup({ ...props }: React.ComponentProps<typeof DropdownMenuPrimitive.RadioGroup>) {
108
- return <DropdownMenuPrimitive.RadioGroup data-slot="dropdown-menu-radio-group" {...props} />;
108
+ return <DropdownMenuPrimitive.RadioGroup data-slot="dropdown-menu-radio-group" {...props} />;
109
109
  }
110
110
 
111
111
  /** A radio-selectable item within a DropdownMenuRadioGroup. Shows a dot indicator when selected. */
112
112
  function DropdownMenuRadioItem({
113
- className,
114
- children,
115
- ...props
113
+ className,
114
+ children,
115
+ ...props
116
116
  }: React.ComponentProps<typeof DropdownMenuPrimitive.RadioItem>) {
117
- return (
118
- <DropdownMenuPrimitive.RadioItem
119
- data-slot="dropdown-menu-radio-item"
120
- className={cn(
121
- "focus:bg-accent focus:text-accent-foreground relative flex cursor-default items-center gap-2 rounded-sm py-1.5 pr-2 pl-8 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",
122
- className,
123
- )}
124
- {...props}
125
- >
126
- <span className="pointer-events-none absolute left-2 flex size-3.5 items-center justify-center">
127
- <DropdownMenuPrimitive.ItemIndicator>
128
- <CircleIcon className="size-2 fill-current" />
129
- </DropdownMenuPrimitive.ItemIndicator>
130
- </span>
131
- {children}
132
- </DropdownMenuPrimitive.RadioItem>
133
- );
117
+ return (
118
+ <DropdownMenuPrimitive.RadioItem
119
+ data-slot="dropdown-menu-radio-item"
120
+ className={cn(
121
+ "focus:bg-accent focus:text-accent-foreground relative flex cursor-default items-center gap-2 rounded-sm py-1.5 pr-2 pl-8 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",
122
+ className,
123
+ )}
124
+ {...props}
125
+ >
126
+ <span className="pointer-events-none absolute left-2 flex size-3.5 items-center justify-center">
127
+ <DropdownMenuPrimitive.ItemIndicator>
128
+ <CircleIcon className="size-2 fill-current" />
129
+ </DropdownMenuPrimitive.ItemIndicator>
130
+ </span>
131
+ {children}
132
+ </DropdownMenuPrimitive.RadioItem>
133
+ );
134
134
  }
135
135
 
136
136
  /** Non-interactive label within a dropdown menu, used for section headings. */
137
137
  function DropdownMenuLabel({
138
- className,
139
- inset,
140
- ...props
138
+ className,
139
+ inset,
140
+ ...props
141
141
  }: React.ComponentProps<typeof DropdownMenuPrimitive.Label> & {
142
- inset?: boolean;
142
+ inset?: boolean;
143
143
  }) {
144
- return (
145
- <DropdownMenuPrimitive.Label
146
- data-slot="dropdown-menu-label"
147
- data-inset={inset}
148
- className={cn('px-2 py-1.5 text-sm font-medium data-[inset]:pl-8', className)}
149
- {...props}
150
- />
151
- );
144
+ return (
145
+ <DropdownMenuPrimitive.Label
146
+ data-slot="dropdown-menu-label"
147
+ data-inset={inset}
148
+ className={cn('px-2 py-1.5 text-sm font-medium data-[inset]:pl-8', className)}
149
+ {...props}
150
+ />
151
+ );
152
152
  }
153
153
 
154
154
  /** Visual divider between groups of dropdown menu items. */
155
155
  function DropdownMenuSeparator({ className, ...props }: React.ComponentProps<typeof DropdownMenuPrimitive.Separator>) {
156
- return (
157
- <DropdownMenuPrimitive.Separator
158
- data-slot="dropdown-menu-separator"
159
- className={cn('bg-border -mx-1 my-1 h-px', className)}
160
- {...props}
161
- />
162
- );
156
+ return (
157
+ <DropdownMenuPrimitive.Separator
158
+ data-slot="dropdown-menu-separator"
159
+ className={cn('bg-border -mx-1 my-1 h-px', className)}
160
+ {...props}
161
+ />
162
+ );
163
163
  }
164
164
 
165
165
  /** Displays a keyboard shortcut hint aligned to the right side of a dropdown menu item. */
166
166
  function DropdownMenuShortcut({ className, ...props }: React.ComponentProps<'span'>) {
167
- return (
168
- <span
169
- data-slot="dropdown-menu-shortcut"
170
- className={cn('text-muted-foreground ml-auto text-xs tracking-widest', className)}
171
- {...props}
172
- />
173
- );
167
+ return (
168
+ <span
169
+ data-slot="dropdown-menu-shortcut"
170
+ className={cn('text-muted-foreground ml-auto text-xs tracking-widest', className)}
171
+ {...props}
172
+ />
173
+ );
174
174
  }
175
175
 
176
176
  /** Container for a submenu within the dropdown menu. */
177
177
  function DropdownMenuSub({ ...props }: React.ComponentProps<typeof DropdownMenuPrimitive.Sub>) {
178
- return <DropdownMenuPrimitive.Sub data-slot="dropdown-menu-sub" {...props} />;
178
+ return <DropdownMenuPrimitive.Sub data-slot="dropdown-menu-sub" {...props} />;
179
179
  }
180
180
 
181
181
  /** Menu item that opens a nested submenu on hover or keyboard navigation. Shows a chevron indicator. */
182
182
  function DropdownMenuSubTrigger({
183
- className,
184
- inset,
185
- children,
186
- ...props
183
+ className,
184
+ inset,
185
+ children,
186
+ ...props
187
187
  }: React.ComponentProps<typeof DropdownMenuPrimitive.SubTrigger> & {
188
- inset?: boolean;
188
+ inset?: boolean;
189
189
  }) {
190
- return (
191
- <DropdownMenuPrimitive.SubTrigger
192
- data-slot="dropdown-menu-sub-trigger"
193
- data-inset={inset}
194
- className={cn(
195
- "focus:bg-accent focus:text-accent-foreground data-[state=open]:bg-accent data-[state=open]:text-accent-foreground [&_svg:not([class*='text-'])]:text-muted-foreground flex cursor-default items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-hidden select-none data-[inset]:pl-8 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
196
- className,
197
- )}
198
- {...props}
199
- >
200
- {children}
201
- <ChevronRightIcon className="ml-auto size-4" />
202
- </DropdownMenuPrimitive.SubTrigger>
203
- );
190
+ return (
191
+ <DropdownMenuPrimitive.SubTrigger
192
+ data-slot="dropdown-menu-sub-trigger"
193
+ data-inset={inset}
194
+ className={cn(
195
+ "focus:bg-accent focus:text-accent-foreground data-[state=open]:bg-accent data-[state=open]:text-accent-foreground [&_svg:not([class*='text-'])]:text-muted-foreground flex cursor-default items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-hidden select-none data-[inset]:pl-8 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
196
+ className,
197
+ )}
198
+ {...props}
199
+ >
200
+ {children}
201
+ <ChevronRightIcon className="ml-auto size-4" />
202
+ </DropdownMenuPrimitive.SubTrigger>
203
+ );
204
204
  }
205
205
 
206
206
  /** Popup content for a nested submenu. */
207
207
  function DropdownMenuSubContent({
208
- className,
209
- ...props
208
+ className,
209
+ ...props
210
210
  }: React.ComponentProps<typeof DropdownMenuPrimitive.SubContent>) {
211
- return (
212
- <DropdownMenuPrimitive.SubContent
213
- data-slot="dropdown-menu-sub-content"
214
- className={cn(
215
- 'bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=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 z-50 min-w-[8rem] origin-(--radix-dropdown-menu-content-transform-origin) overflow-hidden rounded-md border p-1 shadow-lg',
216
- className,
217
- )}
218
- {...props}
219
- />
220
- );
211
+ return (
212
+ <DropdownMenuPrimitive.SubContent
213
+ data-slot="dropdown-menu-sub-content"
214
+ className={cn(
215
+ 'bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=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 z-50 min-w-[8rem] origin-(--radix-dropdown-menu-content-transform-origin) overflow-hidden rounded-md border p-1 shadow-lg',
216
+ className,
217
+ )}
218
+ {...props}
219
+ />
220
+ );
221
221
  }
222
222
 
223
223
  export {
224
- DropdownMenu,
225
- DropdownMenuPortal,
226
- DropdownMenuTrigger,
227
- DropdownMenuContent,
228
- DropdownMenuGroup,
229
- DropdownMenuLabel,
230
- DropdownMenuItem,
231
- DropdownMenuCheckboxItem,
232
- DropdownMenuRadioGroup,
233
- DropdownMenuRadioItem,
234
- DropdownMenuSeparator,
235
- DropdownMenuShortcut,
236
- DropdownMenuSub,
237
- DropdownMenuSubTrigger,
238
- DropdownMenuSubContent,
224
+ DropdownMenu,
225
+ DropdownMenuPortal,
226
+ DropdownMenuTrigger,
227
+ DropdownMenuContent,
228
+ DropdownMenuGroup,
229
+ DropdownMenuLabel,
230
+ DropdownMenuItem,
231
+ DropdownMenuCheckboxItem,
232
+ DropdownMenuRadioGroup,
233
+ DropdownMenuRadioItem,
234
+ DropdownMenuSeparator,
235
+ DropdownMenuShortcut,
236
+ DropdownMenuSub,
237
+ DropdownMenuSubTrigger,
238
+ DropdownMenuSubContent,
239
239
  };
@@ -1,37 +1,37 @@
1
1
  import type { Meta, StoryObj } from '@storybook/react-vite';
2
- import { Empty, EmptyHeader, EmptyTitle, EmptyDescription, EmptyMedia } from '@/components/ui/Empty';
3
2
  import { InboxIcon } from 'lucide-react';
3
+ import { Empty, EmptyDescription, EmptyHeader, EmptyMedia, EmptyTitle } from '@/components/ui/Empty';
4
4
 
5
5
  const meta: Meta<typeof Empty> = {
6
- title: 'UI Components/Empty',
7
- component: Empty,
6
+ title: 'UI Components/Empty',
7
+ component: Empty,
8
8
  };
9
9
  export default meta;
10
10
  type Story = StoryObj<typeof Empty>;
11
11
 
12
12
  /** Shows a basic empty state with a title and description text. */
13
13
  export const Default: Story = {
14
- render: () => (
15
- <Empty>
16
- <EmptyHeader>
17
- <EmptyTitle>No results found</EmptyTitle>
18
- <EmptyDescription>Try adjusting your search or filter to find what you are looking for.</EmptyDescription>
19
- </EmptyHeader>
20
- </Empty>
21
- ),
14
+ render: () => (
15
+ <Empty>
16
+ <EmptyHeader>
17
+ <EmptyTitle>No results found</EmptyTitle>
18
+ <EmptyDescription>Try adjusting your search or filter to find what you are looking for.</EmptyDescription>
19
+ </EmptyHeader>
20
+ </Empty>
21
+ ),
22
22
  };
23
23
 
24
24
  /** Shows an empty state with a styled icon container above the title and description. */
25
25
  export const WithIcon: Story = {
26
- render: () => (
27
- <Empty>
28
- <EmptyHeader>
29
- <EmptyMedia variant="icon">
30
- <InboxIcon />
31
- </EmptyMedia>
32
- <EmptyTitle>Your inbox is empty</EmptyTitle>
33
- <EmptyDescription>New messages will appear here when you receive them.</EmptyDescription>
34
- </EmptyHeader>
35
- </Empty>
36
- ),
26
+ render: () => (
27
+ <Empty>
28
+ <EmptyHeader>
29
+ <EmptyMedia variant="icon">
30
+ <InboxIcon />
31
+ </EmptyMedia>
32
+ <EmptyTitle>Your inbox is empty</EmptyTitle>
33
+ <EmptyDescription>New messages will appear here when you receive them.</EmptyDescription>
34
+ </EmptyHeader>
35
+ </Empty>
36
+ ),
37
37
  };
@@ -8,42 +8,42 @@ import { cn } from '@/lib/utils';
8
8
  * to build structured empty state layouts with icons and call-to-action areas.
9
9
  */
10
10
  function Empty({ className, ...props }: React.ComponentProps<'div'>) {
11
- return (
12
- <div
13
- data-slot="empty"
14
- className={cn(
15
- 'flex min-w-0 flex-1 flex-col items-center justify-center gap-6 rounded-lg border-dashed p-6 text-center text-balance md:p-12',
16
- className,
17
- )}
18
- {...props}
19
- />
20
- );
11
+ return (
12
+ <div
13
+ data-slot="empty"
14
+ className={cn(
15
+ 'flex min-w-0 flex-1 flex-col items-center justify-center gap-6 rounded-lg border-dashed p-6 text-center text-balance md:p-12',
16
+ className,
17
+ )}
18
+ {...props}
19
+ />
20
+ );
21
21
  }
22
22
 
23
23
  /** Container for the title, description, and optional media in an empty state. */
24
24
  function EmptyHeader({ className, ...props }: React.ComponentProps<'div'>) {
25
- return (
26
- <div
27
- data-slot="empty-header"
28
- className={cn('flex max-w-sm flex-col items-center gap-2 text-center', className)}
29
- {...props}
30
- />
31
- );
25
+ return (
26
+ <div
27
+ data-slot="empty-header"
28
+ className={cn('flex max-w-sm flex-col items-center gap-2 text-center', className)}
29
+ {...props}
30
+ />
31
+ );
32
32
  }
33
33
 
34
34
  const emptyMediaVariants = cva(
35
- 'flex shrink-0 items-center justify-center mb-2 [&_svg]:pointer-events-none [&_svg]:shrink-0',
36
- {
37
- variants: {
38
- variant: {
39
- default: 'bg-transparent',
40
- icon: "bg-muted text-foreground flex size-10 shrink-0 items-center justify-center rounded-lg [&_svg:not([class*='size-'])]:size-6",
41
- },
42
- },
43
- defaultVariants: {
44
- variant: 'default',
45
- },
46
- },
35
+ 'flex shrink-0 items-center justify-center mb-2 [&_svg]:pointer-events-none [&_svg]:shrink-0',
36
+ {
37
+ variants: {
38
+ variant: {
39
+ default: 'bg-transparent',
40
+ icon: "bg-muted text-foreground flex size-10 shrink-0 items-center justify-center rounded-lg [&_svg:not([class*='size-'])]:size-6",
41
+ },
42
+ },
43
+ defaultVariants: {
44
+ variant: 'default',
45
+ },
46
+ },
47
47
  );
48
48
 
49
49
  /**
@@ -51,48 +51,48 @@ const emptyMediaVariants = cva(
51
51
  * Use variant="icon" for a styled icon container with a muted background.
52
52
  */
53
53
  function EmptyMedia({
54
- className,
55
- variant = 'default',
56
- ...props
54
+ className,
55
+ variant = 'default',
56
+ ...props
57
57
  }: React.ComponentProps<'div'> & VariantProps<typeof emptyMediaVariants>) {
58
- return (
59
- <div
60
- data-slot="empty-icon"
61
- data-variant={variant}
62
- className={cn(emptyMediaVariants({ variant, className }))}
63
- {...props}
64
- />
65
- );
58
+ return (
59
+ <div
60
+ data-slot="empty-icon"
61
+ data-variant={variant}
62
+ className={cn(emptyMediaVariants({ variant, className }))}
63
+ {...props}
64
+ />
65
+ );
66
66
  }
67
67
 
68
68
  /** Title text for the empty state message. */
69
69
  function EmptyTitle({ className, ...props }: React.ComponentProps<'div'>) {
70
- return <div data-slot="empty-title" className={cn('text-lg font-medium tracking-tight', className)} {...props} />;
70
+ return <div data-slot="empty-title" className={cn('text-lg font-medium tracking-tight', className)} {...props} />;
71
71
  }
72
72
 
73
73
  /** Descriptive text explaining why the content is empty or what the user can do. */
74
74
  function EmptyDescription({ className, ...props }: React.ComponentProps<'p'>) {
75
- return (
76
- <div
77
- data-slot="empty-description"
78
- className={cn(
79
- 'text-muted-foreground [&>a:hover]:text-primary text-sm/relaxed [&>a]:underline [&>a]:underline-offset-4',
80
- className,
81
- )}
82
- {...props}
83
- />
84
- );
75
+ return (
76
+ <div
77
+ data-slot="empty-description"
78
+ className={cn(
79
+ 'text-muted-foreground [&>a:hover]:text-primary text-sm/relaxed [&>a]:underline [&>a]:underline-offset-4',
80
+ className,
81
+ )}
82
+ {...props}
83
+ />
84
+ );
85
85
  }
86
86
 
87
87
  /** Container for action buttons or additional content below the empty state message. */
88
88
  function EmptyContent({ className, ...props }: React.ComponentProps<'div'>) {
89
- return (
90
- <div
91
- data-slot="empty-content"
92
- className={cn('flex w-full max-w-sm min-w-0 flex-col items-center gap-4 text-sm text-balance', className)}
93
- {...props}
94
- />
95
- );
89
+ return (
90
+ <div
91
+ data-slot="empty-content"
92
+ className={cn('flex w-full max-w-sm min-w-0 flex-col items-center gap-4 text-sm text-balance', className)}
93
+ {...props}
94
+ />
95
+ );
96
96
  }
97
97
 
98
98
  export { Empty, EmptyHeader, EmptyTitle, EmptyDescription, EmptyContent, EmptyMedia };