Components › Records & data › Table › Segment table

Segment table

canon

Listing table: sortable header, frozen checkbox and identity columns, lazy loading by 50 and an optional summary row in its own tfoot.

Engine lives in the app (components/segment/SegmentScreen.tsx — SegmentTable); the lite variant strips checkbox, column menu, summary and frozen identity. Row height is --row-h (37px) — the 44/52 densities belong to Item list, not here. The registry previously listed .sgb-summary, which does not exist: the summary row is the table tfoot and .sgb-sum is the per-column control.

Used in 23 files · 22 areas · 23× — pages/AccountingInvoicesPage, pages/AccountingOpenItemsPage, pages/AccountingReceivedInvoicesPage, pages/AiZamestnanciPage, pages/DokumentyPage, pages/FirmyPage …

The data table of every listing: sortable header, frozen checkbox and identity columns, clipped cells, lazy loading by 50 rows and an optional summary row. The engine lives in the app (apps/web/src/components/segment/SegmentScreen.tsx — SegmentTable); CSS apps/web/src/ds/segment-screen.css (.sgb-*, .table-wrap, .cell-*).

lite is the same engine with the chrome stripped — no checkbox column, no column menu, no "add column", no summary row, no frozen identity — for tables embedded in a record.

When to use

  • A listing the user compares and sorts by column: companies, people, deals, invoices, orders, documents.
  • A table inside a record where the columns still matter (lite).

When not to use

  • A list the user scans and opens rather than compares — that is Item list.
  • The fields of one record — that is Record rail.
  • A hand-built <table>: the engine owns the sticky header, the frozen columns, the clipping and the lazy loading, and every hand-built table loses them.

Anatomy

  • Wrapper .table-wrap (the scroll surface; .scrolled-x adds the shadow behind the frozen columns) → table.sgb-table.
  • Header: th.sgb-th-col with .sgb-th-in (icon, label, sort mark); sortable columns add .sgb-th-sortable, the per-column menu is .sgb-th-kebab and appears on hover.
  • Rows: tr.sgb-rowclick (hover fill; .sel when selected). Row height is var(--row-h) — 37px in this engine; the 44/52 densities belong to Item list.
  • Checkbox column td.col-ck with label.sgb-ck: the real <input> is visually hidden and the visible box is .ck, revealed on hover and kept once the row is picked.
  • Cells: .cell-id (avatar + .nm, frozen and clipped at --sgb-id-w), .cell-v (plain), .cell-mono (tabular figures, still the sans face), .cell-link, .cell-bool-on/off, .grade.
  • Summary: the table's own <tfoot> — that is why the columns line up for free. The per-column control is .sgb-sum (value + function), and the aggregation is chosen from its menu.
  • More rows arrive as the user scrolls, 50 at a time; there is no bottom bar.
  • Column panel: the only entry to the column set is a narrow + (IconButton plus sm, label "Přidat sloupec") in th.sgb-th-add at the end of the header row. It opens the shared CheckMenu: search (diacritics-insensitive), visible columns in table order (reorderable), a separator, then hidden columns. The identity column is never listed and the last visible column cannot be hidden. A column switched on is appended at the end and the panel stays open. On a phone the panel is a bottom sheet titled "Sloupce". The per-column ⋮ menu and the section bar are unchanged.
  • Phone (≤ 720px): the identity column is 50vw wide and frozen, so the header labels (.sgb-th-in) and the summary controls stick at left: calc(var(--ck-w) + var(--sgb-id-w)) — at the end of the horizontal scroll the last column's label stays readable instead of sliding under the frozen name.

Best practices

Do
  • Let the engine own the table; pass columns and rows, not markup.
  • Use lite inside a record, where the checkbox and the column menu would be noise.
  • Keep numbers in .cell-mono — tabular figures line up, and the face stays sans (monospace is only for accounting statements).
  • Turn the summary on where a total is what the user came for; leave it off elsewhere.
Don’t
  • Build a <table> by hand. Today AssetDetailPage, HovoryStatistikaPage / TeamDayDrilldown and CompanyRecordPage do, and they are on the migration list.
  • Put row actions in a trailing column — this engine has none, and adding one would fork the row.
  • Abbreviate numbers in the summary (1,3M); it shows full values by design.
  • Use the table for a list the user only scans; that is Item list.
  • Put a wide "Přidat sloupec" button in the header or a second column-set entry in the section bar; the + at the end of the header is the only one.

Content

  • Column labels are short nouns in sentence case.
  • The identity cell carries the record's own name, nothing else.
  • The summary says the function next to the value (3 830 000 · součet).
  • table-row — the row anatomy.
  • item-list — the canonical listing for scanning.
  • filter-bar — the row of filters above the table.
  • Stories: components--segment-table--default, --variants, --states, --with-icon-and-kbd, --composition, --column-panel.

Source: docs/table/segment-table.usage.md · GitLab