Skip to content

Commit 235c377

Browse files
authored
feat(preset-mini)!: prioritize length instead of color (#3353)
1 parent 9f2bd6d commit 235c377

File tree

25 files changed

+293
-246
lines changed

25 files changed

+293
-246
lines changed

docs/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,6 @@
1616
"@iconify-json/vscode-icons": "^1.1.31",
1717
"ofetch": "^1.3.3",
1818
"unocss": "workspace:*",
19-
"vitepress": "1.0.0-rc.29"
19+
"vitepress": "1.0.0-rc.31"
2020
}
2121
}

packages/preset-mini/src/_rules/behaviors.ts

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
1-
import type { Rule } from '@unocss/core'
1+
import type { CSSObject, Rule, RuleContext } from '@unocss/core'
22
import type { Theme } from '../theme'
3-
import { colorResolver, globalKeywords, h } from '../utils'
3+
import { colorResolver, globalKeywords, h, isCSSMathFn } from '../utils'
44

55
export const outline: Rule<Theme>[] = [
66
// size
7-
[/^outline-(?:width-|size-)?(.+)$/, ([, d], { theme }) => ({ 'outline-width': theme.lineWidth?.[d] ?? h.bracket.cssvar.global.px(d) }), { autocomplete: 'outline-(width|size)-<num>' }],
7+
[/^outline-(?:width-|size-)?(.+)$/, handleWidth, { autocomplete: 'outline-(width|size)-<num>' }],
88

99
// color
10-
[/^outline-(?:color-)?(.+)$/, colorResolver('outline-color', 'outline-color', 'borderColor'), { autocomplete: 'outline-$colors' }],
10+
[/^outline-(?:color-)?(.+)$/, handleColorOrWidth, { autocomplete: 'outline-$colors' }],
1111

1212
// offset
1313
[/^outline-offset-(.+)$/, ([, d], { theme }) => ({ 'outline-offset': theme.lineWidth?.[d] ?? h.bracket.cssvar.global.px(d) }), { autocomplete: 'outline-(offset)-<num>' }],
@@ -18,6 +18,16 @@ export const outline: Rule<Theme>[] = [
1818
['outline-none', { 'outline': '2px solid transparent', 'outline-offset': '2px' }],
1919
]
2020

21+
function handleWidth([, b]: string[], { theme }: RuleContext<Theme>): CSSObject {
22+
return { 'outline-width': theme.lineWidth?.[b] ?? h.bracket.cssvar.global.px(b) }
23+
}
24+
25+
function handleColorOrWidth(match: RegExpMatchArray, ctx: RuleContext<Theme>): CSSObject | undefined {
26+
if (isCSSMathFn(h.bracket(match[1])))
27+
return handleWidth(match, ctx)
28+
return colorResolver('outline-color', 'outline-color', 'borderColor')(match, ctx) as CSSObject | undefined
29+
}
30+
2131
export const appearance: Rule[] = [
2232
['appearance-none', {
2333
'-webkit-appearance': 'none',

packages/preset-mini/src/_rules/border.ts

Lines changed: 20 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,11 @@ export const borderStyles = ['solid', 'dashed', 'dotted', 'double', 'hidden', 'n
77

88
export const borders: Rule[] = [
99
// compound
10-
[/^(?:border|b)()(?:-(.+))?$/, handlerBorder, { autocomplete: '(border|b)-<directions>' }],
11-
[/^(?:border|b)-([xy])(?:-(.+))?$/, handlerBorder],
12-
[/^(?:border|b)-([rltbse])(?:-(.+))?$/, handlerBorder],
13-
[/^(?:border|b)-(block|inline)(?:-(.+))?$/, handlerBorder],
14-
[/^(?:border|b)-([bi][se])(?:-(.+))?$/, handlerBorder],
10+
[/^(?:border|b)()(?:-(.+))?$/, handlerBorderSize, { autocomplete: '(border|b)-<directions>' }],
11+
[/^(?:border|b)-([xy])(?:-(.+))?$/, handlerBorderSize],
12+
[/^(?:border|b)-([rltbse])(?:-(.+))?$/, handlerBorderSize],
13+
[/^(?:border|b)-(block|inline)(?:-(.+))?$/, handlerBorderSize],
14+
[/^(?:border|b)-([bi][se])(?:-(.+))?$/, handlerBorderSize],
1515

1616
// size
1717
[/^(?:border|b)-()(?:width|size)-(.+)$/, handlerBorderSize, { autocomplete: ['(border|b)-<num>', '(border|b)-<directions>-<num>'] }],
@@ -21,11 +21,11 @@ export const borders: Rule[] = [
2121
[/^(?:border|b)-([bi][se])-(?:width|size)-(.+)$/, handlerBorderSize],
2222

2323
// colors
24-
[/^(?:border|b)-()(?:color-)?(.+)$/, handlerBorderColor, { autocomplete: ['(border|b)-$colors', '(border|b)-<directions>-$colors'] }],
25-
[/^(?:border|b)-([xy])-(?:color-)?(.+)$/, handlerBorderColor],
26-
[/^(?:border|b)-([rltbse])-(?:color-)?(.+)$/, handlerBorderColor],
27-
[/^(?:border|b)-(block|inline)-(?:color-)?(.+)$/, handlerBorderColor],
28-
[/^(?:border|b)-([bi][se])-(?:color-)?(.+)$/, handlerBorderColor],
24+
[/^(?:border|b)-()(?:color-)?(.+)$/, handlerBorderColorOrSize, { autocomplete: ['(border|b)-$colors', '(border|b)-<directions>-$colors'] }],
25+
[/^(?:border|b)-([xy])-(?:color-)?(.+)$/, handlerBorderColorOrSize],
26+
[/^(?:border|b)-([rltbse])-(?:color-)?(.+)$/, handlerBorderColorOrSize],
27+
[/^(?:border|b)-(block|inline)-(?:color-)?(.+)$/, handlerBorderColorOrSize],
28+
[/^(?:border|b)-([bi][se])-(?:color-)?(.+)$/, handlerBorderColorOrSize],
2929

3030
// opacity
3131
[/^(?:border|b)-()op(?:acity)?-?(.+)$/, handlerBorderOpacity, { autocomplete: '(border|b)-(op|opacity)-<percent>' }],
@@ -80,35 +80,29 @@ function borderColorResolver(direction: string) {
8080
}
8181
}
8282
else if (color) {
83-
if (isCSSMathFn(color)) {
84-
return {
85-
'border-width': color,
86-
}
87-
}
88-
8983
return {
9084
[`border${direction}-color`]: colorToString(color, alpha),
9185
}
9286
}
9387
}
9488
}
9589

96-
function handlerBorder(m: string[], ctx: RuleContext): CSSEntries | undefined {
97-
return handlerBorderSize(m, ctx)
98-
}
99-
10090
function handlerBorderSize([, a = '', b]: string[], { theme }: RuleContext<Theme>): CSSEntries | undefined {
10191
const v = theme.lineWidth?.[b || 'DEFAULT'] ?? h.bracket.cssvar.global.px(b || '1')
10292
if (a in directionMap && v != null)
10393
return directionMap[a].map(i => [`border${i}-width`, v])
10494
}
10595

106-
function handlerBorderColor([, a = '', c]: string[], { theme }: RuleContext<Theme>): CSSObject | undefined {
107-
if (a in directionMap && hasParseableColor(c, theme, 'borderColor')) {
108-
return Object.assign(
109-
{},
110-
...directionMap[a].map(i => borderColorResolver(i)(['', c], theme)),
111-
)
96+
function handlerBorderColorOrSize([, a = '', b]: string[], ctx: RuleContext<Theme>): CSSEntries | undefined {
97+
if (a in directionMap) {
98+
if (isCSSMathFn(h.bracket(b)))
99+
return handlerBorderSize(['', a, b], ctx)
100+
if (hasParseableColor(b, ctx.theme, 'borderColor')) {
101+
return Object.assign(
102+
{},
103+
...directionMap[a].map(i => borderColorResolver(i)(['', b], ctx.theme)),
104+
)
105+
}
112106
}
113107
}
114108

packages/preset-mini/src/_rules/color.ts

Lines changed: 1 addition & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import type { Rule } from '@unocss/core'
2-
import { colorResolver, globalKeywords, h, isSize } from '../utils'
3-
import { numberWithUnitRE } from '../_utils/handlers/regex'
2+
import { colorResolver, h, isSize } from '../utils'
43

54
/**
65
* @example op10 op-30 opacity-100
@@ -9,17 +8,6 @@ export const opacity: Rule[] = [
98
[/^op(?:acity)?-?(.+)$/, ([, d]) => ({ opacity: h.bracket.percent.cssvar(d) })],
109
]
1110

12-
/**
13-
* @example c-red color-red5 text-red-300
14-
*/
15-
export const textColors: Rule[] = [
16-
[/^(?:color|c)-(.+)$/, colorResolver('color', 'text', 'textColor'), { autocomplete: '(color|c)-$colors' }],
17-
// auto detection and fallback to font-size if the content looks like a size
18-
[/^text-(.+)$/, colorResolver('color', 'text', 'textColor', css => !css.color?.toString().match(numberWithUnitRE)), { autocomplete: 'text-$colors' }],
19-
[/^(?:text|color|c)-(.+)$/, ([, v]) => globalKeywords.includes(v) ? { color: v } : undefined, { autocomplete: `(text|color|c)-(${globalKeywords.join('|')})` }],
20-
[/^(?:text|color|c)-op(?:acity)?-?(.+)$/, ([, opacity]) => ({ '--un-text-opacity': h.bracket.percent.cssvar(opacity) }), { autocomplete: '(text|color|c)-(op|opacity)-<percent>' }],
21-
]
22-
2311
const bgUrlRE = /^\[url\(.+\)\]$/
2412
const bgLengthRE = /^\[length:.+\]$/
2513
const bgPositionRE = /^\[position:.+\]$/
Lines changed: 21 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,18 @@
1-
import type { CSSObject, Rule } from '@unocss/core'
1+
import type { CSSObject, Rule, RuleContext } from '@unocss/core'
22
import type { Theme } from '../theme'
3-
import { colorResolver, globalKeywords, h } from '../utils'
3+
import { colorResolver, globalKeywords, h, isCSSMathFn } from '../utils'
44

55
const decorationStyles = ['solid', 'double', 'dotted', 'dashed', 'wavy', ...globalKeywords]
66

77
export const textDecorations: Rule<Theme>[] = [
88
[/^(?:decoration-)?(underline|overline|line-through)$/, ([, s]) => ({ 'text-decoration-line': s }), { autocomplete: 'decoration-(underline|overline|line-through)' }],
99

1010
// size
11-
[/^(?:underline|decoration)-(?:size-)?(.+)$/, ([, s], { theme }) => ({ 'text-decoration-thickness': theme.lineWidth?.[s] ?? h.bracket.cssvar.global.px(s) }), { autocomplete: '(underline|decoration)-<num>' }],
11+
[/^(?:underline|decoration)-(?:size-)?(.+)$/, handleWidth, { autocomplete: '(underline|decoration)-<num>' }],
1212
[/^(?:underline|decoration)-(auto|from-font)$/, ([, s]) => ({ 'text-decoration-thickness': s }), { autocomplete: '(underline|decoration)-(auto|from-font)' }],
1313

1414
// colors
15-
[/^(?:underline|decoration)-(.+)$/, (match, ctx) => {
16-
const result = colorResolver('text-decoration-color', 'line', 'borderColor')(match, ctx) as CSSObject | undefined
17-
if (result) {
18-
return {
19-
'-webkit-text-decoration-color': result['text-decoration-color'],
20-
...result,
21-
}
22-
}
23-
}, { autocomplete: '(underline|decoration)-$colors' }],
15+
[/^(?:underline|decoration)-(.+)$/, handleColorOrWidth, { autocomplete: '(underline|decoration)-$colors' }],
2416
[/^(?:underline|decoration)-op(?:acity)?-?(.+)$/, ([, opacity]) => ({ '--un-line-opacity': h.bracket.percent.cssvar(opacity) }), { autocomplete: '(underline|decoration)-(op|opacity)-<percent>' }],
2517

2618
// offset
@@ -32,3 +24,20 @@ export const textDecorations: Rule<Theme>[] = [
3224
['no-underline', { 'text-decoration': 'none' }],
3325
['decoration-none', { 'text-decoration': 'none' }],
3426
]
27+
28+
function handleWidth([, b]: string[], { theme }: RuleContext<Theme>): CSSObject {
29+
return { 'text-decoration-thickness': theme.lineWidth?.[b] ?? h.bracket.cssvar.global.px(b) }
30+
}
31+
32+
function handleColorOrWidth(match: RegExpMatchArray, ctx: RuleContext<Theme>): CSSObject | undefined {
33+
if (isCSSMathFn(h.bracket(match[1])))
34+
return handleWidth(match, ctx)
35+
36+
const result = colorResolver('text-decoration-color', 'line', 'borderColor')(match, ctx) as CSSObject | undefined
37+
if (result) {
38+
return {
39+
'-webkit-text-decoration-color': result['text-decoration-color'],
40+
...result,
41+
}
42+
}
43+
}

packages/preset-mini/src/_rules/default.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import type { Rule } from '@unocss/core'
22
import type { Theme } from '../theme'
33
import { transitions } from './transition'
44
import { borders } from './border'
5-
import { bgColors, colorScheme, opacity, textColors } from './color'
5+
import { bgColors, colorScheme, opacity } from './color'
66
import { flex } from './flex'
77
import { fonts, tabSizes, textIndents, textShadows, textStrokes } from './typography'
88
import { gaps } from './gap'
@@ -45,7 +45,6 @@ export const rules: Rule<Theme>[] = [
4545
textShadows,
4646
textTransforms,
4747
textAligns,
48-
textColors,
4948
fontStyles,
5049
fontSmoothings,
5150
boxShadows,

packages/preset-mini/src/_rules/ring.ts

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
import type { Rule } from '@unocss/core'
1+
import type { CSSObject, Rule, RuleContext } from '@unocss/core'
22
import type { Theme } from '../theme'
3-
import { colorResolver, h } from '../utils'
3+
import { colorResolver, h, isCSSMathFn } from '../utils'
44
import { varEmpty } from './static'
55

66
export const ringBase = {
@@ -13,7 +13,7 @@ export const ringBase = {
1313
}
1414

1515
export const rings: Rule<Theme>[] = [
16-
// size
16+
// ring
1717
[/^ring(?:-(.+))?$/, ([, d], { theme }) => {
1818
const value = theme.ringWidth?.[d || 'DEFAULT'] ?? h.px(d || '1')
1919
if (value) {
@@ -25,14 +25,16 @@ export const rings: Rule<Theme>[] = [
2525
}
2626
}
2727
}, { autocomplete: 'ring-$ringWidth' }],
28-
[/^ring-(?:width-|size-)(.+)$/, ([, d], { theme }) => ({ '--un-ring-width': theme.lineWidth?.[d] ?? h.bracket.cssvar.px(d) }), { autocomplete: 'ring-(width|size)-$lineWidth' }],
28+
29+
// size
30+
[/^ring-(?:width-|size-)(.+)$/, handleWidth, { autocomplete: 'ring-(width|size)-$lineWidth' }],
2931

3032
// offset size
3133
['ring-offset', { '--un-ring-offset-width': '1px' }],
3234
[/^ring-offset-(?:width-|size-)?(.+)$/, ([, d], { theme }) => ({ '--un-ring-offset-width': theme.lineWidth?.[d] ?? h.bracket.cssvar.px(d) }), { autocomplete: 'ring-offset-(width|size)-$lineWidth' }],
3335

3436
// colors
35-
[/^ring-(.+)$/, colorResolver('--un-ring-color', 'ring', 'borderColor'), { autocomplete: 'ring-$colors' }],
37+
[/^ring-(.+)$/, handleColorOrWidth, { autocomplete: 'ring-$colors' }],
3638
[/^ring-op(?:acity)?-?(.+)$/, ([, opacity]) => ({ '--un-ring-opacity': h.bracket.percent.cssvar(opacity) }), { autocomplete: 'ring-(op|opacity)-<percent>' }],
3739

3840
// offset color
@@ -42,3 +44,13 @@ export const rings: Rule<Theme>[] = [
4244
// style
4345
['ring-inset', { '--un-ring-inset': 'inset' }],
4446
]
47+
48+
function handleWidth([, b]: string[], { theme }: RuleContext<Theme>): CSSObject {
49+
return { '--un-ring-width': theme.ringWidth?.[b] ?? h.bracket.cssvar.px(b) }
50+
}
51+
52+
function handleColorOrWidth(match: RegExpMatchArray, ctx: RuleContext<Theme>): CSSObject | undefined {
53+
if (isCSSMathFn(h.bracket(match[1])))
54+
return handleWidth(match, ctx)
55+
return colorResolver('--un-ring-color', 'ring', 'borderColor')(match, ctx) as CSSObject | undefined
56+
}

packages/preset-mini/src/_rules/svg.ts

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
import type { Rule } from '@unocss/core'
1+
import type { CSSObject, Rule, RuleContext } from '@unocss/core'
22
import type { Theme } from '../theme'
3-
import { colorResolver, h } from '../utils'
3+
import { colorResolver, h, isCSSMathFn } from '../utils'
44

55
export const svgUtilities: Rule<Theme>[] = [
66
// fills
@@ -9,14 +9,14 @@ export const svgUtilities: Rule<Theme>[] = [
99
['fill-none', { fill: 'none' }],
1010

1111
// stroke size
12-
[/^stroke-(?:width-|size-)?(.+)$/, ([, s], { theme }) => ({ 'stroke-width': theme.lineWidth?.[s] ?? h.bracket.cssvar.fraction.px.number(s) }), { autocomplete: ['stroke-width-$lineWidth', 'stroke-size-$lineWidth'] }],
12+
[/^stroke-(?:width-|size-)?(.+)$/, handleWidth, { autocomplete: ['stroke-width-$lineWidth', 'stroke-size-$lineWidth'] }],
1313

1414
// stroke dash
1515
[/^stroke-dash-(.+)$/, ([, s]) => ({ 'stroke-dasharray': h.bracket.cssvar.number(s) }), { autocomplete: 'stroke-dash-<num>' }],
1616
[/^stroke-offset-(.+)$/, ([, s], { theme }) => ({ 'stroke-dashoffset': theme.lineWidth?.[s] ?? h.bracket.cssvar.px.numberWithUnit(s) }), { autocomplete: 'stroke-offset-$lineWidth' }],
1717

1818
// stroke colors
19-
[/^stroke-(.+)$/, colorResolver('stroke', 'stroke', 'borderColor'), { autocomplete: 'stroke-$colors' }],
19+
[/^stroke-(.+)$/, handleColorOrWidth, { autocomplete: 'stroke-$colors' }],
2020
[/^stroke-op(?:acity)?-?(.+)$/, ([, opacity]) => ({ '--un-stroke-opacity': h.bracket.percent.cssvar(opacity) }), { autocomplete: 'stroke-(op|opacity)-<percent>' }],
2121

2222
// line cap
@@ -34,3 +34,13 @@ export const svgUtilities: Rule<Theme>[] = [
3434
// none
3535
['stroke-none', { stroke: 'none' }],
3636
]
37+
38+
function handleWidth([, b]: string[], { theme }: RuleContext<Theme>): CSSObject {
39+
return { 'stroke-width': theme.lineWidth?.[b] ?? h.bracket.cssvar.fraction.px.number(b) }
40+
}
41+
42+
function handleColorOrWidth(match: RegExpMatchArray, ctx: RuleContext<Theme>): CSSObject | undefined {
43+
if (isCSSMathFn(h.bracket(match[1])))
44+
return handleWidth(match, ctx)
45+
return colorResolver('stroke', 'stroke', 'borderColor')(match, ctx) as CSSObject | undefined
46+
}

0 commit comments

Comments
 (0)