npm package: @register-ui/typography
Description: A tool for building websites with beautiful typography, that aligns perfectly to a basline grid.
Author: parker.pierpont
Latest version: 1.4.27

# Typography

A tool for building websites with beautiful typography, that aligns perfectly
to a basline grid.

## Why

Although there are existing tools for developing typographic systems,
they tend to be opinionated and hard to incorporate into frameworks and designs.

Additionally, they aren't typed, and as a result can be hard to work with for typescript users. They also tend to product output that is either opinionated,
or highly variable depending on the inputs you give it.

The goal of this utility is not to be a framework, or a system – it's only meant to simplify the creation of other systems or frameworks, because of the following:

- It doesn't care what font size, or line height you use – in any instance, you can force it to align to a certain basepoint grid.
- It builds-in the ability to detect if a font has already been loaded, and thus, is safe to use in functional react components.
- It is typesafe.
- It provides automatic tracking adjustment, and several inputs that allow client code to further define tracking for individual parts of the type scales.

## Other notable features

- Although this system uses the modular scale philosophy of defining type systems, we have found that modular scales can be great for typography that is _larger_ than the base font-size, but often to harsh when defining smaller sizes. Often, there's only one size that is still accessible to use in practice. For this reason, there is some logic built into how smaller sizes are generated. This simply allows for greater opportunity for use when creating _actual_ user interfaces, where there are often several variants of small-size text.

## Use

```js
import { typography } from '../';

const type = typography({
  baseFontSize: 20,
  adjustLargeSizeTracking: -0.01,
});

let scale_points = [4, 3, 2, 1, 0, -1, -2];

scale_points.forEach(point => {
  let styles = type.scale({
    scalePosition: point,
  });

  const div = document.createElement('div');
  const weight = point > 0 ? (point === 4 ? 800 : 700) : 400;
  div.style.cssText = `
   ${styles.toCss()}
   font-family: ${point > 0 ? ex.theme.headerFontFamily : ex.theme.bodyFontFamily}; font-weight: ${weight};`;
  div.innerText = `Hello, I'm the ${point} point.`;
  document.body.appendChild(div);
});
```

## Options

```ts
export interface VerticalRhythmOptions {
  /**
   * The root font size of the document.
   *
   * e.g. - What the root html element's default font size is
   * within your project.
   *
   * @default 16
   */
  htmlFontSizePx: number;

  /**
   * The base font size to use.
   *
   * @default 16
   */
  baseFontSize: number;

  /**
   * The approximate line height to use on elements
   * that are equal to, or smaller than the base font-size.
   *
   * When in doubt, go for a smaller value than normal, as
   * it will round-up when matching the baseline grid.
   *
   * @default 1.3
   */
  lineHeightUnitless: number;

  /**
   * The approximate line height to use on elements
   * that are larger than the base font-size.
   *
   * When in doubt, go for a smaller value than normal, as
   * it will round-up when matching the baseline grid.
   *
   * * @default 1.1
   */
  headerLineHeightUnitless: number;

  /**
   * The default size of the border around a text-containing
   * element. Allows the utility to factor this in to maintain
   * spacing on the defined grid.
   *
   * @default 1
   */
  defaultBorderWidthPx: number;

  /**
   * Snap to the baseline grid
   * @default 8
   */
  baselineGrid: number;

  /**
   * If a piece of type has less than this amount
   * of padding within it's line-height, it will
   * round up to the nearest baseline-grid divisible
   * value.
   * @default 2
   */
  minimumLinePadding: number;

  /**
   * A number between 0 and 1 that is used as a multiplier
   * to affect tracking. This multipier disproportionately
   * affects **larger** font sizes.
   * @default 0
   */
  adjustLargeSizeTracking: number;

  /**
   * A number between 0 and 1 that is used as a multiplier
   * to affect tracking. This multipier disproportionately
   * affects **smaller** font sizes.
   * @default 0
   */
  adjustSmallSizeTracking: number;

  /**
   * A number between 0 and 1 that is used as a multiplier
   * to affect tracking. This multipier affects all font sizes
   * globally.
   * @default 0
   */
  adjustGlobalTracking: number;

  /**
   * The modular scale 'ratio' that you'd like to use.
   * @default 1.225
   */
  scaleRatio: number;
}

export interface FontOptions {
  /**
   * Load google fonts.
   * Feeds directly into webfontloader
   * @see https://github.com/typekit/webfontloader#google;
   */
  googleFonts?: Google;

  /**
   * Load custom fonts.
   * Feeds directly into webfontloader
   * @see https://github.com/typekit/webfontloader#custom;
   */
  customFonts?: Custom;

  /**
   * The font family to use when the size is larger than
   * the base font size.
   */
  headerFontFamily: string[] | string;

  /**
   * The font family to use when the size is equal to or smaller
   * than the base font size.
   */
  bodyFontFamily: string[] | string;

  /**
   * The default weight of header text.
   * @default '400'
   */
  headerWeight: string;

  /**
   * The default weight of body text.
   * @default '400'
   */
  bodyWeight: string;
}

export type TypographyTheme = FontOptions & VerticalRhythmOptions;
```