Skip to content

Commit

Permalink
implement in-* as a compound variant
Browse files Browse the repository at this point in the history
  • Loading branch information
RobinMalfait committed Nov 18, 2024
1 parent d177f4c commit 34678d1
Show file tree
Hide file tree
Showing 4 changed files with 39 additions and 55 deletions.
25 changes: 0 additions & 25 deletions packages/tailwindcss/src/utils/is-alpha.bench.ts

This file was deleted.

14 changes: 0 additions & 14 deletions packages/tailwindcss/src/utils/is-alpha.ts

This file was deleted.

21 changes: 14 additions & 7 deletions packages/tailwindcss/src/variants.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1694,13 +1694,20 @@ test('not', async () => {
})

test('in', async () => {
expect(await run(['in-p:flex', 'in-[p]:flex', 'in-[.group]:flex', 'not-in-p:flex']))
.toMatchInlineSnapshot(`
".not-in-p\\:flex:not(:where(p) *), :where(p) .in-p\\:flex, :where(.group) .in-\\[\\.group\\]\\:flex, :where(p) .in-\\[p\\]\\:flex {
display: flex;
}"
`)
expect(await run(['in-foo-bar:flex'])).toEqual('')
expect(
await run([
'in-[p]:flex',
'in-[.group]:flex',
'not-in-[p]:flex',
'not-in-[.group]:flex',
'in-data-visible:flex',
]),
).toMatchInlineSnapshot(`
".not-in-\\[\\.group\\]\\:flex:not(:where(.group) *), .not-in-\\[p\\]\\:flex:not(:where(:is(p)) *), :where([data-visible]) .in-data-visible\\:flex, :where(.group) .in-\\[\\.group\\]\\:flex, :where(:is(p)) .in-\\[p\\]\\:flex {
display: flex;
}"
`)
expect(await run(['in-p:flex', 'in-foo-bar:flex'])).toEqual('')
})

test('has', async () => {
Expand Down
34 changes: 25 additions & 9 deletions packages/tailwindcss/src/variants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ import type { Theme } from './theme'
import { compareBreakpoints } from './utils/compare-breakpoints'
import { DefaultMap } from './utils/default-map'
import { isPositiveInteger } from './utils/infer-data-type'
import { isAlpha } from './utils/is-alpha'
import { segment } from './utils/segment'

type VariantFn<T extends Variant['kind']> = (
Expand Down Expand Up @@ -712,16 +711,33 @@ export function createVariants(theme: Theme): Variants {

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

variants.functional('in', (ruleNode, variant) => {
if (!variant.value || variant.modifier) return null
variants.compound('in', Compounds.StyleRules, (ruleNode, variant) => {
if (variant.modifier) return null

// Named values should be alpha (tag selector). This prevents `in-foo-bar`
// from being used as a variant.
if (variant.value.kind === 'named' && !isAlpha(variant.value.value)) {
return null
}
let didApply = false

walk([ruleNode], (node, { path }) => {
if (node.kind !== 'rule') return WalkAction.Continue

// Throw out any candidates with variants using nested style rules
for (let parent of path.slice(0, -1)) {
if (parent.kind !== 'rule') continue

ruleNode.nodes = [styleRule(`:where(${variant.value.value}) &`, ruleNode.nodes)]
didApply = false
return WalkAction.Stop
}

// Replace `&` in target variant with `*`, so variants like `&:hover`
// become `:where(*:hover) &`. The `*` will often be optimized away.
node.selector = `:where(${node.selector.replaceAll('&', '*')}) &`

// Track that the variant was actually applied
didApply = true
})

// If the node wasn't modified, this variant is not compatible with
// `in-*` so discard the candidate.
if (!didApply) return null
})

variants.compound('has', Compounds.StyleRules, (ruleNode, variant) => {
Expand Down

0 comments on commit 34678d1

Please sign in to comment.