@kinetixui/ui 0.6.5 → 0.7.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/dist/index.d.ts +11 -1
- package/dist/index.js +395 -380
- package/package.json +2 -2
- package/src/components/accordion.tsx +1 -1
- package/src/components/alert-dialog.tsx +2 -2
- package/src/components/app-bar.tsx +1 -1
- package/src/components/audio-player.tsx +3 -0
- package/src/components/badge.tsx +13 -4
- package/src/components/button.tsx +2 -2
- package/src/components/calendar.tsx +9 -5
- package/src/components/checkbox.tsx +1 -1
- package/src/components/circular-progress.tsx +1 -1
- package/src/components/command.tsx +4 -2
- package/src/components/context-menu.tsx +2 -2
- package/src/components/dialog.tsx +3 -3
- package/src/components/drawer.tsx +2 -2
- package/src/components/dropdown-menu.tsx +4 -2
- package/src/components/fab.tsx +1 -1
- package/src/components/file-upload.tsx +1 -1
- package/src/components/hover-card.tsx +1 -1
- package/src/components/image.tsx +2 -2
- package/src/components/inform.tsx +1 -1
- package/src/components/input-group.tsx +2 -2
- package/src/components/input-otp.tsx +3 -3
- package/src/components/input.tsx +2 -2
- package/src/components/label.tsx +1 -1
- package/src/components/list.tsx +1 -1
- package/src/components/menubar.tsx +2 -2
- package/src/components/modal.tsx +2 -2
- package/src/components/navigation-menu.tsx +4 -4
- package/src/components/number-input.tsx +3 -3
- package/src/components/popover.tsx +1 -1
- package/src/components/radio-group.tsx +1 -1
- package/src/components/resizable.tsx +1 -1
- package/src/components/select.tsx +5 -3
- package/src/components/sheet.tsx +3 -3
- package/src/components/sidebar.tsx +5 -5
- package/src/components/slider.tsx +1 -1
- package/src/components/switch.tsx +1 -1
- package/src/components/tabs.tsx +1 -1
- package/src/components/tag.tsx +27 -15
- package/src/components/textarea.tsx +2 -2
- package/src/components/toggle.tsx +1 -1
- package/src/components/tooltip.tsx +1 -1
- package/src/components-behavior.test.tsx +37 -0
- package/tailwind.config.ts +29 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kinetixui/ui",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.7.0",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "KinetixUI React components — CVA + Radix + Tailwind on the KinetixUI token contract. Also distributed via the kinetixui CLI as a component registry.",
|
|
6
6
|
"keywords": [
|
|
@@ -90,7 +90,7 @@
|
|
|
90
90
|
"react-dom": ">=18"
|
|
91
91
|
},
|
|
92
92
|
"devDependencies": {
|
|
93
|
-
"@kinetixui/tokens": "0.
|
|
93
|
+
"@kinetixui/tokens": "0.7.0",
|
|
94
94
|
"@testing-library/jest-dom": "^7.0.1",
|
|
95
95
|
"@testing-library/react": "^16.3.3",
|
|
96
96
|
"@testing-library/user-event": "^14.6.7",
|
|
@@ -29,7 +29,7 @@ const AccordionTrigger = React.forwardRef<
|
|
|
29
29
|
{...props}
|
|
30
30
|
>
|
|
31
31
|
{children}
|
|
32
|
-
<ChevronDown className="size-4 shrink-0 text-muted-foreground transition-transform duration-
|
|
32
|
+
<ChevronDown className="size-4 shrink-0 text-muted-foreground transition-transform duration-fast" />
|
|
33
33
|
</AccordionPrimitive.Trigger>
|
|
34
34
|
</AccordionPrimitive.Header>
|
|
35
35
|
));
|
|
@@ -16,7 +16,7 @@ const AlertDialogOverlay = React.forwardRef<
|
|
|
16
16
|
<AlertDialogPrimitive.Overlay
|
|
17
17
|
ref={ref}
|
|
18
18
|
className={cn(
|
|
19
|
-
"fixed inset-0 z-
|
|
19
|
+
"fixed inset-0 z-overlay bg-foreground/40 backdrop-blur-sm data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0",
|
|
20
20
|
className,
|
|
21
21
|
)}
|
|
22
22
|
{...props}
|
|
@@ -33,7 +33,7 @@ const AlertDialogContent = React.forwardRef<
|
|
|
33
33
|
<AlertDialogPrimitive.Content
|
|
34
34
|
ref={ref}
|
|
35
35
|
className={cn(
|
|
36
|
-
"fixed left-1/2 top-1/2 z-
|
|
36
|
+
"fixed left-1/2 top-1/2 z-overlay grid w-full max-w-lg -translate-x-1/2 -translate-y-1/2 gap-4 border bg-background p-6 shadow-lg sm:rounded-xl font-sans",
|
|
37
37
|
"data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95",
|
|
38
38
|
className,
|
|
39
39
|
)}
|
|
@@ -48,7 +48,7 @@ const AppBar = React.forwardRef<HTMLElement, React.HTMLAttributes<HTMLElement>>(
|
|
|
48
48
|
<header
|
|
49
49
|
ref={ref}
|
|
50
50
|
className={cn(
|
|
51
|
-
"sticky top-0 z-
|
|
51
|
+
"sticky top-0 z-sticky w-full border-b border-border bg-background/95 font-sans",
|
|
52
52
|
"backdrop-blur supports-[backdrop-filter]:bg-background/75",
|
|
53
53
|
className,
|
|
54
54
|
)}
|
|
@@ -73,6 +73,9 @@ const AudioPlayer = React.forwardRef<HTMLDivElement, AudioPlayerProps>(
|
|
|
73
73
|
</button>
|
|
74
74
|
);
|
|
75
75
|
|
|
76
|
+
// disabled:opacity-40 (not --opacity-disabled's 0.5) is a real, pre-existing
|
|
77
|
+
// inconsistency — left as a literal rather than silently changing the
|
|
78
|
+
// rendered value; a design call, not a rename.
|
|
76
79
|
const iconBtn =
|
|
77
80
|
"grid size-8 shrink-0 place-items-center rounded-full text-muted-foreground outline-none transition-colors hover:bg-muted hover:text-foreground focus-visible:text-foreground disabled:opacity-40 [&>svg]:size-4";
|
|
78
81
|
|
package/src/components/badge.tsx
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
|
|
3
3
|
import * as React from "react";
|
|
4
|
+
import { Slot } from "@radix-ui/react-slot";
|
|
4
5
|
import { cva, type VariantProps } from "class-variance-authority";
|
|
5
6
|
import { cn } from "../lib/utils";
|
|
6
7
|
|
|
@@ -31,10 +32,18 @@ const badgeVariants = cva(
|
|
|
31
32
|
|
|
32
33
|
export interface BadgeProps
|
|
33
34
|
extends React.HTMLAttributes<HTMLDivElement>,
|
|
34
|
-
VariantProps<typeof badgeVariants> {
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
35
|
+
VariantProps<typeof badgeVariants> {
|
|
36
|
+
/** render as the single child element (Radix Slot) instead of <div> —
|
|
37
|
+
* e.g. `<Badge asChild><a href="/new">New</a></Badge>` for a linked badge */
|
|
38
|
+
asChild?: boolean;
|
|
38
39
|
}
|
|
39
40
|
|
|
41
|
+
const Badge = React.forwardRef<HTMLDivElement, BadgeProps>(
|
|
42
|
+
({ className, variant, asChild = false, ...props }, ref) => {
|
|
43
|
+
const Comp = asChild ? Slot : "div";
|
|
44
|
+
return <Comp ref={ref} className={cn(badgeVariants({ variant }), className)} {...props} />;
|
|
45
|
+
},
|
|
46
|
+
);
|
|
47
|
+
Badge.displayName = "Badge";
|
|
48
|
+
|
|
40
49
|
export { Badge, badgeVariants };
|
|
@@ -28,7 +28,7 @@ const buttonVariants = cva(
|
|
|
28
28
|
"font-sans font-medium whitespace-nowrap select-none",
|
|
29
29
|
"rounded-md transition-colors outline-none",
|
|
30
30
|
"focus-visible:shadow-focus",
|
|
31
|
-
"disabled:pointer-events-none disabled:opacity-
|
|
31
|
+
"disabled:pointer-events-none disabled:opacity-disabled",
|
|
32
32
|
"[&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg]:size-[18px]",
|
|
33
33
|
],
|
|
34
34
|
{
|
|
@@ -72,7 +72,7 @@ const buttonVariants = cva(
|
|
|
72
72
|
Hover: "",
|
|
73
73
|
Focus: "shadow-focus",
|
|
74
74
|
Active: "",
|
|
75
|
-
Disabled: "pointer-events-none opacity-
|
|
75
|
+
Disabled: "pointer-events-none opacity-disabled",
|
|
76
76
|
},
|
|
77
77
|
/** corner style — matches the design source's Corners property */
|
|
78
78
|
corners: {
|
|
@@ -19,13 +19,17 @@ function Calendar({ className, classNames, showOutsideDays = true, ...props }: C
|
|
|
19
19
|
month_caption: "flex justify-center pt-1 relative items-center w-full",
|
|
20
20
|
caption_label: "text-sm font-medium",
|
|
21
21
|
nav: "flex items-center gap-1",
|
|
22
|
+
// Resting-dim/hover-brighten nav icons — numerically the disabled
|
|
23
|
+
// value (0.5) but not a disabled state, so left as a literal rather
|
|
24
|
+
// than forced into --opacity-disabled or --opacity-muted (0.7, which
|
|
25
|
+
// would change the rendered value).
|
|
22
26
|
button_previous: cn(
|
|
23
27
|
buttonVariants({ variant: "Outline", size: "icon" }),
|
|
24
|
-
"absolute left-1 size-7 bg-transparent p-0 opacity-50 hover:opacity-
|
|
28
|
+
"absolute left-1 size-7 bg-transparent p-0 opacity-50 hover:opacity-visible",
|
|
25
29
|
),
|
|
26
30
|
button_next: cn(
|
|
27
31
|
buttonVariants({ variant: "Outline", size: "icon" }),
|
|
28
|
-
"absolute right-1 size-7 bg-transparent p-0 opacity-50 hover:opacity-
|
|
32
|
+
"absolute right-1 size-7 bg-transparent p-0 opacity-50 hover:opacity-visible",
|
|
29
33
|
),
|
|
30
34
|
month_grid: "w-full border-collapse space-x-1",
|
|
31
35
|
weekdays: "flex",
|
|
@@ -36,19 +40,19 @@ function Calendar({ className, classNames, showOutsideDays = true, ...props }: C
|
|
|
36
40
|
// accent background + corner rounding and hands the primary-colored
|
|
37
41
|
// "selected" circle down to `day_button` via a `group` class.
|
|
38
42
|
day: cn(
|
|
39
|
-
"group relative p-0 text-center text-sm focus-within:relative focus-within:z-
|
|
43
|
+
"group relative p-0 text-center text-sm focus-within:relative focus-within:z-focus aria-selected:bg-accent",
|
|
40
44
|
props.mode === "range" ? "" : "aria-selected:rounded-md",
|
|
41
45
|
),
|
|
42
46
|
day_button: cn(
|
|
43
47
|
buttonVariants({ variant: "Ghost", size: "icon" }),
|
|
44
|
-
"size-8 p-0 font-normal group-aria-selected:opacity-
|
|
48
|
+
"size-8 p-0 font-normal group-aria-selected:opacity-visible group-data-[selected=true]:bg-primary group-data-[selected=true]:text-primary-foreground group-data-[selected=true]:hover:bg-primary group-data-[selected=true]:hover:text-primary-foreground group-data-[selected=true]:focus:bg-primary group-data-[selected=true]:focus:text-primary-foreground",
|
|
45
49
|
),
|
|
46
50
|
range_start: "day-range-start rounded-l-md",
|
|
47
51
|
range_end: "day-range-end rounded-r-md",
|
|
48
52
|
range_middle: "aria-selected:bg-accent aria-selected:text-accent-foreground",
|
|
49
53
|
today: "bg-accent text-accent-foreground",
|
|
50
54
|
outside: "day-outside text-muted-foreground aria-selected:text-muted-foreground",
|
|
51
|
-
disabled: "text-muted-foreground opacity-
|
|
55
|
+
disabled: "text-muted-foreground opacity-disabled",
|
|
52
56
|
hidden: "invisible",
|
|
53
57
|
...classNames,
|
|
54
58
|
}}
|
|
@@ -20,7 +20,7 @@ const Checkbox = React.forwardRef<
|
|
|
20
20
|
className={cn(
|
|
21
21
|
"peer size-[18px] shrink-0 rounded-sm border-2 border-input outline-none transition-colors",
|
|
22
22
|
"focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background",
|
|
23
|
-
"disabled:cursor-not-allowed disabled:opacity-
|
|
23
|
+
"disabled:cursor-not-allowed disabled:opacity-disabled",
|
|
24
24
|
"data-[state=checked]:border-primary data-[state=checked]:bg-primary data-[state=checked]:text-primary-foreground",
|
|
25
25
|
"data-[state=indeterminate]:border-primary data-[state=indeterminate]:bg-primary data-[state=indeterminate]:text-primary-foreground",
|
|
26
26
|
"aria-invalid:border-destructive aria-invalid:data-[state=checked]:border-destructive aria-invalid:data-[state=checked]:bg-destructive",
|
|
@@ -52,7 +52,7 @@ const CircularProgress = React.forwardRef<HTMLDivElement, CircularProgressProps>
|
|
|
52
52
|
strokeLinecap="round"
|
|
53
53
|
strokeDasharray={c}
|
|
54
54
|
strokeDashoffset={c - (v / 100) * c}
|
|
55
|
-
className="stroke-primary transition-[stroke-dashoffset] duration-
|
|
55
|
+
className="stroke-primary transition-[stroke-dashoffset] duration-base"
|
|
56
56
|
/>
|
|
57
57
|
</svg>
|
|
58
58
|
{(showValue || label != null) && (
|
|
@@ -36,11 +36,13 @@ const CommandInput = React.forwardRef<
|
|
|
36
36
|
React.ComponentPropsWithoutRef<typeof CommandPrimitive.Input>
|
|
37
37
|
>(({ className, ...props }, ref) => (
|
|
38
38
|
<div className="flex items-center border-b px-3" cmdk-input-wrapper="">
|
|
39
|
+
{/* Resting-dim icon, no hover/disabled state — numerically the disabled
|
|
40
|
+
value (0.5) but not that role; left as a literal, see calendar.tsx */}
|
|
39
41
|
<Search className="mr-2 size-4 shrink-0 opacity-50" />
|
|
40
42
|
<CommandPrimitive.Input
|
|
41
43
|
ref={ref}
|
|
42
44
|
className={cn(
|
|
43
|
-
"flex h-10 w-full rounded-md bg-transparent py-3 text-sm outline-none placeholder:text-muted-foreground disabled:cursor-not-allowed disabled:opacity-
|
|
45
|
+
"flex h-10 w-full rounded-md bg-transparent py-3 text-sm outline-none placeholder:text-muted-foreground disabled:cursor-not-allowed disabled:opacity-disabled",
|
|
44
46
|
className,
|
|
45
47
|
)}
|
|
46
48
|
{...props}
|
|
@@ -97,7 +99,7 @@ const CommandItem = React.forwardRef<
|
|
|
97
99
|
<CommandPrimitive.Item
|
|
98
100
|
ref={ref}
|
|
99
101
|
className={cn(
|
|
100
|
-
"relative flex cursor-default select-none items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-none data-[disabled=true]:pointer-events-none data-[selected=true]:bg-accent data-[selected=true]:text-accent-foreground data-[disabled=true]:opacity-
|
|
102
|
+
"relative flex cursor-default select-none items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-none data-[disabled=true]:pointer-events-none data-[selected=true]:bg-accent data-[selected=true]:text-accent-foreground data-[disabled=true]:opacity-disabled [&_svg]:size-4 [&_svg]:shrink-0",
|
|
101
103
|
className,
|
|
102
104
|
)}
|
|
103
105
|
{...props}
|
|
@@ -13,9 +13,9 @@ const ContextMenuSub = ContextMenuPrimitive.Sub;
|
|
|
13
13
|
const ContextMenuRadioGroup = ContextMenuPrimitive.RadioGroup;
|
|
14
14
|
|
|
15
15
|
const itemCls =
|
|
16
|
-
"relative flex cursor-default select-none items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-none focus:bg-accent focus:text-accent-foreground focus:ring-1 focus:ring-inset focus:ring-ring data-[disabled]:pointer-events-none data-[disabled]:opacity-
|
|
16
|
+
"relative flex cursor-default select-none items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-none focus:bg-accent focus:text-accent-foreground focus:ring-1 focus:ring-inset focus:ring-ring data-[disabled]:pointer-events-none data-[disabled]:opacity-disabled";
|
|
17
17
|
const contentCls =
|
|
18
|
-
"z-
|
|
18
|
+
"z-overlay min-w-[8rem] overflow-hidden rounded-md border bg-popover p-1 text-popover-foreground shadow-md font-sans data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95";
|
|
19
19
|
|
|
20
20
|
const ContextMenuSubTrigger = React.forwardRef<
|
|
21
21
|
React.ElementRef<typeof ContextMenuPrimitive.SubTrigger>,
|
|
@@ -17,7 +17,7 @@ const DialogOverlay = React.forwardRef<
|
|
|
17
17
|
<DialogPrimitive.Overlay
|
|
18
18
|
ref={ref}
|
|
19
19
|
className={cn(
|
|
20
|
-
"fixed inset-0 z-
|
|
20
|
+
"fixed inset-0 z-overlay bg-foreground/40 backdrop-blur-sm data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0",
|
|
21
21
|
className,
|
|
22
22
|
)}
|
|
23
23
|
{...props}
|
|
@@ -34,14 +34,14 @@ const DialogContent = React.forwardRef<
|
|
|
34
34
|
<DialogPrimitive.Content
|
|
35
35
|
ref={ref}
|
|
36
36
|
className={cn(
|
|
37
|
-
"fixed left-1/2 top-1/2 z-
|
|
37
|
+
"fixed left-1/2 top-1/2 z-overlay grid w-full max-w-lg -translate-x-1/2 -translate-y-1/2 gap-4 border bg-background p-6 shadow-lg sm:rounded-xl font-sans",
|
|
38
38
|
"data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95",
|
|
39
39
|
className,
|
|
40
40
|
)}
|
|
41
41
|
{...props}
|
|
42
42
|
>
|
|
43
43
|
{children}
|
|
44
|
-
<DialogPrimitive.Close className="absolute right-4 top-4 rounded-sm opacity-
|
|
44
|
+
<DialogPrimitive.Close className="absolute right-4 top-4 rounded-sm opacity-muted transition-opacity hover:opacity-visible focus:outline-none focus:ring-2 focus:ring-ring disabled:pointer-events-none">
|
|
45
45
|
<X className="size-4" />
|
|
46
46
|
<span className="sr-only">Close</span>
|
|
47
47
|
</DialogPrimitive.Close>
|
|
@@ -17,7 +17,7 @@ const DrawerOverlay = React.forwardRef<
|
|
|
17
17
|
React.ElementRef<typeof DrawerPrimitive.Overlay>,
|
|
18
18
|
React.ComponentPropsWithoutRef<typeof DrawerPrimitive.Overlay>
|
|
19
19
|
>(({ className, ...props }, ref) => (
|
|
20
|
-
<DrawerPrimitive.Overlay ref={ref} className={cn("fixed inset-0 z-
|
|
20
|
+
<DrawerPrimitive.Overlay ref={ref} className={cn("fixed inset-0 z-overlay bg-foreground/40", className)} {...props} />
|
|
21
21
|
));
|
|
22
22
|
DrawerOverlay.displayName = DrawerPrimitive.Overlay.displayName;
|
|
23
23
|
|
|
@@ -30,7 +30,7 @@ const DrawerContent = React.forwardRef<
|
|
|
30
30
|
<DrawerPrimitive.Content
|
|
31
31
|
ref={ref}
|
|
32
32
|
className={cn(
|
|
33
|
-
"fixed inset-x-0 bottom-0 z-
|
|
33
|
+
"fixed inset-x-0 bottom-0 z-overlay mt-24 flex h-auto flex-col rounded-t-[10px] border bg-background font-sans",
|
|
34
34
|
className,
|
|
35
35
|
)}
|
|
36
36
|
{...props}
|
|
@@ -13,9 +13,9 @@ const DropdownMenuSub = DropdownMenuPrimitive.Sub;
|
|
|
13
13
|
const DropdownMenuRadioGroup = DropdownMenuPrimitive.RadioGroup;
|
|
14
14
|
|
|
15
15
|
const contentCls =
|
|
16
|
-
"z-
|
|
16
|
+
"z-overlay min-w-[8rem] overflow-hidden rounded-md border bg-popover p-1 text-popover-foreground shadow-md font-sans data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95";
|
|
17
17
|
const itemCls =
|
|
18
|
-
"relative flex cursor-default select-none items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-none transition-colors focus:bg-accent focus:text-accent-foreground focus:ring-1 focus:ring-inset focus:ring-ring data-[disabled]:pointer-events-none data-[disabled]:opacity-
|
|
18
|
+
"relative flex cursor-default select-none items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-none transition-colors focus:bg-accent focus:text-accent-foreground focus:ring-1 focus:ring-inset focus:ring-ring data-[disabled]:pointer-events-none data-[disabled]:opacity-disabled";
|
|
19
19
|
|
|
20
20
|
const DropdownMenuContent = React.forwardRef<
|
|
21
21
|
React.ElementRef<typeof DropdownMenuPrimitive.Content>,
|
|
@@ -85,6 +85,8 @@ const DropdownMenuSeparator = React.forwardRef<
|
|
|
85
85
|
));
|
|
86
86
|
DropdownMenuSeparator.displayName = DropdownMenuPrimitive.Separator.displayName;
|
|
87
87
|
|
|
88
|
+
// opacity-60 (not --opacity-muted's 0.7) is a pre-existing inconsistency —
|
|
89
|
+
// left as a literal rather than silently changing the rendered value.
|
|
88
90
|
const DropdownMenuShortcut = ({ className, ...props }: React.HTMLAttributes<HTMLSpanElement>) => (
|
|
89
91
|
<span className={cn("ml-auto text-xs tracking-widest opacity-60", className)} {...props} />
|
|
90
92
|
);
|
package/src/components/fab.tsx
CHANGED
|
@@ -13,7 +13,7 @@ const fabVariants = cva(
|
|
|
13
13
|
[
|
|
14
14
|
"inline-flex shrink-0 items-center justify-center gap-2 rounded-full font-sans font-medium",
|
|
15
15
|
"shadow-lg outline-none transition-colors",
|
|
16
|
-
"focus-visible:shadow-focus disabled:pointer-events-none disabled:opacity-
|
|
16
|
+
"focus-visible:shadow-focus disabled:pointer-events-none disabled:opacity-disabled",
|
|
17
17
|
"[&_svg]:pointer-events-none [&_svg]:shrink-0",
|
|
18
18
|
],
|
|
19
19
|
{
|
|
@@ -84,7 +84,7 @@ const FileUpload = React.forwardRef<HTMLDivElement, FileUploadProps>(
|
|
|
84
84
|
"flex flex-col items-center gap-2 rounded-md border border-dashed border-input p-6 text-center outline-none transition-colors",
|
|
85
85
|
!disabled && "cursor-pointer hover:bg-accent/50 focus-visible:shadow-focus",
|
|
86
86
|
dragging && "border-primary bg-accent",
|
|
87
|
-
disabled && "pointer-events-none opacity-
|
|
87
|
+
disabled && "pointer-events-none opacity-disabled",
|
|
88
88
|
)}
|
|
89
89
|
>
|
|
90
90
|
<Upload className="size-6 text-muted-foreground" aria-hidden />
|
|
@@ -16,7 +16,7 @@ const HoverCardContent = React.forwardRef<
|
|
|
16
16
|
align={align}
|
|
17
17
|
sideOffset={sideOffset}
|
|
18
18
|
className={cn(
|
|
19
|
-
"z-
|
|
19
|
+
"z-overlay w-64 rounded-md border bg-popover p-4 text-popover-foreground shadow-md outline-none font-sans",
|
|
20
20
|
"data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95",
|
|
21
21
|
className,
|
|
22
22
|
)}
|
package/src/components/image.tsx
CHANGED
|
@@ -64,8 +64,8 @@ const Image = React.forwardRef<HTMLImageElement, ImageProps>(
|
|
|
64
64
|
ref={setRef}
|
|
65
65
|
alt={alt}
|
|
66
66
|
className={cn(
|
|
67
|
-
"size-full object-cover transition-opacity duration-
|
|
68
|
-
status === "loaded" ? "opacity-
|
|
67
|
+
"size-full object-cover transition-opacity duration-base",
|
|
68
|
+
status === "loaded" ? "opacity-visible" : "opacity-hidden",
|
|
69
69
|
)}
|
|
70
70
|
onLoad={(e) => {
|
|
71
71
|
setStatus("loaded");
|
|
@@ -68,7 +68,7 @@ const Inform = React.forwardRef<HTMLDivElement, InformProps>(
|
|
|
68
68
|
type="button"
|
|
69
69
|
onClick={onDismiss}
|
|
70
70
|
aria-label="Dismiss"
|
|
71
|
-
className="-m-0.5 shrink-0 rounded-[2px] p-0.5 opacity-
|
|
71
|
+
className="-m-0.5 shrink-0 rounded-[2px] p-0.5 opacity-muted outline-none transition-opacity hover:opacity-visible focus-visible:opacity-visible focus-visible:ring-1 focus-visible:ring-current"
|
|
72
72
|
>
|
|
73
73
|
<X className="size-3.5" />
|
|
74
74
|
</button>
|
|
@@ -24,7 +24,7 @@ const InputGroup = React.forwardRef<HTMLDivElement, React.HTMLAttributes<HTMLDiv
|
|
|
24
24
|
"flex w-full items-center overflow-hidden rounded-sm border border-input bg-background font-sans transition-colors",
|
|
25
25
|
"focus-within:border-primary focus-within:shadow-focus",
|
|
26
26
|
"has-[[aria-invalid=true]]:border-destructive has-[[aria-invalid=true]]:focus-within:shadow-focus-destructive",
|
|
27
|
-
"has-[:disabled]:cursor-not-allowed has-[:disabled]:opacity-
|
|
27
|
+
"has-[:disabled]:cursor-not-allowed has-[:disabled]:opacity-disabled",
|
|
28
28
|
className,
|
|
29
29
|
)}
|
|
30
30
|
{...props}
|
|
@@ -85,7 +85,7 @@ const InputGroupButton = React.forwardRef<
|
|
|
85
85
|
className={cn(
|
|
86
86
|
"flex h-full shrink-0 items-center gap-1.5 self-stretch border-l border-input bg-muted px-3 text-label-md text-foreground",
|
|
87
87
|
// base is bg-muted and muted==accent on dark, so the fill is a no-op there — the ring carries it
|
|
88
|
-
"outline-none transition-colors hover:bg-accent hover:ring-1 hover:ring-inset hover:ring-ring focus-visible:bg-accent focus-visible:ring-1 focus-visible:ring-inset focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-
|
|
88
|
+
"outline-none transition-colors hover:bg-accent hover:ring-1 hover:ring-inset hover:ring-ring focus-visible:bg-accent focus-visible:ring-1 focus-visible:ring-inset focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-disabled",
|
|
89
89
|
"[&_svg]:size-4 [&_svg]:shrink-0",
|
|
90
90
|
className,
|
|
91
91
|
)}
|
|
@@ -11,7 +11,7 @@ const InputOTP = React.forwardRef<
|
|
|
11
11
|
>(({ className, containerClassName, ...props }, ref) => (
|
|
12
12
|
<OTPInput
|
|
13
13
|
ref={ref}
|
|
14
|
-
containerClassName={cn("flex items-center gap-2 has-[:disabled]:opacity-
|
|
14
|
+
containerClassName={cn("flex items-center gap-2 has-[:disabled]:opacity-disabled", containerClassName)}
|
|
15
15
|
className={cn("disabled:cursor-not-allowed", className)}
|
|
16
16
|
{...props}
|
|
17
17
|
/>
|
|
@@ -35,7 +35,7 @@ const InputOTPSlot = React.forwardRef<
|
|
|
35
35
|
ref={ref}
|
|
36
36
|
className={cn(
|
|
37
37
|
"relative flex size-9 items-center justify-center border-y border-r border-input text-sm shadow-sm transition-all first:rounded-l-md first:border-l last:rounded-r-md",
|
|
38
|
-
isActive && "z-
|
|
38
|
+
isActive && "z-docked ring-1 ring-ring",
|
|
39
39
|
className,
|
|
40
40
|
)}
|
|
41
41
|
{...props}
|
|
@@ -43,7 +43,7 @@ const InputOTPSlot = React.forwardRef<
|
|
|
43
43
|
{char}
|
|
44
44
|
{hasFakeCaret && (
|
|
45
45
|
<div className="pointer-events-none absolute inset-0 flex items-center justify-center">
|
|
46
|
-
<div className="h-4 w-px animate-caret-blink bg-foreground duration-
|
|
46
|
+
<div className="h-4 w-px animate-caret-blink bg-foreground duration-slower" />
|
|
47
47
|
</div>
|
|
48
48
|
)}
|
|
49
49
|
</div>
|
package/src/components/input.tsx
CHANGED
|
@@ -26,7 +26,7 @@ const inputVariants = cva(
|
|
|
26
26
|
"placeholder:text-muted-foreground",
|
|
27
27
|
"outline-none transition-colors",
|
|
28
28
|
"focus-visible:border-primary focus-visible:shadow-focus",
|
|
29
|
-
"disabled:cursor-not-allowed disabled:opacity-
|
|
29
|
+
"disabled:cursor-not-allowed disabled:opacity-disabled",
|
|
30
30
|
"aria-[invalid=true]:border-destructive aria-[invalid=true]:focus-visible:border-destructive aria-[invalid=true]:focus-visible:shadow-focus-destructive",
|
|
31
31
|
],
|
|
32
32
|
{
|
|
@@ -35,7 +35,7 @@ const inputVariants = cva(
|
|
|
35
35
|
Default: "",
|
|
36
36
|
Focus: "border-primary shadow-focus",
|
|
37
37
|
Error: "border-destructive",
|
|
38
|
-
Disabled: "opacity-
|
|
38
|
+
Disabled: "opacity-disabled pointer-events-none",
|
|
39
39
|
},
|
|
40
40
|
/** corner style — matches the design source's Corners property */
|
|
41
41
|
corners: {
|
package/src/components/label.tsx
CHANGED
|
@@ -6,7 +6,7 @@ import { cva, type VariantProps } from "class-variance-authority";
|
|
|
6
6
|
import { cn } from "../lib/utils";
|
|
7
7
|
|
|
8
8
|
const labelVariants = cva(
|
|
9
|
-
"text-sm font-medium leading-none font-sans peer-disabled:cursor-not-allowed peer-disabled:opacity-
|
|
9
|
+
"text-sm font-medium leading-none font-sans peer-disabled:cursor-not-allowed peer-disabled:opacity-muted",
|
|
10
10
|
);
|
|
11
11
|
|
|
12
12
|
const Label = React.forwardRef<
|
package/src/components/list.tsx
CHANGED
|
@@ -51,7 +51,7 @@ const ListItem = React.forwardRef<HTMLDivElement, ListItemProps>(
|
|
|
51
51
|
// ring keeps the highlighted row perceptible where the accent fill is <3:1 (dark)
|
|
52
52
|
interactive &&
|
|
53
53
|
"cursor-pointer hover:bg-accent hover:ring-1 hover:ring-inset hover:ring-ring focus-visible:bg-accent focus-visible:ring-1 focus-visible:ring-inset focus-visible:ring-ring",
|
|
54
|
-
disabled && "pointer-events-none opacity-
|
|
54
|
+
disabled && "pointer-events-none opacity-disabled",
|
|
55
55
|
className,
|
|
56
56
|
)}
|
|
57
57
|
{...props}
|
|
@@ -22,9 +22,9 @@ const MenubarRadioGroup = (props: React.ComponentProps<typeof MenubarPrimitive.R
|
|
|
22
22
|
);
|
|
23
23
|
|
|
24
24
|
const itemCls =
|
|
25
|
-
"relative flex cursor-default select-none items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-none focus:bg-accent focus:text-accent-foreground focus:ring-1 focus:ring-inset focus:ring-ring data-[disabled]:pointer-events-none data-[disabled]:opacity-
|
|
25
|
+
"relative flex cursor-default select-none items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-none focus:bg-accent focus:text-accent-foreground focus:ring-1 focus:ring-inset focus:ring-ring data-[disabled]:pointer-events-none data-[disabled]:opacity-disabled";
|
|
26
26
|
const contentCls =
|
|
27
|
-
"z-
|
|
27
|
+
"z-overlay min-w-[12rem] overflow-hidden rounded-md border bg-popover p-1 text-popover-foreground shadow-md font-sans data-[state=open]:animate-in data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=open]:zoom-in-95";
|
|
28
28
|
|
|
29
29
|
const Menubar = React.forwardRef<
|
|
30
30
|
React.ElementRef<typeof MenubarPrimitive.Root>,
|
package/src/components/modal.tsx
CHANGED
|
@@ -68,7 +68,7 @@ function Modal({
|
|
|
68
68
|
<DialogOverlay />
|
|
69
69
|
<DialogPrimitive.Content
|
|
70
70
|
className={cn(
|
|
71
|
-
"fixed left-1/2 top-1/2 z-
|
|
71
|
+
"fixed left-1/2 top-1/2 z-overlay flex w-full max-w-[480px] -translate-x-1/2 -translate-y-1/2 flex-col overflow-hidden rounded-xl bg-background font-sans",
|
|
72
72
|
"shadow-[0_4px_24px_rgba(0,0,0,0.12)]",
|
|
73
73
|
"data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95",
|
|
74
74
|
className,
|
|
@@ -79,7 +79,7 @@ function Modal({
|
|
|
79
79
|
{title}
|
|
80
80
|
</DialogPrimitive.Title>
|
|
81
81
|
<DialogPrimitive.Close
|
|
82
|
-
className="rounded-sm opacity-
|
|
82
|
+
className="rounded-sm opacity-muted outline-none transition-opacity hover:opacity-visible focus-visible:ring-2 focus-visible:ring-ring"
|
|
83
83
|
aria-label="Close"
|
|
84
84
|
>
|
|
85
85
|
<X className="size-5" />
|
|
@@ -12,7 +12,7 @@ const NavigationMenu = React.forwardRef<
|
|
|
12
12
|
>(({ className, children, ...props }, ref) => (
|
|
13
13
|
<NavigationMenuPrimitive.Root
|
|
14
14
|
ref={ref}
|
|
15
|
-
className={cn("relative z-
|
|
15
|
+
className={cn("relative z-docked flex max-w-max flex-1 items-center justify-center font-sans", className)}
|
|
16
16
|
{...props}
|
|
17
17
|
>
|
|
18
18
|
{children}
|
|
@@ -36,7 +36,7 @@ NavigationMenuList.displayName = NavigationMenuPrimitive.List.displayName;
|
|
|
36
36
|
const NavigationMenuItem = NavigationMenuPrimitive.Item;
|
|
37
37
|
|
|
38
38
|
const navigationMenuTriggerStyle = cva(
|
|
39
|
-
"group inline-flex h-9 w-max items-center justify-center rounded-md bg-background px-4 py-2 text-sm font-medium transition-colors hover:bg-accent hover:text-accent-foreground focus:bg-accent focus:text-accent-foreground focus:outline-none disabled:pointer-events-none disabled:opacity-
|
|
39
|
+
"group inline-flex h-9 w-max items-center justify-center rounded-md bg-background px-4 py-2 text-sm font-medium transition-colors hover:bg-accent hover:text-accent-foreground focus:bg-accent focus:text-accent-foreground focus:outline-none disabled:pointer-events-none disabled:opacity-disabled data-[state=open]:bg-accent/50",
|
|
40
40
|
);
|
|
41
41
|
|
|
42
42
|
const NavigationMenuTrigger = React.forwardRef<
|
|
@@ -46,7 +46,7 @@ const NavigationMenuTrigger = React.forwardRef<
|
|
|
46
46
|
<NavigationMenuPrimitive.Trigger ref={ref} className={cn(navigationMenuTriggerStyle(), "group", className)} {...props}>
|
|
47
47
|
{children}
|
|
48
48
|
<ChevronDown
|
|
49
|
-
className="relative top-px ml-1 size-3 transition-transform duration-
|
|
49
|
+
className="relative top-px ml-1 size-3 transition-transform duration-fast group-data-[state=open]:rotate-180"
|
|
50
50
|
aria-hidden
|
|
51
51
|
/>
|
|
52
52
|
</NavigationMenuPrimitive.Trigger>
|
|
@@ -94,7 +94,7 @@ const NavigationMenuIndicator = React.forwardRef<
|
|
|
94
94
|
<NavigationMenuPrimitive.Indicator
|
|
95
95
|
ref={ref}
|
|
96
96
|
className={cn(
|
|
97
|
-
"top-full z-
|
|
97
|
+
"top-full z-raised flex h-1.5 items-end justify-center overflow-hidden data-[state=visible]:animate-in data-[state=hidden]:animate-out data-[state=hidden]:fade-out data-[state=visible]:fade-in",
|
|
98
98
|
className,
|
|
99
99
|
)}
|
|
100
100
|
{...props}
|
|
@@ -42,7 +42,7 @@ const NumberInput = React.forwardRef<HTMLInputElement, NumberInputProps>(
|
|
|
42
42
|
<div
|
|
43
43
|
className={cn(
|
|
44
44
|
"flex h-10 items-stretch overflow-hidden rounded-md border border-input font-sans focus-within:shadow-focus",
|
|
45
|
-
disabled && "pointer-events-none opacity-
|
|
45
|
+
disabled && "pointer-events-none opacity-disabled",
|
|
46
46
|
className,
|
|
47
47
|
)}
|
|
48
48
|
>
|
|
@@ -51,7 +51,7 @@ const NumberInput = React.forwardRef<HTMLInputElement, NumberInputProps>(
|
|
|
51
51
|
aria-label="Decrease"
|
|
52
52
|
disabled={disabled || (min != null && current <= min)}
|
|
53
53
|
onClick={() => set(current - step)}
|
|
54
|
-
className="flex w-9 shrink-0 items-center justify-center text-muted-foreground outline-none transition-colors hover:bg-accent hover:text-foreground focus-visible:bg-accent focus-visible:text-foreground focus-visible:ring-1 focus-visible:ring-inset focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-
|
|
54
|
+
className="flex w-9 shrink-0 items-center justify-center text-muted-foreground outline-none transition-colors hover:bg-accent hover:text-foreground focus-visible:bg-accent focus-visible:text-foreground focus-visible:ring-1 focus-visible:ring-inset focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-disabled"
|
|
55
55
|
>
|
|
56
56
|
<Minus className="size-4" />
|
|
57
57
|
</button>
|
|
@@ -76,7 +76,7 @@ const NumberInput = React.forwardRef<HTMLInputElement, NumberInputProps>(
|
|
|
76
76
|
aria-label="Increase"
|
|
77
77
|
disabled={disabled || (max != null && current >= max)}
|
|
78
78
|
onClick={() => set(current + step)}
|
|
79
|
-
className="flex w-9 shrink-0 items-center justify-center text-muted-foreground outline-none transition-colors hover:bg-accent hover:text-foreground focus-visible:bg-accent focus-visible:text-foreground focus-visible:ring-1 focus-visible:ring-inset focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-
|
|
79
|
+
className="flex w-9 shrink-0 items-center justify-center text-muted-foreground outline-none transition-colors hover:bg-accent hover:text-foreground focus-visible:bg-accent focus-visible:text-foreground focus-visible:ring-1 focus-visible:ring-inset focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-disabled"
|
|
80
80
|
>
|
|
81
81
|
<Plus className="size-4" />
|
|
82
82
|
</button>
|
|
@@ -18,7 +18,7 @@ const PopoverContent = React.forwardRef<
|
|
|
18
18
|
align={align}
|
|
19
19
|
sideOffset={sideOffset}
|
|
20
20
|
className={cn(
|
|
21
|
-
"z-
|
|
21
|
+
"z-overlay w-72 rounded-md border bg-popover p-4 text-popover-foreground shadow-md outline-none font-sans",
|
|
22
22
|
"data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95",
|
|
23
23
|
"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",
|
|
24
24
|
className,
|
|
@@ -27,7 +27,7 @@ const RadioGroupItem = React.forwardRef<
|
|
|
27
27
|
className={cn(
|
|
28
28
|
"aspect-square size-[18px] rounded-full border-2 border-input text-primary outline-none transition-colors",
|
|
29
29
|
"focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background",
|
|
30
|
-
"disabled:cursor-not-allowed disabled:opacity-
|
|
30
|
+
"disabled:cursor-not-allowed disabled:opacity-disabled",
|
|
31
31
|
"data-[state=checked]:border-primary",
|
|
32
32
|
"aria-invalid:border-destructive",
|
|
33
33
|
className,
|
|
@@ -51,7 +51,7 @@ const ResizableHandle = ({
|
|
|
51
51
|
{...props}
|
|
52
52
|
>
|
|
53
53
|
{withHandle && (
|
|
54
|
-
<div className="z-
|
|
54
|
+
<div className="z-docked flex h-4 w-3 items-center justify-center rounded-sm border bg-border">
|
|
55
55
|
<GripVertical className="size-2.5" />
|
|
56
56
|
</div>
|
|
57
57
|
)}
|
|
@@ -28,13 +28,15 @@ const SelectTrigger = React.forwardRef<
|
|
|
28
28
|
"focus:border-primary focus:shadow-focus",
|
|
29
29
|
"data-[state=open]:border-primary",
|
|
30
30
|
"aria-[invalid=true]:border-destructive aria-[invalid=true]:focus:border-destructive aria-[invalid=true]:focus:shadow-focus-destructive",
|
|
31
|
-
"disabled:cursor-not-allowed disabled:opacity-
|
|
31
|
+
"disabled:cursor-not-allowed disabled:opacity-disabled",
|
|
32
32
|
className,
|
|
33
33
|
)}
|
|
34
34
|
{...props}
|
|
35
35
|
>
|
|
36
36
|
{children}
|
|
37
37
|
<SelectPrimitive.Icon asChild>
|
|
38
|
+
{/* opacity-60 (not --opacity-muted's 0.7) is a pre-existing
|
|
39
|
+
inconsistency — left as a literal, see dropdown-menu.tsx */}
|
|
38
40
|
<ChevronDown className="size-4 shrink-0 opacity-60" />
|
|
39
41
|
</SelectPrimitive.Icon>
|
|
40
42
|
</SelectPrimitive.Trigger>
|
|
@@ -50,7 +52,7 @@ const SelectContent = React.forwardRef<
|
|
|
50
52
|
ref={ref}
|
|
51
53
|
position={position}
|
|
52
54
|
className={cn(
|
|
53
|
-
"relative z-
|
|
55
|
+
"relative z-overlay max-h-96 min-w-[8rem] overflow-hidden rounded-md border bg-popover text-popover-foreground shadow-md font-sans",
|
|
54
56
|
"data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95",
|
|
55
57
|
position === "popper" && "data-[side=bottom]:translate-y-1 data-[side=top]:-translate-y-1",
|
|
56
58
|
className,
|
|
@@ -89,7 +91,7 @@ const SelectItem = React.forwardRef<
|
|
|
89
91
|
ref={ref}
|
|
90
92
|
className={cn(
|
|
91
93
|
"relative flex w-full cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none",
|
|
92
|
-
"focus:bg-accent focus:text-accent-foreground focus:ring-1 focus:ring-inset focus:ring-ring data-[disabled]:pointer-events-none data-[disabled]:opacity-
|
|
94
|
+
"focus:bg-accent focus:text-accent-foreground focus:ring-1 focus:ring-inset focus:ring-ring data-[disabled]:pointer-events-none data-[disabled]:opacity-disabled",
|
|
93
95
|
className,
|
|
94
96
|
)}
|
|
95
97
|
{...props}
|