PhoenixKitWeb.Components.Core.DraggableList (phoenix_kit v1.7.71)

Copy Markdown View Source

A reusable drag-and-drop sortable component supporting both grid and list layouts.

Uses SortableJS (auto-loaded from CDN) to enable drag-and-drop reordering of items. The component sends a LiveView event when items are reordered.

Design Philosophy

This component provides minimal opinionated styling - it handles drag-drop behavior while you control the appearance through classes and slot content.

Usage - Grid Layout (default)

Perfect for image galleries, card grids, etc:

<.draggable_list
  id="post-images"
  items={@images}
  on_reorder="reorder_images"
  cols={4}
>
  <:item :let={img}>
    <img src={img.url} class="w-full aspect-square object-cover rounded" />
  </:item>
  <:add_button>
    <button phx-click="add_image" class="btn">Add</button>
  </:add_button>
</.draggable_list>

Usage - List Layout

Perfect for column selectors, ordered lists, etc:

<.draggable_list
  id="table-columns"
  items={@columns}
  on_reorder="reorder_columns"
  layout={:list}
  item_class="flex items-center p-3 bg-base-100 border rounded-lg hover:bg-base-200"
>
  <:item :let={col}>
    <div class="mr-3 text-base-content/40">
      <.icon name="hero-bars-3" class="w-5 h-5" />
    </div>
    <span class="flex-1 font-medium">{col.label}</span>
    <button phx-click="remove_column" phx-value-id={col.id} class="btn btn-ghost btn-xs">
      <.icon name="hero-x-mark" class="w-4 h-4" />
    </button>
  </:item>
</.draggable_list>

Event Handler

The on_reorder event receives %{"ordered_ids" => [id1, id2, ...]} with the new order:

def handle_event("reorder_items", %{"ordered_ids" => ordered_ids}, socket) do
  # ordered_ids is a list of item IDs in the new order
  {:noreply, socket}
end

Summary

Functions

draggable_list(assigns)

Attributes

  • id (:string) (required) - Unique ID for the container.
  • items (:list) (required) - List of items to display.
  • item_id (:any) - Function to extract ID from item, defaults to &(&1.id). Defaults to nil.
  • on_reorder (:string) (required) - Event name to send on reorder.
  • layout (:atom) - Layout mode. Defaults to :grid. Must be one of :grid, or :list.
  • cols (:integer) - Number of grid columns (only for layout={:grid}). Defaults to 4.
  • gap (:string) - Gap between items (Tailwind class). Defaults to "gap-2".
  • class (:string) - Additional CSS classes for the container. Defaults to "".
  • item_class (:string) - Additional CSS classes for each item wrapper. Defaults to "".

Slots

  • item (required) - Slot to render each item, receives the item as let.
  • add_button - Optional slot for add button at end of container.