From 651e3dd4c339243c206d0070aa30cf1b532205c7 Mon Sep 17 00:00:00 2001 From: Jordan Pittman Date: Wed, 12 Oct 2022 09:27:13 -0400 Subject: [PATCH 1/4] Fix plugin types --- types/config.d.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/types/config.d.ts b/types/config.d.ts index 4ea61e7da..2e6fb1438 100644 --- a/types/config.d.ts +++ b/types/config.d.ts @@ -326,8 +326,8 @@ 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 } + | { (options: any): { handler: PluginCreator; config?: Partial }; __isOptionsFunction: true } )[] // Top level config related From 285b02c9de91ec7c2051e31771636a8784631e43 Mon Sep 17 00:00:00 2001 From: Jordan Pittman Date: Wed, 12 Oct 2022 10:43:43 -0400 Subject: [PATCH 2/4] Change `matchVariant` API to use positional arguments --- src/corePlugins.js | 5 ++--- src/lib/setupContextUtils.js | 4 ++-- tests/match-variants.test.js | 36 ++++++++++++++++++------------------ types/config.d.ts | 18 +++++++----------- 4 files changed, 29 insertions(+), 34 deletions(-) diff --git a/src/corePlugins.js b/src/corePlugins.js index bd1e43c16..504ef5451 100644 --- a/src/corePlugins.js +++ b/src/corePlugins.js @@ -153,8 +153,7 @@ export let variantPlugins = { for (let [name, fn] of Object.entries(variants)) { matchVariant( name, - (ctx = {}) => { - let { modifier, value = '' } = ctx + (value = '', modifier) => { if (modifier) { log.warn(`modifier-${name}-experimental`, [ `The ${name} variant modifier feature in Tailwind CSS is currently in preview.`, @@ -232,7 +231,7 @@ export let variantPlugins = { supportsVariants: ({ matchVariant, theme }) => { matchVariant( 'supports', - ({ value = '' }) => { + (value = '') => { let check = normalize(value) let isRaw = /^\w*\s*\(/.test(check) diff --git a/src/lib/setupContextUtils.js b/src/lib/setupContextUtils.js index fa0969ffb..bfd9483ef 100644 --- a/src/lib/setupContextUtils.js +++ b/src/lib/setupContextUtils.js @@ -525,7 +525,7 @@ 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 }), { + Object.assign(({ args }) => variantFn(value, args.modifier), { [MATCH_VARIANT]: true, }), { ...options, value, id } @@ -534,7 +534,7 @@ function buildPluginApi(tailwindConfig, context, { variantList, variantMap, offs api.addVariant( variant, - Object.assign(({ args, container }) => variantFn({ ...args, container }), { + Object.assign(({ args }) => variantFn(args.value, args.modifier), { [MATCH_VARIANT]: true, }), { ...options, id } diff --git a/tests/match-variants.test.js b/tests/match-variants.test.js index 7b80a0639..fad171936 100644 --- a/tests/match-variants.test.js +++ b/tests/match-variants.test.js @@ -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) { diff --git a/types/config.d.ts b/types/config.d.ts index 2e6fb1438..3412d377a 100644 --- a/types/config.d.ts +++ b/types/config.d.ts @@ -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( name: string, - cb: (options: { value: string; modifier: string | null }) => string | string[] - ): void - matchVariant( - 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, modifier: string | null) => string | string[], + options?: { + values?: KeyValuePair, + sort?( + a: { value: T | string; modifier: string | null }, + b: { value: T | string; modifier: string | null } ): number } ): void From 2049989184325b3252dfa58b4d85f5d6c4d3d01e Mon Sep 17 00:00:00 2001 From: Jordan Pittman Date: Wed, 12 Oct 2022 17:11:50 -0400 Subject: [PATCH 3/4] Fix CS wip --- types/config.d.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/types/config.d.ts b/types/config.d.ts index 3412d377a..0d980284e 100644 --- a/types/config.d.ts +++ b/types/config.d.ts @@ -323,7 +323,10 @@ export type PluginCreator = (api: PluginAPI) => void export type PluginsConfig = ( | PluginCreator | { handler: PluginCreator; config?: Partial } - | { (options: any): { handler: PluginCreator; config?: Partial }; __isOptionsFunction: true } + | { + (options: any): { handler: PluginCreator; config?: Partial } + __isOptionsFunction: true + } )[] // Top level config related From a9015fc14cdab58817692ec1cc362ffc95ea7d5e Mon Sep 17 00:00:00 2001 From: Jordan Pittman Date: Wed, 12 Oct 2022 17:12:47 -0400 Subject: [PATCH 4/4] Change match variant wrap modifier in an object Needed for compat w/ some group and peer plugins --- src/corePlugins.js | 12 ++++++------ src/lib/setupContextUtils.js | 18 ++++++++++++------ types/config.d.ts | 4 ++-- 3 files changed, 20 insertions(+), 14 deletions(-) diff --git a/src/corePlugins.js b/src/corePlugins.js index 504ef5451..0ae64d9b0 100644 --- a/src/corePlugins.js +++ b/src/corePlugins.js @@ -144,27 +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, - (value = '', modifier) => { - 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) } diff --git a/src/lib/setupContextUtils.js b/src/lib/setupContextUtils.js index bfd9483ef..bbc2454c4 100644 --- a/src/lib/setupContextUtils.js +++ b/src/lib/setupContextUtils.js @@ -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 }) => variantFn(value, args.modifier), { - [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 }) => variantFn(args.value, args.modifier), { - [MATCH_VARIANT]: true, - }), + Object.assign( + ({ args, container }) => variantFn(args.value, { modifier: args.modifier, container }), + { + [MATCH_VARIANT]: true, + } + ), { ...options, id } ) }, diff --git a/types/config.d.ts b/types/config.d.ts index 0d980284e..b08490cd1 100644 --- a/types/config.d.ts +++ b/types/config.d.ts @@ -298,9 +298,9 @@ export interface PluginAPI { addVariant(name: string, definition: string | string[] | (() => string) | (() => string)[]): void matchVariant( name: string, - cb: (value: T | string, modifier: string | null) => string | string[], + cb: (value: T | string, extra: { modifier: string | null }) => string | string[], options?: { - values?: KeyValuePair, + values?: KeyValuePair sort?( a: { value: T | string; modifier: string | null }, b: { value: T | string; modifier: string | null }