Prose
Optional typography sugar around long-form text (markdown, message bodies, paragraphs). Documents intent ("this content is long-form text") and provides column-stacking defaults. Wrap chains work without <Prose> — silvery's CSS-correct flex defaults handle wrap automatically.
Import
import { Prose } from "silvery"Status: optional sugar
silvery uses CSS-correct flex defaults (flexShrink: 1, alignContent: stretch, plus CSS §4.5 flex-item auto min-size). Wrap chains work without ceremony — both forms below produce the same wrapping behavior:
// Both work — choose Prose for typography intent
<Box flexDirection="column">
<MarkdownView source={text} />
</Box>
<Prose>
<MarkdownView source={text} />
</Prose>Use <Prose> when the surrounding context benefits from a named "this is prose" boundary (e.g., when typography presets like H1, Muted, Blockquote are nested inside).
History
Before silvery's CSS-defaults flip (April 2026), flexily defaulted flex-shrink: 0 (Yoga semantics). Without flexShrink={1} minWidth={0} on every box in the chain from a fixed-width ancestor down to a <Text wrap="wrap">, an intermediate row/column measured at sum(children.maxContent) and the wrappable Text never wrapped. <Prose> was created as a named primitive so consumers didn't have to remember that incantation. The flip to CSS-correct defaults plus flexily's auto min-size implementation made the chain unnecessary; <Prose> survives as a typography primitive.
Defaults
flexDirection: "column"— paragraphs stack vertically.
Other flex props (flexShrink: 1, alignContent: stretch, auto min-size) come from silvery's CSS-correct defaults; <Prose> doesn't need to set them. Any prop can be overridden — pass flexGrow={1} for a row child that should fill, or flexDirection="row" if your prose stitches inline runs.
Props
ProseProps extends BoxProps, so every Box prop is available. The defaults above apply unless a caller-provided prop overrides them.
Examples
Wrapping a markdown view
import { Prose } from "silvery"
import { MarkdownView } from "./MarkdownView"
;<Prose>
<MarkdownView source={longMarkdown} />
</Prose>Wrapping multiple paragraphs
<Prose gap={1} paddingX={1}>
<Text wrap="wrap">{paragraph1}</Text>
<Text wrap="wrap">{paragraph2}</Text>
</Prose>Inside a flex row
<Box flexDirection="row" gap={1}>
<Text bold color="$fg-accent">
●
</Text>
<Prose flexGrow={1}>
<MarkdownView source={response} />
</Prose>
</Box>Historical anti-pattern (now obsolete)
Pre-CSS-defaults, the wrap chain required threading flexShrink={1} minWidth={0} from any fixed-width ancestor down to wrappable text:
// ❌ Pre-flip (Yoga defaults) — easy to forget one prop in a deep chain
<Box flexDirection="column" flexShrink={1} minWidth={0}>
<MarkdownView source={text} />
</Box>Both forms now wrap correctly — <Prose> survives as documentation of typography intent, not as a wrap-enablement primitive.
See Also
- Box -- the primitive Prose wraps.
- Text --
wrap="wrap"is the typical leaf inside Prose. - typography -- typography presets (
H1,Muted,Blockquote) compose with Prose for full document layouts.