Skip to content

Commit 2f8edc1

Browse files
committed
Updated ShadCN components
1 parent dee7880 commit 2f8edc1

25 files changed

Lines changed: 675 additions & 532 deletions

‎packages/shadcn/components.json‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
{
22
"$schema": "https://ui.shadcn.com/schema/index.json",
3-
"style": "default",
3+
"style": "base-vega",
44
"rsc": false,
55
"tsx": true,
6+
"iconLibrary": "lucide",
67
"tailwind": {
78
"css": "src/style.css",
89
"baseColor": "slate",

‎packages/shadcn/package.json‎

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -55,25 +55,16 @@
5555
"clean": "rimraf dist && rimraf types"
5656
},
5757
"dependencies": {
58+
"@base-ui/react": "^1.6.0",
5859
"@blocknote/core": "workspace:^",
5960
"@blocknote/react": "workspace:^",
60-
"@radix-ui/react-avatar": "^1.1.10",
61-
"@radix-ui/react-dropdown-menu": "^2.1.16",
62-
"@radix-ui/react-label": "^2.1.7",
63-
"@radix-ui/react-popover": "^1.1.15",
64-
"@radix-ui/react-select": "^2.2.6",
65-
"@radix-ui/react-slot": "^1.2.3",
66-
"@radix-ui/react-tabs": "^1.1.13",
67-
"@radix-ui/react-toggle": "^1.1.10",
68-
"@radix-ui/react-tooltip": "^1.2.8",
6961
"class-variance-authority": "^0.7.1",
7062
"clsx": "^2.1.1",
7163
"lucide-react": "^0.525.0",
7264
"react-hook-form": "^7.65.0",
7365
"tailwind-merge": "^2.6.0"
7466
},
7567
"devDependencies": {
76-
"@radix-ui/colors": "^3.0.0",
7768
"@types/node": "^20.19.22",
7869
"@types/react": "^19.2.3",
7970
"@types/react-dom": "^19.2.3",

‎packages/shadcn/src/ShadCNComponentsContext.tsx‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import {
1313
DropdownMenu as ShadCNDropdownMenu,
1414
DropdownMenuCheckboxItem as ShadCNDropdownMenuCheckboxItem,
1515
DropdownMenuContent as ShadCNDropdownMenuContent,
16+
DropdownMenuGroup as ShadCNDropdownMenuGroup,
1617
DropdownMenuItem as ShadCNDropdownMenuItem,
1718
DropdownMenuLabel as ShadCNDropdownMenuLabel,
1819
DropdownMenuSeparator as ShadCNDropdownMenuSeparator,
@@ -73,6 +74,7 @@ export const ShadCNDefaultComponents = {
7374
DropdownMenu: ShadCNDropdownMenu,
7475
DropdownMenuCheckboxItem: ShadCNDropdownMenuCheckboxItem,
7576
DropdownMenuContent: ShadCNDropdownMenuContent,
77+
DropdownMenuGroup: ShadCNDropdownMenuGroup,
7678
DropdownMenuItem: ShadCNDropdownMenuItem,
7779
DropdownMenuLabel: ShadCNDropdownMenuLabel,
7880
DropdownMenuSeparator: ShadCNDropdownMenuSeparator,

‎packages/shadcn/src/badge/Badge.tsx‎

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { assertEmpty } from "@blocknote/core";
2-
import { ComponentProps } from "@blocknote/react";
2+
import { ComponentProps, useBlockNoteEditor } from "@blocknote/react";
33
import { forwardRef } from "react";
44

55
import { cn } from "../lib/utils.js";
@@ -25,6 +25,10 @@ export const Badge = forwardRef<
2525

2626
const ShadCNComponents = useShadCNComponentsContext()!;
2727

28+
// Portal the tooltip into the editor's portal element so it inherits the
29+
// editor's light/dark color scheme instead of the document body's.
30+
const editor = useBlockNoteEditor();
31+
2832
const badge = (
2933
<ShadCNComponents.Button.Button
3034
variant={isSelected ? "secondary" : "outline"}
@@ -47,10 +51,9 @@ export const Badge = forwardRef<
4751

4852
return (
4953
<ShadCNComponents.Tooltip.Tooltip>
50-
<ShadCNComponents.Tooltip.TooltipTrigger asChild>
51-
{badge}
52-
</ShadCNComponents.Tooltip.TooltipTrigger>
54+
<ShadCNComponents.Tooltip.TooltipTrigger render={badge} />
5355
<ShadCNComponents.Tooltip.TooltipContent
56+
container={editor.portalElement}
5457
className={"flex flex-col items-center whitespace-pre-wrap"}
5558
>
5659
<span>{mainTooltip}</span>
@@ -71,7 +74,7 @@ export const BadgeGroup = forwardRef<
7174
const ShadCNComponents = useShadCNComponentsContext()!;
7275

7376
return (
74-
<ShadCNComponents.Tooltip.TooltipProvider delayDuration={0}>
77+
<ShadCNComponents.Tooltip.TooltipProvider delay={0}>
7578
<div
7679
className={cn(className, "flex w-full flex-row flex-wrap gap-1")}
7780
ref={ref}
Lines changed: 67 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,36 @@
1-
"use client";
2-
31
import * as React from "react";
4-
import * as AvatarPrimitive from "@radix-ui/react-avatar";
2+
import { Avatar as AvatarPrimitive } from "@base-ui/react/avatar";
53

64
import { cn } from "../../lib/utils";
75

86
function Avatar({
97
className,
8+
size = "default",
109
...props
11-
}: React.ComponentProps<typeof AvatarPrimitive.Root>) {
10+
}: AvatarPrimitive.Root.Props & {
11+
size?: "default" | "sm" | "lg";
12+
}) {
1213
return (
1314
<AvatarPrimitive.Root
1415
data-slot="avatar"
16+
data-size={size}
1517
className={cn(
16-
"relative flex size-8 shrink-0 overflow-hidden rounded-full",
18+
"group/avatar relative flex size-8 shrink-0 rounded-full select-none after:absolute after:inset-0 after:rounded-full after:border after:border-border after:mix-blend-darken data-[size=lg]:size-10 data-[size=sm]:size-6 dark:after:mix-blend-lighten",
1719
className,
1820
)}
1921
{...props}
2022
/>
2123
);
2224
}
2325

24-
function AvatarImage({
25-
className,
26-
...props
27-
}: React.ComponentProps<typeof AvatarPrimitive.Image>) {
26+
function AvatarImage({ className, ...props }: AvatarPrimitive.Image.Props) {
2827
return (
2928
<AvatarPrimitive.Image
3029
data-slot="avatar-image"
31-
className={cn("aspect-square size-full", className)}
30+
className={cn(
31+
"aspect-square size-full rounded-full object-cover",
32+
className,
33+
)}
3234
{...props}
3335
/>
3436
);
@@ -37,17 +39,69 @@ function AvatarImage({
3739
function AvatarFallback({
3840
className,
3941
...props
40-
}: React.ComponentProps<typeof AvatarPrimitive.Fallback>) {
42+
}: AvatarPrimitive.Fallback.Props) {
4143
return (
4244
<AvatarPrimitive.Fallback
4345
data-slot="avatar-fallback"
4446
className={cn(
45-
"bg-muted flex size-full items-center justify-center rounded-full",
47+
"flex size-full items-center justify-center rounded-full bg-muted text-sm text-muted-foreground group-data-[size=sm]/avatar:text-xs",
48+
className,
49+
)}
50+
{...props}
51+
/>
52+
);
53+
}
54+
55+
function AvatarBadge({ className, ...props }: React.ComponentProps<"span">) {
56+
return (
57+
<span
58+
data-slot="avatar-badge"
59+
className={cn(
60+
"absolute right-0 bottom-0 z-10 inline-flex items-center justify-center rounded-full bg-primary text-primary-foreground bg-blend-color ring-2 ring-background select-none",
61+
"group-data-[size=sm]/avatar:size-2 group-data-[size=sm]/avatar:[&>svg]:hidden",
62+
"group-data-[size=default]/avatar:size-2.5 group-data-[size=default]/avatar:[&>svg]:size-2",
63+
"group-data-[size=lg]/avatar:size-3 group-data-[size=lg]/avatar:[&>svg]:size-2",
64+
className,
65+
)}
66+
{...props}
67+
/>
68+
);
69+
}
70+
71+
function AvatarGroup({ className, ...props }: React.ComponentProps<"div">) {
72+
return (
73+
<div
74+
data-slot="avatar-group"
75+
className={cn(
76+
"group/avatar-group flex -space-x-2 *:data-[slot=avatar]:ring-2 *:data-[slot=avatar]:ring-background",
77+
className,
78+
)}
79+
{...props}
80+
/>
81+
);
82+
}
83+
84+
function AvatarGroupCount({
85+
className,
86+
...props
87+
}: React.ComponentProps<"div">) {
88+
return (
89+
<div
90+
data-slot="avatar-group-count"
91+
className={cn(
92+
"relative flex size-8 shrink-0 items-center justify-center rounded-full bg-muted text-sm text-muted-foreground ring-2 ring-background group-has-data-[size=lg]/avatar-group:size-10 group-has-data-[size=sm]/avatar-group:size-6 [&>svg]:size-4 group-has-data-[size=lg]/avatar-group:[&>svg]:size-5 group-has-data-[size=sm]/avatar-group:[&>svg]:size-3",
4693
className,
4794
)}
4895
{...props}
4996
/>
5097
);
5198
}
5299

53-
export { Avatar, AvatarImage, AvatarFallback };
100+
export {
101+
Avatar,
102+
AvatarImage,
103+
AvatarFallback,
104+
AvatarGroup,
105+
AvatarGroupCount,
106+
AvatarBadge,
107+
};
Lines changed: 27 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,24 @@
1-
import * as React from "react";
2-
import { Slot } from "@radix-ui/react-slot";
1+
import { mergeProps } from "@base-ui/react/merge-props";
2+
import { useRender } from "@base-ui/react/use-render";
33
import { cva, type VariantProps } from "class-variance-authority";
44

55
import { cn } from "../../lib/utils";
66

77
const badgeVariants = cva(
8-
"inline-flex items-center justify-center rounded-md border px-2 py-0.5 text-xs font-medium w-fit whitespace-nowrap shrink-0 [&>svg]:size-3 gap-1 [&>svg]:pointer-events-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive transition-[color,box-shadow] overflow-hidden",
8+
"group/badge inline-flex h-5 w-fit shrink-0 items-center justify-center gap-1 overflow-hidden rounded-4xl border border-transparent px-2 py-0.5 text-xs font-medium whitespace-nowrap transition-all focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 aria-invalid:border-destructive aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 [&>svg]:pointer-events-none [&>svg]:size-3!",
99
{
1010
variants: {
1111
variant: {
12-
default:
13-
"border-transparent bg-primary text-primary-foreground [a&]:hover:bg-primary/90",
12+
default: "bg-primary text-primary-foreground [a]:hover:bg-primary/80",
1413
secondary:
15-
"border-transparent bg-secondary text-secondary-foreground [a&]:hover:bg-secondary/90",
14+
"bg-secondary text-secondary-foreground [a]:hover:bg-secondary/80",
1615
destructive:
17-
"border-transparent bg-destructive text-white [a&]:hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60",
16+
"bg-destructive/10 text-destructive focus-visible:ring-destructive/20 dark:bg-destructive/20 dark:focus-visible:ring-destructive/40 [a]:hover:bg-destructive/20",
1817
outline:
19-
"text-foreground [a&]:hover:bg-accent [a&]:hover:text-accent-foreground",
18+
"border-border text-foreground [a]:hover:bg-muted [a]:hover:text-muted-foreground",
19+
ghost:
20+
"hover:bg-muted hover:text-muted-foreground dark:hover:bg-muted/50",
21+
link: "text-primary underline-offset-4 hover:underline",
2022
},
2123
},
2224
defaultVariants: {
@@ -27,20 +29,24 @@ const badgeVariants = cva(
2729

2830
function Badge({
2931
className,
30-
variant,
31-
asChild = false,
32+
variant = "default",
33+
render,
3234
...props
33-
}: React.ComponentProps<"span"> &
34-
VariantProps<typeof badgeVariants> & { asChild?: boolean }) {
35-
const Comp = asChild ? Slot : "span";
36-
37-
return (
38-
<Comp
39-
data-slot="badge"
40-
className={cn(badgeVariants({ variant }), className)}
41-
{...props}
42-
/>
43-
);
35+
}: useRender.ComponentProps<"span"> & VariantProps<typeof badgeVariants>) {
36+
return useRender({
37+
defaultTagName: "span",
38+
props: mergeProps<"span">(
39+
{
40+
className: cn(badgeVariants({ variant }), className),
41+
},
42+
props,
43+
),
44+
render,
45+
state: {
46+
slot: "badge",
47+
variant,
48+
},
49+
});
4450
}
4551

4652
export { Badge, badgeVariants };

‎packages/shadcn/src/components/ui/button.tsx‎

Lines changed: 22 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,36 @@
1-
import * as React from "react";
2-
import { Slot } from "@radix-ui/react-slot";
1+
import { Button as ButtonPrimitive } from "@base-ui/react/button";
32
import { cva, type VariantProps } from "class-variance-authority";
43

54
import { cn } from "../../lib/utils";
65

76
const buttonVariants = cva(
8-
"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-all disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*=size-])]:size-4 shrink-0 [&_svg]:shrink-0 outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive",
7+
"group/button inline-flex shrink-0 items-center justify-center rounded-md border border-transparent bg-clip-padding text-sm font-medium whitespace-nowrap transition-all outline-none select-none focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 active:not-aria-[haspopup]:translate-y-px disabled:pointer-events-none disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 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",
98
{
109
variants: {
1110
variant: {
12-
default:
13-
"bg-primary text-primary-foreground shadow-xs hover:bg-primary/90",
14-
destructive:
15-
"bg-destructive text-white shadow-xs hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60",
11+
default: "bg-primary text-primary-foreground hover:bg-primary/80",
1612
outline:
17-
"border bg-background shadow-xs hover:bg-accent hover:text-accent-foreground dark:bg-input/30 dark:border-input dark:hover:bg-input/50",
13+
"border-border bg-background shadow-xs hover:bg-muted hover:text-foreground aria-expanded:bg-muted aria-expanded:text-foreground dark:border-input dark:bg-input/30 dark:hover:bg-input/50",
1814
secondary:
19-
"bg-secondary text-secondary-foreground shadow-xs hover:bg-secondary/80",
15+
"bg-secondary text-secondary-foreground hover:bg-[color-mix(in_oklch,var(--secondary),var(--foreground)_5%)] aria-expanded:bg-secondary aria-expanded:text-secondary-foreground",
2016
ghost:
21-
"hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50",
17+
"hover:bg-muted hover:text-foreground aria-expanded:bg-muted aria-expanded:text-foreground dark:hover:bg-muted/50",
18+
destructive:
19+
"bg-destructive/10 text-destructive hover:bg-destructive/20 focus-visible:border-destructive/40 focus-visible:ring-destructive/20 dark:bg-destructive/20 dark:hover:bg-destructive/30 dark:focus-visible:ring-destructive/40",
2220
link: "text-primary underline-offset-4 hover:underline",
2321
},
2422
size: {
25-
default: "h-9 px-4 py-2 has-[>svg]:px-3",
26-
sm: "h-8 rounded-md gap-1.5 px-3 has-[>svg]:px-2.5",
27-
lg: "h-10 rounded-md px-6 has-[>svg]:px-4",
23+
default:
24+
"h-9 gap-1.5 px-2.5 in-data-[slot=button-group]:rounded-md has-data-[icon=inline-end]:pr-2 has-data-[icon=inline-start]:pl-2",
25+
xs: "h-6 gap-1 rounded-[min(var(--radius-md),8px)] px-2 text-xs in-data-[slot=button-group]:rounded-md has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 [&_svg:not([class*='size-'])]:size-3",
26+
sm: "h-8 gap-1 rounded-[min(var(--radius-md),10px)] px-2.5 in-data-[slot=button-group]:rounded-md has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5",
27+
lg: "h-10 gap-1.5 px-2.5 has-data-[icon=inline-end]:pr-2 has-data-[icon=inline-start]:pl-2",
2828
icon: "size-9",
29+
"icon-xs":
30+
"size-6 rounded-[min(var(--radius-md),8px)] in-data-[slot=button-group]:rounded-md [&_svg:not([class*='size-'])]:size-3",
31+
"icon-sm":
32+
"size-8 rounded-[min(var(--radius-md),10px)] in-data-[slot=button-group]:rounded-md",
33+
"icon-lg": "size-10",
2934
},
3035
},
3136
defaultVariants: {
@@ -37,18 +42,12 @@ const buttonVariants = cva(
3742

3843
function Button({
3944
className,
40-
variant,
41-
size,
42-
asChild = false,
45+
variant = "default",
46+
size = "default",
4347
...props
44-
}: React.ComponentProps<"button"> &
45-
VariantProps<typeof buttonVariants> & {
46-
asChild?: boolean;
47-
}) {
48-
const Comp = asChild ? Slot : "button";
49-
48+
}: ButtonPrimitive.Props & VariantProps<typeof buttonVariants>) {
5049
return (
51-
<Comp
50+
<ButtonPrimitive
5251
data-slot="button"
5352
className={cn(buttonVariants({ variant, size, className }))}
5453
{...props}

0 commit comments

Comments
 (0)