Skip to content

Commit

Permalink
use separators from config
Browse files Browse the repository at this point in the history
  • Loading branch information
chu121su12 committed Dec 4, 2022
1 parent 22c4e70 commit 6f1900d
Show file tree
Hide file tree
Showing 17 changed files with 276 additions and 179 deletions.
7 changes: 6 additions & 1 deletion packages/core/src/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ export function resolveConfig<Theme extends {} = {}>(

const layers = Object.assign(DEFAULT_LAYERS, ...rawPresets.map(i => i.layers), userConfig.layers)

function mergePresets<T extends 'rules' | 'variants' | 'extractors' | 'shortcuts' | 'preflights' | 'preprocess' | 'postprocess' | 'extendTheme' | 'safelist'>(key: T): Required<UserConfig<Theme>>[T] {
function mergePresets<T extends 'rules' | 'variants' | 'extractors' | 'shortcuts' | 'preflights' | 'preprocess' | 'postprocess' | 'extendTheme' | 'safelist' | 'separators'>(key: T): Required<UserConfig>[T] {
return uniq([
...sortedPresets.flatMap(p => toArray(p[key] || []) as any[]),
...toArray(config[key] || []) as any[],
Expand Down Expand Up @@ -93,6 +93,10 @@ export function resolveConfig<Theme extends {} = {}>(
.sort((a, b) => (a.order || 0) - (b.order || 0)),
}

let separators = toArray(mergePresets('separators'))
if (!separators.length)
separators = [':', '-']

return {
mergeSelectors: true,
warn: true,
Expand All @@ -115,5 +119,6 @@ export function resolveConfig<Theme extends {} = {}>(
shortcuts: resolveShortcuts(mergePresets('shortcuts')),
extractors,
safelist: mergePresets('safelist'),
separators,
}
}
8 changes: 8 additions & 0 deletions packages/core/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -307,6 +307,13 @@ export interface ConfigBase<Theme extends {} = {}> {
*/
rules?: Rule<Theme>[]

/**
* Variant separator
*
* @default [':', '-']
*/
separators?: Arrayable<string>

/**
* Variants that preprocess the selectors,
* having the ability to rewrite the CSS object.
Expand Down Expand Up @@ -632,6 +639,7 @@ RequiredByKey<UserConfig<Theme>, 'mergeSelectors' | 'theme' | 'rules' | 'variant
templates: (AutoCompleteFunction | AutoCompleteTemplate)[]
extractors: AutoCompleteExtractor[]
}
separators: string[]
}

export interface GenerateResult {
Expand Down
12 changes: 10 additions & 2 deletions packages/core/src/utils/variantGroup.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,19 @@
import type MagicString from 'magic-string'

export const regexClassGroup = /((?:[!\w+:_/-]|\[&?>?:?.*\])+?)([:-])\(((?:[~!\w\s:/\\,%#.$-]|\[.*?\])*?)\)/gm
const regexCache: Record<string, RegExp> = {}

export function makeRegexClassGroup(seperators = ['-', ':']) {
const key = seperators.join('|')
if (!regexCache[key])
regexCache[key] = new RegExp(`((?:[!\\w+:_/-]|\\[&?>?:?.*\\])+?)(${key})\\(((?:[~!\\w\\s:/\\\\,%#.$-]|\\[.*?\\])*?)\\)`, 'gm')
regexCache[key].lastIndex = 0
return regexCache[key]
}

export function expandVariantGroup(str: string, seperators?: string[], depth?: number): string
export function expandVariantGroup(str: MagicString, seperators?: string[], depth?: number): MagicString
export function expandVariantGroup(str: string | MagicString, seperators = ['-', ':'], depth = 5) {
regexClassGroup.lastIndex = 0
const regexClassGroup = makeRegexClassGroup(seperators)
let hasChanged = false
let content = str.toString()
do {
Expand Down
14 changes: 10 additions & 4 deletions packages/preset-mini/src/_utils/variants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,13 @@ import { escapeRegExp } from '@unocss/core'
import { getBracket } from '../utils'

export const variantMatcher = (name: string, handler: (input: VariantHandlerContext) => Record<string, any>): VariantObject => {
const re = new RegExp(`^${escapeRegExp(name)}[:-]`)
let re: RegExp
return {
name,
match(input) {
match(input, ctx) {
if (!re)
re = new RegExp(`^${escapeRegExp(name)}(?:${ctx.generator.config.separators.join('|')})`)

const match = input.match(re)
if (match) {
return {
Expand All @@ -23,10 +26,13 @@ export const variantMatcher = (name: string, handler: (input: VariantHandlerCont
}

export const variantParentMatcher = (name: string, parent: string): VariantObject => {
const re = new RegExp(`^${escapeRegExp(name)}[:-]`)
let re: RegExp
return {
name,
match(input) {
match(input, ctx) {
if (!re)
re = new RegExp(`^${escapeRegExp(name)}(?:${ctx.generator.config.separators.join('|')})`)

const match = input.match(re)
if (match) {
return {
Expand Down
104 changes: 52 additions & 52 deletions packages/preset-mini/src/_variants/breakpoints.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,5 @@
import type { Variant } from '@unocss/core'
import type { VariantObject } from '@unocss/core'
import { resolveBreakpoints } from '../utils'
import type { Theme } from '../theme'

const regexCache: Record<string, RegExp> = {}

export const calcMaxWidthBySize = (size: string) => {
const value = size.match(/^-?[0-9]+\.?[0-9]*/)?.[0] || ''
Expand All @@ -11,69 +8,72 @@ export const calcMaxWidthBySize = (size: string) => {
return Number.isNaN(maxWidth) ? size : `${maxWidth}${unit}`
}

export const variantBreakpoints: Variant<Theme> = {
name: 'breakpoints',
match(matcher, context) {
const variantEntries: Array<[string, string, number]>
= Object.entries(resolveBreakpoints(context) ?? {}).map(([point, size], idx) => [point, size, idx])
for (const [point, size, idx] of variantEntries) {
if (!regexCache[point])
regexCache[point] = new RegExp(`^((?:[al]t-)?${point}[:-])`)
export const variantBreakpoints = (): VariantObject => {
const regexCache: Record<string, RegExp> = {}
return {
name: 'breakpoints',
match(matcher, context) {
const variantEntries: Array<[string, string, number]>
= Object.entries(resolveBreakpoints(context) ?? {}).map(([point, size], idx) => [point, size, idx])
for (const [point, size, idx] of variantEntries) {
if (!regexCache[point])
regexCache[point] = new RegExp(`^((?:[al]t-)?${point}(?:${context.generator.config.separators.join('|')}))`)

const match = matcher.match(regexCache[point])
if (!match)
continue
const match = matcher.match(regexCache[point])
if (!match)
continue

const [, pre] = match
const [, pre] = match

const m = matcher.slice(pre.length)
// container rule is responsive, but also is breakpoint aware
// it is handled on its own module (container.ts) and so we
// exclude it from here
if (m === 'container')
continue
const m = matcher.slice(pre.length)
// container rule is responsive, but also is breakpoint aware
// it is handled on its own module (container.ts) and so we
// exclude it from here
if (m === 'container')
continue

const isLtPrefix = pre.startsWith('lt-')
const isAtPrefix = pre.startsWith('at-')
const isLtPrefix = pre.startsWith('lt-')
const isAtPrefix = pre.startsWith('at-')

let order = 1000 // parseInt(size)
let order = 1000 // parseInt(size)

if (isLtPrefix) {
order -= (idx + 1)
return {
matcher: m,
handle: (input, next) => next({
...input,
parent: `${input.parent ? `${input.parent} $$ ` : ''}@media (max-width: ${calcMaxWidthBySize(size)})`,
parentOrder: order,
}),
if (isLtPrefix) {
order -= (idx + 1)
return {
matcher: m,
handle: (input, next) => next({
...input,
parent: `${input.parent ? `${input.parent} $$ ` : ''}@media (max-width: ${calcMaxWidthBySize(size)})`,
parentOrder: order,
}),
}
}
}

order += (idx + 1)
order += (idx + 1)

// support for windicss @<breakpoint> => last breakpoint will not have the upper bound
if (isAtPrefix && idx < variantEntries.length - 1) {
return {
matcher: m,
handle: (input, next) => next({
...input,
parent: `${input.parent ? `${input.parent} $$ ` : ''}@media (min-width: ${size}) and (max-width: ${calcMaxWidthBySize(variantEntries[idx + 1][1])})`,
parentOrder: order,
}),
}
}

// support for windicss @<breakpoint> => last breakpoint will not have the upper bound
if (isAtPrefix && idx < variantEntries.length - 1) {
return {
matcher: m,
handle: (input, next) => next({
...input,
parent: `${input.parent ? `${input.parent} $$ ` : ''}@media (min-width: ${size}) and (max-width: ${calcMaxWidthBySize(variantEntries[idx + 1][1])})`,
parent: `${input.parent ? `${input.parent} $$ ` : ''}@media (min-width: ${size})`,
parentOrder: order,
}),
}
}

return {
matcher: m,
handle: (input, next) => next({
...input,
parent: `${input.parent ? `${input.parent} $$ ` : ''}@media (min-width: ${size})`,
parentOrder: order,
}),
}
}
},
multiPass: true,
autocomplete: '(at-|lt-|)$breakpoints:',
},
multiPass: true,
autocomplete: '(at-|lt-|)$breakpoints:',
}
}
7 changes: 4 additions & 3 deletions packages/preset-mini/src/_variants/combinators.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,14 @@ import { handler as h, variantGetBracket } from '../utils'

const scopeMatcher = (name: string, combinator: string): VariantObject => ({
name: `combinator:${name}`,
match(matcher) {
match(matcher, ctx) {
if (!matcher.startsWith(name))
return

let body = variantGetBracket(`${name}-`, matcher, [':', '-'])
const separators = ctx.generator.config.separators
let body = variantGetBracket(`${name}-`, matcher, separators)
if (!body) {
for (const separator of [':', '-']) {
for (const separator of separators) {
if (matcher.startsWith(`${name}${separator}`)) {
body = ['', matcher.slice(name.length + separator.length)]
break
Expand Down
8 changes: 4 additions & 4 deletions packages/preset-mini/src/_variants/default.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,15 +23,15 @@ export const variants = (options: PresetMiniOptions): Variant<Theme>[] => [
variantSelector,
variantInternalLayer,
variantNegative,
variantImportant,
variantImportant(),
variantSupports,
variantPrint,
variantCustomMedia,
variantBreakpoints,
variantBreakpoints(),
...variantCombinators,

variantPseudoClassesAndElements,
variantPseudoClassFunctions,
variantPseudoClassesAndElements(),
variantPseudoClassFunctions(),
...variantTaggedPseudoClasses(options),

partClasses,
Expand Down
49 changes: 27 additions & 22 deletions packages/preset-mini/src/_variants/important.ts
Original file line number Diff line number Diff line change
@@ -1,27 +1,32 @@
import type { Variant } from '@unocss/core'
import type { VariantObject } from '@unocss/core'

export const variantImportant: Variant = {
name: 'important',
match(matcher) {
let base: string | undefined
export const variantImportant = (): VariantObject => {
let re: RegExp
return {
name: 'important',
match(matcher, ctx) {
if (!re)
re = new RegExp(`^(important(?:${ctx.generator.config.separators.join('|')})|!)`)

const match = matcher.match(/^(important[:-]|!)/)
if (match)
base = matcher.slice(match[0].length)
else if (matcher.endsWith('!'))
base = matcher.slice(0, -1)
let base: string | undefined
const match = matcher.match(re)
if (match)
base = matcher.slice(match[0].length)
else if (matcher.endsWith('!'))
base = matcher.slice(0, -1)

if (base) {
return {
matcher: base,
body: (body) => {
body.forEach((v) => {
if (v[1])
v[1] += ' !important'
})
return body
},
if (base) {
return {
matcher: base,
body: (body) => {
body.forEach((v) => {
if (v[1])
v[1] += ' !important'
})
return body
},
}
}
}
},
},
}
}
10 changes: 5 additions & 5 deletions packages/preset-mini/src/_variants/media.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,19 @@
import type { Variant, VariantContext, VariantObject } from '@unocss/core'
import type { VariantContext, VariantObject } from '@unocss/core'
import type { Theme } from '../theme'
import { handler as h, variantGetParameter, variantParentMatcher } from '../utils'

export const variantPrint: Variant = variantParentMatcher('print', '@media print')
export const variantPrint: VariantObject = variantParentMatcher('print', '@media print')

export const variantCustomMedia: VariantObject = {
name: 'media',
match(matcher, { theme }: VariantContext<Theme>) {
const variant = variantGetParameter('media-', matcher, [':', '-'])
match(matcher, ctx: VariantContext<Theme>) {
const variant = variantGetParameter('media-', matcher, ctx.generator.config.separators)
if (variant) {
const [match, rest] = variant

let media = h.bracket(match) ?? ''
if (media === '')
media = theme.media?.[match] ?? ''
media = ctx.theme.media?.[match] ?? ''

if (media) {
return {
Expand Down

0 comments on commit 6f1900d

Please sign in to comment.