Skip to the content

Kongens Nytorv

Metro M1, M2 and M3.

Next train to Lufthavnen in 3 min

Variants and states

Rest
Raised
Next train to Lufthavnen in 3 min
Inset
Next train to Lufthavnen in 3 min
Glass
Next train to Lufthavnen in 3 min
Opaque
Next train to Lufthavnen in 3 min
  • Rest
    Next train to Lufthavnen in 3 min

Props

NameTypeDefaultDescription
variant'raised' | 'inset' | 'glass' | 'opaque''raised'The step of the surface ladder: raised for a card inside a panel, inset for a box or track set into one, glass for a panel floating over the map, opaque for a floating panel full of text on a phone, where glass would let the map show through.
childrenReactNode—The content the surface holds
classNamestring—Reaches the root; className is merged after pn-Surface
styleCSSProperties—Reaches the root; className is merged after pn-Surface
refRef<HTMLElement>—Reaches the root element, whichever element render makes it
variant'raised' | 'inset' | 'glass' | 'opaque', default 'raised'
The step of the surface ladder: raised for a card inside a panel, inset for a box or track set into one, glass for a panel floating over the map, opaque for a floating panel full of text on a phone, where glass would let the map show through.
childrenReactNode, default —
The content the surface holds
classNamestring, default —
Reaches the root; className is merged after pn-Surface
styleCSSProperties, default —
Reaches the root; className is merged after pn-Surface
refRef<HTMLElement>, default —
Reaches the root element, whichever element render makes it

Use it

import { Surface } from '@mylder/perron'

Ask your agent

search_docs({ query: "Surface" })

Keyboard and ARIA

Surface is a box: it takes no focus, and no key does anything. Focus moves through the caller's content in reading order. A caller who makes it a link or button through render brings that element's own keys.

KeyDoesFrom
noneSurface is not focusable or operable; Tab reaches its contentPerron
ElementRoleAccessible name fromStates announced
rootnone: a generic <div>Not named. Through render, a <section>, <aside> or <article> takes its name from the caller's heading by aria-labelledbynone

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 surface tells the eye only grouping and depth, which the content's own headings and order tell the ear; Surface carries no colour that means a state (no color prop).
  • Every landmark and named region has an accessible name: the root is a generic <div> and no landmark; a caller who renders it as <section>, <aside> or <article> names it with aria-labelledby pointing at its heading, as the Nested story shows.
  • Every default label can be overridden: none here; Surface owns no label.
  • Every shape the type accepts renders, in every variant: children as a string, an element and a list all render in each of the four variants, shown by the variant stories.
  • A hidden copy kept for animation is aria-hidden, and a collapsed region is inert: none here; Surface does not animate or collapse.
  • Native semantics first: a <div> with no role and no ARIA; the caller picks <section>, <aside> or <article> through render when the box is a region.
  • Focus moves in reading order and returns on close: Surface takes no focus and does not reorder its content; it does not clip, so a focused child's ring shows in full (CR-4).
  • Every target is at least size.target-min square: no target; Surface is not pressed.
  • Loops stop when the system asks for less motion: none here; Surface has no motion.

Owned strings

No owned strings: Surface shows and announces no words of its own; every word inside it is the caller's.

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.

RuleLevelDoDon'tChecked by
DD-1shouldUse glass for a panel that floats over the map, and opaque for one full of text on a phone, as Elevation says.Use glass over a plain background or inside another panel: the blur has nothing to soften, and glass on glass loses its edge.review
DD-2shouldPut raised cards and inset boxes inside a panel, stepping down the ladder.Nest a floating glass or opaque surface inside another surface, or add a shadow to a card with className: only floating panels cast one.review
DD-3shouldRender it as <section> or <aside> with aria-labelledby on its heading when the box is a region someone navigates to.Give every card a landmark element: a screen of unnamed regions is noisier than plain boxes.review
DD-4mustUse Dialog or Sheet for a panel that opens and closes over the screen, since they bring the focus, Esc and scrim.Build a dialog from a glass Surface: it would look right and trap no focus.review
DD-5mustSay a state in words or with an icon inside the surface.Tint a surface with a status colour through className to mean warning or success: colour is never alone.review
DD-6shouldChange the padding through className with a space.* token when rows must run to the edge.Set raw pixel padding, radius or colours on it, which leave the ladder and the themes behind.review