# `FrappeUIPhx.Components.Sortable`
[🔗](https://github.com/moacirbishopcamata/frappe_ui_phx/blob/v0.3.1/lib/frappe_ui_phx/components/sortable.ex#L1)

Lista reordenável por arrastar-e-soltar (HTML5 nativo).

O cliente só serializa o mínimo (`id`, `to`, `position`) e o drop termina em
`pushEvent` — a persistência é decisão do servidor (use `move/5` para
reordenar o assign e salve numa transação). O hook (`Sortable`) é reutilizado
por `List` e `Tree` pelo nome completo `FrappeUIPhx.Components.Sortable.Sortable`.

# `hook_name`

Nome do hook colocated, derivado do módulo (renomear o módulo não quebra `List`/`Tree`
em silêncio; um teste confere que o nome existe no manifesto de hooks).

# `item_attrs`

```elixir
@spec item_attrs(term(), boolean(), term()) :: map()
```

Atributos de um item arrastável. `parent` identifica o nível (Tree): o hook só aceita
soltar entre itens com o mesmo `parent`. Vazio quando `enabled?` é falso.

# `move`

```elixir
@spec move(
  [term()],
  (term() -&gt; term()),
  String.t(),
  String.t(),
  :before | :after | String.t()
) :: [
  term()
]
```

Move o item `id` para antes/depois de `to` (função pura, para o `handle_event` do drop).

Ids são comparados como texto (vêm do DOM). Id inexistente ou igual ao destino
devolve a lista inalterada — evento forjado não corrompe a ordem.

# `root_attrs`

```elixir
@spec root_attrs(String.t() | nil) :: map()
```

Atributos da raiz da lista reordenável (`phx-hook` e o evento de drop). Vazio sem `on_drop`.
Único dono do protocolo de DOM, usado por `sortable`, `list` e `tree`.

# `sortable`

## Attributes

* `id` (`:string`) (required)
* `items` (`:list`) (required)
* `item_id` (`:any`) - função item -> id (padrão: `item.id`). Defaults to `&FrappeUIPhx.Components.Sortable.default_id/1`.
* `on_drop` (`:string`) (required) - evento do servidor: %{"id", "to", "position"}.
* `class` (`:any`) - Defaults to `nil`.
* Global attributes are accepted.
## Slots

* `item` (required)

---

*Consult [api-reference.md](api-reference.md) for complete listing*
