Skip to content

Overlay

A sheet over the whole page that blocks interaction. Use it while the user has to wait with nothing to answer: a save, a load, a replacement in progress.

tsx
import { Overlay, ProgressCircular } from 'neba';

<Overlay open={saving} tone="blur" label="Saving">
  <ProgressCircular size="lg" />
</Overlay>;

Props

PropTypeDefaultDescription
localestringBCP 47 tag naming the overlay in that language
openbooleanThe overlay is shown. Use with onOpenChange for a controlled overlay
defaultOpenbooleanfalseWhether the overlay starts shown
onOpenChange(open: boolean) => voidCalled when the overlay opens or closes
tone'scrim' | 'blur' | 'solid' | 'clear''scrim'How much of the page is taken away. Four steps on one axis, tuned with the blur radius as much as with the alpha
dismissiblebooleanfalseWhether a click or Escape closes it. Off, the other way round from Dialog: an overlay is not asking anything, and a save dismissed by a stray click is a save the user will believe finished
modalboolean | 'trap-focus'trueWhether the page behind is taken away for the keyboard too. 'trap-focus' leaves it scrollable and clickable while still holding focus inside
alignshared'start' | 'center' | 'end''center'Where the content sits down the viewport
sizeshared'xs' | 'sm' | 'md' | 'lg' | 'xl''md'Scale of the padding around the content
colorshared'primary' | 'secondary' | 'success' | 'warning' | 'danger' | 'info''primary'Semantic colour role. Reaches the focus ring and whatever the content reads
labelstringThe accessible name. It has a default rather than being optional: an overlay that holds nothing readable still has to say what it is
childrenReactNodeWhat sits on top of the scrim: a spinner, a line of text, a small card

Native <div> attributes pass through to the sheet. Only color and children are excluded, since the table above spells them differently.

An Overlay has no surface, no border, no title and no actions. If there is a decision to make, use Dialog instead.

Examples

tone

Four steps deciding how legible the page behind stays.

toneThe page behind
scrimStays readable; only interaction is blocked. Same value as Dialog's backdrop, so the two never show a seam.
blurPresent as shape and colour, gone as words. For content being replaced.
solidHidden entirely, covered opaquely in the page surface colour.
clearNothing is drawn; only the pointer is blocked.

dismissible

Off by default, which is the other way round from Dialog. An Overlay is not asking for an answer, it is saying wait, so Escape and a click on the scrim are both refused. Turn it on for an overlay whose job is to catch a click outside something.

modal="trap-focus" leaves the page scrollable and clickable while holding focus inside the overlay: a good fit with the clear tone.

Accessibility

  • Renders with role="dialog", and label is its accessible name. label has a default because an overlay holding only a spinner, or a clear one, still has to say what it is.
  • The portal, the scroll lock, focus held inside, the page behind going inert, and focus returning on close are all handled.
  • The entrance animates opacity only.
  • locale decides the overlay's accessible name; label writes it out instead.

Released under the MIT License