Tables
@atscript/vue-table renders smart, server-driven tables straight from an annotated .as type. Sorting, filtering, pagination, virtual scrolling, column resize/reorder, row selection and contextual actions all flow from the same metadata you already wrote for your DB layer — no schema duplication, no hand-wired column definitions, no per-cell glue.
Mental model
The pipeline is three short steps:
.as type + /meta → TableDef → <AsTable> / <AsWindowTable>
(source) (parsed) (rendered).astype. A normal atscript interface, usually the same one that describes your DB table — decorated with@db.*(for the server),@meta.*,@expect.*,@ui.table.*and@ui.dict.*. Optional dynamic annotations come from@atscript/ui-fns.createTableDef(meta, type)in@atscript/uicombines the server's/metaresponse (capabilities, CRUD permissions, actions, search indexes) with the deserialised type to produce a framework-agnosticTableDef— a list ofColumnDefs plus action and CRUD descriptors.<AsTableRoot>calls this for you; consumers rarely invoke it directly.<AsTableRoot url=".." :types :controls>owns state. It fetches/meta, buildsTableDef, manages reactive query state (filters,sorters,searchTerm,pagination,columnNames), dispatches queries and exposes everything via av-slot. A child<AsTable>(paginated) or<AsWindowTable>(virtualised) consumes that context and renders rows.
Component tiers
Every vue-table component lives in one of three tiers (see CLAUDE.md):
- Tier 1 — Primary. What users tag in templates:
AsTableRoot,AsTable,AsWindowTable,AsTableActions,AsFilters,AsPresetPicker. Auto-resolved byAsResolver(). - Tier 2 — Defaults. Swappable cells and dialogs:
AsCellArray,AsCellDate,AsCellJson,AsCellNumber,AsCellUnion,AsTableCellValue,AsConfigDialog,AsFilterDialog,AsPresetDialog,AsConfirmDialog,AsActionFormDialog,AsTableHeaderCell,AsRowActions,AsColumnMenu,AsFilterField,AsFilterInput. Composed via:types/:controls/:componentsprop maps. - Tier 3 — Internals.
AsTableBase,AsTableVirtualizer,AsFilterValueHelp,AsOrderableList, … — not exported.
Paginated vs windowed
Two renderers consume the same root context:
<AsTable>— classic paginated table. Pair with a pagination control bound tostate.pagination. Best for stable, smaller result sets and CRUD-heavy admin screens.<AsWindowTable>— virtualised, block-aligned fetcher. Renders only the visible window of rows and streams blocks of size:limitas the user scrolls. Best for 10k+ row datasets or infinite-scroll feels.
See Pagination & Virtualization for the trade-offs and tuning knobs.
Model-driven state
Table state is the contract. Call sites — dialogs, toolbars, external v-model, devtools, custom toolbars — only mutate the model arrays (filterFields, filters, columnNames, sorters, searchTerm, pagination). Reactions (re-query, pagination reset, mustRefresh) live in a single root-level watcher, so any writer triggers identical behaviour. Mutators are pure — each touches exactly one entity. In particular, filterFields (which filter inputs are shown) and filters (applied conditions) are independent: hiding an input does not clear its value, clearing a value does not hide its input.
state.query() is reserved for user-initiated refreshes (refresh button, pull-to-refresh). Never call it to "apply" a state change — that path is the watcher's job.
Where to go next
- Hello World — a full working table in 25 lines.
- Annotations Reference — every
@ui.table.*,@ui.dict.*,@meta.*,@expect.*and@db.*key the table reads. - Query Function — moost-db wiring AND the custom
queryFnescape hatch. - Filtering — the filter model, value-help, and how UI state translates to Uniquery.
- Sorting — multi-sort, force sorters, header interactions.
- Pagination & Virtualization — choosing between
<AsTable>and<AsWindowTable>, tuning block size.
Related ecosystem docs
The .as language, asc CLI and the core @meta.* / @expect.* families live in the atscript core docs. The @db.* annotations and the moost-db HTTP surface (/meta, /q, relations, search indexes) are documented in the atscript-db docs.