Skip to content

Commit

Permalink
feat(preset-mini): support arbitrary properties with quotes (#1904)
Browse files Browse the repository at this point in the history
  • Loading branch information
sibbng committed Nov 24, 2022
1 parent 3d805df commit 22c4e70
Show file tree
Hide file tree
Showing 6 changed files with 44 additions and 4 deletions.
2 changes: 1 addition & 1 deletion packages/core/src/extractors/index.ts
@@ -1,2 +1,2 @@
export { extractorSplit } from './split'
export { extractorSplit, cssPropertyRE } from './split'
export { extractorSvelte } from './svelte'
16 changes: 15 additions & 1 deletion packages/core/src/extractors/split.ts
@@ -1,7 +1,21 @@
import type { Extractor } from '../types'
import { isValidSelector } from '../utils'

export const splitCode = (code: string) => [...new Set(code.split(/\\?[\s'"`;{}]+/g))].filter(isValidSelector)
const defaultSplitRE = /\\?[\s'"`;{}]+/g
export const cssPropertyRE = /[\s'"`](\[(\\\W|[\w-])+:['"]?\S*?['"]?\])/g

export const splitCode = (code: string) => {
const result = new Set<string>()

for (const match of code.matchAll(cssPropertyRE))
result.add(match[1])

code.split(defaultSplitRE).forEach((match) => {
isValidSelector(match) && result.add(match)
})

return [...result]
}

export const extractorSplit: Extractor = {
name: 'split',
Expand Down
2 changes: 1 addition & 1 deletion packages/preset-mini/src/_rules/variables.ts
Expand Up @@ -26,5 +26,5 @@ export const cssVariables: Rule[] = [
]

export const cssProperty: Rule[] = [
[/^\[([\w_-]+):([^'"]+)\]$/, ([, prop, value]) => ({ [prop]: h.bracket(`[${value}]`) })],
[/^\[(--(\w|\\\W)+|[\w-]+):(.+)\]$/, ([, prop,, value]) => ({ [prop]: h.bracket(`[${value}]`) })],
]
10 changes: 9 additions & 1 deletion packages/shared-common/src/index.ts
@@ -1,5 +1,5 @@
import type { UnoGenerator } from '@unocss/core'
import { escapeRegExp, isAttributifySelector, regexClassGroup } from '@unocss/core'
import { cssPropertyRE, escapeRegExp, isAttributifySelector, regexClassGroup } from '@unocss/core'
import MagicString from 'magic-string'

// https://github.com/dsblv/string-replace-async/blob/main/index.js
Expand Down Expand Up @@ -53,6 +53,14 @@ export function getMatchedPositions(code: string, matched: string[], hasVariantG
start = end
})

// highlight for arbitrary css properties
for (const match of code.matchAll(cssPropertyRE)) {
const start = match.index! + 1
const end = start + match[1].length
if (plain.has(match[1]))
result.push([start, end, match[1]])
}

// highlight for variant group
if (hasVariantGroup) {
Array.from(code.matchAll(regexClassGroup))
Expand Down
6 changes: 6 additions & 0 deletions test/__snapshots__/preset-mini.test.ts.snap
Expand Up @@ -41,10 +41,16 @@ exports[`preset-mini > targets 1`] = `
.fw-\\\\$variable{font-weight:var(--variable);}
.items-\\\\$size{align-items:var(--size);}
.ws-\\\\$variable{white-space:var(--variable);}
.\\\\[--css-variable\\\\:\\\\\\"wght\\\\\\"_400\\\\,_\\\\\\"opsz\\\\\\"_14\\\\]{--css-variable:\\"wght\\" 400, \\"opsz\\" 14;}
.\\\\[--escaped\\\\\\\\\\\\~variable\\\\\\\\\\\\:\\\\:100\\\\%\\\\]{--escaped\\\\~variable\\\\::100%;}
.\\\\[a\\\\:b\\\\]{a:b;}
.\\\\[background-image\\\\:url\\\\(star_transparent\\\\.gif\\\\)\\\\,_url\\\\(cat_front\\\\.png\\\\)\\\\]{background-image:url(star_transparent.gif), url(cat_front.png);}
.\\\\[content\\\\:attr\\\\(attr_content\\\\)\\\\]{content:attr(attr content);}
.\\\\[content\\\\:attr\\\\(attr\\\\\\\\_content\\\\)\\\\]{content:attr(attr_content);}
.\\\\[font-family\\\\:\\\\'Inter\\\\'\\\\,_sans-serif\\\\]{font-family:'Inter', sans-serif;}
.\\\\[font-family\\\\:var\\\\(--font-family\\\\)\\\\]{font-family:var(--font-family);}
.\\\\[font-feature-settings\\\\:\\\\'cv02\\\\'\\\\,\\\\'cv03\\\\'\\\\,\\\\'cv04\\\\'\\\\,\\\\'cv11\\\\'\\\\]{font-feature-settings:'cv02','cv03','cv04','cv11';}
.\\\\[font-variation-settings\\\\:\\\\\\"wght\\\\\\"_400\\\\,_\\\\\\"opsz\\\\\\"_14\\\\]{font-variation-settings:\\"wght\\" 400, \\"opsz\\" 14;}
.\\\\[margin\\\\:logical_1rem_2rem_3rem\\\\]{margin:logical 1rem 2rem 3rem;}
.all-\\\\[\\\\.target\\\\]-\\\\[combinator\\\\:test-2\\\\] .target,
.children-\\\\[\\\\.target\\\\]-\\\\[combinator\\\\:test-2\\\\]>.target,
Expand Down
12 changes: 12 additions & 0 deletions test/assets/preset-mini-targets.ts
Expand Up @@ -850,6 +850,12 @@ export const presetMiniTargets: string[] = [
'[content:attr(attr_content)]',
'[content:attr(attr\\_content)]',
'[background-image:url(star_transparent.gif),_url(cat_front.png)]',
'[font-family:var(--font-family)]',
'[font-family:\'Inter\',_sans-serif]',
'[font-feature-settings:\'cv02\',\'cv03\',\'cv04\',\'cv11\']',
'[font-variation-settings:"wght"_400,_"opsz"_14]',
'[--css-variable:"wght"_400,_"opsz"_14]',
'[--escaped\\~variable\\::100%]',

// variants
'active:scale-4',
Expand Down Expand Up @@ -1044,4 +1050,10 @@ export const presetMiniNonTargets = [

// variants - combinator
'all:[svg]:fill-red',

// arbitrary css properties edge cases that cause invalid output
'[name].[hash:9]',
'["update:modelValue"]',
// escaped arbitrary css properties only allowed in css variables
'[cant\~escape:me]',
]

0 comments on commit 22c4e70

Please sign in to comment.