import { KbqTreeModule } from '@koobiq/components/tree';@Component({ selector: 'kbq-tree', exportAs: 'kbqTree' }) class KbqTree extends KbqTreeBase<any> { treeControl = input<C>(); readonly trackBy = input<TrackByFunction<T>>(); dataSource = input<DataSource<T> | Observable<T[]> | T[] | null | undefined>(); get nodeOutlet(): KbqTreeNodeOutlet; readonly nodeDefs: Signal<readonly KbqTreeNodeDef<T>[]>; viewChange: BehaviorSubject<{ start: number; end: number }>; get hasSavedState(): boolean; saveState(): void; clearSavedState(): void; renderNodeChanges( data: T[] | ReadonlyArray<T>, dataDiffer?: IterableDiffer<T>, viewContainer?: ViewContainerRef, parentData?: T ): void; getNodeDef(data: T, i: number): KbqTreeNodeDef<T>; insertNode( nodeData: T, index: number, viewContainer?: ViewContainerRef, parentData?: T ): void; }
useStateSavingboolean Whether the component remembers its state across reloads and restores it on the next render.
Defaults to true, or to whatever KBQ_STATE_SAVING_ENABLED is provided as.
stateSavingKeystring The key the state is persisted under. While it is empty the key is derived from where the
component sits in the document, which moves when the surrounding markup is restructured — an id
on the component or any ancestor pins it just as well as this input does.
treeControlC Controls the expanded state and holds the data nodes of the tree.
trackByTrackByFunction<T> Tracking function that will be used to check the differences in data changes. Used similarly
to ngFor trackBy function. Optimize node operations by identifying a node based on its data
relative to the function to know if a node should be added/removed/moved.
Accepts a function that takes two parameters, index and item.
Views are reused for nodes the function reports as unchanged, which a data source that rebuilds its node objects on every emission — a flattener among them — otherwise cannot get.
Defaults to the trackBy of the tree control, read when the tree initializes and when the data source changes.
dataSourceDataSource<T> | Observable<T[]> | T[] | null | undefined Provides a stream containing the latest data array to render. Influenced by the tree's stream of view window (what dataNodes are currently on screen). Data source can be an observable of data array, or a data array to render.
nodeOutletKbqTreeNodeOutlet Outlet within the tree's template where the data nodes are inserted.
nodeDefsSignal<readonly KbqTreeNodeDef<T>[]> The tree node template for the tree
viewChangeBehaviorSubject<{ start: number; end: number }> Stream containing the latest information on what rows are being displayed on screen. Can be used by the data source to as a heuristic of what data should be provided.
The tree renders every expanded node eagerly, so the window is the whole data set; a data source cannot use it to page or virtualize. Windowing would have to emit a real range from a scroll listener here first.
hasSavedStateboolean Whether state is currently persisted for this tree — restored on init, or written since.
Always false while useStateSaving is unset, and false again after clearSavedState().
saveState()void Persists the values of the currently expanded nodes.
Called for every expansion and collapse a user performs. Expansion driven by the application —
treeControl.expandAll(), or writing to expansionModel — is not persisted; call this to record it.
A no-op while a filter is active: what is expanded then is the result set, not a chosen state.
clearSavedState()void Removes the state persisted for this tree.
Persistence itself stays on — the next expansion is written again.
renderNodeChanges()void Check for changes made in the data and render each change (node added/removed/moved).
getNodeDef()KbqTreeNodeDef<T> Finds the matching node definition that should be used for this node data. If there is only one node definition, it is returned. Otherwise, find the node definition that has a when predicate that returns true with the data. If none return true, return the default node definition.
insertNode()void Create the embedded view for the data node template and place it in the correct index location within the data node view container.
@Component({ selector: 'kbq-tree-node-toggle', exportAs: 'kbqTreeNodeToggle' }) class KbqTreeNodeToggleComponent<T> extends KbqTreeNodeToggleBaseDirective<T> { readonly node = input<T>(); readonly recursive = input<boolean>(false, { alias: 'kbqTreeNodeToggleRecursive' }); disabled = input<boolean>(false); get iconState(): boolean; toggle(event: Event): void; }
kbqTreeNodeToggleRecursiveboolean Whether toggling expands or collapses the whole subtree instead of the node alone.
@Component({ selector: 'kbq-tree-option', exportAs: 'kbqTreeOption' }) class KbqTreeOption<T = any> extends KbqTreeNode<T> implements KbqTitleTextRef { readonly checkboxThirdState = input<boolean>(false); disabled = input<boolean>(false); readonly selectable = input<boolean>(true); showCheckbox = input<boolean | undefined>(); readonly selectionChange = output<KbqTreeOptionChange>(); /** @deprecated */ readonly onSelectionChange = output<KbqTreeOptionChange>(); tree: KbqTreeOptionParent<T> & KbqTreeBase<T>; readonly onFocus: Observable<KbqTreeOptionEvent>; readonly onBlur: Observable<KbqTreeOptionEvent>; preventBlur: boolean; get parentTextElement(): ElementRef<HTMLElement> | undefined; get textElement(): ElementRef<HTMLElement> | undefined; readonly toggleElementDirective: Signal<KbqTreeNodeToggleDirective<any> | undefined>; readonly toggleElementComponent: Signal<KbqTreeNodeToggleComponent<any> | undefined>; readonly pseudoCheckbox: Signal<KbqPseudoCheckbox | undefined>; readonly actionButton: Signal<KbqOptionActionComponent | undefined>; get tooltipTrigger(): KbqTooltipTrigger | undefined; get dropdownTrigger(): KbqDropdownTrigger | undefined; get externalPseudoCheckbox(): boolean; value: any; readonly userInteraction: EventEmitter<void>; selected: boolean; get id(): string; get viewValue(): string; hasFocus: boolean; get isExpandable(): boolean; get level(): number; get toggleElement(): KbqTreeNodeToggleBaseDirective<T> | undefined; get isToggleInDefaultPlace(): boolean; checkboxState: KbqPseudoCheckboxState; updateCheckboxState: () => void; data: T; get isExpanded(): boolean; /** @deprecated */ static mostRecentTreeNode: KbqTreeNode<any> | null; descendantsAllSelected(): boolean; descendantsPartiallySelected(): boolean; updateParentsCheckboxState(node: T): void; toggle(): void; setSelected(selected: boolean): void; focus(focusOrigin?: FocusOrigin): void; blur(): void; select(setFocus?: boolean): void; deselect(): void; onKeydown($event: any): void; selectViaInteraction($event?: KeyboardEvent | MouseEvent): void; emitSelectionChangeEvent(): void; getHostElement(): HTMLElement; markForCheck(): void; }
disabledboolean Whether the option is disabled: through its own input, the tree, or the tree control's isDisabled.
selectableboolean Whether the option can be selected by user interaction (click, keyboard, select all).
A non-selectable option remains focusable, navigable and expandable.
Programmatic selection (setSelected, select, value accessor) is not affected.
Options that are not rendered (e.g. collapsed) are not checked by "select all".
showCheckboxboolean | undefined Whether the option renders a pseudo-checkbox. Falls back to the tree's own mode until bound.
selectionChangeKbqTreeOptionChange Emits whenever the selected state of the option changes.
onSelectionChangeKbqTreeOptionChange Use selectionChange instead. Will be removed in 22.0.0.
onFocusObservable<KbqTreeOptionEvent> Emits when the option takes focus.
onBlurObservable<KbqTreeOptionEvent> Emits when the option loses focus.
parentTextElementElementRef<HTMLElement> | undefined Container of the option text, measured by kbq-title.
tooltipTriggerKbqTooltipTrigger | undefined Tooltip trigger projected into the option.
dropdownTriggerKbqDropdownTrigger | undefined Dropdown trigger projected into the option.
levelnumber The "select all" row sits above the tree at root depth; getLevel has no node to resolve for it.
mostRecentTreeNodeKbqTreeNode<any> | null The most recently created KbqTreeNode, across every tree on the page.
Kept for backwards compatibility only — the tree hands a node its data through
KbqTreeBase.registerNode, which is scoped to the tree that owns the node. Will be removed in 22.0.0.
@Component({ selector: 'kbq-tree-selection', exportAs: 'kbqTreeSelection' }) class KbqTreeSelection<T = any, K = T> extends KbqTreeBase<T, FlatTreeControl<T, K>> implements ControlValueAccessor { readonly ariaLabel = input<string>(undefined, { alias: 'aria-label' }); readonly ariaLabelledby = input<string>(undefined, { alias: 'aria-labelledby' }); autoSelect = input<boolean | undefined>(); multiple = input<KbqMultipleInput | undefined>(); noUnselectLast = input<boolean | undefined>(); typeAhead = input<boolean>(true); readonly selectAllToggle = input<boolean>(false); selectAll = model<boolean>(false); disabled = input<boolean | undefined>(); selectAllHandler = input<((event: KeyboardEvent, tree: KbqTreeSelection<T, K>) => void) | undefined>(); treeControl = input<C>(); readonly trackBy = input<TrackByFunction<T>>(); dataSource = input<DataSource<T> | Observable<T[]> | T[] | null | undefined>(); readonly navigationChange = output<KbqTreeNavigationChange<KbqTreeOption<T>, T, K>>(); /** @deprecated */ readonly onSelectAll = output<KbqTreeSelectAllEvent<KbqTreeOption<T>, T, K>>(); inSelect: boolean; renderedOptions: QueryList<KbqTreeOption<T>>; keyManager: FocusKeyManager<KbqTreeOption<T>>; selectionModel: SelectionModel<T>; resetFocusedItemOnBlur: boolean; userTabIndex: number | null; optionShouldHoldFocusOnBlur: boolean; ownsKeyboard: boolean; readonly selectAllOption: Signal<KbqTreeOption<T> | undefined>; get unorderedOptions(): QueryList<KbqTreeOption<T>>; readonly selectionChange: EventEmitter<KbqTreeSelectionChange<KbqTreeOption<T>, T, K>>; readonly copyChange: EventEmitter<KbqTreeCopyEvent<KbqTreeOption<T>, T, K>>; /** @deprecated */ readonly onCopy: EventEmitter<KbqTreeCopyEvent<KbqTreeOption<T>, T, K>>; get optionFocusChanges(): Observable<KbqTreeOptionEvent>; get optionBlurChanges(): Observable<KbqTreeOptionEvent>; multipleMode: MultipleMode | null; get allOptionsSelected(): boolean; get selectAllState(): KbqPseudoCheckboxState; get showCheckbox(): boolean; get isEmpty(): boolean; get nodesCount(): number; get nodeOutlet(): KbqTreeNodeOutlet; readonly nodeDefs: Signal<readonly KbqTreeNodeDef<T>[]>; viewChange: BehaviorSubject<{ start: number; end: number }>; get hasSavedState(): boolean; initializeForEmbedding(selectionModel: SelectionModel<T>): void; focus($event: any): void; blur(): void; onKeyDown(event: KeyboardEvent): void; handleKeydown(event: KeyboardEvent): void; selectAllOptions(allowDeselect?: boolean): void; copyActiveOption(event: KeyboardEvent): void; setStateChildren(option: KbqTreeOption<T>, state: boolean): void; saveState(): void; clearSavedState(): void; getNodeDef(data: T, i: number): KbqTreeNodeDef<T>; insertNode( nodeData: T, index: number, viewContainer?: ViewContainerRef, parentData?: T ): void; }
aria-labelstring Accessible name of the tree. Set it whenever the tree has no visible label of its own; a tree
embedded in a kbq-tree-select is labelled by the select instead.
aria-labelledbystring Id of the element that labels the tree, for when the label is rendered next to it.
autoSelectboolean | undefined Whether clicking a node clears the rest of the selection. Defaults to true, and to false for
multiple="checkbox".
Assigning it — from a template binding or imperatively, as KbqTreeSelect does — replaces the
derived default, so a later multiple change leaves the value alone.
multipleKbqMultipleInput | undefined Selection mode of the tree.
checkbox renders a checkbox in every node, keyboard selects without one. A bare multiple and
true both mean checkbox; single, false and an absent attribute mean single selection. The mode
can be changed at any time — narrowing it to single selection keeps the first selected node and
reports the shortened value through the ControlValueAccessor.
A tree rendered inside a kbq-tree-select shares its SelectionModel with the select, so the
select decides how many nodes may be selected: switching this input between single and multiple
selection there throws. Switching between checkbox and keyboard only changes the presentation
and is allowed.
The getter reports whether more than one node can be selected; read multipleMode for the mode
itself.
noUnselectLastboolean | undefined Whether the last selected node can be deselected.
Derived from the mode until assigned, like autoSelect.
typeAheadboolean Whether typing printable characters moves the focus to the next option whose label starts with them. On by default.
Turn it off wherever the tree shares its keystrokes with a text field: an embedder such as
KbqTreeSelect routes everything the user types — the search query included — into this key
manager, and type-ahead would move the active option out from under the query.
selectAllToggleboolean When true, a repeated Ctrl/Cmd+A deselects all options. Off by default (Ctrl+A only selects).
selectAllboolean Whether to render the "select all" master checkbox above the nodes. Multiple selection only.
Enabling it also makes Ctrl/Cmd + A a two-way toggle, so the shortcut and the checkbox never
disagree (selectAllToggle is implied).
disabledboolean | undefined Whether the tree is disabled, bound with [disabled] or set by a form control.
selectAllHandler((event: KeyboardEvent, tree: KbqTreeSelection<T, K>) => void) | undefined Function for handling the combination Ctrl + A (select all). By default, the internal handler is used, which toggles the selection of all non-disabled, selectable options.
useStateSavingboolean Whether the component remembers its state across reloads and restores it on the next render.
Defaults to true, or to whatever KBQ_STATE_SAVING_ENABLED is provided as.
stateSavingKeystring The key the state is persisted under. While it is empty the key is derived from where the
component sits in the document, which moves when the surrounding markup is restructured — an id
on the component or any ancestor pins it just as well as this input does.
localeOverridesKbqPartialLocaleData | undefined Localized strings for this element and its subtree, keyed by locale section. Every key is optional at every depth.
treeControlC Controls the expanded state and holds the data nodes of the tree.
trackByTrackByFunction<T> Tracking function that will be used to check the differences in data changes. Used similarly
to ngFor trackBy function. Optimize node operations by identifying a node based on its data
relative to the function to know if a node should be added/removed/moved.
Accepts a function that takes two parameters, index and item.
Views are reused for nodes the function reports as unchanged, which a data source that rebuilds its node objects on every emission — a flattener among them — otherwise cannot get.
Defaults to the trackBy of the tree control, read when the tree initializes and when the data source changes.
dataSourceDataSource<T> | Observable<T[]> | T[] | null | undefined Provides a stream containing the latest data array to render. Influenced by the tree's stream of view window (what dataNodes are currently on screen). Data source can be an observable of data array, or a data array to render.
onSelectAllKbqTreeSelectAllEvent<KbqTreeOption<T>, T, K> Use selectAllChange instead. Will be removed in 22.0.0.
inSelectboolean Whether this tree-selection is rendered inside a select panel (enables option
hover-to-focus). Defaults to detecting a wrapping KbqFormField, and is forced to true
by the host KbqTreeSelect so hover works even when the tree-select has no form-field
wrapper (e.g. the filter-bar pipes render the tree-select bare).
selectionModelSelectionModel<T> Model backing the selection.
The instance is replaced whenever multiple changes the multiplicity, because CDK freezes that
flag at construction. Subscribe to selectionChange rather than to selectionModel.changed:
a subscription taken on the model directly is left behind on the discarded instance.
T is the type of the data nodes, inferred from [treeControl] in a template. A query names it:
viewChild.required<KbqTreeSelection<Node>>(KbqTreeSelection), and a tree whose control has a trackBy
names the key type too: KbqTreeSelection<Node, string>.
ownsKeyboardboolean Whether the tree acts on keyboard input itself. Turned off by an embedding host that owns the
keyboard, such as KbqTreeSelect.
selectAllOptionSignal<KbqTreeOption<T> | undefined> Reference to the built-in "select all" row, rendered only while selectAll is on.
selectionChangeEventEmitter<KbqTreeSelectionChange<KbqTreeOption<T>, T, K>> Emits when the selection changes. A stream rather than an output(): KbqTreeSelect pipes it with rxjs.
copyChangeEventEmitter<KbqTreeCopyEvent<KbqTreeOption<T>, T, K>> Emits when the active option is copied with Ctrl/Cmd + C. Subscribing replaces the built-in
clipboard handler, so the event has to stay an EventEmitter: the decision is made by reading
observed, which OutputEmitterRef does not have. A template listener subscribes to it through
the output below.
onCopyEventEmitter<KbqTreeCopyEvent<KbqTreeOption<T>, T, K>> Use copyChange instead. Will be removed in 22.0.0.
optionFocusChangesObservable<KbqTreeOptionEvent> Emits when an option of the tree takes focus.
optionBlurChangesObservable<KbqTreeOptionEvent> Emits when an option of the tree loses focus.
multipleModeMultipleMode | null Resolved selection mode, or null when only one node can be selected.
allOptionsSelectedboolean Whether every node "select all" can act on is selected.
selectAllStateKbqPseudoCheckboxState State of the "select all" master checkbox.
nodesCountnumber Number of real, data-backed nodes currently rendered — unlike renderedOptions.length, never
includes the "select all" row, which is appended to renderedOptions on its own, later-processed
reactive pass and would otherwise make a consumer's own node count race against that pass.
nodeOutletKbqTreeNodeOutlet Outlet within the tree's template where the data nodes are inserted.
nodeDefsSignal<readonly KbqTreeNodeDef<T>[]> The tree node template for the tree
viewChangeBehaviorSubject<{ start: number; end: number }> Stream containing the latest information on what rows are being displayed on screen. Can be used by the data source to as a heuristic of what data should be provided.
The tree renders every expanded node eagerly, so the window is the whole data set; a data source cannot use it to page or virtualize. Windowing would have to emit a real range from a scroll listener here first.
hasSavedStateboolean Whether state is currently persisted for this tree — restored on init, or written since.
Always false while useStateSaving is unset, and false again after clearSavedState().
initializeForEmbedding()void Rebuilds the tree around a selection model owned by an embedding host, such as KbqTreeSelect.
The host has to take the model over before the tree starts reacting to it, and re-running
ngAfterContentInit() is not a way to do that: neither unorderedOptions nor renderedOptions is
ever re-created, so a second run would only leave a second set of subscribers on both — every options
change handled twice, and the whole option sweep run twice per emission. Only the subscription that
depends on the model has to move, which is exactly what bindSelectionModel does.
onKeyDown()void Host listener for keyboard input.
Does nothing while an embedding host owns the keyboard — KbqTreeSelect routes every key through
its own panel handler and calls back into handleKeydown for the parts it delegates, so without
this guard the same event would be acted on twice.
handleKeydown()void Runs the tree's own keyboard handling, whether or not it owns the keyboard.
saveState()void Persists the values of the currently expanded nodes.
Called for every expansion and collapse a user performs. Expansion driven by the application —
treeControl.expandAll(), or writing to expansionModel — is not persisted; call this to record it.
A no-op while a filter is active: what is expanded then is the result set, not a chosen state.
clearSavedState()void Removes the state persisted for this tree.
Persistence itself stays on — the next expansion is written again.
getNodeDef()KbqTreeNodeDef<T> Finds the matching node definition that should be used for this node data. If there is only one node definition, it is returned. Otherwise, find the node definition that has a when predicate that returns true with the data. If none return true, return the default node definition.
insertNode()void Create the embedded view for the data node template and place it in the correct index location within the data node view container.
Rendering core of the tree.
Originally forked from @angular/cdk/tree and maintained independently since: the node/outlet
contract, the option-based selection model and the filtering pipeline have all diverged, so
@angular/cdk/tree is deliberately not a dependency of this package and upstream fixes have to be
ported by hand.
C narrows the tree control a concrete tree accepts, and so the type its treeControl binding is checked against.
The bound leaves out expansionModel and trackBy, the members typed by the control's key, so that it admits
a control of any key type: the model makes a control invariant in that type.
@Directive() class KbqTreeBase<T, C extends Omit<TreeControl<T>, 'expansionModel' | 'trackBy'> = TreeControl<T>> implements CollectionViewer { treeControl = input<C>(); readonly trackBy = input<TrackByFunction<T>>(); dataSource = input<DataSource<T> | Observable<T[]> | T[] | null | undefined>(); get nodeOutlet(): KbqTreeNodeOutlet; readonly nodeDefs: Signal<readonly KbqTreeNodeDef<T>[]>; viewChange: BehaviorSubject<{ start: number; end: number }>; get hasSavedState(): boolean; saveState(): void; clearSavedState(): void; renderNodeChanges( data: T[] | ReadonlyArray<T>, dataDiffer?: IterableDiffer<T>, viewContainer?: ViewContainerRef, parentData?: T ): void; getNodeDef(data: T, i: number): KbqTreeNodeDef<T>; insertNode( nodeData: T, index: number, viewContainer?: ViewContainerRef, parentData?: T ): void; }
treeControlC Controls the expanded state and holds the data nodes of the tree.
trackByTrackByFunction<T> Tracking function that will be used to check the differences in data changes. Used similarly
to ngFor trackBy function. Optimize node operations by identifying a node based on its data
relative to the function to know if a node should be added/removed/moved.
Accepts a function that takes two parameters, index and item.
Views are reused for nodes the function reports as unchanged, which a data source that rebuilds its node objects on every emission — a flattener among them — otherwise cannot get.
Defaults to the trackBy of the tree control, read when the tree initializes and when the data source changes.
dataSourceDataSource<T> | Observable<T[]> | T[] | null | undefined Provides a stream containing the latest data array to render. Influenced by the tree's stream of view window (what dataNodes are currently on screen). Data source can be an observable of data array, or a data array to render.
nodeOutletKbqTreeNodeOutlet Outlet within the tree's template where the data nodes are inserted.
nodeDefsSignal<readonly KbqTreeNodeDef<T>[]> The tree node template for the tree
viewChangeBehaviorSubject<{ start: number; end: number }> Stream containing the latest information on what rows are being displayed on screen. Can be used by the data source to as a heuristic of what data should be provided.
The tree renders every expanded node eagerly, so the window is the whole data set; a data source cannot use it to page or virtualize. Windowing would have to emit a real range from a scroll listener here first.
hasSavedStateboolean Whether state is currently persisted for this tree — restored on init, or written since.
Always false while useStateSaving is unset, and false again after clearSavedState().
saveState()void Persists the values of the currently expanded nodes.
Called for every expansion and collapse a user performs. Expansion driven by the application —
treeControl.expandAll(), or writing to expansionModel — is not persisted; call this to record it.
A no-op while a filter is active: what is expanded then is the result set, not a chosen state.
clearSavedState()void Removes the state persisted for this tree.
Persistence itself stays on — the next expansion is written again.
renderNodeChanges()void Check for changes made in the data and render each change (node added/removed/moved).
getNodeDef()KbqTreeNodeDef<T> Finds the matching node definition that should be used for this node data. If there is only one node definition, it is returned. Otherwise, find the node definition that has a when predicate that returns true with the data. If none return true, return the default node definition.
insertNode()void Create the embedded view for the data node template and place it in the correct index location within the data node view container.
@Directive({ selector: 'kbq-tree-node', exportAs: 'kbqTreeNode' }) class KbqTreeNode<T> implements IFocusableOption { tree: KbqTreeBase<T, TreeControl<T, T>>; data: T; get isExpanded(): boolean; get level(): number; /** @deprecated */ static mostRecentTreeNode: KbqTreeNode<any> | null; focus(): void; }
mostRecentTreeNodeKbqTreeNode<any> | null The most recently created KbqTreeNode, across every tree on the page.
Kept for backwards compatibility only — the tree hands a node its data through
KbqTreeBase.registerNode, which is scoped to the tree that owns the node. Will be removed in 22.0.0.
Data node definition for the KbqTree. Captures the node's template and a when predicate that describes when this node should be used.
@Directive({ selector: '[kbqTreeNodeDef]' }) class KbqTreeNodeDef<T> { readonly data = input<T>(undefined, { alias: 'kbqTreeNode' }); @Input('kbqTreeNodeDefWhen') when: (index: number, nodeData: T) => boolean; template: TemplateRef<any>; }
kbqTreeNodeDefWhen(index: number, nodeData: T) => boolean Function that should return true if this node template should be used for the provided node data and index. If left undefined, this node will be considered the default node template to use when no other when functions return true for the data. For every node, there must be at least one when function that passes or an undefined to default.
@Directive({ selector: '[kbqTreeNodeOutlet]' }) class KbqTreeNodeOutlet { viewContainer: ViewContainerRef; }
@Directive({ selector: '[kbqTreeNodePadding]', exportAs: 'kbqTreeNodePadding' }) class KbqTreeNodePadding<T> { readonly indent = input<number | string>(12, { alias: 'kbqTreeNodePaddingIndent' }); level: number; get leftPadding(): number; get leftPaddingForFirstLevel(): number; get indentUnits(): string; withIcon: boolean; iconWidth: number; paddingIndent(): string | null; }
kbqTreeNodePaddingIndentnumber | string Indentation added per nesting level. Accepts a bare number (px) or a value with CSS units.
indentUnitsstring CSS units used for the indentation value.
iconWidthnumber Horizontal room a toggle takes up in a row: its own 16px box plus the option's 8px gap. A node
without a toggle reserves the same amount so its content lines up with a sibling that has one —
which is why widening the toggle itself pushes every branch row out of line.
@Directive({ selector: '[kbq-tree-node-toggle], [kbqTreeNodeToggle]', exportAs: 'kbqTreeNodeToggle' }) class KbqTreeNodeToggleDirective<T> extends KbqTreeNodeToggleBaseDirective<T> { readonly node = input<T>(); readonly recursive = input<boolean>(false, { alias: 'kbqTreeNodeToggleRecursive' }); disabled = input<boolean>(false); get iconState(): boolean; toggle(event: Event): void; }
kbqTreeNodeToggleRecursiveboolean Whether toggling expands or collapses the whole subtree instead of the node alone.
Base tree control. It has basic toggle/expand/collapse operations on a single data node.
abstract class BaseTreeControl<T, K = T> implements TreeControl<T, K> { dataNodes: T[]; expansionModel: SelectionModel<K>; trackBy?: (dataNode: T) => K; filterModel: SelectionModel<T>; filterValue: BehaviorSubject<T[] | string | null>; getLevel: (dataNode: T) => number; isExpandable: (dataNode: T) => boolean; getChildren: (dataNode: T) => Observable<T[]>; abstract getDescendants(dataNode: T): T[]; abstract expandAll(): void; toggle(dataNode: T): void; expand(dataNode: T): void; collapse(dataNode: T): void; isExpanded(dataNode: T): boolean; toggleDescendants(dataNode: T): void; collapseAll(): void; expandDescendants(dataNode: T): void; collapseDescendants(dataNode: T): void; protected expansionKey(dataNode: T): K; }
expansionModelSelectionModel<K> A selection model with multi-selection to track expansion status: it holds the key of every expanded node.
trackBy(dataNode: T) => K Gives the key a data node is expanded by. Without it the node object is its own key, so a node rebuilt as a new object — as a flattener does whenever its data changes — comes back collapsed.
Set it before anything is expanded: keys stored under another function no longer match.
getLevel(dataNode: T) => number Get depth of a given data node, return the level number. This is for flat tree node.
isExpandable(dataNode: T) => boolean Whether the data node is expandable. Returns true if expandable. This is for flat tree node.
getChildren(dataNode: T) => Observable<T[]> Gets a stream that emits whenever the given data node's children change.
getDescendants()T[] Gets a list of descendent data nodes of a subtree rooted at given data node recursively.
expandAll()void Expands all data nodes in the tree.
toggle()void Toggles one single data node's expanded/collapsed state.
expand()void Expands one single data node.
collapse()void Collapses one single data node.
isExpanded()boolean Whether a given data node is expanded or not. Returns true if the data node is expanded.
toggleDescendants()void Toggles a subtree rooted at node recursively.
collapseAll()void Collapse all dataNodes in the tree.
expandDescendants()void Expands a subtree rooted at given data node recursively.
collapseDescendants()void Collapses a subtree rooted at given data node recursively.
expansionKey()K The key expansionModel holds for a data node.
class FilterByValues<T, K = T> implements FlatTreeControlFilter<T> { result: T[]; setValues: (values: string[]) => void; constructor(control: FlatTreeControl<T, K>); handle(_: any, prevFilter?: FlatTreeControlFilter<T>): T[]; getValues(): string[]; }
Flat tree control. Able to expand/collapse a subtree recursively for flattened tree.
class FlatTreeControl<T, K = T> extends BaseTreeControl<T, K> { expandedItemsBeforeFiltration: K[]; getLevel: (dataNode: T) => number; isExpandable: (dataNode: T) => boolean; getValue: (dataNode: T) => any; getViewValue: (dataNode: T) => string; compareValues: (firstValue: any, secondValue: any) => boolean; compareViewValues: (firstViewValue: any, secondViewValue: any) => boolean; isDisabled: (dataNode: T) => boolean; dataNodes: T[]; expansionModel: SelectionModel<K>; trackBy?: (dataNode: T) => K; filterModel: SelectionModel<T>; filterValue: BehaviorSubject<T[] | string | null>; getChildren: (dataNode: T) => Observable<T[]>; constructor( getLevel: (dataNode: T) => number, isExpandable: (dataNode: T) => boolean, getValue: (dataNode: T) => any, getViewValue: (dataNode: T) => string, compareValues?: (firstValue: any, secondValue: any) => boolean, compareViewValues?: (firstViewValue: any, secondViewValue: any) => boolean, isDisabled?: (dataNode: T) => boolean, options?: KbqTreeControlOptions<T, K> ); getFilters(): FlatTreeControlFilter<T>[]; setFilters(...filters: FlatTreeControlFilter<T>[]): void; getDescendants(dataNode: T): T[]; expandAll(): void; getParents(node: T, result?: T[]): T[]; hasValue(value: string): T | undefined; filterNodes(value?: string | null): void; toggle(dataNode: T): void; expand(dataNode: T): void; collapse(dataNode: T): void; isExpanded(dataNode: T): boolean; toggleDescendants(dataNode: T): void; collapseAll(): void; expandDescendants(dataNode: T): void; collapseDescendants(dataNode: T): void; protected expansionKey(dataNode: T): K; }
getValue(dataNode: T) => any getValue will be used to determine if the tree contains value or not. Used in method hasValue
getViewValue(dataNode: T) => string getViewValue will be used for filter nodes. Returned value will be first argument in filterNodesFunction
compareValues(firstValue: any, secondValue: any) => boolean compareValues will be used to comparing values.
compareViewValues(firstViewValue: any, secondViewValue: any) => boolean compareValues will be used to comparing values.
isDisabled(dataNode: T) => boolean isDisabled will be used to determine if the node is disabled.
expansionModelSelectionModel<K> A selection model with multi-selection to track expansion status: it holds the key of every expanded node.
trackBy(dataNode: T) => K Gives the key a data node is expanded by. Without it the node object is its own key, so a node rebuilt as a new object — as a flattener does whenever its data changes — comes back collapsed.
Set it before anything is expanded: keys stored under another function no longer match.
getChildren(dataNode: T) => Observable<T[]> Gets a stream that emits whenever the given data node's children change.
constructor()Construct with flat tree data node functions getLevel, isExpandable, getValue and getViewValue.
getValue(dataNode: T) => any getValue will be used to determine if the tree contains value or not. Used in method hasValue
getViewValue(dataNode: T) => string getViewValue will be used for filter nodes. Returned value will be first argument in filterNodesFunction
compareValues?(firstValue: any, secondValue: any) => boolean compareValues will be used to comparing values.
compareViewValues?(firstViewValue: any, secondViewValue: any) => boolean compareValues will be used to comparing values.
isDisabled?(dataNode: T) => boolean isDisabled will be used to determine if the node is disabled.
options?KbqTreeControlOptions<T, K> Further options: the trackBy the nodes are expanded by.
getDescendants()T[] Gets a list of the data node's subtree of descendent data nodes.
To make this working, the dataNodes of the TreeControl must be flattened tree nodes
with correct levels.
expandAll()void Expands all data nodes in the tree.
To make this working, the dataNodes variable of the TreeControl must be set to all flattened
data nodes of the tree.
getParents()T[] Ancestors of a data node, outermost first.
Derived from dataNodes rather than from a parent back-reference: the flattened nodes are in
depth-first order, so scanning backwards from the node, the first node of a smaller level is its
parent, and repeating with that level yields the whole chain. A data node whose shape carries no
parent therefore resolves just as well as one that does.
result?T[] Collector the ancestors are prepended to. Provided so callers can accumulate into an existing array; a fresh one is used when omitted.
toggle()void Toggles one single data node's expanded/collapsed state.
expand()void Expands one single data node.
collapse()void Collapses one single data node.
isExpanded()boolean Whether a given data node is expanded or not. Returns true if the data node is expanded.
toggleDescendants()void Toggles a subtree rooted at node recursively.
collapseAll()void Collapse all dataNodes in the tree.
expandDescendants()void Expands a subtree rooted at given data node recursively.
collapseDescendants()void Collapses a subtree rooted at given data node recursively.
expansionKey()K The key expansionModel holds for a data node.
Event class that occurs when copying an item from the KbqTreeSelection. Used to pass data about the copied item and copy context.
class KbqTreeCopyEvent<T, N = any, K = N> { source: KbqTreeSelection<N, K>; option: T; event?: KeyboardEvent; constructor( source: KbqTreeSelection<N, K>, option: T, event?: KeyboardEvent ); }
Data source for flat tree.
The data source need to handle expansion/collapsion of the tree node and change the data feed
to KbqTree.
The nested tree nodes of type T are flattened through KbqTreeFlattener, and converted
to type F for KbqTree to consume.
class KbqTreeFlatDataSource<T, F, K = F> extends DataSource<F> { flattenedData: BehaviorSubject<F[]>; expandedData: BehaviorSubject<F[]>; filteredData: BehaviorSubject<F[]>; data: T[]; constructor( treeControl: FlatTreeControl<F, K>, treeFlattener: KbqTreeFlattener<T, F>, initialData?: T[] ); connect(collectionViewer: CollectionViewer): Observable<F[]>; filterHandler(): F[]; expansionHandler(_change: SelectionChange<K>): F[]; disconnect(): void; }
Tree flattener to convert a normal type of node to node with children & level information.
Transform nested nodes of type T to flattened nodes of type F.
For example, the input data of type T is nested, and contains its children data:
SomeNode: { key: 'Fruits', children: [ NodeOne: { key: 'Apple' }, NodeTwo: { key: 'Pear' } ] }
After flattener flatten the tree, the structure will become
SomeNode: { key: 'Fruits', expandable: true, level: 1 }, NodeOne: { key: 'Apple', expandable: false, level: 2 }, NodeTwo: { key: 'Pear', expandable: false, level: 2 }
and the output flattened type is F with additional information.
class KbqTreeFlattener<T, F> { transformFunction: (node: T, level: number, parent: F | null) => F; getLevel: (node: F) => number; isExpandable: (node: F) => boolean; getChildren: (node: T) => T[] | Observable<T[]> | null | undefined; constructor( transformFunction: (node: T, level: number, parent: F | null) => F, getLevel: (node: F) => number, isExpandable: (node: F) => boolean, getChildren: (node: T) => T[] | Observable<T[]> | null | undefined ); flattenNodes(structuredData: T[]): F[]; expandFlattenedNodes( nodes: F[], treeControl: Pick<TreeControl<F>, 'isExpanded'> ): F[]; }
flattenNodes()F[] Flatten a list of node type T to flattened version of node F.
Please note that type T may be nested, and the length of structuredData may be different
from that of returned list F[].
expandFlattenedNodes()F[] Expand flattened node with current expansion status. The returned list may have different length.
Reads only isExpanded of the tree control, so it takes a control of any key type.
class KbqTreeNavigationChange<T, N = any, K = N> { source: KbqTreeSelection<N, K>; option: T; constructor(source: KbqTreeSelection<N, K>, option: T); }
Data source for nested tree.
The data source for nested tree doesn't have to consider node flattener, or the way to expand or collapse. The expansion/collapsion will be handled by TreeControl and each non-leaf node.
class KbqTreeNestedDataSource<T> extends DataSource<T> { data: T[]; connect(collectionViewer: CollectionViewer): Observable<T[]>; disconnect(): void; }
Context provided to the tree node component.
class KbqTreeNodeOutletContext<T> { $implicit: T; level: number; index?: number; count?: number; constructor(data: T); }
$implicitT Data for the node.
levelnumber Depth of the node.
indexnumber Index location of the node.
countnumber Length of the number of total dataNodes.
Represents a change event for a tree option.
class KbqTreeOptionChange { source: KbqTreeOption<any>; constructor(source: KbqTreeOption<any>); }
sourceKbqTreeOption<any> The tree option that has been modified or selected.
constructor()sourceKbqTreeOption<any> The tree option that has been modified or selected.
class KbqTreeSelectAllEvent<T, N = any, K = N> { source: KbqTreeSelection<N, K>; options: T[]; constructor(source: KbqTreeSelection<N, K>, options: T[]); }
class KbqTreeSelectionChange<T, N = any, K = N> { source: KbqTreeSelection<N, K>; option: T; options?: T[]; constructor( source: KbqTreeSelection<N, K>, option: T, options?: T[] ); }
Nested tree control. Able to expand/collapse a subtree recursively for NestedNode type.
class NestedTreeControl<T, K = T> extends BaseTreeControl<T, K> { getChildren: (dataNode: T) => Observable<T[]>; dataNodes: T[]; expansionModel: SelectionModel<K>; trackBy?: (dataNode: T) => K; filterModel: SelectionModel<T>; filterValue: BehaviorSubject<T[] | string | null>; getLevel: (dataNode: T) => number; isExpandable: (dataNode: T) => boolean; constructor( getChildren: (dataNode: T) => Observable<T[]>, options?: KbqTreeControlOptions<T, K> ); expandAll(): void; getDescendants(dataNode: T): T[]; toggle(dataNode: T): void; expand(dataNode: T): void; collapse(dataNode: T): void; isExpanded(dataNode: T): boolean; toggleDescendants(dataNode: T): void; collapseAll(): void; expandDescendants(dataNode: T): void; collapseDescendants(dataNode: T): void; protected expansionKey(dataNode: T): K; }
getChildren(dataNode: T) => Observable<T[]> Must emit synchronously (e.g. of(children) or a BehaviorSubject).
getDescendants walks the tree with take(1) and returns as soon as the recursion unwinds, so
an asynchronous source yields an incomplete — usually empty — descendant list.
expansionModelSelectionModel<K> A selection model with multi-selection to track expansion status: it holds the key of every expanded node.
trackBy(dataNode: T) => K Gives the key a data node is expanded by. Without it the node object is its own key, so a node rebuilt as a new object — as a flattener does whenever its data changes — comes back collapsed.
Set it before anything is expanded: keys stored under another function no longer match.
getLevel(dataNode: T) => number Get depth of a given data node, return the level number. This is for flat tree node.
isExpandable(dataNode: T) => boolean Whether the data node is expandable. Returns true if expandable. This is for flat tree node.
constructor()Construct with nested tree function getChildren.
getChildren(dataNode: T) => Observable<T[]> Must emit synchronously (e.g. of(children) or a BehaviorSubject).
getDescendants walks the tree with take(1) and returns as soon as the recursion unwinds, so
an asynchronous source yields an incomplete — usually empty — descendant list.
expandAll()void Expands all dataNodes in the tree.
To make this working, the dataNodes variable of the TreeControl must be set to all root level
data nodes of the tree.
getDescendants()T[] Gets a list of descendant dataNodes of a subtree rooted at given data node recursively.
toggle()void Toggles one single data node's expanded/collapsed state.
expand()void Expands one single data node.
collapse()void Collapses one single data node.
isExpanded()boolean Whether a given data node is expanded or not. Returns true if the data node is expanded.
toggleDescendants()void Toggles a subtree rooted at node recursively.
collapseAll()void Collapse all dataNodes in the tree.
expandDescendants()void Expands a subtree rooted at given data node recursively.
collapseDescendants()void Collapses a subtree rooted at given data node recursively.
expansionKey()K The key expansionModel holds for a data node.
function defaultCompareValues( firstValue: string, secondValue: string ): boolean;
function defaultCompareViewValues( firstViewValue: string, secondViewValue: string ): boolean;
interface FlatTreeControlFilter<T> { result: T[]; handle( value: string | null, prevFilter?: FlatTreeControlFilter<T> | null ): T[]; }
Options of FlatTreeControl and NestedTreeControl.
interface KbqTreeControlOptions<T, K> { trackBy?: (dataNode: T) => K; }
trackBy(dataNode: T) => K Initial value of the control's trackBy.
interface KbqTreeOptionEvent { option: KbqTreeOption; }
The part of the tree an option talks to.
Declared as an interface rather than as KbqTreeSelection so the token stays free of a circular
import, and so anything embedding options only has to provide these members.
interface KbqTreeOptionParent<T = any> { disabled: boolean; multiple: boolean; showCheckbox: boolean; inSelect: boolean; optionShouldHoldFocusOnBlur: boolean; selectAllState: KbqPseudoCheckboxState; treeControl: FlatTreeControl<T>; selectionModel: SelectionModel<T>; unorderedOptions: QueryList<KbqTreeOption<T>>; setSelectedOptionsByClick( option: KbqTreeOption<T>, shiftKey: boolean, ctrlKey: boolean ): void; reportOptionFocus?(event: KbqTreeOptionEvent): void; reportOptionBlur?(event: KbqTreeOptionEvent): void; }
disabledboolean Whether the whole tree is disabled.
multipleboolean Whether more than one option can be selected at a time.
showCheckboxboolean Whether the options render a checkbox.
inSelectboolean Whether the tree is rendered inside a select panel, which makes hovering an option focus it.
optionShouldHoldFocusOnBlurboolean Whether an option keeps focus while the tree loses it, as a select with a search field needs.
selectAllStateKbqPseudoCheckboxState State of the tree-level "select all" checkbox.
reportOptionFocus()void Called when an option takes focus.
reportOptionBlur()void Called when an option loses focus.
The persisted state of a tree — the values of the nodes that were expanded.
type KbqTreeState = string[];Tree control interface. User can implement TreeControl to expand/collapse dataNodes in the tree.
The Tree will use this TreeControl to expand/collapse a node.
User can also use it outside the <kbq-tree> to control the expansion status of the tree.
interface TreeControl<T, K = T> { dataNodes: T[]; expansionModel: SelectionModel<K>; filterModel: SelectionModel<T>; trackBy?: (dataNode: T) => K; filterValue: BehaviorSubject<T[] | string | null>; getLevel(dataNode: T): number; isExpandable(dataNode: T): boolean; getChildren(dataNode: T): Observable<T[]>; isExpanded(dataNode: T): boolean; getDescendants(dataNode: T): any[]; toggle(dataNode: T): void; expand(dataNode: T): void; collapse(dataNode: T): void; expandAll(): void; collapseAll(): void; toggleDescendants(dataNode: T): void; expandDescendants(dataNode: T): void; collapseDescendants(dataNode: T): void; }
dataNodesT[] The saved tree nodes data for expandAll action.
expansionModelSelectionModel<K> The expansion model: the keys of the expanded data nodes, which are the nodes themselves by default.
trackBy(dataNode: T) => K Gives the key a data node is expanded by. Without it the node object is its own key.
getLevel()number Get depth of a given data node, return the level number. This is for flat tree node.
isExpandable()boolean Whether the data node is expandable. Returns true if expandable. This is for flat tree node.
getChildren()Observable<T[]> Gets a stream that emits whenever the given data node's children change.
isExpanded()boolean Whether the data node is expanded or collapsed. Return true if it's expanded.
getDescendants()any[] Get all descendants of a data node
toggle()void Expand or collapse data node
expand()void Expand one data node
collapse()void Collapse one data node
expandAll()void Expand all the dataNodes in the tree
collapseAll()void Collapse all the dataNodes in the tree
toggleDescendants()void Toggle a data node by expand/collapse it and all its descendants
expandDescendants()void Expand a data node and all its descendants
collapseDescendants()void Collapse a data node and all its descendants
const KBQ_SELECTION_TREE_VALUE_ACCESSOR: Provider;Injection token used to provide the parent component to options.
const KBQ_TREE_OPTION_PARENT_COMPONENT: InjectionToken<KbqTreeOptionParent>;const kbqTreeSelectAllValue: string;