Tabbed data

Listers and forms as tab panes — one card, the same filters and search everywhere
User
Role
Status
Created
Product
Category
Stock
Price
A short line shown on the profile.

The rules — the tabbed-data page

  • The tab shell is the tabs standard unchanged: pills in the card header, panes as plain card-body content. Putting a lister or a form in a pane changes NOTHING about how it is built — this page exists to show exactly that.
  • A pane with a full data list is the data-list composition unchanged — THE STANDARD SHELL (lister.md "Page markup"): the toolbar inside .lister-main with the Filters toggle (icon + word) left and the ONE .btn-primary right; the collapsible lister-panel as two cards — Filters (title + the lister-reset Reset link + the close button; the search on top, then the filter fields) and Display (order + page size); the list card holding the header and the rows; the count and the pager on the .lister-footer line. SAME filters, SAME search everywhere — every tabbed list in an app reads identically.
  • The minimal variant is the compact composition: search + order in the toolbar, the list card (the header row + the rows), the footer, no panel — for panes where the list IS the whole story and a filter panel would be noise.
  • Rows in a pane are THE STANDARD ROW (lister.md "The standard row"; the reference: the data list): FIT columns (lister-col-w + lister-col-min, a lister-col-priority + lister-col="Label" on each column that may hide — by the LIST's width, so a narrow pane hides them as a phone would), rowClick: 'expand' + lister-more-inset: the card opens the details where the hidden columns land; "Details" (marked lister-expand) rides first in the row's dropdown, or stands as the bare button where it is the row's only action (Products — hidden, its place kept, while nothing hides). No caret at the row end.
  • Several synced listers, one page: give each its own urlPrefix (u-/p- here — the prefix is concatenated literally: u-page, p-search) so URL sync never collides. The OPEN TAB itself stays un-synced — the tabs standard: a tab that must deep-link wants to be a page.
  • Hidden tabs never fetch: a lister outside the active pane gets autoload: false (here: the lister-autoload attribute) and loads ONCE on its tab’s first shown.bs.tab — data the user never opens is never requested.
  • Side info about the list — pending invitations, hidden-row counts, totals — goes in the lister’s NOTICE STRIP: [lister-notice] above the rows, a .lister-notice-label + .lister-notice-chip values, filled from lister:loaded. The extras ride the SAME payload as the rows (atypical payloads — never a second fetch), and :empty means the strip does not exist — nothing to show needs no page logic. When the info is something AWAITING the user (the pending invitations here), the tab may carry the .badge-count pill from the same payload — the tab-pill law. Page errors/warnings are NOT notices: they stay alerts above the lister.
  • Form panes follow the settings standard: each pane is its OWN form with its OWN submit — one giant form across tabs stays forbidden. In a real app each form rides former.
  • Everything else comes straight from the source patterns when a tabbed list needs it: bulk selection from the data-list page, create/edit in the offcanvas on former (shown here), delete through g.confirm (shown here).

Edit user