diff --git a/CHANGELOG.md b/CHANGELOG.md index 3b36ccc..559bf31 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Don't augment global Prettier `ParserOptions` and `RequiredOptions` types ([#354](https://github.com/tailwindlabs/prettier-plugin-tailwindcss/pull/354)) - Drop support for `prettier-plugin-import-sort` ([#385](https://github.com/tailwindlabs/prettier-plugin-tailwindcss/pull/385)) +- Format quotes in `@source`, `@plugin`, and `@config` ([#387](https://github.com/tailwindlabs/prettier-plugin-tailwindcss/pull/387)) ## [0.6.14] - 2025-07-09 diff --git a/src/index.ts b/src/index.ts index f9a86ce..ceda00f 100644 --- a/src/index.ts +++ b/src/index.ts @@ -786,7 +786,38 @@ function transformJavaScript( } function transformCss(ast: any, { env }: TransformerContext) { + // `parseValue` inside Prettier's CSS parser is private API so we have to + // produce the same result by parsing an import statement with the same params + function tryParseAtRuleParams(name: string, params: any) { + // It might already be an object or array. Could happen in the future if + // Prettier decides to start parsing these. + if (typeof params !== 'string') return params + + // Otherwise we let prettier re-parse the params into its custom value AST + // based on postcss-value parser. + try { + let parser = base.parsers.css + let root = parser.parse(`@import ${params};`, env.options) + + return root.nodes[0].params + } catch (err) { + console.warn(`[prettier-plugin-tailwindcss] Unable to parse at rule`) + console.warn({ name, params }) + console.warn(err) + } + + return params + } + ast.walk((node: any) => { + if ( + node.name === 'plugin' || + node.name === 'config' || + node.name === 'source' + ) { + node.params = tryParseAtRuleParams(node.name, node.params) + } + if (node.type === 'css-atrule' && node.name === 'apply') { let isImportant = /\s+(?:!important|#{(['"]*)!important\1})\s*$/.test( node.params, diff --git a/tests/tests.ts b/tests/tests.ts index ab11ca9..b85b93e 100644 --- a/tests/tests.ts +++ b/tests/tests.ts @@ -43,6 +43,14 @@ let css: TestEntry[] = [ '@apply p-0\n sm:p-0;', { tailwindPreserveWhitespace: true }, ], + + // Quote conversion for custom at-rules + [`@import "./file.css";`, `@import './file.css';`], + [`@plugin "./file.js";`, `@plugin './file.js';`], + [`@config "./file.js";`, `@config './file.js';`], + [`@source "./file.js";`, `@source './file.js';`], + [`@source not "./file.js";`, `@source not './file.js';`], + [`@source inline("./file.js");`, `@source inline('./file.js');`], ] export let javascript: TestEntry[] = [