Components › Overlays & dialogs › Dialog › Drawer form

Drawer form

deprecated
Deprecated — use Form-less dialog (dialog family) — first case: „Nový kontakt", proposal /preview/_navrhy/ramec.html?b=navrh&v=osoba instead. AD 14 September 2026 (OV-2): „drawer form už na nic nepoužíváme, nebudeme používat" — replaced by the form-less dialog. Code on main still has 20 <DrawerForm> call sites in 17 files (Lidé, Firmy, Banka, Majetek, Uživatelé, Zasedačky, Pokladna, Rozpočty, Telefony, Týmy, Vozidla, Dokumenty, Šanony, AI zaměstnanci, provize, náklady) — migration is open work, not done. Existing usages stay until they are migrated; do not build anything new on it.

Deprecated — create/edit forms move to the form-less dialog (e.g. „Nový kontakt"). The side panel with a field form is no longer used for new work.

Used in 18 files · 13 areas · 85× — components/deal, components/mail, components/orders, components/products, components/projects, pages/AiZamestnanciPage …

Keyboard

  • Tab walks head → fields → footer in reading order; the first field usually takes focus through autoFocus on the input the screen marks.
  • The close control and both footer buttons are ordinary buttons: Enter and Space activate them.
  • Missing: Escape does not close the drawer (DrawerForm registers no key handler), and there is no focus trap — the drawer is part of the page, not a modal layer.
  • A disabled primary button is skipped by Tab, so a form that cannot be submitted has no keyboard path to an explanation; the reason must be in a field hint.

ARIA

  • Panel: role="dialog" with aria-label = the title. It is deliberately not aria-modal, because the listing behind it stays live.
  • The head icon is decorative; the name comes from the title.
  • Each field is a <Field>, so the label is programmatically linked to the control and the hint is read with it.
  • The error sentence is plain text appended to the body — it is not a live region, so a failed save is silent for a screen reader, and it is not linked to any field.

Focus

  • Foundation ring from ds.css on the close control and the footer buttons; fields carry the input ring from ds.css.
  • Opening the drawer does not move focus by itself — the screen decides via autoFocus.
  • Closing returns nothing: focus is left where it was, which after a click on the close control means <body>.

Contrast

Computed from packages/ui/src/tokens/tokens.css:

  • Title .pdr-top-name --ink-900 on --surface-100 = 17.59:1 light, 14.53:1 dark.
  • Field label and hint follow <Field>: label --label token, hint --hint (400 12px) in --fg-muted = 2.85:1 light, 3.63:1 dark — below AA for text.
  • Error sentence --critical-ink on --surface-100 = 5.37:1 light, 5.80:1 dark — passes AA.
  • Primary button: white on --accent = 4.44:1 light.
  • Focus ring --accent on --surface-100 = 4.44:1 light, 3.83:1 dark.

Known limits

  • No Escape and no focus trap: the drawer behaves like part of the page even though it is announced as a dialog.
  • The failure message is not announced and is not tied to a field.
  • The error prop cannot carry a message, so the drawer cannot say why the save failed.
  • Hint text sits at 2.85:1 in light theme (system-wide --fg-muted limit).

Source: docs/dialog/drawer-form.a11y.md · GitLab