@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.
- package/CHANGELOG.md +12 -0
- package/LICENSE +10 -0
- package/dist/src/commands/generate-react-client.d.ts +21 -0
- package/dist/src/commands/generate-react-client.d.ts.map +1 -0
- package/dist/src/commands/generate-react-client.js +62 -0
- package/dist/src/commands/generate-react-client.js.map +1 -0
- package/dist/src/copy-starter.d.ts +2 -0
- package/dist/src/copy-starter.d.ts.map +1 -0
- package/dist/src/copy-starter.js +34 -0
- package/dist/src/copy-starter.js.map +1 -0
- package/dist/src/index.d.ts +10 -0
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/index.js +4 -0
- package/dist/src/index.js.map +1 -0
- package/dist/starter/.storybook/main.ts +33 -0
- package/dist/starter/.storybook/preview.tsx +35 -0
- package/dist/starter/components.json +29 -0
- package/dist/starter/index.html +12 -0
- package/dist/starter/package.json +60 -0
- package/dist/starter/pnpm-lock.yaml +5236 -0
- package/dist/starter/public/mockServiceWorker.js +336 -0
- package/dist/starter/src/App.tsx +15 -0
- package/dist/starter/src/components/.gitkeep +0 -0
- package/dist/starter/src/components/ui/Accordion.stories.tsx +47 -0
- package/dist/starter/src/components/ui/Accordion.tsx +51 -0
- package/dist/starter/src/components/ui/Alert.stories.tsx +27 -0
- package/dist/starter/src/components/ui/Alert.tsx +49 -0
- package/dist/starter/src/components/ui/AlertDialog.stories.tsx +65 -0
- package/dist/starter/src/components/ui/AlertDialog.tsx +163 -0
- package/dist/starter/src/components/ui/AspectRatio.stories.tsx +33 -0
- package/dist/starter/src/components/ui/AspectRatio.tsx +9 -0
- package/dist/starter/src/components/ui/Avatar.stories.tsx +42 -0
- package/dist/starter/src/components/ui/Avatar.tsx +87 -0
- package/dist/starter/src/components/ui/Badge.stories.tsx +36 -0
- package/dist/starter/src/components/ui/Badge.tsx +40 -0
- package/dist/starter/src/components/ui/Breadcrumb.stories.tsx +52 -0
- package/dist/starter/src/components/ui/Breadcrumb.tsx +92 -0
- package/dist/starter/src/components/ui/Button.stories.tsx +92 -0
- package/dist/starter/src/components/ui/Button.tsx +62 -0
- package/dist/starter/src/components/ui/ButtonGroup.stories.tsx +30 -0
- package/dist/starter/src/components/ui/ButtonGroup.tsx +75 -0
- package/dist/starter/src/components/ui/Calendar.stories.tsx +38 -0
- package/dist/starter/src/components/ui/Calendar.tsx +159 -0
- package/dist/starter/src/components/ui/Card.stories.tsx +42 -0
- package/dist/starter/src/components/ui/Card.tsx +56 -0
- package/dist/starter/src/components/ui/Carousel.stories.tsx +54 -0
- package/dist/starter/src/components/ui/Carousel.tsx +216 -0
- package/dist/starter/src/components/ui/Chart.stories.tsx +38 -0
- package/dist/starter/src/components/ui/Chart.tsx +296 -0
- package/dist/starter/src/components/ui/Checkbox.stories.tsx +31 -0
- package/dist/starter/src/components/ui/Checkbox.tsx +29 -0
- package/dist/starter/src/components/ui/Collapsible.stories.tsx +56 -0
- package/dist/starter/src/components/ui/Collapsible.tsx +15 -0
- package/dist/starter/src/components/ui/Combobox.stories.tsx +73 -0
- package/dist/starter/src/components/ui/Combobox.tsx +267 -0
- package/dist/starter/src/components/ui/Command.stories.tsx +69 -0
- package/dist/starter/src/components/ui/Command.tsx +137 -0
- package/dist/starter/src/components/ui/ContextMenu.stories.tsx +66 -0
- package/dist/starter/src/components/ui/ContextMenu.tsx +211 -0
- package/dist/starter/src/components/ui/DesignSystem-Colors.mdx +68 -0
- package/dist/starter/src/components/ui/DesignSystem-Colors.stories.tsx +116 -0
- package/dist/starter/src/components/ui/DesignSystem-Layout.mdx +64 -0
- package/dist/starter/src/components/ui/DesignSystem-Layout.stories.tsx +166 -0
- package/dist/starter/src/components/ui/DesignSystem-Typography.mdx +31 -0
- package/dist/starter/src/components/ui/DesignSystem-Typography.stories.tsx +79 -0
- package/dist/starter/src/components/ui/Dialog.stories.tsx +72 -0
- package/dist/starter/src/components/ui/Dialog.tsx +136 -0
- package/dist/starter/src/components/ui/Direction.stories.tsx +36 -0
- package/dist/starter/src/components/ui/Direction.tsx +18 -0
- package/dist/starter/src/components/ui/Drawer.stories.tsx +68 -0
- package/dist/starter/src/components/ui/Drawer.tsx +106 -0
- package/dist/starter/src/components/ui/DropdownMenu.stories.tsx +72 -0
- package/dist/starter/src/components/ui/DropdownMenu.tsx +219 -0
- package/dist/starter/src/components/ui/Empty.stories.tsx +35 -0
- package/dist/starter/src/components/ui/Empty.tsx +85 -0
- package/dist/starter/src/components/ui/Field.stories.tsx +47 -0
- package/dist/starter/src/components/ui/Field.tsx +226 -0
- package/dist/starter/src/components/ui/Form.stories.tsx +44 -0
- package/dist/starter/src/components/ui/Form.tsx +136 -0
- package/dist/starter/src/components/ui/HoverCard.stories.tsx +47 -0
- package/dist/starter/src/components/ui/HoverCard.tsx +36 -0
- package/dist/starter/src/components/ui/Input.stories.tsx +38 -0
- package/dist/starter/src/components/ui/Input.tsx +21 -0
- package/dist/starter/src/components/ui/InputGroup.stories.tsx +50 -0
- package/dist/starter/src/components/ui/InputGroup.tsx +147 -0
- package/dist/starter/src/components/ui/InputOTP.stories.tsx +40 -0
- package/dist/starter/src/components/ui/InputOTP.tsx +68 -0
- package/dist/starter/src/components/ui/Item.stories.tsx +61 -0
- package/dist/starter/src/components/ui/Item.tsx +158 -0
- package/dist/starter/src/components/ui/Kbd.stories.tsx +54 -0
- package/dist/starter/src/components/ui/Kbd.tsx +18 -0
- package/dist/starter/src/components/ui/Label.stories.tsx +85 -0
- package/dist/starter/src/components/ui/Label.tsx +40 -0
- package/dist/starter/src/components/ui/Menubar.stories.tsx +76 -0
- package/dist/starter/src/components/ui/Menubar.tsx +236 -0
- package/dist/starter/src/components/ui/NativeSelect.stories.tsx +42 -0
- package/dist/starter/src/components/ui/NativeSelect.tsx +44 -0
- package/dist/starter/src/components/ui/NavigationMenu.stories.tsx +78 -0
- package/dist/starter/src/components/ui/NavigationMenu.tsx +142 -0
- package/dist/starter/src/components/ui/Pagination.stories.tsx +75 -0
- package/dist/starter/src/components/ui/Pagination.tsx +100 -0
- package/dist/starter/src/components/ui/Popover.stories.tsx +51 -0
- package/dist/starter/src/components/ui/Popover.tsx +52 -0
- package/dist/starter/src/components/ui/Progress.stories.tsx +28 -0
- package/dist/starter/src/components/ui/Progress.tsx +24 -0
- package/dist/starter/src/components/ui/RadioGroup.stories.tsx +48 -0
- package/dist/starter/src/components/ui/RadioGroup.tsx +31 -0
- package/dist/starter/src/components/ui/Resizable.stories.tsx +69 -0
- package/dist/starter/src/components/ui/Resizable.tsx +47 -0
- package/dist/starter/src/components/ui/ScrollArea.stories.tsx +43 -0
- package/dist/starter/src/components/ui/ScrollArea.tsx +46 -0
- package/dist/starter/src/components/ui/Select.stories.tsx +57 -0
- package/dist/starter/src/components/ui/Select.tsx +162 -0
- package/dist/starter/src/components/ui/Separator.stories.tsx +40 -0
- package/dist/starter/src/components/ui/Separator.tsx +26 -0
- package/dist/starter/src/components/ui/Sheet.stories.tsx +66 -0
- package/dist/starter/src/components/ui/Sheet.tsx +107 -0
- package/dist/starter/src/components/ui/Sidebar.stories.tsx +94 -0
- package/dist/starter/src/components/ui/Sidebar.tsx +675 -0
- package/dist/starter/src/components/ui/Skeleton.stories.tsx +38 -0
- package/dist/starter/src/components/ui/Skeleton.tsx +7 -0
- package/dist/starter/src/components/ui/Slider.stories.tsx +21 -0
- package/dist/starter/src/components/ui/Slider.tsx +54 -0
- package/dist/starter/src/components/ui/Sonner.stories.tsx +44 -0
- package/dist/starter/src/components/ui/Sonner.tsx +34 -0
- package/dist/starter/src/components/ui/Spinner.stories.tsx +23 -0
- package/dist/starter/src/components/ui/Spinner.tsx +9 -0
- package/dist/starter/src/components/ui/Switch.stories.tsx +35 -0
- package/dist/starter/src/components/ui/Switch.tsx +33 -0
- package/dist/starter/src/components/ui/Table.stories.tsx +65 -0
- package/dist/starter/src/components/ui/Table.tsx +75 -0
- package/dist/starter/src/components/ui/Tabs.stories.tsx +51 -0
- package/dist/starter/src/components/ui/Tabs.tsx +69 -0
- package/dist/starter/src/components/ui/Textarea.stories.tsx +24 -0
- package/dist/starter/src/components/ui/Textarea.tsx +18 -0
- package/dist/starter/src/components/ui/Toast.stories.tsx +112 -0
- package/dist/starter/src/components/ui/Toast.tsx +114 -0
- package/dist/starter/src/components/ui/Toaster.tsx +28 -0
- package/dist/starter/src/components/ui/Toggle.stories.tsx +40 -0
- package/dist/starter/src/components/ui/Toggle.tsx +41 -0
- package/dist/starter/src/components/ui/ToggleGroup.stories.tsx +58 -0
- package/dist/starter/src/components/ui/ToggleGroup.tsx +80 -0
- package/dist/starter/src/components/ui/Tooltip.stories.tsx +40 -0
- package/dist/starter/src/components/ui/Tooltip.tsx +42 -0
- package/dist/starter/src/hooks/use-mobile.ts +19 -0
- package/dist/starter/src/hooks/use-toast.ts +186 -0
- package/dist/starter/src/index.css +123 -0
- package/dist/starter/src/lib/utils.ts +6 -0
- package/dist/starter/src/main.tsx +5 -0
- package/dist/starter/tsconfig.app.json +25 -0
- package/dist/starter/tsconfig.json +4 -0
- package/dist/starter/vite.config.ts +16 -0
- package/dist/tsconfig.tsbuildinfo +1 -0
- package/package.json +37 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from '@storybook/react-vite';
|
|
2
|
+
import { Slider } from '@/components/ui/Slider';
|
|
3
|
+
|
|
4
|
+
const meta: Meta<typeof Slider> = {
|
|
5
|
+
title: 'Slider',
|
|
6
|
+
component: Slider,
|
|
7
|
+
};
|
|
8
|
+
export default meta;
|
|
9
|
+
type Story = StoryObj<typeof Slider>;
|
|
10
|
+
|
|
11
|
+
export const Default: Story = {
|
|
12
|
+
render: () => <Slider defaultValue={[50]} max={100} step={1} className="w-[60%]" />,
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
export const Range: Story = {
|
|
16
|
+
render: () => <Slider defaultValue={[25, 75]} max={100} step={1} className="w-[60%]" />,
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
export const WithSteps: Story = {
|
|
20
|
+
render: () => <Slider defaultValue={[20]} max={100} step={10} className="w-[60%]" />,
|
|
21
|
+
};
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { Slider as SliderPrimitive } from 'radix-ui';
|
|
3
|
+
|
|
4
|
+
import { cn } from '@/lib/utils';
|
|
5
|
+
|
|
6
|
+
function Slider({
|
|
7
|
+
className,
|
|
8
|
+
defaultValue,
|
|
9
|
+
value,
|
|
10
|
+
min = 0,
|
|
11
|
+
max = 100,
|
|
12
|
+
...props
|
|
13
|
+
}: React.ComponentProps<typeof SliderPrimitive.Root>) {
|
|
14
|
+
const _values = React.useMemo(
|
|
15
|
+
() => (Array.isArray(value) ? value : Array.isArray(defaultValue) ? defaultValue : [min, max]),
|
|
16
|
+
[value, defaultValue, min, max],
|
|
17
|
+
);
|
|
18
|
+
|
|
19
|
+
return (
|
|
20
|
+
<SliderPrimitive.Root
|
|
21
|
+
data-slot="slider"
|
|
22
|
+
defaultValue={defaultValue}
|
|
23
|
+
value={value}
|
|
24
|
+
min={min}
|
|
25
|
+
max={max}
|
|
26
|
+
className={cn(
|
|
27
|
+
'relative flex w-full touch-none items-center select-none data-[disabled]:opacity-50 data-[orientation=vertical]:h-full data-[orientation=vertical]:min-h-44 data-[orientation=vertical]:w-auto data-[orientation=vertical]:flex-col',
|
|
28
|
+
className,
|
|
29
|
+
)}
|
|
30
|
+
{...props}
|
|
31
|
+
>
|
|
32
|
+
<SliderPrimitive.Track
|
|
33
|
+
data-slot="slider-track"
|
|
34
|
+
className={cn(
|
|
35
|
+
'bg-muted relative grow overflow-hidden rounded-full data-[orientation=horizontal]:h-1.5 data-[orientation=horizontal]:w-full data-[orientation=vertical]:h-full data-[orientation=vertical]:w-1.5',
|
|
36
|
+
)}
|
|
37
|
+
>
|
|
38
|
+
<SliderPrimitive.Range
|
|
39
|
+
data-slot="slider-range"
|
|
40
|
+
className={cn('bg-primary absolute data-[orientation=horizontal]:h-full data-[orientation=vertical]:w-full')}
|
|
41
|
+
/>
|
|
42
|
+
</SliderPrimitive.Track>
|
|
43
|
+
{Array.from({ length: _values.length }, (_, index) => (
|
|
44
|
+
<SliderPrimitive.Thumb
|
|
45
|
+
data-slot="slider-thumb"
|
|
46
|
+
key={index}
|
|
47
|
+
className="border-primary ring-ring/50 block size-4 shrink-0 rounded-full border bg-white shadow-sm transition-[color,box-shadow] hover:ring-4 focus-visible:ring-4 focus-visible:outline-hidden disabled:pointer-events-none disabled:opacity-50"
|
|
48
|
+
/>
|
|
49
|
+
))}
|
|
50
|
+
</SliderPrimitive.Root>
|
|
51
|
+
);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
export { Slider };
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from '@storybook/react-vite';
|
|
2
|
+
import { ThemeProvider } from 'next-themes';
|
|
3
|
+
import { toast } from 'sonner';
|
|
4
|
+
import { Toaster } from '@/components/ui/Sonner';
|
|
5
|
+
import { Button } from '@/components/ui/Button';
|
|
6
|
+
|
|
7
|
+
const meta: Meta<typeof Toaster> = {
|
|
8
|
+
title: 'Sonner',
|
|
9
|
+
component: Toaster,
|
|
10
|
+
decorators: [
|
|
11
|
+
(Story) => (
|
|
12
|
+
<ThemeProvider attribute="class" defaultTheme="light">
|
|
13
|
+
<Story />
|
|
14
|
+
</ThemeProvider>
|
|
15
|
+
),
|
|
16
|
+
],
|
|
17
|
+
};
|
|
18
|
+
export default meta;
|
|
19
|
+
type Story = StoryObj<typeof Toaster>;
|
|
20
|
+
|
|
21
|
+
export const Default: Story = {
|
|
22
|
+
render: () => (
|
|
23
|
+
<div>
|
|
24
|
+
<Toaster />
|
|
25
|
+
<div className="flex flex-wrap gap-2">
|
|
26
|
+
<Button variant="outline" onClick={() => toast('Event has been created.')}>
|
|
27
|
+
Show Toast
|
|
28
|
+
</Button>
|
|
29
|
+
<Button variant="outline" onClick={() => toast.success('Successfully saved!')}>
|
|
30
|
+
Success
|
|
31
|
+
</Button>
|
|
32
|
+
<Button variant="outline" onClick={() => toast.error('Something went wrong.')}>
|
|
33
|
+
Error
|
|
34
|
+
</Button>
|
|
35
|
+
<Button variant="outline" onClick={() => toast.warning('Please check your input.')}>
|
|
36
|
+
Warning
|
|
37
|
+
</Button>
|
|
38
|
+
<Button variant="outline" onClick={() => toast.info('Here is some information.')}>
|
|
39
|
+
Info
|
|
40
|
+
</Button>
|
|
41
|
+
</div>
|
|
42
|
+
</div>
|
|
43
|
+
),
|
|
44
|
+
};
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
import { CircleCheckIcon, InfoIcon, Loader2Icon, OctagonXIcon, TriangleAlertIcon } from 'lucide-react';
|
|
4
|
+
import { useTheme } from 'next-themes';
|
|
5
|
+
import { Toaster as Sonner, type ToasterProps } from 'sonner';
|
|
6
|
+
|
|
7
|
+
const Toaster = ({ ...props }: ToasterProps) => {
|
|
8
|
+
const { theme = 'system' } = useTheme();
|
|
9
|
+
|
|
10
|
+
return (
|
|
11
|
+
<Sonner
|
|
12
|
+
theme={theme as ToasterProps['theme']}
|
|
13
|
+
className="toaster group"
|
|
14
|
+
icons={{
|
|
15
|
+
success: <CircleCheckIcon className="size-4" />,
|
|
16
|
+
info: <InfoIcon className="size-4" />,
|
|
17
|
+
warning: <TriangleAlertIcon className="size-4" />,
|
|
18
|
+
error: <OctagonXIcon className="size-4" />,
|
|
19
|
+
loading: <Loader2Icon className="size-4 animate-spin" />,
|
|
20
|
+
}}
|
|
21
|
+
style={
|
|
22
|
+
{
|
|
23
|
+
'--normal-bg': 'var(--popover)',
|
|
24
|
+
'--normal-text': 'var(--popover-foreground)',
|
|
25
|
+
'--normal-border': 'var(--border)',
|
|
26
|
+
'--border-radius': 'var(--radius)',
|
|
27
|
+
} as React.CSSProperties
|
|
28
|
+
}
|
|
29
|
+
{...props}
|
|
30
|
+
/>
|
|
31
|
+
);
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
export { Toaster };
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from '@storybook/react-vite';
|
|
2
|
+
import { Spinner } from '@/components/ui/Spinner';
|
|
3
|
+
|
|
4
|
+
const meta: Meta<typeof Spinner> = {
|
|
5
|
+
title: 'Spinner',
|
|
6
|
+
component: Spinner,
|
|
7
|
+
};
|
|
8
|
+
export default meta;
|
|
9
|
+
type Story = StoryObj<typeof Spinner>;
|
|
10
|
+
|
|
11
|
+
export const Default: Story = {};
|
|
12
|
+
|
|
13
|
+
export const Small: Story = {
|
|
14
|
+
args: {
|
|
15
|
+
className: 'size-3',
|
|
16
|
+
},
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
export const Large: Story = {
|
|
20
|
+
args: {
|
|
21
|
+
className: 'size-8',
|
|
22
|
+
},
|
|
23
|
+
};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { Loader2Icon } from 'lucide-react';
|
|
2
|
+
|
|
3
|
+
import { cn } from '@/lib/utils';
|
|
4
|
+
|
|
5
|
+
function Spinner({ className, ...props }: React.ComponentProps<'svg'>) {
|
|
6
|
+
return <Loader2Icon role="status" aria-label="Loading" className={cn('size-4 animate-spin', className)} {...props} />;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export { Spinner };
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import type { Meta, StoryObj } from '@storybook/react-vite';
|
|
3
|
+
import { Switch } from '@/components/ui/Switch';
|
|
4
|
+
|
|
5
|
+
const meta: Meta<typeof Switch> = {
|
|
6
|
+
title: 'Switch',
|
|
7
|
+
component: Switch,
|
|
8
|
+
};
|
|
9
|
+
export default meta;
|
|
10
|
+
type Story = StoryObj<typeof Switch>;
|
|
11
|
+
|
|
12
|
+
export const Default: Story = {};
|
|
13
|
+
|
|
14
|
+
export const Checked: Story = {
|
|
15
|
+
args: {
|
|
16
|
+
defaultChecked: true,
|
|
17
|
+
},
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
export const Disabled: Story = {
|
|
21
|
+
args: {
|
|
22
|
+
disabled: true,
|
|
23
|
+
},
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
export const WithLabel: Story = {
|
|
27
|
+
render: () => (
|
|
28
|
+
<div className="flex items-center gap-2">
|
|
29
|
+
<Switch id="airplane-mode" />
|
|
30
|
+
<label htmlFor="airplane-mode" className="text-sm">
|
|
31
|
+
Airplane Mode
|
|
32
|
+
</label>
|
|
33
|
+
</div>
|
|
34
|
+
),
|
|
35
|
+
};
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { Switch as SwitchPrimitive } from 'radix-ui';
|
|
3
|
+
|
|
4
|
+
import { cn } from '@/lib/utils';
|
|
5
|
+
|
|
6
|
+
function Switch({
|
|
7
|
+
className,
|
|
8
|
+
size = 'default',
|
|
9
|
+
...props
|
|
10
|
+
}: React.ComponentProps<typeof SwitchPrimitive.Root> & {
|
|
11
|
+
size?: 'sm' | 'default';
|
|
12
|
+
}) {
|
|
13
|
+
return (
|
|
14
|
+
<SwitchPrimitive.Root
|
|
15
|
+
data-slot="switch"
|
|
16
|
+
data-size={size}
|
|
17
|
+
className={cn(
|
|
18
|
+
'peer data-[state=checked]:bg-primary data-[state=unchecked]:bg-input focus-visible:border-ring focus-visible:ring-ring/50 dark:data-[state=unchecked]:bg-input/80 group/switch inline-flex shrink-0 items-center rounded-full border border-transparent shadow-xs transition-all outline-none focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-50 data-[size=default]:h-[1.15rem] data-[size=default]:w-8 data-[size=sm]:h-3.5 data-[size=sm]:w-6',
|
|
19
|
+
className,
|
|
20
|
+
)}
|
|
21
|
+
{...props}
|
|
22
|
+
>
|
|
23
|
+
<SwitchPrimitive.Thumb
|
|
24
|
+
data-slot="switch-thumb"
|
|
25
|
+
className={cn(
|
|
26
|
+
'bg-background dark:data-[state=unchecked]:bg-foreground dark:data-[state=checked]:bg-primary-foreground pointer-events-none block rounded-full ring-0 transition-transform group-data-[size=default]/switch:size-4 group-data-[size=sm]/switch:size-3 data-[state=checked]:translate-x-[calc(100%-2px)] data-[state=unchecked]:translate-x-0',
|
|
27
|
+
)}
|
|
28
|
+
/>
|
|
29
|
+
</SwitchPrimitive.Root>
|
|
30
|
+
);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export { Switch };
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from '@storybook/react-vite';
|
|
2
|
+
import { Table, TableHeader, TableBody, TableRow, TableHead, TableCell, TableCaption } from '@/components/ui/Table';
|
|
3
|
+
|
|
4
|
+
const meta: Meta<typeof Table> = {
|
|
5
|
+
title: 'Table',
|
|
6
|
+
component: Table,
|
|
7
|
+
};
|
|
8
|
+
export default meta;
|
|
9
|
+
type Story = StoryObj<typeof Table>;
|
|
10
|
+
|
|
11
|
+
const invoices = [
|
|
12
|
+
{ invoice: 'INV001', status: 'Paid', method: 'Credit Card', amount: '$250.00' },
|
|
13
|
+
{ invoice: 'INV002', status: 'Pending', method: 'PayPal', amount: '$150.00' },
|
|
14
|
+
{ invoice: 'INV003', status: 'Unpaid', method: 'Bank Transfer', amount: '$350.00' },
|
|
15
|
+
{ invoice: 'INV004', status: 'Paid', method: 'Credit Card', amount: '$450.00' },
|
|
16
|
+
];
|
|
17
|
+
|
|
18
|
+
export const Default: Story = {
|
|
19
|
+
render: () => (
|
|
20
|
+
<Table>
|
|
21
|
+
<TableCaption>A list of recent invoices.</TableCaption>
|
|
22
|
+
<TableHeader>
|
|
23
|
+
<TableRow>
|
|
24
|
+
<TableHead>Invoice</TableHead>
|
|
25
|
+
<TableHead>Status</TableHead>
|
|
26
|
+
<TableHead>Method</TableHead>
|
|
27
|
+
<TableHead className="text-right">Amount</TableHead>
|
|
28
|
+
</TableRow>
|
|
29
|
+
</TableHeader>
|
|
30
|
+
<TableBody>
|
|
31
|
+
{invoices.map((invoice) => (
|
|
32
|
+
<TableRow key={invoice.invoice}>
|
|
33
|
+
<TableCell className="font-medium">{invoice.invoice}</TableCell>
|
|
34
|
+
<TableCell>{invoice.status}</TableCell>
|
|
35
|
+
<TableCell>{invoice.method}</TableCell>
|
|
36
|
+
<TableCell className="text-right">{invoice.amount}</TableCell>
|
|
37
|
+
</TableRow>
|
|
38
|
+
))}
|
|
39
|
+
</TableBody>
|
|
40
|
+
</Table>
|
|
41
|
+
),
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
export const Minimal: Story = {
|
|
45
|
+
render: () => (
|
|
46
|
+
<Table>
|
|
47
|
+
<TableHeader>
|
|
48
|
+
<TableRow>
|
|
49
|
+
<TableHead>Name</TableHead>
|
|
50
|
+
<TableHead>Role</TableHead>
|
|
51
|
+
</TableRow>
|
|
52
|
+
</TableHeader>
|
|
53
|
+
<TableBody>
|
|
54
|
+
<TableRow>
|
|
55
|
+
<TableCell>Alice</TableCell>
|
|
56
|
+
<TableCell>Engineer</TableCell>
|
|
57
|
+
</TableRow>
|
|
58
|
+
<TableRow>
|
|
59
|
+
<TableCell>Bob</TableCell>
|
|
60
|
+
<TableCell>Designer</TableCell>
|
|
61
|
+
</TableRow>
|
|
62
|
+
</TableBody>
|
|
63
|
+
</Table>
|
|
64
|
+
),
|
|
65
|
+
};
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
import * as React from 'react';
|
|
4
|
+
|
|
5
|
+
import { cn } from '@/lib/utils';
|
|
6
|
+
|
|
7
|
+
function Table({ className, ...props }: React.ComponentProps<'table'>) {
|
|
8
|
+
return (
|
|
9
|
+
<div data-slot="table-container" className="relative w-full overflow-x-auto">
|
|
10
|
+
<table data-slot="table" className={cn('w-full caption-bottom text-sm', className)} {...props} />
|
|
11
|
+
</div>
|
|
12
|
+
);
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
function TableHeader({ className, ...props }: React.ComponentProps<'thead'>) {
|
|
16
|
+
return <thead data-slot="table-header" className={cn('[&_tr]:border-b', className)} {...props} />;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
function TableBody({ className, ...props }: React.ComponentProps<'tbody'>) {
|
|
20
|
+
return <tbody data-slot="table-body" className={cn('[&_tr:last-child]:border-0', className)} {...props} />;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
function TableFooter({ className, ...props }: React.ComponentProps<'tfoot'>) {
|
|
24
|
+
return (
|
|
25
|
+
<tfoot
|
|
26
|
+
data-slot="table-footer"
|
|
27
|
+
className={cn('bg-muted/50 border-t font-medium [&>tr]:last:border-b-0', className)}
|
|
28
|
+
{...props}
|
|
29
|
+
/>
|
|
30
|
+
);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
function TableRow({ className, ...props }: React.ComponentProps<'tr'>) {
|
|
34
|
+
return (
|
|
35
|
+
<tr
|
|
36
|
+
data-slot="table-row"
|
|
37
|
+
className={cn('hover:bg-muted/50 data-[state=selected]:bg-muted border-b transition-colors', className)}
|
|
38
|
+
{...props}
|
|
39
|
+
/>
|
|
40
|
+
);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
function TableHead({ className, ...props }: React.ComponentProps<'th'>) {
|
|
44
|
+
return (
|
|
45
|
+
<th
|
|
46
|
+
data-slot="table-head"
|
|
47
|
+
className={cn(
|
|
48
|
+
'text-foreground h-10 px-2 text-left align-middle font-medium whitespace-nowrap [&:has([role=checkbox])]:pr-0 [&>[role=checkbox]]:translate-y-[2px]',
|
|
49
|
+
className,
|
|
50
|
+
)}
|
|
51
|
+
{...props}
|
|
52
|
+
/>
|
|
53
|
+
);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
function TableCell({ className, ...props }: React.ComponentProps<'td'>) {
|
|
57
|
+
return (
|
|
58
|
+
<td
|
|
59
|
+
data-slot="table-cell"
|
|
60
|
+
className={cn(
|
|
61
|
+
'p-2 align-middle whitespace-nowrap [&:has([role=checkbox])]:pr-0 [&>[role=checkbox]]:translate-y-[2px]',
|
|
62
|
+
className,
|
|
63
|
+
)}
|
|
64
|
+
{...props}
|
|
65
|
+
/>
|
|
66
|
+
);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
function TableCaption({ className, ...props }: React.ComponentProps<'caption'>) {
|
|
70
|
+
return (
|
|
71
|
+
<caption data-slot="table-caption" className={cn('text-muted-foreground mt-4 text-sm', className)} {...props} />
|
|
72
|
+
);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
export { Table, TableHeader, TableBody, TableFooter, TableHead, TableRow, TableCell, TableCaption };
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from '@storybook/react-vite';
|
|
2
|
+
import { Tabs, TabsList, TabsTrigger, TabsContent } from '@/components/ui/Tabs';
|
|
3
|
+
|
|
4
|
+
const meta: Meta<typeof Tabs> = {
|
|
5
|
+
title: 'Tabs',
|
|
6
|
+
component: Tabs,
|
|
7
|
+
};
|
|
8
|
+
export default meta;
|
|
9
|
+
type Story = StoryObj<typeof Tabs>;
|
|
10
|
+
|
|
11
|
+
export const Default: Story = {
|
|
12
|
+
render: () => (
|
|
13
|
+
<Tabs defaultValue="account" className="w-[400px]">
|
|
14
|
+
<TabsList>
|
|
15
|
+
<TabsTrigger value="account">Account</TabsTrigger>
|
|
16
|
+
<TabsTrigger value="password">Password</TabsTrigger>
|
|
17
|
+
<TabsTrigger value="settings">Settings</TabsTrigger>
|
|
18
|
+
</TabsList>
|
|
19
|
+
<TabsContent value="account">
|
|
20
|
+
<p className="text-sm text-muted-foreground p-4">Make changes to your account here.</p>
|
|
21
|
+
</TabsContent>
|
|
22
|
+
<TabsContent value="password">
|
|
23
|
+
<p className="text-sm text-muted-foreground p-4">Change your password here.</p>
|
|
24
|
+
</TabsContent>
|
|
25
|
+
<TabsContent value="settings">
|
|
26
|
+
<p className="text-sm text-muted-foreground p-4">Adjust your settings here.</p>
|
|
27
|
+
</TabsContent>
|
|
28
|
+
</Tabs>
|
|
29
|
+
),
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
export const LineVariant: Story = {
|
|
33
|
+
render: () => (
|
|
34
|
+
<Tabs defaultValue="overview" className="w-[400px]">
|
|
35
|
+
<TabsList variant="line">
|
|
36
|
+
<TabsTrigger value="overview">Overview</TabsTrigger>
|
|
37
|
+
<TabsTrigger value="analytics">Analytics</TabsTrigger>
|
|
38
|
+
<TabsTrigger value="reports">Reports</TabsTrigger>
|
|
39
|
+
</TabsList>
|
|
40
|
+
<TabsContent value="overview">
|
|
41
|
+
<p className="text-sm text-muted-foreground p-4">Overview content goes here.</p>
|
|
42
|
+
</TabsContent>
|
|
43
|
+
<TabsContent value="analytics">
|
|
44
|
+
<p className="text-sm text-muted-foreground p-4">Analytics content goes here.</p>
|
|
45
|
+
</TabsContent>
|
|
46
|
+
<TabsContent value="reports">
|
|
47
|
+
<p className="text-sm text-muted-foreground p-4">Reports content goes here.</p>
|
|
48
|
+
</TabsContent>
|
|
49
|
+
</Tabs>
|
|
50
|
+
),
|
|
51
|
+
};
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { cva, type VariantProps } from 'class-variance-authority';
|
|
3
|
+
import { Tabs as TabsPrimitive } from 'radix-ui';
|
|
4
|
+
|
|
5
|
+
import { cn } from '@/lib/utils';
|
|
6
|
+
|
|
7
|
+
function Tabs({ className, orientation = 'horizontal', ...props }: React.ComponentProps<typeof TabsPrimitive.Root>) {
|
|
8
|
+
return (
|
|
9
|
+
<TabsPrimitive.Root
|
|
10
|
+
data-slot="tabs"
|
|
11
|
+
data-orientation={orientation}
|
|
12
|
+
orientation={orientation}
|
|
13
|
+
className={cn('group/tabs flex gap-2 data-[orientation=horizontal]:flex-col', className)}
|
|
14
|
+
{...props}
|
|
15
|
+
/>
|
|
16
|
+
);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
const tabsListVariants = cva(
|
|
20
|
+
'rounded-lg p-[3px] group-data-[orientation=horizontal]/tabs:h-9 data-[variant=line]:rounded-none group/tabs-list text-muted-foreground inline-flex w-fit items-center justify-center group-data-[orientation=vertical]/tabs:h-fit group-data-[orientation=vertical]/tabs:flex-col',
|
|
21
|
+
{
|
|
22
|
+
variants: {
|
|
23
|
+
variant: {
|
|
24
|
+
default: 'bg-muted',
|
|
25
|
+
line: 'gap-1 bg-transparent',
|
|
26
|
+
},
|
|
27
|
+
},
|
|
28
|
+
defaultVariants: {
|
|
29
|
+
variant: 'default',
|
|
30
|
+
},
|
|
31
|
+
},
|
|
32
|
+
);
|
|
33
|
+
|
|
34
|
+
function TabsList({
|
|
35
|
+
className,
|
|
36
|
+
variant = 'default',
|
|
37
|
+
...props
|
|
38
|
+
}: React.ComponentProps<typeof TabsPrimitive.List> & VariantProps<typeof tabsListVariants>) {
|
|
39
|
+
return (
|
|
40
|
+
<TabsPrimitive.List
|
|
41
|
+
data-slot="tabs-list"
|
|
42
|
+
data-variant={variant}
|
|
43
|
+
className={cn(tabsListVariants({ variant }), className)}
|
|
44
|
+
{...props}
|
|
45
|
+
/>
|
|
46
|
+
);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
function TabsTrigger({ className, ...props }: React.ComponentProps<typeof TabsPrimitive.Trigger>) {
|
|
50
|
+
return (
|
|
51
|
+
<TabsPrimitive.Trigger
|
|
52
|
+
data-slot="tabs-trigger"
|
|
53
|
+
className={cn(
|
|
54
|
+
"focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:outline-ring text-foreground/60 hover:text-foreground dark:text-muted-foreground dark:hover:text-foreground relative inline-flex h-[calc(100%-1px)] flex-1 items-center justify-center gap-1.5 rounded-md border border-transparent px-2 py-1 text-sm font-medium whitespace-nowrap transition-all group-data-[orientation=vertical]/tabs:w-full group-data-[orientation=vertical]/tabs:justify-start focus-visible:ring-[3px] focus-visible:outline-1 disabled:pointer-events-none disabled:opacity-50 group-data-[variant=default]/tabs-list:data-[state=active]:shadow-sm group-data-[variant=line]/tabs-list:data-[state=active]:shadow-none [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
|
|
55
|
+
'group-data-[variant=line]/tabs-list:bg-transparent group-data-[variant=line]/tabs-list:data-[state=active]:bg-transparent dark:group-data-[variant=line]/tabs-list:data-[state=active]:border-transparent dark:group-data-[variant=line]/tabs-list:data-[state=active]:bg-transparent',
|
|
56
|
+
'data-[state=active]:bg-background dark:data-[state=active]:text-foreground dark:data-[state=active]:border-input dark:data-[state=active]:bg-input/30 data-[state=active]:text-foreground',
|
|
57
|
+
'after:bg-foreground after:absolute after:opacity-0 after:transition-opacity group-data-[orientation=horizontal]/tabs:after:inset-x-0 group-data-[orientation=horizontal]/tabs:after:bottom-[-5px] group-data-[orientation=horizontal]/tabs:after:h-0.5 group-data-[orientation=vertical]/tabs:after:inset-y-0 group-data-[orientation=vertical]/tabs:after:-right-1 group-data-[orientation=vertical]/tabs:after:w-0.5 group-data-[variant=line]/tabs-list:data-[state=active]:after:opacity-100',
|
|
58
|
+
className,
|
|
59
|
+
)}
|
|
60
|
+
{...props}
|
|
61
|
+
/>
|
|
62
|
+
);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
function TabsContent({ className, ...props }: React.ComponentProps<typeof TabsPrimitive.Content>) {
|
|
66
|
+
return <TabsPrimitive.Content data-slot="tabs-content" className={cn('flex-1 outline-none', className)} {...props} />;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
export { Tabs, TabsList, TabsTrigger, TabsContent, tabsListVariants };
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from '@storybook/react-vite';
|
|
2
|
+
import { Textarea } from '@/components/ui/Textarea';
|
|
3
|
+
|
|
4
|
+
const meta: Meta<typeof Textarea> = {
|
|
5
|
+
title: 'Textarea',
|
|
6
|
+
component: Textarea,
|
|
7
|
+
};
|
|
8
|
+
export default meta;
|
|
9
|
+
type Story = StoryObj<typeof Textarea>;
|
|
10
|
+
|
|
11
|
+
export const Default: Story = {};
|
|
12
|
+
|
|
13
|
+
export const WithPlaceholder: Story = {
|
|
14
|
+
args: {
|
|
15
|
+
placeholder: 'Type your message here...',
|
|
16
|
+
},
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
export const Disabled: Story = {
|
|
20
|
+
args: {
|
|
21
|
+
placeholder: 'This textarea is disabled',
|
|
22
|
+
disabled: true,
|
|
23
|
+
},
|
|
24
|
+
};
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
|
|
3
|
+
import { cn } from '@/lib/utils';
|
|
4
|
+
|
|
5
|
+
function Textarea({ className, ...props }: React.ComponentProps<'textarea'>) {
|
|
6
|
+
return (
|
|
7
|
+
<textarea
|
|
8
|
+
data-slot="textarea"
|
|
9
|
+
className={cn(
|
|
10
|
+
'border-input placeholder:text-muted-foreground focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:bg-input/30 flex field-sizing-content min-h-16 w-full rounded-md border bg-transparent px-3 py-2 text-base shadow-xs transition-[color,box-shadow] outline-none focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-50 md:text-sm',
|
|
11
|
+
className,
|
|
12
|
+
)}
|
|
13
|
+
{...props}
|
|
14
|
+
/>
|
|
15
|
+
);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export { Textarea };
|