Skip to content

Commit

Permalink
fix(preset-mini): let negate variant negate negative numbers & functi…
Browse files Browse the repository at this point in the history
…ons (#3399)
  • Loading branch information
chu121su12 committed Nov 30, 2023
1 parent da3996a commit 130943e
Show file tree
Hide file tree
Showing 7 changed files with 41 additions and 12 deletions.
2 changes: 1 addition & 1 deletion packages/preset-mini/src/_utils/mappings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -114,4 +114,4 @@ export const globalKeywords = [
'unset',
]

export const cssMathFnRE = /(?:calc|clamp|min|max)\s*\(.*\)/
export const cssMathFnRE = /^(calc|clamp|min|max)\s*\((.+)\)(.*)/
43 changes: 32 additions & 11 deletions packages/preset-mini/src/_variants/negative.ts
Original file line number Diff line number Diff line change
@@ -1,22 +1,36 @@
import type { Variant } from '@unocss/core'
import { getStringComponent } from '@unocss/rule-utils'
import { CONTROL_MINI_NO_NEGATIVE } from '../utils'
import { CONTROL_MINI_NO_NEGATIVE, cssMathFnRE } from '../utils'

const numberRE = /[0-9.]+(?:[a-z]+|%)?/
const numberRE = /-?[0-9.]+(?:[a-z]+|%)?/

const ignoreProps = [
/opacity|color|flex/,
/\b(opacity|color|flex|backdrop-filter|^filter|transform)\b/,
]

function negateFunctions(value: string) {
const match = value.match(/^(calc|clamp|max|min)\s*(\(.*)/)
function negateMathFunction(value: string) {
const match = value.match(cssMathFnRE)
if (match) {
const [fnBody, rest] = getStringComponent(match[2], '(', ')', ' ') ?? []
const [fnBody, rest] = getStringComponent(`(${match[2]})${match[3]}`, '(', ')', ' ') ?? []
if (fnBody)
return `calc(${match[1]}${fnBody} * -1)${rest ? ` ${rest}` : ''}`
}
}

const negateFunctionBodyRE = /\b(hue-rotate)\s*(\(.*)/
function negateFunctionBody(value: string) {
const match = value.match(negateFunctionBodyRE)
if (match) {
const [fnBody, rest] = getStringComponent(match[2], '(', ')', ' ') ?? []
if (fnBody) {
const body = numberRE.test(fnBody)
? fnBody.replace(numberRE, i => i.startsWith('-') ? i.slice(1) : `-${i}`)
: `(calc(${fnBody} * -1))`
return `${match[1]}${body}${rest ? ` ${rest}` : ''}`
}
}
}

export const variantNegative: Variant = {
name: 'negative',
match(matcher) {
Expand All @@ -35,13 +49,20 @@ export const variantNegative: Variant = {
return
if (ignoreProps.some(i => i.test(v[0])))
return
const negated = negateFunctions(value)
if (negated) {
v[1] = negated
const negatedFn = negateMathFunction(value)
if (negatedFn) {
v[1] = negatedFn
changed = true
return
}
const negatedBody = negateFunctionBody(value)
if (negatedBody) {
v[1] = negatedBody
changed = true
return
}
else if (numberRE.test(value)) {
v[1] = value.replace(numberRE, i => `-${i}`)
if (numberRE.test(value)) {
v[1] = value.replace(numberRE, i => i.startsWith('-') ? i.slice(1) : `-${i}`)
changed = true
}
})
Expand Down
2 changes: 2 additions & 0 deletions test/__snapshots__/postcss.test.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -348,6 +348,8 @@ exports[`postcss > @unocss 1`] = `
.grayscale-\\$variable{--un-grayscale:grayscale(var(--variable));filter:var(--un-blur) var(--un-brightness) var(--un-contrast) var(--un-drop-shadow) var(--un-grayscale) var(--un-hue-rotate) var(--un-invert) var(--un-saturate) var(--un-sepia);}
.grayscale-90{--un-grayscale:grayscale(0.9);filter:var(--un-blur) var(--un-brightness) var(--un-contrast) var(--un-drop-shadow) var(--un-grayscale) var(--un-hue-rotate) var(--un-invert) var(--un-saturate) var(--un-sepia);}
.-backdrop-hue-rotate-90{--un-backdrop-hue-rotate:hue-rotate(-90deg);-webkit-backdrop-filter:var(--un-backdrop-blur) var(--un-backdrop-brightness) var(--un-backdrop-contrast) var(--un-backdrop-grayscale) var(--un-backdrop-hue-rotate) var(--un-backdrop-invert) var(--un-backdrop-opacity) var(--un-backdrop-saturate) var(--un-backdrop-sepia);backdrop-filter:var(--un-backdrop-blur) var(--un-backdrop-brightness) var(--un-backdrop-contrast) var(--un-backdrop-grayscale) var(--un-backdrop-hue-rotate) var(--un-backdrop-invert) var(--un-backdrop-opacity) var(--un-backdrop-saturate) var(--un-backdrop-sepia);}
.-hue-rotate--90{--un-hue-rotate:hue-rotate(90deg);filter:var(--un-blur) var(--un-brightness) var(--un-contrast) var(--un-drop-shadow) var(--un-grayscale) var(--un-hue-rotate) var(--un-invert) var(--un-saturate) var(--un-sepia);}
.-hue-rotate-\\[var\\(--for-hue\\,0\\.5turn\\)\\]{--un-hue-rotate:hue-rotate(var(--for-hue,-0.5turn));filter:var(--un-blur) var(--un-brightness) var(--un-contrast) var(--un-drop-shadow) var(--un-grayscale) var(--un-hue-rotate) var(--un-invert) var(--un-saturate) var(--un-sepia);}
.-hue-rotate-90{--un-hue-rotate:hue-rotate(-90deg);filter:var(--un-blur) var(--un-brightness) var(--un-contrast) var(--un-drop-shadow) var(--un-grayscale) var(--un-hue-rotate) var(--un-invert) var(--un-saturate) var(--un-sepia);}
.backdrop-hue-rotate-0{--un-backdrop-hue-rotate:hue-rotate(0);-webkit-backdrop-filter:var(--un-backdrop-blur) var(--un-backdrop-brightness) var(--un-backdrop-contrast) var(--un-backdrop-grayscale) var(--un-backdrop-hue-rotate) var(--un-backdrop-invert) var(--un-backdrop-opacity) var(--un-backdrop-saturate) var(--un-backdrop-sepia);backdrop-filter:var(--un-backdrop-blur) var(--un-backdrop-brightness) var(--un-backdrop-contrast) var(--un-backdrop-grayscale) var(--un-backdrop-hue-rotate) var(--un-backdrop-invert) var(--un-backdrop-opacity) var(--un-backdrop-saturate) var(--un-backdrop-sepia);}
.backdrop-hue-rotate-360{--un-backdrop-hue-rotate:hue-rotate(360deg);-webkit-backdrop-filter:var(--un-backdrop-blur) var(--un-backdrop-brightness) var(--un-backdrop-contrast) var(--un-backdrop-grayscale) var(--un-backdrop-hue-rotate) var(--un-backdrop-invert) var(--un-backdrop-opacity) var(--un-backdrop-saturate) var(--un-backdrop-sepia);backdrop-filter:var(--un-backdrop-blur) var(--un-backdrop-brightness) var(--un-backdrop-contrast) var(--un-backdrop-grayscale) var(--un-backdrop-hue-rotate) var(--un-backdrop-invert) var(--un-backdrop-opacity) var(--un-backdrop-saturate) var(--un-backdrop-sepia);}
Expand Down
1 change: 1 addition & 0 deletions test/assets/output/preset-mini-targets.css
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@
.my-revert-layer{margin-top:revert-layer;margin-bottom:revert-layer;}
.-\!mb-safe{margin-bottom:calc(max(env(safe-area-inset-left), env(safe-area-inset-right)) * -1) !important;}
.-mb-px{margin-bottom:-1px;}
.-mt--5cm{margin-top:5cm;}
.-mt-safe{margin-top:calc(max(env(safe-area-inset-left), env(safe-area-inset-right)) * -1);}
.\!-ms-safe{margin-inline-start:calc(max(env(safe-area-inset-left), env(safe-area-inset-right)) * -1) !important;}
.me-8{margin-inline-end:2rem;}
Expand Down
2 changes: 2 additions & 0 deletions test/assets/output/preset-wind-targets.css

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions test/assets/preset-mini-targets.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1036,6 +1036,7 @@ export const presetMiniTargets: string[] = [
'!p-5px',
'-gap-y-5',
'-mb-px',
'-mt--5cm',
'-p-px',
'-z-1',

Expand Down
2 changes: 2 additions & 0 deletions test/assets/preset-wind-targets.ts
Original file line number Diff line number Diff line change
Expand Up @@ -385,6 +385,8 @@ export const presetWindTargets: string[] = [
'!animate-ping',
'-backdrop-hue-rotate-90',
'-hue-rotate-90',
'-hue-rotate--90',
'-hue-rotate-[var(--for-hue,0.5turn)]',
'hover:animate-bounce',

'-scroll-mb-px',
Expand Down

0 comments on commit 130943e

Please sign in to comment.