Skip to content

Section

Open .md
Live preview

Loading example…

A titled block of a page: a header row (title, count, description, actions) and a body. It never pads the inline edges (the page layout owns the gutter), and sections nest without stacking: each titled level steps its heading down and its vertical spacing tighter, while a titleless wrapper takes no level at all. Named by its title when it has one.

Two ways to fill it, which mix: the props (title, count, description, actions, with the children as the body) or the parts Section.Header, Section.Title, Section.Count, Section.Description, Section.Actions and Section.Body. As soon as a part is a direct child, the children are rendered as written and the body is wherever you place Section.Body.

import { Section } from "@jcsoftdev/ui/containers";

Single-component entry points tree-shake to just this component: @jcsoftdev/ui/containers/section.

<Section
title="Guardians"
description="People who can pick the student up."
count={3}
>
<p className="m-0 text-body text-ink-2">Section body.</p>
</Section>
Prop Type Default Description
as "article" | "div" | "section" "section"
title ReactNode
count ReactNode Outlined count next to the title (a record total, say).
description ReactNode
actions ReactNode Slot at the end of the header row; takes the full row under 560px of the section’s own width.
titleAs "h2" | "h3" | "h4" | "h5" | "h6" Heading element of the title. Defaults to h2, one level deeper per nested section.
divider boolean false Hairline above the section.
padded boolean true Vertical padding around the body. Defaults to true; false leaves the body edge to edge.
classNames Partial<Record<SectionPart, string>> Per-part classes merged with cn; consumer classes win. className still targets the root and is merged last.

* marks a required prop.

It also accepts the native props of the element or primitive it renders (for example className, id, aria-* and event handlers).

packages/ui/src/containers/section/section.tsx