Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
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
43 changes: 43 additions & 0 deletions packages/tailwindcss/src/utilities.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25727,6 +25727,49 @@ test('leading', async () => {
}
"
`)

// Custom named --spacing-* values should not shadow the none keyword but remain resolvable by name
expect(
await run(
['leading-none', 'leading-big'],
css`
@theme {
--spacing-none: 0;
--spacing-big: 3rem;
}
@tailwind utilities;
`,
),
).toMatchInlineSnapshot(`
"
@layer properties {
@supports (((-webkit-hyphens: none)) and (not (margin-trim: inline))) or ((-moz-orient: inline) and (not (color: rgb(from red r g b)))) {
*, :before, :after, ::backdrop {
--tw-leading: initial;
}
}
}

:root, :host {
--spacing-big: 3rem;
}

.leading-big {
--tw-leading: var(--spacing-big);
line-height: var(--spacing-big);
}

.leading-none {
--tw-leading: 1;
line-height: 1;
}

@property --tw-leading {
syntax: "*";
inherits: false
}
"
`)
})

test('tracking', async () => {
Expand Down
27 changes: 25 additions & 2 deletions packages/tailwindcss/src/utilities.ts
Original file line number Diff line number Diff line change
Expand Up @@ -381,6 +381,7 @@ export function createUtilities(theme: Theme) {
supportsNegative?: boolean
supportsFractions?: boolean
themeKeys?: ThemeKey[]
fallbackThemeKeys?: ThemeKey[]
defaultValue?: string | null
staticValues?: Record<string, AstNode[]>
handleBareValue?: (value: NamedUtilityValue) => string | null
Expand Down Expand Up @@ -421,6 +422,19 @@ export function createUtilities(theme: Theme) {
desc.themeKeys ?? [],
)

if (value === null && desc.fallbackThemeKeys) {
// Static keywords like leading-none win over fallback namespaces like --spacing
if (!negative && desc.staticValues && !candidate.modifier) {
let fallback = desc.staticValues[candidate.value.value]
if (fallback) return fallback.map(cloneAstNode)
}

value = theme.resolve(
candidate.value.fraction ?? candidate.value.value,
desc.fallbackThemeKeys,
)
}

// Automatically handle things like `w-1/2` without requiring `1/2` to
// exist as a theme value.
if (value === null && desc.supportsFractions && candidate.value.fraction) {
Expand Down Expand Up @@ -467,7 +481,7 @@ export function createUtilities(theme: Theme) {
suggest(classRoot, () => [
{
supportsNegative: desc.supportsNegative,
valueThemeKeys: desc.themeKeys ?? [],
valueThemeKeys: [...(desc.themeKeys ?? []), ...(desc.fallbackThemeKeys ?? [])],
hasDefaultValue: desc.defaultValue !== undefined && desc.defaultValue !== null,
supportsFractions: desc.supportsFractions,
},
Expand Down Expand Up @@ -543,8 +557,17 @@ export function createUtilities(theme: Theme) {
utilities.static(`-${name}-px`, () => handle('-1px'))
}
utilities.static(`${name}-px`, () => handle('1px'))

// The generic `--spacing` namespace (and everything after it) is resolved
// only after `staticValues`, so custom values like `--spacing-none` don't
// shadow canonical keywords like `leading-none`.
let fallbackIndex = themeKeys.indexOf('--spacing')
let ownThemeKeys = fallbackIndex === -1 ? themeKeys : themeKeys.slice(0, fallbackIndex)
let fallbackThemeKeys = fallbackIndex === -1 ? undefined : themeKeys.slice(fallbackIndex)

functionalUtility(name, {
themeKeys,
themeKeys: ownThemeKeys,
fallbackThemeKeys,
supportsFractions,
supportsNegative,
defaultValue: null,
Expand Down