@robomous/ui-core 0.1.1 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +15 -7
- package/dist/{primitives → components}/alert.js +1 -1
- package/dist/{primitives → components}/badge.js +1 -1
- package/dist/{primitives → components}/button.d.ts +1 -1
- package/dist/{primitives → components}/button.js +4 -1
- package/dist/{primitives → components}/card.d.ts +1 -1
- package/dist/{primitives → components}/card.js +2 -2
- package/dist/{primitives → components}/combobox.js +3 -3
- package/dist/{primitives → components}/dialog.js +1 -1
- package/dist/{primitives → components}/dropdown-menu.js +11 -6
- package/dist/{primitives → components}/field.js +2 -4
- package/dist/{primitives → components}/input-group.js +1 -1
- package/dist/{primitives → components}/input.js +1 -1
- package/dist/{primitives → components}/label.js +1 -1
- package/dist/components/progress.js +7 -0
- package/dist/{primitives → components}/select.d.ts +3 -1
- package/dist/{primitives → components}/select.js +6 -4
- package/dist/{primitives → components}/separator.js +1 -1
- package/dist/{primitives → components}/sheet.js +1 -1
- package/dist/{primitives → components}/skeleton.js +1 -1
- package/dist/{primitives → components}/sonner.js +17 -12
- package/dist/{primitives → components}/table.d.ts +1 -1
- package/dist/{primitives → components}/table.js +3 -3
- package/dist/{primitives → components}/tabs.js +1 -1
- package/dist/{primitives → components}/textarea.js +1 -1
- package/dist/{primitives → components}/tooltip.js +1 -1
- package/dist/gates/index.d.ts +28 -0
- package/dist/gates/index.js +142 -0
- package/dist/index.d.ts +31 -32
- package/dist/index.js +32 -33
- package/dist/{tokens.d.ts → theme/tokens.d.ts} +5 -5
- package/dist/{tokens.js → theme/tokens.js} +12 -12
- package/package.json +23 -12
- package/{shadcn → src/components}/alert.tsx +14 -21
- package/src/{primitives → components}/badge.tsx +15 -21
- package/src/{primitives → components}/button.tsx +13 -10
- package/{shadcn → src/components}/card.tsx +16 -31
- package/src/{primitives → components}/combobox.test.tsx +15 -2
- package/src/{primitives → components}/combobox.tsx +45 -74
- package/src/{primitives/primitives.test.tsx → components/components.test.tsx} +106 -69
- package/src/{primitives → components}/dialog.tsx +31 -54
- package/src/{primitives → components}/dropdown-menu.tsx +51 -65
- package/src/{primitives → components}/field.tsx +48 -62
- package/src/{primitives → components}/input-group.tsx +37 -49
- package/{shadcn → src/components}/input.tsx +5 -5
- package/{shadcn → src/components}/label.tsx +7 -10
- package/src/{primitives → components}/progress.tsx +7 -6
- package/{shadcn → src/components}/select.tsx +39 -41
- package/{shadcn → src/components}/separator.tsx +7 -7
- package/src/{primitives → components}/sheet.tsx +27 -44
- package/{shadcn → src/components}/skeleton.tsx +3 -3
- package/src/{primitives → components}/sonner.test.tsx +12 -4
- package/src/components/sonner.tsx +67 -0
- package/{shadcn → src/components}/table.tsx +17 -44
- package/{shadcn → src/components}/tabs.tsx +16 -26
- package/{shadcn → src/components}/textarea.tsx +5 -5
- package/{shadcn → src/components}/tooltip.tsx +12 -16
- package/src/gates/design.test.ts +188 -0
- package/src/gates/index.test.ts +11 -0
- package/src/gates/index.ts +165 -0
- package/src/gates/tokens.test.ts +215 -0
- package/src/harness.test.tsx +1 -1
- package/src/index.ts +63 -33
- package/src/theme/imports.test.ts +160 -0
- package/src/{statusTone.test.ts → theme/statusTone.test.ts} +5 -1
- package/src/{styles.css → theme/styles.css} +45 -31
- package/src/theme/tailwind.css +646 -0
- package/src/{tokens.test.ts → theme/tokens.test.ts} +30 -23
- package/src/{tokens.ts → theme/tokens.ts} +12 -12
- package/components.json +0 -13
- package/dist/lib/button.d.ts +0 -1
- package/dist/lib/button.js +0 -4
- package/dist/lib/cn.d.ts +0 -18
- package/dist/lib/cn.js +0 -21
- package/dist/lib/menu.d.ts +0 -1
- package/dist/lib/menu.js +0 -16
- package/dist/lib/progress.d.ts +0 -3
- package/dist/lib/progress.js +0 -6
- package/dist/lib/select.d.ts +0 -1
- package/dist/lib/select.js +0 -3
- package/dist/primitives/progress.js +0 -7
- package/gates/canonical.test.mjs +0 -71
- package/gates/extensions.test.mjs +0 -373
- package/gates/index.d.mts +0 -51
- package/gates/index.mjs +0 -514
- package/gates/tokens.test.mjs +0 -276
- package/shadcn/README.md +0 -13
- package/shadcn/badge.tsx +0 -49
- package/shadcn/button.tsx +0 -67
- package/shadcn/combobox.tsx +0 -299
- package/shadcn/dialog.tsx +0 -166
- package/shadcn/dropdown-menu.tsx +0 -267
- package/shadcn/field.tsx +0 -236
- package/shadcn/input-group.tsx +0 -154
- package/shadcn/progress.tsx +0 -29
- package/shadcn/sheet.tsx +0 -145
- package/shadcn/sonner.tsx +0 -49
- package/src/lib/button.ts +0 -4
- package/src/lib/cn.test.ts +0 -33
- package/src/lib/cn.ts +0 -23
- package/src/lib/menu.ts +0 -16
- package/src/lib/progress.ts +0 -6
- package/src/lib/select.ts +0 -4
- package/src/primitives/alert.tsx +0 -76
- package/src/primitives/card.tsx +0 -103
- package/src/primitives/input.tsx +0 -19
- package/src/primitives/label.tsx +0 -22
- package/src/primitives/select.tsx +0 -192
- package/src/primitives/separator.tsx +0 -28
- package/src/primitives/skeleton.tsx +0 -13
- package/src/primitives/sonner.tsx +0 -65
- package/src/primitives/table.tsx +0 -114
- package/src/primitives/tabs.tsx +0 -88
- package/src/primitives/textarea.tsx +0 -18
- package/src/primitives/tooltip.tsx +0 -57
- /package/dist/{primitives → components}/alert.d.ts +0 -0
- /package/dist/{primitives → components}/badge.d.ts +0 -0
- /package/dist/{primitives → components}/combobox.d.ts +0 -0
- /package/dist/{primitives → components}/dialog.d.ts +0 -0
- /package/dist/{primitives → components}/dropdown-menu.d.ts +0 -0
- /package/dist/{primitives → components}/field.d.ts +0 -0
- /package/dist/{primitives → components}/input-group.d.ts +0 -0
- /package/dist/{primitives → components}/input.d.ts +0 -0
- /package/dist/{primitives → components}/label.d.ts +0 -0
- /package/dist/{primitives → components}/progress.d.ts +0 -0
- /package/dist/{primitives → components}/separator.d.ts +0 -0
- /package/dist/{primitives → components}/sheet.d.ts +0 -0
- /package/dist/{primitives → components}/skeleton.d.ts +0 -0
- /package/dist/{primitives → components}/sonner.d.ts +0 -0
- /package/dist/{primitives → components}/tabs.d.ts +0 -0
- /package/dist/{primitives → components}/textarea.d.ts +0 -0
- /package/dist/{primitives → components}/tooltip.d.ts +0 -0
- /package/dist/{statusTone.d.ts → theme/statusTone.d.ts} +0 -0
- /package/dist/{statusTone.js → theme/statusTone.js} +0 -0
- /package/src/{statusTone.ts → theme/statusTone.ts} +0 -0
|
@@ -1,43 +1,39 @@
|
|
|
1
|
-
"use client"
|
|
1
|
+
"use client";
|
|
2
2
|
|
|
3
|
-
import * as React from "react"
|
|
4
|
-
import { Select as SelectPrimitive } from "radix-ui"
|
|
3
|
+
import * as React from "react";
|
|
4
|
+
import { Select as SelectPrimitive } from "radix-ui";
|
|
5
5
|
|
|
6
|
-
import { cn } from "
|
|
7
|
-
import { ChevronDownIcon, CheckIcon, ChevronUpIcon } from "lucide-react"
|
|
6
|
+
import { cn } from "cn";
|
|
7
|
+
import { ChevronDownIcon, CheckIcon, ChevronUpIcon } from "lucide-react";
|
|
8
8
|
|
|
9
|
-
function Select({
|
|
10
|
-
...props
|
|
11
|
-
}: React.ComponentProps<typeof SelectPrimitive.Root>) {
|
|
12
|
-
return <SelectPrimitive.Root data-slot="select" {...props} />
|
|
9
|
+
function Select({ ...props }: React.ComponentProps<typeof SelectPrimitive.Root>) {
|
|
10
|
+
return <SelectPrimitive.Root data-slot="select" {...props} />;
|
|
13
11
|
}
|
|
14
12
|
|
|
15
|
-
function SelectGroup({
|
|
16
|
-
className,
|
|
17
|
-
...props
|
|
18
|
-
}: React.ComponentProps<typeof SelectPrimitive.Group>) {
|
|
13
|
+
function SelectGroup({ className, ...props }: React.ComponentProps<typeof SelectPrimitive.Group>) {
|
|
19
14
|
return (
|
|
20
15
|
<SelectPrimitive.Group
|
|
21
16
|
data-slot="select-group"
|
|
22
17
|
className={cn("scroll-my-1 p-1", className)}
|
|
23
18
|
{...props}
|
|
24
19
|
/>
|
|
25
|
-
)
|
|
20
|
+
);
|
|
26
21
|
}
|
|
27
22
|
|
|
28
|
-
function SelectValue({
|
|
29
|
-
...props
|
|
30
|
-
}: React.ComponentProps<typeof SelectPrimitive.Value>) {
|
|
31
|
-
return <SelectPrimitive.Value data-slot="select-value" {...props} />
|
|
23
|
+
function SelectValue({ ...props }: React.ComponentProps<typeof SelectPrimitive.Value>) {
|
|
24
|
+
return <SelectPrimitive.Value data-slot="select-value" {...props} />;
|
|
32
25
|
}
|
|
33
26
|
|
|
34
27
|
function SelectTrigger({
|
|
35
28
|
className,
|
|
36
29
|
size = "default",
|
|
30
|
+
multiline = false,
|
|
37
31
|
children,
|
|
38
32
|
...props
|
|
39
33
|
}: React.ComponentProps<typeof SelectPrimitive.Trigger> & {
|
|
40
|
-
size?: "sm" | "default"
|
|
34
|
+
size?: "sm" | "default";
|
|
35
|
+
/** Let the closed trigger grow to its value instead of clamping it to one line. */
|
|
36
|
+
multiline?: boolean;
|
|
41
37
|
}) {
|
|
42
38
|
return (
|
|
43
39
|
<SelectPrimitive.Trigger
|
|
@@ -45,7 +41,9 @@ function SelectTrigger({
|
|
|
45
41
|
data-size={size}
|
|
46
42
|
className={cn(
|
|
47
43
|
"flex w-fit items-center justify-between gap-1.5 rounded-lg border border-input bg-transparent py-2 pr-2 pl-2.5 text-sm whitespace-nowrap transition-colors outline-none select-none focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 disabled:cursor-not-allowed disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 data-placeholder:text-muted-foreground data-[size=default]:h-8 data-[size=sm]:h-7 data-[size=sm]:rounded-[min(var(--radius-md),10px)] *:data-[slot=select-value]:line-clamp-1 *:data-[slot=select-value]:flex *:data-[slot=select-value]:items-center *:data-[slot=select-value]:gap-1.5 dark:bg-input/30 dark:hover:bg-input/50 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
|
|
48
|
-
|
|
44
|
+
multiline &&
|
|
45
|
+
"data-[size=default]:h-auto min-h-8 *:data-[slot=select-value]:line-clamp-none",
|
|
46
|
+
className,
|
|
49
47
|
)}
|
|
50
48
|
{...props}
|
|
51
49
|
>
|
|
@@ -54,7 +52,7 @@ function SelectTrigger({
|
|
|
54
52
|
<ChevronDownIcon className="pointer-events-none size-4 text-muted-foreground" />
|
|
55
53
|
</SelectPrimitive.Icon>
|
|
56
54
|
</SelectPrimitive.Trigger>
|
|
57
|
-
)
|
|
55
|
+
);
|
|
58
56
|
}
|
|
59
57
|
|
|
60
58
|
function SelectContent({
|
|
@@ -69,7 +67,12 @@ function SelectContent({
|
|
|
69
67
|
<SelectPrimitive.Content
|
|
70
68
|
data-slot="select-content"
|
|
71
69
|
data-align-trigger={position === "item-aligned"}
|
|
72
|
-
className={cn(
|
|
70
|
+
className={cn(
|
|
71
|
+
"relative z-50 max-h-(--radix-select-content-available-height) min-w-36 origin-(--radix-select-content-transform-origin) overflow-x-hidden overflow-y-auto rounded-lg bg-popover text-popover-foreground shadow-md ring-1 ring-foreground/10 duration-100 data-[align-trigger=true]:animate-none 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 data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95",
|
|
72
|
+
position === "popper" &&
|
|
73
|
+
"data-[side=bottom]:translate-y-1 data-[side=left]:-translate-x-1 data-[side=right]:translate-x-1 data-[side=top]:-translate-y-1",
|
|
74
|
+
className,
|
|
75
|
+
)}
|
|
73
76
|
position={position}
|
|
74
77
|
align={align}
|
|
75
78
|
{...props}
|
|
@@ -79,7 +82,7 @@ function SelectContent({
|
|
|
79
82
|
data-position={position}
|
|
80
83
|
className={cn(
|
|
81
84
|
"data-[position=popper]:h-(--radix-select-trigger-height) data-[position=popper]:w-full data-[position=popper]:min-w-(--radix-select-trigger-width)",
|
|
82
|
-
position === "popper" && ""
|
|
85
|
+
position === "popper" && "",
|
|
83
86
|
)}
|
|
84
87
|
>
|
|
85
88
|
{children}
|
|
@@ -87,20 +90,17 @@ function SelectContent({
|
|
|
87
90
|
<SelectScrollDownButton />
|
|
88
91
|
</SelectPrimitive.Content>
|
|
89
92
|
</SelectPrimitive.Portal>
|
|
90
|
-
)
|
|
93
|
+
);
|
|
91
94
|
}
|
|
92
95
|
|
|
93
|
-
function SelectLabel({
|
|
94
|
-
className,
|
|
95
|
-
...props
|
|
96
|
-
}: React.ComponentProps<typeof SelectPrimitive.Label>) {
|
|
96
|
+
function SelectLabel({ className, ...props }: React.ComponentProps<typeof SelectPrimitive.Label>) {
|
|
97
97
|
return (
|
|
98
98
|
<SelectPrimitive.Label
|
|
99
99
|
data-slot="select-label"
|
|
100
100
|
className={cn("px-1.5 py-1 text-xs text-muted-foreground", className)}
|
|
101
101
|
{...props}
|
|
102
102
|
/>
|
|
103
|
-
)
|
|
103
|
+
);
|
|
104
104
|
}
|
|
105
105
|
|
|
106
106
|
function SelectItem({
|
|
@@ -113,7 +113,7 @@ function SelectItem({
|
|
|
113
113
|
data-slot="select-item"
|
|
114
114
|
className={cn(
|
|
115
115
|
"relative flex w-full cursor-default items-center gap-1.5 rounded-md py-1 pr-8 pl-1.5 text-sm outline-hidden select-none focus:bg-accent focus:text-accent-foreground not-data-[variant=destructive]:focus:**:text-accent-foreground data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4 *:[span]:last:flex *:[span]:last:items-center *:[span]:last:gap-2",
|
|
116
|
-
className
|
|
116
|
+
className,
|
|
117
117
|
)}
|
|
118
118
|
{...props}
|
|
119
119
|
>
|
|
@@ -124,7 +124,7 @@ function SelectItem({
|
|
|
124
124
|
</span>
|
|
125
125
|
<SelectPrimitive.ItemText>{children}</SelectPrimitive.ItemText>
|
|
126
126
|
</SelectPrimitive.Item>
|
|
127
|
-
)
|
|
127
|
+
);
|
|
128
128
|
}
|
|
129
129
|
|
|
130
130
|
function SelectSeparator({
|
|
@@ -137,7 +137,7 @@ function SelectSeparator({
|
|
|
137
137
|
className={cn("pointer-events-none -mx-1 my-1 h-px bg-border", className)}
|
|
138
138
|
{...props}
|
|
139
139
|
/>
|
|
140
|
-
)
|
|
140
|
+
);
|
|
141
141
|
}
|
|
142
142
|
|
|
143
143
|
function SelectScrollUpButton({
|
|
@@ -149,14 +149,13 @@ function SelectScrollUpButton({
|
|
|
149
149
|
data-slot="select-scroll-up-button"
|
|
150
150
|
className={cn(
|
|
151
151
|
"z-10 flex cursor-default items-center justify-center bg-popover py-1 [&_svg:not([class*='size-'])]:size-4",
|
|
152
|
-
className
|
|
152
|
+
className,
|
|
153
153
|
)}
|
|
154
154
|
{...props}
|
|
155
155
|
>
|
|
156
|
-
<ChevronUpIcon
|
|
157
|
-
/>
|
|
156
|
+
<ChevronUpIcon />
|
|
158
157
|
</SelectPrimitive.ScrollUpButton>
|
|
159
|
-
)
|
|
158
|
+
);
|
|
160
159
|
}
|
|
161
160
|
|
|
162
161
|
function SelectScrollDownButton({
|
|
@@ -168,14 +167,13 @@ function SelectScrollDownButton({
|
|
|
168
167
|
data-slot="select-scroll-down-button"
|
|
169
168
|
className={cn(
|
|
170
169
|
"z-10 flex cursor-default items-center justify-center bg-popover py-1 [&_svg:not([class*='size-'])]:size-4",
|
|
171
|
-
className
|
|
170
|
+
className,
|
|
172
171
|
)}
|
|
173
172
|
{...props}
|
|
174
173
|
>
|
|
175
|
-
<ChevronDownIcon
|
|
176
|
-
/>
|
|
174
|
+
<ChevronDownIcon />
|
|
177
175
|
</SelectPrimitive.ScrollDownButton>
|
|
178
|
-
)
|
|
176
|
+
);
|
|
179
177
|
}
|
|
180
178
|
|
|
181
179
|
export {
|
|
@@ -189,4 +187,4 @@ export {
|
|
|
189
187
|
SelectSeparator,
|
|
190
188
|
SelectTrigger,
|
|
191
189
|
SelectValue,
|
|
192
|
-
}
|
|
190
|
+
};
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
"use client"
|
|
1
|
+
"use client";
|
|
2
2
|
|
|
3
|
-
import * as React from "react"
|
|
4
|
-
import { Separator as SeparatorPrimitive } from "radix-ui"
|
|
3
|
+
import * as React from "react";
|
|
4
|
+
import { Separator as SeparatorPrimitive } from "radix-ui";
|
|
5
5
|
|
|
6
|
-
import { cn } from "
|
|
6
|
+
import { cn } from "cn";
|
|
7
7
|
|
|
8
8
|
function Separator({
|
|
9
9
|
className,
|
|
@@ -18,11 +18,11 @@ function Separator({
|
|
|
18
18
|
orientation={orientation}
|
|
19
19
|
className={cn(
|
|
20
20
|
"shrink-0 bg-border data-horizontal:h-px data-horizontal:w-full data-vertical:w-px data-vertical:self-stretch",
|
|
21
|
-
className
|
|
21
|
+
className,
|
|
22
22
|
)}
|
|
23
23
|
{...props}
|
|
24
24
|
/>
|
|
25
|
-
)
|
|
25
|
+
);
|
|
26
26
|
}
|
|
27
27
|
|
|
28
|
-
export { Separator }
|
|
28
|
+
export { Separator };
|
|
@@ -1,30 +1,24 @@
|
|
|
1
|
-
import * as React from "react"
|
|
2
|
-
import { Dialog as SheetPrimitive } from "radix-ui"
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import { Dialog as SheetPrimitive } from "radix-ui";
|
|
3
3
|
|
|
4
|
-
import { cn } from "
|
|
5
|
-
import { Button } from "./button.js"
|
|
6
|
-
import { XIcon } from "lucide-react"
|
|
4
|
+
import { cn } from "cn";
|
|
5
|
+
import { Button } from "./button.js";
|
|
6
|
+
import { XIcon } from "lucide-react";
|
|
7
7
|
|
|
8
8
|
function Sheet({ ...props }: React.ComponentProps<typeof SheetPrimitive.Root>) {
|
|
9
|
-
return <SheetPrimitive.Root data-slot="sheet" {...props}
|
|
9
|
+
return <SheetPrimitive.Root data-slot="sheet" {...props} />;
|
|
10
10
|
}
|
|
11
11
|
|
|
12
|
-
function SheetTrigger({
|
|
13
|
-
...props
|
|
14
|
-
}: React.ComponentProps<typeof SheetPrimitive.Trigger>) {
|
|
15
|
-
return <SheetPrimitive.Trigger data-slot="sheet-trigger" {...props} />
|
|
12
|
+
function SheetTrigger({ ...props }: React.ComponentProps<typeof SheetPrimitive.Trigger>) {
|
|
13
|
+
return <SheetPrimitive.Trigger data-slot="sheet-trigger" {...props} />;
|
|
16
14
|
}
|
|
17
15
|
|
|
18
|
-
function SheetClose({
|
|
19
|
-
...props
|
|
20
|
-
}: React.ComponentProps<typeof SheetPrimitive.Close>) {
|
|
21
|
-
return <SheetPrimitive.Close data-slot="sheet-close" {...props} />
|
|
16
|
+
function SheetClose({ ...props }: React.ComponentProps<typeof SheetPrimitive.Close>) {
|
|
17
|
+
return <SheetPrimitive.Close data-slot="sheet-close" {...props} />;
|
|
22
18
|
}
|
|
23
19
|
|
|
24
|
-
function SheetPortal({
|
|
25
|
-
...props
|
|
26
|
-
}: React.ComponentProps<typeof SheetPrimitive.Portal>) {
|
|
27
|
-
return <SheetPrimitive.Portal data-slot="sheet-portal" {...props} />
|
|
20
|
+
function SheetPortal({ ...props }: React.ComponentProps<typeof SheetPrimitive.Portal>) {
|
|
21
|
+
return <SheetPrimitive.Portal data-slot="sheet-portal" {...props} />;
|
|
28
22
|
}
|
|
29
23
|
|
|
30
24
|
function SheetOverlay({
|
|
@@ -36,11 +30,11 @@ function SheetOverlay({
|
|
|
36
30
|
data-slot="sheet-overlay"
|
|
37
31
|
className={cn(
|
|
38
32
|
"fixed inset-0 z-50 bg-black/10 duration-100 supports-backdrop-filter:backdrop-blur-xs data-open:animate-in data-open:fade-in-0 data-closed:animate-out data-closed:fade-out-0",
|
|
39
|
-
className
|
|
33
|
+
className,
|
|
40
34
|
)}
|
|
41
35
|
{...props}
|
|
42
36
|
/>
|
|
43
|
-
)
|
|
37
|
+
);
|
|
44
38
|
}
|
|
45
39
|
|
|
46
40
|
function SheetContent({
|
|
@@ -50,8 +44,8 @@ function SheetContent({
|
|
|
50
44
|
showCloseButton = true,
|
|
51
45
|
...props
|
|
52
46
|
}: React.ComponentProps<typeof SheetPrimitive.Content> & {
|
|
53
|
-
side?: "top" | "right" | "bottom" | "left"
|
|
54
|
-
showCloseButton?: boolean
|
|
47
|
+
side?: "top" | "right" | "bottom" | "left";
|
|
48
|
+
showCloseButton?: boolean;
|
|
55
49
|
}) {
|
|
56
50
|
return (
|
|
57
51
|
<SheetPortal>
|
|
@@ -61,27 +55,22 @@ function SheetContent({
|
|
|
61
55
|
data-side={side}
|
|
62
56
|
className={cn(
|
|
63
57
|
"fixed z-50 flex flex-col gap-4 bg-popover bg-clip-padding text-sm text-popover-foreground shadow-lg transition duration-200 ease-in-out data-[side=bottom]:inset-x-0 data-[side=bottom]:bottom-0 data-[side=bottom]:h-auto data-[side=bottom]:border-t data-[side=left]:inset-y-0 data-[side=left]:left-0 data-[side=left]:h-full data-[side=left]:w-3/4 data-[side=left]:border-r data-[side=right]:inset-y-0 data-[side=right]:right-0 data-[side=right]:h-full data-[side=right]:w-3/4 data-[side=right]:border-l data-[side=top]:inset-x-0 data-[side=top]:top-0 data-[side=top]:h-auto data-[side=top]:border-b data-[side=left]:sm:max-w-sm data-[side=right]:sm:max-w-sm data-open:animate-in data-open:fade-in-0 data-[side=bottom]:data-open:slide-in-from-bottom-10 data-[side=left]:data-open:slide-in-from-left-10 data-[side=right]:data-open:slide-in-from-right-10 data-[side=top]:data-open:slide-in-from-top-10 data-closed:animate-out data-closed:fade-out-0 data-[side=bottom]:data-closed:slide-out-to-bottom-10 data-[side=left]:data-closed:slide-out-to-left-10 data-[side=right]:data-closed:slide-out-to-right-10 data-[side=top]:data-closed:slide-out-to-top-10",
|
|
64
|
-
className
|
|
58
|
+
className,
|
|
65
59
|
)}
|
|
66
60
|
{...props}
|
|
67
61
|
>
|
|
68
62
|
{children}
|
|
69
63
|
{showCloseButton && (
|
|
70
64
|
<SheetPrimitive.Close data-slot="sheet-close" asChild>
|
|
71
|
-
<Button
|
|
72
|
-
|
|
73
|
-
className="absolute top-3 right-3"
|
|
74
|
-
size="icon-sm"
|
|
75
|
-
>
|
|
76
|
-
<XIcon
|
|
77
|
-
/>
|
|
65
|
+
<Button variant="ghost" className="absolute top-3 right-3" size="icon-sm">
|
|
66
|
+
<XIcon />
|
|
78
67
|
<span className="sr-only">Close</span>
|
|
79
68
|
</Button>
|
|
80
69
|
</SheetPrimitive.Close>
|
|
81
70
|
)}
|
|
82
71
|
</SheetPrimitive.Content>
|
|
83
72
|
</SheetPortal>
|
|
84
|
-
)
|
|
73
|
+
);
|
|
85
74
|
}
|
|
86
75
|
|
|
87
76
|
function SheetHeader({ className, ...props }: React.ComponentProps<"div">) {
|
|
@@ -91,7 +80,7 @@ function SheetHeader({ className, ...props }: React.ComponentProps<"div">) {
|
|
|
91
80
|
className={cn("flex flex-col gap-0.5 p-4", className)}
|
|
92
81
|
{...props}
|
|
93
82
|
/>
|
|
94
|
-
)
|
|
83
|
+
);
|
|
95
84
|
}
|
|
96
85
|
|
|
97
86
|
function SheetFooter({ className, ...props }: React.ComponentProps<"div">) {
|
|
@@ -101,23 +90,17 @@ function SheetFooter({ className, ...props }: React.ComponentProps<"div">) {
|
|
|
101
90
|
className={cn("mt-auto flex flex-col gap-2 p-4", className)}
|
|
102
91
|
{...props}
|
|
103
92
|
/>
|
|
104
|
-
)
|
|
93
|
+
);
|
|
105
94
|
}
|
|
106
95
|
|
|
107
|
-
function SheetTitle({
|
|
108
|
-
className,
|
|
109
|
-
...props
|
|
110
|
-
}: React.ComponentProps<typeof SheetPrimitive.Title>) {
|
|
96
|
+
function SheetTitle({ className, ...props }: React.ComponentProps<typeof SheetPrimitive.Title>) {
|
|
111
97
|
return (
|
|
112
98
|
<SheetPrimitive.Title
|
|
113
99
|
data-slot="sheet-title"
|
|
114
|
-
className={cn(
|
|
115
|
-
"font-heading text-base font-medium text-foreground",
|
|
116
|
-
className
|
|
117
|
-
)}
|
|
100
|
+
className={cn("font-heading text-base font-medium text-foreground", className)}
|
|
118
101
|
{...props}
|
|
119
102
|
/>
|
|
120
|
-
)
|
|
103
|
+
);
|
|
121
104
|
}
|
|
122
105
|
|
|
123
106
|
function SheetDescription({
|
|
@@ -130,7 +113,7 @@ function SheetDescription({
|
|
|
130
113
|
className={cn("text-sm text-muted-foreground", className)}
|
|
131
114
|
{...props}
|
|
132
115
|
/>
|
|
133
|
-
)
|
|
116
|
+
);
|
|
134
117
|
}
|
|
135
118
|
|
|
136
119
|
export {
|
|
@@ -142,4 +125,4 @@ export {
|
|
|
142
125
|
SheetFooter,
|
|
143
126
|
SheetTitle,
|
|
144
127
|
SheetDescription,
|
|
145
|
-
}
|
|
128
|
+
};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { cn } from "
|
|
1
|
+
import { cn } from "cn";
|
|
2
2
|
|
|
3
3
|
function Skeleton({ className, ...props }: React.ComponentProps<"div">) {
|
|
4
4
|
return (
|
|
@@ -7,7 +7,7 @@ function Skeleton({ className, ...props }: React.ComponentProps<"div">) {
|
|
|
7
7
|
className={cn("animate-pulse rounded-md bg-muted", className)}
|
|
8
8
|
{...props}
|
|
9
9
|
/>
|
|
10
|
-
)
|
|
10
|
+
);
|
|
11
11
|
}
|
|
12
12
|
|
|
13
|
-
export { Skeleton }
|
|
13
|
+
export { Skeleton };
|
|
@@ -16,7 +16,9 @@ describe("toaster theme", () => {
|
|
|
16
16
|
const { container } = render(<Toaster />);
|
|
17
17
|
toast("hi");
|
|
18
18
|
await waitFor(() => {
|
|
19
|
-
expect(
|
|
19
|
+
expect(
|
|
20
|
+
container.querySelector("[data-sonner-toaster]")?.getAttribute("data-sonner-theme"),
|
|
21
|
+
).toBe("light");
|
|
20
22
|
});
|
|
21
23
|
});
|
|
22
24
|
it("is dark when <html> carries .dark", async () => {
|
|
@@ -24,18 +26,24 @@ describe("toaster theme", () => {
|
|
|
24
26
|
const { container } = render(<Toaster />);
|
|
25
27
|
toast("hi");
|
|
26
28
|
await waitFor(() => {
|
|
27
|
-
expect(
|
|
29
|
+
expect(
|
|
30
|
+
container.querySelector("[data-sonner-toaster]")?.getAttribute("data-sonner-theme"),
|
|
31
|
+
).toBe("dark");
|
|
28
32
|
});
|
|
29
33
|
});
|
|
30
34
|
it("follows <html> from light to dark after mount, via the MutationObserver", async () => {
|
|
31
35
|
const { container } = render(<Toaster />);
|
|
32
36
|
toast("hi");
|
|
33
37
|
await waitFor(() => {
|
|
34
|
-
expect(
|
|
38
|
+
expect(
|
|
39
|
+
container.querySelector("[data-sonner-toaster]")?.getAttribute("data-sonner-theme"),
|
|
40
|
+
).toBe("light");
|
|
35
41
|
});
|
|
36
42
|
document.documentElement.classList.add("dark");
|
|
37
43
|
await waitFor(() => {
|
|
38
|
-
expect(
|
|
44
|
+
expect(
|
|
45
|
+
container.querySelector("[data-sonner-toaster]")?.getAttribute("data-sonner-theme"),
|
|
46
|
+
).toBe("dark");
|
|
39
47
|
});
|
|
40
48
|
});
|
|
41
49
|
});
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import * as React from "react";
|
|
4
|
+
import { Toaster as Sonner, type ToasterProps } from "sonner";
|
|
5
|
+
import {
|
|
6
|
+
CircleCheckIcon,
|
|
7
|
+
InfoIcon,
|
|
8
|
+
TriangleAlertIcon,
|
|
9
|
+
OctagonXIcon,
|
|
10
|
+
Loader2Icon,
|
|
11
|
+
} from "lucide-react";
|
|
12
|
+
|
|
13
|
+
// The theme this package runs on has one source: the `dark` class on <html>,
|
|
14
|
+
// which is what `styles.css`'s `@custom-variant dark` keys off and therefore
|
|
15
|
+
// what every other component in here already follows. A toast is portalled
|
|
16
|
+
// outside the tree but reads the same page, so it has to answer to the same
|
|
17
|
+
// source — hence this hook rather than a `next-themes` `useTheme`, which asks
|
|
18
|
+
// for a React provider none of this runs under. Sonner needs the answer as a
|
|
19
|
+
// value, not a class, which is the only reason the class has to be observed
|
|
20
|
+
// at all.
|
|
21
|
+
function useTheme(): { theme: "light" | "dark" } {
|
|
22
|
+
const read = () =>
|
|
23
|
+
typeof document !== "undefined" && document.documentElement.classList.contains("dark")
|
|
24
|
+
? "dark"
|
|
25
|
+
: "light";
|
|
26
|
+
const [theme, setTheme] = React.useState<"light" | "dark">(read);
|
|
27
|
+
React.useEffect(() => {
|
|
28
|
+
const observer = new MutationObserver(() => setTheme(read()));
|
|
29
|
+
observer.observe(document.documentElement, { attributes: true, attributeFilter: ["class"] });
|
|
30
|
+
return () => observer.disconnect();
|
|
31
|
+
}, []);
|
|
32
|
+
return { theme };
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
const Toaster = ({ ...props }: ToasterProps) => {
|
|
36
|
+
const { theme = "system" } = useTheme();
|
|
37
|
+
|
|
38
|
+
return (
|
|
39
|
+
<Sonner
|
|
40
|
+
theme={theme as ToasterProps["theme"]}
|
|
41
|
+
className="toaster group"
|
|
42
|
+
icons={{
|
|
43
|
+
success: <CircleCheckIcon className="size-4" />,
|
|
44
|
+
info: <InfoIcon className="size-4" />,
|
|
45
|
+
warning: <TriangleAlertIcon className="size-4" />,
|
|
46
|
+
error: <OctagonXIcon className="size-4" />,
|
|
47
|
+
loading: <Loader2Icon className="size-4 animate-spin" />,
|
|
48
|
+
}}
|
|
49
|
+
style={
|
|
50
|
+
{
|
|
51
|
+
"--normal-bg": "var(--popover)",
|
|
52
|
+
"--normal-text": "var(--popover-foreground)",
|
|
53
|
+
"--normal-border": "var(--border)",
|
|
54
|
+
"--border-radius": "var(--radius)",
|
|
55
|
+
} as React.CSSProperties
|
|
56
|
+
}
|
|
57
|
+
toastOptions={{
|
|
58
|
+
classNames: {
|
|
59
|
+
toast: "cn-toast",
|
|
60
|
+
},
|
|
61
|
+
}}
|
|
62
|
+
{...props}
|
|
63
|
+
/>
|
|
64
|
+
);
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
export { Toaster };
|
|
@@ -1,30 +1,21 @@
|
|
|
1
|
-
import * as React from "react"
|
|
1
|
+
import * as React from "react";
|
|
2
2
|
|
|
3
|
-
import { cn } from "
|
|
3
|
+
import { cn } from "cn";
|
|
4
4
|
|
|
5
5
|
function Table({ className, ...props }: React.ComponentProps<"table">) {
|
|
6
6
|
return (
|
|
7
|
-
<div
|
|
8
|
-
data-slot="table-container"
|
|
9
|
-
className="relative w-full overflow-x-auto"
|
|
10
|
-
>
|
|
7
|
+
<div data-slot="table-container" className="relative w-full overflow-x-auto">
|
|
11
8
|
<table
|
|
12
9
|
data-slot="table"
|
|
13
10
|
className={cn("w-full caption-bottom text-sm", className)}
|
|
14
11
|
{...props}
|
|
15
12
|
/>
|
|
16
13
|
</div>
|
|
17
|
-
)
|
|
14
|
+
);
|
|
18
15
|
}
|
|
19
16
|
|
|
20
17
|
function TableHeader({ className, ...props }: React.ComponentProps<"thead">) {
|
|
21
|
-
return (
|
|
22
|
-
<thead
|
|
23
|
-
data-slot="table-header"
|
|
24
|
-
className={cn("[&_tr]:border-b", className)}
|
|
25
|
-
{...props}
|
|
26
|
-
/>
|
|
27
|
-
)
|
|
18
|
+
return <thead data-slot="table-header" className={cn("[&_tr]:border-b", className)} {...props} />;
|
|
28
19
|
}
|
|
29
20
|
|
|
30
21
|
function TableBody({ className, ...props }: React.ComponentProps<"tbody">) {
|
|
@@ -34,20 +25,17 @@ function TableBody({ className, ...props }: React.ComponentProps<"tbody">) {
|
|
|
34
25
|
className={cn("[&_tr:last-child]:border-0", className)}
|
|
35
26
|
{...props}
|
|
36
27
|
/>
|
|
37
|
-
)
|
|
28
|
+
);
|
|
38
29
|
}
|
|
39
30
|
|
|
40
31
|
function TableFooter({ className, ...props }: React.ComponentProps<"tfoot">) {
|
|
41
32
|
return (
|
|
42
33
|
<tfoot
|
|
43
34
|
data-slot="table-footer"
|
|
44
|
-
className={cn(
|
|
45
|
-
"border-t bg-muted/50 font-medium [&>tr]:last:border-b-0",
|
|
46
|
-
className
|
|
47
|
-
)}
|
|
35
|
+
className={cn("border-t bg-muted/50 font-medium [&>tr]:last:border-b-0", className)}
|
|
48
36
|
{...props}
|
|
49
37
|
/>
|
|
50
|
-
)
|
|
38
|
+
);
|
|
51
39
|
}
|
|
52
40
|
|
|
53
41
|
function TableRow({ className, ...props }: React.ComponentProps<"tr">) {
|
|
@@ -56,11 +44,11 @@ function TableRow({ className, ...props }: React.ComponentProps<"tr">) {
|
|
|
56
44
|
data-slot="table-row"
|
|
57
45
|
className={cn(
|
|
58
46
|
"border-b transition-colors hover:bg-muted/50 has-aria-expanded:bg-muted/50 data-[state=selected]:bg-muted",
|
|
59
|
-
className
|
|
47
|
+
className,
|
|
60
48
|
)}
|
|
61
49
|
{...props}
|
|
62
50
|
/>
|
|
63
|
-
)
|
|
51
|
+
);
|
|
64
52
|
}
|
|
65
53
|
|
|
66
54
|
function TableHead({ className, ...props }: React.ComponentProps<"th">) {
|
|
@@ -69,46 +57,31 @@ function TableHead({ className, ...props }: React.ComponentProps<"th">) {
|
|
|
69
57
|
data-slot="table-head"
|
|
70
58
|
className={cn(
|
|
71
59
|
"h-10 px-2 text-left align-middle font-medium whitespace-nowrap text-foreground [&:has([role=checkbox])]:pr-0",
|
|
72
|
-
className
|
|
60
|
+
className,
|
|
73
61
|
)}
|
|
74
62
|
{...props}
|
|
75
63
|
/>
|
|
76
|
-
)
|
|
64
|
+
);
|
|
77
65
|
}
|
|
78
66
|
|
|
79
67
|
function TableCell({ className, ...props }: React.ComponentProps<"td">) {
|
|
80
68
|
return (
|
|
81
69
|
<td
|
|
82
70
|
data-slot="table-cell"
|
|
83
|
-
className={cn(
|
|
84
|
-
"p-2 align-middle whitespace-nowrap [&:has([role=checkbox])]:pr-0",
|
|
85
|
-
className
|
|
86
|
-
)}
|
|
71
|
+
className={cn("p-2 align-middle whitespace-nowrap [&:has([role=checkbox])]:pr-0", className)}
|
|
87
72
|
{...props}
|
|
88
73
|
/>
|
|
89
|
-
)
|
|
74
|
+
);
|
|
90
75
|
}
|
|
91
76
|
|
|
92
|
-
function TableCaption({
|
|
93
|
-
className,
|
|
94
|
-
...props
|
|
95
|
-
}: React.ComponentProps<"caption">) {
|
|
77
|
+
function TableCaption({ className, ...props }: React.ComponentProps<"caption">) {
|
|
96
78
|
return (
|
|
97
79
|
<caption
|
|
98
80
|
data-slot="table-caption"
|
|
99
81
|
className={cn("mt-4 text-sm text-muted-foreground", className)}
|
|
100
82
|
{...props}
|
|
101
83
|
/>
|
|
102
|
-
)
|
|
84
|
+
);
|
|
103
85
|
}
|
|
104
86
|
|
|
105
|
-
export {
|
|
106
|
-
Table,
|
|
107
|
-
TableHeader,
|
|
108
|
-
TableBody,
|
|
109
|
-
TableFooter,
|
|
110
|
-
TableHead,
|
|
111
|
-
TableRow,
|
|
112
|
-
TableCell,
|
|
113
|
-
TableCaption,
|
|
114
|
-
}
|
|
87
|
+
export { Table, TableHeader, TableBody, TableFooter, TableHead, TableRow, TableCell, TableCaption };
|