Irozon Design System — design foundations, tokens and components by Irozon AB.
Irozon Design System · v1.0
Components / Dialog & Sheet

Native <dialog>, not a div pretending to be one.

Dialog & Sheet v1 — packages/design-system/src/components/dialog.css. showModal() gives focus trapping, Escape-to-dismiss and a ::backdrop for free — the canonical CSS only draws the surface; every demo below calls the native API directly.

Base
.iz-dialog on a native <dialog>.
Structure
.iz-dialog__header / __body / __footer — all optional, use only what the content needs.
Sheet
data-variant="sheet" — pinned to the inline-end edge. The default is narrow; data-size="large" uses about 80% of the desktop viewport. Both sizes fill the available width on small screens.
Basic dialog

Header, body, footer — all optional.

Invite a teammate

They'll get an email with a link to join this workspace. This is a plain <dialog> shown with showModal() — Tab stays trapped inside it, and Escape closes it, with zero extra JS.

Confirmation

A destructive action, named plainly.

Nothing structurally different from a basic dialog — the distinction is entirely in content and using data-variant="destructive" on the confirming button, the same Destructive role documented on Buttons.

Delete "Nordkap AB"?

This removes all data associated with this project. This can't be undone.

Long content

The body scrolls. The header and footer stay put.

Terms of service

Section 1. This is placeholder legal-shaped copy, repeated to force scroll.

Section 2. .iz-dialog__body caps at 60vh and scrolls independently — the header and footer never move.

Section 3. Same paragraph, again, to keep scrolling.

Section 4. Same paragraph, again, to keep scrolling.

Section 5. Same paragraph, again, to keep scrolling.

Section 6. Same paragraph, again, to keep scrolling.

Section 7. That's the bottom.

Sheet

Directional, with two sizes.

Same <dialog> foundation, data-variant="sheet". The default is a narrow detail panel. Choose data-size="large" for an approximately 80%-wide desktop workspace. Both sizes fill the available width on small screens and collapse to a bottom sheet.

Nordkap AB

Plan: Scale · MRR: $1,240 · Seats: 18

A Sheet suits detail/edit panels that want more room than a centered Dialog without fully leaving the current context.

Large workspace

The large Sheet gives detailed work more room while keeping the current page visible behind it.

Behavior

What native <dialog> already gives you.

Focus
Moves into the dialog on showModal(); returns to the triggering element automatically on close — no manual focus management.
Escape
Closes the dialog natively via the cancel event. Listen for cancel if you need to intercept it (see below).
Explicit close
Any element with data-dialog-close inside the dialog calls .close() — see the tiny controller in site.js.
Backdrop dismissal
Not automatic — clicking the ::backdrop does nothing by default. Wire a click listener on the dialog element that checks event.target === dialog if backdrop-dismiss is wanted for a given dialog.
Preventing accidental loss
Listen for the cancel event and call event.preventDefault() when there's unsaved work, then show your own "discard changes?" confirmation instead of dismissing silently.
React

Dialog and ConfirmDialog from @irozon/design-system-react.

Dialog (plus DialogHeader/DialogBody/ DialogFooter) is a controlled wrapper over the native element above — pass open and it calls showModal()/close() for you, and calls onClose for both an explicit close and native dismissal (Escape). ConfirmDialog composes it for the common "are you sure?" case.

For a Sheet, pass variant="sheet". Add size="large" for the 80%-wide desktop layout; omitting size keeps the narrow default.

import { ConfirmDialog } from "@irozon/design-system-react";

<ConfirmDialog
  open={confirmOpen}
  title="Delete invoice?"
  description="This cannot be undone."
  onConfirm={handleDelete}
  onCancel={() => setConfirmOpen(false)}
/>