Skip to content

Commit a63cf59

Browse files
authored
feat(preset-mini): add font-size/leading shorthand (#2059)
1 parent 448798d commit a63cf59

File tree

4 files changed

+48
-16
lines changed

4 files changed

+48
-16
lines changed

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

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import type { Rule } from '@unocss/core'
22
import { toArray } from '@unocss/core'
33
import type { Theme } from '../theme'
4-
import { colorResolver, colorableShadows, handler as h } from '../utils'
4+
import { colorResolver, colorableShadows, handler as h, splitShorthand } from '../utils'
55

66
const weightMap: Record<string, string> = {
77
thin: '100',
@@ -16,6 +16,10 @@ const weightMap: Record<string, string> = {
1616
// int[0, 900] -> int
1717
}
1818

19+
function handleLineHeight(s: string, theme: Theme) {
20+
return theme.lineHeight?.[s] || h.bracket.cssvar.global.rem(s)
21+
}
22+
1923
export const fonts: Rule<Theme>[] = [
2024
// family
2125
[
@@ -28,12 +32,22 @@ export const fonts: Rule<Theme>[] = [
2832
[
2933
/^text-(.+)$/,
3034
([, s = 'base'], { theme }) => {
31-
const themed = toArray(theme.fontSize?.[s])
32-
if (themed?.[0]) {
33-
const [size, height = '1'] = themed
35+
const [size, leading] = splitShorthand(s, 'length')
36+
const sizePairs = toArray(theme.fontSize?.[size])
37+
const lineHeight = leading ? handleLineHeight(leading, theme) : undefined
38+
39+
if (sizePairs?.[0]) {
40+
const [fontSize, height] = sizePairs
41+
return {
42+
'font-size': fontSize,
43+
'line-height': lineHeight ?? height ?? '1',
44+
}
45+
}
46+
47+
if (lineHeight) {
3448
return {
35-
'font-size': size,
36-
'line-height': height,
49+
'font-size': h.bracketOfLength.rem(size),
50+
'line-height': lineHeight,
3751
}
3852
}
3953

@@ -58,7 +72,7 @@ export const fonts: Rule<Theme>[] = [
5872
// leadings
5973
[
6074
/^(?:font-)?(?:leading|lh)-(.+)$/,
61-
([, s], { theme }) => ({ 'line-height': theme.lineHeight?.[s] || h.bracket.cssvar.global.rem(s) }),
75+
([, s], { theme }) => ({ 'line-height': handleLineHeight(s, theme) }),
6276
{ autocomplete: '(leading|lh)-$lineHeight' },
6377
],
6478

packages/preset-mini/src/_utils/utilities.ts

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,22 @@ function getThemeColor(theme: Theme, colors: string[]) {
4646
return obj
4747
}
4848

49+
/**
50+
* Split utility shorthand delimited by / or :
51+
*/
52+
export function splitShorthand(body: string, type: string) {
53+
const split = body.split(/(?:\/|:)/)
54+
55+
if (split[0] === `[${type}`) {
56+
return [
57+
split.slice(0, 2).join(':'),
58+
split[2],
59+
]
60+
}
61+
62+
return split
63+
}
64+
4965
/**
5066
* Parse color string into {@link ParsedColorValue} (if possible). Color value will first be matched to theme object before parsing.
5167
* See also color.tests.ts for more examples.
@@ -61,15 +77,7 @@ function getThemeColor(theme: Theme, colors: string[]) {
6177
* @return {ParsedColorValue|undefined} {@link ParsedColorValue} object if string is parseable.
6278
*/
6379
export function parseColor(body: string, theme: Theme): ParsedColorValue | undefined {
64-
const split = body.split(/(?:\/|:)/)
65-
let main, opacity
66-
if (split[0] === '[color') {
67-
main = split.slice(0, 2).join(':')
68-
opacity = split[2]
69-
}
70-
else {
71-
[main, opacity] = split
72-
}
80+
const [main, opacity] = splitShorthand(body, 'color')
7381

7482
const colors = main
7583
.replace(/([a-z])([0-9])/g, '$1-$2')

test/__snapshots__/preset-mini.test.ts.snap

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -322,14 +322,19 @@ unocss .scope-\\\\[unocss\\\\]\\\\:block{display:block;}
322322
.peer:not(:placeholder-shown)~.peer-not-placeholder-shown\\\\:text-3xl{font-size:1.875rem;line-height:2.25rem;}
323323
.peer:not(:placeholder-shown)~.peer-not-placeholder-shown\\\\:text-2xl{font-size:1.5rem;line-height:2rem;}
324324
.text-\\\\[100px\\\\]{font-size:100px;}
325+
.text-\\\\[11px\\\\]\\\\/4{font-size:11px;line-height:1rem;}
326+
.text-\\\\[12px\\\\]\\\\/\\\\[13px\\\\]{font-size:12px;line-height:13px;}
325327
.text-\\\\[2em\\\\],
326328
.text-\\\\[length\\\\:2em\\\\],
327329
.text-2em,
328330
.text-size-\\\\[2em\\\\]{font-size:2em;}
329331
.text-\\\\[length\\\\:calc\\\\(1em-1px\\\\)\\\\]{font-size:calc(1em - 1px);}
330332
.text-\\\\[length\\\\:var\\\\(--size\\\\)\\\\]{font-size:var(--size);}
333+
.text-\\\\[length\\\\:var\\\\(--size\\\\)\\\\]\\\\:\\\\$leading{font-size:var(--size);line-height:var(--leading);}
331334
.text-base{font-size:1rem;line-height:1.5rem;}
332335
.text-lg{font-size:1.125rem;line-height:1.75rem;}
336+
.text-sm\\\\/\\\\[10px\\\\]{font-size:0.875rem;line-height:10px;}
337+
.text-sm\\\\/3{font-size:0.875rem;line-height:0.75rem;}
333338
.text-size-\\\\$variable{font-size:var(--variable);}
334339
.text-size-unset{font-size:unset;}
335340
.as-parent .group .group-\\\\[\\\\.as-parent_\\\\&\\\\]\\\\:font-13{font-weight:13;}

test/assets/preset-mini-targets.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -205,6 +205,11 @@ export const presetMiniTargets: string[] = [
205205
'text-[length:calc(1em-1px)]',
206206
'text-[color:var(--color)]',
207207
'text-[color:var(--color-x)]:[trick]',
208+
'text-sm/3',
209+
'text-sm/[10px]',
210+
'text-[11px]/4',
211+
'text-[12px]/[13px]',
212+
'text-[length:var(--size)]:$leading',
208213

209214
// color - bg
210215
'bg-[#153]/10',

0 commit comments

Comments
 (0)