mirror of
https://github.com/tailwindlabs/tailwindcss.git
synced 2025-12-08 21:36:08 +00:00
Use a bit flags for theme options instead of an object with booleans (#14337)
This PR is a small improvement to the theme options where it's just a simple number now instead of an object with booleans.
This commit is contained in:
parent
af774e8f24
commit
7f06777d6c
@ -1,4 +1,5 @@
|
||||
import type { DesignSystem } from '../design-system'
|
||||
import { ThemeOptions } from '../theme'
|
||||
import { resolveConfig, type ConfigFile } from './config/resolve-config'
|
||||
import type { ResolvedConfig } from './config/types'
|
||||
|
||||
@ -24,11 +25,11 @@ export function applyConfigToTheme(designSystem: DesignSystem, configs: ConfigFi
|
||||
|
||||
for (let [path, value] of themeableValues(theme)) {
|
||||
let name = keyPathToCssProperty(path)
|
||||
designSystem.theme.add(`--${name}`, value as any, {
|
||||
isInline: true,
|
||||
isReference: true,
|
||||
isDefault: true,
|
||||
})
|
||||
designSystem.theme.add(
|
||||
`--${name}`,
|
||||
value as any,
|
||||
ThemeOptions.INLINE | ThemeOptions.REFERENCE | ThemeOptions.DEFAULT,
|
||||
)
|
||||
}
|
||||
|
||||
// If someone has updated `fontFamily.sans` or `fontFamily.mono` in a JS
|
||||
@ -38,11 +39,7 @@ export function applyConfigToTheme(designSystem: DesignSystem, configs: ConfigFi
|
||||
// `--font-family-sans--feature-settings` (which the `--default-font-*`
|
||||
// variables reference) won't exist in the generated CSS.
|
||||
if (Object.hasOwn(theme, 'fontFamily')) {
|
||||
let options = {
|
||||
isInline: true,
|
||||
isReference: false,
|
||||
isDefault: true,
|
||||
}
|
||||
let options = ThemeOptions.INLINE | ThemeOptions.DEFAULT
|
||||
|
||||
// Replace `--default-font-*` with `fontFamily.sans` values
|
||||
{
|
||||
|
||||
@ -7,7 +7,7 @@ import { substituteFunctions, THEME_FUNCTION_INVOCATION } from './css-functions'
|
||||
import * as CSS from './css-parser'
|
||||
import { buildDesignSystem, type DesignSystem } from './design-system'
|
||||
import { registerPlugins, type CssPluginOptions, type Plugin } from './plugin-api'
|
||||
import { Theme } from './theme'
|
||||
import { Theme, ThemeOptions } from './theme'
|
||||
import { segment } from './utils/segment'
|
||||
|
||||
const IS_VALID_UTILITY_NAME = /^[a-z][a-zA-Z0-9/%._-]*$/
|
||||
@ -26,21 +26,19 @@ function throwOnConfig(): never {
|
||||
}
|
||||
|
||||
function parseThemeOptions(selector: string) {
|
||||
let isReference = false
|
||||
let isInline = false
|
||||
let isDefault = false
|
||||
let options = ThemeOptions.NONE
|
||||
|
||||
for (let option of segment(selector.slice(6) /* '@theme'.length */, ' ')) {
|
||||
if (option === 'reference') {
|
||||
isReference = true
|
||||
options |= ThemeOptions.REFERENCE
|
||||
} else if (option === 'inline') {
|
||||
isInline = true
|
||||
options |= ThemeOptions.INLINE
|
||||
} else if (option === 'default') {
|
||||
isDefault = true
|
||||
options |= ThemeOptions.DEFAULT
|
||||
}
|
||||
}
|
||||
|
||||
return { isReference, isInline, isDefault }
|
||||
return options
|
||||
}
|
||||
|
||||
async function parseCss(
|
||||
@ -267,7 +265,7 @@ async function parseCss(
|
||||
|
||||
if (node.selector !== '@theme' && !node.selector.startsWith('@theme ')) return
|
||||
|
||||
let { isReference, isInline, isDefault } = parseThemeOptions(node.selector)
|
||||
let themeOptions = parseThemeOptions(node.selector)
|
||||
|
||||
// Record all custom properties in the `@theme` declaration
|
||||
walk(node.nodes, (child, { replaceWith }) => {
|
||||
@ -281,7 +279,7 @@ async function parseCss(
|
||||
|
||||
if (child.kind === 'comment') return
|
||||
if (child.kind === 'declaration' && child.property.startsWith('--')) {
|
||||
theme.add(child.property, child.value ?? '', { isReference, isInline, isDefault })
|
||||
theme.add(child.property, child.value ?? '', themeOptions)
|
||||
return
|
||||
}
|
||||
|
||||
@ -297,7 +295,7 @@ async function parseCss(
|
||||
|
||||
// Keep a reference to the first `@theme` rule to update with the full theme
|
||||
// later, and delete any other `@theme` rules.
|
||||
if (!firstThemeRule && !isReference) {
|
||||
if (!firstThemeRule && !(themeOptions & ThemeOptions.REFERENCE)) {
|
||||
firstThemeRule = node
|
||||
} else {
|
||||
replaceWith([])
|
||||
@ -341,7 +339,7 @@ async function parseCss(
|
||||
let nodes = []
|
||||
|
||||
for (let [key, value] of theme.entries()) {
|
||||
if (value.isReference) continue
|
||||
if (value.options & ThemeOptions.REFERENCE) continue
|
||||
nodes.push(decl(key, value.value))
|
||||
}
|
||||
|
||||
|
||||
@ -1,18 +1,16 @@
|
||||
import { escape } from './utils/escape'
|
||||
|
||||
export class Theme {
|
||||
constructor(
|
||||
private values = new Map<
|
||||
string,
|
||||
{ value: string; isReference: boolean; isInline: boolean; isDefault: boolean }
|
||||
>(),
|
||||
) {}
|
||||
export const enum ThemeOptions {
|
||||
NONE = 0,
|
||||
INLINE = 1 << 0,
|
||||
REFERENCE = 1 << 1,
|
||||
DEFAULT = 1 << 2,
|
||||
}
|
||||
|
||||
add(
|
||||
key: string,
|
||||
value: string,
|
||||
{ isReference = false, isInline = false, isDefault = false } = {},
|
||||
): void {
|
||||
export class Theme {
|
||||
constructor(private values = new Map<string, { value: string; options: number }>()) {}
|
||||
|
||||
add(key: string, value: string, options = ThemeOptions.NONE): void {
|
||||
if (key.endsWith('-*')) {
|
||||
if (value !== 'initial') {
|
||||
throw new Error(`Invalid theme value \`${value}\` for namespace \`${key}\``)
|
||||
@ -24,15 +22,15 @@ export class Theme {
|
||||
}
|
||||
}
|
||||
|
||||
if (isDefault) {
|
||||
if (options & ThemeOptions.DEFAULT) {
|
||||
let existing = this.values.get(key)
|
||||
if (existing && !existing.isDefault) return
|
||||
if (existing && !(existing.options & ThemeOptions.DEFAULT)) return
|
||||
}
|
||||
|
||||
if (value === 'initial') {
|
||||
this.values.delete(key)
|
||||
} else {
|
||||
this.values.set(key, { value, isReference, isInline, isDefault })
|
||||
this.values.set(key, { value, options })
|
||||
}
|
||||
}
|
||||
|
||||
@ -68,7 +66,7 @@ export class Theme {
|
||||
}
|
||||
|
||||
hasDefault(key: string): boolean {
|
||||
return this.values.get(key)?.isDefault ?? false
|
||||
return ((this.values.get(key)?.options ?? 0) & ThemeOptions.DEFAULT) === ThemeOptions.DEFAULT
|
||||
}
|
||||
|
||||
entries() {
|
||||
@ -111,7 +109,7 @@ export class Theme {
|
||||
|
||||
let value = this.values.get(themeKey)!
|
||||
|
||||
if (value.isInline) {
|
||||
if (value.options & ThemeOptions.INLINE) {
|
||||
return value.value
|
||||
}
|
||||
|
||||
@ -141,7 +139,7 @@ export class Theme {
|
||||
let nestedValue = this.values.get(nestedKey)!
|
||||
if (!nestedValue) continue
|
||||
|
||||
if (nestedValue.isInline) {
|
||||
if (nestedValue.options & ThemeOptions.INLINE) {
|
||||
extra[name] = nestedValue.value
|
||||
} else {
|
||||
extra[name] = this.#var(nestedKey)!
|
||||
@ -150,7 +148,7 @@ export class Theme {
|
||||
|
||||
let value = this.values.get(themeKey)!
|
||||
|
||||
if (value.isInline) {
|
||||
if (value.options & ThemeOptions.INLINE) {
|
||||
return [value.value, extra]
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user