LanternUI.Components.DataTable (LanternUI v0.8.2)

Copy Markdown View Source

The admin data table — one Flop-driven table to replace the per-app admin_table copies. API deliberately mirrors the enventory/skusync baseline so swaps are mechanical.

<.data_table id="orders" rows={@orders} meta={@meta} path={~p"/orders"}>
  <:col label="Order" field={:reference} sortable :let={o}>{o.reference}</:col>
  <:col label="Total" field={:total} sortable td_class="lui-td-num" :let={o}>
    {o.total}
  </:col>
  <:bulk_action label="Delete" icon="trash" event="bulk-delete" />
  <:row_action :let={o}>…</:row_action>
  <:empty>No orders yet.</:empty>
</.data_table>
  • meta is a Flop.Meta (duck-typed — any map with flop, params, current_page, total_pages, page_size, total_count works), so lantern_ui carries no flop dependency.
  • Sorting, pagination, and page size are patch navigation against path — table state lives in the URL. Existing query params (meta.params, e.g. filters) are preserved.
  • Selection is server-owned: rows emit toggle_select (phx-value-id), the header checkbox emits select_all_page, the bulk bar emits clear_selection and each bulk_action's event — all to target (defaults to the parent LiveView). Same contract as the baseline.

Search, filter bar, tabs, and the stat overview arrive as chrome slots in a follow-up; this is the core.

Summary

Functions

The aria-sort value for a sortable column: "ascending", "descending", or "none".

Functions

data_table(assigns)

Attributes

  • id (:string) (required) - Stable DOM id for the table root and chrome.
  • rows (:list) (required) - Current page of row structs/maps to render.
  • meta (:map) (required) - Flop.Meta (or same-shaped map).
  • path (:string) (required) - base path for sort/pagination patches.
  • selected_ids (:any) - MapSet (or enumerable) of selected row ids. Defaults to MapSet.new([]).
  • row_id (:any) - row -> id fn; defaults to & &1.id. Defaults to nil.
  • show_checkboxes (:boolean) - Show row selection checkboxes and bulk bar. Defaults to true.
  • target (:any) - LiveView target for selection and bulk events. Defaults to nil.
  • title (:string) - Optional table heading above the toolbar. Defaults to nil.
  • subtitle (:string) - Secondary line under the table title. Defaults to nil.
  • info_modal_id (:string) - modal id the title's info button opens (LanternUI.open_dialog). Defaults to nil.
  • page_size_options (:list) - Choices for the page-size control. Defaults to [10, 25, 50, 100].
  • search_field (:atom) - Flop filter field the built-in search box binds to. Defaults to nil.
  • search_op (:string) - Flop op for the search filter. Defaults to "ilike".
  • search_placeholder (:string) - Placeholder for the toolbar search input. Defaults to "Search…".
  • view (:string) - active view when a :card or :list_item slot is given. The switcher always offers exactly two, never three: list + cards on a page with a :list_item slot, and table + cards on one without (otherwise the grid would be a dead end). table is also the rendering used when a page supplies neither slot. Defaults to "table". Must be one of "table", "cards", or "list".
  • flush (:boolean) - Drop the panel chrome — border, radius, shadow, raised surface — and pull the header, toolbar, cells and pagination out to the page gutter, so the table reads as the page rather than as a card sitting on it. This is what the list and card views already do for themselves; flush is how a table view asks for it. Use it when the table IS the page. Defaults to false.
  • class (:any) - Extra classes merged onto the root element. Defaults to nil.
  • fill (:boolean) - Stretch to the parent's height (the parent must be a flex column with a definite height), scroll the table body, and pin the header/overview/pagination. Without it the table is its natural content height. Defaults to false.
  • Global attributes are accepted. Arbitrary HTML/phx-* attributes passed through.

Slots

  • header_action - Actions rendered in the title row (right side).
  • toolbar - Extra controls in the filter/search toolbar.
  • col (required) - One data column; body is rendered per row via :let. Accepts attributes:
    • label (:string) - Header label for the column.
    • field (:atom) - Flop sort field when sortable.
    • sortable (:boolean) - Enable sort patch links on the header.
    • class (:any) - Extra classes on the header cell.
    • td_class (:any) - Extra classes on body cells for this column.
  • bulk_action - Action shown in the bulk bar when rows are selected. Accepts attributes:
    • label (:string) - Button label for the bulk action.
    • icon (:string) - Optional leading icon name.
    • event (:string) - phx-click event name fired to target.
    • color (:string) - Button color token (e.g. danger).
  • row_action - Per-row trailing actions cell; receives the row via :let.
  • empty - Empty-state content when there are no rows.
  • stat - Overview metric card above the table. Accepts attributes:
    • label (:string) - Stat caption under or beside the value.
    • value (:any) - Primary metric value to display.
    • icon (:string) - Optional heroicon name shown top-right of the label row.
    • subtitle (:string) - Optional muted caption under the value.
    • href (:string) - Optional link target wrapping the stat.
    • class (:any) - Extra classes on this stat card.
  • tab - Filter preset tab in the table chrome. Accepts attributes:
    • label (:string) - Tab label text.
    • count (:integer) - Optional badge count beside the label.
    • filters (:list) - Flop filter preset, e.g. [%{field: "status", value: "pending"}]; omit for the unfiltered tab.
  • filter - Toolbar filter control bound to a Flop field. Accepts attributes:
    • field (:atom) - Flop filter field atom.
    • label (:string) - Accessible/visible label for the control.
    • type (:atom) - :select (default) | :text | :range.

    • op (:string) - Flop filter op (e.g. ==, ilike); defaults by type.
    • options (:list) - Select options as values or {label, value} tuples.
    • prompt (:string) - Blank/prompt option label for select filters.
    • placeholder (:string) - Placeholder for text filters.
    • multiple (:boolean) - multi-select filter (Flop op: in).
    • searchable (:boolean) - search box in the filter's listbox.
  • card - per-row card rendering for the cards view; enables the view toggle.
  • list_item - per-row simple list rendering; enables the list view.

sort_direction(meta, field)

The aria-sort value for a sortable column: "ascending", "descending", or "none".

ARIA requires this on the header cell (the <th>), not on the inner sort link, and only on columns that are actually sortable — "none" means "sortable but not the current sort key", which is a different claim from a plain column with no sort affordance at all.