Packages
corex
0.1.0-beta.4
0.1.2
0.1.1
0.1.0
0.1.0-rc.1
0.1.0-rc.0
0.1.0-beta.5
0.1.0-beta.4
0.1.0-beta.3
0.1.0-beta.2
0.1.0-beta.1
0.1.0-alpha.33
0.1.0-alpha.32
0.1.0-alpha.31
0.1.0-alpha.30
0.1.0-alpha.29
0.1.0-alpha.28
0.1.0-alpha.27
0.1.0-alpha.26
0.1.0-alpha.25
0.1.0-alpha.24
0.1.0-alpha.23
0.1.0-alpha.22
0.1.0-alpha.21
0.1.0-alpha.20
0.1.0-alpha.19
0.1.0-alpha.18
0.1.0-alpha.17
0.1.0-alpha.16
0.1.0-alpha.15
0.1.0-alpha.14
0.1.0-alpha.13
0.1.0-alpha.12
0.1.0-alpha.11
0.1.0-alpha.10
0.1.0-alpha.9
0.1.0-alpha.8
0.1.0-alpha.7
0.1.0-alpha.6
0.1.0-alpha.5
0.1.0-alpha.4
0.1.0-alpha.3
0.1.0-alpha.2
0.1.0-alpha.1
Accessible and unstyled UI components library written in Elixir and TypeScript that integrates Zag.js state machines into the Phoenix Framework.
Current section
Files
Jump to
Current section
Files
lib/components/data_table/selection.ex
defmodule Corex.DataTable.Selection do
import Phoenix.Component, only: [assign: 3]
@moduledoc """
Helpers for selectable `.data_table` usage in LiveViews.
Use in mount to assign initial selection state, and in
handle_event("select", ...) / handle_event("select_all", ...) to update
selection and sync checkboxes. Keeps the LiveView minimal.
## Example
def mount(_params, _session, socket) do
socket =
socket
|> assign(:users, fetch_users())
|> Corex.DataTable.Selection.assign_for_selection(:users, table_id: "users-table", row_id: &"user-\#{&1.id}")
{:ok, socket}
end
def handle_event("select", params, socket) do
{:noreply, Corex.DataTable.Selection.handle_select(socket, params, :users)}
end
def handle_event("select_all", params, socket) do
{:noreply, Corex.DataTable.Selection.handle_select_all(socket, params, :users)}
end
def render(assigns) do
~H\"\"\"
<.data_table
id="users-table"
rows={@users}
row_id={&"user-\#{&1.id}"}
selectable={true}
selected={@selected}
on_select="select"
on_select_all="select_all"
>
<:col :let={user} label="ID">{user.id}</:col>
<:col :let={user} label="Name">{user.name}</:col>
</.data_table>
\"\"\"
end
"""
@doc """
Assigns selection state for the data table.
Use in `mount/3` after assigning the rows list. Options:
- `:table_id` – required, the data_table `id` (e.g. `"users-table"`)
- `:row_id` – required, function from row to string id (e.g. `&"user-\#{&1.id}"`)
Adds `:selected` (empty list), `:selection_table_id`, and `:selection_row_id`
for use by the handlers.
"""
def assign_for_selection(socket, _rows_assign, opts) do
table_id = Keyword.fetch!(opts, :table_id)
row_id = Keyword.fetch!(opts, :row_id)
socket
|> assign(:selected, [])
|> assign(:selection_table_id, table_id)
|> assign(:selection_row_id, row_id)
end
@doc """
Handles the "select" event (single row checkbox) and returns the updated socket.
Use in `handle_event("select", params, socket)` and return
`{:noreply, Corex.DataTable.Selection.handle_select(socket, params, :users)}`.
`params` must contain `"id"` (checkbox DOM id) and `"checked"`. `rows_assign`
is the assign key holding the list (e.g. `:users`).
"""
def handle_select(socket, %{"id" => checkbox_id, "checked" => checked}, rows_assign) do
table_id = socket.assigns.selection_table_id
row_id = String.replace(checkbox_id, "#{table_id}-select-", "")
rows = socket.assigns[rows_assign] || []
selected =
if checked do
[row_id | socket.assigns.selected] |> Enum.uniq()
else
List.delete(socket.assigns.selected, row_id)
end
all_selected = length(selected) == length(rows)
socket
|> assign(:selected, selected)
|> Corex.Checkbox.set_checked("#{table_id}-select-all", all_selected)
end
@doc """
Handles the "select_all" event and returns the updated socket.
Use in `handle_event("select_all", params, socket)` and return
`{:noreply, Corex.DataTable.Selection.handle_select_all(socket, params, :users)}`.
`params` must contain `"checked"`. Syncs all row checkboxes via
`Corex.Checkbox.set_checked`. `rows_assign` is the assign key holding the list.
"""
def handle_select_all(socket, %{"checked" => checked}, rows_assign) do
table_id = socket.assigns.selection_table_id
row_id_fn = socket.assigns.selection_row_id
rows = socket.assigns[rows_assign] || []
selected =
if checked do
Enum.map(rows, row_id_fn)
else
[]
end
socket =
socket
|> assign(:selected, selected)
socket =
Enum.reduce(rows, socket, fn row, acc ->
Corex.Checkbox.set_checked(acc, "#{table_id}-select-#{row_id_fn.(row)}", checked)
end)
socket
end
end