Typography and Display Primitives
Typography and Display Primitives: anatomy, keyboard behavior, state, and theming in Askr.
Example
import { TypographyH1, TypographyLead, TypographyP } from '@askrjs/themes/components';
<>
<TypographyH1>Project activity</TypographyH1>
<TypographyLead>Changes across the current workspace.</TypographyLead>
<TypographyP>Filter the timeline by actor, action, or date.</TypographyP>
</>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 tokens — sizing off --ak-font-size-* (there's no separate --ak-type-* family; font size is the same scale used everywhere else in the theme), so switching themes updates every Typography component consistently rather than requiring per-component overrides. TypographyMuted pulls its color from --ak-color-text-subtle 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.
Related pages
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 Layout Primitives and Advanced Layout.