Components › Navigation › App shell › Sidebar nav item

Sidebar nav item

canon

Row of the left navigation: top-level row, section divider and sub-item, plus the split parent that navigates and folds.

React implementation lives in the app (apps/web/src/components/AppShell.tsx — WorkspaceNav/NavGo), not in @acrm/ui. The dead rules .as-row .notif/.count were removed on 11 September 2026 (NAV-1, acrm !3403); counts are .acrm-pill. Debt: no standalone segment-tile component — `.sg` (the 18px coloured tile with the list's glyph) exists only as `.as-sub .sg` in `apps/web/src/ds/app-shell.css`. `AddToListDialog` (acrm !4019, 27 Sep 2026, see the "add-to-list dialog" subsection of formless-dialog.usage.md) reuses it by extending the same selector rather than duplicating the rule — `.as-sub .sg, .atl-list .sg { … }` — one definition serving both the left menu and the dialog's list rows; accepted by the AD 27 Sep 2026 as a stopgap. Target: extract a canonical `SegmentTile` so a third consumer does not repeat the same selector-extension trick. 30 Sep 2026 (acrm !4296, AD FA216/FA233): optional dot?: blue | amber | green | purple | rose | critical draws the canonical category dot .il-dot[data-tone] (6 px, gap --sp-1) before the PLAIN count, no capsule. Category meaning only (Komunikace: Důležité critical, Delegováno mnou purple — owner R15, Delegováno mně amber); never unread (unread = blue dot elsewhere). acrm !4319 (1. 10. 2026, ověřeno na devu 1440/390 světlá+tmavá): tichý počet .as-navcnt místo modré kapsle, kapsle jen kritický odznak, horní blok 6, ⋯ akce seznamů (MenuButton) a + u Seznamů. Komunikace menu (20 Oct 2026, owner "1 Schváleno", proto/komunikace-menu-zobrazit-vse@0b7180f3a, ACRM-558, 560–569): rarely used Mail views (Newsletters, Sent, Archive, Trash, Snoozed, Drafts, Scheduled) live in a collapsible section "Další" (`.as-grp.as-more`, heading styled like "Chaty", collapsed by default, hidden-unread count on the right while collapsed); the active hidden view is shown as a copy above it; rows drag (HTML5 DnD) within and between groups and move with Alt+↑/↓ (aria-live announces the new place); personal preference in localStorage. No ⋮ menu on views. Row marks: `sgDot` = colour dot in the label colour (`.as-sub .sg.dot`, labels), `sgPlain` = bare muted glyph ("+ New label/folder/deal" rows), `sgTint` = bare glyph in the channel colour (chats: Telegram --ic-blue, WhatsApp --ic-green, SMS new token --ic-mint #34c759; the Chaty section is collapsible and open by default); a folder tile takes its own icon and tone (fallback grey `folder`). Tokens: new `--ic-mint`. Module icon Komunikace = `message-chatbot`, "All chats" = `message-circle`. AD 24 Oct 2026 (a2a FA278, acrm !5560): menu axis UX-62 accepted — .as-row-chev / .as-sub-chev / .as-sub-more share one axis (the sub-menu ⋯ sits exactly on the count, count hides on hover/open); .as-shared = sharing badge with ONE meaning only: the subject is shared with other users (who + level reachable on touch via ⋮/detail, not hover-only). Amber capsule (badgeAmber) NOT approved: the only coloured capsule in the menu stays critical; other counts are quiet. Pending from the author: stories States „sdílený“ + „osa“ with light/dark baseline, 390 check.

Used in 5 files · 4 areas · 22× — components/AppShell, components/NavItemMenu, components/segment, pages/settings

The row the left navigation is made of. Three kinds, one rhythm: a top-level row (.as-row), a section divider (.as-grp) and a sub-item (.as-sub) — plus the split "parent" variants whose body navigates and whose chevron folds. CSS apps/web/src/ds/app-shell.css; the React implementation is WorkspaceNav / NavGo in apps/web/src/components/AppShell.tsx (app-side, not in @acrm/ui).

The navigation is one flat model (NavItem[]), not a nested tree: depth is expressed by the item kind and its indent, so a row can move between levels without being re-parented.

When to use

  • Any destination in the left navigation of a workspace: a section (Obchody, Lidé), a saved segment under it, or a group heading that folds a block.
  • A row that both navigates and folds — that is the split parent variant.

When not to use

  • Tabs inside a record or a page — that is Tab strip.
  • A menu that opens on click — that is Popover / Picker menu.
  • A settings sub-navigation: settings has its own rail (.set-rail, apps/web/src/ds/settings.css), a separate family.
  • An action (create, export). The navigation navigates; actions live in the Section top bar.

Anatomy

  • Row .as-row: height: var(--row-h-nav), padding: 0 var(--sp-3), gap: 10px, radius-md, 500 13px, text --ink-700, icon 16px in --ink-500. Hover --hover-surface; active --active-surface with --ink-900 text.
  • Group .as-grp: quiet divider with a chevron that rotates when folded (.chev.col); it keeps its top margin so the block above stays separated.
  • Sub-item .as-sub: a leading tile .sg (the segment's colour) or the wizard .wand, then the label; indents .lvl1 / .lvl2.
  • Split parent (.as-row.parent / .as-sub.parent): two sibling controls — .as-row-nav (link) and .as-row-chev (button). They are siblings on purpose: a button inside a link is invalid HTML and would fire twice.
  • Count .as-navcnt (NavItem.quietCount): a quiet number at the end of the row, --fg-muted / --small, no capsule; --ink-700 on the active row; zero is not drawn. An optional category dot .il-dot sits before it (NavItem.dot). Úkoly counts only my tasks due today + overdue (open, in progress, blocked).
  • Critical badge .acrm-pill.sm.critical (NavItem.badge): the only capsule in the sidebar, for a queue that needs action (Komunikace Důležité). Never drawn together with the quiet count.
  • Row actions on saved lists: ⋯ = canonical MenuButton (Přejmenovat · Duplikovat · separator · Smazat danger with Confirm „Smazat seznam?“ / „Seznam „…“ se nevratně smaže.“), a sibling of the link; on hover on desktop (24 px compact), always visible on touch with a 44 px target. Duplikovat only for filter lists. Section header Seznamy has + (Seznam lidí / Seznam institucí → wizard).
  • Top block: six daily queues (Dashboard, Úkoly, Kalendář, Email, Setkání, Aktivita); rarely used reports (Statistika hovorů, Kariéra) live in the folded group Přehledy (acrm !4319, measured by 7-day API usage).
  • Footer .as-side-foot: the rail toggle, outside the scrolling nav.
  • Rail (.as-side.rail, ≥901px): icon-only, 56px; labels, groups, sub-items and chevrons are hidden and the name survives as title / aria-label.

Collapsible section, dots, bare glyphs (Komunikace, 2026-10-20)

  • Section "Další" (.as-grp.as-more): a collapsible heading styled like "Chaty", collapsed by default. It holds rarely used views; collapsed, it shows the count of hidden unread items on the right. The active hidden view is shown as a copy above it. Rows drag within and between groups and move with Alt+↑/↓ (the move is announced in an aria-live region). No ⋮ menu on views.
  • sgDot — a colour dot in the label colour instead of a tile (labels). sgPlain — a bare muted glyph (the "+ New …" rows). sgTint — a bare glyph in the channel colour (chats). A folder keeps a tile in its own icon and tone, grey folder by default.
  • Token --ic-mint (#34c759) is the SMS channel colour.
  • One axis on the right. The row chevron (.as-row-chev), the sub-row chevron (.as-sub-chev) and the sub-menu ⋯ (.as-sub-more) share one vertical axis. The ⋯ sits exactly where the count is; the count hides while you hover or while the menu is open, so the two never stand side by side.
  • Sharing badge .as-shared has one meaning only: this subject is shared with other users. Don't reuse it for delegation direction, status or ownership. Who and at what level must be reachable on touch too (⋮ or the detail), not only in a hover tooltip.
  • Counts stay quiet (.as-navcnt). The only coloured capsule in the menu is .acrm-pill.sm.critical; amber or blue capsules are not part of the canon.

Best practices

Do
  • Give every row an icon — in the rail it is the only thing left.
  • Keep the active row tied to how the screen was opened, not to the raw URL: opening a contact from Hovory keeps Hovory highlighted.
  • Fold with the chevron, navigate with the body; never make one control do both.
  • Let a group disappear when everything in it is hidden by permissions (withoutEmptyGroups) — an empty heading is noise.
Don’t
  • A row without a destination that only opens a menu; that is a control, not navigation.
  • A second colour system in the sidebar — the segment tile is the only coloured mark.
  • A count on a row that is not a queue: numbers belong where the user is expected to act (Pošta, Úkoly).
  • A coloured capsule for an ordinary count; only the critical badge is a capsule.
  • A menu item that does nothing yet (e.g. Do oblíbených before favourites exist).
  • Deep nesting: two indents are the floor plan, a third is a sign the model is wrong.

Content

  • Labels are nouns in sentence case, as short as they can be while staying unambiguous: Obchody, Poznámky, Bonitní Pražané.
  • Group headings are one word where possible (Obchod, Nastavení).
  • No counts in labels ("Úkoly (3)") — the quiet count carries the number.
  • top-bar — the bar above the sidebar.
  • drawer-slot — the panel slot next to the page.
  • section-top-bar — the per-screen bar, not part of the shell.
  • Stories: components--sidebar-nav-item--default, --variants, --states, --with-icon-and-kbd, --composition.

Source: docs/app-shell/sidebar-nav-item.usage.md · GitLab