From 2fade2326a0685e0d0d303ddfe0bac2fab27c46f Mon Sep 17 00:00:00 2001 From: shadcn Date: Fri, 28 Mar 2025 17:48:59 +0400 Subject: [PATCH 01/18] feat(shadcn): add css props to schema (#7072) * feat(shadcn): add css props to schema * fix: types --- apps/www/config/docs.ts | 5 + apps/www/content/docs/registry/examples.mdx | 273 +++++++++++++++ .../docs/registry/registry-item-json.mdx | 39 +++ apps/www/contentlayer.config.js | 2 +- apps/www/public/schema/registry-item.json | 32 ++ packages/shadcn/src/commands/add.ts | 27 +- packages/shadcn/src/commands/init.ts | 14 +- packages/shadcn/src/registry/api.ts | 6 + packages/shadcn/src/registry/schema.ts | 15 + packages/shadcn/src/utils/add-components.ts | 20 +- .../src/utils/updaters/update-css-vars.ts | 2 +- .../shadcn/src/utils/updaters/update-css.ts | 324 +++++++++++++++++ .../registry-resolve-items-tree.test.ts.snap | 3 + .../test/utils/updaters/update-css.test.ts | 331 ++++++++++++++++++ 14 files changed, 1074 insertions(+), 19 deletions(-) create mode 100644 apps/www/content/docs/registry/examples.mdx create mode 100644 packages/shadcn/src/utils/updaters/update-css.ts create mode 100644 packages/shadcn/test/utils/updaters/update-css.test.ts diff --git a/apps/www/config/docs.ts b/apps/www/config/docs.ts index e1352ed2b8..83e65611e8 100644 --- a/apps/www/config/docs.ts +++ b/apps/www/config/docs.ts @@ -433,6 +433,11 @@ 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", diff --git a/apps/www/content/docs/registry/examples.mdx b/apps/www/content/docs/registry/examples.mdx new file mode 100644 index 0000000000..3f1213a996 --- /dev/null +++ b/apps/www/content/docs/registry/examples.mdx @@ -0,0 +1,273 @@ +--- +title: Examples +description: "Examples of registry items: styles, components, css vars, etc." +--- + +## 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", + } + } +} +``` + +## 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" + ] +} +``` + +## Install custom CSS variables + +The following style will init using shadcn/ui defaults and then override the background and foreground css vars. + +```json title="example-style.json" showLineNumbers +{ + "$schema": "https://ui.shadcn.com/schema/registry-item.json", + "name": "custom-style", + "type": "registry:style", + "cssVars": { + "light": { + "background": "oklch(0.99 0.00 0)", + "foreground": "oklch(0.14 0.00 286)" + }, + "dark": { + "background": "oklch(0.14 0.00 286)", + "foreground": "oklch(0.99 0.00 0)" + } + } +} +``` + +## 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)" + } + } + } +} +``` diff --git a/apps/www/content/docs/registry/registry-item-json.mdx b/apps/www/content/docs/registry/registry-item-json.mdx index f736bc7d75..b8bf5acdec 100644 --- a/apps/www/content/docs/registry/registry-item-json.mdx +++ b/apps/www/content/docs/registry/registry-item-json.mdx @@ -36,6 +36,10 @@ The `registry-item.json` schema is used to define your custom registry items. } ``` +
+ See more examples +
+ ## Definitions You can see the JSON Schema for `registry-item.json` [here](https://ui.shadcn.com/schema/registry-item.json). @@ -254,6 +258,41 @@ 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)" + } + } + } +} +``` + ### docs Use `docs` to show custom documentation or message when installing your registry item via the CLI. diff --git a/apps/www/contentlayer.config.js b/apps/www/contentlayer.config.js index 3394d28b28..147105797c 100644 --- a/apps/www/contentlayer.config.js +++ b/apps/www/contentlayer.config.js @@ -113,7 +113,7 @@ export default makeSource({ [ rehypePrettyCode, { - theme: "github-dark", + theme: "github-dark-default", getHighlighter, onVisitLine(node) { // Prevent lines from collapsing in `display: grid` mode, and allow empty diff --git a/apps/www/public/schema/registry-item.json b/apps/www/public/schema/registry-item.json index 16bb183b73..1f4b887403 100644 --- a/apps/www/public/schema/registry-item.json +++ b/apps/www/public/schema/registry-item.json @@ -156,6 +156,38 @@ } } }, + "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.", diff --git a/packages/shadcn/src/commands/add.ts b/packages/shadcn/src/commands/add.ts index 049bb34c12..2ef8fb6210 100644 --- a/packages/shadcn/src/commands/add.ts +++ b/packages/shadcn/src/commands/add.ts @@ -1,7 +1,8 @@ import path from "path" import { runInit } from "@/src/commands/init" import { preFlightAdd } from "@/src/preflights/preflight-add" -import { getRegistryIndex } from "@/src/registry/api" +import { getRegistryIndex, getRegistryItem } from "@/src/registry/api" +import { registryItemTypeSchema } from "@/src/registry/schema" import { addComponents } from "@/src/utils/add-components" import { createProject } from "@/src/utils/create-project" import * as ERRORS from "@/src/utils/errors" @@ -78,23 +79,31 @@ export const add = new Command() ...opts, }) - // 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) { + let itemType: z.infer | undefined + + if (components.length > 0) { + const item = await getRegistryItem(components[0], "") + itemType = item?.type + } + + if ( + !options.yes && + (itemType === "registry:style" || itemType === "registry:theme") + ) { logger.break() const { confirm } = await prompts({ type: "confirm", name: "confirm", message: highlighter.warn( - "You are about to install a new theme. \nExisting CSS variables will be overwritten. Continue?" + `You are about to install a new ${itemType.replace( + "registry:", + "" + )}. \nExisting CSS variables and components will be overwritten. Continue?` ), }) if (!confirm) { logger.break() - logger.log("Theme installation cancelled.") + logger.log(`Installation cancelled.`) logger.break() process.exit(1) } diff --git a/packages/shadcn/src/commands/init.ts b/packages/shadcn/src/commands/init.ts index 0171708c4e..820af01e81 100644 --- a/packages/shadcn/src/commands/init.ts +++ b/packages/shadcn/src/commands/init.ts @@ -127,13 +127,15 @@ export const init = new Command() // 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. - const item = await getRegistryItem(components[0], "") + if (components.length > 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" + // 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) diff --git a/packages/shadcn/src/registry/api.ts b/packages/shadcn/src/registry/api.ts index 3ead257724..28219e0114 100644 --- a/packages/shadcn/src/registry/api.ts +++ b/packages/shadcn/src/registry/api.ts @@ -307,6 +307,11 @@ 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) { @@ -324,6 +329,7 @@ export async function registryResolveItemsTree( files: deepmerge.all(payload.map((item) => item.files ?? [])), tailwind, cssVars, + css, docs, }) } catch (error) { diff --git a/packages/shadcn/src/registry/schema.ts b/packages/shadcn/src/registry/schema.ts index 3d7c6c36e7..6b1af728a0 100644 --- a/packages/shadcn/src/registry/schema.ts +++ b/packages/shadcn/src/registry/schema.ts @@ -51,6 +51,19 @@ export const registryItemCssVarsSchema = z.object({ 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(), @@ -65,6 +78,7 @@ 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(), @@ -111,5 +125,6 @@ export const registryResolvedItemsTreeSchema = registryItemSchema.pick({ files: true, tailwind: true, cssVars: true, + css: true, docs: true, }) diff --git a/packages/shadcn/src/utils/add-components.ts b/packages/shadcn/src/utils/add-components.ts index 033d5fe485..20639476c4 100644 --- a/packages/shadcn/src/utils/add-components.ts +++ b/packages/shadcn/src/utils/add-components.ts @@ -19,6 +19,7 @@ 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" @@ -97,6 +98,11 @@ async function addProjectComponents( initIndex: options.style ? options.style === "index" : false, }) + // Add CSS updater + await updateCss(tree.css, config, { + silent: options.silent, + }) + await updateDependencies(tree.dependencies, config, { silent: options.silent, }) @@ -196,12 +202,22 @@ async function addWorkspaceComponents( ) } - // 3. Update dependencies. + // 3. Update CSS + if (component.css) { + await updateCss(component.css, targetConfig, { + silent: true, + }) + filesUpdated.push( + path.relative(workspaceRoot, targetConfig.resolvedPaths.tailwindCss) + ) + } + + // 4. Update dependencies. await updateDependencies(component.dependencies, targetConfig, { silent: true, }) - // 4. Update files. + // 5. Update files. const files = await updateFiles(component.files, targetConfig, { overwrite: options.overwrite, silent: true, diff --git a/packages/shadcn/src/utils/updaters/update-css-vars.ts b/packages/shadcn/src/utils/updaters/update-css-vars.ts index 81c588febe..00ca1a6ee1 100644 --- a/packages/shadcn/src/utils/updaters/update-css-vars.ts +++ b/packages/shadcn/src/utils/updaters/update-css-vars.ts @@ -45,7 +45,7 @@ export async function updateCssVars( cssFilepath ) const cssVarsSpinner = spinner( - `Updating ${highlighter.info(cssFilepathRelative)}`, + `Updating CSS variables in ${highlighter.info(cssFilepathRelative)}`, { silent: options.silent, } diff --git a/packages/shadcn/src/utils/updaters/update-css.ts b/packages/shadcn/src/utils/updaters/update-css.ts new file mode 100644 index 0000000000..7c64b7e68e --- /dev/null +++ b/packages/shadcn/src/utils/updaters/update-css.ts @@ -0,0 +1,324 @@ +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 | 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 +) { + 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) { + 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 + } + } +} diff --git a/packages/shadcn/test/utils/schema/__snapshots__/registry-resolve-items-tree.test.ts.snap b/packages/shadcn/test/utils/schema/__snapshots__/registry-resolve-items-tree.test.ts.snap index 80a4ab2cc0..91e0fe90d7 100644 --- a/packages/shadcn/test/utils/schema/__snapshots__/registry-resolve-items-tree.test.ts.snap +++ b/packages/shadcn/test/utils/schema/__snapshots__/registry-resolve-items-tree.test.ts.snap @@ -2,6 +2,7 @@ exports[`registryResolveItemTree > should resolve index 1`] = ` { + "css": {}, "cssVars": { "dark": {}, "light": { @@ -87,6 +88,7 @@ export { Label } exports[`registryResolveItemTree > should resolve items tree 1`] = ` { + "css": {}, "cssVars": {}, "dependencies": [ "@radix-ui/react-slot", @@ -164,6 +166,7 @@ export { Button, buttonVariants } exports[`registryResolveItemTree > should resolve multiple items tree 1`] = ` { + "css": {}, "cssVars": {}, "dependencies": [ "@radix-ui/react-slot", diff --git a/packages/shadcn/test/utils/updaters/update-css.test.ts b/packages/shadcn/test/utils/updaters/update-css.test.ts new file mode 100644 index 0000000000..08cb618c4b --- /dev/null +++ b/packages/shadcn/test/utils/updaters/update-css.test.ts @@ -0,0 +1,331 @@ +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); + } + } + }" + `) + }) +}) From b52fa4559ce99ce1892028125ced1dca278a4737 Mon Sep 17 00:00:00 2001 From: shadcn Date: Fri, 28 Mar 2025 21:05:55 +0400 Subject: [PATCH 02/18] docs(www): update registry examples --- apps/www/content/docs/registry/examples.mdx | 115 +++++++++++++++++--- 1 file changed, 99 insertions(+), 16 deletions(-) diff --git a/apps/www/content/docs/registry/examples.mdx b/apps/www/content/docs/registry/examples.mdx index 3f1213a996..248fb55530 100644 --- a/apps/www/content/docs/registry/examples.mdx +++ b/apps/www/content/docs/registry/examples.mdx @@ -3,7 +3,9 @@ title: Examples description: "Examples of registry items: styles, components, css vars, etc." --- -## Custom style that extends shadcn/ui +## 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: @@ -38,7 +40,7 @@ The following registry item is a custom style that extends shadcn/ui. On `npx sh } ``` -## Custom style from scratch +### Custom style from scratch The following registry item is a custom style that doesn't extend shadcn/ui. See the `extends: none` field. @@ -87,7 +89,90 @@ On `npx shadcn add`, the following will: } ``` -## Install a block and override primitives +## 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. @@ -110,29 +195,27 @@ On `npx shadcn add`, the following will: } ``` -## Install custom CSS variables +## CSS Variables -The following style will init using shadcn/ui defaults and then override the background and foreground css vars. +### Custom Theme Variables -```json title="example-style.json" showLineNumbers +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-style", - "type": "registry:style", + "name": "custom-theme", + "type": "registry:theme", "cssVars": { - "light": { - "background": "oklch(0.99 0.00 0)", - "foreground": "oklch(0.14 0.00 286)" - }, - "dark": { - "background": "oklch(0.14 0.00 286)", - "foreground": "oklch(0.99 0.00 0)" + "theme": { + "font-heading": "Inter, sans-serif", + "shadow-card": "0 0 0 1px rgba(0, 0, 0, 0.1)" } } } ``` -## Override Tailwind CSS variables +### Override Tailwind CSS variables ```json title="example-theme.json" showLineNumbers { From 812e2300f1ab9f8bf4c65abb9ae94426e1967461 Mon Sep 17 00:00:00 2001 From: shadcn Date: Sun, 30 Mar 2025 05:43:29 +0400 Subject: [PATCH 03/18] fix(shadcn): only run preflight check if url --- packages/shadcn/src/commands/add.ts | 4 ++-- packages/shadcn/src/commands/init.ts | 3 ++- packages/shadcn/src/registry/api.ts | 2 +- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/packages/shadcn/src/commands/add.ts b/packages/shadcn/src/commands/add.ts index 2ef8fb6210..c9917da09c 100644 --- a/packages/shadcn/src/commands/add.ts +++ b/packages/shadcn/src/commands/add.ts @@ -1,7 +1,7 @@ import path from "path" import { runInit } from "@/src/commands/init" import { preFlightAdd } from "@/src/preflights/preflight-add" -import { getRegistryIndex, getRegistryItem } from "@/src/registry/api" +import { getRegistryIndex, getRegistryItem, isUrl } from "@/src/registry/api" import { registryItemTypeSchema } from "@/src/registry/schema" import { addComponents } from "@/src/utils/add-components" import { createProject } from "@/src/utils/create-project" @@ -81,7 +81,7 @@ export const add = new Command() let itemType: z.infer | undefined - if (components.length > 0) { + if (components.length > 0 && isUrl(components[0])) { const item = await getRegistryItem(components[0], "") itemType = item?.type } diff --git a/packages/shadcn/src/commands/init.ts b/packages/shadcn/src/commands/init.ts index 820af01e81..068b8f94b7 100644 --- a/packages/shadcn/src/commands/init.ts +++ b/packages/shadcn/src/commands/init.ts @@ -6,6 +6,7 @@ import { getRegistryBaseColors, getRegistryItem, getRegistryStyles, + isUrl, } from "@/src/registry/api" import { addComponents } from "@/src/utils/add-components" import { TEMPLATES, createProject } from "@/src/utils/create-project" @@ -127,7 +128,7 @@ export const init = new Command() // 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) { + if (components.length > 0 && isUrl(components[0])) { const item = await getRegistryItem(components[0], "") // Skip base color if style. diff --git a/packages/shadcn/src/registry/api.ts b/packages/shadcn/src/registry/api.ts index 28219e0114..c251599196 100644 --- a/packages/shadcn/src/registry/api.ts +++ b/packages/shadcn/src/registry/api.ts @@ -473,7 +473,7 @@ function getRegistryUrl(path: string) { return `${REGISTRY_URL}/${path}` } -function isUrl(path: string) { +export function isUrl(path: string) { try { new URL(path) return true From 1bd209a4dbe555eab45a47d03d3fe6c819b5e753 Mon Sep 17 00:00:00 2001 From: shadcn Date: Mon, 31 Mar 2025 10:33:48 +0400 Subject: [PATCH 04/18] feat: add oklch colors to themes (#7090) * wip * feat: add oklch theme * fix: keys --- apps/www/app/(app)/themes/layout.tsx | 16 +- apps/www/components/theme-customizer.tsx | 605 ++++++++++++---------- apps/www/registry/registry-base-colors.ts | 547 +++++++++++++++++++ 3 files changed, 883 insertions(+), 285 deletions(-) diff --git a/apps/www/app/(app)/themes/layout.tsx b/apps/www/app/(app)/themes/layout.tsx index cbb27a03dd..e2763d3385 100644 --- a/apps/www/app/(app)/themes/layout.tsx +++ b/apps/www/app/(app)/themes/layout.tsx @@ -7,7 +7,8 @@ import { PageHeaderDescription, PageHeaderHeading, } from "@/components/page-header" -import { ThemeCustomizer } from "@/components/theme-customizer" +import { Customizer } from "@/components/theme-customizer" +import { Button } from "@/registry/new-york/ui/button" const title = "Add colors. Make it yours." const description = @@ -48,10 +49,17 @@ export default function ThemesLayout({ {title} {description} - - - +
+ New Theme Editor coming soon +
+
+
+
+ +
+
+
diff --git a/apps/www/components/theme-customizer.tsx b/apps/www/components/theme-customizer.tsx index a66a03d756..a454fb81b4 100644 --- a/apps/www/components/theme-customizer.tsx +++ b/apps/www/components/theme-customizer.tsx @@ -2,7 +2,7 @@ import * as React from "react" import template from "lodash/template" -import { Check, Copy, Moon, Repeat, Sun } from "lucide-react" +import { Check, ClipboardIcon, Copy } from "lucide-react" import { useTheme } from "next-themes" import { cn } from "@/lib/utils" @@ -21,6 +21,9 @@ import { import { Drawer, DrawerContent, + DrawerDescription, + DrawerHeader, + DrawerTitle, DrawerTrigger, } from "@/registry/new-york/ui/drawer" import { Label } from "@/registry/new-york/ui/label" @@ -29,15 +32,28 @@ 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 { - Tooltip, - TooltipContent, - TooltipTrigger, -} from "@/registry/new-york/ui/tooltip" -import { BaseColor, baseColors } from "@/registry/registry-base-colors" + BaseColor, + baseColors, + baseColorsOKLCH, +} 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 + dark: Record +} export function ThemeCustomizer() { const [config, setConfig] = useConfig() @@ -78,9 +94,9 @@ export function ThemeCustomizer() { ) } -function Customizer() { +export function Customizer() { const [mounted, setMounted] = React.useState(false) - const { setTheme: setMode, resolvedTheme: mode } = useTheme() + const { resolvedTheme: mode } = useTheme() const [config, setConfig] = useConfig() React.useEffect(() => { @@ -88,39 +104,11 @@ function Customizer() { }, []) return ( - -
-
-
- Theme Customizer -
-
- Customize your components colors. -
-
- -
-
-
- -
+ +
+
+ +
{baseColors .filter( (theme) => @@ -131,7 +119,7 @@ function Customizer() { return mounted ? ( ) : ( - + ) })}
-
- -
+ +
+ +
{["0", "0.3", "0.5", "0.75", "1.0"].map((value) => { return (
-
- -
- {mounted ? ( - <> - - - - ) : ( - <> - - - - )} -
+
+
) } -function CopyCodeButton({ +export function CopyCodeButton({ className, ...props }: React.ComponentProps) { - 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 ( <> - {activeTheme && ( - - )} + + + + + + + Theme + + Copy and paste the following code into your CSS file. + + + + + + + - @@ -280,28 +244,6 @@ function CopyCodeButton({ - {activeTheme && ( - - )} @@ -311,168 +253,269 @@ function CopyCodeButton({ function CustomizerCode() { const [config] = useConfig() - const activeTheme = baseColors.find((theme) => theme.name === config.theme) + 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]) return ( -
-
-          
-            @layer base {
-              :root {
-            
-                  --background:{" "}
-              {activeTheme?.cssVars.light["background"]};
-            
-            
-                  --foreground:{" "}
-              {activeTheme?.cssVars.light["foreground"]};
-            
-            {[
-              "card",
-              "popover",
-              "primary",
-              "secondary",
-              "muted",
-              "accent",
-              "destructive",
-            ].map((prefix) => (
-              <>
-                
-                      --{prefix}:{" "}
-                  {
-                    activeTheme?.cssVars.light[
-                      prefix as keyof typeof activeTheme.cssVars.light
-                    ]
-                  }
-                  ;
-                
-                
-                      --{prefix}-foreground:{" "}
-                  {
-                    activeTheme?.cssVars.light[
-                      `${prefix}-foreground` as keyof typeof activeTheme.cssVars.light
-                    ]
-                  }
-                  ;
-                
-              
-            ))}
-            
-                  --border:{" "}
-              {activeTheme?.cssVars.light["border"]};
-            
-            
-                  --input:{" "}
-              {activeTheme?.cssVars.light["input"]};
-            
-            
-                  --ring:{" "}
-              {activeTheme?.cssVars.light["ring"]};
-            
-            
-                  --radius: {config.radius}rem;
-            
-            {["chart-1", "chart-2", "chart-3", "chart-4", "chart-5"].map(
-              (prefix) => (
-                <>
-                  
-                        --{prefix}:{" "}
-                    {
-                      activeTheme?.cssVars.light[
-                        prefix as keyof typeof activeTheme.cssVars.light
-                      ]
-                    }
-                    ;
-                  
-                
+      
+        
+ + Tailwind v4 + v3 + + +
+ +
+
+              
+                 :root {
                 
-                      --{prefix}:{" "}
-                  {
-                    activeTheme?.cssVars.dark[
-                      prefix as keyof typeof activeTheme.cssVars.dark
-                    ]
-                  }
-                  ;
+                     --radius: {config.radius}rem;
                 
-                
-                      --{prefix}-foreground:{" "}
-                  {
-                    activeTheme?.cssVars.dark[
-                      `${prefix}-foreground` as keyof typeof activeTheme.cssVars.dark
-                    ]
-                  }
-                  ;
-                
-              
-            ))}
-            
-                  --border:{" "}
-              {activeTheme?.cssVars.dark["border"]};
-            
-            
-                  --input:{" "}
-              {activeTheme?.cssVars.dark["input"]};
-            
-            
-                  --ring:{" "}
-              {activeTheme?.cssVars.dark["ring"]};
-            
-            {["chart-1", "chart-2", "chart-3", "chart-4", "chart-5"].map(
-              (prefix) => (
-                <>
-                  
-                        --{prefix}:{" "}
-                    {
-                      activeTheme?.cssVars.dark[
-                        prefix as keyof typeof activeTheme.cssVars.dark
-                      ]
-                    }
-                    ;
+                {Object.entries(activeThemeOKLCH?.light).map(([key, value]) => (
+                  
+                       --{key}: {value};
                   
-                
-              )
-            )}
-              }
-            }
-          
-        
-
+ ))} +  } +   +  .dark { + {Object.entries(activeThemeOKLCH?.dark).map(([key, value]) => ( + +    --{key}: {value}; + + ))} +  } +
+
+
+ + +
+
+              
+                @layer base {
+                
+                    :root {
+                
+                
+                      --background:{" "}
+                  {activeTheme?.cssVars.light["background"]};
+                
+                
+                      --foreground:{" "}
+                  {activeTheme?.cssVars.light["foreground"]};
+                
+                {[
+                  "card",
+                  "popover",
+                  "primary",
+                  "secondary",
+                  "muted",
+                  "accent",
+                  "destructive",
+                ].map((prefix) => (
+                  <>
+                    
+                          --{prefix}:{" "}
+                      {
+                        activeTheme?.cssVars.light[
+                          prefix as keyof typeof activeTheme.cssVars.light
+                        ]
+                      }
+                      ;
+                    
+                    
+                          --{prefix}-foreground:{" "}
+                      {
+                        activeTheme?.cssVars.light[
+                          `${prefix}-foreground` as keyof typeof activeTheme.cssVars.light
+                        ]
+                      }
+                      ;
+                    
+                  
+                ))}
+                
+                      --border:{" "}
+                  {activeTheme?.cssVars.light["border"]};
+                
+                
+                      --input:{" "}
+                  {activeTheme?.cssVars.light["input"]};
+                
+                
+                      --ring:{" "}
+                  {activeTheme?.cssVars.light["ring"]};
+                
+                
+                      --radius: {config.radius}rem;
+                
+                {["chart-1", "chart-2", "chart-3", "chart-4", "chart-5"].map(
+                  (prefix) => (
+                    <>
+                      
+                            --{prefix}:{" "}
+                        {
+                          activeTheme?.cssVars.light[
+                            prefix as keyof typeof activeTheme.cssVars.light
+                          ]
+                        }
+                        ;
+                      
+                    
+                  )
+                )}
+                  }
+                 
+                
+                    .dark {
+                
+                
+                      --background:{" "}
+                  {activeTheme?.cssVars.dark["background"]};
+                
+                
+                      --foreground:{" "}
+                  {activeTheme?.cssVars.dark["foreground"]};
+                
+                {[
+                  "card",
+                  "popover",
+                  "primary",
+                  "secondary",
+                  "muted",
+                  "accent",
+                  "destructive",
+                ].map((prefix) => (
+                  <>
+                    
+                          --{prefix}:{" "}
+                      {
+                        activeTheme?.cssVars.dark[
+                          prefix as keyof typeof activeTheme.cssVars.dark
+                        ]
+                      }
+                      ;
+                    
+                    
+                          --{prefix}-foreground:{" "}
+                      {
+                        activeTheme?.cssVars.dark[
+                          `${prefix}-foreground` as keyof typeof activeTheme.cssVars.dark
+                        ]
+                      }
+                      ;
+                    
+                  
+                ))}
+                
+                      --border:{" "}
+                  {activeTheme?.cssVars.dark["border"]};
+                
+                
+                      --input:{" "}
+                  {activeTheme?.cssVars.dark["input"]};
+                
+                
+                      --ring:{" "}
+                  {activeTheme?.cssVars.dark["ring"]};
+                
+                {["chart-1", "chart-2", "chart-3", "chart-4", "chart-5"].map(
+                  (prefix) => (
+                    <>
+                      
+                            --{prefix}:{" "}
+                        {
+                          activeTheme?.cssVars.dark[
+                            prefix as keyof typeof activeTheme.cssVars.dark
+                          ]
+                        }
+                        ;
+                      
+                    
+                  )
+                )}
+                  }
+                }
+              
+            
+
+
+
) } -function getThemeCode(theme: BaseColor, radius: number) { +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) { if (!theme) { return "" } return template(BASE_STYLES_WITH_VARIABLES)({ colors: theme.cssVars, - radius, + radius: radius.toString(), }) } diff --git a/apps/www/registry/registry-base-colors.ts b/apps/www/registry/registry-base-colors.ts index b3db7804ae..badbf61fa0 100644 --- a/apps/www/registry/registry-base-colors.ts +++ b/apps/www/registry/registry-base-colors.ts @@ -1102,3 +1102,550 @@ 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%) + }, + }, +} From 625be136f46f1c1504870e384753d3f4e279bd18 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 7 Apr 2025 15:16:43 +0400 Subject: [PATCH 05/18] chore(release): version packages (#6505) Co-authored-by: github-actions[bot] --- .changeset/brave-cheetahs-smile.md | 5 --- .changeset/cold-impalas-call.md | 5 --- .changeset/cool-mails-bake.md | 5 --- .changeset/curly-impalas-give.md | 5 --- .changeset/curvy-taxis-help.md | 5 --- .changeset/few-houses-impress.md | 5 --- .changeset/five-hounds-tell.md | 5 --- .changeset/fluffy-years-knock.md | 5 --- .changeset/fresh-cherries-brush.md | 5 --- .changeset/great-olives-flow.md | 5 --- .changeset/green-eels-shout.md | 5 --- .changeset/large-timers-kneel.md | 5 --- .changeset/metal-queens-hang.md | 5 --- .changeset/new-cheetahs-dance.md | 5 --- .changeset/nine-llamas-sell.md | 5 --- .changeset/ninety-needles-brake.md | 5 --- .changeset/orange-papayas-relax.md | 5 --- .changeset/proud-snails-switch.md | 5 --- .changeset/quiet-grapes-poke.md | 5 --- .changeset/serious-geese-reply.md | 5 --- .changeset/shaggy-months-tease.md | 5 --- .changeset/six-queens-argue.md | 5 --- .changeset/slow-tools-relax.md | 5 --- .changeset/spotty-plants-juggle.md | 5 --- .changeset/tasty-walls-drum.md | 5 --- .changeset/warm-fans-protect.md | 5 --- apps/v4/package.json | 2 +- apps/www/package.json | 2 +- packages/shadcn/CHANGELOG.md | 58 ++++++++++++++++++++++++++++++ packages/shadcn/package.json | 2 +- 30 files changed, 61 insertions(+), 133 deletions(-) delete mode 100644 .changeset/brave-cheetahs-smile.md delete mode 100644 .changeset/cold-impalas-call.md delete mode 100644 .changeset/cool-mails-bake.md delete mode 100644 .changeset/curly-impalas-give.md delete mode 100644 .changeset/curvy-taxis-help.md delete mode 100644 .changeset/few-houses-impress.md delete mode 100644 .changeset/five-hounds-tell.md delete mode 100644 .changeset/fluffy-years-knock.md delete mode 100644 .changeset/fresh-cherries-brush.md delete mode 100644 .changeset/great-olives-flow.md delete mode 100644 .changeset/green-eels-shout.md delete mode 100644 .changeset/large-timers-kneel.md delete mode 100644 .changeset/metal-queens-hang.md delete mode 100644 .changeset/new-cheetahs-dance.md delete mode 100644 .changeset/nine-llamas-sell.md delete mode 100644 .changeset/ninety-needles-brake.md delete mode 100644 .changeset/orange-papayas-relax.md delete mode 100644 .changeset/proud-snails-switch.md delete mode 100644 .changeset/quiet-grapes-poke.md delete mode 100644 .changeset/serious-geese-reply.md delete mode 100644 .changeset/shaggy-months-tease.md delete mode 100644 .changeset/six-queens-argue.md delete mode 100644 .changeset/slow-tools-relax.md delete mode 100644 .changeset/spotty-plants-juggle.md delete mode 100644 .changeset/tasty-walls-drum.md delete mode 100644 .changeset/warm-fans-protect.md diff --git a/.changeset/brave-cheetahs-smile.md b/.changeset/brave-cheetahs-smile.md deleted file mode 100644 index ad4775459d..0000000000 --- a/.changeset/brave-cheetahs-smile.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"shadcn": minor ---- - -add support for TanStack Start diff --git a/.changeset/cold-impalas-call.md b/.changeset/cold-impalas-call.md deleted file mode 100644 index 5de218772a..0000000000 --- a/.changeset/cold-impalas-call.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"shadcn": patch ---- - -support for version detection in monorepo diff --git a/.changeset/cool-mails-bake.md b/.changeset/cool-mails-bake.md deleted file mode 100644 index 085f768e35..0000000000 --- a/.changeset/cool-mails-bake.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"shadcn": patch ---- - -upgrade @antfu/ni diff --git a/.changeset/curly-impalas-give.md b/.changeset/curly-impalas-give.md deleted file mode 100644 index 6667f901d3..0000000000 --- a/.changeset/curly-impalas-give.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"shadcn": patch ---- - -allow silent mode with npm diff --git a/.changeset/curvy-taxis-help.md b/.changeset/curvy-taxis-help.md deleted file mode 100644 index c17b6d1b5a..0000000000 --- a/.changeset/curvy-taxis-help.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"shadcn": patch ---- - -do not add ring for v3 diff --git a/.changeset/few-houses-impress.md b/.changeset/few-houses-impress.md deleted file mode 100644 index 8feeafd979..0000000000 --- a/.changeset/few-houses-impress.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"shadcn": minor ---- - -add theme vars support diff --git a/.changeset/five-hounds-tell.md b/.changeset/five-hounds-tell.md deleted file mode 100644 index 849f1c114b..0000000000 --- a/.changeset/five-hounds-tell.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"shadcn": minor ---- - -add tailwind version detection diff --git a/.changeset/fluffy-years-knock.md b/.changeset/fluffy-years-knock.md deleted file mode 100644 index fc167c719e..0000000000 --- a/.changeset/fluffy-years-knock.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"shadcn": minor ---- - -add --base-color flag diff --git a/.changeset/fresh-cherries-brush.md b/.changeset/fresh-cherries-brush.md deleted file mode 100644 index f57423cce4..0000000000 --- a/.changeset/fresh-cherries-brush.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"shadcn": minor ---- - -add support for tailwind v4 diff --git a/.changeset/great-olives-flow.md b/.changeset/great-olives-flow.md deleted file mode 100644 index d58ad002ad..0000000000 --- a/.changeset/great-olives-flow.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"shadcn": minor ---- - -default to css vars. add --no-css-variables diff --git a/.changeset/green-eels-shout.md b/.changeset/green-eels-shout.md deleted file mode 100644 index a7013814ca..0000000000 --- a/.changeset/green-eels-shout.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"shadcn": patch ---- - -cache registry calls diff --git a/.changeset/large-timers-kneel.md b/.changeset/large-timers-kneel.md deleted file mode 100644 index b49b194acf..0000000000 --- a/.changeset/large-timers-kneel.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"shadcn": minor ---- - -replace tailwindcss-animate with tw-animate-css diff --git a/.changeset/metal-queens-hang.md b/.changeset/metal-queens-hang.md deleted file mode 100644 index 8b2d3ef60d..0000000000 --- a/.changeset/metal-queens-hang.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"shadcn": patch ---- - -add --template flag diff --git a/.changeset/new-cheetahs-dance.md b/.changeset/new-cheetahs-dance.md deleted file mode 100644 index 31bf21a2e3..0000000000 --- a/.changeset/new-cheetahs-dance.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"shadcn": minor ---- - -default for new-york for v4 diff --git a/.changeset/nine-llamas-sell.md b/.changeset/nine-llamas-sell.md deleted file mode 100644 index 14f7e942a2..0000000000 --- a/.changeset/nine-llamas-sell.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"shadcn": minor ---- - -fix handling of sidebar colors diff --git a/.changeset/ninety-needles-brake.md b/.changeset/ninety-needles-brake.md deleted file mode 100644 index d138c882cc..0000000000 --- a/.changeset/ninety-needles-brake.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"shadcn": patch ---- - -do not overwrite user defined vars diff --git a/.changeset/orange-papayas-relax.md b/.changeset/orange-papayas-relax.md deleted file mode 100644 index 56389409db..0000000000 --- a/.changeset/orange-papayas-relax.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"shadcn": patch ---- - -fix cn import bug in monorepo diff --git a/.changeset/proud-snails-switch.md b/.changeset/proud-snails-switch.md deleted file mode 100644 index 9aa3af62f7..0000000000 --- a/.changeset/proud-snails-switch.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"shadcn": patch ---- - -filter out deprecated from --all diff --git a/.changeset/quiet-grapes-poke.md b/.changeset/quiet-grapes-poke.md deleted file mode 100644 index c2edf88139..0000000000 --- a/.changeset/quiet-grapes-poke.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"shadcn": minor ---- - -add oklch base color diff --git a/.changeset/serious-geese-reply.md b/.changeset/serious-geese-reply.md deleted file mode 100644 index 0da0143c06..0000000000 --- a/.changeset/serious-geese-reply.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"shadcn": minor ---- - -hotswap style for v4 diff --git a/.changeset/shaggy-months-tease.md b/.changeset/shaggy-months-tease.md deleted file mode 100644 index eb292424f7..0000000000 --- a/.changeset/shaggy-months-tease.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"shadcn": patch ---- - -check for empty css vars diff --git a/.changeset/six-queens-argue.md b/.changeset/six-queens-argue.md deleted file mode 100644 index a33549d53d..0000000000 --- a/.changeset/six-queens-argue.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"shadcn": patch ---- - -only show deprecated for new projects diff --git a/.changeset/slow-tools-relax.md b/.changeset/slow-tools-relax.md deleted file mode 100644 index 68f1588ab8..0000000000 --- a/.changeset/slow-tools-relax.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"shadcn": minor ---- - -add warning for deprecated components diff --git a/.changeset/spotty-plants-juggle.md b/.changeset/spotty-plants-juggle.md deleted file mode 100644 index 0474dc152d..0000000000 --- a/.changeset/spotty-plants-juggle.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"shadcn": patch ---- - -fix tanstack check diff --git a/.changeset/tasty-walls-drum.md b/.changeset/tasty-walls-drum.md deleted file mode 100644 index ea8d908288..0000000000 --- a/.changeset/tasty-walls-drum.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"shadcn": minor ---- - -add support for route install for react-router and laravel diff --git a/.changeset/warm-fans-protect.md b/.changeset/warm-fans-protect.md deleted file mode 100644 index 61465c5b05..0000000000 --- a/.changeset/warm-fans-protect.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"shadcn": minor ---- - -add theme prop to registry-item schema diff --git a/apps/v4/package.json b/apps/v4/package.json index 3d5019fb03..ada439aea4 100644 --- a/apps/v4/package.json +++ b/apps/v4/package.json @@ -73,7 +73,7 @@ "react-resizable-panels": "^2.1.7", "recharts": "2.15.1", "rimraf": "^6.0.1", - "shadcn": "2.3.0", + "shadcn": "2.4.0", "sonner": "^2.0.0", "tailwind-merge": "^3.0.1", "tailwindcss": "^4.0.7", diff --git a/apps/www/package.json b/apps/www/package.json index 5863f8300e..47806d4f1b 100644 --- a/apps/www/package.json +++ b/apps/www/package.json @@ -86,7 +86,7 @@ "react-resizable-panels": "^2.0.22", "react-wrap-balancer": "^0.4.1", "recharts": "2.12.7", - "shadcn": "2.3.0", + "shadcn": "2.4.0", "sharp": "^0.32.6", "sonner": "^1.2.3", "swr": "2.2.6-beta.3", diff --git a/packages/shadcn/CHANGELOG.md b/packages/shadcn/CHANGELOG.md index c34ed1ad65..08103da282 100644 --- a/packages/shadcn/CHANGELOG.md +++ b/packages/shadcn/CHANGELOG.md @@ -1,5 +1,63 @@ # @shadcn/ui +## 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 diff --git a/packages/shadcn/package.json b/packages/shadcn/package.json index d76fef74aa..fd01cc8489 100644 --- a/packages/shadcn/package.json +++ b/packages/shadcn/package.json @@ -1,6 +1,6 @@ { "name": "shadcn", - "version": "2.3.0", + "version": "2.4.0", "description": "Add components to your apps.", "publishConfig": { "access": "public" From 6d2728db2e0ef8f2004e5fe655a87de4c077f94a Mon Sep 17 00:00:00 2001 From: shadcn Date: Mon, 7 Apr 2025 15:19:36 +0400 Subject: [PATCH 06/18] deps: update --- pnpm-lock.yaml | 171 ++++++++++++++++++++++++++++--------------------- 1 file changed, 99 insertions(+), 72 deletions(-) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 1880dcd618..3b34884682 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -58,7 +58,7 @@ importers: version: 7.37.4(eslint@8.57.1) eslint-plugin-tailwindcss: specifier: 3.13.1 - version: 3.13.1(tailwindcss@3.4.6(ts-node@10.9.2(@types/node@20.5.1)(typescript@5.7.3))) + version: 3.13.1(tailwindcss@3.4.6(ts-node@10.9.2(@types/node@20.17.16)(typescript@5.7.3))) postcss: specifier: ^8.4.24 version: 8.5.1 @@ -73,10 +73,10 @@ importers: version: 23.11.1(typescript@5.7.3) tailwindcss: specifier: 3.4.6 - version: 3.4.6(ts-node@10.9.2(@types/node@20.5.1)(typescript@5.7.3)) + version: 3.4.6(ts-node@10.9.2(@types/node@20.17.16)(typescript@5.7.3)) tailwindcss-animate: specifier: ^1.0.5 - version: 1.0.7(tailwindcss@3.4.6(ts-node@10.9.2(@types/node@20.5.1)(typescript@5.7.3))) + version: 1.0.7(tailwindcss@3.4.6(ts-node@10.9.2(@types/node@20.17.16)(typescript@5.7.3))) tsx: specifier: ^4.1.4 version: 4.19.2 @@ -283,7 +283,7 @@ importers: specifier: ^6.0.1 version: 6.0.1 shadcn: - specifier: 2.3.0 + specifier: 2.4.0 version: link:../../packages/shadcn sonner: specifier: ^2.0.0 @@ -542,7 +542,7 @@ importers: specifier: 2.12.7 version: 2.12.7(react-dom@18.3.1(react@18.3.1))(react@18.3.1) shadcn: - specifier: 2.3.0 + specifier: 2.4.0 version: link:../../packages/shadcn sharp: specifier: ^0.32.6 @@ -689,7 +689,7 @@ importers: version: 4.1.5 msw: specifier: ^2.7.1 - version: 2.7.1(@types/node@20.17.16)(typescript@4.9.5) + version: 2.7.1(@types/node@22.13.0)(typescript@4.9.5) node-fetch: specifier: ^3.3.0 version: 3.3.2 @@ -738,7 +738,7 @@ importers: version: 6.0.1 tsup: specifier: ^6.6.3 - version: 6.7.0(postcss@8.5.1)(ts-node@10.9.2(@types/node@20.17.16)(typescript@4.9.5))(typescript@4.9.5) + version: 6.7.0(postcss@8.5.1)(ts-node@10.9.2(@types/node@22.13.0)(typescript@4.9.5))(typescript@4.9.5) type-fest: specifier: ^3.8.0 version: 3.13.1 @@ -8813,7 +8813,7 @@ snapshots: lodash.merge: 4.6.2 lodash.uniq: 4.5.0 resolve-from: 5.0.0 - ts-node: 10.9.2(@types/node@20.17.16)(typescript@5.7.3) + ts-node: 10.9.2(@types/node@20.5.1)(typescript@5.7.3) typescript: 5.7.3 transitivePeerDependencies: - '@swc/core' @@ -9595,6 +9595,14 @@ snapshots: '@inquirer/type': 3.0.4(@types/node@20.17.16) optionalDependencies: '@types/node': 20.17.16 + optional: true + + '@inquirer/confirm@5.1.6(@types/node@22.13.0)': + dependencies: + '@inquirer/core': 10.1.7(@types/node@22.13.0) + '@inquirer/type': 3.0.4(@types/node@22.13.0) + optionalDependencies: + '@types/node': 22.13.0 '@inquirer/core@10.1.7(@types/node@20.17.16)': dependencies: @@ -9608,12 +9616,31 @@ snapshots: yoctocolors-cjs: 2.1.2 optionalDependencies: '@types/node': 20.17.16 + optional: true + + '@inquirer/core@10.1.7(@types/node@22.13.0)': + dependencies: + '@inquirer/figures': 1.0.10 + '@inquirer/type': 3.0.4(@types/node@22.13.0) + ansi-escapes: 4.3.2 + cli-width: 4.1.0 + mute-stream: 2.0.0 + signal-exit: 4.1.0 + wrap-ansi: 6.2.0 + yoctocolors-cjs: 2.1.2 + optionalDependencies: + '@types/node': 22.13.0 '@inquirer/figures@1.0.10': {} '@inquirer/type@3.0.4(@types/node@20.17.16)': optionalDependencies: '@types/node': 20.17.16 + optional: true + + '@inquirer/type@3.0.4(@types/node@22.13.0)': + optionalDependencies: + '@types/node': 22.13.0 '@isaacs/cliui@8.0.2': dependencies: @@ -12610,7 +12637,7 @@ snapshots: dependencies: '@types/node': 20.5.1 cosmiconfig: 8.3.6(typescript@5.7.3) - ts-node: 10.9.2(@types/node@20.17.16)(typescript@5.7.3) + ts-node: 10.9.2(@types/node@20.5.1)(typescript@5.7.3) typescript: 5.7.3 cosmiconfig@8.3.6(typescript@4.9.5): @@ -13329,7 +13356,7 @@ snapshots: debug: 4.3.7 enhanced-resolve: 5.16.1 eslint: 8.57.1 - eslint-module-utils: 2.12.0(@typescript-eslint/parser@5.61.0(eslint@8.57.1)(typescript@5.7.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@5.61.0(eslint@8.57.1)(typescript@5.7.3))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.31.0)(eslint@8.57.1))(eslint@8.57.1) + eslint-module-utils: 2.12.0(@typescript-eslint/parser@5.61.0(eslint@8.57.1)(typescript@5.7.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.1) eslint-plugin-import: 2.31.0(@typescript-eslint/parser@5.61.0(eslint@8.57.1)(typescript@5.7.3))(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.1) fast-glob: 3.3.3 get-tsconfig: 4.7.5 @@ -13346,7 +13373,7 @@ snapshots: debug: 4.3.7 enhanced-resolve: 5.16.1 eslint: 9.19.0(jiti@2.4.2) - eslint-module-utils: 2.12.0(@typescript-eslint/parser@5.61.0(eslint@9.19.0(jiti@2.4.2))(typescript@5.7.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@5.61.0(eslint@9.19.0(jiti@2.4.2))(typescript@5.7.3))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.31.0)(eslint@9.19.0(jiti@2.4.2)))(eslint@9.19.0(jiti@2.4.2)) + eslint-module-utils: 2.12.0(@typescript-eslint/parser@5.61.0(eslint@9.19.0(jiti@2.4.2))(typescript@5.7.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1)(eslint@9.19.0(jiti@2.4.2)) eslint-plugin-import: 2.31.0(@typescript-eslint/parser@5.61.0(eslint@9.19.0(jiti@2.4.2))(typescript@5.7.3))(eslint-import-resolver-typescript@3.6.1)(eslint@9.19.0(jiti@2.4.2)) fast-glob: 3.3.3 get-tsconfig: 4.7.5 @@ -13358,7 +13385,7 @@ snapshots: - eslint-import-resolver-webpack - supports-color - eslint-module-utils@2.12.0(@typescript-eslint/parser@5.61.0(eslint@8.57.1)(typescript@5.7.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@5.61.0(eslint@8.57.1)(typescript@5.7.3))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.31.0)(eslint@8.57.1))(eslint@8.57.1): + eslint-module-utils@2.12.0(@typescript-eslint/parser@5.61.0(eslint@8.57.1)(typescript@5.7.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.1): dependencies: debug: 3.2.7 optionalDependencies: @@ -13369,7 +13396,7 @@ snapshots: transitivePeerDependencies: - supports-color - eslint-module-utils@2.12.0(@typescript-eslint/parser@5.61.0(eslint@9.19.0(jiti@2.4.2))(typescript@5.7.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@5.61.0(eslint@9.19.0(jiti@2.4.2))(typescript@5.7.3))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.31.0)(eslint@9.19.0(jiti@2.4.2)))(eslint@9.19.0(jiti@2.4.2)): + eslint-module-utils@2.12.0(@typescript-eslint/parser@5.61.0(eslint@9.19.0(jiti@2.4.2))(typescript@5.7.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1)(eslint@9.19.0(jiti@2.4.2)): dependencies: debug: 3.2.7 optionalDependencies: @@ -13391,7 +13418,7 @@ snapshots: doctrine: 2.1.0 eslint: 8.57.1 eslint-import-resolver-node: 0.3.9 - eslint-module-utils: 2.12.0(@typescript-eslint/parser@5.61.0(eslint@8.57.1)(typescript@5.7.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@5.61.0(eslint@8.57.1)(typescript@5.7.3))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.31.0)(eslint@8.57.1))(eslint@8.57.1) + eslint-module-utils: 2.12.0(@typescript-eslint/parser@5.61.0(eslint@8.57.1)(typescript@5.7.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.1) hasown: 2.0.2 is-core-module: 2.16.1 is-glob: 4.0.3 @@ -13420,7 +13447,7 @@ snapshots: doctrine: 2.1.0 eslint: 9.19.0(jiti@2.4.2) eslint-import-resolver-node: 0.3.9 - eslint-module-utils: 2.12.0(@typescript-eslint/parser@5.61.0(eslint@9.19.0(jiti@2.4.2))(typescript@5.7.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@5.61.0(eslint@9.19.0(jiti@2.4.2))(typescript@5.7.3))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.31.0)(eslint@9.19.0(jiti@2.4.2)))(eslint@9.19.0(jiti@2.4.2)) + eslint-module-utils: 2.12.0(@typescript-eslint/parser@5.61.0(eslint@9.19.0(jiti@2.4.2))(typescript@5.7.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1)(eslint@9.19.0(jiti@2.4.2)) hasown: 2.0.2 is-core-module: 2.16.1 is-glob: 4.0.3 @@ -13528,11 +13555,11 @@ snapshots: string.prototype.matchall: 4.0.12 string.prototype.repeat: 1.0.0 - eslint-plugin-tailwindcss@3.13.1(tailwindcss@3.4.6(ts-node@10.9.2(@types/node@20.5.1)(typescript@5.7.3))): + eslint-plugin-tailwindcss@3.13.1(tailwindcss@3.4.6(ts-node@10.9.2(@types/node@20.17.16)(typescript@5.7.3))): dependencies: fast-glob: 3.3.3 postcss: 8.5.1 - tailwindcss: 3.4.6(ts-node@10.9.2(@types/node@20.5.1)(typescript@5.7.3)) + tailwindcss: 3.4.6(ts-node@10.9.2(@types/node@20.17.16)(typescript@5.7.3)) eslint-plugin-turbo@1.13.4(eslint@8.57.1): dependencies: @@ -15636,31 +15663,6 @@ snapshots: ms@2.1.3: {} - msw@2.7.1(@types/node@20.17.16)(typescript@4.9.5): - dependencies: - '@bundled-es-modules/cookie': 2.0.1 - '@bundled-es-modules/statuses': 1.0.1 - '@bundled-es-modules/tough-cookie': 0.1.6 - '@inquirer/confirm': 5.1.6(@types/node@20.17.16) - '@mswjs/interceptors': 0.37.6 - '@open-draft/deferred-promise': 2.2.0 - '@open-draft/until': 2.1.0 - '@types/cookie': 0.6.0 - '@types/statuses': 2.0.5 - graphql: 16.10.0 - headers-polyfill: 4.0.3 - is-node-process: 1.2.0 - outvariant: 1.4.3 - path-to-regexp: 6.3.0 - picocolors: 1.1.1 - strict-event-emitter: 0.5.1 - type-fest: 4.33.0 - yargs: 17.7.2 - optionalDependencies: - typescript: 4.9.5 - transitivePeerDependencies: - - '@types/node' - msw@2.7.1(@types/node@20.17.16)(typescript@5.7.3): dependencies: '@bundled-es-modules/cookie': 2.0.1 @@ -15687,6 +15689,31 @@ snapshots: - '@types/node' optional: true + msw@2.7.1(@types/node@22.13.0)(typescript@4.9.5): + dependencies: + '@bundled-es-modules/cookie': 2.0.1 + '@bundled-es-modules/statuses': 1.0.1 + '@bundled-es-modules/tough-cookie': 0.1.6 + '@inquirer/confirm': 5.1.6(@types/node@22.13.0) + '@mswjs/interceptors': 0.37.6 + '@open-draft/deferred-promise': 2.2.0 + '@open-draft/until': 2.1.0 + '@types/cookie': 0.6.0 + '@types/statuses': 2.0.5 + graphql: 16.10.0 + headers-polyfill: 4.0.3 + is-node-process: 1.2.0 + outvariant: 1.4.3 + path-to-regexp: 6.3.0 + picocolors: 1.1.1 + strict-event-emitter: 0.5.1 + type-fest: 4.33.0 + yargs: 17.7.2 + optionalDependencies: + typescript: 4.9.5 + transitivePeerDependencies: + - '@types/node' + mute-stream@2.0.0: {} mz@2.7.0: @@ -16090,13 +16117,13 @@ snapshots: camelcase-css: 2.0.1 postcss: 8.5.1 - postcss-load-config@3.1.4(postcss@8.5.1)(ts-node@10.9.2(@types/node@20.17.16)(typescript@4.9.5)): + postcss-load-config@3.1.4(postcss@8.5.1)(ts-node@10.9.2(@types/node@22.13.0)(typescript@4.9.5)): dependencies: lilconfig: 2.1.0 yaml: 1.10.2 optionalDependencies: postcss: 8.5.1 - ts-node: 10.9.2(@types/node@20.17.16)(typescript@4.9.5) + ts-node: 10.9.2(@types/node@22.13.0)(typescript@4.9.5) postcss-load-config@3.1.4(postcss@8.5.1)(ts-node@10.9.2(@types/node@22.13.0)(typescript@5.7.3)): dependencies: @@ -16114,13 +16141,13 @@ snapshots: postcss: 8.5.1 ts-node: 10.9.2(@types/node@17.0.45)(typescript@5.7.3) - postcss-load-config@4.0.2(postcss@8.5.1)(ts-node@10.9.2(@types/node@20.5.1)(typescript@5.7.3)): + postcss-load-config@4.0.2(postcss@8.5.1)(ts-node@10.9.2(@types/node@20.17.16)(typescript@5.7.3)): dependencies: lilconfig: 3.1.3 yaml: 2.7.0 optionalDependencies: postcss: 8.5.1 - ts-node: 10.9.2(@types/node@20.17.16)(typescript@5.7.3) + ts-node: 10.9.2(@types/node@20.5.1)(typescript@5.7.3) postcss-nested@6.2.0(postcss@8.5.1): dependencies: @@ -17316,9 +17343,9 @@ snapshots: tailwind-merge@3.0.1: {} - tailwindcss-animate@1.0.7(tailwindcss@3.4.6(ts-node@10.9.2(@types/node@20.5.1)(typescript@5.7.3))): + tailwindcss-animate@1.0.7(tailwindcss@3.4.6(ts-node@10.9.2(@types/node@20.17.16)(typescript@5.7.3))): dependencies: - tailwindcss: 3.4.6(ts-node@10.9.2(@types/node@20.5.1)(typescript@5.7.3)) + tailwindcss: 3.4.6(ts-node@10.9.2(@types/node@20.17.16)(typescript@5.7.3)) tailwindcss@3.4.6(ts-node@10.9.2(@types/node@17.0.45)(typescript@5.7.3)): dependencies: @@ -17347,7 +17374,7 @@ snapshots: transitivePeerDependencies: - ts-node - tailwindcss@3.4.6(ts-node@10.9.2(@types/node@20.5.1)(typescript@5.7.3)): + tailwindcss@3.4.6(ts-node@10.9.2(@types/node@20.17.16)(typescript@5.7.3)): dependencies: '@alloc/quick-lru': 5.2.0 arg: 5.0.2 @@ -17366,7 +17393,7 @@ snapshots: postcss: 8.5.1 postcss-import: 15.1.0(postcss@8.5.1) postcss-js: 4.0.1(postcss@8.5.1) - postcss-load-config: 4.0.2(postcss@8.5.1)(ts-node@10.9.2(@types/node@20.5.1)(typescript@5.7.3)) + postcss-load-config: 4.0.2(postcss@8.5.1)(ts-node@10.9.2(@types/node@20.17.16)(typescript@5.7.3)) postcss-nested: 6.2.0(postcss@8.5.1) postcss-selector-parser: 6.1.2 resolve: 1.22.10 @@ -17534,14 +17561,32 @@ snapshots: yn: 3.1.1 optional: true - ts-node@10.9.2(@types/node@20.17.16)(typescript@4.9.5): + ts-node@10.9.2(@types/node@20.5.1)(typescript@5.7.3): dependencies: '@cspotcode/source-map-support': 0.8.1 '@tsconfig/node10': 1.0.11 '@tsconfig/node12': 1.0.11 '@tsconfig/node14': 1.0.3 '@tsconfig/node16': 1.0.4 - '@types/node': 20.17.16 + '@types/node': 20.5.1 + acorn: 8.14.0 + acorn-walk: 8.3.4 + arg: 4.1.3 + create-require: 1.1.1 + diff: 4.0.2 + make-error: 1.3.6 + typescript: 5.7.3 + v8-compile-cache-lib: 3.0.1 + yn: 3.1.1 + + ts-node@10.9.2(@types/node@22.13.0)(typescript@4.9.5): + dependencies: + '@cspotcode/source-map-support': 0.8.1 + '@tsconfig/node10': 1.0.11 + '@tsconfig/node12': 1.0.11 + '@tsconfig/node14': 1.0.3 + '@tsconfig/node16': 1.0.4 + '@types/node': 22.13.0 acorn: 8.14.0 acorn-walk: 8.3.4 arg: 4.1.3 @@ -17553,24 +17598,6 @@ snapshots: yn: 3.1.1 optional: true - ts-node@10.9.2(@types/node@20.17.16)(typescript@5.7.3): - dependencies: - '@cspotcode/source-map-support': 0.8.1 - '@tsconfig/node10': 1.0.11 - '@tsconfig/node12': 1.0.11 - '@tsconfig/node14': 1.0.3 - '@tsconfig/node16': 1.0.4 - '@types/node': 20.17.16 - acorn: 8.14.0 - acorn-walk: 8.3.4 - arg: 4.1.3 - create-require: 1.1.1 - diff: 4.0.2 - make-error: 1.3.6 - typescript: 5.7.3 - v8-compile-cache-lib: 3.0.1 - yn: 3.1.1 - ts-node@10.9.2(@types/node@22.13.0)(typescript@5.7.3): dependencies: '@cspotcode/source-map-support': 0.8.1 @@ -17615,7 +17642,7 @@ snapshots: tslib@2.8.1: {} - tsup@6.7.0(postcss@8.5.1)(ts-node@10.9.2(@types/node@20.17.16)(typescript@4.9.5))(typescript@4.9.5): + tsup@6.7.0(postcss@8.5.1)(ts-node@10.9.2(@types/node@22.13.0)(typescript@4.9.5))(typescript@4.9.5): dependencies: bundle-require: 4.2.1(esbuild@0.17.19) cac: 6.7.14 @@ -17625,7 +17652,7 @@ snapshots: execa: 5.1.1 globby: 11.1.0 joycon: 3.1.1 - postcss-load-config: 3.1.4(postcss@8.5.1)(ts-node@10.9.2(@types/node@20.17.16)(typescript@4.9.5)) + postcss-load-config: 3.1.4(postcss@8.5.1)(ts-node@10.9.2(@types/node@22.13.0)(typescript@4.9.5)) resolve-from: 5.0.0 rollup: 3.29.5 source-map: 0.8.0-beta.0 From 617483fe9c26d607665fcaf79ee26e35d9825d7c Mon Sep 17 00:00:00 2001 From: shadcn Date: Tue, 15 Apr 2025 15:01:20 +0400 Subject: [PATCH 07/18] fix(shadcn): do not throw for empty dir (#7196) * fix(shadcn): do not throw for empty dir * chore: changeset --- .changeset/few-kangaroos-stare.md | 5 +++++ packages/shadcn/src/utils/get-project-info.ts | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) create mode 100644 .changeset/few-kangaroos-stare.md diff --git a/.changeset/few-kangaroos-stare.md b/.changeset/few-kangaroos-stare.md new file mode 100644 index 0000000000..e97e5e12b7 --- /dev/null +++ b/.changeset/few-kangaroos-stare.md @@ -0,0 +1,5 @@ +--- +"shadcn": patch +--- + +do not throw if empty dir diff --git a/packages/shadcn/src/utils/get-project-info.ts b/packages/shadcn/src/utils/get-project-info.ts index 6236b5138c..05f04df821 100644 --- a/packages/shadcn/src/utils/get-project-info.ts +++ b/packages/shadcn/src/utils/get-project-info.ts @@ -154,7 +154,7 @@ export async function getTailwindVersion( cwd: string ): Promise { const [packageInfo, config] = await Promise.all([ - getPackageInfo(cwd), + getPackageInfo(cwd, false), getConfig(cwd), ]) From d1a36d3e178a92ff2538f9e3f2c9b6f7e7e768a7 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 15 Apr 2025 16:30:10 +0400 Subject: [PATCH 08/18] chore(release): version packages (#7198) * chore(release): version packages * fix --------- Co-authored-by: github-actions[bot] Co-authored-by: shadcn --- .changeset/few-kangaroos-stare.md | 5 ----- apps/v4/package.json | 2 +- apps/www/package.json | 2 +- packages/shadcn/CHANGELOG.md | 6 ++++++ packages/shadcn/package.json | 2 +- pnpm-lock.yaml | 4 ++-- 6 files changed, 11 insertions(+), 10 deletions(-) delete mode 100644 .changeset/few-kangaroos-stare.md diff --git a/.changeset/few-kangaroos-stare.md b/.changeset/few-kangaroos-stare.md deleted file mode 100644 index e97e5e12b7..0000000000 --- a/.changeset/few-kangaroos-stare.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"shadcn": patch ---- - -do not throw if empty dir diff --git a/apps/v4/package.json b/apps/v4/package.json index ada439aea4..67dbbd8e6f 100644 --- a/apps/v4/package.json +++ b/apps/v4/package.json @@ -73,7 +73,7 @@ "react-resizable-panels": "^2.1.7", "recharts": "2.15.1", "rimraf": "^6.0.1", - "shadcn": "2.4.0", + "shadcn": "2.4.1", "sonner": "^2.0.0", "tailwind-merge": "^3.0.1", "tailwindcss": "^4.0.7", diff --git a/apps/www/package.json b/apps/www/package.json index 47806d4f1b..da854494c4 100644 --- a/apps/www/package.json +++ b/apps/www/package.json @@ -86,7 +86,7 @@ "react-resizable-panels": "^2.0.22", "react-wrap-balancer": "^0.4.1", "recharts": "2.12.7", - "shadcn": "2.4.0", + "shadcn": "2.4.1", "sharp": "^0.32.6", "sonner": "^1.2.3", "swr": "2.2.6-beta.3", diff --git a/packages/shadcn/CHANGELOG.md b/packages/shadcn/CHANGELOG.md index 08103da282..0ac2f00801 100644 --- a/packages/shadcn/CHANGELOG.md +++ b/packages/shadcn/CHANGELOG.md @@ -1,5 +1,11 @@ # @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 diff --git a/packages/shadcn/package.json b/packages/shadcn/package.json index fd01cc8489..116c858205 100644 --- a/packages/shadcn/package.json +++ b/packages/shadcn/package.json @@ -1,6 +1,6 @@ { "name": "shadcn", - "version": "2.4.0", + "version": "2.4.1", "description": "Add components to your apps.", "publishConfig": { "access": "public" diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 3b34884682..4ca03e9b7b 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -283,7 +283,7 @@ importers: specifier: ^6.0.1 version: 6.0.1 shadcn: - specifier: 2.4.0 + specifier: 2.4.1 version: link:../../packages/shadcn sonner: specifier: ^2.0.0 @@ -542,7 +542,7 @@ importers: specifier: 2.12.7 version: 2.12.7(react-dom@18.3.1(react@18.3.1))(react@18.3.1) shadcn: - specifier: 2.4.0 + specifier: 2.4.1 version: link:../../packages/shadcn sharp: specifier: ^0.32.6 From e3ca257f6e2f1b7b6610942aa01cabfc8b9955ec Mon Sep 17 00:00:00 2001 From: Titouan V <39600279+titouv@users.noreply.github.com> Date: Fri, 18 Apr 2025 08:44:46 +0200 Subject: [PATCH 09/18] chore(www): replace shadcn-ui deprecated mentions to shadcn (#7207) --- apps/www/content/docs/changelog.mdx | 10 +++++----- apps/www/content/docs/installation/gatsby.mdx | 2 +- apps/www/content/docs/installation/react-router.mdx | 2 +- apps/www/content/docs/installation/remix.mdx | 2 +- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/apps/www/content/docs/changelog.mdx b/apps/www/content/docs/changelog.mdx index 1a30b1c151..622be8300f 100644 --- a/apps/www/content/docs/changelog.mdx +++ b/apps/www/content/docs/changelog.mdx @@ -321,7 +321,7 @@ I've been working on a new CLI for the past few weeks. It's a complete rewrite. ### `init` ```bash -npx shadcn-ui@latest init +npx shadcn@latest init ``` When you run the `init` command, you will be asked a few questions to configure `components.json`: @@ -363,7 +363,7 @@ This means you can now use the CLI with any directory structure including `src` ### `add` ```bash -npx shadcn-ui@latest add +npx shadcn@latest add ``` The `add` command is now much more capable. You can now add UI components but also import more complex components (coming soon). @@ -373,7 +373,7 @@ The CLI will automatically resolve all components and dependencies, format them ### `diff` (experimental) ```bash -npx shadcn-ui diff +npx shadcn diff ``` We're also introducing a new `diff` command to help you keep track of upstream updates. @@ -383,7 +383,7 @@ You can use this command to see what has changed in the upstream repository and Run the `diff` command to get a list of components that have updates available: ```bash -npx shadcn-ui diff +npx shadcn diff ``` ```txt @@ -398,7 +398,7 @@ The following components have updates available: Then run `diff [component]` to see the changes: ```bash -npx shadcn-ui diff alert +npx shadcn diff alert ``` ```diff /pl-12/ diff --git a/apps/www/content/docs/installation/gatsby.mdx b/apps/www/content/docs/installation/gatsby.mdx index 030deb1e22..9b6dbf9ff2 100644 --- a/apps/www/content/docs/installation/gatsby.mdx +++ b/apps/www/content/docs/installation/gatsby.mdx @@ -79,7 +79,7 @@ export const onCreateWebpackConfig = ({ actions }) => { ### Run the CLI -Run the `shadcn-ui` init command to setup your project: +Run the `shadcn` init command to setup your project: ```bash npx shadcn@latest init diff --git a/apps/www/content/docs/installation/react-router.mdx b/apps/www/content/docs/installation/react-router.mdx index 684a88432d..5493289d7d 100644 --- a/apps/www/content/docs/installation/react-router.mdx +++ b/apps/www/content/docs/installation/react-router.mdx @@ -13,7 +13,7 @@ npx create-react-router@latest my-app ### Run the CLI -Run the `shadcn-ui` init command to setup your project: +Run the `shadcn` init command to setup your project: ```bash npx shadcn@latest init diff --git a/apps/www/content/docs/installation/remix.mdx b/apps/www/content/docs/installation/remix.mdx index 9b62feae47..dc60d2581a 100644 --- a/apps/www/content/docs/installation/remix.mdx +++ b/apps/www/content/docs/installation/remix.mdx @@ -26,7 +26,7 @@ npx create-remix@latest my-app ### Run the CLI -Run the `shadcn-ui` init command to setup your project: +Run the `shadcn` init command to setup your project: ```bash npx shadcn@latest init From f1e5cc4666ced2166a859660d769ccee16cde46e Mon Sep 17 00:00:00 2001 From: Neeraj Dalal Date: Sat, 19 Apr 2025 14:35:52 +0530 Subject: [PATCH 10/18] =?UTF-8?q?=F0=9F=94=A5=20feat(fix):=20mark=20"tw-an?= =?UTF-8?q?imate-css"=20as=20devDep=20(#6985)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * chore: tweaks to build-registry.mts ~ 1 file 2+ 5- apps/v4/scripts/build-registry.mts * chore: tweaks to index.json ~ 1 file 4+ 9- apps/www/public/r/styles/new-york-v4/index.json * chore: tweaks to registry.json ~ 1 file 221+ 850- apps/v4/registry.json * chore: tweaks to index.json ~ 1 file 47+ 144- apps/www/public/r/index.json * chore: tweaks to registry.json ~ 1 file 852+ 221- apps/v4/registry.json * chore: tweaks to build-registry.mts ~ 1 file 7+ 2- apps/v4/scripts/build-registry.mts * chore: tweaks to build-registry.mts ~ 1 file 2+ 2- apps/v4/scripts/build-registry.mts * chore: tweaks to index.json ~ 1 file 11+ 4- apps/www/public/r/styles/new-york-v4/index.json * chore: tweaks to index.json ~ 1 file 1+ 1- apps/www/public/r/index.json * chore: tweaks to index.json ~ 1 file 143+ 46- apps/www/public/r/index.json * chore: tweaks to update-dependencies.ts ~ 1 file 20+ packages/shadcn/src/utils/updaters/update-dependencies.ts * chore: tweaks to update-dependencies.ts ~ 1 file 1- packages/shadcn/src/utils/updaters/update-dependencies.ts * chore: tweaks to update-dependencies.ts ~ 1 file 19- packages/shadcn/src/utils/updaters/update-dependencies.ts * chore: tweaks to add-components.ts update-dependencies.ts ~ 2 files 21+ 2- packages/shadcn/src/utils/add-components.ts packages/shadcn/src/utils/updaters/update-dependencies.ts * chore: tweaks to update-dependencies.ts ~ 1 file 29+ 28- packages/shadcn/src/utils/updaters/update-dependencies.ts * refactor: remove redundant code tw-animate-css already has accordion animations * chore: tweaks > migrate-icons.ts packages/shadcn/src/migrations/migrate-icons.ts * fix: formatting > add-components.ts update-dependencies.ts packages/shadcn/src/utils/add-components.ts packages/shadcn/src/utils/updaters/update-dependencies.ts * chore: add changeset --------- Co-authored-by: shadcn --- .changeset/spicy-singers-try.md | 5 +++ apps/v4/registry.json | 38 +++------------- apps/v4/scripts/build-registry.mts | 4 +- .../public/r/styles/new-york-v4/index.json | 4 +- .../shadcn/src/migrations/migrate-icons.ts | 2 +- packages/shadcn/src/utils/add-components.ts | 13 ++++-- .../src/utils/updaters/update-dependencies.ts | 44 ++++++++++++++----- 7 files changed, 58 insertions(+), 52 deletions(-) create mode 100644 .changeset/spicy-singers-try.md diff --git a/.changeset/spicy-singers-try.md b/.changeset/spicy-singers-try.md new file mode 100644 index 0000000000..fcbede33bb --- /dev/null +++ b/.changeset/spicy-singers-try.md @@ -0,0 +1,5 @@ +--- +"shadcn": patch +--- + +move tw-animate-css to devDependencies diff --git a/apps/v4/registry.json b/apps/v4/registry.json index b18af6c66d..1c71b11f69 100644 --- a/apps/v4/registry.json +++ b/apps/v4/registry.json @@ -6,10 +6,12 @@ "name": "index", "type": "registry:style", "dependencies": [ - "tw-animate-css", "class-variance-authority", "lucide-react" ], + "devDependencies": [ + "tw-animate-css" + ], "registryDependencies": [ "utils" ], @@ -27,37 +29,7 @@ "path": "registry/new-york-v4/ui/accordion.tsx", "type": "registry:ui" } - ], - "tailwind": { - "config": { - "theme": { - "extend": { - "keyframes": { - "accordion-down": { - "from": { - "height": "0" - }, - "to": { - "height": "var(--radix-accordion-content-height)" - } - }, - "accordion-up": { - "from": { - "height": "var(--radix-accordion-content-height)" - }, - "to": { - "height": "0" - } - } - }, - "animation": { - "accordion-down": "accordion-down 0.2s ease-out", - "accordion-up": "accordion-up 0.2s ease-out" - } - } - } - } - } + ] }, { "name": "alert", @@ -2833,4 +2805,4 @@ ] } ] -} \ No newline at end of file +} diff --git a/apps/v4/scripts/build-registry.mts b/apps/v4/scripts/build-registry.mts index e583049d62..72ed29a20b 100644 --- a/apps/v4/scripts/build-registry.mts +++ b/apps/v4/scripts/build-registry.mts @@ -21,10 +21,12 @@ const registry = { name: "index", type: "registry:style", dependencies: [ - "tw-animate-css", "class-variance-authority", "lucide-react", ], + "devDependencies": [ + "tw-animate-css", + ], registryDependencies: ["utils"], cssVars: {}, files: [], diff --git a/apps/www/public/r/styles/new-york-v4/index.json b/apps/www/public/r/styles/new-york-v4/index.json index 8e85cbd881..3a8ab07687 100644 --- a/apps/www/public/r/styles/new-york-v4/index.json +++ b/apps/www/public/r/styles/new-york-v4/index.json @@ -3,10 +3,12 @@ "name": "index", "type": "registry:style", "dependencies": [ - "tw-animate-css", "class-variance-authority", "lucide-react" ], + "devDependencies": [ + "tw-animate-css" + ], "registryDependencies": [ "utils" ], diff --git a/packages/shadcn/src/migrations/migrate-icons.ts b/packages/shadcn/src/migrations/migrate-icons.ts index 91142c8446..343678ed49 100644 --- a/packages/shadcn/src/migrations/migrate-icons.ts +++ b/packages/shadcn/src/migrations/migrate-icons.ts @@ -98,7 +98,7 @@ export async function migrateIcons(config: Config) { } if (targetLibrary.package) { - await updateDependencies([targetLibrary.package], config, { + await updateDependencies([targetLibrary.package], [], config, { silent: false, }) } diff --git a/packages/shadcn/src/utils/add-components.ts b/packages/shadcn/src/utils/add-components.ts index 20639476c4..444776358b 100644 --- a/packages/shadcn/src/utils/add-components.ts +++ b/packages/shadcn/src/utils/add-components.ts @@ -103,7 +103,7 @@ async function addProjectComponents( silent: options.silent, }) - await updateDependencies(tree.dependencies, config, { + await updateDependencies(tree.dependencies, tree.devDependencies, config, { silent: options.silent, }) await updateFiles(tree.files, config, { @@ -213,9 +213,14 @@ async function addWorkspaceComponents( } // 4. Update dependencies. - await updateDependencies(component.dependencies, targetConfig, { - silent: true, - }) + await updateDependencies( + component.dependencies, + component.devDependencies, + targetConfig, + { + silent: true, + } + ) // 5. Update files. const files = await updateFiles(component.files, targetConfig, { diff --git a/packages/shadcn/src/utils/updaters/update-dependencies.ts b/packages/shadcn/src/utils/updaters/update-dependencies.ts index e4f0570f98..1006b48548 100644 --- a/packages/shadcn/src/utils/updaters/update-dependencies.ts +++ b/packages/shadcn/src/utils/updaters/update-dependencies.ts @@ -9,13 +9,16 @@ import prompts from "prompts" export async function updateDependencies( dependencies: RegistryItem["dependencies"], + devDependencies: RegistryItem["devDependencies"], config: Config, options: { silent?: boolean } ) { dependencies = Array.from(new Set(dependencies)) - if (!dependencies?.length) { + devDependencies = Array.from(new Set(devDependencies)) + + if (!dependencies?.length && !devDependencies?.length) { return } @@ -59,17 +62,34 @@ export async function updateDependencies( dependenciesSpinner?.start() - await execa( - packageManager, - [ - packageManager === "npm" ? "install" : "add", - ...(packageManager === "npm" && flag ? [`--${flag}`] : []), - ...dependencies, - ], - { - cwd: config.resolvedPaths.cwd, - } - ) + if (dependencies?.length) { + await execa( + packageManager, + [ + packageManager === "npm" ? "install" : "add", + ...(packageManager === "npm" && flag ? [`--${flag}`] : []), + ...dependencies, + ], + { + cwd: config.resolvedPaths.cwd, + } + ) + } + + if (devDependencies?.length) { + await execa( + packageManager, + [ + packageManager === "npm" ? "install" : "add", + ...(packageManager === "npm" && flag ? [`--${flag}`] : []), + "-D", + ...devDependencies, + ], + { + cwd: config.resolvedPaths.cwd, + } + ) + } dependenciesSpinner?.succeed() } From d0306774fe0ecc1eae9ef1e918bf7862e866a9e8 Mon Sep 17 00:00:00 2001 From: shadcn Date: Sat, 19 Apr 2025 13:31:04 +0400 Subject: [PATCH 11/18] feat(shadcn): resolve imports from anywhere (#7220) * feat(shadcn): resolve imports from anywhere * fix: type errors * fix: add debug * feat: handle root paths * fix: src prefix * fix: tests * chore: changeset --- .changeset/funny-coins-remember.md | 5 + .../shadcn/src/utils/updaters/update-files.ts | 248 ++++++++++++- .../test/utils/updaters/update-files.test.ts | 340 ++++++++++++++++++ 3 files changed, 590 insertions(+), 3 deletions(-) create mode 100644 .changeset/funny-coins-remember.md diff --git a/.changeset/funny-coins-remember.md b/.changeset/funny-coins-remember.md new file mode 100644 index 0000000000..5507cb1327 --- /dev/null +++ b/.changeset/funny-coins-remember.md @@ -0,0 +1,5 @@ +--- +"shadcn": minor +--- + +resolve imports from anywhere diff --git a/packages/shadcn/src/utils/updaters/update-files.ts b/packages/shadcn/src/utils/updaters/update-files.ts index 5ad751cbab..5aab4efde2 100644 --- a/packages/shadcn/src/utils/updaters/update-files.ts +++ b/packages/shadcn/src/utils/updaters/update-files.ts @@ -1,4 +1,5 @@ import { existsSync, promises as fs } from "fs" +import { tmpdir } from "os" import path, { basename } from "path" import { getRegistryBaseColor } from "@/src/registry/api" import { RegistryItem, registryItemFileSchema } from "@/src/registry/schema" @@ -6,6 +7,7 @@ import { Config } from "@/src/utils/get-config" import { ProjectInfo, getProjectInfo } from "@/src/utils/get-project-info" import { highlighter } from "@/src/utils/highlighter" import { logger } from "@/src/utils/logger" +import { resolveImport } from "@/src/utils/resolve-import" import { spinner } from "@/src/utils/spinner" import { transform } from "@/src/utils/transformers" import { transformCssVars } from "@/src/utils/transformers/transform-css-vars" @@ -14,6 +16,8 @@ import { transformImport } from "@/src/utils/transformers/transform-import" import { transformRsc } from "@/src/utils/transformers/transform-rsc" import { transformTwPrefixes } from "@/src/utils/transformers/transform-tw-prefix" import prompts from "prompts" +import { Project, ScriptKind } from "ts-morph" +import { loadConfig } from "tsconfig-paths" import { z } from "zod" export async function updateFiles( @@ -50,9 +54,9 @@ export async function updateFiles( getRegistryBaseColor(config.tailwind.baseColor), ]) - const filesCreated = [] - const filesUpdated = [] - const filesSkipped = [] + let filesCreated: string[] = [] + let filesUpdated: string[] = [] + let filesSkipped: string[] = [] for (const file of files) { if (!file.content) { @@ -153,11 +157,25 @@ export async function updateFiles( : filesCreated.push(path.relative(config.resolvedPaths.cwd, filePath)) } + const allFiles = [...filesCreated, ...filesUpdated, ...filesSkipped] + const updatedFiles = await resolveImports(allFiles, config) + + // Let's update filesUpdated with the updated files. + filesUpdated.push(...updatedFiles) + + // If a file is in filesCreated and filesUpdated, we should remove it from filesUpdated. + filesUpdated = filesUpdated.filter((file) => !filesCreated.includes(file)) + const hasUpdatedFiles = filesCreated.length || filesUpdated.length if (!hasUpdatedFiles && !filesSkipped.length) { filesCreatedSpinner?.info("No files updated.") } + // Remove duplicates. + filesCreated = Array.from(new Set(filesCreated)) + filesUpdated = Array.from(new Set(filesUpdated)) + filesSkipped = Array.from(new Set(filesSkipped)) + if (filesCreated.length) { filesCreatedSpinner?.succeed( `Created ${filesCreated.length} ${ @@ -371,3 +389,227 @@ export function resolvePageTarget( return "" } + +async function resolveImports(filePaths: string[], config: Config) { + const project = new Project({ + compilerOptions: {}, + }) + const projectInfo = await getProjectInfo(config.resolvedPaths.cwd) + const tsConfig = await loadConfig(config.resolvedPaths.cwd) + const updatedFiles = [] + + if (!projectInfo || tsConfig.resultType === "failed") { + return [] + } + + for (const filepath of filePaths) { + const resolvedPath = path.resolve(config.resolvedPaths.cwd, filepath) + + // Check if the file exists. + if (!existsSync(resolvedPath)) { + continue + } + + const content = await fs.readFile(resolvedPath, "utf-8") + + const dir = await fs.mkdtemp(path.join(tmpdir(), "shadcn-")) + const sourceFile = project.createSourceFile( + path.join(dir, basename(resolvedPath)), + content, + { + scriptKind: ScriptKind.TSX, + } + ) + + const importDeclarations = sourceFile.getImportDeclarations() + for (const importDeclaration of importDeclarations) { + const moduleSpecifier = importDeclaration.getModuleSpecifierValue() + + // Filter out non-local imports. + if ( + projectInfo?.aliasPrefix && + !moduleSpecifier.startsWith(`${projectInfo.aliasPrefix}/`) + ) { + continue + } + + // Find the probable import file path. + // This is where we expect to find the file on disk. + const probableImportFilePath = await resolveImport( + moduleSpecifier, + tsConfig + ) + + if (!probableImportFilePath) { + continue + } + + // Find the actual import file path. + // This is the path where the file has been installed. + const resolvedImportFilePath = resolveModuleByProbablePath( + probableImportFilePath, + filePaths, + config + ) + + if (!resolvedImportFilePath) { + continue + } + + // Convert the resolved import file path to an aliased import. + const newImport = toAliasedImport( + resolvedImportFilePath, + config, + projectInfo + ) + + if (!newImport || newImport === moduleSpecifier) { + continue + } + + importDeclaration.setModuleSpecifier(newImport) + + // Write the updated content to the file. + await fs.writeFile(resolvedPath, sourceFile.getFullText(), "utf-8") + + // Track the updated file. + updatedFiles.push(filepath) + } + } + + return updatedFiles +} + +/** + * Given an absolute "probable" import path (no ext), + * plus an array of absolute file paths you already know about, + * return 0–N matches (best match first), and also check disk for any missing ones. + */ +export function resolveModuleByProbablePath( + probableImportFilePath: string, + files: string[], + config: Config, + extensions: string[] = [".tsx", ".ts", ".js", ".jsx", ".css"] +) { + const cwd = path.normalize(config.resolvedPaths.cwd) + + // 1) Build a set of POSIX-normalized, project-relative files + const relativeFiles = files.map((f) => f.split(path.sep).join(path.posix.sep)) + const fileSet = new Set(relativeFiles) + + // 2) Strip any existing extension off the absolute base path + const extInPath = path.extname(probableImportFilePath) + const hasExt = extInPath !== "" + const absBase = hasExt + ? probableImportFilePath.slice(0, -extInPath.length) + : probableImportFilePath + + // 3) Compute the project-relative "base" directory for strong matching + const relBaseRaw = path.relative(cwd, absBase) + const relBase = relBaseRaw.split(path.sep).join(path.posix.sep) + + // 4) Decide which extensions to try + const tryExts = hasExt ? [extInPath] : extensions + + // 5) Collect candidates + const candidates = new Set() + + // 5a) Fast‑path: [base + ext] and [base/index + ext] + for (const e of tryExts) { + const absCand = absBase + e + const relCand = path.posix.normalize(path.relative(cwd, absCand)) + if (fileSet.has(relCand) || existsSync(absCand)) { + candidates.add(relCand) + } + + const absIdx = path.join(absBase, `index${e}`) + const relIdx = path.posix.normalize(path.relative(cwd, absIdx)) + if (fileSet.has(relIdx) || existsSync(absIdx)) { + candidates.add(relIdx) + } + } + + // 5b) Fallback: scan known files by basename + const name = path.basename(absBase) + for (const f of relativeFiles) { + if (tryExts.some((e) => f.endsWith(`/${name}${e}`))) { + candidates.add(f) + } + } + + // 6) If no matches, bail + if (candidates.size === 0) return null + + // 7) Sort by (1) extension priority, then (2) "strong" base match + const sorted = Array.from(candidates).sort((a, b) => { + // a) extension order + const aExt = path.posix.extname(a) + const bExt = path.posix.extname(b) + const ord = tryExts.indexOf(aExt) - tryExts.indexOf(bExt) + if (ord !== 0) return ord + // b) strong match if path starts with relBase + const aStrong = relBase && a.startsWith(relBase) ? -1 : 1 + const bStrong = relBase && b.startsWith(relBase) ? -1 : 1 + return aStrong - bStrong + }) + + // 8) Return the first (best) candidate + return sorted[0] +} + +export function toAliasedImport( + filePath: string, + config: Config, + projectInfo: ProjectInfo +): string | null { + const abs = path.normalize(path.join(config.resolvedPaths.cwd, filePath)) + + // 1️⃣ Find the longest matching alias root in resolvedPaths + // e.g. key="ui", root="/…/components/ui" beats key="components" + const matches = Object.entries(config.resolvedPaths) + .filter( + ([, root]) => root && abs.startsWith(path.normalize(root + path.sep)) + ) + .sort((a, b) => b[1].length - a[1].length) + + if (matches.length === 0) { + return null + } + const [aliasKey, rootDir] = matches[0] + + // 2️⃣ Compute the path UNDER that root + let rel = path.relative(rootDir, abs) + // force POSIX-style separators + rel = rel.split(path.sep).join("/") // e.g. "button/index.tsx" + + // 3️⃣ Strip code-file extensions, keep others (css, json, etc.) + const ext = path.posix.extname(rel) + const codeExts = [".ts", ".tsx", ".js", ".jsx"] + const keepExt = codeExts.includes(ext) ? "" : ext + let noExt = rel.slice(0, rel.length - ext.length) + + // 4️⃣ Collapse "/index" to its directory + if (noExt.endsWith("/index")) { + noExt = noExt.slice(0, -"/index".length) + } + + // 5️⃣ Build the aliased path + // config.aliases[aliasKey] is e.g. "@/components/ui" + const aliasBase = + aliasKey === "cwd" + ? projectInfo.aliasPrefix + : config.aliases[aliasKey as keyof typeof config.aliases] + if (!aliasBase) { + return null + } + // if noExt is empty (i.e. file was exactly at the root), we import the root + let suffix = noExt === "" ? "" : `/${noExt}` + + // Rremove /src from suffix. + // Alias will handle this. + suffix = suffix.replace("/src", "") + + // 6️⃣ Prepend the prefix from projectInfo (e.g. "@") if needed + // but usually config.aliases already include it. + return `${aliasBase}${suffix}${keepExt}` +} diff --git a/packages/shadcn/test/utils/updaters/update-files.test.ts b/packages/shadcn/test/utils/updaters/update-files.test.ts index 3dfbcf554c..e0b65a7c2c 100644 --- a/packages/shadcn/test/utils/updaters/update-files.test.ts +++ b/packages/shadcn/test/utils/updaters/update-files.test.ts @@ -1,3 +1,4 @@ +import { existsSync } from "fs" import path from "path" import { afterAll, afterEach, describe, expect, test, vi } from "vitest" @@ -5,7 +6,9 @@ import { getConfig } from "../../../src/utils/get-config" import { findCommonRoot, resolveFilePath, + resolveModuleByProbablePath, resolveNestedFilePath, + toAliasedImport, updateFiles, } from "../../../src/utils/updaters/update-files" @@ -809,3 +812,340 @@ return
Hello World
`) }) }) + +describe("resolveModuleByProbablePath", () => { + test("should resolve exact file match in provided files list", () => { + const files = [ + "components/button.tsx", + "components/card.tsx", + "lib/utils.ts", + ] + const config = { + resolvedPaths: { + cwd: "/foo/bar", + }, + } + expect( + resolveModuleByProbablePath("/foo/bar/components/button", files, config) + ).toBe("components/button.tsx") + }) + + test("should resolve index file", () => { + const files = ["components/button/index.tsx", "components/card.tsx"] + const config = { + resolvedPaths: { + cwd: "/foo/bar", + }, + } + expect( + resolveModuleByProbablePath("/foo/bar/components/button", files, config) + ).toBe("components/button/index.tsx") + }) + + test("should try different extensions", () => { + const files = ["components/button.jsx", "components/card.tsx"] + const config = { + resolvedPaths: { + cwd: "/foo/bar", + }, + } + expect( + resolveModuleByProbablePath("/foo/bar/components/button", files, config) + ).toBe("components/button.jsx") + }) + + test("should fallback to basename matching", () => { + const files = ["components/ui/button.tsx", "components/card.tsx"] + const config = { + resolvedPaths: { + cwd: "/foo/bar", + }, + } + expect( + resolveModuleByProbablePath("/foo/bar/components/button", files, config) + ).toBe("components/ui/button.tsx") + }) + + test("should return null when file not found", () => { + const files = ["components/card.tsx", "lib/utils.ts"] + const config = { + resolvedPaths: { + cwd: "/foo/bar", + }, + } + expect( + resolveModuleByProbablePath("/foo/bar/components/button", files, config) + ).toBeNull() + }) + + test("should sort by extension priority", () => { + const files = [ + "components/button.jsx", + "components/button.tsx", + "components/button.js", + ] + const config = { + resolvedPaths: { + cwd: "/foo/bar", + }, + } + expect( + resolveModuleByProbablePath("/foo/bar/components/button", files, config, [ + ".tsx", + ".jsx", + ".js", + ]) + ).toBe("components/button.tsx") + }) + + test("should preserve extension if specified in path", () => { + const files = ["components/button.tsx", "components/button.css"] + const config = { + resolvedPaths: { + cwd: "/foo/bar", + }, + } + expect( + resolveModuleByProbablePath( + "/foo/bar/components/button.css", + files, + config + ) + ).toBe("components/button.css") + }) +}) + +describe("toAliasedImport", () => { + test("should convert components path to aliased import", () => { + const filePath = "components/button.tsx" + const config = { + resolvedPaths: { + cwd: "/foo/bar", + components: "/foo/bar/components", + ui: "/foo/bar/components/ui", + lib: "/foo/bar/lib", + }, + aliases: { + components: "@/components", + ui: "@/components/ui", + lib: "@/lib", + }, + } + const projectInfo = { + aliasPrefix: "@", + } + expect(toAliasedImport(filePath, config, projectInfo)).toBe( + "@/components/button" + ) + }) + + test("should convert ui path to aliased import", () => { + const filePath = "components/ui/button.tsx" + const config = { + resolvedPaths: { + cwd: "/foo/bar", + components: "/foo/bar/components", + ui: "/foo/bar/components/ui", + lib: "/foo/bar/lib", + }, + aliases: { + components: "@/components", + ui: "@/components/ui", + lib: "@/lib", + }, + } + const projectInfo = { + aliasPrefix: "@", + } + expect(toAliasedImport(filePath, config, projectInfo)).toBe( + "@/components/ui/button" + ) + }) + + test("should collapse index files", () => { + const filePath = "components/ui/button/index.tsx" + const config = { + resolvedPaths: { + cwd: "/foo/bar", + components: "/foo/bar/components", + ui: "/foo/bar/components/ui", + lib: "/foo/bar/lib", + }, + aliases: { + components: "@/components", + ui: "@/components/ui", + lib: "@/lib", + }, + } + const projectInfo = { + aliasPrefix: "@", + } + expect(toAliasedImport(filePath, config, projectInfo)).toBe( + "@/components/ui/button" + ) + }) + + test("should return null when no matching alias found", () => { + const filePath = "src/pages/index.tsx" + const config = { + resolvedPaths: { + cwd: "/foo/bar", + components: "/foo/bar/components", + ui: "/foo/bar/components/ui", + lib: "/foo/bar/lib", + }, + aliases: { + components: "@/components", + ui: "@/components/ui", + lib: "@/lib", + }, + } + const projectInfo = { + aliasPrefix: "@", + } + expect(toAliasedImport(filePath, config, projectInfo)).toBe("@/pages") + }) + + test("should handle nested directories", () => { + const filePath = "components/forms/inputs/text-input.tsx" + const config = { + resolvedPaths: { + cwd: "/foo/bar", + components: "/foo/bar/components", + ui: "/foo/bar/components/ui", + lib: "/foo/bar/lib", + }, + aliases: { + components: "@/components", + ui: "@/components/ui", + lib: "@/lib", + }, + } + const projectInfo = { + aliasPrefix: "@", + } + expect(toAliasedImport(filePath, config, projectInfo)).toBe( + "@/components/forms/inputs/text-input" + ) + }) + + test("should keep non-code file extensions", () => { + const filePath = "components/styles/theme.css" + const config = { + resolvedPaths: { + cwd: "/foo/bar", + components: "/foo/bar/components", + ui: "/foo/bar/components/ui", + lib: "/foo/bar/lib", + }, + aliases: { + components: "@/components", + ui: "@/components/ui", + lib: "@/lib", + }, + } + const projectInfo = { + aliasPrefix: "@", + } + expect(toAliasedImport(filePath, config, projectInfo)).toBe( + "@/components/styles/theme.css" + ) + }) + + test("should prefer longer matching paths", () => { + const filePath = "components/ui/button.tsx" + const config = { + resolvedPaths: { + cwd: "/foo/bar", + components: "/foo/bar/components", + ui: "/foo/bar/components/ui", + }, + aliases: { + components: "@/components", + ui: "@/ui", + }, + } + const projectInfo = { + aliasPrefix: "@", + } + expect(toAliasedImport(filePath, config, projectInfo)).toBe("@/ui/button") + }) + + test("should support tilde (~) alias prefix", () => { + const filePath = "components/button.tsx" + const config = { + resolvedPaths: { + cwd: "/foo/bar", + components: "/foo/bar/components", + }, + aliases: { + components: "~components", + }, + } + const projectInfo = { + aliasPrefix: "~", + } + expect(toAliasedImport(filePath, config, projectInfo)).toBe( + "~components/button" + ) + }) + + test("should support @shadcn alias prefix", () => { + const filePath = "components/ui/button.tsx" + const config = { + resolvedPaths: { + cwd: "/foo/bar", + components: "/foo/bar/components", + ui: "/foo/bar/components/ui", + }, + aliases: { + components: "@shadcn/components", + ui: "@shadcn/ui", + }, + } + const projectInfo = { + aliasPrefix: "@shadcn", + } + expect(toAliasedImport(filePath, config, projectInfo)).toBe( + "@shadcn/ui/button" + ) + }) + + test("should support ~cn alias prefix", () => { + const filePath = "lib/utils/index.tsx" + const config = { + resolvedPaths: { + cwd: "/foo/bar", + lib: "/foo/bar/lib", + }, + aliases: { + lib: "~cn/lib", + }, + } + const projectInfo = { + aliasPrefix: "~cn", + } + expect(toAliasedImport(filePath, config, projectInfo)).toBe("~cn/lib/utils") + }) + + test("should use project alias prefix when aliasKey is cwd", () => { + const filePath = "src/pages/home.tsx" + const config = { + resolvedPaths: { + cwd: "/foo/bar", + components: "/foo/bar/components", + ui: "/foo/bar/components/ui", + lib: "/foo/bar/lib", + }, + aliases: { + components: "@/components", + ui: "@/components/ui", + lib: "@/lib", + }, + } + const projectInfo = { + aliasPrefix: "@", + } + expect(toAliasedImport(filePath, config, projectInfo)).toBe("@/pages/home") + }) +}) From 6f702f5fbf2b82a388e7da6ea08bcc84c2ec19c6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=BF=B7=E6=B8=A1?= Date: Tue, 22 Apr 2025 03:36:36 +0800 Subject: [PATCH 12/18] fix: Add `npm:` specifier when install dependencies with Deno (#6899) * fix: Add `npm:` specifier when install dependencies with Deno * chore: changeset --------- Co-authored-by: shadcn --- .changeset/warm-taxis-search.md | 5 +++++ packages/shadcn/src/utils/updaters/update-dependencies.ts | 8 ++++++-- 2 files changed, 11 insertions(+), 2 deletions(-) create mode 100644 .changeset/warm-taxis-search.md diff --git a/.changeset/warm-taxis-search.md b/.changeset/warm-taxis-search.md new file mode 100644 index 0000000000..c55dbc0af8 --- /dev/null +++ b/.changeset/warm-taxis-search.md @@ -0,0 +1,5 @@ +--- +"shadcn": patch +--- + +add deno support diff --git a/packages/shadcn/src/utils/updaters/update-dependencies.ts b/packages/shadcn/src/utils/updaters/update-dependencies.ts index 1006b48548..25925d5a61 100644 --- a/packages/shadcn/src/utils/updaters/update-dependencies.ts +++ b/packages/shadcn/src/utils/updaters/update-dependencies.ts @@ -68,7 +68,9 @@ export async function updateDependencies( [ packageManager === "npm" ? "install" : "add", ...(packageManager === "npm" && flag ? [`--${flag}`] : []), - ...dependencies, + ...(packageManager === "deno" + ? dependencies.map((dep) => `npm:${dep}`) + : dependencies), ], { cwd: config.resolvedPaths.cwd, @@ -83,7 +85,9 @@ export async function updateDependencies( packageManager === "npm" ? "install" : "add", ...(packageManager === "npm" && flag ? [`--${flag}`] : []), "-D", - ...devDependencies, + ...(packageManager === "deno" + ? devDependencies.map((dep) => `npm:${dep}`) + : devDependencies), ], { cwd: config.resolvedPaths.cwd, From e8468793fcffba0d42db94ec4711d3e5997103ae Mon Sep 17 00:00:00 2001 From: shadcn Date: Tue, 22 Apr 2025 05:07:56 +0400 Subject: [PATCH 13/18] chore: temporarily move tw-animate-css to dependencies --- apps/v4/registry.json | 4 +--- apps/v4/scripts/build-registry.mts | 2 -- apps/www/public/r/styles/new-york-v4/index.json | 4 +--- 3 files changed, 2 insertions(+), 8 deletions(-) diff --git a/apps/v4/registry.json b/apps/v4/registry.json index 1c71b11f69..0c3d1bb725 100644 --- a/apps/v4/registry.json +++ b/apps/v4/registry.json @@ -7,9 +7,7 @@ "type": "registry:style", "dependencies": [ "class-variance-authority", - "lucide-react" - ], - "devDependencies": [ + "lucide-react", "tw-animate-css" ], "registryDependencies": [ diff --git a/apps/v4/scripts/build-registry.mts b/apps/v4/scripts/build-registry.mts index 72ed29a20b..d0673e8cc2 100644 --- a/apps/v4/scripts/build-registry.mts +++ b/apps/v4/scripts/build-registry.mts @@ -23,8 +23,6 @@ const registry = { dependencies: [ "class-variance-authority", "lucide-react", - ], - "devDependencies": [ "tw-animate-css", ], registryDependencies: ["utils"], diff --git a/apps/www/public/r/styles/new-york-v4/index.json b/apps/www/public/r/styles/new-york-v4/index.json index 3a8ab07687..ca5bd73ff1 100644 --- a/apps/www/public/r/styles/new-york-v4/index.json +++ b/apps/www/public/r/styles/new-york-v4/index.json @@ -4,9 +4,7 @@ "type": "registry:style", "dependencies": [ "class-variance-authority", - "lucide-react" - ], - "devDependencies": [ + "lucide-react", "tw-animate-css" ], "registryDependencies": [ From 9ad24d6a16bf780f2ba9000dab4557276faf5ecc Mon Sep 17 00:00:00 2001 From: Richard Szalay Date: Tue, 22 Apr 2025 21:20:00 +1000 Subject: [PATCH 14/18] chore(shadcn): add update-dependencies tests (#7067) --- .../src/utils/updaters/update-dependencies.ts | 2 +- .../test/fixtures/project-deno/deno.json | 1 + .../test/fixtures/project-deno/deno.lock | 0 .../project-npm-react19/package-lock.json | 13 ++ .../fixtures/project-npm-react19/package.json | 10 ++ .../updaters/update-dependencies.test.ts | 139 ++++++++++++++++++ 6 files changed, 164 insertions(+), 1 deletion(-) create mode 100644 packages/shadcn/test/fixtures/project-deno/deno.json create mode 100644 packages/shadcn/test/fixtures/project-deno/deno.lock create mode 100644 packages/shadcn/test/fixtures/project-npm-react19/package-lock.json create mode 100644 packages/shadcn/test/fixtures/project-npm-react19/package.json create mode 100644 packages/shadcn/test/utils/updaters/update-dependencies.test.ts diff --git a/packages/shadcn/src/utils/updaters/update-dependencies.ts b/packages/shadcn/src/utils/updaters/update-dependencies.ts index 25925d5a61..a12f9799be 100644 --- a/packages/shadcn/src/utils/updaters/update-dependencies.ts +++ b/packages/shadcn/src/utils/updaters/update-dependencies.ts @@ -99,7 +99,7 @@ export async function updateDependencies( } function isUsingReact19(config: Config) { - const packageInfo = getPackageInfo(config.resolvedPaths.cwd) + const packageInfo = getPackageInfo(config.resolvedPaths.cwd, false) if (!packageInfo?.dependencies?.react) { return false diff --git a/packages/shadcn/test/fixtures/project-deno/deno.json b/packages/shadcn/test/fixtures/project-deno/deno.json new file mode 100644 index 0000000000..9e26dfeeb6 --- /dev/null +++ b/packages/shadcn/test/fixtures/project-deno/deno.json @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/packages/shadcn/test/fixtures/project-deno/deno.lock b/packages/shadcn/test/fixtures/project-deno/deno.lock new file mode 100644 index 0000000000..e69de29bb2 diff --git a/packages/shadcn/test/fixtures/project-npm-react19/package-lock.json b/packages/shadcn/test/fixtures/project-npm-react19/package-lock.json new file mode 100644 index 0000000000..9b6d3cd8de --- /dev/null +++ b/packages/shadcn/test/fixtures/project-npm-react19/package-lock.json @@ -0,0 +1,13 @@ +{ + "name": "test-cli-npm-project", + "version": "1.0.0", + "lockfileVersion": 2, + "requires": true, + "packages": { + "": { + "name": "npm-project", + "version": "1.0.0", + "license": "MIT" + } + } +} diff --git a/packages/shadcn/test/fixtures/project-npm-react19/package.json b/packages/shadcn/test/fixtures/project-npm-react19/package.json new file mode 100644 index 0000000000..61ef91b3c7 --- /dev/null +++ b/packages/shadcn/test/fixtures/project-npm-react19/package.json @@ -0,0 +1,10 @@ +{ + "name": "test-cli-project-npm", + "version": "1.0.0", + "main": "index.js", + "author": "shadcn", + "license": "MIT", + "dependencies": { + "react": "19.0.0" + } +} diff --git a/packages/shadcn/test/utils/updaters/update-dependencies.test.ts b/packages/shadcn/test/utils/updaters/update-dependencies.test.ts new file mode 100644 index 0000000000..7e0c36e682 --- /dev/null +++ b/packages/shadcn/test/utils/updaters/update-dependencies.test.ts @@ -0,0 +1,139 @@ +import { vi, describe, afterEach, test, expect } from "vitest" +import { execa } from "execa" +import prompts from "prompts" +import { updateDependencies } from "../../../src/utils/updaters/update-dependencies" +import path from "path" + +vi.mock("execa") +vi.mock("prompts") + +describe("updateDependencies", () => { + afterEach(() => { + vi.restoreAllMocks() + }) + + test.each([ + { + description: "npm without react 19 includes no additional flags", + options: { silent: true }, + dependencies: ["first", "second", "third"], + devDependencies: ["fourth"], + config: { + resolvedPaths: { + cwd: path.resolve(__dirname, "../../fixtures/project-npm") + } + }, + expectedPackageManager: "npm", + expectedArgs: ["install", "first", "second", "third"], + expectedDevArgs: ["install", "-D", "fourth"] + }, + { + description: "npm with react 19 applies force prompt when silent", + options: { silent: true }, + dependencies: ["first", "second", "third"], + devDependencies: ["fourth"], + config: { + resolvedPaths: { + cwd: path.resolve(__dirname, "../../fixtures/project-npm-react19") + } + }, + expectedPackageManager: "npm", + expectedArgs: ["install", "--force", "first", "second", "third"], + expectedDevArgs: ["install", "--force", "-D", "fourth"] + }, + { + description: "npm with react 19 prompts for flag when not silent", + flagPrompt: "legacy-peer-deps", + dependencies: ["first", "second", "third"], + devDependencies: ["fourth"], + config: { + resolvedPaths: { + cwd: path.resolve(__dirname, "../../fixtures/project-npm-react19") + } + }, + expectedPackageManager: "npm", + expectedArgs: ["install", "--legacy-peer-deps", "first", "second", "third"], + expectedDevArgs: ["install", "--legacy-peer-deps", "-D", "fourth"] + }, + { + description: "deno uses npm: package prefix", + dependencies: ["first", "second", "third"], + devDependencies: ["fourth"], + config: { + resolvedPaths: { + cwd: path.resolve(__dirname, "../../fixtures/project-deno") + } + }, + expectedPackageManager: "deno", + expectedArgs: ["add", "npm:first", "npm:second", "npm:third"], + expectedDevArgs: ["add", "-D", "npm:fourth"] + }, + { + description: "bun uses bun", + dependencies: ["first", "second", "third"], + devDependencies: ["fourth"], + config: { + resolvedPaths: { + cwd: path.resolve(__dirname, "../../fixtures/project-bun") + } + }, + expectedPackageManager: "bun", + expectedArgs: ["add", "first", "second", "third"], + expectedDevArgs: ["add", "-D", "fourth"] + }, + { + description: "pnpm uses pnpm", + dependencies: ["first", "second", "third"], + devDependencies: ["fourth"], + config: { + resolvedPaths: { + cwd: path.resolve(__dirname, "../../fixtures/project-pnpm") + } + }, + expectedPackageManager: "pnpm", + expectedArgs: ["add", "first", "second", "third"], + expectedDevArgs: ["add", "-D", "fourth"] + }, + { + description: "deduplicates input dependencies", + options: { silent: true }, + dependencies: ["first", "first"], + devDependencies: ["second", "second"], + config: { + resolvedPaths: { + cwd: path.resolve(__dirname, "../../fixtures/project-npm") + } + }, + expectedPackageManager: "npm", + expectedArgs: ["install", "first"], + expectedDevArgs: ["install", "-D", "second"] + } + ])("$description", async ({ options, flagPrompt, config, dependencies, devDependencies, expectedPackageManager, expectedArgs, expectedDevArgs }) => { + + vi.mocked(prompts).mockResolvedValue({ flag: flagPrompt }) + + await updateDependencies( + dependencies, + devDependencies, + config, + options ?? {} + ) + + if (flagPrompt) { + expect(prompts).toHaveBeenCalled() + } + + + expect(execa).toHaveBeenCalledWith( + expectedPackageManager, + expectedArgs, + { cwd: config?.resolvedPaths.cwd } + ) + + expect(execa).toHaveBeenCalledWith( + expectedPackageManager, + expectedDevArgs, + { cwd: config?.resolvedPaths.cwd } + ) + }) +}) \ No newline at end of file From 11267f2fed873954b2ffdd83908f729e3db1604a Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 23 Apr 2025 16:28:59 +0400 Subject: [PATCH 15/18] chore(release): version packages (#7228) * chore(release): version packages * deps: update pnpm lock --------- Co-authored-by: github-actions[bot] Co-authored-by: shadcn --- .changeset/funny-coins-remember.md | 5 ----- .changeset/spicy-singers-try.md | 5 ----- .changeset/warm-taxis-search.md | 5 ----- apps/v4/package.json | 2 +- apps/www/package.json | 2 +- packages/shadcn/CHANGELOG.md | 12 ++++++++++++ packages/shadcn/package.json | 2 +- pnpm-lock.yaml | 4 ++-- 8 files changed, 17 insertions(+), 20 deletions(-) delete mode 100644 .changeset/funny-coins-remember.md delete mode 100644 .changeset/spicy-singers-try.md delete mode 100644 .changeset/warm-taxis-search.md diff --git a/.changeset/funny-coins-remember.md b/.changeset/funny-coins-remember.md deleted file mode 100644 index 5507cb1327..0000000000 --- a/.changeset/funny-coins-remember.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"shadcn": minor ---- - -resolve imports from anywhere diff --git a/.changeset/spicy-singers-try.md b/.changeset/spicy-singers-try.md deleted file mode 100644 index fcbede33bb..0000000000 --- a/.changeset/spicy-singers-try.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"shadcn": patch ---- - -move tw-animate-css to devDependencies diff --git a/.changeset/warm-taxis-search.md b/.changeset/warm-taxis-search.md deleted file mode 100644 index c55dbc0af8..0000000000 --- a/.changeset/warm-taxis-search.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"shadcn": patch ---- - -add deno support diff --git a/apps/v4/package.json b/apps/v4/package.json index 67dbbd8e6f..9cefbae84a 100644 --- a/apps/v4/package.json +++ b/apps/v4/package.json @@ -73,7 +73,7 @@ "react-resizable-panels": "^2.1.7", "recharts": "2.15.1", "rimraf": "^6.0.1", - "shadcn": "2.4.1", + "shadcn": "2.5.0", "sonner": "^2.0.0", "tailwind-merge": "^3.0.1", "tailwindcss": "^4.0.7", diff --git a/apps/www/package.json b/apps/www/package.json index da854494c4..1c7aa843bd 100644 --- a/apps/www/package.json +++ b/apps/www/package.json @@ -86,7 +86,7 @@ "react-resizable-panels": "^2.0.22", "react-wrap-balancer": "^0.4.1", "recharts": "2.12.7", - "shadcn": "2.4.1", + "shadcn": "2.5.0", "sharp": "^0.32.6", "sonner": "^1.2.3", "swr": "2.2.6-beta.3", diff --git a/packages/shadcn/CHANGELOG.md b/packages/shadcn/CHANGELOG.md index 0ac2f00801..d72d1e80ab 100644 --- a/packages/shadcn/CHANGELOG.md +++ b/packages/shadcn/CHANGELOG.md @@ -1,5 +1,17 @@ # @shadcn/ui +## 2.5.0 + +### Minor Changes + +- [#7220](https://github.com/shadcn-ui/ui/pull/7220) [`d0306774fe0ecc1eae9ef1e918bf7862e866a9e8`](https://github.com/shadcn-ui/ui/commit/d0306774fe0ecc1eae9ef1e918bf7862e866a9e8) Thanks [@shadcn](https://github.com/shadcn)! - resolve imports from anywhere + +### Patch Changes + +- [#6985](https://github.com/shadcn-ui/ui/pull/6985) [`f1e5cc4666ced2166a859660d769ccee16cde46e`](https://github.com/shadcn-ui/ui/commit/f1e5cc4666ced2166a859660d769ccee16cde46e) Thanks [@nrjdalal](https://github.com/nrjdalal)! - move tw-animate-css to devDependencies + +- [#6899](https://github.com/shadcn-ui/ui/pull/6899) [`6f702f5fbf2b82a388e7da6ea08bcc84c2ec19c6`](https://github.com/shadcn-ui/ui/commit/6f702f5fbf2b82a388e7da6ea08bcc84c2ec19c6) Thanks [@justjavac](https://github.com/justjavac)! - add deno support + ## 2.4.1 ### Patch Changes diff --git a/packages/shadcn/package.json b/packages/shadcn/package.json index 116c858205..e2e0f9a9a9 100644 --- a/packages/shadcn/package.json +++ b/packages/shadcn/package.json @@ -1,6 +1,6 @@ { "name": "shadcn", - "version": "2.4.1", + "version": "2.5.0", "description": "Add components to your apps.", "publishConfig": { "access": "public" diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 4ca03e9b7b..3e0add4113 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -283,7 +283,7 @@ importers: specifier: ^6.0.1 version: 6.0.1 shadcn: - specifier: 2.4.1 + specifier: 2.5.0 version: link:../../packages/shadcn sonner: specifier: ^2.0.0 @@ -542,7 +542,7 @@ importers: specifier: 2.12.7 version: 2.12.7(react-dom@18.3.1(react@18.3.1))(react@18.3.1) shadcn: - specifier: 2.4.1 + specifier: 2.5.0 version: link:../../packages/shadcn sharp: specifier: ^0.32.6 From c41c6ece86b5de472668729ed336ee4aac96ee16 Mon Sep 17 00:00:00 2001 From: shadcn Date: Wed, 23 Apr 2025 16:45:23 +0400 Subject: [PATCH 16/18] fix: move tw-animate-css to devDependencies (#7251) --- apps/v4/registry.json | 6 ++-- apps/v4/scripts/build-registry.mts | 12 ++++--- .../r/styles/new-york-v4/accordion.json | 32 +------------------ .../public/r/styles/new-york-v4/index.json | 4 ++- 4 files changed, 15 insertions(+), 39 deletions(-) diff --git a/apps/v4/registry.json b/apps/v4/registry.json index 0c3d1bb725..473efd3f9e 100644 --- a/apps/v4/registry.json +++ b/apps/v4/registry.json @@ -7,7 +7,9 @@ "type": "registry:style", "dependencies": [ "class-variance-authority", - "lucide-react", + "lucide-react" + ], + "devDependencies": [ "tw-animate-css" ], "registryDependencies": [ @@ -2803,4 +2805,4 @@ ] } ] -} +} \ No newline at end of file diff --git a/apps/v4/scripts/build-registry.mts b/apps/v4/scripts/build-registry.mts index d0673e8cc2..29efbea274 100644 --- a/apps/v4/scripts/build-registry.mts +++ b/apps/v4/scripts/build-registry.mts @@ -20,11 +20,8 @@ const registry = { { name: "index", type: "registry:style", - dependencies: [ - "class-variance-authority", - "lucide-react", - "tw-animate-css", - ], + dependencies: ["class-variance-authority", "lucide-react"], + devDependencies: ["tw-animate-css"], registryDependencies: ["utils"], cssVars: {}, files: [], @@ -78,6 +75,11 @@ const registry = { if (item.name === "dashboard-01") { item.dependencies?.push("@tabler/icons-react") } + + if (item.name === "accordion" && "tailwind" in item) { + delete item.tailwind + } + return item }) ), diff --git a/apps/www/public/r/styles/new-york-v4/accordion.json b/apps/www/public/r/styles/new-york-v4/accordion.json index d5dae3ddba..2a03bbc62a 100644 --- a/apps/www/public/r/styles/new-york-v4/accordion.json +++ b/apps/www/public/r/styles/new-york-v4/accordion.json @@ -11,35 +11,5 @@ "content": "\"use client\"\n\nimport * as React from \"react\"\nimport * as AccordionPrimitive from \"@radix-ui/react-accordion\"\nimport { ChevronDownIcon } from \"lucide-react\"\n\nimport { cn } from \"@/lib/utils\"\n\nfunction Accordion({\n ...props\n}: React.ComponentProps) {\n return \n}\n\nfunction AccordionItem({\n className,\n ...props\n}: React.ComponentProps) {\n return (\n \n )\n}\n\nfunction AccordionTrigger({\n className,\n children,\n ...props\n}: React.ComponentProps) {\n return (\n \n svg]:rotate-180\",\n className\n )}\n {...props}\n >\n {children}\n \n \n \n )\n}\n\nfunction AccordionContent({\n className,\n children,\n ...props\n}: React.ComponentProps) {\n return (\n \n
{children}
\n \n )\n}\n\nexport { Accordion, AccordionItem, AccordionTrigger, AccordionContent }\n", "type": "registry:ui" } - ], - "tailwind": { - "config": { - "theme": { - "extend": { - "keyframes": { - "accordion-down": { - "from": { - "height": "0" - }, - "to": { - "height": "var(--radix-accordion-content-height)" - } - }, - "accordion-up": { - "from": { - "height": "var(--radix-accordion-content-height)" - }, - "to": { - "height": "0" - } - } - }, - "animation": { - "accordion-down": "accordion-down 0.2s ease-out", - "accordion-up": "accordion-up 0.2s ease-out" - } - } - } - } - } + ] } \ No newline at end of file diff --git a/apps/www/public/r/styles/new-york-v4/index.json b/apps/www/public/r/styles/new-york-v4/index.json index ca5bd73ff1..3a8ab07687 100644 --- a/apps/www/public/r/styles/new-york-v4/index.json +++ b/apps/www/public/r/styles/new-york-v4/index.json @@ -4,7 +4,9 @@ "type": "registry:style", "dependencies": [ "class-variance-authority", - "lucide-react", + "lucide-react" + ], + "devDependencies": [ "tw-animate-css" ], "registryDependencies": [ From 2773f9e2e29cf67e521632d15d1ba302a82e39e9 Mon Sep 17 00:00:00 2001 From: Joshua Date: Mon, 19 May 2025 09:31:12 +0200 Subject: [PATCH 17/18] fix(tailwind-prefix): resolve prefixing issue for Tailwind CSS v4 compatibility (including tests) (#6885) * WIP * fix(tailwind-prefix): resolve prefixing issue for Tailwind CSS v4 compatibility 1. Fixed incorrect prefix application causing issues with Tailwind CSS v4. 2. Optimized implementation using map() for better performance and readability. * fix(tailwind-prefix): fix test transform-tw-prefixt * fix(tailwind-prefix): fix test apply-prefix * fix(tailwind-prefix): add backwards compatibility for applyPrefix * fix(tailwind-prefix): added changeset --------- Co-authored-by: Al-Amin Islam Nerob Co-authored-by: shadcn --- .changeset/honest-humans-invite.md | 5 ++ .../utils/transformers/transform-tw-prefix.ts | 82 +++++++++++++------ .../transform-tw-prefix.test.ts.snap | 12 +-- .../shadcn/test/utils/apply-prefix.test.ts | 43 +++++++++- .../test/utils/transform-tw-prefix.test.ts | 11 +-- 5 files changed, 115 insertions(+), 38 deletions(-) create mode 100644 .changeset/honest-humans-invite.md diff --git a/.changeset/honest-humans-invite.md b/.changeset/honest-humans-invite.md new file mode 100644 index 0000000000..9d208718a9 --- /dev/null +++ b/.changeset/honest-humans-invite.md @@ -0,0 +1,5 @@ +--- +"shadcn": patch +--- + +resolved prefixing issue for Tailwind CSS v4 compatibility diff --git a/packages/shadcn/src/utils/transformers/transform-tw-prefix.ts b/packages/shadcn/src/utils/transformers/transform-tw-prefix.ts index 22559abf2b..a5178e8c5f 100644 --- a/packages/shadcn/src/utils/transformers/transform-tw-prefix.ts +++ b/packages/shadcn/src/utils/transformers/transform-tw-prefix.ts @@ -1,6 +1,10 @@ import { Transformer } from "@/src/utils/transformers" import { SyntaxKind } from "ts-morph" +import { + TailwindVersion, + getProjectTailwindVersionFromConfig, +} from "../get-project-info" import { splitClassName } from "./transform-css-vars" export const transformTwPrefixes: Transformer = async ({ @@ -10,6 +14,7 @@ export const transformTwPrefixes: Transformer = async ({ if (!config.tailwind?.prefix) { return sourceFile } + const tailwindVersion = await getProjectTailwindVersionFromConfig(config) // Find the cva function calls. sourceFile @@ -23,7 +28,8 @@ export const transformTwPrefixes: Transformer = async ({ defaultClassNames.replaceWithText( `"${applyPrefix( defaultClassNames.getText()?.replace(/"|'/g, ""), - config.tailwind.prefix + config.tailwind.prefix, + tailwindVersion )}"` ) } @@ -47,7 +53,8 @@ export const transformTwPrefixes: Transformer = async ({ classNames?.replaceWithText( `"${applyPrefix( classNames.getText()?.replace(/"|'/g, ""), - config.tailwind.prefix + config.tailwind.prefix, + tailwindVersion )}"` ) } @@ -66,7 +73,8 @@ export const transformTwPrefixes: Transformer = async ({ value.replaceWithText( `"${applyPrefix( value.getText()?.replace(/"|'/g, ""), - config.tailwind.prefix + config.tailwind.prefix, + tailwindVersion )}"` ) } @@ -92,7 +100,8 @@ export const transformTwPrefixes: Transformer = async ({ node.replaceWithText( `"${applyPrefix( node.getText()?.replace(/"|'/g, ""), - config.tailwind.prefix + config.tailwind.prefix, + tailwindVersion )}"` ) }) @@ -102,7 +111,8 @@ export const transformTwPrefixes: Transformer = async ({ node.replaceWithText( `"${applyPrefix( node.getText()?.replace(/"|'/g, ""), - config.tailwind.prefix + config.tailwind.prefix, + tailwindVersion )}"` ) } @@ -131,7 +141,8 @@ export const transformTwPrefixes: Transformer = async ({ node.replaceWithText( `"${applyPrefix( node.getText()?.replace(/"|'/g, ""), - config.tailwind.prefix + config.tailwind.prefix, + tailwindVersion )}"` ) }) @@ -141,7 +152,8 @@ export const transformTwPrefixes: Transformer = async ({ arg.replaceWithText( `"${applyPrefix( arg.getText()?.replace(/"|'/g, ""), - config.tailwind.prefix + config.tailwind.prefix, + tailwindVersion )}"` ) } @@ -156,7 +168,8 @@ export const transformTwPrefixes: Transformer = async ({ classNames.replaceWithText( `"${applyPrefix( classNames.getText()?.replace(/"|'/g, ""), - config.tailwind.prefix + config.tailwind.prefix, + tailwindVersion )}"` ) } @@ -170,30 +183,49 @@ export const transformTwPrefixes: Transformer = async ({ return sourceFile } -export function applyPrefix(input: string, prefix: string = "") { - const classNames = input.split(" ") - const prefixed: string[] = [] - for (let className of classNames) { - const [variant, value, modifier] = splitClassName(className) - if (variant) { - modifier - ? prefixed.push(`${variant}:${prefix}${value}/${modifier}`) - : prefixed.push(`${variant}:${prefix}${value}`) - } else { - modifier - ? prefixed.push(`${prefix}${value}/${modifier}`) - : prefixed.push(`${prefix}${value}`) - } +export function applyPrefix( + input: string, + prefix: string = "", + tailwindVersion: TailwindVersion +) { + if (tailwindVersion === "v3") { + return input + .split(" ") + .map((className) => { + const [variant, value, modifier] = splitClassName(className) + if (variant) { + return modifier + ? `${variant}:${prefix}${value}/${modifier}` + : `${variant}:${prefix}${value}` + } else { + return modifier + ? `${prefix}${value}/${modifier}` + : `${prefix}${value}` + } + }) + .join(" ") } - return prefixed.join(" ") + + return input + .split(" ") + .map((className) => + className.indexOf(`${prefix}:`) === 0 + ? className + : `${prefix}:${className.trim()}` + ) + .join(" ") } -export function applyPrefixesCss(css: string, prefix: string) { +export function applyPrefixesCss( + css: string, + prefix: string, + tailwindVersion: TailwindVersion +) { const lines = css.split("\n") for (let line of lines) { if (line.includes("@apply")) { const originalTWCls = line.replace("@apply", "").trim() - const prefixedTwCls = applyPrefix(originalTWCls, prefix) + const prefixedTwCls = applyPrefix(originalTWCls, prefix, tailwindVersion) css = css.replace(originalTWCls, prefixedTwCls) } } diff --git a/packages/shadcn/test/utils/__snapshots__/transform-tw-prefix.test.ts.snap b/packages/shadcn/test/utils/__snapshots__/transform-tw-prefix.test.ts.snap index 5019ddb6d7..6f5dcdf5e4 100644 --- a/packages/shadcn/test/utils/__snapshots__/transform-tw-prefix.test.ts.snap +++ b/packages/shadcn/test/utils/__snapshots__/transform-tw-prefix.test.ts.snap @@ -3,7 +3,7 @@ exports[`transform tailwind prefix 1`] = ` "import * as React from "react" export function Foo() { - return
foo
+ return
foo
} " `; @@ -11,7 +11,7 @@ exports[`transform tailwind prefix 1`] = ` exports[`transform tailwind prefix 2`] = ` "import * as React from "react" export function Foo() { - return
foo
+ return
foo
} " `; @@ -19,7 +19,7 @@ export function Foo() { exports[`transform tailwind prefix 3`] = ` "import * as React from "react" export function Foo() { - return
foo
+ return
foo
} " `; @@ -27,7 +27,7 @@ export function Foo() { exports[`transform tailwind prefix 4`] = ` "import * as React from "react" export function Foo() { - return
foo
+ return
foo
} " `; @@ -105,10 +105,10 @@ exports[`transform tailwind prefix 5`] = ` @layer base { * { - @apply tw-border-border; + @apply tw::border-border; } body { - @apply tw-bg-background tw-text-foreground; + @apply tw::bg-background tw::text-foreground; } }" `; diff --git a/packages/shadcn/test/utils/apply-prefix.test.ts b/packages/shadcn/test/utils/apply-prefix.test.ts index 9afed4c4ed..9ae669e72b 100644 --- a/packages/shadcn/test/utils/apply-prefix.test.ts +++ b/packages/shadcn/test/utils/apply-prefix.test.ts @@ -2,7 +2,7 @@ import { describe, expect, test } from "vitest" import { applyPrefix } from "../../src/utils/transformers/transform-tw-prefix" -describe("apply tailwind prefix", () => { +describe("apply tailwind prefix v3", () => { test.each([ { input: "bg-slate-800 text-gray-500", @@ -37,6 +37,45 @@ describe("apply tailwind prefix", () => { "tw-absolute tw-right-4 tw-top-4 tw-bg-primary tw-rounded-sm tw-opacity-70 tw-ring-offset-background tw-transition-opacity hover:tw-opacity-100 focus:tw-outline-none focus:tw-ring-2 focus:tw-ring-ring focus:tw-ring-offset-2 disabled:tw-pointer-events-none data-[state=open]:tw-bg-secondary", }, ])(`applyTwPrefix($input) -> $output`, ({ input, output }) => { - expect(applyPrefix(input, "tw-")).toBe(output) + expect(applyPrefix(input, "tw-", "v3")).toBe(output) + }) +}) + +describe("apply tailwind prefix v4", () => { + test.each([ + { + input: "bg-slate-800 text-gray-500", + output: "tw:bg-slate-800 tw:text-gray-500", + }, + { + input: "hover:dark:bg-background dark:text-foreground", + output: "tw:hover:dark:bg-background tw:dark:text-foreground", + }, + { + input: + "rounded-lg border border-slate-200 bg-white text-slate-950 shadow-sm dark:border-slate-800 dark:bg-slate-950 dark:text-slate-50", + output: + "tw:rounded-lg tw:border tw:border-slate-200 tw:bg-white tw:text-slate-950 tw:shadow-sm tw:dark:border-slate-800 tw:dark:bg-slate-950 tw:dark:text-slate-50", + }, + { + input: + "text-red-500 border-red-500/50 dark:border-red-500 [&>svg]:text-red-500 text-red-500 dark:text-red-900 dark:border-red-900/50 dark:dark:border-red-900 dark:[&>svg]:text-red-900 dark:text-red-900", + output: + "tw:text-red-500 tw:border-red-500/50 tw:dark:border-red-500 tw:[&>svg]:text-red-500 tw:text-red-500 tw:dark:text-red-900 tw:dark:border-red-900/50 tw:dark:dark:border-red-900 tw:dark:[&>svg]:text-red-900 tw:dark:text-red-900", + }, + { + input: + "flex h-full w-full items-center justify-center rounded-full bg-muted", + output: + "tw:flex tw:h-full tw:w-full tw:items-center tw:justify-center tw:rounded-full tw:bg-muted", + }, + { + input: + "absolute right-4 top-4 bg-primary rounded-sm opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:pointer-events-none data-[state=open]:bg-secondary", + output: + "tw:absolute tw:right-4 tw:top-4 tw:bg-primary tw:rounded-sm tw:opacity-70 tw:ring-offset-background tw:transition-opacity tw:hover:opacity-100 tw:focus:outline-none tw:focus:ring-2 tw:focus:ring-ring tw:focus:ring-offset-2 tw:disabled:pointer-events-none tw:data-[state=open]:bg-secondary", + }, + ])(`applyTwPrefix($input) -> $output`, ({ input, output }) => { + expect(applyPrefix(input, "tw", "v4")).toBe(output) }) }) diff --git a/packages/shadcn/test/utils/transform-tw-prefix.test.ts b/packages/shadcn/test/utils/transform-tw-prefix.test.ts index 21529f3cbf..31fc37c8e0 100644 --- a/packages/shadcn/test/utils/transform-tw-prefix.test.ts +++ b/packages/shadcn/test/utils/transform-tw-prefix.test.ts @@ -16,7 +16,7 @@ test("transform tailwind prefix", async () => { config: { tailwind: { baseColor: "stone", - prefix: "tw-", + prefix: "tw:", }, aliases: { components: "@/components", @@ -39,7 +39,7 @@ export function Foo() { tailwind: { baseColor: "stone", cssVariables: false, - prefix: "tw-", + prefix: "tw:", }, aliases: { components: "@/components", @@ -62,7 +62,7 @@ export function Foo() { tailwind: { baseColor: "stone", cssVariables: false, - prefix: "tw-", + prefix: "tw:", }, aliases: { components: "@/components", @@ -85,7 +85,7 @@ export function Foo() { tailwind: { baseColor: "stone", cssVariables: false, - prefix: "tw-", + prefix: "tw:", }, aliases: { components: "@/components", @@ -99,7 +99,8 @@ export function Foo() { expect( applyPrefixesCss( "@tailwind base;\n@tailwind components;\n@tailwind utilities;\n \n@layer base {\n :root {\n --background: 0 0% 100%;\n --foreground: 224 71.4% 4.1%;\n \n --muted: 220 14.3% 95.9%;\n --muted-foreground: 220 8.9% 46.1%;\n \n --popover: 0 0% 100%;\n --popover-foreground: 224 71.4% 4.1%;\n \n --card: 0 0% 100%;\n --card-foreground: 224 71.4% 4.1%;\n \n --border: 220 13% 91%;\n --input: 220 13% 91%;\n \n --primary: 220.9 39.3% 11%;\n --primary-foreground: 210 20% 98%;\n \n --secondary: 220 14.3% 95.9%;\n --secondary-foreground: 220.9 39.3% 11%;\n \n --accent: 220 14.3% 95.9%;\n --accent-foreground: 220.9 39.3% 11%;\n \n --destructive: 0 84.2% 60.2%;\n --destructive-foreground: 210 20% 98%;\n \n --ring: 217.9 10.6% 64.9%;\n \n --radius: 0.5rem;\n }\n \n .dark {\n --background: 224 71.4% 4.1%;\n --foreground: 210 20% 98%;\n \n --muted: 215 27.9% 16.9%;\n --muted-foreground: 217.9 10.6% 64.9%;\n \n --popover: 224 71.4% 4.1%;\n --popover-foreground: 210 20% 98%;\n \n --card: 224 71.4% 4.1%;\n --card-foreground: 210 20% 98%;\n \n --border: 215 27.9% 16.9%;\n --input: 215 27.9% 16.9%;\n \n --primary: 210 20% 98%;\n --primary-foreground: 220.9 39.3% 11%;\n \n --secondary: 215 27.9% 16.9%;\n --secondary-foreground: 210 20% 98%;\n \n --accent: 215 27.9% 16.9%;\n --accent-foreground: 210 20% 98%;\n \n --destructive: 0 62.8% 30.6%;\n --destructive-foreground: 0 85.7% 97.3%;\n \n --ring: 215 27.9% 16.9%;\n }\n}\n \n@layer base {\n * {\n @apply border-border;\n }\n body {\n @apply bg-background text-foreground;\n }\n}", - "tw-" + "tw:", + "v4" ) ).toMatchSnapshot() }) From b84c990e4270febdac0015f7eb31f0514c42d2eb Mon Sep 17 00:00:00 2001 From: Thibault Le Ouay Date: Wed, 28 May 2025 14:52:24 +0200 Subject: [PATCH 18/18] fix registry item schema (#7486) --- apps/www/public/schema/registry-item.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/apps/www/public/schema/registry-item.json b/apps/www/public/schema/registry-item.json index 1f4b887403..18e03d59bf 100644 --- a/apps/www/public/schema/registry-item.json +++ b/apps/www/public/schema/registry-item.json @@ -78,7 +78,8 @@ "registry:hook", "registry:theme", "registry:page", - "registry:file" + "registry:file", + "registry:style" ], "description": "The type of the file. This is used to determine the type of the file when resolved for a project." },