@auto-engineer/frontend-generator-react-graphql 0.11.2 → 0.11.4
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 +18 -0
- package/dist/mui-starter/auto-configure.ts +114 -0
- package/dist/mui-starter/codegen.ts +16 -0
- package/dist/mui-starter/design-system-principles.md +32 -0
- package/dist/mui-starter/eslint.config.ts +57 -0
- package/dist/mui-starter/index.html +26 -0
- package/dist/mui-starter/package.json +70 -0
- package/dist/mui-starter/postcss.config.ts +5 -0
- package/dist/mui-starter/public/favicon.ico +0 -0
- package/dist/mui-starter/src/App.css +42 -0
- package/dist/mui-starter/src/App.tsx +21 -0
- package/dist/mui-starter/src/apolloClient.ts +8 -0
- package/dist/mui-starter/src/hooks/use-mobile.tsx +19 -0
- package/dist/mui-starter/src/hooks/use-toast.ts +186 -0
- package/dist/mui-starter/src/index.css +0 -0
- package/dist/mui-starter/src/main.tsx +5 -0
- package/dist/mui-starter/src/pages/Index.tsx +10 -0
- package/dist/mui-starter/src/pages/NotFound.tsx +20 -0
- package/dist/mui-starter/src/theme.ts +86 -0
- package/dist/mui-starter/src/theme.ts.ejs +3 -0
- package/dist/mui-starter/tsconfig.json +40 -0
- package/dist/mui-starter/vite.config.ts +21 -0
- package/dist/shadcn-starter/auto-configure.ts +107 -0
- package/dist/shadcn-starter/codegen.ts +16 -0
- package/dist/shadcn-starter/components.json +20 -0
- package/dist/shadcn-starter/design-system-principles.md +23 -0
- package/dist/shadcn-starter/eslint.config.ts +57 -0
- package/dist/shadcn-starter/index.html +26 -0
- package/dist/shadcn-starter/package.json +101 -0
- package/dist/shadcn-starter/pnpm-lock.yaml +8234 -0
- package/dist/shadcn-starter/postcss.config.ts +6 -0
- package/dist/shadcn-starter/public/favicon.ico +0 -0
- package/dist/shadcn-starter/src/App.css +6 -0
- package/dist/shadcn-starter/src/App.tsx +28 -0
- package/dist/shadcn-starter/src/apolloClient.ts +8 -0
- package/dist/shadcn-starter/src/components/atoms/accordion.tsx +52 -0
- package/dist/shadcn-starter/src/components/atoms/alert-dialog.tsx +104 -0
- package/dist/shadcn-starter/src/components/atoms/alert.tsx +43 -0
- package/dist/shadcn-starter/src/components/atoms/aspect-ratio.tsx +5 -0
- package/dist/shadcn-starter/src/components/atoms/avatar.tsx +40 -0
- package/dist/shadcn-starter/src/components/atoms/badge.tsx +29 -0
- package/dist/shadcn-starter/src/components/atoms/breadcrumb.tsx +90 -0
- package/dist/shadcn-starter/src/components/atoms/button.tsx +47 -0
- package/dist/shadcn-starter/src/components/atoms/calendar.tsx +158 -0
- package/dist/shadcn-starter/src/components/atoms/card.tsx +43 -0
- package/dist/shadcn-starter/src/components/atoms/carousel.tsx +224 -0
- package/dist/shadcn-starter/src/components/atoms/chart.tsx +307 -0
- package/dist/shadcn-starter/src/components/atoms/checkbox.tsx +26 -0
- package/dist/shadcn-starter/src/components/atoms/collapsible.tsx +11 -0
- package/dist/shadcn-starter/src/components/atoms/command.tsx +132 -0
- package/dist/shadcn-starter/src/components/atoms/context-menu.tsx +178 -0
- package/dist/shadcn-starter/src/components/atoms/dialog.tsx +97 -0
- package/dist/shadcn-starter/src/components/atoms/drawer.tsx +87 -0
- package/dist/shadcn-starter/src/components/atoms/dropdown-menu.tsx +181 -0
- package/dist/shadcn-starter/src/components/atoms/form.tsx +136 -0
- package/dist/shadcn-starter/src/components/atoms/hover-card.tsx +27 -0
- package/dist/shadcn-starter/src/components/atoms/input-otp.tsx +61 -0
- package/dist/shadcn-starter/src/components/atoms/input.tsx +22 -0
- package/dist/shadcn-starter/src/components/atoms/label.tsx +19 -0
- package/dist/shadcn-starter/src/components/atoms/menubar.tsx +217 -0
- package/dist/shadcn-starter/src/components/atoms/navigation-menu.tsx +120 -0
- package/dist/shadcn-starter/src/components/atoms/pagination.tsx +81 -0
- package/dist/shadcn-starter/src/components/atoms/popover.tsx +29 -0
- package/dist/shadcn-starter/src/components/atoms/progress.tsx +25 -0
- package/dist/shadcn-starter/src/components/atoms/radio-group.tsx +36 -0
- package/dist/shadcn-starter/src/components/atoms/resizable.tsx +39 -0
- package/dist/shadcn-starter/src/components/atoms/scroll-area.tsx +38 -0
- package/dist/shadcn-starter/src/components/atoms/select.tsx +145 -0
- package/dist/shadcn-starter/src/components/atoms/separator.tsx +20 -0
- package/dist/shadcn-starter/src/components/atoms/sheet.tsx +109 -0
- package/dist/shadcn-starter/src/components/atoms/sidebar.tsx +641 -0
- package/dist/shadcn-starter/src/components/atoms/skeleton.tsx +7 -0
- package/dist/shadcn-starter/src/components/atoms/slider.tsx +23 -0
- package/dist/shadcn-starter/src/components/atoms/sonner.tsx +29 -0
- package/dist/shadcn-starter/src/components/atoms/switch.tsx +27 -0
- package/dist/shadcn-starter/src/components/atoms/table.tsx +72 -0
- package/dist/shadcn-starter/src/components/atoms/tabs.tsx +53 -0
- package/dist/shadcn-starter/src/components/atoms/textarea.tsx +21 -0
- package/dist/shadcn-starter/src/components/atoms/toggle-group.tsx +51 -0
- package/dist/shadcn-starter/src/components/atoms/toggle.tsx +37 -0
- package/dist/shadcn-starter/src/components/atoms/tooltip.tsx +30 -0
- package/dist/shadcn-starter/src/hooks/use-mobile.tsx +19 -0
- package/dist/shadcn-starter/src/hooks/use-toast.ts +186 -0
- package/dist/shadcn-starter/src/index.css +103 -0
- package/dist/shadcn-starter/src/index.css.ejs +27 -0
- package/dist/shadcn-starter/src/lib/utils.ts +6 -0
- package/dist/shadcn-starter/src/main.tsx +5 -0
- package/dist/shadcn-starter/src/mockApolloClient.ts +93 -0
- package/dist/shadcn-starter/src/pages/NotFound.tsx +22 -0
- package/dist/shadcn-starter/tailwind.config.ts +92 -0
- package/dist/shadcn-starter/tsconfig.json +48 -0
- package/dist/shadcn-starter/vite.config.ts +21 -0
- package/dist/src/builder.js +3 -3
- package/dist/src/builder.js.map +1 -1
- package/dist/src/commands/copy-example.js +1 -1
- package/dist/src/commands/copy-example.js.map +1 -1
- package/dist/src/commands/generate-client.d.ts +2 -1
- package/dist/src/commands/generate-client.d.ts.map +1 -1
- package/dist/src/commands/generate-client.js +14 -4
- package/dist/src/commands/generate-client.js.map +1 -1
- package/dist/src/configure-starter.js +1 -1
- package/dist/src/configure-starter.js.map +1 -1
- package/dist/src/generator/generateComponents.js +3 -3
- package/dist/src/generator/generateComponents.js.map +1 -1
- package/dist/src/run-codegen.js +2 -2
- package/dist/src/run-codegen.js.map +1 -1
- package/dist/src/write-graphql-schema.js +1 -1
- package/dist/src/write-graphql-schema.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +5 -5
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
import { useTheme } from 'next-themes';
|
|
4
|
+
import { Toaster as Sonner } from 'sonner';
|
|
5
|
+
|
|
6
|
+
type ToasterProps = React.ComponentProps<typeof Sonner>;
|
|
7
|
+
|
|
8
|
+
const Toaster = ({ ...props }: ToasterProps) => {
|
|
9
|
+
const { theme = 'system' } = useTheme();
|
|
10
|
+
|
|
11
|
+
return (
|
|
12
|
+
<Sonner
|
|
13
|
+
theme={theme as ToasterProps['theme']}
|
|
14
|
+
className="toaster group"
|
|
15
|
+
toastOptions={{
|
|
16
|
+
classNames: {
|
|
17
|
+
toast:
|
|
18
|
+
'group toast group-[.toaster]:bg-background group-[.toaster]:text-foreground group-[.toaster]:border-border group-[.toaster]:shadow-lg',
|
|
19
|
+
description: 'group-[.toast]:text-muted-foreground',
|
|
20
|
+
actionButton: 'group-[.toast]:bg-primary group-[.toast]:text-primary-foreground',
|
|
21
|
+
cancelButton: 'group-[.toast]:bg-muted group-[.toast]:text-muted-foreground',
|
|
22
|
+
},
|
|
23
|
+
}}
|
|
24
|
+
{...props}
|
|
25
|
+
/>
|
|
26
|
+
);
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
export { Toaster };
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import * as SwitchPrimitives from '@radix-ui/react-switch';
|
|
3
|
+
|
|
4
|
+
import { cn } from '@/lib/utils';
|
|
5
|
+
|
|
6
|
+
const Switch = React.forwardRef<
|
|
7
|
+
React.ElementRef<typeof SwitchPrimitives.Root>,
|
|
8
|
+
React.ComponentPropsWithoutRef<typeof SwitchPrimitives.Root>
|
|
9
|
+
>(({ className, ...props }, ref) => (
|
|
10
|
+
<SwitchPrimitives.Root
|
|
11
|
+
className={cn(
|
|
12
|
+
'peer inline-flex h-6 w-11 shrink-0 cursor-pointer items-center rounded-full border-2 border-transparent transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background disabled:cursor-not-allowed disabled:opacity-50 data-[state=checked]:bg-primary data-[state=unchecked]:bg-input',
|
|
13
|
+
className,
|
|
14
|
+
)}
|
|
15
|
+
{...props}
|
|
16
|
+
ref={ref}
|
|
17
|
+
>
|
|
18
|
+
<SwitchPrimitives.Thumb
|
|
19
|
+
className={cn(
|
|
20
|
+
'pointer-events-none block h-5 w-5 rounded-full bg-background shadow-lg ring-0 transition-transform data-[state=checked]:translate-x-5 data-[state=unchecked]:translate-x-0',
|
|
21
|
+
)}
|
|
22
|
+
/>
|
|
23
|
+
</SwitchPrimitives.Root>
|
|
24
|
+
));
|
|
25
|
+
Switch.displayName = SwitchPrimitives.Root.displayName;
|
|
26
|
+
|
|
27
|
+
export { Switch };
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
|
|
3
|
+
import { cn } from '@/lib/utils';
|
|
4
|
+
|
|
5
|
+
const Table = React.forwardRef<HTMLTableElement, React.HTMLAttributes<HTMLTableElement>>(
|
|
6
|
+
({ className, ...props }, ref) => (
|
|
7
|
+
<div className="relative w-full overflow-auto">
|
|
8
|
+
<table ref={ref} className={cn('w-full caption-bottom text-sm', className)} {...props} />
|
|
9
|
+
</div>
|
|
10
|
+
),
|
|
11
|
+
);
|
|
12
|
+
Table.displayName = 'Table';
|
|
13
|
+
|
|
14
|
+
const TableHeader = React.forwardRef<HTMLTableSectionElement, React.HTMLAttributes<HTMLTableSectionElement>>(
|
|
15
|
+
({ className, ...props }, ref) => <thead ref={ref} className={cn('[&_tr]:border-b', className)} {...props} />,
|
|
16
|
+
);
|
|
17
|
+
TableHeader.displayName = 'TableHeader';
|
|
18
|
+
|
|
19
|
+
const TableBody = React.forwardRef<HTMLTableSectionElement, React.HTMLAttributes<HTMLTableSectionElement>>(
|
|
20
|
+
({ className, ...props }, ref) => (
|
|
21
|
+
<tbody ref={ref} className={cn('[&_tr:last-child]:border-0', className)} {...props} />
|
|
22
|
+
),
|
|
23
|
+
);
|
|
24
|
+
TableBody.displayName = 'TableBody';
|
|
25
|
+
|
|
26
|
+
const TableFooter = React.forwardRef<HTMLTableSectionElement, React.HTMLAttributes<HTMLTableSectionElement>>(
|
|
27
|
+
({ className, ...props }, ref) => (
|
|
28
|
+
<tfoot ref={ref} className={cn('border-t bg-muted/50 font-medium [&>tr]:last:border-b-0', className)} {...props} />
|
|
29
|
+
),
|
|
30
|
+
);
|
|
31
|
+
TableFooter.displayName = 'TableFooter';
|
|
32
|
+
|
|
33
|
+
const TableRow = React.forwardRef<HTMLTableRowElement, React.HTMLAttributes<HTMLTableRowElement>>(
|
|
34
|
+
({ className, ...props }, ref) => (
|
|
35
|
+
<tr
|
|
36
|
+
ref={ref}
|
|
37
|
+
className={cn('border-b transition-colors hover:bg-muted/50 data-[state=selected]:bg-muted', className)}
|
|
38
|
+
{...props}
|
|
39
|
+
/>
|
|
40
|
+
),
|
|
41
|
+
);
|
|
42
|
+
TableRow.displayName = 'TableRow';
|
|
43
|
+
|
|
44
|
+
const TableHead = React.forwardRef<HTMLTableCellElement, React.ThHTMLAttributes<HTMLTableCellElement>>(
|
|
45
|
+
({ className, ...props }, ref) => (
|
|
46
|
+
<th
|
|
47
|
+
ref={ref}
|
|
48
|
+
className={cn(
|
|
49
|
+
'h-12 px-4 text-left align-middle font-medium text-muted-foreground [&:has([role=checkbox])]:pr-0',
|
|
50
|
+
className,
|
|
51
|
+
)}
|
|
52
|
+
{...props}
|
|
53
|
+
/>
|
|
54
|
+
),
|
|
55
|
+
);
|
|
56
|
+
TableHead.displayName = 'TableHead';
|
|
57
|
+
|
|
58
|
+
const TableCell = React.forwardRef<HTMLTableCellElement, React.TdHTMLAttributes<HTMLTableCellElement>>(
|
|
59
|
+
({ className, ...props }, ref) => (
|
|
60
|
+
<td ref={ref} className={cn('p-4 align-middle [&:has([role=checkbox])]:pr-0', className)} {...props} />
|
|
61
|
+
),
|
|
62
|
+
);
|
|
63
|
+
TableCell.displayName = 'TableCell';
|
|
64
|
+
|
|
65
|
+
const TableCaption = React.forwardRef<HTMLTableCaptionElement, React.HTMLAttributes<HTMLTableCaptionElement>>(
|
|
66
|
+
({ className, ...props }, ref) => (
|
|
67
|
+
<caption ref={ref} className={cn('mt-4 text-sm text-muted-foreground', className)} {...props} />
|
|
68
|
+
),
|
|
69
|
+
);
|
|
70
|
+
TableCaption.displayName = 'TableCaption';
|
|
71
|
+
|
|
72
|
+
export { Table, TableHeader, TableBody, TableFooter, TableHead, TableRow, TableCell, TableCaption };
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import * as TabsPrimitive from '@radix-ui/react-tabs';
|
|
3
|
+
|
|
4
|
+
import { cn } from '@/lib/utils';
|
|
5
|
+
|
|
6
|
+
const Tabs = TabsPrimitive.Root;
|
|
7
|
+
|
|
8
|
+
const TabsList = React.forwardRef<
|
|
9
|
+
React.ElementRef<typeof TabsPrimitive.List>,
|
|
10
|
+
React.ComponentPropsWithoutRef<typeof TabsPrimitive.List>
|
|
11
|
+
>(({ className, ...props }, ref) => (
|
|
12
|
+
<TabsPrimitive.List
|
|
13
|
+
ref={ref}
|
|
14
|
+
className={cn(
|
|
15
|
+
'inline-flex h-10 items-center justify-center rounded-md bg-muted p-1 text-muted-foreground',
|
|
16
|
+
className,
|
|
17
|
+
)}
|
|
18
|
+
{...props}
|
|
19
|
+
/>
|
|
20
|
+
));
|
|
21
|
+
TabsList.displayName = TabsPrimitive.List.displayName;
|
|
22
|
+
|
|
23
|
+
const TabsTrigger = React.forwardRef<
|
|
24
|
+
React.ElementRef<typeof TabsPrimitive.Trigger>,
|
|
25
|
+
React.ComponentPropsWithoutRef<typeof TabsPrimitive.Trigger>
|
|
26
|
+
>(({ className, ...props }, ref) => (
|
|
27
|
+
<TabsPrimitive.Trigger
|
|
28
|
+
ref={ref}
|
|
29
|
+
className={cn(
|
|
30
|
+
'inline-flex items-center justify-center whitespace-nowrap rounded-sm px-3 py-1.5 text-sm font-medium ring-offset-background transition-all focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 data-[state=active]:bg-background data-[state=active]:text-foreground data-[state=active]:shadow-sm',
|
|
31
|
+
className,
|
|
32
|
+
)}
|
|
33
|
+
{...props}
|
|
34
|
+
/>
|
|
35
|
+
));
|
|
36
|
+
TabsTrigger.displayName = TabsPrimitive.Trigger.displayName;
|
|
37
|
+
|
|
38
|
+
const TabsContent = React.forwardRef<
|
|
39
|
+
React.ElementRef<typeof TabsPrimitive.Content>,
|
|
40
|
+
React.ComponentPropsWithoutRef<typeof TabsPrimitive.Content>
|
|
41
|
+
>(({ className, ...props }, ref) => (
|
|
42
|
+
<TabsPrimitive.Content
|
|
43
|
+
ref={ref}
|
|
44
|
+
className={cn(
|
|
45
|
+
'mt-2 ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2',
|
|
46
|
+
className,
|
|
47
|
+
)}
|
|
48
|
+
{...props}
|
|
49
|
+
/>
|
|
50
|
+
));
|
|
51
|
+
TabsContent.displayName = TabsPrimitive.Content.displayName;
|
|
52
|
+
|
|
53
|
+
export { Tabs, TabsList, TabsTrigger, TabsContent };
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
|
|
3
|
+
import { cn } from '@/lib/utils';
|
|
4
|
+
|
|
5
|
+
const Textarea = React.forwardRef<HTMLTextAreaElement, React.ComponentProps<'textarea'>>(
|
|
6
|
+
({ className, ...props }, ref) => {
|
|
7
|
+
return (
|
|
8
|
+
<textarea
|
|
9
|
+
className={cn(
|
|
10
|
+
'flex min-h-[80px] w-full rounded-md border border-input bg-background px-3 py-2 text-base ring-offset-background placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 md:text-sm',
|
|
11
|
+
className,
|
|
12
|
+
)}
|
|
13
|
+
ref={ref}
|
|
14
|
+
{...props}
|
|
15
|
+
/>
|
|
16
|
+
);
|
|
17
|
+
},
|
|
18
|
+
);
|
|
19
|
+
Textarea.displayName = 'Textarea';
|
|
20
|
+
|
|
21
|
+
export { Textarea };
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
import * as React from 'react';
|
|
4
|
+
import * as ToggleGroupPrimitive from '@radix-ui/react-toggle-group';
|
|
5
|
+
import { type VariantProps } from 'class-variance-authority';
|
|
6
|
+
|
|
7
|
+
import { cn } from '@/lib/utils';
|
|
8
|
+
import { toggleVariants } from '@/components/atoms/toggle';
|
|
9
|
+
|
|
10
|
+
const ToggleGroupContext = React.createContext<VariantProps<typeof toggleVariants>>({
|
|
11
|
+
size: 'default',
|
|
12
|
+
variant: 'default',
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
const ToggleGroup = React.forwardRef<
|
|
16
|
+
React.ElementRef<typeof ToggleGroupPrimitive.Root>,
|
|
17
|
+
React.ComponentPropsWithoutRef<typeof ToggleGroupPrimitive.Root> & VariantProps<typeof toggleVariants>
|
|
18
|
+
>(({ className, variant, size, children, ...props }, ref) => (
|
|
19
|
+
<ToggleGroupPrimitive.Root ref={ref} className={cn('flex items-center justify-center gap-1', className)} {...props}>
|
|
20
|
+
<ToggleGroupContext.Provider value={{ variant, size }}>{children}</ToggleGroupContext.Provider>
|
|
21
|
+
</ToggleGroupPrimitive.Root>
|
|
22
|
+
));
|
|
23
|
+
|
|
24
|
+
ToggleGroup.displayName = ToggleGroupPrimitive.Root.displayName;
|
|
25
|
+
|
|
26
|
+
const ToggleGroupItem = React.forwardRef<
|
|
27
|
+
React.ElementRef<typeof ToggleGroupPrimitive.Item>,
|
|
28
|
+
React.ComponentPropsWithoutRef<typeof ToggleGroupPrimitive.Item> & VariantProps<typeof toggleVariants>
|
|
29
|
+
>(({ className, children, variant, size, ...props }, ref) => {
|
|
30
|
+
const context = React.useContext(ToggleGroupContext);
|
|
31
|
+
|
|
32
|
+
return (
|
|
33
|
+
<ToggleGroupPrimitive.Item
|
|
34
|
+
ref={ref}
|
|
35
|
+
className={cn(
|
|
36
|
+
toggleVariants({
|
|
37
|
+
variant: context.variant || variant,
|
|
38
|
+
size: context.size || size,
|
|
39
|
+
}),
|
|
40
|
+
className,
|
|
41
|
+
)}
|
|
42
|
+
{...props}
|
|
43
|
+
>
|
|
44
|
+
{children}
|
|
45
|
+
</ToggleGroupPrimitive.Item>
|
|
46
|
+
);
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
ToggleGroupItem.displayName = ToggleGroupPrimitive.Item.displayName;
|
|
50
|
+
|
|
51
|
+
export { ToggleGroup, ToggleGroupItem };
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import * as TogglePrimitive from '@radix-ui/react-toggle';
|
|
3
|
+
import { cva, type VariantProps } from 'class-variance-authority';
|
|
4
|
+
|
|
5
|
+
import { cn } from '@/lib/utils';
|
|
6
|
+
|
|
7
|
+
const toggleVariants = cva(
|
|
8
|
+
'inline-flex items-center justify-center rounded-md text-sm font-medium ring-offset-background transition-colors hover:bg-muted hover:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 data-[state=on]:bg-accent data-[state=on]:text-accent-foreground [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0 gap-2',
|
|
9
|
+
{
|
|
10
|
+
variants: {
|
|
11
|
+
variant: {
|
|
12
|
+
default: 'bg-transparent',
|
|
13
|
+
outline: 'border border-input bg-transparent hover:bg-accent hover:text-accent-foreground',
|
|
14
|
+
},
|
|
15
|
+
size: {
|
|
16
|
+
default: 'h-10 px-3 min-w-10',
|
|
17
|
+
sm: 'h-9 px-2.5 min-w-9',
|
|
18
|
+
lg: 'h-11 px-5 min-w-11',
|
|
19
|
+
},
|
|
20
|
+
},
|
|
21
|
+
defaultVariants: {
|
|
22
|
+
variant: 'default',
|
|
23
|
+
size: 'default',
|
|
24
|
+
},
|
|
25
|
+
},
|
|
26
|
+
);
|
|
27
|
+
|
|
28
|
+
const Toggle = React.forwardRef<
|
|
29
|
+
React.ElementRef<typeof TogglePrimitive.Root>,
|
|
30
|
+
React.ComponentPropsWithoutRef<typeof TogglePrimitive.Root> & VariantProps<typeof toggleVariants>
|
|
31
|
+
>(({ className, variant, size, ...props }, ref) => (
|
|
32
|
+
<TogglePrimitive.Root ref={ref} className={cn(toggleVariants({ variant, size, className }))} {...props} />
|
|
33
|
+
));
|
|
34
|
+
|
|
35
|
+
Toggle.displayName = TogglePrimitive.Root.displayName;
|
|
36
|
+
|
|
37
|
+
export { Toggle, toggleVariants };
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
import * as React from 'react';
|
|
4
|
+
import * as TooltipPrimitive from '@radix-ui/react-tooltip';
|
|
5
|
+
|
|
6
|
+
import { cn } from '@/lib/utils';
|
|
7
|
+
|
|
8
|
+
const TooltipProvider = TooltipPrimitive.Provider;
|
|
9
|
+
|
|
10
|
+
const Tooltip = TooltipPrimitive.Root;
|
|
11
|
+
|
|
12
|
+
const TooltipTrigger = TooltipPrimitive.Trigger;
|
|
13
|
+
|
|
14
|
+
const TooltipContent = React.forwardRef<
|
|
15
|
+
React.ElementRef<typeof TooltipPrimitive.Content>,
|
|
16
|
+
React.ComponentPropsWithoutRef<typeof TooltipPrimitive.Content>
|
|
17
|
+
>(({ className, sideOffset = 4, ...props }, ref) => (
|
|
18
|
+
<TooltipPrimitive.Content
|
|
19
|
+
ref={ref}
|
|
20
|
+
sideOffset={sideOffset}
|
|
21
|
+
className={cn(
|
|
22
|
+
'z-50 overflow-hidden rounded-md border bg-popover px-3 py-1.5 text-sm text-popover-foreground shadow-md 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 origin-[--radix-tooltip-content-transform-origin]',
|
|
23
|
+
className,
|
|
24
|
+
)}
|
|
25
|
+
{...props}
|
|
26
|
+
/>
|
|
27
|
+
));
|
|
28
|
+
TooltipContent.displayName = TooltipPrimitive.Content.displayName;
|
|
29
|
+
|
|
30
|
+
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 useMobile() {
|
|
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
|
+
}
|
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
|
|
3
|
+
const TOAST_LIMIT = 1;
|
|
4
|
+
const TOAST_REMOVE_DELAY = 1000000;
|
|
5
|
+
|
|
6
|
+
type ToasterToast = any & {
|
|
7
|
+
id: string;
|
|
8
|
+
title?: React.ReactNode;
|
|
9
|
+
description?: React.ReactNode;
|
|
10
|
+
action?: any;
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
const actionTypes = {
|
|
14
|
+
ADD_TOAST: 'ADD_TOAST',
|
|
15
|
+
UPDATE_TOAST: 'UPDATE_TOAST',
|
|
16
|
+
DISMISS_TOAST: 'DISMISS_TOAST',
|
|
17
|
+
REMOVE_TOAST: 'REMOVE_TOAST',
|
|
18
|
+
} as const;
|
|
19
|
+
|
|
20
|
+
let count = 0;
|
|
21
|
+
|
|
22
|
+
function genId() {
|
|
23
|
+
count = (count + 1) % Number.MAX_SAFE_INTEGER;
|
|
24
|
+
return count.toString();
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
type ActionType = typeof actionTypes;
|
|
28
|
+
|
|
29
|
+
type Action =
|
|
30
|
+
| {
|
|
31
|
+
type: ActionType['ADD_TOAST'];
|
|
32
|
+
toast: ToasterToast;
|
|
33
|
+
}
|
|
34
|
+
| {
|
|
35
|
+
type: ActionType['UPDATE_TOAST'];
|
|
36
|
+
toast: Partial<ToasterToast>;
|
|
37
|
+
}
|
|
38
|
+
| {
|
|
39
|
+
type: ActionType['DISMISS_TOAST'];
|
|
40
|
+
toastId?: ToasterToast['id'];
|
|
41
|
+
}
|
|
42
|
+
| {
|
|
43
|
+
type: ActionType['REMOVE_TOAST'];
|
|
44
|
+
toastId?: ToasterToast['id'];
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
interface State {
|
|
48
|
+
toasts: ToasterToast[];
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
const toastTimeouts = new Map<string, ReturnType<typeof setTimeout>>();
|
|
52
|
+
|
|
53
|
+
const addToRemoveQueue = (toastId: string) => {
|
|
54
|
+
if (toastTimeouts.has(toastId)) {
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
const timeout = setTimeout(() => {
|
|
59
|
+
toastTimeouts.delete(toastId);
|
|
60
|
+
dispatch({
|
|
61
|
+
type: 'REMOVE_TOAST',
|
|
62
|
+
toastId: toastId,
|
|
63
|
+
});
|
|
64
|
+
}, TOAST_REMOVE_DELAY);
|
|
65
|
+
|
|
66
|
+
toastTimeouts.set(toastId, timeout);
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
export const reducer = (state: State, action: Action): State => {
|
|
70
|
+
switch (action.type) {
|
|
71
|
+
case 'ADD_TOAST':
|
|
72
|
+
return {
|
|
73
|
+
...state,
|
|
74
|
+
toasts: [action.toast, ...state.toasts].slice(0, TOAST_LIMIT),
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
case 'UPDATE_TOAST':
|
|
78
|
+
return {
|
|
79
|
+
...state,
|
|
80
|
+
toasts: state.toasts.map((t) => (t.id === action.toast.id ? { ...t, ...action.toast } : t)),
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
case 'DISMISS_TOAST': {
|
|
84
|
+
const { toastId } = action;
|
|
85
|
+
|
|
86
|
+
// ! Side effects ! - This could be extracted into a dismissToast() action,
|
|
87
|
+
// but I'll keep it here for simplicity
|
|
88
|
+
if (toastId) {
|
|
89
|
+
addToRemoveQueue(toastId);
|
|
90
|
+
} else {
|
|
91
|
+
state.toasts.forEach((toast) => {
|
|
92
|
+
addToRemoveQueue(toast.id);
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
return {
|
|
97
|
+
...state,
|
|
98
|
+
toasts: state.toasts.map((t) =>
|
|
99
|
+
t.id === toastId || toastId === undefined
|
|
100
|
+
? {
|
|
101
|
+
...t,
|
|
102
|
+
open: false,
|
|
103
|
+
}
|
|
104
|
+
: t,
|
|
105
|
+
),
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
case 'REMOVE_TOAST':
|
|
109
|
+
if (action.toastId === undefined) {
|
|
110
|
+
return {
|
|
111
|
+
...state,
|
|
112
|
+
toasts: [],
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
return {
|
|
116
|
+
...state,
|
|
117
|
+
toasts: state.toasts.filter((t) => t.id !== action.toastId),
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
};
|
|
121
|
+
|
|
122
|
+
const listeners: Array<(state: State) => void> = [];
|
|
123
|
+
|
|
124
|
+
let memoryState: State = { toasts: [] };
|
|
125
|
+
|
|
126
|
+
function dispatch(action: Action) {
|
|
127
|
+
memoryState = reducer(memoryState, action);
|
|
128
|
+
listeners.forEach((listener) => {
|
|
129
|
+
listener(memoryState);
|
|
130
|
+
});
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
type Toast = Omit<ToasterToast, 'id'>;
|
|
134
|
+
|
|
135
|
+
function toast({ ...props }: Toast) {
|
|
136
|
+
const id = genId();
|
|
137
|
+
|
|
138
|
+
const update = (props: ToasterToast) =>
|
|
139
|
+
dispatch({
|
|
140
|
+
type: 'UPDATE_TOAST',
|
|
141
|
+
toast: { ...props, id },
|
|
142
|
+
});
|
|
143
|
+
const dismiss = () => dispatch({ type: 'DISMISS_TOAST', toastId: id });
|
|
144
|
+
|
|
145
|
+
dispatch({
|
|
146
|
+
type: 'ADD_TOAST',
|
|
147
|
+
toast: {
|
|
148
|
+
...props,
|
|
149
|
+
id,
|
|
150
|
+
open: true,
|
|
151
|
+
onOpenChange: (open) => {
|
|
152
|
+
if (!open) dismiss();
|
|
153
|
+
},
|
|
154
|
+
},
|
|
155
|
+
});
|
|
156
|
+
|
|
157
|
+
return {
|
|
158
|
+
id: id,
|
|
159
|
+
dismiss,
|
|
160
|
+
update,
|
|
161
|
+
};
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
function useToast() {
|
|
165
|
+
const [state, setState] = React.useState<State>(memoryState);
|
|
166
|
+
|
|
167
|
+
React.useEffect(() => {
|
|
168
|
+
listeners.push(setState);
|
|
169
|
+
return () => {
|
|
170
|
+
const index = listeners.indexOf(setState);
|
|
171
|
+
if (index > -1) {
|
|
172
|
+
listeners.splice(index, 1);
|
|
173
|
+
}
|
|
174
|
+
};
|
|
175
|
+
}, [state]);
|
|
176
|
+
|
|
177
|
+
return {
|
|
178
|
+
...state,
|
|
179
|
+
toast,
|
|
180
|
+
dismiss: (toastId?: string) => {
|
|
181
|
+
if (toastId) dispatch({ type: 'DISMISS_TOAST', toastId });
|
|
182
|
+
},
|
|
183
|
+
};
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
export { useToast, toast };
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
@tailwind base;
|
|
2
|
+
@tailwind components;
|
|
3
|
+
@tailwind utilities;
|
|
4
|
+
|
|
5
|
+
@layer base {
|
|
6
|
+
:root {
|
|
7
|
+
--radius: 0.5rem;
|
|
8
|
+
|
|
9
|
+
--background: 0 0% 100%;
|
|
10
|
+
--foreground: 0 0% 7%;
|
|
11
|
+
|
|
12
|
+
--card: 0 0% 100%;
|
|
13
|
+
--card-foreground: 0 0% 7%;
|
|
14
|
+
|
|
15
|
+
--popover: 0 0% 100%;
|
|
16
|
+
--popover-foreground: 0 0% 7%;
|
|
17
|
+
|
|
18
|
+
--primary: 0 100% 40%;
|
|
19
|
+
--primary-foreground: 0 0% 100%;
|
|
20
|
+
|
|
21
|
+
--secondary: 0 0% 96%;
|
|
22
|
+
--secondary-foreground: 0 0% 7%;
|
|
23
|
+
|
|
24
|
+
--muted: 0 0% 94%;
|
|
25
|
+
--muted-foreground: 0 0% 40%;
|
|
26
|
+
|
|
27
|
+
--accent: 0 0% 97%;
|
|
28
|
+
--accent-foreground: 0 0% 7%;
|
|
29
|
+
|
|
30
|
+
--destructive: 351 100% 45%;
|
|
31
|
+
--destructive-foreground: 0 0% 100%;
|
|
32
|
+
|
|
33
|
+
--border: 0 0% 90%;
|
|
34
|
+
--input: 0 0% 90%;
|
|
35
|
+
--ring: 0 0% 84%;
|
|
36
|
+
|
|
37
|
+
--chart-1: 0 100% 40%;
|
|
38
|
+
--chart-2: 0 0% 60%;
|
|
39
|
+
--chart-3: 0 0% 40%;
|
|
40
|
+
--chart-4: 351 100% 45%;
|
|
41
|
+
--chart-5: 48 100% 50%;
|
|
42
|
+
|
|
43
|
+
--sidebar: 0 0% 100%;
|
|
44
|
+
--sidebar-foreground: 240 5.3% 26.1%;
|
|
45
|
+
--sidebar-primary: 240 5.9% 10%;
|
|
46
|
+
--sidebar-primary-foreground: 0 0% 98%;
|
|
47
|
+
--sidebar-accent: 240 4.8% 95.9%;
|
|
48
|
+
--sidebar-accent-foreground: 240 5.9% 10%;
|
|
49
|
+
--sidebar-border: 220 13% 91%;
|
|
50
|
+
--sidebar-ring: 217.2 91.2% 59.8%;
|
|
51
|
+
--sidebar-background: 0 0% 98%;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
.dark {
|
|
55
|
+
--background: 0 0% 7%;
|
|
56
|
+
--foreground: 0 0% 100%;
|
|
57
|
+
|
|
58
|
+
--card: 0 0% 7%;
|
|
59
|
+
--card-foreground: 0 0% 100%;
|
|
60
|
+
|
|
61
|
+
--popover: 0 0% 7%;
|
|
62
|
+
--popover-foreground: 0 0% 100%;
|
|
63
|
+
|
|
64
|
+
--primary: 0 0% 100%;
|
|
65
|
+
--primary-foreground: 0 100% 40%;
|
|
66
|
+
|
|
67
|
+
--secondary: 0 0% 20%;
|
|
68
|
+
--secondary-foreground: 0 0% 100%;
|
|
69
|
+
|
|
70
|
+
--muted: 0 0% 20%;
|
|
71
|
+
--muted-foreground: 0 0% 70%;
|
|
72
|
+
|
|
73
|
+
--accent: 0 0% 20%;
|
|
74
|
+
--accent-foreground: 0 0% 100%;
|
|
75
|
+
|
|
76
|
+
--destructive: 0 100% 25%;
|
|
77
|
+
--destructive-foreground: 0 0% 100%;
|
|
78
|
+
|
|
79
|
+
--border: 0 0% 20%;
|
|
80
|
+
--input: 0 0% 20%;
|
|
81
|
+
--ring: 0 0% 84%;
|
|
82
|
+
|
|
83
|
+
--sidebar: 0 0% 10%;
|
|
84
|
+
--sidebar-foreground: 240 4.8% 95.9%;
|
|
85
|
+
--sidebar-primary: 224.3 76.3% 48%;
|
|
86
|
+
--sidebar-primary-foreground: 0 0% 100%;
|
|
87
|
+
--sidebar-accent: 240 3.7% 15.9%;
|
|
88
|
+
--sidebar-accent-foreground: 240 4.8% 95.9%;
|
|
89
|
+
--sidebar-border: 240 3.7% 15.9%;
|
|
90
|
+
--sidebar-ring: 217.2 91.2% 59.8%;
|
|
91
|
+
--sidebar-background: 240 5.9% 10%;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
@layer base {
|
|
96
|
+
* {
|
|
97
|
+
@apply border-border;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
body {
|
|
101
|
+
@apply bg-background text-foreground;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
@tailwind base;
|
|
2
|
+
@tailwind components;
|
|
3
|
+
@tailwind utilities;
|
|
4
|
+
|
|
5
|
+
@layer base {
|
|
6
|
+
:root {
|
|
7
|
+
<% for (const [key, value] of Object.entries(tokens)) { %>
|
|
8
|
+
--<%= key %>: <%= value %>;
|
|
9
|
+
<% } %>
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
.dark {
|
|
13
|
+
<% for (const [key, value] of Object.entries(tokensDark)) { %>
|
|
14
|
+
--<%= key %>: <%= value %>;
|
|
15
|
+
<% } %>
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
@layer base {
|
|
20
|
+
* {
|
|
21
|
+
@apply border-border;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
body {
|
|
25
|
+
@apply bg-background text-foreground;
|
|
26
|
+
}
|
|
27
|
+
}
|