Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(preset-mini): add backdrop:x variant for ::backdrop pseudo element #1022

Merged
merged 2 commits into from May 29, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
27 changes: 18 additions & 9 deletions packages/preset-mini/src/variants/pseudo.ts
Expand Up @@ -59,7 +59,11 @@ const PseudoClasses: Record<string, string> = Object.fromEntries([
['selection', '::selection'],
['marker', '::marker'],
['file', '::file-selector-button'],
].map(key => typeof key === 'string' ? [key, `:${key}`] : key))
].map(key => Array.isArray(key) ? key : [key, `:${key}`]))

const PseudoClassesColon: Record<string, string> = Object.fromEntries([
['backdrop', '::backdrop'],
].map(key => Array.isArray(key) ? key : [key, `:${key}`]))

const PseudoClassFunctions = [
'not',
Expand All @@ -69,6 +73,7 @@ const PseudoClassFunctions = [
]

const PseudoClassesStr = Object.entries(PseudoClasses).filter(([, pseudo]) => !pseudo.startsWith('::')).map(([key]) => key).join('|')
const PseudoClassesColonStr = Object.entries(PseudoClassesColon).filter(([, pseudo]) => !pseudo.startsWith('::')).map(([key]) => key).join('|')
const PseudoClassFunctionsStr = PseudoClassFunctions.join('|')

const sortValue = (pseudo: string) => {
Expand All @@ -77,14 +82,15 @@ const sortValue = (pseudo: string) => {
}

const taggedPseudoClassMatcher = (tag: string, parent: string, combinator: string): VariantObject => {
const re = new RegExp(`^${tag}-((?:(${PseudoClassFunctionsStr})-)?(${PseudoClassesStr}))[:-]`)
const rawRe = new RegExp(`^${escapeRegExp(parent)}:`)
const pseudoRE = new RegExp(`^${tag}-((?:(${PseudoClassFunctionsStr})-)?(${PseudoClassesStr}))[:-]`)
const pseudoColonRE = new RegExp(`^${tag}-((?:(${PseudoClassFunctionsStr})-)?(${PseudoClassesColonStr}))[:]`)
return {
name: `pseudo:${tag}`,
match(input: string) {
const match = input.match(re)
const match = input.match(pseudoRE) || input.match(pseudoColonRE)
if (match) {
let pseudo = PseudoClasses[match[3]] || `:${match[3]}`
let pseudo = PseudoClasses[match[3]] || PseudoClassesColon[match[3]] || `:${match[3]}`
if (match[2])
pseudo = `:${match[2]}(${pseudo})`
return {
Expand All @@ -100,13 +106,15 @@ const taggedPseudoClassMatcher = (tag: string, parent: string, combinator: strin
}

const PseudoClassesAndElementsStr = Object.entries(PseudoClasses).map(([key]) => key).join('|')
const PseudoClassesAndElementsColonStr = Object.entries(PseudoClassesColon).map(([key]) => key).join('|')
const PseudoClassesAndElementsRE = new RegExp(`^(${PseudoClassesAndElementsStr})[:-]`)
const PseudoClassesAndElementsColonRE = new RegExp(`^(${PseudoClassesAndElementsColonStr})[:]`)
export const variantPseudoClassesAndElements: VariantObject = {
name: 'pseudo',
match: (input: string) => {
const match = input.match(PseudoClassesAndElementsRE)
const match = input.match(PseudoClassesAndElementsRE) || input.match(PseudoClassesAndElementsColonRE)
if (match) {
const pseudo = PseudoClasses[match[1]] || `:${match[1]}`
const pseudo = PseudoClasses[match[1]] || PseudoClassesColon[match[1]] || `:${match[1]}`
return {
matcher: input.slice(match[0].length),
selector: s => `${s}${pseudo}`,
Expand All @@ -119,20 +127,21 @@ export const variantPseudoClassesAndElements: VariantObject = {
}

const PseudoClassFunctionsRE = new RegExp(`^(${PseudoClassFunctionsStr})-(${PseudoClassesStr})[:-]`)
const PseudoClassColonFunctionsRE = new RegExp(`^(${PseudoClassFunctionsStr})-(${PseudoClassesColonStr})[:]`)
export const variantPseudoClassFunctions: VariantObject = {
match: (input: string) => {
const match = input.match(PseudoClassFunctionsRE)
const match = input.match(PseudoClassFunctionsRE) || input.match(PseudoClassColonFunctionsRE)
if (match) {
const fn = match[1]
const pseudo = PseudoClasses[match[2]] || `:${match[2]}`
const pseudo = PseudoClasses[match[2]] || PseudoClassesColon[match[2]] || `:${match[2]}`
return {
matcher: input.slice(match[0].length),
selector: s => `${s}:${fn}(${pseudo})`,
}
}
},
multiPass: true,
autocomplete: `(${PseudoClassFunctionsStr})-(${PseudoClassesStr}):`,
autocomplete: `(${PseudoClassFunctionsStr})-(${PseudoClassesStr}|${PseudoClassesColonStr}):`,
}

export const variantTaggedPseudoClasses = (options: PresetMiniOptions = {}): VariantObject[] => {
Expand Down
1 change: 1 addition & 0 deletions test/__snapshots__/preset-mini.test.ts.snap
Expand Up @@ -408,6 +408,7 @@ div:hover .group-\\\\[div\\\\:hover\\\\]-\\\\[combinator\\\\:test-4\\\\]{combina
.shadow{--un-shadow:var(--un-shadow-inset) 0 1px 3px 0 var(--un-shadow-color, rgba(0,0,0,0.1)),var(--un-shadow-inset) 0 1px 2px -1px var(--un-shadow-color, rgba(0,0,0,0.1));box-shadow:var(--un-ring-offset-shadow, 0 0 #0000), var(--un-ring-shadow, 0 0 #0000), var(--un-shadow);}
.shadow-none{--un-shadow:0 0 var(--un-shadow-color, rgba(0,0,0,0));box-shadow:var(--un-ring-offset-shadow, 0 0 #0000), var(--un-ring-shadow, 0 0 #0000), var(--un-shadow);}
.shadow-xl{--un-shadow:var(--un-shadow-inset) 0 20px 25px -5px var(--un-shadow-color, rgba(0,0,0,0.1)),var(--un-shadow-inset) 0 8px 10px -6px var(--un-shadow-color, rgba(0,0,0,0.1));box-shadow:var(--un-ring-offset-shadow, 0 0 #0000), var(--un-ring-shadow, 0 0 #0000), var(--un-shadow);}
.backdrop\\\\:shadow-green::backdrop{--un-shadow-opacity:1;--un-shadow-color:rgba(74,222,128,var(--un-shadow-opacity));}
.shadow-current{--un-shadow-color:currentColor;}
.shadow-green-500{--un-shadow-opacity:1;--un-shadow-color:rgba(34,197,94,var(--un-shadow-opacity));}
.shadow-green-900\\\\/50{--un-shadow-color:rgba(20,83,45,0.5);}
Expand Down
1 change: 1 addition & 0 deletions test/assets/preset-mini-targets.ts
Expand Up @@ -824,6 +824,7 @@ export const presetMiniTargets: string[] = [
'marker:bg-violet-200',
'file:bg-violet-50',
'hover:file:bg-violet-100',
'backdrop:shadow-green',

// variants - pseudo classes
'rtl:text-right',
Expand Down
3 changes: 3 additions & 0 deletions test/preset-uno.test.ts
Expand Up @@ -97,6 +97,9 @@ const nonTargets = [
'tab-$',
'ws-$',

// mini - pseudo colon only
'backdrop-shadow-green',

// wind - placeholder
'$-placeholder-red-200',

Expand Down