|
| 1 | +# fusion-plugin-font-loader-react |
| 2 | + |
| 3 | +Provides : |
| 4 | +1. A fusion plugin that generates @font-faces and preloads fallback fonts based on app-level font configuration. |
| 5 | +2. A Higher Order Component for loading custom web fonts (and associated utils). During font loading, this HOC temporarily swaps the element to a well-matched fallback font, avoiding FOIT and FOUT. See https://www.zachleat.com/web/comprehensive-webfonts/#critical-foft-preload for more on this. |
| 6 | + |
| 7 | +## Installation |
| 8 | + |
| 9 | +``` |
| 10 | +yarn add fusion-plugin-font-loading |
| 11 | +``` |
| 12 | + |
| 13 | +## Usage |
| 14 | + |
| 15 | +### Configuration |
| 16 | +Consuming apps should define a `font-config.js` which a) provides data for @font-face generation, b) is used to derive the fallback font and styles that will be used by the `with-font-loading.js` HOC. |
| 17 | + |
| 18 | +_Sample \<app\>/src/font-config.js file_ |
| 19 | +```js |
| 20 | +import {assetUrl} from 'fusion-core'; |
| 21 | +export const preloadDepth = 1; |
| 22 | +export const fonts = { |
| 23 | + 'Lato-Regular': { |
| 24 | + urls: { |
| 25 | + woff2: assetUrl('../static/Lato-Regular.woff2'), |
| 26 | + }, |
| 27 | + fallback: { |
| 28 | + name: 'Helvetica', |
| 29 | + }, |
| 30 | + }, |
| 31 | + 'Lato-Bold': { |
| 32 | + urls: { |
| 33 | + woff2: assetUrl('../static/Lato-Bold.woff2'), |
| 34 | + }, |
| 35 | + fallback: { |
| 36 | + name: 'Lato-Regular', |
| 37 | + styles: { |
| 38 | + 'font-weight': 'bold', |
| 39 | + }, |
| 40 | + }, |
| 41 | + }, |
| 42 | + 'Lato-Thin': { |
| 43 | + urls: { |
| 44 | + woff2: assetUrl('./static/Lato-Thin.woff2'), |
| 45 | + }, |
| 46 | + fallback: { |
| 47 | + name: 'Lato-Regular', |
| 48 | + styles: { |
| 49 | + 'font-weight': '100', |
| 50 | + }, |
| 51 | + }, |
| 52 | + }, |
| 53 | +}; |
| 54 | +``` |
| 55 | + |
| 56 | +#### @font-face generation |
| 57 | + |
| 58 | +Based on the example configuration file above the following @font-face would be generated in <head> |
| 59 | + |
| 60 | +```css |
| 61 | +@font-face {font-family: "Lato-Regular"; src: url("/_static/ca614426b50ca7d007056aa00954764b.woff2") format("woff2");} |
| 62 | +@font-face {font-family: "Lato-Bold"; src: url("/_static/ca104da8af9a2e0771e8fe2b31f8ec1e.woff2") format("woff2");} |
| 63 | +@font-face {font-family: "Lato-Thin"; src: url("/_static/03b64805a8cd2d53fadc5814445c2fb5.woff2") format("woff2");} |
| 64 | +``` |
| 65 | + |
| 66 | +#### font loading |
| 67 | + |
| 68 | +1. An in-memory font fallback tree is generated at runtime based on the defintitions provided in `font-config.js` |
| 69 | +2. Fallbacks at and above the specified `preloadDepth` will be preloaded/prefetched on page load |
| 70 | +3. Remaining fonts will lazily loaded. |
| 71 | + |
| 72 | +Based on the sample config above (`preloadDepth` is set to 1), the HOC example above would yield the following values for `prop.fontStyles`: |
| 73 | + |
| 74 | +while loading font: |
| 75 | +```js |
| 76 | +{ |
| 77 | + fontFamily: 'Lato-Regular' |
| 78 | + fontWeight: 'bold' |
| 79 | +} |
| 80 | +``` |
| 81 | + |
| 82 | +when font is loaded: |
| 83 | +```js |
| 84 | +{ |
| 85 | + fontFamily: 'Lato-Bold' |
| 86 | +} |
| 87 | +``` |
| 88 | + |
| 89 | +If `preloadDepth` were 0 then every font would be preloaded, and there would be no fallback fonts |
| 90 | + |
| 91 | +If `preloadDepth` were 2 then the only fallback font would be Helvetica, and since Helvetica is a system font, no custom fonts would be preloaded. |
| 92 | + |
| 93 | +### Higher Order Component |
| 94 | + |
| 95 | +This repo also supplies a `with-font-loading.js` Higher Order Component which is used to: |
| 96 | +1. Load a specified font |
| 97 | +2. Temporarily assign a fallback font and styles to the wrapped component via `props.fontStyles` |
| 98 | +3. When the font is loaded assign the true font to child component via `props.fontStyles` |
| 99 | + |
| 100 | +```js |
| 101 | +const FancyLink1 = withFontLoading('Lato-Bold'.( |
| 102 | + styled('a', props => ({ |
| 103 | + ':hover': {fontSize: `${props.answer}px`}. |
| 104 | + ...props.fontStyles, |
| 105 | + })) |
| 106 | +); |
| 107 | +``` |
| 108 | +
|
| 109 | +This will lazy-load `Lato-Bold` and meanwhile assign a fallback font and styling to the element via `props.fontStyles`. |
| 110 | +
|
| 111 | +## Utils |
| 112 | +
|
| 113 | +### font-loader.js |
| 114 | +
|
| 115 | +Promise used by `with-font-loading.js` HOC to dynamically load specified font; calls `resolve` when load is complete. |
| 116 | +
|
| 117 | +Uses `document.fonts.load` where available (chrome and firefox as of 10/17), otherwise uses a polyfill. |
| 118 | +
|
| 119 | +
|
| 120 | +
|
| 121 | +
|
| 122 | +
|
| 123 | +
|
| 124 | +
|
| 125 | +
|
| 126 | +
|
0 commit comments