Skip to content

Commit 530774b

Browse files
authored
Ensure --default-font-* and --default-mono-font-* variables respect theme customizations in JS config files (#14344)
This PR fixes an issue where variables like `--default-font-family` wouldn't behave as expected when customizing `fontFamily.sans` or `fontFamily.mono` in a JS config. Because theme values added by JS config files are added as `reference`, customizing `fontFamily.sans` means the `--font-family-sans` variable no longer exists in the generated CSS. The `--default-font-family` variable is set to `var(--font-family-sans)` by default, so because that variable doesn't exist, `--default-font-family` is effectively undefined and the browser default font stack is used. This is unexpected because historically customizing `fontFamily.sans` has updated your default font for your entire project. --------- Co-authored-by: Adam Wathan <[email protected]>
1 parent 262e99e commit 530774b

File tree

4 files changed

+555
-2
lines changed

4 files changed

+555
-2
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
2323
- Don’t suggest named opacity modifiers in intellisense ([#14339](https://github.com/tailwindlabs/tailwindcss/pull/14339))
2424
- Fix a crash with older Node.js versions ([#14342](https://github.com/tailwindlabs/tailwindcss/pull/14342))
2525
- Support defining theme values as arrays of strings in JS config files ([#14343](https://github.com/tailwindlabs/tailwindcss/pull/14343))
26+
- Ensure `--default-font-*` and `--default-mono-font-*` variables respect theme customizations in JS config files ([#14344](https://github.com/tailwindlabs/tailwindcss/pull/14344))
2627

2728
## [4.0.0-alpha.21] - 2024-09-02
2829

packages/tailwindcss/src/compat/apply-config-to-theme.ts

Lines changed: 67 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,19 +2,85 @@ import type { DesignSystem } from '../design-system'
22
import { resolveConfig, type ConfigFile } from './config/resolve-config'
33
import type { ResolvedConfig } from './config/types'
44

5+
function resolveThemeValue(value: unknown, subValue: string | null = null): string | null {
6+
if (
7+
Array.isArray(value) &&
8+
value.length === 2 &&
9+
typeof value[1] === 'object' &&
10+
typeof value[1] !== null
11+
) {
12+
return subValue ? (value[1][subValue] ?? null) : value[0]
13+
} else if (Array.isArray(value) && subValue === null) {
14+
return value.join(', ')
15+
} else if (typeof value === 'string' && subValue === null) {
16+
return value
17+
}
18+
19+
return null
20+
}
21+
522
export function applyConfigToTheme(designSystem: DesignSystem, configs: ConfigFile[]) {
623
let theme = resolveConfig(designSystem, configs).theme
724

825
for (let [path, value] of themeableValues(theme)) {
926
let name = keyPathToCssProperty(path)
10-
1127
designSystem.theme.add(`--${name}`, value as any, {
1228
isInline: true,
1329
isReference: true,
1430
isDefault: true,
1531
})
1632
}
1733

34+
// If someone has updated `fontFamily.sans` or `fontFamily.mono` in a JS
35+
// config, we need to make sure variables like `--default-font-family` and
36+
// `--default-font-feature-settings` are updated to match those explicit
37+
// values, because variables like `--font-family-sans` and
38+
// `--font-family-sans--feature-settings` (which the `--default-font-*`
39+
// variables reference) won't exist in the generated CSS.
40+
if (Object.hasOwn(theme, 'fontFamily')) {
41+
let options = {
42+
isInline: true,
43+
isReference: false,
44+
isDefault: true,
45+
}
46+
47+
// Replace `--default-font-*` with `fontFamily.sans` values
48+
{
49+
let fontFamily = resolveThemeValue(theme.fontFamily.sans)
50+
if (fontFamily && designSystem.theme.hasDefault('--font-family-sans')) {
51+
designSystem.theme.add('--default-font-family', fontFamily, options)
52+
designSystem.theme.add(
53+
'--default-font-feature-settings',
54+
resolveThemeValue(theme.fontFamily.sans, 'fontFeatureSettings') ?? 'normal',
55+
options,
56+
)
57+
designSystem.theme.add(
58+
'--default-font-variation-settings',
59+
resolveThemeValue(theme.fontFamily.sans, 'fontVariationSettings') ?? 'normal',
60+
options,
61+
)
62+
}
63+
}
64+
65+
// Replace `--default-mono-font-*` with `fontFamily.mono` values
66+
{
67+
let fontFamily = resolveThemeValue(theme.fontFamily.mono)
68+
if (fontFamily && designSystem.theme.hasDefault('--font-family-mono')) {
69+
designSystem.theme.add('--default-mono-font-family', 'theme(fontFamily.mono)', options)
70+
designSystem.theme.add(
71+
'--default-mono-font-feature-settings',
72+
resolveThemeValue(theme.fontFamily.mono, 'fontFeatureSettings') ?? 'normal',
73+
options,
74+
)
75+
designSystem.theme.add(
76+
'--default-mono-font-variation-settings',
77+
resolveThemeValue(theme.fontFamily.mono, 'fontVariationSettings') ?? 'normal',
78+
options,
79+
)
80+
}
81+
}
82+
}
83+
1884
return theme
1985
}
2086

0 commit comments

Comments
 (0)