import * as _angular_core from '@angular/core'; import { InjectionToken, Signal, Provider } from '@angular/core'; import { WritingDirection, RovingTabindex, ListNavigationAction } from 'forty-cdk/core'; import * as forty_cdk_tree from 'forty-cdk/tree'; /** * A visible tree node plus its resolved parent host — the flattened list the root walks. * * Generic over the node value type, which `ForTree` instantiates at its own `T`. */ interface ForTreeVisibleNode { readonly handle: ForTreeItemHandle; readonly parentHost: HTMLElement | null; } /** * Handle a `ForTreeItem` registers with its enclosing container so the root * can flatten the currently-visible nodes, run typeahead, and resolve the * roving-tabindex entry point — all from registered handles plus the * `expanded` set, never from the DOM. */ interface ForTreeItemHandle { /** The `role="treeitem"` host element. */ readonly host: HTMLElement; /** * Stable node value. Reads the `unsetInput` sentinel while the item's * `[value]` binding is still unwritten — the window the synchronous * registration opens, and the reason the item can register at all without * `afterNextRender`. Guard with `isUnset` before the value leaves the read * site (a `descendantsOf` call) or reaches either writable model. */ readonly value: Signal; /** Effective disabled state (own `disabled` OR the root's `disabled`). */ readonly disabled: Signal; /** Whether a `[forTreeItemToggle]` is registered, marking the item a parent. */ readonly expandable: Signal; /** Nested `[forTreeGroup]` container, present only while the item is expanded. */ readonly childContainer: Signal | null>; /** Typeahead text override; empty when the default label text should be used. */ readonly textValue: Signal; /** The `[forTreeItemLabel]` element, used as the default typeahead text source. */ readonly labelEl: Signal; /** Stable host id for the activedescendant focus model (virtualized path). */ readonly id: Signal; /** Absolute index in the flattened visible-node list; `null` outside the virtualized path. */ readonly itemIndex: Signal; /** Resolved tree depth (1-based). Used for flat-space parent/child navigation. */ readonly level: Signal; } /** * Root-only coordination contract owned by `ForTree`. Items derive their * selection / expansion state from it; keyboard and pointer handlers route * navigation, selection, and expansion through it. * * Generic over the node value type. The contract itself defaults to `unknown`, * which is how the token is declared; `ForTree` instantiates it at * its own `T`, the one type that keys `[(value)]`, `[(expanded)]` and * `[forTreeItem][value]`. Node identity is resolved by {@link ForTreeContext.compareWith}. */ interface ForTreeContext { /** Selected node values. Single mode keeps the array at length <= 1. */ readonly value: Signal; /** Open (expanded) parent node values. Always multi — no single mode. */ readonly expanded: Signal; /** * Equality comparator for node values, resolving every identity question the * tree asks — selection and expansion membership, cascade descendants, the * range anchor, and drag-drop drop resolution. Defaults to `===`. */ readonly compareWith: Signal<(a: T, b: T) => boolean>; readonly multiple: Signal; readonly disabled: Signal; readonly orientation: Signal<'horizontal' | 'vertical'>; readonly dir: Signal; readonly selectionFollowsFocus: Signal; /** Selection presentation: `'highlight'` (aria-selected) or `'checkbox'` (aria-checked). */ readonly selectionMode: Signal<'highlight' | 'checkbox'>; /** Whether cascade selection is enabled (checkbox mode only). */ readonly cascade: Signal; readonly roving: RovingTabindex; /** * Length of the flattened visible-node list when virtualizing, `undefined` in * the roving-tabindex path. Setting it (via `[forTree][totalCount]`) switches * the tree to the activedescendant focus model. */ readonly totalCount: Signal; /** Inclusive-exclusive `[start, end)` rendered window; `undefined` when not virtualizing. */ readonly visibleRange: Signal; /** * The active node's id under the activedescendant focus model, `null` in the * roving path. The root reflects it as `aria-activedescendant`; items read it * for `data-highlighted`. */ readonly activeDescendantId: Signal; /** * Called by an item on pointer activation in the virtualized path: moves * `aria-activedescendant` to that item and returns DOM focus to the tree * container. A no-op in the roving path. */ notifyItemClick(itemId: string): void; isExpanded(value: T): boolean; isSelected(value: T): boolean; /** * Tri-state check status of a node in checkbox mode: `'true'` / `'false'`, or * `'mixed'` for a cascade parent with some-but-not-all descendants checked. */ checkState(value: T): 'true' | 'false' | 'mixed'; /** Open or close a node, mutating the `expanded` array immutably. */ setExpanded(value: T, open: boolean): void; /** Single mode replaces the selection; multi mode toggles the value. */ select(value: T): void; /** * Move roving focus from `currentItem` to the next / previous / first / * last enabled node in visible (flattened) order. In single mode with * `selectionFollowsFocus`, the destination is also selected. */ navigate(currentItem: HTMLElement, action: ListNavigationAction): void; /** * Right arrow (LTR): expand a closed parent (focus stays); on an open * parent move focus to its first child; no-op on a leaf. */ expandOrEnter(currentItem: HTMLElement): void; /** * Left arrow (LTR): collapse an open parent (focus stays); otherwise move * focus to the parent node; no-op at a closed root-level node. */ collapseOrLeave(currentItem: HTMLElement): void; /** `*`: expand every sibling parent at the focused node's level. */ expandSiblings(currentItem: HTMLElement): void; /** * Multi mode only. Shift+Arrow: move focus to the next / previous visible * node and toggle its selection. */ extendByArrow(currentItem: HTMLElement, action: 'next' | 'prev'): void; /** * Multi mode only. Shift+Space: select every enabled visible node from the * anchor (set on the last unmodified selection) up to and including * `currentItem`. */ selectRangeToFocused(currentItem: HTMLElement): void; /** * Multi mode only. Ctrl/Cmd+A: select every enabled visible node, or clear * the selection when all visible nodes are already selected. */ selectAll(): void; /** * Forward a keydown to the typeahead helper. When the key is printable, * focuses the first matching visible node and returns `true`. */ handleTypeahead(event: KeyboardEvent): boolean; /** Whether `el` is the first enabled root node — the default roving-tabindex entry point. */ isFirstFocusableItem(el: HTMLElement): boolean; /** * Flattened currently-visible nodes in DOM order, each with its resolved parent host. Exposed for * drag-drop composition (`[forTreeNodeDrag]`). Reflects expansion: collapsed subtrees are absent, * and so is an item whose `[value]` binding is not written yet (see * {@link ForTreeItemHandle.value}) — it folds in on the run that writes it. */ readonly visibleNodes: Signal[]>; } declare const FOR_TREE_CONTEXT: InjectionToken>; /** * Container contract implemented by both `ForTree` (the root, level 1) and * every `ForTreeGroup` (level = parent item level + 1). Items register here * to get their `aria-level` / `aria-posinset` / `aria-setsize`, and the root * walks containers recursively to flatten the visible nodes. */ interface ForTreeContainerContext { readonly level: Signal; readonly items: Signal[]>; registerItem(handle: ForTreeItemHandle): void; unregisterItem(handle: ForTreeItemHandle): void; indexOfHost(el: HTMLElement): number; } declare const FOR_TREE_CONTAINER_CONTEXT: InjectionToken>; /** * Per-item contract provided by `ForTreeItem`, consumed by its label, toggle, * and nested group. A registered toggle marks the item expandable (D4); the * nested group reads `level` and registers itself as the item's child * container. */ interface ForTreeItemContext { readonly value: Signal; readonly level: Signal; readonly expanded: Signal; readonly expandable: Signal; /** Whether this node is in the root's selection set (its `aria-checked` / `aria-selected` state). */ readonly selected: Signal; /** Tri-state checkbox status of this node (`'true'` / `'false'` / `'mixed'`). */ readonly checkState: Signal<'true' | 'false' | 'mixed'>; /** Register a toggle. Presence makes the item expandable (D4). Returns an unregister fn. */ registerToggle(): () => void; /** Set (or clear, on collapse) the nested `[forTreeGroup]` container. */ setChildContainer(container: ForTreeContainerContext | null): void; /** Set (or clear) the `[forTreeItemLabel]` element used for typeahead text. */ setLabel(el: HTMLElement | null): void; /** Toggle expansion. No-op on leaves or when disabled. */ toggle(): void; /** Select / activate the item. No-op when disabled. */ select(): void; /** Move roving focus to the item. No-op when disabled. */ focusItem(): void; } declare const FOR_TREE_ITEM_CONTEXT: InjectionToken>; /** * Headless implementation of the * [WAI-ARIA Tree View pattern](https://www.w3.org/WAI/ARIA/apg/patterns/treeview/). * * A nested tree (`role="tree"` → `treeitem` → `group` → `treeitem`) with * `@if`-driven expansion, roving-tabindex focus management (APG Approach A — * DOM focus rides the `treeitem`), typeahead, RTL arrow mirroring, and full * `aria-level` / `aria-setsize` / `aria-posinset` wiring. * * Two orthogonal models, both keyed by the node value type `T` (default * `string`, inferred from `[(value)]` / `[(expanded)]`): * - `value` — selected node values; single mode (default) keeps 0 or 1 * element, multi mode accumulates. * - `expanded` — open parent node values; always multi (no single mode). * * Single-select consumers read the sole value through {@link ForTree.selected} * instead of unwrapping `value()[0]`. * * @example * ```html *
    * *
* ``` */ declare class ForTree implements ForTreeContext, ForTreeContainerContext { #private; /** * Two-way bindable. Selected node values. Single mode keeps the array at * length <= 1. The `model()` change emitter (`(valueChange)`) fires only on * internal selection changes (node activation or `selectionFollowsFocus` * navigation), never on consumer writes via `[(value)]`. */ readonly value: _angular_core.ModelSignal; /** * Two-way bindable. Open (expanded) parent node values, keyed by the same * node value type as {@link ForTree.value} — the shape `ForTable.expanded` * uses for its open parent rows. Always multi — any number of nodes can be * open. The `model()` change emitter (`(expandedChange)`) fires only on * internal expand / collapse, never on consumer writes via `[(expanded)]`. */ readonly expanded: _angular_core.ModelSignal; /** * Equality comparator for node values, resolving every identity question the * tree asks — selection and expansion membership, cascade descendants, the * range anchor, and drag-drop drop resolution. Defaults to `===`, which is * correct for the default `string` node values; supply an id-based comparator * for object values: `[compareWith]="(a, b) => a.id === b.id"`. */ readonly compareWith: _angular_core.InputSignal<(a: T, b: T) => boolean>; /** * When true, multiple nodes can be selected. Single mode (default) replaces. * * Multi-select range keyboard (Shift+Arrow, Shift+Space, Ctrl/Cmd+A) is not * supported together with virtualization (`totalCount` set): range selection * needs the full set of enabled nodes across the range, which is unavailable * while the list is partially unmounted. Pressing one of those combinations on * a virtualized multi-select tree throws in dev mode. Use * `selectionMode="checkbox"` for multi-select over large virtualized trees. */ readonly multiple: _angular_core.InputSignalWithTransform; /** Disables the whole tree: nodes are not selectable and report `aria-disabled`. */ readonly disabled: _angular_core.InputSignalWithTransform; /** Navigation axis. `'vertical'` (default) uses ArrowUp/Down for movement. */ readonly orientation: _angular_core.InputSignal<"horizontal" | "vertical">; /** * Selection presentation. `'highlight'` (default) keeps the `aria-selected` * contract; `'checkbox'` switches each `treeitem` to `aria-checked` and is * inherently multi-select (each node toggles independently). */ readonly selectionMode: _angular_core.InputSignal<"highlight" | "checkbox">; /** * Enables cascade selection in `selectionMode="checkbox"`: checking or * unchecking a node propagates to all its descendants, and a parent derives * `aria-checked="mixed"` when only some descendants are checked. Ignored in * `'highlight'` mode. Requires {@link ForTree.descendantsOf}. Default `false`. */ readonly cascade: _angular_core.InputSignalWithTransform; /** * Returns the selectable descendant values of a node (excluding the node * itself), used to cascade selection and derive `'mixed'` across collapsed — * possibly unmounted — subtrees. **Required** when {@link ForTree.cascade} is * `true`; the tree throws a `[forty-cdk/tree]` error otherwise. */ readonly descendantsOf: _angular_core.InputSignal<((value: T) => readonly T[]) | undefined>; /** * Total number of nodes in the flattened visible-node list. When set, enables * the virtualized activedescendant focus model. Leave unset (default * `undefined`) for the standard roving-tabindex model. */ readonly totalCount: _angular_core.InputSignalWithTransform; /** * Inclusive-exclusive `[start, end)` index range of the currently rendered * nodes. The virtualizer provides this; the tree uses it to decide whether a * navigation target is in the visible window. */ readonly visibleRange: _angular_core.InputSignal; /** * Optional virtualized-only seam that tells the directive the flattened node * list changed **without** a `totalCount` transition — a same-length re-sort * or refresh. Bind any value that changes on such a refresh (a version * counter, the array reference, a sort-key string); when it changes the * position snapshot rebuilds from empty so navigation never resolves against a * stale off-window entry. Leave unset (default) when the node count always * changes on a refresh. Equivalent to calling {@link ForTree.invalidateSnapshot} * imperatively. */ readonly dataVersion: _angular_core.InputSignal; /** * Emitted when keyboard navigation reaches a node outside the rendered * window. The consumer passes this index to `injectVirtualizer`'s * `scrollToIndex` so the correct node mounts. */ readonly scrollToIndex: _angular_core.OutputEmitterRef; /** * Manual `aria-label` for the tree. Use this when no visible label element * exists; otherwise prefer pointing `aria-labelledby` at one. A `null` * (default) or empty value emits no attribute. */ 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 and swaps the * expand / collapse arrow semantics in RTL. */ readonly _dirInput: _angular_core.InputSignal; readonly dir: Signal; /** * Single-mode only: when true, arrow navigation also selects the focused * node. The default is read from `provideForTreeDefaults` for the * surrounding scope. * * Not supported together with virtualization (`totalCount` set): the * virtualized `aria-activedescendant` focus model resolves off-window * navigation targets asynchronously, so selection cannot follow focus there * without deriving the committed value from a render side effect. * Keyboard-navigating a virtualized tree with it set throws in dev mode, from * the move the combination degrades. */ readonly selectionFollowsFocus: _angular_core.InputSignalWithTransform; /** * Read-only single-select convenience view of {@link value}. Returns the * sole selected value when exactly one node is selected, otherwise `null` * (empty selection, or multiple selections in `multiple` mode). */ readonly selected: Signal; /** Root container hosts level-1 items. */ readonly level: _angular_core.WritableSignal; readonly roving: RovingTabindex; readonly items: Signal[]>; /** * Flattened currently-visible nodes in DOM order, each with its resolved parent host. Exposed for * drag-drop composition (`[forTreeNodeDrag]`). Reflects expansion: collapsed subtrees are absent, * and so is an item whose `[value]` binding is not written yet — it folds in on the run that * writes it. */ readonly visibleNodes: Signal[]>; /** * The active node's `id` when using the activedescendant focus model, * `null` in the roving-tabindex path. The host reflects this as * `aria-activedescendant`; items read it to compute `data-highlighted`. */ readonly activeDescendantId: Signal; /** * Tabindex for the tree host. In the virtualized path the host is always the * single tab stop. In the roving path the host carries no tabindex (items own * their own tab stop). A disabled tree is never tabbable. */ protected readonly hostTabindex: Signal<"0" | null>; /** * Force the virtualized position snapshot to rebuild from empty on the next * fold, discarding stale off-window entries. Call after a same-length refresh * of the flattened node list (a re-sort / reload that keeps `totalCount` * unchanged) when you cannot express the change through the reactive * `[dataVersion]` input. No-op when the tree is not virtualized (`totalCount` * unset). */ invalidateSnapshot(): void; constructor(); isExpanded(value: T): boolean; isSelected(value: T): boolean; /** * Tri-state check status of a node in `selectionMode="checkbox"`. Without * cascade (or in `'highlight'` mode) returns `'true'` / `'false'` by direct * membership. With cascade a parent returns `'true'` when all its descendants * are checked, `'false'` when none are, and `'mixed'` otherwise. * * An item whose `[value]` binding is not written yet reports `'false'`, and * your `descendantsOf` is never called for it. */ checkState(value: T): 'true' | 'false' | 'mixed'; /** * Open or close a node. An item whose `[value]` binding is not written yet is * ignored, so it never enters the `expanded` model. */ setExpanded(value: T, open: boolean): void; /** * Single mode replaces the selection; multi and checkbox modes toggle the * value. An item whose `[value]` binding is not written yet is dropped. */ select(value: T): void; navigate(_currentItem: HTMLElement, action: ListNavigationAction): void; expandOrEnter(_currentItem: HTMLElement): void; collapseOrLeave(_currentItem: HTMLElement): void; expandSiblings(currentItem: HTMLElement): void; extendByArrow(currentItem: HTMLElement, action: 'next' | 'prev'): void; selectRangeToFocused(currentItem: HTMLElement): void; selectAll(): void; handleTypeahead(event: KeyboardEvent): boolean; isFirstFocusableItem(el: HTMLElement): boolean; protected onHostKeyDown(event: KeyboardEvent): void; protected onHostFocusIn(): void; registerItem(handle: ForTreeItemHandle): void; notifyItemClick(itemId: string): void; unregisterItem(handle: ForTreeItemHandle): void; indexOfHost(el: HTMLElement): number; static ɵfac: _angular_core.ɵɵFactoryDeclaration, never>; static ɵdir: _angular_core.ɵɵDirectiveDeclaration, "[forTree]", ["forTree"], { "value": { "alias": "value"; "required": false; "isSignal": true; }; "expanded": { "alias": "expanded"; "required": false; "isSignal": true; }; "compareWith": { "alias": "compareWith"; "required": false; "isSignal": true; }; "multiple": { "alias": "multiple"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "orientation": { "alias": "orientation"; "required": false; "isSignal": true; }; "selectionMode": { "alias": "selectionMode"; "required": false; "isSignal": true; }; "cascade": { "alias": "cascade"; "required": false; "isSignal": true; }; "descendantsOf": { "alias": "descendantsOf"; "required": false; "isSignal": true; }; "totalCount": { "alias": "totalCount"; "required": false; "isSignal": true; }; "visibleRange": { "alias": "visibleRange"; "required": false; "isSignal": true; }; "dataVersion": { "alias": "dataVersion"; "required": false; "isSignal": true; }; "ariaLabel": { "alias": "ariaLabel"; "required": false; "isSignal": true; }; "_dirInput": { "alias": "dir"; "required": false; "isSignal": true; }; "selectionFollowsFocus": { "alias": "selectionFollowsFocus"; "required": false; "isSignal": true; }; }, { "value": "valueChange"; "expanded": "expandedChange"; "scrollToIndex": "scrollToIndex"; }, never, never, true, never>; } /** * A single node in a `ForTree`. Carries the `role="treeitem"`, its ARIA state * (`aria-expanded` only when a `[forTreeItemToggle]` is registered, plus * `aria-selected` / `aria-level` / `aria-setsize` / `aria-posinset`), the * roving tab stop, and the full keyboard interaction. * * Apply on the structural element (typically `
  • `); place a * `[forTreeItemLabel]` inside as the pointer target and a `[forTreeGroup]` * (behind `@if`) for children. */ declare class ForTreeItem implements ForTreeItemContext { #private; /** * Stable identifier for this node, mirrored into `[(value)]` / `[(expanded)]`. * * Mandatory — an unbound item throws in dev mode. * * That seeding is what lets the item register **synchronously**, so its * `aria-posinset` / `aria-setsize` resolve from the container in the creation * pass — including a real server render, where `afterNextRender` never fires * and a deferred registration left the pre-hydration DOM claiming * `aria-posinset="0"` / `aria-setsize="0"`, values WAI-ARIA defines no meaning * for. */ readonly value: _angular_core.InputSignal; /** Disables this node: not selectable, skipped by keyboard navigation. */ readonly disabled: _angular_core.InputSignalWithTransform; /** * Typeahead text source override. Falls back to the `[forTreeItemLabel]` * element's text content when empty (default). */ readonly textValue: _angular_core.InputSignal; /** * Virtualized path: zero-based absolute index in the flattened visible-node list. * Leave unset (default `null`) outside the virtualized path. */ readonly itemIndex: _angular_core.InputSignal; /** * Virtualized path: tree depth of this node (1-based, matching `aria-level`). * When set, overrides the container-derived level in the virtualized path. * Leave unset outside the virtualized path. */ readonly _levelInput: _angular_core.InputSignal; /** * Virtualized path: total number of siblings at this node's level (matching * `aria-setsize`). When set, overrides the container-derived setsize in the * virtualized path. Leave unset outside the virtualized path. */ readonly _setSizeInput: _angular_core.InputSignal; /** * Virtualized path: 1-based position among siblings at this node's level * (matching `aria-posinset`). When set, overrides the container-derived * posinset in the virtualized path. Leave unset outside the virtualized path. */ readonly _posInSetInput: _angular_core.InputSignal; readonly id: _angular_core.Signal; /** True once a `[forTreeItemToggle]` registers, marking the node a parent (D4). */ readonly expandable: _angular_core.Signal; readonly expanded: _angular_core.Signal; readonly selected: _angular_core.Signal; /** True when the root tree is in `'checkbox'` selection mode. */ readonly checkboxMode: _angular_core.Signal; /** * Tri-state checkbox status of this node — `'true'` / `'false'`, or `'mixed'` * when cascade is on and only some descendants are checked. Drives the * checkbox anatomy; meaningful only in `selectionMode="checkbox"`. */ readonly checkState: _angular_core.Signal<"true" | "false" | "mixed">; /** * True when this node is the current keyboard-focused / active candidate. * In the roving-tabindex path tracks DOM focus; in the virtualized * activedescendant path tracks `aria-activedescendant`. Reflected as * `data-highlighted`. */ readonly highlighted: _angular_core.Signal; readonly effectiveDisabled: _angular_core.Signal; /** * Drop-indicator hook for `[forTreeNodeDrag]`: `'before'` / `'after'` when a live drag would * land adjacent to this row, `null` otherwise (and always `null` without a drag coordinator). * Reflected as `data-drop-position`. */ protected readonly _dropPosition: _angular_core.Signal<"before" | "after" | null>; readonly level: _angular_core.Signal; readonly posinset: _angular_core.Signal; readonly setsize: _angular_core.Signal; protected readonly tabindex: _angular_core.Signal<0 | -1>; constructor(); registerToggle(): () => void; setChildContainer(container: ForTreeContainerContext | null): void; setLabel(el: HTMLElement | null): void; toggle(): void; select(): void; focusItem(): void; protected onFocus(): void; protected onPointerDown(event: PointerEvent): void; protected onKeyDown(event: KeyboardEvent): void; static ɵfac: _angular_core.ɵɵFactoryDeclaration, never>; static ɵdir: _angular_core.ɵɵDirectiveDeclaration, "[forTreeItem]", ["forTreeItem"], { "value": { "alias": "value"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "textValue": { "alias": "textValue"; "required": false; "isSignal": true; }; "itemIndex": { "alias": "itemIndex"; "required": false; "isSignal": true; }; "_levelInput": { "alias": "level"; "required": false; "isSignal": true; }; "_setSizeInput": { "alias": "setSize"; "required": false; "isSignal": true; }; "_posInSetInput": { "alias": "posInSet"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>; } /** * Pointer target for a `ForTreeItem` and the default typeahead text source. * Clicking it selects the node and moves roving focus to the `treeitem` * (focus stays on the item, never on the label). Place the * `[forTreeItemToggle]` and the node's visible text inside it. */ declare class ForTreeItemLabel { #private; constructor(); protected onClick(): void; static ɵfac: _angular_core.ɵɵFactoryDeclaration; static ɵdir: _angular_core.ɵɵDirectiveDeclaration; } /** * Optional expand / collapse control inside a `ForTreeItem`. Its mere presence * marks the item as a parent (D4): a `treeitem` emits `aria-expanded` / * `data-state` only when a toggle is registered, so leaves (no toggle) emit * neither — matching the APG "end nodes lack `aria-expanded`" rule. * * Decorative: the enclosing `treeitem` owns `aria-expanded`, so the toggle is * `aria-hidden` and not separately focusable. Clicking it toggles expansion * without selecting the node. */ declare class ForTreeItemToggle { protected readonly buttonType: _angular_core.Signal; protected readonly item: forty_cdk_tree.ForTreeItemContext; constructor(); protected onClick(event: MouseEvent): void; static ɵfac: _angular_core.ɵɵFactoryDeclaration; static ɵdir: _angular_core.ɵɵDirectiveDeclaration; } /** * Nested container (`role="group"`) holding a parent node's child * `ForTreeItem`s. Rendered behind `@if` so a collapsed parent drops its group * entirely. Its `level` is one deeper than the enclosing item, and it * registers itself as that item's child container so the root can flatten the * visible nodes. * * @example * ```html * @if (n.children?.length && isExpanded(n.id)) { *
      * @for (child of n.children; track child.id) { ... } *
    * } * ``` */ declare class ForTreeGroup implements ForTreeContainerContext { #private; readonly items: _angular_core.Signal[]>; readonly level: _angular_core.Signal; constructor(); registerItem(handle: ForTreeItemHandle): void; unregisterItem(handle: ForTreeItemHandle): void; indexOfHost(el: HTMLElement): number; static ɵfac: _angular_core.ɵɵFactoryDeclaration; static ɵdir: _angular_core.ɵɵDirectiveDeclaration; } /** * Defaults inherited by descendant trees in the surrounding injector scope. * Configure with `provideForTreeDefaults` either at the application root or in * any component's `providers` array; partial overrides merge with the parent * scope. */ interface ForTreeDefaults { /** * Single-mode only: when `true`, arrow navigation also selects the focused * node. APG calls this optional and recommends caution — leave `false` * unless the UX truly benefits from selection following focus. */ selectionFollowsFocus: boolean; /** * `[forTreeNodeDrag]` announcement when a node is picked up for drag * (assertive). Override to localize. */ dragAnnounceLift: (label: string) => string; /** * `[forTreeNodeDrag]` announcement on each intermediate move while a node is * lifted (polite). `position` / `total` are 1-based; `parentLabel` is `null` * at the root, so the consumer phrases the root-vs-parent distinction in * their own language. Override to localize. */ dragAnnounceMove: (label: string, parentLabel: string | null, position: number, total: number) => string; /** * `[forTreeNodeDrag]` announcement when a node is committed to its new * position (assertive). `position` / `total` are 1-based; `parentLabel` is * `null` at the root. Override to localize. */ dragAnnounceDrop: (label: string, parentLabel: string | null, position: number, total: number) => string; /** * `[forTreeNodeDrag]` announcement when a lift is cancelled and the node * returns to its origin (assertive). Override to localize. */ dragAnnounceCancel: (label: string) => string; /** * `[forTreeNodeDrag]` announcement when a `canDrop` veto rejects the * attempted drop (assertive). Override to localize. */ dragAnnounceInvalid: (label: string) => string; } /** Token holding the resolved tree defaults for the current scope. */ declare const FOR_TREE_DEFAULTS: _angular_core.InjectionToken; /** * Configures forty-cdk tree defaults for this injector scope. Partial * overrides inherit unspecified keys from the parent scope (or library * defaults at the root). */ declare function provideForTreeDefaults(defaults?: Partial): Provider[]; /** * Visible checkbox surface inside a `ForTreeItem`, used in the tree's * `selectionMode="checkbox"` anatomy. Decorative for assistive tech — the * enclosing `treeitem` owns `aria-checked`, so this element is `aria-hidden` * and not separately focusable. Reflects `data-state="checked" | "unchecked" | * "indeterminate"` for styling. Clicking it toggles the node's selection and * moves roving focus to the node; place a `[forTreeItemCheckboxIndicator]` * inside for the glyph. */ declare class ForTreeItemCheckbox { protected readonly item: forty_cdk_tree.ForTreeItemContext; protected readonly dataState: _angular_core.Signal<"checked" | "indeterminate" | "unchecked">; protected onClick(event: MouseEvent): void; static ɵfac: _angular_core.ɵɵFactoryDeclaration; static ɵdir: _angular_core.ɵɵDirectiveDeclaration; } /** * Optional glyph slot inside a `[forTreeItemCheckbox]`. Shows while the node * is checked or indeterminate (`data-state="checked"` or `"indeterminate"`); * self-hides only when fully unchecked. Hidden state is enforced with an inline * `display: none` (which beats any author `display` rule applied via a class) * in addition to the `hidden` attribute that removes it from the a11y tree. * Mirrors `data-state="checked" | "unchecked" | "indeterminate"` from the item. */ declare class ForTreeItemCheckboxIndicator { protected readonly item: forty_cdk_tree.ForTreeItemContext; protected readonly shown: _angular_core.Signal; protected readonly dataState: _angular_core.Signal<"checked" | "indeterminate" | "unchecked">; static ɵfac: _angular_core.ɵɵFactoryDeclaration; static ɵdir: _angular_core.ɵɵDirectiveDeclaration; } /** * Returns the de-duplicated ancestor values that must be added to a tree's * `expanded` set so every matched node becomes visible. * * Pure and headless: filtering stays consumer-owned — the consumer matches its * own data, re-renders the tree, and feeds its hierarchy through `ancestorsOf`. * Merge the result into `[(expanded)]`: * * ```ts * this.expanded.update((open) => [ * ...new Set([...open, ...expandToReveal(matches, this.ancestorsOf)]), * ]); * ``` * * The matched nodes themselves are not returned — a node is made visible by * expanding its ancestors, so a root-level match contributes nothing. * * @param matches The values of the nodes that matched the current filter. * @param ancestorsOf Returns a node's ancestor values (the node itself excluded); * order is irrelevant and a root node returns an empty list. * @returns The unique ancestor values to expand. Empty when `matches` is empty * or every match is a root. */ declare function expandToReveal(matches: Iterable, ancestorsOf: (value: T) => readonly T[]): readonly T[]; /** * Emitted by `[forTreeNodeDrag]` on a committed move. Carries the tree's node values, * generic over their type `T` (default `string`, matching `ForTree`'s own default). */ interface ForTreeDragDropEvent { /** The moved node's value. */ readonly node: T; /** The node's parent value before the move, or `null` if it was a root node. */ readonly previousParent: T | null; /** The node's parent value after the move, or `null` if dropped at the root level. */ readonly newParent: T | null; /** The node's index among its previous parent's children. */ readonly previousIndex: number; /** The node's index among its new parent's children, post-removal. */ readonly currentIndex: number; } /** * Where the lifted node will land, for rendering an insertion indicator. `null` when idle. */ interface ForTreeDropIndicator { /** The visible row the indicator anchors to (the node value). */ readonly anchor: T; /** Whether the line sits just before or just after the anchor row in DOM order. */ readonly position: 'before' | 'after'; /** Resolved 1-based depth of the drop (mirror of `--for-tree-drop-level`). */ readonly level: number; } /** The coordination contract the handle uses to register with the coordinator. */ interface ForTreeNodeDragContext { /** Register a drag handle element for the item that contains it. */ registerHandle(el: HTMLElement): void; /** Unregister a previously registered handle element. */ unregisterHandle(el: HTMLElement): void; /** Resolved drop indicator while a drag is live; `null` when idle. */ readonly dropIndicator: Signal | null>; } /** InjectionToken for the `[forTreeNodeDrag]` coordinator. */ declare const FOR_TREE_NODE_DRAG_CONTEXT: InjectionToken; /** * Root-level drag-drop coordinator for `ForTree`. Apply on the same element as `[forTree]` to * enable reordering and re-parenting of tree nodes by pointer and keyboard. * * Keyboard: focus a node, then press Ctrl+Space (or Cmd+Space) to lift. While lifted, ArrowUp/Down * move the sibling position, ArrowRight/Left change depth, Space/Enter drops, Escape cancels. * * Pointer: drag any enabled item to a new position; an optional `[forTreeNodeDragHandle]` on an * item constrains the grab area. * * The `(nodeDrop)` output fires once per committed move. Apply `moveTreeNode` in the handler to * update the consumer's data. Provide a `[canDrop]` function to veto specific moves. * * Generic over the tree's node value type `T`, which defaults to `string` like `ForTree`'s own. * Unlike `ForTree`, this directive has no input that carries `T` on its own, so **a tree whose * node values are not `string` must bind `[canDrop]` typed at the node value** — that is the one * channel Angular's template type checker can infer `T` from. Without it `T` stays `string` and * `(nodeDrop)` reports `ForTreeDragDropEvent` while the runtime carries the node value: * a handler typed at the real node fails with `TS2345`, and retyping that handler to `string` to * satisfy the diagnostic is what makes `moveTreeNode` silently return its `roots` unchanged. * A `[canDrop]` that vetoes nothing (`() => true`) is enough to carry the inference. Annotating a * `viewChild` reference recovers `T` only for reading {@link ForTreeNodeDrag.dropIndicator} from * TypeScript; it cannot retype a template binding. */ declare class ForTreeNodeDrag implements ForTreeNodeDragContext { #private; /** Disables all drag interactions on this tree. */ readonly disabled: _angular_core.InputSignalWithTransform; /** * Optional veto callback. Return `false` to reject a specific drop — the node is returned to its * original position and an announcement is made. When omitted, all drops are accepted. */ readonly canDrop: _angular_core.InputSignal<((event: ForTreeDragDropEvent) => boolean) | undefined>; /** Emitted once per committed move. Apply `moveTreeNode` in the handler to update your data. */ readonly nodeDrop: _angular_core.OutputEmitterRef>; protected readonly _dragging: _angular_core.WritableSignal; protected readonly _dropTargetValid: _angular_core.WritableSignal; protected readonly _dropLevel: _angular_core.WritableSignal; /** Resolved drop indicator while a drag is live; `null` when idle. */ readonly dropIndicator: Signal | null>; constructor(); registerHandle(el: HTMLElement): void; unregisterHandle(el: HTMLElement): void; static ɵfac: _angular_core.ɵɵFactoryDeclaration, never>; static ɵdir: _angular_core.ɵɵDirectiveDeclaration, "[forTreeNodeDrag]", ["forTreeNodeDrag"], { "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "canDrop": { "alias": "canDrop"; "required": false; "isSignal": true; }; }, { "nodeDrop": "nodeDrop"; }, never, never, true, never>; } /** * Optional drag handle for a tree node. When placed inside a tree item, it constrains the pointer * grab area — only pointer events originating from within this element start a drag for that item. * Has no effect on the keyboard drag path (Ctrl+Space on the focused item always works). * * @example * ```html *
  • * * File.txt *
  • * ``` */ declare class ForTreeNodeDragHandle { constructor(); static ɵfac: _angular_core.ɵɵFactoryDeclaration; static ɵdir: _angular_core.ɵɵDirectiveDeclaration; } /** * Options for {@link moveTreeNode}. Generic over the consumer's node type `T` and the * tree's node value type `V` (default `string`, matching `ForTree`'s own default). */ interface MoveTreeNodeOptions { /** The move descriptor as emitted by `(nodeDrop)`. Carries the tree's node values. */ readonly event: ForTreeDragDropEvent; /** Stable id of a node — must return the same value used as the tree item `[value]`. */ readonly trackBy: (node: T) => V; /** A node's children, or `undefined` / `[]` for a leaf. */ readonly children: (node: T) => readonly T[] | undefined; /** Returns a copy of `node` with its children replaced. MUST NOT mutate `node`. */ readonly withChildren: (node: T, children: readonly T[]) => T; } /** * Applies a {@link ForTreeDragDropEvent} to a nested, consumer-owned tree, returning a new roots * array. Pure and immutable — never mutates `roots` or any node. Detaches `event.node` from its * current parent and re-inserts it (with its subtree) under `event.newParent` at * `event.currentIndex` (or among the roots when `newParent` is `null`). Returns a shallow copy of * `roots` unchanged when the move is a no-op or invalid (node not found, or `newParent` is the node * itself or one of its descendants). */ declare function moveTreeNode(roots: readonly T[], options: MoveTreeNodeOptions): T[]; export { FOR_TREE_CONTAINER_CONTEXT, FOR_TREE_CONTEXT, FOR_TREE_DEFAULTS, FOR_TREE_ITEM_CONTEXT, FOR_TREE_NODE_DRAG_CONTEXT, ForTree, ForTreeGroup, ForTreeItem, ForTreeItemCheckbox, ForTreeItemCheckboxIndicator, ForTreeItemLabel, ForTreeItemToggle, ForTreeNodeDrag, ForTreeNodeDragHandle, expandToReveal, moveTreeNode, provideForTreeDefaults }; export type { ForTreeContainerContext, ForTreeContext, ForTreeDefaults, ForTreeDragDropEvent, ForTreeDropIndicator, ForTreeItemContext, ForTreeItemHandle, ForTreeNodeDragContext, ForTreeVisibleNode, MoveTreeNodeOptions };