Generic LIVE column-configuration modal for admin tables: a "Shown" list (drag to reorder via the SortableGrid hook, ✕ to remove) beside an "Available" list (click to add), with Reset + Close. There is no Apply step — the consumer applies each change immediately, so the table updates behind the modal as the user works.
Ownership model
Pure presentation. The consumer owns the column catalog, the selected
list, and persistence, and implements these events. LiveView callers
need no extra wiring; LiveComponent callers pass target (a CSS
selector for the component root) so clicks and the SortableGrid hook
reach that component instead of the host LiveView:
add_column %{"column_id" => id}
remove_column %{"column_id" => id}
reorder_columns %{"ordered_ids" => ids} (from SortableGrid)
reset_columns %{}
hide_column_modal %{} (Close / backdrop / Esc)Usage
<.column_settings_modal
show={@show_columns}
columns={[%{id: "sku", label: "SKU"}, %{id: "price", label: fn -> gettext("Price") end}]}
selected={@columns}
/>columns is every configurable column; selected is the shown ids in
display order. Labels may be strings or 0-arity functions (evaluated at
render, so gettext labels stay lazy). Ids in selected that are not in
columns are ignored, so consumers with unmanaged always-on columns
(a Name column outside the editor) can pass their full list. A column's
optional group heads the Available list for consecutive columns of
that group (standard fields, then custom fields).
A page with several tables passes sections instead — one block each,
titled when there is more than one — and add/remove/reorder then carry
"section" => id; Reset carries none and means every section.
PhoenixKitWeb.TableColumns implements the events and keeps each user's
choice; a consumer that uses it needs only the open/close events.
Shown rows use the sortable-item class the SortableGrid hook actually
reads (draggable, item-count, ordered_ids). A custom class is
ignored. Drag starts only on .pk-drag-handle so the remove button is
not a drag surface.
Summary
Functions
Attributes
show(:boolean) (required)id(:string) - Defaults to"pk-column-settings-modal".columns(:list) - Every configurable column: %{id: String.t(), label: String.t() | (-> String.t())}, optionallygroup:(a heading for the Available list, string or 0-arity fn). Defaults tonil.selected(:list) - Shown column ids, in display order. Defaults tonil.sections(:list) - Several tables in one modal, instead ofcolumns/selected: [%{id: String.t(), title: String.t(), columns: [...], selected: [...]}]. Add, remove and reorder carry"section" => id; Reset carries none and resets them all. Defaults tonil.target(:any) - Optional LiveComponent CSS selector (e.g.#my-table). Set on everyphx-clickand ondata-sortable-targetso a LiveComponent consumer receives add/remove/reorder/reset/close. Defaults tonil.