import * as forty_cdk_core from 'forty-cdk/core'; import { WritingDirection } from 'forty-cdk/core'; import * as _angular_core from '@angular/core'; import { InjectionToken, Signal, Type, Provider, TemplateRef, Injector, ElementRef } from '@angular/core'; import * as forty_cdk_table from 'forty-cdk/table'; import * as i1 from 'forty-cdk/drag-drop'; /** ARIA pattern the table renders as. `'table'` is the static structure; `'grid'` / `'treegrid'` add roving + 2D keyboard navigation. */ type TableMode = 'table' | 'grid' | 'treegrid'; /** Row-selection mode for `ForTable`. `'none'` disables selection. */ type TableSelectionMode = 'none' | 'single' | 'multiple'; /** How a row click mutates selection. `'toggle'` flips it; `'replace'` replaces (modifier-aware). */ type TableSelectionBehavior = 'toggle' | 'replace'; /** Aggregate selection state across the table's selectable rows, for the select-all tri-state. */ type TableSelectAllState = 'none' | 'some' | 'all'; /** Sticky placement for a cell: pinned to the start edge (`true`), the end edge (`'end'`), or not sticky (`false`). */ type TableStickyValue = boolean | 'end'; /** * Consumer-facing coordination surface owned by `ForTable`: the resolved ARIA * mode / direction / selection mode, the row counts, and the selection / * expansion commands. * * It carries neither the piece-registration protocol nor the * roving-grid model: how header rows, header cells, data rows, the declarative * body's row count, the virtualization seams and the resized column widths wire * themselves into the root, and where the grid's single tab stop currently * sits, are the library's own business and change without notice. */ interface ForTableContext { /** The resolved ARIA mode; cells derive `role` (`cell` vs `gridcell`) from it, and navigation engages when it is not `'table'`. */ readonly mode: Signal; /** The resolved writing direction (flips ArrowLeft / ArrowRight in `rtl`). */ readonly dir: Signal; /** The active row-selection mode. `'none'` means selection is disabled. */ readonly selectionMode: Signal; /** Returns whether `value` is currently in the selection. */ isRowSelected(value: unknown): boolean; /** Toggles `value` in or out of the selection, respecting `selectionMode`. No-op in `'none'` mode. */ toggleRowSelection(value: unknown): void; /** * Applies a row selection click with optional modifier keys, honoring `selectionBehavior`: * `'toggle'` always flips; `'replace'` replaces (Ctrl/Cmd toggles a single item, * Shift extends a range in multiple mode). */ selectRow(value: unknown, modifiers?: { ctrlKey?: boolean; metaKey?: boolean; shiftKey?: boolean; }): void; /** Aggregate selection state across all selectable rows (`'none'` / `'some'` / `'all'`). */ readonly selectAllState: Signal; /** Selects all selectable rows when not all are selected; clears when all are. No-op outside `'multiple'` mode. */ toggleSelectAll(): void; /** * The resolved true total data-row count for `aria-rowcount` and the virtualized * scroll range, in resolution order: the explicit `[rowCount]` input when set, * else the declarative ``'s dataset length when a body has * registered one, else `undefined` (readers fall back to the rendered row count). */ readonly rowCount: Signal; /** * The count of currently loaded data rows (the declarative `` * dataset length), or `undefined` when no body has registered one (raw-primitive * rendering). Distinct from `rowCount`, which an explicit `[rowCount]` raises to a * server-known total larger than the loaded rows; cross-window navigation clamps * unmounted targets to this so a target beyond the loaded prefix cannot stash a * pending focus move that resolves only when a far page later loads. */ readonly loadedRowCount: Signal; /** * Absolute index of the row that owns the currently roving-focused cell, or `null` * when no cell is focused (or the focused row carries no `virtualIndex`). Read by * `[forTableVirtualized]` to keep the focused row mounted across recycling. */ readonly focusedRowIndex: Signal; /** Whether `value` is in the open-rows set (`treegrid` expansion). */ isRowExpanded(value: unknown): boolean; /** Toggles a parent row's expansion in/out of `[(expanded)]`. No-op when value is undefined. */ toggleRowExpansion(value: unknown): void; } /** * The table's piece-coordination surface: the 2D roving grid model the rows, * cells and header cells resolve their `tabindex` / `data-highlighted` / * keydown through, and the ARIA index arithmetic derived from it. * * **Not** part of {@link ForTableContext} and never exported from * `public-api.ts`. A consumer reads the selection and expansion state off the * token; where the grid's single tab stop currently sits is the library's own * navigation model, refactored without notice. */ interface TablePieceContext { /** * 1-based `aria-rowindex` for the header row in `grid` / `treegrid` mode (always * `1`, since ARIA counts the header row as the grid's first row), or `null` in * `mode="table"` where no row index space exists. */ readonly headerRowIndex: Signal; /** * Offset ARIA adds to every data row's 1-based `aria-rowindex` so the numbering * counts the header row: `1` when a header row participates in the row-index * space (`grid` / `treegrid` mode with a registered header row), else `0`. */ readonly dataRowIndexOffset: Signal; /** Roving `tabindex` (`0` for the single tab stop, `-1` otherwise) for a header cell in grid mode. */ headerCellTabIndex(host: HTMLElement): 0 | -1; /** 0-based index of a header cell host among registered header cells in DOM order, or -1 if not registered. */ headerCellIndexOf(host: HTMLElement): number; /** * Whether the registered header cells form a complete row that joins the body's * roving composite grid (`grid` / `treegrid` mode, header cell count matches the * data column count). Draggable header cells (`[forTableColumnReorder]`) participate * too, so a column-reorderable grid stays a single composite tab stop. `false` in * `table` mode or when no header cells registered. */ readonly headerParticipatesInRoving: Signal; /** 0-based index of a data row host in DOM order, or -1 if not registered. */ rowIndexOf(host: HTMLElement): number; /** Roving `tabindex` (`0` for the single tab stop, `-1` otherwise) for a data cell in grid mode. */ cellTabIndex(host: HTMLElement): 0 | -1; /** Whether a data cell is the currently roving-focused cell (drives `data-highlighted`). */ isCellHighlighted(host: HTMLElement): boolean; /** Promotes a data cell to the active roving cell (called on the cell's `(focus)`). */ activateCell(host: HTMLElement): void; /** Resolves and applies a keydown originating on a data cell: 2D move + focus. */ handleCellKeydown(event: KeyboardEvent, host: HTMLElement): void; /** * Resolves grid navigation for a header cell that yields its host interaction to a * co-located `[forDraggable]`. `[forTableColumnReorder]` calls this from a * capture-phase listener for idle header cells so Arrow / Home / End / Page keys move * roving focus across the composite header + body grid, while Space / Enter fall * through to the draggable's lift. Returns `true` when the key was consumed as a grid * action, `false` otherwise (including outside a participating `grid` / `treegrid`). */ handleHeaderCellKeydown(event: KeyboardEvent, host: HTMLElement): boolean; /** 1-based `aria-posinset` for a row host among its same-level siblings (treegrid). */ rowPosinset(host: HTMLElement): number; /** Total `aria-setsize` of a row host's same-level sibling set (treegrid). */ rowSetsize(host: HTMLElement): number; } /** * The table's internal coordination surface: everything {@link ForTableContext} * publishes plus the {@link TablePieceContext} grid model. * * Never exported from `public-api.ts`. It is the type the pieces read * {@link FOR_TABLE_CONTEXT} at, so a consumer who injects that token gets the * read surface while the pieces get the navigation model. `ForTable` declares * those members TS-`private`, which keeps them out of the emitted `.d.ts` while * `useExisting` still satisfies this contract at runtime. * * Distinct from the **piece-registration** protocol, which is the one surface * that genuinely needs a second token: it lives in `forty-cdk/core` because * `forty-cdk/table-virtualization` registers through it. */ interface TableContext extends ForTableContext, TablePieceContext { } /** * DI token for the table's coordination surface, provided by `[forTable]`. * * Publicly typed as the read surface {@link ForTableContext}, which is the whole of what * the token promises a consumer. The pieces read the same token at an internal type that * adds the roving grid model, so a wrapper re-providing it must alias it to the root: * `{ provide: FOR_TABLE_CONTEXT, useExisting: MyTable }`, where `MyTable` extends * `ForTable`. A value that merely satisfies the declared type resolves too, and is * rejected in dev mode by the first piece to reach the model. */ declare const FOR_TABLE_CONTEXT: InjectionToken; /** * Per-row read surface owned by `ForTableRow`, injected by its data cells. The * cell-registration half lives on {@link TableRowContext}, so no `register*` * member reaches `ForTableRow`'s emitted public type. */ interface ForTableRowContext { /** 0-based index of a cell host within this row in DOM order, or -1 if not registered. */ cellIndexOf(host: HTMLElement): number; /** The active row-selection mode from the root table. */ readonly selectionMode: Signal; /** Whether this row is currently selected. */ readonly selected: Signal; /** Toggles this row's selection. No-op when the row has no `[value]` or mode is `'none'`. */ toggleSelected(): void; } /** * Root of the Table primitive. Sets the ARIA `role` from `mode`, reflects * writing direction, and publishes the `--for-table-header-height` CSS custom * property (driven by a `ResizeObserver` on the first registered header row) * so consumers can `position: sticky` header cells without hard-coding offsets. * * Implements the [WAI-ARIA Table pattern](https://www.w3.org/WAI/ARIA/apg/patterns/table/) * and the [WAI-ARIA Grid pattern](https://www.w3.org/WAI/ARIA/apg/patterns/grid/). * * Use `mode="grid"` or `mode="treegrid"` for interactive grid semantics: a * single-tab-stop roving group with 2D arrow navigation over data cells. * The default `mode="table"` is the static read-only structure. */ declare class ForTable implements ForTableContext { #private; /** * ARIA role emitted on the host. `'table'` is the default static read-only * structure. `'grid'` and `'treegrid'` provide single-tab-stop roving + 2D * arrow navigation over data cells. */ readonly mode: _angular_core.InputSignal; /** * Accessible label for the table. When set, reflected as `aria-label`. * Consumers with a visible caption should prefer pointing native * `aria-labelledby` at it instead; this input is the reactive convenience * hook for cases where no visible label element exists. */ readonly ariaLabel: _angular_core.InputSignal; protected readonly resolvedAriaLabel: Signal; /** * Writing direction. When unset (default `null`), the inherited ambient * direction is resolved from the nearest ancestor carrying a `dir` attribute * (or ``), defaulting to `'ltr'`. An explicit `[dir]` always wins. * The resolved value is reflected to the host `dir` attribute. */ readonly _dirInput: _angular_core.InputSignal; readonly dir: Signal; /** * Explicit override for the true total data-row count (`aria-rowcount` and the * virtualized scroll range). A declarative `` supplies this * automatically from its `rows` dataset length, so bind `[rowCount]` only for a * server-known total larger than the loaded rows; when set it wins over the * body-derived count. Defaults to the body count, else the rendered data-row * count plus the header offset — so an empty non-virtualized grid with a header * row reports `aria-rowcount="1"`, because its rendered rows are all the rows it * has. A **windowed** grid rendering no data row is the one shape whose total is * unknowable, and there `aria-rowcount` reports `-1`, the value ARIA reserves for * an unknown total. An explicit value is emitted verbatim, including `0`. Ignored * in `mode="table"`. */ readonly _rowCountInput: _angular_core.InputSignal; /** * Resolved true total data-row count: the explicit `[rowCount]` input when set, * else the declarative ``'s dataset length, else `undefined` * (readers fall back to the rendered count). Feeds `aria-rowcount`, the * cross-window navigation total, and the virtualizer's count. */ readonly rowCount: Signal; /** * The count of currently loaded data rows (the declarative `` * dataset length), or `undefined` when no body has registered one (raw-primitive * rendering). Distinct from `rowCount`, which an explicit `[rowCount]` raises to a * server-known total larger than the loaded rows; cross-window navigation clamps * unmounted targets to this so a target beyond the loaded prefix cannot stash a * pending focus move that resolves — and steals focus — only when a far page later * loads. */ readonly loadedRowCount: Signal; /** * True total number of columns for `aria-colcount`. Defaults to the rendered * column count (the cells of the first data row that has any, else the registered * header cells) — and when no channel knows the count, `aria-colcount` reports * `-1`, the value ARIA reserves for an unknown total. That is the shape a * virtualized grid with no header row has until its first window resolves: no row * is rendered, so no cell has registered. * * Unlike `aria-rowcount`, that sentinel is **unconditional** — it is not gated on * the grid being windowed. * A non-windowed grid with no registered cell has rows without cells, or no markup * at all: degenerate either way, so there is no state where `0` is the resolved * answer rather than the missing one, and emitting it would re-open exactly the * "`0` reads as a real answer" defect the sentinel exists for. * * An explicit value is emitted verbatim, including `0`. Ignored in `mode="table"`. */ readonly colCount: _angular_core.InputSignal; /** Row selection mode. `'none'` (default) disables selection entirely. */ readonly selectionMode: _angular_core.InputSignal; /** * How a row click changes the selection. `'toggle'` (default) flips the clicked * row. `'replace'` replaces the selection with the clicked row; Ctrl/Cmd-click * toggles a single row and Shift-click extends a range (multiple mode only). */ readonly selectionBehavior: _angular_core.InputSignal; /** * Two-way bindable selected row values (each row's `[value]`). Single mode keeps * 0–1 entries. The implicit `valueChange` fires only on internal mutations * (selector / row click / Space / select-all), never on consumer writes. The * directive infers the row-value type `T` from this binding. */ readonly value: _angular_core.ModelSignal; /** Equality comparator for row values. Defaults to `===`; supply id-based for objects. */ readonly compareWith: _angular_core.InputSignal<(a: T, b: T) => boolean>; /** * Full ordered set of selectable row values (each row's `[value]`), for a * virtualized or server-paged table whose aggregate selection operations must * span rows beyond the rendered window. When `null` (default), the select-all * tri-state, `toggleSelectAll`, and Shift-click range selection compute against * the registered (rendered) rows only. When supplied, they use this set as the * universe of selectable values, so a range can span unmounted rows and the * tri-state reflects the true dataset. Per-row selection is unaffected. */ readonly selectableValues: _angular_core.InputSignal; /** * Two-way bindable open parent-row values (each row's `[value]`), for * `mode="treegrid"`. The implicit `expandedChange` fires only on internal * expand/collapse (ArrowRight/ArrowLeft, `toggleRowExpansion`), never on * consumer writes through `[(expanded)]`. Ignored outside `treegrid` mode. */ readonly expanded: _angular_core.ModelSignal; protected readonly headerSize: Signal; private readonly headerParticipatesInRoving; /** 1-based row offset ARIA applies to data rows because the header row occupies index 1. */ private readonly dataRowIndexOffset; private readonly headerRowIndex; readonly selectAllState: Signal; /** * Absolute index of the row that owns the currently roving-focused cell, or `null` * when no cell is focused (or the focused row carries no `virtualIndex`). Used by * `[forTableVirtualized]` to keep the focused row mounted across recycling. */ readonly focusedRowIndex: Signal; protected readonly rowCountAttr: Signal; protected readonly colCountAttr: Signal; isRowExpanded(value: T): boolean; toggleRowExpansion(value: T): void; private rowPosinset; private rowSetsize; private rowIndexOf; private cellTabIndex; private headerCellTabIndex; private headerCellIndexOf; private isCellHighlighted; private activateCell; isRowSelected(value: T): boolean; toggleRowSelection(value: T): void; selectRow(value: T, modifiers?: { ctrlKey?: boolean; metaKey?: boolean; shiftKey?: boolean; }): void; toggleSelectAll(): void; private handleCellKeydown; /** * Resolves grid navigation for a header cell that yields its host interaction to a * co-located `[forDraggable]` (a `[forTableColumnReorder]` row). `[forTableColumnReorder]` * calls this from a capture-phase listener for idle (not-lifted) header cells, so Arrow / * Home / End / Page keys move roving focus across the composite header + body grid while * Space / Enter still fall through to the draggable's lift. Returns `true` when the key * resolved to a grid action (and was consumed), `false` otherwise. No-op (returns `false`) * outside `grid` / `treegrid` mode or when the header row does not join the composite grid. */ private handleHeaderCellKeydown; static ɵfac: _angular_core.ɵɵFactoryDeclaration, never>; static ɵdir: _angular_core.ɵɵDirectiveDeclaration, "[forTable]", ["forTable"], { "mode": { "alias": "mode"; "required": false; "isSignal": true; }; "ariaLabel": { "alias": "ariaLabel"; "required": false; "isSignal": true; }; "_dirInput": { "alias": "dir"; "required": false; "isSignal": true; }; "_rowCountInput": { "alias": "rowCount"; "required": false; "isSignal": true; }; "colCount": { "alias": "colCount"; "required": false; "isSignal": true; }; "selectionMode": { "alias": "selectionMode"; "required": false; "isSignal": true; }; "selectionBehavior": { "alias": "selectionBehavior"; "required": false; "isSignal": true; }; "value": { "alias": "value"; "required": false; "isSignal": true; }; "compareWith": { "alias": "compareWith"; "required": false; "isSignal": true; }; "selectableValues": { "alias": "selectableValues"; "required": false; "isSignal": true; }; "expanded": { "alias": "expanded"; "required": false; "isSignal": true; }; }, { "value": "valueChange"; "expanded": "expandedChange"; }, never, never, true, never>; } /** * The providers a `[forTable]` root installs: the public * {@link FOR_TABLE_CONTEXT}, aliased to `root`, plus the internal * piece-registration wiring the table's pieces resolve. * * `ForTable` declares its own providers through this helper, so a wrapper that * **subclasses** the root has a single call to keep in step with it. That * matters because Angular does not inherit a directive's `providers`: a subclass * carrying its own `@Directive` metadata replaces the array wholesale, so * re-providing `FOR_TABLE_CONTEXT` alone leaves the registration wiring absent * and every piece — down to the root's own constructor — fails to resolve it. * The internal providers are unnameable outside the library, which is why the * wrapper cannot list them by hand. * * ```ts * providers: provideForTable(MyTable), * ``` * * Wrapping through `hostDirectives: [ForTable]` needs none of this — a host * directive brings its own providers to the element. */ declare function provideForTable(root: Type>): Provider[]; /** * Template context handed to each `[forTableCellDef]` stamped by `ForTableBody`: * the row datum (`let-row`) and its 0-based dataset index (`let-i="index"`). */ interface ForTableCellDefContext { /** The row datum for this cell (`let-row`). */ $implicit: T; /** * 0-based dataset index of the row (`let-i="index"`). In a non-virtualized * table this equals the row's rendered position; under `[forTableVirtualized]` * it is the **absolute** index into the full dataset, not the position within * the rendered window. */ index: number; } /** * Marks the header-cell template of a column definition. Place on an * `` inside a `[forTableColumnDef]`; its content is * stamped into the column's `[forTableHeaderCell]` by `ForTableBody`. */ declare class ForTableHeaderCellDef { /** The captured header-cell template. */ readonly template: TemplateRef; static ɵfac: _angular_core.ɵɵFactoryDeclaration; static ɵdir: _angular_core.ɵɵDirectiveDeclaration; } /** * Marks the data-cell template of a column definition. Place on an * `` inside a `[forTableColumnDef]`; its content is stamped * into the column's `[forTableCell]` for every rendered row, with the row datum * and index exposed through `ForTableCellDefContext`. * * Bind `[forTableCellDefRow]` to the same array passed to `ForTableBody`'s `rows` * to type `let-row` — the input is read only for type inference, never at * runtime. * * When the row type is a discriminated union whose variant members render * through a `[forTableRowDef]` instead of the per-column cells, bind * `[forTableCellDefUnless]` to the same type guard(s) used on those defs' `[when]` * so `let-row` is narrowed to the variant-excluded members (`Exclude`). */ declare class ForTableCellDef { /** The captured data-cell template, typed with `ForTableCellDefContext`. */ readonly template: TemplateRef>; /** * Type-inference hint: bind to the same collection as `ForTableBody`'s `rows` * so `let-row` is typed as the row type. Read only by the compiler; the * directive never touches its value. */ readonly rowType: _angular_core.InputSignal; /** * Type-inference hint: bind the type guard(s) that match the variant rows * rendered by `[forTableRowDef]` (the same predicate used on their `[when]`) so * `let-row` is narrowed to `Exclude` — the members this per-column * template actually receives. Compose several variants into one union guard * (`(r): r is A | B => …`). Read only by the compiler; the directive never * touches its value. Omitting it leaves `let-row` typed as the full `T`. */ readonly excludeType: _angular_core.InputSignal<((row: T, index: number) => row is V) | null>; /** Narrows the template context type for `let-row` under strict template checking. */ static ngTemplateContextGuard(_directive: ForTableCellDef, _context: unknown): _context is ForTableCellDefContext>; static ɵfac: _angular_core.ɵɵFactoryDeclaration, never>; static ɵdir: _angular_core.ɵɵDirectiveDeclaration, "ng-template[forTableCellDef]", never, { "rowType": { "alias": "forTableCellDefRow"; "required": false; "isSignal": true; }; "excludeType": { "alias": "forTableCellDefUnless"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>; } /** * Marks the placeholder/skeleton template of a column definition. Optional; * place on an `` inside a `[forTableColumnDef]`. When * `ForTableBody` is in its `loading` state it stamps this into the column's * `[forTableCell]` for each placeholder row. * * It is the first step of a three-step resolution: a column's own * `[forTablePlaceholderCellDef]` wins, else the body-level * `[forTablePlaceholderCellDefault]`, else the cell stays empty. */ declare class ForTablePlaceholderCellDef { /** The captured placeholder-cell template. */ readonly template: TemplateRef; static ɵfac: _angular_core.ɵɵFactoryDeclaration; static ɵdir: _angular_core.ɵɵDirectiveDeclaration; } /** * Marks the **body-level default** placeholder/skeleton template. Optional and * declared **once per body** (not per column); place on an * `` among the `[forTableColumnDef]`s. * `ForTableBody` stamps it into every displayed column that declares no * `[forTablePlaceholderCellDef]` of its own — most columns of a table share one skeleton * shape, so it is declared once rather than repeated per def. * * Resolution order per column, in both stamping paths (`[loading]` placeholder * rows and `placeholderCells` row variants): the column's own * `[forTablePlaceholderCellDef]` → this default → an empty cell when neither exists. * The template receives no context, exactly like `[forTablePlaceholderCellDef]`. * * It registers itself with the surrounding body's def registry at construction, * so a wrapping component can declare it (or project it) — see * {@link ForTableDefRegistry}. Declared outside any registry it throws. */ declare class ForTablePlaceholderCellDefault { /** The captured default placeholder-cell template. */ readonly template: TemplateRef; constructor(); static ɵfac: _angular_core.ɵɵFactoryDeclaration; static ɵdir: _angular_core.ɵɵDirectiveDeclaration; } /** * Marks the shared drag placeholder for the reorderable columns of a * ``. Optional and declared **once per body** (not per column); * place on an `` among the `[forTableColumnDef]`s. * `ForTableBody` stamps it as every reorderable header cell's * `[forDragPlaceholder]`, so during a pointer reorder the dragged column's slot * shows this template. Omit it to keep drag-drop's default placeholder behaviour. * * It registers itself with the surrounding body's def registry at construction, * so a wrapping component can declare it (or project it) — see * {@link ForTableDefRegistry}. Declared outside any registry it throws. */ declare class ForTableColumnDragPlaceholder { /** The captured placeholder template rendered in a reordered column's slot. */ readonly template: TemplateRef; constructor(); static ɵfac: _angular_core.ɵɵFactoryDeclaration; static ɵdir: _angular_core.ɵɵDirectiveDeclaration; } /** * Declarative definition of a single table column, co-locating its header, * data, and (optional) placeholder templates plus its per-column config in one * place. Place `[forTableColumnDef]` on an `` inside a ``; * the container renders nothing itself — `ForTableBody` harvests the defs and * stamps the header row and data rows from them. * * The def **registers itself** with the surrounding body through DI at * construction (and unregisters when destroyed), so it does not have to be * declared content of the `` element: a preset column component * may declare it in its own view, and a scaffold wrapper may project it into a * body it owns. See {@link ForTableDefRegistry} for both recipes. A def with no * reachable registry throws. * * @example * ```html * * Name * {{ row.name }} * * ``` */ declare class ForTableColumnDef { /** * Column identifier — reflected as `data-column` on the stamped cells and used to key the resize * width var. Mandatory — an unbound def throws in dev mode. */ readonly name: _angular_core.InputSignal; /** * Sticky placement forwarded to both the header cell and every data cell: * `true` (or the bare `sticky` attribute) pins to the start edge, `'end'` to * the end edge, `false` (default) is not sticky. The consumer applies * `position: sticky` + offsets in CSS off the emitted `data-sticky` hook. */ readonly sticky: _angular_core.InputSignalWithTransform; /** * When set, the column's header cell becomes a sortable affordance: `ForTableBody` * applies `[forTableSortHeader]`, derives its direction from the body's `sort` * input, and re-emits activation through the body's `sortChange` output. */ readonly sortable: _angular_core.InputSignalWithTransform; /** * When set, `ForTableBody` renders a `[forTableColumnResizer]` inside the column's * header cell and re-emits its commits through the body's `resizeCommit` output. * Provide `resizeAriaLabel` so the handle is named. Tune the handle per column with * `resizeMin` / `resizeMax` / `resizeStep` / `autoFit` / `fitIncludesHeader`, and * seed / track its width through the body's `[(columnWidths)]`. */ readonly resizable: _angular_core.InputSignalWithTransform; /** * When set, the column's header cell becomes a drag-reorder handle: with at least * one `reorderable` column, `ForTableBody` applies `[forTableColumnReorder]` to the * stamped header row and `[forDraggable]` (with `[dragData]` set to this column's * `name`) to this header cell, and re-emits committed reorders through the body's * `columnReorder` output. Non-reorderable columns stay static (not draggable). * The body bundles `forty-cdk/drag-drop` whether or not a column is `reorderable` * (a measured 18.0 kB raw / 5.1 kB gzip — see the table README's bundle note). */ readonly reorderable: _angular_core.InputSignalWithTransform; /** * Accessible name for the auto-wired resize handle (only meaningful with * `resizable`). Supplied by the consumer so it is localizable; `null` (default) * ships no `aria-label`. */ readonly resizeAriaLabel: _angular_core.InputSignal; /** * Minimum width (px) the auto-wired resize handle clamps to (only meaningful with * `resizable`). Forwarded to the stamped `[forTableColumnResizer]`'s `min`; drives * its `aria-valuemin`. Default `0`. */ readonly resizeMin: _angular_core.InputSignal; /** * Maximum width (px) the auto-wired resize handle clamps to (only meaningful with * `resizable`). Forwarded to the stamped `[forTableColumnResizer]`'s `max`; drives * its `aria-valuemax` (omitted when non-finite). Default `Infinity` (no upper bound). */ readonly resizeMax: _angular_core.InputSignal; /** * Pixels applied per `ArrowLeft` / `ArrowRight` press on the auto-wired resize * handle (only meaningful with `resizable`). Forwarded to the stamped * `[forTableColumnResizer]`'s `step`. Default `10`. */ readonly resizeStep: _angular_core.InputSignal; /** * Whether double-clicking the auto-wired resize handle fits the column to its * widest content (only meaningful with `resizable`). Forwarded to the stamped * `[forTableColumnResizer]`'s `autoFit`. Default `true` — the historical * hardcoded behaviour; set `false` to make the double-click a no-op. */ readonly autoFit: _angular_core.InputSignalWithTransform; /** * Whether header-inclusive auto-fit also accounts for the column header's label * (only meaningful with `resizable` + `autoFit`). Forwarded to the stamped * `[forTableColumnResizer]`'s `fitIncludesHeader`; isolate the header text with a * `[forTableColumnLabel]` inside the `[forTableHeaderCellDef]` template. Default `false`. */ readonly fitIncludesHeader: _angular_core.InputSignalWithTransform; /** * `grid-template-columns` track fragment for this column (e.g. `'160px'`, * `'minmax(160px, 1fr)'`). When unset, `ForTableBody` falls back to the * published `--for-table-col--width` resize var with `fallbackWidth` * (or `minmax(0, 1fr)`) as the var's default, so a resized column drives its * own track. A static `width` **takes precedence** over that resize var — so * leave it unset on a `resizable` column whose width you drive through * `resizeCommit` or the body's `[(columnWidths)]`, otherwise the pinned track * ignores the resized width (the handle still reports `aria-valuenow` but the * column won't move). Dev-mode-guarded against fragments that would escape the * derived track string (see `fallbackWidth`). */ readonly width: _angular_core.InputSignal; /** * `grid-template-columns` track fragment used as the resize-var **fallback** * for a column with no explicit `width` — the track the column renders before * a width is committed or seeded (e.g. `'minmax(120px, 2.5fr)'` for a * weighted, floor-bounded fluid column). Unlike `width` it does not pin the * column, so the resizer (and the body's `[(columnWidths)]`) still drives it * and the first published width snaps the column to px. Ignored when `width` * is set. Defaults to `minmax(0, 1fr)`. * * Any open track vocabulary is accepted (`minmax()`, `fit-content()`, * `calc()`, `clamp()`, `var()`), but in dev mode a fragment that would escape * the derived `grid-template-columns` string throws instead of silently * collapsing the layout: an empty fragment (pass `null` to leave the track * unset), a `;` / `{` / `}` / quote / comment opener, or unbalanced * parentheses — a stray `)` here would close the enclosing `var(` early and * swallow the rest of the track. */ readonly fallbackWidth: _angular_core.InputSignal; /** * Static class(es) applied to this column's stamped `[forTableHeaderCell]`. * `ForTableBody` owns the header cell element, so this is the styling seam a * consumer (or wrapping design system) uses to reach it without scoping CSS to * the body's template internals. `null` (default) adds no class attribute. */ readonly headerClass: _angular_core.InputSignal; /** * Static class(es) applied to this column's stamped `[forTableCell]` on every * data **and** placeholder row. The styling seam for the cell box itself * (padding, truncation, alignment, sticky backgrounds) that `ForTableBody` * owns. Per-datum row styling is out of scope. `null` (default) adds no class * attribute. */ readonly cellClass: _angular_core.InputSignal; /** The column's header-cell template. */ readonly header: _angular_core.Signal; /** The column's data-cell template. */ readonly dataCell: _angular_core.Signal>; /** * The column's optional placeholder-cell template. When absent, `ForTableBody` * falls back to its `[forTablePlaceholderCellDefault]`, then to an empty cell. */ readonly placeholderCell: _angular_core.Signal; constructor(); static ɵfac: _angular_core.ɵɵFactoryDeclaration; static ɵdir: _angular_core.ɵɵDirectiveDeclaration; } /** * Marks the content template of a full-span row variant. Place on an * `` inside a `[forTableRowDef]`; its content is * stamped into a single cell that spans every column of the matched row, with the * row datum and its index exposed through `ForTableCellDefContext`. * * The spanning cell is presentational, so its template must **not** contain * interactive content (buttons, links, form controls) — the variant row stays * out of the grid's single-tab-stop roving order, so nested tabbables become * unreachable — nor a `[forTableCell]`, which would register a cell handle on * the variant row and make the roving grid ragged. * * Bind `[forTableRowCellDefRow]` to the same array passed to `ForTableBody`'s * `rows` to type `let-row` — the input is read only for type inference, never at * runtime. * * When the row type is a discriminated union, also bind `[forTableRowCellDefWhen]` * to the same type guard used on the def's `[when]` so `let-row` is narrowed to * the matched variant member (`V`) instead of staying the full union. */ declare class ForTableRowCellDef { /** The captured row-variant template, typed with `ForTableCellDefContext`. */ readonly template: TemplateRef>; /** * Type-inference hint: bind to the same collection as `ForTableBody`'s `rows` * so `let-row` is typed as the row type. Read only by the compiler; the * directive never touches its value. */ readonly rowType: _angular_core.InputSignal; /** * Type-inference hint: bind the same type guard used on this def's `[when]` * so `let-row` is narrowed to the matched variant member (`V`). Read only by * the compiler; the directive never touches its value. Omitting it leaves * `let-row` typed as the full `T`. */ readonly narrowType: _angular_core.InputSignal<((row: T, index: number) => row is V) | null>; /** Narrows the template context type for `let-row` under strict template checking. */ static ngTemplateContextGuard(_directive: ForTableRowCellDef, _context: unknown): _context is ForTableCellDefContext; static ɵfac: _angular_core.ɵɵFactoryDeclaration, never>; static ɵdir: _angular_core.ɵɵDirectiveDeclaration, "ng-template[forTableRowCellDef]", never, { "rowType": { "alias": "forTableRowCellDefRow"; "required": false; "isSignal": true; }; "narrowType": { "alias": "forTableRowCellDefWhen"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>; } /** * Declarative definition of a row variant for ``. Place * `[forTableRowDef]` on an `` alongside the `[forTableColumnDef]`s and * bind a `[when]` predicate; for every datum the predicate matches, `ForTableBody` * renders this variant instead of the per-column data cells. A def comes in one of * two shapes, and must declare **exactly one** of them: * * - **Full-span** (a `[forTableRowCellDef]` template): the row's single cell spans every * column — group headers, section separators, summary or empty-state rows. It carries * the row's `role` plus `aria-colindex="1"` and an `aria-colspan` equal to the column * count, but registers no cell handle, so roving arrow navigation steps over the row. * - **Placeholder cells** (the `placeholderCells` flag, no `[forTableRowCellDef]`): the row * stamps one cell per displayed column from each column's `[forTablePlaceholderCellDef]` * — skeleton rows for infinite-scroll or paginated tables. These keep the roving grid * rectangular, and are stamped disabled so arrow navigation steps over them. * * Either way the variant row is presentational and non-selectable — its `value` stays `undefined` — * while still occupying a row slot and counting towards `aria-rowindex` / `aria-rowcount`. * * When several defs match a datum the first in DOM order wins; a datum matched by none renders the * standard per-column row. * * Like `[forTableColumnDef]`, the def registers itself with the surrounding body through DI at * construction, so a preset component may declare it in its own view and a scaffold wrapper may * project it into a body it owns — see {@link ForTableDefRegistry}. A def with no reachable * registry throws. * * @example * ```html * * * Name * {{ row.name }} * * * * * * {{ row.group }} * * * * * * ``` */ declare class ForTableRowDef { /** * Predicate selecting which data rows render this variant instead of the * per-column row. Receives the datum and its 0-based dataset index and returns * `true` to render the variant. In a non-virtualized table the index equals * the row's rendered position; under `[forTableVirtualized]` it is the * **absolute** index into the full dataset. Evaluated for every datum on each * change-detection pass, so keep it cheap and free of side effects. * * Mandatory — an unbound def throws in dev mode. */ readonly when: _angular_core.InputSignal<(row: T, index: number) => boolean>; /** * The variant's full-span content template. Present for a full-span def; absent * (and unused) when `placeholderCells` is set. A def must declare exactly one of * a `[forTableRowCellDef]` template or `placeholderCells` — the body validates this and * throws a `[forty-cdk/table]` error otherwise. */ readonly cell: _angular_core.Signal | undefined>; /** * Render this variant's matched rows as **per-column placeholder cells** instead * of a full-span `[forTableRowCellDef]`. Set it (the bare `placeholderCells` attribute) * for interleaved / trailing skeleton rows — infinite-scroll or paginated tables * that keep their loaded rows and append placeholder rows while the next page * loads. The body stamps one `[forTableCell]` per displayed column from that * column's `[forTablePlaceholderCellDef]` template (an empty cell when the column omits * it), exactly like the `loading` state, but stamps the cells disabled so * grid-mode arrow navigation steps over them and the roving grid stays * rectangular. * * A def must declare **exactly one** of a `[forTableRowCellDef]` template or * `placeholderCells`; declaring both or neither throws a `[forty-cdk/table]` * error. */ readonly placeholderCells: _angular_core.InputSignalWithTransform; constructor(); static ɵfac: _angular_core.ɵɵFactoryDeclaration, never>; static ɵdir: _angular_core.ɵɵDirectiveDeclaration, "[forTableRowDef]", never, { "when": { "alias": "when"; "required": false; "isSignal": true; }; "placeholderCells": { "alias": "placeholderCells"; "required": false; "isSignal": true; }; }, {}, ["cell"], never, true, never>; } /** * The def registry a `` renders from — the seam that lets a * **scaffold wrapper** own the table shell while its consumers keep declaring * plain `[forTableColumnDef]` / `[forTableRowDef]` blocks. * * Defs discover their registry through DI at construction, and element DI follows * the **declaration** tree: a def projected through a wrapper's `` is * a child of the wrapper's host, not of the `` inside the * wrapper's template, so it never sees the body's own registry. A wrapper * therefore provides its own registry with `provideForTableDefRegistry()` and * hands it to its inner body through `[defs]`; projected defs register with it, * and the body renders them exactly as if they had been declared inside its own * tags. See the table README for the full recipe. * * A **preset column component** (`` collapsing a * column's header / data templates into one line) needs none of this: the preset * host is declared inside the body's tags, so the def in the preset's view * resolves the body's registry through the element-injector chain. * * The read members here are the whole public surface. How defs wire themselves * into a registry is a separate, unexported protocol, so the library keeps * refactoring it; the only supported implementation is the one * `provideForTableDefRegistry()` installs, and `` rejects any * other value bound to `[defs]`. */ interface ForTableDefRegistry { /** * The `name` of every registered `[forTableColumnDef]`, in document order — the * default column order a bound `` renders. A wrapper can seed * its own `[displayedColumns]` from it (say, to move a fixed action column to * the end) without knowing which defs its consumer projected. * * Reading it resolves each def's `name` input, and a def whose binding is not * written yet is left out, so read it from a template, a `computed`, or an * `afterNextRender` — not from a constructor, where the projected defs' inputs * are not bound yet and the list would come back short. */ readonly columnNames: Signal; } declare const FOR_TABLE_DEF_REGISTRY: InjectionToken; /** * The provider set installing a def registry on a host: the registry itself, the * public {@link FOR_TABLE_DEF_REGISTRY} read token, and the internal * registration protocol the declarative defs resolve. * * `` declares it so defs declared inside its own tags register * with it. A **scaffold wrapper** declares it too, so defs its consumers project * through `` reach a registry at all, and binds * `inject(FOR_TABLE_DEF_REGISTRY)` to its inner body's `[defs]`. */ declare function provideForTableDefRegistry(): Provider[]; /** Payload of `columnReorder`: the move's indices and the resulting column-name order. */ interface TableColumnReorderDescriptor { /** * Previous 0-based index into the **full displayed column order**, counting * non-reorderable columns; feed it (with `to`) to `moveItemInArray` over the * full displayed-columns array. */ from: number; /** * New 0-based index into the **full displayed column order**, counting * non-reorderable columns; feed it (with `from`) to `moveItemInArray` over the * full displayed-columns array. */ to: number; /** * The reorderable columns in their new order, read from each draggable header * cell's `dragData`. Equal to the full displayed order only when every displayed * column is reorderable; otherwise it omits the non-reorderable columns. */ columns: readonly string[]; } /** * Opt-in **column reordering** for `ForTable`, composed over the drag-drop primitive. * * Apply on the `[forTableHeaderRow]` element. It wraps `[forDropList]` (via * `hostDirectives`) so the header cells become a reorderable list, then translates * drag-drop's generic drop into the table-friendly `columnReorder` output. Mark each * `[forTableHeaderCell]` as `[forDraggable]` with `[dragData]` set to the column name. * On a committed drop (pointer or keyboard) it emits the previous / new index (into the * full displayed column order) and the reorderable columns' new order; the consumer * applies it to their own column array. **It never reorders columns itself** (BYO-data). * * The wrapped list defaults to `orientation="horizontal"` (a column reorder is always along * the row axis), so no `orientation` binding is needed. Bind `orientation="vertical"` to * override for the rare case. * * In `mode="grid"` / `mode="treegrid"` the draggable header cells join the table's composite * roving grid as its first row, so a sortable + column-reorderable grid keeps the **single * tab stop** the WAI-ARIA Data Grid pattern calls for: `Tab` enters the grid once, Arrow keys * cross between header and body, and `Space` on a header cell lifts it for keyboard reordering. * It hands its drop-list roving to the grid via `FOR_DROP_LIST_ROVING_DELEGATE` and routes idle * header navigation through the table's grid keyboard handler. * * When a header cell is both sortable (`[forTableSortHeader]`) and reorderable, the two * keyboard activations split along WAI-ARIA lines so a single key never both sorts and lifts: * `Space` lifts the column, `Enter` toggles the sort. The split is enforced via a * `FOR_DRAGGABLE_LIFT_GUARD` that defers `Enter` to the sort header on cells carrying the * `data-sortable` marker — detected by DOM marker, so `forty-cdk/drag-drop` needs no table * import. A reorder-only header (no sort header) still lifts on both `Enter` and `Space`. * * @example * ```html *
* @for (col of columns(); track col) { *
{{ col }}
* } *
* ``` */ declare class ForTableColumnReorder { #private; protected readonly ctx: TableContext; /** * Fires once per committed reorder gesture (pointer drop or keyboard drop) with the * previous / new column index (into the full displayed column order, counting * non-reorderable columns) and the reorderable columns' new order after the move. */ readonly columnReorder: _angular_core.OutputEmitterRef; constructor(); static ɵfac: _angular_core.ɵɵFactoryDeclaration; static ɵdir: _angular_core.ɵɵDirectiveDeclaration; } /** Payload of `resizeCommit`: which column was resized and its committed width (px). */ interface TableResizeDescriptor { column: string; width: number; } /** * Turns a focusable element inside a `[forTableHeaderCell]` into a column-resize * handle. Supports pointer drag (with a dead-zone so a plain click is a no-op) and * `ArrowLeft` / `ArrowRight` keyboard resize, both constrained to `[min, max]`. * Pressing `Escape` (or a `pointercancel`) during a drag reverts the width to where * the gesture started and emits no `resizeCommit`. Being destroyed mid-drag reverts * too, reporting the pre-drag width through the `[widthRevert]` callback because the * `[(width)]` model can no longer emit during teardown. * * On every change it publishes the resolved width as the CSS custom property * `--for-table-col--width` on the table root, so the consumer can apply it * to their layout (`grid-template-columns` in `
` mode, a `` / cell width * in native `` mode). **It never lays out columns itself and never resizes * data** — it owns the affordance, accessibility, and the published width only. * * Reflects `data-resizing` (empty string) while a pointer drag is active. Carries * `role="separator"` with `aria-orientation="vertical"` and live `aria-value*`, * mirroring `[forPaneResizer]`. The consumer supplies `aria-label`. Before the first * gesture, `aria-valuenow` falls back to the header-cell width measured once on mount * (browser-only), so a separator with no `[width]` is never announced without a * current value; an explicit `[width]` always takes precedence. * * In `mode="grid"` / `"treegrid"` it yields its tab stop to the composite roving grid * (`tabindex="-1"`) and is reached via cell-entry (Enter / F2 focuses the first focusable * inside the header cell), so it must sit on a natively-focusable element (a ` * ``` */ declare class ForTableColumnResizer { #private; protected readonly ctx: TableContext; /** Column identity; included in the `resizeCommit` payload and the published CSS var name. */ readonly column: _angular_core.InputSignal; /** * Current column width in pixels. Two-way bindable via `[(width)]`. Acts as both * the controlled value and the base a pointer drag / arrow step is applied to. * When unset, the base for the first gesture is measured from the header cell. * Its implicit `widthChange` fires on every live update (drag tick, arrow press); * `resizeCommit` is the distinct column-aware gesture-end event. */ readonly width: _angular_core.ModelSignal; /** Minimum width in pixels. Default `0`. */ readonly min: _angular_core.InputSignal; /** Maximum width in pixels. Default `Infinity` (no upper bound). */ readonly max: _angular_core.InputSignal; /** Pixels applied per `ArrowLeft` / `ArrowRight` press. Default `10`. */ readonly step: _angular_core.InputSignal; /** * Opt-in size-to-content. When set, double-clicking the handle fits the column to * its widest data-cell content via `fitToContent()`. Unset (default), `dblclick` is * a no-op and the resize behaviour is unchanged. */ readonly autoFit: _angular_core.InputSignalWithTransform; /** * Opt-in: also account for the column header's label width when fitting to content, * so `fitToContent()` sizes to `max(header label, …data cells)` instead of data cells * only. The header label is isolated through a sibling `[forTableColumnLabel]` marker * (the resize handle / sort affordance are excluded). When set without a marker present, * it degrades to data-cells-only. Unset (default), the header is ignored. */ readonly fitIncludesHeader: _angular_core.InputSignalWithTransform; /** * Fires once per resize gesture — at pointer-up after a drag, and on every arrow * press — with the column identity and its committed width. Bind it to persist * the width; live updates during a drag come through `[(width)]` / `widthChange`. */ readonly resizeCommit: _angular_core.OutputEmitterRef; /** * Teardown-only revert channel. Called with the pre-drag width when the handle is * destroyed mid-drag — the column is removed, or `resizable` is toggled off — so the * transient drag width never survives as the consumer's persisted value. On every * other revert path (`Escape`, `pointercancel`) the pre-drag width arrives through * `[(width)]` / `widthChange` as usual and this callback does not fire. * * Bound as a function reference (`[widthRevert]="onRevert"`), not as an event binding: * the `[(width)]` model — like any `output()` on this directive — is already destroyed * when the unmount revert happens, so an emitter-based channel cannot deliver it. */ readonly widthRevert: _angular_core.InputSignal<((descriptor: TableResizeDescriptor) => void) | undefined>; /** `aria-valuemax`, omitted when `max` is non-finite (the default unbounded case). */ protected readonly ariaValueMax: _angular_core.Signal; protected readonly tabindex: _angular_core.Signal<0 | -1>; /** Whether a pointer drag is currently active (drives `data-resizing`). */ protected readonly resizing: _angular_core.Signal; /** * Header-cell width measured once on mount (browser-only). Backs `aria-valuenow` * before any explicit `[width]` so the focusable separator never ships without a * current value on the measured-fallback path; an explicit `[width]` still wins. */ protected readonly measuredWidth: _angular_core.Signal; constructor(); /** * Sizes the column to its content: measures the widest natural width across the * column's data cells (resolved through the table context, browser-only) — and, when * `[fitIncludesHeader]` is set with a sibling `[forTableColumnLabel]` present, the * header label too, so the fit becomes `max(header label, …data cells)`. Clamps the * result to `[min, max]`, applies it as the new `[(width)]`, and emits `resizeCommit`. * Wired to a `dblclick` on the handle when `[autoFit]` is set, and callable * imperatively (e.g. from a column menu) via `exportAs="forTableColumnResizer"`. * Returns the applied width; a no-op returning the current width off the browser. */ fitToContent(): number; protected onKeyDown(event: KeyboardEvent): void; protected onClick(event: MouseEvent): void; static ɵfac: _angular_core.ɵɵFactoryDeclaration; static ɵdir: _angular_core.ɵɵDirectiveDeclaration; } /** Sort direction for a column header. `'none'` means unsorted (no aria-sort emitted). */ type TableSortDirection = 'ascending' | 'descending' | 'none'; /** Payload of `sortChange`: which column changed and its new direction. */ interface TableSortDescriptor { column: string; direction: TableSortDirection; } /** * Turns a `[forTableHeaderCell]` into a sortable affordance that emits `aria-sort` * and fires `sortChange` on activation (click, Enter, Space). The directive is * **self-contained**: it owns only its own `direction` state and does NOT register * with the table context or auto-reset sibling headers. The "one sorted column at a * time" guarantee is the consumer's responsibility — hold a single sort descriptor * signal and derive each header's `direction` from it. Apply this directive on the * same element as `[forTableHeaderCell]`. * * The directive emits its own `tabindex="0"` only in `mode="table"`. In `grid` / * `treegrid` mode the header cell owns the roving composite tab stop, so this directive * emits no `tabindex`; `aria-sort` / `data-sorted` and click / keyboard activation stay * on the cell. When a `[forDraggable]` (column reorder) shares the same host cell — in * either mode — this directive also yields its `tabindex` to the draggable's roving tab * stop so the two never collide on the host attribute, and the keyboard activation splits * along WAI-ARIA lines: `Space` lifts the column for reordering while `Enter` toggles the * sort, so a single key press never both sorts and starts a drag-lift. The draggable is * detected by DOM marker (the `forDraggable` / `forFreeDrag` attribute), not by a * drag-drop value-import. * * While `sortable`, the directive reflects the `data-sortable` marker (a CSS styling * hook, absent when `sortable` is `false`). In `grid` / `treegrid` mode the header cell * reads that marker to defer APG cell entry on `Enter`: `Enter` toggles the sort and * keeps focus on the cell, while `F2` remains the cell-entry key — so a sortable + * resizable header does not both sort and drop focus onto the resize handle. * * Cycle (default `firstClickDirection='ascending'`): `none → ascending → descending → none`. * With `disableClear`: `none → ascending → descending → ascending`. * * `firstClickDirection='descending'` flips the entry pole, so a freshly activated * column starts descending: `none → descending → ascending → none` (and with * `disableClear`: `none → descending → ascending → descending`) — the descending-first * behavior used by single-always-active sort descriptors. * * A `click`, `Space`, or `Enter` originating from an interactive descendant of the * header cell — a stamped `[forTableColumnResizer]` handle, or a consumer-placed * `button` / `a[href]` / `input` / `select` / `textarea` / `summary` / editable * `contenteditable` / role-based control — does not toggle the sort and leaves the * descendant's own activation intact. (A non-native custom handle carrying only * `role="separator"` / `tabindex` is not matched by the shared interactive-descendant * selector, so it would still bubble to sort; the stamped resize handle and the * documented example are native ` * ``` */ declare class ForTableColumnLabel { #private; constructor(); static ɵfac: _angular_core.ɵɵFactoryDeclaration; static ɵdir: _angular_core.ɵɵDirectiveDeclaration; } /** Payload of `rowReorder`: the previous and new row index. */ interface TableRowReorderDescriptor { /** Previous row index (0-based). Absolute (dataset) index under virtualization, else rendered order. */ from: number; /** New row index (0-based). Absolute (dataset) index under virtualization, else rendered order. */ to: number; } /** * Opt-in **row reordering** for `ForTable`, composed over the drag-drop primitive. * * Apply on the rowgroup element that wraps the data rows (`
` in * `
` mode, `
` in native `
* Name * * * Department * *
` mode). It wraps `[forDropList]` (via * `hostDirectives`, vertical by default) so the rows become a reorderable list, then * translates drag-drop's generic drop into the table-friendly `rowReorder` output. Mark * each `[forTableRow]` as `[forDraggable]` with a `[dragData]`. On a committed drop it * emits the previous / new index; the consumer applies the move to their own row array * (e.g. `moveItemInArray`). **It never reorders rows itself** (BYO-data). * * In `mode="grid"` / `mode="treegrid"` the draggable rows **yield their tab stop** to the * table's composite roving grid, keeping the **single tab stop** the WAI-ARIA Data Grid * pattern calls for. Keyboard reordering is therefore initiated from a focused **cell**: * press `Ctrl`/`Cmd`+`Space` on any cell to lift the enclosing row, then `ArrowUp` / * `ArrowDown` (`Home` / `End`, `PageUp` / `PageDown`) move the target, `Space` / `Enter` * drop, and `Escape` / `Tab` cancel. Idle Arrow keys stay grid navigation, and `Space` still * selects the row when a selection mode is set. In the static `mode="table"` the rowgroup * keeps its own draggable-owned tab stop and the plain `Space` / `Enter` lift on a focused * row. * * Under `[forTableVirtualized]`, `rowReorder` emits **absolute** dataset indices so * `moveItemInArray` over the full array moves the right row; a non-virtualized table emits * rendered-order indices. Pointer drag works within the rendered window and reaches rows * beyond it via auto-scroll; keyboard reorder steps the target across the entire dataset, * scrolling unmounted rows into view. Holding **Shift** during a pointer drag engages * **windowed scrub** — the scroll viewport maps onto the whole dataset (top edge → row 0, * bottom edge → the last row) so a single gesture can drop the lifted row at an arbitrary * far row. * * Focus leaving the rowgroup cancels a keyboard lift. A window recycle that briefly blurs * the retained lifted row does not: focus returns to it once the window settles. * * **One gesture at a time.** Pointer and keyboard reorder are mutually exclusive: a live * keyboard lift stands the pointer channel down, and a lift key pressed during a pointer * drag is ignored. * * A pointer press is refused outright when the rowgroup is `disabled`, when a **mouse** press * uses a non-primary button (touch and pen presses keep whatever `button` their engine * reports), or when the pressed row carries no registered `[forDraggable]` or its draggable * is `[dragDisabled]`. * * @example * ```html *
* @for (row of rows(); track row.id) { *
* } *
* ``` */ declare class ForTableRowReorder { #private; protected readonly ctx: TableContext; /** Fires once per committed reorder gesture with the previous / new row index. */ readonly rowReorder: _angular_core.OutputEmitterRef; constructor(); static ɵfac: _angular_core.ɵɵFactoryDeclaration; static ɵdir: _angular_core.ɵɵDirectiveDeclaration; } export { FOR_TABLE_CONTEXT, FOR_TABLE_DEF_REGISTRY, ForTable, ForTableBody, ForTableCell, ForTableCellDef, ForTableColumnDef, ForTableColumnDragPlaceholder, ForTableColumnLabel, ForTableColumnReorder, ForTableColumnResizer, ForTableHeaderCell, ForTableHeaderCellDef, ForTableHeaderRow, ForTablePlaceholderCellDef, ForTablePlaceholderCellDefault, ForTableRow, ForTableRowCellDef, ForTableRowDef, ForTableRowReorder, ForTableRowSelector, ForTableSelectAll, ForTableSortHeader, provideForTable, provideForTableDefRegistry }; export type { ForTableCellDefContext, ForTableContext, ForTableDefRegistry, TableColumnReorderDescriptor, TableMode, TableResizeDescriptor, TableRowActivateEvent, TableRowContextMenuEvent, TableRowReorderDescriptor, TableSelectAllState, TableSelectionBehavior, TableSelectionMode, TableSortDescriptor, TableSortDirection, TableStickyValue };