8000 feat(preset-web-fonts): introduce `subsets` & `preferStatic` option f… · unocss/unocss@411deb5 · GitHub
[go: up one dir, main page]

Skip to content

Commit 411deb5

Browse files
Jungzlzyyv
andauthored
feat(preset-web-fonts): introduce subsets & preferStatic option for fontsource provider (#4742)
Co-authored-by: Chris <hizyyv@gmail.com>
1 parent f3a6c75 commit 411deb5

File tree

5 files changed

+180
-3
lines changed

5 files changed

+180
-3
lines changed

docs/presets/web-fonts.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,8 @@ Currently supported Providers:
6464
- `google` - [Google Fonts](https://fonts.google.com/)
6565
- `bunny` - [Privacy-Friendly Google Fonts](https://fonts.bunny.net/)
6666
- `fontshare` - [Quality Font Service by ITF](https://www.fontshare.com/)
67+
- `fontsource` - [Self-Host Open Source Fonts in Neatly Bundled NPM Packages](https://fontsource.org/)
68+
- `coollabs` - [A Privacy-Friendly Drop-In Replacement for Google Fonts](https://fonts.coollabs.io/)
6769

6870
::: info
6971
PR welcome to add more providers. 🙌
@@ -106,7 +108,7 @@ export default defineConfig({
106108
Provider service of the web fonts.
107109

108110
```ts
109-
type WebFontsProviders = 'google' | 'bunny' | 'fontshare' | 'none'
111+
type WebFontsProviders = 'google' | 'bunny' | 'fontshare' | 'fontsource' | 'coollabs' | 'none'
110112
```
111113
112114
### fonts

packages-presets/preset-web-fonts/src/providers/fontsource/index.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,10 @@ export function createFontSourceProvider(name: WebFontsProviders, host: string):
2525
}
2626
}
2727

28-
const { subsets, weights } = metadata
28+
const { weights } = metadata
29+
const subsets = metadata.subsets.filter(subset => font.subsets ? font.subsets.includes(subset) : true)
2930

30-
if (metadata.variable) {
31+
if (metadata.variable && !font.preferStatic) {
3132
let variableData = variablesMap.get(id)
3233
const url = `https://api.fontsource.org/v1/variable/${id}`
3334

packages-presets/preset-web-fonts/src/types.ts

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,46 @@ import type { Arrayable, Awaitable } from '@unocss/core'
33
export type WebFontsProviders = 'google' | 'bunny' | 'fontshare' | 'fontsource' | 'coollabs' | 'none' | Provider
44

55
export interface WebFontMeta {
6+
/**
7+
* The name of the font family
8+
* @example 'Fira Code'
9+
*/
610
name: string
11+
12+
/**
13+
* Font weight(s) to include, and respect the weight order
14+
* @example [400, 700]
15+
*/
716
weights?: (string | number)[] // wght axis
17+
18+
/**
19+
* Use italic style
20+
*/
821
italic?: boolean // ital axis
22+
23+
/**
24+
* Variable font settings
25+
* @example
26+
* ```ts
27+
* variable: {
28+
* wght: { default: '400', min: '100', max: '900', step: '100' },
29+
* wdth: { default: '100', min: '50', max: '200', step: '10' },
30+
* slnt: { default: '0', min: '-20', max: '20', step: '1' },
31+
* }
32+
*/
933
variable?: Record<string, Partial<Axes>> // variable font
34+
35+
/**
36+
* The font subsets to include
37+
* @example ['latin', 'cyrillic']
38+
*/
39+
subsets?: string[]
40+
41+
/**
42+
* Prefer static font files over variable
43+
*/
44+
preferStatic?: boolean
45+
1046
/**
1147
* Override the provider
1248
* @default <matches root config>

test/__snapshots__/preset-web-fonts.test.ts.snap

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,98 @@ exports[`fontsource provider > custom wght 1`] = `
172172
.font-fm{font-family:"Fira Mono";}"
173173
`;
174174
175+
exports[`fontsource provider > prefer static 1`] = `
176+
"/* layer: preflights */
177+
*,::before,::after{--un-rotate:0;--un-rotate-x:0;--un-rotate-y:0;--un-rotate-z:0;--un-scale-x:1;--un-scale-y:1;--un-scale-z:1;--un-skew-x:0;--un-skew-y:0;--un-translate-x:0;--un-translate-y:0;--un-translate-z:0;--un-ring-offset-shadow:0 0 rgb(0 0 0 / 0);--un-ring-shadow:0 0 rgb(0 0 0 / 0);--un-shadow-inset: ;--un-shadow:0 0 rgb(0 0 0 / 0);--un-ring-inset: ;--un-ring-offset-width:0px;--un-ring-offset-color:#fff;--un-ring-width:0px;--un-ring-color:rgb(147 197 253 / 0.5);}::backdrop{--un-rotate:0;--un-rotate-x:0;--un-rotate-y:0;--un-rotate-z:0;--un-scale-x:1;--un-scale-y:1;--un-scale-z:1;--un-skew-x:0;--un-skew-y:0;--un-translate-x:0;--un-translate-y:0;--un-translate-z:0;--un-ring-offset-shadow:0 0 rgb(0 0 0 / 0);--un-ring-shadow:0 0 rgb(0 0 0 / 0);--un-shadow-inset: ;--un-shadow:0 0 rgb(0 0 0 / 0);--un-ring-inset: ;--un-ring-offset-width:0px;--un-ring-offset-color:#fff;--un-ring-width:0px;--un-ring-color:rgb(147 197 253 / 0.5);}
178+
/* dm-sans-latin-400-normal */
179+
@font-face {
180+
font-family: 'DM Sans';
181+
font-style: normal;
182+
font-display: swap;
183+
font-weight: 400;
184+
src: url(https://cdn.jsdelivr.net/fontsource/fonts/dm-sans@latest/latin-400-normal.woff2) format('woff2');
185+
unicode-range: U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+2074,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;
186+
}
187+
188+
/* dm-sans-latin-700-normal */
189+
@font-face {
190+
font-family: 'DM Sans';
191+
font-style: normal;
192+
font-display: swap;
193+
font-weight: 700;
194+
src: url(https://cdn.jsdelivr.net/fontsource/fonts/dm-sans@latest/latin-700-normal.woff2) format('woff2');
195+
unicode-range: U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+2074,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;
196+
}
197+
198+
/* dm-sans-latin-ext-400-normal */
199+
@font-face {
200+
font-family: 'DM Sans';
201+
font-style: normal;
202+
font-display: swap;
203+
font-weight: 400;
204+
src: url(https://cdn.jsdelivr.net/fontsource/fonts/dm-sans@latest/latin-ext-400-normal.woff2) format('woff2');
205+
unicode-range: U+0100-02AF,U+0304,U+0308,U+0329,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF;
206+
}
207+
208+
/* dm-sans-latin-ext-700-normal */
209+
@font-face {
210+
font-family: 'DM Sans';
211+
font-style: normal;
212+
font-display: swap;
213+
font-weight: 700;
214+
src: url(https://cdn.jsdelivr.net/fontsource/fonts/dm-sans@latest/latin-ext-700-normal.woff2) format('woff2');
215+
unicode-range: U+0100-02AF,U+0304,U+0308,U+0329,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF;
216+
}
217+
/* layer: default */
218+
.font-dm{font-family:"Dm Sans";}"
219+
`;
220+
221+
exports[`fontsource provider > specific subsets 1`] = `
222+
"/* layer: preflights */
223+
*,::before,::after{--un-rotate:0;--un-rotate-x:0;--un-rotate-y:0;--un-rotate-z:0;--un-scale-x:1;--un-scale-y:1;--un-scale-z:1;--un-skew-x:0;--un-skew-y:0;--un-translate-x:0;--un-translate-y:0;--un-translate-z:0;--un-ring-offset-shadow:0 0 rgb(0 0 0 / 0);--un-ring-shadow:0 0 rgb(0 0 0 / 0);--un-shadow-inset: ;--un-shadow:0 0 rgb(0 0 0 / 0);--un-ring-inset: ;--un-ring-offset-width:0px;--un-ring-offset-color:#fff;--un-ring-width:0px;--un-ring-color:rgb(147 197 253 / 0.5);}::backdrop{--un-rotate:0;--un-rotate-x:0;--un-rotate-y:0;--un-rotate-z:0;--un-scale-x:1;--un-scale-y:1;--un-scale-z:1;--un-skew-x:0;--un-skew-y:0;--un-translate-x:0;--un-translate-y:0;--un-translate-z:0;--un-ring-offset-shadow:0 0 rgb(0 0 0 / 0);--un-ring-shadow:0 0 rgb(0 0 0 / 0);--un-shadow-inset: ;--un-shadow:0 0 rgb(0 0 0 / 0);--un-ring-inset: ;--un-ring-offset-width:0px;--un-ring-offset-color:#fff;--un-ring-width:0px;--un-ring-color:rgb(147 197 253 / 0.5);}
224+
/* fira-mono-cyrillic-400-normal */
225+
@font-face {
226+
font-family: 'Fira Mono';
227+
font-style: normal;
228+
font-display: swap;
229+
font-weight: 400;
230+
src: url(https://cdn.jsdelivr.net/fontsource/fonts/fira-mono@latest/cyrillic-400-normal.woff2) format('woff2');
231+
unicode-range: U+0301,U+0400-045F,U+0490-0491,U+04B0-04B1,U+2116;
232+
}
233+
234+
/* fira-mono-cyrillic-700-normal */
235+
@font-face {
236+
font-family: 'Fira Mono';
237+
font-style: normal;
238+
font-display: swap;
239+
font-weight: 700;
240+
src: url(https://cdn.jsdelivr.net/fontsource/fonts/fira-mono@latest/cyrillic-700-normal.woff2) format('woff2');
241+
unicode-range: U+0301,U+0400-045F,U+0490-0491,U+04B0-04B1,U+2116;
242+
}
243+
244+
/* fira-mono-latin-400-normal */
245+
@font-face {
246+
font-family: 'Fira Mono';
247+
font-style: normal;
248+
font-display: swap;
249+
font-weight: 400;
250+
src: url(https://cdn.jsdelivr.net/fontsource/fonts/fira-mono@latest/latin-400-normal.woff2) format('woff2');
251+
unicode-range: U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+2074,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;
252+
}
253+
254+
/* fira-mono-latin-700-normal */
255+
@font-face {
256+
font-family: 'Fira Mono';
257+
font-style: normal;
258+
font-display: swap;
259+
font-weight: 700;
260+
src: url(https://cdn.jsdelivr.net/fontsource/fonts/fira-mono@latest/latin-700-normal.woff2) format('woff2');
261+
unicode-range: U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+2074,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;
262+
}
263+
/* layer: default */
264+
.font-fm{font-family:"Fira Mono";}"
265+
`;
266+
175267
exports[`fontsource provider > staticFonts 1`] = `
176268
"/* layer: preflights */
177269
*,::before,::after{--un-rotate:0;--un-rotate-x:0;--un-rotate-y:0;--un-rotate-z:0;--un-scale-x:1;--un-scale-y:1;--un-scale-z:1;--un-skew-x:0;--un-skew-y:0;--un-translate-x:0;--un-translate-y:0;--un-translate-z:0;--un-ring-offset-shadow:0 0 rgb(0 0 0 / 0);--un-ring-shadow:0 0 rgb(0 0 0 / 0);--un-shadow-inset: ;--un-shadow:0 0 rgb(0 0 0 / 0);--un-ring-inset: ;--un-ring-offset-width:0px;--un-ring-offset-color:#fff;--un-ring-width:0px;--un-ring-color:rgb(147 197 253 / 0.5);}::backdrop{--un-rotate:0;--un-rotate-x:0;--un-rotate-y:0;--un-rotate-z:0;--un-scale-x:1;--un-scale-y:1;--un-scale-z:1;--un-skew-x:0;--un-skew-y:0;--un-translate-x:0;--un-translate-y:0;--un-translate-z:0;--un-ring-offset-shadow:0 0 rgb(0 0 0 / 0);--un-ring-shadow:0 0 rgb(0 0 0 / 0);--un-shadow-inset: ;--un-shadow:0 0 rgb(0 0 0 / 0);--un-ring-inset: ;--un-ring-offset-width:0px;--un-ring-offset-color:#fff;--un-ring-width:0px;--un-ring-color:rgb(147 197 253 / 0.5);}

test/preset-web-fonts.test.ts

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -227,4 +227,50 @@ describe('fontsource provider', async () => {
227227

228228
expect(css).toMatchSnapshot()
229229
})
230+
231+
it('specific subsets', async () => {
232+
const uno = await createGenerator({
233+
presets: [
234+
presetMini(),
235+
presetWebFonts({
236+
provider: 'fontsource',
237+
fonts: {
238+
fm: {
239+
name: 'Fira Mono',
240+
weights: ['400', '700'],
241+
subsets: ['cyrillic', 'latin'],
242+
},
243+
},
244+
}),
245+
],
246+
})
247+
248+
const { css } = await uno.generate('font-fm')
249+
250+
expect(css).toMatchSnapshot()
251+
})
252+
253+
it('prefer static', async () => {
254+
const uno = await createGenerator({
255+
presets: [
256+
presetMini(),
257+
presetWebFonts({
258+
provider: 'fontsource',
259+
fonts: {
260+
dm: {
261+
name: 'Dm Sans',
262+
// When `preferStatic` is true, it will use static font files
263+
// So it produces `@font-face` for `400` and `700`
264+
weights: ['400', '700'],
265+
preferStatic: true,
266+
},
267+
},
268+
}),
269+
],
270+
})
271+
272+
const { css } = await uno.generate('font-dm')
273+
274+
expect(css).toMatchSnapshot()
275+
})
230276
})

0 commit comments

Comments
 (0)
0