The top of the detail panel: it names what the panel shows, a line's vehicle by its line badge and destination or a stop by its marker and name, with a line under it and room for the panel's own controls.
When to use
Use DetailHeader for the top of a detail panel the screen draws itself, to name the line's vehicle or the stop the panel shows.
| Use instead | When |
|---|---|
| DetailPanel | The whole panel is wanted, opening beside the map with its close button; it draws a DetailHeader of its own |
| Section | A part inside a panel needs a heading |
5C Husum Torv
Variants and states
| Rest | |
|---|---|
| Line | 5C Husum TorvNext stop: Nørreport St. ~08:16 |
| Stop | Nørreport St.Metro, S-tog and buses |
- Rest
5C Husum Torv
Next stop: Nørreport St. ~08:16
Props
| Name | Type | Default | Description |
|---|---|---|---|
variant | 'line' | 'stop' | 'line' | What the panel shows: line heads a vehicle or a line with its line badge and destination; stop heads a stop or station with its marker and name. Set on the root as data-variant. |
line | 'm1' | 'm2' | 'm3' | 'm4' | 'a' | 'b' | 'c' | 'e' | 'f' | 'h' | 'bus' | 'regional' | — | The line whose colours the mark takes, typed as LineBadge's and StationIcon's line. In line, the badge's colours, needed with lineName; in stop, the marker's colour, left out for a stop several lines serve. |
lineName | ReactNode | — | The line's short name as riders know it, "5C", "M2" or "A": the badge's label in line, also read first in the title. Not used in stop. |
title* | ReactNode | — | The panel's title: the destination in line ("Husum Torv"), the stop's name in stop ("Nørreport St."). Required. Replaces the HTML title attribute. |
subheader | ReactNode | — | One supporting line under the title, such as "Next stop: Nørreport St." or the lines a stop has. |
action | ReactNode | — | The panel's own controls at the end of the row, such as a "Show on map" button. The panel's close button is DetailPanel's, from the Sheet, and needs no place here. |
slotProps | { mark?: DetailedHTMLProps<HTMLAttributes<HTMLDivElement>, HTMLDivElement> | undefined; title?: DetailedHTMLProps<HTMLAttributes<HTMLHeadingElement>, HTMLHeadingElement> | undefined; subheader?: DetailedHTMLProps<HTMLAttributes<HTMLDivElement>, HTMLDivElement> | undefined; action?: DetailedHTMLProps<HTMLAttributes<HTMLDivElement>, HTMLDivElement> | undefined; } | — | Props for each part: mark, title, subheader, action. |
variant'line' | 'stop', default'line'- What the panel shows:
lineheads a vehicle or a line with its line badge and destination;stopheads a stop or station with its marker and name. Set on the root asdata-variant. line'm1' | 'm2' | 'm3' | 'm4' | 'a' | 'b' | 'c' | 'e' | 'f' | 'h' | 'bus' | 'regional', default —- The line whose colours the mark takes, typed as LineBadge's and StationIcon's
line. Inline, the badge's colours, needed withlineName; instop, the marker's colour, left out for a stop several lines serve. lineNameReactNode, default —- The line's short name as riders know it, "5C", "M2" or "A": the badge's label in
line, also read first in the title. Not used instop. title (required)ReactNode, default —- The panel's title: the destination in
line("Husum Torv"), the stop's name instop("Nørreport St."). Required. Replaces the HTMLtitleattribute. subheaderReactNode, default —- One supporting line under the title, such as "Next stop: Nørreport St." or the lines a stop has.
actionReactNode, default —- The panel's own controls at the end of the row, such as a "Show on map" button. The panel's close button is DetailPanel's, from the Sheet, and needs no place here.
slotProps{ mark?: DetailedHTMLProps<HTMLAttributes<HTMLDivElement>, HTMLDivElement> | undefined; title?: DetailedHTMLProps<HTMLAttributes<HTMLHeadingElement>, HTMLHeadingElement> | undefined; subheader?: DetailedHTMLProps<HTMLAttributes<HTMLDivElement>, HTMLDivElement> | undefined; action?: DetailedHTMLProps<HTMLAttributes<HTMLDivElement>, HTMLDivElement> | undefined; }, default —- Props for each part:
mark,title,subheader,action.
Use it
import { DetailHeader } from '@mylder/perron/patterns'Ask your agent
search_docs({ query: "DetailHeader" })Keyboard and ARIA
DetailHeader has no keys of its own and is never focusable. The controls in action follow the title in the DOM and on screen, so Tab reaches them in reading order.
| Key | Does | From |
|---|---|---|
Tab | Moves to the first focusable element in action, after the title | The browser |
Shift+Tab | Moves back out of action, to whatever came before the header | The browser |
| Element | Role | Accessible name from | States announced |
|---|---|---|---|
root | None (generic div) | None | None |
mark | Hidden: aria-hidden="true" | None: the title says the line in words | None |
title | Heading, level 2 | Its text: in line, the hidden lineName then title, as "5C Husum Torv"; in stop, title | None |
subheader | None (generic div) | None | None |
action | None (generic div); the caller's controls carry their own roles | The caller's controls' own names | Theirs |
- The title is always an
h2, with anidthe caller can set throughslotProps.title(React'suseIdotherwise), so DetailPanel can name its Sheet witharia-labelledbypointing at it: the header heads one panel over a page whose own heading is theh1, and with norendera pattern can't swap the level. - In the
linevariant the mark isaria-hiddenand the title starts withlineNamein aVisuallyHiddenspan and a space, so the heading, and the panel name taken from it, reads "5C Husum Torv" rather than "Husum Torv" with the badge read apart before it: a screen reader moving by headings, and the panel's name, then carry the line, and the badge is read once.
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 badge's line name is read in the title (CR-4), and the StationIcon is decorative beside the stop's name, which the title says; the line's colour is never the only sign of the line.
- Every landmark and named region has an accessible name: none here, the root is not a landmark; the title's
idlets DetailPanel name its panel from the heading (CR-5). - Every default label can be overridden: none here; DetailHeader owns no string.
- Every shape the type accepts renders, in every variant:
title,lineName,subheaderandactioneach render a string, an element and a list alike;subheaderandactionaredivs, so block content is valid there, and the title takes phrasing content as anh2does. - A hidden copy kept for animation is
aria-hidden, and a collapsed region isinert: none here; nothing animates or collapses. Themarkisaria-hiddenbecause the title repeats it, not for animation. - Native semantics first: an
h2for the title, plaindivs for the rest, and the caller's ownbuttonora hrefin the action; no ARIA butaria-hiddenon the mark. - Focus moves in reading order and returns on close: the action follows the title and subheader in the DOM and on screen; DetailHeader never moves focus, and the Sheet around it returns focus on close.
- Every target is at least
size.target-minsquare: DetailHeader has no target of its own; the action's controls keep their own sizes,size.controlfor an icon button. - Loops stop when the system asks for less motion: none here; nothing moves.
Owned strings
No owned strings: every word DetailHeader shows or announces comes from the caller, through lineName, title, subheader and action, and the panel's close label belongs to the Sheet's close button, which DetailPanel sets after the header, not in action.
Do and don't
For a caller using the pattern, 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 | should | Give the destination as title and the line's short name as lineName: "Husum Torv" with "5C" | Put the line in the title as well, "5C Husum Torv": the header already reads the line first, so it would be said twice | review |
| DD-2 | must | Leave line off in stop for a station several lines serve, and name its lines in subheader | Pick one line's colour for a shared station, which tells the eye only one line stops there | review |
| DD-3 | should | Keep subheader to one plain line that says no more than the data knows: "Next stop: Nørreport St." | Put a list of departures or delays in subheader; they belong in the panel's body | review |
| DD-4 | must | Put at most one of the panel's own controls in action, such as "Show on map" | Put a close button in action, which DetailPanel draws from the Sheet after the header; or add a brand action there when the panel already has its main action | review |
| DD-5 | must | Use one DetailHeader at the top of a detail panel, and name the panel from its title's id | Use it to head a section inside a panel: its title is always an h2 | review |
| DD-6 | should | Let the panel set the surface and padding around it | Give it a fill or a border with className; it would draw a card inside the panel | review |