Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion packages/shadcn/components.json
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
{
"$schema": "https://ui.shadcn.com/schema/index.json",
"style": "default",
"style": "base-vega",
"rsc": false,
"tsx": true,
"iconLibrary": "lucide",
"tailwind": {
"css": "src/style.css",
"baseColor": "slate",
Expand Down
11 changes: 1 addition & 10 deletions packages/shadcn/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -55,25 +55,16 @@
"clean": "rimraf dist && rimraf types"
},
"dependencies": {
"@base-ui/react": "^1.6.0",
"@blocknote/core": "workspace:^",
"@blocknote/react": "workspace:^",
"@radix-ui/react-avatar": "^1.1.10",
"@radix-ui/react-dropdown-menu": "^2.1.16",
"@radix-ui/react-label": "^2.1.7",
"@radix-ui/react-popover": "^1.1.15",
"@radix-ui/react-select": "^2.2.6",
"@radix-ui/react-slot": "^1.2.3",
"@radix-ui/react-tabs": "^1.1.13",
"@radix-ui/react-toggle": "^1.1.10",
"@radix-ui/react-tooltip": "^1.2.8",
"class-variance-authority": "^0.7.1",
"clsx": "^2.1.1",
"lucide-react": "^0.525.0",
"react-hook-form": "^7.65.0",
"tailwind-merge": "^2.6.0"
},
"devDependencies": {
"@radix-ui/colors": "^3.0.0",
"@types/node": "^20.19.22",
"@types/react": "^19.2.3",
"@types/react-dom": "^19.2.3",
Expand Down
2 changes: 2 additions & 0 deletions packages/shadcn/src/ShadCNComponentsContext.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import {
DropdownMenu as ShadCNDropdownMenu,
DropdownMenuCheckboxItem as ShadCNDropdownMenuCheckboxItem,
DropdownMenuContent as ShadCNDropdownMenuContent,
DropdownMenuGroup as ShadCNDropdownMenuGroup,
DropdownMenuItem as ShadCNDropdownMenuItem,
DropdownMenuLabel as ShadCNDropdownMenuLabel,
DropdownMenuSeparator as ShadCNDropdownMenuSeparator,
Expand Down Expand Up @@ -73,6 +74,7 @@ export const ShadCNDefaultComponents = {
DropdownMenu: ShadCNDropdownMenu,
DropdownMenuCheckboxItem: ShadCNDropdownMenuCheckboxItem,
DropdownMenuContent: ShadCNDropdownMenuContent,
DropdownMenuGroup: ShadCNDropdownMenuGroup,
DropdownMenuItem: ShadCNDropdownMenuItem,
DropdownMenuLabel: ShadCNDropdownMenuLabel,
DropdownMenuSeparator: ShadCNDropdownMenuSeparator,
Expand Down
13 changes: 8 additions & 5 deletions packages/shadcn/src/badge/Badge.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { assertEmpty } from "@blocknote/core";
import { ComponentProps } from "@blocknote/react";
import { ComponentProps, useBlockNoteEditor } from "@blocknote/react";
import { forwardRef } from "react";

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

const ShadCNComponents = useShadCNComponentsContext()!;

// Portal the tooltip into the editor's portal element so it inherits the
// editor's light/dark color scheme instead of the document body's.
const editor = useBlockNoteEditor();

const badge = (
<ShadCNComponents.Button.Button
variant={isSelected ? "secondary" : "outline"}
Expand All @@ -47,10 +51,9 @@ export const Badge = forwardRef<

return (
<ShadCNComponents.Tooltip.Tooltip>
<ShadCNComponents.Tooltip.TooltipTrigger asChild>
{badge}
</ShadCNComponents.Tooltip.TooltipTrigger>
<ShadCNComponents.Tooltip.TooltipTrigger render={badge} />
<ShadCNComponents.Tooltip.TooltipContent
container={editor.portalElement}
className={"flex flex-col items-center whitespace-pre-wrap"}
>
<span>{mainTooltip}</span>
Expand All @@ -71,7 +74,7 @@ export const BadgeGroup = forwardRef<
const ShadCNComponents = useShadCNComponentsContext()!;

return (
<ShadCNComponents.Tooltip.TooltipProvider delayDuration={0}>
<ShadCNComponents.Tooltip.TooltipProvider delay={0}>
<div
className={cn(className, "flex w-full flex-row flex-wrap gap-1")}
ref={ref}
Expand Down
80 changes: 67 additions & 13 deletions packages/shadcn/src/components/ui/avatar.tsx
Original file line number Diff line number Diff line change
@@ -1,34 +1,36 @@
"use client";

import * as React from "react";
import * as AvatarPrimitive from "@radix-ui/react-avatar";
import { Avatar as AvatarPrimitive } from "@base-ui/react/avatar";
Comment thread
matthewlipski marked this conversation as resolved.

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

function Avatar({
className,
size = "default",
...props
}: React.ComponentProps<typeof AvatarPrimitive.Root>) {
}: AvatarPrimitive.Root.Props & {
size?: "default" | "sm" | "lg";
}) {
return (
<AvatarPrimitive.Root
data-slot="avatar"
data-size={size}
className={cn(
"relative flex size-8 shrink-0 overflow-hidden rounded-full",
"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",
className,
)}
{...props}
/>
);
}

function AvatarImage({
className,
...props
}: React.ComponentProps<typeof AvatarPrimitive.Image>) {
function AvatarImage({ className, ...props }: AvatarPrimitive.Image.Props) {
return (
<AvatarPrimitive.Image
data-slot="avatar-image"
className={cn("aspect-square size-full", className)}
className={cn(
"aspect-square size-full rounded-full object-cover",
className,
)}
{...props}
/>
);
Expand All @@ -37,17 +39,69 @@ function AvatarImage({
function AvatarFallback({
className,
...props
}: React.ComponentProps<typeof AvatarPrimitive.Fallback>) {
}: AvatarPrimitive.Fallback.Props) {
return (
<AvatarPrimitive.Fallback
data-slot="avatar-fallback"
className={cn(
"bg-muted flex size-full items-center justify-center rounded-full",
"flex size-full items-center justify-center rounded-full bg-muted text-sm text-muted-foreground group-data-[size=sm]/avatar:text-xs",
className,
)}
{...props}
/>
);
}

function AvatarBadge({ className, ...props }: React.ComponentProps<"span">) {
return (
<span
data-slot="avatar-badge"
className={cn(
"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",
"group-data-[size=sm]/avatar:size-2 group-data-[size=sm]/avatar:[&>svg]:hidden",
"group-data-[size=default]/avatar:size-2.5 group-data-[size=default]/avatar:[&>svg]:size-2",
"group-data-[size=lg]/avatar:size-3 group-data-[size=lg]/avatar:[&>svg]:size-2",
className,
)}
{...props}
/>
);
}

function AvatarGroup({ className, ...props }: React.ComponentProps<"div">) {
return (
<div
data-slot="avatar-group"
className={cn(
"group/avatar-group flex -space-x-2 *:data-[slot=avatar]:ring-2 *:data-[slot=avatar]:ring-background",
className,
)}
{...props}
/>
);
}

function AvatarGroupCount({
className,
...props
}: React.ComponentProps<"div">) {
return (
<div
data-slot="avatar-group-count"
className={cn(
"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",
className,
)}
{...props}
/>
);
}

export { Avatar, AvatarImage, AvatarFallback };
export {
Avatar,
AvatarImage,
AvatarFallback,
AvatarGroup,
AvatarGroupCount,
AvatarBadge,
};
48 changes: 27 additions & 21 deletions packages/shadcn/src/components/ui/badge.tsx
Original file line number Diff line number Diff line change
@@ -1,22 +1,24 @@
import * as React from "react";
import { Slot } from "@radix-ui/react-slot";
import { mergeProps } from "@base-ui/react/merge-props";
import { useRender } from "@base-ui/react/use-render";
import { cva, type VariantProps } from "class-variance-authority";

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

const badgeVariants = cva(
"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",
"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!",
{
variants: {
variant: {
default:
"border-transparent bg-primary text-primary-foreground [a&]:hover:bg-primary/90",
default: "bg-primary text-primary-foreground [a]:hover:bg-primary/80",
secondary:
"border-transparent bg-secondary text-secondary-foreground [a&]:hover:bg-secondary/90",
"bg-secondary text-secondary-foreground [a]:hover:bg-secondary/80",
destructive:
"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",
"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",
outline:
"text-foreground [a&]:hover:bg-accent [a&]:hover:text-accent-foreground",
"border-border text-foreground [a]:hover:bg-muted [a]:hover:text-muted-foreground",
ghost:
"hover:bg-muted hover:text-muted-foreground dark:hover:bg-muted/50",
link: "text-primary underline-offset-4 hover:underline",
},
},
defaultVariants: {
Expand All @@ -27,20 +29,24 @@ const badgeVariants = cva(

function Badge({
className,
variant,
asChild = false,
variant = "default",
render,
...props
}: React.ComponentProps<"span"> &
VariantProps<typeof badgeVariants> & { asChild?: boolean }) {
const Comp = asChild ? Slot : "span";

return (
<Comp
data-slot="badge"
className={cn(badgeVariants({ variant }), className)}
{...props}
/>
);
}: useRender.ComponentProps<"span"> & VariantProps<typeof badgeVariants>) {
return useRender({
defaultTagName: "span",
props: mergeProps<"span">(
{
className: cn(badgeVariants({ variant }), className),
},
props,
),
render,
state: {
slot: "badge",
variant,
},
});
}

export { Badge, badgeVariants };
45 changes: 22 additions & 23 deletions packages/shadcn/src/components/ui/button.tsx
Original file line number Diff line number Diff line change
@@ -1,31 +1,36 @@
import * as React from "react";
import { Slot } from "@radix-ui/react-slot";
import { Button as ButtonPrimitive } from "@base-ui/react/button";
import { cva, type VariantProps } from "class-variance-authority";

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

const buttonVariants = cva(
"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",
"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",
{
variants: {
variant: {
default:
"bg-primary text-primary-foreground shadow-xs hover:bg-primary/90",
destructive:
"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",
default: "bg-primary text-primary-foreground hover:bg-primary/80",
outline:
"border bg-background shadow-xs hover:bg-accent hover:text-accent-foreground dark:bg-input/30 dark:border-input dark:hover:bg-input/50",
"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",
secondary:
"bg-secondary text-secondary-foreground shadow-xs hover:bg-secondary/80",
"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",
ghost:
"hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50",
"hover:bg-muted hover:text-foreground aria-expanded:bg-muted aria-expanded:text-foreground dark:hover:bg-muted/50",
destructive:
"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",
link: "text-primary underline-offset-4 hover:underline",
},
size: {
default: "h-9 px-4 py-2 has-[>svg]:px-3",
sm: "h-8 rounded-md gap-1.5 px-3 has-[>svg]:px-2.5",
lg: "h-10 rounded-md px-6 has-[>svg]:px-4",
default:
"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",
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",
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",
lg: "h-10 gap-1.5 px-2.5 has-data-[icon=inline-end]:pr-2 has-data-[icon=inline-start]:pl-2",
icon: "size-9",
"icon-xs":
"size-6 rounded-[min(var(--radius-md),8px)] in-data-[slot=button-group]:rounded-md [&_svg:not([class*='size-'])]:size-3",
"icon-sm":
"size-8 rounded-[min(var(--radius-md),10px)] in-data-[slot=button-group]:rounded-md",
"icon-lg": "size-10",
},
},
defaultVariants: {
Expand All @@ -37,18 +42,12 @@ const buttonVariants = cva(

function Button({
className,
variant,
size,
asChild = false,
variant = "default",
size = "default",
...props
}: React.ComponentProps<"button"> &
VariantProps<typeof buttonVariants> & {
asChild?: boolean;
}) {
const Comp = asChild ? Slot : "button";

}: ButtonPrimitive.Props & VariantProps<typeof buttonVariants>) {
return (
<Comp
<ButtonPrimitive
data-slot="button"
className={cn(buttonVariants({ variant, size, className }))}
{...props}
Expand Down
Loading
Loading