Askr
UI & Components

Typography and Display Primitives

Use typography and display primitives with the current published Askr packages.

  • @askrjs/themes/typography0.0.13

How to use typography and display primitives

Typography and Display Primitives should use the standard themed surface unless the application is deliberately implementing its own design system on top of @askrjs/ui.

  1. Import the themed component from @askrjs/themes/components; use @askrjs/ui directly only when building a custom visual system.
  2. Keep typography and display primitives labels, state, and application actions visible at the call site instead of styling internal DOM nodes.
  3. Verify keyboard behavior, focus movement or return, disabled state, and both standard themes.
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@askrjs/themes/components';

<Card>
  <CardHeader><CardTitle>Project health</CardTitle><CardDescription>Updated just now</CardDescription></CardHeader>
  <CardContent><ProjectHealth /></CardContent>
</Card>

Purpose

This page covers the `Typography` family in `@askrjs/themes/typography` — a set of styled text components (`TypographyH1` through `TypographyH4`, `TypographyP`, `TypographyBlockquote`, `TypographyList`, `TypographyLead`, `TypographyMuted`, and a generic `Typography` wrapper) that give you consistent type scale and rhythm without writing raw heading and paragraph markup by hand everywhere. There's no `@askrjs/ui` equivalent because text rendering doesn't need behavior — this is pure presentation, so it lives entirely in the themes package.

Install and import

Everything comes from `@askrjs/themes/typography`, which resolves to the same shared component bundle as the broader `@askrjs/themes/components` barrel. Import only the specific variants you need — `TypographyH1`, `TypographyLead`, `TypographyMuted`, and so on — rather than the whole set, since most pages only use a handful of these at once.

Live examples

Use `TypographyH1` through `TypographyH4` for actual document headings, `TypographyP` for body copy, and `TypographyLead` for the larger intro paragraph that often follows a page's main heading. `TypographyMuted` is the standard choice for secondary text — timestamps, helper copy, de-emphasized labels — and `TypographyBlockquote` and `TypographyList` cover quoted and list-formatted content that still needs to match the rest of the type scale.

Anatomy

Each `Typography*` component is a single element wrapping whatever native tag makes sense for its role — headings render heading tags, `TypographyP` renders a paragraph, and so on — with no internal nesting or sub-parts to manage. The generic `Typography` component is the base wrapper the more specific variants build on, useful when you want typographic styling without committing to a specific semantic tag.

State model

Rendering is all these components do — there's nothing stateful to track once you land on typography and display primitives. Every one of them shares the same generic prop shape, `CatalogComponentProps`, giving you `as` to swap which element gets rendered and `asChild` to merge props onto a child rather than wrap it. That's how, say, `TypographyH2` can render as an `h3` when you need the visual weight of an H2 without breaking your document's heading hierarchy.

Keyboard and accessibility

Because these are static text elements, there's no keyboard interaction to design for. The main accessibility responsibility falls on you: use the `as` prop deliberately to keep the actual heading level correct for the page's outline, since the visual size of `TypographyH1`–`H4` is independent from which heading tag it renders. Screen readers navigate by real heading level, not by font size, so don't pick a `Typography` variant purely for its look if it puts the wrong tag in the document.

Styling and tokens

Type scale, weight, and color come from the theme's shared type tokens, so switching themes or overriding `--ak-type-*` variables updates every `Typography` component consistently rather than requiring per-component overrides. `TypographyMuted` pulls from the muted-foreground color token specifically, which keeps secondary text in sync with other de-emphasized UI (helper text, placeholder text) elsewhere in the theme.

API

Every variant accepts the same `CatalogComponentProps`: `as?: CatalogElement` to override the rendered tag, `asChild?: boolean` to compose onto a child element, `children`, and `class`, plus any other native attribute since the type is a loose `Record<string, unknown>` intersection. There are no variant-specific props beyond that — size and weight are baked into which `Typography*` component you choose, not configured through props.

Edge cases

Because `as` lets you swap the underlying tag freely, it's easy to end up with a page that looks right but has a broken heading outline — worth a periodic accessibility check rather than trusting the visual hierarchy. Long unbroken strings (URLs, IDs) inside `TypographyP` will overflow their container unless you handle wrapping yourself; there's no automatic truncation or word-break behavior built in.

Card's `CardTitle` and `CardDescription` cover heading and text needs specifically inside a card and don't need to be paired with `Typography` separately. Field's label and description parts handle typography inside forms with their own conventions. For page-level structure that typography sits inside, see Application Layout and Advanced Layout.