2022-10-17 12:38:21 +02:00
import postcss from 'postcss'
import selectorParser from 'postcss-selector-parser'
import resolveConfig from '../src/public/resolve-config'
import { createContext } from '../src/lib/setupContextUtils'
2024-03-22 17:12:14 +01:00
it ( 'should return a list of variants with meta information about the variant' , ( ) => {
let config = { }
let context = createContext ( resolveConfig ( config ) )
2022-10-17 12:38:21 +02:00
2024-03-22 17:12:14 +01:00
let variants = context . getVariants ( )
2022-10-17 12:38:21 +02:00
2024-03-22 17:12:14 +01:00
expect ( variants ) . toContainEqual ( {
name : 'hover' ,
isArbitrary : false ,
hasDash : true ,
values : [ ] ,
selectors : expect . any ( Function ) ,
2023-01-20 12:45:04 -05:00
} )
2022-10-17 12:38:21 +02:00
2024-03-22 17:12:14 +01:00
expect ( variants ) . toContainEqual ( {
name : 'group' ,
isArbitrary : true ,
hasDash : true ,
values : expect . any ( Array ) ,
selectors : expect . any ( Function ) ,
} )
2022-10-17 12:38:21 +02:00
2024-03-22 17:12:14 +01:00
// `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 ( )
} )
2022-10-17 12:38:21 +02:00
2024-03-22 17:12:14 +01:00
it ( 'should provide selectors for simple variants' , ( ) => {
let config = { }
let context = createContext ( resolveConfig ( config ) )
2022-10-17 12:38:21 +02:00
2024-03-22 17:12:14 +01:00
let variants = context . getVariants ( )
2022-10-17 12:38:21 +02:00
2024-03-22 17:12:14 +01:00
let variant = variants . find ( ( v ) => v . name === 'hover' )
expect ( variant . selectors ( ) ) . toEqual ( [ '&:hover' ] )
} )
2022-10-17 12:38:21 +02:00
2024-03-22 17:12:14 +01:00
it ( 'should provide selectors for parallel variants' , ( ) => {
let config = { }
let context = createContext ( resolveConfig ( config ) )
2022-10-17 12:38:21 +02:00
2024-03-22 17:12:14 +01:00
let variants = context . getVariants ( )
2023-06-28 12:37:52 -04:00
2024-03-22 17:12:14 +01:00
let variant = variants . find ( ( v ) => v . name === 'marker' )
expect ( variant . selectors ( ) ) . toEqual ( [ '& *::marker' , '&::marker' ] )
} )
2022-10-17 12:38:21 +02:00
2024-03-22 17:12:14 +01:00
it ( 'should provide selectors for complex matchVariant variants like `group`' , ( ) => {
let config = { }
let context = createContext ( resolveConfig ( config ) )
2022-10-17 12:38:21 +02:00
2024-03-22 17:12:14 +01:00
let variants = context . getVariants ( )
2022-10-17 12:38:21 +02:00
2024-03-22 17:12:14 +01:00
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 complex matchVariant variants like `group` (when using a prefix)' , ( ) => {
let config = { prefix : 'tw-' }
let context = createContext ( resolveConfig ( config ) )
let variants = context . getVariants ( )
let variant = variants . find ( ( v ) => v . name === 'group' )
expect ( variant . selectors ( ) ) . toEqual ( [ '.tw-group &' ] )
expect ( variant . selectors ( { } ) ) . toEqual ( [ '.tw-group &' ] )
expect ( variant . selectors ( { value : 'hover' } ) ) . toEqual ( [ '.tw-group:hover &' ] )
expect ( variant . selectors ( { value : '.foo_&' } ) ) . toEqual ( [ '.foo .tw-group &' ] )
expect ( variant . selectors ( { modifier : 'foo' , value : 'hover' } ) ) . toEqual ( [
'.tw-group\\/foo:hover &' ,
] )
expect ( variant . selectors ( { modifier : 'foo' , value : '.foo_&' } ) ) . toEqual ( [
'.foo .tw-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 [
`
2022-10-17 12:38:21 +02:00
@ supports ( foo : $ { modifier } ) {
@ media ( width <= 400 px ) {
& : hover
}
}
` ,
2024-03-22 17:12:14 +01:00
` . ${ 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' ,
] )
} )
2022-10-17 12:38:21 +02:00
2024-03-22 17:12:14 +01:00
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 )
2022-10-17 12:38:21 +02:00
} )
2023-01-20 12:45:04 -05:00
2024-03-22 17:12:14 +01:00
// 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\\:& }' ] )
} )
2022-10-17 17:13:33 +02:00
2024-03-22 17:12:14 +01:00
it ( 'should special case the `@`' , ( ) => {
let config = {
plugins : [
( { matchVariant } ) => {
matchVariant (
'@' ,
( value , { modifier } ) => ` @container ${ modifier ? ? '' } (min-width: ${ value } ) ` ,
{
modifiers : 'any' ,
values : {
xs : '20rem' ,
sm : '24rem' ,
md : '28rem' ,
lg : '32rem' ,
xl : '36rem' ,
'2xl' : '42rem' ,
'3xl' : '48rem' ,
'4xl' : '56rem' ,
'5xl' : '64rem' ,
'6xl' : '72rem' ,
'7xl' : '80rem' ,
} ,
}
)
} ,
] ,
}
let context = createContext ( resolveConfig ( config ) )
let variants = context . getVariants ( )
let variant = variants . find ( ( v ) => v . name === '@' )
expect ( variant ) . toEqual ( {
name : '@' ,
isArbitrary : true ,
hasDash : false ,
values : expect . any ( Array ) ,
selectors : expect . any ( Function ) ,
2022-10-17 17:13:33 +02:00
} )
2024-03-22 17:12:14 +01:00
expect ( variant . selectors ( { value : 'xs' , modifier : 'foo' } ) ) . toEqual ( [
'@container foo (min-width: 20rem)' ,
] )
2022-10-17 17:13:33 +02:00
} )