Section
Content scaffolding — a heading with optional icon, supporting text and actions, over a body and a footer.
The board
Everything the Amber Hall has posted, at a glance.
Usage
import {
SectionRoot, SectionHeader, SectionIcon, SectionTitleGroup,
SectionTitle, SectionDescription, SectionActions, SectionBody, SectionFooter,
} from "@kanzo-tech/ui";<SectionRoot>
<SectionHeader>
<SectionIcon><ScrollTextIcon /></SectionIcon>
<SectionTitleGroup>
<SectionTitle>Open contracts</SectionTitle>
<SectionDescription>Posted to the board. Anyone chartered may claim them.</SectionDescription>
</SectionTitleGroup>
<SectionActions><Button>Edit</Button></SectionActions>
</SectionHeader>
<SectionBody>{/* … */}</SectionBody>
</SectionRoot>Section vs Shell
Different axis, so they never compete. Shell positions the window —
regions, asides, what scrolls. Section positions the content inside one of those regions,
and nests within ShellMain.
The one header vocabulary
Section is where a heading with an optional icon, supporting text and end-aligned controls is
described, once, for every screen that needs one.
CardHeader and DialogHeader have this same shape and are not part of it — a header wired
to a machine stays with its machine, and DialogHeader wires Ark's aria-labelledby. That is
the header rule.
Scale
scale is what actually differed between the three. It changes breathing room and the title's
weight, nothing else.
section(default) — a block within a screen. No padding of its own, so it sits in whatever container you put it in.page— the top of a screen. Adds the page padding and a heavier title.
<SectionHeader scale="page">
<SectionTitleGroup>
<SectionTitle level={1} scale="page">The board</SectionTitle>
</SectionTitleGroup>
</SectionHeader>level and scale are deliberately separate. How big a title looks and where it sits in
the document outline are different questions — tying them would force a visual choice to change
your heading semantics. Set level={1} on a page title because it is the page's heading, not
because it is large.
Layout
SectionHeader is a flex row, not a grid: SectionTitleGroup plus ms-auto on the actions
aligns them without a second code path under RTL, and handles the optional icon a two-column grid
could not.
SectionTitleGroup carries min-w-0, which is what lets a long title truncate instead of
pushing the actions off the row.
Open contracts
Posted to the board. Anyone chartered may claim them.
Bordered
bordered draws a separator under the header, for when the body below it is dense enough that
the heading would otherwise float.
Party rules
Checked when a party signs, and again when it comes back.
Body and footer
SectionBody renders <section>, never <main> — it nests inside a shell that already
owns the page's single <main> landmark.
SectionFooter carries a surface and a top border, unlike the header: it sits against the
bottom of a scrolling body and has to separate itself from the content sliding under it.
API Reference
SectionHeader
| Prop | Type | Default |
|---|---|---|
scale | "page" | "section" | "section" |
bordered | boolean | false |
Extends ComponentProps<typeof ark.header>, so asChild, ref and every native prop pass
through.
SectionTitle
| Prop | Type | Default |
|---|---|---|
level | 1 | 2 | 3 | 4 | 5 | 6 | 2 |
scale | "page" | "section" | "section" |
Renders h{level} directly rather than through the ark factory, so it extends
ComponentProps<"h2"> with ref omitted — and there is no asChild, because level already
covers what you would reach for it.
SectionBody
| Prop | Type | Default |
|---|---|---|
scale | "page" | "section" | "section" |
Renders <section>, never <main>. Extends ComponentProps<typeof ark.section>.
Other parts
SectionRoot, SectionIcon, SectionTitleGroup and SectionActions have no props of their
own and extend ComponentProps<typeof ark.div>; SectionDescription is ark.p and
SectionFooter is ark.footer. All of them take asChild, ref and their element's native
props.
Every part's props are exported as an interface — SectionBodyProps, SectionHeaderProps,
SectionRootProps and SectionTitleProps — so a wrapper can take the same props without restating
them.