Xenia.Adapters.SortableJS (Xenia v0.1.1)

Copy Markdown View Source

<.sortable_list>: drag-and-drop lists (SortableJS), through Xenia's official adapter.

Setup

Install the library in your app:

npm install sortablejs --prefix assets

Pass it to the adapter, and register it, in assets/js/app.js:

import { createSortablejs } from "xenia/sortablejs"

const sortablejs = createSortablejs({
    load: () => import("sortablejs"),
})

hooks: { ...colocatedHooks, ...createHooks({ SortableJS: sortablejs }) },

Then import Xenia.Adapters.SortableJS in html_helpers, and render <.sortable_list id="..."> with the props below. Every event becomes an on_<event> attribute; commands go through Xenia.push_to/4.

The factory returns a plain adapter object: spread it to add or change props, commands and events, without copying the adapter.

The tag uses the adapter name "SortableJS". To register it under another name, render <.xenia adapter="..."> or declare your own tag.

Reference

Xenia's official adapter for SortableJS: a drag-and-drop list, optionally sharing items with other lists (kanban boards) and working as a form field.

Inside Xenia's container the server can't render children, so the adapter renders the items itself from the items prop. Labels are set as text, never as HTML.

Props:

items     [%{id, label, disabled?, class?}]   the list, in order
group     a group name: lists with the same name exchange items. Or
          %{name, pull: true | false | "clone", put: true | false}
handle    true shows a drag handle; only the handle starts a drag
disabled  true turns dragging off
list_class, item_class   extra CSS classes for the <ul> and each <li>
options   any other SortableJS option, snake_case or camelCase:
          animation, ghost_class, delay, swap_threshold, sort, ...

Commands:

reset                 re-render from the last `items` prop, e.g. after
                      the server refused a move without changing `items`

Events:

sort    %{ids, item_id, old_index, new_index}    reordered within this list
add     %{ids, item_id, new_index, from}         received from another list
remove  %{ids, item_id, old_index, to}           moved to another list
error   %{source, message, code}
`ids` is this list's order after the change; `from`/`to` are the other
list's component id. A move between lists sends `remove` from one and
`add` from the other: update both lists' items on the server.

Form field: with field={@form[:order]}, the ids are submitted as a JSON array string, e.g. "["a","c","b"]" (decode it with Jason).

Summary

Functions

sortable_list(assigns)

Attributes

  • id (:string) (required) - Stable DOM id used for adapter commands.
  • items (:list) (required)
  • group (:any)
  • handle (:boolean)
  • disabled (:boolean)
  • list_class (:string)
  • item_class (:string)
  • options (:map)
  • on_sort (:string) - LiveView event triggered when the adapter emits :sort. Defaults to nil.
  • on_add (:string) - LiveView event triggered when the adapter emits :add. Defaults to nil.
  • on_remove (:string) - LiveView event triggered when the adapter emits :remove. Defaults to nil.
  • on_error (:string) - LiveView event triggered when the adapter emits :error. Defaults to nil.
  • shortcuts (:map) - Key combination => LiveView event, while focus is inside (see Xenia.Shortcuts). Defaults to %{}.
  • on_crash (:string) - LiveView event sent if the adapter throws (see Xenia.Component). Defaults to nil.
  • Global attributes are accepted.

Slots

  • loading - Shown until the island's first mount finishes.
  • error - Shown if the adapter throws; data-xenia-retry starts it again.