Skip to content

Commit a45db82

Browse files
Migrate static plugins with options to CSS
1 parent 34fc9b0 commit a45db82

File tree

7 files changed

+87
-18
lines changed

7 files changed

+87
-18
lines changed

CHANGELOG.md

+3-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
77

88
## [Unreleased]
99

10-
- Nothing yet!
10+
### Added
11+
12+
- _Upgrade (experimental)_: Migrate `plugins` with options to CSS ([#14700](https://github.com/tailwindlabs/tailwindcss/pull/14700))
1113

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

integrations/upgrade/index.test.ts

-4
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,6 @@ test(
4040
4141
--- ./src/input.css ---
4242
@import 'tailwindcss';
43-
44-
@source './**/*.{html,js}';
4543
"
4644
`)
4745

@@ -100,8 +98,6 @@ test(
10098
--- ./src/input.css ---
10199
@import 'tailwindcss' prefix(tw);
102100
103-
@source './**/*.{html,js}';
104-
105101
.btn {
106102
@apply tw:rounded-md! tw:px-2 tw:py-1 tw:bg-blue-500 tw:text-white;
107103
}

integrations/upgrade/js-config.test.ts

+48-9
Original file line numberDiff line numberDiff line change
@@ -82,9 +82,6 @@ test(
8282
--- src/input.css ---
8383
@import 'tailwindcss';
8484
85-
@source './**/*.{html,js}';
86-
@source '../my-app/**/*.{html,js}';
87-
8885
@variant dark (&:where(.dark, .dark *));
8986
9087
@theme {
@@ -155,14 +152,33 @@ test(
155152
import customPlugin from './custom-plugin'
156153
157154
export default {
158-
plugins: [typography, customPlugin],
155+
plugins: [
156+
typography,
157+
customPlugin({
158+
'is-null': null,
159+
'is-true': true,
160+
'is-false': false,
161+
'is-int': 1234567,
162+
'is-float': 1.35,
163+
'is-sci': 1.35e-5,
164+
'is-str-null': 'null',
165+
'is-str-true': 'true',
166+
'is-str-false': 'false',
167+
'is-str-int': '1234567',
168+
'is-str-float': '1.35',
169+
'is-str-sci': '1.35e-5',
170+
'is-arr': ['foo', 'bar'],
171+
'is-arr-mixed': [null, true, false, 1234567, 1.35, 'foo', 'bar', 'true'],
172+
}),
173+
],
159174
} satisfies Config
160175
`,
161176
'custom-plugin.js': ts`
162-
export default function ({ addVariant }) {
177+
import plugin from 'tailwindcss/plugin'
178+
export default plugin.withOptions((_options) => ({ addVariant }) => {
163179
addVariant('inverted', '@media (inverted-colors: inverted)')
164180
addVariant('hocus', ['&:focus', '&:hover'])
165-
}
181+
})
166182
`,
167183
'src/input.css': css`
168184
@tailwind base;
@@ -178,15 +194,38 @@ test(
178194
"
179195
--- src/input.css ---
180196
@import 'tailwindcss';
181-
182-
@plugin '@tailwindcss/typography';
183-
@plugin '../custom-plugin';
197+
@config '../tailwind.config.ts';
184198
"
185199
`)
186200

187201
expect(await fs.dumpFiles('tailwind.config.ts')).toMatchInlineSnapshot(`
188202
"
203+
--- tailwind.config.ts ---
204+
import { type Config } from 'tailwindcss'
205+
import typography from '@tailwindcss/typography'
206+
import customPlugin from './custom-plugin'
189207
208+
export default {
209+
plugins: [
210+
typography,
211+
customPlugin({
212+
'is-null': null,
213+
'is-true': true,
214+
'is-false': false,
215+
'is-int': 1234567,
216+
'is-float': 1.35,
217+
'is-sci': 1.35e-5,
218+
'is-str-null': 'null',
219+
'is-str-true': 'true',
220+
'is-str-false': 'false',
221+
'is-str-int': '1234567',
222+
'is-str-float': '1.35',
223+
'is-str-sci': '1.35e-5',
224+
'is-arr': ['foo', 'bar'],
225+
'is-arr-mixed': [null, true, false, 1234567, 1.35, 'foo', 'bar', 'true'],
226+
}),
227+
],
228+
} satisfies Config
190229
"
191230
`)
192231
},

packages/@tailwindcss-upgrade/src/codemods/format-nodes.ts

+9-1
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,15 @@ export function formatNodes(): Plugin {
1818
// Format the nodes
1919
await Promise.all(
2020
nodesToFormat.map(async (node) => {
21-
node.replaceWith(parse(await format(node.toString(), { parser: 'css', semi: true })))
21+
node.replaceWith(
22+
parse(
23+
await format(node.toString(), {
24+
parser: 'css',
25+
semi: true,
26+
singleQuote: true,
27+
}),
28+
),
29+
)
2230
}),
2331
)
2432
}

packages/@tailwindcss-upgrade/src/codemods/migrate-at-layer-utilities.test.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -413,7 +413,7 @@ it('should migrate classes with attribute selectors', async () => {
413413
`),
414414
).toMatchInlineSnapshot(`
415415
"@utility no-scrollbar {
416-
&[data-checked=""] {
416+
&[data-checked=''] {
417417
display: none;
418418
}
419419
}"

packages/@tailwindcss-upgrade/src/codemods/migrate-config.ts

+25-1
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,27 @@ export function migrateConfig(
6363
plugin.path[0] === '.'
6464
? relativeToStylesheet(sheet, path.resolve(plugin.base, plugin.path))
6565
: plugin.path
66-
css += `@plugin '${relative}';\n`
66+
67+
if (plugin.options === null) {
68+
css += `@plugin '${relative}';\n`
69+
} else {
70+
css += `@plugin '${relative}' {\n`
71+
for (let [property, value] of Object.entries(plugin.options)) {
72+
let cssValue = ''
73+
if (typeof value === 'string') {
74+
cssValue = quoteString(value)
75+
} else if (Array.isArray(value)) {
76+
cssValue = value
77+
.map((v) => (typeof v === 'string' ? quoteString(v) : '' + v))
78+
.join(', ')
79+
} else {
80+
cssValue = '' + value
81+
}
82+
83+
css += ` ${property}: ${cssValue};\n`
84+
}
85+
css += '}\n'
86+
}
6787
}
6888
if (jsConfigMigration.plugins.length > 0) {
6989
css = css + '\n'
@@ -149,3 +169,7 @@ function relativeToStylesheet(sheet: Stylesheet, absolute: string) {
149169
// glob.
150170
return normalizePath(relative)
151171
}
172+
173+
function quoteString(value: string): string {
174+
return `'${value.replace(/\\/g, '\\\\').replace(/'/g, "\\'")}'`
175+
}

packages/@tailwindcss-upgrade/src/migrate-js-config.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ export type JSConfigMigration =
2424
// Could not convert the config file, need to inject it as-is in a @config directive
2525
null | {
2626
sources: { base: string; pattern: string }[]
27-
plugins: { base: string; path: string }[]
27+
plugins: { base: string; path: string; options: null | StaticPluginOptions }[]
2828
css: string
2929
}
3030

0 commit comments

Comments
 (0)