Skip to content

Commit

Permalink
feat(preset-mini)!: prioritize length instead of color (#3353)
Browse files Browse the repository at this point in the history
  • Loading branch information
chu121su12 committed Nov 30, 2023
1 parent 9f2bd6d commit 235c377
Show file tree
Hide file tree
Showing 25 changed files with 293 additions and 246 deletions.
2 changes: 1 addition & 1 deletion docs/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,6 @@
"@iconify-json/vscode-icons": "^1.1.31",
"ofetch": "^1.3.3",
"unocss": "workspace:*",
"vitepress": "1.0.0-rc.29"
"vitepress": "1.0.0-rc.31"
}
}
18 changes: 14 additions & 4 deletions packages/preset-mini/src/_rules/behaviors.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import type { Rule } from '@unocss/core'
import type { CSSObject, Rule, RuleContext } from '@unocss/core'
import type { Theme } from '../theme'
import { colorResolver, globalKeywords, h } from '../utils'
import { colorResolver, globalKeywords, h, isCSSMathFn } from '../utils'

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

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

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

function handleWidth([, b]: string[], { theme }: RuleContext<Theme>): CSSObject {
return { 'outline-width': theme.lineWidth?.[b] ?? h.bracket.cssvar.global.px(b) }
}

function handleColorOrWidth(match: RegExpMatchArray, ctx: RuleContext<Theme>): CSSObject | undefined {
if (isCSSMathFn(h.bracket(match[1])))
return handleWidth(match, ctx)
return colorResolver('outline-color', 'outline-color', 'borderColor')(match, ctx) as CSSObject | undefined
}

export const appearance: Rule[] = [
['appearance-none', {
'-webkit-appearance': 'none',
Expand Down
46 changes: 20 additions & 26 deletions packages/preset-mini/src/_rules/border.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,11 @@ export const borderStyles = ['solid', 'dashed', 'dotted', 'double', 'hidden', 'n

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

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

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

// opacity
[/^(?:border|b)-()op(?:acity)?-?(.+)$/, handlerBorderOpacity, { autocomplete: '(border|b)-(op|opacity)-<percent>' }],
Expand Down Expand Up @@ -80,35 +80,29 @@ function borderColorResolver(direction: string) {
}
}
else if (color) {
if (isCSSMathFn(color)) {
return {
'border-width': color,
}
}

return {
[`border${direction}-color`]: colorToString(color, alpha),
}
}
}
}

function handlerBorder(m: string[], ctx: RuleContext): CSSEntries | undefined {
return handlerBorderSize(m, ctx)
}

function handlerBorderSize([, a = '', b]: string[], { theme }: RuleContext<Theme>): CSSEntries | undefined {
const v = theme.lineWidth?.[b || 'DEFAULT'] ?? h.bracket.cssvar.global.px(b || '1')
if (a in directionMap && v != null)
return directionMap[a].map(i => [`border${i}-width`, v])
}

function handlerBorderColor([, a = '', c]: string[], { theme }: RuleContext<Theme>): CSSObject | undefined {
if (a in directionMap && hasParseableColor(c, theme, 'borderColor')) {
return Object.assign(
{},
...directionMap[a].map(i => borderColorResolver(i)(['', c], theme)),
)
function handlerBorderColorOrSize([, a = '', b]: string[], ctx: RuleContext<Theme>): CSSEntries | undefined {
if (a in directionMap) {
if (isCSSMathFn(h.bracket(b)))
return handlerBorderSize(['', a, b], ctx)
if (hasParseableColor(b, ctx.theme, 'borderColor')) {
return Object.assign(
{},
...directionMap[a].map(i => borderColorResolver(i)(['', b], ctx.theme)),
)
}
}
}

Expand Down
14 changes: 1 addition & 13 deletions packages/preset-mini/src/_rules/color.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import type { Rule } from '@unocss/core'
import { colorResolver, globalKeywords, h, isSize } from '../utils'
import { numberWithUnitRE } from '../_utils/handlers/regex'
import { colorResolver, h, isSize } from '../utils'

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

/**
* @example c-red color-red5 text-red-300
*/
export const textColors: Rule[] = [
[/^(?:color|c)-(.+)$/, colorResolver('color', 'text', 'textColor'), { autocomplete: '(color|c)-$colors' }],
// auto detection and fallback to font-size if the content looks like a size
[/^text-(.+)$/, colorResolver('color', 'text', 'textColor', css => !css.color?.toString().match(numberWithUnitRE)), { autocomplete: 'text-$colors' }],
[/^(?:text|color|c)-(.+)$/, ([, v]) => globalKeywords.includes(v) ? { color: v } : undefined, { autocomplete: `(text|color|c)-(${globalKeywords.join('|')})` }],
[/^(?:text|color|c)-op(?:acity)?-?(.+)$/, ([, opacity]) => ({ '--un-text-opacity': h.bracket.percent.cssvar(opacity) }), { autocomplete: '(text|color|c)-(op|opacity)-<percent>' }],
]

const bgUrlRE = /^\[url\(.+\)\]$/
const bgLengthRE = /^\[length:.+\]$/
const bgPositionRE = /^\[position:.+\]$/
Expand Down
33 changes: 21 additions & 12 deletions packages/preset-mini/src/_rules/decoration.ts
Original file line number Diff line number Diff line change
@@ -1,26 +1,18 @@
import type { CSSObject, Rule } from '@unocss/core'
import type { CSSObject, Rule, RuleContext } from '@unocss/core'
import type { Theme } from '../theme'
import { colorResolver, globalKeywords, h } from '../utils'
import { colorResolver, globalKeywords, h, isCSSMathFn } from '../utils'

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

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

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

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

// offset
Expand All @@ -32,3 +24,20 @@ export const textDecorations: Rule<Theme>[] = [
['no-underline', { 'text-decoration': 'none' }],
['decoration-none', { 'text-decoration': 'none' }],
]

function handleWidth([, b]: string[], { theme }: RuleContext<Theme>): CSSObject {
return { 'text-decoration-thickness': theme.lineWidth?.[b] ?? h.bracket.cssvar.global.px(b) }
}

function handleColorOrWidth(match: RegExpMatchArray, ctx: RuleContext<Theme>): CSSObject | undefined {
if (isCSSMathFn(h.bracket(match[1])))
return handleWidth(match, ctx)

const result = colorResolver('text-decoration-color', 'line', 'borderColor')(match, ctx) as CSSObject | undefined
if (result) {
return {
'-webkit-text-decoration-color': result['text-decoration-color'],
...result,
}
}
}
3 changes: 1 addition & 2 deletions packages/preset-mini/src/_rules/default.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import type { Rule } from '@unocss/core'
import type { Theme } from '../theme'
import { transitions } from './transition'
import { borders } from './border'
import { bgColors, colorScheme, opacity, textColors } from './color'
import { bgColors, colorScheme, opacity } from './color'
import { flex } from './flex'
import { fonts, tabSizes, textIndents, textShadows, textStrokes } from './typography'
import { gaps } from './gap'
Expand Down Expand Up @@ -45,7 +45,6 @@ export const rules: Rule<Theme>[] = [
textShadows,
textTransforms,
textAligns,
textColors,
fontStyles,
fontSmoothings,
boxShadows,
Expand Down
22 changes: 17 additions & 5 deletions packages/preset-mini/src/_rules/ring.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import type { Rule } from '@unocss/core'
import type { CSSObject, Rule, RuleContext } from '@unocss/core'
import type { Theme } from '../theme'
import { colorResolver, h } from '../utils'
import { colorResolver, h, isCSSMathFn } from '../utils'
import { varEmpty } from './static'

export const ringBase = {
Expand All @@ -13,7 +13,7 @@ export const ringBase = {
}

export const rings: Rule<Theme>[] = [
// size
// ring
[/^ring(?:-(.+))?$/, ([, d], { theme }) => {
const value = theme.ringWidth?.[d || 'DEFAULT'] ?? h.px(d || '1')
if (value) {
Expand All @@ -25,14 +25,16 @@ export const rings: Rule<Theme>[] = [
}
}
}, { autocomplete: 'ring-$ringWidth' }],
[/^ring-(?:width-|size-)(.+)$/, ([, d], { theme }) => ({ '--un-ring-width': theme.lineWidth?.[d] ?? h.bracket.cssvar.px(d) }), { autocomplete: 'ring-(width|size)-$lineWidth' }],

// size
[/^ring-(?:width-|size-)(.+)$/, handleWidth, { autocomplete: 'ring-(width|size)-$lineWidth' }],

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

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

// offset color
Expand All @@ -42,3 +44,13 @@ export const rings: Rule<Theme>[] = [
// style
['ring-inset', { '--un-ring-inset': 'inset' }],
]

function handleWidth([, b]: string[], { theme }: RuleContext<Theme>): CSSObject {
return { '--un-ring-width': theme.ringWidth?.[b] ?? h.bracket.cssvar.px(b) }
}

function handleColorOrWidth(match: RegExpMatchArray, ctx: RuleContext<Theme>): CSSObject | undefined {
if (isCSSMathFn(h.bracket(match[1])))
return handleWidth(match, ctx)
return colorResolver('--un-ring-color', 'ring', 'borderColor')(match, ctx) as CSSObject | undefined
}
18 changes: 14 additions & 4 deletions packages/preset-mini/src/_rules/svg.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import type { Rule } from '@unocss/core'
import type { CSSObject, Rule, RuleContext } from '@unocss/core'
import type { Theme } from '../theme'
import { colorResolver, h } from '../utils'
import { colorResolver, h, isCSSMathFn } from '../utils'

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

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

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

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

// line cap
Expand All @@ -34,3 +34,13 @@ export const svgUtilities: Rule<Theme>[] = [
// none
['stroke-none', { stroke: 'none' }],
]

function handleWidth([, b]: string[], { theme }: RuleContext<Theme>): CSSObject {
return { 'stroke-width': theme.lineWidth?.[b] ?? h.bracket.cssvar.fraction.px.number(b) }
}

function handleColorOrWidth(match: RegExpMatchArray, ctx: RuleContext<Theme>): CSSObject | undefined {
if (isCSSMathFn(h.bracket(match[1])))
return handleWidth(match, ctx)
return colorResolver('stroke', 'stroke', 'borderColor')(match, ctx) as CSSObject | undefined
}

0 comments on commit 235c377

Please sign in to comment.