Skip to content

Commit 317115b

Browse files
authored
Merge branch 'main' into fix/vite-html-style-blocks
2 parents 9405d42 + c09bb5e commit 317115b

File tree

10 files changed

+285
-125
lines changed

10 files changed

+285
-125
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1010
### Fixed
1111

1212
- Only generate positive `grid-cols-*` and `grid-rows-*` utilities ([#16020](https://github.com/tailwindlabs/tailwindcss/pull/16020))
13+
- Ensure we process Tailwind CSS features when only using `@reference` or `@variant` ([#16057](https://github.com/tailwindlabs/tailwindcss/pull/16057))
14+
- Refactor gradient implementation to work around [prettier/prettier#17058](https://github.com/prettier/prettier/issues/17058) ([#16072](https://github.com/tailwindlabs/tailwindcss/pull/16072))
15+
- Vite: Ensure hot-reloading works with SolidStart setups ([#16052](https://github.com/tailwindlabs/tailwindcss/pull/16052))
16+
- Vite: Fix a crash when starting the development server in SolidStart setups ([#16052](https://github.com/tailwindlabs/tailwindcss/pull/16052))
1317
- Vite: Transform `<style>` blocks in HTML files ([#16069](https://github.com/tailwindlabs/tailwindcss/pull/16069))
1418

1519
## [4.0.1] - 2025-01-29
Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
import { candidate, css, fetchStyles, js, json, retryAssertion, test, ts } from '../utils'
2+
3+
const WORKSPACE = {
4+
'package.json': json`
5+
{
6+
"type": "module",
7+
"dependencies": {
8+
"@solidjs/start": "^1",
9+
"solid-js": "^1",
10+
"vinxi": "^0",
11+
"@tailwindcss/vite": "workspace:^",
12+
"tailwindcss": "workspace:^"
13+
}
14+
}
15+
`,
16+
'jsconfig.json': json`
17+
{
18+
"compilerOptions": {
19+
"jsx": "preserve",
20+
"jsxImportSource": "solid-js"
21+
}
22+
}
23+
`,
24+
'app.config.js': ts`
25+
import { defineConfig } from '@solidjs/start/config'
26+
import tailwindcss from '@tailwindcss/vite'
27+
28+
export default defineConfig({
29+
vite: {
30+
plugins: [tailwindcss()],
31+
},
32+
})
33+
`,
34+
'src/entry-server.jsx': js`
35+
// @refresh reload
36+
import { createHandler, StartServer } from '@solidjs/start/server'
37+
38+
export default createHandler(() => (
39+
<StartServer
40+
document={({ assets, children, scripts }) => (
41+
<html lang="en">
42+
<head>{assets}</head>
43+
<body>
44+
<div id="app">{children}</div>
45+
{scripts}
46+
</body>
47+
</html>
48+
)}
49+
/>
50+
))
51+
`,
52+
'src/entry-client.jsx': js`
53+
// @refresh reload
54+
import { mount, StartClient } from '@solidjs/start/client'
55+
56+
mount(() => <StartClient />, document.getElementById('app'))
57+
`,
58+
'src/app.jsx': js`
59+
import './app.css'
60+
export default function App() {
61+
return <h1 class="underline">Hello world!</h1>
62+
}
63+
`,
64+
'src/app.css': css`@import 'tailwindcss';`,
65+
}
66+
67+
test(
68+
'dev mode',
69+
{
70+
fs: WORKSPACE,
71+
},
72+
async ({ fs, spawn, expect }) => {
73+
let process = await spawn('pnpm vinxi dev', {
74+
env: {
75+
TEST: 'false', // VERY IMPORTANT OTHERWISE YOU WON'T GET OUTPUT
76+
NODE_ENV: 'development',
77+
},
78+
})
79+
80+
let url = ''
81+
await process.onStdout((m) => {
82+
let match = /Local:\s*(http.*)\//.exec(m)
83+
if (match) url = match[1]
84+
return Boolean(url)
85+
})
86+
87+
await retryAssertion(async () => {
88+
let css = await fetchStyles(url)
89+
expect(css).toContain(candidate`underline`)
90+
})
91+
92+
await retryAssertion(async () => {
93+
await fs.write(
94+
'src/app.jsx',
95+
js`
96+
import './app.css'
97+
export default function App() {
98+
return <h1 class="underline font-bold">Hello world!</h1>
99+
}
100+
`,
101+
)
102+
103+
let css = await fetchStyles(url)
104+
expect(css).toContain(candidate`underline`)
105+
expect(css).toContain(candidate`font-bold`)
106+
})
107+
},
108+
)

packages/@tailwindcss-postcss/src/index.test.ts

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -248,6 +248,56 @@ test('bail early when Tailwind is not used', async () => {
248248
`)
249249
})
250250

251+
test('handle CSS when only using a `@reference` (we should not bail early)', async () => {
252+
let processor = postcss([
253+
tailwindcss({ base: `${__dirname}/fixtures/example-project`, optimize: { minify: false } }),
254+
])
255+
256+
let result = await processor.process(
257+
css`
258+
@reference "tailwindcss/theme.css";
259+
260+
.foo {
261+
@variant md {
262+
bar: baz;
263+
}
264+
}
265+
`,
266+
{ from: inputCssFilePath() },
267+
)
268+
269+
expect(result.css.trim()).toMatchInlineSnapshot(`
270+
"@media (width >= 48rem) {
271+
.foo {
272+
bar: baz;
273+
}
274+
}"
275+
`)
276+
})
277+
278+
test('handle CSS when using a `@variant` using variants that do not rely on the `@theme`', async () => {
279+
let processor = postcss([
280+
tailwindcss({ base: `${__dirname}/fixtures/example-project`, optimize: { minify: false } }),
281+
])
282+
283+
let result = await processor.process(
284+
css`
285+
.foo {
286+
@variant data-is-hoverable {
287+
bar: baz;
288+
}
289+
}
290+
`,
291+
{ from: inputCssFilePath() },
292+
)
293+
294+
expect(result.css.trim()).toMatchInlineSnapshot(`
295+
".foo[data-is-hoverable] {
296+
bar: baz;
297+
}"
298+
`)
299+
})
300+
251301
test('runs `Once` plugins in the right order', async () => {
252302
let before = ''
253303
let after = ''

packages/@tailwindcss-postcss/src/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,9 @@ function tailwindcss(opts: PluginOptions = {}): AcceptedPlugin {
7777
root.walkAtRules((node) => {
7878
if (
7979
node.name === 'import' ||
80+
node.name === 'reference' ||
8081
node.name === 'theme' ||
82+
node.name === 'variant' ||
8183
node.name === 'config' ||
8284
node.name === 'plugin' ||
8385
node.name === 'apply'

packages/@tailwindcss-vite/src/index.ts

Lines changed: 10 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ export default function tailwindcss(): Plugin[] {
6464
)
6565
})
6666

67-
function scanFile(id: string, content: string, extension: string, isSSR: boolean) {
67+
function scanFile(id: string, content: string, extension: string) {
6868
for (let dependency of IGNORED_DEPENDENCIES) {
6969
// We validated that Vite IDs always use posix style path separators, even on Windows.
7070
// In dev build, Vite precompiles dependencies
@@ -84,26 +84,16 @@ export default function tailwindcss(): Plugin[] {
8484
}
8585

8686
if (updated) {
87-
invalidateAllRoots(isSSR)
87+
invalidateAllRoots()
8888
}
8989
}
9090

91-
function invalidateAllRoots(isSSR: boolean) {
91+
function invalidateAllRoots() {
9292
for (let server of servers) {
9393
let updates: Update[] = []
94-
for (let [id, root] of roots.entries()) {
94+
for (let [id] of roots.entries()) {
9595
let module = server.moduleGraph.getModuleById(id)
96-
if (!module) {
97-
// Note: Removing this during SSR is not safe and will produce
98-
// inconsistent results based on the timing of the removal and
99-
// the order / timing of transforms.
100-
if (!isSSR) {
101-
// It is safe to remove the item here since we're iterating on a copy
102-
// of the keys.
103-
roots.delete(id)
104-
}
105-
continue
106-
}
96+
if (!module) continue
10797

10898
roots.get(id).requiresRebuild = false
10999
server.moduleGraph.invalidateModule(module)
@@ -114,7 +104,6 @@ export default function tailwindcss(): Plugin[] {
114104
timestamp: Date.now(),
115105
})
116106
}
117-
118107
if (updates.length > 0) {
119108
server.hot.send({ type: 'update', updates })
120109
}
@@ -211,12 +200,15 @@ export default function tailwindcss(): Plugin[] {
211200

212201
// Scan all non-CSS files for candidates
213202
transformIndexHtml(html, { path }) {
214-
scanFile(path, html, 'html', isSSR)
203+
// SolidStart emits HTML chunks with an undefined path and the html content of `\`.
204+
if (!path) return
205+
206+
scanFile(path, html, 'html')
215207
},
216208
transform(src, id, options) {
217209
let extension = getExtension(id)
218210
if (isPotentialCssRootFile(id)) return
219-
scanFile(id, src, extension, options?.ssr ?? false)
211+
scanFile(id, src, extension)
220212
},
221213
},
222214

packages/tailwindcss/src/compat/legacy-utilities.test.ts

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -22,42 +22,42 @@ test('bg-gradient-*', async () => {
2222
),
2323
).toMatchInlineSnapshot(`
2424
".bg-gradient-to-b {
25-
--tw-gradient-position: to bottom in oklab, ;
25+
--tw-gradient-position: to bottom in oklab;
2626
background-image: linear-gradient(var(--tw-gradient-stops));
2727
}
2828
2929
.bg-gradient-to-bl {
30-
--tw-gradient-position: to bottom left in oklab, ;
30+
--tw-gradient-position: to bottom left in oklab;
3131
background-image: linear-gradient(var(--tw-gradient-stops));
3232
}
3333
3434
.bg-gradient-to-br {
35-
--tw-gradient-position: to bottom right in oklab, ;
35+
--tw-gradient-position: to bottom right in oklab;
3636
background-image: linear-gradient(var(--tw-gradient-stops));
3737
}
3838
3939
.bg-gradient-to-l {
40-
--tw-gradient-position: to left in oklab, ;
40+
--tw-gradient-position: to left in oklab;
4141
background-image: linear-gradient(var(--tw-gradient-stops));
4242
}
4343
4444
.bg-gradient-to-r {
45-
--tw-gradient-position: to right in oklab, ;
45+
--tw-gradient-position: to right in oklab;
4646
background-image: linear-gradient(var(--tw-gradient-stops));
4747
}
4848
4949
.bg-gradient-to-t {
50-
--tw-gradient-position: to top in oklab, ;
50+
--tw-gradient-position: to top in oklab;
5151
background-image: linear-gradient(var(--tw-gradient-stops));
5252
}
5353
5454
.bg-gradient-to-tl {
55-
--tw-gradient-position: to top left in oklab, ;
55+
--tw-gradient-position: to top left in oklab;
5656
background-image: linear-gradient(var(--tw-gradient-stops));
5757
}
5858
5959
.bg-gradient-to-tr {
60-
--tw-gradient-position: to top right in oklab, ;
60+
--tw-gradient-position: to top right in oklab;
6161
background-image: linear-gradient(var(--tw-gradient-stops));
6262
}"
6363
`)

packages/tailwindcss/src/compat/legacy-utilities.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ export function registerLegacyUtilities(designSystem: DesignSystem) {
1414
['tl', 'top left'],
1515
]) {
1616
designSystem.utilities.static(`bg-gradient-to-${value}`, () => [
17-
decl('--tw-gradient-position', `to ${direction} in oklab,`),
17+
decl('--tw-gradient-position', `to ${direction} in oklab`),
1818
decl('background-image', `linear-gradient(var(--tw-gradient-stops))`),
1919
])
2020
}

0 commit comments

Comments
 (0)