Component Kitchen Sink
Every MDX component the chapter renderer knows about, stacked back to back so vertical rhythm is easy to eyeball.
This page exists purely to exercise the reading surface. It is not a chapter — it is every block the MDX renderer knows how to draw, laid out in the order that stresses the spacing rules hardest: heading against figure, callout against code, showcase against table. If two blocks collide or drift apart here, they do it everywhere.
Body copy sits at the size chosen in the toolbar, and every gap below is measured in
em, so the rhythm holds at Small through Extra Large. Toggle focus mode
(⌘+.) to drop the sidebar and table of contents and bring up the
margin reading ruler on the right.
A paragraph, then a second paragraph, so the gap between them is visible without
squinting. Inline treatments live here too: useControllableState as inline code,
bold for emphasis, and a link back to the chapter list with its
underline offset.
A pull quote in the serif face, set italic. It should breathe on both sides without leaving a hole in the column.
Source references are inline elements, so they should sit on the baseline without disturbing line height: radix/packages/react/context/src/createContext.tsx.
The rule above separates two stretches of prose. It carries the largest gap in the scale, which is what makes it read as a section break rather than a divider.
Third-level headings introduce a subsection without the horizontal rule that h2
draws. The gap above them is smaller than the gap above an h2 but larger than the
gap between paragraphs.
Fourth-level headings sit closest to their body copy — the gap below is deliberately tight so the heading reads as attached to the paragraph it introduces.
Code blocks carry equal margins top and bottom, so a block sandwiched between two paragraphs is centred in its gap.
function createContextScope<T>(scopeName: string) {
const Context = React.createContext<T | null>(null);
function Provider({ children, ...value }: T & { children: React.ReactNode }) {
const memo = React.useMemo(() => value, Object.values(value)) as T;
return <Context.Provider value={memo}>{children}</Context.Provider>;
}
function useScope(consumerName: string): T {
const context = React.useContext(Context);
if (context === null) {
throw new Error(`\`${consumerName}\` must be used within \`${scopeName}\``);
}
return context;
}
return [Provider, useScope] as const;
}Two code blocks in a row collapse to a single gap rather than stacking two:
export type Placement = `${Side}` | `${Side}-${Alignment}`;Tables are full-bleed inside the column and scroll horizontally on narrow screens.
| Pattern | Owner | Since | Status |
|---|---|---|---|
| Compound Component | Radix | v0.1 | Stable |
Slot / asChild | Radix | v0.1 | Stable |
| Positioning Engine | Floating UI | v1.0 | Stable |
| Safe Polygon | Floating UI | v0.19 | Experimental |
| Collection System | Radix | v1.0 | Stable |
Figures carry a caption block with an optional serif number and a monospace credit line.
A paragraph between two figures, to check that the gap under a caption matches the gap above the next block.
Showcases break out further than figures and put the component on a textured surface with a metadata bar.
A caption pinned to the showcase above — it should read as attached to the frame, not as a new paragraph.
The lab mounts lazily once it scrolls within 200px of the viewport, so the skeleton below should be the same height as the playground that replaces it — no jump.
A compound component shares state through context rather than props, which is the reason the markup stays the consumer's to arrange.[2] Hover either mark to see the preview card.