Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
d141afa
Add function for depth-first AST traversal
thecrypticace Oct 17, 2024
aa5fc87
Fix intellisense variant selector calculation
thecrypticace Oct 14, 2024
f8143a6
Add Intellisense API benchmark
thecrypticace Oct 21, 2024
12b9fae
Use single rule for parallel variants when possible
thecrypticace Oct 17, 2024
5b5bfc9
Add path information to `visit`
thecrypticace Oct 17, 2024
bc391bc
Simplify nesting checks in compound variants
thecrypticace Oct 17, 2024
22673e5
Filter the kinds of rules compound variants support
thecrypticace Oct 21, 2024
6a03a06
Register compound variants with the kinds of rules they support
thecrypticace Oct 21, 2024
8dc719c
Let `not-*` variant handle simple conditional at rules
thecrypticace Oct 21, 2024
cc3e774
Update tests
thecrypticace Oct 21, 2024
414bc16
Update changelog
thecrypticace Oct 21, 2024
22e5614
Use bitfield enum
thecrypticace Oct 22, 2024
9f1a7d3
Compute compounds when using staticVariant
thecrypticace Oct 22, 2024
92e8d31
Add tests
thecrypticace Oct 22, 2024
fa3effb
Refactor
thecrypticace Oct 23, 2024
9e365df
Compute compunds for arbitrary variants
thecrypticace Oct 23, 2024
5b7e104
Compute compounds for `@variant`
thecrypticace Oct 23, 2024
4cc3f16
Compute compounds for `addVariant`
thecrypticace Oct 23, 2024
fb0eabf
Add tests
thecrypticace Oct 23, 2024
a1ab176
Update CHANGELOG.md
thecrypticace Oct 23, 2024
6ac6829
Apply suggestions from code review
thecrypticace Oct 23, 2024
a8ee1fb
Merge branch 'next' into feat/v4-not-tweaks
thecrypticace Oct 24, 2024
48139ad
Update changelog
thecrypticace Oct 24, 2024
ba33ae0
Merge branch 'next' into feat/v4-not-tweaks
thecrypticace Oct 24, 2024
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
Prev Previous commit
Next Next commit
Fix intellisense variant selector calculation
  • Loading branch information
thecrypticace authored and RobinMalfait committed Oct 24, 2024
commit aa5fc874cf0cb156bc3ebfb52e9d9af64ed8e3d5
33 changes: 30 additions & 3 deletions packages/tailwindcss/src/intellisense.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -72,14 +72,41 @@ test('getVariants compound', () => {
]

expect(list).toEqual([
['&:is(:where(.group):hover *)'],
['&:is(:where(.group\\/sidebar):hover *)'],
['&:is(:where(.group):is(:where(.group):hover *) *)'],
['@media (hover: hover) { &:is(:where(.group):hover *) }'],
['@media (hover: hover) { &:is(:where(.group\\/sidebar):hover *) }'],
['@media (hover: hover) { &:is(:where(.group):is(:where(.group):hover *) *) }'],
[],
[],
])
})

test('variant selectors are in the correct order', async () => {
let input = css`
@variant overactive {
&:hover {
@media (hover: hover) {
&:focus {
&:active {
@slot;
}
}
}
}
}
`

let design = await __unstable__loadDesignSystem(input)
let variants = design.getVariants()
let overactive = variants.find((v) => v.name === 'overactive')!

expect(overactive).toBeTruthy()
expect(overactive.selectors({})).toMatchInlineSnapshot(`
[
"@media (hover: hover) { &:hover { &:focus { &:active } } }",
]
`)
})

test('The variant `has-force` does not crash', () => {
let design = loadDesignSystem()
let variants = design.getVariants()
Expand Down
42 changes: 36 additions & 6 deletions packages/tailwindcss/src/intellisense.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { decl, rule } from './ast'
import { rule, walkDepth } from './ast'
import { applyVariant } from './compile'
import type { DesignSystem } from './design-system'

Expand Down Expand Up @@ -69,7 +69,7 @@ export function getVariants(design: DesignSystem) {
if (!variant) return []

// Apply the variant to a placeholder rule
let node = rule('.__placeholder__', [decl('color', 'red')])
let node = rule('.__placeholder__', [])

// If the rule produces no nodes it means the variant does not apply
if (applyVariant(node, variant, design.variants) === null) {
Expand All @@ -79,11 +79,41 @@ export function getVariants(design: DesignSystem) {
// Now look at the selector(s) inside the rule
let selectors: string[] = []

for (let child of node.nodes) {
if (child.kind === 'rule') {
selectors.push(child.selector)
// Produce v3-style selector strings in the face of nested rules
// This is more visible for things like group-*, not-*, etc…
walkDepth(node.nodes, (node, { path }) => {
if (node.kind !== 'rule') return
if (node.nodes.length > 0) return

// Sort at-rules before style rules
path.sort((a, b) => {
// This won't actually happen, but it's here to make TypeScript happy
if (a.kind !== 'rule' || b.kind !== 'rule') return 0

let aIsAtRule = a.selector.startsWith('@')
let bIsAtRule = b.selector.startsWith('@')

if (aIsAtRule && !bIsAtRule) return -1
if (!aIsAtRule && bIsAtRule) return 1

return 0
})

// A list of the selectors / at rules encountered to get to this point
let group = path.flatMap((node) => {
if (node.kind !== 'rule') return []
return node.selector === '&' ? [] : [node.selector]
})

// Build a v3-style nested selector
let selector = ''

for (let i = group.length - 1; i >= 0; i--) {
selector = selector === '' ? group[i] : `${group[i]} { ${selector} }`
}
}

selectors.push(selector)
})

return selectors
}
Expand Down