Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Migrate static plugins with options to CSS #14700

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

- Nothing yet!
### Added

- _Upgrade (experimental)_: Migrate `plugins` with options to CSS ([#14700](https://github.com/tailwindlabs/tailwindcss/pull/14700))

## [4.0.0-alpha.28] - 2024-10-17

Expand Down
44 changes: 39 additions & 5 deletions integrations/upgrade/js-config.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ test(

--font-family-sans: Inter, system-ui, sans-serif;
--font-family-display: Cabinet Grotesk, ui-sans-serif, system-ui, sans-serif,
"Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol', 'Noto Color Emoji';

--radius-4xl: 2rem;

Expand Down Expand Up @@ -155,14 +155,33 @@ test(
import customPlugin from './custom-plugin'

export default {
plugins: [typography, customPlugin],
plugins: [
typography,
customPlugin({
'is-null': null,
'is-true': true,
'is-false': false,
'is-int': 1234567,
'is-float': 1.35,
'is-sci': 1.35e-5,
'is-str-null': 'null',
'is-str-true': 'true',
'is-str-false': 'false',
'is-str-int': '1234567',
'is-str-float': '1.35',
'is-str-sci': '1.35e-5',
'is-arr': ['foo', 'bar'],
'is-arr-mixed': [null, true, false, 1234567, 1.35, 'foo', 'bar', 'true'],
}),
],
} satisfies Config
`,
'custom-plugin.js': ts`
export default function ({ addVariant }) {
import plugin from 'tailwindcss/plugin'
export default plugin.withOptions((_options) => ({ addVariant }) => {
addVariant('inverted', '@media (inverted-colors: inverted)')
addVariant('hocus', ['&:focus', '&:hover'])
}
})
`,
'src/input.css': css`
@tailwind base;
Expand All @@ -180,7 +199,22 @@ test(
@import 'tailwindcss';

@plugin '@tailwindcss/typography';
@plugin '../custom-plugin';
@plugin '../custom-plugin' {
is-null: null;
is-true: true;
is-false: false;
is-int: 1234567;
is-float: 1.35;
is-sci: 0.0000135;
is-str-null: 'null';
is-str-true: 'true';
is-str-false: 'false';
is-str-int: '1234567';
is-str-float: '1.35';
is-str-sci: '1.35e-5';
is-arr: 'foo', 'bar';
is-arr-mixed: null, true, false, 1234567, 1.35, 'foo', 'bar', 'true';
}
"
`)

Expand Down
10 changes: 9 additions & 1 deletion packages/@tailwindcss-upgrade/src/codemods/format-nodes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,15 @@ export function formatNodes(): Plugin {
// Format the nodes
await Promise.all(
nodesToFormat.map(async (node) => {
node.replaceWith(parse(await format(node.toString(), { parser: 'css', semi: true })))
node.replaceWith(
parse(
await format(node.toString(), {
parser: 'css',
semi: true,
singleQuote: true,
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I noticed that we inconsistently used single quotes for the @plugin and @config directives but double-quotes for CSS values so this is just a consistency change.

}),
),
)
}),
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -413,7 +413,7 @@ it('should migrate classes with attribute selectors', async () => {
`),
).toMatchInlineSnapshot(`
"@utility no-scrollbar {
&[data-checked=""] {
&[data-checked=''] {
display: none;
}
}"
Expand Down
26 changes: 25 additions & 1 deletion packages/@tailwindcss-upgrade/src/codemods/migrate-config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,27 @@ export function migrateConfig(
plugin.path[0] === '.'
? relativeToStylesheet(sheet, path.resolve(plugin.base, plugin.path))
: plugin.path
css += `@plugin '${relative}';\n`

if (plugin.options === null) {
css += `@plugin '${relative}';\n`
} else {
css += `@plugin '${relative}' {\n`
for (let [property, value] of Object.entries(plugin.options)) {
let cssValue = ''
if (typeof value === 'string') {
cssValue = quoteString(value)
} else if (Array.isArray(value)) {
cssValue = value
.map((v) => (typeof v === 'string' ? quoteString(v) : '' + v))
.join(', ')
} else {
cssValue = '' + value
}

css += ` ${property}: ${cssValue};\n`
}
css += '}\n'
}
}
if (jsConfigMigration.plugins.length > 0) {
css = css + '\n'
Expand Down Expand Up @@ -149,3 +169,7 @@ function relativeToStylesheet(sheet: Stylesheet, absolute: string) {
// glob.
return normalizePath(relative)
}

function quoteString(value: string): string {
return `'${value.replace(/\\/g, '\\\\').replace(/'/g, "\\'")}'`
}
2 changes: 1 addition & 1 deletion packages/@tailwindcss-upgrade/src/migrate-js-config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ export type JSConfigMigration =
// Could not convert the config file, need to inject it as-is in a @config directive
null | {
sources: { base: string; pattern: string }[]
plugins: { base: string; path: string }[]
plugins: { base: string; path: string; options: null | StaticPluginOptions }[]
css: string
}

Expand Down