Skip to content

Commit

Permalink
Use bitfield enum
Browse files Browse the repository at this point in the history
  • Loading branch information
thecrypticace committed Oct 22, 2024
1 parent 3c33a44 commit 275a8ec
Show file tree
Hide file tree
Showing 2 changed files with 59 additions and 57 deletions.
8 changes: 4 additions & 4 deletions packages/tailwindcss/src/candidate.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { expect, it } from 'vitest'
import { buildDesignSystem } from './design-system'
import { Theme } from './theme'
import { Utilities } from './utilities'
import { Variants } from './variants'
import { Compounds, Variants } from './variants'

function run(
candidate: string,
Expand Down Expand Up @@ -209,7 +209,7 @@ it('should parse compound variants with an arbitrary value as an arbitrary varia
utilities.static('flex', () => [])

let variants = new Variants()
variants.compoundWith('group', ['selector'], () => {})
variants.compoundWith('group', Compounds.StyleRules, () => {})

expect(run('group-[&_p]/parent-name:flex', { utilities, variants })).toMatchInlineSnapshot(`
[
Expand Down Expand Up @@ -244,7 +244,7 @@ it('should parse a simple utility with a parameterized variant and a modifier',
utilities.static('flex', () => [])

let variants = new Variants()
variants.compoundWith('group', ['selector'], () => {})
variants.compoundWith('group', Compounds.StyleRules, () => {})
variants.functional('aria', () => {})

expect(run('group-aria-[disabled]/parent-name:flex', { utilities, variants }))
Expand Down Expand Up @@ -286,7 +286,7 @@ it('should parse compound group with itself group-group-*', () => {

let variants = new Variants()
variants.static('hover', () => {})
variants.compoundWith('group', ['selector'], () => {})
variants.compoundWith('group', Compounds.StyleRules, () => {})

expect(run('group-group-group-hover/parent-name:flex', { utilities, variants }))
.toMatchInlineSnapshot(`
Expand Down
108 changes: 55 additions & 53 deletions packages/tailwindcss/src/variants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,11 @@ type VariantFn<T extends Variant['kind']> = (

type CompareFn = (a: Variant, z: Variant) => number

type CompoundKind = false | Array<'at-rule' | 'selector'>
export const enum Compounds {
Never = 0,
AtRules = 1 << 0,
StyleRules = 1 << 1,
}

export class Variants {
public compareFns = new Map<number, CompareFn>()
Expand All @@ -24,11 +28,11 @@ export class Variants {
applyFn: VariantFn<any>

// The kind of rules that are allowed in this compound variant
compoundsWith: CompoundKind
compoundsWith: Compounds

// The kind of rules that are generated by this variant
// Determines whether or not a compound variant can use this variant
compounds: CompoundKind
compounds: Compounds
}
>()

Expand All @@ -50,13 +54,13 @@ export class Variants {
static(
name: string,
applyFn: VariantFn<'static'>,
{ compounds, order }: { compounds?: CompoundKind; order?: number } = {},
{ compounds, order }: { compounds?: Compounds; order?: number } = {},
) {
this.set(name, {
kind: 'static',
applyFn,
compoundsWith: false,
compounds: compounds ?? ['selector'],
compoundsWith: Compounds.Never,
compounds: compounds ?? Compounds.StyleRules,
order,
})
}
Expand All @@ -72,28 +76,28 @@ export class Variants {
functional(
name: string,
applyFn: VariantFn<'functional'>,
{ compounds, order }: { compounds?: CompoundKind; order?: number } = {},
{ compounds, order }: { compounds?: Compounds; order?: number } = {},
) {
this.set(name, {
kind: 'functional',
applyFn,
compoundsWith: false,
compounds: compounds ?? ['selector'],
compoundsWith: Compounds.Never,
compounds: compounds ?? Compounds.StyleRules,
order,
})
}

compoundWith(
name: string,
compoundsWith: CompoundKind,
compoundsWith: Compounds,
applyFn: VariantFn<'compound'>,
{ compounds, order }: { compounds?: CompoundKind; order?: number } = {},
{ compounds, order }: { compounds?: Compounds; order?: number } = {},
) {
this.set(name, {
kind: 'compound',
applyFn,
compoundsWith,
compounds: compounds ?? ['selector'],
compounds: compounds ?? Compounds.StyleRules,
order,
})
}
Expand Down Expand Up @@ -123,7 +127,7 @@ export class Variants {
typeof child === 'string'
? this.variants.get(child)
: child.kind === 'arbitrary'
? { compounds: ['selector'] as CompoundKind }
? { compounds: Compounds.StyleRules }
: this.variants.get(child.root)

// One of the variants don't exist
Expand All @@ -138,16 +142,14 @@ export class Variants {
// variant at runtime to see if the rules are compatible.

// The `child` variant cannot compound *ever*
if (childInfo.compounds === false) return false
if (childInfo.compounds === Compounds.Never) return false

// The `parent` variant cannot compound *ever*
// This shouldn't ever happen because `kind` is `compound`
if (parentInfo.compoundsWith === false) return false
if (parentInfo.compoundsWith === Compounds.Never) return false

// Any rule that `child` may generate must be supported by `parent`
for (let compound of childInfo.compounds) {
if (!parentInfo.compoundsWith.includes(compound)) return false
}
if ((parentInfo.compoundsWith & childInfo.compounds) === 0) return false

return true
}
Expand Down Expand Up @@ -217,8 +219,8 @@ export class Variants {
}: {
kind: T
applyFn: VariantFn<T>
compoundsWith: CompoundKind
compounds: CompoundKind
compoundsWith: Compounds
compounds: Compounds
order?: number
},
) {
Expand Down Expand Up @@ -257,7 +259,7 @@ export function createVariants(theme: Theme): Variants {
function staticVariant(
name: string,
selectors: string[],
{ compounds }: { compounds?: CompoundKind } = {},
{ compounds }: { compounds?: Compounds } = {},
) {
variants.static(
name,
Expand All @@ -268,8 +270,8 @@ export function createVariants(theme: Theme): Variants {
)
}

variants.static('force', () => {}, { compounds: false })
staticVariant('*', [':where(& > *)'], { compounds: false })
variants.static('force', () => {}, { compounds: Compounds.Never })
staticVariant('*', [':where(& > *)'], { compounds: Compounds.Never })

function negateConditions(ruleName: string, conditions: string[]) {
return conditions.map((condition) => {
Expand Down Expand Up @@ -343,7 +345,7 @@ export function createVariants(theme: Theme): Variants {
return `&:not(${selectors.join(', ')})`
}

variants.compoundWith('not', ['selector', 'at-rule'], (ruleNode, variant) => {
variants.compoundWith('not', Compounds.StyleRules | Compounds.AtRules, (ruleNode, variant) => {
if (variant.variant.kind === 'arbitrary' && variant.variant.relative) return null

if (variant.modifier) return null
Expand Down Expand Up @@ -418,7 +420,7 @@ export function createVariants(theme: Theme): Variants {
})
})

variants.compoundWith('group', ['selector'], (ruleNode, variant) => {
variants.compoundWith('group', Compounds.StyleRules, (ruleNode, variant) => {
if (variant.variant.kind === 'arbitrary' && variant.variant.relative) return null

// Name the group by appending the modifier to `group` class itself if
Expand Down Expand Up @@ -474,7 +476,7 @@ export function createVariants(theme: Theme): Variants {
})
})

variants.compoundWith('peer', ['selector'], (ruleNode, variant) => {
variants.compoundWith('peer', Compounds.StyleRules, (ruleNode, variant) => {
if (variant.variant.kind === 'arbitrary' && variant.variant.relative) return null

// Name the peer by appending the modifier to `peer` class itself if
Expand Down Expand Up @@ -530,16 +532,16 @@ export function createVariants(theme: Theme): Variants {
})
})

staticVariant('first-letter', ['&::first-letter'], { compounds: false })
staticVariant('first-line', ['&::first-line'], { compounds: false })
staticVariant('first-letter', ['&::first-letter'], { compounds: Compounds.Never })
staticVariant('first-line', ['&::first-line'], { compounds: Compounds.Never })

// TODO: Remove alpha vars or no?
staticVariant('marker', ['& *::marker', '&::marker'], { compounds: false })
staticVariant('marker', ['& *::marker', '&::marker'], { compounds: Compounds.Never })

staticVariant('selection', ['& *::selection', '&::selection'], { compounds: false })
staticVariant('file', ['&::file-selector-button'], { compounds: false })
staticVariant('placeholder', ['&::placeholder'], { compounds: false })
staticVariant('backdrop', ['&::backdrop'], { compounds: false })
staticVariant('selection', ['& *::selection', '&::selection'], { compounds: Compounds.Never })
staticVariant('file', ['&::file-selector-button'], { compounds: Compounds.Never })
staticVariant('placeholder', ['&::placeholder'], { compounds: Compounds.Never })
staticVariant('backdrop', ['&::backdrop'], { compounds: Compounds.Never })

{
function contentProperties() {
Expand All @@ -562,7 +564,7 @@ export function createVariants(theme: Theme): Variants {
]),
]
},
{ compounds: false },
{ compounds: Compounds.Never },
)

variants.static(
Expand All @@ -572,7 +574,7 @@ export function createVariants(theme: Theme): Variants {
rule('&::after', [contentProperties(), decl('content', 'var(--tw-content)'), ...v.nodes]),
]
},
{ compounds: false },
{ compounds: Compounds.Never },
)
}

Expand Down Expand Up @@ -621,7 +623,7 @@ export function createVariants(theme: Theme): Variants {

staticVariant('inert', ['&:is([inert], [inert] *)'])

variants.compoundWith('has', ['selector'], (ruleNode, variant) => {
variants.compoundWith('has', Compounds.StyleRules, (ruleNode, variant) => {
if (variant.modifier) return null

let didApply = false
Expand Down Expand Up @@ -767,21 +769,21 @@ export function createVariants(theme: Theme): Variants {

ruleNode.nodes = [rule(`@supports ${value}`, ruleNode.nodes)]
},
{ compounds: ['at-rule'] },
{ compounds: Compounds.AtRules },
)

staticVariant('motion-safe', ['@media (prefers-reduced-motion: no-preference)'], {
compounds: ['at-rule'],
compounds: Compounds.AtRules,
})
staticVariant('motion-reduce', ['@media (prefers-reduced-motion: reduce)'], {
compounds: ['at-rule'],
compounds: Compounds.AtRules,
})

staticVariant('contrast-more', ['@media (prefers-contrast: more)'], {
compounds: ['at-rule'],
compounds: Compounds.AtRules,
})
staticVariant('contrast-less', ['@media (prefers-contrast: less)'], {
compounds: ['at-rule'],
compounds: Compounds.AtRules,
})

{
Expand Down Expand Up @@ -894,7 +896,7 @@ export function createVariants(theme: Theme): Variants {

ruleNode.nodes = [rule(`@media (width < ${value})`, ruleNode.nodes)]
},
{ compounds: ['at-rule'] },
{ compounds: Compounds.AtRules },
)
},
(a, z) => compareBreakpoints(a, z, 'desc', resolvedBreakpoints),
Expand All @@ -916,7 +918,7 @@ export function createVariants(theme: Theme): Variants {
(ruleNode) => {
ruleNode.nodes = [rule(`@media (width >= ${value})`, ruleNode.nodes)]
},
{ compounds: ['at-rule'] },
{ compounds: Compounds.AtRules },
)
}

Expand All @@ -929,7 +931,7 @@ export function createVariants(theme: Theme): Variants {

ruleNode.nodes = [rule(`@media (width >= ${value})`, ruleNode.nodes)]
},
{ compounds: ['at-rule'] },
{ compounds: Compounds.AtRules },
)
},
(a, z) => compareBreakpoints(a, z, 'asc', resolvedBreakpoints),
Expand Down Expand Up @@ -987,7 +989,7 @@ export function createVariants(theme: Theme): Variants {
),
]
},
{ compounds: ['at-rule'] },
{ compounds: Compounds.AtRules },
)
},
(a, z) => compareBreakpoints(a, z, 'desc', resolvedWidths),
Expand Down Expand Up @@ -1015,7 +1017,7 @@ export function createVariants(theme: Theme): Variants {
),
]
},
{ compounds: ['at-rule'] },
{ compounds: Compounds.AtRules },
)
variants.functional(
'@min',
Expand All @@ -1032,7 +1034,7 @@ export function createVariants(theme: Theme): Variants {
),
]
},
{ compounds: ['at-rule'] },
{ compounds: Compounds.AtRules },
)
},
(a, z) => compareBreakpoints(a, z, 'asc', resolvedWidths),
Expand All @@ -1045,24 +1047,24 @@ export function createVariants(theme: Theme): Variants {
}
}

staticVariant('portrait', ['@media (orientation: portrait)'], { compounds: ['at-rule'] })
staticVariant('portrait', ['@media (orientation: portrait)'], { compounds: Compounds.AtRules })
staticVariant('landscape', ['@media (orientation: landscape)'], {
compounds: ['at-rule'],
compounds: Compounds.AtRules,
})

staticVariant('ltr', ['&:where(:dir(ltr), [dir="ltr"], [dir="ltr"] *)'])
staticVariant('rtl', ['&:where(:dir(rtl), [dir="rtl"], [dir="rtl"] *)'])

staticVariant('dark', ['@media (prefers-color-scheme: dark)'], {
compounds: ['at-rule'],
compounds: Compounds.AtRules,
})

staticVariant('starting', ['@starting-style'], { compounds: false })
staticVariant('starting', ['@starting-style'], { compounds: Compounds.Never })

staticVariant('print', ['@media print'], { compounds: ['at-rule'] })
staticVariant('print', ['@media print'], { compounds: Compounds.AtRules })

staticVariant('forced-colors', ['@media (forced-colors: active)'], {
compounds: ['at-rule'],
compounds: Compounds.AtRules,
})

return variants
Expand Down

0 comments on commit 275a8ec

Please sign in to comment.