Skip to content

Commit

Permalink
update label syntax
Browse files Browse the repository at this point in the history
  • Loading branch information
chu121su12 committed Oct 23, 2022
1 parent d7ec381 commit 7e86e84
Show file tree
Hide file tree
Showing 6 changed files with 98 additions and 50 deletions.
34 changes: 34 additions & 0 deletions packages/preset-mini/src/_utils/utilities.ts
Expand Up @@ -227,6 +227,40 @@ export function makeGlobalStaticRules(prefix: string, property?: string) {
return globalKeywords.map(keyword => [`${prefix}-${keyword}`, { [property ?? prefix]: keyword }] as Rule)
}

export function getBracket(str: string, open: string, close: string) {
if (str === '')
return

const l = str.length
let parenthesis = 0
let opened = false
let openAt = 0
for (let i = 0; i < l; i++) {
switch (str[i]) {
case open:
if (!opened) {
opened = true
openAt = i
}
parenthesis++
break

case close:
--parenthesis
if (parenthesis < 0)
return
if (parenthesis === 0) {
return [
str.slice(openAt, i + 1),
str.slice(i + 1),
str.slice(0, openAt),
]
}
break
}
}
}

export function getComponent(str: string, open: string, close: string, separators: string | string[]) {
if (str === '')
return
Expand Down
14 changes: 13 additions & 1 deletion packages/preset-mini/src/_utils/variants.ts
@@ -1,6 +1,6 @@
import type { VariantHandler, VariantHandlerContext, VariantObject } from '@unocss/core'
import { escapeRegExp } from '@unocss/core'
import { getComponent } from '../utils'
import { getBracket, getComponent } from '../utils'

export const variantMatcher = (name: string, handler: (input: VariantHandlerContext) => Record<string, any>): VariantObject => {
const re = new RegExp(`^${escapeRegExp(name)}[:-]`)
Expand Down Expand Up @@ -52,3 +52,15 @@ export const variantGetComponent = (name: string, matcher: string): string[] | u
}
}

export const variantGetBracket = (name: string, matcher: string, separators: string[]): string[] | undefined => {
if (matcher.startsWith(`${name}-[`)) {
const [match, rest] = getBracket(matcher.slice(name.length + 1), '[', ']') ?? []
if (match && rest) {
for (const separator of separators) {
if (rest.startsWith(separator))
return [match, rest.slice(separator.length), separator]
}
return [match, rest, '']
}
}
}
3 changes: 2 additions & 1 deletion packages/preset-mini/src/_variants/default.ts
Expand Up @@ -13,7 +13,6 @@ import { variantSupports } from './supports'
import { partClasses, variantPseudoClassFunctions, variantPseudoClassesAndElements, variantTaggedPseudoClasses } from './pseudo'

export const variants = (options: PresetMiniOptions): Variant<Theme>[] => [
variantVariables,
variantCssLayer,

variantSelector,
Expand All @@ -34,4 +33,6 @@ export const variants = (options: PresetMiniOptions): Variant<Theme>[] => [
...variantColorsMediaOrClass(options),
...variantLanguageDirections,
variantScope,

variantVariables,
]
73 changes: 35 additions & 38 deletions packages/preset-mini/src/_variants/pseudo.ts
@@ -1,7 +1,7 @@
import type { VariantObject } from '@unocss/core'
import { escapeRegExp, escapeSelector, warnOnce } from '@unocss/core'
import type { PresetMiniOptions } from '..'
import { getComponent, handler as h } from '../_utils'
import { handler as h, variantGetBracket } from '../_utils'

const PseudoClasses: Record<string, string> = Object.fromEntries([
// pseudo elements part 1
Expand Down Expand Up @@ -83,61 +83,58 @@ const sortValue = (pseudo: string) => {
}

const taggedPseudoClassMatcher = (tag: string, parent: string, combinator: string): VariantObject => {
const rawRe = new RegExp(`^(${escapeRegExp(parent)}(?:<[^>]+>)?:)(\\S+)${escapeRegExp(combinator)}\\1`)
const maybeWithBracketRE = new RegExp(`^${tag}(?:<[^>]+>)?-\\[`)
const pseudoRE = new RegExp(`^${tag}(<[^>]+>)?-(?:(?:(${PseudoClassFunctionsStr})-)?(${PseudoClassesStr}))[:-]`)
const pseudoColonRE = new RegExp(`^${tag}(<[^>]+>)?-(?:(?:(${PseudoClassFunctionsStr})-)?(${PseudoClassesColonStr}))[:]`)
const rawRe = new RegExp(`^(${escapeRegExp(parent)}:)(\\S+)${escapeRegExp(combinator)}\\1`)
const pseudoRE = new RegExp(`^${tag}-(?:(?:(${PseudoClassFunctionsStr})-)?(${PseudoClassesStr}))(?:(/\\w+))?[:-]`)
const pseudoColonRE = new RegExp(`^${tag}-(?:(?:(${PseudoClassFunctionsStr})-)?(${PseudoClassesColonStr}))(?:(/\\w+))?[:]`)
return {
name: `pseudo:${tag}`,
match(input: string) {
if (!input.startsWith(tag))
return

if (input.match(maybeWithBracketRE)) {
const labelMatcher = input.substring(tag.length)
const [label, afterLabel] = getComponent(labelMatcher, '<', '>', '-') ?? ['', labelMatcher.slice(1)]
const body = getComponent(afterLabel, '[', ']', [':', '-'])

if (!body)
return
let label: string
let prefix: string
let matcher: string
let sort: number | undefined

const body = variantGetBracket(tag, input, [])
if (body) {
const [match, rest] = body
const bracketValue = h.bracket(match)

if (bracketValue == null)
return

if (label)
warnOnce('The labeled pseudo is experimental and may be changed in breaking ways at any time.')

let prefix = `${parent}${escapeSelector(label)}`
label = rest.split(/[:-]/, 1)?.[0] ?? ''
prefix = `${parent}${escapeSelector(label)}`
prefix = bracketValue.includes('&') ? bracketValue.replace(/&/g, prefix) : `${prefix}${bracketValue}`

return {
matcher: input.slice(input.length - rest.length),
handle: (input, next) => next({
...input,
prefix: `${prefix}${combinator}${input.prefix}`.replace(rawRe, '$1$2:'),
}),
}
matcher = input.slice(input.length - (rest.length - label.length - 1))
}
else {
const match = input.match(pseudoRE) || input.match(pseudoColonRE)
if (!match)
return

const match = input.match(pseudoRE) || input.match(pseudoColonRE)
if (match) {
const [original, label = '', fn, pseudoKey] = match
if (label)
warnOnce('The labeled pseudo is experimental and may be changed in breaking ways at any time.')
const [original, fn, pseudoKey] = match
let pseudo = PseudoClasses[pseudoKey] || PseudoClassesColon[pseudoKey] || `:${pseudoKey}`
if (fn)
pseudo = `:${fn}(${pseudo})`
return {
matcher: input.slice(original.length),
handle: (input, next) => next({
...input,
prefix: `${parent}${escapeSelector(label)}${pseudo}${combinator}${input.prefix}`.replace(rawRe, '$1$2:'),
sort: sortValue(pseudoKey),
}),
}

label = match[3] ?? ''
prefix = `${parent}${escapeSelector(label)}${pseudo}`
matcher = input.slice(original.length)
sort = sortValue(pseudoKey)
}

if (label !== '')
warnOnce('The labeled pseudo is experimental and may be changed in breaking ways at any time.')

return {
matcher,
handle: (input, next) => next({
...input,
prefix: `${prefix}${combinator}${input.prefix}`.replace(rawRe, '$1$2:'),
}),
sort,
}
},
multiPass: true,
Expand Down
12 changes: 7 additions & 5 deletions test/__snapshots__/preset-mini.test.ts.snap
Expand Up @@ -163,7 +163,7 @@ unocss .scope-\\\\[unocss\\\\]\\\\:block{display:block;}
.hover\\\\:not-first\\\\:checked\\\\:bg-red\\\\/10:checked:not(:first-child):hover{background-color:rgba(248,113,113,0.1);}
.marker\\\\:bg-violet-200::marker{--un-bg-opacity:1;background-color:rgba(221,214,254,var(--un-bg-opacity));}
.peer:checked~.peer-checked\\\\:bg-blue-500{--un-bg-opacity:1;background-color:rgba(59,130,246,var(--un-bg-opacity));}
.previous\\\\<label\\\\>:checked+.previous\\\\<label\\\\>-checked\\\\:bg-red-500{--un-bg-opacity:1;background-color:rgba(239,68,68,var(--un-bg-opacity));}
.previous\\\\/label:checked+.previous-checked\\\\/label\\\\:bg-red-500{--un-bg-opacity:1;background-color:rgba(239,68,68,var(--un-bg-opacity));}
.bg-opacity-45{--un-bg-opacity:0.45;}
.all-\\\\[svg\\\\]\\\\:fill-red svg{--un-fill-opacity:1;fill:rgba(248,113,113,var(--un-fill-opacity));}
.fill-\\\\[\\\\#123\\\\]{--un-fill-opacity:1;fill:rgba(17,34,51,var(--un-fill-opacity));}
Expand Down Expand Up @@ -325,7 +325,7 @@ unocss .scope-\\\\[unocss\\\\]\\\\:block{display:block;}
.text-size-\\\\$variable{font-size:var(--variable);}
.text-size-unset{font-size:unset;}
.as-parent .group .group-\\\\[\\\\.as-parent_\\\\&\\\\]\\\\:font-13{font-weight:13;}
.as-parent .group\\\\<label\\\\> .group\\\\<label\\\\>-\\\\[\\\\.as-parent_\\\\&\\\\]\\\\:font-18{font-weight:18;}
.as-parent .group\\\\/label .group-\\\\[\\\\.as-parent_\\\\&\\\\]\\\\/label\\\\:font-18{font-weight:18;}
.font-050,
.font-50,
.fw-050,
Expand All @@ -335,11 +335,13 @@ unocss .scope-\\\\[unocss\\\\]\\\\:block{display:block;}
.font-inherit{font-weight:inherit;}
.font-thin{font-weight:100;}
.group:hover .group-\\\\[\\\\:hover\\\\]\\\\:font-11{font-weight:11;}
.group:hover .group-hover\\\\:font-10{font-weight:10;}
.group.not-parent .group-\\\\[\\\\.not-parent\\\\]\\\\:font-14{font-weight:14;}
.group[data-attr] .group-\\\\[\\\\[data-attr\\\\]\\\\]\\\\:font-12{font-weight:12;}
.group\\\\<label\\\\>:hover .group\\\\<label\\\\>-\\\\[\\\\:hover\\\\]\\\\:font-16{font-weight:16;}
.group\\\\<label\\\\>.not-parent .group\\\\<label\\\\>-\\\\[\\\\.not-parent\\\\]\\\\:font-19{font-weight:19;}
.group\\\\<label\\\\>[data-attr] .group\\\\<label\\\\>-\\\\[\\\\[data-attr\\\\]\\\\]\\\\:font-17{font-weight:17;}
.group\\\\/label:hover .group-\\\\[\\\\:hover\\\\]\\\\/label\\\\:font-16{font-weight:16;}
.group\\\\/label:hover .group-hover\\\\/label\\\\:font-15{font-weight:15;}
.group\\\\/label.not-parent .group-\\\\[\\\\.not-parent\\\\]\\\\/label\\\\:font-19{font-weight:19;}
.group\\\\/label[data-attr] .group-\\\\[\\\\[data-attr\\\\]\\\\]\\\\/label\\\\:font-17{font-weight:17;}
.font-leading-2,
.leading-2{line-height:0.5rem;}
.leading-\\\\$variable,
Expand Down
12 changes: 7 additions & 5 deletions test/assets/preset-mini-targets.ts
Expand Up @@ -967,15 +967,17 @@ export const presetMiniTargets: string[] = [
'group-focus:p-4',
'peer-checked:bg-blue-500',
'parent-hover:text-center',
'previous<label>-checked:bg-red-500',
'previous-checked/label:bg-red-500',
'group-hover:font-10',
'group-[:hover]:font-11',
'group-[[data-attr]]:font-12',
'group-[.as-parent_&]:font-13',
'group-[.not-parent]:font-14',
'group<label>-[:hover]:font-16',
'group<label>-[[data-attr]]:font-17',
'group<label>-[.as-parent_&]:font-18',
'group<label>-[.not-parent]:font-19',
'group-hover/label:font-15',
'group-[:hover]/label:font-16',
'group-[[data-attr]]/label:font-17',
'group-[.as-parent_&]/label:font-18',
'group-[.not-parent]/label:font-19',

// variants - variables
'[&:nth-child(2)]:m-10',
Expand Down

0 comments on commit 7e86e84

Please sign in to comment.