diff --git a/packages/preset-mini/src/_utils/handlers/handlers.ts b/packages/preset-mini/src/_utils/handlers/handlers.ts index d26dd7e8ef..16fa529265 100644 --- a/packages/preset-mini/src/_utils/handlers/handlers.ts +++ b/packages/preset-mini/src/_utils/handlers/handlers.ts @@ -91,16 +91,21 @@ export function fraction(str: string) { return `${round(num * 100)}%` } -const bracketTypeRe = /^\[(color|length|position):/i -function bracketWithType(str: string, type?: string) { +const bracketTypeRe = /^\[(color|length|position|raw|string):/i +function bracketWithType(str: string, requiredType?: string) { if (str && str.startsWith('[') && str.endsWith(']')) { let base: string | undefined + let hintedType: string | undefined const match = str.match(bracketTypeRe) - if (!match) + if (!match) { base = str.slice(1, -1) - else if (type && match[1] === type) + } + else { + if (!requiredType) + hintedType = match[1] base = str.slice(match[0].length, -1) + } if (!base) return @@ -119,9 +124,19 @@ function bracketWithType(str: string, type?: string) { if (curly) return + switch (hintedType) { + case 'raw': return base + + case 'string': return base + .replace(/(^|[^\\])_/g, '$1 ') + .replace(/\\_/g, '_') + .replace(/(['\\])/g, '\\$1') + .replace(/^(.+)$/, '\'$1\'') + } + return base .replace(/(url\(.*?\))/g, v => v.replace(/_/g, '\\_')) - .replace(/([^\\])_/g, '$1 ') + .replace(/(^|[^\\])_/g, '$1 ') .replace(/\\_/g, '_') .replace(/(?:calc|clamp|max|min)\((.*)/g, (v) => { return v.replace(/(-?\d*\.?\d(?!\b-.+[,)](?![^+\-/*])\D)(?:%|[a-z]+)?|\))([+\-/*])/g, '$1 $2 ') diff --git a/test/handler.test.ts b/test/handler.test.ts index f5e14396c3..52df680c62 100644 --- a/test/handler.test.ts +++ b/test/handler.test.ts @@ -24,9 +24,24 @@ describe('value handler', () => { it('bracket underscore', () => { expect(h.bracket('[a_b]')).eql('a b') expect(h.bracket('[a\\_b]')).eql('a_b') + expect(h.bracket('[_b_only]')).eql(' b only') + expect(h.bracket('[\\_b]')).eql('_b') expect(h.bracket('[url(a_b)]')).eql('url(a_b)') expect(h.bracket('[url(a\\_b)]')).eql('url(a\\_b)') expect(h.bracket('[var(--A_B)]')).eql('var(--A B)') expect(h.bracket('[var(--A\\_B)]')).eql('var(--A_B)') }) + + it('bracket raw-type', () => { + expect(h.bracket('[raw:a b]')).eql('a b') + expect(h.bracket('[raw:a_b]')).eql('a_b') + expect(h.bracket('[raw:a\\_b]')).eql('a\\_b') + expect(h.bracket('[raw:attr("data-label") ":" attr("data-value")]')).eql('attr("data-label") ":" attr("data-value")') + }) + + it('bracket string-type', () => { + expect(h.bracket('[string:a_b]')).eql('\'a b\'') + expect(h.bracket('[string:a\\_b]')).eql('\'a_b\'') + expect(h.bracket('[string:with-\\,-\'-and-"]')).eql('\'with-\\\\,-\\\'-and-"\'') + }) })