From 52cf7acaed3bf24fd10b4c1bcea87a6b1dc48163 Mon Sep 17 00:00:00 2001 From: shadcn Date: Fri, 23 Aug 2024 21:05:20 +0400 Subject: [PATCH] fix: tailwind config --- .../utils/updaters/update-tailwind-config.ts | 15 +-- .../updaters/update-tailwind-config.test.ts | 91 ++++++++++++++++++- 2 files changed, 96 insertions(+), 10 deletions(-) diff --git a/packages/cli/src/utils/updaters/update-tailwind-config.ts b/packages/cli/src/utils/updaters/update-tailwind-config.ts index a85ecefd49..ee87773f2a 100644 --- a/packages/cli/src/utils/updaters/update-tailwind-config.ts +++ b/packages/cli/src/utils/updaters/update-tailwind-config.ts @@ -175,12 +175,14 @@ async function addTailwindConfigTheme( if (themeInitializer?.isKind(SyntaxKind.ObjectLiteralExpression)) { const themeObjectString = themeInitializer.getText() const themeObject = await parseObjectLiteral(themeObjectString) - const result = deepmerge(themeObject, theme) as Record + const result = deepmerge(themeObject, theme) const resultString = objectToString(result) .replace(/\'\"/g, "'") .replace(/\"\'/g, "'") .replace(/\'\[/g, "[") .replace(/\]\'/g, "]") + .replace(/\\\'/g, "") + .replace(/\\\'/g, "") themeInitializer.replaceWithText(resultString) } @@ -206,14 +208,14 @@ function addTailwindConfigPlugin( if (existingPlugins.isKind(SyntaxKind.PropertyAssignment)) { const initializer = existingPlugins.getInitializer() - // If property is an array, append. if (initializer?.isKind(SyntaxKind.ArrayLiteralExpression)) { - // Check if the array already contains the value. if ( initializer .getElements() - .map((element) => element.getText()) - .includes(plugin) + .map((element) => { + return element.getText().replace(/["']/g, "") + }) + .includes(plugin.replace(/["']/g, "")) ) { return configObject } @@ -303,7 +305,6 @@ export function unnestSpreadProperties(obj: ObjectLiteralExpression) { propAssignment.remove() } } else if (initializer?.isKind(SyntaxKind.ObjectLiteralExpression)) { - // Recursively process nested object literals unnestSpreadProperties(initializer as ObjectLiteralExpression) } } @@ -334,7 +335,7 @@ function parseObjectLiteralExpression(node: ObjectLiteralExpression): any { const result: any = {} for (const property of node.getProperties()) { if (property.isKind(SyntaxKind.PropertyAssignment)) { - const name = property.getName() + const name = property.getName().replace(/\'/g, "") if ( property.getInitializer()?.isKind(SyntaxKind.ObjectLiteralExpression) ) { diff --git a/packages/cli/test/utils/updaters/update-tailwind-config.test.ts b/packages/cli/test/utils/updaters/update-tailwind-config.test.ts index 725858ce3b..e433005e42 100644 --- a/packages/cli/test/utils/updaters/update-tailwind-config.test.ts +++ b/packages/cli/test/utils/updaters/update-tailwind-config.test.ts @@ -395,7 +395,7 @@ const config: Config = { export default config `, { - plugins: ["tailwindcss-animate"], + plugins: ['require("tailwindcss-animate")'], }, { config: SHARED_CONFIG, @@ -429,7 +429,7 @@ const config: Config = { export default config `, { - plugins: ["tailwindcss-animate"], + plugins: ['require("tailwindcss-animate")'], }, { config: SHARED_CONFIG, @@ -463,7 +463,7 @@ const config: Config = { export default config `, { - plugins: ["tailwindcss-animate"], + plugins: ["require('tailwindcss-animate')"], }, { config: SHARED_CONFIG, @@ -675,6 +675,91 @@ export default config ) ).toMatchSnapshot() }) + + test("should not make any updates running on already updated config", async () => { + const input = `import type { Config } from 'tailwindcss' + +const config: Config = { +content: [ + "./pages/**/*.{js,ts,jsx,tsx,mdx}", + "./components/**/*.{js,ts,jsx,tsx,mdx}", + "./app/**/*.{js,ts,jsx,tsx,mdx}", +], +theme: { + extend: { + fontFamily: { + sans: ["var(--font-geist-sans)", ...fontFamily.sans], + mono: ["var(--font-mono)", ...fontFamily.mono], + }, + colors: { + ...defaultColors, + background: "hsl(var(--background))", + foreground: "hsl(var(--foreground))", + }, + boxShadow: { + ...defaultBoxShadow, + "3xl": "0 35px 60px -15px rgba(0, 0, 0, 0.3)", + }, + borderRadius: { + "3xl": "2rem", + }, + animation: { + ...defaultAnimation, + "spin-slow": "spin 3s linear infinite", + }, + }, +}, +} +export default config +` + + const tailwindConfig = { + theme: { + extend: { + fontFamily: { + heading: ["var(--font-geist-sans)"], + }, + colors: { + border: "hsl(var(--border))", + input: "hsl(var(--input))", + ring: "hsl(var(--ring))", + primary: { + DEFAULT: "hsl(var(--primary))", + foreground: "hsl(var(--primary-foreground))", + }, + card: { + DEFAULT: "hsl(var(--card))", + foreground: "hsl(var(--card-foreground))", + }, + }, + borderRadius: { + lg: "var(--radius)", + md: "calc(var(--radius) - 2px)", + sm: "calc(var(--radius) - 4px)", + }, + animation: { + "accordion-down": "accordion-down 0.2s ease-out", + "accordion-up": "accordion-up 0.2s ease-out", + }, + }, + }, + } + + const output1 = await transformTailwindConfig(input, tailwindConfig, { + config: SHARED_CONFIG, + }) + + const output2 = await transformTailwindConfig(output1, tailwindConfig, { + config: SHARED_CONFIG, + }) + + const output3 = await transformTailwindConfig(output2, tailwindConfig, { + config: SHARED_CONFIG, + }) + + expect(output3).toBe(output1) + expect(output3).toBe(output2) + }) }) describe("nestSpreadProperties", () => {