Each file is standalone, has no build step of its own, and is small enough to read whole and copy in full.
npm run build once — the examples load
../dist/av-grid.js, which is a build artifact and is not checked in. And open
them through a server, not off the filesystem: browsers block ES module imports
over file://.
npx serve . or python -m http.server, then open
examples/.
rows and nothing else. Columns, labels, widths, data types
and row keys all inferred.
Explicit widths (pixels and percent), alignment, dataType,
displayFormat, a computed column, a hidden one.
A render hook returning markup, a header renderer,
onCellClass, and a button handled through onCellClick.
Header sorting, the funnel popover, the filter-chip bar, free-text search, and filters that persist across a reload.
Row selection by checkbox and a cell range by drag or shift — two different things at once — plus full keyboard navigation.
Click-to-edit with the caret where you clicked, a dropdown column, a
boolean checkbox, validate, and an onEdit that can veto.
Excel-compatible copy in four modes, cut, and paste — from the keyboard and from the API.
Live token editing and a dark theme, with a paint counter proving the re-tint costs zero paints.
First paint, paint cost at the top against row 99,000, and the flat-cost ratio those two produce.
All seven host hooks in one file: status colours from
cellClass, an overdue row from rowClass, a date-picker
editor, a date-range filter, a copyValue on a
rendered column, and a priority sortValue.
The four things a host supplies around the rows: a grid that calls its
rows links (rowNoun), a term marked without filtering
(highlightString), a host footer under the last row
(extraElement) with room reserved by whiteSpaceY, and a
host-drawn context menu whose icons are matched by the built-in item
ids.
The same grid through av-grid/react:
<AVGridReact>, a detached <AVGridFilterBar>, and
the real instance through a ref. React comes from a CDN — the file has no
build step and no JSX.
A label column pinned: "left", twelve scrolling month
columns, a pinned: "right" Total column, and a grand-total row in
footerRows — formatted by the same columns as the data, pinned below
it, untouched by sorting and filtering.
Twelve month columns under four quarter labels — group: "Q1"
on the columns that belong together and the two-row header appears on its own — and
multiSort: true: Ctrl+click adds a sort level, each sorted header shows
its position beside the arrow.
A fake async server holds 50,000 rows; the grid holds one page.
externalFilter / externalSort keep the whole filter and
sort UI while every change round-trips through onFiltersChange /
onSortChange — and the Name column is the built-in
filterType: "text": contains / equals / starts with.
The deepest level is fetched when a node is expanded. While the request
is in flight treeColumn.busy puts a spinner in the chevron's own slot and
takes the gesture off — press as often as you like, nothing toggles, and the row does
not move. treeColumn.spinner replaces the built-in spinner with yours.
A native <dialog> opened with
showModal() puts itself in the browser's top layer and makes the rest of
the page inert. Every popover the grid opens — the context menu, a submenu, a header
funnel — follows it there, with nothing asked of the host. Escape closes the popover
and leaves the dialog standing.
The grid on a board, themed entirely by the --p-* contract —
with no theming code at all. Not a live page here: a board runs inside
Persephone, which injects the persephone API and the --p-*
theme — on a plain https page none of that exists. The README shows how to scaffold
it with create_board.
The full API reference is docs/api.md.