Review kategorie Navigation — nálezy, bug list, rozhodnutí pro AD
Datum: 4. 9. 2026 · zdroj pravdy: origin/main acrm (/root/acrm-main) · web: <http://192.168.230.131:3777/ds/components/app-shell/sidebar-nav-item?preview=ds-navigation-stories>
Rodiny: App shell (Sidebar nav item, Top bar, Drawer slot) · Section top bar (bar, Title with entity tile) · Tabs (Tab strip, Record tabs). Sedm podkomponent, dosud nula ukázek na webu.
0. Shrnutí
Navigace je paradox: je to nejvíc opsaná část systému (app-shell.css je port 1:1 s poznámkou „needituj ručně", Section top bar má v hlavičce rozhodovací tabulku i vývojářská varování, Record tabs mají tři vrstvy skladby tabů) — a přitom na DS webu nebyla vidět vůbec. Vady, které jsem našel, jsou drobné, ale dvě z nich jsou toho druhu, který se sám nikdy neopraví: mrtvý kus CSS a jméno ikony, které neexistuje.
1. Nálezy per podkomponenta (ověřeno v kódu)
1.1 Sidebar nav item (AppShell.tsx → WorkspaceNav/NavGo, ds/app-shell.css)
- Řádky jsou skutečné
<a>/<button>, aktivní nesearia-current="page". Focus ring není vada: app-shell.css výslovně jen strhává nativní chrome tlačítka aoutlinenevypíná, takže platí základní ring zds.css. .as-row .notifa.as-row .countjsou mrtvé — v CSS jsou plně nadefinované, v JSX je nikdo nekreslí. Počty se dnes sázejí jako.acrm-pill.blue.sm/.amber.sm.- Výchozí ikona řádku je
circle, která v rejstříku ikon není (AppShell.tsx:<Icon name={n.icon ?? 'circle'} />). Položka bez ikony tedy tiše spadne na náhradní glyf. - Rail (ikonový sidebar) je jen ≥901px; pod tím je off-canvas. Obojí je otestované, ale nikde vidět.
- Nastavení mají vlastní paralelní rail (
.set-rail,ds/settings.css) — jiná rodina tříd na tutéž práci.
1.2 Top bar (AppShell.tsx → TopBar)
- Třísloupcová mřížka
1fr minmax(280px,560px) 1frdrží hledání uprostřed nezávisle na tom, co přibude po stranách — dobré rozhodnutí, které nikde nebylo zapsané. .as-ai-triggerje v CSS kompletní, ale appka mountuje jen.as-ai-btn; komentář v kódu říká, že jméno je „rezervované". Rezervovaná, nepoužitá varianta v kanonu je dluh.- Hledání je
<button>, ne<input>— správně (otevírá paletu), ale vypadá jako pole; v docs je to teď napsané.
1.3 Drawer slot (ds/app-shell.css, shell/ShellDrawer.tsx, drawer/use-drawer-side.ts)
- Slot se nikdy neodmountuje (jen skryje), takže obsah přežije zavření — stejný kontrakt jako u stavů okna dialogu. Strana se volí podle toho, kde uživatel klikl (panel nezakryje řádek, který ho otevřel).
.as-drawer.fullje mrtvý kód — podle komentáře od P276 nemá konzumenta.
1.4 Section top bar (packages/ui/src/components/SectionTopBar.tsx)
- Nejlépe „zamčená" komponenta v systému: rozhodovací tabulka v hlavičce +
warnMisusena tři chybné kombinace. To je vzor pro ostatní rodiny. .plpage .tchip(pipeline) je metrická odchylka od kanonu: padding 8px místo 10px, gap 6px místo 7px, výška i velikost ikony zapsané v px místo tokenů. Chip v pipeline je tedy užší než chip všude jinde.- Čtyři obrazovky (
PersonRecordPage,CompanyRecordPage,TeamDetailPage,ClenTymuPage) používají bar, ale identitu si kreslí ručně z.tbar-id/.tbar-h/.tbar-mark, protože potřebují něco navíc (hvězdička stavu, spouštěč loga, barevný vzorek). Únikový východ je legitimní, ale obchází všechna varování komponenty. - Story „DetailBar" v legacy přehledu ukazuje „N z M" — tedy přesně to, co si bar sám zakazuje (výjimka pro navigační šipky mezi záznamy je zdokumentovaná, ale na webu vypadá jako povolení).
1.5 Title with entity tile
- Pět identit, právě jedna povinná — a komponenta to hlídá. Přejmenování má západku proti dvojímu uložení (Enter + blur) i proti oživení zrušené editace.
- Chybí chybový stav přejmenování:
renamingumí „ukládám", ale „nepovedlo se" musí vyřešit obrazovka.
1.6 Tab strip (packages/ui/src/components/TabStrip.tsx)
- Plně řízený,
role="tablist"+role="tab"+aria-selected. Přetečení řeší sám (měří scroll, rozsvítí okraj a šipku, posune o ~60 % šířky). - Mezi taby nejezdí šipky. Vzor tablistu očekává ←/→ a Home/End; dnes je každý tab vlastní zastávkou tabulátoru.
- Taby nejsou svázané s panelem — chybí
aria-controls/role="tabpanel". - Není
disabled— ani prop, ani CSS. To je v pořádku jako rozhodnutí, jen to nikde nebylo napsané (teď je).
1.7 Record tabs (record/RecordTabsRow.tsx, record/record-tabs.ts)
- Tři vrstvy skladby (katalog typu záznamu → produkční pořadí → osobní pořadí a skrytí) plus automatika „prázdný tab se schová" a rozlišení
undefined(načítá se) vs0(opravdu prázdný). Tohle je nejchytřejší kus rodiny a nikde to nebylo popsané. - Řazení tabů v ⚙ je jen tažením — klávesnicí nepřestavitelné.
2. Bug list — DS (web, registr, stories, docs)
| # | Nález | Stav |
|---|---|---|
| D1 | Celá kategorie Navigation neměla per-sekci stories (0/7) | OPRAVENO (7 souborů, 32 stories) |
| D2 | Chyběly usage.md a a11y.md pro všech sedm podkomponent | OPRAVENO (14 souborů) |
| D3 | Katalog Ladle nenačítal ds/app-shell.css → .as-* nešlo ukázat | OPRAVENO (provider) |
| D4 | Registr neříkal, že App shell i Record tabs žijí v appce, ne v @acrm/ui | OPRAVENO (notes) |
| D5 | Nikde nebylo zapsané, co bar zakazuje (počet, breadcrumb, dva primáry) ani proč | OPRAVENO (usage) |
3. Bug list — aplikace (kanon v kódu)
| # | Nález | Návrh | Kdo rozhodne |
|---|---|---|---|
| A1 | .as-row .notif / .count = mrtvé CSS | smazat, počty už kreslí .acrm-pill | hotovo 11. 9. 2026 — acrm !3403 (appka i zrcadlo) |
| A2 | Výchozí ikona navigace circle v rejstříku není | buď ikonu doplnit, nebo fallback změnit na existující jméno | AD ano/ne (drobnost, ale tichá) |
| A3 | .as-drawer.full = mrtvý kód (bez konzumenta od P276) | smazat | hotovo 11. 9. 2026 — acrm !3403 (appka i zrcadlo) |
| A4 | .as-ai-trigger = rezervovaná nepoužitá varianta | smazat, nebo v kanonu napsat, kdy se má použít | AD |
| A5 | .plpage .tchip má jiné metriky než kanon (8/6px vs 10/7px, px místo tokenů) | srovnat s kanonem, nebo z odchylky udělat pojmenovanou variantu | AD (vizuální změna v pipeline) |
| A6 | Čtyři obrazovky kreslí identitu baru ručně | rozšířit SectionTopBarTitle o slot pro doplněk (hvězdička, logo, vzorek) | AD |
| A7 | Tab strip: chybí šipky mezi taby a aria-controls | doplnit do TabStrip.tsx | AD ano/ne |
| A8 | Řazení tabů v ⚙ jen tažením | doplnit klávesovou alternativu (posunout nahoru/dolů) | AD ano/ne |
| A9 | Nastavení mají vlastní rail .set-rail | sjednotit s .as-*, nebo zapsat do DS jako vlastní rodinu | AD |
| A10 | Globální .ti (velikost a řádkování VŠECH ikon) deklarují TŘI sheety: ds/app-shell.css, ds/segment-screen.css a ds/auth.css | sjednotit do jednoho pravidla (ds.css / index.css), kopie zrušit | hotovo 9. 9. 2026 — acrm 2e04c7d4c, globální .ti zůstalo jen v ds/app-shell.css |
4. Rozhodnutí pro AD
- N1 — sedm podkomponent Navigation jako kanon. Schválit podle ukázek na webu. Doporučuji ano.
- N2 — úklid mrtvého CSS (A1+A3+A4 jako jeden balík). Doporučuji ano — tři kusy kódu, které nikdo nekreslí, a jeden z nich (
.as-ai-trigger) svádí k použití. - N3 —
.plpage .tchip(A5). Doporučuji srovnat s kanonem. Chip má být všude stejný; pokud pipeline opravdu potřebuje užší, ať je to pojmenovaná varianta, ne scoped kopie. - N4 — klávesnice v tabech (A7). Doporučuji ano, je to jedna oprava na jednom místě a týká se každého záznamu v systému.
- N6 — tři kopie globálního
.ti(A10). Doporučuji sjednotit do jednoho pravidla. Dnes se hodnoty shodují, takže se nic nekreslí jinak; jde o pojistku do budoucna — tři globální pravidla na tutéž věc znamenají, že o velikosti ikon rozhoduje pořadí načtení sheetů. - N5 — slot v identitě baru (A6). Doporučuji ano — čtyři obrazovky dnes obcházejí guardrails komponenty jen kvůli jednomu doplňku.
5. Co teď
- MR do acrm
polish/ds-navigation-stories— stories + zpřístupněníapp-shell.csskatalogu. - DS repo: registr, docs, tenhle review.
- Po schválení:
approvedAt, pak N2–N5 jako samostatné MR (N3 a N5 mění vzhled, ty chtějí tvoje oko).
Source: docs/REVIEW-navigation-family.md · GitLab