npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

react-fout-stager

v3.0.0

Published

Load weights and styles of typefaces in stages. Based on the techniques of [@zachleat](https://twitter.com/zachleat)'s work on [FOUT with Two Stage Render](https://www.zachleat.com/web/comprehensive-webfonts/).

Downloads

6,200

Readme

React FOUT Stager

Load weights and styles of typefaces in stages. Based on the techniques of @zachleat's work on FOUT with Two Stage Render.

demo

Features

  • Load multiple typefaces with weights and styles in potentially multiple stages
  • Caches/optimizes repeat views per session with sessionStorage
  • Receive event when all fonts have been loaded
  • Should work in IE9+

Installation

You can install react-fout-stager via Yarn or npm:

# If using Yarn:
yarn add react-fout-stager

# If using npm:
npm install --save react-fout-stager

The core component from react-fout-stager is FoutStager. This module can be required via ES imports, CommonJS require, or UMD.

import FoutStager from 'react-fout-stager';

// using require
const FoutStager = require('react-fout-stager');

Important! If you need to use the ES5 version, such as within Create React App, you will need to import the component at react-fout-stager/es5, e.g.:

import FoutStager from 'react-fout-stager/es5/FoutStager';

// using require
const FoutStager = require('react-fout-stager/es5/FoutStager');

Usage

After importing react-fout-stager, it can be rendered anywhere in the React tree. Once react-fout-stager will mount, it will kick off loading any typefaces defined in the stages prop.

import React from 'react';
import { render } from 'react-dom';
import FoutStager from 'react-fout-stager';

render((
  <FoutStager stages={[{
    className: 'font-stage-primary',
    families: [{ family: 'Roboto' }],
    stages: [{
      className: 'font-stage-secondary',
      families: [
        { family: 'RobotoBold', options: { weight: 700 } },
        { family: 'RobotoItalic', options: { style: 'italic' } },
        { family: 'RobotoBoldItalic', options: { weight: 700, style: 'italic' } }
      ]
    }]
  }]} />
), document.getElementById('root'));

If you pass any children to FoutStager, they will not be rendered until the typefaces have all loaded.

import React from 'react';
import { render } from 'react-dom';
import FoutStager from 'react-fout-stager';

render((
  <FoutStager stages={[{
    className: 'font-stage-primary',
    families: [{ family: 'Roboto' }],
    stages: [{
      className: 'font-stage-secondary',
      families: [
        { family: 'RobotoBold', options: { weight: 700 } },
        { family: 'RobotoItalic', options: { style: 'italic' } },
        { family: 'RobotoBoldItalic', options: { weight: 700, style: 'italic' } }
      ]
    }]
  }]}>
    <em>I won't render until all these "Roboto" typefaces have loaded!</em>
  </FoutStager>
), document.getElementById('root'));

Props

FoutStager accepts a few props to customize its behavior:

| Property | Type | Required? | Description | |:---|:---|:---:|:---| | stages | arrayOf(stage) | ✓ | A list of stages with associated typefaces to load. | | sessionKey | string | | The sessionStorage key which is used to cache typeface loads. Defaults to foutStagerLoaded. This will need to be overridden if you use multiple FoutStagers in an application. | | onStagesLoad | func | | Execute a function when all typefaces have loaded. | | children | node | | Render children when all typefaces have loaded. |

stages

The stages prop of FoutStager accepts an array of stages. The shape of a stage is:

Stage :: {
  className: string.isRequired,
  families: arrayOf(shape({
    family: string.isRequired,
    options: object
  })).isRequired,
  stages: arrayOf(Stage)
}

Or said more verbosely:

  • Each stage is an object.
  • A stage must include a property named className which is a string class name to place on the html tag when the stage has loaded.
  • A stage must include a property named families which is an array of objects, each of which represents a typeface (font family) to load in this stage.
  • Each family in families must include a property named family which corresponds to a font-family defined in CSS. Creating font families is detailed below.
  • Each family in families can optionally include a property named options, which is an object that defines a font description with properties of weight, style, and stretch. These accept values that are defined by the fontfaceobserver library.
  • A stage can also include a property named stages, which is another array of stages to load once the current stage has completed.

All adjacent stages are loaded in parallel. The use of the stages property on a stage should be use for loading stages serially.

CSS

In order to load typefaces with FoutStager, they need to have a defined font-family in CSS. For example, here is a @font-face with a font-family defined for the Roboto (Regular) typeface:

@font-face {
  font-family: Roboto;
  font-style: normal;
  font-display: swap;
  font-weight: 400;
  src:
    local('Roboto Regular'),
    local('Roboto Regular '),
    local('Roboto-Regular'),
    url('~typeface-roboto/files/roboto-latin-400.woff2') format('woff2'),
    url('~typeface-roboto/files/roboto-latin-400.woff') format('woff');
}

Take note of the font-family: Roboto property. This is how you will reference this particular font in FoutStager:

<FoutStager stages={[{
  className: 'font-stage-primary',
  families: [{ family: 'Roboto' }]
}]} />

Loading variants of a typeface should have their own font-family name. For example, to define the Roboto Italic font:

@font-face {
  font-family: RobotoItalic;
  font-style: italic;
  font-display: swap;
  font-weight: 400;
  src:
    local('Roboto Regular italic'),
    local('Roboto-Regularitalic'),
    url('~typeface-roboto/files/roboto-latin-400italic.woff2') format('woff2'),
    url('~typeface-roboto/files/roboto-latin-400italic.woff') format('woff');
}
<FoutStager stages={[{
  className: 'font-stage-primary',
  families: [{ family: 'RobotoItalic', options: { style: 'italic' } }]
}]} />

Notice the use of options when loading fonts with non-normal font descriptions.

Example

This demo can be seen in action on the hosted styleguide.

For a canonical example, we are going to replicate Zach Leatherman's FOFT, or FOUT with Two Stage Render demo in React.

@font-face {
  font-family: Lato;
  src:
    url('/files/lato-regular-webfont.woff2') format('woff2'),
    url('/files/lato-regular-webfont.woff') format('woff');
  font-weight: 400;
  font-style: normal;
}
@font-face {
  font-family: LatoBold;
  src:
    url('/files/lato-bold-webfont.woff2') format('woff2'),
    url('/files/lato-bold-webfont.woff') format('woff');
  font-weight: 700;
  font-style: normal;
}
@font-face {
  font-family: LatoItalic;
  src:
    url('/files/lato-italic-webfont.woff2') format('woff2'),
    url('/files/lato-italic-webfont.woff') format('woff');
  font-weight: 400;
  font-style: italic;
}
@font-face {
  font-family: LatoBoldItalic;
  src:
    url('/files/lato-bolditalic-webfont.woff2') format('woff2'),
    url('/files/lato-bolditalic-webfont.woff') format('woff');
  font-weight: 700;
  font-style: italic;
}

/*
  The purpose of defining class stages is to
  re-render once a stage has been met. We start
  with the minimal default stage of sans-serif,
  and progressively re-render.
*/
body {
  font-family: sans-serif;
}

/*
  The defined stages now modify the display of
  elements once they are loaded.
*/

/*
  During stage 1 we only load the Lato font.
  Once it's loaded, update the body to use it.
*/
.fonts-stage-1 body {
  font-family: Lato, sans-serif;
  font-weight: 400;
  font-style: normal;
}

/*
  During stage 2 we load Lato Bold, Lato Italic, and
  Lato Bold Italic. Once these 3 are loaded, we can
  once again update relevant elements to render using
  these fonts.
*/
.fonts-stage-2 h1, .fonts-stage-2 strong {
  font-family: LatoBold, sans-serif;
  font-weight: 700;
}
.fonts-stage-2 em {
  font-family: LatoItalic, sans-serif;
  font-style: italic;
}
.fonts-stage-2 strong em,
.fonts-stage-2 em strong {
  font-family: LatoBoldItalic, sans-serif;
  font-weight: 700;
  font-style: italic;
}
import React from 'react';
import { render } from 'react-dom';
import FoutStager from 'react-fout-stager';
import './lato-family.css';

render((
  <div>
    <h1>FOFT, or FOUT with Two Stage Render</h1>
    <p>
      This is a paragraph.
      <strong> This is heavier text.</strong>
      <em> This is emphasized text.</em>
      <strong><em> This is heavier and emphasized text.</em></strong>
    </p>
    <FoutStager
      stages={[{
        className: 'fonts-stage-1',
        families: [{ family: 'Lato' }],
        stages: [{
          className: 'fonts-stage-2',
          families: [
            { family: 'LatoBold', options: { weight: 700 } },
            { family: 'LatoItalic', options: { style: 'italic' } },
            { family: 'LatoBoldItalic', options: { weight: 700, style: 'italic' } }
          ]
        }]
      }]} />
  </div>
)), document.getElementById('root'));

Development and Contributing

This repository uses Neutrino and the following Neutrino middleware for developing, previewing, and building React components:

To get started:

  • Fork and clone this repo.
  • Install the dependencies with yarn.
  • Start the development server with yarn start.
  • Use CTRL-C to exit the development server.
  • Use yarn build to generate the compiled component for publishing to npm.

Feel free to open an issue, submit a pull request, or contribute however you would like. Understand that this documentation is always a work in progress, so file an issue or submit a PR to ask questions or make improvements. Thanks!