diff --git a/packages/preset-mini/src/_rules/typography.ts b/packages/preset-mini/src/_rules/typography.ts index e2e2db0685..6995e6eb4d 100644 --- a/packages/preset-mini/src/_rules/typography.ts +++ b/packages/preset-mini/src/_rules/typography.ts @@ -1,7 +1,7 @@ import type { Rule } from '@unocss/core' import { toArray } from '@unocss/core' import type { Theme } from '../theme' -import { colorResolver, colorableShadows, handler as h } from '../utils' +import { colorResolver, colorableShadows, handler as h, splitShorthand } from '../utils' const weightMap: Record = { thin: '100', @@ -16,6 +16,10 @@ const weightMap: Record = { // int[0, 900] -> int } +function handleLineHeight(s: string, theme: Theme) { + return theme.lineHeight?.[s] || h.bracket.cssvar.global.rem(s) +} + export const fonts: Rule[] = [ // family [ @@ -28,12 +32,22 @@ export const fonts: Rule[] = [ [ /^text-(.+)$/, ([, s = 'base'], { theme }) => { - const themed = toArray(theme.fontSize?.[s]) - if (themed?.[0]) { - const [size, height = '1'] = themed + const [size, leading] = splitShorthand(s, 'length') + const sizePairs = toArray(theme.fontSize?.[size]) + const lineHeight = leading ? handleLineHeight(leading, theme) : undefined + + if (sizePairs?.[0]) { + const [fontSize, height] = sizePairs + return { + 'font-size': fontSize, + 'line-height': lineHeight ?? height ?? '1', + } + } + + if (lineHeight) { return { - 'font-size': size, - 'line-height': height, + 'font-size': h.bracketOfLength.rem(size), + 'line-height': lineHeight, } } @@ -58,7 +72,7 @@ export const fonts: Rule[] = [ // leadings [ /^(?:font-)?(?:leading|lh)-(.+)$/, - ([, s], { theme }) => ({ 'line-height': theme.lineHeight?.[s] || h.bracket.cssvar.global.rem(s) }), + ([, s], { theme }) => ({ 'line-height': handleLineHeight(s, theme) }), { autocomplete: '(leading|lh)-$lineHeight' }, ], diff --git a/packages/preset-mini/src/_utils/utilities.ts b/packages/preset-mini/src/_utils/utilities.ts index fe31ef5521..e65803672c 100644 --- a/packages/preset-mini/src/_utils/utilities.ts +++ b/packages/preset-mini/src/_utils/utilities.ts @@ -46,6 +46,22 @@ function getThemeColor(theme: Theme, colors: string[]) { return obj } +/** + * Split utility shorthand delimited by / or : + */ +export function splitShorthand(body: string, type: string) { + const split = body.split(/(?:\/|:)/) + + if (split[0] === `[${type}`) { + return [ + split.slice(0, 2).join(':'), + split[2], + ] + } + + return split +} + /** * Parse color string into {@link ParsedColorValue} (if possible). Color value will first be matched to theme object before parsing. * See also color.tests.ts for more examples. @@ -61,15 +77,7 @@ function getThemeColor(theme: Theme, colors: string[]) { * @return {ParsedColorValue|undefined} {@link ParsedColorValue} object if string is parseable. */ export function parseColor(body: string, theme: Theme): ParsedColorValue | undefined { - const split = body.split(/(?:\/|:)/) - let main, opacity - if (split[0] === '[color') { - main = split.slice(0, 2).join(':') - opacity = split[2] - } - else { - [main, opacity] = split - } + const [main, opacity] = splitShorthand(body, 'color') const colors = main .replace(/([a-z])([0-9])/g, '$1-$2') diff --git a/test/__snapshots__/preset-mini.test.ts.snap b/test/__snapshots__/preset-mini.test.ts.snap index d3aed38b0a..64f2e25b0e 100644 --- a/test/__snapshots__/preset-mini.test.ts.snap +++ b/test/__snapshots__/preset-mini.test.ts.snap @@ -322,14 +322,19 @@ unocss .scope-\\\\[unocss\\\\]\\\\:block{display:block;} .peer:not(:placeholder-shown)~.peer-not-placeholder-shown\\\\:text-3xl{font-size:1.875rem;line-height:2.25rem;} .peer:not(:placeholder-shown)~.peer-not-placeholder-shown\\\\:text-2xl{font-size:1.5rem;line-height:2rem;} .text-\\\\[100px\\\\]{font-size:100px;} +.text-\\\\[11px\\\\]\\\\/4{font-size:11px;line-height:1rem;} +.text-\\\\[12px\\\\]\\\\/\\\\[13px\\\\]{font-size:12px;line-height:13px;} .text-\\\\[2em\\\\], .text-\\\\[length\\\\:2em\\\\], .text-2em, .text-size-\\\\[2em\\\\]{font-size:2em;} .text-\\\\[length\\\\:calc\\\\(1em-1px\\\\)\\\\]{font-size:calc(1em - 1px);} .text-\\\\[length\\\\:var\\\\(--size\\\\)\\\\]{font-size:var(--size);} +.text-\\\\[length\\\\:var\\\\(--size\\\\)\\\\]\\\\:\\\\$leading{font-size:var(--size);line-height:var(--leading);} .text-base{font-size:1rem;line-height:1.5rem;} .text-lg{font-size:1.125rem;line-height:1.75rem;} +.text-sm\\\\/\\\\[10px\\\\]{font-size:0.875rem;line-height:10px;} +.text-sm\\\\/3{font-size:0.875rem;line-height:0.75rem;} .text-size-\\\\$variable{font-size:var(--variable);} .text-size-unset{font-size:unset;} .as-parent .group .group-\\\\[\\\\.as-parent_\\\\&\\\\]\\\\:font-13{font-weight:13;} diff --git a/test/assets/preset-mini-targets.ts b/test/assets/preset-mini-targets.ts index cdf5aa6178..22bfe107c1 100644 --- a/test/assets/preset-mini-targets.ts +++ b/test/assets/preset-mini-targets.ts @@ -205,6 +205,11 @@ export const presetMiniTargets: string[] = [ 'text-[length:calc(1em-1px)]', 'text-[color:var(--color)]', 'text-[color:var(--color-x)]:[trick]', + 'text-sm/3', + 'text-sm/[10px]', + 'text-[11px]/4', + 'text-[12px]/[13px]', + 'text-[length:var(--size)]:$leading', // color - bg 'bg-[#153]/10',