diff --git a/.changeset/cold-kids-fly.md b/.changeset/cold-kids-fly.md new file mode 100644 index 0000000000..ad774f8155 --- /dev/null +++ b/.changeset/cold-kids-fly.md @@ -0,0 +1,5 @@ +--- +"shadcn": patch +--- + +fix chartColor in presets diff --git a/apps/v4/app/(create)/init/parse-config.test.ts b/apps/v4/app/(create)/init/parse-config.test.ts index 245a7b6151..01a7051c6e 100644 --- a/apps/v4/app/(create)/init/parse-config.test.ts +++ b/apps/v4/app/(create)/init/parse-config.test.ts @@ -3,6 +3,21 @@ import { describe, expect, it } from "vitest" import { parseDesignSystemConfig } from "./parse-config" describe("parseDesignSystemConfig", () => { + it("defaults missing chartColor from the selected theme", () => { + const result = parseDesignSystemConfig( + new URLSearchParams( + "base=base&style=sera&baseColor=taupe&theme=taupe&iconLibrary=lucide&font=noto-sans&rtl=false&menuAccent=subtle&menuColor=default&radius=default&fontHeading=playfair-display&template=vite&track=1" + ) + ) + + expect(result.success).toBe(true) + if (!result.success) { + throw new Error(result.error) + } + + expect(result.data.chartColor).toBe("taupe") + }) + it("honors explicit fontHeading and chartColor overrides when a preset is present", () => { const result = parseDesignSystemConfig( new URLSearchParams( diff --git a/apps/v4/registry/config.test.ts b/apps/v4/registry/config.test.ts index 1513e35d1b..76809189d7 100644 --- a/apps/v4/registry/config.test.ts +++ b/apps/v4/registry/config.test.ts @@ -65,6 +65,23 @@ describe("buildRegistryBase", () => { expect(result.chartColor).toBe("neutral") }) + it("defaults chartColor to the selected theme when omitted", () => { + const result = designSystemConfigSchema.parse({ + base: "base", + style: "sera", + iconLibrary: "lucide", + baseColor: "taupe", + theme: "taupe", + font: "noto-sans", + fontHeading: "playfair-display", + menuAccent: "subtle", + menuColor: "default", + radius: "default", + }) + + expect(result.chartColor).toBe("taupe") + }) + it("rejects chartColor values that are unavailable for the selected base color", () => { const result = designSystemConfigSchema.safeParse({ base: "radix", diff --git a/apps/v4/registry/config.ts b/apps/v4/registry/config.ts index a2f825b700..dadab12a16 100644 --- a/apps/v4/registry/config.ts +++ b/apps/v4/registry/config.ts @@ -98,7 +98,7 @@ export const designSystemConfigSchema = z theme: z.enum(THEMES.map((t) => t.name) as [ThemeName, ...ThemeName[]]), chartColor: z .enum(THEMES.map((t) => t.name) as [ChartColorName, ...ChartColorName[]]) - .default("neutral"), + .optional(), font: z.enum(fontValues).default("inter"), fontHeading: z.enum(fontHeadingValues).default("inherit"), item: z.string().optional(), @@ -136,6 +136,10 @@ export const designSystemConfigSchema = z .default("next") .optional(), }) + .transform((data) => ({ + ...data, + chartColor: data.chartColor ?? data.theme, + })) .refine( (data) => { const availableThemes = getThemesForBaseColor(data.baseColor) diff --git a/packages/shadcn/src/preset/presets.test.ts b/packages/shadcn/src/preset/presets.test.ts index bd1f3d0153..c36b9797f3 100644 --- a/packages/shadcn/src/preset/presets.test.ts +++ b/packages/shadcn/src/preset/presets.test.ts @@ -1,7 +1,7 @@ import { REGISTRY_URL } from "@/src/registry/constants" import { describe, expect, it } from "vitest" -import { resolveCreateUrl, resolveInitUrl } from "./presets" +import { DEFAULT_PRESETS, resolveCreateUrl, resolveInitUrl } from "./presets" const SHADCN_URL = REGISTRY_URL.replace(/\/r\/?$/, "") @@ -79,6 +79,12 @@ describe("buildInitUrl", () => { expect(parsed.searchParams.get("chartColor")).toBe("emerald") }) + it("should include chartColor from default presets", () => { + const url = resolveInitUrl({ ...DEFAULT_PRESETS.sera, base: "base" }) + const parsed = new URL(url) + expect(parsed.searchParams.get("chartColor")).toBe("taupe") + }) + it("should not include chartColor when not provided", () => { const url = resolveInitUrl(mockPreset) const parsed = new URL(url) diff --git a/packages/shadcn/src/preset/presets.ts b/packages/shadcn/src/preset/presets.ts index 815913f0d8..a882712567 100644 --- a/packages/shadcn/src/preset/presets.ts +++ b/packages/shadcn/src/preset/presets.ts @@ -19,6 +19,7 @@ export const DEFAULT_PRESETS = { style: "nova", baseColor: "neutral", theme: "neutral", + chartColor: "neutral", iconLibrary: "lucide", font: "geist", fontHeading: "inherit", @@ -34,6 +35,7 @@ export const DEFAULT_PRESETS = { style: "vega", baseColor: "neutral", theme: "neutral", + chartColor: "neutral", iconLibrary: "lucide", font: "inter", fontHeading: "inherit", @@ -49,6 +51,7 @@ export const DEFAULT_PRESETS = { style: "maia", baseColor: "neutral", theme: "neutral", + chartColor: "neutral", iconLibrary: "hugeicons", font: "figtree", fontHeading: "inherit", @@ -64,6 +67,7 @@ export const DEFAULT_PRESETS = { style: "lyra", baseColor: "neutral", theme: "neutral", + chartColor: "neutral", iconLibrary: "phosphor", font: "jetbrains-mono", fontHeading: "inherit", @@ -79,6 +83,7 @@ export const DEFAULT_PRESETS = { style: "mira", baseColor: "neutral", theme: "neutral", + chartColor: "neutral", iconLibrary: "hugeicons", font: "inter", fontHeading: "inherit", @@ -94,6 +99,7 @@ export const DEFAULT_PRESETS = { style: "luma", baseColor: "neutral", theme: "neutral", + chartColor: "neutral", iconLibrary: "lucide", font: "inter", fontHeading: "inherit", @@ -109,6 +115,7 @@ export const DEFAULT_PRESETS = { style: "sera", baseColor: "taupe", theme: "taupe", + chartColor: "taupe", iconLibrary: "lucide", font: "noto-sans", fontHeading: "playfair-display",