@webstudio-is/fonts 0.95.0 → 0.96.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/index.js +160 -5
- package/package.json +3 -3
- package/lib/constants.js +0 -16
- package/lib/font-weights.js +0 -39
- package/lib/get-font-faces.js +0 -48
- package/lib/get-font-faces.test.js +0 -101
- package/lib/schema.js +0 -44
package/lib/index.js
CHANGED
|
@@ -1,5 +1,160 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
1
|
+
// src/constants.ts
|
|
2
|
+
var SYSTEM_FONTS = /* @__PURE__ */ new Map([
|
|
3
|
+
["Arial", ["Roboto", "sans-serif"]],
|
|
4
|
+
["Times New Roman", ["sans"]],
|
|
5
|
+
["Courier New", ["monospace"]],
|
|
6
|
+
["system-ui", []]
|
|
7
|
+
]);
|
|
8
|
+
var DEFAULT_FONT_FALLBACK = "sans-serif";
|
|
9
|
+
var FONT_FORMATS = /* @__PURE__ */ new Map([
|
|
10
|
+
["woff", "woff"],
|
|
11
|
+
["woff2", "woff2"],
|
|
12
|
+
["ttf", "truetype"],
|
|
13
|
+
["otf", "opentype"]
|
|
14
|
+
]);
|
|
15
|
+
var FONT_MIME_TYPES = Array.from(FONT_FORMATS.keys()).map((format) => `.${format}`).join(", ");
|
|
16
|
+
var FONT_STYLES = ["normal", "italic", "oblique"];
|
|
17
|
+
|
|
18
|
+
// src/get-font-faces.ts
|
|
19
|
+
var formatFace = (asset, format, url) => {
|
|
20
|
+
if ("variationAxes" in asset.meta) {
|
|
21
|
+
const { wght, wdth } = asset.meta?.variationAxes ?? {};
|
|
22
|
+
return {
|
|
23
|
+
fontFamily: asset.meta.family,
|
|
24
|
+
fontStyle: "normal",
|
|
25
|
+
fontDisplay: "swap",
|
|
26
|
+
src: `url('${url}') format('${format}')`,
|
|
27
|
+
fontStretch: wdth ? `${wdth.min}% ${wdth.max}%` : void 0,
|
|
28
|
+
fontWeight: wght ? `${wght.min} ${wght.max}` : void 0
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
return {
|
|
32
|
+
fontFamily: asset.meta.family,
|
|
33
|
+
fontStyle: asset.meta.style,
|
|
34
|
+
fontWeight: asset.meta.weight,
|
|
35
|
+
fontDisplay: "swap",
|
|
36
|
+
src: `url('${url}') format('${format}')`
|
|
37
|
+
};
|
|
38
|
+
};
|
|
39
|
+
var getKey = (asset) => {
|
|
40
|
+
if ("variationAxes" in asset.meta) {
|
|
41
|
+
return asset.meta.family + Object.values(asset.meta.variationAxes).join("");
|
|
42
|
+
}
|
|
43
|
+
return asset.meta.family + asset.meta.style + asset.meta.weight;
|
|
44
|
+
};
|
|
45
|
+
var getFontFaces = (assets, options) => {
|
|
46
|
+
const { assetBaseUrl } = options;
|
|
47
|
+
const faces = /* @__PURE__ */ new Map();
|
|
48
|
+
for (const asset of assets) {
|
|
49
|
+
const url = `${assetBaseUrl}${asset.name}`;
|
|
50
|
+
const assetKey = getKey(asset);
|
|
51
|
+
const face = faces.get(assetKey);
|
|
52
|
+
const format = FONT_FORMATS.get(asset.format);
|
|
53
|
+
if (format === void 0) {
|
|
54
|
+
continue;
|
|
55
|
+
}
|
|
56
|
+
if (face === void 0) {
|
|
57
|
+
const face2 = formatFace(asset, format, url);
|
|
58
|
+
faces.set(assetKey, face2);
|
|
59
|
+
continue;
|
|
60
|
+
}
|
|
61
|
+
face.src += `, url('${url}') format('${format}')`;
|
|
62
|
+
}
|
|
63
|
+
return Array.from(faces.values());
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
// src/schema.ts
|
|
67
|
+
import { z } from "zod";
|
|
68
|
+
var FontFormat = z.union([
|
|
69
|
+
z.literal("ttf"),
|
|
70
|
+
z.literal("woff"),
|
|
71
|
+
z.literal("woff2"),
|
|
72
|
+
z.literal("otf")
|
|
73
|
+
]);
|
|
74
|
+
var AxisName = z.enum([
|
|
75
|
+
"wght",
|
|
76
|
+
"wdth",
|
|
77
|
+
"slnt",
|
|
78
|
+
"opsz",
|
|
79
|
+
"ital",
|
|
80
|
+
"GRAD",
|
|
81
|
+
"XTRA",
|
|
82
|
+
"XOPQ",
|
|
83
|
+
"YOPQ",
|
|
84
|
+
"YTLC",
|
|
85
|
+
"YTUC",
|
|
86
|
+
"YTAS",
|
|
87
|
+
"YTDE",
|
|
88
|
+
"YTFI"
|
|
89
|
+
]);
|
|
90
|
+
var VariationAxes = z.record(
|
|
91
|
+
AxisName,
|
|
92
|
+
z.object({
|
|
93
|
+
name: z.string(),
|
|
94
|
+
min: z.number(),
|
|
95
|
+
default: z.number(),
|
|
96
|
+
max: z.number()
|
|
97
|
+
})
|
|
98
|
+
);
|
|
99
|
+
var FontMetaStatic = z.object({
|
|
100
|
+
family: z.string(),
|
|
101
|
+
style: z.enum(FONT_STYLES),
|
|
102
|
+
weight: z.number()
|
|
103
|
+
});
|
|
104
|
+
var FontMetaVariable = z.object({
|
|
105
|
+
family: z.string(),
|
|
106
|
+
variationAxes: VariationAxes
|
|
107
|
+
});
|
|
108
|
+
var FontMeta = z.union([FontMetaStatic, FontMetaVariable]);
|
|
109
|
+
|
|
110
|
+
// src/font-weights.ts
|
|
111
|
+
var fontWeights = {
|
|
112
|
+
"100": {
|
|
113
|
+
label: "Thin",
|
|
114
|
+
names: ["thin", "hairline"]
|
|
115
|
+
},
|
|
116
|
+
"200": {
|
|
117
|
+
label: "Extra Light",
|
|
118
|
+
names: ["extra light", "extralight", "ultra light", "ultralight"]
|
|
119
|
+
},
|
|
120
|
+
"300": {
|
|
121
|
+
label: "Light",
|
|
122
|
+
names: ["light"]
|
|
123
|
+
},
|
|
124
|
+
"400": {
|
|
125
|
+
label: "Normal",
|
|
126
|
+
names: ["normal", "regular"]
|
|
127
|
+
},
|
|
128
|
+
"500": {
|
|
129
|
+
label: "Medium",
|
|
130
|
+
names: ["medium"]
|
|
131
|
+
},
|
|
132
|
+
"600": {
|
|
133
|
+
label: "Semi Bold",
|
|
134
|
+
names: ["semi bold", "semibold", "demi bold", "demibold"]
|
|
135
|
+
},
|
|
136
|
+
"700": {
|
|
137
|
+
label: "Bold",
|
|
138
|
+
names: ["bold", "bold"]
|
|
139
|
+
},
|
|
140
|
+
"800": {
|
|
141
|
+
label: "Extra Bold",
|
|
142
|
+
names: ["extra bold", "extrabold", "ultra bold", "ultrabold"]
|
|
143
|
+
},
|
|
144
|
+
"900": {
|
|
145
|
+
label: "Black",
|
|
146
|
+
names: ["black", "heavy"]
|
|
147
|
+
}
|
|
148
|
+
};
|
|
149
|
+
export {
|
|
150
|
+
DEFAULT_FONT_FALLBACK,
|
|
151
|
+
FONT_FORMATS,
|
|
152
|
+
FONT_MIME_TYPES,
|
|
153
|
+
FONT_STYLES,
|
|
154
|
+
FontFormat,
|
|
155
|
+
FontMeta,
|
|
156
|
+
FontMetaStatic,
|
|
157
|
+
SYSTEM_FONTS,
|
|
158
|
+
fontWeights,
|
|
159
|
+
getFontFaces
|
|
160
|
+
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@webstudio-is/fonts",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.96.0",
|
|
4
4
|
"description": "Fonts utils",
|
|
5
5
|
"author": "Webstudio <github@webstudio.is>",
|
|
6
6
|
"homepage": "https://webstudio.is",
|
|
@@ -33,8 +33,8 @@
|
|
|
33
33
|
"typecheck": "tsc",
|
|
34
34
|
"test": "NODE_OPTIONS=--experimental-vm-modules jest",
|
|
35
35
|
"checks": "pnpm typecheck && pnpm test",
|
|
36
|
-
"dev": "
|
|
37
|
-
"build": "rm -rf lib && esbuild
|
|
36
|
+
"dev": "rm -rf lib && esbuild 'src/**/*.ts' 'src/**/*.tsx' --outdir=lib --watch",
|
|
37
|
+
"build": "rm -rf lib && esbuild src/index.ts --outdir=lib --bundle --format=esm --packages=external",
|
|
38
38
|
"dts": "tsc --project tsconfig.dts.json"
|
|
39
39
|
}
|
|
40
40
|
}
|
package/lib/constants.js
DELETED
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
export const SYSTEM_FONTS = /* @__PURE__ */ new Map([
|
|
3
|
-
["Arial", ["Roboto", "sans-serif"]],
|
|
4
|
-
["Times New Roman", ["sans"]],
|
|
5
|
-
["Courier New", ["monospace"]],
|
|
6
|
-
["system-ui", []]
|
|
7
|
-
]);
|
|
8
|
-
export const DEFAULT_FONT_FALLBACK = "sans-serif";
|
|
9
|
-
export const FONT_FORMATS = /* @__PURE__ */ new Map([
|
|
10
|
-
["woff", "woff"],
|
|
11
|
-
["woff2", "woff2"],
|
|
12
|
-
["ttf", "truetype"],
|
|
13
|
-
["otf", "opentype"]
|
|
14
|
-
]);
|
|
15
|
-
export const FONT_MIME_TYPES = Array.from(FONT_FORMATS.keys()).map((format) => `.${format}`).join(", ");
|
|
16
|
-
export const FONT_STYLES = ["normal", "italic", "oblique"];
|
package/lib/font-weights.js
DELETED
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
export const fontWeights = {
|
|
3
|
-
"100": {
|
|
4
|
-
label: "Thin",
|
|
5
|
-
names: ["thin", "hairline"]
|
|
6
|
-
},
|
|
7
|
-
"200": {
|
|
8
|
-
label: "Extra Light",
|
|
9
|
-
names: ["extra light", "extralight", "ultra light", "ultralight"]
|
|
10
|
-
},
|
|
11
|
-
"300": {
|
|
12
|
-
label: "Light",
|
|
13
|
-
names: ["light"]
|
|
14
|
-
},
|
|
15
|
-
"400": {
|
|
16
|
-
label: "Normal",
|
|
17
|
-
names: ["normal", "regular"]
|
|
18
|
-
},
|
|
19
|
-
"500": {
|
|
20
|
-
label: "Medium",
|
|
21
|
-
names: ["medium"]
|
|
22
|
-
},
|
|
23
|
-
"600": {
|
|
24
|
-
label: "Semi Bold",
|
|
25
|
-
names: ["semi bold", "semibold", "demi bold", "demibold"]
|
|
26
|
-
},
|
|
27
|
-
"700": {
|
|
28
|
-
label: "Bold",
|
|
29
|
-
names: ["bold", "bold"]
|
|
30
|
-
},
|
|
31
|
-
"800": {
|
|
32
|
-
label: "Extra Bold",
|
|
33
|
-
names: ["extra bold", "extrabold", "ultra bold", "ultrabold"]
|
|
34
|
-
},
|
|
35
|
-
"900": {
|
|
36
|
-
label: "Black",
|
|
37
|
-
names: ["black", "heavy"]
|
|
38
|
-
}
|
|
39
|
-
};
|
package/lib/get-font-faces.js
DELETED
|
@@ -1,48 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
import { FONT_FORMATS } from "./constants";
|
|
3
|
-
const formatFace = (asset, format, url) => {
|
|
4
|
-
if ("variationAxes" in asset.meta) {
|
|
5
|
-
const { wght, wdth } = asset.meta?.variationAxes ?? {};
|
|
6
|
-
return {
|
|
7
|
-
fontFamily: asset.meta.family,
|
|
8
|
-
fontStyle: "normal",
|
|
9
|
-
fontDisplay: "swap",
|
|
10
|
-
src: `url('${url}') format('${format}')`,
|
|
11
|
-
fontStretch: wdth ? `${wdth.min}% ${wdth.max}%` : void 0,
|
|
12
|
-
fontWeight: wght ? `${wght.min} ${wght.max}` : void 0
|
|
13
|
-
};
|
|
14
|
-
}
|
|
15
|
-
return {
|
|
16
|
-
fontFamily: asset.meta.family,
|
|
17
|
-
fontStyle: asset.meta.style,
|
|
18
|
-
fontWeight: asset.meta.weight,
|
|
19
|
-
fontDisplay: "swap",
|
|
20
|
-
src: `url('${url}') format('${format}')`
|
|
21
|
-
};
|
|
22
|
-
};
|
|
23
|
-
const getKey = (asset) => {
|
|
24
|
-
if ("variationAxes" in asset.meta) {
|
|
25
|
-
return asset.meta.family + Object.values(asset.meta.variationAxes).join("");
|
|
26
|
-
}
|
|
27
|
-
return asset.meta.family + asset.meta.style + asset.meta.weight;
|
|
28
|
-
};
|
|
29
|
-
export const getFontFaces = (assets, options) => {
|
|
30
|
-
const { assetBaseUrl } = options;
|
|
31
|
-
const faces = /* @__PURE__ */ new Map();
|
|
32
|
-
for (const asset of assets) {
|
|
33
|
-
const url = `${assetBaseUrl}${asset.name}`;
|
|
34
|
-
const assetKey = getKey(asset);
|
|
35
|
-
const face = faces.get(assetKey);
|
|
36
|
-
const format = FONT_FORMATS.get(asset.format);
|
|
37
|
-
if (format === void 0) {
|
|
38
|
-
continue;
|
|
39
|
-
}
|
|
40
|
-
if (face === void 0) {
|
|
41
|
-
const face2 = formatFace(asset, format, url);
|
|
42
|
-
faces.set(assetKey, face2);
|
|
43
|
-
continue;
|
|
44
|
-
}
|
|
45
|
-
face.src += `, url('${url}') format('${format}')`;
|
|
46
|
-
}
|
|
47
|
-
return Array.from(faces.values());
|
|
48
|
-
};
|
|
@@ -1,101 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
import { describe, test, expect } from "@jest/globals";
|
|
3
|
-
import { getFontFaces } from "./get-font-faces";
|
|
4
|
-
describe("getFontFaces()", () => {
|
|
5
|
-
test("different formats", () => {
|
|
6
|
-
const assets = [
|
|
7
|
-
{
|
|
8
|
-
format: "woff",
|
|
9
|
-
meta: {
|
|
10
|
-
family: "Roboto",
|
|
11
|
-
style: "normal",
|
|
12
|
-
weight: 400
|
|
13
|
-
},
|
|
14
|
-
name: "roboto.woff"
|
|
15
|
-
},
|
|
16
|
-
{
|
|
17
|
-
format: "ttf",
|
|
18
|
-
meta: {
|
|
19
|
-
family: "Roboto",
|
|
20
|
-
style: "normal",
|
|
21
|
-
weight: 400
|
|
22
|
-
},
|
|
23
|
-
name: "roboto.ttf"
|
|
24
|
-
}
|
|
25
|
-
];
|
|
26
|
-
expect(getFontFaces(assets, { assetBaseUrl: "/fonts/" })).toMatchSnapshot();
|
|
27
|
-
});
|
|
28
|
-
test("different style", () => {
|
|
29
|
-
const assets = [
|
|
30
|
-
{
|
|
31
|
-
format: "ttf",
|
|
32
|
-
meta: {
|
|
33
|
-
family: "Roboto",
|
|
34
|
-
style: "normal",
|
|
35
|
-
weight: 400
|
|
36
|
-
},
|
|
37
|
-
name: "roboto.ttf"
|
|
38
|
-
},
|
|
39
|
-
{
|
|
40
|
-
format: "ttf",
|
|
41
|
-
meta: {
|
|
42
|
-
family: "Roboto",
|
|
43
|
-
style: "italic",
|
|
44
|
-
weight: 400
|
|
45
|
-
},
|
|
46
|
-
name: "roboto-italic.ttf"
|
|
47
|
-
}
|
|
48
|
-
];
|
|
49
|
-
expect(getFontFaces(assets, { assetBaseUrl: "/fonts/" })).toMatchSnapshot();
|
|
50
|
-
});
|
|
51
|
-
test("different weight", () => {
|
|
52
|
-
const assets = [
|
|
53
|
-
{
|
|
54
|
-
format: "ttf",
|
|
55
|
-
meta: {
|
|
56
|
-
family: "Roboto",
|
|
57
|
-
style: "normal",
|
|
58
|
-
weight: 400
|
|
59
|
-
},
|
|
60
|
-
name: "roboto.ttf"
|
|
61
|
-
},
|
|
62
|
-
{
|
|
63
|
-
format: "ttf",
|
|
64
|
-
meta: {
|
|
65
|
-
family: "Roboto",
|
|
66
|
-
style: "normal",
|
|
67
|
-
weight: 500
|
|
68
|
-
},
|
|
69
|
-
name: "roboto-bold.ttf"
|
|
70
|
-
}
|
|
71
|
-
];
|
|
72
|
-
expect(getFontFaces(assets, { assetBaseUrl: "/fonts/" })).toMatchSnapshot();
|
|
73
|
-
});
|
|
74
|
-
test("variable font", () => {
|
|
75
|
-
const assets = [
|
|
76
|
-
{
|
|
77
|
-
format: "ttf",
|
|
78
|
-
meta: {
|
|
79
|
-
family: "Inter",
|
|
80
|
-
variationAxes: {
|
|
81
|
-
wght: { name: "wght", min: 100, default: 400, max: 1e3 },
|
|
82
|
-
wdth: { name: "wdth", min: 25, default: 100, max: 151 },
|
|
83
|
-
opsz: { name: "opsz", min: 8, default: 14, max: 144 },
|
|
84
|
-
GRAD: { name: "GRAD", min: -200, default: 0, max: 150 },
|
|
85
|
-
slnt: { name: "slnt", min: -10, default: 0, max: 0 },
|
|
86
|
-
XTRA: { name: "XTRA", min: 323, default: 468, max: 603 },
|
|
87
|
-
XOPQ: { name: "XOPQ", min: 27, default: 96, max: 175 },
|
|
88
|
-
YOPQ: { name: "YOPQ", min: 25, default: 79, max: 135 },
|
|
89
|
-
YTLC: { name: "YTLC", min: 416, default: 514, max: 570 },
|
|
90
|
-
YTUC: { name: "YTUC", min: 528, default: 712, max: 760 },
|
|
91
|
-
YTAS: { name: "YTAS", min: 649, default: 750, max: 854 },
|
|
92
|
-
YTDE: { name: "YTDE", min: -305, default: -203, max: -98 },
|
|
93
|
-
YTFI: { name: "YTFI", min: 560, default: 738, max: 788 }
|
|
94
|
-
}
|
|
95
|
-
},
|
|
96
|
-
name: "inter.ttf"
|
|
97
|
-
}
|
|
98
|
-
];
|
|
99
|
-
expect(getFontFaces(assets, { assetBaseUrl: "/fonts/" })).toMatchSnapshot();
|
|
100
|
-
});
|
|
101
|
-
});
|
package/lib/schema.js
DELETED
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
import { z } from "zod";
|
|
3
|
-
import { FONT_STYLES } from "./constants";
|
|
4
|
-
export const FontFormat = z.union([
|
|
5
|
-
z.literal("ttf"),
|
|
6
|
-
z.literal("woff"),
|
|
7
|
-
z.literal("woff2"),
|
|
8
|
-
z.literal("otf")
|
|
9
|
-
]);
|
|
10
|
-
const AxisName = z.enum([
|
|
11
|
-
"wght",
|
|
12
|
-
"wdth",
|
|
13
|
-
"slnt",
|
|
14
|
-
"opsz",
|
|
15
|
-
"ital",
|
|
16
|
-
"GRAD",
|
|
17
|
-
"XTRA",
|
|
18
|
-
"XOPQ",
|
|
19
|
-
"YOPQ",
|
|
20
|
-
"YTLC",
|
|
21
|
-
"YTUC",
|
|
22
|
-
"YTAS",
|
|
23
|
-
"YTDE",
|
|
24
|
-
"YTFI"
|
|
25
|
-
]);
|
|
26
|
-
const VariationAxes = z.record(
|
|
27
|
-
AxisName,
|
|
28
|
-
z.object({
|
|
29
|
-
name: z.string(),
|
|
30
|
-
min: z.number(),
|
|
31
|
-
default: z.number(),
|
|
32
|
-
max: z.number()
|
|
33
|
-
})
|
|
34
|
-
);
|
|
35
|
-
export const FontMetaStatic = z.object({
|
|
36
|
-
family: z.string(),
|
|
37
|
-
style: z.enum(FONT_STYLES),
|
|
38
|
-
weight: z.number()
|
|
39
|
-
});
|
|
40
|
-
const FontMetaVariable = z.object({
|
|
41
|
-
family: z.string(),
|
|
42
|
-
variationAxes: VariationAxes
|
|
43
|
-
});
|
|
44
|
-
export const FontMeta = z.union([FontMetaStatic, FontMetaVariable]);
|