Record drawer
canonThe side panel that opens a record next to its listing without leaving it; the listing behind stays live. The only drawer in the canon.
React implementation lives in the app (apps/web/src/components/drawer/RecordDrawer.tsx); DrawerForm shares only the .pdr shell, not .pdr-sec/.pdr-row. AD 14 September 2026 (OV-2): the only drawer — Drawer form is deprecated. The catalog stories and the overlays proposal still show an OLD body (.pdr-sec/.pdr-row sections) and an old two-button footer („Přidat do segmentu" / „Odemknout informace"). Measured on deployed dev (Lidé → row click): the body is the record rail in drawer variant (PersonRail variant="drawer": stav spolupráce, quick actions, nejbližší aktivita, quick note, Aktivita/Poznámky tabs, Detail záznamu) and the footer holds one primary „Otevřít osobu" — the same card the ↗ in the header opens in a new tab. Stories must be rebuilt from the real call site. Delivered 14 September 2026 (OV-2b, acrm !3515), verified on dev: the footer is gone; ↗ in the head opens the detail in the same tab with the listing context (onOpenDetail), Ctrl/⌘+click opens a new tab; the dead „Odemknout informace" button in segments went with it. Catalog stories still show the old body and footer — to be rebuilt.
Used in 6 files · 6 areas · 7× — components/setkani, pages/FirmyPage, pages/LidePage, pages/PipelinePage, pages/SegmentDetailPage, pages/telefony
apps/web <RecordDrawer>.pdr .pdr-rail .pdr-sec .pdr-row +1SourceStoryLegacy card Person Drawer.htmlLegacy card Company Drawer.htmlLegacy card Deal Drawer.htmlKeyboard
- The drawer is part of the page: Tab reaches the head controls, then the body, in reading order. There is no footer since 14 Sep 2026.
- Previous / next / close / the record menu are ordinary buttons. Open ↗ is a real
<a href>: Enter or a plain click opens the detail in the same tab with the listing context, while ⌘/Ctrl-click, middle click and the context menu still open a new tab, because the in-app open only intercepts an unmodified primary click. - Escape is handled by the app shell's chain ("drawer full → drawer → AI panel"), not by the drawer itself — which is why a modeless dialog above it must not swallow the key.
- There is no focus trap, and none is wanted: the listing next to the drawer stays reachable.
ARIA
- Panel:
<aside aria-label="Náhled — {name}">; norole="dialog"and noaria-modal— the drawer does not block the page. - Loading state adds
aria-busy="true"; the failure state changes the label toNáhled — chyba. - Rows are text pairs (
.k/.v), not a definition list; the key is read before the value because of the DOM order, not because of a role. - Icon controls carry
title(and the close control an accessible name through it); the avatar is decorative next to the name. - Masked values are plain text (
+420 6•• ••• •••) — a screen reader reads the mask, which is intended: the value genuinely is not available.
Focus
- Foundation ring from
ds.csson the head controls and the open link. .pdr-ico:disableddims the control (previous / next at the ends of the list) and takes it out of the tab order.- Opening the drawer does not move focus; the row in the listing keeps it, so arrow-key stepping through rows keeps working.
Contrast
Computed from packages/ui/src/tokens/tokens.css:
- Record name
.pdr-top-name--ink-900on--surface-100= 17.59:1 light, 14.53:1 dark. - Row key
.k--fg-mutedon--surface-100= 2.85:1 light, 3.63:1 dark — below AA for text; the value.vcarries the meaning at--ink-900. - Section title
.pdr-sec-tuses the section token; on--surface-100it is ink, well above AA. - Icon controls
--fg-muted= 2.85:1 light — below the 3:1 non-text minimum; hover raises it. - Failure state text
--fg-mutedwith the heading in--fg(17.59:1). - Focus ring
--accenton--surface-100= 4.44:1 light, 3.83:1 dark.
Known limits
- Row keys and icon controls sit at 2.85:1 in light theme.
- Opening, closing and stepping to the next record are silent for assistive technology — no live region announces that the drawer now shows a different record.
- The drawer has no keyboard shortcut of its own; it is reached by Tab from the listing row.
Source: docs/dialog/record-drawer.a11y.md · GitLab