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,31 +0,0 @@
1
- import { Meta, Stories } from '@storybook/addon-docs/blocks';
2
-
3
- <Meta title="Design System/Typography" />
4
-
5
- # Typography
6
-
7
- Typography classes used across the design system. All styles are composed from
8
- Tailwind CSS utility classes -- no custom font-size tokens are needed.
9
-
10
- ## Reference
11
-
12
- | Element | Tailwind Classes | Usage |
13
- | --- | --- | --- |
14
- | **H1** | `text-5xl font-extrabold tracking-tight` | Hero or display headings |
15
- | **H2** | `text-4xl font-bold tracking-tight` | Page-level headings |
16
- | **H3** | `text-3xl font-bold` | Section headings |
17
- | **H4** | `text-2xl font-semibold` | Subsection headings |
18
- | **H5** | `text-xl font-semibold` | Card or widget headings |
19
- | **Body (lead)** | `text-base leading-relaxed` | Long-form paragraphs where extra line-height aids readability |
20
- | **Body** | `text-base` | Default body text, UI labels |
21
- | **Muted** | `text-sm text-muted-foreground` | Descriptions, help text, secondary information |
22
- | **Small / Caption** | `text-xs text-muted-foreground` | Captions, timestamps, metadata |
23
-
24
- ## Guidelines
25
-
26
- - Prefer semantic heading order (`H1` > `H2` > `H3` ...) for accessibility.
27
- - Use **lead body** (`leading-relaxed`) only for multi-line content blocks; single-line labels should use the plain **body** style.
28
- - `text-muted-foreground` maps to the theme's muted colour and automatically adapts between light and dark modes.
29
- - Avoid mixing heading classes with body classes on the same element.
30
-
31
- <Stories />
@@ -1,80 +0,0 @@
1
- import type { Meta, StoryObj } from '@storybook/react-vite';
2
-
3
- interface TypographyRowProps {
4
- label: string;
5
- className: string;
6
- sample?: string;
7
- }
8
-
9
- function TypographyRow({ label, className, sample }: TypographyRowProps) {
10
- return (
11
- <div className="flex flex-col gap-1 border-b border-border pb-4">
12
- <div className="flex items-baseline gap-3">
13
- <span className="text-xs font-mono text-muted-foreground min-w-[120px] shrink-0">{label}</span>
14
- <code className="text-xs bg-muted px-1.5 py-0.5 rounded font-mono">{className}</code>
15
- </div>
16
- <div className={className}>{sample ?? 'The quick brown fox jumps over the lazy dog'}</div>
17
- </div>
18
- );
19
- }
20
-
21
- function TypographyScale() {
22
- return (
23
- <div className="flex flex-col gap-6 max-w-3xl">
24
- <div className="flex flex-col gap-1 pb-4">
25
- <h2 className="text-2xl font-semibold">Typography Scale</h2>
26
- <p className="text-sm text-muted-foreground">
27
- Visual reference for typography classes used throughout the design system.
28
- </p>
29
- </div>
30
-
31
- <div className="flex flex-col gap-6">
32
- <h3 className="text-lg font-semibold text-muted-foreground uppercase tracking-wide">Headings</h3>
33
- <TypographyRow label="H1" className="text-5xl font-extrabold tracking-tight" sample="Display Heading" />
34
- <TypographyRow label="H2" className="text-4xl font-bold tracking-tight" sample="Page Heading" />
35
- <TypographyRow label="H3" className="text-3xl font-bold" sample="Section Heading" />
36
- <TypographyRow label="H4" className="text-2xl font-semibold" sample="Subsection Heading" />
37
- <TypographyRow label="H5" className="text-xl font-semibold" sample="Card Heading" />
38
- </div>
39
-
40
- <div className="flex flex-col gap-6 mt-4">
41
- <h3 className="text-lg font-semibold text-muted-foreground uppercase tracking-wide">Body</h3>
42
- <TypographyRow
43
- label="Body (lead)"
44
- className="text-base leading-relaxed"
45
- sample="Body text with relaxed leading for longer paragraphs. This style improves readability for multi-line content blocks."
46
- />
47
- <TypographyRow
48
- label="Body"
49
- className="text-base"
50
- sample="Default body text used for general content and UI labels."
51
- />
52
- </div>
53
-
54
- <div className="flex flex-col gap-6 mt-4">
55
- <h3 className="text-lg font-semibold text-muted-foreground uppercase tracking-wide">Muted &amp; Small</h3>
56
- <TypographyRow
57
- label="Muted"
58
- className="text-sm text-muted-foreground"
59
- sample="Secondary text for descriptions, help text, and supplementary information."
60
- />
61
- <TypographyRow
62
- label="Small / Caption"
63
- className="text-xs text-muted-foreground"
64
- sample="Captions, timestamps, and fine-print details."
65
- />
66
- </div>
67
- </div>
68
- );
69
- }
70
-
71
- const meta: Meta = {
72
- title: 'Design System/Typography',
73
- tags: ['!autodocs', '!manifest'],
74
- };
75
- export default meta;
76
- type Story = StoryObj;
77
-
78
- export const TypeScale: Story = {
79
- render: () => <TypographyScale />,
80
- };
@@ -1,74 +0,0 @@
1
- import type { Meta, StoryObj } from '@storybook/react-vite';
2
- import {
3
- Dialog,
4
- DialogContent,
5
- DialogDescription,
6
- DialogFooter,
7
- DialogHeader,
8
- DialogTitle,
9
- DialogTrigger,
10
- } from '@/components/ui/Dialog';
11
- import { Button } from '@/components/ui/Button';
12
- import { Input } from '@/components/ui/Input';
13
- import { Label } from '@/components/ui/Label';
14
-
15
- const meta: Meta<typeof Dialog> = {
16
- title: 'UI Components/Dialog',
17
- component: Dialog,
18
- };
19
- export default meta;
20
- type Story = StoryObj<typeof Dialog>;
21
-
22
- /** Shows a dialog with a form for editing profile information. */
23
- export const Default: Story = {
24
- render: () => (
25
- <Dialog>
26
- <DialogTrigger asChild>
27
- <Button variant="outline">Edit Profile</Button>
28
- </DialogTrigger>
29
- <DialogContent className="sm:max-w-[425px]">
30
- <DialogHeader>
31
- <DialogTitle>Edit profile</DialogTitle>
32
- <DialogDescription>Make changes to your profile here. Click save when you are done.</DialogDescription>
33
- </DialogHeader>
34
- <div className="grid gap-4 py-4">
35
- <div className="grid grid-cols-4 items-center gap-4">
36
- <Label htmlFor="name" className="text-right">
37
- Name
38
- </Label>
39
- <Input id="name" defaultValue="John Doe" className="col-span-3" />
40
- </div>
41
- <div className="grid grid-cols-4 items-center gap-4">
42
- <Label htmlFor="username" className="text-right">
43
- Username
44
- </Label>
45
- <Input id="username" defaultValue="@johndoe" className="col-span-3" />
46
- </div>
47
- </div>
48
- <DialogFooter>
49
- <Button type="submit">Save changes</Button>
50
- </DialogFooter>
51
- </DialogContent>
52
- </Dialog>
53
- ),
54
- };
55
-
56
- /** Shows a confirmation dialog with a footer close button and a destructive action. */
57
- export const WithCloseButton: Story = {
58
- render: () => (
59
- <Dialog>
60
- <DialogTrigger asChild>
61
- <Button variant="outline">Open Dialog</Button>
62
- </DialogTrigger>
63
- <DialogContent>
64
- <DialogHeader>
65
- <DialogTitle>Confirm Action</DialogTitle>
66
- <DialogDescription>Are you sure you want to proceed? This action cannot be undone.</DialogDescription>
67
- </DialogHeader>
68
- <DialogFooter showCloseButton>
69
- <Button variant="destructive">Confirm</Button>
70
- </DialogFooter>
71
- </DialogContent>
72
- </Dialog>
73
- ),
74
- };
@@ -1,154 +0,0 @@
1
- import * as React from 'react';
2
- import { XIcon } from 'lucide-react';
3
- import { Dialog as DialogPrimitive } from 'radix-ui';
4
-
5
- import { cn } from '@/lib/utils';
6
- import { Button } from '@/components/ui/Button';
7
-
8
- /** A modal overlay with focus trapping and scroll locking. Click outside or press Escape to close. */
9
- function Dialog({ ...props }: React.ComponentProps<typeof DialogPrimitive.Root>) {
10
- return <DialogPrimitive.Root data-slot="dialog" {...props} />;
11
- }
12
-
13
- /** Button or element that opens the dialog when clicked. */
14
- function DialogTrigger({ ...props }: React.ComponentProps<typeof DialogPrimitive.Trigger>) {
15
- return <DialogPrimitive.Trigger data-slot="dialog-trigger" {...props} />;
16
- }
17
-
18
- /** Renders dialog content into a React portal. */
19
- function DialogPortal({ ...props }: React.ComponentProps<typeof DialogPrimitive.Portal>) {
20
- return <DialogPrimitive.Portal data-slot="dialog-portal" {...props} />;
21
- }
22
-
23
- /** Programmatic close trigger for the dialog. */
24
- function DialogClose({ ...props }: React.ComponentProps<typeof DialogPrimitive.Close>) {
25
- return <DialogPrimitive.Close data-slot="dialog-close" {...props} />;
26
- }
27
-
28
- /** Semi-transparent backdrop behind the dialog that dims the page content. */
29
- function DialogOverlay({ className, ...props }: React.ComponentProps<typeof DialogPrimitive.Overlay>) {
30
- return (
31
- <DialogPrimitive.Overlay
32
- data-slot="dialog-overlay"
33
- className={cn(
34
- 'data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 fixed inset-0 z-50 bg-black/50',
35
- className,
36
- )}
37
- {...props}
38
- />
39
- );
40
- }
41
-
42
- /**
43
- * The main dialog panel centered on screen with overlay backdrop.
44
- * Set showCloseButton={false} to hide the top-right X button.
45
- */
46
- function DialogContent({
47
- className,
48
- children,
49
- /** Whether to render the close (X) button in the top-right corner. */
50
- showCloseButton = true,
51
- ...props
52
- }: React.ComponentProps<typeof DialogPrimitive.Content> & {
53
- showCloseButton?: boolean;
54
- }) {
55
- return (
56
- <DialogPortal data-slot="dialog-portal">
57
- <DialogOverlay />
58
- <DialogPrimitive.Content
59
- data-slot="dialog-content"
60
- className={cn(
61
- 'bg-background 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 fixed top-[50%] left-[50%] z-50 grid w-full max-w-[calc(100%-2rem)] translate-x-[-50%] translate-y-[-50%] gap-4 rounded-lg border p-6 shadow-lg duration-200 outline-none sm:max-w-lg',
62
- className,
63
- )}
64
- {...props}
65
- >
66
- {children}
67
- {showCloseButton && (
68
- <DialogPrimitive.Close
69
- data-slot="dialog-close"
70
- className="ring-offset-background focus:ring-ring data-[state=open]:bg-accent data-[state=open]:text-muted-foreground absolute top-4 right-4 rounded-xs opacity-70 transition-opacity hover:opacity-100 focus:ring-2 focus:ring-offset-2 focus:outline-hidden disabled:pointer-events-none [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4"
71
- >
72
- <XIcon />
73
- <span className="sr-only">Close</span>
74
- </DialogPrimitive.Close>
75
- )}
76
- </DialogPrimitive.Content>
77
- </DialogPortal>
78
- );
79
- }
80
-
81
- /** Container for DialogTitle and DialogDescription at the top of the dialog. */
82
- function DialogHeader({ className, ...props }: React.ComponentProps<'div'>) {
83
- return (
84
- <div
85
- data-slot="dialog-header"
86
- className={cn('flex flex-col gap-2 text-center sm:text-left', className)}
87
- {...props}
88
- />
89
- );
90
- }
91
-
92
- /**
93
- * Container for action buttons at the bottom of the dialog.
94
- * Set showCloseButton to add an automatic "Close" button.
95
- */
96
- function DialogFooter({
97
- className,
98
- /** Whether to append a "Close" button that dismisses the dialog. */
99
- showCloseButton = false,
100
- children,
101
- ...props
102
- }: React.ComponentProps<'div'> & {
103
- showCloseButton?: boolean;
104
- }) {
105
- return (
106
- <div
107
- data-slot="dialog-footer"
108
- className={cn('flex flex-col-reverse gap-2 sm:flex-row sm:justify-end', className)}
109
- {...props}
110
- >
111
- {children}
112
- {showCloseButton && (
113
- <DialogPrimitive.Close asChild>
114
- <Button variant="outline">Close</Button>
115
- </DialogPrimitive.Close>
116
- )}
117
- </div>
118
- );
119
- }
120
-
121
- /** Accessible title for the dialog. Required for screen reader support. */
122
- function DialogTitle({ className, ...props }: React.ComponentProps<typeof DialogPrimitive.Title>) {
123
- return (
124
- <DialogPrimitive.Title
125
- data-slot="dialog-title"
126
- className={cn('text-lg leading-none font-semibold', className)}
127
- {...props}
128
- />
129
- );
130
- }
131
-
132
- /** Accessible description text for the dialog, displayed below the title. */
133
- function DialogDescription({ className, ...props }: React.ComponentProps<typeof DialogPrimitive.Description>) {
134
- return (
135
- <DialogPrimitive.Description
136
- data-slot="dialog-description"
137
- className={cn('text-muted-foreground text-sm', className)}
138
- {...props}
139
- />
140
- );
141
- }
142
-
143
- export {
144
- Dialog,
145
- DialogClose,
146
- DialogContent,
147
- DialogDescription,
148
- DialogFooter,
149
- DialogHeader,
150
- DialogOverlay,
151
- DialogPortal,
152
- DialogTitle,
153
- DialogTrigger,
154
- };
@@ -1,38 +0,0 @@
1
- import type { Meta, StoryObj } from '@storybook/react-vite';
2
- import { DirectionProvider, useDirection } from '@/components/ui/Direction';
3
-
4
- const meta: Meta<typeof DirectionProvider> = {
5
- title: 'UI Components/Direction',
6
- component: DirectionProvider,
7
- };
8
- export default meta;
9
- type Story = StoryObj<typeof DirectionProvider>;
10
-
11
- function DirectionDisplay() {
12
- const direction = useDirection();
13
- return <p className="text-sm text-muted-foreground">Current direction: {direction ?? 'not set'}</p>;
14
- }
15
-
16
- /** Shows the DirectionProvider in left-to-right mode. */
17
- export const LTR: Story = {
18
- render: () => (
19
- <DirectionProvider dir="ltr">
20
- <div className="space-y-2">
21
- <DirectionDisplay />
22
- <p>This content is rendered in a left-to-right context.</p>
23
- </div>
24
- </DirectionProvider>
25
- ),
26
- };
27
-
28
- /** Shows the DirectionProvider in right-to-left mode for internationalization support. */
29
- export const RTL: Story = {
30
- render: () => (
31
- <DirectionProvider dir="rtl">
32
- <div className="space-y-2" dir="rtl">
33
- <DirectionDisplay />
34
- <p>This content is rendered in a right-to-left context.</p>
35
- </div>
36
- </DirectionProvider>
37
- ),
38
- };
@@ -1,24 +0,0 @@
1
- 'use client';
2
-
3
- import * as React from 'react';
4
- import { Direction } from 'radix-ui';
5
-
6
- /**
7
- * Provides text direction (LTR/RTL) context to all descendant Radix UI components.
8
- * Accepts either `dir` or `direction` prop for convenience.
9
- */
10
- function DirectionProvider({
11
- dir,
12
- /** Alias for `dir`. If both are provided, `direction` takes precedence. */
13
- direction,
14
- children,
15
- }: React.ComponentProps<typeof Direction.DirectionProvider> & {
16
- direction?: React.ComponentProps<typeof Direction.DirectionProvider>['dir'];
17
- }) {
18
- return <Direction.DirectionProvider dir={direction ?? dir}>{children}</Direction.DirectionProvider>;
19
- }
20
-
21
- /** Hook to read the current text direction from the nearest DirectionProvider. */
22
- const useDirection = Direction.useDirection;
23
-
24
- export { DirectionProvider, useDirection };
@@ -1,70 +0,0 @@
1
- import type { Meta, StoryObj } from '@storybook/react-vite';
2
- import {
3
- Drawer,
4
- DrawerTrigger,
5
- DrawerContent,
6
- DrawerHeader,
7
- DrawerFooter,
8
- DrawerTitle,
9
- DrawerDescription,
10
- DrawerClose,
11
- } from '@/components/ui/Drawer';
12
- import { Button } from '@/components/ui/Button';
13
-
14
- const meta: Meta<typeof Drawer> = {
15
- title: 'UI Components/Drawer',
16
- component: Drawer,
17
- };
18
- export default meta;
19
- type Story = StoryObj<typeof Drawer>;
20
-
21
- /** Shows a bottom drawer with a title, description, body content, and action buttons. */
22
- export const Default: Story = {
23
- render: () => (
24
- <Drawer>
25
- <DrawerTrigger asChild>
26
- <Button variant="outline">Open Drawer</Button>
27
- </DrawerTrigger>
28
- <DrawerContent>
29
- <DrawerHeader>
30
- <DrawerTitle>Move Goal</DrawerTitle>
31
- <DrawerDescription>Set your daily activity goal.</DrawerDescription>
32
- </DrawerHeader>
33
- <div className="p-4">
34
- <p className="text-muted-foreground text-sm">Adjust the settings below to configure your preferences.</p>
35
- </div>
36
- <DrawerFooter>
37
- <Button>Submit</Button>
38
- <DrawerClose asChild>
39
- <Button variant="outline">Cancel</Button>
40
- </DrawerClose>
41
- </DrawerFooter>
42
- </DrawerContent>
43
- </Drawer>
44
- ),
45
- };
46
-
47
- /** Shows a drawer sliding in from the right side, useful for side panels and detail views. */
48
- export const RightSide: Story = {
49
- render: () => (
50
- <Drawer direction="right">
51
- <DrawerTrigger asChild>
52
- <Button variant="outline">Open Right Drawer</Button>
53
- </DrawerTrigger>
54
- <DrawerContent>
55
- <DrawerHeader>
56
- <DrawerTitle>Side Panel</DrawerTitle>
57
- <DrawerDescription>This drawer opens from the right side.</DrawerDescription>
58
- </DrawerHeader>
59
- <div className="p-4">
60
- <p className="text-muted-foreground text-sm">Content goes here.</p>
61
- </div>
62
- <DrawerFooter>
63
- <DrawerClose asChild>
64
- <Button variant="outline">Close</Button>
65
- </DrawerClose>
66
- </DrawerFooter>
67
- </DrawerContent>
68
- </Drawer>
69
- ),
70
- };
@@ -1,124 +0,0 @@
1
- import * as React from 'react';
2
- import { Drawer as DrawerPrimitive } from 'vaul';
3
-
4
- import { cn } from '@/lib/utils';
5
-
6
- /**
7
- * A panel that slides in from the edge of the screen, ideal for mobile-friendly interactions.
8
- * Built on Vaul with swipe-to-dismiss gestures. Supports top, bottom, left, and right directions.
9
- *
10
- * Compose with DrawerTrigger, DrawerContent, DrawerHeader, DrawerTitle, DrawerDescription, and DrawerFooter.
11
- */
12
- function Drawer({ ...props }: React.ComponentProps<typeof DrawerPrimitive.Root>) {
13
- return <DrawerPrimitive.Root data-slot="drawer" {...props} />;
14
- }
15
-
16
- /** Button or element that opens the drawer when clicked. */
17
- function DrawerTrigger({ ...props }: React.ComponentProps<typeof DrawerPrimitive.Trigger>) {
18
- return <DrawerPrimitive.Trigger data-slot="drawer-trigger" {...props} />;
19
- }
20
-
21
- /** Renders drawer content into a React portal. */
22
- function DrawerPortal({ ...props }: React.ComponentProps<typeof DrawerPrimitive.Portal>) {
23
- return <DrawerPrimitive.Portal data-slot="drawer-portal" {...props} />;
24
- }
25
-
26
- /** Programmatic close trigger for the drawer. */
27
- function DrawerClose({ ...props }: React.ComponentProps<typeof DrawerPrimitive.Close>) {
28
- return <DrawerPrimitive.Close data-slot="drawer-close" {...props} />;
29
- }
30
-
31
- /** Semi-transparent backdrop behind the drawer that dims the page content. */
32
- function DrawerOverlay({ className, ...props }: React.ComponentProps<typeof DrawerPrimitive.Overlay>) {
33
- return (
34
- <DrawerPrimitive.Overlay
35
- data-slot="drawer-overlay"
36
- className={cn(
37
- 'data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 fixed inset-0 z-50 bg-black/50',
38
- className,
39
- )}
40
- {...props}
41
- />
42
- );
43
- }
44
-
45
- /**
46
- * The main drawer panel that slides in from the configured direction.
47
- * Automatically shows a drag handle for bottom drawers.
48
- */
49
- function DrawerContent({ className, children, ...props }: React.ComponentProps<typeof DrawerPrimitive.Content>) {
50
- return (
51
- <DrawerPortal data-slot="drawer-portal">
52
- <DrawerOverlay />
53
- <DrawerPrimitive.Content
54
- data-slot="drawer-content"
55
- className={cn(
56
- 'group/drawer-content bg-background fixed z-50 flex h-auto flex-col',
57
- 'data-[vaul-drawer-direction=top]:inset-x-0 data-[vaul-drawer-direction=top]:top-0 data-[vaul-drawer-direction=top]:mb-24 data-[vaul-drawer-direction=top]:max-h-[80vh] data-[vaul-drawer-direction=top]:rounded-b-lg data-[vaul-drawer-direction=top]:border-b',
58
- 'data-[vaul-drawer-direction=bottom]:inset-x-0 data-[vaul-drawer-direction=bottom]:bottom-0 data-[vaul-drawer-direction=bottom]:mt-24 data-[vaul-drawer-direction=bottom]:max-h-[80vh] data-[vaul-drawer-direction=bottom]:rounded-t-lg data-[vaul-drawer-direction=bottom]:border-t',
59
- 'data-[vaul-drawer-direction=right]:inset-y-0 data-[vaul-drawer-direction=right]:right-0 data-[vaul-drawer-direction=right]:w-3/4 data-[vaul-drawer-direction=right]:border-l data-[vaul-drawer-direction=right]:sm:max-w-sm',
60
- 'data-[vaul-drawer-direction=left]:inset-y-0 data-[vaul-drawer-direction=left]:left-0 data-[vaul-drawer-direction=left]:w-3/4 data-[vaul-drawer-direction=left]:border-r data-[vaul-drawer-direction=left]:sm:max-w-sm',
61
- className,
62
- )}
63
- {...props}
64
- >
65
- <div className="bg-muted mx-auto mt-4 hidden h-2 w-[100px] shrink-0 rounded-full group-data-[vaul-drawer-direction=bottom]/drawer-content:block" />
66
- {children}
67
- </DrawerPrimitive.Content>
68
- </DrawerPortal>
69
- );
70
- }
71
-
72
- /** Container for DrawerTitle and DrawerDescription at the top of the drawer. */
73
- function DrawerHeader({ className, ...props }: React.ComponentProps<'div'>) {
74
- return (
75
- <div
76
- data-slot="drawer-header"
77
- className={cn(
78
- 'flex flex-col gap-0.5 p-4 group-data-[vaul-drawer-direction=bottom]/drawer-content:text-center group-data-[vaul-drawer-direction=top]/drawer-content:text-center md:gap-1.5 md:text-left',
79
- className,
80
- )}
81
- {...props}
82
- />
83
- );
84
- }
85
-
86
- /** Container for action buttons at the bottom of the drawer. */
87
- function DrawerFooter({ className, ...props }: React.ComponentProps<'div'>) {
88
- return <div data-slot="drawer-footer" className={cn('mt-auto flex flex-col gap-2 p-4', className)} {...props} />;
89
- }
90
-
91
- /** Accessible title for the drawer. */
92
- function DrawerTitle({ className, ...props }: React.ComponentProps<typeof DrawerPrimitive.Title>) {
93
- return (
94
- <DrawerPrimitive.Title
95
- data-slot="drawer-title"
96
- className={cn('text-foreground font-semibold', className)}
97
- {...props}
98
- />
99
- );
100
- }
101
-
102
- /** Accessible description text for the drawer, displayed below the title. */
103
- function DrawerDescription({ className, ...props }: React.ComponentProps<typeof DrawerPrimitive.Description>) {
104
- return (
105
- <DrawerPrimitive.Description
106
- data-slot="drawer-description"
107
- className={cn('text-muted-foreground text-sm', className)}
108
- {...props}
109
- />
110
- );
111
- }
112
-
113
- export {
114
- Drawer,
115
- DrawerPortal,
116
- DrawerOverlay,
117
- DrawerTrigger,
118
- DrawerClose,
119
- DrawerContent,
120
- DrawerHeader,
121
- DrawerFooter,
122
- DrawerTitle,
123
- DrawerDescription,
124
- };
@@ -1,74 +0,0 @@
1
- import type { Meta, StoryObj } from '@storybook/react-vite';
2
- import {
3
- DropdownMenu,
4
- DropdownMenuTrigger,
5
- DropdownMenuContent,
6
- DropdownMenuItem,
7
- DropdownMenuLabel,
8
- DropdownMenuSeparator,
9
- DropdownMenuShortcut,
10
- DropdownMenuGroup,
11
- } from '@/components/ui/DropdownMenu';
12
- import { Button } from '@/components/ui/Button';
13
- import { UserIcon, SettingsIcon, LogOutIcon, CreditCardIcon } from 'lucide-react';
14
-
15
- const meta: Meta<typeof DropdownMenu> = {
16
- title: 'UI Components/DropdownMenu',
17
- component: DropdownMenu,
18
- };
19
- export default meta;
20
- type Story = StoryObj<typeof DropdownMenu>;
21
-
22
- /** Shows a dropdown menu with grouped items, icons, keyboard shortcuts, and a destructive logout action. */
23
- export const Default: Story = {
24
- render: () => (
25
- <DropdownMenu>
26
- <DropdownMenuTrigger asChild>
27
- <Button variant="outline">Open Menu</Button>
28
- </DropdownMenuTrigger>
29
- <DropdownMenuContent className="w-56">
30
- <DropdownMenuLabel>My Account</DropdownMenuLabel>
31
- <DropdownMenuSeparator />
32
- <DropdownMenuGroup>
33
- <DropdownMenuItem>
34
- <UserIcon />
35
- <span>Profile</span>
36
- <DropdownMenuShortcut>Ctrl+P</DropdownMenuShortcut>
37
- </DropdownMenuItem>
38
- <DropdownMenuItem>
39
- <CreditCardIcon />
40
- <span>Billing</span>
41
- <DropdownMenuShortcut>Ctrl+B</DropdownMenuShortcut>
42
- </DropdownMenuItem>
43
- <DropdownMenuItem>
44
- <SettingsIcon />
45
- <span>Settings</span>
46
- <DropdownMenuShortcut>Ctrl+S</DropdownMenuShortcut>
47
- </DropdownMenuItem>
48
- </DropdownMenuGroup>
49
- <DropdownMenuSeparator />
50
- <DropdownMenuItem variant="destructive">
51
- <LogOutIcon />
52
- <span>Log out</span>
53
- </DropdownMenuItem>
54
- </DropdownMenuContent>
55
- </DropdownMenu>
56
- ),
57
- };
58
-
59
- /** Shows a minimal dropdown menu with basic edit/duplicate/delete actions. */
60
- export const Simple: Story = {
61
- render: () => (
62
- <DropdownMenu>
63
- <DropdownMenuTrigger asChild>
64
- <Button variant="outline">Actions</Button>
65
- </DropdownMenuTrigger>
66
- <DropdownMenuContent>
67
- <DropdownMenuItem>Edit</DropdownMenuItem>
68
- <DropdownMenuItem>Duplicate</DropdownMenuItem>
69
- <DropdownMenuSeparator />
70
- <DropdownMenuItem variant="destructive">Delete</DropdownMenuItem>
71
- </DropdownMenuContent>
72
- </DropdownMenu>
73
- ),
74
- };