Narabe.Components (Narabe v0.1.0)

Copy Markdown View Source

Lists, trees and boards that people reorder: sortable_list/1, tree/1, board/1, and tree_picker/1 to choose a place in a tree.

import Narabe.Components

<.sortable_list id="tasks" items={@streams.tasks} on_move="move">
  <:item :let={task}>{task.title}</:item>
</.sortable_list>

<.tree id="pages" items={@pages} on_move="move" rules={[nest: true, max_depth: 6]} filter />

<.board id="sprint" columns={@columns} cards={@cards} on_move="move_card" move_columns>
  <:column :let={column}>{column.name}</:column>
  <:card :let={card}>{card.title}</:card>
</.board>

<.tree_picker field={@form[:folder_id]} items={@folders} />

Items move with a mouse, a finger (a short hold), or the keyboard (Space lifts, the arrows move, Space drops); several move together when multiple. A drop moves them in the page at once and sends on_move to the LiveView (or to phx-target), with the move as Narabe.Move.parse/2 reads it:

%{"v" => 1, "ids" => ["7"], "parent" => nil, "after" => "3", "before" => "9", "index" => 2}

Reply {:reply, %{ok: true}, socket} to keep it, or %{error: "..."} to put the items back (Narabe.Live.reply/1 makes the reply from what Narabe.Ecto.move/4 returned). A refused move tells the person why.

The items are structs or maps; the component reads their id from :id and a label for screen readers from :name, :title or :label, or from the functions item_id and item_label. A list's items may be a stream.

The lists need the Narabe hook in the LiveSocket and the Narabe CSS (see the README).

Summary

Functions

A board: columns of cards that people move within a column and across them, and, with move_columns, columns that move too. A kanban, a sprint, a pipeline.

A list that people reorder: tasks, a playlist, a menu's links.

A tree that people reorder and nest: pages, folders and files, an outline.

A field of a form that chooses an item of a tree: a folder to move files to, a parent page, a category. It posts the item's id, as a <select> would; disabled items are shown and not offered (the item being moved, and those under it).

Functions

board(assigns)

A board: columns of cards that people move within a column and across them, and, with move_columns, columns that move too. A kanban, a sprint, a pipeline.

columns are in their order; cards are flat, each with its column's id (card_column, :column_id by default), in their order. A card's move says its new column as parent; a column's move has "columns" => true.

Rules about kinds apply with the column's kind as the parent's (column_kind), so a column may refuse some cards (accepts).

Attributes

  • id (:string) (required) - the element's id, and the list's in its events.
  • label (:string) - the accessible name of the whole. Defaults to nil.
  • on_move (:string) - the event of a move; without it, nothing moves. Defaults to nil.
  • on_select (:string) - the event of a change of the selected items: %{"v" => 1, "ids" => [...]}. Defaults to nil.
  • rules (:any) - what may go where: Narabe.Rules, its options, or a schema with use Narabe.Ordered. Defaults to nil.
  • multiple (:boolean) - whether several items are selected and moved together. Defaults to false.
  • handle (:boolean) - whether items drag by their handle only (a finger still holds them anywhere). Defaults to false.
  • readonly (:boolean) - no moves, only focus and selection. Defaults to false.
  • locale (:string) - the language of the words (Narabe.Messages). Defaults to "en".
  • messages (:map) - other words, by the keys of Narabe.Messages.keys/0. Defaults to %{}.
  • item_id (:any) - an item's id: a key or a function. Defaults to :id.
  • item_label (:any) - an item's label, for screen readers and the filter: a key or a function. Defaults to nil.
  • item_kind (:any) - an item's kind, for the rules: a key or a function. Defaults to nil.
  • item_locked (:any) - why an item may not move (a string), or nil: a key or a function. Defaults to nil.
  • issho (:list) - the list's room with Issho (Narabe.Issho): [instance: MyApp.Issho, document: "board:7/cards"]. Defaults to nil.
  • user (:any) - the person, with issho. Defaults to nil.
  • class (:any) - Defaults to nil.
  • columns (:list) (required) - the columns, in their order.
  • cards (:list) (required) - the cards, flat, in their order.
  • card_column (:any) - a card's column id: a key or a function. Defaults to :column_id.
  • column_id (:any) - Defaults to :id.
  • column_label (:any) - Defaults to nil.
  • column_kind (:any) - Defaults to nil.
  • move_columns (:boolean) - whether the columns move too. Defaults to false.
  • Global attributes are accepted. Supports all globals plus: ["phx-target"].

Slots

  • column - a column's header, given the column as :let; its label by default.
  • item - a card's content, given the card as :let; its label by default.
  • card - the same as item.
  • actions - buttons a finger swipes into view (a phone), given the card as :let.
  • footer - the end of each column (an "Add a card" button), given the column as :let.

sortable_list(assigns)

A list that people reorder: tasks, a playlist, a menu's links.

items is a list or a stream (@streams.tasks). With a stream, insert and delete as usual; after a move, Narabe.Live.stream_move/4 puts the item in its new place for every other viewer.

Attributes

  • id (:string) (required) - the element's id, and the list's in its events.
  • label (:string) - the accessible name of the whole. Defaults to nil.
  • on_move (:string) - the event of a move; without it, nothing moves. Defaults to nil.
  • on_select (:string) - the event of a change of the selected items: %{"v" => 1, "ids" => [...]}. Defaults to nil.
  • rules (:any) - what may go where: Narabe.Rules, its options, or a schema with use Narabe.Ordered. Defaults to nil.
  • multiple (:boolean) - whether several items are selected and moved together. Defaults to false.
  • handle (:boolean) - whether items drag by their handle only (a finger still holds them anywhere). Defaults to false.
  • readonly (:boolean) - no moves, only focus and selection. Defaults to false.
  • locale (:string) - the language of the words (Narabe.Messages). Defaults to "en".
  • messages (:map) - other words, by the keys of Narabe.Messages.keys/0. Defaults to %{}.
  • item_id (:any) - an item's id: a key or a function. Defaults to :id.
  • item_label (:any) - an item's label, for screen readers and the filter: a key or a function. Defaults to nil.
  • item_kind (:any) - an item's kind, for the rules: a key or a function. Defaults to nil.
  • item_locked (:any) - why an item may not move (a string), or nil: a key or a function. Defaults to nil.
  • issho (:list) - the list's room with Issho (Narabe.Issho): [instance: MyApp.Issho, document: "board:7/cards"]. Defaults to nil.
  • user (:any) - the person, with issho. Defaults to nil.
  • class (:any) - Defaults to nil.
  • items (:any) (required) - the items, in their order: a list or a stream.
  • Global attributes are accepted. Supports all globals plus: ["phx-target"].

Slots

  • item - an item, given as :let; its label by default.
  • actions - buttons a finger swipes into view (a phone), given the item as :let.

tree(assigns)

A tree that people reorder and nest: pages, folders and files, an outline.

items is flat, as the database has it: each with its parent's id (item_parent, :parent_id by default), in their order. The tree shows each under its parent (Narabe.Tree.rows/2); a deep tree is fine.

Rows open and close with a click on their arrow, or Left and Right. With on_expand, an item with children not loaded yet (item_children) sends %{"v" => 1, "id" => id} as it opens: add its children to items.

With filter, a box above the tree shows the items that match, and their ancestors. With on_rename, F2 or a double click on a label renames the item in place and sends %{"v" => 1, "id" => id, "name" => name}.

On a phone, a tree shows as a tree, or one level at a time with phone={:drill}.

Attributes

  • id (:string) (required) - the element's id, and the list's in its events.
  • label (:string) - the accessible name of the whole. Defaults to nil.
  • on_move (:string) - the event of a move; without it, nothing moves. Defaults to nil.
  • on_select (:string) - the event of a change of the selected items: %{"v" => 1, "ids" => [...]}. Defaults to nil.
  • rules (:any) - what may go where: Narabe.Rules, its options, or a schema with use Narabe.Ordered. Defaults to nil.
  • multiple (:boolean) - whether several items are selected and moved together. Defaults to false.
  • handle (:boolean) - whether items drag by their handle only (a finger still holds them anywhere). Defaults to false.
  • readonly (:boolean) - no moves, only focus and selection. Defaults to false.
  • locale (:string) - the language of the words (Narabe.Messages). Defaults to "en".
  • messages (:map) - other words, by the keys of Narabe.Messages.keys/0. Defaults to %{}.
  • item_id (:any) - an item's id: a key or a function. Defaults to :id.
  • item_label (:any) - an item's label, for screen readers and the filter: a key or a function. Defaults to nil.
  • item_kind (:any) - an item's kind, for the rules: a key or a function. Defaults to nil.
  • item_locked (:any) - why an item may not move (a string), or nil: a key or a function. Defaults to nil.
  • issho (:list) - the list's room with Issho (Narabe.Issho): [instance: MyApp.Issho, document: "board:7/cards"]. Defaults to nil.
  • user (:any) - the person, with issho. Defaults to nil.
  • class (:any) - Defaults to nil.
  • items (:list) (required) - the items, flat, in their order.
  • item_parent (:any) - an item's parent's id: a key or a function. Defaults to :parent_id.
  • item_children (:any) - whether an item has children not loaded yet: a key or a function. Defaults to nil.
  • expanded (:list) - the ids of the items open at first. Defaults to [].
  • on_expand (:string) - the event of an item opened whose children are not loaded. Defaults to nil.
  • on_rename (:string) - the event of a rename; without it, no renaming. Defaults to nil.
  • filter (:boolean) - whether a box filters the items. Defaults to false.
  • phone (:atom) - how the tree shows on a phone. Defaults to :tree. Must be one of :tree, or :drill.
  • Global attributes are accepted. Supports all globals plus: ["phx-target"].

Slots

  • item - an item's content, given the item as :let; its label by default.
  • actions - buttons a finger swipes into view (a phone), given the item as :let.

tree_picker(assigns)

A field of a form that chooses an item of a tree: a folder to move files to, a parent page, a category. It posts the item's id, as a <select> would; disabled items are shown and not offered (the item being moved, and those under it).

<.tree_picker field={@form[:parent_id]} items={@pages} disabled={[@page.id]} />

On a phone it shows one level at a time unless phone={:tree}.

Attributes

  • id (:string) - Defaults to nil.
  • field (Phoenix.HTML.FormField) - the form's field. Defaults to nil.
  • name (:string) - Defaults to nil.
  • value (:any) - Defaults to nil.
  • label (:string) - Defaults to nil.
  • items (:list) (required) - the items, flat, in their order.
  • item_id (:any) - Defaults to :id.
  • item_label (:any) - Defaults to nil.
  • item_kind (:any) - Defaults to nil.
  • item_parent (:any) - Defaults to :parent_id.
  • item_children (:any) - Defaults to nil.
  • disabled (:list) - ids that may not be chosen (and the items under them). Defaults to [].
  • expanded (:list) - the ids open at first; by default, the chosen item's ancestors. Defaults to nil.
  • on_expand (:string) - Defaults to nil.
  • filter (:boolean) - Defaults to true.
  • phone (:atom) - Defaults to :drill. Must be one of :tree, or :drill.
  • rules (:any) - Defaults to nil.
  • locale (:string) - Defaults to "en".
  • messages (:map) - Defaults to %{}.
  • class (:any) - Defaults to nil.
  • Global attributes are accepted. Supports all globals plus: ["phx-target"].

Slots

  • item