@auto-engineer/generate-react-client 1.12.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (154) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/LICENSE +10 -0
  3. package/dist/src/commands/generate-react-client.d.ts +21 -0
  4. package/dist/src/commands/generate-react-client.d.ts.map +1 -0
  5. package/dist/src/commands/generate-react-client.js +62 -0
  6. package/dist/src/commands/generate-react-client.js.map +1 -0
  7. package/dist/src/copy-starter.d.ts +2 -0
  8. package/dist/src/copy-starter.d.ts.map +1 -0
  9. package/dist/src/copy-starter.js +34 -0
  10. package/dist/src/copy-starter.js.map +1 -0
  11. package/dist/src/index.d.ts +10 -0
  12. package/dist/src/index.d.ts.map +1 -0
  13. package/dist/src/index.js +4 -0
  14. package/dist/src/index.js.map +1 -0
  15. package/dist/starter/.storybook/main.ts +33 -0
  16. package/dist/starter/.storybook/preview.tsx +35 -0
  17. package/dist/starter/components.json +29 -0
  18. package/dist/starter/index.html +12 -0
  19. package/dist/starter/package.json +60 -0
  20. package/dist/starter/pnpm-lock.yaml +5236 -0
  21. package/dist/starter/public/mockServiceWorker.js +336 -0
  22. package/dist/starter/src/App.tsx +15 -0
  23. package/dist/starter/src/components/.gitkeep +0 -0
  24. package/dist/starter/src/components/ui/Accordion.stories.tsx +47 -0
  25. package/dist/starter/src/components/ui/Accordion.tsx +51 -0
  26. package/dist/starter/src/components/ui/Alert.stories.tsx +27 -0
  27. package/dist/starter/src/components/ui/Alert.tsx +49 -0
  28. package/dist/starter/src/components/ui/AlertDialog.stories.tsx +65 -0
  29. package/dist/starter/src/components/ui/AlertDialog.tsx +163 -0
  30. package/dist/starter/src/components/ui/AspectRatio.stories.tsx +33 -0
  31. package/dist/starter/src/components/ui/AspectRatio.tsx +9 -0
  32. package/dist/starter/src/components/ui/Avatar.stories.tsx +42 -0
  33. package/dist/starter/src/components/ui/Avatar.tsx +87 -0
  34. package/dist/starter/src/components/ui/Badge.stories.tsx +36 -0
  35. package/dist/starter/src/components/ui/Badge.tsx +40 -0
  36. package/dist/starter/src/components/ui/Breadcrumb.stories.tsx +52 -0
  37. package/dist/starter/src/components/ui/Breadcrumb.tsx +92 -0
  38. package/dist/starter/src/components/ui/Button.stories.tsx +92 -0
  39. package/dist/starter/src/components/ui/Button.tsx +62 -0
  40. package/dist/starter/src/components/ui/ButtonGroup.stories.tsx +30 -0
  41. package/dist/starter/src/components/ui/ButtonGroup.tsx +75 -0
  42. package/dist/starter/src/components/ui/Calendar.stories.tsx +38 -0
  43. package/dist/starter/src/components/ui/Calendar.tsx +159 -0
  44. package/dist/starter/src/components/ui/Card.stories.tsx +42 -0
  45. package/dist/starter/src/components/ui/Card.tsx +56 -0
  46. package/dist/starter/src/components/ui/Carousel.stories.tsx +54 -0
  47. package/dist/starter/src/components/ui/Carousel.tsx +216 -0
  48. package/dist/starter/src/components/ui/Chart.stories.tsx +38 -0
  49. package/dist/starter/src/components/ui/Chart.tsx +296 -0
  50. package/dist/starter/src/components/ui/Checkbox.stories.tsx +31 -0
  51. package/dist/starter/src/components/ui/Checkbox.tsx +29 -0
  52. package/dist/starter/src/components/ui/Collapsible.stories.tsx +56 -0
  53. package/dist/starter/src/components/ui/Collapsible.tsx +15 -0
  54. package/dist/starter/src/components/ui/Combobox.stories.tsx +73 -0
  55. package/dist/starter/src/components/ui/Combobox.tsx +267 -0
  56. package/dist/starter/src/components/ui/Command.stories.tsx +69 -0
  57. package/dist/starter/src/components/ui/Command.tsx +137 -0
  58. package/dist/starter/src/components/ui/ContextMenu.stories.tsx +66 -0
  59. package/dist/starter/src/components/ui/ContextMenu.tsx +211 -0
  60. package/dist/starter/src/components/ui/DesignSystem-Colors.mdx +68 -0
  61. package/dist/starter/src/components/ui/DesignSystem-Colors.stories.tsx +116 -0
  62. package/dist/starter/src/components/ui/DesignSystem-Layout.mdx +64 -0
  63. package/dist/starter/src/components/ui/DesignSystem-Layout.stories.tsx +166 -0
  64. package/dist/starter/src/components/ui/DesignSystem-Typography.mdx +31 -0
  65. package/dist/starter/src/components/ui/DesignSystem-Typography.stories.tsx +79 -0
  66. package/dist/starter/src/components/ui/Dialog.stories.tsx +72 -0
  67. package/dist/starter/src/components/ui/Dialog.tsx +136 -0
  68. package/dist/starter/src/components/ui/Direction.stories.tsx +36 -0
  69. package/dist/starter/src/components/ui/Direction.tsx +18 -0
  70. package/dist/starter/src/components/ui/Drawer.stories.tsx +68 -0
  71. package/dist/starter/src/components/ui/Drawer.tsx +106 -0
  72. package/dist/starter/src/components/ui/DropdownMenu.stories.tsx +72 -0
  73. package/dist/starter/src/components/ui/DropdownMenu.tsx +219 -0
  74. package/dist/starter/src/components/ui/Empty.stories.tsx +35 -0
  75. package/dist/starter/src/components/ui/Empty.tsx +85 -0
  76. package/dist/starter/src/components/ui/Field.stories.tsx +47 -0
  77. package/dist/starter/src/components/ui/Field.tsx +226 -0
  78. package/dist/starter/src/components/ui/Form.stories.tsx +44 -0
  79. package/dist/starter/src/components/ui/Form.tsx +136 -0
  80. package/dist/starter/src/components/ui/HoverCard.stories.tsx +47 -0
  81. package/dist/starter/src/components/ui/HoverCard.tsx +36 -0
  82. package/dist/starter/src/components/ui/Input.stories.tsx +38 -0
  83. package/dist/starter/src/components/ui/Input.tsx +21 -0
  84. package/dist/starter/src/components/ui/InputGroup.stories.tsx +50 -0
  85. package/dist/starter/src/components/ui/InputGroup.tsx +147 -0
  86. package/dist/starter/src/components/ui/InputOTP.stories.tsx +40 -0
  87. package/dist/starter/src/components/ui/InputOTP.tsx +68 -0
  88. package/dist/starter/src/components/ui/Item.stories.tsx +61 -0
  89. package/dist/starter/src/components/ui/Item.tsx +158 -0
  90. package/dist/starter/src/components/ui/Kbd.stories.tsx +54 -0
  91. package/dist/starter/src/components/ui/Kbd.tsx +18 -0
  92. package/dist/starter/src/components/ui/Label.stories.tsx +85 -0
  93. package/dist/starter/src/components/ui/Label.tsx +40 -0
  94. package/dist/starter/src/components/ui/Menubar.stories.tsx +76 -0
  95. package/dist/starter/src/components/ui/Menubar.tsx +236 -0
  96. package/dist/starter/src/components/ui/NativeSelect.stories.tsx +42 -0
  97. package/dist/starter/src/components/ui/NativeSelect.tsx +44 -0
  98. package/dist/starter/src/components/ui/NavigationMenu.stories.tsx +78 -0
  99. package/dist/starter/src/components/ui/NavigationMenu.tsx +142 -0
  100. package/dist/starter/src/components/ui/Pagination.stories.tsx +75 -0
  101. package/dist/starter/src/components/ui/Pagination.tsx +100 -0
  102. package/dist/starter/src/components/ui/Popover.stories.tsx +51 -0
  103. package/dist/starter/src/components/ui/Popover.tsx +52 -0
  104. package/dist/starter/src/components/ui/Progress.stories.tsx +28 -0
  105. package/dist/starter/src/components/ui/Progress.tsx +24 -0
  106. package/dist/starter/src/components/ui/RadioGroup.stories.tsx +48 -0
  107. package/dist/starter/src/components/ui/RadioGroup.tsx +31 -0
  108. package/dist/starter/src/components/ui/Resizable.stories.tsx +69 -0
  109. package/dist/starter/src/components/ui/Resizable.tsx +47 -0
  110. package/dist/starter/src/components/ui/ScrollArea.stories.tsx +43 -0
  111. package/dist/starter/src/components/ui/ScrollArea.tsx +46 -0
  112. package/dist/starter/src/components/ui/Select.stories.tsx +57 -0
  113. package/dist/starter/src/components/ui/Select.tsx +162 -0
  114. package/dist/starter/src/components/ui/Separator.stories.tsx +40 -0
  115. package/dist/starter/src/components/ui/Separator.tsx +26 -0
  116. package/dist/starter/src/components/ui/Sheet.stories.tsx +66 -0
  117. package/dist/starter/src/components/ui/Sheet.tsx +107 -0
  118. package/dist/starter/src/components/ui/Sidebar.stories.tsx +94 -0
  119. package/dist/starter/src/components/ui/Sidebar.tsx +675 -0
  120. package/dist/starter/src/components/ui/Skeleton.stories.tsx +38 -0
  121. package/dist/starter/src/components/ui/Skeleton.tsx +7 -0
  122. package/dist/starter/src/components/ui/Slider.stories.tsx +21 -0
  123. package/dist/starter/src/components/ui/Slider.tsx +54 -0
  124. package/dist/starter/src/components/ui/Sonner.stories.tsx +44 -0
  125. package/dist/starter/src/components/ui/Sonner.tsx +34 -0
  126. package/dist/starter/src/components/ui/Spinner.stories.tsx +23 -0
  127. package/dist/starter/src/components/ui/Spinner.tsx +9 -0
  128. package/dist/starter/src/components/ui/Switch.stories.tsx +35 -0
  129. package/dist/starter/src/components/ui/Switch.tsx +33 -0
  130. package/dist/starter/src/components/ui/Table.stories.tsx +65 -0
  131. package/dist/starter/src/components/ui/Table.tsx +75 -0
  132. package/dist/starter/src/components/ui/Tabs.stories.tsx +51 -0
  133. package/dist/starter/src/components/ui/Tabs.tsx +69 -0
  134. package/dist/starter/src/components/ui/Textarea.stories.tsx +24 -0
  135. package/dist/starter/src/components/ui/Textarea.tsx +18 -0
  136. package/dist/starter/src/components/ui/Toast.stories.tsx +112 -0
  137. package/dist/starter/src/components/ui/Toast.tsx +114 -0
  138. package/dist/starter/src/components/ui/Toaster.tsx +28 -0
  139. package/dist/starter/src/components/ui/Toggle.stories.tsx +40 -0
  140. package/dist/starter/src/components/ui/Toggle.tsx +41 -0
  141. package/dist/starter/src/components/ui/ToggleGroup.stories.tsx +58 -0
  142. package/dist/starter/src/components/ui/ToggleGroup.tsx +80 -0
  143. package/dist/starter/src/components/ui/Tooltip.stories.tsx +40 -0
  144. package/dist/starter/src/components/ui/Tooltip.tsx +42 -0
  145. package/dist/starter/src/hooks/use-mobile.ts +19 -0
  146. package/dist/starter/src/hooks/use-toast.ts +186 -0
  147. package/dist/starter/src/index.css +123 -0
  148. package/dist/starter/src/lib/utils.ts +6 -0
  149. package/dist/starter/src/main.tsx +5 -0
  150. package/dist/starter/tsconfig.app.json +25 -0
  151. package/dist/starter/tsconfig.json +4 -0
  152. package/dist/starter/vite.config.ts +16 -0
  153. package/dist/tsconfig.tsbuildinfo +1 -0
  154. package/package.json +37 -0
@@ -0,0 +1,112 @@
1
+ import type { Meta, StoryObj } from '@storybook/react-vite';
2
+ import { Button } from '@/components/ui/Button';
3
+ import {
4
+ Toast,
5
+ ToastAction,
6
+ ToastClose,
7
+ ToastDescription,
8
+ ToastProvider,
9
+ ToastTitle,
10
+ ToastViewport,
11
+ } from '@/components/ui/Toast';
12
+ import { Toaster } from '@/components/ui/Toaster';
13
+ import { useToast } from '@/hooks/use-toast';
14
+
15
+ const meta: Meta<typeof Toast> = {
16
+ title: 'Toast',
17
+ component: Toast,
18
+ };
19
+ export default meta;
20
+ type Story = StoryObj<typeof Toast>;
21
+
22
+ function ToastDemo() {
23
+ const { toast } = useToast();
24
+
25
+ return (
26
+ <div>
27
+ <Toaster />
28
+ <Button
29
+ variant="outline"
30
+ onClick={() => {
31
+ toast({
32
+ title: 'Scheduled: Catch up',
33
+ description: 'Friday, February 10, 2026 at 5:57 PM',
34
+ });
35
+ }}
36
+ >
37
+ Show Toast
38
+ </Button>
39
+ </div>
40
+ );
41
+ }
42
+
43
+ export const Default: Story = {
44
+ render: () => <ToastDemo />,
45
+ };
46
+
47
+ function ToastDestructiveDemo() {
48
+ const { toast } = useToast();
49
+
50
+ return (
51
+ <div>
52
+ <Toaster />
53
+ <Button
54
+ variant="outline"
55
+ onClick={() => {
56
+ toast({
57
+ variant: 'destructive',
58
+ title: 'Uh oh! Something went wrong.',
59
+ description: 'There was a problem with your request.',
60
+ });
61
+ }}
62
+ >
63
+ Show Destructive Toast
64
+ </Button>
65
+ </div>
66
+ );
67
+ }
68
+
69
+ export const Destructive: Story = {
70
+ render: () => <ToastDestructiveDemo />,
71
+ };
72
+
73
+ function ToastWithActionDemo() {
74
+ const { toast } = useToast();
75
+
76
+ return (
77
+ <div>
78
+ <Toaster />
79
+ <Button
80
+ variant="outline"
81
+ onClick={() => {
82
+ toast({
83
+ title: 'Event created',
84
+ description: 'Sunday, December 03, 2023 at 9:00 AM',
85
+ action: <ToastAction altText="Undo">Undo</ToastAction>,
86
+ });
87
+ }}
88
+ >
89
+ Show Toast with Action
90
+ </Button>
91
+ </div>
92
+ );
93
+ }
94
+
95
+ export const WithAction: Story = {
96
+ render: () => <ToastWithActionDemo />,
97
+ };
98
+
99
+ export const Inline: Story = {
100
+ render: () => (
101
+ <ToastProvider>
102
+ <Toast open>
103
+ <div className="grid gap-1">
104
+ <ToastTitle>Toast Title</ToastTitle>
105
+ <ToastDescription>This is a toast description.</ToastDescription>
106
+ </div>
107
+ <ToastClose />
108
+ </Toast>
109
+ <ToastViewport />
110
+ </ToastProvider>
111
+ ),
112
+ };
@@ -0,0 +1,114 @@
1
+ 'use client';
2
+
3
+ import * as React from 'react';
4
+ import { cva, type VariantProps } from 'class-variance-authority';
5
+ import { XIcon } from 'lucide-react';
6
+ import { Toast as ToastPrimitive } from 'radix-ui';
7
+
8
+ import { cn } from '@/lib/utils';
9
+
10
+ function ToastProvider({ ...props }: React.ComponentProps<typeof ToastPrimitive.Provider>) {
11
+ return <ToastPrimitive.Provider data-slot="toast-provider" {...props} />;
12
+ }
13
+
14
+ function ToastViewport({ className, ...props }: React.ComponentProps<typeof ToastPrimitive.Viewport>) {
15
+ return (
16
+ <ToastPrimitive.Viewport
17
+ data-slot="toast-viewport"
18
+ className={cn(
19
+ 'fixed top-0 z-[100] flex max-h-screen w-full flex-col-reverse p-4 sm:bottom-0 sm:right-0 sm:top-auto sm:flex-col md:max-w-[420px]',
20
+ className,
21
+ )}
22
+ {...props}
23
+ />
24
+ );
25
+ }
26
+
27
+ const toastVariants = cva(
28
+ 'group pointer-events-auto relative flex w-full items-center justify-between space-x-2 overflow-hidden rounded-md border p-4 pr-6 shadow-lg transition-all data-[swipe=cancel]:translate-x-0 data-[swipe=end]:translate-x-[var(--radix-toast-swipe-end-x)] data-[swipe=move]:translate-x-[var(--radix-toast-swipe-move-x)] data-[swipe=move]:transition-none data-[state=open]:animate-in data-[state=closed]:animate-out data-[swipe=end]:animate-out data-[state=closed]:fade-out-80 data-[state=closed]:slide-out-to-right-full data-[state=open]:slide-in-from-top-full data-[state=open]:sm:slide-in-from-bottom-full',
29
+ {
30
+ variants: {
31
+ variant: {
32
+ default: 'border bg-background text-foreground',
33
+ destructive: 'destructive group border-destructive bg-destructive text-destructive-foreground',
34
+ },
35
+ },
36
+ defaultVariants: {
37
+ variant: 'default',
38
+ },
39
+ },
40
+ );
41
+
42
+ function Toast({
43
+ className,
44
+ variant,
45
+ ...props
46
+ }: React.ComponentProps<typeof ToastPrimitive.Root> & VariantProps<typeof toastVariants>) {
47
+ return <ToastPrimitive.Root data-slot="toast" className={cn(toastVariants({ variant }), className)} {...props} />;
48
+ }
49
+
50
+ function ToastAction({ className, ...props }: React.ComponentProps<typeof ToastPrimitive.Action>) {
51
+ return (
52
+ <ToastPrimitive.Action
53
+ data-slot="toast-action"
54
+ className={cn(
55
+ 'inline-flex h-8 shrink-0 items-center justify-center rounded-md border bg-transparent px-3 text-sm font-medium transition-colors hover:bg-secondary focus:outline-none focus:ring-1 focus:ring-ring disabled:pointer-events-none disabled:opacity-50 group-[.destructive]:border-muted/40 group-[.destructive]:hover:border-destructive/30 group-[.destructive]:hover:bg-destructive group-[.destructive]:hover:text-destructive-foreground group-[.destructive]:focus:ring-destructive',
56
+ className,
57
+ )}
58
+ {...props}
59
+ />
60
+ );
61
+ }
62
+
63
+ function ToastClose({ className, ...props }: React.ComponentProps<typeof ToastPrimitive.Close>) {
64
+ return (
65
+ <ToastPrimitive.Close
66
+ data-slot="toast-close"
67
+ className={cn(
68
+ 'absolute right-1 top-1 rounded-md p-1 text-foreground/50 opacity-0 transition-opacity hover:text-foreground focus:opacity-100 focus:outline-none focus:ring-1 group-hover:opacity-100 group-[.destructive]:text-red-300 group-[.destructive]:hover:text-red-50 group-[.destructive]:focus:ring-red-400 group-[.destructive]:focus:ring-offset-red-600',
69
+ className,
70
+ )}
71
+ toast-close=""
72
+ {...props}
73
+ >
74
+ <XIcon className="h-4 w-4" />
75
+ </ToastPrimitive.Close>
76
+ );
77
+ }
78
+
79
+ function ToastTitle({ className, ...props }: React.ComponentProps<typeof ToastPrimitive.Title>) {
80
+ return (
81
+ <ToastPrimitive.Title
82
+ data-slot="toast-title"
83
+ className={cn('text-sm font-semibold [&+div]:text-xs', className)}
84
+ {...props}
85
+ />
86
+ );
87
+ }
88
+
89
+ function ToastDescription({ className, ...props }: React.ComponentProps<typeof ToastPrimitive.Description>) {
90
+ return (
91
+ <ToastPrimitive.Description
92
+ data-slot="toast-description"
93
+ className={cn('text-sm opacity-90', className)}
94
+ {...props}
95
+ />
96
+ );
97
+ }
98
+
99
+ type ToastProps = React.ComponentPropsWithoutRef<typeof Toast>;
100
+
101
+ type ToastActionElement = React.ReactElement<typeof ToastAction>;
102
+
103
+ export {
104
+ type ToastProps,
105
+ type ToastActionElement,
106
+ ToastProvider,
107
+ ToastViewport,
108
+ Toast,
109
+ ToastTitle,
110
+ ToastDescription,
111
+ ToastClose,
112
+ ToastAction,
113
+ toastVariants,
114
+ };
@@ -0,0 +1,28 @@
1
+ 'use client';
2
+
3
+ import { useToast } from '@/hooks/use-toast';
4
+ import { Toast, ToastClose, ToastDescription, ToastProvider, ToastTitle, ToastViewport } from '@/components/ui/Toast';
5
+
6
+ function Toaster() {
7
+ const { toasts } = useToast();
8
+
9
+ return (
10
+ <ToastProvider>
11
+ {toasts.map(function ({ id, title, description, action, ...props }) {
12
+ return (
13
+ <Toast key={id} {...props}>
14
+ <div className="grid gap-1">
15
+ {title && <ToastTitle>{title}</ToastTitle>}
16
+ {description && <ToastDescription>{description}</ToastDescription>}
17
+ </div>
18
+ {action}
19
+ <ToastClose />
20
+ </Toast>
21
+ );
22
+ })}
23
+ <ToastViewport />
24
+ </ToastProvider>
25
+ );
26
+ }
27
+
28
+ export { Toaster };
@@ -0,0 +1,40 @@
1
+ import type { Meta, StoryObj } from '@storybook/react-vite';
2
+ import { BoldIcon } from 'lucide-react';
3
+ import { Toggle } from '@/components/ui/Toggle';
4
+
5
+ const meta: Meta<typeof Toggle> = {
6
+ title: 'Toggle',
7
+ component: Toggle,
8
+ };
9
+ export default meta;
10
+ type Story = StoryObj<typeof Toggle>;
11
+
12
+ export const Default: Story = {
13
+ args: {
14
+ 'aria-label': 'Toggle bold',
15
+ children: <BoldIcon />,
16
+ },
17
+ };
18
+
19
+ export const Outline: Story = {
20
+ args: {
21
+ variant: 'outline',
22
+ 'aria-label': 'Toggle bold',
23
+ children: <BoldIcon />,
24
+ },
25
+ };
26
+
27
+ export const WithText: Story = {
28
+ args: {
29
+ 'aria-label': 'Toggle italic',
30
+ children: 'Italic',
31
+ },
32
+ };
33
+
34
+ export const Pressed: Story = {
35
+ args: {
36
+ defaultPressed: true,
37
+ 'aria-label': 'Toggle bold',
38
+ children: <BoldIcon />,
39
+ },
40
+ };
@@ -0,0 +1,41 @@
1
+ 'use client';
2
+
3
+ import * as React from 'react';
4
+ import { cva, type VariantProps } from 'class-variance-authority';
5
+ import { Toggle as TogglePrimitive } from 'radix-ui';
6
+
7
+ import { cn } from '@/lib/utils';
8
+
9
+ const toggleVariants = cva(
10
+ "inline-flex items-center justify-center gap-2 rounded-md text-sm font-medium hover:bg-muted hover:text-muted-foreground disabled:pointer-events-none disabled:opacity-50 data-[state=on]:bg-accent data-[state=on]:text-accent-foreground [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 [&_svg]:shrink-0 focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] outline-none transition-[color,box-shadow] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive whitespace-nowrap",
11
+ {
12
+ variants: {
13
+ variant: {
14
+ default: 'bg-transparent',
15
+ outline: 'border border-input bg-transparent shadow-xs hover:bg-accent hover:text-accent-foreground',
16
+ },
17
+ size: {
18
+ default: 'h-9 px-2 min-w-9',
19
+ sm: 'h-8 px-1.5 min-w-8',
20
+ lg: 'h-10 px-2.5 min-w-10',
21
+ },
22
+ },
23
+ defaultVariants: {
24
+ variant: 'default',
25
+ size: 'default',
26
+ },
27
+ },
28
+ );
29
+
30
+ function Toggle({
31
+ className,
32
+ variant,
33
+ size,
34
+ ...props
35
+ }: React.ComponentProps<typeof TogglePrimitive.Root> & VariantProps<typeof toggleVariants>) {
36
+ return (
37
+ <TogglePrimitive.Root data-slot="toggle" className={cn(toggleVariants({ variant, size, className }))} {...props} />
38
+ );
39
+ }
40
+
41
+ export { Toggle, toggleVariants };
@@ -0,0 +1,58 @@
1
+ import type { Meta, StoryObj } from '@storybook/react-vite';
2
+ import { BoldIcon, ItalicIcon, UnderlineIcon } from 'lucide-react';
3
+ import { ToggleGroup, ToggleGroupItem } from '@/components/ui/ToggleGroup';
4
+
5
+ const meta: Meta<typeof ToggleGroup> = {
6
+ title: 'ToggleGroup',
7
+ component: ToggleGroup,
8
+ };
9
+ export default meta;
10
+ type Story = StoryObj<typeof ToggleGroup>;
11
+
12
+ export const Single: Story = {
13
+ render: () => (
14
+ <ToggleGroup type="single">
15
+ <ToggleGroupItem value="bold" aria-label="Toggle bold">
16
+ <BoldIcon />
17
+ </ToggleGroupItem>
18
+ <ToggleGroupItem value="italic" aria-label="Toggle italic">
19
+ <ItalicIcon />
20
+ </ToggleGroupItem>
21
+ <ToggleGroupItem value="underline" aria-label="Toggle underline">
22
+ <UnderlineIcon />
23
+ </ToggleGroupItem>
24
+ </ToggleGroup>
25
+ ),
26
+ };
27
+
28
+ export const Multiple: Story = {
29
+ render: () => (
30
+ <ToggleGroup type="multiple" defaultValue={['bold', 'italic']}>
31
+ <ToggleGroupItem value="bold" aria-label="Toggle bold">
32
+ <BoldIcon />
33
+ </ToggleGroupItem>
34
+ <ToggleGroupItem value="italic" aria-label="Toggle italic">
35
+ <ItalicIcon />
36
+ </ToggleGroupItem>
37
+ <ToggleGroupItem value="underline" aria-label="Toggle underline">
38
+ <UnderlineIcon />
39
+ </ToggleGroupItem>
40
+ </ToggleGroup>
41
+ ),
42
+ };
43
+
44
+ export const Outline: Story = {
45
+ render: () => (
46
+ <ToggleGroup type="single" variant="outline">
47
+ <ToggleGroupItem value="bold" aria-label="Toggle bold">
48
+ <BoldIcon />
49
+ </ToggleGroupItem>
50
+ <ToggleGroupItem value="italic" aria-label="Toggle italic">
51
+ <ItalicIcon />
52
+ </ToggleGroupItem>
53
+ <ToggleGroupItem value="underline" aria-label="Toggle underline">
54
+ <UnderlineIcon />
55
+ </ToggleGroupItem>
56
+ </ToggleGroup>
57
+ ),
58
+ };
@@ -0,0 +1,80 @@
1
+ 'use client';
2
+
3
+ import * as React from 'react';
4
+ import { type VariantProps } from 'class-variance-authority';
5
+ import { ToggleGroup as ToggleGroupPrimitive } from 'radix-ui';
6
+
7
+ import { cn } from '@/lib/utils';
8
+ import { toggleVariants } from '@/components/ui/Toggle';
9
+
10
+ const ToggleGroupContext = React.createContext<
11
+ VariantProps<typeof toggleVariants> & {
12
+ spacing?: number;
13
+ }
14
+ >({
15
+ size: 'default',
16
+ variant: 'default',
17
+ spacing: 0,
18
+ });
19
+
20
+ function ToggleGroup({
21
+ className,
22
+ variant,
23
+ size,
24
+ spacing = 0,
25
+ children,
26
+ ...props
27
+ }: React.ComponentProps<typeof ToggleGroupPrimitive.Root> &
28
+ VariantProps<typeof toggleVariants> & {
29
+ spacing?: number;
30
+ }) {
31
+ return (
32
+ <ToggleGroupPrimitive.Root
33
+ data-slot="toggle-group"
34
+ data-variant={variant}
35
+ data-size={size}
36
+ data-spacing={spacing}
37
+ style={{ '--gap': spacing } as React.CSSProperties}
38
+ className={cn(
39
+ 'group/toggle-group flex w-fit items-center gap-[--spacing(var(--gap))] rounded-md data-[spacing=default]:data-[variant=outline]:shadow-xs',
40
+ className,
41
+ )}
42
+ {...props}
43
+ >
44
+ <ToggleGroupContext.Provider value={{ variant, size, spacing }}>{children}</ToggleGroupContext.Provider>
45
+ </ToggleGroupPrimitive.Root>
46
+ );
47
+ }
48
+
49
+ function ToggleGroupItem({
50
+ className,
51
+ children,
52
+ variant,
53
+ size,
54
+ ...props
55
+ }: React.ComponentProps<typeof ToggleGroupPrimitive.Item> & VariantProps<typeof toggleVariants>) {
56
+ const context = React.useContext(ToggleGroupContext);
57
+
58
+ return (
59
+ <ToggleGroupPrimitive.Item
60
+ data-slot="toggle-group-item"
61
+ data-variant={context.variant || variant}
62
+ data-size={context.size || size}
63
+ data-spacing={context.spacing}
64
+ className={cn(
65
+ toggleVariants({
66
+ variant: context.variant || variant,
67
+ size: context.size || size,
68
+ }),
69
+ 'w-auto min-w-0 shrink-0 px-3 focus:z-10 focus-visible:z-10',
70
+ 'data-[spacing=0]:rounded-none data-[spacing=0]:shadow-none data-[spacing=0]:first:rounded-l-md data-[spacing=0]:last:rounded-r-md data-[spacing=0]:data-[variant=outline]:border-l-0 data-[spacing=0]:data-[variant=outline]:first:border-l',
71
+ className,
72
+ )}
73
+ {...props}
74
+ >
75
+ {children}
76
+ </ToggleGroupPrimitive.Item>
77
+ );
78
+ }
79
+
80
+ export { ToggleGroup, ToggleGroupItem };
@@ -0,0 +1,40 @@
1
+ import type { Meta, StoryObj } from '@storybook/react-vite';
2
+ import { Button } from '@/components/ui/Button';
3
+ import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from '@/components/ui/Tooltip';
4
+
5
+ const meta: Meta<typeof Tooltip> = {
6
+ title: 'Tooltip',
7
+ component: Tooltip,
8
+ };
9
+ export default meta;
10
+ type Story = StoryObj<typeof Tooltip>;
11
+
12
+ export const Default: Story = {
13
+ render: () => (
14
+ <TooltipProvider>
15
+ <Tooltip>
16
+ <TooltipTrigger asChild>
17
+ <Button variant="outline">Hover me</Button>
18
+ </TooltipTrigger>
19
+ <TooltipContent>
20
+ <p>This is a tooltip</p>
21
+ </TooltipContent>
22
+ </Tooltip>
23
+ </TooltipProvider>
24
+ ),
25
+ };
26
+
27
+ export const WithSideOffset: Story = {
28
+ render: () => (
29
+ <TooltipProvider>
30
+ <Tooltip>
31
+ <TooltipTrigger asChild>
32
+ <Button variant="outline">With offset</Button>
33
+ </TooltipTrigger>
34
+ <TooltipContent sideOffset={8}>
35
+ <p>Tooltip with side offset</p>
36
+ </TooltipContent>
37
+ </Tooltip>
38
+ </TooltipProvider>
39
+ ),
40
+ };
@@ -0,0 +1,42 @@
1
+ import * as React from 'react';
2
+ import { Tooltip as TooltipPrimitive } from 'radix-ui';
3
+
4
+ import { cn } from '@/lib/utils';
5
+
6
+ function TooltipProvider({ delayDuration = 0, ...props }: React.ComponentProps<typeof TooltipPrimitive.Provider>) {
7
+ return <TooltipPrimitive.Provider data-slot="tooltip-provider" delayDuration={delayDuration} {...props} />;
8
+ }
9
+
10
+ function Tooltip({ ...props }: React.ComponentProps<typeof TooltipPrimitive.Root>) {
11
+ return <TooltipPrimitive.Root data-slot="tooltip" {...props} />;
12
+ }
13
+
14
+ function TooltipTrigger({ ...props }: React.ComponentProps<typeof TooltipPrimitive.Trigger>) {
15
+ return <TooltipPrimitive.Trigger data-slot="tooltip-trigger" {...props} />;
16
+ }
17
+
18
+ function TooltipContent({
19
+ className,
20
+ sideOffset = 0,
21
+ children,
22
+ ...props
23
+ }: React.ComponentProps<typeof TooltipPrimitive.Content>) {
24
+ return (
25
+ <TooltipPrimitive.Portal>
26
+ <TooltipPrimitive.Content
27
+ data-slot="tooltip-content"
28
+ sideOffset={sideOffset}
29
+ className={cn(
30
+ 'bg-foreground text-background animate-in fade-in-0 zoom-in-95 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-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 w-fit origin-(--radix-tooltip-content-transform-origin) rounded-md px-3 py-1.5 text-xs text-balance',
31
+ className,
32
+ )}
33
+ {...props}
34
+ >
35
+ {children}
36
+ <TooltipPrimitive.Arrow className="bg-foreground fill-foreground z-50 size-2.5 translate-y-[calc(-50%_-_2px)] rotate-45 rounded-[2px]" />
37
+ </TooltipPrimitive.Content>
38
+ </TooltipPrimitive.Portal>
39
+ );
40
+ }
41
+
42
+ export { Tooltip, TooltipTrigger, TooltipContent, TooltipProvider };
@@ -0,0 +1,19 @@
1
+ import * as React from 'react';
2
+
3
+ const MOBILE_BREAKPOINT = 768;
4
+
5
+ export function useIsMobile() {
6
+ const [isMobile, setIsMobile] = React.useState<boolean | undefined>(undefined);
7
+
8
+ React.useEffect(() => {
9
+ const mql = window.matchMedia(`(max-width: ${MOBILE_BREAKPOINT - 1}px)`);
10
+ const onChange = () => {
11
+ setIsMobile(window.innerWidth < MOBILE_BREAKPOINT);
12
+ };
13
+ mql.addEventListener('change', onChange);
14
+ setIsMobile(window.innerWidth < MOBILE_BREAKPOINT);
15
+ return () => mql.removeEventListener('change', onChange);
16
+ }, []);
17
+
18
+ return !!isMobile;
19
+ }