diff --git a/CHANGELOG.md b/CHANGELOG.md index 2987652bbced..06d27203950a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Export `tailwindcss/lib/util/flattenColorPalette.js` for backward compatibility ([#16411](https://github.com/tailwindlabs/tailwindcss/pull/16411)) - Fix sorting numeric utilities when they have different magnitudes ([#16414](https://github.com/tailwindlabs/tailwindcss/pull/16414)) - Show suggestions for fractions in IntelliSense ([#16353](https://github.com/tailwindlabs/tailwindcss/pull/16353)) +- Don’t replace `_` in suggested theme keys ([#16433](https://github.com/tailwindlabs/tailwindcss/pull/16433)) ## [4.0.6] - 2025-02-10 diff --git a/packages/tailwindcss/src/intellisense.test.ts b/packages/tailwindcss/src/intellisense.test.ts index b95c843fd9d0..4a69aa5009ff 100644 --- a/packages/tailwindcss/src/intellisense.test.ts +++ b/packages/tailwindcss/src/intellisense.test.ts @@ -526,3 +526,40 @@ test('Custom functional @utility', async () => { expect(classNames).toContain('example-xs') expect(classMap.get('example-xs')?.modifiers).toEqual(['foo', 'bar']) }) + +test('Theme keys with underscores are suggested with underscores', async () => { + let input = css` + @import 'tailwindcss/utilities'; + + @theme { + /* Disable the spacing scale */ + --spacing: initial; + + /* This will get suggeted with a dot because its surrounded by numbers */ + --spacing-1_5: 1.5rem; + + /* This will get suggeted with a dot */ + --spacing-2\.5: 1.5rem; + + /* This will get suggeted with an underscore */ + --spacing-logo_margin: 0.875rem; + } + ` + + let design = await __unstable__loadDesignSystem(input, { + loadStylesheet: async (_, base) => ({ + base, + content: '@tailwind utilities;', + }), + }) + + let entries = design.getClassList().filter(([name]) => name.startsWith('p-')) + + expect(entries).toContainEqual(['p-1.5', { modifiers: [] }]) + expect(entries).toContainEqual(['p-2.5', { modifiers: [] }]) + expect(entries).toContainEqual(['p-logo_margin', { modifiers: [] }]) + + expect(entries).not.toContainEqual(['p-1_5', { modifiers: [] }]) + expect(entries).not.toContainEqual(['p-2_5', { modifiers: [] }]) + expect(entries).not.toContainEqual(['p-logo.margin', { modifiers: [] }]) +}) diff --git a/packages/tailwindcss/src/utilities.ts b/packages/tailwindcss/src/utilities.ts index 57e753be1dcf..ea9a39ec466b 100644 --- a/packages/tailwindcss/src/utilities.ts +++ b/packages/tailwindcss/src/utilities.ts @@ -220,9 +220,20 @@ export function createUtilities(theme: Theme) { * Register list of suggestions for a class */ function suggest(classRoot: string, defns: () => SuggestionDefinition[]) { + /** + * The alpha and beta releases used `_` in theme keys to represent a `.`. This meant we used + * `--leading-1_5` instead of `--leading-1\.5` to add utilities like `leading-1.5`. + * + * We prefer the use of the escaped dot now but still want to make sure suggestions for the + * legacy key format still works as expected when surrounded by numbers. + */ + const LEGACY_NUMERIC_KEY = /(\d+)_(\d+)/g + function* resolve(themeKeys: ThemeKey[]) { for (let value of theme.keysInNamespaces(themeKeys)) { - yield value.replaceAll('_', '.') + yield value.replace(LEGACY_NUMERIC_KEY, (_, a, b) => { + return `${a}.${b}` + }) } }