LineaUI.Components.Table (linea_ui v0.1.1)

Copy Markdown View Source

LineOne's tables: basic, bordered, hoverable, zebra and the grid look, with :col slots the way Phoenix's generated CoreComponents.table/1 takes them.

<.table id="users" rows={@users}>
  <:col :let={user} label="Name">{user.name}</:col>
  <:col :let={user} label="Job">{user.job}</:col>
</.table>

<.table id="users" rows={@streams.users} variant="hoverable" row_click={&JS.navigate(~p"/users/#{elem(&1, 1)}")}>
  <:col :let={{_id, user}} label="Name">{user.name}</:col>
  <:action :let={{_id, user}}><.button size="xs">Edit</.button></:action>
</.table>

variant="hoverable" and "zebra" draw the filled header; rounded picks its corners: row rounds both ends of the header row (a table inside a padded card), top only the top corners (a table that is the top of a card) and none keeps it square (full width).

Sortable headers: give a column sort_key and the table on_sort; the header becomes a button that sends on_sort with %{"column" => sort_key, "direction" => "asc" | "desc"}, the direction being the one to sort by next. sort_by and sort_dir mark the current order.

<.table id="t" rows={@rows} on_sort="sort" sort_by={@sort_by} sort_dir={@sort_dir}>
  <:col :let={row} label="Name" sort_key="name">{row.name}</:col>
</.table>

Row selection: on_select adds a checkbox column. Each checkbox sends on_select with %{"id" => key, "selected" => "true" | "false"} (the new state of that row); the header one sends on_select_all with %{"selected" => "true" | "false"}. selected is the list of keys checked. The key is row_key.(row), or the row's DOM id when row_key is not given; keys are compared as given, so pass strings or convert the "id" back.

Density and chrome: compact tightens the cell padding, borderless drops the row rules (and the cell borders of bordered), headless leaves out the <thead> altogether. A column's align (left, center, right) aligns its header and cells.

<.table id="stats" rows={@rows} compact borderless headless>
  <:col :let={row}>{row.label}</:col>
  <:col :let={row} align="right">{row.count}</:col>
</.table>

Every event attr takes an event name or a %JS{}; target sets phx-target.

Expandable rows: an :expand slot adds a last column with a chevron that shows a detail row under each row (expand_label names that column). The slot receives %{row: row, toggle: js}, toggle being the JS that opens and closes it. Expandable rows render one <tbody> per row, so they take a list, not a stream.

Summary

Functions

Renders a table of rows (a list or a stream), one column per :col slot.

The JS that shows or hides the detail panel of the expandable row with DOM id row_id (the toggle the :expand slot receives is this, already bound to its row).

Functions

table(assigns)

Renders a table of rows (a list or a stream), one column per :col slot.

<.table id="people" rows={@streams.people} variant="zebra">
  <:col :let={{_id, person}} label="Name">{person.name}</:col>
  <:col :let={{_id, person}} label="Job">{person.job}</:col>
  <:action :let={{_id, person}}>
    <.button size="xs" phx-click="edit" phx-value-id={person.id}>Edit</.button>
  </:action>
</.table>

Events (each an event name or a %JS{}, sent to target when given):

  • on_sort — a sortable header was clicked: %{"column" => sort_key, "direction" => "asc" | "desc"} (the direction to sort by next).
  • on_select — a row checkbox: %{"id" => key, "selected" => "true" | "false"}.

  • on_select_all — the header checkbox: %{"selected" => "true" | "false"}.

With a stream, selected only reaches the rows the server re-renders: stream_insert the rows whose selection changed, and give all_selected for the header checkbox.

Attributes

  • id (:string) (required)
  • rows (:any) (required) - A list or a @streams.x stream.
  • row_id (:any) - A function giving each row's DOM id. Streams default to the stream id. Defaults to nil.
  • row_click (:any) - A function of the row returning a JS or an event. Defaults to nil.
  • row_item (:any) - Maps each row before it is given to the slots. Defaults to &Function.identity/1.
  • row_key (:any) - A function giving the selection key of a row. Defaults to the row's DOM id. Defaults to nil.
  • variant (:string) - grid is the gridjs look of LineOne's Grid Table page. Defaults to "basic". Must be one of "basic", "bordered", "hoverable", "zebra", or "grid".
  • rounded (:string) - Corners of the filled header of hoverable and zebra. Defaults to "row". Must be one of "row", "top", or "none".
  • sort_by (:string) - The sort_key of the sorted column. Defaults to nil.
  • sort_dir (:string) - Direction of sort_by. Defaults to "asc". Must be one of "asc", or "desc".
  • on_sort (:any) - Event sent when a sortable header is clicked. Defaults to nil.
  • on_select (:any) - Event sent when a row checkbox is clicked. Defaults to nil.
  • on_select_all (:any) - Event sent by the header checkbox. Defaults to nil.
  • selected (:list) - The keys of the selected rows. Defaults to [].
  • all_selected (:boolean) - Whether the header checkbox is checked. Computed for lists; give it for streams. Defaults to nil.
  • hoverable (:boolean) - Highlights the hovered row. Defaults to the variant's own behavior. Defaults to nil.
  • compact (:boolean) - Tighter cells: px-3 py-2 instead of the variant's padding. Defaults to false.
  • headless (:boolean) - Renders no <thead> at all (not hidden columns), for list-like tables. Defaults to false.
  • borderless (:boolean) - Removes the rules between rows, and the cell borders of the bordered variant. Defaults to false.
  • target (:any) - phx-target of the events. Defaults to nil.
  • expand_label (:string) - Header of the expand column. Defaults to nil.
  • wrapper_class (:any) - Classes of the scrolling wrapper. Defaults to nil.
  • class (:any) - Defaults to nil.
  • Global attributes are accepted.

Slots

  • col (required) - A column; receives the row (after row_item). Accepts attributes:
    • label (:string) - Header text.
    • class (:any) - Extra classes of the column's cells (the header takes head_class).
    • head_class (:any) - Extra classes of the column's header.
    • align (:string) - Text alignment of the column's header and cells. Must be one of "left", "center", or "right".
    • sort_key (:string) - Makes the header sortable; sent as "column" in on_sort.
  • action - Cells appended to every row, after the columns.
  • expand - Detail shown under a row; receives %{row: row, toggle: js}.
  • empty - Shown in a full-width row when rows is an empty list.

table_toggle_row(js \\ %JS{}, row_id)

@spec table_toggle_row(Phoenix.LiveView.JS.t(), String.t()) :: Phoenix.LiveView.JS.t()

The JS that shows or hides the detail panel of the expandable row with DOM id row_id (the toggle the :expand slot receives is this, already bound to its row).

<.button phx-click={table_toggle_row("devs-row-0")}>Details</.button>