Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Expose
context.getVariants
for intellisense (#9505)
* add `context.getVariants` * use `modifier` instead of `label` * handle `modifySelectors` version * use reference * reverse engineer manual format strings if container was touched * use new positional API for `matchVariant` * update changelog
- Loading branch information
1 parent
b7d5a2f
commit bc00445
Showing
5 changed files
with
308 additions
and
26 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,140 @@ | ||
import postcss from 'postcss' | ||
import selectorParser from 'postcss-selector-parser' | ||
import resolveConfig from '../src/public/resolve-config' | ||
import { createContext } from '../src/lib/setupContextUtils' | ||
|
||
it('should return a list of variants with meta information about the variant', () => { | ||
let config = {} | ||
let context = createContext(resolveConfig(config)) | ||
|
||
let variants = context.getVariants() | ||
|
||
expect(variants).toContainEqual({ | ||
name: 'hover', | ||
isArbitrary: false, | ||
values: [], | ||
selectors: expect.any(Function), | ||
}) | ||
|
||
expect(variants).toContainEqual({ | ||
name: 'group', | ||
isArbitrary: true, | ||
values: expect.any(Array), | ||
selectors: expect.any(Function), | ||
}) | ||
|
||
// `group-hover` now belongs to the `group` variant. The information exposed for the `group` | ||
// variant is all you need. | ||
expect(variants.find((v) => v.name === 'group-hover')).toBeUndefined() | ||
}) | ||
|
||
it('should provide selectors for simple variants', () => { | ||
let config = {} | ||
let context = createContext(resolveConfig(config)) | ||
|
||
let variants = context.getVariants() | ||
|
||
let variant = variants.find((v) => v.name === 'hover') | ||
expect(variant.selectors()).toEqual(['&:hover']) | ||
}) | ||
|
||
it('should provide selectors for parallel variants', () => { | ||
let config = {} | ||
let context = createContext(resolveConfig(config)) | ||
|
||
let variants = context.getVariants() | ||
|
||
let variant = variants.find((v) => v.name === 'marker') | ||
expect(variant.selectors()).toEqual(['& *::marker', '&::marker']) | ||
}) | ||
|
||
it('should provide selectors for complex matchVariant variants like `group`', () => { | ||
let config = {} | ||
let context = createContext(resolveConfig(config)) | ||
|
||
let variants = context.getVariants() | ||
|
||
let variant = variants.find((v) => v.name === 'group') | ||
expect(variant.selectors()).toEqual(['.group &']) | ||
expect(variant.selectors({})).toEqual(['.group &']) | ||
expect(variant.selectors({ value: 'hover' })).toEqual(['.group:hover &']) | ||
expect(variant.selectors({ value: '.foo_&' })).toEqual(['.foo .group &']) | ||
expect(variant.selectors({ modifier: 'foo', value: 'hover' })).toEqual(['.group\\/foo:hover &']) | ||
expect(variant.selectors({ modifier: 'foo', value: '.foo_&' })).toEqual(['.foo .group\\/foo &']) | ||
}) | ||
|
||
it('should provide selectors for variants with atrules', () => { | ||
let config = {} | ||
let context = createContext(resolveConfig(config)) | ||
|
||
let variants = context.getVariants() | ||
|
||
let variant = variants.find((v) => v.name === 'supports') | ||
expect(variant.selectors({ value: 'display:grid' })).toEqual(['@supports (display:grid)']) | ||
expect(variant.selectors({ value: 'aspect-ratio' })).toEqual([ | ||
'@supports (aspect-ratio: var(--tw))', | ||
]) | ||
}) | ||
|
||
it('should provide selectors for custom plugins that do a combination of parallel variants with modifiers with arbitrary values and with atrules', () => { | ||
let config = { | ||
plugins: [ | ||
function ({ matchVariant }) { | ||
matchVariant('foo', (value, { modifier }) => { | ||
return [ | ||
` | ||
@supports (foo: ${modifier}) { | ||
@media (width <= 400px) { | ||
&:hover | ||
} | ||
} | ||
`, | ||
`.${modifier}\\/${value} &:focus`, | ||
] | ||
}) | ||
}, | ||
], | ||
} | ||
let context = createContext(resolveConfig(config)) | ||
|
||
let variants = context.getVariants() | ||
|
||
let variant = variants.find((v) => v.name === 'foo') | ||
expect(variant.selectors({ modifier: 'bar', value: 'baz' })).toEqual([ | ||
'@supports (foo: bar) { @media (width <= 400px) { &:hover } }', | ||
'.bar\\/baz &:focus', | ||
]) | ||
}) | ||
|
||
it('should work for plugins that still use the modifySelectors API', () => { | ||
let config = { | ||
plugins: [ | ||
function ({ addVariant }) { | ||
addVariant('foo', ({ modifySelectors, container }) => { | ||
// Manually mutating the selector | ||
modifySelectors(({ selector }) => { | ||
return selectorParser((selectors) => { | ||
selectors.walkClasses((classNode) => { | ||
classNode.value = `foo:${classNode.value}` | ||
classNode.parent.insertBefore(classNode, selectorParser().astSync(`.foo `)) | ||
}) | ||
}).processSync(selector) | ||
}) | ||
|
||
// Manually wrap in supports query | ||
let wrapper = postcss.atRule({ name: 'supports', params: 'display: grid' }) | ||
let nodes = container.nodes | ||
container.removeAll() | ||
wrapper.append(nodes) | ||
container.append(wrapper) | ||
}) | ||
}, | ||
], | ||
} | ||
let context = createContext(resolveConfig(config)) | ||
|
||
let variants = context.getVariants() | ||
|
||
let variant = variants.find((v) => v.name === 'foo') | ||
expect(variant.selectors({})).toEqual(['@supports (display: grid) { .foo .foo\\:& }']) | ||
}) |