UNPKG

polished

Version:

A lightweight toolset for writing styles in Javascript.

135 lines (121 loc) 3.62 kB
// @flow import PolishedError from '../internalHelpers/_errors' import type { FontFaceConfiguration } from '../types/fontFaceConfiguration' import type { Styles } from '../types/style' const dataURIRegex = /^\s*data:([a-z]+\/[a-z-]+(;[a-z-]+=[a-z-]+)?)?(;charset=[a-z0-9-]+)?(;base64)?,[a-z0-9!$&',()*+,;=\-._~:@/?%\s]*\s*$/i const formatHintMap = { woff: 'woff', woff2: 'woff2', ttf: 'truetype', otf: 'opentype', eot: 'embedded-opentype', svg: 'svg', svgz: 'svg', } function generateFormatHint(format: string, formatHint: boolean): string { if (!formatHint) return '' return ` format("${formatHintMap[format]}")` } function isDataURI(fontFilePath: string): boolean { return !!fontFilePath.replace(/\s+/g, ' ').match(dataURIRegex) } function generateFileReferences( fontFilePath: string, fileFormats: Array<string>, formatHint: boolean, ): string { if (isDataURI(fontFilePath)) { return `url("${fontFilePath}")${generateFormatHint(fileFormats[0], formatHint)}` } const fileFontReferences = fileFormats.map( format => `url("${fontFilePath}.${format}")${generateFormatHint(format, formatHint)}`, ) return fileFontReferences.join(', ') } function generateLocalReferences(localFonts: Array<string>): string { const localFontReferences = localFonts.map(font => `local("${font}")`) return localFontReferences.join(', ') } function generateSources( fontFilePath?: string, localFonts: Array<string> | null, fileFormats: Array<string>, formatHint: boolean, ): string { const fontReferences = [] if (localFonts) fontReferences.push(generateLocalReferences(localFonts)) if (fontFilePath) { fontReferences.push(generateFileReferences(fontFilePath, fileFormats, formatHint)) } return fontReferences.join(', ') } /** * CSS for a @font-face declaration. Defaults to check for local copies of the font on the user's machine. You can disable this by passing `null` to localFonts. * * @example * // Styles as object basic usage * const styles = { * ...fontFace({ * 'fontFamily': 'Sans-Pro', * 'fontFilePath': 'path/to/file' * }) * } * * // styled-components basic usage * const GlobalStyle = createGlobalStyle`${ * fontFace({ * 'fontFamily': 'Sans-Pro', * 'fontFilePath': 'path/to/file' * } * )}` * * // CSS as JS Output * * '@font-face': { * 'fontFamily': '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")', * } */ export default function fontFace({ fontFamily, fontFilePath, fontStretch, fontStyle, fontVariant, fontWeight, fileFormats = ['eot', 'woff2', 'woff', 'ttf', 'svg'], formatHint = false, localFonts = [fontFamily], unicodeRange, fontDisplay, fontVariationSettings, fontFeatureSettings, }: FontFaceConfiguration): Styles { // Error Handling if (!fontFamily) throw new PolishedError(55) if (!fontFilePath && !localFonts) { throw new PolishedError(52) } if (localFonts && !Array.isArray(localFonts)) { throw new PolishedError(53) } if (!Array.isArray(fileFormats)) { throw new PolishedError(54) } const fontFaceDeclaration = { '@font-face': { fontFamily, src: generateSources(fontFilePath, localFonts, fileFormats, formatHint), unicodeRange, fontStretch, fontStyle, fontVariant, fontWeight, fontDisplay, fontVariationSettings, fontFeatureSettings, }, } // Removes undefined fields for cleaner css object. return JSON.parse(JSON.stringify(fontFaceDeclaration)) }