<!-- Generated by npm run gen:skill from ui/Table/skill.md - do not edit. -->

# Table

## `<table>`

- `selection`: none | row | cell
- `selection-mode`: single | multi
- `open-on`: enter | dblclick | click
- `virtual`: auto | true | false
- `category-sort`: ascending | descending
- `paging`: none | all
- `item-height`, `deselect`, `editable`, `new-row`, `reorder`, `loading`, `secondary-sort` (column:asc or column:desc), `state`, `paginate` (rows per page), `paging-max` (number of rows), `draggable`, `droppable`, `accept`, `upload`, `upload-folders`, `upload-accept`
- bound state, `attr="{xpath}"` into the `state` document: `sort`, `filter`, `column-order`, `column-hidden`, `column-widths`, `selected`, `selected-xpath`, `focused`, `cell`, `acted`, `page`, `total`, `loaded`, `drop-slot`, `drag-key`, `drop-key`
- per row, `attr="{xpath}"` read on each row's node: `category`
- Rows and Columns: `match`, `key` (XPath, e.g. @id), `name` (unique within the table), `label`, `display` ({xpath}), `match`, `type` (text|int|number|date|bool), `width` (120 (px), 1fr, minmax(100px, 2fr)), `align` (left|center|right), `sortable`, `filter`, `editable`, `resizable`, `frozen`, `hidden`
- events: Select, Clear, Open, DoubleClick, Delete, Menu, Action, Change, CellChange, NewRow, HeaderMenu, ContextMenu, DragOver, Drop, FileUploadStarted, FileUploadComplete, PageRequest
- methods: getSelection, setSelection, showColumn, hideColumn, moveColumn, sortColumn, selectAll, deselect, selectFirstRow, selectLastRow, setReadOnly, redraw, update

```xml
<table name="tasks" draggable="true" droppable="true" state="#ui" drop-slot="{//ui/@dropSlot}">
  <row match="task" key="@id"/>
  <column name="title" display="{@title}" label="Task" width="1fr"/>
</table>

<trigger view="v" component="tasks" event="Drop" step="moved"/>
<step id="moved">
  <alias name="dragged" value="{selection(!)}" model="value"/>
  <operation name="change" value="#tasks">
    <move select="{$dragged}" before="{#ui#//ui/@dropSlot}"/>
  </operation>
</step>
```

## Guidance

- `<row match="person" key="@id"/>` and `<column name="salary" label="Salary" display="{@salary}" type="number" sortable="true"/>` go side by side, directly in the table. Bind the table to the rows' parent (`select="/staff"` for `person` rows).
- Editing: `selection="cell"` with `editable` (or a column's) fires CellChange; `new-row="true"` fires NewRow.
- `paginate` with `total` and a PageRequest step for server pages; `paging="all"` instead loads a paginated bind whole, and `loaded`/`total` count it (no footer).
- Methods through callMethod: string params, a boolean one for setReadOnly.
- `type="bool"` shows true/false text. For a checkbox, markup in the column (stamped per row): `<column name="done" label="Done"><button data-action="toggleDone" aria-pressed="{@done}">{@done}</button></column>`; `acted` names the row.
- A `label` in a rows/columns/flow panel names the table. Every drag needs another way: moveColumn or `column-order`, `column-widths`, an `Alt+ArrowUp` trigger for rows.
