Body text

Running text, emphasis, fine print and labels, each with its size and weight fixed.

Overview

Every run of text that is not a heading: a paragraph, a supporting line, a note, a label.

Paragraph

Do

Invoice INV-204 is due on Friday.

Sent 2 minutes ago

import { Body, BodyStrong, Caption, Stack } from "@hackcove/ui";

<Stack gap="xs">
  <Body as="p">
    Invoice <BodyStrong>INV-204</BodyStrong> is due on Friday.
  </Body>
  <Caption as="p">Sent 2 minutes ago</Caption>
</Stack>
Body copy is Body as="p", with BodyStrong for emphasis inside it and Caption for the fine print.
Don't

Invoice INV-204 is due on Friday.

Sent 2 minutes ago
import { Stack } from "@hackcove/ui";

<Stack gap="xs">
  <p>
    Invoice <strong>INV-204</strong> is due on Friday.
  </p>
  <small>Sent 2 minutes ago</small>
</Stack>
Plain HTML text elements carry no size, weight or colour of the theme. Every run of text is a typography part.

Meaning

Do

Saved.

Could not save: the name is taken.

import { Body, Stack } from "@hackcove/ui";

<Stack gap="xs">
  <Body as="p" tone="positive">
    Saved.
  </Body>
  <Body as="p" tone="danger">
    Could not save: the name is taken.
  </Body>
</Stack>
tone says what a run of text means: positive for "Saved.", danger for an error.
Don't

Saved.

Could not save: the name is taken.

import { Body, Stack } from "@hackcove/ui";

<Stack gap="xs">
  <Body as="p" color="brand">
    Saved.
  </Body>
  <Body as="p" color="muted">
    Could not save: the name is taken.
  </Body>
</Stack>
color is the hierarchy of text, not its meaning: an error in the accent colour reads as a link, and in muted grey as nothing at all.

Labels

Do
Billing

Invoices

import { Overline, SectionHeading, Stack } from "@hackcove/ui";

<Stack gap="xs">
  <Overline>Billing</Overline>
  <SectionHeading>Invoices</SectionHeading>
</Stack>
An Overline is the small label above a heading, naming the group it belongs to.
Don't
Invoices

Two invoices are due this week.

import { Body, Overline, Stack } from "@hackcove/ui";

<Stack gap="xs">
  <Overline>Invoices</Overline>
  <Body as="p">Two invoices are due this week.</Body>
</Stack>
An Overline is a span, not a heading: a section titled by one has no place in the page outline. Use SectionHeading.

Usage

  • Set a paragraph in Body as="p". Body is a span by default so it sits inside a sentence; a block of it stops at a readable line length.
  • Emphasise a run with BodyStrong inside the Body. Use Caption for fine print and metadata, as Caption as="p" when it stands alone.
  • Put Subtitle under a heading and Lead under a Display. Overline is the small all-caps label above a group, not a title.
  • tone says what a run means: positive, warn, danger, info or muted. It beats color, and the words still say it, so colour is never the only signal. color is only the hierarchy of the text.
  • numeric sets tabular figures so a column of amounts lines up, mono the monospace face for an id or a path, and truncate cuts a run to one line.
  • preserveNewlines on Body keeps the line breaks of text a person typed, such as a note.
  • Never write a bare <p>, <span>, <strong> or <small>: they carry none of the theme's type scale or colour.

Accessibility

  • Body, BodyStrong, Caption and Overline render a span, and Lead and Subtitle a p. as changes the element, for a p or an li, or a label for an Overline with htmlFor.
  • Overline is a label, not a heading: it adds nothing to the page outline.
  • truncate sets the full text as the title when the content is plain text, so a pointer user can read what was cut. Give a title of your own when the content is not.
  • A tone changes only the colour. The wording has to carry the meaning.

API

Body

Default running text. span (inline; as="p" for a paragraph), text-sm/5 normal, secondary. A block of it stops at a readable line length (max-w-[72ch]), wherever it sits. preserveNewlines keeps the line breaks in the text (a user-typed note); runs of spaces still collapse. tone colours it by meaning (positive for "Saved.", danger for an error; it wins over color), numeric sets tabular figures, mono the monospace face, and truncate cuts it to one line with an ellipsis (the full text becomes its title).


as
Type
any

color

Colour token; each component sets a sensible default.

Type
any

mono

The monospace face, for an id, a path or a command.

Type
boolean

numeric

Tabular figures, so a column of amounts lines up.

Type
boolean

preserveNewlines
Type
boolean

tone

A meaning's colour (see TextTone). Wins over color.

Type
"positive" | "danger" | "info" | "warn" | "muted"

truncate

One line, cut with an ellipsis where the container ends; the full text is the title.

Type
boolean

BodyStrong

Emphasised run of body text. span, text-sm/5 medium, primary text. Takes tone, numeric, mono and truncate like Body.


as
Type
any

color

Colour token; each component sets a sensible default.

Type
any

mono

The monospace face, for an id, a path or a command.

Type
boolean

numeric

Tabular figures, so a column of amounts lines up.

Type
boolean

tone

A meaning's colour (see TextTone). Wins over color.

Type
"positive" | "danger" | "info" | "warn" | "muted"

truncate

One line, cut with an ellipsis where the container ends; the full text is the title.

Type
boolean

Caption

Fine print / metadata. span (inline; as="p" for a block), text-xs/4 normal, tertiary. Takes tone, numeric, mono and truncate like Body.


as
Type
any

color

Colour token; each component sets a sensible default.

Type
any

mono

The monospace face, for an id, a path or a command.

Type
boolean

numeric

Tabular figures, so a column of amounts lines up.

Type
boolean

tone

A meaning's colour (see TextTone). Wins over color.

Type
"positive" | "danger" | "info" | "warn" | "muted"

truncate

One line, cut with an ellipsis where the container ends; the full text is the title.

Type
boolean

Overline

Small all-caps label above a group. span, text-xs semibold uppercase, tertiary. tone, numeric, mono and truncate are opt-in, as on Body.


as
Type
any

color

Colour token; each component sets a sensible default.

Type
any

mono

The monospace face, for an id, a path or a command.

Type
boolean

numeric

Tabular figures, so a column of amounts lines up.

Type
boolean

tone

A meaning's colour (see TextTone). Wins over color.

Type
"positive" | "danger" | "info" | "warn" | "muted"

truncate

One line, cut with an ellipsis where the container ends; the full text is the title.

Type
boolean

Lead

The supporting sentence under a Display. p, text-lg/7 normal, secondary.


as
Type
ElementType

color

Colour token; each component sets a sensible default.

Type
"brand" | "default" | "muted" | "secondary" | "tertiary"

Subtitle

Supporting line under a heading. p, text-sm/5 normal, secondary.


as
Type
ElementType

color

Colour token; each component sets a sensible default.

Type
"brand" | "default" | "muted" | "secondary" | "tertiary"