A general-purpose LiveComponent for selecting, ordering, previewing and removing a set of images.
Generalizes the gallery + picker pattern so any PhoenixKit consumer can embed it instead of re-implementing the plumbing. The component manages an ordered list of file UUIDs and reports changes to the parent LiveView.
Usage
<.live_component
module={PhoenixKitWeb.Components.MediaGallery}
id="my-gallery"
selected={@image_uuids}
phoenix_kit_current_user={@current_user}
/>
# Receive changes in parent LiveView
def handle_info({PhoenixKitWeb.Components.MediaGallery, "my-gallery", {:changed, uuids}}, socket) do
{:noreply, assign(socket, :image_uuids, uuids)}
endAttrs
id— required; used for element IDs and change notificationstitle— optional heading above the galleryselected— ordered list of file UUIDs (current selection); default[]mode—:singleor:multiple(default:multiple)cols— grid columns for the thumbnail layout (default4). Either an integer 1..6, or a string of Tailwind grid-column classes for a responsive grid (e.g."grid-cols-4 lg:grid-cols-6 2xl:grid-cols-8"). Plumbed straight through to<.draggable_list>.featured_first— whentrue, the first item in:selectedrenders a "Featured" badge in the top-left corner. Matches thephoenix_kit_postspost-creation convention where the first image is the featured one and drag-reordering changes the feature. Defaultfalseso existing consumers aren't surprised.scope_folder_id— folder scope passed to the pickerphoenix_kit_current_user— required for upload in the pickerreadonly— whentrue, hides the pick button, remove buttons, and DnD; preview (lightbox) still works; defaultfalsemax_count— integer upper bound on the number of selected images for:multiplemode;nilmeans unlimited. For:singlemode the limit is always 1 (implied bymode). When the limit is reached, the "Add" tile is hidden entirely (not just disabled) andapply_selectionrefuses to exceed it.
Change notifications — required host wiring (silent failure otherwise)
This is a LiveComponent, so it has no handle_info of its own: after
any change (pick / remove / reorder) it sends a process message to the
host LiveView via send/2:
{PhoenixKitWeb.Components.MediaGallery, id, {:changed, ordered_uuids}}The host MUST handle this (see the Usage example above) and persist
ordered_uuids — it is a controlled component: it renders whatever the
host passes back as :selected. Forget the handler and the user's
picks/reorders are silently dropped (no crash, no warning). Each host
stores the selection differently (its own field/assoc), so there is
intentionally no use ...Embed macro — the handling is yours to write.
Reorder event contract
The thumbnail grid uses the canonical <.draggable_list> primitive
(PhoenixKitWeb.Components.Core.DraggableList), which fires the
"reorder_images" event with payload %{"ordered_ids" => uuids}.
Because MediaGallery is a LiveComponent, the grid is rendered with
target={"##{@id}"} so the SortableGrid hook routes the event via
pushEventTo to this component's own handle_event/3 — not the host
LiveView. Each gallery's id is unique, so multiple galleries on the same
page never cross-deliver reorder events.
Summary
Functions
Callback implementation for Phoenix.LiveComponent.render/1.
Functions
Callback implementation for Phoenix.LiveComponent.render/1.