Compare commits

..

1 Commits

Author SHA1 Message Date
shadcn
dcd08c1abe feat(shadcn): remove npm flags 2025-03-24 09:02:00 +04:00
71 changed files with 1244 additions and 3497 deletions

View File

@@ -0,0 +1,5 @@
---
"shadcn": minor
---
add support for TanStack Start

View File

@@ -0,0 +1,5 @@
---
"shadcn": patch
---
support for version detection in monorepo

View File

@@ -0,0 +1,5 @@
---
"shadcn": patch
---
upgrade @antfu/ni

View File

@@ -0,0 +1,5 @@
---
"shadcn": patch
---
allow silent mode with npm

View File

@@ -0,0 +1,5 @@
---
"shadcn": patch
---
do not add ring for v3

View File

@@ -0,0 +1,5 @@
---
"shadcn": minor
---
add theme vars support

View File

@@ -0,0 +1,5 @@
---
"shadcn": minor
---
add tailwind version detection

View File

@@ -0,0 +1,5 @@
---
"shadcn": minor
---
add --base-color flag

View File

@@ -0,0 +1,5 @@
---
"shadcn": minor
---
add support for tailwind v4

View File

@@ -0,0 +1,5 @@
---
"shadcn": minor
---
default to css vars. add --no-css-variables

View File

@@ -0,0 +1,5 @@
---
"shadcn": patch
---
cache registry calls

View File

@@ -0,0 +1,5 @@
---
"shadcn": minor
---
replace tailwindcss-animate with tw-animate-css

View File

@@ -0,0 +1,5 @@
---
"shadcn": patch
---
add --template flag

View File

@@ -0,0 +1,5 @@
---
"shadcn": minor
---
default for new-york for v4

View File

@@ -0,0 +1,5 @@
---
"shadcn": minor
---
fix handling of sidebar colors

View File

@@ -0,0 +1,5 @@
---
"shadcn": patch
---
do not overwrite user defined vars

View File

@@ -0,0 +1,5 @@
---
"shadcn": patch
---
fix cn import bug in monorepo

View File

@@ -0,0 +1,5 @@
---
"shadcn": patch
---
filter out deprecated from --all

View File

@@ -0,0 +1,5 @@
---
"shadcn": minor
---
add oklch base color

View File

@@ -0,0 +1,5 @@
---
"shadcn": minor
---
hotswap style for v4

View File

@@ -0,0 +1,5 @@
---
"shadcn": patch
---
check for empty css vars

View File

@@ -0,0 +1,5 @@
---
"shadcn": patch
---
only show deprecated for new projects

View File

@@ -0,0 +1,5 @@
---
"shadcn": minor
---
add warning for deprecated components

View File

@@ -0,0 +1,5 @@
---
"shadcn": patch
---
fix tanstack check

View File

@@ -0,0 +1,5 @@
---
"shadcn": minor
---
add support for route install for react-router and laravel

View File

@@ -1,6 +0,0 @@
version: 2
updates:
- package-ecosystem: "npm"
directory: "/"
schedule:
interval: "weekly"

View File

@@ -1,9 +0,0 @@
# Security Policy
If you believe you have found a security vulnerability, we encourage you to let us know right away.
We will investigate all legitimate reports and do our best to quickly fix the problem.
Our preference is that you make use of GitHub's private vulnerability reporting feature to disclose potential security vulnerabilities in our Open Source Software.
To do this, please visit the security tab of the repository and click the "Report a vulnerability" button.

View File

@@ -39,7 +39,7 @@
"@radix-ui/react-portal": "^1.1.3",
"@radix-ui/react-progress": "^1.1.1",
"@radix-ui/react-radio-group": "^1.2.2",
"@radix-ui/react-scroll-area": "^1.2.3",
"@radix-ui/react-scroll-area": "^1.2.2",
"@radix-ui/react-select": "^2.1.5",
"@radix-ui/react-separator": "^1.1.1",
"@radix-ui/react-slider": "^1.2.2",
@@ -63,7 +63,7 @@
"geist": "^1.2.2",
"input-otp": "^1.4.2",
"lucide-react": "0.474.0",
"next": "15.2.3",
"next": "15.2.0-canary.33",
"next-themes": "^0.4.3",
"postcss": "^8.5.1",
"react": "^19.0.0",
@@ -73,7 +73,7 @@
"react-resizable-panels": "^2.1.7",
"recharts": "2.15.1",
"rimraf": "^6.0.1",
"shadcn": "2.4.1",
"shadcn": "2.3.0",
"sonner": "^2.0.0",
"tailwind-merge": "^3.0.1",
"tailwindcss": "^4.0.7",

View File

@@ -240,7 +240,7 @@
"name": "command",
"type": "registry:ui",
"dependencies": [
"cmdk"
"cmdk@1.0.0"
],
"registryDependencies": [
"dialog"

View File

@@ -14,7 +14,7 @@ const badgeVariants = cva(
secondary:
"border-transparent bg-secondary text-secondary-foreground [a&]:hover:bg-secondary/90",
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",
"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/70",
outline:
"text-foreground [a&]:hover:bg-accent [a&]:hover:text-accent-foreground",
},

View File

@@ -59,7 +59,7 @@ function NavigationMenuItem({
}
const navigationMenuTriggerStyle = cva(
"group inline-flex h-9 w-max items-center justify-center rounded-md bg-background px-4 py-2 text-sm font-medium hover:bg-accent hover:text-accent-foreground focus:bg-accent focus:text-accent-foreground disabled:pointer-events-none disabled:opacity-50 data-[state=open]:hover:bg-accent data-[state=open]:text-accent-foreground data-[state=open]:focus:bg-accent data-[state=open]:bg-accent/50 focus-visible:ring-ring/50 outline-none transition-[color,box-shadow] focus-visible:ring-[3px] focus-visible:outline-1"
"group inline-flex h-9 w-max items-center justify-center rounded-md bg-background px-4 py-2 text-sm font-medium hover:bg-accent hover:text-accent-foreground focus:bg-accent focus:text-accent-foreground disabled:pointer-events-none disabled:opacity-50 data-[state=open]:hover:bg-accent data-[state=open]:text-accent-foreground data-[state=open]:focus:bg-accent data-[state=open]:bg-accent/50 ring-ring/10 dark:ring-ring/20 dark:outline-ring/40 outline-ring/50 transition-[color,box-shadow] focus-visible:ring-4 focus-visible:outline-1"
)
function NavigationMenuTrigger({
@@ -129,7 +129,7 @@ function NavigationMenuLink({
<NavigationMenuPrimitive.Link
data-slot="navigation-menu-link"
className={cn(
"data-[active=true]:focus:bg-accent data-[active=true]:hover:bg-accent data-[active=true]:bg-accent/50 data-[active=true]:text-accent-foreground hover:bg-accent hover:text-accent-foreground focus:bg-accent focus:text-accent-foreground focus-visible:ring-ring/50 [&_svg:not([class*='text-'])]:text-muted-foreground flex flex-col gap-1 rounded-sm p-2 text-sm transition-all outline-none focus-visible:ring-[3px] focus-visible:outline-1 [&_svg:not([class*='size-'])]:size-4",
"data-[active=true]:focus:bg-accent data-[active=true]:hover:bg-accent data-[active=true]:bg-accent/50 data-[active=true]:text-accent-foreground hover:bg-accent hover:text-accent-foreground focus:bg-accent focus:text-accent-foreground ring-ring/10 dark:ring-ring/20 dark:outline-ring/40 outline-ring/50 [&_svg:not([class*='text-'])]:text-muted-foreground flex flex-col gap-1 rounded-sm p-2 text-sm transition-[color,box-shadow] focus-visible:ring-4 focus-visible:outline-1 [&_svg:not([class*='size-'])]:size-4",
className
)}
{...props}

View File

@@ -18,7 +18,7 @@ function ScrollArea({
>
<ScrollAreaPrimitive.Viewport
data-slot="scroll-area-viewport"
className="focus-visible:ring-ring/50 size-full rounded-[inherit] transition-[color,box-shadow] outline-none focus-visible:ring-[3px] focus-visible:outline-1"
className="ring-ring/10 dark:ring-ring/20 dark:outline-ring/40 outline-ring/50 size-full rounded-[inherit] transition-[color,box-shadow] focus-visible:ring-4 focus-visible:outline-1"
>
{children}
</ScrollAreaPrimitive.Viewport>

View File

@@ -7,8 +7,7 @@ import {
PageHeaderDescription,
PageHeaderHeading,
} from "@/components/page-header"
import { Customizer } from "@/components/theme-customizer"
import { Button } from "@/registry/new-york/ui/button"
import { ThemeCustomizer } from "@/components/theme-customizer"
const title = "Add colors. Make it yours."
const description =
@@ -49,17 +48,10 @@ export default function ThemesLayout({
<Announcement />
<PageHeaderHeading>{title}</PageHeaderHeading>
<PageHeaderDescription>{description}</PageHeaderDescription>
<div className="mt-2 rounded-full bg-blue-600 px-3 py-1 text-xs text-white">
New Theme Editor coming soon
</div>
<PageActions>
<ThemeCustomizer />
</PageActions>
</PageHeader>
<div id="themes" className="border-grid scroll-mt-24 border-b">
<div className="container-wrapper">
<div className="container flex items-center py-4">
<Customizer />
</div>
</div>
</div>
<div className="container-wrapper">
<div className="container py-6">
<section id="themes" className="scroll-mt-20">

View File

@@ -79,22 +79,20 @@ export function CodeBlockCommand({
})}
</TabsList>
</div>
<div className="overflow-x-auto">
{Object.entries(tabs).map(([key, value]) => {
return (
<TabsContent key={key} value={key} className="mt-0">
<pre className="px-4 py-5">
<code
className="relative font-mono text-sm leading-none"
data-language="bash"
>
{value}
</code>
</pre>
</TabsContent>
)
})}
</div>
{Object.entries(tabs).map(([key, value]) => {
return (
<TabsContent key={key} value={key} className="mt-0">
<pre className="px-4 py-5">
<code
className="relative font-mono text-sm leading-none"
data-language="bash"
>
{value}
</code>
</pre>
</TabsContent>
)
})}
</Tabs>
<Button
size="icon"

View File

@@ -2,7 +2,7 @@
import * as React from "react"
import template from "lodash/template"
import { Check, ClipboardIcon, Copy } from "lucide-react"
import { Check, Copy, Moon, Repeat, Sun } from "lucide-react"
import { useTheme } from "next-themes"
import { cn } from "@/lib/utils"
@@ -21,9 +21,6 @@ import {
import {
Drawer,
DrawerContent,
DrawerDescription,
DrawerHeader,
DrawerTitle,
DrawerTrigger,
} from "@/registry/new-york/ui/drawer"
import { Label } from "@/registry/new-york/ui/label"
@@ -32,28 +29,15 @@ import {
PopoverContent,
PopoverTrigger,
} from "@/registry/new-york/ui/popover"
import { Separator } from "@/registry/new-york/ui/separator"
import { Skeleton } from "@/registry/new-york/ui/skeleton"
import {
BaseColor,
baseColors,
baseColorsOKLCH,
} from "@/registry/registry-base-colors"
Tooltip,
TooltipContent,
TooltipTrigger,
} from "@/registry/new-york/ui/tooltip"
import { BaseColor, baseColors } from "@/registry/registry-base-colors"
import "@/styles/mdx.css"
import { toast } from "sonner"
import {
Tabs,
TabsContent,
TabsList,
TabsTrigger,
} from "@/registry/new-york/ui/tabs"
interface BaseColorOKLCH {
light: Record<string, string>
dark: Record<string, string>
}
export function ThemeCustomizer() {
const [config, setConfig] = useConfig()
@@ -94,9 +78,9 @@ export function ThemeCustomizer() {
)
}
export function Customizer() {
function Customizer() {
const [mounted, setMounted] = React.useState(false)
const { resolvedTheme: mode } = useTheme()
const { setTheme: setMode, resolvedTheme: mode } = useTheme()
const [config, setConfig] = useConfig()
React.useEffect(() => {
@@ -104,11 +88,39 @@ export function Customizer() {
}, [])
return (
<ThemeWrapper defaultTheme="zinc">
<div className="grid w-full flex-1 grid-cols-2 flex-wrap items-start gap-2 sm:flex sm:items-center md:gap-6">
<div className="flex flex-col gap-2">
<Label className="sr-only text-xs">Color</Label>
<div className="flex flex-wrap gap-1 md:gap-2">
<ThemeWrapper
defaultTheme="zinc"
className="flex flex-col space-y-4 md:space-y-6"
>
<div className="flex items-start pt-4 md:pt-0">
<div className="space-y-1 pr-2">
<div className="font-semibold leading-none tracking-tight">
Theme Customizer
</div>
<div className="text-xs text-muted-foreground">
Customize your components colors.
</div>
</div>
<Button
variant="ghost"
size="icon"
className="ml-auto rounded-[0.5rem]"
onClick={() => {
setConfig({
...config,
theme: "zinc",
radius: 0.5,
})
}}
>
<Repeat />
<span className="sr-only">Reset</span>
</Button>
</div>
<div className="flex flex-1 flex-col space-y-4 md:space-y-6">
<div className="space-y-1.5">
<Label className="text-xs">Color</Label>
<div className="grid grid-cols-3 gap-2">
{baseColors
.filter(
(theme) =>
@@ -119,7 +131,7 @@ export function Customizer() {
return mounted ? (
<Button
variant="outline"
variant={"outline"}
size="sm"
key={theme.name}
onClick={() => {
@@ -129,8 +141,8 @@ export function Customizer() {
})
}}
className={cn(
"w-[32px] rounded-lg lg:px-2.5 xl:w-[86px]",
isActive && "border-primary/50 ring-[2px] ring-primary/30"
"justify-start",
isActive && "border-2 border-primary"
)}
style={
{
@@ -142,28 +154,22 @@ export function Customizer() {
>
<span
className={cn(
"flex h-4 w-4 shrink-0 items-center justify-center rounded-full bg-[--theme-primary]"
"mr-1 flex h-5 w-5 shrink-0 -translate-x-1 items-center justify-center rounded-full bg-[--theme-primary]"
)}
>
{isActive && <Check className="!size-2.5 text-white" />}
</span>
<span className="hidden xl:block">
{theme.label === "Zinc" ? "Default" : theme.label}
{isActive && <Check className="h-4 w-4 text-white" />}
</span>
{theme.label}
</Button>
) : (
<Skeleton
className="h-8 w-[32px] xl:w-[86px]"
key={theme.name}
/>
<Skeleton className="h-8 w-full" key={theme.name} />
)
})}
</div>
</div>
<Separator orientation="vertical" className="hidden h-6 sm:block" />
<div className="flex flex-col gap-2">
<Label className="sr-only text-xs">Radius</Label>
<div className="flex flex-wrap gap-1 md:gap-2">
<div className="space-y-1.5">
<Label className="text-xs">Radius</Label>
<div className="grid grid-cols-5 gap-2">
{["0", "0.3", "0.5", "0.75", "1.0"].map((value) => {
return (
<Button
@@ -177,9 +183,8 @@ export function Customizer() {
})
}}
className={cn(
"w-[40px] rounded-lg",
config.radius === parseFloat(value) &&
"border-primary/50 ring-[2px] ring-primary/30"
"border-2 border-primary"
)}
>
{value}
@@ -188,50 +193,81 @@ export function Customizer() {
})}
</div>
</div>
<div className="flex gap-2 sm:ml-auto">
<CopyCodeButton />
<div className="space-y-1.5">
<Label className="text-xs">Mode</Label>
<div className="grid grid-cols-3 gap-2">
{mounted ? (
<>
<Button
variant={"outline"}
size="sm"
onClick={() => setMode("light")}
className={cn(mode === "light" && "border-2 border-primary")}
>
<Sun className="mr-1 -translate-x-1" />
Light
</Button>
<Button
variant={"outline"}
size="sm"
onClick={() => setMode("dark")}
className={cn(mode === "dark" && "border-2 border-primary")}
>
<Moon className="mr-1 -translate-x-1" />
Dark
</Button>
</>
) : (
<>
<Skeleton className="h-8 w-full" />
<Skeleton className="h-8 w-full" />
</>
)}
</div>
</div>
</div>
</ThemeWrapper>
)
}
export function CopyCodeButton({
function CopyCodeButton({
className,
...props
}: React.ComponentProps<typeof Button>) {
const [config] = useConfig()
const activeTheme = baseColors.find((theme) => theme.name === config.theme)
const [hasCopied, setHasCopied] = React.useState(false)
React.useEffect(() => {
setTimeout(() => {
setHasCopied(false)
}, 2000)
}, [hasCopied])
return (
<>
<Drawer>
<DrawerTrigger asChild>
<Button
className={cn("h-8 rounded-lg shadow-none sm:hidden", className)}
{...props}
>
Copy
</Button>
</DrawerTrigger>
<DrawerContent>
<DrawerHeader>
<DrawerTitle>Theme</DrawerTitle>
<DrawerDescription>
Copy and paste the following code into your CSS file.
</DrawerDescription>
</DrawerHeader>
<ThemeWrapper defaultTheme="zinc" className="relative px-6">
<CustomizerCode />
</ThemeWrapper>
</DrawerContent>
</Drawer>
{activeTheme && (
<Button
onClick={() => {
copyToClipboardWithMeta(getThemeCode(activeTheme, config.radius), {
name: "copy_theme_code",
properties: {
theme: activeTheme.name,
radius: config.radius,
},
})
setHasCopied(true)
}}
className={cn("md:hidden", className)}
{...props}
>
{hasCopied ? <Check /> : <Copy />}
Copy code
</Button>
)}
<Dialog>
<DialogTrigger asChild>
<Button
className={cn(
"hidden h-8 rounded-lg shadow-none sm:flex",
className
)}
{...props}
>
<Button className={cn("hidden md:flex", className)} {...props}>
Copy code
</Button>
</DialogTrigger>
@@ -244,6 +280,28 @@ export function CopyCodeButton({
</DialogHeader>
<ThemeWrapper defaultTheme="zinc" className="relative">
<CustomizerCode />
{activeTheme && (
<Button
size="sm"
onClick={() => {
copyToClipboardWithMeta(
getThemeCode(activeTheme, config.radius),
{
name: "copy_theme_code",
properties: {
theme: activeTheme.name,
radius: config.radius,
},
}
)
setHasCopied(true)
}}
className="absolute right-4 top-4 bg-muted text-muted-foreground hover:bg-muted hover:text-muted-foreground"
>
{hasCopied ? <Check /> : <Copy />}
Copy
</Button>
)}
</ThemeWrapper>
</DialogContent>
</Dialog>
@@ -253,269 +311,168 @@ export function CopyCodeButton({
function CustomizerCode() {
const [config] = useConfig()
const [hasCopied, setHasCopied] = React.useState(false)
const [themeVersion, setThemeVersion] = React.useState("v4")
const activeTheme = React.useMemo(
() => baseColors.find((theme) => theme.name === config.theme),
[config.theme]
)
const activeThemeOKLCH = React.useMemo(
() => baseColorsOKLCH[config.theme as keyof typeof baseColorsOKLCH],
[config.theme]
)
React.useEffect(() => {
if (hasCopied) {
setTimeout(() => {
setHasCopied(false)
}, 2000)
}
}, [hasCopied])
const activeTheme = baseColors.find((theme) => theme.name === config.theme)
return (
<ThemeWrapper defaultTheme="zinc" className="relative space-y-4">
<Tabs value={themeVersion} onValueChange={setThemeVersion}>
<div className="flex items-center justify-between">
<TabsList>
<TabsTrigger value="v4">Tailwind v4</TabsTrigger>
<TabsTrigger value="v3">v3</TabsTrigger>
</TabsList>
<Button
size="sm"
variant="outline"
onClick={() => {
copyToClipboardWithMeta(
themeVersion === "v3"
? getThemeCode(activeTheme, config.radius)
: getThemeCodeOKLCH(activeThemeOKLCH, config.radius),
{
name: "copy_theme_code",
properties: {
theme: config.theme,
radius: config.radius,
},
}
<div data-rehype-pretty-code-fragment="">
<pre className="max-h-[450px] overflow-x-auto rounded-lg border bg-zinc-950 py-4 dark:bg-zinc-900">
<code className="relative rounded bg-muted px-[0.3rem] py-[0.2rem] font-mono text-sm">
<span className="line text-white">@layer base &#123;</span>
<span className="line text-white">&nbsp;&nbsp;:root &#123;</span>
<span className="line text-white">
&nbsp;&nbsp;&nbsp;&nbsp;--background:{" "}
{activeTheme?.cssVars.light["background"]};
</span>
<span className="line text-white">
&nbsp;&nbsp;&nbsp;&nbsp;--foreground:{" "}
{activeTheme?.cssVars.light["foreground"]};
</span>
{[
"card",
"popover",
"primary",
"secondary",
"muted",
"accent",
"destructive",
].map((prefix) => (
<>
<span className="line text-white">
&nbsp;&nbsp;&nbsp;&nbsp;--{prefix}:{" "}
{
activeTheme?.cssVars.light[
prefix as keyof typeof activeTheme.cssVars.light
]
}
;
</span>
<span className="line text-white">
&nbsp;&nbsp;&nbsp;&nbsp;--{prefix}-foreground:{" "}
{
activeTheme?.cssVars.light[
`${prefix}-foreground` as keyof typeof activeTheme.cssVars.light
]
}
;
</span>
</>
))}
<span className="line text-white">
&nbsp;&nbsp;&nbsp;&nbsp;--border:{" "}
{activeTheme?.cssVars.light["border"]};
</span>
<span className="line text-white">
&nbsp;&nbsp;&nbsp;&nbsp;--input:{" "}
{activeTheme?.cssVars.light["input"]};
</span>
<span className="line text-white">
&nbsp;&nbsp;&nbsp;&nbsp;--ring:{" "}
{activeTheme?.cssVars.light["ring"]};
</span>
<span className="line text-white">
&nbsp;&nbsp;&nbsp;&nbsp;--radius: {config.radius}rem;
</span>
{["chart-1", "chart-2", "chart-3", "chart-4", "chart-5"].map(
(prefix) => (
<>
<span className="line text-white">
&nbsp;&nbsp;&nbsp;&nbsp;--{prefix}:{" "}
{
activeTheme?.cssVars.light[
prefix as keyof typeof activeTheme.cssVars.light
]
}
;
</span>
</>
)
setHasCopied(true)
}}
className="absolute right-0 top-0 shadow-none"
>
{hasCopied ? <Check /> : <ClipboardIcon />}
Copy
</Button>
</div>
<TabsContent value="v4">
<div data-rehype-pretty-code-fragment="">
<pre className="max-h-[450px] overflow-x-auto rounded-lg border bg-zinc-950 py-4 dark:bg-zinc-900">
<code className="relative rounded bg-muted px-[0.3rem] py-[0.2rem] font-mono text-sm">
<span className="line text-white">&nbsp;:root &#123;</span>
)}
<span className="line text-white">&nbsp;&nbsp;&#125;</span>
<span className="line text-white">&nbsp;</span>
<span className="line text-white">&nbsp;&nbsp;.dark &#123;</span>
<span className="line text-white">
&nbsp;&nbsp;&nbsp;&nbsp;--background:{" "}
{activeTheme?.cssVars.dark["background"]};
</span>
<span className="line text-white">
&nbsp;&nbsp;&nbsp;&nbsp;--foreground:{" "}
{activeTheme?.cssVars.dark["foreground"]};
</span>
{[
"card",
"popover",
"primary",
"secondary",
"muted",
"accent",
"destructive",
].map((prefix) => (
<>
<span className="line text-white">
&nbsp;&nbsp;&nbsp;--radius: {config.radius}rem;
&nbsp;&nbsp;&nbsp;&nbsp;--{prefix}:{" "}
{
activeTheme?.cssVars.dark[
prefix as keyof typeof activeTheme.cssVars.dark
]
}
;
</span>
{Object.entries(activeThemeOKLCH?.light).map(([key, value]) => (
<span className="line text-white" key={key}>
&nbsp;&nbsp;&nbsp;--{key}: {value};
<span className="line text-white">
&nbsp;&nbsp;&nbsp;&nbsp;--{prefix}-foreground:{" "}
{
activeTheme?.cssVars.dark[
`${prefix}-foreground` as keyof typeof activeTheme.cssVars.dark
]
}
;
</span>
</>
))}
<span className="line text-white">
&nbsp;&nbsp;&nbsp;&nbsp;--border:{" "}
{activeTheme?.cssVars.dark["border"]};
</span>
<span className="line text-white">
&nbsp;&nbsp;&nbsp;&nbsp;--input:{" "}
{activeTheme?.cssVars.dark["input"]};
</span>
<span className="line text-white">
&nbsp;&nbsp;&nbsp;&nbsp;--ring:{" "}
{activeTheme?.cssVars.dark["ring"]};
</span>
{["chart-1", "chart-2", "chart-3", "chart-4", "chart-5"].map(
(prefix) => (
<>
<span className="line text-white">
&nbsp;&nbsp;&nbsp;&nbsp;--{prefix}:{" "}
{
activeTheme?.cssVars.dark[
prefix as keyof typeof activeTheme.cssVars.dark
]
}
;
</span>
))}
<span className="line text-white">&nbsp;&#125;</span>
<span className="line text-white">&nbsp;</span>
<span className="line text-white">&nbsp;.dark &#123;</span>
{Object.entries(activeThemeOKLCH?.dark).map(([key, value]) => (
<span className="line text-white" key={key}>
&nbsp;&nbsp;&nbsp;--{key}: {value};
</span>
))}
<span className="line text-white">&nbsp;&#125;</span>
</code>
</pre>
</div>
</TabsContent>
<TabsContent value="v3">
<div data-rehype-pretty-code-fragment="">
<pre className="max-h-[450px] overflow-x-auto rounded-lg border bg-zinc-950 py-4 dark:bg-zinc-900">
<code className="relative rounded bg-muted px-[0.3rem] py-[0.2rem] font-mono text-sm">
<span className="line text-white">@layer base &#123;</span>
<span className="line text-white">
&nbsp;&nbsp;:root &#123;
</span>
<span className="line text-white">
&nbsp;&nbsp;&nbsp;&nbsp;--background:{" "}
{activeTheme?.cssVars.light["background"]};
</span>
<span className="line text-white">
&nbsp;&nbsp;&nbsp;&nbsp;--foreground:{" "}
{activeTheme?.cssVars.light["foreground"]};
</span>
{[
"card",
"popover",
"primary",
"secondary",
"muted",
"accent",
"destructive",
].map((prefix) => (
<>
<span className="line text-white">
&nbsp;&nbsp;&nbsp;&nbsp;--{prefix}:{" "}
{
activeTheme?.cssVars.light[
prefix as keyof typeof activeTheme.cssVars.light
]
}
;
</span>
<span className="line text-white">
&nbsp;&nbsp;&nbsp;&nbsp;--{prefix}-foreground:{" "}
{
activeTheme?.cssVars.light[
`${prefix}-foreground` as keyof typeof activeTheme.cssVars.light
]
}
;
</span>
</>
))}
<span className="line text-white">
&nbsp;&nbsp;&nbsp;&nbsp;--border:{" "}
{activeTheme?.cssVars.light["border"]};
</span>
<span className="line text-white">
&nbsp;&nbsp;&nbsp;&nbsp;--input:{" "}
{activeTheme?.cssVars.light["input"]};
</span>
<span className="line text-white">
&nbsp;&nbsp;&nbsp;&nbsp;--ring:{" "}
{activeTheme?.cssVars.light["ring"]};
</span>
<span className="line text-white">
&nbsp;&nbsp;&nbsp;&nbsp;--radius: {config.radius}rem;
</span>
{["chart-1", "chart-2", "chart-3", "chart-4", "chart-5"].map(
(prefix) => (
<>
<span className="line text-white">
&nbsp;&nbsp;&nbsp;&nbsp;--{prefix}:{" "}
{
activeTheme?.cssVars.light[
prefix as keyof typeof activeTheme.cssVars.light
]
}
;
</span>
</>
)
)}
<span className="line text-white">&nbsp;&nbsp;&#125;</span>
<span className="line text-white">&nbsp;</span>
<span className="line text-white">
&nbsp;&nbsp;.dark &#123;
</span>
<span className="line text-white">
&nbsp;&nbsp;&nbsp;&nbsp;--background:{" "}
{activeTheme?.cssVars.dark["background"]};
</span>
<span className="line text-white">
&nbsp;&nbsp;&nbsp;&nbsp;--foreground:{" "}
{activeTheme?.cssVars.dark["foreground"]};
</span>
{[
"card",
"popover",
"primary",
"secondary",
"muted",
"accent",
"destructive",
].map((prefix) => (
<>
<span className="line text-white">
&nbsp;&nbsp;&nbsp;&nbsp;--{prefix}:{" "}
{
activeTheme?.cssVars.dark[
prefix as keyof typeof activeTheme.cssVars.dark
]
}
;
</span>
<span className="line text-white">
&nbsp;&nbsp;&nbsp;&nbsp;--{prefix}-foreground:{" "}
{
activeTheme?.cssVars.dark[
`${prefix}-foreground` as keyof typeof activeTheme.cssVars.dark
]
}
;
</span>
</>
))}
<span className="line text-white">
&nbsp;&nbsp;&nbsp;&nbsp;--border:{" "}
{activeTheme?.cssVars.dark["border"]};
</span>
<span className="line text-white">
&nbsp;&nbsp;&nbsp;&nbsp;--input:{" "}
{activeTheme?.cssVars.dark["input"]};
</span>
<span className="line text-white">
&nbsp;&nbsp;&nbsp;&nbsp;--ring:{" "}
{activeTheme?.cssVars.dark["ring"]};
</span>
{["chart-1", "chart-2", "chart-3", "chart-4", "chart-5"].map(
(prefix) => (
<>
<span className="line text-white">
&nbsp;&nbsp;&nbsp;&nbsp;--{prefix}:{" "}
{
activeTheme?.cssVars.dark[
prefix as keyof typeof activeTheme.cssVars.dark
]
}
;
</span>
</>
)
)}
<span className="line text-white">&nbsp;&nbsp;&#125;</span>
<span className="line text-white">&#125;</span>
</code>
</pre>
</div>
</TabsContent>
</Tabs>
</>
)
)}
<span className="line text-white">&nbsp;&nbsp;&#125;</span>
<span className="line text-white">&#125;</span>
</code>
</pre>
</div>
</ThemeWrapper>
)
}
function getThemeCodeOKLCH(theme: BaseColorOKLCH | undefined, radius: number) {
if (!theme) {
return ""
}
const rootSection =
":root {\n --radius: " +
radius +
"rem;\n" +
Object.entries(theme.light)
.map((entry) => " --" + entry[0] + ": " + entry[1] + ";")
.join("\n") +
"\n}\n\n.dark {\n" +
Object.entries(theme.dark)
.map((entry) => " --" + entry[0] + ": " + entry[1] + ";")
.join("\n") +
"\n}\n"
return rootSection
}
function getThemeCode(theme: BaseColor | undefined, radius: number) {
function getThemeCode(theme: BaseColor, radius: number) {
if (!theme) {
return ""
}
return template(BASE_STYLES_WITH_VARIABLES)({
colors: theme.cssVars,
radius: radius.toString(),
radius,
})
}

View File

@@ -433,11 +433,6 @@ export const docsConfig: DocsConfig = {
href: "/docs/registry/getting-started",
items: [],
},
{
title: "Examples",
href: "/docs/registry/examples",
items: [],
},
{
title: "Open in v0",
href: "/docs/registry/open-in-v0",

View File

@@ -1,356 +0,0 @@
---
title: Examples
description: "Examples of registry items: styles, components, css vars, etc."
---
## registry:style
### Custom style that extends shadcn/ui
The following registry item is a custom style that extends shadcn/ui. On `npx shadcn init`, it will:
- Install `@tabler/icons-react` as a dependency.
- Add the `login-01` block and `calendar` component to the project.
- Add the `editor` from a remote registry.
- Set the `font-sans` variable to `Inter, sans-serif`.
- Install a `brand` color in light and dark mode.
```json title="example-style.json" showLineNumbers
{
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
"name": "example-style",
"type": "registry:style",
"dependencies": ["@tabler/icons-react"],
"registryDependencies": [
"login-01",
"calendar",
"https://example.com/r/editor.json"
],
"cssVars": {
"theme": {
"font-sans": "Inter, sans-serif"
},
"light": {
"brand": "20 14.3% 4.1%"
},
"dark": {
"brand": "20 14.3% 4.1%"
}
}
}
```
### Custom style from scratch
The following registry item is a custom style that doesn't extend shadcn/ui. See the `extends: none` field.
It can be used to create a new style from scratch i.e custom components, css vars, dependencies, etc.
On `npx shadcn add`, the following will:
- Install `tailwind-merge` and `clsx` as dependencies.
- Add the `utils` registry item from the shadcn/ui registry.
- Add the `button`, `input`, `label`, and `select` components from a remote registry.
- Install new css vars: `main`, `bg`, `border`, `text`, `ring`.
```json title="example-style.json" showLineNumbers
{
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
"extends": "none",
"name": "new-style",
"type": "registry:style",
"dependencies": ["tailwind-merge", "clsx"],
"registryDependencies": [
"utils",
"https://example.com/r/button.json",
"https://example.com/r/input.json",
"https://example.com/r/label.json",
"https://example.com/r/select.json"
],
"cssVars": {
"theme": {
"font-sans": "Inter, sans-serif",
}
"light": {
"main": "#88aaee",
"bg": "#dfe5f2",
"border": "#000",
"text": "#000",
"ring": "#000",
},
"dark": {
"main": "#88aaee",
"bg": "#272933",
"border": "#000",
"text": "#e6e6e6",
"ring": "#fff",
}
}
}
```
## registry:theme
### Custom theme
```json title="example-theme.json" showLineNumbers
{
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
"name": "custom-theme",
"type": "registry:theme",
"cssVars": {
"light": {
"background": "oklch(1 0 0)",
"foreground": "oklch(0.141 0.005 285.823)",
"primary": "oklch(0.546 0.245 262.881)",
"primary-foreground": "oklch(0.97 0.014 254.604)",
"ring": "oklch(0.746 0.16 232.661)",
"sidebar-primary": "oklch(0.546 0.245 262.881)",
"sidebar-primary-foreground": "oklch(0.97 0.014 254.604)",
"sidebar-ring": "oklch(0.746 0.16 232.661)"
},
"dark": {
"background": "oklch(1 0 0)",
"foreground": "oklch(0.141 0.005 285.823)",
"primary": "oklch(0.707 0.165 254.624)",
"primary-foreground": "oklch(0.97 0.014 254.604)",
"ring": "oklch(0.707 0.165 254.624)",
"sidebar-primary": "oklch(0.707 0.165 254.624)",
"sidebar-primary-foreground": "oklch(0.97 0.014 254.604)",
"sidebar-ring": "oklch(0.707 0.165 254.624)"
}
}
}
```
### Custom colors
The following style will init using shadcn/ui defaults and then add a custom `brand` color.
```json title="example-style.json" showLineNumbers
{
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
"name": "custom-style",
"type": "registry:style",
"cssVars": {
"light": {
"brand": "oklch(0.99 0.00 0)"
},
"dark": {
"brand": "oklch(0.14 0.00 286)"
}
}
}
```
## registry:block
### Custom block
This blocks installs the `login-01` block from the shadcn/ui registry.
```json title="login-01.json" showLineNumbers
{
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
"name": "login-01",
"type": "registry:block",
"description": "A simple login form.",
"registryDependencies": ["button", "card", "input", "label"],
"files": [
{
"path": "blocks/login-01/page.tsx",
"content": "import { LoginForm } ...",
"type": "registry:page",
"target": "app/login/page.tsx"
},
{
"path": "blocks/login-01/components/login-form.tsx",
"content": "...",
"type": "registry:component"
}
]
}
```
### Install a block and override primitives
You can install a block fromt the shadcn/ui registry and override the primitives using your custom ones.
On `npx shadcn add`, the following will:
- Add the `login-01` block from the shadcn/ui registry.
- Override the `button`, `input`, and `label` primitives with the ones from the remote registry.
```json title="example-style.json" showLineNumbers
{
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
"name": "custom-login",
"type": "registry:block",
"registryDependencies": [
"login-01",
"https://example.com/r/button.json",
"https://example.com/r/input.json",
"https://example.com/r/label.json"
]
}
```
## CSS Variables
### Custom Theme Variables
Add custom theme variables to the `theme` object.
```json title="example-theme.json" showLineNumbers
{
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
"name": "custom-theme",
"type": "registry:theme",
"cssVars": {
"theme": {
"font-heading": "Inter, sans-serif",
"shadow-card": "0 0 0 1px rgba(0, 0, 0, 0.1)"
}
}
}
```
### Override Tailwind CSS variables
```json title="example-theme.json" showLineNumbers
{
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
"name": "custom-theme",
"type": "registry:theme",
"cssVars": {
"theme": {
"spacing": "0.2rem",
"breakpoint-sm": "640px",
"breakpoint-md": "768px",
"breakpoint-lg": "1024px",
"breakpoint-xl": "1280px",
"breakpoint-2xl": "1536px"
}
}
}
```
## Add custom CSS
### Base styles
```json title="example-base.json" showLineNumbers
{
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
"name": "custom-style",
"type": "registry:style",
"css": {
"@layer base": {
"h1": {
"font-size": "var(--text-2xl)"
},
"h2": {
"font-size": "var(--text-xl)"
}
}
}
}
```
### Components
```json title="example-card.json" showLineNumbers
{
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
"name": "custom-card",
"type": "registry:component",
"css": {
"@layer components": {
"card": {
"background-color": "var(--color-white)",
"border-radius": "var(--rounded-lg)",
"padding": "var(--spacing-6)",
"box-shadow": "var(--shadow-xl)"
}
}
}
}
```
## Add custom utilities
### Simple utility
```json title="example-component.json" showLineNumbers
{
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
"name": "custom-component",
"type": "registry:component",
"css": {
"@utility content-auto": {
"content-visibility": "auto"
}
}
}
```
### Complex utility
```json title="example-utility.json" showLineNumbers
{
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
"name": "custom-component",
"type": "registry:component",
"css": {
"@utility scrollbar-hidden": {
"scrollbar-hidden": {
"&::-webkit-scrollbar": {
"display": "none"
}
}
}
}
}
```
### Functional utilities
```json title="example-functional.json" showLineNumbers
{
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
"name": "custom-component",
"type": "registry:component",
"css": {
"@utility tab-*": {
"tab-size": "var(--tab-size-*)"
}
}
}
```
## Add custom animations
Note: you need to define both `@keyframes` in css and `theme` in cssVars to use animations.
```json title="example-component.json" showLineNumbers
{
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
"name": "custom-component",
"type": "registry:component",
"cssVars": {
"theme": {
"--animate-wiggle": "wiggle 1s ease-in-out infinite"
}
},
"css": {
"@keyframes wiggle": {
"0%, 100%": {
"transform": "rotate(-3deg)"
},
"50%": {
"transform": "rotate(3deg)"
}
}
}
}
```

View File

@@ -49,46 +49,6 @@ Here's an example of a complex component that installs a page, two components, a
### How do I add a new Tailwind color?
<Tabs defaultValue="v4">
<TabsList>
<TabsTrigger value="v4">Tailwind CSS v4</TabsTrigger>
<TabsTrigger value="v3">Tailwind CSS v3</TabsTrigger>
</TabsList>
<TabsContent value="v4">
To add a new color you need to add it to `cssVars` under `light` and `dark` keys.
```json showLineNumbers {10-18}
{
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
"name": "hello-world",
"title": "Hello World",
"type": "registry:block",
"description": "A complex hello world component",
"files": [
// ...
],
"cssVars": {
"light": {
"brand-background": "20 14.3% 4.1%",
"brand-accent": "20 14.3% 4.1%"
},
"dark": {
"brand-background": "20 14.3% 4.1%",
"brand-accent": "20 14.3% 4.1%"
}
}
}
```
The CLI will update the project CSS file. Once updated, the new colors will be available to be used as utility classes: `bg-brand` and `text-brand-accent`.
</TabsContent>
<TabsContent value="v3">
To add a new color you need to add it to `cssVars` and `tailwind.config.theme.extend.colors`.
```json showLineNumbers {10-19} {24-29}
@@ -130,47 +90,9 @@ To add a new color you need to add it to `cssVars` and `tailwind.config.theme.ex
The CLI will update the project CSS file and tailwind.config.js file. Once updated, the new colors will be available to be used as utility classes: `bg-brand` and `text-brand-accent`.
</TabsContent>
</Tabs>
### How do I add a Tailwind animation?
### How do I add or override a Tailwind theme variable?
<Tabs defaultValue="v4">
<TabsList>
<TabsTrigger value="v4">Tailwind CSS v4</TabsTrigger>
<TabsTrigger value="v3">Tailwind CSS v3</TabsTrigger>
</TabsList>
<TabsContent value="v4">
To add or override a theme variable you add it to `cssVars.theme` under the key you want to add or override.
```json showLineNumbers {10-15}
{
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
"name": "hello-world",
"title": "Hello World",
"type": "registry:block",
"description": "A complex hello world component",
"files": [
// ...
],
"cssVars": {
"theme": {
"text-base": "3rem",
"ease-in-out": "cubic-bezier(0.4, 0, 0.2, 1)",
"font-heading": "Poppins, sans-serif"
}
}
}
```
</TabsContent>
<TabsContent value="v3">
To override a theme variable you add it to `tailwind.config.theme.extend` under the key you want to override.
To add a new animation you add it to `tailwind.config.theme.extend.animation` and `tailwind.config.theme.extend.keyframes`.
```json showLineNumbers {14-22}
{
@@ -186,8 +108,14 @@ To override a theme variable you add it to `tailwind.config.theme.extend` under
"config": {
"theme": {
"extend": {
"text": {
"base": "3rem"
"keyframes": {
"wiggle": {
"0%, 100%": { "transform": "rotate(-3deg)" },
"50%": { "transform": "rotate(3deg)" }
}
},
"animation": {
"wiggle": "wiggle 1s ease-in-out infinite"
}
}
}
@@ -195,6 +123,3 @@ To override a theme variable you add it to `tailwind.config.theme.extend` under
}
}
```
</TabsContent>
</Tabs>

View File

@@ -21,25 +21,10 @@ The `registry-item.json` schema is used to define your custom registry items.
"path": "registry/new-york/hello-world/use-hello-world.ts",
"type": "registry:hook"
}
],
"cssVars": {
"theme": {
"font-heading": "Poppins, sans-serif"
},
"light": {
"brand": "20 14.3% 4.1%"
},
"dark": {
"brand": "20 14.3% 4.1%"
}
}
]
}
```
<div className="flex gap-2 items-center mt-6">
<Link href="/docs/registry/examples">See more examples</Link>
</div>
## Definitions
You can see the JSON Schema for `registry-item.json` [here](https://ui.shadcn.com/schema/registry-item.json).
@@ -56,7 +41,7 @@ The `$schema` property is used to specify the schema for the `registry-item.json
### name
The name of the item. This is used to identify the item in the registry. It should be unique for your registry.
The `name` property is used to specify the name of your registry item.
```json title="registry-item.json" showLineNumbers
{
@@ -86,7 +71,7 @@ A description of your registry item. This can be longer and more detailed than t
### type
The `type` property is used to specify the type of your registry item. This is used to determine the type and target path of the item when resolved for a project.
The `type` property is used to specify the type of your registry item.
```json title="registry-item.json" showLineNumbers
{
@@ -105,8 +90,6 @@ The following types are supported:
| `registry:ui` | Use for UI components and single-file primitives |
| `registry:page` | Use for page or file-based routes. |
| `registry:file` | Use for miscellaneous files. |
| `registry:style` | Use for registry styles. eg. `new-york` |
| `registry:theme` | Use for themes. |
### author
@@ -139,7 +122,7 @@ Use `@version` to specify the version of your registry item.
### registryDependencies
Used for registry dependencies. Can be names or URLs. Use the name of the item to reference shadcn/ui components and urls to reference other registries.
Used for registry dependencies. Can be names or URLs.
- For `shadcn/ui` registry items such as `button`, `input`, `select`, etc use the name eg. `['button', 'input', 'select']`.
- For custom registry items use the URL of the registry item eg. `['https://example.com/r/hello-world.json']`.
@@ -206,8 +189,6 @@ Use `~` to refer to the root of the project e.g `~/foo.config.js`.
### tailwind
**DEPRECATED:** Use `cssVars.theme` instead for Tailwind v4 projects.
The `tailwind` property is used for tailwind configuration such as `theme`, `plugins` and `content`.
You can use the `tailwind.config` property to add colors, animations and plugins to your registry item.
@@ -244,9 +225,6 @@ Use to define CSS variables for your registry item.
```json title="registry-item.json" showLineNumbers
{
"cssVars": {
"theme": {
"font-heading": "Poppins, sans-serif"
},
"light": {
"brand": "20 14.3% 4.1%",
"radius": "0.5rem"
@@ -258,40 +236,10 @@ Use to define CSS variables for your registry item.
}
```
### css
Use `css` to add new rules to the project's CSS file eg. `@layer base`, `@layer components`, `@utility`, `@keyframes`, etc.
```json title="registry-item.json" showLineNumbers
{
"css": {
"@layer base": {
"body": {
"font-size": "var(--text-base)",
"line-height": "1.5"
}
},
"@layer components": {
"button": {
"background-color": "var(--color-primary)",
"color": "var(--color-white)"
}
},
"@utility text-magic": {
"font-size": "var(--text-base)",
"line-height": "1.5"
},
"@keyframes wiggle": {
"0%, 100%": {
"transform": "rotate(-3deg)"
},
"50%": {
"transform": "rotate(3deg)"
}
}
}
}
```
<Callout>
**Note:** When adding colors, make sure to also add them to the
`tailwind.config.theme.extend.colors` property.
</Callout>
### docs

View File

@@ -92,7 +92,6 @@ Here's the list of variables available for customization:
```css title="app/globals.css"
:root {
--radius: 0.625rem;
--background: oklch(1 0 0);
--foreground: oklch(0.145 0 0);
--card: oklch(1 0 0);
@@ -108,6 +107,7 @@ Here's the list of variables available for customization:
--accent: oklch(0.97 0 0);
--accent-foreground: oklch(0.205 0 0);
--destructive: oklch(0.577 0.245 27.325);
--destructive-foreground: oklch(0.577 0.245 27.325);
--border: oklch(0.922 0 0);
--input: oklch(0.922 0 0);
--ring: oklch(0.708 0 0);
@@ -116,6 +116,7 @@ Here's the list of variables available for customization:
--chart-3: oklch(0.398 0.07 227.392);
--chart-4: oklch(0.828 0.189 84.429);
--chart-5: oklch(0.769 0.188 70.08);
--radius: 0.625rem;
--sidebar: oklch(0.985 0 0);
--sidebar-foreground: oklch(0.145 0 0);
--sidebar-primary: oklch(0.205 0 0);
@@ -129,21 +130,22 @@ Here's the list of variables available for customization:
.dark {
--background: oklch(0.145 0 0);
--foreground: oklch(0.985 0 0);
--card: oklch(0.205 0 0);
--card: oklch(0.145 0 0);
--card-foreground: oklch(0.985 0 0);
--popover: oklch(0.269 0 0);
--popover: oklch(0.145 0 0);
--popover-foreground: oklch(0.985 0 0);
--primary: oklch(0.922 0 0);
--primary: oklch(0.985 0 0);
--primary-foreground: oklch(0.205 0 0);
--secondary: oklch(0.269 0 0);
--secondary-foreground: oklch(0.985 0 0);
--muted: oklch(0.269 0 0);
--muted-foreground: oklch(0.708 0 0);
--accent: oklch(0.371 0 0);
--accent: oklch(0.269 0 0);
--accent-foreground: oklch(0.985 0 0);
--destructive: oklch(0.704 0.191 22.216);
--border: oklch(1 0 0 / 10%);
--input: oklch(1 0 0 / 15%);
--destructive: oklch(0.396 0.141 25.723);
--destructive-foreground: oklch(0.637 0.237 25.331);
--border: oklch(0.269 0 0);
--input: oklch(0.269 0 0);
--ring: oklch(0.556 0 0);
--chart-1: oklch(0.488 0.243 264.376);
--chart-2: oklch(0.696 0.17 162.48);
@@ -156,7 +158,7 @@ Here's the list of variables available for customization:
--sidebar-primary-foreground: oklch(0.985 0 0);
--sidebar-accent: oklch(0.269 0 0);
--sidebar-accent-foreground: oklch(0.985 0 0);
--sidebar-border: oklch(1 0 0 / 10%);
--sidebar-border: oklch(0.269 0 0);
--sidebar-ring: oklch(0.439 0 0);
}
```

View File

@@ -113,7 +113,7 @@ export default makeSource({
[
rehypePrettyCode,
{
theme: "github-dark-default",
theme: "github-dark",
getHighlighter,
onVisitLine(node) {
// Prevent lines from collapsing in `display: grid` mode, and allow empty

View File

@@ -46,7 +46,7 @@
"@radix-ui/react-portal": "^1.0.4",
"@radix-ui/react-progress": "^1.0.3",
"@radix-ui/react-radio-group": "^1.1.3",
"@radix-ui/react-scroll-area": "^1.2.3",
"@radix-ui/react-scroll-area": "^1.0.4",
"@radix-ui/react-select": "^2.0.0",
"@radix-ui/react-separator": "^1.0.3",
"@radix-ui/react-slider": "^1.1.2",
@@ -86,8 +86,8 @@
"react-resizable-panels": "^2.0.22",
"react-wrap-balancer": "^0.4.1",
"recharts": "2.12.7",
"shadcn": "2.4.1",
"sharp": "^0.32.6",
"shadcn": "2.3.0",
"sharp": "^0.31.3",
"sonner": "^1.2.3",
"swr": "2.2.6-beta.3",
"tailwind-merge": "^1.12.0",
@@ -102,7 +102,7 @@
"@types/react": "^18.2.65",
"@types/react-color": "^3.0.6",
"@types/react-dom": "^18.2.22",
"esbuild": "^0.25.0",
"esbuild": "^0.17.19",
"eslint": "^8.41.0",
"mdast-util-toc": "^6.1.1",
"postcss": "^8.4.24",
@@ -112,7 +112,7 @@
"rehype-slug": "^5.1.0",
"remark": "^14.0.3",
"remark-code-import": "^1.2.0",
"remark-gfm": "^4.0.1",
"remark-gfm": "^4.0.0",
"rimraf": "^4.1.3",
"shiki": "^1.10.1",
"tailwindcss": "3.4.6",

View File

@@ -223,7 +223,7 @@
"name": "command",
"type": "registry:ui",
"dependencies": [
"cmdk"
"cmdk@1.0.0"
],
"registryDependencies": [
"dialog"

View File

@@ -4,7 +4,7 @@
"type": "registry:ui",
"author": "shadcn (https://ui.shadcn.com)",
"dependencies": [
"cmdk"
"cmdk@1.0.0"
],
"registryDependencies": [
"dialog"

View File

@@ -8,7 +8,7 @@
"files": [
{
"path": "registry/new-york-v4/ui/badge.tsx",
"content": "import * as React from \"react\"\nimport { Slot } from \"@radix-ui/react-slot\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\n\nimport { cn } from \"@/lib/utils\"\n\nconst badgeVariants = cva(\n \"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\",\n {\n variants: {\n variant: {\n default:\n \"border-transparent bg-primary text-primary-foreground [a&]:hover:bg-primary/90\",\n secondary:\n \"border-transparent bg-secondary text-secondary-foreground [a&]:hover:bg-secondary/90\",\n destructive:\n \"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\",\n outline:\n \"text-foreground [a&]:hover:bg-accent [a&]:hover:text-accent-foreground\",\n },\n },\n defaultVariants: {\n variant: \"default\",\n },\n }\n)\n\nfunction Badge({\n className,\n variant,\n asChild = false,\n ...props\n}: React.ComponentProps<\"span\"> &\n VariantProps<typeof badgeVariants> & { asChild?: boolean }) {\n const Comp = asChild ? Slot : \"span\"\n\n return (\n <Comp\n data-slot=\"badge\"\n className={cn(badgeVariants({ variant }), className)}\n {...props}\n />\n )\n}\n\nexport { Badge, badgeVariants }\n",
"content": "import * as React from \"react\"\nimport { Slot } from \"@radix-ui/react-slot\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\n\nimport { cn } from \"@/lib/utils\"\n\nconst badgeVariants = cva(\n \"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\",\n {\n variants: {\n variant: {\n default:\n \"border-transparent bg-primary text-primary-foreground [a&]:hover:bg-primary/90\",\n secondary:\n \"border-transparent bg-secondary text-secondary-foreground [a&]:hover:bg-secondary/90\",\n destructive:\n \"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/70\",\n outline:\n \"text-foreground [a&]:hover:bg-accent [a&]:hover:text-accent-foreground\",\n },\n },\n defaultVariants: {\n variant: \"default\",\n },\n }\n)\n\nfunction Badge({\n className,\n variant,\n asChild = false,\n ...props\n}: React.ComponentProps<\"span\"> &\n VariantProps<typeof badgeVariants> & { asChild?: boolean }) {\n const Comp = asChild ? Slot : \"span\"\n\n return (\n <Comp\n data-slot=\"badge\"\n className={cn(badgeVariants({ variant }), className)}\n {...props}\n />\n )\n}\n\nexport { Badge, badgeVariants }\n",
"type": "registry:ui"
}
]

View File

@@ -3,7 +3,7 @@
"name": "command",
"type": "registry:ui",
"dependencies": [
"cmdk"
"cmdk@1.0.0"
],
"registryDependencies": [
"dialog"

File diff suppressed because one or more lines are too long

View File

@@ -8,7 +8,7 @@
"files": [
{
"path": "registry/new-york-v4/ui/scroll-area.tsx",
"content": "\"use client\"\n\nimport * as React from \"react\"\nimport * as ScrollAreaPrimitive from \"@radix-ui/react-scroll-area\"\n\nimport { cn } from \"@/lib/utils\"\n\nfunction ScrollArea({\n className,\n children,\n ...props\n}: React.ComponentProps<typeof ScrollAreaPrimitive.Root>) {\n return (\n <ScrollAreaPrimitive.Root\n data-slot=\"scroll-area\"\n className={cn(\"relative\", className)}\n {...props}\n >\n <ScrollAreaPrimitive.Viewport\n data-slot=\"scroll-area-viewport\"\n className=\"focus-visible:ring-ring/50 size-full rounded-[inherit] transition-[color,box-shadow] outline-none focus-visible:ring-[3px] focus-visible:outline-1\"\n >\n {children}\n </ScrollAreaPrimitive.Viewport>\n <ScrollBar />\n <ScrollAreaPrimitive.Corner />\n </ScrollAreaPrimitive.Root>\n )\n}\n\nfunction ScrollBar({\n className,\n orientation = \"vertical\",\n ...props\n}: React.ComponentProps<typeof ScrollAreaPrimitive.ScrollAreaScrollbar>) {\n return (\n <ScrollAreaPrimitive.ScrollAreaScrollbar\n data-slot=\"scroll-area-scrollbar\"\n orientation={orientation}\n className={cn(\n \"flex touch-none p-px transition-colors select-none\",\n orientation === \"vertical\" &&\n \"h-full w-2.5 border-l border-l-transparent\",\n orientation === \"horizontal\" &&\n \"h-2.5 flex-col border-t border-t-transparent\",\n className\n )}\n {...props}\n >\n <ScrollAreaPrimitive.ScrollAreaThumb\n data-slot=\"scroll-area-thumb\"\n className=\"bg-border relative flex-1 rounded-full\"\n />\n </ScrollAreaPrimitive.ScrollAreaScrollbar>\n )\n}\n\nexport { ScrollArea, ScrollBar }\n",
"content": "\"use client\"\n\nimport * as React from \"react\"\nimport * as ScrollAreaPrimitive from \"@radix-ui/react-scroll-area\"\n\nimport { cn } from \"@/lib/utils\"\n\nfunction ScrollArea({\n className,\n children,\n ...props\n}: React.ComponentProps<typeof ScrollAreaPrimitive.Root>) {\n return (\n <ScrollAreaPrimitive.Root\n data-slot=\"scroll-area\"\n className={cn(\"relative\", className)}\n {...props}\n >\n <ScrollAreaPrimitive.Viewport\n data-slot=\"scroll-area-viewport\"\n className=\"ring-ring/10 dark:ring-ring/20 dark:outline-ring/40 outline-ring/50 size-full rounded-[inherit] transition-[color,box-shadow] focus-visible:ring-4 focus-visible:outline-1\"\n >\n {children}\n </ScrollAreaPrimitive.Viewport>\n <ScrollBar />\n <ScrollAreaPrimitive.Corner />\n </ScrollAreaPrimitive.Root>\n )\n}\n\nfunction ScrollBar({\n className,\n orientation = \"vertical\",\n ...props\n}: React.ComponentProps<typeof ScrollAreaPrimitive.ScrollAreaScrollbar>) {\n return (\n <ScrollAreaPrimitive.ScrollAreaScrollbar\n data-slot=\"scroll-area-scrollbar\"\n orientation={orientation}\n className={cn(\n \"flex touch-none p-px transition-colors select-none\",\n orientation === \"vertical\" &&\n \"h-full w-2.5 border-l border-l-transparent\",\n orientation === \"horizontal\" &&\n \"h-2.5 flex-col border-t border-t-transparent\",\n className\n )}\n {...props}\n >\n <ScrollAreaPrimitive.ScrollAreaThumb\n data-slot=\"scroll-area-thumb\"\n className=\"bg-border relative flex-1 rounded-full\"\n />\n </ScrollAreaPrimitive.ScrollAreaScrollbar>\n )\n}\n\nexport { ScrollArea, ScrollBar }\n",
"type": "registry:ui"
}
]

View File

@@ -4,7 +4,7 @@
"type": "registry:ui",
"author": "shadcn (https://ui.shadcn.com)",
"dependencies": [
"cmdk"
"cmdk@1.0.0"
],
"registryDependencies": [
"dialog"

View File

@@ -3,8 +3,7 @@
"type": "object",
"properties": {
"name": {
"type": "string",
"description": "The name of the item. This is used to identify the item in the registry. It should be unique for your registry."
"type": "string"
},
"type": {
"type": "string",
@@ -16,57 +15,46 @@
"registry:hook",
"registry:theme",
"registry:page",
"registry:file",
"registry:style"
],
"description": "The type of the item. This is used to determine the type and target path of the item when resolved for a project."
"registry:file"
]
},
"description": {
"type": "string",
"description": "The description of the item. This is used to provide a brief overview of the item."
"type": "string"
},
"title": {
"type": "string",
"description": "The human-readable title for your registry item. Keep it short and descriptive."
"type": "string"
},
"author": {
"type": "string",
"description": "The author of the item. Recommended format: username <url>"
"type": "string"
},
"dependencies": {
"type": "array",
"description": "An array of NPM dependencies required by the registry item.",
"items": {
"type": "string"
}
},
"devDependencies": {
"type": "array",
"description": "An array of NPM dev dependencies required by the registry item.",
"items": {
"type": "string"
}
},
"registryDependencies": {
"type": "array",
"description": "An array of registry items that this item depends on. Use the name of the item to reference shadcn/ui components and urls to reference other registries.",
"items": {
"type": "string"
}
},
"files": {
"type": "array",
"description": "The main payload of the registry item. This is an array of files that are part of the registry item. Each file is an object with a path, content, type, and target.",
"items": {
"type": "object",
"properties": {
"path": {
"type": "string",
"description": "The path to the file relative to the registry root."
"type": "string"
},
"content": {
"type": "string",
"description": "The content of the file."
"type": "string"
},
"type": {
"type": "string",
@@ -79,12 +67,10 @@
"registry:theme",
"registry:page",
"registry:file"
],
"description": "The type of the file. This is used to determine the type of the file when resolved for a project."
]
},
"target": {
"type": "string",
"description": "The target path of the file. This is the path to the file in the project."
"type": "string"
}
},
"if": {
@@ -104,7 +90,6 @@
},
"tailwind": {
"type": "object",
"description": "The tailwind configuration for the registry item. This is an object with a config property. Use cssVars for Tailwind v4 projects.",
"properties": {
"config": {
"type": "object",
@@ -131,82 +116,33 @@
},
"cssVars": {
"type": "object",
"description": "The css variables for the registry item. This will be merged with the project's css variables.",
"properties": {
"theme": {
"type": "object",
"description": "CSS variables for the @theme directive. For Tailwind v4 projects only. Use tailwind for older projects.",
"additionalProperties": {
"type": "string"
}
},
"light": {
"type": "object",
"description": "CSS variables for the light theme.",
"additionalProperties": {
"type": "string"
}
},
"dark": {
"type": "object",
"description": "CSS variables for the dark theme.",
"additionalProperties": {
"type": "string"
}
}
}
},
"css": {
"type": "object",
"description": "CSS definitions to be added to the project's CSS file. Supports at-rules, selectors, nested rules, utilities, layers, and more.",
"additionalProperties": {
"oneOf": [
{
"type": "string",
"description": "Direct CSS string (e.g., 'font-family: sans-serif; line-height: 1.5;')"
},
{
"type": "object",
"description": "CSS properties or nested selectors",
"additionalProperties": {
"oneOf": [
{
"type": "string",
"description": "CSS property value (e.g., 'blue', 'var(--color-primary)')"
},
{
"type": "object",
"description": "Nested selector or rule with properties",
"additionalProperties": {
"type": "string",
"description": "CSS property value for nested rule"
}
}
]
}
}
]
}
},
"meta": {
"type": "object",
"description": "Additional metadata for the registry item. This is an object with any key value pairs.",
"additionalProperties": true
},
"docs": {
"type": "string",
"description": "The documentation for the registry item. This is a markdown string."
"type": "string"
},
"categories": {
"type": "array",
"items": {
"type": "string",
"description": "The categories of the registry item. This is an array of strings."
"type": "string"
}
},
"extends": {
"type": "string",
"description": "The name of the registry item to extend. This is used to extend the base shadcn/ui style. Set to none to start fresh. This is available for registry:style items only."
}
},
"required": ["name", "type"]

View File

@@ -1102,550 +1102,3 @@ export const baseColorsV4 = {
},
},
} as const
export const baseColorsOKLCH = {
zinc: {
light: {
background: "oklch(1 0 0)", // --color-zinc-50
foreground: "oklch(0.141 0.005 285.823)", // --color-zinc-950
card: "oklch(1 0 0)", // --color-zinc-50
"card-foreground": "oklch(0.141 0.005 285.823)", // --color-zinc-950
popover: "oklch(1 0 0)", // --color-zinc-50
"popover-foreground": "oklch(0.141 0.005 285.823)", // --color-zinc-950
primary: "oklch(0.21 0.006 285.885)", // --color-zinc-900
"primary-foreground": "oklch(0.985 0 0)", // --color-zinc-50
secondary: "oklch(0.967 0.001 286.375)", // --color-zinc-100
"secondary-foreground": "oklch(0.21 0.006 285.885)", // --color-zinc-900
muted: "oklch(0.967 0.001 286.375)", // --color-zinc-100
"muted-foreground": "oklch(0.552 0.016 285.938)", // --color-zinc-500
accent: "oklch(0.967 0.001 286.375)", // --color-zinc-100
"accent-foreground": "oklch(0.21 0.006 285.885)", // --color-zinc-900
destructive: "oklch(0.577 0.245 27.325)", // --color-red-600
border: "oklch(0.92 0.004 286.32)", // --color-zinc-200
input: "oklch(0.92 0.004 286.32)", // --color-zinc-200
ring: "oklch(0.705 0.015 286.067)", // --color-zinc-400
"chart-1": "oklch(0.646 0.222 41.116)", // --color-orange-600
"chart-2": "oklch(0.6 0.118 184.704)", // --color-teal-600
"chart-3": "oklch(0.398 0.07 227.392)", // --color-cyan-900
"chart-4": "oklch(0.828 0.189 84.429)", // --color-amber-400
"chart-5": "oklch(0.769 0.188 70.08)", // --color-amber-500
sidebar: "oklch(0.985 0 0)", // --color-zinc-50
"sidebar-foreground": "oklch(0.141 0.005 285.823)", // --color-zinc-950
"sidebar-primary": "oklch(0.21 0.006 285.885)", // --color-zinc-900
"sidebar-primary-foreground": "oklch(0.985 0 0)", // --color-zinc-50
"sidebar-accent": "oklch(0.967 0.001 286.375)", // --color-zinc-100
"sidebar-accent-foreground": "oklch(0.21 0.006 285.885)", // --color-zinc-900
"sidebar-border": "oklch(0.92 0.004 286.32)", // --color-zinc-200
"sidebar-ring": "oklch(0.705 0.015 286.067)", // --color-zinc-400
},
dark: {
background: "oklch(0.141 0.005 285.823)", // --color-zinc-950
foreground: "oklch(0.985 0 0)", // --color-zinc-50
card: "oklch(0.21 0.006 285.885)", // --color-zinc-900
"card-foreground": "oklch(0.985 0 0)", // --color-zinc-50
popover: "oklch(0.21 0.006 285.885)", // --color-zinc-900
"popover-foreground": "oklch(0.985 0 0)", // --color-zinc-50
primary: "oklch(0.92 0.004 286.32)", // --color-zinc-200
"primary-foreground": "oklch(0.21 0.006 285.885)", // --color-zinc-900
secondary: "oklch(0.274 0.006 286.033)", // --color-zinc-800
"secondary-foreground": "oklch(0.985 0 0)", // --color-zinc-50
muted: "oklch(0.274 0.006 286.033)", // --color-zinc-800
"muted-foreground": "oklch(0.705 0.015 286.067)", // --color-zinc-400
accent: "oklch(0.274 0.006 286.033)", // --color-zinc-800
"accent-foreground": "oklch(0.985 0 0)", // --color-zinc-50
destructive: "oklch(0.704 0.191 22.216)", // --color-red-400
border: "oklch(1 0 0 / 10%)", // --color-white
input: "oklch(1 0 0 / 15%)", // --color-white
ring: "oklch(0.552 0.016 285.938)", // --color-zinc-500
"chart-1": "oklch(0.488 0.243 264.376)", // --color-blue-700
"chart-2": "oklch(0.696 0.17 162.48)", // --color-emerald-500
"chart-3": "oklch(0.769 0.188 70.08)", // --color-amber-500
"chart-4": "oklch(0.627 0.265 303.9)", // --color-purple-500
"chart-5": "oklch(0.645 0.246 16.439)", // --color-rose-500
sidebar: "oklch(0.21 0.006 285.885)", // --color-zinc-900
"sidebar-foreground": "oklch(0.985 0 0)", // --color-zinc-50
"sidebar-primary": "oklch(0.488 0.243 264.376)", // --color-blue-700
"sidebar-primary-foreground": "oklch(0.985 0 0)", // --color-zinc-50
"sidebar-accent": "oklch(0.274 0.006 286.033)", // --color-zinc-800
"sidebar-accent-foreground": "oklch(0.985 0 0)", // --color-zinc-50
"sidebar-border": "oklch(1 0 0 / 10%)", // --color-white
"sidebar-ring": "oklch(0.552 0.016 285.938)", // --color-zinc-500
},
},
red: {
light: {
background: "oklch(1 0 0)", // --color-zinc-50 (from zinc)
foreground: "oklch(0.141 0.005 285.823)", // --color-zinc-950 (from zinc)
card: "oklch(1 0 0)", // --color-zinc-50 (from zinc)
"card-foreground": "oklch(0.141 0.005 285.823)", // --color-zinc-950 (from zinc)
popover: "oklch(1 0 0)", // --color-zinc-50 (from zinc)
"popover-foreground": "oklch(0.141 0.005 285.823)", // --color-zinc-950 (from zinc)
primary: "oklch(0.637 0.237 25.331)", // --color-red-500 (approx HSL 0 72.2% 50.6%)
"primary-foreground": "oklch(0.971 0.013 17.38)", // --color-red-50 (approx HSL 0 85.7% 97.3%)
secondary: "oklch(0.967 0.001 286.375)", // --color-zinc-100 (from zinc)
"secondary-foreground": "oklch(0.21 0.006 285.885)", // --color-zinc-900 (from zinc)
muted: "oklch(0.967 0.001 286.375)", // --color-zinc-100 (from zinc)
"muted-foreground": "oklch(0.552 0.016 285.938)", // --color-zinc-500 (from zinc)
accent: "oklch(0.967 0.001 286.375)", // --color-zinc-100 (from zinc)
"accent-foreground": "oklch(0.21 0.006 285.885)", // --color-zinc-900 (from zinc)
destructive: "oklch(0.577 0.245 27.325)", // --color-red-600 (from zinc)
border: "oklch(0.92 0.004 286.32)", // --color-zinc-200 (from zinc)
input: "oklch(0.92 0.004 286.32)", // --color-zinc-200 (from zinc)
ring: "oklch(0.637 0.237 25.331)", // --color-red-500 (approx HSL 0 72.2% 50.6%)
"chart-1": "oklch(0.646 0.222 41.116)", // --color-orange-600 (from zinc)
"chart-2": "oklch(0.6 0.118 184.704)", // --color-teal-600 (from zinc)
"chart-3": "oklch(0.398 0.07 227.392)", // --color-cyan-900 (from zinc)
"chart-4": "oklch(0.828 0.189 84.429)", // --color-amber-400 (from zinc)
"chart-5": "oklch(0.769 0.188 70.08)", // --color-amber-500 (from zinc)
sidebar: "oklch(0.985 0 0)", // --color-zinc-50 (from zinc)
"sidebar-foreground": "oklch(0.141 0.005 285.823)", // --color-zinc-950 (from zinc)
"sidebar-primary": "oklch(0.637 0.237 25.331)", // --color-red-500 (approx HSL 0 72.2% 50.6%)
"sidebar-primary-foreground": "oklch(0.971 0.013 17.38)", // --color-red-50 (approx HSL 0 85.7% 97.3%)
"sidebar-accent": "oklch(0.967 0.001 286.375)", // --color-zinc-100 (from zinc)
"sidebar-accent-foreground": "oklch(0.21 0.006 285.885)", // --color-zinc-900 (from zinc)
"sidebar-border": "oklch(0.92 0.004 286.32)", // --color-zinc-200 (from zinc)
"sidebar-ring": "oklch(0.637 0.237 25.331)", // --color-red-500 (approx HSL 0 72.2% 50.6%)
},
dark: {
background: "oklch(0.141 0.005 285.823)", // --color-zinc-950 (from zinc)
foreground: "oklch(0.985 0 0)", // --color-zinc-50 (from zinc)
card: "oklch(0.21 0.006 285.885)", // --color-zinc-900 (from zinc)
"card-foreground": "oklch(0.985 0 0)", // --color-zinc-50 (from zinc)
popover: "oklch(0.21 0.006 285.885)", // --color-zinc-900 (from zinc)
"popover-foreground": "oklch(0.985 0 0)", // --color-zinc-50 (from zinc)
primary: "oklch(0.637 0.237 25.331)", // --color-red-500 (approx HSL 0 72.2% 50.6%)
"primary-foreground": "oklch(0.971 0.013 17.38)", // --color-red-50 (approx HSL 0 85.7% 97.3%)
secondary: "oklch(0.274 0.006 286.033)", // --color-zinc-800 (from zinc)
"secondary-foreground": "oklch(0.985 0 0)", // --color-zinc-50 (from zinc)
muted: "oklch(0.274 0.006 286.033)", // --color-zinc-800 (from zinc)
"muted-foreground": "oklch(0.705 0.015 286.067)", // --color-zinc-400 (from zinc)
accent: "oklch(0.274 0.006 286.033)", // --color-zinc-800 (from zinc)
"accent-foreground": "oklch(0.985 0 0)", // --color-zinc-50 (from zinc)
destructive: "oklch(0.704 0.191 22.216)", // --color-red-400 (from zinc)
border: "oklch(1 0 0 / 10%)", // --color-white (from zinc)
input: "oklch(1 0 0 / 15%)", // --color-white (from zinc)
ring: "oklch(0.637 0.237 25.331)", // --color-red-500 (approx HSL 0 72.2% 50.6%)
"chart-1": "oklch(0.488 0.243 264.376)", // --color-blue-700 (from zinc)
"chart-2": "oklch(0.696 0.17 162.48)", // --color-emerald-500 (from zinc)
"chart-3": "oklch(0.769 0.188 70.08)", // --color-amber-500 (from zinc)
"chart-4": "oklch(0.627 0.265 303.9)", // --color-purple-500 (from zinc)
"chart-5": "oklch(0.645 0.246 16.439)", // --color-rose-500 (from zinc)
sidebar: "oklch(0.21 0.006 285.885)", // --color-zinc-900 (from zinc)
"sidebar-foreground": "oklch(0.985 0 0)", // --color-zinc-50 (from zinc)
"sidebar-primary": "oklch(0.637 0.237 25.331)", // --color-red-500 (approx HSL 0 72.2% 50.6%)
"sidebar-primary-foreground": "oklch(0.971 0.013 17.38)", // --color-red-50 (approx HSL 0 85.7% 97.3%)
"sidebar-accent": "oklch(0.274 0.006 286.033)", // --color-zinc-800 (from zinc)
"sidebar-accent-foreground": "oklch(0.985 0 0)", // --color-zinc-50 (from zinc)
"sidebar-border": "oklch(1 0 0 / 10%)", // --color-white (from zinc)
"sidebar-ring": "oklch(0.637 0.237 25.331)", // --color-red-500 (approx HSL 0 72.2% 50.6%)
},
},
rose: {
light: {
background: "oklch(1 0 0)", // --color-zinc-50 (from zinc)
foreground: "oklch(0.141 0.005 285.823)", // --color-zinc-950 (from zinc)
card: "oklch(1 0 0)", // --color-zinc-50 (from zinc)
"card-foreground": "oklch(0.141 0.005 285.823)", // --color-zinc-950 (from zinc)
popover: "oklch(1 0 0)", // --color-zinc-50 (from zinc)
"popover-foreground": "oklch(0.141 0.005 285.823)", // --color-zinc-950 (from zinc)
primary: "oklch(0.645 0.246 16.439)", // --color-rose-500 (approx HSL 346.8 77.2% 49.8%)
"primary-foreground": "oklch(0.969 0.015 12.422)", // --color-rose-50 (approx HSL 355.7 100% 97.3%)
secondary: "oklch(0.967 0.001 286.375)", // --color-zinc-100 (from zinc)
"secondary-foreground": "oklch(0.21 0.006 285.885)", // --color-zinc-900 (from zinc)
muted: "oklch(0.967 0.001 286.375)", // --color-zinc-100 (from zinc)
"muted-foreground": "oklch(0.552 0.016 285.938)", // --color-zinc-500 (from zinc)
accent: "oklch(0.967 0.001 286.375)", // --color-zinc-100 (from zinc)
"accent-foreground": "oklch(0.21 0.006 285.885)", // --color-zinc-900 (from zinc)
destructive: "oklch(0.577 0.245 27.325)", // --color-red-600 (from zinc)
border: "oklch(0.92 0.004 286.32)", // --color-zinc-200 (from zinc)
input: "oklch(0.92 0.004 286.32)", // --color-zinc-200 (from zinc)
ring: "oklch(0.645 0.246 16.439)", // --color-rose-500 (approx HSL 346.8 77.2% 49.8%)
"chart-1": "oklch(0.646 0.222 41.116)", // --color-orange-600 (from zinc)
"chart-2": "oklch(0.6 0.118 184.704)", // --color-teal-600 (from zinc)
"chart-3": "oklch(0.398 0.07 227.392)", // --color-cyan-900 (from zinc)
"chart-4": "oklch(0.828 0.189 84.429)", // --color-amber-400 (from zinc)
"chart-5": "oklch(0.769 0.188 70.08)", // --color-amber-500 (from zinc)
sidebar: "oklch(0.985 0 0)", // --color-zinc-50 (from zinc)
"sidebar-foreground": "oklch(0.141 0.005 285.823)", // --color-zinc-950 (from zinc)
"sidebar-primary": "oklch(0.645 0.246 16.439)", // --color-rose-500 (approx HSL 346.8 77.2% 49.8%)
"sidebar-primary-foreground": "oklch(0.969 0.015 12.422)", // --color-rose-50 (approx HSL 355.7 100% 97.3%)
"sidebar-accent": "oklch(0.967 0.001 286.375)", // --color-zinc-100 (from zinc)
"sidebar-accent-foreground": "oklch(0.21 0.006 285.885)", // --color-zinc-900 (from zinc)
"sidebar-border": "oklch(0.92 0.004 286.32)", // --color-zinc-200 (from zinc)
"sidebar-ring": "oklch(0.645 0.246 16.439)", // --color-rose-500 (approx HSL 346.8 77.2% 49.8%)
},
dark: {
background: "oklch(0.141 0.005 285.823)", // --color-zinc-950 (from zinc)
foreground: "oklch(0.985 0 0)", // --color-zinc-50 (from zinc)
card: "oklch(0.21 0.006 285.885)", // --color-zinc-900 (from zinc)
"card-foreground": "oklch(0.985 0 0)", // --color-zinc-50 (from zinc)
popover: "oklch(0.21 0.006 285.885)", // --color-zinc-900 (from zinc)
"popover-foreground": "oklch(0.985 0 0)", // --color-zinc-50 (from zinc)
primary: "oklch(0.645 0.246 16.439)", // --color-rose-500 (approx HSL 346.8 77.2% 49.8%)
"primary-foreground": "oklch(0.969 0.015 12.422)", // --color-rose-50 (approx HSL 355.7 100% 97.3%)
secondary: "oklch(0.274 0.006 286.033)", // --color-zinc-800 (from zinc)
"secondary-foreground": "oklch(0.985 0 0)", // --color-zinc-50 (from zinc)
muted: "oklch(0.274 0.006 286.033)", // --color-zinc-800 (from zinc)
"muted-foreground": "oklch(0.705 0.015 286.067)", // --color-zinc-400 (from zinc)
accent: "oklch(0.274 0.006 286.033)", // --color-zinc-800 (from zinc)
"accent-foreground": "oklch(0.985 0 0)", // --color-zinc-50 (from zinc)
destructive: "oklch(0.704 0.191 22.216)", // --color-red-400 (from zinc)
border: "oklch(1 0 0 / 10%)", // --color-white (from zinc)
input: "oklch(1 0 0 / 15%)", // --color-white (from zinc)
ring: "oklch(0.645 0.246 16.439)", // --color-rose-500 (approx HSL 346.8 77.2% 49.8%)
"chart-1": "oklch(0.488 0.243 264.376)", // --color-blue-700 (from zinc)
"chart-2": "oklch(0.696 0.17 162.48)", // --color-emerald-500 (from zinc)
"chart-3": "oklch(0.769 0.188 70.08)", // --color-amber-500 (from zinc)
"chart-4": "oklch(0.627 0.265 303.9)", // --color-purple-500 (from zinc)
"chart-5": "oklch(0.645 0.246 16.439)", // --color-rose-500 (from zinc)
sidebar: "oklch(0.21 0.006 285.885)", // --color-zinc-900 (from zinc)
"sidebar-foreground": "oklch(0.985 0 0)", // --color-zinc-50 (from zinc)
"sidebar-primary": "oklch(0.645 0.246 16.439)", // --color-rose-500 (approx HSL 346.8 77.2% 49.8%)
"sidebar-primary-foreground": "oklch(0.969 0.015 12.422)", // --color-rose-50 (approx HSL 355.7 100% 97.3%)
"sidebar-accent": "oklch(0.274 0.006 286.033)", // --color-zinc-800 (from zinc)
"sidebar-accent-foreground": "oklch(0.985 0 0)", // --color-zinc-50 (from zinc)
"sidebar-border": "oklch(1 0 0 / 10%)", // --color-white (from zinc)
"sidebar-ring": "oklch(0.645 0.246 16.439)", // --color-rose-500 (approx HSL 346.8 77.2% 49.8%)
},
},
orange: {
light: {
background: "oklch(1 0 0)", // --color-zinc-50 (from zinc)
foreground: "oklch(0.141 0.005 285.823)", // --color-zinc-950 (from zinc)
card: "oklch(1 0 0)", // --color-zinc-50 (from zinc)
"card-foreground": "oklch(0.141 0.005 285.823)", // --color-zinc-950 (from zinc)
popover: "oklch(1 0 0)", // --color-zinc-50 (from zinc)
"popover-foreground": "oklch(0.141 0.005 285.823)", // --color-zinc-950 (from zinc)
primary: "oklch(0.705 0.213 47.604)", // --color-orange-500 (approx HSL 24.6 95% 53.1%)
"primary-foreground": "oklch(0.98 0.016 73.684)", // --color-orange-50 (approx HSL 60 9.1% 97.8%)
secondary: "oklch(0.967 0.001 286.375)", // --color-zinc-100 (from zinc)
"secondary-foreground": "oklch(0.21 0.006 285.885)", // --color-zinc-900 (from zinc)
muted: "oklch(0.967 0.001 286.375)", // --color-zinc-100 (from zinc)
"muted-foreground": "oklch(0.552 0.016 285.938)", // --color-zinc-500 (from zinc)
accent: "oklch(0.967 0.001 286.375)", // --color-zinc-100 (from zinc)
"accent-foreground": "oklch(0.21 0.006 285.885)", // --color-zinc-900 (from zinc)
destructive: "oklch(0.577 0.245 27.325)", // --color-red-600 (from zinc)
border: "oklch(0.92 0.004 286.32)", // --color-zinc-200 (from zinc)
input: "oklch(0.92 0.004 286.32)", // --color-zinc-200 (from zinc)
ring: "oklch(0.705 0.213 47.604)", // --color-orange-500 (approx HSL 24.6 95% 53.1%)
"chart-1": "oklch(0.646 0.222 41.116)", // --color-orange-600 (from zinc)
"chart-2": "oklch(0.6 0.118 184.704)", // --color-teal-600 (from zinc)
"chart-3": "oklch(0.398 0.07 227.392)", // --color-cyan-900 (from zinc)
"chart-4": "oklch(0.828 0.189 84.429)", // --color-amber-400 (from zinc)
"chart-5": "oklch(0.769 0.188 70.08)", // --color-amber-500 (from zinc)
sidebar: "oklch(0.985 0 0)", // --color-zinc-50 (from zinc)
"sidebar-foreground": "oklch(0.141 0.005 285.823)", // --color-zinc-950 (from zinc)
"sidebar-primary": "oklch(0.705 0.213 47.604)", // --color-orange-500 (approx HSL 24.6 95% 53.1%)
"sidebar-primary-foreground": "oklch(0.98 0.016 73.684)", // --color-orange-50 (approx HSL 60 9.1% 97.8%)
"sidebar-accent": "oklch(0.967 0.001 286.375)", // --color-zinc-100 (from zinc)
"sidebar-accent-foreground": "oklch(0.21 0.006 285.885)", // --color-zinc-900 (from zinc)
"sidebar-border": "oklch(0.92 0.004 286.32)", // --color-zinc-200 (from zinc)
"sidebar-ring": "oklch(0.705 0.213 47.604)", // --color-orange-500 (approx HSL 24.6 95% 53.1%)
},
dark: {
background: "oklch(0.141 0.005 285.823)", // --color-zinc-950 (from zinc)
foreground: "oklch(0.985 0 0)", // --color-zinc-50 (from zinc)
card: "oklch(0.21 0.006 285.885)", // --color-zinc-900 (from zinc)
"card-foreground": "oklch(0.985 0 0)", // --color-zinc-50 (from zinc)
popover: "oklch(0.21 0.006 285.885)", // --color-zinc-900 (from zinc)
"popover-foreground": "oklch(0.985 0 0)", // --color-zinc-50 (from zinc)
primary: "oklch(0.646 0.222 41.116)", // --color-orange-600 (approx HSL 20.5 90.2% 48.2%)
"primary-foreground": "oklch(0.98 0.016 73.684)", // --color-orange-50 (approx HSL 60 9.1% 97.8%)
secondary: "oklch(0.274 0.006 286.033)", // --color-zinc-800 (from zinc)
"secondary-foreground": "oklch(0.985 0 0)", // --color-zinc-50 (from zinc)
muted: "oklch(0.274 0.006 286.033)", // --color-zinc-800 (from zinc)
"muted-foreground": "oklch(0.705 0.015 286.067)", // --color-zinc-400 (from zinc)
accent: "oklch(0.274 0.006 286.033)", // --color-zinc-800 (from zinc)
"accent-foreground": "oklch(0.985 0 0)", // --color-zinc-50 (from zinc)
destructive: "oklch(0.704 0.191 22.216)", // --color-red-400 (from zinc)
border: "oklch(1 0 0 / 10%)", // --color-white (from zinc)
input: "oklch(1 0 0 / 15%)", // --color-white (from zinc)
ring: "oklch(0.646 0.222 41.116)", // --color-orange-600 (approx HSL 20.5 90.2% 48.2%)
"chart-1": "oklch(0.488 0.243 264.376)", // --color-blue-700 (from zinc)
"chart-2": "oklch(0.696 0.17 162.48)", // --color-emerald-500 (from zinc)
"chart-3": "oklch(0.769 0.188 70.08)", // --color-amber-500 (from zinc)
"chart-4": "oklch(0.627 0.265 303.9)", // --color-purple-500 (from zinc)
"chart-5": "oklch(0.645 0.246 16.439)", // --color-rose-500 (from zinc)
sidebar: "oklch(0.21 0.006 285.885)", // --color-zinc-900 (from zinc)
"sidebar-foreground": "oklch(0.985 0 0)", // --color-zinc-50 (from zinc)
"sidebar-primary": "oklch(0.646 0.222 41.116)", // --color-orange-600 (approx HSL 20.5 90.2% 48.2%)
"sidebar-primary-foreground": "oklch(0.98 0.016 73.684)", // --color-orange-50 (approx HSL 60 9.1% 97.8%)
"sidebar-accent": "oklch(0.274 0.006 286.033)", // --color-zinc-800 (from zinc)
"sidebar-accent-foreground": "oklch(0.985 0 0)", // --color-zinc-50 (from zinc)
"sidebar-border": "oklch(1 0 0 / 10%)", // --color-white (from zinc)
"sidebar-ring": "oklch(0.646 0.222 41.116)", // --color-orange-600 (approx HSL 20.5 90.2% 48.2%)
},
},
green: {
light: {
background: "oklch(1 0 0)", // --color-zinc-50 (from zinc)
foreground: "oklch(0.141 0.005 285.823)", // --color-zinc-950 (from zinc)
card: "oklch(1 0 0)", // --color-zinc-50 (from zinc)
"card-foreground": "oklch(0.141 0.005 285.823)", // --color-zinc-950 (from zinc)
popover: "oklch(1 0 0)", // --color-zinc-50 (from zinc)
"popover-foreground": "oklch(0.141 0.005 285.823)", // --color-zinc-950 (from zinc)
primary: "oklch(0.723 0.219 149.579)", // --color-green-500 (approx HSL 142.1 76.2% 36.3%)
"primary-foreground": "oklch(0.982 0.018 155.826)", // --color-green-50 (approx HSL 355.7 100% 97.3%)
secondary: "oklch(0.967 0.001 286.375)", // --color-zinc-100 (from zinc)
"secondary-foreground": "oklch(0.21 0.006 285.885)", // --color-zinc-900 (from zinc)
muted: "oklch(0.967 0.001 286.375)", // --color-zinc-100 (from zinc)
"muted-foreground": "oklch(0.552 0.016 285.938)", // --color-zinc-500 (from zinc)
accent: "oklch(0.967 0.001 286.375)", // --color-zinc-100 (from zinc)
"accent-foreground": "oklch(0.21 0.006 285.885)", // --color-zinc-900 (from zinc)
destructive: "oklch(0.577 0.245 27.325)", // --color-red-600 (from zinc)
border: "oklch(0.92 0.004 286.32)", // --color-zinc-200 (from zinc)
input: "oklch(0.92 0.004 286.32)", // --color-zinc-200 (from zinc)
ring: "oklch(0.723 0.219 149.579)", // --color-green-500 (approx HSL 142.1 76.2% 36.3%)
"chart-1": "oklch(0.646 0.222 41.116)", // --color-orange-600 (from zinc)
"chart-2": "oklch(0.6 0.118 184.704)", // --color-teal-600 (from zinc)
"chart-3": "oklch(0.398 0.07 227.392)", // --color-cyan-900 (from zinc)
"chart-4": "oklch(0.828 0.189 84.429)", // --color-amber-400 (from zinc)
"chart-5": "oklch(0.769 0.188 70.08)", // --color-amber-500 (from zinc)
sidebar: "oklch(0.985 0 0)", // --color-zinc-50 (from zinc)
"sidebar-foreground": "oklch(0.141 0.005 285.823)", // --color-zinc-950 (from zinc)
"sidebar-primary": "oklch(0.723 0.219 149.579)", // --color-green-500 (approx HSL 142.1 76.2% 36.3%)
"sidebar-primary-foreground": "oklch(0.982 0.018 155.826)", // --color-green-50 (approx HSL 355.7 100% 97.3%)
"sidebar-accent": "oklch(0.967 0.001 286.375)", // --color-zinc-100 (from zinc)
"sidebar-accent-foreground": "oklch(0.21 0.006 285.885)", // --color-zinc-900 (from zinc)
"sidebar-border": "oklch(0.92 0.004 286.32)", // --color-zinc-200 (from zinc)
"sidebar-ring": "oklch(0.723 0.219 149.579)", // --color-green-500 (approx HSL 142.1 76.2% 36.3%)
},
dark: {
background: "oklch(0.141 0.005 285.823)", // --color-zinc-950 (from zinc)
foreground: "oklch(0.985 0 0)", // --color-zinc-50 (from zinc)
card: "oklch(0.21 0.006 285.885)", // --color-zinc-900 (from zinc)
"card-foreground": "oklch(0.985 0 0)", // --color-zinc-50 (from zinc)
popover: "oklch(0.21 0.006 285.885)", // --color-zinc-900 (from zinc)
"popover-foreground": "oklch(0.985 0 0)", // --color-zinc-50 (from zinc)
primary: "oklch(0.696 0.17 162.48)", // --color-emerald-500 (approx HSL 142.1 70.6% 45.3%)
"primary-foreground": "oklch(0.393 0.095 152.535)", // --color-green-900 (approx HSL 144.9 80.4% 10%)
secondary: "oklch(0.274 0.006 286.033)", // --color-zinc-800 (from zinc)
"secondary-foreground": "oklch(0.985 0 0)", // --color-zinc-50 (from zinc)
muted: "oklch(0.274 0.006 286.033)", // --color-zinc-800 (from zinc)
"muted-foreground": "oklch(0.705 0.015 286.067)", // --color-zinc-400 (from zinc)
accent: "oklch(0.274 0.006 286.033)", // --color-zinc-800 (from zinc)
"accent-foreground": "oklch(0.985 0 0)", // --color-zinc-50 (from zinc)
destructive: "oklch(0.704 0.191 22.216)", // --color-red-400 (from zinc)
border: "oklch(1 0 0 / 10%)", // --color-white (from zinc)
input: "oklch(1 0 0 / 15%)", // --color-white (from zinc)
ring: "oklch(0.527 0.154 150.069)", // --color-green-700 (approx HSL 142.4 71.8% 29.2%)
"chart-1": "oklch(0.488 0.243 264.376)", // --color-blue-700 (from zinc)
"chart-2": "oklch(0.696 0.17 162.48)", // --color-emerald-500 (from zinc)
"chart-3": "oklch(0.769 0.188 70.08)", // --color-amber-500 (from zinc)
"chart-4": "oklch(0.627 0.265 303.9)", // --color-purple-500 (from zinc)
"chart-5": "oklch(0.645 0.246 16.439)", // --color-rose-500 (from zinc)
sidebar: "oklch(0.21 0.006 285.885)", // --color-zinc-900 (from zinc)
"sidebar-foreground": "oklch(0.985 0 0)", // --color-zinc-50 (from zinc)
"sidebar-primary": "oklch(0.696 0.17 162.48)", // --color-emerald-500 (approx HSL 142.1 70.6% 45.3%)
"sidebar-primary-foreground": "oklch(0.393 0.095 152.535)", // --color-green-900 (approx HSL 144.9 80.4% 10%)
"sidebar-accent": "oklch(0.274 0.006 286.033)", // --color-zinc-800 (from zinc)
"sidebar-accent-foreground": "oklch(0.985 0 0)", // --color-zinc-50 (from zinc)
"sidebar-border": "oklch(1 0 0 / 10%)", // --color-white (from zinc)
"sidebar-ring": "oklch(0.527 0.154 150.069)", // --color-green-700 (approx HSL 142.4 71.8% 29.2%)
},
},
blue: {
light: {
background: "oklch(1 0 0)", // --color-zinc-50 (from zinc)
foreground: "oklch(0.141 0.005 285.823)", // --color-zinc-950 (from zinc)
card: "oklch(1 0 0)", // --color-zinc-50 (from zinc)
"card-foreground": "oklch(0.141 0.005 285.823)", // --color-zinc-950 (from zinc)
popover: "oklch(1 0 0)", // --color-zinc-50 (from zinc)
"popover-foreground": "oklch(0.141 0.005 285.823)", // --color-zinc-950 (from zinc)
primary: "oklch(0.623 0.214 259.815)", // --color-blue-500 (approx HSL 221.2 83.2% 53.3%)
"primary-foreground": "oklch(0.97 0.014 254.604)", // --color-blue-50 (approx HSL 210 40% 98%)
secondary: "oklch(0.967 0.001 286.375)", // --color-zinc-100 (from zinc)
"secondary-foreground": "oklch(0.21 0.006 285.885)", // --color-zinc-900 (from zinc)
muted: "oklch(0.967 0.001 286.375)", // --color-zinc-100 (from zinc)
"muted-foreground": "oklch(0.552 0.016 285.938)", // --color-zinc-500 (from zinc)
accent: "oklch(0.967 0.001 286.375)", // --color-zinc-100 (from zinc)
"accent-foreground": "oklch(0.21 0.006 285.885)", // --color-zinc-900 (from zinc)
destructive: "oklch(0.577 0.245 27.325)", // --color-red-600 (from zinc)
border: "oklch(0.92 0.004 286.32)", // --color-zinc-200 (from zinc)
input: "oklch(0.92 0.004 286.32)", // --color-zinc-200 (from zinc)
ring: "oklch(0.623 0.214 259.815)", // --color-blue-500 (approx HSL 221.2 83.2% 53.3%)
"chart-1": "oklch(0.646 0.222 41.116)", // --color-orange-600 (from zinc)
"chart-2": "oklch(0.6 0.118 184.704)", // --color-teal-600 (from zinc)
"chart-3": "oklch(0.398 0.07 227.392)", // --color-cyan-900 (from zinc)
"chart-4": "oklch(0.828 0.189 84.429)", // --color-amber-400 (from zinc)
"chart-5": "oklch(0.769 0.188 70.08)", // --color-amber-500 (from zinc)
sidebar: "oklch(0.985 0 0)", // --color-zinc-50 (from zinc)
"sidebar-foreground": "oklch(0.141 0.005 285.823)", // --color-zinc-950 (from zinc)
"sidebar-primary": "oklch(0.623 0.214 259.815)", // --color-blue-500 (approx HSL 221.2 83.2% 53.3%)
"sidebar-primary-foreground": "oklch(0.97 0.014 254.604)", // --color-blue-50 (approx HSL 210 40% 98%)
"sidebar-accent": "oklch(0.967 0.001 286.375)", // --color-zinc-100 (from zinc)
"sidebar-accent-foreground": "oklch(0.21 0.006 285.885)", // --color-zinc-900 (from zinc)
"sidebar-border": "oklch(0.92 0.004 286.32)", // --color-zinc-200 (from zinc)
"sidebar-ring": "oklch(0.623 0.214 259.815)", // --color-blue-500 (approx HSL 221.2 83.2% 53.3%)
},
dark: {
background: "oklch(0.141 0.005 285.823)", // --color-zinc-950 (from zinc)
foreground: "oklch(0.985 0 0)", // --color-zinc-50 (from zinc)
card: "oklch(0.21 0.006 285.885)", // --color-zinc-900 (from zinc)
"card-foreground": "oklch(0.985 0 0)", // --color-zinc-50 (from zinc)
popover: "oklch(0.21 0.006 285.885)", // --color-zinc-900 (from zinc)
"popover-foreground": "oklch(0.985 0 0)", // --color-zinc-50 (from zinc)
primary: "oklch(0.546 0.245 262.881)", // --color-blue-600 (approx HSL 217.2 91.2% 59.8%)
"primary-foreground": "oklch(0.379 0.146 265.522)", // --color-blue-900 (approx HSL 222.2 47.4% 11.2%)
secondary: "oklch(0.274 0.006 286.033)", // --color-zinc-800 (from zinc)
"secondary-foreground": "oklch(0.985 0 0)", // --color-zinc-50 (from zinc)
muted: "oklch(0.274 0.006 286.033)", // --color-zinc-800 (from zinc)
"muted-foreground": "oklch(0.705 0.015 286.067)", // --color-zinc-400 (from zinc)
accent: "oklch(0.274 0.006 286.033)", // --color-zinc-800 (from zinc)
"accent-foreground": "oklch(0.985 0 0)", // --color-zinc-50 (from zinc)
destructive: "oklch(0.704 0.191 22.216)", // --color-red-400 (from zinc)
border: "oklch(1 0 0 / 10%)", // --color-white (from zinc)
input: "oklch(1 0 0 / 15%)", // --color-white (from zinc)
ring: "oklch(0.488 0.243 264.376)", // --color-blue-700 (approx HSL 224.3 76.3% 48%)
"chart-1": "oklch(0.488 0.243 264.376)", // --color-blue-700 (from zinc)
"chart-2": "oklch(0.696 0.17 162.48)", // --color-emerald-500 (from zinc)
"chart-3": "oklch(0.769 0.188 70.08)", // --color-amber-500 (from zinc)
"chart-4": "oklch(0.627 0.265 303.9)", // --color-purple-500 (from zinc)
"chart-5": "oklch(0.645 0.246 16.439)", // --color-rose-500 (from zinc)
sidebar: "oklch(0.21 0.006 285.885)", // --color-zinc-900 (from zinc)
"sidebar-foreground": "oklch(0.985 0 0)", // --color-zinc-50 (from zinc)
"sidebar-primary": "oklch(0.546 0.245 262.881)", // --color-blue-600 (approx HSL 217.2 91.2% 59.8%)
"sidebar-primary-foreground": "oklch(0.379 0.146 265.522)", // --color-blue-900 (approx HSL 222.2 47.4% 11.2%)
"sidebar-accent": "oklch(0.274 0.006 286.033)", // --color-zinc-800 (from zinc)
"sidebar-accent-foreground": "oklch(0.985 0 0)", // --color-zinc-50 (from zinc)
"sidebar-border": "oklch(1 0 0 / 10%)", // --color-white (from zinc)
"sidebar-ring": "oklch(0.488 0.243 264.376)", // --color-blue-700 (approx HSL 224.3 76.3% 48%)
},
},
yellow: {
light: {
background: "oklch(1 0 0)", // --color-zinc-50 (from zinc)
foreground: "oklch(0.141 0.005 285.823)", // --color-zinc-950 (from zinc)
card: "oklch(1 0 0)", // --color-zinc-50 (from zinc)
"card-foreground": "oklch(0.141 0.005 285.823)", // --color-zinc-950 (from zinc)
popover: "oklch(1 0 0)", // --color-zinc-50 (from zinc)
"popover-foreground": "oklch(0.141 0.005 285.823)", // --color-zinc-950 (from zinc)
primary: "oklch(0.795 0.184 86.047)", // --color-yellow-500 (approx HSL 47.9 95.8% 53.1%)
"primary-foreground": "oklch(0.421 0.095 57.708)", // --color-yellow-900 (approx HSL 26 83.3% 14.1%)
secondary: "oklch(0.967 0.001 286.375)", // --color-zinc-100 (from zinc)
"secondary-foreground": "oklch(0.21 0.006 285.885)", // --color-zinc-900 (from zinc)
muted: "oklch(0.967 0.001 286.375)", // --color-zinc-100 (from zinc)
"muted-foreground": "oklch(0.552 0.016 285.938)", // --color-zinc-500 (from zinc)
accent: "oklch(0.967 0.001 286.375)", // --color-zinc-100 (from zinc)
"accent-foreground": "oklch(0.21 0.006 285.885)", // --color-zinc-900 (from zinc)
destructive: "oklch(0.577 0.245 27.325)", // --color-red-600 (from zinc)
border: "oklch(0.92 0.004 286.32)", // --color-zinc-200 (from zinc)
input: "oklch(0.92 0.004 286.32)", // --color-zinc-200 (from zinc)
ring: "oklch(0.795 0.184 86.047)", // --color-yellow-500 (approx HSL 47.9 95.8% 53.1%)
"chart-1": "oklch(0.646 0.222 41.116)", // --color-orange-600 (from zinc)
"chart-2": "oklch(0.6 0.118 184.704)", // --color-teal-600 (from zinc)
"chart-3": "oklch(0.398 0.07 227.392)", // --color-cyan-900 (from zinc)
"chart-4": "oklch(0.828 0.189 84.429)", // --color-amber-400 (from zinc)
"chart-5": "oklch(0.769 0.188 70.08)", // --color-amber-500 (from zinc)
sidebar: "oklch(0.985 0 0)", // --color-zinc-50 (from zinc)
"sidebar-foreground": "oklch(0.141 0.005 285.823)", // --color-zinc-950 (from zinc)
"sidebar-primary": "oklch(0.795 0.184 86.047)", // --color-yellow-500 (approx HSL 47.9 95.8% 53.1%)
"sidebar-primary-foreground": "oklch(0.421 0.095 57.708)", // --color-yellow-900 (approx HSL 26 83.3% 14.1%)
"sidebar-accent": "oklch(0.967 0.001 286.375)", // --color-zinc-100 (from zinc)
"sidebar-accent-foreground": "oklch(0.21 0.006 285.885)", // --color-zinc-900 (from zinc)
"sidebar-border": "oklch(0.92 0.004 286.32)", // --color-zinc-200 (from zinc)
"sidebar-ring": "oklch(0.795 0.184 86.047)", // --color-yellow-500 (approx HSL 47.9 95.8% 53.1%)
},
dark: {
background: "oklch(0.141 0.005 285.823)", // --color-zinc-950 (from zinc)
foreground: "oklch(0.985 0 0)", // --color-zinc-50 (from zinc)
card: "oklch(0.21 0.006 285.885)", // --color-zinc-900 (from zinc)
"card-foreground": "oklch(0.985 0 0)", // --color-zinc-50 (from zinc)
popover: "oklch(0.21 0.006 285.885)", // --color-zinc-900 (from zinc)
"popover-foreground": "oklch(0.985 0 0)", // --color-zinc-50 (from zinc)
primary: "oklch(0.795 0.184 86.047)", // --color-yellow-500 (approx HSL 47.9 95.8% 53.1%)
"primary-foreground": "oklch(0.421 0.095 57.708)", // --color-yellow-900 (approx HSL 26 83.3% 14.1%)
secondary: "oklch(0.274 0.006 286.033)", // --color-zinc-800 (from zinc)
"secondary-foreground": "oklch(0.985 0 0)", // --color-zinc-50 (from zinc)
muted: "oklch(0.274 0.006 286.033)", // --color-zinc-800 (from zinc)
"muted-foreground": "oklch(0.705 0.015 286.067)", // --color-zinc-400 (from zinc)
accent: "oklch(0.274 0.006 286.033)", // --color-zinc-800 (from zinc)
"accent-foreground": "oklch(0.985 0 0)", // --color-zinc-50 (from zinc)
destructive: "oklch(0.704 0.191 22.216)", // --color-red-400 (from zinc)
border: "oklch(1 0 0 / 10%)", // --color-white (from zinc)
input: "oklch(1 0 0 / 15%)", // --color-white (from zinc)
ring: "oklch(0.554 0.135 66.442)", // --color-yellow-700 (approx HSL 35.5 91.7% 32.9%)
"chart-1": "oklch(0.488 0.243 264.376)", // --color-blue-700 (from zinc)
"chart-2": "oklch(0.696 0.17 162.48)", // --color-emerald-500 (from zinc)
"chart-3": "oklch(0.769 0.188 70.08)", // --color-amber-500 (from zinc)
"chart-4": "oklch(0.627 0.265 303.9)", // --color-purple-500 (from zinc)
"chart-5": "oklch(0.645 0.246 16.439)", // --color-rose-500 (from zinc)
sidebar: "oklch(0.21 0.006 285.885)", // --color-zinc-900 (from zinc)
"sidebar-foreground": "oklch(0.985 0 0)", // --color-zinc-50 (from zinc)
"sidebar-primary": "oklch(0.795 0.184 86.047)", // --color-yellow-500 (approx HSL 47.9 95.8% 53.1%)
"sidebar-primary-foreground": "oklch(0.421 0.095 57.708)", // --color-yellow-900 (approx HSL 26 83.3% 14.1%)
"sidebar-accent": "oklch(0.274 0.006 286.033)", // --color-zinc-800 (from zinc)
"sidebar-accent-foreground": "oklch(0.985 0 0)", // --color-zinc-50 (from zinc)
"sidebar-border": "oklch(1 0 0 / 10%)", // --color-white (from zinc)
"sidebar-ring": "oklch(0.554 0.135 66.442)", // --color-yellow-700 (approx HSL 35.5 91.7% 32.9%)
},
},
violet: {
light: {
background: "oklch(1 0 0)", // --color-zinc-50 (from zinc)
foreground: "oklch(0.141 0.005 285.823)", // --color-zinc-950 (from zinc)
card: "oklch(1 0 0)", // --color-zinc-50 (from zinc)
"card-foreground": "oklch(0.141 0.005 285.823)", // --color-zinc-950 (from zinc)
popover: "oklch(1 0 0)", // --color-zinc-50 (from zinc)
"popover-foreground": "oklch(0.141 0.005 285.823)", // --color-zinc-950 (from zinc)
primary: "oklch(0.606 0.25 292.717)", // --color-violet-500 (approx HSL 262.1 83.3% 57.8%)
"primary-foreground": "oklch(0.969 0.016 293.756)", // --color-violet-50 (approx HSL 210 20% 98%)
secondary: "oklch(0.967 0.001 286.375)", // --color-zinc-100 (from zinc)
"secondary-foreground": "oklch(0.21 0.006 285.885)", // --color-zinc-900 (from zinc)
muted: "oklch(0.967 0.001 286.375)", // --color-zinc-100 (from zinc)
"muted-foreground": "oklch(0.552 0.016 285.938)", // --color-zinc-500 (from zinc)
accent: "oklch(0.967 0.001 286.375)", // --color-zinc-100 (from zinc)
"accent-foreground": "oklch(0.21 0.006 285.885)", // --color-zinc-900 (from zinc)
destructive: "oklch(0.577 0.245 27.325)", // --color-red-600 (from zinc)
border: "oklch(0.92 0.004 286.32)", // --color-zinc-200 (from zinc)
input: "oklch(0.92 0.004 286.32)", // --color-zinc-200 (from zinc)
ring: "oklch(0.606 0.25 292.717)", // --color-violet-500 (approx HSL 262.1 83.3% 57.8%)
"chart-1": "oklch(0.646 0.222 41.116)", // --color-orange-600 (from zinc)
"chart-2": "oklch(0.6 0.118 184.704)", // --color-teal-600 (from zinc)
"chart-3": "oklch(0.398 0.07 227.392)", // --color-cyan-900 (from zinc)
"chart-4": "oklch(0.828 0.189 84.429)", // --color-amber-400 (from zinc)
"chart-5": "oklch(0.769 0.188 70.08)", // --color-amber-500 (from zinc)
sidebar: "oklch(0.985 0 0)", // --color-zinc-50 (from zinc)
"sidebar-foreground": "oklch(0.141 0.005 285.823)", // --color-zinc-950 (from zinc)
"sidebar-primary": "oklch(0.606 0.25 292.717)", // --color-violet-500 (approx HSL 262.1 83.3% 57.8%)
"sidebar-primary-foreground": "oklch(0.969 0.016 293.756)", // --color-violet-50 (approx HSL 210 20% 98%)
"sidebar-accent": "oklch(0.967 0.001 286.375)", // --color-zinc-100 (from zinc)
"sidebar-accent-foreground": "oklch(0.21 0.006 285.885)", // --color-zinc-900 (from zinc)
"sidebar-border": "oklch(0.92 0.004 286.32)", // --color-zinc-200 (from zinc)
"sidebar-ring": "oklch(0.606 0.25 292.717)", // --color-violet-500 (approx HSL 262.1 83.3% 57.8%)
},
dark: {
background: "oklch(0.141 0.005 285.823)", // --color-zinc-950 (from zinc)
foreground: "oklch(0.985 0 0)", // --color-zinc-50 (from zinc)
card: "oklch(0.21 0.006 285.885)", // --color-zinc-900 (from zinc)
"card-foreground": "oklch(0.985 0 0)", // --color-zinc-50 (from zinc)
popover: "oklch(0.21 0.006 285.885)", // --color-zinc-900 (from zinc)
"popover-foreground": "oklch(0.985 0 0)", // --color-zinc-50 (from zinc)
primary: "oklch(0.541 0.281 293.009)", // --color-violet-600 (approx HSL 263.4 70% 50.4%)
"primary-foreground": "oklch(0.969 0.016 293.756)", // --color-violet-50 (approx HSL 210 20% 98%)
secondary: "oklch(0.274 0.006 286.033)", // --color-zinc-800 (from zinc)
"secondary-foreground": "oklch(0.985 0 0)", // --color-zinc-50 (from zinc)
muted: "oklch(0.274 0.006 286.033)", // --color-zinc-800 (from zinc)
"muted-foreground": "oklch(0.705 0.015 286.067)", // --color-zinc-400 (from zinc)
accent: "oklch(0.274 0.006 286.033)", // --color-zinc-800 (from zinc)
"accent-foreground": "oklch(0.985 0 0)", // --color-zinc-50 (from zinc)
destructive: "oklch(0.704 0.191 22.216)", // --color-red-400 (from zinc)
border: "oklch(1 0 0 / 10%)", // --color-white (from zinc)
input: "oklch(1 0 0 / 15%)", // --color-white (from zinc)
ring: "oklch(0.541 0.281 293.009)", // --color-violet-600 (approx HSL 263.4 70% 50.4%)
"chart-1": "oklch(0.488 0.243 264.376)", // --color-blue-700 (from zinc)
"chart-2": "oklch(0.696 0.17 162.48)", // --color-emerald-500 (from zinc)
"chart-3": "oklch(0.769 0.188 70.08)", // --color-amber-500 (from zinc)
"chart-4": "oklch(0.627 0.265 303.9)", // --color-purple-500 (from zinc)
"chart-5": "oklch(0.645 0.246 16.439)", // --color-rose-500 (from zinc)
sidebar: "oklch(0.21 0.006 285.885)", // --color-zinc-900 (from zinc)
"sidebar-foreground": "oklch(0.985 0 0)", // --color-zinc-50 (from zinc)
"sidebar-primary": "oklch(0.541 0.281 293.009)", // --color-violet-600 (approx HSL 263.4 70% 50.4%)
"sidebar-primary-foreground": "oklch(0.969 0.016 293.756)", // --color-violet-50 (approx HSL 210 20% 98%)
"sidebar-accent": "oklch(0.274 0.006 286.033)", // --color-zinc-800 (from zinc)
"sidebar-accent-foreground": "oklch(0.985 0 0)", // --color-zinc-50 (from zinc)
"sidebar-border": "oklch(1 0 0 / 10%)", // --color-white (from zinc)
"sidebar-ring": "oklch(0.541 0.281 293.009)", // --color-violet-600 (approx HSL 263.4 70% 50.4%)
},
},
}

View File

@@ -182,7 +182,7 @@ export const ui: Registry["items"] = [
{
name: "command",
type: "registry:ui",
dependencies: ["cmdk"],
dependencies: ["cmdk@1.0.0"],
registryDependencies: ["dialog"],
files: [
{

View File

@@ -75,9 +75,9 @@
"tailwindcss-animate": "^1.0.5",
"tsx": "^4.1.4",
"turbo": "^1.9.9",
"vite": "^5.4.15",
"vite": "^5.4.1",
"vite-tsconfig-paths": "^4.2.0",
"vitest": "^2.1.9"
"vitest": "^2.0.5"
},
"devDependencies": {
"@types/node": "^20.11.27",

View File

@@ -1,69 +1,5 @@
# @shadcn/ui
## 2.4.1
### Patch Changes
- [#7196](https://github.com/shadcn-ui/ui/pull/7196) [`617483fe9c26d607665fcaf79ee26e35d9825d7c`](https://github.com/shadcn-ui/ui/commit/617483fe9c26d607665fcaf79ee26e35d9825d7c) Thanks [@shadcn](https://github.com/shadcn)! - do not throw if empty dir
## 2.4.0
### Minor Changes
- [#6507](https://github.com/shadcn-ui/ui/pull/6507) [`5234c46722750f964d69c92ccbef2c4d260c211d`](https://github.com/shadcn-ui/ui/commit/5234c46722750f964d69c92ccbef2c4d260c211d) Thanks [@shadcn](https://github.com/shadcn)! - add support for TanStack Start
- [#6487](https://github.com/shadcn-ui/ui/pull/6487) [`5ef2bc5f455dfc394116267788c0514b696e13b0`](https://github.com/shadcn-ui/ui/commit/5ef2bc5f455dfc394116267788c0514b696e13b0) Thanks [@shadcn](https://github.com/shadcn)! - add theme vars support
- [#6478](https://github.com/shadcn-ui/ui/pull/6478) [`8f6a64f176defdb1f9c493598d952fb4e9844cd0`](https://github.com/shadcn-ui/ui/commit/8f6a64f176defdb1f9c493598d952fb4e9844cd0) Thanks [@shadcn](https://github.com/shadcn)! - add tailwind version detection
- [#6864](https://github.com/shadcn-ui/ui/pull/6864) [`19665adeeddc4ddb34e91fca219753d15bd46480`](https://github.com/shadcn-ui/ui/commit/19665adeeddc4ddb34e91fca219753d15bd46480) Thanks [@shadcn](https://github.com/shadcn)! - add --base-color flag
- [#6490](https://github.com/shadcn-ui/ui/pull/6490) [`9a14c1d0925d3df2c8f57a3381d212cc3e54f4a6`](https://github.com/shadcn-ui/ui/commit/9a14c1d0925d3df2c8f57a3381d212cc3e54f4a6) Thanks [@shadcn](https://github.com/shadcn)! - add support for tailwind v4
- [#6707](https://github.com/shadcn-ui/ui/pull/6707) [`3db8a07b3f132d396d7fb2e50da96156efcb4138`](https://github.com/shadcn-ui/ui/commit/3db8a07b3f132d396d7fb2e50da96156efcb4138) Thanks [@shadcn](https://github.com/shadcn)! - default to css vars. add --no-css-variables
- [#6968](https://github.com/shadcn-ui/ui/pull/6968) [`205bfc637e093717908ebd2c591b215672950558`](https://github.com/shadcn-ui/ui/commit/205bfc637e093717908ebd2c591b215672950558) Thanks [@shadcn](https://github.com/shadcn)! - replace tailwindcss-animate with tw-animate-css
- [#6574](https://github.com/shadcn-ui/ui/pull/6574) [`1e357cb20d6024b2bc9766fb15f61cb989eb7024`](https://github.com/shadcn-ui/ui/commit/1e357cb20d6024b2bc9766fb15f61cb989eb7024) Thanks [@shadcn](https://github.com/shadcn)! - default for new-york for v4
- [#6515](https://github.com/shadcn-ui/ui/pull/6515) [`d1eb24e23a973646d78cf101fa1e0a22861ac9fd`](https://github.com/shadcn-ui/ui/commit/d1eb24e23a973646d78cf101fa1e0a22861ac9fd) Thanks [@shadcn](https://github.com/shadcn)! - fix handling of sidebar colors
- [#6693](https://github.com/shadcn-ui/ui/pull/6693) [`3740373f99e39943514a45f5808ecb5f17faf700`](https://github.com/shadcn-ui/ui/commit/3740373f99e39943514a45f5808ecb5f17faf700) Thanks [@shadcn](https://github.com/shadcn)! - add oklch base color
- [#6571](https://github.com/shadcn-ui/ui/pull/6571) [`c74a094f14a6e338124709547932dbb20c8d1324`](https://github.com/shadcn-ui/ui/commit/c74a094f14a6e338124709547932dbb20c8d1324) Thanks [@shadcn](https://github.com/shadcn)! - hotswap style for v4
- [#6576](https://github.com/shadcn-ui/ui/pull/6576) [`9f4d65fc8fe72f632706fafd4036f63fd9317780`](https://github.com/shadcn-ui/ui/commit/9f4d65fc8fe72f632706fafd4036f63fd9317780) Thanks [@shadcn](https://github.com/shadcn)! - add warning for deprecated components
- [#6811](https://github.com/shadcn-ui/ui/pull/6811) [`bc7df68620f242ce6aa640839c80ddc8afc7e091`](https://github.com/shadcn-ui/ui/commit/bc7df68620f242ce6aa640839c80ddc8afc7e091) Thanks [@shadcn](https://github.com/shadcn)! - add support for route install for react-router and laravel
- [#7016](https://github.com/shadcn-ui/ui/pull/7016) [`b3b2fe2755e0ec1271c41a2a61b1a6933af42bc6`](https://github.com/shadcn-ui/ui/commit/b3b2fe2755e0ec1271c41a2a61b1a6933af42bc6) Thanks [@shadcn](https://github.com/shadcn)! - add theme prop to registry-item schema
### Patch Changes
- [#6724](https://github.com/shadcn-ui/ui/pull/6724) [`a3fe5074c1375cbd92e1ccdaab38d6808bfec696`](https://github.com/shadcn-ui/ui/commit/a3fe5074c1375cbd92e1ccdaab38d6808bfec696) Thanks [@Kaikaikaifang](https://github.com/Kaikaikaifang)! - support for version detection in monorepo
- [#6414](https://github.com/shadcn-ui/ui/pull/6414) [`202131cd7bf8829b962ae4027545afbdfe79e688`](https://github.com/shadcn-ui/ui/commit/202131cd7bf8829b962ae4027545afbdfe79e688) Thanks [@palmithor](https://github.com/palmithor)! - upgrade @antfu/ni
- [#6965](https://github.com/shadcn-ui/ui/pull/6965) [`69fc8e23cc0631aac6b708ba0481509f1125d3d7`](https://github.com/shadcn-ui/ui/commit/69fc8e23cc0631aac6b708ba0481509f1125d3d7) Thanks [@jherr](https://github.com/jherr)! - allow silent mode with npm
- [#6814](https://github.com/shadcn-ui/ui/pull/6814) [`8539dd6eec948e7a6218c7ca3372d2b1f349d7c0`](https://github.com/shadcn-ui/ui/commit/8539dd6eec948e7a6218c7ca3372d2b1f349d7c0) Thanks [@shadcn](https://github.com/shadcn)! - do not add ring for v3
- [#6732](https://github.com/shadcn-ui/ui/pull/6732) [`839afa714f61e2c0f83e9417354ea6ba8246c177`](https://github.com/shadcn-ui/ui/commit/839afa714f61e2c0f83e9417354ea6ba8246c177) Thanks [@shadcn](https://github.com/shadcn)! - cache registry calls
- [#6863](https://github.com/shadcn-ui/ui/pull/6863) [`c16c58d0f9e672edddd554269fdd0eb0d412cb9d`](https://github.com/shadcn-ui/ui/commit/c16c58d0f9e672edddd554269fdd0eb0d412cb9d) Thanks [@shadcn](https://github.com/shadcn)! - add --template flag
- [#6721](https://github.com/shadcn-ui/ui/pull/6721) [`a5122f9029c91963f493e7348ef7681dad4834e5`](https://github.com/shadcn-ui/ui/commit/a5122f9029c91963f493e7348ef7681dad4834e5) Thanks [@shadcn](https://github.com/shadcn)! - do not overwrite user defined vars
- [#6530](https://github.com/shadcn-ui/ui/pull/6530) [`d6159023ed0817adf14b4398874b1f5f05a73b02`](https://github.com/shadcn-ui/ui/commit/d6159023ed0817adf14b4398874b1f5f05a73b02) Thanks [@zwarunek](https://github.com/zwarunek)! - fix cn import bug in monorepo
- [#6617](https://github.com/shadcn-ui/ui/pull/6617) [`bd8533bd265de7765831d398f4db687483a0e53a`](https://github.com/shadcn-ui/ui/commit/bd8533bd265de7765831d398f4db687483a0e53a) Thanks [@shadcn](https://github.com/shadcn)! - filter out deprecated from --all
- [#6733](https://github.com/shadcn-ui/ui/pull/6733) [`779517a1d46f567c8e3fa8fcdea4c75c65ad4eb4`](https://github.com/shadcn-ui/ui/commit/779517a1d46f567c8e3fa8fcdea4c75c65ad4eb4) Thanks [@shadcn](https://github.com/shadcn)! - check for empty css vars
- [#6967](https://github.com/shadcn-ui/ui/pull/6967) [`9eae13639c10f0219872b5fd28f523a4c25f40df`](https://github.com/shadcn-ui/ui/commit/9eae13639c10f0219872b5fd28f523a4c25f40df) Thanks [@shadcn](https://github.com/shadcn)! - only show deprecated for new projects
- [#6590](https://github.com/shadcn-ui/ui/pull/6590) [`16d4d38f564c75d4187977275f04d5999ee9e2f4`](https://github.com/shadcn-ui/ui/commit/16d4d38f564c75d4187977275f04d5999ee9e2f4) Thanks [@prateekkumarweb](https://github.com/prateekkumarweb)! - fix tanstack check
## 2.2.0
### Minor Changes

View File

@@ -1,6 +1,6 @@
{
"name": "shadcn",
"version": "2.4.1",
"version": "2.3.0",
"description": "Add components to your apps.",
"publishConfig": {
"access": "public"

View File

@@ -1,8 +1,7 @@
import path from "path"
import { runInit } from "@/src/commands/init"
import { preFlightAdd } from "@/src/preflights/preflight-add"
import { getRegistryIndex, getRegistryItem, isUrl } from "@/src/registry/api"
import { registryItemTypeSchema } from "@/src/registry/schema"
import { getRegistryIndex } from "@/src/registry/api"
import { addComponents } from "@/src/utils/add-components"
import { createProject } from "@/src/utils/create-project"
import * as ERRORS from "@/src/utils/errors"
@@ -79,31 +78,23 @@ export const add = new Command()
...opts,
})
let itemType: z.infer<typeof registryItemTypeSchema> | undefined
if (components.length > 0 && isUrl(components[0])) {
const item = await getRegistryItem(components[0], "")
itemType = item?.type
}
if (
!options.yes &&
(itemType === "registry:style" || itemType === "registry:theme")
) {
// Confirm if user is installing themes.
// For now, we assume a theme is prefixed with "theme-".
const isTheme = options.components?.some((component) =>
component.includes("theme-")
)
if (!options.yes && isTheme) {
logger.break()
const { confirm } = await prompts({
type: "confirm",
name: "confirm",
message: highlighter.warn(
`You are about to install a new ${itemType.replace(
"registry:",
""
)}. \nExisting CSS variables and components will be overwritten. Continue?`
"You are about to install a new theme. \nExisting CSS variables will be overwritten. Continue?"
),
})
if (!confirm) {
logger.break()
logger.log(`Installation cancelled.`)
logger.log("Theme installation cancelled.")
logger.break()
process.exit(1)
}
@@ -157,7 +148,6 @@ export const add = new Command()
isNewProject: false,
srcDir: options.srcDir,
cssVariables: options.cssVariables,
style: "index",
})
}
@@ -189,7 +179,6 @@ export const add = new Command()
isNewProject: true,
srcDir: options.srcDir,
cssVariables: options.cssVariables,
style: "index",
})
shouldUpdateAppIndex =

View File

@@ -4,9 +4,7 @@ import { preFlightInit } from "@/src/preflights/preflight-init"
import {
BASE_COLORS,
getRegistryBaseColors,
getRegistryItem,
getRegistryStyles,
isUrl,
} from "@/src/registry/api"
import { addComponents } from "@/src/utils/add-components"
import { TEMPLATES, createProject } from "@/src/utils/create-project"
@@ -76,7 +74,6 @@ export const initOptionsSchema = z.object({
).join("', '")}'`,
}
),
style: z.string(),
})
export const init = new Command()
@@ -121,24 +118,9 @@ export const init = new Command()
cwd: path.resolve(opts.cwd),
isNewProject: false,
components,
style: "index",
...opts,
})
// We need to check if we're initializing with a new style.
// We fetch the payload of the first item.
// This is okay since the request is cached and deduped.
if (components.length > 0 && isUrl(components[0])) {
const item = await getRegistryItem(components[0], "")
// Skip base color if style.
// We set a default and let the style override it.
if (item?.type === "registry:style") {
options.baseColor = "neutral"
options.style = item.extends ?? "index"
}
}
await runInit(options)
logger.log(
@@ -209,15 +191,11 @@ export async function runInit(
// Add components.
const fullConfig = await resolveConfigPaths(options.cwd, config)
const components = [
...(options.style === "none" ? [] : [options.style]),
...(options.components ?? []),
]
const components = ["index", ...(options.components || [])]
await addComponents(components, fullConfig, {
// Init will always overwrite files.
overwrite: true,
silent: options.silent,
style: options.style,
isNewProject:
options.isNewProject || projectInfo?.framework.name === "next-app",
})

View File

@@ -289,14 +289,6 @@ export async function registryResolveItemsTree(
}
}
// Sort the payload so that registry:theme is always first.
payload.sort((a, b) => {
if (a.type === "registry:theme") {
return -1
}
return 1
})
let tailwind = {}
payload.forEach((item) => {
tailwind = deepmerge(tailwind, item.tailwind ?? {})
@@ -307,11 +299,6 @@ export async function registryResolveItemsTree(
cssVars = deepmerge(cssVars, item.cssVars ?? {})
})
let css = {}
payload.forEach((item) => {
css = deepmerge(css, item.css ?? {})
})
let docs = ""
payload.forEach((item) => {
if (item.docs) {
@@ -329,7 +316,6 @@ export async function registryResolveItemsTree(
files: deepmerge.all(payload.map((item) => item.files ?? [])),
tailwind,
cssVars,
css,
docs,
})
} catch (error) {
@@ -410,7 +396,6 @@ export async function registryGetTheme(name: string, config: Config) {
},
},
cssVars: {
theme: {},
light: {
radius: "0.5rem",
},
@@ -421,13 +406,9 @@ export async function registryGetTheme(name: string, config: Config) {
if (config.tailwind.cssVariables) {
theme.tailwind.config.theme.extend.colors = {
...theme.tailwind.config.theme.extend.colors,
...buildTailwindThemeColorsFromCssVars(baseColor.cssVars.dark ?? {}),
...buildTailwindThemeColorsFromCssVars(baseColor.cssVars.dark),
}
theme.cssVars = {
theme: {
...baseColor.cssVars.theme,
...theme.cssVars.theme,
},
light: {
...baseColor.cssVars.light,
...theme.cssVars.light,
@@ -440,10 +421,6 @@ export async function registryGetTheme(name: string, config: Config) {
if (tailwindVersion === "v4" && baseColor.cssVarsV4) {
theme.cssVars = {
theme: {
...baseColor.cssVarsV4.theme,
...theme.cssVars.theme,
},
light: {
radius: "0.625rem",
...baseColor.cssVarsV4.light,
@@ -473,7 +450,7 @@ function getRegistryUrl(path: string) {
return `${REGISTRY_URL}/${path}`
}
export function isUrl(path: string) {
function isUrl(path: string) {
try {
new URL(path)
return true

View File

@@ -11,11 +11,11 @@ export const registryItemTypeSchema = z.enum([
"registry:hook",
"registry:page",
"registry:file",
"registry:theme",
"registry:style",
// Internal use only
"registry:theme",
"registry:example",
"registry:style",
"registry:internal",
])
@@ -46,27 +46,12 @@ export const registryItemTailwindSchema = z.object({
})
export const registryItemCssVarsSchema = z.object({
theme: z.record(z.string(), z.string()).optional(),
light: z.record(z.string(), z.string()).optional(),
dark: z.record(z.string(), z.string()).optional(),
})
export const registryItemCssSchema = z.record(
z.string(),
z.lazy(() =>
z.union([
z.string(),
z.record(
z.string(),
z.union([z.string(), z.record(z.string(), z.string())])
),
])
)
)
export const registryItemSchema = z.object({
$schema: z.string().optional(),
extends: z.string().optional(),
name: z.string(),
type: registryItemTypeSchema,
title: z.string().optional(),
@@ -78,7 +63,6 @@ export const registryItemSchema = z.object({
files: z.array(registryItemFileSchema).optional(),
tailwind: registryItemTailwindSchema.optional(),
cssVars: registryItemCssVarsSchema.optional(),
css: registryItemCssSchema.optional(),
meta: z.record(z.string(), z.any()).optional(),
docs: z.string().optional(),
categories: z.array(z.string()).optional(),
@@ -113,8 +97,16 @@ export const registryBaseColorSchema = z.object({
light: z.record(z.string(), z.string()),
dark: z.record(z.string(), z.string()),
}),
cssVars: registryItemCssVarsSchema,
cssVarsV4: registryItemCssVarsSchema.optional(),
cssVars: z.object({
light: z.record(z.string(), z.string()),
dark: z.record(z.string(), z.string()),
}),
cssVarsV4: z
.object({
light: z.record(z.string(), z.string()),
dark: z.record(z.string(), z.string()),
})
.optional(),
inlineColorsTemplate: z.string(),
cssVarsTemplate: z.string(),
})
@@ -125,6 +117,5 @@ export const registryResolvedItemsTreeSchema = registryItemSchema.pick({
files: true,
tailwind: true,
cssVars: true,
css: true,
docs: true,
})

View File

@@ -19,7 +19,6 @@ import { getProjectTailwindVersionFromConfig } from "@/src/utils/get-project-inf
import { handleError } from "@/src/utils/handle-error"
import { logger } from "@/src/utils/logger"
import { spinner } from "@/src/utils/spinner"
import { updateCss } from "@/src/utils/updaters/update-css"
import { updateCssVars } from "@/src/utils/updaters/update-css-vars"
import { updateDependencies } from "@/src/utils/updaters/update-dependencies"
import { updateFiles } from "@/src/utils/updaters/update-files"
@@ -33,14 +32,12 @@ export async function addComponents(
overwrite?: boolean
silent?: boolean
isNewProject?: boolean
style?: string
}
) {
options = {
overwrite: false,
silent: false,
isNewProject: false,
style: "index",
...options,
}
@@ -67,14 +64,12 @@ async function addProjectComponents(
overwrite?: boolean
silent?: boolean
isNewProject?: boolean
style?: string
}
) {
const registrySpinner = spinner(`Checking registry.`, {
silent: options.silent,
})?.start()
const tree = await registryResolveItemsTree(components, config)
if (!tree) {
registrySpinner?.fail()
return handleError(new Error("Failed to fetch components from registry."))
@@ -87,20 +82,11 @@ async function addProjectComponents(
silent: options.silent,
tailwindVersion,
})
const overwriteCssVars = await shouldOverwriteCssVars(components, config)
await updateCssVars(tree.cssVars, config, {
cleanupDefaultNextStyles: options.isNewProject,
silent: options.silent,
tailwindVersion,
tailwindConfig: tree.tailwind?.config,
overwriteCssVars,
initIndex: options.style ? options.style === "index" : false,
})
// Add CSS updater
await updateCss(tree.css, config, {
silent: options.silent,
})
await updateDependencies(tree.dependencies, config, {
@@ -125,7 +111,6 @@ async function addWorkspaceComponents(
silent?: boolean
isNewProject?: boolean
isRemote?: boolean
style?: string
}
) {
const registrySpinner = spinner(`Checking registry.`, {
@@ -190,34 +175,22 @@ async function addWorkspaceComponents(
// 2. Update css vars.
if (component.cssVars) {
const overwriteCssVars = await shouldOverwriteCssVars(components, config)
await updateCssVars(component.cssVars, targetConfig, {
silent: true,
tailwindVersion,
tailwindConfig: component.tailwind?.config,
overwriteCssVars,
})
filesUpdated.push(
path.relative(workspaceRoot, targetConfig.resolvedPaths.tailwindCss)
)
}
// 3. Update CSS
if (component.css) {
await updateCss(component.css, targetConfig, {
silent: true,
})
filesUpdated.push(
path.relative(workspaceRoot, targetConfig.resolvedPaths.tailwindCss)
)
}
// 4. Update dependencies.
// 3. Update dependencies.
await updateDependencies(component.dependencies, targetConfig, {
silent: true,
})
// 5. Update files.
// 4. Update files.
const files = await updateFiles(component.files, targetConfig, {
overwrite: options.overwrite,
silent: true,
@@ -298,17 +271,3 @@ async function addWorkspaceComponents(
}
}
}
async function shouldOverwriteCssVars(
components: z.infer<typeof registryItemSchema>["name"][],
config: z.infer<typeof configSchema>
) {
let registryItems = await resolveRegistryItems(components, config)
let result = await fetchRegistry(registryItems)
const payload = z.array(registryItemSchema).parse(result)
return payload.some(
(component) =>
component.type === "registry:theme" || component.type === "registry:style"
)
}

View File

@@ -154,7 +154,7 @@ export async function getTailwindVersion(
cwd: string
): Promise<ProjectInfo["tailwindVersion"]> {
const [packageInfo, config] = await Promise.all([
getPackageInfo(cwd, false),
getPackageInfo(cwd),
getConfig(cwd),
])

View File

@@ -20,8 +20,6 @@ export async function updateCssVars(
config: Config,
options: {
cleanupDefaultNextStyles?: boolean
overwriteCssVars?: boolean
initIndex?: boolean
silent?: boolean
tailwindVersion?: TailwindVersion
tailwindConfig?: z.infer<typeof registryItemTailwindSchema>["config"]
@@ -35,8 +33,6 @@ export async function updateCssVars(
cleanupDefaultNextStyles: false,
silent: false,
tailwindVersion: "v3",
overwriteCssVars: false,
initIndex: true,
...options,
}
const cssFilepath = config.resolvedPaths.tailwindCss
@@ -45,7 +41,7 @@ export async function updateCssVars(
cssFilepath
)
const cssVarsSpinner = spinner(
`Updating CSS variables in ${highlighter.info(cssFilepathRelative)}`,
`Updating ${highlighter.info(cssFilepathRelative)}`,
{
silent: options.silent,
}
@@ -55,8 +51,6 @@ export async function updateCssVars(
cleanupDefaultNextStyles: options.cleanupDefaultNextStyles,
tailwindVersion: options.tailwindVersion,
tailwindConfig: options.tailwindConfig,
overwriteCssVars: options.overwriteCssVars,
initIndex: options.initIndex,
})
await fs.writeFile(cssFilepath, output, "utf8")
cssVarsSpinner.succeed()
@@ -70,22 +64,16 @@ export async function transformCssVars(
cleanupDefaultNextStyles?: boolean
tailwindVersion?: TailwindVersion
tailwindConfig?: z.infer<typeof registryItemTailwindSchema>["config"]
overwriteCssVars?: boolean
initIndex?: boolean
} = {
cleanupDefaultNextStyles: false,
tailwindVersion: "v3",
tailwindConfig: undefined,
overwriteCssVars: false,
initIndex: true,
}
) {
options = {
cleanupDefaultNextStyles: false,
tailwindVersion: "v3",
tailwindConfig: undefined,
overwriteCssVars: false,
initIndex: true,
...options,
}
@@ -103,8 +91,7 @@ export async function transformCssVars(
const packageInfo = getPackageInfo(config.resolvedPaths.cwd)
if (
!packageInfo?.dependencies?.["tailwindcss-animate"] &&
!packageInfo?.devDependencies?.["tailwindcss-animate"] &&
options.initIndex
!packageInfo?.devDependencies?.["tailwindcss-animate"]
) {
plugins.push(addCustomImport({ params: "tw-animate-css" }))
}
@@ -116,11 +103,7 @@ export async function transformCssVars(
plugins.push(cleanupDefaultNextStylesPlugin())
}
plugins.push(
updateCssVarsPluginV4(cssVars, {
overwriteCssVars: options.overwriteCssVars,
})
)
plugins.push(updateCssVarsPluginV4(cssVars))
plugins.push(updateThemePlugin(cssVars))
if (options.tailwindConfig) {
@@ -130,7 +113,7 @@ export async function transformCssVars(
}
}
if (config.tailwind.cssVariables && options.initIndex) {
if (config.tailwind.cssVariables) {
plugins.push(
updateBaseLayerPlugin({ tailwindVersion: options.tailwindVersion })
)
@@ -391,51 +374,13 @@ function addOrUpdateVars(
}
function updateCssVarsPluginV4(
cssVars: z.infer<typeof registryItemCssVarsSchema>,
options: {
overwriteCssVars?: boolean
}
cssVars: z.infer<typeof registryItemCssVarsSchema>
) {
return {
postcssPlugin: "update-css-vars-v4",
Once(root: Root) {
Object.entries(cssVars).forEach(([key, vars]) => {
let selector = key === "light" ? ":root" : `.${key}`
if (key === "theme") {
selector = "@theme"
const themeNode = upsertThemeNode(root)
Object.entries(vars).forEach(([key, value]) => {
const prop = `--${key.replace(/^--/, "")}`
const newDecl = postcss.decl({
prop,
value,
raws: { semicolon: true },
})
const existingDecl = themeNode?.nodes?.find(
(node): node is postcss.Declaration =>
node.type === "decl" && node.prop === prop
)
// Only overwrite if overwriteCssVars is true
// i.e for registry:theme and registry:style
// We do not want new components to overwrite existing vars.
// Keep user defined vars.
if (options.overwriteCssVars) {
if (existingDecl) {
existingDecl.replaceWith(newDecl)
} else {
themeNode?.append(newDecl)
}
} else {
if (!existingDecl) {
themeNode?.append(newDecl)
}
}
})
return
}
const selector = key === "light" ? ":root" : `.${key}`
let ruleNode = root.nodes?.find(
(node): node is Rule =>
@@ -474,20 +419,11 @@ function updateCssVarsPluginV4(
node.type === "decl" && node.prop === prop
)
// Only overwrite if overwriteCssVars is true
// i.e for registry:theme and registry:style
// We do not want new components to overwrite existing vars.
// Do not override existing declarations.
// We do not want new components to override existing vars.
// Keep user defined vars.
if (options.overwriteCssVars) {
if (existingDecl) {
existingDecl.replaceWith(newDecl)
} else {
ruleNode?.append(newDecl)
}
} else {
if (!existingDecl) {
ruleNode?.append(newDecl)
}
if (!existingDecl) {
ruleNode?.append(newDecl)
}
})
})

View File

@@ -1,324 +0,0 @@
import { promises as fs } from "fs"
import path from "path"
import { registryItemCssSchema } from "@/src/registry/schema"
import { Config } from "@/src/utils/get-config"
import { highlighter } from "@/src/utils/highlighter"
import { spinner } from "@/src/utils/spinner"
import postcss from "postcss"
import AtRule from "postcss/lib/at-rule"
import Declaration from "postcss/lib/declaration"
import Root from "postcss/lib/root"
import Rule from "postcss/lib/rule"
import { z } from "zod"
export async function updateCss(
css: z.infer<typeof registryItemCssSchema> | undefined,
config: Config,
options: {
silent?: boolean
}
) {
if (
!config.resolvedPaths.tailwindCss ||
!css ||
Object.keys(css).length === 0
) {
return
}
options = {
silent: false,
...options,
}
const cssFilepath = config.resolvedPaths.tailwindCss
const cssFilepathRelative = path.relative(
config.resolvedPaths.cwd,
cssFilepath
)
const cssSpinner = spinner(
`Updating ${highlighter.info(cssFilepathRelative)}`,
{
silent: options.silent,
}
).start()
const raw = await fs.readFile(cssFilepath, "utf8")
let output = await transformCss(raw, css)
await fs.writeFile(cssFilepath, output, "utf8")
cssSpinner.succeed()
}
export async function transformCss(
input: string,
css: z.infer<typeof registryItemCssSchema>
) {
const plugins = [updateCssPlugin(css)]
const result = await postcss(plugins).process(input, {
from: undefined,
})
let output = result.css
output = output.replace(/\/\* ---break--- \*\//g, "")
output = output.replace(/(\n\s*\n)+/g, "\n\n")
output = output.trimEnd()
return output
}
function updateCssPlugin(css: z.infer<typeof registryItemCssSchema>) {
return {
postcssPlugin: "update-css",
Once(root: Root) {
for (const [selector, properties] of Object.entries(css)) {
if (selector.startsWith("@")) {
// Handle at-rules (@layer, @utility, etc.)
const atRuleMatch = selector.match(/@([a-zA-Z-]+)\s*(.*)/)
if (!atRuleMatch) continue
const [, name, params] = atRuleMatch
// Special handling for keyframes - place them under @theme inline
if (name === "keyframes") {
let themeInline = root.nodes?.find(
(node): node is AtRule =>
node.type === "atrule" &&
node.name === "theme" &&
node.params === "inline"
) as AtRule | undefined
if (!themeInline) {
themeInline = postcss.atRule({
name: "theme",
params: "inline",
raws: { semicolon: true, between: " ", before: "\n" },
})
root.append(themeInline)
root.insertBefore(
themeInline,
postcss.comment({ text: "---break---" })
)
}
const keyframesRule = postcss.atRule({
name: "keyframes",
params,
raws: { semicolon: true, between: " ", before: "\n " },
})
themeInline.append(keyframesRule)
if (typeof properties === "object") {
for (const [step, stepProps] of Object.entries(properties)) {
processRule(keyframesRule, step, stepProps)
}
}
}
// Special handling for utility classes to preserve property values
else if (name === "utility") {
const utilityAtRule = root.nodes?.find(
(node): node is AtRule =>
node.type === "atrule" &&
node.name === name &&
node.params === params
) as AtRule | undefined
if (!utilityAtRule) {
const atRule = postcss.atRule({
name,
params,
raws: { semicolon: true, between: " ", before: "\n" },
})
root.append(atRule)
root.insertBefore(
atRule,
postcss.comment({ text: "---break---" })
)
// Add declarations with their values preserved
if (typeof properties === "object") {
for (const [prop, value] of Object.entries(properties)) {
if (typeof value === "string") {
const decl = postcss.decl({
prop,
value: value,
raws: { semicolon: true, before: "\n " },
})
atRule.append(decl)
} else if (typeof value === "object") {
processRule(atRule, prop, value)
}
}
}
} else {
// Update existing utility class
if (typeof properties === "object") {
for (const [prop, value] of Object.entries(properties)) {
if (typeof value === "string") {
const existingDecl = utilityAtRule.nodes?.find(
(node): node is Declaration =>
node.type === "decl" && node.prop === prop
)
const decl = postcss.decl({
prop,
value: value,
raws: { semicolon: true, before: "\n " },
})
existingDecl
? existingDecl.replaceWith(decl)
: utilityAtRule.append(decl)
} else if (typeof value === "object") {
processRule(utilityAtRule, prop, value)
}
}
}
}
} else {
// Handle other at-rules normally
processAtRule(root, name, params, properties)
}
} else {
// Handle regular CSS rules
processRule(root, selector, properties)
}
}
},
}
}
function processAtRule(
root: Root | AtRule,
name: string,
params: string,
properties: any
) {
// Find or create the at-rule
let atRule = root.nodes?.find(
(node): node is AtRule =>
node.type === "atrule" && node.name === name && node.params === params
) as AtRule | undefined
if (!atRule) {
atRule = postcss.atRule({
name,
params,
raws: { semicolon: true, between: " ", before: "\n" },
})
root.append(atRule)
root.insertBefore(atRule, postcss.comment({ text: "---break---" }))
}
// Process children of this at-rule
if (typeof properties === "object") {
for (const [childSelector, childProps] of Object.entries(properties)) {
if (childSelector.startsWith("@")) {
// Nested at-rule
const nestedMatch = childSelector.match(/@([a-zA-Z-]+)\s*(.*)/)
if (nestedMatch) {
const [, nestedName, nestedParams] = nestedMatch
processAtRule(atRule, nestedName, nestedParams, childProps)
}
} else {
// CSS rule within at-rule
processRule(atRule, childSelector, childProps)
}
}
} else if (typeof properties === "string") {
// Direct string content for the at-rule
try {
// Parse the CSS string with PostCSS
const parsed = postcss.parse(`.temp{${properties}}`)
const tempRule = parsed.first as Rule
if (tempRule && tempRule.nodes) {
// Create a rule for the at-rule if needed
const rule = postcss.rule({
selector: "temp",
raws: { semicolon: true, between: " ", before: "\n " },
})
// Copy all declarations from the temp rule to our actual rule
tempRule.nodes.forEach((node) => {
if (node.type === "decl") {
const clone = node.clone()
clone.raws.before = "\n "
rule.append(clone)
}
})
// Only add the rule if it has declarations
if (rule.nodes?.length) {
atRule.append(rule)
}
}
} catch (error) {
console.error("Error parsing at-rule content:", properties, error)
throw error
}
}
}
function processRule(parent: Root | AtRule, selector: string, properties: any) {
let rule = parent.nodes?.find(
(node): node is Rule => node.type === "rule" && node.selector === selector
) as Rule | undefined
if (!rule) {
rule = postcss.rule({
selector,
raws: { semicolon: true, between: " ", before: "\n " },
})
parent.append(rule)
}
if (typeof properties === "object") {
for (const [prop, value] of Object.entries(properties)) {
if (typeof value === "string") {
const decl = postcss.decl({
prop,
value: value,
raws: { semicolon: true, before: "\n " },
})
// Replace existing property or add new one
const existingDecl = rule.nodes?.find(
(node): node is Declaration =>
node.type === "decl" && node.prop === prop
)
existingDecl ? existingDecl.replaceWith(decl) : rule.append(decl)
} else if (typeof value === "object") {
// Nested selector (including & selectors)
const nestedSelector = prop.startsWith("&")
? selector.replace(/^([^:]+)/, `$1${prop.substring(1)}`)
: prop // Use the original selector for other nested elements
processRule(parent, nestedSelector, value)
}
}
} else if (typeof properties === "string") {
// Direct string content for the rule
try {
// Parse the CSS string with PostCSS
const parsed = postcss.parse(`.temp{${properties}}`)
const tempRule = parsed.first as Rule
if (tempRule && tempRule.nodes) {
// Copy all declarations from the temp rule to our actual rule
tempRule.nodes.forEach((node) => {
if (node.type === "decl") {
const clone = node.clone()
clone.raws.before = "\n "
rule?.append(clone)
}
})
}
} catch (error) {
console.error("Error parsing rule content:", selector, properties, error)
throw error
}
}
}

View File

@@ -1,11 +1,8 @@
import { RegistryItem } from "@/src/registry/schema"
import { Config } from "@/src/utils/get-config"
import { getPackageInfo } from "@/src/utils/get-package-info"
import { getPackageManager } from "@/src/utils/get-package-manager"
import { logger } from "@/src/utils/logger"
import { spinner } from "@/src/utils/spinner"
import { execa } from "execa"
import prompts from "prompts"
export async function updateDependencies(
dependencies: RegistryItem["dependencies"],
@@ -29,43 +26,11 @@ export async function updateDependencies(
})?.start()
const packageManager = await getPackageManager(config.resolvedPaths.cwd)
// Offer to use --force or --legacy-peer-deps if using React 19 with npm.
let flag = ""
if (isUsingReact19(config) && packageManager === "npm") {
if (options.silent) {
flag = "force"
} else {
dependenciesSpinner.stopAndPersist()
logger.warn(
"\nIt looks like you are using React 19. \nSome packages may fail to install due to peer dependency issues in npm (see https://ui.shadcn.com/react-19).\n"
)
const confirmation = await prompts([
{
type: "select",
name: "flag",
message: "How would you like to proceed?",
choices: [
{ title: "Use --force", value: "force" },
{ title: "Use --legacy-peer-deps", value: "legacy-peer-deps" },
],
},
])
if (confirmation) {
flag = confirmation.flag
}
}
}
dependenciesSpinner?.start()
await execa(
packageManager,
[
packageManager === "npm" ? "install" : "add",
...(packageManager === "npm" && flag ? [`--${flag}`] : []),
...dependencies,
],
[packageManager === "npm" ? "install" : "add", ...dependencies],
{
cwd: config.resolvedPaths.cwd,
}
@@ -73,13 +38,3 @@ export async function updateDependencies(
dependenciesSpinner?.succeed()
}
function isUsingReact19(config: Config) {
const packageInfo = getPackageInfo(config.resolvedPaths.cwd)
if (!packageInfo?.dependencies?.react) {
return false
}
return /^(?:\^|~)?19(?:\.\d+)*(?:-.*)?$/.test(packageInfo.dependencies.react)
}

View File

@@ -1,10 +1,7 @@
import { promises as fs } from "fs"
import { tmpdir } from "os"
import path from "path"
import {
registryItemCssVarsSchema,
registryItemTailwindSchema,
} from "@/src/registry/schema"
import { registryItemTailwindSchema } from "@/src/registry/schema"
import { Config } from "@/src/utils/get-config"
import { TailwindVersion } from "@/src/utils/get-project-info"
import { highlighter } from "@/src/utils/highlighter"
@@ -502,7 +499,7 @@ function parseValue(node: any): any {
}
export function buildTailwindThemeColorsFromCssVars(
cssVars: z.infer<typeof registryItemCssVarsSchema>
cssVars: Record<string, string>
) {
const result: Record<string, any> = {}

View File

@@ -2,13 +2,11 @@
exports[`registryResolveItemTree > should resolve index 1`] = `
{
"css": {},
"cssVars": {
"dark": {},
"light": {
"radius": "0.5rem",
},
"theme": {},
},
"dependencies": [
"tailwindcss-animate",
@@ -88,7 +86,6 @@ export { Label }
exports[`registryResolveItemTree > should resolve items tree 1`] = `
{
"css": {},
"cssVars": {},
"dependencies": [
"@radix-ui/react-slot",
@@ -166,11 +163,10 @@ export { Button, buttonVariants }
exports[`registryResolveItemTree > should resolve multiple items tree 1`] = `
{
"css": {},
"cssVars": {},
"dependencies": [
"@radix-ui/react-slot",
"cmdk",
"cmdk@1.0.0",
"@radix-ui/react-dialog",
],
"devDependencies": [],

View File

@@ -309,12 +309,6 @@ describe("transformCssVarsV4", () => {
}
`,
{
theme: {
"font-poppins": "Poppins, sans-serif",
"breakpoint-3xl": "120rem",
"shadow-2xs": "0px 1px 2px 0px rgba(0, 0, 0, 0.05)",
"animate-bounce": "bounce 1s infinite",
},
light: {
background: "215 20.2% 65.1%",
foreground: "222.2 84% 4.9%",
@@ -346,152 +340,6 @@ describe("transformCssVarsV4", () => {
@theme inline {
--color-background: var(--background);
--font-poppins: Poppins, sans-serif;
--breakpoint-3xl: 120rem;
--shadow-2xs: 0px 1px 2px 0px rgba(0, 0, 0, 0.05);
--animate-bounce: bounce 1s infinite;
--color-primary: var(--primary);
--color-foreground: var(--foreground);
}
@layer base {
* {
@apply border-border outline-ring/50;
}
body {
@apply bg-background text-foreground;
}
}
"
`)
})
test("should NOT override theme vars if overwriteCssVars is false", async () => {
expect(
await transformCssVars(
`@import "tailwindcss";
:root {
--background: hsl(210 40% 98%);
}
.dark {
--background: hsl(222.2 84% 4.9%);
}
@theme inline {
--color-background: var(--background);
--font-sans: Inter, sans-serif;
}
`,
{
theme: {
"font-sans": "Poppins, sans-serif",
"breakpoint-3xl": "120rem",
},
light: {
background: "215 20.2% 65.1%",
foreground: "222.2 84% 4.9%",
primary: "215 20.2% 65.1%",
},
dark: {
foreground: "60 9.1% 97.8%",
primary: "222.2 84% 4.9%",
},
},
{ tailwind: { cssVariables: true } },
{ tailwindVersion: "v4" }
)
).toMatchInlineSnapshot(`
"@import "tailwindcss";
@custom-variant dark (&:is(.dark *));
:root {
--background: hsl(210 40% 98%);
--foreground: hsl(222.2 84% 4.9%);
--primary: hsl(215 20.2% 65.1%);
}
.dark {
--background: hsl(222.2 84% 4.9%);
--foreground: hsl(60 9.1% 97.8%);
--primary: hsl(222.2 84% 4.9%);
}
@theme inline {
--color-background: var(--background);
--font-sans: Inter, sans-serif;
--breakpoint-3xl: 120rem;
--color-primary: var(--primary);
--color-foreground: var(--foreground);
}
@layer base {
* {
@apply border-border outline-ring/50;
}
body {
@apply bg-background text-foreground;
}
}
"
`)
})
test("should override theme vars if overwriteCssVars is true", async () => {
expect(
await transformCssVars(
`@import "tailwindcss";
:root {
--background: hsl(210 40% 98%);
}
.dark {
--background: hsl(222.2 84% 4.9%);
}
@theme inline {
--color-background: var(--background);
--font-sans: Inter, sans-serif;
}
`,
{
theme: {
"font-sans": "Poppins, sans-serif",
"breakpoint-3xl": "120rem",
},
light: {
background: "215 20.2% 65.1%",
foreground: "222.2 84% 4.9%",
primary: "215 20.2% 65.1%",
},
dark: {
foreground: "60 9.1% 97.8%",
primary: "222.2 84% 4.9%",
},
},
{ tailwind: { cssVariables: true } },
{ tailwindVersion: "v4", overwriteCssVars: true }
)
).toMatchInlineSnapshot(`
"@import "tailwindcss";
@custom-variant dark (&:is(.dark *));
:root {
--background: hsl(215 20.2% 65.1%);
--foreground: hsl(222.2 84% 4.9%);
--primary: hsl(215 20.2% 65.1%);
}
.dark {
--background: hsl(222.2 84% 4.9%);
--foreground: hsl(60 9.1% 97.8%);
--primary: hsl(222.2 84% 4.9%);
}
@theme inline {
--color-background: var(--background);
--font-sans: Poppins, sans-serif;
--breakpoint-3xl: 120rem;
--color-primary: var(--primary);
--color-foreground: var(--foreground);
}

View File

@@ -1,331 +0,0 @@
import { describe, expect, test } from "vitest"
import { transformCss } from "../../../src/utils/updaters/update-css"
describe("transformCss", () => {
test("should add utility classes", async () => {
const input = `@import "tailwindcss";`
const result = await transformCss(input, {
"@utility content-auto": {
"content-visibility": "auto",
},
})
expect(result).toMatchInlineSnapshot(`
"@import "tailwindcss";
@utility content-auto {
content-visibility: auto;
}"
`)
})
test("should add utility classes with pseudo-selectors", async () => {
const input = `@import "tailwindcss";`
const result = await transformCss(input, {
"@utility scrollbar-hidden": {
"&::-webkit-scrollbar": {
display: "none",
},
},
})
expect(result).toMatchInlineSnapshot(`
"@import "tailwindcss";
@utility scrollbar-hidden {
&::-webkit-scrollbar {
display: none;
}
}"
`)
})
test("should add parameterized utility classes", async () => {
const input = `@import "tailwindcss";`
const result = await transformCss(input, {
"@utility tab-*": {
"tab-size": "--value([integer])",
},
})
expect(result).toMatchInlineSnapshot(`
"@import "tailwindcss";
@utility tab-* {
tab-size: --value([integer]);
}"
`)
})
test("should add component styles", async () => {
const input = `@tailwind base;
@tailwind components;
@tailwind utilities;`
const result = await transformCss(input, {
"@layer components": {
".card": {
"background-color": "var(--color-white)",
"border-radius": "var(--rounded-lg)",
padding: "var(--spacing-6)",
"box-shadow": "var(--shadow-xl)",
},
},
})
expect(result).toMatchInlineSnapshot(`
"@tailwind base;
@tailwind components;
@tailwind utilities;
@layer components {
.card {
background-color: var(--color-white);
border-radius: var(--rounded-lg);
padding: var(--spacing-6);
box-shadow: var(--shadow-xl);
}
}"
`)
})
test("should add base styles", async () => {
const input = `@tailwind base;
@tailwind components;
@tailwind utilities;`
const result = await transformCss(input, {
"@layer base": {
h1: {
"font-size": "var(--text-2xl)",
},
h2: {
"font-size": "var(--text-xl)",
},
},
})
expect(result).toMatchInlineSnapshot(`
"@tailwind base;
@tailwind components;
@tailwind utilities;
@layer base {
h1 {
font-size: var(--text-2xl);
}
h2 {
font-size: var(--text-xl);
}
}"
`)
})
test("should update existing rules", async () => {
const input = `@import "tailwindcss";
@layer components {
.card {
background-color: white;
padding: 1rem;
}
}`
const result = await transformCss(input, {
"@layer components": {
".card": {
"background-color": "var(--color-white)",
"border-radius": "var(--rounded-lg)",
"box-shadow": "var(--shadow-xl)",
},
},
})
expect(result).toMatchInlineSnapshot(`
"@import "tailwindcss";
@layer components {
.card {
background-color: var(--color-white);
padding: 1rem;
border-radius: var(--rounded-lg);
box-shadow: var(--shadow-xl);
}
}"
`)
})
test("should add multiple rules and types", async () => {
const input = `@tailwind base;
@tailwind components;
@tailwind utilities;`
const result = await transformCss(input, {
"@utility content-auto": {
"content-visibility": "auto",
},
"@layer components": {
".card": {
"background-color": "var(--color-white)",
"border-radius": "var(--rounded-lg)",
},
},
"@layer base": {
h1: {
"font-size": "var(--text-2xl)",
},
},
})
expect(result).toMatchInlineSnapshot(`
"@tailwind base;
@tailwind components;
@tailwind utilities;
@utility content-auto {
content-visibility: auto;
}
@layer components {
.card {
background-color: var(--color-white);
border-radius: var(--rounded-lg);
}
}
@layer base {
h1 {
font-size: var(--text-2xl);
}
}"
`)
})
test("should handle nested selectors with &", async () => {
const input = `@tailwind base;
@tailwind components;
@tailwind utilities;`
const result = await transformCss(input, {
"@layer components": {
".button": {
"background-color": "var(--color-primary)",
"&:hover": {
"background-color": "var(--color-primary-dark)",
},
"&:active": {
"background-color": "var(--color-primary-darker)",
},
},
},
})
expect(result).toMatchInlineSnapshot(`
"@tailwind base;
@tailwind components;
@tailwind utilities;
@layer components {
.button {
background-color: var(--color-primary);
}
.button:hover {
background-color: var(--color-primary-dark);
}
.button:active {
background-color: var(--color-primary-darker);
}
}"
`)
})
test("should handle direct string content", async () => {
const input = `@tailwind base;
@tailwind components;
@tailwind utilities;`
const result = await transformCss(input, {
"@layer base": {
body: "font-family: var(--font-sans); line-height: 1.5;",
},
})
expect(result).toMatchInlineSnapshot(`
"@tailwind base;
@tailwind components;
@tailwind utilities;
@layer base {
body {
font-family: var(--font-sans);
line-height: 1.5;
}
}"
`)
})
test("should handle nested at-rules", async () => {
const input = `@tailwind base;
@tailwind components;
@tailwind utilities;`
const result = await transformCss(input, {
"@layer components": {
"@media (min-width: 768px)": {
".card": {
padding: "2rem",
},
},
},
})
expect(result).toMatchInlineSnapshot(`
"@tailwind base;
@tailwind components;
@tailwind utilities;
@layer components {
@media (min-width: 768px) {
.card {
padding: 2rem;
}
}
}"
`)
})
test("should place keyframes under @theme inline directive", async () => {
const input = `@import "tailwindcss";`
const result = await transformCss(input, {
"@keyframes spin": {
"0%": {
transform: "rotate(0deg)",
},
"100%": {
transform: "rotate(360deg)",
},
},
})
expect(result).toMatchInlineSnapshot(`
"@import "tailwindcss";
@theme inline {
@keyframes spin {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
}"
`)
})
})

1445
pnpm-lock.yaml generated

File diff suppressed because it is too large Load Diff

View File

@@ -14,7 +14,7 @@
"dependencies": {
"@workspace/ui": "workspace:*",
"lucide-react": "^0.475.0",
"next": "^15.2.3",
"next": "^15.2.0",
"next-themes": "^0.4.4",
"react": "^19.0.0",
"react-dom": "^19.0.0"

View File

@@ -33,8 +33,8 @@ importers:
specifier: ^0.475.0
version: 0.475.0(react@19.0.0)
next:
specifier: ^15.2.3
version: 15.2.3(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
specifier: ^15.2.0
version: 15.2.0(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
next-themes:
specifier: ^0.4.4
version: 0.4.4(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
@@ -356,56 +356,56 @@ packages:
'@jridgewell/trace-mapping@0.3.9':
resolution: {integrity: sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==}
'@next/env@15.2.3':
resolution: {integrity: sha512-a26KnbW9DFEUsSxAxKBORR/uD9THoYoKbkpFywMN/AFvboTt94b8+g/07T8J6ACsdLag8/PDU60ov4rPxRAixw==}
'@next/env@15.2.0':
resolution: {integrity: sha512-eMgJu1RBXxxqqnuRJQh5RozhskoNUDHBFybvi+Z+yK9qzKeG7dadhv/Vp1YooSZmCnegf7JxWuapV77necLZNA==}
'@next/eslint-plugin-next@15.1.7':
resolution: {integrity: sha512-kRP7RjSxfTO13NE317ek3mSGzoZlI33nc/i5hs1KaWpK+egs85xg0DJ4p32QEiHnR0mVjuUfhRIun7awqfL7pQ==}
'@next/swc-darwin-arm64@15.2.3':
resolution: {integrity: sha512-uaBhA8aLbXLqwjnsHSkxs353WrRgQgiFjduDpc7YXEU0B54IKx3vU+cxQlYwPCyC8uYEEX7THhtQQsfHnvv8dw==}
'@next/swc-darwin-arm64@15.2.0':
resolution: {integrity: sha512-rlp22GZwNJjFCyL7h5wz9vtpBVuCt3ZYjFWpEPBGzG712/uL1bbSkS675rVAUCRZ4hjoTJ26Q7IKhr5DfJrHDA==}
engines: {node: '>= 10'}
cpu: [arm64]
os: [darwin]
'@next/swc-darwin-x64@15.2.3':
resolution: {integrity: sha512-pVwKvJ4Zk7h+4hwhqOUuMx7Ib02u3gDX3HXPKIShBi9JlYllI0nU6TWLbPT94dt7FSi6mSBhfc2JrHViwqbOdw==}
'@next/swc-darwin-x64@15.2.0':
resolution: {integrity: sha512-DiU85EqSHogCz80+sgsx90/ecygfCSGl5P3b4XDRVZpgujBm5lp4ts7YaHru7eVTyZMjHInzKr+w0/7+qDrvMA==}
engines: {node: '>= 10'}
cpu: [x64]
os: [darwin]
'@next/swc-linux-arm64-gnu@15.2.3':
resolution: {integrity: sha512-50ibWdn2RuFFkOEUmo9NCcQbbV9ViQOrUfG48zHBCONciHjaUKtHcYFiCwBVuzD08fzvzkWuuZkd4AqbvKO7UQ==}
'@next/swc-linux-arm64-gnu@15.2.0':
resolution: {integrity: sha512-VnpoMaGukiNWVxeqKHwi8MN47yKGyki5q+7ql/7p/3ifuU2341i/gDwGK1rivk0pVYbdv5D8z63uu9yMw0QhpQ==}
engines: {node: '>= 10'}
cpu: [arm64]
os: [linux]
'@next/swc-linux-arm64-musl@15.2.3':
resolution: {integrity: sha512-2gAPA7P652D3HzR4cLyAuVYwYqjG0mt/3pHSWTCyKZq/N/dJcUAEoNQMyUmwTZWCJRKofB+JPuDVP2aD8w2J6Q==}
'@next/swc-linux-arm64-musl@15.2.0':
resolution: {integrity: sha512-ka97/ssYE5nPH4Qs+8bd8RlYeNeUVBhcnsNUmFM6VWEob4jfN9FTr0NBhXVi1XEJpj3cMfgSRW+LdE3SUZbPrw==}
engines: {node: '>= 10'}
cpu: [arm64]
os: [linux]
'@next/swc-linux-x64-gnu@15.2.3':
resolution: {integrity: sha512-ODSKvrdMgAJOVU4qElflYy1KSZRM3M45JVbeZu42TINCMG3anp7YCBn80RkISV6bhzKwcUqLBAmOiWkaGtBA9w==}
'@next/swc-linux-x64-gnu@15.2.0':
resolution: {integrity: sha512-zY1JduE4B3q0k2ZCE+DAF/1efjTXUsKP+VXRtrt/rJCTgDlUyyryx7aOgYXNc1d8gobys/Lof9P9ze8IyRDn7Q==}
engines: {node: '>= 10'}
cpu: [x64]
os: [linux]
'@next/swc-linux-x64-musl@15.2.3':
resolution: {integrity: sha512-ZR9kLwCWrlYxwEoytqPi1jhPd1TlsSJWAc+H/CJHmHkf2nD92MQpSRIURR1iNgA/kuFSdxB8xIPt4p/T78kwsg==}
'@next/swc-linux-x64-musl@15.2.0':
resolution: {integrity: sha512-QqvLZpurBD46RhaVaVBepkVQzh8xtlUN00RlG4Iq1sBheNugamUNPuZEH1r9X1YGQo1KqAe1iiShF0acva3jHQ==}
engines: {node: '>= 10'}
cpu: [x64]
os: [linux]
'@next/swc-win32-arm64-msvc@15.2.3':
resolution: {integrity: sha512-+G2FrDcfm2YDbhDiObDU/qPriWeiz/9cRR0yMWJeTLGGX6/x8oryO3tt7HhodA1vZ8r2ddJPCjtLcpaVl7TE2Q==}
'@next/swc-win32-arm64-msvc@15.2.0':
resolution: {integrity: sha512-ODZ0r9WMyylTHAN6pLtvUtQlGXBL9voljv6ujSlcsjOxhtXPI1Ag6AhZK0SE8hEpR1374WZZ5w33ChpJd5fsjw==}
engines: {node: '>= 10'}
cpu: [arm64]
os: [win32]
'@next/swc-win32-x64-msvc@15.2.3':
resolution: {integrity: sha512-gHYS9tc+G2W0ZC8rBL+H6RdtXIyk40uLiaos0yj5US85FNhbFEndMA2nW3z47nzOWiSvXTZ5kBClc3rD0zJg0w==}
'@next/swc-win32-x64-msvc@15.2.0':
resolution: {integrity: sha512-8+4Z3Z7xa13NdUuUAcpVNA6o76lNPniBd9Xbo02bwXQXnZgFvEopwY2at5+z7yHl47X9qbZpvwatZ2BRo3EdZw==}
engines: {node: '>= 10'}
cpu: [x64]
os: [win32]
@@ -764,8 +764,8 @@ packages:
camel-case@3.0.0:
resolution: {integrity: sha512-+MbKztAYHXPr1jNTSKQF52VpcFjwY5RkR7fxksV8Doo4KAYc5Fl4UJRgthBbTmEx8C54DqahhbLJkDwjI3PI/w==}
caniuse-lite@1.0.30001707:
resolution: {integrity: sha512-3qtRjw/HQSMlDWf+X79N206fepf4SOOU6SQLMaq/0KkZLmSjPxAkBOQQ+FxbHKfHmYLZFfdWsO3KA90ceHPSnw==}
caniuse-lite@1.0.30001700:
resolution: {integrity: sha512-2S6XIXwaE7K7erT8dY+kLQcpa5ms63XlRkMkReXjle+kf6c5g38vyMl+Z5y8dSxOFDhcFe+nxnn261PLxBSQsQ==}
chalk@2.4.2:
resolution: {integrity: sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==}
@@ -1629,11 +1629,6 @@ packages:
mute-stream@0.0.8:
resolution: {integrity: sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==}
nanoid@3.3.11:
resolution: {integrity: sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==}
engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1}
hasBin: true
nanoid@3.3.8:
resolution: {integrity: sha512-WNLf5Sd8oZxOm+TzppcYk8gVOgP+l58xNy58D0nbUnOxOWRWvlcCV4kUF7ltmI6PsrLl/BgKEyS4mqsGChFN0w==}
engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1}
@@ -1655,8 +1650,8 @@ packages:
react: ^16.8 || ^17 || ^18 || ^19 || ^19.0.0-rc
react-dom: ^16.8 || ^17 || ^18 || ^19 || ^19.0.0-rc
next@15.2.3:
resolution: {integrity: sha512-x6eDkZxk2rPpu46E1ZVUWIBhYCLszmUY6fvHBFcbzJ9dD+qRX6vcHusaqqDlnY+VngKzKbAiG2iRCkPbmi8f7w==}
next@15.2.0:
resolution: {integrity: sha512-VaiM7sZYX8KIAHBrRGSFytKknkrexNfGb8GlG6e93JqueCspuGte8i4ybn8z4ww1x3f2uzY4YpTaBEW4/hvsoQ==}
engines: {node: ^18.18.0 || ^19.8.0 || >= 20.0.0}
hasBin: true
peerDependencies:
@@ -2485,34 +2480,34 @@ snapshots:
'@jridgewell/resolve-uri': 3.1.2
'@jridgewell/sourcemap-codec': 1.5.0
'@next/env@15.2.3': {}
'@next/env@15.2.0': {}
'@next/eslint-plugin-next@15.1.7':
dependencies:
fast-glob: 3.3.1
'@next/swc-darwin-arm64@15.2.3':
'@next/swc-darwin-arm64@15.2.0':
optional: true
'@next/swc-darwin-x64@15.2.3':
'@next/swc-darwin-x64@15.2.0':
optional: true
'@next/swc-linux-arm64-gnu@15.2.3':
'@next/swc-linux-arm64-gnu@15.2.0':
optional: true
'@next/swc-linux-arm64-musl@15.2.3':
'@next/swc-linux-arm64-musl@15.2.0':
optional: true
'@next/swc-linux-x64-gnu@15.2.3':
'@next/swc-linux-x64-gnu@15.2.0':
optional: true
'@next/swc-linux-x64-musl@15.2.3':
'@next/swc-linux-x64-musl@15.2.0':
optional: true
'@next/swc-win32-arm64-msvc@15.2.3':
'@next/swc-win32-arm64-msvc@15.2.0':
optional: true
'@next/swc-win32-x64-msvc@15.2.3':
'@next/swc-win32-x64-msvc@15.2.0':
optional: true
'@nodelib/fs.scandir@2.1.5':
@@ -2930,7 +2925,7 @@ snapshots:
no-case: 2.3.2
upper-case: 1.1.3
caniuse-lite@1.0.30001707: {}
caniuse-lite@1.0.30001700: {}
chalk@2.4.2:
dependencies:
@@ -3943,8 +3938,6 @@ snapshots:
mute-stream@0.0.8: {}
nanoid@3.3.11: {}
nanoid@3.3.8: {}
natural-compare@1.4.0: {}
@@ -3958,26 +3951,26 @@ snapshots:
react: 19.0.0
react-dom: 19.0.0(react@19.0.0)
next@15.2.3(react-dom@19.0.0(react@19.0.0))(react@19.0.0):
next@15.2.0(react-dom@19.0.0(react@19.0.0))(react@19.0.0):
dependencies:
'@next/env': 15.2.3
'@next/env': 15.2.0
'@swc/counter': 0.1.3
'@swc/helpers': 0.5.15
busboy: 1.6.0
caniuse-lite: 1.0.30001707
caniuse-lite: 1.0.30001700
postcss: 8.4.31
react: 19.0.0
react-dom: 19.0.0(react@19.0.0)
styled-jsx: 5.1.6(react@19.0.0)
optionalDependencies:
'@next/swc-darwin-arm64': 15.2.3
'@next/swc-darwin-x64': 15.2.3
'@next/swc-linux-arm64-gnu': 15.2.3
'@next/swc-linux-arm64-musl': 15.2.3
'@next/swc-linux-x64-gnu': 15.2.3
'@next/swc-linux-x64-musl': 15.2.3
'@next/swc-win32-arm64-msvc': 15.2.3
'@next/swc-win32-x64-msvc': 15.2.3
'@next/swc-darwin-arm64': 15.2.0
'@next/swc-darwin-x64': 15.2.0
'@next/swc-linux-arm64-gnu': 15.2.0
'@next/swc-linux-arm64-musl': 15.2.0
'@next/swc-linux-x64-gnu': 15.2.0
'@next/swc-linux-x64-musl': 15.2.0
'@next/swc-win32-arm64-msvc': 15.2.0
'@next/swc-win32-x64-msvc': 15.2.0
sharp: 0.33.5
transitivePeerDependencies:
- '@babel/core'
@@ -4155,7 +4148,7 @@ snapshots:
postcss@8.4.31:
dependencies:
nanoid: 3.3.11
nanoid: 3.3.8
picocolors: 1.1.1
source-map-js: 1.2.1