argus-table 0.3.0 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/argus-column-group.js +66 -0
- package/dist/argus-column-group.js.map +1 -0
- package/dist/argus-column.js +4 -25
- package/dist/argus-column.js.map +1 -1
- package/dist/argus-table.js +553 -200
- package/dist/argus-table.js.map +1 -1
- package/dist/attributes.js +21 -0
- package/dist/attributes.js.map +1 -0
- package/dist/cdn/argus-table.js +92 -57
- package/dist/cdn/argus-table.js.map +1 -1
- package/dist/column-registry.js +23 -0
- package/dist/column-registry.js.map +1 -0
- package/dist/controllers/auto-width.js +6 -5
- package/dist/controllers/auto-width.js.map +1 -1
- package/dist/controllers/column-children.js +32 -9
- package/dist/controllers/column-children.js.map +1 -1
- package/dist/controllers/column-window.js +0 -4
- package/dist/controllers/column-window.js.map +1 -1
- package/dist/controllers/plugins.js +25 -6
- package/dist/controllers/plugins.js.map +1 -1
- package/dist/controllers/reorder-drag.js +12 -9
- package/dist/controllers/reorder-drag.js.map +1 -1
- package/dist/controllers/row-measure.js +2 -1
- package/dist/controllers/row-measure.js.map +1 -1
- package/dist/controllers/virtual-controller.js +25 -32
- package/dist/controllers/virtual-controller.js.map +1 -1
- package/dist/core/src/columns/column-groups.js +129 -0
- package/dist/core/src/columns/column-groups.js.map +1 -0
- package/dist/core/src/columns/column-order.js +125 -31
- package/dist/core/src/columns/column-order.js.map +1 -1
- package/dist/core/src/columns/resolve-columns.js +0 -1
- package/dist/core/src/columns/resolve-columns.js.map +1 -1
- package/dist/core/src/columns/spread-width.js +43 -0
- package/dist/core/src/columns/spread-width.js.map +1 -0
- package/dist/core/src/filters/filter.js +6 -8
- package/dist/core/src/filters/filter.js.map +1 -1
- package/dist/core/src/grid/row-layout.js +19 -11
- package/dist/core/src/grid/row-layout.js.map +1 -1
- package/dist/core/src/state/selection.js +2 -1
- package/dist/core/src/state/selection.js.map +1 -1
- package/dist/core/src/table/create-table.js +57 -22
- package/dist/core/src/table/create-table.js.map +1 -1
- package/dist/core/src/table/sorted-row-model.js.map +1 -1
- package/dist/core/src/virtual/row-sizes.js +0 -4
- package/dist/core/src/virtual/row-sizes.js.map +1 -1
- package/dist/custom-elements.json +489 -245
- package/dist/events.js +16 -16
- package/dist/events.js.map +1 -1
- package/dist/index.d.ts +273 -127
- package/dist/index.js +3 -2
- package/dist/render/body.js +2 -2
- package/dist/render/body.js.map +1 -1
- package/dist/render/cells.js +11 -3
- package/dist/render/cells.js.map +1 -1
- package/dist/render/content-directive.js +1 -1
- package/dist/render/content-directive.js.map +1 -1
- package/dist/render/content.js +15 -3
- package/dist/render/content.js.map +1 -1
- package/dist/render/header.js +82 -19
- package/dist/render/header.js.map +1 -1
- package/dist/styles/base.js +1 -1
- package/dist/styles/base.js.map +1 -1
- package/package.json +1 -1
package/dist/argus-table.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"argus-table.js","names":["_decorate"],"sources":["../src/argus-table.ts"],"sourcesContent":["import {\n LitElement,\n html,\n nothing,\n type CSSResultGroup,\n type PropertyValues,\n type RootPart,\n type TemplateResult,\n} from 'lit';\nimport type { ComplexAttributeConverter } from 'lit';\nimport { customElement, property } from 'lit/decorators.js';\nimport { styleMap } from 'lit/directives/style-map.js';\nimport {\n clickSelection,\n controllable,\n RowLayout,\n sameSelection,\n selectAll,\n selectRange,\n SELECTION_COLUMN_ID,\n toggleRow,\n type ColumnFilterDetail,\n type ColumnHideDetail,\n type ColumnPinDetail,\n type ColumnReorderDetail,\n type ColumnResizeDetail,\n type ColumnView,\n type Controllable,\n type GridRow,\n type SelectionStep,\n type SelectionTarget,\n type TableModel,\n} from '@argus-table/core';\nimport { announce } from './announce.js';\nimport { AutoWidths, measureColumns } from './controllers/auto-width.js';\nimport { ColumnChildrenController } from './controllers/column-children.js';\nimport { ColumnWindowController, type RenderedColumn } from './controllers/column-window.js';\nimport { DataController } from './controllers/data-controller.js';\nimport { PinScrollController } from './controllers/pin-scroll-controller.js';\nimport { PluginController, sameItems } from './controllers/plugins.js';\nimport { RowMeasure } from './controllers/row-measure.js';\nimport {\n canStartReorder,\n dropTarget,\n startReorderDrag,\n type DropSlot,\n} from './controllers/reorder-drag.js';\nimport { startResizeDrag } from './controllers/resize-drag.js';\nimport { TableController } from './controllers/table-controller.js';\nimport { VirtualController, type VirtualWindow } from './controllers/virtual-controller.js';\nimport {\n CELL_CLICK,\n COLUMN_FILTER,\n COLUMN_HIDE,\n COLUMN_PIN,\n COLUMN_REORDER,\n COLUMN_RESIZE,\n fire,\n LOAD_ERROR,\n RANGE_CHANGE,\n ROW_CLICK,\n ROW_SELECT,\n SORT_CHANGE,\n} from './events.js';\nimport { fromInteractive, INTERACTIVE } from './interactive.js';\nimport { bodyCap, watchMaxElementHeight } from './max-height.js';\nimport { renderBody, type ActiveCell, type Loading, type SelectedAt } from './render/body.js';\nimport { renderLightDom } from './render/cells.js';\nimport { content, flushContent, type ContentRenderer } from './render/content-directive.js';\nimport { renderHeader, type CheckAll, type HeaderDrag } from './render/header.js';\nimport type { CheckboxHandlers } from './render/content.js';\nimport { renderPinnedRows } from './render/pinned-rows.js';\nimport type { ArgusPlugin, CellTarget, ColumnInfo, PluginHost } from './plugins.js';\nimport { baseStyles } from './styles/base.js';\nimport type {\n CellContent,\n ColumnDef,\n ColumnFilter,\n ColumnFilterState,\n ColumnOrderState,\n ColumnPin,\n ColumnPinningState,\n ColumnSizingState,\n ColumnVisibilityState,\n DataSource,\n Density,\n PinnedRows,\n SelectionMode,\n SelectionState,\n SortState,\n TableState,\n} from './types.js';\n\n/**\n * The host carries the grid role, so rows rendered in the shadow root become\n * its children in the accessibility tree. ElementInternals sets the default;\n * `connectedCallback` also adds a `role` attribute, because tools such as\n * axe-core can't see the ElementInternals role. A `role` the page sets wins.\n */\nfunction attachGridInternals(host: HTMLElement): ElementInternals {\n const internals = host.attachInternals();\n internals.role = 'grid';\n return internals;\n}\n\n/**\n * The sortable column a header click came from, if any. Works for slotted content\n * too. Clicks on a resize handle never sort, so a click that ends a drag doesn't,\n * and neither do clicks on interactive content in the header (a button, an input).\n */\nfunction sortColumnOf(event: Event): string | undefined {\n for (const target of event.composedPath()) {\n if (!(target instanceof HTMLElement)) continue;\n if (target.dataset.resizeCol !== undefined) return undefined;\n if (target.matches(INTERACTIVE)) return undefined;\n if (target.dataset.sortCol !== undefined) return target.dataset.sortCol;\n if (target.getAttribute('part') === 'header-row') return undefined;\n }\n return undefined;\n}\n\nconst RESIZE_STEP = 10;\n\n/** `row-height`: px (`48` or `48px`) or `auto`; anything else is unset. */\nconst rowHeightConverter: ComplexAttributeConverter<number | 'auto' | undefined> = {\n fromAttribute(value) {\n if (value === null) return undefined;\n const text = value.trim().toLowerCase();\n if (text === 'auto') return 'auto';\n const px = Number(text.replace(/px$/, ''));\n return text !== '' && px > 0 ? px : undefined;\n },\n};\n\n/**\n * The cell holding the grid's single tab stop: a row (its section, and its index\n * there: in the row model for the body, in its list for a pinned row) and a\n * column. `rowId` keeps it on the same body row when the order changes.\n */\ninterface Active extends GridRow {\n rowId: string | undefined;\n col: string;\n}\n\nconst HEADER: GridRow = { section: 'header', index: 0 };\n\n/** Where the rows sit in the grid: header, pinned top, body, pinned bottom. */\nfunction layoutOf<T>(model: TableModel<T, CellContent>): RowLayout {\n return new RowLayout(model.pinnedCount('top'), model.rowCount, model.pinnedCount('bottom'));\n}\n\n/** The grid cell or column header an element is, if any. */\nfunction gridCell(target: EventTarget): HTMLElement | undefined {\n if (!(target instanceof HTMLElement) || target.dataset.col === undefined) return undefined;\n const role = target.getAttribute('role');\n return role === 'gridcell' || role === 'columnheader' ? target : undefined;\n}\n\n/** The grid row a rendered row element is, from its `aria-rowindex`. */\nfunction gridRowOf(row: Element | null, layout: RowLayout): GridRow | undefined {\n const index = row?.getAttribute('aria-rowindex');\n return index ? layout.fromAriaRowIndex(Number(index)) : undefined;\n}\n\n/**\n * The pinned edge's shadow, drawn once per side over the scroller rather than\n * per row: a shadow on every pinned cell repaints on every scroll frame. It\n * covers the pinned columns and casts `--argus-pinned-shadow` onto the rest;\n * PinScrollController sizes it to the visible area.\n */\nfunction pinShadow(side: 'start' | 'end', width: number, contentPx: number) {\n if (width === 0) return nothing;\n return html`<div\n class=\"pin-shadow\"\n data-side=${side}\n aria-hidden=\"true\"\n style=${styleMap({\n inlineSize: `${String(width)}px`,\n '--_content-h': `${String(contentPx)}px`,\n })}\n ></div>`;\n}\n\n/** CSS grid track for a column: fixed px, or a flex share with the min width as floor. */\nfunction track<T>(column: ColumnView<T, CellContent>): string {\n return column.flex === undefined\n ? `${String(column.width)}px`\n : `minmax(${String(column.minWidth)}px, ${String(column.flex)}fr)`;\n}\n\n/**\n * A virtualized data table.\n *\n * Set `columns`, and `data` or `dataSource`, as properties. Columns can also be\n * written as `<argus-column>` children; a non-empty `columns` wins over them.\n * Header and cell content is rendered into the element's light DOM and slotted\n * into the cells, so page CSS and the page's own components work inside cells.\n *\n * Any number of rows scrolls to the end. Browsers limit an element's height\n * (about 800k rows of 40 px in Chromium and Safari, 400k in Firefox), so a taller\n * body renders shorter and its scroll position is scaled onto the rows: the\n * scrollbar still spans every row, and a wheel step covers a few more of them.\n * Use `scrollToRow()` rather than setting the scroll container's `scrollTop`.\n *\n * @summary Data table with pinned rows and columns and infinite loading.\n *\n * @fires {CustomEvent<SortChangeDetail>} argus-sort-change - A sortable header was clicked, or activated with Enter or Space. `detail: { sorting }`: the new order, or the proposed one when `sorting` is controlled.\n * @fires {CustomEvent<ColumnResizeDetail>} argus-column-resize - A column was resized: by dragging its handle, with Alt+Arrow on its header, by a double-click on its handle (fit to content) or by `autosizeColumns()`. `detail: { columnId, width, sizing }`: the new widths, or the proposed ones when `columnSizing` is controlled. Fires on every frame of a drag, and once per column that `autosizeColumns()` changes.\n * @fires {CustomEvent<ColumnReorderDetail>} argus-column-reorder - A column was moved: by dragging its header, or with Alt+Shift+Arrow on its focused header. Columns move within their own group (start-pinned, scrolling, end-pinned). `detail: { columnId, order }`: the new order, or the proposed one when `columnOrder` is controlled. Fires once per move, on drop.\n * @fires {CustomEvent<ColumnPinDetail>} argus-column-pin - A column was pinned to a side or unpinned, through a plugin such as the column menu. `detail: { columnId, pin, pinning }`: `pin` is `'start'`, `'end'` or `false`; `pinning` is the new state, or the proposed one when `columnPinning` is controlled.\n * @fires {CustomEvent<ColumnHideDetail>} argus-column-hide - A column was hidden or shown, through a plugin such as the column menu. `detail: { columnId, hidden, visibility }`: `hidden` is `true` when it was hidden; `visibility` is the new state, or the proposed one when `columnVisibility` is controlled.\n * @fires {CustomEvent<ColumnFilterDetail>} argus-column-filter - A column's filter was set, changed or cleared, through a plugin such as the column menu. `detail: { columnId, filter, filters }`: `filter` is the column's new filter, or `undefined` when it was cleared; `filters` is the new state, or the proposed one when `columnFilters` is controlled.\n * @fires {CustomEvent<CellClickDetail<T>>} argus-cell-click - A body or pinned-row cell was clicked, or Enter was pressed on it. `detail: { row, columnId, value, pinned? }`; `pinned` is `'top'` or `'bottom'` for a pinned row. Fires before `argus-row-click`.\n * @fires {CustomEvent<RowClickDetail<T>>} argus-row-click - A body or pinned row was clicked, or Enter was pressed on one of its cells. `detail: { row, rowId, index, pinned? }`; for a pinned row, `index` is its index in its list.\n * @fires {CustomEvent<RangeChangeDetail>} argus-range-change - The visible rows changed. `detail: { start, end }` (row indices, inclusive).\n * @fires {CustomEvent<RowSelectDetail>} argus-row-select - The selected rows changed: by a click on a row (Ctrl/Cmd toggles, Shift selects a range), with Space, Shift+Arrow or Shift+PageUp/PageDown on a body cell, or with Ctrl/Cmd+A. Only with a `selectionMode`. `detail: { selection }`: the new row ids, or the proposed ones when `selection` is controlled.\n * @fires {CustomEvent<LoadErrorDetail>} argus-load-error - A `dataSource` page failed to load: `getRows()` rejected or threw. `detail: { error, start, end }` (`end` exclusive). The rows show a Retry button.\n *\n * @slot empty - Shown instead of the body when there are no rows. Default: \"No rows\".\n *\n * @csspart table - The scroll container that holds header and body.\n * @csspart header - The sticky header row group.\n * @csspart header-row - The header row.\n * @csspart header-cell - Every header cell.\n * @csspart header-cell-sorted - The header of the sorted column. The direction is in `aria-sort`.\n * @csspart header-cell-filtered - Added to `header-cell` on the headers of filtered columns.\n * @csspart filter-indicator - The mark in the header of a filtered column, after the sort indicator.\n * @csspart header-cell-dragging - Added to `header-cell` on the header being dragged to a new position.\n * @csspart drop-indicator - The line on the edge of the header where a dragged column would land.\n * @csspart resize-handle - The drag handle on the inline-end edge of a resizable column's header. A double-click fits the column to its content.\n * @csspart body - The row group holding the rendered body rows.\n * @csspart row - Every body row.\n * @csspart row-even - Body rows with an even index (0-based).\n * @csspart row-odd - Body rows with an odd index.\n * @csspart row-loading - Body rows whose `dataSource` page hasn't loaded yet, or failed.\n * @csspart row-selected - Body rows whose id is in `selection`.\n * @csspart cell-selection - Added to `cell` in the checkbox column (`selectionCheckboxes`), pinned rows included.\n * @csspart header-cell-selection - Added to `header-cell` on the checkbox column's header.\n * @csspart selection-checkbox - The checkboxes of the checkbox column: one per selectable row, and the select-all one in the header (`multi` mode).\n * @csspart row-pinned - Every row from `pinnedRows`, on either side. Also has `row`, but no `row-even`/`row-odd`.\n * @csspart row-pinned-top - The rows pinned below the header.\n * @csspart row-pinned-bottom - The rows pinned to the bottom.\n * @csspart cell-pinned-row - Every cell of a pinned row (next to `cell`).\n * @csspart cell - Every body cell.\n * @csspart cell-sorted - Body cells in the sorted column.\n * @csspart cell-pinned - Body cells in a pinned column, on either side.\n * @csspart cell-pinned-edge - The pinned body cell next to the scrolling columns (one per pinned side).\n * @csspart skeleton - The placeholder bar in each cell of a row that is still loading.\n * @csspart skeleton-error - Added to `skeleton` in a row whose page failed to load.\n * @csspart retry - The Retry button in the first cell of a failed page's first visible row.\n * @csspart empty - The empty-state container.\n *\n * @cssprop [--argus-bg=Canvas] - Background of the table and rows.\n * @cssprop [--argus-fg=CanvasText] - Text colour.\n * @cssprop [--argus-font=inherit] - Font shorthand for the table.\n * @cssprop [--argus-header-bg] - Header background.\n * @cssprop [--argus-header-fg=inherit] - Header text colour.\n * @cssprop [--argus-border-color] - Colour of the row borders.\n * @cssprop [--argus-border-width=1px] - Width of the row borders.\n * @cssprop [--argus-outline=none] - Border around the whole table, as a `border` shorthand (`1px solid …`). Inside the element's size.\n * @cssprop [--argus-radius=0] - Corner radius of the table. Header, rows and pinned columns are clipped to it.\n * @cssprop [--argus-row-height] - Height of a row. Default per density: 32px, 40px, 52px. With `rowHeight: 'auto'`: the header's height and the least a body or pinned row is.\n * @cssprop [--argus-cell-padding-inline] - Inline padding of cells. Default per density: 8px, 12px, 16px.\n * @cssprop [--argus-cell-padding-block] - Block padding of body and pinned-row cells with `rowHeight: 'auto'`, where content sits at the top of the cell. Default: what centres one line of text in `--argus-row-height`.\n * @cssprop [--argus-row-stripe-bg] - Background of odd rows. Default: no stripes.\n * @cssprop [--argus-pinned-shadow] - Shadow on the pinned edge, as a `box-shadow` falling toward the end side (`4px 0 6px -4px …`). Mirrored for the end edge and in RTL; `none` removes it.\n * @cssprop [--argus-resize-handle-color] - Colour of the resize handle's line, shown on hover, focus and drag.\n * @cssprop [--argus-focus-ring=2px solid Highlight] - Outline of the focused header or cell.\n * @cssprop [--argus-filter-indicator-color=currentColor] - Colour of the mark in the header of a filtered column.\n * @cssprop [--argus-drop-indicator-color=Highlight] - Colour of the line that marks where a dragged column would land.\n * @cssprop [--argus-row-hover-bg] - Background of the hovered row. Default: no change.\n * @cssprop [--argus-pinned-row-bg=var(--argus-bg)] - Background of the pinned rows, pinned columns included.\n * @cssprop [--argus-skeleton-bg] - Colour of the skeleton bars in rows still loading. Default: the text colour at low opacity.\n * @cssprop [--argus-row-selected-bg] - Background of selected rows, pinned columns included. Default: the system highlight colour, mixed into `--argus-bg`. It wins over `--argus-row-hover-bg`.\n */\n@customElement('argus-table')\nexport class ArgusTable<T = unknown> extends LitElement {\n static override styles: CSSResultGroup = baseStyles;\n\n /**\n * Column definitions. Property only: functions can't be attributes. While empty,\n * the table reads its `<argus-column>` children instead. `null` or `undefined`\n * means `[]`.\n */\n @property({ attribute: false })\n get columns(): readonly ColumnDef<T>[] {\n return this.#columnsProp;\n }\n set columns(value: readonly ColumnDef<T>[] | null | undefined) {\n // Framework bindings set `undefined` when a prop goes away.\n this.#columnsProp = value ?? [];\n }\n\n /**\n * The rows to show. Replace the array to update; changes inside it aren't\n * detected. `null` or `undefined` means `[]`.\n */\n @property({ attribute: false })\n get data(): readonly T[] {\n return this.#dataProp;\n }\n set data(value: readonly T[] | null | undefined) {\n this.#dataProp = value ?? [];\n }\n\n /**\n * Loads rows page by page as they scroll into view, instead of `data`:\n * `{ getRows({ start, end, sorting, signal }), pageSize? }`, where `end` is\n * exclusive and `getRows` resolves to `{ rows, total? }`. Without a `total`,\n * the table grows as pages arrive and a short page marks the end. Sorting\n * happens on the server: a new order reloads from the top. While set, it wins\n * over `data`. Replace the object to change `getRows` or `pageSize`.\n */\n @property({ attribute: false })\n dataSource?: DataSource<T>;\n\n /**\n * Rows fixed below the header (`top`) and at the bottom of the view (`bottom`),\n * such as a totals row: `{ top?: T[], bottom?: T[] }`. They are separate\n * objects, not rows of `data`: columns read them the same way, but they are\n * never sorted and work the same with a `dataSource`. A `cell` function gets\n * `pinned: 'top' | 'bottom'` in its context. Replace the object to update.\n */\n @property({ attribute: false })\n pinnedRows?: PinnedRows<T>;\n\n /** Returns a stable id for a row. Default: the row's index (in `data`, or among all `dataSource` rows). */\n @property({ attribute: false })\n getRowId?: (row: T, index: number) => string;\n\n /**\n * Row height in px, or `'auto'` to fit each row to its content (`row-height=\"auto\"`).\n * Unset: the density (or the `--argus-row-height` token) decides. With\n * `'auto'`, that height is the header's and the least a body or pinned row is;\n * rows grow to fit wrapped text (`wrap` columns) and taller content, and cell\n * content sits at the top. Rows are measured as they render: a row's height\n * counts the columns rendered (see `virtualizeColumns`), and rows not seen yet\n * count as one line. Give images a size, so rows don't move when they load.\n */\n @property({ attribute: 'row-height', converter: rowHeightConverter })\n rowHeight?: number | 'auto';\n\n /** Row density: `compact`, `comfortable` or `spacious`. */\n @property({ reflect: true })\n density: Density = 'comfortable';\n\n /** Rows rendered above and below the visible ones. `null` or `undefined` means the default, 6. */\n @property({ type: Number })\n get overscan(): number {\n return this.#overscan;\n }\n set overscan(value: number | null | undefined) {\n this.#overscan = value ?? 6;\n }\n\n /**\n * Renders only the scrolling columns in view (plus two on each side), for\n * wide tables: a few dozen columns and more. Pinned columns, the checkbox\n * column and the focused cell's column always render. Off by default: then\n * every column renders, as before. Cells are placed in their grid column\n * explicitly, so page CSS that relies on their order in the DOM (`:nth-child`\n * on cells) doesn't apply. `autosizeColumns()` and `width: 'auto'` columns\n * still measure columns out of view: they render for the measurement.\n */\n @property({ attribute: 'virtualize-columns', type: Boolean })\n virtualizeColumns = false;\n\n /**\n * The sort order, e.g. `[{ id: 'total', desc: true }]`; `[]` when unsorted. Unset,\n * the table keeps it itself and header clicks change it. Once set, it is\n * controlled: a click only fires `argus-sort-change` with the proposed order,\n * and nothing changes until you set the property. Set `undefined` to hand it back.\n */\n @property({ attribute: false })\n get sorting(): SortState {\n return this.#sorting.value;\n }\n set sorting(value: SortState | undefined) {\n // Lit wraps this accessor and requests the update with the old value.\n this.#sorting.set(value);\n }\n\n /**\n * Resized widths in px by column id, e.g. `{ name: 240 }`. A resized flex column\n * becomes fixed. Uncontrolled until set, like `sorting`: once set, a resize only\n * fires `argus-column-resize` with the proposed widths. `undefined` hands it back.\n */\n @property({ attribute: false })\n get columnSizing(): ColumnSizingState {\n return this.#sizing.value;\n }\n set columnSizing(value: ColumnSizingState | undefined) {\n this.#sizing.set(value);\n }\n\n /**\n * The column order: column ids as the table shows them, e.g.\n * `['id', 'total', 'customer']`. `[]` (the default) keeps the order of `columns`.\n * Each pin group (start-pinned, scrolling, end-pinned) takes its columns in this\n * order; unknown ids are ignored and columns it doesn't list follow the listed\n * ones of their group. After a move it holds every column id. Uncontrolled\n * until set, like `sorting`: once set, a move only fires `argus-column-reorder`\n * with the proposed order. `undefined` hands it back.\n */\n @property({ attribute: false })\n get columnOrder(): ColumnOrderState {\n return this.#order.value;\n }\n set columnOrder(value: ColumnOrderState | undefined) {\n this.#order.set(value);\n }\n\n /**\n * Pins by column id, over the columns' own `pin`: `'start'` or `'end'` pins a\n * column, `false` unpins one whose definition pins it, e.g.\n * `{ total: 'end', id: false }`. Columns it doesn't list keep their `pin`. A pinned\n * column joins the edge of its group nearest its place in `columnOrder`, and stops\n * flexing. Uncontrolled until set, like `sorting`: once set, pinning from a plugin\n * only fires `argus-column-pin` with the proposed pins. `undefined` hands it back.\n */\n @property({ attribute: false })\n get columnPinning(): ColumnPinningState {\n return this.#pinning.value;\n }\n set columnPinning(value: ColumnPinningState | undefined) {\n this.#pinning.set(value);\n }\n\n /**\n * Visibility by column id, over the columns' own `hidden`: `false` hides a column,\n * `true` shows one defined as `hidden`, e.g. `{ email: false }`. Columns it\n * doesn't list keep their `hidden`. A hidden column isn't rendered, but sorting by\n * it still works and it keeps its place in `columnOrder`. Uncontrolled until set,\n * like `sorting`: once set, hiding or showing from a plugin only fires\n * `argus-column-hide` with the proposed visibility. `undefined` hands it back.\n */\n @property({ attribute: false })\n get columnVisibility(): ColumnVisibilityState {\n return this.#visibility.value;\n }\n set columnVisibility(value: ColumnVisibilityState | undefined) {\n this.#visibility.set(value);\n }\n\n /**\n * Filters by column id, e.g. `{ city: { kind: 'set', values: ['Berlin'] } }` or\n * `{ total: { kind: 'number', op: 'gt', value: 100 } }`. A row shows when it passes\n * every filter and `quickFilter`. Filters on hidden columns still apply; unknown ids\n * are ignored. A column's `filterFn` replaces the built-in matching. With a\n * `dataSource`, the filters go to `getRows()` and the server filters. Users set\n * filters through plugins (the column menu) on columns with a `filter` kind.\n * Uncontrolled until set, like `sorting`: once set, a change from a plugin only\n * fires `argus-column-filter` with the proposed filters. `undefined` hands it back.\n */\n @property({ attribute: false })\n get columnFilters(): ColumnFilterState {\n return this.#filters.value;\n }\n set columnFilters(value: ColumnFilterState | undefined) {\n this.#filters.set(value);\n }\n\n /**\n * Shows only rows that contain each word of this text in one of their shown\n * columns, ignoring case, e.g. from a search box. Values are matched as text\n * (dates as `2026-11-10`); objects aren't searched. With a `dataSource`, it goes\n * to `getRows()` and the server filters. `''` (the default) shows every row.\n */\n @property({ attribute: 'quick-filter' })\n get quickFilter(): string {\n return this.#quickFilter;\n }\n set quickFilter(value: string | null | undefined) {\n this.#quickFilter = value ?? '';\n }\n\n /**\n * How rows can be selected: `none` (the default), `single` or `multi`. A click\n * on a body row selects it; in `multi` mode Ctrl/Cmd+click toggles a row,\n * Shift+click selects the range from the last clicked row, and Ctrl/Cmd+A\n * selects every row. Space toggles the focused row. Clicks on buttons, links\n * and inputs inside cells don't select. Pinned rows, and `dataSource` rows not\n * loaded yet, can't be selected.\n */\n @property({ attribute: 'selection-mode' })\n selectionMode: SelectionMode = 'none';\n\n /**\n * Adds a checkbox column, pinned first at the start, while `selectionMode` is\n * `single` or `multi`. A row's checkbox toggles it (Shift+click adds the range\n * from the last row clicked); in `multi` mode the header's checkbox selects\n * every row, or clears the selection when all are selected. Space on a\n * focused checkbox cell does the same. The column isn't part of `columns`,\n * `columnOrder` or `columnSizing`, and it fires no `argus-cell-click`.\n */\n @property({ attribute: 'selection-checkboxes', type: Boolean })\n selectionCheckboxes = false;\n\n /**\n * The selected rows, as row ids (from `getRowId`, or the row's index as a\n * string), e.g. `['p4', 'p7']`. Uncontrolled until set, like `sorting`: once\n * set, a click only fires `argus-row-select` with the proposed ids.\n * `undefined` hands it back. The table never drops ids on its own: they stay\n * through sorting, a new `data` or reloaded pages. With a `dataSource`,\n * Ctrl/Cmd+A selects the loaded rows only.\n */\n @property({ attribute: false })\n get selection(): SelectionState {\n return this.#selection.value;\n }\n set selection(value: SelectionState | undefined) {\n this.#selection.set(value);\n }\n\n /**\n * Renders header and cell content the table can't render itself, such as React\n * elements, Vue VNodes or Angular templates: `{ render(target, content),\n * release(target), flush?() }`. A `header` or `cell` that returns anything other\n * than a string, a number, a DOM node or a Lit template hands it to the renderer,\n * with a target element the table keeps while the cell is reused for other rows.\n * The framework wrappers set it; set it yourself only for another framework.\n */\n @property({ attribute: false })\n contentRenderer?: ContentRenderer;\n\n /**\n * Add-ons, such as `headerMenu()` from `@argus-table/header-menu`. Each one can\n * change the column definitions, handle keys on a focused header or cell, and\n * use the table through a small API. They run in array order. Replace the\n * array to change them; an array with the same plugins in the same order\n * changes nothing. `null` or `undefined` means `[]`.\n */\n @property({ attribute: false })\n get plugins(): readonly ArgusPlugin<T>[] {\n return this.#pluginsProp;\n }\n set plugins(value: readonly ArgusPlugin<T>[] | null | undefined) {\n const next = value ?? [];\n // The same plugins in a new array (a framework re-render) keep their connection.\n if (!sameItems(next, this.#pluginsProp)) this.#pluginsProp = next;\n }\n\n #columnsProp: readonly ColumnDef<T>[] = [];\n #pluginsProp: readonly ArgusPlugin<T>[] = [];\n #dataProp: readonly T[] = [];\n #overscan = 6;\n readonly #sorting = controllable<SortState>([]);\n readonly #sizing = controllable<ColumnSizingState>({});\n readonly #order = controllable<ColumnOrderState>([]);\n readonly #pinning = controllable<ColumnPinningState>({});\n readonly #visibility = controllable<ColumnVisibilityState>({});\n readonly #filters = controllable<ColumnFilterState>({});\n #quickFilter = '';\n /** Filters the table applied itself, by column; their events fire once the update is done. */\n readonly #appliedFilters = new Map<string, ColumnFilterDetail>();\n /** Announce the row count after the update: the filters changed. */\n #announceRows = false;\n /** Pins the table applied itself, by column; their events fire once the update is done. */\n readonly #appliedPins = new Map<string, ColumnPinDetail>();\n /** Hidden or shown columns the table applied itself; their events fire once the update is done. */\n readonly #appliedHides = new Map<string, ColumnHideDetail>();\n readonly #selection = controllable<SelectionState>([]);\n /** `selection` as a set, for the rows rendered; rebuilt when `selection` changes. */\n #selectedIds: { of: SelectionState; ids: ReadonlySet<string> } | undefined;\n /** The row a Shift range starts from: the last row clicked or toggled without Shift. */\n #anchor: string | undefined;\n /** A selection the table applied itself; its event fires once the update is done. */\n #appliedSelection: SelectionState | undefined;\n /** Whether the checkbox column was last shown; a change re-measures the pinned columns. */\n #selectionColumn = false;\n #selectionColumnChanged = false;\n /** The select-all checkbox's state, kept until `selection`, `data` or `getRowId` change. */\n #checkAll: { key: readonly unknown[]; state: CheckAll['state'] } | undefined;\n /** Moves the table applied itself, by column; their events fire once the update is done. */\n readonly #appliedReorders = new Map<string, ColumnReorderDetail>();\n /** The header being dragged to a new position, if any. */\n #drag: HeaderDrag | undefined;\n /** A move from the keyboard, announced once it has rendered: the column and its old position. */\n #announceMove: { id: string; from: number } | undefined;\n /** Resizes the table applied itself, by column; their events fire once the update is done. */\n readonly #appliedResizes = new Map<string, ColumnResizeDetail>();\n /** Columns `autosizeColumns()` renders out of view for its measurement. */\n #measureKeep: readonly string[] = [];\n /** Measured widths of `width: 'auto'` columns. */\n readonly #autoWidths = new AutoWidths(() => {\n this.requestUpdate();\n });\n /** The auto widths last passed to the model; a change re-measures the pinned columns' offsets. */\n #pushedAutoWidths: ColumnSizingState | undefined;\n #autoWidthsChanged = false;\n /** A sort the table applied itself; its event fires once the update is done. */\n #appliedSort: SortState | undefined;\n readonly #internals = attachGridInternals(this);\n readonly #table = new TableController<T>();\n readonly #children = new ColumnChildrenController<T>(this);\n /** What plugins get: closures over the table's private state. */\n readonly #pluginHost: PluginHost<T> = {\n element: this,\n column: (id) => this.#columnInfo(id),\n columns: () =>\n this.#table.model.allColumns.flatMap((c) => {\n const info = this.#columnInfo(c.id);\n return info ? [info] : [];\n }),\n setPin: (columnId, pin) => {\n this.#requestPin(columnId, pin);\n },\n setHidden: (columnId, hidden) => {\n this.#requestHide(columnId, hidden);\n },\n setFilter: (columnId, filter) => {\n this.#requestFilter(columnId, filter);\n },\n filterValues: (columnId, limit) => this.#table.model.filterValues(columnId, limit),\n cellOf: (event) => this.#cellTarget(event),\n setSort: (columnId, direction) => {\n this.#setSort(columnId, direction);\n },\n focusHeader: (columnId) => {\n this.#moveTo(HEADER, columnId, this.#table.model);\n },\n announce: (message) => {\n announce(this.ownerDocument, message);\n },\n invalidateColumns: () => {\n this.#plugins.invalidate();\n this.requestUpdate();\n },\n requestUpdate: () => {\n this.requestUpdate();\n },\n row: (index) => this.#table.model.rowAt(index)?.original,\n content: (value) => content(value),\n };\n readonly #plugins = new PluginController<T>(this, this.#pluginHost);\n #columnsById:\n | {\n of: readonly ColumnView<T, CellContent>[];\n byId: ReadonlyMap<string, ColumnView<T, CellContent>>;\n }\n | undefined;\n /** The columns last passed to the model: `columns`, or the `<argus-column>` children. */\n #columns: readonly ColumnDef<T>[] = [];\n #columnsChanged = false;\n #warnedColumns = false;\n /** End of the light-DOM part holding cell content, so later children stay outside it. */\n #contentEnd: Comment | undefined;\n /** The light-DOM part: disconnected with the table, so foreign content is released. */\n #lightPart: RootPart | undefined;\n #lightConnected = true;\n readonly #data = new DataController<T>(this);\n /** Scroll back to the top after the update (a new sort order for a data source). */\n #scrollToTop = false;\n // Looked up lazily: the virtualizer's hostUpdated runs before firstUpdated.\n readonly #virtual = new VirtualController(this, () =>\n this.renderRoot.querySelector<HTMLElement>('[part~=\"table\"]'),\n );\n readonly #pinScroll = new PinScrollController(this, () =>\n this.renderRoot.querySelector<HTMLElement>('[part~=\"table\"]'),\n );\n readonly #columnWindow = new ColumnWindowController<T>(this, () =>\n this.renderRoot.querySelector<HTMLElement>('[part~=\"table\"]'),\n );\n /** The columns the last render rendered (all of them, unless `virtualizeColumns`). */\n #rendered: RenderedColumn<T>[] = [];\n #rowPx = 40;\n #probeObserver?: ResizeObserver;\n /** The column template and row height the rows were last read for. */\n #rowsKey = '';\n /** Rows of different heights: reads the rendered rows (`rowHeight: 'auto'` only). */\n readonly #rowMeasure = new RowMeasure(this, {\n bodyIndex: (row) => {\n const at = gridRowOf(row, layoutOf(this.#table.model));\n return at?.section === 'body' && this.#data.stateAt(at.index) === 'loaded'\n ? at.index\n : undefined;\n },\n sizeOf: (index) => this.#virtual.sizeOf(index),\n minimum: () => this.#rowPx,\n });\n #window: VirtualWindow = { rows: [], totalSize: 0, range: null };\n #active: Active | undefined;\n /** Move focus to the active cell after the next update (keyboard navigation). */\n #focusPending = false;\n #lastRange = '';\n #unwatchMaxHeight: (() => void) | undefined;\n\n /**\n * The row `setState()` still has to scroll to: a data source's rows that far\n * aren't counted yet. Scrolled to again whenever the row count changes.\n */\n #scrollTarget: { row: number; count: number } | undefined;\n\n constructor() {\n super();\n // The user's own scrolling (or a click, or a key) wins over a restored position.\n for (const type of ['wheel', 'touchstart', 'pointerdown', 'keydown'] as const) {\n this.addEventListener(type, this.#dropScrollTarget, { passive: true });\n }\n }\n\n readonly #dropScrollTarget = () => {\n this.#scrollTarget = undefined;\n };\n\n override connectedCallback(): void {\n super.connectedCallback();\n if (!this.hasAttribute('role')) this.setAttribute('role', 'grid');\n if (this.hasUpdated) this.#observeProbe();\n if (this.#lightPart && !this.#lightConnected) {\n this.#lightConnected = true;\n this.#lightPart.setConnected(true);\n flushContent(this);\n }\n // A zoom change changes the tallest body the engine renders.\n this.#unwatchMaxHeight = watchMaxElementHeight(() => {\n this.requestUpdate();\n });\n }\n\n override disconnectedCallback(): void {\n super.disconnectedCallback();\n this.#probeObserver?.disconnect();\n this.#rowMeasure.stop();\n // Framework content in the cells is unmounted until the table comes back.\n if (this.#lightPart && this.#lightConnected) {\n this.#lightConnected = false;\n this.#lightPart.setConnected(false);\n flushContent(this);\n }\n this.#unwatchMaxHeight?.();\n this.#unwatchMaxHeight = undefined;\n }\n\n /**\n * `columns` when it has any, otherwise the `<argus-column>` children. Keeps its\n * identity while neither changes, so the model is only rebuilt on a change.\n */\n #effectiveColumns(): readonly ColumnDef<T>[] {\n if (this.columns.length === 0) return this.#children.defs;\n if (!this.#warnedColumns && this.#children.present) {\n this.#warnedColumns = true;\n console.warn(\n 'argus-table: the columns property is set, so <argus-column> children are ignored.',\n );\n }\n return this.columns;\n }\n\n /**\n * The node the light-DOM content is rendered before. Lit's part then ends there,\n * so children appended later (an `<argus-column>`) never land inside it. If the\n * marker was removed (say by `innerHTML`), a new one starts a fresh part.\n */\n #lightDomEnd(): Comment {\n if (this.#contentEnd?.parentNode !== this) {\n this.#contentEnd = document.createComment('');\n this.append(this.#contentEnd);\n }\n return this.#contentEnd;\n }\n\n /**\n * With a `dataSource`, drops every loaded page and loads the rows in view\n * again, keeping the scroll position. With `data`, re-renders the cells (after\n * changing row objects in place). Resolves once the table has re-rendered;\n * reloaded rows arrive as their pages load.\n */\n async refresh(): Promise<void> {\n this.#data.refresh();\n this.requestUpdate();\n await this.updateComplete;\n }\n\n /**\n * Fits columns to their content: the header, the pinned rows and the body rows\n * rendered now (rows out of view aren't measured). It resizes them like a drag\n * would, so `argus-column-resize` fires for each column that changes, and with a\n * controlled `columnSizing` nothing changes until you set it. Without `ids`, fits\n * every resizable column; columns with `resizable: false` keep their width.\n * With `virtualizeColumns`, columns out of view render for the measurement.\n * Resolves once the table has re-rendered.\n */\n async autosizeColumns(ids?: readonly string[]): Promise<void> {\n await this.updateComplete;\n const targets = this.#table.model.columns\n .filter((c) => c.resizable && (ids === undefined || ids.includes(c.id)))\n .map((c) => c.id);\n if (this.virtualizeColumns) {\n this.#measureKeep = targets;\n this.requestUpdate();\n await this.updateComplete;\n }\n const widths = measureColumns(this.renderRoot, targets);\n if (this.#measureKeep.length > 0) {\n this.#measureKeep = [];\n this.requestUpdate();\n }\n this.#requestResizes(widths);\n await this.updateComplete;\n }\n\n /** Scrolls so that the row at `index` (in the current row order) is at the top. */\n async scrollToRow(index: number): Promise<void> {\n await this.updateComplete;\n this.#virtual.scrollToIndex(index);\n await this.#settled();\n }\n\n /**\n * Waits for the update, and with `rowHeight: 'auto'` for the ones measured\n * rows request (a few at most: heights don't depend on positions).\n */\n async #settled(): Promise<void> {\n let done = await this.updateComplete;\n for (let i = 0; i < 8 && !done && this.rowHeight === 'auto'; i++) {\n done = await this.updateComplete;\n }\n }\n\n /**\n * The state users change, as one object of plain JSON for saving a user's\n * layout: `sorting`, `columnSizing`, `columnOrder`, `columnPinning`,\n * `columnVisibility`, `columnFilters`, `selection`, `quickFilter`, and `scroll`\n * (the row at the top and the horizontal offset). Controlled properties are\n * included with the values you set. The object is a copy: changing it changes\n * nothing in the table.\n */\n getState(): Required<TableState> {\n const scroller = this.renderRoot.querySelector<HTMLElement>('[part~=\"table\"]');\n return structuredClone({\n sorting: this.#sorting.value,\n columnSizing: this.#sizing.value,\n columnOrder: this.#order.value,\n columnPinning: this.#pinning.value,\n columnVisibility: this.#visibility.value,\n columnFilters: this.#filters.value,\n selection: this.#selection.value,\n quickFilter: this.#quickFilter,\n // Negative in RTL.\n scroll: { row: this.#virtual.topRow, left: Math.abs(scroller?.scrollLeft ?? 0) },\n });\n }\n\n /**\n * Restores state from `getState()`, for example a layout saved in\n * `localStorage`. Only the keys given change; ids of columns that no longer\n * exist are ignored. Properties you control are left alone (set them\n * yourself), and the others stay uncontrolled. No change events fire.\n * `quickFilter` is set like the property: a search box of yours shows it only\n * if you read it back. `scroll` is applied after the rest, so with a\n * `dataSource` the restored rows load where it points. Resolves once the table\n * has re-rendered there.\n */\n async setState(state: TableState): Promise<void> {\n this.#restore('sorting', this.#sorting, state.sorting);\n this.#restore('columnSizing', this.#sizing, state.columnSizing);\n this.#restore('columnOrder', this.#order, state.columnOrder);\n this.#restore('columnPinning', this.#pinning, state.columnPinning);\n this.#restore('columnVisibility', this.#visibility, state.columnVisibility);\n this.#restore('columnFilters', this.#filters, state.columnFilters);\n // A Shift range starts over from the restored selection.\n if (this.#restore('selection', this.#selection, state.selection)) this.#anchor = undefined;\n if (state.quickFilter !== undefined) this.quickFilter = state.quickFilter;\n this.#scrollTarget = undefined;\n await this.updateComplete;\n const { scroll } = state;\n if (!scroll) return;\n this.#virtual.scrollToIndex(scroll.row);\n // A data source counts one page past its loaded rows until it knows the\n // total: scroll on as the count grows.\n const count = this.#table.model.rowCount;\n if (this.#data.rows?.totalKnown === false && scroll.row >= count) {\n this.#scrollTarget = { row: scroll.row, count };\n }\n const scroller = this.renderRoot.querySelector<HTMLElement>('[part~=\"table\"]');\n if (scroller) scroller.scrollLeft = scroll.left * this.#direction();\n // The scroll event comes before the next frame, and the rows move with its update.\n await new Promise(requestAnimationFrame);\n await this.#settled();\n }\n\n /** Scrolls on toward the row `setState()` restored once more rows are counted. */\n #chaseScrollTarget(count: number): void {\n const target = this.#scrollTarget;\n if (!target || target.count === count) return;\n target.count = count;\n this.#virtual.scrollToIndex(target.row);\n if (target.row < count || this.#data.rows?.totalKnown !== false) this.#scrollTarget = undefined;\n }\n\n /**\n * Applies a restored value to uncontrolled state without an event, as a user\n * change would without the event. Returns whether it changed.\n */\n #restore<V>(name: keyof TableState, state: Controllable<V>, value: V | undefined): boolean {\n if (value === undefined || state.controlled) return false;\n // The same value restored again doesn't reload a data source.\n if (JSON.stringify(value) === JSON.stringify(state.value)) return false;\n const old = state.value;\n state.request(structuredClone(value));\n this.requestUpdate(name, old);\n return true;\n }\n\n protected override willUpdate(changed: PropertyValues<this>): void {\n if (changed.has('plugins')) this.#plugins.set(this.plugins);\n const columns = this.#plugins.transform(this.#effectiveColumns());\n this.#columnsChanged = columns !== this.#columns;\n this.#columns = columns;\n const filtersChanged = changed.has('columnFilters') || changed.has('quickFilter');\n if (\n changed.has('dataSource') ||\n changed.has('sorting') ||\n changed.has('getRowId') ||\n filtersChanged\n ) {\n this.#data.configure({\n source: this.dataSource,\n sorting: this.#sorting.value,\n filters: this.#filters.value,\n quickFilter: this.#quickFilter,\n getRowId: this.getRowId,\n });\n // A new order or filter starts over from the first row, so show it.\n if (this.dataSource && this.hasUpdated && (changed.has('sorting') || filtersChanged)) {\n this.#scrollToTop = !changed.has('dataSource');\n }\n // Other rows: a position restored for the old ones no longer applies.\n this.#scrollTarget = undefined;\n }\n if (filtersChanged && this.hasUpdated) this.#announceRows = true;\n if (\n this.#columnsChanged ||\n changed.has('data') ||\n changed.has('getRowId') ||\n changed.has('sorting') ||\n changed.has('columnSizing') ||\n changed.has('columnOrder') ||\n changed.has('columnPinning') ||\n changed.has('columnVisibility') ||\n changed.has('columnFilters') ||\n changed.has('quickFilter') ||\n changed.has('pinnedRows')\n ) {\n if (this.#columnsChanged) {\n this.#autoWidths.sync(columns.filter((c) => c.width === 'auto').map((c) => c.id));\n }\n this.#table.update({\n columns,\n data: this.data,\n getRowId: this.getRowId,\n sorting: this.#sorting.value,\n columnSizing: this.#sizing.value,\n columnOrder: this.#order.value,\n columnPinning: this.#pinning.value,\n columnVisibility: this.#visibility.value,\n columnFilters: this.#filters.value,\n quickFilter: this.#quickFilter,\n pinnedRows: this.pinnedRows,\n });\n }\n // A new page cache (new source, sort order or refresh) or none, and new measured widths.\n const autoWidths = this.#autoWidths.widths;\n this.#autoWidthsChanged = autoWidths !== this.#pushedAutoWidths;\n this.#pushedAutoWidths = autoWidths;\n const selectionColumn = this.selectionCheckboxes && this.#mode() !== 'none';\n this.#selectionColumnChanged = selectionColumn !== this.#selectionColumn;\n this.#selectionColumn = selectionColumn;\n this.#table.update({ remote: this.#data.rows, autoWidths, selectionColumn });\n const model = this.#table.model;\n this.#reconcileActive(model);\n const active = this.#active;\n // -1 tells assistive tech the total is unknown (a data source still growing).\n const unknownTotal = this.#data.rows?.totalKnown === false;\n const layout = layoutOf(model);\n this.#internals.ariaRowCount = unknownTotal ? '-1' : String(layout.total);\n this.#internals.ariaColCount = String(model.columns.length);\n this.#internals.ariaMultiSelectable = this.#mode() === 'multi' ? 'true' : null;\n // The header and pinned rows scroll with the body.\n const extra = this.#rowPx + this.#pinnedPx('top', layout) + this.#pinnedPx('bottom', layout);\n const auto = this.rowHeight === 'auto';\n if (!auto) this.#rowMeasure.stop();\n // Anything but a scroll may change what rows hold (data, columns, widths).\n else if (changed.size > 0 || this.#columnsChanged) this.#rowMeasure.invalidate();\n this.#virtual.configure({\n count: model.rowCount,\n rowHeight: this.#rowPx,\n cap: (logical) => bodyCap(logical, extra),\n auto: auto ? { order: model.rowOrder, indexOf: (id) => model.indexOf(id) } : undefined,\n overscan: Math.max(0, this.overscan),\n rowIdAt: (index) => this.#rowId(model, index),\n // The active body row stays rendered, so the tab stop and focus survive scrolling.\n keep:\n active?.section !== 'body' || active.rowId === undefined\n ? undefined\n : { id: active.rowId, index: active.index },\n });\n }\n\n protected override render(): TemplateResult {\n const model = this.#table.model;\n const columns = model.columns;\n this.#window = this.#virtual.computeWindow();\n const rendered = this.#columnWindow.compute(\n columns,\n this.virtualizeColumns,\n this.virtualizeColumns ? this.#keptColumns(model) : [],\n );\n this.#rendered = rendered;\n const pinnedWidth = (side: 'start' | 'end') =>\n columns.reduce((sum, c) => (c.pin === side ? sum + c.width : sum), 0);\n const pinned = (side: 'start' | 'end') => `${String(pinnedWidth(side))}px`;\n const layout = layoutOf(model);\n const style: Record<string, string> = {\n '--_cols': columns.map(track).join(' '),\n '--_width': `${String(model.totalWidth)}px`,\n '--_pin-start': pinned('start'),\n '--_pin-end': pinned('end'),\n '--_pin-top-rows': String(layout.top),\n '--_pin-bottom-rows': String(layout.bottom),\n };\n const auto = this.rowHeight === 'auto';\n if (auto) {\n // New column widths or a new row height rewrap rows: read them all again.\n const key = `${style['--_cols'] ?? ''}|${String(this.#rowPx)}`;\n if (key !== this.#rowsKey) {\n this.#rowsKey = key;\n this.#rowMeasure.invalidate();\n }\n style['--_pin-top-h'] = `${String(this.#pinnedPx('top', layout))}px`;\n style['--_pin-bottom-h'] = `${String(this.#pinnedPx('bottom', layout))}px`;\n }\n const active = this.#active;\n const activeIn = (section: GridRow['section']): ActiveCell | undefined =>\n active?.section === section ? { index: active.index, col: active.col } : undefined;\n const firstIndex = (section: GridRow['section']) => layout.ariaRowIndex({ section, index: 0 });\n if (typeof this.rowHeight === 'number' && this.rowHeight > 0) {\n style['--_row-height'] = `${String(this.rowHeight)}px`;\n }\n // The header, the pinned rows and the body: what the pinned-column shadows cover.\n const contentPx =\n this.#rowPx +\n this.#pinnedPx('top', layout) +\n this.#pinnedPx('bottom', layout) +\n (model.rowCount === 0 ? 0 : this.#window.totalSize);\n return html`<div\n part=\"table\"\n role=\"presentation\"\n style=${styleMap(style)}\n ?data-dragging=${this.#drag !== undefined}\n ?data-auto-rows=${auto}\n @keydown=${this.#onKeydown}\n @focusin=${this.#onFocusin}\n @mousedown=${this.#onMousedown}\n @click=${this.#onClick}\n >\n ${renderHeader(\n rendered,\n this.#headerHandlers,\n activeIn('header')?.col,\n this.#drag,\n this.#checkAllOf(model),\n )}\n ${renderPinnedRows('top', layout.top, rendered, firstIndex('top'), activeIn('top'))}\n ${\n model.rowCount === 0\n ? html`<div part=\"empty\"><slot name=\"empty\">No rows</slot></div>`\n : renderBody(\n this.#window.rows,\n rendered,\n this.#window.totalSize,\n activeIn('body'),\n firstIndex('body'),\n this.#loading(),\n this.#selectedAt(model),\n this.#selectionColumn ? this.#checkboxHandlers : undefined,\n auto,\n )\n }\n ${renderPinnedRows('bottom', layout.bottom, rendered, firstIndex('bottom'), activeIn('bottom'))}\n <div class=\"probe\" aria-hidden=\"true\"></div>\n </div>\n ${pinShadow('start', pinnedWidth('start'), contentPx)}\n ${pinShadow('end', pinnedWidth('end'), contentPx)}`;\n }\n\n protected override firstUpdated(): void {\n this.#observeProbe();\n this.#measureRowHeight();\n }\n\n protected override updated(changed: PropertyValues<this>): void {\n const model = this.#table.model;\n const part = renderLightDom(\n this,\n model,\n this.#window.rows,\n this.#rendered,\n this.#lightDomEnd(),\n );\n // A new marker starts a new part (the old one was removed): its content is gone.\n if (this.#lightPart && this.#lightPart !== part) this.#lightPart.setConnected(false);\n this.#lightPart = part;\n // Foreign content is committed before anything measures it.\n flushContent(this);\n this.#measureAutoWidths(model);\n // Rows of different heights: placed by the update this requests.\n const resized = this.rowHeight === 'auto' && this.#measureRows();\n if (this.#scrollToTop) {\n this.#scrollToTop = false;\n const scroller = this.renderRoot.querySelector<HTMLElement>('[part~=\"table\"]');\n if (scroller) scroller.scrollTop = 0;\n }\n this.#chaseScrollTarget(model.rowCount);\n if (\n this.#columnsChanged ||\n changed.has('columnSizing') ||\n changed.has('columnOrder') ||\n changed.has('columnPinning') ||\n changed.has('columnVisibility') ||\n this.#autoWidthsChanged ||\n this.#selectionColumnChanged\n ) {\n this.#pinScroll.measure();\n }\n // Rows that just changed height move with the next update: focus them there.\n if (this.#focusPending && !resized) {\n this.#focusPending = false;\n this.#focusActive();\n }\n if (changed.has('density') || changed.has('rowHeight')) this.#measureRowHeight();\n if (this.#appliedResizes.size > 0) {\n const details = [...this.#appliedResizes.values()];\n this.#appliedResizes.clear();\n for (const detail of details) fire(this, COLUMN_RESIZE, detail);\n }\n if (this.#announceMove) {\n this.#announceMoved(model, this.#announceMove);\n this.#announceMove = undefined;\n }\n if (this.#appliedReorders.size > 0) {\n const details = [...this.#appliedReorders.values()];\n this.#appliedReorders.clear();\n for (const detail of details) fire(this, COLUMN_REORDER, detail);\n }\n if (this.#appliedPins.size > 0) {\n const details = [...this.#appliedPins.values()];\n this.#appliedPins.clear();\n for (const detail of details) fire(this, COLUMN_PIN, detail);\n }\n if (this.#appliedHides.size > 0) {\n const details = [...this.#appliedHides.values()];\n this.#appliedHides.clear();\n for (const detail of details) fire(this, COLUMN_HIDE, detail);\n }\n if (this.#appliedFilters.size > 0) {\n const details = [...this.#appliedFilters.values()];\n this.#appliedFilters.clear();\n for (const detail of details) fire(this, COLUMN_FILTER, detail);\n }\n if (this.#announceRows) {\n this.#announceRows = false;\n this.#announceRowCount(model);\n }\n if (this.#appliedSort) {\n const sorting = this.#appliedSort;\n this.#appliedSort = undefined;\n fire(this, SORT_CHANGE, { sorting });\n }\n if (this.#appliedSelection) {\n const selection = this.#appliedSelection;\n this.#appliedSelection = undefined;\n fire(this, ROW_SELECT, { selection });\n }\n const { range } = this.#window;\n const key = range ? `${String(range.start)}:${String(range.end)}` : '';\n if (range && key !== this.#lastRange) {\n this.#lastRange = key;\n fire(this, RANGE_CHANGE, { start: range.start, end: range.end });\n }\n if (range) {\n // The rendered rows: visible plus overscan, end exclusive.\n const over = Math.max(0, this.overscan);\n this.#data.request(Math.max(0, range.start - over), range.end + 1 + over);\n }\n for (const detail of this.#data.takeErrors()) fire(this, LOAD_ERROR, detail);\n }\n\n /**\n * Columns to render wherever they are, with `virtualizeColumns`: the active\n * cell's (its tab stop and focus survive scrolling sideways, and keyboard\n * moves land on a rendered cell), one being dragged, auto widths still to\n * measure, the targets of `autosizeColumns()`, and with a `dataSource` the\n * first data column, which holds the Retry buttons.\n */\n #keptColumns(model: TableModel<T, CellContent>): (string | undefined)[] {\n return [\n this.#active?.col,\n this.#drag?.columnId,\n this.dataSource ? model.columns.find((c) => c.kind === 'data')?.id : undefined,\n ...this.#autoWidths.pending(model.columns),\n ...this.#measureKeep,\n ];\n }\n\n /**\n * Measures the `width: 'auto'` columns once loaded body rows render, or right\n * away when there are no rows (the header and pinned rows only). While a data\n * source's first rows load, they keep the default width. A changed width\n * renders once more.\n */\n #measureAutoWidths(model: TableModel<T, CellContent>): void {\n const loaded = this.#window.rows.some((r) => model.rowAt(r.index) !== undefined);\n if (!loaded && model.rowCount > 0) return;\n if (this.#autoWidths.measure(this.renderRoot, model.columns, loaded)) this.requestUpdate();\n }\n\n /**\n * Loading state for the body while a data source is set: the state of each\n * row, and a Retry button on the first visible row of each failed page.\n */\n #loading(): Loading | undefined {\n const cache = this.#data.rows;\n if (!cache) return undefined;\n const top = this.#window.range?.start ?? 0;\n const firstByPage = new Map<number, number>();\n for (const { index } of this.#window.rows) {\n if (index < top || cache.stateAt(index) !== 'error') continue;\n const page = cache.pageOf(index);\n const first = firstByPage.get(page);\n if (first === undefined || index < first) firstByPage.set(page, index);\n }\n const retry = new Map<number, string>();\n for (const [page, index] of firstByPage) {\n const start = page * cache.pageSize;\n const end = Math.min(start + cache.pageSize, cache.rowCount);\n retry.set(index, `Retry loading rows ${String(start + 1)} to ${String(end)}`);\n }\n return { stateAt: (index) => cache.stateAt(index), retry, onRetry: this.#onRetry };\n }\n\n readonly #onRetry = (event: Event) => {\n const button = event.currentTarget as HTMLElement;\n // The button goes away with the retry; keep focus in the grid, on its cell.\n if (button.matches(':focus')) button.parentElement?.focus({ preventScroll: true });\n this.#data.retry(Number(button.dataset.row));\n };\n\n /**\n * A row's id. A data source row that hasn't loaded gets a stand-in: the\n * active cell's row id if it sits there (so its DOM and focus stay put), else\n * the index, which is also its real id when there is no `getRowId`.\n */\n #rowId(model: TableModel<T, CellContent>, index: number): string {\n const id = model.rowAt(index)?.id;\n if (id !== undefined) return id;\n const active = this.#active;\n if (active?.index === index && active.rowId !== undefined) return active.rowId;\n return this.#placeholderId(index);\n }\n\n /** The id of an unloaded row: its index, or a reserved string if `getRowId` makes the ids. */\n #placeholderId(index: number): string {\n return this.getRowId ? `\\u0000${String(index)}` : String(index);\n }\n\n readonly #headerHandlers = {\n click: (event: MouseEvent) => {\n const id = sortColumnOf(event);\n if (id !== undefined) this.#requestSort(id);\n },\n pointerdown: (event: PointerEvent) => {\n if (event.button !== 0) return;\n const handle = event.composedPath()[0];\n if (!(handle instanceof HTMLElement)) return;\n const id = handle.dataset.resizeCol;\n const cell = handle.parentElement;\n if (id !== undefined && cell) {\n startResizeDrag(\n handle,\n event,\n cell.getBoundingClientRect().width,\n this.#direction(),\n (w) => {\n this.#requestResize(id, w);\n },\n );\n return;\n }\n this.#startReorder(event);\n },\n /** A double-click on a resize handle fits the column to its rendered content. */\n dblclick: (event: MouseEvent) => {\n const handle = event.composedPath()[0];\n const id = handle instanceof HTMLElement ? handle.dataset.resizeCol : undefined;\n if (id === undefined) return;\n this.#requestResizes(measureColumns(this.renderRoot, [id]));\n },\n };\n\n /**\n * Keys on a focused cell or header: arrows by cell, Home/End along the row,\n * PageUp/PageDown by a page of rows (the view scrolls with it), Ctrl+Home/End\n * (or Cmd) to the first header and the last cell. Keys from content inside a\n * cell (an input, a button) are left to that content.\n */\n readonly #onKeydown = (event: KeyboardEvent) => {\n const cell = gridCell(event.composedPath()[0] ?? event.target ?? this);\n const id = cell?.dataset.col;\n if (!cell || id === undefined) return;\n const scroller = event.currentTarget as HTMLElement;\n if (event.key === 'Tab' && event.shiftKey) {\n // Firefox makes the scroll container a tab stop, so Shift+Tab would stop\n // on it before leaving the grid. Take it out of the tab order for this\n // one move only: a tabindex there for good would expose it as a node of\n // its own between the grid and its rows.\n scroller.tabIndex = -1;\n // Put it back once focus has actually moved (a timer can run first).\n cell.addEventListener(\n 'focusout',\n () => {\n scroller.removeAttribute('tabindex');\n },\n { once: true },\n );\n return;\n }\n const pluginTarget = id === SELECTION_COLUMN_ID ? undefined : this.#cellTarget(event);\n if (pluginTarget && this.#plugins.keydown(event, pluginTarget)) return;\n const inHeader = cell.getAttribute('role') === 'columnheader';\n const { key } = event;\n const arrow = key === 'ArrowLeft' || key === 'ArrowRight';\n if (inHeader && arrow && event.altKey && event.shiftKey) {\n event.preventDefault();\n // Logical: the arrow pointing toward the inline end moves the column that way.\n const towardEnd = (key === 'ArrowRight') === (this.#direction() === 1);\n this.#moveByKey(id, towardEnd ? 1 : -1);\n return;\n }\n if (inHeader && event.altKey && arrow) {\n event.preventDefault();\n // Logical: the arrow pointing toward the inline end grows the column.\n const towardEnd = (key === 'ArrowRight') === (this.#direction() === 1);\n this.#requestResize(\n id,\n this.#currentWidth(id, cell) + (towardEnd ? RESIZE_STEP : -RESIZE_STEP),\n );\n return;\n }\n if (inHeader && (key === 'Enter' || key === ' ') && cell.dataset.sortCol !== undefined) {\n event.preventDefault();\n this.#requestSort(id);\n return;\n }\n if (this.#selectionKey(event, cell, id, inHeader, scroller)) return;\n // Ctrl (Cmd on macOS) only goes with Home and End: to the corners.\n const corner = event.ctrlKey || event.metaKey;\n if (event.altKey || event.shiftKey || (corner && key !== 'Home' && key !== 'End')) return;\n const model = this.#table.model;\n const layout = layoutOf(model);\n const from = inHeader ? HEADER : gridRowOf(cell.parentElement, layout);\n if (!from) return;\n if (!inHeader && key === 'Enter') {\n // Enter on a body cell does what a click does; on a failed row, it retries.\n event.preventDefault();\n if (from.section === 'body' && this.#data.stateAt(from.index) === 'error') {\n this.#data.retry(from.index);\n } else {\n this.#activate(event.composedPath());\n }\n return;\n }\n const columns = model.columns;\n // Rows step by grid position: header, pinned top, body, pinned bottom.\n let pos = layout.position(from);\n const last = layout.total - 1;\n let col = columns.findIndex((c) => c.id === id);\n switch (key) {\n case 'PageDown':\n case 'PageUp':\n case 'ArrowDown':\n case 'ArrowUp':\n pos = this.#verticalStep(key, pos, layout, scroller);\n break;\n case 'ArrowRight':\n col += this.#direction();\n break;\n case 'ArrowLeft':\n col -= this.#direction();\n break;\n case 'Home':\n col = 0;\n if (corner) {\n pos = 0;\n this.#virtual.scrollToEdge('start');\n }\n break;\n case 'End':\n col = columns.length - 1;\n if (corner) pos = last;\n break;\n default:\n return;\n }\n event.preventDefault();\n const row = layout.at(pos) ?? HEADER;\n // PageUp/PageDown scroll by as many rows as focus moved, so the focused cell\n // keeps its place on screen. The ends clamp; focusing scrolls the rest of\n // the way. Through the virtualizer: a scaled body's px aren't rows.\n if (key.startsWith('Page') && from.section === 'body' && row.section === 'body') {\n this.#virtual.scrollBy(this.#virtual.startOf(row.index) - this.#virtual.startOf(from.index));\n }\n // Ctrl+End onto a bottom pinned row: show the end of the body too, as\n // Ctrl+Home shows its start.\n if (corner && key === 'End' && row.section === 'bottom') {\n this.#virtual.scrollToEdge('end');\n }\n const target = columns[Math.min(Math.max(col, 0), columns.length - 1)];\n if (target) this.#moveTo(row, target.id, model);\n };\n\n /**\n * The grid position ArrowUp/ArrowDown (one row) or PageUp/PageDown (a page of\n * the body) moves to from `pos`. PageDown from above the body lands a page\n * into it and stops at its last row; PageUp stays in the body.\n */\n #verticalStep(\n key: 'PageDown' | 'PageUp' | 'ArrowDown' | 'ArrowUp',\n pos: number,\n layout: RowLayout,\n scroller: HTMLElement,\n ): number {\n const bodyFirst = layout.position({ section: 'body', index: 0 });\n const bodyLast = bodyFirst + layout.body - 1;\n const page = this.#pageRows(key, pos, layout, scroller);\n switch (key) {\n case 'PageDown':\n return layout.body > 0 && pos <= bodyLast\n ? Math.min(Math.max(pos, bodyFirst - 1) + page, bodyLast)\n : pos;\n case 'PageUp':\n return layout.body > 0 && pos > bodyFirst\n ? Math.max(Math.min(pos, bodyLast + 1) - page, bodyFirst)\n : pos;\n case 'ArrowDown':\n return Math.min(pos + 1, layout.total - 1);\n case 'ArrowUp':\n return Math.max(pos - 1, 0);\n }\n }\n\n /** How many rows PageUp/PageDown move from grid position `pos`. */\n #pageRows(key: string, pos: number, layout: RowLayout, scroller: HTMLElement): number {\n if (this.rowHeight !== 'auto') {\n // Whole rows between the sticky header and pinned rows (each one row tall).\n const fit = Math.floor(scroller.clientHeight / this.#rowPx + 0.01);\n return Math.max(1, fit - 1 - layout.top - layout.bottom);\n }\n // The body rows that fit between the header and the pinned rows, from the\n // focused body row (or the body's first or last row).\n const view =\n scroller.clientHeight -\n this.#rowPx -\n this.#pinnedPx('top', layout) -\n this.#pinnedPx('bottom', layout);\n const bodyFirst = layout.position({ section: 'body', index: 0 });\n const from = Math.min(Math.max(pos - bodyFirst, 0), Math.max(layout.body - 1, 0));\n return this.#virtual.pageRows(from, key === 'PageDown', view);\n }\n\n /**\n * Selection keys, with a `selectionMode`: Space (or Shift+Space) toggles the\n * focused body row; in `multi` mode, Shift+ArrowUp/ArrowDown and\n * Shift+PageUp/PageDown move focus through the body and select from the\n * anchor to it, and Ctrl/Cmd+A selects every row. `true` if it took the key.\n */\n #selectionKey(\n event: KeyboardEvent,\n cell: HTMLElement,\n col: string,\n inHeader: boolean,\n scroller: HTMLElement,\n ): boolean {\n const mode = this.#mode();\n if (mode === 'none' || event.altKey) return false;\n const { key } = event;\n const command = event.ctrlKey || event.metaKey;\n const model = this.#table.model;\n if (command && !event.shiftKey && key.toLowerCase() === 'a') {\n if (mode !== 'multi') return false;\n // Not the page's text: the rows.\n event.preventDefault();\n this.#selectAll();\n return true;\n }\n if (command) return false;\n if (inHeader) {\n // Space on the select-all header does what its checkbox does.\n if (key !== ' ' || col !== SELECTION_COLUMN_ID || mode !== 'multi') return false;\n event.preventDefault();\n this.#toggleAll();\n return true;\n }\n const layout = layoutOf(model);\n const from = gridRowOf(cell.parentElement, layout);\n if (from?.section !== 'body') return false;\n if (key === ' ') {\n // Space would scroll the table.\n event.preventDefault();\n const id = model.rowAt(from.index)?.id;\n if (id !== undefined) this.#requestSelection(toggleRow(this.#selection.value, mode, id));\n return true;\n }\n if (\n !event.shiftKey ||\n mode !== 'multi' ||\n (key !== 'ArrowDown' && key !== 'ArrowUp' && key !== 'PageDown' && key !== 'PageUp')\n ) {\n return false;\n }\n event.preventDefault();\n // A range stays in the body: the header and pinned rows can't be selected.\n const bodyFirst = layout.position({ section: 'body', index: 0 });\n const pos = this.#verticalStep(key, layout.position(from), layout, scroller);\n const to = layout.at(Math.min(Math.max(pos, bodyFirst), bodyFirst + layout.body - 1));\n if (to?.section !== 'body' || to.index === from.index) return true;\n if (key.startsWith('Page')) {\n this.#virtual.scrollBy(this.#virtual.startOf(to.index) - this.#virtual.startOf(from.index));\n }\n const fromId = model.rowAt(from.index)?.id;\n const anchor =\n this.#anchorAt(model) ??\n (fromId === undefined ? undefined : { id: fromId, index: from.index });\n if (anchor) {\n const idAt = (index: number) => model.rowAt(index)?.id;\n const selection = selectRange([], anchor.index, to.index, idAt, false);\n this.#requestSelection({ selection, anchor: anchor.id });\n }\n this.#moveTo(to, col, model);\n return true;\n }\n\n /** Focus that lands in a cell (a click, or content inside it) makes that cell active. */\n readonly #onFocusin = (event: FocusEvent) => {\n // Tab into the grid landed on the scroll container (Firefox makes it a tab\n // stop): move on to the grid's one tab stop, the active cell. Only when focus\n // came from outside the grid: coming from inside means the user is leaving,\n // and sending them back would trap the keyboard.\n const scroller = event.currentTarget as HTMLElement;\n if (event.composedPath()[0] === scroller) {\n const from = event.relatedTarget;\n if (!(from instanceof Node && scroller.contains(from))) {\n this.#focusPending = true;\n this.requestUpdate();\n }\n return;\n }\n for (const target of event.composedPath()) {\n const cell = gridCell(target);\n if (cell?.dataset.col !== undefined) {\n const model = this.#table.model;\n const row =\n cell.getAttribute('role') === 'columnheader'\n ? HEADER\n : gridRowOf(cell.parentElement, layoutOf(model));\n const { col } = cell.dataset;\n const prev = this.#active;\n if (\n row &&\n (row.section !== prev?.section || row.index !== prev.index || col !== prev.col)\n ) {\n this.#active = { ...row, rowId: this.#gridRowId(model, row), col };\n this.requestUpdate();\n }\n return;\n }\n if (target === event.currentTarget) return;\n }\n };\n\n /**\n * `argus-cell-click`, then `argus-row-click`, for clicks in the body; then,\n * with a `selectionMode`, the click selects its row.\n */\n readonly #onClick = (event: MouseEvent) => {\n const path = event.composedPath();\n this.#activate(path);\n const mode = this.#mode();\n const target = mode === 'none' ? undefined : this.#selectableRowOf(path);\n if (!target) return;\n // A click in the checkbox column, beside the checkbox, toggles like it.\n const inSelectionCell = path.some(\n (t) => t instanceof HTMLElement && t.dataset.col === SELECTION_COLUMN_ID,\n );\n this.#clickRow(target, event, inSelectionCell || event.ctrlKey || event.metaKey);\n };\n\n /** Selects for a click on a row, through `clickSelection`. */\n #clickRow(target: SelectionTarget, event: MouseEvent, toggle: boolean): void {\n const model = this.#table.model;\n this.#requestSelection(\n clickSelection(\n this.#selection.value,\n this.#mode(),\n target,\n this.#anchorAt(model),\n { toggle, range: event.shiftKey },\n (index) => model.rowAt(index)?.id,\n ),\n );\n }\n\n /**\n * The checkboxes' handlers. The table owns their state: a click asks for a new\n * selection, and the render that always follows sets every box back to the\n * selection (`live()`), so a change a controlled host turns down unticks it\n * again. Not `preventDefault()`: for a real click the browser runs that render\n * inside the dispatch, then undoes the toggle after it, over the render. A\n * press leaves focus on the cell, so the grid's keys keep working.\n */\n readonly #checkboxHandlers: CheckboxHandlers = {\n row: (event) => {\n const index = Number((event.currentTarget as HTMLElement).dataset.row);\n const id = this.#table.model.rowAt(index)?.id;\n if (id !== undefined) this.#clickRow({ id, index }, event, true);\n this.requestUpdate();\n },\n all: () => {\n this.#toggleAll();\n this.requestUpdate();\n },\n press: (event) => {\n event.preventDefault();\n (event.currentTarget as HTMLElement).parentElement?.focus({ preventScroll: true });\n },\n };\n\n /** Selects every selectable row, keeping the others (with a `dataSource`: the loaded ones). */\n #selectAll(): void {\n const ids = this.#table.model.selectableIds();\n this.#requestSelection({\n selection: selectAll(this.#selection.value, ids),\n anchor: this.#anchor,\n });\n }\n\n /** The select-all checkbox: clears the selection when every row is selected, else selects all. */\n #toggleAll(): void {\n if (this.#checkAllState(this.#table.model) === 'all') {\n this.#requestSelection({ selection: [], anchor: this.#anchor });\n } else {\n this.#selectAll();\n }\n }\n\n /** The select-all checkbox, in the checkbox column of a `multi` table. */\n #checkAllOf(model: TableModel<T, CellContent>): CheckAll | undefined {\n if (!this.#selectionColumn || this.#mode() !== 'multi') return undefined;\n return { state: this.#checkAllState(model), handlers: this.#checkboxHandlers };\n }\n\n /**\n * Whether all, some or none of the selectable rows are selected. With `data`\n * it's worked out once per `selection`, `data` and `getRowId`, not on scroll;\n * with a `dataSource` every time, over the loaded rows, which eviction keeps few.\n */\n #checkAllState(model: TableModel<T, CellContent>): CheckAll['state'] {\n const count = (): CheckAll['state'] => {\n const ids = model.selectableIds();\n const selected = this.#selectedSet();\n const n = ids.reduce((sum, id) => (selected.has(id) ? sum + 1 : sum), 0);\n if (n === 0) return 'none';\n return n === ids.length ? 'all' : 'some';\n };\n if (this.#data.rows) return count();\n // Everything the rows of the model depend on: the data and what filters it.\n const key = [\n this.#selection.value,\n this.data,\n this.getRowId,\n this.#columns,\n this.#filters.value,\n this.#quickFilter,\n this.#visibility.value,\n ];\n const cached = this.#checkAll;\n if (cached?.key.length !== key.length || key.some((k, i) => k !== cached.key[i])) {\n this.#checkAll = { key, state: count() };\n }\n return this.#checkAll?.state ?? 'none';\n }\n\n /**\n * A Shift+press on a row in `multi` mode selects a range of rows, not the\n * page's text from the last click: no text selection, and the cell still\n * takes focus.\n */\n readonly #onMousedown = (event: MouseEvent) => {\n if (!event.shiftKey || event.button !== 0 || this.#mode() !== 'multi') return;\n const path = event.composedPath();\n if (!this.#selectableRowOf(path)) return;\n event.preventDefault();\n for (const target of path) {\n const cell = gridCell(target);\n if (cell) {\n cell.focus({ preventScroll: true });\n return;\n }\n }\n };\n\n /** `selectionMode`, with anything unknown read as `none`. */\n #mode(): SelectionMode {\n const mode = this.selectionMode;\n return mode === 'single' || mode === 'multi' ? mode : 'none';\n }\n\n /** Whether each rendered body row is selected; `undefined` without a `selectionMode`. */\n #selectedAt(model: TableModel<T, CellContent>): SelectedAt | undefined {\n if (this.#mode() === 'none') return undefined;\n const ids = this.#selectedSet();\n return (index) => {\n const id = model.rowAt(index)?.id;\n return id === undefined ? undefined : ids.has(id);\n };\n }\n\n /** `selection` as a set, rebuilt only when `selection` changes. */\n #selectedSet(): ReadonlySet<string> {\n const selection = this.#selection.value;\n if (this.#selectedIds?.of !== selection) {\n this.#selectedIds = { of: selection, ids: new Set(selection) };\n }\n return this.#selectedIds.ids;\n }\n\n /**\n * The loaded body row a pointer event is on, as a selection target. None for\n * the header, pinned rows, rows still loading, and presses on interactive\n * content in a cell (a button, a link, an input).\n */\n #selectableRowOf(path: readonly EventTarget[]): SelectionTarget | undefined {\n const row = path.find(\n (t): t is HTMLElement => t instanceof HTMLElement && t.getAttribute('role') === 'row',\n );\n if (!row || fromInteractive(path, row)) return undefined;\n const model = this.#table.model;\n const at = gridRowOf(row, layoutOf(model));\n if (at?.section !== 'body') return undefined;\n const id = model.rowAt(at.index)?.id;\n return id === undefined ? undefined : { id, index: at.index };\n }\n\n /** The anchor row and where it is now; `undefined` if it isn't in the rows (or not loaded). */\n #anchorAt(model: TableModel<T, CellContent>): SelectionTarget | undefined {\n const id = this.#anchor;\n const index = id === undefined ? undefined : model.indexOf(id);\n return id === undefined || index === undefined ? undefined : { id, index };\n }\n\n /**\n * Changes the selection through the controlled/uncontrolled rules, and moves\n * the anchor. A step that leaves the same rows selected fires nothing.\n */\n #requestSelection(step: SelectionStep | undefined): void {\n if (!step) return;\n this.#anchor = step.anchor;\n const old = this.#selection.value;\n if (sameSelection(step.selection, old)) return;\n const { value, applied } = this.#selection.request(step.selection);\n if (applied) {\n this.#appliedSelection = value;\n this.requestUpdate('selection', old);\n } else {\n fire(this, ROW_SELECT, { selection: value });\n }\n }\n\n /**\n * Fires `argus-cell-click` (when a cell is on the path), then `argus-row-click`,\n * for the body or pinned row on an event path. Clicks and Enter on a cell use\n * it. Rows that haven't loaded, the header and the checkbox column fire nothing.\n */\n #activate(path: EventTarget[]): void {\n let columnId: string | undefined;\n for (const target of path) {\n if (!(target instanceof HTMLElement)) continue;\n const role = target.getAttribute('role');\n if (role === 'gridcell') columnId = target.dataset.col;\n if (columnId === SELECTION_COLUMN_ID) return;\n if (role !== 'row') continue;\n const model = this.#table.model;\n const at = gridRowOf(target, layoutOf(model));\n if (!at || at.section === 'header') return;\n const { index } = at;\n if (at.section === 'body') {\n const row = model.rowAt(index);\n if (!row) return;\n if (columnId !== undefined) {\n fire(this, CELL_CLICK, {\n row: row.original,\n columnId,\n value: model.valueAt(index, columnId),\n });\n }\n fire(this, ROW_CLICK, { row: row.original, rowId: row.id, index });\n return;\n }\n const pinned = at.section;\n const row = model.pinnedRowAt(pinned, index);\n if (!row) return;\n if (columnId !== undefined) {\n fire(this, CELL_CLICK, {\n row: row.original,\n columnId,\n value: model.pinnedValueAt(pinned, index, columnId),\n pinned,\n });\n }\n fire(this, ROW_CLICK, { row: row.original, rowId: row.id, index, pinned });\n return;\n }\n }\n\n /** The id of a grid row: a body or pinned row's id; none for the header. */\n #gridRowId(model: TableModel<T, CellContent>, row: GridRow): string | undefined {\n switch (row.section) {\n case 'header':\n return undefined;\n case 'body':\n return this.#rowId(model, row.index);\n default:\n return model.pinnedRowAt(row.section, row.index)?.id;\n }\n }\n\n /** Makes a cell active and focuses it after the update. The keep-rendered rule renders its row. */\n #moveTo(row: GridRow, col: string, model: TableModel<T, CellContent>): void {\n this.#active = { ...row, rowId: this.#gridRowId(model, row), col };\n this.#focusPending = true;\n this.requestUpdate();\n }\n\n #focusActive(): void {\n const active = this.#active;\n if (!active) return;\n const col = CSS.escape(active.col);\n // aria-rowindex is unique across the grid: header, pinned and body rows.\n const index = layoutOf(this.#table.model).ariaRowIndex(active);\n const cell = this.renderRoot.querySelector<HTMLElement>(\n `[role='row'][aria-rowindex=\"${String(index)}\"] > [data-col=\"${col}\"]`,\n );\n if (!cell) return;\n cell.focus({ preventScroll: true });\n // A scaled body moves `ratio` px of rows per px scrolled, so the browser can't\n // scroll a body row into view: the virtualizer does, and the next update\n // (from its scroll) shows the row and scrolls sideways. Rows of different\n // heights too: rows measured on the way can move the row again, so it\n // scrolls until they're done.\n if (active.section === 'body' && (this.#virtual.scaled || this.rowHeight === 'auto')) {\n const layout = layoutOf(this.#table.model);\n const before = this.#rowPx + this.#pinnedPx('top', layout);\n if (this.#virtual.reveal(active.index, before, this.#pinnedPx('bottom', layout))) {\n this.#focusPending = true;\n return;\n }\n }\n cell.scrollIntoView({ block: 'nearest', inline: 'nearest' });\n }\n\n /**\n * Keeps the active cell valid after columns or rows change. In the body: on the\n * same row id when it still exists (it may have moved), else at the same\n * index, clamped. A data source row that isn't loaded (yet, or any more) keeps\n * its id. A pinned row stays at its index, clamped to its list. A row whose\n * section has no rows left gives way to the header, the default. If its row\n * went away while the grid had focus, focus follows to the replacement.\n */\n #reconcileActive(model: TableModel<T, CellContent>): void {\n const columns = model.columns;\n const first = columns[0];\n if (!first) {\n this.#active = undefined;\n return;\n }\n const prev = this.#active ?? { ...HEADER, rowId: undefined, col: first.id };\n const col = columns.some((c) => c.id === prev.col)\n ? prev.col\n : this.#columnInPlaceOf(model, prev.col, first.id);\n let { section, index, rowId } = prev;\n // The cell went away with its column while focused: focus its replacement.\n let moved = col !== prev.col && this.#active !== undefined;\n if (section === 'body' && rowId !== undefined) {\n const found = model.indexOf(rowId);\n const unloaded = index < model.rowCount && model.rowAt(index) === undefined;\n if (found !== undefined) {\n index = found;\n } else if (!unloaded) {\n index = Math.min(index, model.rowCount - 1);\n rowId = index >= 0 ? (model.rowAt(index)?.id ?? this.#placeholderId(index)) : undefined;\n moved = true;\n }\n } else if (section === 'top' || section === 'bottom') {\n const count = model.pinnedCount(section);\n if (index >= count) {\n index = count - 1;\n moved = true;\n }\n rowId = index >= 0 ? model.pinnedRowAt(section, index)?.id : undefined;\n }\n if (index < 0) {\n ({ section, index } = HEADER);\n rowId = undefined;\n }\n if (moved && this.matches(':focus-within')) this.#focusPending = true;\n if (\n section !== prev.section ||\n index !== prev.index ||\n rowId !== prev.rowId ||\n col !== prev.col ||\n !this.#active\n ) {\n this.#active = { section, index, rowId, col };\n }\n }\n\n /**\n * The shown column that takes a hidden column's place: the next one in the\n * column order, else the one before it. `fallback` for a column that is gone\n * altogether.\n */\n #columnInPlaceOf(model: TableModel<T, CellContent>, id: string, fallback: string): string {\n const all = model.allColumns;\n const at = all.findIndex((c) => c.id === id);\n if (at < 0) return fallback;\n const shown = (c: ColumnView<T, CellContent>) => !c.hidden;\n return (all.slice(at + 1).find(shown) ?? all.slice(0, at).findLast(shown))?.id ?? fallback;\n }\n\n /**\n * The width a resize starts from: the latest requested width (key presses can\n * come faster than renders), else the model's fixed width, else the rendered\n * width of a flex column.\n */\n #currentWidth(columnId: string, cell: HTMLElement): number {\n const sized = this.#sizing.value[columnId];\n if (sized !== undefined) return sized;\n const view = this.#table.model.columns.find((c) => c.id === columnId);\n return view && view.flex === undefined ? view.width : cell.getBoundingClientRect().width;\n }\n\n #direction(): 1 | -1 {\n return getComputedStyle(this).direction === 'rtl' ? -1 : 1;\n }\n\n /** Sets one column's width (clamped by core), through the controlled/uncontrolled rules. */\n #requestResize(columnId: string, width: number): void {\n this.#requestResizes(new Map([[columnId, width]]));\n }\n\n /**\n * Sets column widths (clamped by core) in one change, through the\n * controlled/uncontrolled rules. One `argus-column-resize` per column that\n * changes, each with the whole new sizing.\n */\n #requestResizes(widths: ReadonlyMap<string, number>): void {\n const model = this.#table.model;\n const old = this.#sizing.value;\n const targets: [string, number][] = [];\n for (const [columnId, width] of widths) {\n const target = model.nextSizing(columnId, width)?.[columnId];\n if (target !== undefined && target !== old[columnId]) targets.push([columnId, target]);\n }\n if (targets.length === 0) return;\n const { value, applied } = this.#sizing.request({ ...old, ...Object.fromEntries(targets) });\n const details = targets.map(([columnId, width]) => ({ columnId, width, sizing: value }));\n if (applied) {\n // Only the latest width per column fires, all with the latest sizing.\n for (const detail of this.#appliedResizes.values()) detail.sizing = value;\n for (const detail of details) this.#appliedResizes.set(detail.columnId, detail);\n this.requestUpdate('columnSizing', old);\n } else {\n for (const detail of details) fire(this, COLUMN_RESIZE, detail);\n }\n }\n\n /**\n * Pins or unpins a column through the controlled/uncontrolled rules. Starts\n * from the latest requested pins, so requests can come faster than renders.\n */\n #requestPin(columnId: string, pin: ColumnPin | false): void {\n const old = this.#pinning.value;\n const next = this.#table.model.nextPinning(columnId, pin, old);\n if (!next) return;\n const { value, applied } = this.#pinning.request(next);\n if (applied) {\n for (const detail of this.#appliedPins.values()) detail.pinning = value;\n this.#appliedPins.set(columnId, { columnId, pin, pinning: value });\n this.requestUpdate('columnPinning', old);\n } else {\n fire(this, COLUMN_PIN, { columnId, pin, pinning: value });\n }\n }\n\n /** Hides or shows a column through the controlled/uncontrolled rules. */\n #requestHide(columnId: string, hidden: boolean): void {\n const old = this.#visibility.value;\n const next = this.#table.model.nextVisibility(columnId, hidden, old);\n if (!next) return;\n const { value, applied } = this.#visibility.request(next);\n if (applied) {\n for (const detail of this.#appliedHides.values()) detail.visibility = value;\n this.#appliedHides.set(columnId, { columnId, hidden, visibility: value });\n this.requestUpdate('columnVisibility', old);\n } else {\n fire(this, COLUMN_HIDE, { columnId, hidden, visibility: value });\n }\n }\n\n /** Sets or clears a column's filter through the controlled/uncontrolled rules. */\n #requestFilter(columnId: string, filter: ColumnFilter | undefined): void {\n const old = this.#filters.value;\n const next = this.#table.model.nextFilters(columnId, filter, old);\n if (!next) return;\n const { value, applied } = this.#filters.request(next);\n if (applied) {\n for (const detail of this.#appliedFilters.values()) detail.filters = value;\n this.#appliedFilters.set(columnId, { columnId, filter, filters: value });\n this.requestUpdate('columnFilters', old);\n } else {\n fire(this, COLUMN_FILTER, { columnId, filter, filters: value });\n }\n }\n\n /**\n * Says how many rows the filters leave (\"42 rows\"). With a `dataSource` the count\n * isn't known until the first page answers, so nothing is said.\n */\n #announceRowCount(model: TableModel<T, CellContent>): void {\n if (this.#data.rows) return;\n const n = model.rowCount;\n announce(this.ownerDocument, n === 1 ? '1 row' : `${String(n)} rows`);\n }\n\n /**\n * Moves a column to position `to` among the shown data columns (within its pin group),\n * through the controlled/uncontrolled rules. Starts from the latest requested\n * order, so moves can come faster than renders. `false` if it can't move there.\n */\n #requestReorder(columnId: string, to: number): boolean {\n const old = this.#order.value;\n const next = this.#table.model.nextOrder(columnId, to, old);\n if (!next) return false;\n const { value, applied } = this.#order.request(next);\n if (applied) {\n for (const detail of this.#appliedReorders.values()) detail.order = value;\n this.#appliedReorders.set(columnId, { columnId, order: value });\n this.requestUpdate('columnOrder', old);\n } else {\n fire(this, COLUMN_REORDER, { columnId, order: value });\n }\n return true;\n }\n\n /** Alt+Shift+Arrow on a header: one step toward the start (-1) or the end (1). */\n #moveByKey(columnId: string, step: 1 | -1): void {\n const model = this.#table.model;\n // From the latest requested order, so presses can come faster than renders.\n // Positions count the shown columns: hidden ones keep their place.\n const shown = new Set(model.columns.map((c) => c.id));\n const from = model\n .orderOf(this.#order.value)\n .filter((id) => shown.has(id))\n .indexOf(columnId);\n const view = model.columns.find((c) => c.id === columnId);\n if (from < 0 || !view) return;\n if (!this.#requestReorder(columnId, from + step)) return;\n // The header node moves, which drops its focus: focus it again once rendered.\n this.#focusPending = true;\n this.#announceMove ??= { id: columnId, from: view.colIndex };\n this.requestUpdate();\n }\n\n /** Tells screen readers where a column moved from the keyboard went. */\n #announceMoved(model: TableModel<T, CellContent>, move: { id: string; from: number }): void {\n const view = model.columns.find((c) => c.id === move.id);\n if (!view || view.colIndex === move.from) return;\n const header = this.renderRoot.querySelector(\n `[role='columnheader'][data-col=\"${CSS.escape(move.id)}\"] > slot`,\n );\n const name =\n header instanceof HTMLSlotElement\n ? header\n .assignedNodes({ flatten: true })\n .map((n) => n.textContent)\n .join('')\n .trim()\n : '';\n announce(\n this.ownerDocument,\n `${name || move.id} moved to column ${String(view.colIndex)} of ${String(model.columns.length)}`,\n );\n }\n\n /** A press on a reorderable header: becomes a drag once the pointer moves. */\n #startReorder(down: PointerEvent): void {\n const cell = down\n .composedPath()\n .find(\n (t): t is HTMLElement =>\n t instanceof HTMLElement && t.getAttribute('role') === 'columnheader',\n );\n const columnId = cell?.dataset.moveCol;\n if (!cell || columnId === undefined || !canStartReorder(down, cell)) return;\n const scroller = this.renderRoot.querySelector<HTMLElement>('[part~=\"table\"]');\n if (!scroller) return;\n const pin = this.#table.model.columns.find((c) => c.id === columnId)?.pin;\n startReorderDrag(cell, down, {\n scroller,\n targetAt: (x) => dropTarget(this.#dropSlots(pin), columnId, x, this.#direction()),\n scrollArea: () => (pin === undefined ? this.#scrollArea(scroller) : undefined),\n onStart: () => {\n this.#drag = { columnId, target: undefined };\n this.requestUpdate();\n },\n onTarget: (target) => {\n this.#drag = { columnId, target };\n this.requestUpdate();\n },\n onDrop: (target) => {\n this.#drag = undefined;\n if (target && this.#requestReorder(columnId, target.to)) {\n // The header node moves, which drops its focus: focus it again once rendered.\n if (this.matches(':focus-within')) this.#focusPending = true;\n }\n this.requestUpdate();\n },\n onCancel: () => {\n this.#drag = undefined;\n this.requestUpdate();\n },\n });\n }\n\n /**\n * The rendered headers of one pin group, with their positions in the whole\n * order (which leaves out the checkbox column).\n */\n #dropSlots(pin: ColumnView<T, CellContent>['pin']): DropSlot[] {\n const slots: DropSlot[] = [];\n const columns = this.#table.model.columns.filter((c) => c.kind === 'data');\n columns.forEach((c, index) => {\n if (c.pin !== pin) return;\n const cell = this.renderRoot.querySelector(\n `[role='columnheader'][data-col=\"${CSS.escape(c.id)}\"]`,\n );\n if (cell) slots.push({ id: c.id, index, rect: cell.getBoundingClientRect() });\n });\n return slots;\n }\n\n /** Where the scrolling columns show: the scroller's inside, less the pinned columns. */\n #scrollArea(scroller: HTMLElement): { left: number; right: number } {\n const columns = this.#table.model.columns;\n const width = (side: 'start' | 'end') =>\n columns.reduce((sum, c) => (c.pin === side ? sum + c.width : sum), 0);\n const ltr = this.#direction() === 1;\n const left = scroller.getBoundingClientRect().left + scroller.clientLeft;\n return {\n left: left + width(ltr ? 'start' : 'end'),\n right: left + scroller.clientWidth - width(ltr ? 'end' : 'start'),\n };\n }\n\n /** asc → desc → unsorted, through the controlled/uncontrolled rules. */\n #requestSort(columnId: string): void {\n const next = this.#table.model.nextSorting(columnId);\n if (next) this.#applySorting(next);\n }\n\n /**\n * A plugin's sort: by a column in a direction, or (`null`) cleared if it is by\n * that column. Only sortable columns, and only a change.\n */\n #setSort(columnId: string, direction: 'asc' | 'desc' | null): void {\n const view = this.#table.model.columns.find((c) => c.id === columnId);\n if (view?.kind !== 'data' || !view.sortable) return;\n const sorted = view.sorted === false ? null : view.sorted;\n if (direction === sorted) return;\n if (direction === null) this.#applySorting([]);\n else this.#applySorting([{ id: columnId, desc: direction === 'desc' }]);\n }\n\n /** A new sort order, through the controlled/uncontrolled rules. */\n #applySorting(next: SortState): void {\n const old = this.#sorting.value;\n const { value, applied } = this.#sorting.request(next);\n if (applied) {\n this.#appliedSort = value;\n this.requestUpdate('sorting', old);\n } else {\n fire(this, SORT_CHANGE, { sorting: value });\n }\n }\n\n /**\n * A data column as plugins see it. Header functions call this on every\n * render, so the views are indexed by id once per new column list.\n */\n #columnInfo(id: string): ColumnInfo | undefined {\n const columns = this.#table.model.allColumns;\n if (this.#columnsById?.of !== columns) {\n this.#columnsById = { of: columns, byId: new Map(columns.map((c) => [c.id, c])) };\n }\n const view = this.#columnsById.byId.get(id);\n if (view?.kind !== 'data') return undefined;\n return {\n id,\n sortable: view.sortable,\n resizable: view.resizable,\n pinnable: view.pinnable,\n hideable: view.hideable,\n pin: view.pin,\n hidden: view.hidden,\n width: view.width,\n sorted: view.sorted === false ? undefined : view.sorted,\n filter: view.filter,\n filterValue: this.#filters.value[id],\n };\n }\n\n /** The header or cell an event happened in, for plugins. */\n #cellTarget(event: Event): CellTarget | undefined {\n for (const target of event.composedPath()) {\n const cell = gridCell(target);\n const columnId = cell?.dataset.col;\n if (!cell || columnId === undefined) continue;\n const model = this.#table.model;\n const row =\n cell.getAttribute('role') === 'columnheader'\n ? HEADER\n : gridRowOf(cell.parentElement, layoutOf(model));\n if (!row) return undefined;\n return {\n section: row.section,\n columnId,\n rowIndex: row.index,\n rowId: this.#gridRowId(model, row),\n };\n }\n return undefined;\n }\n\n #observeProbe(): void {\n const probe = this.renderRoot.querySelector('.probe');\n if (!probe) return;\n this.#probeObserver ??= new ResizeObserver(() => {\n this.#measureRowHeight();\n });\n this.#probeObserver.observe(probe);\n }\n\n /** The height of the rows pinned to one side: one row each, or measured with `rowHeight: 'auto'`. */\n #pinnedPx(side: 'top' | 'bottom', layout: RowLayout): number {\n const count = side === 'top' ? layout.top : layout.bottom;\n if (this.rowHeight !== 'auto' || count === 0) return count * this.#rowPx;\n return Math.max(this.#rowMeasure.pinned[side], count * this.#rowPx);\n }\n\n /**\n * `rowHeight: 'auto'`: reads the heights of the rendered rows, after their\n * content has rendered. Returns whether any changed (an update is requested).\n */\n #measureRows(): boolean {\n const { rows, pinnedChanged } = this.#rowMeasure.read(this.renderRoot);\n const resized = this.#virtual.measureRows(rows);\n if (pinnedChanged) this.requestUpdate();\n return resized || pinnedChanged;\n }\n\n /** Reads the resolved row height, so themes and density change the virtualizer too. */\n #measureRowHeight(): void {\n const probe = this.renderRoot.querySelector('.probe');\n const px = probe?.getBoundingClientRect().height ?? 0;\n if (px > 0 && Math.abs(px - this.#rowPx) > 0.01) {\n this.#rowPx = px;\n this.requestUpdate();\n }\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'argus-table': ArgusTable;\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"argus-table.js","names":["_decorate"],"sources":["../src/argus-table.ts"],"sourcesContent":["import {\n LitElement,\n html,\n nothing,\n type CSSResultGroup,\n type PropertyValues,\n type RootPart,\n type TemplateResult,\n} from 'lit';\nimport type { ComplexAttributeConverter } from 'lit';\nimport { customElement, property } from 'lit/decorators.js';\nimport { styleMap } from 'lit/directives/style-map.js';\nimport {\n clickSelection,\n controllable,\n groupKey,\n RowLayout,\n sameUnit,\n spreadWidth,\n sameSelection,\n selectAll,\n selectRange,\n SELECTION_COLUMN_ID,\n toggleRow,\n type ColumnFiltersChangeDetail,\n type ColumnVisibilityChangeDetail,\n type ColumnPinningChangeDetail,\n type ColumnOrderChangeDetail,\n type ColumnSizingChangeDetail,\n type ColumnView,\n type Controllable,\n type GridRow,\n type OrderUnit,\n type SelectionStep,\n type SelectionTarget,\n type TableModel,\n} from '@argus-table/core';\nimport { announce } from './announce.js';\nimport { AutoWidths, measureColumns } from './controllers/auto-width.js';\nimport { ColumnChildrenController } from './controllers/column-children.js';\nimport { ColumnWindowController, type RenderedColumn } from './controllers/column-window.js';\nimport { DataController } from './controllers/data-controller.js';\nimport { PinScrollController } from './controllers/pin-scroll-controller.js';\nimport { PluginController, sameItems } from './controllers/plugins.js';\nimport { RowMeasure } from './controllers/row-measure.js';\nimport {\n canStartReorder,\n dropTarget,\n startReorderDrag,\n type DropSlot,\n} from './controllers/reorder-drag.js';\nimport { startResizeDrag } from './controllers/resize-drag.js';\nimport { TableController } from './controllers/table-controller.js';\nimport { VirtualController, type VirtualWindow } from './controllers/virtual-controller.js';\nimport {\n CELL_CLICK,\n COLUMN_FILTERS_CHANGE,\n COLUMN_ORDER_CHANGE,\n COLUMN_PINNING_CHANGE,\n COLUMN_SIZING_CHANGE,\n COLUMN_VISIBILITY_CHANGE,\n fire,\n LOAD_ERROR,\n RANGE_CHANGE,\n ROW_CLICK,\n SELECTION_CHANGE,\n SORTING_CHANGE,\n} from './events.js';\nimport { fromInteractive, INTERACTIVE } from './interactive.js';\nimport { bodyCap, watchMaxElementHeight } from './max-height.js';\nimport { renderBody, type ActiveCell, type Loading, type SelectedAt } from './render/body.js';\nimport { renderLightDom } from './render/cells.js';\nimport { content, flushContent, type ContentRenderer } from './render/content-directive.js';\nimport { columnKey, renderHeader, type CheckAll, type HeaderDrag } from './render/header.js';\nimport type { CheckboxHandlers } from './render/content.js';\nimport { renderPinnedRows } from './render/pinned-rows.js';\nimport type { ArgusPlugin, CellTarget, ColumnInfo, PluginHost } from './plugins.js';\nimport { baseStyles } from './styles/base.js';\nimport { switchConverter } from './attributes.js';\nimport type {\n CellContent,\n ColumnDef,\n ColumnFilter,\n ColumnGroup,\n ColumnFilterState,\n ColumnOrderState,\n ColumnPin,\n ColumnPinningState,\n ColumnSizingState,\n ColumnVisibilityState,\n DataSource,\n Density,\n PinnedRows,\n SelectionMode,\n SelectionState,\n SortDirection,\n SortState,\n TableState,\n} from './types.js';\n\n/**\n * The host carries the grid role, so rows rendered in the shadow root become\n * its children in the accessibility tree. ElementInternals sets the default;\n * `connectedCallback` also adds a `role` attribute, because tools such as\n * axe-core can't see the ElementInternals role. A `role` the page sets wins.\n */\nfunction attachGridInternals(host: HTMLElement): ElementInternals {\n const internals = host.attachInternals();\n internals.role = 'grid';\n return internals;\n}\n\n/**\n * The sortable column a header click came from, if any. Works for slotted content\n * too. Clicks on a resize handle never sort, so a click that ends a drag doesn't,\n * and neither do clicks on interactive content in the header (a button, an input).\n */\nfunction sortColumnOf(event: Event): string | undefined {\n for (const target of event.composedPath()) {\n if (!(target instanceof HTMLElement)) continue;\n if (target.dataset.resizeCol !== undefined) return undefined;\n if (target.matches(INTERACTIVE)) return undefined;\n if (target.dataset.sortCol !== undefined) return target.dataset.sortCol;\n if (target.getAttribute('role') === 'row') return undefined;\n }\n return undefined;\n}\n\nconst RESIZE_STEP = 10;\n\n/** `row-height`: px (`48` or `48px`) or `auto`; anything else is unset. */\nconst rowHeightConverter: ComplexAttributeConverter<number | 'auto' | undefined> = {\n fromAttribute(value) {\n if (value === null) return undefined;\n const text = value.trim().toLowerCase();\n if (text === 'auto') return 'auto';\n const px = Number(text.replace(/px$/, ''));\n return text !== '' && px > 0 ? px : undefined;\n },\n};\n\n/**\n * The cell holding the grid's single tab stop: a row (its section, and its index\n * there: in the row model for the body, in its list for a pinned row) and a\n * column. `rowId` keeps it on the same body row when the order changes.\n */\ninterface Active extends GridRow {\n rowId: string | undefined;\n col: string;\n}\n\n/** Where the rows sit in the grid: header rows, pinned top, body, pinned bottom. */\nfunction layoutOf<T>(model: TableModel<T, CellContent>): RowLayout {\n return new RowLayout(\n model.pinnedCount('top'),\n model.rowCount,\n model.pinnedCount('bottom'),\n model.headerRows,\n );\n}\n\n/** The drop slot and applied-move key of a column or group (`HeaderDrag.key`). */\nfunction unitKey(unit: OrderUnit): string {\n return unit.kind === 'column' ? columnKey(unit.id) : groupKey(unit.id, unit.pin);\n}\n\n/** The grid cell or column header an element is, if any. */\nfunction gridCell(target: EventTarget): HTMLElement | undefined {\n if (!(target instanceof HTMLElement) || target.dataset.col === undefined) return undefined;\n const role = target.getAttribute('role');\n return role === 'gridcell' || role === 'columnheader' ? target : undefined;\n}\n\n/** The column group header an element is, if any. */\nfunction groupCell(target: EventTarget): HTMLElement | undefined {\n return target instanceof HTMLElement && target.dataset.groupKey !== undefined\n ? target\n : undefined;\n}\n\n/** The grid row a rendered row element is, from its `aria-rowindex`. */\nfunction gridRowOf(row: Element | null, layout: RowLayout): GridRow | undefined {\n const index = row?.getAttribute('aria-rowindex');\n return index ? layout.fromAriaRowIndex(Number(index)) : undefined;\n}\n\n/** The grid row a cell or column header is in. */\nfunction gridRowOfCell(cell: HTMLElement, layout: RowLayout): GridRow | undefined {\n return gridRowOf(cell.parentElement, layout);\n}\n\n/**\n * The pinned edge's shadow, drawn once per side over the scroller rather than\n * per row: a shadow on every pinned cell repaints on every scroll frame. It\n * covers the pinned columns and casts `--argus-pinned-shadow` onto the rest;\n * PinScrollController sizes it to the visible area.\n */\nfunction pinShadow(side: 'start' | 'end', width: number, contentPx: number) {\n if (width === 0) return nothing;\n return html`<div\n class=\"pin-shadow\"\n data-side=${side}\n aria-hidden=\"true\"\n style=${styleMap({\n inlineSize: `${String(width)}px`,\n '--_content-h': `${String(contentPx)}px`,\n })}\n ></div>`;\n}\n\n/** CSS grid track for a column: fixed px, or a flex share with the min width as floor. */\nfunction track<T>(column: ColumnView<T, CellContent>): string {\n return column.flex === undefined\n ? `${String(column.width)}px`\n : `minmax(${String(column.minWidth)}px, ${String(column.flex)}fr)`;\n}\n\n/** Total width of the columns pinned to one side. */\nfunction pinnedWidth<T>(\n columns: readonly ColumnView<T, CellContent>[],\n side: 'start' | 'end',\n): number {\n return columns.reduce((sum, c) => (c.pin === side ? sum + c.width : sum), 0);\n}\n\n/**\n * A virtualized data table.\n *\n * Set `columns`, and `data` or `dataSource`, as properties. Columns can also be\n * written as `<argus-column>` children; a non-empty `columns` wins over them.\n * `columnGroups` (or `<argus-column-group>` children) adds headers over several\n * columns, a header row per level of nesting.\n * Header and cell content is rendered into the element's light DOM and slotted\n * into the cells, so page CSS and the page's own components work inside cells.\n *\n * Any number of rows scrolls to the end. Browsers limit an element's height\n * (about 800k rows of 40 px in Chromium and Safari, 400k in Firefox), so a taller\n * body renders shorter and its scroll position is scaled onto the rows: the\n * scrollbar still spans every row, and a wheel step covers a few more of them.\n * Use `scrollToRow()` rather than setting the scroll container's `scrollTop`.\n *\n * @summary Data table with pinned rows and columns and infinite loading.\n *\n * @fires {CustomEvent<SortingChangeDetail>} argus-sorting-change - `sorting` changed: a sortable header was clicked, or activated with Enter or Space. `detail: { sorting }`. The new value fires after the update that applied it; when the property is controlled, the proposed value fires right away and nothing changes until the host sets it.\n * @fires {CustomEvent<ColumnSizingChangeDetail>} argus-column-sizing-change - `columnSizing` changed: a column was resized by dragging its handle, with Alt+Arrow on its header, by a double-click on its handle (fit to content) or by `autosizeColumns()`. `detail: { columnSizing, columnId, width }`. Fires on every frame of a drag, and once per column that changes (a group resize, `autosizeColumns()`). The new value fires after the update that applied it; when the property is controlled, the proposed value fires right away and nothing changes until the host sets it.\n * @fires {CustomEvent<ColumnOrderChangeDetail>} argus-column-order-change - `columnOrder` changed: a column or column group was moved by dragging its header, or with Alt+Shift+Arrow on its focused header. Columns move within their pin side (start-pinned, scrolling, end-pinned) and their column group; groups move as a whole. `detail: { columnOrder, columnId, groupId? }`: `groupId` is set when a group moved, and `columnId` is then its first column. Fires once per move, on drop. The new value fires after the update that applied it; when the property is controlled, the proposed value fires right away and nothing changes until the host sets it.\n * @fires {CustomEvent<ColumnPinningChangeDetail>} argus-column-pinning-change - `columnPinning` changed: a column was pinned to a side or unpinned, through a plugin such as the column menu. `detail: { columnPinning, columnId, pin }`: `pin` is `'start'`, `'end'` or `false`. The new value fires after the update that applied it; when the property is controlled, the proposed value fires right away and nothing changes until the host sets it.\n * @fires {CustomEvent<ColumnVisibilityChangeDetail>} argus-column-visibility-change - `columnVisibility` changed: a column was hidden or shown, through a plugin such as the column menu. `detail: { columnVisibility, columnId, visible }`: `visible` is `false` when it was hidden. The new value fires after the update that applied it; when the property is controlled, the proposed value fires right away and nothing changes until the host sets it.\n * @fires {CustomEvent<ColumnFiltersChangeDetail>} argus-column-filters-change - `columnFilters` changed: a column's filter was set, changed or cleared, through a plugin such as the column menu. `detail: { columnFilters, columnId, columnFilter }`: `columnFilter` is the column's new filter, or `undefined` when it was cleared. The new value fires after the update that applied it; when the property is controlled, the proposed value fires right away and nothing changes until the host sets it.\n * @fires {CustomEvent<SelectionChangeDetail>} argus-selection-change - `selection` changed: by a click on a row (Ctrl/Cmd toggles, Shift selects a range), with Space, Shift+Arrow or Shift+PageUp/PageDown on a body cell, or with Ctrl/Cmd+A. Only with a `selectionMode`. `detail: { selection }`. The new value fires after the update that applied it; when the property is controlled, the proposed value fires right away and nothing changes until the host sets it.\n * @fires {CustomEvent<CellClickDetail<T>>} argus-cell-click - A body or pinned-row cell was clicked, or Enter was pressed on it. `detail: { row, rowId, index, columnId, value, pinned? }`; `pinned` is `'top'` or `'bottom'` for a pinned row, and `index` is then its index in its list. Fires before `argus-row-click`.\n * @fires {CustomEvent<RowClickDetail<T>>} argus-row-click - A body or pinned row was clicked, or Enter was pressed on one of its cells. `detail: { row, rowId, index, pinned? }`; for a pinned row, `index` is its index in its list.\n * @fires {CustomEvent<RangeChangeDetail>} argus-range-change - The rows in view changed (rows rendered ahead of the scroll position not counted). `detail: { first, last }` (row indices in the current order, both inclusive).\n * @fires {CustomEvent<LoadErrorDetail>} argus-load-error - A `dataSource` page failed to load: `getRows()` rejected or threw. `detail: { error, start, end }` (`end` exclusive). The rows show a Retry button.\n *\n * @slot empty - Shown instead of the body when there are no rows. Default: \"No rows\".\n *\n * @csspart table - The scroll container that holds header and body.\n * @csspart header - The sticky header row group.\n * @csspart header-row - The row of column headers: the last header row when there are column groups.\n * @csspart header-group-row - A row of column group headers (`columnGroups`), one per level of nesting, above `header-row`.\n * @csspart header-group-cell - A column group's header, spanning its columns.\n * @csspart header-group-cell-dragging - Added to `header-group-cell` on the group being dragged to a new position.\n * @csspart header-group-filler - The empty cell of a group row over columns without a group at that level.\n * @csspart header-cell - Every column header.\n * @csspart header-cell-sorted - Added to `header-cell` on the headers of sorted columns. The direction is also in `aria-sort`.\n * @csspart header-cell-sorted-asc - Added to `header-cell` on the headers of columns sorted ascending, next to `header-cell-sorted`.\n * @csspart header-cell-sorted-desc - Added to `header-cell` on the headers of columns sorted descending, next to `header-cell-sorted`.\n * @csspart header-cell-pinned - Added to `header-cell` on the headers of pinned columns, on either side.\n * @csspart header-cell-pinned-edge - Added to `header-cell-pinned` on the pinned header next to the scrolling columns (one per pinned side).\n * @csspart sort-indicator - The chevron in a sortable column's header, shown while it is sorted and pointing the way it sorts. It is drawn with borders in `currentColor`.\n * @csspart header-cell-filtered - Added to `header-cell` on the headers of filtered columns.\n * @csspart filter-indicator - The mark in the header of a filtered column, after the sort indicator.\n * @csspart header-cell-dragging - Added to `header-cell` on the header being dragged to a new position, and on the headers of a dragged group's columns.\n * @csspart drop-indicator - The line on the edge of the header where a dragged column or group would land.\n * @csspart resize-handle - The drag handle on the inline-end edge of a resizable column's header, and of a column group's header with resizable columns. A double-click fits the column (or the group's columns) to its content.\n * @csspart body - The row group holding the rendered body rows.\n * @csspart row - Every body row.\n * @csspart row-even - Body rows with an even index (0-based).\n * @csspart row-odd - Body rows with an odd index.\n * @csspart row-loading - Body rows whose `dataSource` page hasn't loaded yet, or failed.\n * @csspart row-error - Added to `row-loading` on body rows whose `dataSource` page failed to load.\n * @csspart row-selected - Body rows whose id is in `selection`.\n * @csspart cell-selection - Added to `cell` in the checkbox column (`selectionCheckboxes`), pinned rows included.\n * @csspart header-cell-selection - Added to `header-cell` on the checkbox column's header.\n * @csspart selection-checkbox - The checkboxes of the checkbox column: one per selectable row, and the select-all one in the header (`multi` mode).\n * @csspart row-pinned - Every row from `pinnedRows`, on either side. Also has `row`, but no `row-even`/`row-odd`.\n * @csspart row-pinned-top - The rows pinned below the header.\n * @csspart row-pinned-bottom - The rows pinned to the bottom.\n * @csspart cell-in-pinned-row - Every cell of a pinned row (next to `cell`).\n * @csspart cell - Every body cell.\n * @csspart cell-sorted - Body and pinned-row cells in the sorted column.\n * @csspart cell-pinned - Body and pinned-row cells in a pinned column, on either side.\n * @csspart cell-pinned-edge - The pinned cell next to the scrolling columns (one per pinned side), in body and pinned rows.\n * @csspart skeleton - The placeholder bar in each cell of a row that is still loading.\n * @csspart skeleton-error - Added to `skeleton` in a row whose page failed to load.\n * @csspart retry - The Retry button in the first cell of a failed page's first visible row.\n * @csspart empty - The empty-state container.\n *\n * @cssprop [--argus-bg=Canvas] - Background of the table and rows.\n * @cssprop [--argus-fg=CanvasText] - Text colour.\n * @cssprop [--argus-font=inherit] - Font shorthand for the table.\n * @cssprop [--argus-header-bg] - Header background.\n * @cssprop [--argus-header-fg=inherit] - Header text colour.\n * @cssprop [--argus-border-color] - Colour of the row borders.\n * @cssprop [--argus-border-width=1px] - Width of the row borders.\n * @cssprop [--argus-border=none] - Border around the whole table, as a `border` shorthand (`1px solid …`). Inside the element's size. The lines between rows are `--argus-border-width` and `--argus-border-color`.\n * @cssprop [--argus-border-radius=0] - Corner radius of the table. Header, rows and pinned columns are clipped to it.\n * @cssprop [--argus-row-height] - Height of a row, and of each header row. Default per density: 32px, 40px, 52px. With `rowHeight: 'auto'`: the height of each header row and the least a body or pinned row is.\n * @cssprop [--argus-cell-padding-inline] - Inline padding of cells. Default per density: 8px, 12px, 16px.\n * @cssprop [--argus-cell-padding-block] - Block padding of body and pinned-row cells with `rowHeight: 'auto'`, where content sits at the top of the cell. Default: what centres one line of text in `--argus-row-height`.\n * @cssprop [--argus-row-odd-bg] - Background of odd rows. Default: no stripes.\n * @cssprop [--argus-pinned-shadow] - Shadow on the pinned edge, as a `box-shadow` falling toward the end side (`4px 0 6px -4px …`). Mirrored for the end edge and in RTL; `none` removes it.\n * @cssprop [--argus-resize-handle-color] - Colour of the resize handle's line, shown on hover, focus and drag.\n * @cssprop [--argus-focus-ring=2px solid Highlight] - Outline of the focused header or cell.\n * @cssprop [--argus-filter-indicator-color=currentColor] - Colour of the mark in the header of a filtered column.\n * @cssprop [--argus-drop-indicator-color=Highlight] - Colour of the line that marks where a dragged column would land.\n * @cssprop [--argus-row-hover-bg] - Background of the hovered row. Default: no change.\n * @cssprop [--argus-row-pinned-bg=var(--argus-bg)] - Background of the pinned rows, pinned columns included.\n * @cssprop [--argus-skeleton-bg] - Colour of the skeleton bars in rows still loading. Default: the text colour at low opacity.\n * @cssprop [--argus-row-selected-bg] - Background of selected rows, pinned columns included. Default: the system highlight colour, mixed into `--argus-bg`. It wins over `--argus-row-hover-bg`.\n */\n@customElement('argus-table')\nexport class ArgusTable<T = unknown> extends LitElement {\n static override styles: CSSResultGroup = baseStyles;\n\n /**\n * Column definitions. Property only: functions can't be attributes. While empty,\n * the table reads its `<argus-column>` children instead. `null` or `undefined`\n * means `[]`.\n */\n @property({ attribute: false })\n get columns(): readonly ColumnDef<T>[] {\n return this.#columnsProp;\n }\n set columns(value: readonly ColumnDef<T>[] | null | undefined) {\n // Framework bindings set `undefined` when a prop goes away.\n this.#columnsProp = value ?? [];\n }\n\n /**\n * Headers over several columns: `{ id, header, columns }`, where `columns` lists\n * column ids and nested groups. Each level of nesting adds a header row. A group's\n * columns stay next to each other: they move within the group, and the group\n * moves as a whole (drag its header, or Alt+Shift+Arrow). A group whose columns\n * are pinned to different sides shows on each side. Property only. While empty\n * and `columns` is too, the table reads its `<argus-column-group>` children.\n * `null` or `undefined` means `[]`.\n */\n @property({ attribute: false })\n get columnGroups(): readonly ColumnGroup[] {\n return this.#columnGroupsProp;\n }\n set columnGroups(value: readonly ColumnGroup[] | null | undefined) {\n this.#columnGroupsProp = value ?? [];\n }\n\n /**\n * The rows to show. Replace the array to update; changes inside it aren't\n * detected. `null` or `undefined` means `[]`.\n */\n @property({ attribute: false })\n get data(): readonly T[] {\n return this.#dataProp;\n }\n set data(value: readonly T[] | null | undefined) {\n this.#dataProp = value ?? [];\n }\n\n /**\n * Loads rows page by page as they scroll into view, instead of `data`:\n * `{ getRows({ start, end, sorting, filters, quickFilter, signal }), pageSize? }`,\n * where `end` is exclusive and `getRows` resolves to `{ rows, total? }`. Without a\n * `total`, the table grows as pages arrive and a short page marks the end. Sorting\n * and filtering happen on the server: a new order or filter reloads from the top.\n * While set, it wins over `data`. Replace the object to change `getRows` or\n * `pageSize`.\n */\n @property({ attribute: false })\n dataSource?: DataSource<T>;\n\n /**\n * Rows fixed below the header (`top`) and at the bottom of the view (`bottom`),\n * such as a totals row: `{ top?: T[], bottom?: T[] }`. They are separate\n * objects, not rows of `data`: columns read them the same way, but they are\n * never sorted and work the same with a `dataSource`. A `cell` function gets\n * `pinned: 'top' | 'bottom'` in its context. Replace the object to update.\n */\n @property({ attribute: false })\n pinnedRows?: PinnedRows<T>;\n\n /** Returns a stable id for a row. Default: the row's index (in `data`, or among all `dataSource` rows). */\n @property({ attribute: false })\n getRowId?: (row: T, index: number) => string;\n\n /**\n * Row height in px, or `'auto'` to fit each row to its content (`row-height=\"auto\"`).\n * Unset: the density (or the `--argus-row-height` token) decides. With\n * `'auto'`, that height is the header's and the least a body or pinned row is;\n * rows grow to fit wrapped text (`wrap` columns) and taller content, and cell\n * content sits at the top. Rows are measured as they render: a row's height\n * counts the columns rendered (see `virtualizeColumns`), and rows not seen yet\n * count as one line. Give images a size, so rows don't move when they load.\n */\n @property({ attribute: 'row-height', converter: rowHeightConverter })\n rowHeight?: number | 'auto';\n\n /** Row density: `compact`, `comfortable` or `spacious`. */\n @property({ reflect: true })\n density: Density = 'comfortable';\n\n /** Rows rendered above and below the visible ones. `null` or `undefined` means the default, 6. */\n @property({ type: Number })\n get overscan(): number {\n return this.#overscan;\n }\n set overscan(value: number | null | undefined) {\n this.#overscan = value ?? 6;\n }\n\n /**\n * Renders only the scrolling columns in view (plus two on each side), for\n * wide tables: a few dozen columns and more. Pinned columns, the checkbox\n * column and the focused cell's column always render. Off by default: then\n * every column renders, as before. Cells are placed in their grid column\n * explicitly, so page CSS that relies on their order in the DOM (`:nth-child`\n * on cells) doesn't apply. `autosizeColumns()` and `width: 'auto'` columns\n * still measure columns out of view: they render for the measurement.\n * As an attribute, `virtualize-columns=\"false\"` is off, like no attribute.\n */\n @property({ attribute: 'virtualize-columns', converter: switchConverter })\n virtualizeColumns = false;\n\n /**\n * The sort order, e.g. `[{ id: 'total', desc: true }]`; `[]` when unsorted. Unset,\n * the table keeps it itself and header clicks change it. Once set, it is\n * controlled: a click only fires `argus-sorting-change` with the proposed order,\n * and nothing changes until you set the property. Set `undefined` to hand it back.\n */\n @property({ attribute: false })\n get sorting(): SortState {\n return this.#sorting.value;\n }\n set sorting(value: SortState | undefined) {\n // Lit wraps this accessor and requests the update with the old value.\n this.#sorting.set(value);\n }\n\n /**\n * Resized widths in px by column id, e.g. `{ name: 240 }`. A resized flex column\n * becomes fixed. Uncontrolled until set, like `sorting`: once set, a resize only\n * fires `argus-column-sizing-change` with the proposed widths. `undefined` hands it back.\n */\n @property({ attribute: false })\n get columnSizing(): ColumnSizingState {\n return this.#sizing.value;\n }\n set columnSizing(value: ColumnSizingState | undefined) {\n this.#sizing.set(value);\n }\n\n /**\n * The column order: column ids as the table shows them, e.g.\n * `['id', 'total', 'customer']`. `[]` (the default) keeps the order of `columns`.\n * Each pin group (start-pinned, scrolling, end-pinned) takes its columns in this\n * order; unknown ids are ignored and columns it doesn't list follow the listed\n * ones of their group. After a move it holds every column id. Uncontrolled\n * until set, like `sorting`: once set, a move only fires `argus-column-order-change`\n * with the proposed order. `undefined` hands it back.\n */\n @property({ attribute: false })\n get columnOrder(): ColumnOrderState {\n return this.#order.value;\n }\n set columnOrder(value: ColumnOrderState | undefined) {\n this.#order.set(value);\n }\n\n /**\n * Pins by column id, over the columns' own `pin`: `'start'` or `'end'` pins a\n * column, `false` unpins one whose definition pins it, e.g.\n * `{ total: 'end', id: false }`. Columns it doesn't list keep their `pin`. A pinned\n * column joins the edge of its group nearest its place in `columnOrder`, and stops\n * flexing. Uncontrolled until set, like `sorting`: once set, pinning from a plugin\n * only fires `argus-column-pinning-change` with the proposed pins. `undefined` hands it back.\n */\n @property({ attribute: false })\n get columnPinning(): ColumnPinningState {\n return this.#pinning.value;\n }\n set columnPinning(value: ColumnPinningState | undefined) {\n this.#pinning.set(value);\n }\n\n /**\n * Visibility by column id, over the columns' own `hidden`: `false` hides a column,\n * `true` shows one defined as `hidden`, e.g. `{ email: false }`. Columns it\n * doesn't list keep their `hidden`. A hidden column isn't rendered, but sorting by\n * it still works and it keeps its place in `columnOrder`. Uncontrolled until set,\n * like `sorting`: once set, hiding or showing from a plugin only fires\n * `argus-column-visibility-change` with the proposed visibility. `undefined` hands it back.\n */\n @property({ attribute: false })\n get columnVisibility(): ColumnVisibilityState {\n return this.#visibility.value;\n }\n set columnVisibility(value: ColumnVisibilityState | undefined) {\n this.#visibility.set(value);\n }\n\n /**\n * Filters by column id, e.g. `{ city: { kind: 'set', values: ['Berlin'] } }` or\n * `{ total: { kind: 'number', op: 'gt', value: 100 } }`. A row shows when it passes\n * every filter and `quickFilter`. Filters on hidden columns still apply; unknown ids\n * are ignored. A column's `filterFn` replaces the built-in matching. With a\n * `dataSource`, the filters go to `getRows()` and the server filters. Users set\n * filters through plugins (the column menu) on columns with a `filter` kind.\n * Uncontrolled until set, like `sorting`: once set, a change from a plugin only\n * fires `argus-column-filters-change` with the proposed filters. `undefined` hands it back.\n */\n @property({ attribute: false })\n get columnFilters(): ColumnFilterState {\n return this.#filters.value;\n }\n set columnFilters(value: ColumnFilterState | undefined) {\n this.#filters.set(value);\n }\n\n /**\n * Shows only rows that contain each word of this text in one of their shown\n * columns, ignoring case, e.g. from a search box. Values are matched as text\n * (dates as `2026-11-10`); objects aren't searched. With a `dataSource`, it goes\n * to `getRows()` and the server filters. `''` (the default) shows every row.\n */\n @property({ attribute: 'quick-filter' })\n get quickFilter(): string {\n return this.#quickFilter;\n }\n set quickFilter(value: string | null | undefined) {\n this.#quickFilter = value ?? '';\n }\n\n /**\n * How rows can be selected: `none` (the default), `single` or `multi`. A click\n * on a body row selects it; in `multi` mode Ctrl/Cmd+click toggles a row,\n * Shift+click selects the range from the last clicked row, and Ctrl/Cmd+A\n * selects every row. Space toggles the focused row. Clicks on buttons, links\n * and inputs inside cells don't select. Pinned rows, and `dataSource` rows not\n * loaded yet, can't be selected.\n */\n @property({ attribute: 'selection-mode' })\n selectionMode: SelectionMode = 'none';\n\n /**\n * Adds a checkbox column, pinned first at the start, while `selectionMode` is\n * `single` or `multi`. A row's checkbox toggles it (Shift+click adds the range\n * from the last row clicked); in `multi` mode the header's checkbox selects\n * every row, or clears the selection when all are selected. Space on a\n * focused checkbox cell does the same. The column isn't part of `columns`,\n * `columnOrder` or `columnSizing`, and it fires no `argus-cell-click`.\n * As an attribute, `selection-checkboxes=\"false\"` is off, like no attribute.\n */\n @property({ attribute: 'selection-checkboxes', converter: switchConverter })\n selectionCheckboxes = false;\n\n /**\n * The selected rows, as row ids (from `getRowId`, or the row's index as a\n * string), e.g. `['p4', 'p7']`. Uncontrolled until set, like `sorting`: once\n * set, a click only fires `argus-selection-change` with the proposed ids.\n * `undefined` hands it back. The table never drops ids on its own: they stay\n * through sorting, a new `data` or reloaded pages. With a `dataSource`,\n * Ctrl/Cmd+A selects the loaded rows only.\n */\n @property({ attribute: false })\n get selection(): SelectionState {\n return this.#selection.value;\n }\n set selection(value: SelectionState | undefined) {\n this.#selection.set(value);\n }\n\n /**\n * Renders header and cell content the table can't render itself, such as React\n * elements, Vue VNodes or Angular templates: `{ render(target, content),\n * release(target), flush?() }`. A `header` or `cell` that returns anything other\n * than a string, a number, a DOM node or a Lit template hands it to the renderer,\n * with a target element the table keeps while the cell is reused for other rows.\n * The framework wrappers set it; set it yourself only for another framework.\n */\n @property({ attribute: false })\n contentRenderer?: ContentRenderer;\n\n /**\n * Add-ons, such as `headerMenu()` from `@argus-table/header-menu`. Each one can\n * change the column definitions, handle keys on a focused header or cell, and\n * use the table through a small API. They run in array order. Replace the\n * array to change them; an array with the same plugins in the same order\n * changes nothing. `null` or `undefined` means `[]`.\n */\n @property({ attribute: false })\n get plugins(): readonly ArgusPlugin<T>[] {\n return this.#pluginsProp;\n }\n set plugins(value: readonly ArgusPlugin<T>[] | null | undefined) {\n const next = value ?? [];\n // The same plugins in a new array (a framework re-render) keep their connection.\n if (!sameItems(next, this.#pluginsProp)) this.#pluginsProp = next;\n }\n\n #columnsProp: readonly ColumnDef<T>[] = [];\n #columnGroupsProp: readonly ColumnGroup[] = [];\n /** The groups last passed to the model: `columnGroups`, or the `<argus-column-group>` children. */\n #groups: readonly ColumnGroup[] = [];\n #groupsChanged = false;\n #pluginsProp: readonly ArgusPlugin<T>[] = [];\n #dataProp: readonly T[] = [];\n #overscan = 6;\n readonly #sorting = controllable<SortState>([]);\n readonly #sizing = controllable<ColumnSizingState>({});\n readonly #order = controllable<ColumnOrderState>([]);\n readonly #pinning = controllable<ColumnPinningState>({});\n readonly #visibility = controllable<ColumnVisibilityState>({});\n readonly #filters = controllable<ColumnFilterState>({});\n #quickFilter = '';\n /** Filters the table applied itself, by column; their events fire once the update is done. */\n readonly #appliedFilters = new Map<string, ColumnFiltersChangeDetail>();\n /** Announce the row count after the update: the filters changed. */\n #announceRows = false;\n /** Pins the table applied itself, by column; their events fire once the update is done. */\n readonly #appliedPins = new Map<string, ColumnPinningChangeDetail>();\n /** Hidden or shown columns the table applied itself; their events fire once the update is done. */\n readonly #appliedHides = new Map<string, ColumnVisibilityChangeDetail>();\n readonly #selection = controllable<SelectionState>([]);\n /** `selection` as a set, for the rows rendered; rebuilt when `selection` changes. */\n #selectedIds: { of: SelectionState; ids: ReadonlySet<string> } | undefined;\n /** The row a Shift range starts from: the last row clicked or toggled without Shift. */\n #anchor: string | undefined;\n /** A selection the table applied itself; its event fires once the update is done. */\n #appliedSelection: SelectionState | undefined;\n /** Whether the checkbox column was last shown; a change re-measures the pinned columns. */\n #selectionColumn = false;\n #selectionColumnChanged = false;\n /** The select-all checkbox's state, kept until the selection or the shown rows change. */\n #checkAll: { key: readonly unknown[]; state: CheckAll['state'] } | undefined;\n /** Moves the table applied itself, by column or group; their events fire once the update is done. */\n readonly #appliedReorders = new Map<string, ColumnOrderChangeDetail>();\n /** The header being dragged to a new position, if any. */\n #drag: HeaderDrag | undefined;\n /** A move from the keyboard, announced once it has rendered: what moved and its old position. */\n #announceMove: { unit: OrderUnit; from: number } | undefined;\n /** Resizes the table applied itself, by column; their events fire once the update is done. */\n readonly #appliedResizes = new Map<string, ColumnSizingChangeDetail>();\n /** Columns `autosizeColumns()` renders out of view for its measurement. */\n #measureKeep: readonly string[] = [];\n /** Measured widths of `width: 'auto'` columns. */\n readonly #autoWidths = new AutoWidths(() => {\n this.requestUpdate();\n });\n /** The auto widths last passed to the model; a change re-measures the pinned columns' offsets. */\n #pushedAutoWidths: ColumnSizingState | undefined;\n #autoWidthsChanged = false;\n /** A sort the table applied itself; its event fires once the update is done. */\n #appliedSort: SortState | undefined;\n readonly #internals = attachGridInternals(this);\n readonly #table = new TableController<T>();\n readonly #children = new ColumnChildrenController<T>(this);\n /** What plugins get: closures over the table's private state. */\n readonly #pluginHost: PluginHost<T> = {\n element: this,\n column: (id) => this.#columnInfo(id),\n columns: () =>\n this.#table.model.allColumns.flatMap((c) => {\n const info = this.#columnInfo(c.id);\n return info ? [info] : [];\n }),\n setPin: (columnId, pin) => {\n this.#requestPin(columnId, pin);\n },\n setHidden: (columnId, hidden) => {\n this.#requestHide(columnId, hidden);\n },\n setFilter: (columnId, filter) => {\n this.#requestFilter(columnId, filter);\n },\n filterValues: (columnId, limit) => this.#table.model.filterValues(columnId, limit),\n filteredIndexes: (except) => this.#table.model.indexesPassing(except),\n cellOf: (event) => this.#cellTarget(event),\n setSort: (columnId, direction) => {\n this.#setSort(columnId, direction);\n },\n focusHeader: (columnId) => {\n const model = this.#table.model;\n this.#moveTo(layoutOf(model).leafHeader, columnId, model);\n },\n announce: (message) => {\n announce(this.ownerDocument, message);\n },\n invalidateColumns: () => {\n this.#plugins.invalidate();\n this.requestUpdate();\n },\n requestUpdate: () => {\n this.requestUpdate();\n },\n row: (index) => this.#table.model.rowAt(index)?.original,\n content: (value) => content(value),\n };\n readonly #plugins = new PluginController<T>(this, this.#pluginHost);\n #columnsById:\n | {\n of: readonly ColumnView<T, CellContent>[];\n byId: ReadonlyMap<string, ColumnView<T, CellContent>>;\n }\n | undefined;\n /** The columns last passed to the model: `columns`, or the `<argus-column>` children. */\n #columns: readonly ColumnDef<T>[] = [];\n #columnsChanged = false;\n #warnedColumns = false;\n /** The header row of column headers at the last reconcile (`#reconcileActive`). */\n #leafLevel = 0;\n /** End of the light-DOM part holding cell content, so later children stay outside it. */\n #contentEnd: Comment | undefined;\n /** The light-DOM part: disconnected with the table, so foreign content is released. */\n #lightPart: RootPart | undefined;\n #lightConnected = true;\n readonly #data = new DataController<T>(this);\n /** Scroll back to the top after the update (a new sort order for a data source). */\n #scrollToTop = false;\n // Looked up lazily: the virtualizer's hostUpdated runs before firstUpdated.\n readonly #virtual = new VirtualController(this, () => this.#scroller());\n readonly #pinScroll = new PinScrollController(this, () => this.#scroller());\n readonly #columnWindow = new ColumnWindowController<T>(this, () => this.#scroller());\n /** The columns the last render rendered (all of them, unless `virtualizeColumns`). */\n #rendered: RenderedColumn<T>[] = [];\n #rowPx = 40;\n #probeObserver?: ResizeObserver;\n /** The column template and row height the rows were last read for. */\n #rowsKey = '';\n /** Rows of different heights: reads the rendered rows (`rowHeight: 'auto'` only). */\n readonly #rowMeasure = new RowMeasure(this, {\n bodyIndex: (row) => {\n const at = gridRowOf(row, layoutOf(this.#table.model));\n return at?.section === 'body' && this.#data.stateAt(at.index) === 'loaded'\n ? at.index\n : undefined;\n },\n sizeOf: (index) => this.#virtual.sizeOf(index),\n minimum: () => this.#rowPx,\n });\n #window: VirtualWindow = { rows: [], totalSize: 0, range: null };\n #active: Active | undefined;\n /** Move focus to the active cell after the next update (keyboard navigation). */\n #focusPending = false;\n #lastRange = '';\n #unwatchMaxHeight: (() => void) | undefined;\n\n /**\n * The row `setState()` still has to scroll to: a data source's rows that far\n * aren't counted yet. Scrolled to again whenever the row count changes.\n */\n #scrollTarget: { row: number; count: number } | undefined;\n\n /** The scroll container (`part=\"table\"`); `null` before the first render. */\n #scroller(): HTMLElement | null {\n return this.renderRoot.querySelector<HTMLElement>('[part~=\"table\"]');\n }\n\n constructor() {\n super();\n // The user's own scrolling (or a click, or a key) wins over a restored position.\n for (const type of ['wheel', 'touchstart', 'pointerdown', 'keydown'] as const) {\n this.addEventListener(type, this.#dropScrollTarget, { passive: true });\n }\n }\n\n readonly #dropScrollTarget = () => {\n this.#scrollTarget = undefined;\n };\n\n override connectedCallback(): void {\n super.connectedCallback();\n if (!this.hasAttribute('role')) this.setAttribute('role', 'grid');\n if (this.hasUpdated) this.#observeProbe();\n this.#setLightConnected(true);\n // A zoom change changes the tallest body the engine renders.\n this.#unwatchMaxHeight = watchMaxElementHeight(() => {\n this.requestUpdate();\n });\n }\n\n /** Connects or disconnects the cell content (framework content mounts and unmounts with it). */\n #setLightConnected(connected: boolean): void {\n if (!this.#lightPart || this.#lightConnected === connected) return;\n this.#lightConnected = connected;\n this.#lightPart.setConnected(connected);\n flushContent(this);\n }\n\n override disconnectedCallback(): void {\n super.disconnectedCallback();\n this.#probeObserver?.disconnect();\n this.#rowMeasure.stop();\n // Framework content in the cells is unmounted until the table comes back.\n this.#setLightConnected(false);\n this.#unwatchMaxHeight?.();\n this.#unwatchMaxHeight = undefined;\n }\n\n /**\n * `columns` when it has any, otherwise the `<argus-column>` children. Keeps its\n * identity while neither changes, so the model is only rebuilt on a change.\n */\n #effectiveColumns(): readonly ColumnDef<T>[] {\n if (this.columns.length === 0) return this.#children.defs;\n if (!this.#warnedColumns && this.#children.present) {\n this.#warnedColumns = true;\n console.warn(\n 'argus-table: the columns property is set, so <argus-column> children are ignored.',\n );\n }\n return this.columns;\n }\n\n /**\n * `columnGroups` when it has any or `columns` is set (which turns off all\n * children), otherwise the `<argus-column-group>` children.\n */\n #effectiveGroups(): readonly ColumnGroup[] {\n if (this.columnGroups.length > 0 || this.columns.length > 0) return this.columnGroups;\n return this.#children.groups;\n }\n\n /**\n * The node the light-DOM content is rendered before. Lit's part then ends there,\n * so children appended later (an `<argus-column>`) never land inside it. If the\n * marker was removed (say by `innerHTML`), a new one starts a fresh part.\n */\n #lightDomEnd(): Comment {\n if (this.#contentEnd?.parentNode !== this) {\n this.#contentEnd = document.createComment('');\n this.append(this.#contentEnd);\n }\n return this.#contentEnd;\n }\n\n /**\n * With a `dataSource`, drops every loaded page and loads the rows in view\n * again, keeping the scroll position. With `data`, re-renders the cells (after\n * changing row objects in place). Resolves once the table has re-rendered;\n * reloaded rows arrive as their pages load.\n */\n async refresh(): Promise<void> {\n this.#data.refresh();\n this.requestUpdate();\n await this.updateComplete;\n }\n\n /**\n * Fits columns to their content: the header, the pinned rows and the body rows\n * rendered now (rows out of view aren't measured). It resizes them like a drag\n * would, so `argus-column-sizing-change` fires for each column that changes, and with a\n * controlled `columnSizing` nothing changes until you set it. Without `ids`, fits\n * every resizable column; columns with `resizable: false` keep their width.\n * With `virtualizeColumns`, columns out of view render for the measurement.\n * Resolves once the table has re-rendered.\n */\n async autosizeColumns(ids?: readonly string[]): Promise<void> {\n await this.updateComplete;\n const targets = this.#table.model.columns\n .filter((c) => c.resizable && (ids === undefined || ids.includes(c.id)))\n .map((c) => c.id);\n if (this.virtualizeColumns) {\n this.#measureKeep = targets;\n this.requestUpdate();\n await this.updateComplete;\n }\n const widths = measureColumns(this.renderRoot, targets);\n if (this.#measureKeep.length > 0) {\n this.#measureKeep = [];\n this.requestUpdate();\n }\n this.#requestResizes(widths);\n await this.updateComplete;\n }\n\n /** Scrolls so that the row at `index` (in the current row order) is at the top. */\n async scrollToRow(index: number): Promise<void> {\n await this.updateComplete;\n this.#virtual.scrollToIndex(index);\n await this.#settled();\n }\n\n /**\n * Waits for the update, and with `rowHeight: 'auto'` for the ones measured\n * rows request (a few at most: heights don't depend on positions).\n */\n async #settled(): Promise<void> {\n let done = await this.updateComplete;\n for (let i = 0; i < 8 && !done && this.rowHeight === 'auto'; i++) {\n done = await this.updateComplete;\n }\n }\n\n /**\n * The state users change, as one object of plain JSON for saving a user's\n * layout: `sorting`, `columnSizing`, `columnOrder`, `columnPinning`,\n * `columnVisibility`, `columnFilters`, `selection`, `quickFilter`, and `scroll`\n * (the row at the top and the inline offset), with `version: 1`. Controlled properties are\n * included with the values you set. The object is a copy: changing it changes\n * nothing in the table.\n */\n getState(): Required<TableState> {\n const scroller = this.#scroller();\n return structuredClone({\n version: 1 as const,\n sorting: this.#sorting.value,\n columnSizing: this.#sizing.value,\n columnOrder: this.#order.value,\n columnPinning: this.#pinning.value,\n columnVisibility: this.#visibility.value,\n columnFilters: this.#filters.value,\n selection: this.#selection.value,\n quickFilter: this.#quickFilter,\n // Negative in RTL.\n scroll: { row: this.#virtual.topRow, inline: Math.abs(scroller?.scrollLeft ?? 0) },\n });\n }\n\n /**\n * Restores state from `getState()`, for example a layout saved in\n * `localStorage`. Only the keys given change; ids of columns that no longer\n * exist are ignored. State of another `version` is ignored as a whole. Properties you control are left alone (set them\n * yourself), and the others stay uncontrolled. No change events fire.\n * `quickFilter` is set like the property: a search box of yours shows it only\n * if you read it back. `scroll` is applied after the rest, so with a\n * `dataSource` the restored rows load where it points. Resolves once the table\n * has re-rendered there.\n */\n async setState(state: TableState): Promise<void> {\n // Another format (a later version's): nothing it holds can be trusted to mean the same.\n if (((state.version as number | undefined) ?? 1) !== 1) return;\n this.#restore('sorting', this.#sorting, state.sorting);\n this.#restore('columnSizing', this.#sizing, state.columnSizing);\n this.#restore('columnOrder', this.#order, state.columnOrder);\n this.#restore('columnPinning', this.#pinning, state.columnPinning);\n this.#restore('columnVisibility', this.#visibility, state.columnVisibility);\n this.#restore('columnFilters', this.#filters, state.columnFilters);\n // A Shift range starts over from the restored selection.\n if (this.#restore('selection', this.#selection, state.selection)) this.#anchor = undefined;\n if (state.quickFilter !== undefined) this.quickFilter = state.quickFilter;\n this.#scrollTarget = undefined;\n await this.updateComplete;\n const { scroll } = state;\n if (!scroll) return;\n this.#virtual.scrollToIndex(scroll.row);\n // A data source counts one page past its loaded rows until it knows the\n // total: scroll on as the count grows.\n const count = this.#table.model.rowCount;\n if (this.#data.rows?.totalKnown === false && scroll.row >= count) {\n this.#scrollTarget = { row: scroll.row, count };\n }\n const scroller = this.#scroller();\n if (scroller && scroll.inline >= 0) {\n scroller.scrollLeft = scroll.inline * this.#direction();\n }\n // The scroll event comes before the next frame, and the rows move with its update.\n await new Promise(requestAnimationFrame);\n await this.#settled();\n }\n\n /** Scrolls on toward the row `setState()` restored once more rows are counted. */\n #chaseScrollTarget(count: number): void {\n const target = this.#scrollTarget;\n if (!target || target.count === count) return;\n target.count = count;\n this.#virtual.scrollToIndex(target.row);\n if (target.row < count || this.#data.rows?.totalKnown !== false) this.#scrollTarget = undefined;\n }\n\n /**\n * Applies a restored value to uncontrolled state without an event, as a user\n * change would without the event. Returns whether it changed.\n */\n #restore<V>(name: keyof TableState, state: Controllable<V>, value: V | undefined): boolean {\n if (value === undefined || state.controlled) return false;\n // The same value restored again doesn't reload a data source.\n if (JSON.stringify(value) === JSON.stringify(state.value)) return false;\n const old = state.value;\n state.request(structuredClone(value));\n this.requestUpdate(name, old);\n return true;\n }\n\n protected override willUpdate(changed: PropertyValues<this>): void {\n if (changed.has('plugins')) this.#plugins.set(this.plugins);\n // Property names: the keys are strings.\n this.#plugins.willUpdate(new Set(changed.keys()) as ReadonlySet<string>);\n const columns = this.#plugins.transform(this.#effectiveColumns());\n this.#columnsChanged = columns !== this.#columns;\n this.#columns = columns;\n const groups = this.#plugins.transformGroups(this.#effectiveGroups());\n this.#groupsChanged = groups !== this.#groups;\n this.#groups = groups;\n const filtersChanged = changed.has('columnFilters') || changed.has('quickFilter');\n if (\n changed.has('dataSource') ||\n changed.has('sorting') ||\n changed.has('getRowId') ||\n filtersChanged\n ) {\n this.#data.configure({\n source: this.dataSource,\n sorting: this.#sorting.value,\n filters: this.#filters.value,\n quickFilter: this.#quickFilter,\n getRowId: this.getRowId,\n });\n // A new order or filter starts over from the first row, so show it.\n if (this.dataSource && this.hasUpdated && (changed.has('sorting') || filtersChanged)) {\n this.#scrollToTop = !changed.has('dataSource');\n }\n // Other rows: a position restored for the old ones no longer applies.\n this.#scrollTarget = undefined;\n }\n if (filtersChanged && this.hasUpdated) this.#announceRows = true;\n if (\n this.#columnsChanged ||\n this.#groupsChanged ||\n changed.has('data') ||\n changed.has('getRowId') ||\n changed.has('sorting') ||\n changed.has('columnSizing') ||\n changed.has('columnOrder') ||\n changed.has('columnPinning') ||\n changed.has('columnVisibility') ||\n changed.has('columnFilters') ||\n changed.has('quickFilter') ||\n changed.has('pinnedRows')\n ) {\n if (this.#columnsChanged) {\n this.#autoWidths.sync(columns.filter((c) => c.width === 'auto').map((c) => c.id));\n }\n this.#table.update({\n columns,\n columnGroups: groups,\n data: this.data,\n getRowId: this.getRowId,\n sorting: this.#sorting.value,\n columnSizing: this.#sizing.value,\n columnOrder: this.#order.value,\n columnPinning: this.#pinning.value,\n columnVisibility: this.#visibility.value,\n columnFilters: this.#filters.value,\n quickFilter: this.#quickFilter,\n pinnedRows: this.pinnedRows,\n });\n }\n // A new page cache (new source, sort order or refresh) or none, new measured\n // widths, and whether the checkbox column shows.\n const autoWidths = this.#autoWidths.widths;\n this.#autoWidthsChanged = autoWidths !== this.#pushedAutoWidths;\n this.#pushedAutoWidths = autoWidths;\n const selectionColumn = this.selectionCheckboxes && this.#mode() !== 'none';\n this.#selectionColumnChanged = selectionColumn !== this.#selectionColumn;\n this.#selectionColumn = selectionColumn;\n this.#table.update({ remote: this.#data.rows, autoWidths, selectionColumn });\n const model = this.#table.model;\n this.#reconcileActive(model);\n const active = this.#active;\n // -1 tells assistive tech the total is unknown (a data source still growing).\n const unknownTotal = this.#data.rows?.totalKnown === false;\n const layout = layoutOf(model);\n this.#internals.ariaRowCount = unknownTotal ? '-1' : String(layout.total);\n this.#internals.ariaColCount = String(model.columns.length);\n this.#internals.ariaMultiSelectable = this.#mode() === 'multi' ? 'true' : null;\n // The header and pinned rows scroll with the body.\n const extra = this.#headerAndPinnedPx(layout);\n const auto = this.rowHeight === 'auto';\n if (!auto) this.#rowMeasure.stop();\n // Anything but a scroll may change what rows hold (data, columns, widths).\n else if (changed.size > 0 || this.#columnsChanged) this.#rowMeasure.invalidate();\n this.#virtual.configure({\n count: model.rowCount,\n rowHeight: this.#rowPx,\n cap: (logical) => bodyCap(logical, extra),\n auto: auto ? { order: model.rowOrder, indexOf: (id) => model.indexOf(id) } : undefined,\n overscan: Math.max(0, this.overscan),\n rowIdAt: (index) => this.#rowId(model, index),\n // The active body row stays rendered, so the tab stop and focus survive scrolling.\n keep:\n active?.section !== 'body' || active.rowId === undefined\n ? undefined\n : { id: active.rowId, index: active.index },\n });\n }\n\n protected override render(): TemplateResult {\n const model = this.#table.model;\n const columns = model.columns;\n this.#window = this.#virtual.computeWindow();\n const rendered = this.#columnWindow.compute(\n columns,\n this.virtualizeColumns,\n this.virtualizeColumns ? this.#keptColumns(model) : [],\n );\n this.#rendered = rendered;\n const pinStart = pinnedWidth(columns, 'start');\n const pinEnd = pinnedWidth(columns, 'end');\n const cols = columns.map(track).join(' ');\n const layout = layoutOf(model);\n const style: Record<string, string> = {\n '--_cols': cols,\n '--_width': `${String(model.totalWidth)}px`,\n '--_pin-start': `${String(pinStart)}px`,\n '--_pin-end': `${String(pinEnd)}px`,\n '--_header-rows': String(layout.header),\n '--_pin-top-rows': String(layout.top),\n '--_pin-bottom-rows': String(layout.bottom),\n };\n const auto = this.rowHeight === 'auto';\n if (auto) {\n // New column widths or a new row height rewrap rows: read them all again.\n const key = `${cols}|${String(this.#rowPx)}`;\n if (key !== this.#rowsKey) {\n this.#rowsKey = key;\n this.#rowMeasure.invalidate();\n }\n style['--_pin-top-h'] = `${String(this.#pinnedPx('top', layout))}px`;\n style['--_pin-bottom-h'] = `${String(this.#pinnedPx('bottom', layout))}px`;\n }\n const active = this.#active;\n const activeIn = (section: GridRow['section']): ActiveCell | undefined =>\n active?.section === section ? { index: active.index, col: active.col } : undefined;\n const firstIndex = (section: GridRow['section']) => layout.ariaRowIndex({ section, index: 0 });\n if (typeof this.rowHeight === 'number' && this.rowHeight > 0) {\n style['--_row-height'] = `${String(this.rowHeight)}px`;\n }\n // The header, the pinned rows and the body: what the pinned-column shadows cover.\n const contentPx =\n this.#headerAndPinnedPx(layout) + (model.rowCount === 0 ? 0 : this.#window.totalSize);\n return html`<div\n part=\"table\"\n role=\"presentation\"\n style=${styleMap(style)}\n ?data-dragging=${this.#drag !== undefined}\n ?data-auto-rows=${auto}\n @keydown=${this.#onKeydown}\n @focusin=${this.#onFocusin}\n @mousedown=${this.#onMousedown}\n @click=${this.#onClick}\n >\n ${renderHeader({\n columns: rendered,\n groups: model.headerGroups,\n handlers: this.#headerHandlers,\n active: activeIn('header'),\n drag: this.#drag,\n checkAll: this.#checkAllOf(model),\n })}\n ${renderPinnedRows('top', layout.top, rendered, firstIndex('top'), activeIn('top'))}\n ${\n model.rowCount === 0\n ? html`<div part=\"empty\"><slot name=\"empty\">No rows</slot></div>`\n : renderBody(\n this.#window.rows,\n rendered,\n this.#window.totalSize,\n activeIn('body'),\n firstIndex('body'),\n this.#loading(),\n this.#selectedAt(model),\n this.#selectionColumn ? this.#checkboxHandlers : undefined,\n auto,\n )\n }\n ${renderPinnedRows('bottom', layout.bottom, rendered, firstIndex('bottom'), activeIn('bottom'))}\n <div class=\"probe\" aria-hidden=\"true\"></div>\n </div>\n ${pinShadow('start', pinStart, contentPx)} ${pinShadow('end', pinEnd, contentPx)}`;\n }\n\n protected override firstUpdated(): void {\n this.#observeProbe();\n this.#measureRowHeight();\n }\n\n protected override updated(changed: PropertyValues<this>): void {\n const model = this.#table.model;\n const part = renderLightDom(\n this,\n model,\n this.#window.rows,\n this.#rendered,\n model.headerGroups,\n this.#lightDomEnd(),\n );\n // A new marker starts a new part (the old one was removed): its content is gone.\n if (this.#lightPart && this.#lightPart !== part) this.#lightPart.setConnected(false);\n this.#lightPart = part;\n // Foreign content is committed before anything measures it.\n flushContent(this);\n this.#measureAutoWidths(model);\n // Rows of different heights: placed by the update this requests.\n const resized = this.rowHeight === 'auto' && this.#measureRows();\n if (this.#scrollToTop) {\n this.#scrollToTop = false;\n const scroller = this.#scroller();\n if (scroller) scroller.scrollTop = 0;\n }\n this.#chaseScrollTarget(model.rowCount);\n if (\n this.#columnsChanged ||\n this.#groupsChanged ||\n changed.has('columnSizing') ||\n changed.has('columnOrder') ||\n changed.has('columnPinning') ||\n changed.has('columnVisibility') ||\n this.#autoWidthsChanged ||\n this.#selectionColumnChanged\n ) {\n this.#pinScroll.measure();\n }\n // Rows that just changed height move with the next update: focus them there.\n if (this.#focusPending && !resized) {\n this.#focusPending = false;\n this.#focusActive();\n }\n if (changed.has('density') || changed.has('rowHeight')) this.#measureRowHeight();\n this.#fireApplied(this.#appliedResizes, COLUMN_SIZING_CHANGE);\n if (this.#announceMove) {\n this.#announceMoved(model, this.#announceMove);\n this.#announceMove = undefined;\n }\n this.#fireApplied(this.#appliedReorders, COLUMN_ORDER_CHANGE);\n this.#fireApplied(this.#appliedPins, COLUMN_PINNING_CHANGE);\n this.#fireApplied(this.#appliedHides, COLUMN_VISIBILITY_CHANGE);\n this.#fireApplied(this.#appliedFilters, COLUMN_FILTERS_CHANGE);\n if (this.#announceRows) {\n this.#announceRows = false;\n this.#announceRowCount(model);\n }\n if (this.#appliedSort) {\n const sorting = this.#appliedSort;\n this.#appliedSort = undefined;\n fire(this, SORTING_CHANGE, { sorting });\n }\n if (this.#appliedSelection) {\n const selection = this.#appliedSelection;\n this.#appliedSelection = undefined;\n fire(this, SELECTION_CHANGE, { selection });\n }\n const { range } = this.#window;\n const key = range ? `${String(range.start)}:${String(range.end)}` : '';\n if (range && key !== this.#lastRange) {\n this.#lastRange = key;\n fire(this, RANGE_CHANGE, { first: range.start, last: range.end });\n }\n if (range) {\n // The rendered rows: visible plus overscan, end exclusive.\n const over = Math.max(0, this.overscan);\n this.#data.request(Math.max(0, range.start - over), range.end + 1 + over);\n }\n for (const detail of this.#data.takeErrors()) fire(this, LOAD_ERROR, detail);\n }\n\n /**\n * Columns to render wherever they are, with `virtualizeColumns`: the active\n * cell's (its tab stop and focus survive scrolling sideways, and keyboard\n * moves land on a rendered cell), one being dragged, auto widths still to\n * measure, the targets of `autosizeColumns()`, and with a `dataSource` the\n * first data column, which holds the Retry buttons.\n */\n #keptColumns(model: TableModel<T, CellContent>): (string | undefined)[] {\n return [\n this.#active?.col,\n // A dragged column, not a group's: their headers needn't render out of view.\n ...(this.#drag?.key.startsWith('c:') ? this.#drag.columns : []),\n this.dataSource ? model.columns.find((c) => c.kind === 'data')?.id : undefined,\n ...this.#autoWidths.pending(model.columns),\n ...this.#measureKeep,\n ];\n }\n\n /** Fires the events of changes the table applied itself, once the update is done. */\n #fireApplied(applied: Map<string, unknown>, name: string): void {\n if (applied.size === 0) return;\n const details = [...applied.values()];\n applied.clear();\n for (const detail of details) fire(this, name, detail);\n }\n\n /**\n * Measures the `width: 'auto'` columns once loaded body rows render, or right\n * away when there are no rows (the header and pinned rows only). While a data\n * source's first rows load, they keep the default width. A changed width\n * renders once more.\n */\n #measureAutoWidths(model: TableModel<T, CellContent>): void {\n const loaded = this.#window.rows.some((r) => model.rowAt(r.index) !== undefined);\n if (!loaded && model.rowCount > 0) return;\n if (this.#autoWidths.measure(this.renderRoot, model.columns, loaded)) this.requestUpdate();\n }\n\n /**\n * Loading state for the body while a data source is set: the state of each\n * row, and a Retry button on the first visible row of each failed page.\n */\n #loading(): Loading | undefined {\n const cache = this.#data.rows;\n if (!cache) return undefined;\n const top = this.#window.range?.start ?? 0;\n const firstByPage = new Map<number, number>();\n for (const { index } of this.#window.rows) {\n if (index < top || cache.stateAt(index) !== 'error') continue;\n const page = cache.pageOf(index);\n const first = firstByPage.get(page);\n if (first === undefined || index < first) firstByPage.set(page, index);\n }\n const retry = new Map<number, string>();\n for (const [page, index] of firstByPage) {\n const start = page * cache.pageSize;\n const end = Math.min(start + cache.pageSize, cache.rowCount);\n retry.set(index, `Retry loading rows ${String(start + 1)} to ${String(end)}`);\n }\n return { stateAt: (index) => cache.stateAt(index), retry, onRetry: this.#onRetry };\n }\n\n readonly #onRetry = (event: Event) => {\n const button = event.currentTarget as HTMLElement;\n // The button goes away with the retry; keep focus in the grid, on its cell.\n if (button.matches(':focus')) button.parentElement?.focus({ preventScroll: true });\n this.#data.retry(Number(button.dataset.row));\n };\n\n /**\n * A row's id. A data source row that hasn't loaded gets a stand-in: the\n * active cell's row id if it sits there (so its DOM and focus stay put), else\n * the index, which is also its real id when there is no `getRowId`.\n */\n #rowId(model: TableModel<T, CellContent>, index: number): string {\n const id = model.rowAt(index)?.id;\n if (id !== undefined) return id;\n const active = this.#active;\n if (active?.index === index && active.rowId !== undefined) return active.rowId;\n return this.#placeholderId(index);\n }\n\n /** The id of an unloaded row: its index, or a reserved string if `getRowId` makes the ids. */\n #placeholderId(index: number): string {\n return this.getRowId ? `\\u0000${String(index)}` : String(index);\n }\n\n readonly #headerHandlers = {\n click: (event: MouseEvent) => {\n const id = sortColumnOf(event);\n if (id !== undefined) this.#requestSort(id);\n },\n pointerdown: (event: PointerEvent) => {\n if (event.button !== 0) return;\n const handle = event.composedPath()[0];\n if (!(handle instanceof HTMLElement)) return;\n const group = this.#groupCellOf(handle.dataset.resizeGroup);\n if (group) {\n const starts = this.#groupWidths(group.columns);\n const total = [...starts.values()].reduce((sum, w) => sum + w, 0);\n startResizeDrag(handle, event, total, this.#direction(), (w) => {\n this.#requestGroupResize(group.columns, starts, w);\n });\n return;\n }\n const id = handle.dataset.resizeCol;\n const cell = handle.parentElement;\n if (id !== undefined && cell) {\n startResizeDrag(\n handle,\n event,\n cell.getBoundingClientRect().width,\n this.#direction(),\n (w) => {\n this.#requestResize(id, w);\n },\n );\n return;\n }\n this.#startReorder(event);\n },\n /** A double-click on a resize handle fits the column to its rendered content. */\n dblclick: (event: MouseEvent) => {\n const handle = event.composedPath()[0];\n if (!(handle instanceof HTMLElement)) return;\n // A group's handle fits each of its columns (`autosizeColumns()` for them).\n const group = this.#groupCellOf(handle.dataset.resizeGroup);\n if (group) {\n void this.autosizeColumns([...group.columns]);\n return;\n }\n const id = handle.dataset.resizeCol;\n if (id === undefined) return;\n this.#requestResizes(measureColumns(this.renderRoot, [id]));\n },\n };\n\n /**\n * Keys on a focused cell or header: arrows by cell, Home/End along the row,\n * PageUp/PageDown by a page of rows (the view scrolls with it), Ctrl+Home/End\n * (or Cmd) to the first header and the last cell. Keys from content inside a\n * cell (an input, a button) are left to that content.\n */\n readonly #onKeydown = (event: KeyboardEvent) => {\n const origin = event.composedPath()[0] ?? event.target ?? this;\n const group = groupCell(origin);\n const cell = gridCell(origin) ?? group;\n const id = cell?.dataset.col;\n if (!cell || (id === undefined && !group)) return;\n const scroller = event.currentTarget as HTMLElement;\n if (event.key === 'Tab' && event.shiftKey) {\n // Firefox makes the scroll container a tab stop, so Shift+Tab would stop\n // on it before leaving the grid. Take it out of the tab order for this\n // one move only: a tabindex there for good would expose it as a node of\n // its own between the grid and its rows.\n scroller.tabIndex = -1;\n // Put it back once focus has actually moved (a timer can run first).\n cell.addEventListener(\n 'focusout',\n () => {\n scroller.removeAttribute('tabindex');\n },\n { once: true },\n );\n return;\n }\n if (group || id === undefined) {\n this.#groupKey(event, cell, scroller);\n return;\n }\n const pluginTarget = id === SELECTION_COLUMN_ID ? undefined : this.#cellTarget(event);\n if (pluginTarget && this.#plugins.keydown(event, pluginTarget)) return;\n const inHeader = cell.getAttribute('role') === 'columnheader';\n const { key } = event;\n const arrow = key === 'ArrowLeft' || key === 'ArrowRight';\n if (inHeader && arrow && event.altKey) {\n event.preventDefault();\n // Logical: the arrow pointing toward the inline end grows the column, or\n // moves it that way with Shift.\n const towardEnd = (key === 'ArrowRight') === (this.#direction() === 1);\n if (event.shiftKey) {\n this.#moveByKey({ kind: 'column', id }, towardEnd ? 1 : -1);\n } else {\n this.#requestResize(\n id,\n this.#currentWidth(id, cell) + (towardEnd ? RESIZE_STEP : -RESIZE_STEP),\n );\n }\n return;\n }\n if (inHeader && (key === 'Enter' || key === ' ') && cell.dataset.sortCol !== undefined) {\n event.preventDefault();\n this.#requestSort(id);\n return;\n }\n if (this.#selectionKey(event, cell, id, inHeader, scroller)) return;\n // Ctrl (Cmd on macOS) only goes with Home and End: to the corners.\n const corner = event.ctrlKey || event.metaKey;\n if (event.altKey || event.shiftKey || (corner && key !== 'Home' && key !== 'End')) return;\n const model = this.#table.model;\n const layout = layoutOf(model);\n const from = gridRowOfCell(cell, layout);\n if (!from) return;\n if (!inHeader && key === 'Enter') {\n // Enter on a body cell does what a click does; on a failed row, it retries.\n event.preventDefault();\n if (from.section === 'body' && this.#data.stateAt(from.index) === 'error') {\n this.#data.retry(from.index);\n } else {\n this.#activate(event.composedPath());\n }\n return;\n }\n const columns = model.columns;\n // Rows step by grid position: header, pinned top, body, pinned bottom.\n let pos = layout.position(from);\n const last = layout.total - 1;\n let col = columns.findIndex((c) => c.id === id);\n switch (key) {\n case 'PageDown':\n case 'PageUp':\n case 'ArrowDown':\n case 'ArrowUp':\n pos = this.#verticalStep(key, pos, layout, scroller);\n break;\n case 'ArrowRight':\n col += this.#direction();\n break;\n case 'ArrowLeft':\n col -= this.#direction();\n break;\n case 'Home':\n col = 0;\n if (corner) {\n // The top header of the first column: its outermost group, else its header.\n pos = this.#headerLevelDown(model, 0, columns[0]?.id ?? id);\n this.#virtual.scrollToEdge('start');\n }\n break;\n case 'End':\n col = columns.length - 1;\n if (corner) pos = last;\n break;\n default:\n return;\n }\n event.preventDefault();\n let row = layout.at(pos) ?? layout.leafHeader;\n const target = columns[Math.min(Math.max(col, 0), columns.length - 1)];\n if (!target) return;\n if (row.section === 'header' && row.index < layout.header - 1 && key === 'ArrowUp') {\n // Up from a column header: to the nearest group above it, if there is one.\n const level = this.#headerLevelUp(model, row.index, target.id);\n if (level === undefined) return;\n row = { section: 'header', index: level };\n }\n // PageUp/PageDown scroll by as many rows as focus moved, so the focused cell\n // keeps its place on screen. The ends clamp; focusing scrolls the rest of\n // the way. Through the virtualizer: a scaled body's px aren't rows.\n if (key.startsWith('Page') && from.section === 'body' && row.section === 'body') {\n this.#virtual.scrollBy(this.#virtual.startOf(row.index) - this.#virtual.startOf(from.index));\n }\n // Ctrl+End onto a bottom pinned row: show the end of the body too, as\n // Ctrl+Home shows its start.\n if (corner && key === 'End' && row.section === 'bottom') {\n this.#virtual.scrollToEdge('end');\n }\n this.#moveTo(row, target.id, model);\n };\n\n /**\n * The header row to go to from header row `level` down, over a column: the first\n * group row from `level` with a group over it, else the column headers.\n */\n #headerLevelDown(model: TableModel<T, CellContent>, level: number, columnId: string): number {\n const leaf = model.headerGroups.length;\n for (let l = level; l < leaf; l++) {\n if (model.headerCell(l, columnId)?.kind === 'group') return l;\n }\n return leaf;\n }\n\n /** The first group row from `level` up with a group over a column, or `undefined`. */\n #headerLevelUp(\n model: TableModel<T, CellContent>,\n level: number,\n columnId: string,\n ): number | undefined {\n for (let l = Math.min(level, model.headerGroups.length - 1); l >= 0; l--) {\n if (model.headerCell(l, columnId)?.kind === 'group') return l;\n }\n return undefined;\n }\n\n /**\n * Keys on a focused group header. Arrows move between group headers in its row\n * (fillers are skipped) and to the headers above and below it; ArrowDown ends on\n * the column headers. Home and End go to the row's first and last group,\n * PageDown into the body, Ctrl+Home and Ctrl+End to the corners, and\n * Alt+Shift+Arrow moves the group. Groups don't sort or resize.\n */\n #groupKey(event: KeyboardEvent, cell: HTMLElement, scroller: HTMLElement): void {\n const model = this.#table.model;\n const layout = layoutOf(model);\n const at = gridRowOf(cell.parentElement, layout);\n const row = at?.section === 'header' ? model.headerGroups[at.index] : undefined;\n const here = row?.find((c) => c.key === cell.dataset.groupKey);\n if (!at || !row || here?.groupId === undefined) return;\n const level = at.index;\n const active = this.#active;\n const anchor =\n active?.section === 'header' && active.index === level && here.columns.includes(active.col)\n ? active.col\n : here.columns[0];\n if (anchor === undefined) return;\n const { key } = event;\n const arrow = key === 'ArrowLeft' || key === 'ArrowRight';\n const towardEnd = (key === 'ArrowRight') === (this.#direction() === 1);\n if (arrow && event.altKey) {\n event.preventDefault();\n if (event.shiftKey) {\n this.#moveByKey({ kind: 'group', id: here.groupId, pin: here.pin }, towardEnd ? 1 : -1);\n } else if (here.resizable) {\n const starts = this.#groupWidths(here.columns);\n const total = [...starts.values()].reduce((sum, w) => sum + w, 0);\n this.#requestGroupResize(\n here.columns,\n starts,\n total + (towardEnd ? RESIZE_STEP : -RESIZE_STEP),\n );\n }\n return;\n }\n if (key === 'Enter' || key === ' ') {\n event.preventDefault();\n return;\n }\n if (this.#selectionKey(event, cell, anchor, true, scroller)) return;\n const corner = event.ctrlKey || event.metaKey;\n if (event.altKey || event.shiftKey || (corner && key !== 'Home' && key !== 'End')) return;\n const groups = row.filter((c) => c.kind === 'group');\n const columns = model.columns;\n let to: { row: GridRow; col: string } | undefined;\n switch (key) {\n case 'ArrowLeft':\n case 'ArrowRight': {\n const col = groups[groups.indexOf(here) + (towardEnd ? 1 : -1)]?.columns[0];\n if (col !== undefined) to = { row: at, col };\n break;\n }\n case 'Home':\n case 'End':\n if (corner) {\n const first = key === 'Home';\n const col = (first ? columns[0] : columns.at(-1))?.id;\n if (col === undefined) break;\n if (first) this.#virtual.scrollToEdge('start');\n else if (layout.bottom > 0) this.#virtual.scrollToEdge('end');\n const pos = first ? this.#headerLevelDown(model, 0, col) : layout.total - 1;\n to = { row: layout.at(pos) ?? layout.leafHeader, col };\n } else {\n const col = (key === 'Home' ? groups[0] : groups.at(-1))?.columns[0];\n if (col !== undefined) to = { row: at, col };\n }\n break;\n case 'ArrowDown':\n to = {\n row: { section: 'header', index: this.#headerLevelDown(model, level + 1, anchor) },\n col: anchor,\n };\n break;\n case 'ArrowUp': {\n const up = this.#headerLevelUp(model, level - 1, anchor);\n if (up !== undefined) to = { row: { section: 'header', index: up }, col: anchor };\n break;\n }\n case 'PageDown': {\n const pos = this.#verticalStep(key, layout.position(at), layout, scroller);\n to = { row: layout.at(pos) ?? at, col: anchor };\n break;\n }\n case 'PageUp':\n break;\n default:\n return;\n }\n event.preventDefault();\n if (to) this.#moveTo(to.row, to.col, model);\n }\n\n /**\n * The grid position ArrowUp/ArrowDown (one row) or PageUp/PageDown (a page of\n * the body) moves to from `pos`. PageDown from above the body lands a page\n * into it and stops at its last row; PageUp stays in the body.\n */\n #verticalStep(\n key: 'PageDown' | 'PageUp' | 'ArrowDown' | 'ArrowUp',\n pos: number,\n layout: RowLayout,\n scroller: HTMLElement,\n ): number {\n const bodyFirst = layout.position({ section: 'body', index: 0 });\n const bodyLast = bodyFirst + layout.body - 1;\n const page = this.#pageRows(key, pos, layout, scroller);\n switch (key) {\n case 'PageDown':\n return layout.body > 0 && pos <= bodyLast\n ? Math.min(Math.max(pos, bodyFirst - 1) + page, bodyLast)\n : pos;\n case 'PageUp':\n return layout.body > 0 && pos > bodyFirst\n ? Math.max(Math.min(pos, bodyLast + 1) - page, bodyFirst)\n : pos;\n case 'ArrowDown':\n return Math.min(pos + 1, layout.total - 1);\n case 'ArrowUp':\n return Math.max(pos - 1, 0);\n }\n }\n\n /** How many rows PageUp/PageDown move from grid position `pos`. */\n #pageRows(key: string, pos: number, layout: RowLayout, scroller: HTMLElement): number {\n if (this.rowHeight !== 'auto') {\n // Whole rows between the sticky header rows and pinned rows (each one row tall).\n const fit = Math.floor(scroller.clientHeight / this.#rowPx + 0.01);\n return Math.max(1, fit - layout.header - layout.top - layout.bottom);\n }\n // The body rows that fit between the header and the pinned rows, from the\n // focused body row (or the body's first or last row).\n const view = scroller.clientHeight - this.#headerAndPinnedPx(layout);\n const bodyFirst = layout.position({ section: 'body', index: 0 });\n const from = Math.min(Math.max(pos - bodyFirst, 0), Math.max(layout.body - 1, 0));\n return this.#virtual.pageRows(from, key === 'PageDown', view);\n }\n\n /**\n * Selection keys, with a `selectionMode`: Space (or Shift+Space) toggles the\n * focused body row; in `multi` mode, Shift+ArrowUp/ArrowDown and\n * Shift+PageUp/PageDown move focus through the body and select from the\n * anchor to it, and Ctrl/Cmd+A selects every row. `true` if it took the key.\n */\n #selectionKey(\n event: KeyboardEvent,\n cell: HTMLElement,\n col: string,\n inHeader: boolean,\n scroller: HTMLElement,\n ): boolean {\n const mode = this.#mode();\n if (mode === 'none' || event.altKey) return false;\n const { key } = event;\n const command = event.ctrlKey || event.metaKey;\n const model = this.#table.model;\n if (command && !event.shiftKey && key.toLowerCase() === 'a') {\n if (mode !== 'multi') return false;\n // Not the page's text: the rows.\n event.preventDefault();\n this.#selectAll();\n return true;\n }\n if (command) return false;\n if (inHeader) {\n // Space on the select-all header does what its checkbox does.\n if (key !== ' ' || col !== SELECTION_COLUMN_ID || mode !== 'multi') return false;\n event.preventDefault();\n this.#toggleAll();\n return true;\n }\n const layout = layoutOf(model);\n const from = gridRowOf(cell.parentElement, layout);\n if (from?.section !== 'body') return false;\n if (key === ' ') {\n // Space would scroll the table.\n event.preventDefault();\n const id = model.rowAt(from.index)?.id;\n if (id !== undefined) this.#requestSelection(toggleRow(this.#selection.value, mode, id));\n return true;\n }\n if (\n !event.shiftKey ||\n mode !== 'multi' ||\n (key !== 'ArrowDown' && key !== 'ArrowUp' && key !== 'PageDown' && key !== 'PageUp')\n ) {\n return false;\n }\n event.preventDefault();\n // A range stays in the body: the header and pinned rows can't be selected.\n const bodyFirst = layout.position({ section: 'body', index: 0 });\n const pos = this.#verticalStep(key, layout.position(from), layout, scroller);\n const to = layout.at(Math.min(Math.max(pos, bodyFirst), bodyFirst + layout.body - 1));\n if (to?.section !== 'body' || to.index === from.index) return true;\n if (key.startsWith('Page')) {\n this.#virtual.scrollBy(this.#virtual.startOf(to.index) - this.#virtual.startOf(from.index));\n }\n const fromId = model.rowAt(from.index)?.id;\n const anchor =\n this.#anchorAt(model) ??\n (fromId === undefined ? undefined : { id: fromId, index: from.index });\n if (anchor) {\n const idAt = (index: number) => model.rowAt(index)?.id;\n const selection = selectRange([], anchor.index, to.index, idAt, false);\n this.#requestSelection({ selection, anchor: anchor.id });\n }\n this.#moveTo(to, col, model);\n return true;\n }\n\n /** Focus that lands in a cell (a click, or content inside it) makes that cell active. */\n readonly #onFocusin = (event: FocusEvent) => {\n // Tab into the grid landed on the scroll container (Firefox makes it a tab\n // stop): move on to the grid's one tab stop, the active cell. Only when focus\n // came from outside the grid: coming from inside means the user is leaving,\n // and sending them back would trap the keyboard.\n const scroller = event.currentTarget as HTMLElement;\n if (event.composedPath()[0] === scroller) {\n const from = event.relatedTarget;\n if (!(from instanceof Node && scroller.contains(from))) {\n this.#focusPending = true;\n this.requestUpdate();\n }\n return;\n }\n for (const target of event.composedPath()) {\n const group = groupCell(target);\n if (group) {\n this.#focusGroup(group);\n return;\n }\n const cell = gridCell(target);\n if (cell?.dataset.col !== undefined) {\n const model = this.#table.model;\n const row = gridRowOfCell(cell, layoutOf(model));\n const { col } = cell.dataset;\n const prev = this.#active;\n if (\n row &&\n (row.section !== prev?.section || row.index !== prev.index || col !== prev.col)\n ) {\n this.#active = { ...row, rowId: this.#gridRowId(model, row), col };\n this.requestUpdate();\n }\n return;\n }\n if (target === event.currentTarget) return;\n }\n };\n\n /** Focus on a group header makes it active, on the column it was active on, else its first. */\n #focusGroup(cell: HTMLElement): void {\n const model = this.#table.model;\n const row = gridRowOf(cell.parentElement, layoutOf(model));\n const group =\n row && model.headerGroups[row.index]?.find((c) => c.key === cell.dataset.groupKey);\n const first = group?.columns[0];\n if (!row || !group || first === undefined) return;\n const prev = this.#active;\n if (\n prev?.section === 'header' &&\n prev.index === row.index &&\n group.columns.includes(prev.col)\n ) {\n return;\n }\n this.#active = { ...row, rowId: undefined, col: first };\n this.requestUpdate();\n }\n\n /**\n * `argus-cell-click`, then `argus-row-click`, for clicks in the body; then,\n * with a `selectionMode`, the click selects its row.\n */\n readonly #onClick = (event: MouseEvent) => {\n const path = event.composedPath();\n this.#activate(path);\n const mode = this.#mode();\n const target = mode === 'none' ? undefined : this.#selectableRowOf(path);\n if (!target) return;\n // A click in the checkbox column, beside the checkbox, toggles like it.\n const inSelectionCell = path.some(\n (t) => t instanceof HTMLElement && t.dataset.col === SELECTION_COLUMN_ID,\n );\n this.#clickRow(target, event, inSelectionCell || event.ctrlKey || event.metaKey);\n };\n\n /** Selects for a click on a row, through `clickSelection`. */\n #clickRow(target: SelectionTarget, event: MouseEvent, toggle: boolean): void {\n const model = this.#table.model;\n this.#requestSelection(\n clickSelection(\n this.#selection.value,\n this.#mode(),\n target,\n this.#anchorAt(model),\n { toggle, range: event.shiftKey },\n (index) => model.rowAt(index)?.id,\n ),\n );\n }\n\n /**\n * The checkboxes' handlers. The table owns their state: a click asks for a new\n * selection, and the render that always follows sets every box back to the\n * selection (`live()`), so a change a controlled host turns down unticks it\n * again. Not `preventDefault()`: for a real click the browser runs that render\n * inside the dispatch, then undoes the toggle after it, over the render. A\n * press leaves focus on the cell, so the grid's keys keep working.\n */\n readonly #checkboxHandlers: CheckboxHandlers = {\n row: (event) => {\n const index = Number((event.currentTarget as HTMLElement).dataset.row);\n const id = this.#table.model.rowAt(index)?.id;\n if (id !== undefined) this.#clickRow({ id, index }, event, true);\n this.requestUpdate();\n },\n all: () => {\n this.#toggleAll();\n this.requestUpdate();\n },\n press: (event) => {\n event.preventDefault();\n (event.currentTarget as HTMLElement).parentElement?.focus({ preventScroll: true });\n },\n };\n\n /** Selects every selectable row, keeping the others (with a `dataSource`: the loaded ones). */\n #selectAll(): void {\n const ids = this.#table.model.selectableIds();\n this.#requestSelection({\n selection: selectAll(this.#selection.value, ids),\n anchor: this.#anchor,\n });\n }\n\n /** The select-all checkbox: clears the selection when every row is selected, else selects all. */\n #toggleAll(): void {\n if (this.#checkAllState(this.#table.model) === 'all') {\n this.#requestSelection({ selection: [], anchor: this.#anchor });\n } else {\n this.#selectAll();\n }\n }\n\n /** The select-all checkbox, in the checkbox column of a `multi` table. */\n #checkAllOf(model: TableModel<T, CellContent>): CheckAll | undefined {\n if (!this.#selectionColumn || this.#mode() !== 'multi') return undefined;\n return { state: this.#checkAllState(model), handlers: this.#checkboxHandlers };\n }\n\n /**\n * Whether all, some or none of the selectable rows are selected. With `data`\n * it's worked out once per selection and rows shown, not on scroll;\n * with a `dataSource` every time, over the loaded rows, which eviction keeps few.\n */\n #checkAllState(model: TableModel<T, CellContent>): CheckAll['state'] {\n const count = (): CheckAll['state'] => {\n const ids = model.selectableIds();\n const selected = this.#selectedSet();\n const n = ids.reduce((sum, id) => (selected.has(id) ? sum + 1 : sum), 0);\n if (n === 0) return 'none';\n return n === ids.length ? 'all' : 'some';\n };\n if (this.#data.rows) return count();\n // Everything the rows of the model depend on: the data and what filters it.\n const key = [\n this.#selection.value,\n this.data,\n this.getRowId,\n this.#columns,\n this.#filters.value,\n this.#quickFilter,\n this.#visibility.value,\n ];\n const cached = this.#checkAll;\n if (cached?.key.length === key.length && key.every((k, i) => k === cached.key[i])) {\n return cached.state;\n }\n const state = count();\n this.#checkAll = { key, state };\n return state;\n }\n\n /**\n * A Shift+press on a row in `multi` mode selects a range of rows, not the\n * page's text from the last click: no text selection, and the cell still\n * takes focus.\n */\n readonly #onMousedown = (event: MouseEvent) => {\n if (!event.shiftKey || event.button !== 0 || this.#mode() !== 'multi') return;\n const path = event.composedPath();\n if (!this.#selectableRowOf(path)) return;\n event.preventDefault();\n for (const target of path) {\n const cell = gridCell(target);\n if (cell) {\n cell.focus({ preventScroll: true });\n return;\n }\n }\n };\n\n /** `selectionMode`, with anything unknown read as `none`. */\n #mode(): SelectionMode {\n const mode = this.selectionMode;\n return mode === 'single' || mode === 'multi' ? mode : 'none';\n }\n\n /** Whether each rendered body row is selected; `undefined` without a `selectionMode`. */\n #selectedAt(model: TableModel<T, CellContent>): SelectedAt | undefined {\n if (this.#mode() === 'none') return undefined;\n const ids = this.#selectedSet();\n return (index) => {\n const id = model.rowAt(index)?.id;\n return id === undefined ? undefined : ids.has(id);\n };\n }\n\n /** `selection` as a set, rebuilt only when `selection` changes. */\n #selectedSet(): ReadonlySet<string> {\n const selection = this.#selection.value;\n if (this.#selectedIds?.of !== selection) {\n this.#selectedIds = { of: selection, ids: new Set(selection) };\n }\n return this.#selectedIds.ids;\n }\n\n /**\n * The loaded body row a pointer event is on, as a selection target. None for\n * the header, pinned rows, rows still loading, and presses on interactive\n * content in a cell (a button, a link, an input).\n */\n #selectableRowOf(path: readonly EventTarget[]): SelectionTarget | undefined {\n const row = path.find(\n (t): t is HTMLElement => t instanceof HTMLElement && t.getAttribute('role') === 'row',\n );\n if (!row || fromInteractive(path, row)) return undefined;\n const model = this.#table.model;\n const at = gridRowOf(row, layoutOf(model));\n if (at?.section !== 'body') return undefined;\n const id = model.rowAt(at.index)?.id;\n return id === undefined ? undefined : { id, index: at.index };\n }\n\n /** The anchor row and where it is now; `undefined` if it isn't in the rows (or not loaded). */\n #anchorAt(model: TableModel<T, CellContent>): SelectionTarget | undefined {\n const id = this.#anchor;\n if (id === undefined) return undefined;\n const index = model.indexOf(id);\n return index === undefined ? undefined : { id, index };\n }\n\n /**\n * Changes the selection through the controlled/uncontrolled rules, and moves\n * the anchor. A step that leaves the same rows selected fires nothing.\n */\n #requestSelection(step: SelectionStep | undefined): void {\n if (!step) return;\n this.#anchor = step.anchor;\n const old = this.#selection.value;\n if (sameSelection(step.selection, old)) return;\n const { value, applied } = this.#selection.request(step.selection);\n if (applied) {\n this.#appliedSelection = value;\n this.requestUpdate('selection', old);\n } else {\n fire(this, SELECTION_CHANGE, { selection: value });\n }\n }\n\n /**\n * Fires `argus-cell-click` (when a cell is on the path), then `argus-row-click`,\n * for the body or pinned row on an event path. Clicks and Enter on a cell use\n * it. Rows that haven't loaded, the header and the checkbox column fire nothing.\n */\n #activate(path: EventTarget[]): void {\n let columnId: string | undefined;\n for (const target of path) {\n if (!(target instanceof HTMLElement)) continue;\n const role = target.getAttribute('role');\n if (role === 'gridcell') columnId = target.dataset.col;\n if (columnId === SELECTION_COLUMN_ID) return;\n if (role !== 'row') continue;\n const model = this.#table.model;\n const at = gridRowOf(target, layoutOf(model));\n if (!at || at.section === 'header') return;\n const { index } = at;\n if (at.section === 'body') {\n const row = model.rowAt(index);\n if (!row) return;\n if (columnId !== undefined) {\n fire(this, CELL_CLICK, {\n row: row.original,\n rowId: row.id,\n index,\n columnId,\n value: model.valueAt(index, columnId),\n });\n }\n fire(this, ROW_CLICK, { row: row.original, rowId: row.id, index });\n return;\n }\n const pinned = at.section;\n const row = model.pinnedRowAt(pinned, index);\n if (!row) return;\n if (columnId !== undefined) {\n fire(this, CELL_CLICK, {\n row: row.original,\n rowId: row.id,\n index,\n columnId,\n value: model.pinnedValueAt(pinned, index, columnId),\n pinned,\n });\n }\n fire(this, ROW_CLICK, { row: row.original, rowId: row.id, index, pinned });\n return;\n }\n }\n\n /** The id of a grid row: a body or pinned row's id; none for the header. */\n #gridRowId(model: TableModel<T, CellContent>, row: GridRow): string | undefined {\n switch (row.section) {\n case 'header':\n return undefined;\n case 'body':\n return this.#rowId(model, row.index);\n default:\n return model.pinnedRowAt(row.section, row.index)?.id;\n }\n }\n\n /** Makes a cell active and focuses it after the update. The keep-rendered rule renders its row. */\n #moveTo(row: GridRow, col: string, model: TableModel<T, CellContent>): void {\n this.#active = { ...row, rowId: this.#gridRowId(model, row), col };\n this.#focusPending = true;\n this.requestUpdate();\n }\n\n #focusActive(): void {\n const active = this.#active;\n if (!active) return;\n const col = CSS.escape(active.col);\n const model = this.#table.model;\n const layout = layoutOf(model);\n // aria-rowindex is unique across the grid: header, pinned and body rows.\n const index = layout.ariaRowIndex(active);\n const row = `[role='row'][aria-rowindex=\"${String(index)}\"]`;\n if (active.section === 'header' && active.index < layout.header - 1) {\n // A group header: focus it, and show the column it is active on.\n const key = model.headerCell(active.index, active.col)?.key ?? '';\n const group = this.renderRoot.querySelector<HTMLElement>(\n `${row} > [data-group-key=\"${CSS.escape(key)}\"]`,\n );\n if (!group) return;\n group.focus({ preventScroll: true });\n const leaf = `[role='row'][aria-rowindex=\"${String(layout.header)}\"] > [data-col=\"${col}\"]`;\n this.renderRoot.querySelector(leaf)?.scrollIntoView({ block: 'nearest', inline: 'nearest' });\n return;\n }\n const cell = this.renderRoot.querySelector<HTMLElement>(`${row} > [data-col=\"${col}\"]`);\n if (!cell) return;\n cell.focus({ preventScroll: true });\n // A scaled body moves `ratio` px of rows per px scrolled, so the browser can't\n // scroll a body row into view: the virtualizer does, and the next update\n // (from its scroll) shows the row and scrolls sideways. Rows of different\n // heights too: rows measured on the way can move the row again, so it\n // scrolls until they're done.\n if (active.section === 'body' && (this.#virtual.scaled || this.rowHeight === 'auto')) {\n const before = layout.header * this.#rowPx + this.#pinnedPx('top', layout);\n if (this.#virtual.reveal(active.index, before, this.#pinnedPx('bottom', layout))) {\n this.#focusPending = true;\n return;\n }\n }\n cell.scrollIntoView({ block: 'nearest', inline: 'nearest' });\n }\n\n /**\n * Keeps the active cell valid after columns or rows change. In the body: on the\n * same row id when it still exists (it may have moved), else at the same\n * index, clamped. A data source row that isn't loaded (yet, or any more) keeps\n * its id. A pinned row stays at its index, clamped to its list. A row whose\n * section has no rows left gives way to the header, the default. If its row\n * went away while the grid had focus, focus follows to the replacement.\n */\n #reconcileActive(model: TableModel<T, CellContent>): void {\n const columns = model.columns;\n const first = columns[0];\n if (!first) {\n this.#active = undefined;\n return;\n }\n const layout = layoutOf(model);\n const leaf = layout.header - 1;\n const prev = this.#active ?? { ...layout.leafHeader, rowId: undefined, col: first.id };\n const col = columns.some((c) => c.id === prev.col)\n ? prev.col\n : this.#columnInPlaceOf(model, prev.col, first.id);\n let { section, index, rowId } = prev;\n // The cell went away with its column while focused: focus its replacement.\n let moved = col !== prev.col && this.#active !== undefined;\n if (section === 'header') {\n if (!this.#active || index === this.#leafLevel) {\n // On the column headers: still there, though group rows came or went above.\n index = leaf;\n } else if (index >= leaf || model.headerCell(index, col)?.kind !== 'group') {\n // Its group went away: to the column's header.\n index = leaf;\n moved = true;\n }\n }\n this.#leafLevel = leaf;\n if (section === 'body' && rowId !== undefined) {\n const found = model.indexOf(rowId);\n const unloaded = index < model.rowCount && model.rowAt(index) === undefined;\n if (found !== undefined) {\n index = found;\n } else if (!unloaded) {\n index = Math.min(index, model.rowCount - 1);\n rowId = index >= 0 ? (model.rowAt(index)?.id ?? this.#placeholderId(index)) : undefined;\n moved = true;\n }\n } else if (section === 'top' || section === 'bottom') {\n const count = model.pinnedCount(section);\n if (index >= count) {\n index = count - 1;\n moved = true;\n }\n rowId = index >= 0 ? model.pinnedRowAt(section, index)?.id : undefined;\n }\n if (index < 0) {\n ({ section, index } = layout.leafHeader);\n rowId = undefined;\n }\n if (moved && this.matches(':focus-within')) this.#focusPending = true;\n if (\n section !== prev.section ||\n index !== prev.index ||\n rowId !== prev.rowId ||\n col !== prev.col ||\n !this.#active\n ) {\n this.#active = { section, index, rowId, col };\n }\n }\n\n /**\n * The shown column that takes a hidden column's place: the next one in the\n * column order, else the one before it. `fallback` for a column that is gone\n * altogether.\n */\n #columnInPlaceOf(model: TableModel<T, CellContent>, id: string, fallback: string): string {\n const all = model.allColumns;\n const at = all.findIndex((c) => c.id === id);\n if (at < 0) return fallback;\n const shown = (c: ColumnView<T, CellContent>) => !c.hidden;\n return (all.slice(at + 1).find(shown) ?? all.slice(0, at).findLast(shown))?.id ?? fallback;\n }\n\n /**\n * The width a resize starts from: the latest requested width (key presses can\n * come faster than renders), else the model's fixed width, else the rendered\n * width of a flex column.\n */\n #currentWidth(columnId: string, cell: HTMLElement): number {\n const sized = this.#sizing.value[columnId];\n if (sized !== undefined) return sized;\n const view = this.#table.model.columns.find((c) => c.id === columnId);\n return view && view.flex === undefined ? view.width : cell.getBoundingClientRect().width;\n }\n\n /** The group header cell with a key, from the model. */\n #groupCellOf(key: string | undefined) {\n if (key === undefined) return undefined;\n return this.#table.model.headerGroups.flat().find((c) => c.key === key);\n }\n\n /**\n * The widths a group resize starts from, by column: the latest requested ones\n * (key presses can come faster than renders), else the model's, else the\n * rendered width of a flex column.\n */\n #groupWidths(columnIds: readonly string[]): Map<string, number> {\n const widths = new Map<string, number>();\n for (const id of columnIds) {\n const header = this.renderRoot.querySelector<HTMLElement>(\n `[part~='header-cell'][data-col=\"${CSS.escape(id)}\"]`,\n );\n const view = this.#table.model.columns.find((c) => c.id === id);\n const sized = this.#sizing.value[id];\n widths.set(id, sized ?? (header ? this.#currentWidth(id, header) : (view?.width ?? 0)));\n }\n return widths;\n }\n\n /**\n * Resizes a group to `total` px: the change is spread over its resizable columns\n * in proportion to their widths, within their bounds (one `argus-column-sizing-change`\n * per column that changes). The other columns keep their width.\n */\n #requestGroupResize(\n columnIds: readonly string[],\n starts: ReadonlyMap<string, number>,\n total: number,\n ): void {\n const views = new Map(this.#table.model.columns.map((c) => [c.id, c]));\n let fixed = 0;\n const spread = [];\n for (const id of columnIds) {\n const view = views.get(id);\n const width = starts.get(id) ?? view?.width ?? 0;\n if (view?.resizable) {\n spread.push({ id, width, minWidth: view.minWidth, maxWidth: view.maxWidth });\n } else {\n fixed += width;\n }\n }\n if (spread.length === 0) return;\n this.#requestResizes(spreadWidth(spread, total - fixed));\n }\n\n #direction(): 1 | -1 {\n return getComputedStyle(this).direction === 'rtl' ? -1 : 1;\n }\n\n /** Sets one column's width (clamped by core), through the controlled/uncontrolled rules. */\n #requestResize(columnId: string, width: number): void {\n this.#requestResizes(new Map([[columnId, width]]));\n }\n\n /**\n * Sets column widths (clamped by core) in one change, through the\n * controlled/uncontrolled rules. One `argus-column-sizing-change` per column\n * that changes, each with the whole new sizing.\n */\n #requestResizes(widths: ReadonlyMap<string, number>): void {\n const model = this.#table.model;\n const old = this.#sizing.value;\n const targets: [string, number][] = [];\n for (const [columnId, width] of widths) {\n const target = model.nextSizing(columnId, width)?.[columnId];\n if (target !== undefined && target !== old[columnId]) targets.push([columnId, target]);\n }\n if (targets.length === 0) return;\n const { value, applied } = this.#sizing.request({ ...old, ...Object.fromEntries(targets) });\n const details = targets.map(([columnId, width]) => ({ columnSizing: value, columnId, width }));\n if (applied) {\n // Only the latest width per column fires, all with the latest sizing.\n for (const detail of this.#appliedResizes.values()) detail.columnSizing = value;\n for (const detail of details) this.#appliedResizes.set(detail.columnId, detail);\n this.requestUpdate('columnSizing', old);\n } else {\n for (const detail of details) fire(this, COLUMN_SIZING_CHANGE, detail);\n }\n }\n\n /**\n * Pins or unpins a column through the controlled/uncontrolled rules. Starts\n * from the latest requested pins, so requests can come faster than renders.\n */\n #requestPin(columnId: string, pin: ColumnPin | false): void {\n const old = this.#pinning.value;\n const next = this.#table.model.nextPinning(columnId, pin, old);\n if (!next) return;\n const { value, applied } = this.#pinning.request(next);\n if (applied) {\n for (const detail of this.#appliedPins.values()) detail.columnPinning = value;\n this.#appliedPins.set(columnId, { columnPinning: value, columnId, pin });\n this.requestUpdate('columnPinning', old);\n } else {\n fire(this, COLUMN_PINNING_CHANGE, { columnPinning: value, columnId, pin });\n }\n }\n\n /** Hides or shows a column through the controlled/uncontrolled rules. */\n #requestHide(columnId: string, hidden: boolean): void {\n const old = this.#visibility.value;\n const next = this.#table.model.nextVisibility(columnId, hidden, old);\n if (!next) return;\n const { value, applied } = this.#visibility.request(next);\n if (applied) {\n for (const detail of this.#appliedHides.values()) detail.columnVisibility = value;\n this.#appliedHides.set(columnId, { columnVisibility: value, columnId, visible: !hidden });\n this.requestUpdate('columnVisibility', old);\n } else {\n fire(this, COLUMN_VISIBILITY_CHANGE, { columnVisibility: value, columnId, visible: !hidden });\n }\n }\n\n /** Sets or clears a column's filter through the controlled/uncontrolled rules. */\n #requestFilter(columnId: string, filter: ColumnFilter | undefined): void {\n const old = this.#filters.value;\n const next = this.#table.model.nextFilters(columnId, filter, old);\n if (!next) return;\n const { value, applied } = this.#filters.request(next);\n if (applied) {\n for (const detail of this.#appliedFilters.values()) detail.columnFilters = value;\n this.#appliedFilters.set(columnId, { columnFilters: value, columnId, columnFilter: filter });\n this.requestUpdate('columnFilters', old);\n } else {\n fire(this, COLUMN_FILTERS_CHANGE, {\n columnFilters: value,\n columnId,\n columnFilter: filter,\n });\n }\n }\n\n /**\n * Says how many rows the filters leave (\"42 rows\"). With a `dataSource` the count\n * isn't known until the first page answers, so nothing is said.\n */\n #announceRowCount(model: TableModel<T, CellContent>): void {\n if (this.#data.rows) return;\n const n = model.rowCount;\n announce(this.ownerDocument, n === 1 ? '1 row' : `${String(n)} rows`);\n }\n\n /**\n * Moves a column or group to position `to` among its siblings (the columns and\n * groups of its parent group on its pin side), through the controlled/uncontrolled\n * rules. Starts from the latest requested order, so moves can come faster than\n * renders. `false` if it can't move there.\n */\n #requestReorder(unit: OrderUnit, to: number): boolean {\n const old = this.#order.value;\n const model = this.#table.model;\n const moving = model.siblingUnits(unit, old).find((s) => sameUnit(s.unit, unit));\n const next = model.nextMove(unit, to, old);\n const columnId = moving?.columns[0];\n if (!next || columnId === undefined) return false;\n const detail = (columnOrder: ColumnOrderState): ColumnOrderChangeDetail =>\n unit.kind === 'group'\n ? { columnOrder, columnId, groupId: unit.id }\n : { columnOrder, columnId };\n const { value, applied } = this.#order.request(next);\n if (applied) {\n for (const pending of this.#appliedReorders.values()) pending.columnOrder = value;\n this.#appliedReorders.set(unitKey(unit), detail(value));\n this.requestUpdate('columnOrder', old);\n } else {\n fire(this, COLUMN_ORDER_CHANGE, detail(value));\n }\n return true;\n }\n\n /** Alt+Shift+Arrow on a column or group header: one step toward the start (-1) or the end (1). */\n #moveByKey(unit: OrderUnit, step: 1 | -1): void {\n const model = this.#table.model;\n // From the latest requested order, so presses can come faster than renders.\n // Positions count the shown columns and groups: hidden columns keep their place.\n const from = model\n .siblingUnits(unit, this.#order.value)\n .findIndex((s) => sameUnit(s.unit, unit));\n const at = this.#colIndexOf(model, unit);\n if (from < 0 || at === undefined) return;\n if (!this.#requestReorder(unit, from + step)) return;\n // The header node moves, which drops its focus: focus it again once rendered.\n this.#focusPending = true;\n this.#announceMove ??= { unit, from: at };\n this.requestUpdate();\n }\n\n /** `aria-colindex` of a column's header, or of a group's first column on its side. */\n #colIndexOf(model: TableModel<T, CellContent>, unit: OrderUnit): number | undefined {\n if (unit.kind === 'column') return model.columns.find((c) => c.id === unit.id)?.colIndex;\n const key = unitKey(unit);\n return model.headerGroups.flat().find((c) => c.key === key)?.colIndex;\n }\n\n /** Tells screen readers where a column or group moved from the keyboard went. */\n #announceMoved(model: TableModel<T, CellContent>, move: { unit: OrderUnit; from: number }): void {\n const { unit } = move;\n const total = String(model.columns.length);\n if (unit.kind === 'column') {\n const view = model.columns.find((c) => c.id === unit.id);\n if (!view || view.colIndex === move.from) return;\n const name = this.#slotText(\n `[role='columnheader'][data-col=\"${CSS.escape(unit.id)}\"] > slot`,\n );\n announce(\n this.ownerDocument,\n `${name || unit.id} moved to column ${String(view.colIndex)} of ${total}`,\n );\n return;\n }\n const key = unitKey(unit);\n const cell = model.headerGroups.flat().find((c) => c.key === key);\n if (!cell || cell.colIndex === move.from) return;\n const name = this.#slotText(`[data-group-key=\"${CSS.escape(key)}\"] slot`);\n const last = cell.colIndex + cell.span - 1;\n const where =\n cell.span === 1\n ? `column ${String(cell.colIndex)}`\n : `columns ${String(cell.colIndex)} to ${String(last)}`;\n announce(this.ownerDocument, `${name || unit.id} moved to ${where} of ${total}`);\n }\n\n /** The text slotted into a header, read through the slot's assigned nodes. */\n #slotText(selector: string): string {\n const slot = this.renderRoot.querySelector(selector);\n return slot instanceof HTMLSlotElement\n ? slot\n .assignedNodes({ flatten: true })\n .map((n) => n.textContent)\n .join('')\n .trim()\n : '';\n }\n\n /** A press on a reorderable column or group header: becomes a drag once the pointer moves. */\n #startReorder(down: PointerEvent): void {\n const cell = down\n .composedPath()\n .find(\n (t): t is HTMLElement =>\n t instanceof HTMLElement && t.getAttribute('role') === 'columnheader',\n );\n if (!cell || !canStartReorder(down, cell)) return;\n const model = this.#table.model;\n let unit: OrderUnit;\n if (cell.dataset.moveCol !== undefined) {\n unit = { kind: 'column', id: cell.dataset.moveCol };\n } else {\n const key = cell.dataset.moveGroup;\n const group = model.headerGroups.flat().find((c) => c.key === key);\n if (group?.groupId === undefined) return;\n unit = { kind: 'group', id: group.groupId, pin: group.pin };\n }\n const scroller = this.#scroller();\n const moving = model.siblingUnits(unit).find((s) => sameUnit(s.unit, unit));\n if (!scroller || !moving) return;\n const key = unitKey(unit);\n const columns = new Set(moving.columns);\n const pin = unit.kind === 'group' ? unit.pin : model.columns.find((c) => c.id === unit.id)?.pin;\n startReorderDrag(cell, down, {\n scroller,\n targetAt: (x) => dropTarget(this.#dropSlots(unit), key, x, this.#direction()),\n scrollArea: () => (pin === undefined ? this.#scrollArea(scroller) : undefined),\n onStart: () => {\n this.#drag = { key, columns, target: undefined };\n this.requestUpdate();\n },\n onTarget: (target) => {\n this.#drag = { key, columns, target };\n this.requestUpdate();\n },\n onDrop: (target) => {\n this.#drag = undefined;\n if (target && this.#requestReorder(unit, target.to)) {\n // The header node moves, which drops its focus: focus it again once rendered.\n if (this.matches(':focus-within')) this.#focusPending = true;\n }\n this.requestUpdate();\n },\n onCancel: () => {\n this.#drag = undefined;\n this.requestUpdate();\n },\n });\n }\n\n /**\n * The rendered headers of what a column or group moves among (see\n * `siblingUnits`), with their positions there. With `virtualizeColumns`, columns\n * out of view have no header and no slot.\n */\n #dropSlots(unit: OrderUnit): DropSlot[] {\n const slots: DropSlot[] = [];\n this.#table.model.siblingUnits(unit).forEach((sibling, index) => {\n const id = unitKey(sibling.unit);\n const cell = this.renderRoot.querySelector(\n sibling.unit.kind === 'column'\n ? `[role='columnheader'][data-col=\"${CSS.escape(sibling.unit.id)}\"]`\n : `[data-group-key=\"${CSS.escape(id)}\"]`,\n );\n if (cell) slots.push({ id, index, rect: cell.getBoundingClientRect() });\n });\n return slots;\n }\n\n /** Where the scrolling columns show: the scroller's inside, less the pinned columns. */\n #scrollArea(scroller: HTMLElement): { left: number; right: number } {\n const width = (side: 'start' | 'end') => pinnedWidth(this.#table.model.columns, side);\n const ltr = this.#direction() === 1;\n const left = scroller.getBoundingClientRect().left + scroller.clientLeft;\n return {\n left: left + width(ltr ? 'start' : 'end'),\n right: left + scroller.clientWidth - width(ltr ? 'end' : 'start'),\n };\n }\n\n /** asc → desc → unsorted, through the controlled/uncontrolled rules. */\n #requestSort(columnId: string): void {\n const next = this.#table.model.nextSorting(columnId);\n if (next) this.#applySorting(next);\n }\n\n /**\n * A plugin's sort: by a column in a direction, or (`null`) cleared if it is by\n * that column. Only sortable columns, and only a change.\n */\n #setSort(columnId: string, direction: SortDirection | undefined): void {\n const view = this.#table.model.columns.find((c) => c.id === columnId);\n if (view?.kind !== 'data' || !view.sortable) return;\n const sorted = view.sorted === false ? undefined : view.sorted;\n if (direction === sorted) return;\n if (direction === undefined) this.#applySorting([]);\n else this.#applySorting([{ id: columnId, desc: direction === 'desc' }]);\n }\n\n /** A new sort order, through the controlled/uncontrolled rules. */\n #applySorting(next: SortState): void {\n const old = this.#sorting.value;\n const { value, applied } = this.#sorting.request(next);\n if (applied) {\n this.#appliedSort = value;\n this.requestUpdate('sorting', old);\n } else {\n fire(this, SORTING_CHANGE, { sorting: value });\n }\n }\n\n /**\n * A data column as plugins see it. Header functions call this on every\n * render, so the views are indexed by id once per new column list.\n */\n #columnInfo(id: string): ColumnInfo | undefined {\n const columns = this.#table.model.allColumns;\n if (this.#columnsById?.of !== columns) {\n this.#columnsById = { of: columns, byId: new Map(columns.map((c) => [c.id, c])) };\n }\n const view = this.#columnsById.byId.get(id);\n if (view?.kind !== 'data') return undefined;\n return {\n id,\n sortable: view.sortable,\n resizable: view.resizable,\n pinnable: view.pinnable,\n hideable: view.hideable,\n pin: view.pin,\n hidden: view.hidden,\n width: view.width,\n sorted: view.sorted === false ? undefined : view.sorted,\n filter: view.filter,\n columnFilter: this.#filters.value[id],\n };\n }\n\n /** The header or cell an event happened in, for plugins. */\n #cellTarget(event: Event): CellTarget | undefined {\n for (const target of event.composedPath()) {\n const cell = gridCell(target);\n const columnId = cell?.dataset.col;\n if (!cell || columnId === undefined) continue;\n const model = this.#table.model;\n const row = gridRowOfCell(cell, layoutOf(model));\n if (!row) return undefined;\n return {\n section: row.section,\n columnId,\n // `0` for the column headers, whatever group rows are above them.\n rowIndex: row.section === 'header' ? 0 : row.index,\n rowId: this.#gridRowId(model, row),\n };\n }\n return undefined;\n }\n\n #observeProbe(): void {\n const probe = this.renderRoot.querySelector('.probe');\n if (!probe) return;\n this.#probeObserver ??= new ResizeObserver(() => {\n this.#measureRowHeight();\n });\n this.#probeObserver.observe(probe);\n }\n\n /** The height of the rows pinned to one side: one row each, or measured with `rowHeight: 'auto'`. */\n #pinnedPx(side: 'top' | 'bottom', layout: RowLayout): number {\n const count = side === 'top' ? layout.top : layout.bottom;\n if (this.rowHeight !== 'auto' || count === 0) return count * this.#rowPx;\n return Math.max(this.#rowMeasure.pinned[side], count * this.#rowPx);\n }\n\n /** The header rows and the pinned rows: the rows in the scroller besides the body. */\n #headerAndPinnedPx(layout: RowLayout): number {\n return (\n layout.header * this.#rowPx + this.#pinnedPx('top', layout) + this.#pinnedPx('bottom', layout)\n );\n }\n\n /**\n * `rowHeight: 'auto'`: reads the heights of the rendered rows, after their\n * content has rendered. Returns whether any changed (an update is requested).\n */\n #measureRows(): boolean {\n const { rows, pinnedChanged } = this.#rowMeasure.read(this.renderRoot);\n const resized = this.#virtual.measureRows(rows);\n if (pinnedChanged) this.requestUpdate();\n return resized || pinnedChanged;\n }\n\n /** Reads the resolved row height, so themes and density change the virtualizer too. */\n #measureRowHeight(): void {\n const probe = this.renderRoot.querySelector('.probe');\n const px = probe?.getBoundingClientRect().height ?? 0;\n if (px > 0 && Math.abs(px - this.#rowPx) > 0.01) {\n this.#rowPx = px;\n this.requestUpdate();\n }\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'argus-table': ArgusTable;\n }\n}\n"],"mappings":"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"}
|