Skip to content

Commit 61870de

Browse files
committed
feat(theme): support toRem and convert
1 parent d34d16f commit 61870de

File tree

10 files changed

+135
-13
lines changed

10 files changed

+135
-13
lines changed

packages/varlet-ui/docs/browserAdaptation.en-US.md

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ module.exports = {
4343
}
4444
```
4545

46-
#### Theme Unit Adaptation
46+
#### Theme Unit Adaptation (Viewport)
4747

4848
Because the theme is mounted at runtime and is not affected by postcss, the component library provides a utility tool `Themes.toViewport` for adaptation. The theme returned by the function will use the `375px -> 100vmin` rule by default.
4949

@@ -68,6 +68,29 @@ const viewportTheme = Themes.toViewport(Themes.md3Dark, {
6868
})
6969
```
7070

71+
#### Theme Unit Adaptation (Rem)
72+
73+
Similar to the Viewport solution
74+
75+
```js
76+
import { Themes } from '@varlet/ui'
77+
78+
const remTheme = Themes.toRem(Themes.md3Dark)
79+
```
80+
81+
Or customize
82+
83+
```js
84+
import { Themes } from '@varlet/ui'
85+
86+
const viewportTheme = Themes.toRem(Themes.md3Dark, {
87+
// defaults 16
88+
rootFontSize: 32,
89+
// defaults 6
90+
unitPrecision: 4,
91+
})
92+
```
93+
7194
### Desktop Adaptation
7295

7396
Because component library interaction events are developed using `touch` events, `mouse` events on the desktop side are not supported.

packages/varlet-ui/docs/browserAdaptation.zh-CN.md

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ module.exports = {
4242
}
4343
```
4444

45-
#### 主题包单位适配
45+
#### 主题包单位适配 (Viewport)
4646

4747
因为主题包是运行时挂载的,不受 postcss 影响,组件库提供了实用工具 `Themes.toViewport` 进行适配,函数返回的主题将默认使用 `375px -> 100vmin` 的规则。
4848

@@ -67,6 +67,29 @@ const viewportTheme = Themes.toViewport(Themes.md3Dark, {
6767
})
6868
```
6969

70+
#### 主题包单位适配 (Rem)
71+
72+
`Viewport` 方案类似
73+
74+
```js
75+
import { Themes } from '@varlet/ui'
76+
77+
const remTheme = Themes.toRem(Themes.md3Dark)
78+
```
79+
80+
也支持自定义
81+
82+
```js
83+
import { Themes } from '@varlet/ui'
84+
85+
const viewportTheme = Themes.toRem(Themes.md3Dark, {
86+
// 默认值为 16
87+
rootFontSize: 32,
88+
// 默认值为 6
89+
unitPrecision: 4,
90+
})
91+
```
92+
7093
### 桌面端适配
7194

7295
由于组件库交互事件使用 `touch` 事件进行开发,不支持桌面端的 `mouse` 事件,

packages/varlet-ui/src/themes/__tests__/index.spec.js

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,3 +61,51 @@ test('toViewport', () => {
6161
'--g': 'calc(100% - 4vw)',
6262
})
6363
})
64+
65+
test('toRem', () => {
66+
expect(
67+
Themes.toRem({
68+
'--a': '30px',
69+
'--b': '30px -30px',
70+
'--c': '30px 30px 30px',
71+
'--d': '30px 30px 30px 30px',
72+
'--e': '10px',
73+
'--f': '10.55px',
74+
'--g': 'calc(100% - 30px)',
75+
}),
76+
).toStrictEqual({
77+
'--a': '1.875rem',
78+
'--b': '1.875rem -1.875rem',
79+
'--c': '1.875rem 1.875rem 1.875rem',
80+
'--d': '1.875rem 1.875rem 1.875rem 1.875rem',
81+
'--e': '0.625rem',
82+
'--f': '0.659375rem',
83+
'--g': 'calc(100% - 1.875rem)',
84+
})
85+
86+
expect(
87+
Themes.toRem(
88+
{
89+
'--a': '30px',
90+
'--b': '30px -30px',
91+
'--c': '30px 30px 30px',
92+
'--d': '30px 30px 30px 30px',
93+
'--e': '10px',
94+
'--f': '10.55px',
95+
'--g': 'calc(100% - 30px)',
96+
},
97+
{
98+
rootFontSize: 30,
99+
unitPrecision: 4,
100+
},
101+
),
102+
).toStrictEqual({
103+
'--a': '1rem',
104+
'--b': '1rem -1rem',
105+
'--c': '1rem 1rem 1rem',
106+
'--d': '1rem 1rem 1rem 1rem',
107+
'--e': '0.3333rem',
108+
'--f': '0.3517rem',
109+
'--g': 'calc(100% - 1rem)',
110+
})
111+
})
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
import { Themes } from '../../types'
2+
3+
declare const convert: Themes['convert']
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import { StyleVars } from '../style-provider'
2+
3+
export function convert(theme: StyleVars, converter: (value: number) => string) {
4+
return Object.entries(theme).reduce((target, [key, value]) => {
5+
target[key] = value.includes('px') ? value.replace(/(\d+(\.\d+)?)px/g, (_, p1) => converter(p1)) : value
6+
7+
return target
8+
}, {} as StyleVars)
9+
}

packages/varlet-ui/src/themes/index.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
1+
import { convert } from './convert'
12
import dark from './dark'
23
import md3Dark from './md3-dark'
34
import md3Light from './md3-light'
5+
import { toRem } from './toRem'
46
import { toViewport } from './toViewport'
57

6-
const Themes = { dark, md3Light, md3Dark, toViewport }
8+
const Themes = { dark, md3Light, md3Dark, toViewport, toRem, convert }
79

810
export const _ThemesComponent = null
911

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
import { Themes } from '../../types'
2+
3+
declare const toRem: Themes['toRem']
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import { StyleVars } from '../style-provider'
2+
import { convert } from './convert'
3+
4+
export interface ThemesToRemOptions {
5+
rootFontSize?: number
6+
unitPrecision?: number
7+
}
8+
9+
export function toRem(theme: StyleVars, options: ThemesToRemOptions = {}) {
10+
const { rootFontSize = 16, unitPrecision = 6 } = options
11+
return convert(theme, (value) => `${Number((value / rootFontSize).toFixed(unitPrecision))}rem`)
12+
}
Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { StyleVars } from '../style-provider'
2+
import { convert } from './convert'
23

34
export interface ThemesToViewportOptions {
45
viewportWidth?: number
@@ -9,14 +10,5 @@ export interface ThemesToViewportOptions {
910
export function toViewport(theme: StyleVars, options: ThemesToViewportOptions = {}) {
1011
const { viewportWidth = 375, viewportUnit = 'vmin', unitPrecision = 6 } = options
1112

12-
return Object.entries(theme).reduce((target, [key, value]) => {
13-
target[key] = value.includes('px')
14-
? value.replace(
15-
/(\d+(\.\d+)?)px/g,
16-
(_, p1) => `${Number(((p1 / viewportWidth) * 100).toFixed(unitPrecision))}${viewportUnit}`,
17-
)
18-
: value
19-
20-
return target
21-
}, {} as StyleVars)
13+
return convert(theme, (value) => `${Number(((value / viewportWidth) * 100).toFixed(unitPrecision))}${viewportUnit}`)
2214
}

packages/varlet-ui/types/themes.d.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,19 @@ export interface ThemesToViewportOptions {
66
unitPrecision?: number
77
}
88

9+
export interface ThemesToRemOptions {
10+
rootFontSize?: number
11+
unitPrecision?: number
12+
}
13+
914
interface Themes {
1015
dark: StyleVars
1116
md3Light: StyleVars
1217
md3Dark: StyleVars
1318

19+
convert(theme: StyleVars, converter: (value: number) => string): StyleVars
1420
toViewport(theme: StyleVars, options?: ThemesToViewportOptions): StyleVars
21+
toRem(theme: StyleVars, options?: ThemesToRemOptions): StyleVars
1522
}
1623

1724
export declare const Themes: Themes

0 commit comments

Comments
 (0)