Skip to content

Commit 94ef122

Browse files
authored
Merge branch 'main' into feat/enable-codemods-on-v4-projects
2 parents d20902f + 8bf06ab commit 94ef122

8 files changed

Lines changed: 81 additions & 97 deletions

File tree

CHANGELOG.md

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

1212
- Don't scan `.geojson` files for classes by default ([#17700](https://github.com/tailwindlabs/tailwindcss/pull/17700))
13+
- Hide default shadow suggestions when missing theme keys ([#17743](https://github.com/tailwindlabs/tailwindcss/pull/17743))
14+
- Replace `_` with `.` in theme suggestions for `@utility` if surrounded by digits ([#17743](https://github.com/tailwindlabs/tailwindcss/pull/17743))
1315

1416
## [4.1.4] - 2025-04-14
1517

packages/tailwindcss/src/__snapshots__/intellisense.test.ts.snap

Lines changed: 0 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -4755,28 +4755,6 @@ exports[`getClassList 1`] = `
47554755
"inset-ring-transparent/90",
47564756
"inset-ring-transparent/95",
47574757
"inset-ring-transparent/100",
4758-
"inset-shadow",
4759-
"inset-shadow/0",
4760-
"inset-shadow/5",
4761-
"inset-shadow/10",
4762-
"inset-shadow/15",
4763-
"inset-shadow/20",
4764-
"inset-shadow/25",
4765-
"inset-shadow/30",
4766-
"inset-shadow/35",
4767-
"inset-shadow/40",
4768-
"inset-shadow/45",
4769-
"inset-shadow/50",
4770-
"inset-shadow/55",
4771-
"inset-shadow/60",
4772-
"inset-shadow/65",
4773-
"inset-shadow/70",
4774-
"inset-shadow/75",
4775-
"inset-shadow/80",
4776-
"inset-shadow/85",
4777-
"inset-shadow/90",
4778-
"inset-shadow/95",
4779-
"inset-shadow/100",
47804758
"inset-shadow-current",
47814759
"inset-shadow-current/0",
47824760
"inset-shadow-current/5",
@@ -9685,28 +9663,6 @@ exports[`getClassList 1`] = `
96859663
"sepia-0",
96869664
"sepia-50",
96879665
"sepia-100",
9688-
"shadow",
9689-
"shadow/0",
9690-
"shadow/5",
9691-
"shadow/10",
9692-
"shadow/15",
9693-
"shadow/20",
9694-
"shadow/25",
9695-
"shadow/30",
9696-
"shadow/35",
9697-
"shadow/40",
9698-
"shadow/45",
9699-
"shadow/50",
9700-
"shadow/55",
9701-
"shadow/60",
9702-
"shadow/65",
9703-
"shadow/70",
9704-
"shadow/75",
9705-
"shadow/80",
9706-
"shadow/85",
9707-
"shadow/90",
9708-
"shadow/95",
9709-
"shadow/100",
97109666
"shadow-current",
97119667
"shadow-current/0",
97129668
"shadow-current/5",
@@ -10157,28 +10113,6 @@ exports[`getClassList 1`] = `
1015710113
"text-nowrap",
1015810114
"text-pretty",
1015910115
"text-right",
10160-
"text-shadow",
10161-
"text-shadow/0",
10162-
"text-shadow/5",
10163-
"text-shadow/10",
10164-
"text-shadow/15",
10165-
"text-shadow/20",
10166-
"text-shadow/25",
10167-
"text-shadow/30",
10168-
"text-shadow/35",
10169-
"text-shadow/40",
10170-
"text-shadow/45",
10171-
"text-shadow/50",
10172-
"text-shadow/55",
10173-
"text-shadow/60",
10174-
"text-shadow/65",
10175-
"text-shadow/70",
10176-
"text-shadow/75",
10177-
"text-shadow/80",
10178-
"text-shadow/85",
10179-
"text-shadow/90",
10180-
"text-shadow/95",
10181-
"text-shadow/100",
1018210116
"text-shadow-current",
1018310117
"text-shadow-current/0",
1018410118
"text-shadow-current/5",

packages/tailwindcss/src/intellisense.test.ts

Lines changed: 45 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -579,6 +579,10 @@ test('Theme keys with underscores are suggested with underscores', async () => {
579579
/* This will get suggeted with an underscore */
580580
--spacing-logo_margin: 0.875rem;
581581
}
582+
583+
@utility ex-* {
584+
width: --value(--spacing- *);
585+
}
582586
`
583587

584588
let design = await __unstable__loadDesignSystem(input, {
@@ -588,13 +592,53 @@ test('Theme keys with underscores are suggested with underscores', async () => {
588592
}),
589593
})
590594

591-
let entries = design.getClassList().filter(([name]) => name.startsWith('p-'))
595+
let entries = design
596+
.getClassList()
597+
.filter(([name]) => name.startsWith('p-') || name.startsWith('ex-'))
592598

593599
expect(entries).toContainEqual(['p-1.5', { modifiers: [] }])
594600
expect(entries).toContainEqual(['p-2.5', { modifiers: [] }])
595601
expect(entries).toContainEqual(['p-logo_margin', { modifiers: [] }])
596602

603+
expect(entries).toContainEqual(['ex-1.5', { modifiers: [] }])
604+
expect(entries).toContainEqual(['ex-2.5', { modifiers: [] }])
605+
expect(entries).toContainEqual(['ex-logo_margin', { modifiers: [] }])
606+
597607
expect(entries).not.toContainEqual(['p-1_5', { modifiers: [] }])
598608
expect(entries).not.toContainEqual(['p-2_5', { modifiers: [] }])
599609
expect(entries).not.toContainEqual(['p-logo.margin', { modifiers: [] }])
610+
611+
expect(entries).not.toContainEqual(['ex-1_5', { modifiers: [] }])
612+
expect(entries).not.toContainEqual(['ex-2_5', { modifiers: [] }])
613+
expect(entries).not.toContainEqual(['ex-logo.margin', { modifiers: [] }])
614+
})
615+
616+
test('shadow utility default suggestions', async () => {
617+
let input = css`
618+
@theme {
619+
/* nothing */
620+
}
621+
`
622+
623+
let design = await __unstable__loadDesignSystem(input)
624+
let classNames = design.getClassList().map(([name]) => name)
625+
626+
expect(classNames).not.toContain('shadow')
627+
expect(classNames).not.toContain('inset-shadow')
628+
expect(classNames).not.toContain('text-shadow')
629+
630+
input = css`
631+
@theme {
632+
--shadow: 0 0 0 solid black;
633+
--text-shadow: 0 0 0 solid black;
634+
--inset-shadow: 0 0 0 solid black;
635+
}
636+
`
637+
638+
design = await __unstable__loadDesignSystem(input)
639+
classNames = design.getClassList().map(([name]) => name)
640+
641+
expect(classNames).toContain('shadow')
642+
expect(classNames).toContain('inset-shadow')
643+
expect(classNames).toContain('text-shadow')
600644
})

packages/tailwindcss/src/utilities.ts

Lines changed: 17 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -266,22 +266,22 @@ function resolveThemeColor<T extends ThemeKey>(
266266
return value ? asColor(value, candidate.modifier, theme) : null
267267
}
268268

269+
/**
270+
* The alpha and beta releases used `_` in theme keys to represent a `.`. This meant we used
271+
* `--leading-1_5` instead of `--leading-1\.5` to add utilities like `leading-1.5`.
272+
*
273+
* We prefer the use of the escaped dot now but still want to make sure suggestions for the
274+
* legacy key format still works as expected when surrounded by numbers.
275+
*/
276+
const LEGACY_NUMERIC_KEY = /(\d+)_(\d+)/g
277+
269278
export function createUtilities(theme: Theme) {
270279
let utilities = new Utilities()
271280

272281
/**
273282
* Register list of suggestions for a class
274283
*/
275284
function suggest(classRoot: string, defns: () => SuggestionDefinition[]) {
276-
/**
277-
* The alpha and beta releases used `_` in theme keys to represent a `.`. This meant we used
278-
* `--leading-1_5` instead of `--leading-1\.5` to add utilities like `leading-1.5`.
279-
*
280-
* We prefer the use of the escaped dot now but still want to make sure suggestions for the
281-
* legacy key format still works as expected when surrounded by numbers.
282-
*/
283-
const LEGACY_NUMERIC_KEY = /(\d+)_(\d+)/g
284-
285285
function* resolve(themeKeys: ThemeKey[]) {
286286
for (let value of theme.keysInNamespaces(themeKeys)) {
287287
yield value.replace(LEGACY_NUMERIC_KEY, (_, a, b) => {
@@ -5182,7 +5182,7 @@ export function createUtilities(theme: Theme) {
51825182
{
51835183
valueThemeKeys: ['--text-shadow'],
51845184
modifiers: Array.from({ length: 21 }, (_, index) => `${index * 5}`),
5185-
hasDefaultValue: true,
5185+
hasDefaultValue: theme.get(['--text-shadow']) !== null,
51865186
},
51875187
])
51885188

@@ -5335,7 +5335,7 @@ export function createUtilities(theme: Theme) {
53355335
{
53365336
valueThemeKeys: ['--shadow'],
53375337
modifiers: Array.from({ length: 21 }, (_, index) => `${index * 5}`),
5338-
hasDefaultValue: true,
5338+
hasDefaultValue: theme.get(['--shadow']) !== null,
53395339
},
53405340
])
53415341

@@ -5462,7 +5462,7 @@ export function createUtilities(theme: Theme) {
54625462
{
54635463
valueThemeKeys: ['--inset-shadow'],
54645464
modifiers: Array.from({ length: 21 }, (_, index) => `${index * 5}`),
5465-
hasDefaultValue: true,
5465+
hasDefaultValue: theme.get(['--inset-shadow']) !== null,
54665466
},
54675467
])
54685468

@@ -6060,7 +6060,11 @@ export function createCssUtility(node: AtRule) {
60606060

60616061
// Suggest theme values. E.g.: `--value(--color-*)`
60626062
for (let value of designSystem.theme.keysInNamespaces(themeKeys)) {
6063-
target.push(value)
6063+
target.push(
6064+
value.replace(LEGACY_NUMERIC_KEY, (_, a, b) => {
6065+
return `${a}.${b}`
6066+
}),
6067+
)
60646068
}
60656069
}
60666070

playgrounds/nextjs/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
},
1919
"devDependencies": {
2020
"@types/node": "catalog:",
21-
"@types/react": "^19.0.12",
21+
"@types/react": "^19.1.2",
2222
"@types/react-dom": "^19.1.1",
2323
"eslint": "^9.24.0",
2424
"eslint-config-next": "^15.2.4",

playgrounds/v3/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
},
1717
"devDependencies": {
1818
"@types/node": "^20.14.8",
19-
"@types/react": "^19.0.12",
19+
"@types/react": "^19.1.2",
2020
"@types/react-dom": "^19.1.1",
2121
"autoprefixer": "^10.4.21",
2222
"eslint": "^9.24.0",

playgrounds/vite/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
"tailwindcss": "workspace:^"
1717
},
1818
"devDependencies": {
19-
"@types/react": "^19.0.12",
19+
"@types/react": "^19.1.2",
2020
"@types/react-dom": "^19.1.1",
2121
"bun": "^1.2.8",
2222
"vite": "catalog:"

pnpm-lock.yaml

Lines changed: 14 additions & 14 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)