Typography
Renders text on the library's type scale, so headings, body copy and captions all share the same size steps.
import { Typography } from 'neba';
<Typography level="h2">A sheet of cut acrylic</Typography>
<Typography>Every surface is the same material at a different opacity.</Typography>;Props
| Prop | Type | Default | Description |
|---|---|---|---|
| level | 'h1'…'h6' | 'lead' | 'body' | 'caption' | 'overline' | 'body' | The type scale, and the element that carries it. Not called `variant`: that word already means the weight of a surface here |
| colorshared | 'primary' | 'secondary' | 'success' | 'warning' | 'danger' | 'info' | — | Semantic colour role. Unlike every other component this has no default: unset means the page’s own colour |
| weight | 'regular' | 'medium' | 'semibold' | 'bold' | — | Overrides the weight the level would pick |
| align | 'start' | 'center' | 'end' | 'justify' | — | Text alignment |
| lines | number | — | Clamps to this many lines with an ellipsis. 1 is a single-line truncation |
| gutter | boolean | false | Adds the space below. Off by default: a component that injects margins is one a layout has to fight |
| render | useRender.RenderProp | — | Changes the element without changing the type scale. Base UI's own escape hatch |
| children | ReactNode | — | The text |
| transitionshared | NebaTransition | — | An entrance animation, run once on mount (transition="fade"). Wrap it in an Animate* component for a trigger or a replay |
Two props differ from the rest of the library. The type scale is chosen with level rather than variant, since variant means the weight of a surface everywhere else. And color has no default: leave it unset and the text inherits the surrounding colour.
The root carries the class neba-typography. It is the hook a stylesheet uses to reach the text from outside React — .neba-typography { text-wrap: balance } — since the utilities a level resolves to are not a contract.
Examples
level
level sets both the type scale and the element rendered. body matches the body step of an md Card, so a paragraph inside a card and one outside it are the same size. The heading steps tighten their leading as they grow.
color
lines
lines={1} truncates to one line with an ellipsis. 2 or more is a line clamp at that many lines.
render
Use render when the element level implies is not the element you need: a subheading that should stay out of the document outline, or a <p> that has to look like a heading.
<Typography level="h3" render={<p />}>
Looks like a heading, is not one
</Typography>gutter
gutter is off by default, so there are no vertical margins. Turn it on for a run of prose; leave it off inside a flex container that already owns its spacing.
Overriding the size
Each level's leading is a ratio, not a length, so a size set through className keeps a line box in proportion to it:
<Typography level="h2" className="text-[2.75rem]!">
42
</Typography>The ! is required, and it is the way to override the weight, the ink and the gutter too. The scale is written at two-class strength so that it clears a host stylesheet — .prose h2 and VitePress's .vp-doc h2 both set font-size, line-height, letter-spacing and font-weight on the tag, at a specificity a single utility cannot reach, and without this a Neba heading inside rendered Markdown took the article's type instead of its own. There is no specificity above that rule and below a plain utility, so ! is the way in. Add a leading-* beside it when the proportion is what you want to change.
align and lines are deliberately left as plain utilities: nothing styles text-align or a line clamp by tag name, so className reaches them without !.