A titled group of content inside a panel or a page, such as a stop's departures or the lines that call at it: a small heading in capitals, an optional action beside it, and the caller's content below.
When to use
Use Section for a titled group of content inside a panel or a page, such as a stop's departures or the lines that call at it.
| Use instead | When |
|---|---|
| Surface | The group needs a card or a box of its own, with a fill, an edge or a shadow |
| Accordion | Each group opens and closes its content under its heading |
| Tabs | One group shows at a time, picked from a row of tabs |
| Fieldset | The group is a set of related form controls, named by its legend |
| Separator | Two groups need a line between them and no heading |
Kongens Nytorv
Metro M1, M2 and M3.
Departures
- 5C Husum Torv 08:14
- 5C Lufthavnen 08:17
- 350S Ballerup St. 08:21
Props
| Name | Type | Default | Description |
|---|---|---|---|
title* | ReactNode | — | What the section is about, in a word or two and in sentence case: "Departures". Set in capitals by the style; it names the section for screen readers. Required. Replaces the HTML title attribute |
children | ReactNode | — | The section's content, below the title |
action | ReactNode | — | One small action at the end of the header, such as a small outline LinkButton to everything the section lists |
slotProps | { header?: ComponentProps<"div", {}, HTMLProps> | undefined; title?: ComponentProps<"h3", {}, HTMLProps> | undefined; action?: ComponentProps<"div", {}, HTMLProps> | undefined; content?: ComponentProps<"div", {}, HTMLProps> | undefined; } | — | Props for each part: header, title, action, content. |
title (required)ReactNode, default —- What the section is about, in a word or two and in sentence case: "Departures". Set in capitals by the style; it names the section for screen readers. Required. Replaces the HTML
titleattribute childrenReactNode, default —- The section's content, below the title
actionReactNode, default —- One small action at the end of the header, such as a small
outlineLinkButton to everything the section lists slotProps{ header?: ComponentProps<"div", {}, HTMLProps> | undefined; title?: ComponentProps<"h3", {}, HTMLProps> | undefined; action?: ComponentProps<"div", {}, HTMLProps> | undefined; content?: ComponentProps<"div", {}, HTMLProps> | undefined; }, default —- Props for each part:
header,title,action,content.
Use it
import { Section } from '@mylder/perron'Ask your agent
search_docs({ query: "Section" })Keyboard and ARIA
Section has no keys of its own and is never focusable. The caller's action, then the caller's content, are reached in reading order.
| Key | Does | From |
|---|---|---|
Tab | Moves to the first focusable element in the action, then on into the content | The browser |
Shift+Tab | Moves back through the content and the action, out to what came before the Section | The browser |
| Element | Role | Accessible name from | States announced |
|---|---|---|---|
root | region, from a section with an accessible name; generic when render makes it a div | aria-labelledby, the title's id: its text | None |
header | None (generic div) | None | None |
title | heading, level 3, or the level slotProps.title.render gives | Its text, from title, read as written in sentence case | None |
action | None (generic div); the caller's controls carry their own roles | The caller's controls' own names | Theirs |
content | None (generic div); the caller's content carries its own roles | None | None |
What axe won't catch, from the contract, each with how this component meets it:
- Everything the eye is told, the ear is told, for every shape each prop accepts: the eye gets a grouping under a heading, and the ear the same heading and a region named by it; the capitals are style over sentence-case text (CR-7), so a screen reader reads the word, not its letters.
- Every landmark and named region has an accessible name: the root is a
sectionnamed by its own title througharia-labelledby(CR-2), and theDefaultstory'splaychecks the region's name. - Every default label can be overridden: none here; Section owns no string.
- Every shape the type accepts renders, in every variant:
title,actionandchildreneach render a string, an element and an array; the title is a heading, so it takes phrasing content, andcontentandactionaredivs, so block content such as a list is valid inside them. - A hidden copy kept for animation is
aria-hidden, and a collapsed region isinert: none here; nothing animates or collapses. - Native semantics first: a native
sectionandh3, witharia-labelledbythe only ARIA, naming the region from the heading that is already there; the action holds the caller's owna hreforbutton. - Focus moves in reading order and returns on close: the title, the action and the content follow each other in the DOM as on screen, including when the header wraps (CR-6); Section never moves focus, and nothing in it closes.
- Every target is at least
size.target-minsquare: Section has no target of its own; the action's targets are the caller's components, which keep their own sizes (a small LinkButton issize.button-sm). - Loops stop when the system asks for less motion: none here; nothing moves.
Owned strings
No owned strings: every word Section shows or announces comes from the caller, through title, action and children, and the region's name is the title.
Do and don't
For a caller using the component, with the reason. Each row is a rule: a must row's Don't is never right, a should row's needs a reason, and Checked by says what catches the Don't in a caller's code.
| Rule | Level | Do | Don't | Checked by |
|---|---|---|---|---|
| DD-1 | must | Write the title in sentence case, a word or two, and let the style set the capitals: "Departures" | Type the title in capitals: a screen reader may spell it out letter by letter, and content design writes source text in sentence case | review |
| DD-2 | must | Give the title the level that fits the page's outline through slotProps.title.render: h3 under a panel's h2, h4 inside an h3's section | Skip a level, or wrap a heading element inside title: the part is already a heading, and a heading inside a heading is invalid | review |
| DD-3 | must | Put one small, neutral action in the header, such as a small outline LinkButton to the whole list | Put the panel's main action, or a brand button, in a section's header: a screen has one brand action, and it belongs to the panel | review |
| DD-4 | should | Give the content one block per child: a paragraph, a list, a row of buttons | Pass a sentence with a link in it straight as children: each element becomes a block of its own, so wrap the sentence in a paragraph | review |
| DD-5 | should | Space sections apart in the caller's layout, space.600 between blocks of a pane | Add margins or padding to Section with raw values, or rely on it for the space between sections: it adds none | review |
| DD-6 | should | Wrap a section in a Surface when it needs a card or a box of its own | Add a fill, border or shadow to Section through className: a box is Surface's job, and the ladder lives there | review |
| DD-7 | should | Render the root as a div through render when the group is too small to be worth a region of its own | Leave a screen full of tiny named regions: a screen reader's landmark list then says less than its headings | review |
| DD-8 | must | Leave a group that opens and closes to a collapsible component, built on Base UI's Collapsible | Build a collapsible group from Section by hiding its content: it brings no button, state or keys | review |
| DD-9 | must | Set the title's id through slotProps.title.id | Put an id on the element in slotProps.title.render: it replaces the generated one and the region loses its name | review |