-
-
Notifications
You must be signed in to change notification settings - Fork 209
/
fontFace.js
94 lines (85 loc) · 2.72 KB
/
fontFace.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
// @flow
/** */
type FontFaceConfiguration = {
fontFamily: string;
fontFilePath?: string;
fontStretch?: string;
fontStyle?: string;
fontVariant?: string;
fontWeight?: string;
fileFormats?: Array<string>;
localFonts?: Array<string>;
unicodeRange?: string
}
function generateFileReferences(fontFilePath: string, fileFormats: Array<string>) {
const fileFontReferences = fileFormats.map((format) => `url("${fontFilePath}.${format}")`)
return fileFontReferences.join(', ')
}
function generateLocalReferences(localFonts: Array<string>) {
const localFontReferences = localFonts.map((font) => `local("${font}")`)
return localFontReferences.join(', ')
}
function generateSources(fontFilePath?: string, localFonts?: Array<string>, fileFormats: Array<string>) {
const fontReferences = []
if (localFonts) fontReferences.push(generateLocalReferences(localFonts))
if (fontFilePath) fontReferences.push(generateFileReferences(fontFilePath, fileFormats))
return fontReferences.join(', ')
}
/**
* CSS for a @font-face declaration.
*
* @example
* // Styles as object basic usage
* const styles = {
* ...fontFace({
* 'fontFamily': 'Sans-Pro'
* 'fontFilePath': 'path/to/file'
* })
* }
*
* // styled-components basic usage
* injectGlobal`${
* fontFace({
* 'fontFamily': 'Sans-Pro'
* 'fontFilePath': 'path/to/file'
* }
* )}`
*
* // CSS as JS Output
*
* '@font-face': {
* 'font-family': 'Sans-Pro',
* 'src': 'url("path/to/file.eot"), url("path/to/file.woff2"), url("path/to/file.woff"), url("path/to/file.ttf"), url("path/to/file.svg")',
* }
*/
function fontFace({
fontFamily,
fontFilePath,
fontStretch,
fontStyle,
fontVariant,
fontWeight,
fileFormats = ['eot', 'woff2', 'woff', 'ttf', 'svg'],
localFonts,
unicodeRange,
}: FontFaceConfiguration) {
// Error Handling
if (!fontFamily) throw new Error('fontFace expects a name of a font-family.')
if (!fontFilePath && !localFonts) throw new Error('fontFace expects either the path to the font file(s) or a name of a local copy.')
if (localFonts && !Array.isArray(localFonts)) throw new Error('fontFace expects localFonts to be an array.')
if (!Array.isArray(fileFormats)) throw new Error('fontFace expects fileFormats to be an array.')
const fontFaceDeclaration = {
'@font-face': {
'font-family': fontFamily,
'src': generateSources(fontFilePath, localFonts, fileFormats),
'unicode-range': unicodeRange,
'font-stretch': fontStretch,
'font-style': fontStyle,
'font-variant': fontVariant,
'font-weight': fontWeight,
},
}
// Removes undefined fields for cleaner css object.
return JSON.parse(JSON.stringify(fontFaceDeclaration))
}
export default fontFace