@inspirare/design-system 0.0.9 → 0.0.11
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/dist/index.css +1 -1
- package/package.json +5 -3
- package/src/App.css +184 -0
- package/src/App.tsx +222 -0
- package/src/assets/hero.png +0 -0
- package/src/assets/react.svg +1 -0
- package/src/assets/vite.svg +1 -0
- package/src/components/ui/accessibility-improvements.tsx +117 -0
- package/src/components/ui/accordion.tsx +66 -0
- package/src/components/ui/alert-dialog.tsx +151 -0
- package/src/components/ui/avatar.tsx +53 -0
- package/src/components/ui/badge.tsx +46 -0
- package/src/components/ui/button.tsx +59 -0
- package/src/components/ui/calendar.tsx +220 -0
- package/src/components/ui/card.tsx +92 -0
- package/src/components/ui/checkbox.tsx +32 -0
- package/src/components/ui/collapsible.tsx +36 -0
- package/src/components/ui/color-picker.tsx +183 -0
- package/src/components/ui/command.tsx +184 -0
- package/src/components/ui/dialog.tsx +157 -0
- package/src/components/ui/drawer.tsx +149 -0
- package/src/components/ui/dropdown-menu.tsx +259 -0
- package/src/components/ui/form.tsx +168 -0
- package/src/components/ui/hover-card.tsx +49 -0
- package/src/components/ui/input.tsx +21 -0
- package/src/components/ui/label.tsx +24 -0
- package/src/components/ui/popover.tsx +55 -0
- package/src/components/ui/progress.tsx +31 -0
- package/src/components/ui/radio-group.tsx +43 -0
- package/src/components/ui/scroll-area.tsx +32 -0
- package/src/components/ui/select.tsx +185 -0
- package/src/components/ui/separator.tsx +28 -0
- package/src/components/ui/sheet.tsx +153 -0
- package/src/components/ui/skeleton.tsx +121 -0
- package/src/components/ui/slider.tsx +63 -0
- package/src/components/ui/sonner.tsx +25 -0
- package/src/components/ui/switch.tsx +35 -0
- package/src/components/ui/table.tsx +116 -0
- package/src/components/ui/tabs.tsx +66 -0
- package/src/components/ui/textarea.tsx +18 -0
- package/src/components/ui/theme-toggle.tsx +106 -0
- package/src/components/ui/toggle-group.tsx +73 -0
- package/src/components/ui/toggle.tsx +47 -0
- package/src/components/ui/tooltip.tsx +68 -0
- package/src/demo/ButtonsDemo.tsx +82 -0
- package/src/demo/CalendarDemo.tsx +25 -0
- package/src/demo/FeedbackDemo.tsx +113 -0
- package/src/demo/FormsDemo.tsx +100 -0
- package/src/demo/NavigationDemo.tsx +141 -0
- package/src/demo/OverlaysDemo.tsx +187 -0
- package/src/index.css +1434 -0
- package/src/index.ts +41 -0
- package/src/lib/utils.ts +6 -0
- package/src/main.tsx +13 -0
|
@@ -0,0 +1,116 @@
|
|
|
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
|
|
10
|
+
data-slot="table-container"
|
|
11
|
+
className="relative w-full overflow-x-auto"
|
|
12
|
+
>
|
|
13
|
+
<table
|
|
14
|
+
data-slot="table"
|
|
15
|
+
className={cn("w-full caption-bottom text-sm", className)}
|
|
16
|
+
{...props}
|
|
17
|
+
/>
|
|
18
|
+
</div>
|
|
19
|
+
);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
function TableHeader({ className, ...props }: React.ComponentProps<"thead">) {
|
|
23
|
+
return (
|
|
24
|
+
<thead
|
|
25
|
+
data-slot="table-header"
|
|
26
|
+
className={cn("[&_tr]:border-b", className)}
|
|
27
|
+
{...props}
|
|
28
|
+
/>
|
|
29
|
+
);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
function TableBody({ className, ...props }: React.ComponentProps<"tbody">) {
|
|
33
|
+
return (
|
|
34
|
+
<tbody
|
|
35
|
+
data-slot="table-body"
|
|
36
|
+
className={cn("[&_tr:last-child]:border-0", className)}
|
|
37
|
+
{...props}
|
|
38
|
+
/>
|
|
39
|
+
);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
function TableFooter({ className, ...props }: React.ComponentProps<"tfoot">) {
|
|
43
|
+
return (
|
|
44
|
+
<tfoot
|
|
45
|
+
data-slot="table-footer"
|
|
46
|
+
className={cn(
|
|
47
|
+
"bg-muted/50 border-t font-medium [&>tr]:last:border-b-0",
|
|
48
|
+
className
|
|
49
|
+
)}
|
|
50
|
+
{...props}
|
|
51
|
+
/>
|
|
52
|
+
);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
function TableRow({ className, ...props }: React.ComponentProps<"tr">) {
|
|
56
|
+
return (
|
|
57
|
+
<tr
|
|
58
|
+
data-slot="table-row"
|
|
59
|
+
className={cn(
|
|
60
|
+
"hover:bg-muted/50 data-[state=selected]:bg-muted border-b transition-colors",
|
|
61
|
+
className
|
|
62
|
+
)}
|
|
63
|
+
{...props}
|
|
64
|
+
/>
|
|
65
|
+
);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
function TableHead({ className, ...props }: React.ComponentProps<"th">) {
|
|
69
|
+
return (
|
|
70
|
+
<th
|
|
71
|
+
data-slot="table-head"
|
|
72
|
+
className={cn(
|
|
73
|
+
"text-foreground h-10 px-2 text-left align-middle font-medium whitespace-nowrap [&:has([role=checkbox])]:pr-0 [&>[role=checkbox]]:translate-y-[2px]",
|
|
74
|
+
className
|
|
75
|
+
)}
|
|
76
|
+
{...props}
|
|
77
|
+
/>
|
|
78
|
+
);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
function TableCell({ className, ...props }: React.ComponentProps<"td">) {
|
|
82
|
+
return (
|
|
83
|
+
<td
|
|
84
|
+
data-slot="table-cell"
|
|
85
|
+
className={cn(
|
|
86
|
+
"p-2 align-middle whitespace-nowrap [&:has([role=checkbox])]:pr-0 [&>[role=checkbox]]:translate-y-[2px]",
|
|
87
|
+
className
|
|
88
|
+
)}
|
|
89
|
+
{...props}
|
|
90
|
+
/>
|
|
91
|
+
);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
function TableCaption({
|
|
95
|
+
className,
|
|
96
|
+
...props
|
|
97
|
+
}: React.ComponentProps<"caption">) {
|
|
98
|
+
return (
|
|
99
|
+
<caption
|
|
100
|
+
data-slot="table-caption"
|
|
101
|
+
className={cn("text-muted-foreground mt-4 text-sm", className)}
|
|
102
|
+
{...props}
|
|
103
|
+
/>
|
|
104
|
+
);
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
export {
|
|
108
|
+
Table,
|
|
109
|
+
TableHeader,
|
|
110
|
+
TableBody,
|
|
111
|
+
TableFooter,
|
|
112
|
+
TableHead,
|
|
113
|
+
TableRow,
|
|
114
|
+
TableCell,
|
|
115
|
+
TableCaption,
|
|
116
|
+
};
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import * as React from "react";
|
|
4
|
+
import * as TabsPrimitive from "@radix-ui/react-tabs";
|
|
5
|
+
|
|
6
|
+
import { cn } from "@/lib/utils";
|
|
7
|
+
|
|
8
|
+
function Tabs({
|
|
9
|
+
className,
|
|
10
|
+
...props
|
|
11
|
+
}: React.ComponentProps<typeof TabsPrimitive.Root>) {
|
|
12
|
+
return (
|
|
13
|
+
<TabsPrimitive.Root
|
|
14
|
+
data-slot="tabs"
|
|
15
|
+
className={cn("flex flex-col gap-2", className)}
|
|
16
|
+
{...props}
|
|
17
|
+
/>
|
|
18
|
+
);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
function TabsList({
|
|
22
|
+
className,
|
|
23
|
+
...props
|
|
24
|
+
}: React.ComponentProps<typeof TabsPrimitive.List>) {
|
|
25
|
+
return (
|
|
26
|
+
<TabsPrimitive.List
|
|
27
|
+
data-slot="tabs-list"
|
|
28
|
+
className={cn(
|
|
29
|
+
"bg-muted text-muted-foreground inline-flex h-9 w-fit items-center justify-center rounded-lg p-[3px]",
|
|
30
|
+
className
|
|
31
|
+
)}
|
|
32
|
+
{...props}
|
|
33
|
+
/>
|
|
34
|
+
);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
function TabsTrigger({
|
|
38
|
+
className,
|
|
39
|
+
...props
|
|
40
|
+
}: React.ComponentProps<typeof TabsPrimitive.Trigger>) {
|
|
41
|
+
return (
|
|
42
|
+
<TabsPrimitive.Trigger
|
|
43
|
+
data-slot="tabs-trigger"
|
|
44
|
+
className={cn(
|
|
45
|
+
"data-[state=active]:bg-background dark:data-[state=active]:text-foreground focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:outline-ring dark:data-[state=active]:border-input dark:data-[state=active]:bg-input/30 text-foreground dark:text-muted-foreground inline-flex h-[calc(100%-1px)] flex-1 cursor-pointer items-center justify-center gap-1.5 rounded-md border border-transparent px-2 py-1 text-sm font-medium whitespace-nowrap transition-[color,box-shadow] focus-visible:ring-[3px] focus-visible:outline-1 disabled:pointer-events-none disabled:opacity-50 data-[state=active]:shadow-sm [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
|
|
46
|
+
className
|
|
47
|
+
)}
|
|
48
|
+
{...props}
|
|
49
|
+
/>
|
|
50
|
+
);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
function TabsContent({
|
|
54
|
+
className,
|
|
55
|
+
...props
|
|
56
|
+
}: React.ComponentProps<typeof TabsPrimitive.Content>) {
|
|
57
|
+
return (
|
|
58
|
+
<TabsPrimitive.Content
|
|
59
|
+
data-slot="tabs-content"
|
|
60
|
+
className={cn("flex-1 outline-none", className)}
|
|
61
|
+
{...props}
|
|
62
|
+
/>
|
|
63
|
+
);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
export { Tabs, TabsList, TabsTrigger, TabsContent };
|
|
@@ -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 };
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import { Button } from "@/components/ui/button";
|
|
4
|
+
import { cn } from "@/lib/utils";
|
|
5
|
+
import { Moon, Sun } from "lucide-react";
|
|
6
|
+
import { useTheme } from "next-themes";
|
|
7
|
+
import { memo, useCallback, useEffect, useState } from "react";
|
|
8
|
+
|
|
9
|
+
interface ThemeToggleProps {
|
|
10
|
+
className?: string;
|
|
11
|
+
showLabel?: boolean;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export const ThemeToggle = memo(function ThemeToggle({
|
|
15
|
+
className,
|
|
16
|
+
showLabel,
|
|
17
|
+
}: ThemeToggleProps) {
|
|
18
|
+
const { theme, setTheme } = useTheme();
|
|
19
|
+
const [mounted, setMounted] = useState(false);
|
|
20
|
+
|
|
21
|
+
useEffect(() => {
|
|
22
|
+
setMounted(true);
|
|
23
|
+
}, []);
|
|
24
|
+
|
|
25
|
+
const cycleTheme = useCallback(() => {
|
|
26
|
+
if (theme === "light") {
|
|
27
|
+
setTheme("dark");
|
|
28
|
+
} else {
|
|
29
|
+
setTheme("light");
|
|
30
|
+
}
|
|
31
|
+
}, [theme, setTheme]);
|
|
32
|
+
|
|
33
|
+
const getThemeIcon = () => {
|
|
34
|
+
if (!mounted) return <Moon className="h-4 w-4" />;
|
|
35
|
+
|
|
36
|
+
switch (theme) {
|
|
37
|
+
case "light":
|
|
38
|
+
return <Sun className="h-4 w-4" />;
|
|
39
|
+
case "dark":
|
|
40
|
+
default:
|
|
41
|
+
return <Moon className="h-4 w-4" />;
|
|
42
|
+
}
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
const getThemeLabel = () => {
|
|
46
|
+
if (!mounted) return "Tema escuro";
|
|
47
|
+
|
|
48
|
+
switch (theme) {
|
|
49
|
+
case "light":
|
|
50
|
+
return "Tema claro";
|
|
51
|
+
case "dark":
|
|
52
|
+
default:
|
|
53
|
+
return "Tema escuro";
|
|
54
|
+
}
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
const getNextThemeLabel = () => {
|
|
58
|
+
if (!mounted) return "Mudar para tema claro";
|
|
59
|
+
|
|
60
|
+
switch (theme) {
|
|
61
|
+
case "light":
|
|
62
|
+
return "Mudar para tema escuro";
|
|
63
|
+
case "dark":
|
|
64
|
+
default:
|
|
65
|
+
return "Mudar para tema claro";
|
|
66
|
+
}
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
return (
|
|
70
|
+
<div className="relative">
|
|
71
|
+
<Button
|
|
72
|
+
variant="ghost"
|
|
73
|
+
size="sm"
|
|
74
|
+
onClick={cycleTheme}
|
|
75
|
+
className={cn(
|
|
76
|
+
"h-9 p-0 text-primary transition-all duration-300 shadow-sm hover:shadow-md backdrop-blur-sm rounded-lg",
|
|
77
|
+
"hover:bg-accent/50 active:scale-95",
|
|
78
|
+
!showLabel ? "w-9" : "px-3 w-auto",
|
|
79
|
+
className
|
|
80
|
+
)}
|
|
81
|
+
title={getNextThemeLabel()}
|
|
82
|
+
aria-label={getThemeLabel()}
|
|
83
|
+
>
|
|
84
|
+
<div className={cn("flex items-center gap-1.5", !showLabel && "justify-center")}>
|
|
85
|
+
<div className="transition-transform duration-300 hover:rotate-12">
|
|
86
|
+
{getThemeIcon()}
|
|
87
|
+
</div>
|
|
88
|
+
{showLabel && (
|
|
89
|
+
<span className="text-sm font-medium hidden lg:inline">
|
|
90
|
+
Tema
|
|
91
|
+
</span>
|
|
92
|
+
)}
|
|
93
|
+
</div>
|
|
94
|
+
</Button>
|
|
95
|
+
|
|
96
|
+
{/* Indicador visual sutil do tema atual */}
|
|
97
|
+
<div
|
|
98
|
+
className={cn(
|
|
99
|
+
"absolute -bottom-1 left-1/2 transform -translate-x-1/2 w-1 h-1 rounded-full transition-all duration-300",
|
|
100
|
+
theme === "light" ? "bg-yellow-500" : "bg-blue-500",
|
|
101
|
+
!mounted && "bg-blue-500"
|
|
102
|
+
)}
|
|
103
|
+
/>
|
|
104
|
+
</div>
|
|
105
|
+
);
|
|
106
|
+
});
|
|
@@ -0,0 +1,73 @@
|
|
|
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/ui/toggle";
|
|
9
|
+
|
|
10
|
+
const ToggleGroupContext = React.createContext<
|
|
11
|
+
VariantProps<typeof toggleVariants>
|
|
12
|
+
>({
|
|
13
|
+
size: "default",
|
|
14
|
+
variant: "default",
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
function ToggleGroup({
|
|
18
|
+
className,
|
|
19
|
+
variant,
|
|
20
|
+
size,
|
|
21
|
+
children,
|
|
22
|
+
...props
|
|
23
|
+
}: React.ComponentProps<typeof ToggleGroupPrimitive.Root> &
|
|
24
|
+
VariantProps<typeof toggleVariants>) {
|
|
25
|
+
return (
|
|
26
|
+
<ToggleGroupPrimitive.Root
|
|
27
|
+
data-slot="toggle-group"
|
|
28
|
+
data-variant={variant}
|
|
29
|
+
data-size={size}
|
|
30
|
+
className={cn(
|
|
31
|
+
"group/toggle-group flex w-fit items-center rounded-md data-[variant=outline]:shadow-xs",
|
|
32
|
+
className
|
|
33
|
+
)}
|
|
34
|
+
{...props}
|
|
35
|
+
>
|
|
36
|
+
<ToggleGroupContext.Provider value={{ variant, size }}>
|
|
37
|
+
{children}
|
|
38
|
+
</ToggleGroupContext.Provider>
|
|
39
|
+
</ToggleGroupPrimitive.Root>
|
|
40
|
+
);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
function ToggleGroupItem({
|
|
44
|
+
className,
|
|
45
|
+
children,
|
|
46
|
+
variant,
|
|
47
|
+
size,
|
|
48
|
+
...props
|
|
49
|
+
}: React.ComponentProps<typeof ToggleGroupPrimitive.Item> &
|
|
50
|
+
VariantProps<typeof toggleVariants>) {
|
|
51
|
+
const context = React.useContext(ToggleGroupContext);
|
|
52
|
+
|
|
53
|
+
return (
|
|
54
|
+
<ToggleGroupPrimitive.Item
|
|
55
|
+
data-slot="toggle-group-item"
|
|
56
|
+
data-variant={context.variant || variant}
|
|
57
|
+
data-size={context.size || size}
|
|
58
|
+
className={cn(
|
|
59
|
+
toggleVariants({
|
|
60
|
+
variant: context.variant || variant,
|
|
61
|
+
size: context.size || size,
|
|
62
|
+
}),
|
|
63
|
+
"min-w-0 flex-1 shrink-0 rounded-none shadow-none first:rounded-l-md last:rounded-r-md focus:z-10 focus-visible:z-10 data-[variant=outline]:border-l-0 data-[variant=outline]:first:border-l",
|
|
64
|
+
className
|
|
65
|
+
)}
|
|
66
|
+
{...props}
|
|
67
|
+
>
|
|
68
|
+
{children}
|
|
69
|
+
</ToggleGroupPrimitive.Item>
|
|
70
|
+
);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
export { ToggleGroup, ToggleGroupItem };
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import * as React from "react";
|
|
4
|
+
import * as TogglePrimitive from "@radix-ui/react-toggle";
|
|
5
|
+
import { cva, type VariantProps } from "class-variance-authority";
|
|
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 cursor-pointer 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:
|
|
16
|
+
"border border-input bg-transparent shadow-xs hover:bg-accent hover:text-accent-foreground",
|
|
17
|
+
},
|
|
18
|
+
size: {
|
|
19
|
+
default: "h-9 px-2 min-w-9",
|
|
20
|
+
sm: "h-8 px-1.5 min-w-8",
|
|
21
|
+
lg: "h-10 px-2.5 min-w-10",
|
|
22
|
+
},
|
|
23
|
+
},
|
|
24
|
+
defaultVariants: {
|
|
25
|
+
variant: "default",
|
|
26
|
+
size: "default",
|
|
27
|
+
},
|
|
28
|
+
}
|
|
29
|
+
);
|
|
30
|
+
|
|
31
|
+
function Toggle({
|
|
32
|
+
className,
|
|
33
|
+
variant,
|
|
34
|
+
size,
|
|
35
|
+
...props
|
|
36
|
+
}: React.ComponentProps<typeof TogglePrimitive.Root> &
|
|
37
|
+
VariantProps<typeof toggleVariants>) {
|
|
38
|
+
return (
|
|
39
|
+
<TogglePrimitive.Root
|
|
40
|
+
data-slot="toggle"
|
|
41
|
+
className={cn(toggleVariants({ variant, size, className }))}
|
|
42
|
+
{...props}
|
|
43
|
+
/>
|
|
44
|
+
);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export { Toggle, toggleVariants };
|
|
@@ -0,0 +1,68 @@
|
|
|
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
|
+
function TooltipProvider({
|
|
9
|
+
delayDuration = 0,
|
|
10
|
+
...props
|
|
11
|
+
}: React.ComponentProps<typeof TooltipPrimitive.Provider>) {
|
|
12
|
+
return (
|
|
13
|
+
<TooltipPrimitive.Provider
|
|
14
|
+
data-slot="tooltip-provider"
|
|
15
|
+
delayDuration={delayDuration}
|
|
16
|
+
{...props}
|
|
17
|
+
/>
|
|
18
|
+
);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
function Tooltip({
|
|
22
|
+
...props
|
|
23
|
+
}: React.ComponentProps<typeof TooltipPrimitive.Root>) {
|
|
24
|
+
return (
|
|
25
|
+
<TooltipProvider>
|
|
26
|
+
<TooltipPrimitive.Root data-slot="tooltip" {...props} />
|
|
27
|
+
</TooltipProvider>
|
|
28
|
+
);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
function TooltipTrigger({
|
|
32
|
+
className,
|
|
33
|
+
...props
|
|
34
|
+
}: React.ComponentProps<typeof TooltipPrimitive.Trigger>) {
|
|
35
|
+
return (
|
|
36
|
+
<TooltipPrimitive.Trigger
|
|
37
|
+
data-slot="tooltip-trigger"
|
|
38
|
+
className={cn("cursor-pointer", className)}
|
|
39
|
+
{...props}
|
|
40
|
+
/>
|
|
41
|
+
);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
function TooltipContent({
|
|
45
|
+
className,
|
|
46
|
+
sideOffset = 0,
|
|
47
|
+
children,
|
|
48
|
+
...props
|
|
49
|
+
}: React.ComponentProps<typeof TooltipPrimitive.Content>) {
|
|
50
|
+
return (
|
|
51
|
+
<TooltipPrimitive.Portal>
|
|
52
|
+
<TooltipPrimitive.Content
|
|
53
|
+
data-slot="tooltip-content"
|
|
54
|
+
sideOffset={sideOffset}
|
|
55
|
+
className={cn(
|
|
56
|
+
"bg-primary text-primary-foreground 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",
|
|
57
|
+
className
|
|
58
|
+
)}
|
|
59
|
+
{...props}
|
|
60
|
+
>
|
|
61
|
+
{children}
|
|
62
|
+
<TooltipPrimitive.Arrow className="bg-primary fill-primary z-50 size-2.5 translate-y-[calc(-50%_-_2px)] rotate-45 rounded-[2px]" />
|
|
63
|
+
</TooltipPrimitive.Content>
|
|
64
|
+
</TooltipPrimitive.Portal>
|
|
65
|
+
);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
export { Tooltip, TooltipTrigger, TooltipContent, TooltipProvider };
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import { Button } from "../components/ui/button";
|
|
2
|
+
import { Badge } from "../components/ui/badge";
|
|
3
|
+
import { Toggle } from "../components/ui/toggle";
|
|
4
|
+
import { ToggleGroup, ToggleGroupItem } from "../components/ui/toggle-group";
|
|
5
|
+
import { Card, CardContent, CardHeader, CardTitle } from "../components/ui/card";
|
|
6
|
+
import { Bold, Italic, Underline } from "lucide-react";
|
|
7
|
+
|
|
8
|
+
export function ButtonsDemo() {
|
|
9
|
+
return (
|
|
10
|
+
<div className="space-y-8">
|
|
11
|
+
<Card>
|
|
12
|
+
<CardHeader>
|
|
13
|
+
<CardTitle>Variantes de Botões</CardTitle>
|
|
14
|
+
</CardHeader>
|
|
15
|
+
<CardContent className="flex flex-wrap gap-4 items-center">
|
|
16
|
+
<Button variant="default">Padrão</Button>
|
|
17
|
+
<Button variant="secondary">Secundário</Button>
|
|
18
|
+
<Button variant="outline">Contorno (Outline)</Button>
|
|
19
|
+
<Button variant="ghost">Fantasma (Ghost)</Button>
|
|
20
|
+
<Button variant="link">Link</Button>
|
|
21
|
+
<Button variant="destructive">Destrutivo</Button>
|
|
22
|
+
</CardContent>
|
|
23
|
+
</Card>
|
|
24
|
+
|
|
25
|
+
<Card>
|
|
26
|
+
<CardHeader>
|
|
27
|
+
<CardTitle>Tamanhos de Botões</CardTitle>
|
|
28
|
+
</CardHeader>
|
|
29
|
+
<CardContent className="flex flex-wrap gap-4 items-center">
|
|
30
|
+
<Button size="sm">Pequeno</Button>
|
|
31
|
+
<Button size="default">Padrão</Button>
|
|
32
|
+
<Button size="lg">Grande</Button>
|
|
33
|
+
<Button size="icon">
|
|
34
|
+
<span className="sr-only">Ícone</span>
|
|
35
|
+
<Bold className="w-4 h-4" />
|
|
36
|
+
</Button>
|
|
37
|
+
</CardContent>
|
|
38
|
+
</Card>
|
|
39
|
+
|
|
40
|
+
<Card>
|
|
41
|
+
<CardHeader>
|
|
42
|
+
<CardTitle>Variantes de Badges</CardTitle>
|
|
43
|
+
</CardHeader>
|
|
44
|
+
<CardContent className="flex flex-wrap gap-4 items-center">
|
|
45
|
+
<Badge variant="default">Padrão</Badge>
|
|
46
|
+
<Badge variant="secondary">Secundário</Badge>
|
|
47
|
+
<Badge variant="outline">Contorno</Badge>
|
|
48
|
+
<Badge variant="destructive">Destrutivo</Badge>
|
|
49
|
+
</CardContent>
|
|
50
|
+
</Card>
|
|
51
|
+
|
|
52
|
+
<Card>
|
|
53
|
+
<CardHeader>
|
|
54
|
+
<CardTitle>Toggles</CardTitle>
|
|
55
|
+
</CardHeader>
|
|
56
|
+
<CardContent className="flex flex-wrap gap-8 items-center">
|
|
57
|
+
<div className="space-y-2">
|
|
58
|
+
<p className="text-sm text-muted-foreground">Toggle Simples</p>
|
|
59
|
+
<Toggle aria-label="Ativar negrito">
|
|
60
|
+
<Bold className="h-4 w-4" />
|
|
61
|
+
</Toggle>
|
|
62
|
+
</div>
|
|
63
|
+
|
|
64
|
+
<div className="space-y-2">
|
|
65
|
+
<p className="text-sm text-muted-foreground">Toggle Group (Múltiplo)</p>
|
|
66
|
+
<ToggleGroup type="multiple">
|
|
67
|
+
<ToggleGroupItem value="bold" aria-label="Toggle bold">
|
|
68
|
+
<Bold className="h-4 w-4" />
|
|
69
|
+
</ToggleGroupItem>
|
|
70
|
+
<ToggleGroupItem value="italic" aria-label="Toggle italic">
|
|
71
|
+
<Italic className="h-4 w-4" />
|
|
72
|
+
</ToggleGroupItem>
|
|
73
|
+
<ToggleGroupItem value="underline" aria-label="Toggle underline">
|
|
74
|
+
<Underline className="h-4 w-4" />
|
|
75
|
+
</ToggleGroupItem>
|
|
76
|
+
</ToggleGroup>
|
|
77
|
+
</div>
|
|
78
|
+
</CardContent>
|
|
79
|
+
</Card>
|
|
80
|
+
</div>
|
|
81
|
+
);
|
|
82
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { useState } from "react";
|
|
2
|
+
import { Card, CardContent, CardHeader, CardTitle } from "../components/ui/card";
|
|
3
|
+
import { Calendar } from "../components/ui/calendar";
|
|
4
|
+
|
|
5
|
+
export function CalendarDemo() {
|
|
6
|
+
const [date, setDate] = useState<Date | undefined>(new Date());
|
|
7
|
+
|
|
8
|
+
return (
|
|
9
|
+
<div className="space-y-8">
|
|
10
|
+
<Card>
|
|
11
|
+
<CardHeader>
|
|
12
|
+
<CardTitle>Calendário</CardTitle>
|
|
13
|
+
</CardHeader>
|
|
14
|
+
<CardContent className="flex justify-center">
|
|
15
|
+
<Calendar
|
|
16
|
+
mode="single"
|
|
17
|
+
selected={date}
|
|
18
|
+
onSelect={setDate}
|
|
19
|
+
className="rounded-md border"
|
|
20
|
+
/>
|
|
21
|
+
</CardContent>
|
|
22
|
+
</Card>
|
|
23
|
+
</div>
|
|
24
|
+
);
|
|
25
|
+
}
|