The rules — the data-list page
- The list page is a FULL-WIDTH lister — no grid, no wrapping card (the lister brings its own frame). The toolbar: filters toggle + selection tools left, the ONE
.btn-primary(New …) right. - Filters live in the collapsible
lister-panel: search on top, then the filter fields, thenhr, then order + page size. Reset clears everything and returns to page 1. - Create/edit opens in an OFFCANVAS (
.offcanvas-end; the form wraps header + body +.offcanvas-footerwith the standard button row) on former — fill, dirty guard, save pipeline,refreshpointed at the lister; former treats the parent offcanvas exactly like a modal. Sizes: default 30rem,.offcanvas-size-sm(20rem),-lg(40rem),-xl(max(40rem, 60vw) — floored at -lg),-full(100vw); on a phone (below 576px) every offcanvas is full-width. - Delete — single or bulk — stays a MODAL:
g.confirmwithdanger: true, never a hand-built one. - Row markup follows THE COLUMN STANDARD: one flex line (
d-flex align-items-center) holding the data zone.lister-cols— cells sized with thew-*percentage utilities, mobile-first (w-100 w-md-70= stacked on mobile, a 70% column from md; whole columns hide viad-none d-md-block), percentages summing to ≤ 100 per breakpoint. Cells space with padding (pe-3), never flex gap; free text getstext-truncate— a long value truncates, the columns never drift. Cell content is the person-cell pattern (tables) + status badges; secondary fields collapse behindlister-expand. - Buttons get THEIR OWN column:
.lister-actions, fixed width via--lister-actions-won the lister root (size it to the widest action set), present IDENTICALLY on every row — a row without buttons keeps the empty zone, so text never slides under a neighbour's buttons. - Column ALIGNMENT is positional and automatic (from md up): the FIRST column aligns start; BUTTON columns align end (
.lister-actionsright-aligns its content — action buttons and the expand toggle alike); DATA columns CENTER; the LAST data column aligns end ONLY when nothing follows it — with an actions column after (this page), it stays centered; on a list without buttons it right-aligns. The lib detects the actions column from--lister-actions-wby itself — zero authoring. Override per cell with thetext-*utilities only when the page genuinely needs a different alignment. - An OPTIONAL header row (
.lister-headerabove the rows — ONE.lister-colswith the samew-*cells, labels over columns) exists for lists whose cells carry no inline labels; preferable on COMPACT listers (lister shows it), never required. The actions-column width is reserved AUTOMATICALLY from--lister-actions-w— never put a.lister-actionsin the header (double reservation); without the automatic one the last label would right-align at the row edge while its column stops before the buttons. Hide the header below the stacking breakpoint. - Row actions have ONE shape, in the row's count: a lone action (fixed or left by the row's status) renders as a bare
.btn-sm .btn-actions-contrastbutton; 2+ actions render the PRIMARY action + a.dropdown-toggle-splitcaret (both.btn-actions-contrast) opening the rest. Visible button AND every.dropdown-item: icon + text; destructive items LAST as.dropdown-item.text-danger, under a.dropdown-dividerwhen mixed with harmless ones, never as the visible half. THE ONE COLOR EXCEPTION: a row whose only action is DESTRUCTIVE renders it bare in the solid.btn-danger(the card below shows it; row actions are never outline;g.confirmstays mandatory). Actions never wrap and the shape never changes at a breakpoint. The size is.btn-smat every width — never author.btn-xson row actions; a list that crowds on mobile scopes the xs metrics below the breakpoint in its routestyle.scss(lister.md "Row actions" has the snippet). The expand toggle is NEVER part of the group: the small round.btn-contrastat the row end (.btn-xs .btn-icon-round), separated from the actions. - The row-action standard governs EVERY list row — hand-rendered rows too (the card below). The color is themable (
$actions-contrast-*in the control panel; a project overrides it inprivate/config/theme.scss— foundation "Project theming"); never substitute another button color (lister.md "Row actions"). - Keyboard comes free: row shortcuts via
lister-key(e/d/n/f here) and?for the overlay — declare them, do not write key handlers. - Empty, loading and error states are the lister's own — never rebuild them (states).
Hand-rendered rows — the same standard, no lister
1. Introduction to the platform
4 materials · quiz · 25 min
Session 12 — Advanced routing
Today 18:00 · 34 attending
Draft certificate — no file attached
Created Aug 9 · never issued
Session 11 — Rendering deep dive
Aug 12 · recording 1h 42m