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

@gvrs/chakra-capsize

v2.0.0

Published

Chakra Text & Heading components with whitespace trimmed

Downloads

4

Readme

yarn add @gvrs/chakra-capsize

Usage

import { withCappedText } from "@gvrs/chakra-capsize/theme";
import { CappedText, CappedHeading } from "@gvrs/chakra-capsize";
import { ChakraProvider, extendTheme } from "@chakra-ui/react";
import robotoFontMetrics from "@capsizecss/metrics/roboto";

const theme = extendTheme(
  defaultTheme,
  {
    fonts: {
      heading: "Roboto",
      body: "Roboto",
    },
    capHeights: {
      sm: 10,
      md: 14,
      lg: 18,
      xl: 24,
    },
  },
  withCappedText({
    fontMetrics: {
      Roboto: robotoFontMetrics,
    },
  })
);

const App = () => {
  return (
    <ChakraProvider theme={theme}>
      <div>
        <CappedHeading as="h1" size="2xl">
          Hi!
        </CappedHeading>
        <CappedText>
          This paragraph will have surrounding whitespace trimmed. It will also
          have space between the lines of text reduced to 0.
        </CappedText>
        <CappedText capHeight="lg" lineGap={4}>
          Setting a capHeight overrides any fontSize prop for more exact sizing.
          Meanwhile, a lineGap uses the Chakra 'spacings' scale to insert space
          between lines of text just like any other Chakra element.
        </CappedText>
      </div>
    </ChakraProvider>
  );
};

Theming

Setting up your theme requires the following:

  • A defined body & heading font
  • Font metrics for each defined font
  • Text size theme keys
  • Extending the theme with withCappedText

Body & Heading font

Capsize recommends using non-system / non-fallback fonts to get the best results & most accurate trimming.

Specying fonts can be done in the following ways;

  1. Using chakra's fonts theme key (default)
    • chakra-capsize will use the theme's fonts.body & fonts.heading theme values for <CappedText> & <CappedHeading> respectively unless a more specific font family is passed in.
  2. Setting fontFamily on components.Text / components.Heading.
    • This is particularly useful when you have variants that use different font faces such as pull quotes or buttons.
  3. Passing fontFamily directly to a <CappedText> / <CappedHeading>.
    • The fontFamily prop passed will override any value on Components.Text / components.Heading or the fonts theme key.

Font metrics for each defined font

Once your component has a font, chakra-capsize requires the corresponding font metrics to be available for calculating the correct trim values.

Importantly, the key used when passing metrics to the withCappedText##fontMetrics option must exactly match the font family name.

For example, when using the Open Sans font, you must set it up like so:

withCappedText({
  fontMetrics: {
    'Open Sans': { ... }
  }
})

// ...

<CappedText fontFamily="Open Sans">...

Text size theme keys

chakra-capsize has two primary configuration methods, mapping to the underlaying implementation of capsize:

  1. Text size
  2. Space between lines of text

Text size

chakra-capsize allows defining the Text size as either a fontSize value, or a capHeight value, where capHeight will override fontSize if set.

By default, chakra-capsize will use fontSize as it's the easiest to get started with, and often more closely matches measurements from design tools such as Figma & Sketch.

When you're ready to have more accurate control over the exact size of text, you can use the capHeight prop by setting the capHeights key in your Chakra theme:

const theme = {
  capHeights: {
    sm: 10,
    md: 12,
    lg: 14,
    // ...
  },
};

Then the corresponding values can be passed either directly to a <CappedText> / <CappedHeading> component:

<CappedText capHeight="lg">...

or on variants, etc, in your component theme:

const theme = {
  components: {
    Text: {
      variants: {
        huge: {
          capHeight: "2xl",
        },
      },
    },
  },
};

Space between lines

When multiple lines of text are displayed, a default gap of 0px is applied, resulting in lines of text whos capital letters press up againt each other.

This gap can be configured in multiple ways, two of which (lineGap & leading) are closely related while the third (lineHeight) is available to support values supplied in Chakra's default theme.

lineGap is the number of pixels between the bottom of one capital letter and the top of a capital letter on the next line. lineGap uses the spacings theme key.

leading can be thought of as lineGap + capHeight. Or, to put it another way; the distance from the bottom of one capital letter to the bottom of a capital letter on the next line. leading uses the sizes theme key.

lineHeight will set the value directly onto the text, however it's important to note that it will not affect the spacing at the top/bottom of the text element (it will remain trimmed).

As with capHeight, lineGap & leading can be specified on the component directly:

<CappedText lineGap={6}>...

or on variants, etc, in your component theme:

const theme = {
  components: {
    Text: {
      variants: {
        huge: {
          lineGap: 12,
        },
      },
    },
  },
};

<CappedText> & <CappedHeading>

Extending Chakra's <Text> and <Heading> components, <CappedText> / <CappedHeading> uses capsize to trim space surrounding and between lines of text.

Note when using isTruncated or noOfLines props: To avoid ascenders and descenders from being cut off (due to overflow: hidden), an extra <span> element is inserted inside the element when either isTruncated or noOfLines is set.

Props

All of <Text> / <Heading>'s props are fully supported. In addition, the following props are available:

A note on responsive values: Each of the following props fully support responsive formats (both array and object) with one restriction: a base size must be set, otherwise an error is thrown.

capHeight

Specifies the height, in pixels, of a capital letter in the line of text. Internally, chakra-capsize trims surrounding whitespace via capsize which makes capHeight equivalent to setting min-height on a <div>.

Can be a number, or one of the capHeights theme key (which resolves to a number).

When set, capHeight will override any fontSize values set.

lineGap

Default: 0.

When multiple lines of text are displayed, lineGap specifies the gap, in pixels, between those lines.

lineGap uses the spacings theme scale.

When set, lineGap will override any leading or lineHeight values set.

leading

When multiple lines of text are displayed, leading specifies the distance between one baseline to the next.

leading uses the sizes theme scale.

sx

Using the sx prop is fully supported, however behaviour is undefined when attempting to set any of fontSize, lineHeight, ::before, or :;after. It is recommended to only set fontSize and lineHeight via props, and avoid setting ::before or ::after at all.

truncatedRef

<CappedText> and <CappedHeading> can be passed a ref to access the React DOM node under the hood. However, when either isTruncated or noOfLines is set, an extra inner <span> is rendered; to access this inner DOM node, use the truncatedRef prop.

withCappedText(options)

import { withCappedText } from '@gvrs/chakra-capsize/theme'

Add support for capsize to your Chakra theme via withCappedText. It must be passed in as an argument to Chakra's extendTheme to correctly extend the the values required.

options.fontMetrics

Capsize requires a set of known font metrics to correctly trim whitespace from around and between lines of text.

chakra-capsize also uses font metrics to support theming with Chakra.

The easiest way to generate font metrics is with the @capsizecss/metrics package:

import robotoFontMetrics from "@capsizecss/metrics/roboto";
// ...
extendTheme(
  withCappedText({
    fontMetrics: {
      Roboto: robotoFontMetrics,
    },
  })
);

(See the capsize docs for more ways of obtaining the necessary font metrics.)

options.defaultFontSize

Default: 'md'

For chakra-capsize to work correctly out of the box, a default font size must be set for all <Text> / <CappedText> / <Heading> / <CappedHeading> components. The defaultFontSize option will use the fontSizes theme scale.

options.htmlFontSize

Default: 16

To safely convert between rem & px font sizes needed by Capsize, chakra-capsize must know what the html font size is. All modern browsers set this default to 16px, and chakra-capsize does too.

You should only ever need to set this if you explicitly change the font-size of the html element.

Frequently Asked Questions

Why are descenders cut off when using isTruncated or noOfLines?

To fix it, add a lineGap that is at least the height of the descenders.

This occurs due to chakra-capsizes default of lineGap = 0 which instructs capsize to set the container to be the same height as a capital letter. Then when isTruncated sets overflow: hidden, the ascenders & descenders are cut off. By setting a lineGap (or leading or lineHeight), the height of the container is increased to stop the cut off while maintaining the correct