# `Masu.Components`
[🔗](https://github.com/hattoriai/masu/blob/v0.1.0/lib/masu/components.ex#L1)

The grid component.

    import Masu.Components

    <.data_grid id="users" rows={@users} label="Users">
      <:col field={:name} />
      <:col field={:email} />
      <:col field={:inserted_at} type={:datetime} label="Joined" />
    </.data_grid>

`data_grid/1` goes in a LiveView. It needs the `Masu` hook in the
LiveSocket and the Masu CSS (see the README). The rows come from a
list (`rows`), or from an Ecto query or schema and a repo (`source` and
`repo`), which then sorts, filters and counts in the database; see the
[Sources](sources.md) guide.

# `data_grid`

Renders a data grid.

The browser draws only the rows on the screen, and asks the grid for
the others as the person scrolls. A click on a column's header sorts by
it (with Shift, by it too); the edge of a header resizes its column,
and a double click there fits the column to its content. The arrow keys
move between the cells, Shift with them selects a range, and ⌘C (Ctrl+C)
copies the range as text that a spreadsheet pastes.

## Columns

Each `:col` is a column (see `Masu.Column`):

  * `field` - the key of the row's value (a map key or a struct field);
  * `value` - a function of the row that computes the value instead;
    it needs a `key`, and does not sort or filter with an Ecto source;
  * `key` - the name of the column in `Masu.Test` and in filters; the
    field as a string unless given;
  * `label` - the header; the field in words unless given;
  * `type` - `:text` (the default), `:enum`, `:integer`, `:number`,
    `:decimal`, `:date`, `:datetime`, `:time` or `:boolean`;
  * `width` and `min_width` - in pixels;
  * `align` - `:start`, `:center` or `:end` (numbers are at the end);
  * `sortable`, `filterable` and `searchable` - `false` to turn off,
    `searchable` is on for text and enums;
  * `editable` - in a grid that edits: `false` for a read-only column, or
    a function of the row that says whether its cell edits;
  * `values` - the values of an `:enum` column, which its editor offers;
  * `decimals` - the digits after the point of a `:decimal` or `:number`
    column, whatever the value has.

A `:col` with content renders each cell, with the row as `:let`:

    <:col :let={user} field={:name}>
      <.link navigate={~p"/users/#{user}"}>{user.name}</.link>
    </:col>

## Menus

`cell_menu` gives each cell a menu (a right click, or the context-menu
key or Shift+F10 on the active cell): copy, filter by the cell's value,
sort. `:header_action` and `:cell_action` add items of your own to the
header menus and to the menu of the cells; see `Masu.Action` and the
[Menus of your own](menus.md) guide.

## Attributes

* `id` (`:string`) (required) - the id of the grid.
* `rows` (`:list`) - the rows: maps or structs, or lists of values (see `columns`). Defaults to `nil`.
* `columns` (`:list`) - for a grid with no `:col` slots: its columns, each a key, or a keyword list or map of a `:col`'s attributes; without a `field`, a column reads the row at its place (rows as lists), and without a `type`, it takes the type of its values (`:auto`); see the Columns guide. Defaults to `nil`.
* `source` (`:any`) - an Ecto query or schema (with `repo`), or `{module, opts}` of a `Masu.Source`. Defaults to `nil`.
* `repo` (`:atom`) - the repo of an Ecto source. Defaults to `nil`.
* `repo_opts` (`:list`) - options for each call to the repo. Defaults to `[]`.
* `changeset` (`:any`) - a function of a row and params that gives a changeset: the person edits the cells, see the Editing guide. Defaults to `nil`.
* `update` (`:any`) - a function of a row and params that saves them: `{:ok, row}` or `{:error, changeset_or_message}`; instead of `changeset`. Defaults to `nil`.
* `create` (`:any`) - a function of params that inserts a new row: `{:ok, row}` or `{:error, changeset_or_message}`; the person adds rows, see the Editing guide. Defaults to `nil`.
* `struct` (`:any`) - with `changeset`: the struct of a new row (or a function that gives it), which the changeset casts and the repo inserts; the person adds rows. Defaults to `nil`.
* `delete` (`:any`) - a function of a row that deletes it: `:ok`, `{:ok, row}` or `{:error, changeset_or_message}`; the person deletes rows. Defaults to `nil`.
* `deletable` (`:any`) - `true` to delete rows with the repo of an Ecto source (or from a list), or a function of a row that says whether it deletes. Defaults to `nil`.
* `restore` (`:any`) - with `delete`: a function of a deleted row that brings it back (an undo); a grid that deletes with the repo inserts it again. Defaults to `nil`.
* `on_delete` (`:any`) - a function called with the rows deleted, in the LiveView's process. Defaults to `nil`.
* `row_editable` (`:any`) - a function of a row: `false` makes every cell of the row read-only. Defaults to `nil`.
* `on_save` (`:any`) - a function called with the rows saved by an edit, in the LiveView's process. Defaults to `nil`.
* `live` (`:any`) - `{pubsub, topic}`: shows the rows that change on the topic as they change, see `Masu.Live`. Defaults to `nil`.
* `presence` (`:atom`) - your app's `Phoenix.Presence` module: shows the other people who have the grid open, see `Masu.Presence`. Defaults to `nil`.
* `user` (`:map`) - with `presence`: this person, `%{id: ..., name: ..., color: ..., avatar: ...}`. Defaults to `nil`.
* `url` (`:boolean`) - when `true`, the person's view (order, filters, search, columns) goes into the URL's params, under the grid's id, and a link opens it; see `Masu.View`. Defaults to `false`.
* `views` (`:atom`) - a `Masu.Views` store: the grid keeps each person's last view, and a views menu saves named views; needs `user`. Defaults to `nil`.
* `views_key` (`:string`) - with `views`: the name of the grid in the store; its id unless given. Defaults to `nil`.
* `columns_menu` (`:boolean`) - when `true`, a columns menu to show, hide, pin and move columns. Defaults to `false`.
* `share_view` (`:boolean`) - with `presence`: whether the person's order, filters and search go to the others, who see them when they follow the person. Defaults to `true`.
* `selectable` (`:boolean`) - rows with a box to select them, and every row of the query at once; see `Masu.Live.selected/1`. Defaults to `false`.
* `on_select` (`:any`) - a function called with `%{count: n, all: boolean}` when the selection changes. Defaults to `nil`.
* `export` (`:any`) - an Export menu: `true` for CSV and XLSX, or a list of `:csv` and `:xlsx`; `false` (the default) has none, and the server exports nothing; see `Masu.Export`. Defaults to `false`.
* `cell_menu` (`:any`) - a menu on each cell (a right click, or the context-menu key or Shift+F10 on the active cell): `true` for its built-in items, or a list of `:copy`, `:filter` and `:sort`; `false` (the default) has only the `:cell_action` items, if any; see `Masu.Action`. Defaults to `false`.
* `group_by` (`:any`) - the keys of the columns the rows start grouped by, the first the outermost; see `Masu.Group`. Defaults to `[]`.
* `tree` (`:any`) - rows in a tree: the field of a row that holds its parent's id (or a function of the row); see `Masu.Tree`. Defaults to `nil`.
* `expanded` (`:list`) - with `tree`: the ids of the rows that start open. Defaults to `[]`.
* `count` (`:atom`) - how the grid counts its rows: `:exact` with the query, `:deferred` after the first rows (in a task), `:none` only when the person goes to the end; see the Export, selection and large tables guide. Defaults to `:exact`. Must be one of `:exact`, `:deferred`, or `:none`.
* `paging` (`:atom`) - `:pages` shows a page of rows at a time, with a pager below the grid, and the page in the view. Defaults to `:scroll`. Must be one of `:scroll`, or `:pages`.
* `page_size` (`:integer`) - with `paging={:pages}`: the rows of a page, read from the source at once (at most `max_block`). Defaults to `50`.
* `block_size` (`:integer`) - the rows the grid reads from its source at once as the person scrolls (at most `max_block`). Defaults to `100`.
* `max_block` (`:integer`) - the most rows of one read from the source: higher for a source where a read is costly and rows are small; see the Export, selection and large tables guide. Defaults to `500`.
* `load` (`:atom`) - how the grid reads its source: `:inline` (the default) in the event, `:async` in a task, for a slow source: the LiveView answers meanwhile, the grid says it runs, with Stop; see the Sources guide. Defaults to `:inline`. Must be one of `:inline`, or `:async`.
* `timeout` (`:integer`) - with `load={:async}`: the milliseconds a read may take, then it stops and the grid says so. Defaults to `nil`.
* `on_query` (`:any`) - a controlled grid: the LiveView runs the query. The grid shows `rows` as they are, and calls this function with `%{query: %Masu.Query{}, page: n, offset: n, limit: n}` when the person sorts, filters, searches or goes to a page; see the Sources guide. Defaults to `nil`.
* `total` (`:integer`) - with `on_query`: how many rows the LiveView's query has (its rows are a page of them). Defaults to `nil`.
* `loading` (`:boolean`) - with `on_query`: the LiveView runs its query; the grid says so, and keeps its rows until the new ones come. Defaults to `false`.
* `multi_sort` (`:boolean`) - `false` sorts by one column at a time: Shift adds none. Defaults to `true`.
* `row_id` (`:any`) - a function that gives a row's id; the `id` of the row unless given, or its place in the query for a row without one in a grid that needs no ids. `:position`: the place in the query, always, for a read-only grid of rows with no id; see the Sources guide. Defaults to `nil`.
* `sort` (`:list`) - the first order: keys, `{key, :asc | :desc}` or `Masu.Sort` structs. Defaults to `[]`.
* `filters` (`:list`) - the first filters: `{key, op, value}` or `Masu.Filter` structs. Defaults to `[]`.
* `searchable` (`:boolean`) - when `true`, a search box above the grid. Defaults to `false`.
* `label` (`:string`) - the name of the grid for a screen reader. Defaults to `nil`.
* `label_id` (`:string`) - the id of an element that names the grid. Defaults to `nil`.
* `density` (`:atom`) - the room around a cell's text: rows of 28, 36 or 48 pixels and their padding, unless `row_height` is given. Defaults to `:normal`. Must be one of `:compact`, `:normal`, or `:comfortable`.
* `row_height` (`:integer`) - the height of a row, in pixels; of the `density` unless given. Defaults to `nil`.
* `height` (`:string`) - the height of the grid, as CSS. Defaults to `"32rem"`.
* `locale` (`:string`) - the locale that formats numbers and dates; the browser's unless given. Defaults to `nil`.
* `messages` (`:map`) - words that replace the built-in ones (`search`, `empty`, `rows`, `loading`; the pager's `previous`, `next`, `page`, `of_pages`, `range`). Defaults to `%{}`.
* `class` (`:any`) - classes for the grid element. Defaults to `nil`.
* Global attributes are accepted. attributes for the grid element.
## Slots

* `col` - a column; without any, the columns are `columns`, or the source's. Accepts attributes:

  * `field` (`:any`)
  * `value` (`:any`)
  * `key` (`:string`)
  * `label` (`:string`)
  * `type` (`:atom`)
  * `width` (`:integer`)
  * `min_width` (`:integer`)
  * `align` (`:atom`)
  * `sortable` (`:boolean`)
  * `filterable` (`:boolean`)
  * `searchable` (`:boolean`)
  * `editable` (`:any`)
  * `values` (`:list`)
  * `decimals` (`:integer`)
  * `hidden` (`:boolean`)
  * `pinned` (`:atom`)
  * `aggregate` (`:any`)
* `header_action` - an item of each column's header menu: a function, an event to the LiveView, a JS command, or a panel of its content; see `Masu.Action`. Accepts attributes:

  * `label` (`:string`) (required)
  * `on_action` (`:any`)
  * `event` (`:string`)
  * `js` (`:any`)
  * `columns` (`:list`)
  * `types` (`:list`)
  * `show` (`:any`)
* `cell_action` - an item of the menu of a cell, as `:header_action`; see `Masu.Action`. Accepts attributes:

  * `label` (`:string`) (required)
  * `on_action` (`:any`)
  * `event` (`:string`)
  * `js` (`:any`)
  * `columns` (`:list`)
  * `types` (`:list`)
  * `show` (`:any`)
* `empty` - what the grid shows when it has no rows.
* `detail` - what a row shows when it opens, under it: any HEEx, another `data_grid` too; it gets the row.
* `person` - draws a person who has the grid open (`:let`), see `Masu.Presence`; initials in their color unless given.

---

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