Compare commits

...
Sign in to create a new pull request.

4 commits

Author SHA1 Message Date
Jordan Pittman
a9015fc14c Change match variant wrap modifier in an object
Needed for compat w/ some group and peer plugins
2022-10-12 17:18:37 -04:00
Jordan Pittman
2049989184 Fix CS
wip
2022-10-12 17:11:50 -04:00
Jordan Pittman
285b02c9de Change matchVariant API to use positional arguments 2022-10-12 10:43:43 -04:00
Jordan Pittman
651e3dd4c3 Fix plugin types 2022-10-12 09:27:17 -04:00
4 changed files with 49 additions and 45 deletions

View file

@ -144,28 +144,27 @@ export let variantPlugins = {
}
let variants = {
group: ({ modifier }) =>
group: (_, { modifier }) =>
modifier ? [`:merge(.group\\/${modifier})`, ' &'] : [`:merge(.group)`, ' &'],
peer: ({ modifier }) =>
peer: (_, { modifier }) =>
modifier ? [`:merge(.peer\\/${modifier})`, ' ~ &'] : [`:merge(.peer)`, ' ~ &'],
}
for (let [name, fn] of Object.entries(variants)) {
matchVariant(
name,
(ctx = {}) => {
let { modifier, value = '' } = ctx
if (modifier) {
(value = '', extra) => {
if (extra.modifier) {
log.warn(`modifier-${name}-experimental`, [
`The ${name} variant modifier feature in Tailwind CSS is currently in preview.`,
'Preview features are not covered by semver, and may be improved in breaking ways at any time.',
])
}
let result = normalize(typeof value === 'function' ? value(ctx) : value)
let result = normalize(typeof value === 'function' ? value(extra) : value)
if (!result.includes('&')) result = '&' + result
let [a, b] = fn({ modifier })
let [a, b] = fn('', extra)
return result.replace(/&(\S+)?/g, (_, pseudo = '') => a + pseudo + b)
},
{ values: Object.fromEntries(pseudoVariants) }
@ -232,7 +231,7 @@ export let variantPlugins = {
supportsVariants: ({ matchVariant, theme }) => {
matchVariant(
'supports',
({ value = '' }) => {
(value = '') => {
let check = normalize(value)
let isRaw = /^\w*\s*\(/.test(check)

View file

@ -525,18 +525,24 @@ function buildPluginApi(tailwindConfig, context, { variantList, variantMap, offs
for (let [key, value] of Object.entries(options?.values ?? {})) {
api.addVariant(
isSpecial ? `${variant}${key}` : `${variant}-${key}`,
Object.assign(({ args, container }) => variantFn({ ...args, container, value }), {
[MATCH_VARIANT]: true,
}),
Object.assign(
({ args, container }) => variantFn(value, { modifier: args.modifier, container }),
{
[MATCH_VARIANT]: true,
}
),
{ ...options, value, id }
)
}
api.addVariant(
variant,
Object.assign(({ args, container }) => variantFn({ ...args, container }), {
[MATCH_VARIANT]: true,
}),
Object.assign(
({ args, container }) => variantFn(args.value, { modifier: args.modifier, container }),
{
[MATCH_VARIANT]: true,
}
),
{ ...options, id }
)
},

View file

@ -10,7 +10,7 @@ test('partial arbitrary variants', () => {
corePlugins: { preflight: false },
plugins: [
({ matchVariant }) => {
matchVariant('potato', ({ value: flavor }) => `.potato-${flavor} &`)
matchVariant('potato', (flavor) => `.potato-${flavor} &`)
},
],
}
@ -43,7 +43,7 @@ test('partial arbitrary variants with at-rules', () => {
corePlugins: { preflight: false },
plugins: [
({ matchVariant }) => {
matchVariant('potato', ({ value: flavor }) => `@media (potato: ${flavor})`)
matchVariant('potato', (flavor) => `@media (potato: ${flavor})`)
},
],
}
@ -79,7 +79,7 @@ test('partial arbitrary variants with at-rules and placeholder', () => {
corePlugins: { preflight: false },
plugins: [
({ matchVariant }) => {
matchVariant('potato', ({ value: flavor }) => `@media (potato: ${flavor}) { &:potato }`)
matchVariant('potato', (flavor) => `@media (potato: ${flavor}) { &:potato }`)
},
],
}
@ -115,7 +115,7 @@ test('partial arbitrary variants with default values', () => {
corePlugins: { preflight: false },
plugins: [
({ matchVariant }) => {
matchVariant('tooltip', ({ value: side }) => `&${side}`, {
matchVariant('tooltip', (side) => `&${side}`, {
values: {
bottom: '[data-location="bottom"]',
top: '[data-location="top"]',
@ -154,7 +154,7 @@ test('matched variant values maintain the sort order they are registered in', ()
corePlugins: { preflight: false },
plugins: [
({ matchVariant }) => {
matchVariant('alphabet', ({ value: side }) => `&${side}`, {
matchVariant('alphabet', (side) => `&${side}`, {
values: {
a: '[data-value="a"]',
b: '[data-value="b"]',
@ -201,7 +201,7 @@ test('matchVariant can return an array of format strings from the function', ()
corePlugins: { preflight: false },
plugins: [
({ matchVariant }) => {
matchVariant('test', ({ value: selector }) =>
matchVariant('test', (selector) =>
selector.split(',').map((selector) => `&.${selector} > *`)
)
},
@ -243,7 +243,7 @@ it('should be possible to sort variants', () => {
corePlugins: { preflight: false },
plugins: [
({ matchVariant }) => {
matchVariant('min', ({ value }) => `@media (min-width: ${value})`, {
matchVariant('min', (value) => `@media (min-width: ${value})`, {
sort(a, z) {
return parseInt(a.value) - parseInt(z.value)
},
@ -287,7 +287,7 @@ it('should be possible to compare arbitrary variants and hardcoded variants', ()
corePlugins: { preflight: false },
plugins: [
({ matchVariant }) => {
matchVariant('min', ({ value }) => `@media (min-width: ${value})`, {
matchVariant('min', (value) => `@media (min-width: ${value})`, {
values: {
example: '600px',
},
@ -347,13 +347,13 @@ it('should be possible to sort stacked arbitrary variants correctly', () => {
corePlugins: { preflight: false },
plugins: [
({ matchVariant }) => {
matchVariant('min', ({ value }) => `@media (min-width: ${value})`, {
matchVariant('min', (value) => `@media (min-width: ${value})`, {
sort(a, z) {
return parseInt(a.value) - parseInt(z.value)
},
})
matchVariant('max', ({ value }) => `@media (max-width: ${value})`, {
matchVariant('max', (value) => `@media (max-width: ${value})`, {
sort(a, z) {
return parseInt(z.value) - parseInt(a.value)
},
@ -412,13 +412,13 @@ it('should maintain sort from other variants, if sort functions of arbitrary var
corePlugins: { preflight: false },
plugins: [
({ matchVariant }) => {
matchVariant('min', ({ value }) => `@media (min-width: ${value})`, {
matchVariant('min', (value) => `@media (min-width: ${value})`, {
sort(a, z) {
return parseInt(a.value) - parseInt(z.value)
},
})
matchVariant('max', ({ value }) => `@media (max-width: ${value})`, {
matchVariant('max', (value) => `@media (max-width: ${value})`, {
sort(a, z) {
return parseInt(z.value) - parseInt(a.value)
},
@ -464,12 +464,12 @@ it('should sort arbitrary variants left to right (1)', () => {
corePlugins: { preflight: false },
plugins: [
({ matchVariant }) => {
matchVariant('min', ({ value }) => `@media (min-width: ${value})`, {
matchVariant('min', (value) => `@media (min-width: ${value})`, {
sort(a, z) {
return parseInt(a.value) - parseInt(z.value)
},
})
matchVariant('max', ({ value }) => `@media (max-width: ${value})`, {
matchVariant('max', (value) => `@media (max-width: ${value})`, {
sort(a, z) {
return parseInt(z.value) - parseInt(a.value)
},
@ -532,12 +532,12 @@ it('should sort arbitrary variants left to right (2)', () => {
corePlugins: { preflight: false },
plugins: [
({ matchVariant }) => {
matchVariant('min', ({ value }) => `@media (min-width: ${value})`, {
matchVariant('min', (value) => `@media (min-width: ${value})`, {
sort(a, z) {
return parseInt(a.value) - parseInt(z.value)
},
})
matchVariant('max', ({ value }) => `@media (max-width: ${value})`, {
matchVariant('max', (value) => `@media (max-width: ${value})`, {
sort(a, z) {
return parseInt(z.value) - parseInt(a.value)
},
@ -598,7 +598,7 @@ it('should guarantee that we are not passing values from other variants to the w
corePlugins: { preflight: false },
plugins: [
({ matchVariant }) => {
matchVariant('min', ({ value }) => `@media (min-width: ${value})`, {
matchVariant('min', (value) => `@media (min-width: ${value})`, {
sort(a, z) {
let lookup = ['100px', '200px']
if (lookup.indexOf(a.value) === -1 || lookup.indexOf(z.value) === -1) {
@ -607,7 +607,7 @@ it('should guarantee that we are not passing values from other variants to the w
return lookup.indexOf(a.value) - lookup.indexOf(z.value)
},
})
matchVariant('max', ({ value }) => `@media (max-width: ${value})`, {
matchVariant('max', (value) => `@media (max-width: ${value})`, {
sort(a, z) {
let lookup = ['300px', '400px']
if (lookup.indexOf(a.value) === -1 || lookup.indexOf(z.value) === -1) {

25
types/config.d.ts vendored
View file

@ -296,18 +296,14 @@ export interface PluginAPI {
addBase(base: CSSRuleObject | CSSRuleObject[]): void
// for registering custom variants
addVariant(name: string, definition: string | string[] | (() => string) | (() => string)[]): void
matchVariant(
matchVariant<T = string>(
name: string,
cb: (options: { value: string; modifier: string | null }) => string | string[]
): void
matchVariant<Values extends {}>(
name: string,
cb: (options: { value: string; modifier: string | null }) => string | string[],
options: {
values: Values
sort(
a: { value: keyof Values | string; modifier: string | null },
b: { value: keyof Values | string; modifier: string | null }
cb: (value: T | string, extra: { modifier: string | null }) => string | string[],
options?: {
values?: KeyValuePair<string, T>
sort?(
a: { value: T | string; modifier: string | null },
b: { value: T | string; modifier: string | null }
): number
}
): void
@ -326,8 +322,11 @@ export interface PluginAPI {
export type PluginCreator = (api: PluginAPI) => void
export type PluginsConfig = (
| PluginCreator
| { handler: PluginCreator; config?: Config }
| { (options: any): { handler: PluginCreator; config?: Config }; __isOptionsFunction: true }
| { handler: PluginCreator; config?: Partial<Config> }
| {
(options: any): { handler: PluginCreator; config?: Partial<Config> }
__isOptionsFunction: true
}
)[]
// Top level config related