TreeTable
Display hierarchical records in columns, with explicit relationships, expansion and selection.
- Category
- Data and hierarchy
- Import
@neural-ui/core/tree-table- Selector
neu-tree-table
import { NeuTreeTableComponent } from '@neural-ui/core/tree-table';Hierarchy and expansion
| Task | Hours |
|---|---|
Design | 24 |
Delivery | 12 |
Expanded keys: โ
Configurator
| Task | Hours |
|---|---|
Design | 24 |
Research | 8 |
Prototype | 16 |
Delivery | 12 |
The generated template reflects the selected options. The Code tab includes data, imports and state.
Structured data, callbacks and templates are shown in the examples and API.
Code adds advanced options when they differ from the default. Current configuration data and values appear in the template state.
<neu-tree-table
[data]="rows()"
[columns]="columns()"
[rowKey]="rowKey"
[hierarchy]="hierarchy"
[labels]="labels()"
[appearance]='{
"density": "normal",
"borders": "rows",
"striped": false,
"stickyHeader": false,
"responsive": "contained-scroll"
}'
[hierarchyOptions]='{
"treeColumnId": "name",
"indentSize": 20
}'
[expandedKeys]="expanded()"
(expandedKeysChange)="expanded.set($event.next)"
[selection]="selection()"
[selectionOptions]='{
"mode": "single",
"indicator": "radio",
"selectOnRowClick": true,
"allowClear": false
}'
(selectionChange)="selection.set($event.next)"
[query]="query()"
(queryChange)="query.set($event)"
[filterOptions]='{
"surfaces": [],
"globalFields": [],
"predicates": {},
"debounceMs": 0,
"commit": "immediate"
}'
[exportOptions]="{ formats: ['csv'], defaultFilename: 'work-plan' }"
/>These values match the current preview. Complete handlers, Core imports and templates are in Source.
import { signal } from '@angular/core';
export const rows = signal([
{
"id": "design",
"name": "Design",
"hours": 24
},
{
"id": "research",
"name": "Research",
"hours": 8
},
{
"id": "prototype",
"name": "Prototype",
"hours": 16
},
{
"id": "delivery",
"name": "Delivery",
"hours": 12
}
]);
export const columns = signal([
{
"id": "name",
"field": "name",
"header": "Task"
},
{
"id": "hours",
"field": "hours",
"header": "Hours"
}
]);
export const rowKey = () => { /* Handler in the complete example. */ };
export const hierarchy = {
"hierarchyRevision": 1,
"queryRevision": 0,
"roots": {
"status": "loaded",
"keys": [
"design",
"delivery"
],
"relationRevision": 1,
"appliedRequestId": null,
"total": 2,
"completeness": "complete"
},
"children": [
{
"parentKey": "design",
"relation": {
"status": "loaded",
"keys": [
"research",
"prototype"
],
"relationRevision": 1,
"appliedRequestId": null,
"total": 2,
"completeness": "complete"
}
},
{
"parentKey": "research",
"relation": {
"status": "loaded",
"keys": [],
"relationRevision": 1,
"appliedRequestId": null,
"total": 0,
"completeness": "complete"
}
},
{
"parentKey": "prototype",
"relation": {
"status": "loaded",
"keys": [],
"relationRevision": 1,
"appliedRequestId": null,
"total": 0,
"completeness": "complete"
}
},
{
"parentKey": "delivery",
"relation": {
"status": "loaded",
"keys": [],
"relationRevision": 1,
"appliedRequestId": null,
"total": 0,
"completeness": "complete"
}
}
]
};
export const labels = signal({
"ariaLabel": "Work plan",
"empty": "No tasks",
"error": "Tasks could not be loaded",
"loading": "Loading tasks",
"pagination": "Pagination",
"retry": "Retry",
"selection": "Select task",
"expand": "Expand",
"collapse": "Collapse"
});
export const expanded = signal([
"design"
]);
export const selection = signal({
"kind": "keys",
"keys": [
"design"
]
});
export const query = signal({
"page": 0,
"pageSize": 25,
"search": "",
"sort": [],
"filters": null
});These inputs require a model or function, not a checkbox. Edit the same-named field in the Source component and bind it in the template; data already used by this preview appears in the state above.
columns ยท readonly NeuTreeTableColumn<T, F>[]In Source: define columns with this type and use [columns]="columns" (or columns() for a signal).
data ยท readonly T[]In Source: define data with this type and use [data]="data" (or data() for a signal).
editingOptions ยท NeuTreeTableEditingOptions<T, K, F>In Source: define editingOptions with this type and use [editingOptions]="editingOptions" (or editingOptions() for a signal).
editState ยท NeuTreeTableEditState<K>In Source: define editState with this type and use [editState]="editState" (or editState() for a signal).
exportOptions ยท NeuTreeTableExportOptionsIn Source: define exportOptions with this type and use [exportOptions]="exportOptions" (or exportOptions() for a signal).
hierarchy ยท NeuTreeTableHierarchy<K>In Source: define hierarchy with this type and use [hierarchy]="hierarchy" (or hierarchy() for a signal).
interactionOptions ยท NeuTreeTableInteractionOptionsIn Source: define interactionOptions with this type and use [interactionOptions]="interactionOptions" (or interactionOptions() for a signal).
labels ยท NeuTreeTableLabelsIn Source: define labels with this type and use [labels]="labels" (or labels() for a signal).
layout ยท NeuTreeTableLayoutStateIn Source: define layout with this type and use [layout]="layout" (or layout() for a signal).
paginationOptions ยท NeuTreeTablePaginationOptionsIn Source: define paginationOptions with this type and use [paginationOptions]="paginationOptions" (or paginationOptions() for a signal).
rowKey ยท (value: T) => KIn Source: define rowKey with this type and use [rowKey]="rowKey" (or rowKey() for a signal).
rowOptions ยท NeuTreeTableRowOptions<T>In Source: define rowOptions with this type and use [rowOptions]="rowOptions" (or rowOptions() for a signal).
sortOptions ยท NeuTreeTableSortOptionsIn Source: define sortOptions with this type and use [sortOptions]="sortOptions" (or sortOptions() for a signal).
virtualizationOptions ยท NeuTreeTableVirtualizationOptionsIn Source: define virtualizationOptions with this type and use [virtualizationOptions]="virtualizationOptions" (or virtualizationOptions() for a signal).
Select loaded descendants
| Hours | |
|---|---|
| 24 | |
| 8 | |
| 16 | |
| 12 |
Selected keys: โ
Load roots and children
Apply the roots response first. Then expand Design and apply its children response.
| Task | Hours |
|---|---|
| No tasks | |
Pending request: โ
Virtualize visible rows
| Task | Hours |
|---|---|
Task 1 | 1 |
Task 2 | 2 |
Task 3 | 3 |
Task 4 | 4 |
Task 5 | 5 |
Task 6 | 6 |
Task 7 | 7 |
Task 8 | 8 |
Task 9 | 1 |
Task 10 | 2 |
Task 11 | 3 |
Task 12 | 4 |
Task 13 | 5 |
Task 14 | 6 |
Accessibility and keyboard
Key | Action |
|---|---|
| Tab / Shift+Tab | Enter and leave the treegrid and its enabled controls. |
| ArrowUp / ArrowDown | Move through visible rows when row navigation is enabled. |
| ArrowRight / ArrowLeft | Expand or collapse a node in hierarchical navigation. |
| Enter / Space | Activate the focused expansion or selection control. |
API
Inputs
Configure the component with [property]="value". Your application supplies these values; the component does not replace the state you pass in.
Name | Type | Default | Template binding | Description |
|---|---|---|---|---|
appearance | NeuTreeTableAppearance | {
density: 'normal',
borders: 'rows',
striped: false,
stickyHeader: false,
responsive: 'contained-scroll',
} | [appearance] | |
columns | readonly NeuTreeTableColumn<T, F>[] | [] | [columns] | |
data | readonly T[] | [] | [data] | |
dataMode | NeuTreeTableDataMode | 'client' | [dataMode] | |
editingOptions | NeuTreeTableEditingOptions<T, K, F> | { mode: 'none' } | [editingOptions] | |
editState | NeuTreeTableEditState<K> | {
kind: 'none',
} | [editState] | |
expandedKeys | readonly K[] | [] | [expandedKeys] | |
exportOptions | NeuTreeTableExportOptions | {
formats: [],
defaultFilename: 'tree-table',
} | [exportOptions] | |
filterOptions | NeuTreeTableFilterOptions<T, F> | { surfaces: [], globalFields: [], predicates: {}, debounceMs: 0, commit: 'immediate' } | [filterOptions] | |
hierarchy | NeuTreeTableHierarchy<K> | EMPTY_HIERARCHY as NeuTreeTableHierarchy<K>Derived default | [hierarchy] | |
hierarchyOptions | NeuTreeTableHierarchyOptions | Required | [hierarchyOptions] | |
interactionOptions | NeuTreeTableInteractionOptions | {
navigation: 'row',
wrapFocus: false,
announceChanges: false,
contextMenuAction: false,
} | [interactionOptions] | |
labels | NeuTreeTableLabels | {
ariaLabel: 'Tree table',
empty: 'No data',
loading: 'Loading',
error: 'Unable to load tree data',
retry: 'Retry',
expand: 'Expand node',
collapse: 'Collapse node',
selection: 'Selection',
pagination: 'Pagination',
} | [labels] | |
layout | NeuTreeTableLayoutState | {
order: [],
hidden: [],
widths: {},
pinnedStart: [],
pinnedEnd: [],
} | [layout] | |
paginationOptions | NeuTreeTablePaginationOptions | {
enabled: false,
pageSizeOptions: [],
position: 'bottom',
report: 'none',
} | [paginationOptions] | |
query | NeuTreeTableQuery<F> | {
page: 0,
pageSize: 25,
search: '',
sort: [],
filters: null,
} | [query] | |
rowKey | (value: T) => K | Required | [rowKey] | |
rowOptions | NeuTreeTableRowOptions<T> | {} | [rowOptions] | |
selection | NeuTreeTableSelection<K> | {
kind: 'keys',
keys: [],
} | [selection] | |
selectionOptions | NeuTreeTableSelectionOptions<T> | { mode: 'none' } | [selectionOptions] | |
sortOptions | NeuTreeTableSortOptions | {
mode: 'single',
removable: true,
defaultDirection: 'asc',
resetRootPageOnChange: true,
} | [sortOptions] | |
virtualizationOptions | NeuTreeTableVirtualizationOptions | { enabled: false } | [virtualizationOptions] |
Outputs
Listen to an event with (event)="handler($event)". The table explains the data your handler receives and how to use it.
Name | Payload | Template binding | Description |
|---|---|---|---|
dataRequest | NeuTreeTableDataRequest<K, F> | (dataRequest)="onDataRequest($event)" | |
editCancel | NeuTreeTableEditCancel<T, K> | (editCancel)="onEditCancel($event)" | |
editCommit | NeuTreeTableEditCommit<T, K, F> | (editCommit)="onEditCommit($event)" | |
editStateChange | NeuTreeTableEditChange<K> | (editStateChange)="onEditStateChange($event)" | |
expandedKeysChange | NeuTreeTableExpandedKeysChange<K> | (expandedKeysChange)="onExpandedKeysChange($event)" | |
exportRequest | NeuTreeTableExportRequest<F> | (exportRequest)="onExportRequest($event)" | |
featureError | NeuTreeTableFeatureError | (featureError)="onFeatureError($event)" | |
layoutChange | NeuTreeTableLayoutChange | (layoutChange)="onLayoutChange($event)" | |
queryChange | NeuTreeTableQuery<F> | (queryChange)="onQueryChange($event)" | |
rangeChange | NeuTreeTableRangeChange | (rangeChange)="onRangeChange($event)" | |
rowAction | NeuTreeTableRowAction<T, K> | (rowAction)="onRowAction($event)" | |
selectionChange | NeuTreeTableSelectionChange<T, K> | (selectionChange)="onSelectionChange($event)" |
Templates
ng-content projects content into the component. TemplateRef inputs receive a template; ng-template directives identify templates with a typed context. A directive shared by an entrypoint is not necessarily a slot of this component.
Name | Mechanism | Contract |
|---|---|---|
NeuTreeTableCaptionDirective | Public template directive (entrypoint) | ng-template[neuTreeTableCaption]Context used: template.d.ts context.d.ts |
NeuTreeTableCellDirective | Public template directive (entrypoint) | ng-template[neuTreeTableCell]Context used: template.d.ts context.d.ts |
NeuTreeTableEditorDirective | Public template directive (entrypoint) | ng-template[neuTreeTableEditor]Context used: template.d.ts context.d.ts |
NeuTreeTableEmptyDirective | Public template directive (entrypoint) | ng-template[neuTreeTableEmpty]Context used: template.d.ts context.d.ts |
NeuTreeTableErrorDirective | Public template directive (entrypoint) | ng-template[neuTreeTableError]Context used: template.d.ts context.d.ts |
NeuTreeTableFooterDirective | Public template directive (entrypoint) | ng-template[neuTreeTableFooter]Context used: template.d.ts context.d.ts |
NeuTreeTableHeaderDirective | Public template directive (entrypoint) | ng-template[neuTreeTableHeader]Context used: template.d.ts context.d.ts |
NeuTreeTableLoadingDirective | Public template directive (entrypoint) | ng-template[neuTreeTableLoading]Context used: template.d.ts context.d.ts |
NeuTreeTableNodeDirective | Public template directive (entrypoint) | ng-template[neuTreeTableNode]Context used: template.d.ts context.d.ts |
NeuTreeTableSummaryDirective | Public template directive (entrypoint) | ng-template[neuTreeTableSummary]Context used: template.d.ts context.d.ts |
NeuTreeTableToolbarDirective | Public template directive (entrypoint) | ng-template[neuTreeTableToolbar]Context used: template.d.ts context.d.ts |
Usage example
Use the pencil to edit the hours. Save the change or cancel from the editor.
| Task | Hours |
|---|---|
Design(level 0) | 24 h |
Research(level 1) | 8 h |
Prototype(level 1) | 16 h |
Delivery(level 0) | 12 h |
| Planned hours | |
Available tasks: 4 | |
Public methods
Name | Contract |
|---|---|
export | export(request: NeuTreeTableExportRequest<F>): Promise<NeuTreeTableExportOutcome>;Export visible, loaded, or selected data. Check the returned outcome and handle delegated requests in your application. example.ts |
focus | focus(target: NeuTreeTableFocusTarget<K>): void;Focus a node, a cell, or the first or last visible node. This does not expand collapsed parents. example.ts |
retryData | retryData(target: NeuTreeTableRetryTarget<K>): void;Retry loading roots or the children of one parent. The application handles the resulting dataRequest. example.ts |
scrollTo | scrollTo(target: NeuTreeTableScrollTarget<K>): void;Scroll to a node, row index, or pixel offset. Choose the target kind explicitly. example.ts |
Public Types
Open a type to inspect its definition and interface fields.
import type { NeuTreeRelation } from '@neural-ui/core/tree-table';
import type { NeuTreeTableKey } from '@neural-ui/core/tree-table';
import type { NeuTreeChildRelation } from '@neural-ui/core/tree-table';
// Public declaration (reference only)
export interface NeuTreeChildRelation<K extends NeuTreeTableKey> {
readonly parentKey: K;
readonly relation: NeuTreeRelation<K>;
}import type { NeuTreeValueAccessor } from '@neural-ui/core/tree-table';
import type { NeuTreeEditColumn } from '@neural-ui/core/tree-table';
// Public declaration (reference only)
export interface NeuTreeEditColumn<T, F extends string> {
readonly field: F;
readonly read?: NeuTreeValueAccessor<T>;
readonly write?: (value: T, candidate: unknown) => T;
}import type { NeuTreeTableKey } from '@neural-ui/core/tree-table';
import type { NeuTreeErrorRelation } from '@neural-ui/core/tree-table';
// Public declaration (reference only)
export interface NeuTreeErrorRelation<K extends NeuTreeTableKey> {
readonly appliedRequestId: number | null;
readonly error: unknown;
readonly keys: readonly K[];
readonly relationRevision: number;
readonly status: 'error';
readonly total: number | null;
}import type { NeuTreeFilterConstraint } from '@neural-ui/core/tree-table';
import type { NeuTreeValueAccessor } from '@neural-ui/core/tree-table';
import type { NeuTreeFilterColumn } from '@neural-ui/core/tree-table';
// Public declaration (reference only)
export interface NeuTreeFilterColumn<T, F extends string> {
readonly defaultRule: NeuTreeFilterConstraint<F>['rule'];
readonly field: F;
readonly rules: readonly NeuTreeFilterConstraint<F>['rule'][];
readonly value?: NeuTreeValueAccessor<T>;
}import type { NeuTreeFilterConstraint } from '@neural-ui/core/tree-table';
// Public declaration (reference only)
export interface NeuTreeFilterConstraint<F extends string> {
readonly field: F;
readonly kind: 'condition';
readonly rule: 'equals' | 'notEquals' | 'contains' | 'notContains' | 'startsWith' | 'endsWith' | 'lessThan' | 'lessThanOrEqual' | 'greaterThan' | 'greaterThanOrEqual' | 'between' | 'in' | 'notIn' | 'isNull' | 'isNotNull' | 'isEmpty' | 'isNotEmpty';
readonly value: unknown;
}import type { NeuTreeFilterConstraint } from '@neural-ui/core/tree-table';
import type { NeuTreeFilterGroup } from '@neural-ui/core/tree-table';
import type { NeuTreeFilterExpression } from '@neural-ui/core/tree-table';
// Public declaration (reference only)
export type NeuTreeFilterExpression<F extends string> = NeuTreeFilterConstraint<F> | NeuTreeFilterGroup<F>;import type { NeuTreeFilterExpression } from '@neural-ui/core/tree-table';
import type { NeuTreeFilterOperator } from '@neural-ui/core/tree-table';
import type { NeuTreeFilterGroup } from '@neural-ui/core/tree-table';
// Public declaration (reference only)
export interface NeuTreeFilterGroup<F extends string> {
readonly children: readonly NeuTreeFilterExpression<F>[];
readonly kind: 'group';
readonly operator: NeuTreeFilterOperator;
}import type { NeuTreeFilterOperator } from '@neural-ui/core/tree-table';
// Public declaration (reference only)
export type NeuTreeFilterOperator = 'and' | 'or';import type { NeuTreeFilterPredicateContext } from '@neural-ui/core/tree-table';
import type { NeuTreeFilterPredicate } from '@neural-ui/core/tree-table';
// Public declaration (reference only)
export type NeuTreeFilterPredicate<T, F extends string> = (context: NeuTreeFilterPredicateContext<T, F>) => boolean;import type { NeuTreeFilterPredicateContext } from '@neural-ui/core/tree-table';
// Public declaration (reference only)
export interface NeuTreeFilterPredicateContext<T, F extends string> {
readonly candidate: unknown;
readonly field: F;
readonly filterValue: unknown;
readonly value: T;
}import type { NeuTreeFilterSurface } from '@neural-ui/core/tree-table';
// Public declaration (reference only)
export type NeuTreeFilterSurface = 'row' | 'menu' | 'builder';import type { NeuTreeRelationCompleteness } from '@neural-ui/core/tree-table';
import type { NeuTreeTableKey } from '@neural-ui/core/tree-table';
import type { NeuTreeLoadedRelation } from '@neural-ui/core/tree-table';
// Public declaration (reference only)
export interface NeuTreeLoadedRelation<K extends NeuTreeTableKey> {
readonly appliedRequestId: number | null;
readonly completeness: NeuTreeRelationCompleteness;
readonly keys: readonly K[];
readonly relationRevision: number;
readonly status: 'loaded';
readonly total: number | null;
}import type { NeuTreeTableKey } from '@neural-ui/core/tree-table';
import type { NeuTreeLoadingRelation } from '@neural-ui/core/tree-table';
// Public declaration (reference only)
export interface NeuTreeLoadingRelation<K extends NeuTreeTableKey> {
readonly appliedRequestId: number;
readonly keys: readonly K[];
readonly relationRevision: number;
readonly status: 'loading';
readonly total: number | null;
}import type { NeuTreeErrorRelation } from '@neural-ui/core/tree-table';
import type { NeuTreeLoadedRelation } from '@neural-ui/core/tree-table';
import type { NeuTreeLoadingRelation } from '@neural-ui/core/tree-table';
import type { NeuTreeTableKey } from '@neural-ui/core/tree-table';
import type { NeuTreeUnloadedRelation } from '@neural-ui/core/tree-table';
import type { NeuTreeRelation } from '@neural-ui/core/tree-table';
// Public declaration (reference only)
export type NeuTreeRelation<K extends NeuTreeTableKey> = NeuTreeUnloadedRelation<K> | NeuTreeLoadingRelation<K> | NeuTreeErrorRelation<K> | NeuTreeLoadedRelation<K>;import type { NeuTreeRelationCompleteness } from '@neural-ui/core/tree-table';
// Public declaration (reference only)
export type NeuTreeRelationCompleteness = 'partial' | 'complete';import type { NeuTreeRelationStatus } from '@neural-ui/core/tree-table';
// Public declaration (reference only)
export type NeuTreeRelationStatus = 'unloaded' | 'loading' | 'error' | 'loaded';import type { NeuTreeValueAccessor } from '@neural-ui/core/tree-table';
import type { NeuTreeSortColumn } from '@neural-ui/core/tree-table';
// Public declaration (reference only)
export interface NeuTreeSortColumn<T, F extends string> {
readonly compare?: (left: T, right: T) => number;
readonly field: F;
readonly value?: NeuTreeValueAccessor<T>;
}import type { NeuTreeSortDirection } from '@neural-ui/core/tree-table';
// Public declaration (reference only)
export type NeuTreeSortDirection = 'asc' | 'desc';import type { NeuTreeSortDirection } from '@neural-ui/core/tree-table';
import type { NeuTreeSortEntry } from '@neural-ui/core/tree-table';
// Public declaration (reference only)
export interface NeuTreeSortEntry<F extends string> {
readonly direction: NeuTreeSortDirection;
readonly field: F;
}import type { NeuTreeTableAppearance } from '@neural-ui/core/tree-table';
// Public declaration (reference only)
export interface NeuTreeTableAppearance {
readonly borders: 'none' | 'rows' | 'cells';
readonly density: 'compact' | 'normal' | 'relaxed';
readonly responsive: 'contained-scroll' | 'stacked';
readonly stickyHeader: boolean;
readonly striped: boolean;
}import type { NeuTreeTableColumn } from '@neural-ui/core/tree-table';
import type { NeuTreeTableKey } from '@neural-ui/core/tree-table';
import type { NeuTreeTableNodeContext } from '@neural-ui/core/tree-table';
import type { NeuTreeTableCellContext } from '@neural-ui/core/tree-table';
// Public declaration (reference only)
export interface NeuTreeTableCellContext<T, K extends NeuTreeTableKey, F extends string> extends NeuTreeTableNodeContext<T, K> {
readonly column: NeuTreeTableColumn<T, F>;
readonly columnIndex: number;
readonly logicalIndex: number;
}import type { NeuTreeTableKey } from '@neural-ui/core/tree-table';
import type { NeuTreeTableRequestBase } from '@neural-ui/core/tree-table';
import type { NeuTreeTableChildrenRequest } from '@neural-ui/core/tree-table';
// Public declaration (reference only)
export interface NeuTreeTableChildrenRequest<K extends NeuTreeTableKey, F extends string> extends NeuTreeTableRequestBase<F> {
readonly kind: 'children';
readonly parentKey: K;
readonly reason: 'expand' | 'query' | 'retry';
readonly relationRevision: number;
}import type { NeuTreeEditColumn } from '@neural-ui/core/tree-table';
import type { NeuTreeFilterColumn } from '@neural-ui/core/tree-table';
import type { NeuTreeSortColumn } from '@neural-ui/core/tree-table';
import type { NeuTreeValueAccessor } from '@neural-ui/core/tree-table';
import type { NeuTreeTableColumn } from '@neural-ui/core/tree-table';
// Public declaration (reference only)
export interface NeuTreeTableColumn<T, F extends string> {
readonly align?: 'start' | 'center' | 'end';
readonly edit?: NeuTreeEditColumn<T, F>;
readonly field?: F;
readonly filter?: NeuTreeFilterColumn<T, F>;
readonly header: string;
readonly id: string;
readonly maxWidth?: string;
readonly minWidth?: string;
readonly sort?: NeuTreeSortColumn<T, F>;
readonly value?: NeuTreeValueAccessor<T>;
readonly width?: string;
}import type { NeuTreeTableDataMode } from '@neural-ui/core/tree-table';
// Public declaration (reference only)
export type NeuTreeTableDataMode = 'client' | 'remote';import type { NeuTreeTableChildrenRequest } from '@neural-ui/core/tree-table';
import type { NeuTreeTableKey } from '@neural-ui/core/tree-table';
import type { NeuTreeTableRootsRequest } from '@neural-ui/core/tree-table';
import type { NeuTreeTableDataRequest } from '@neural-ui/core/tree-table';
// Public declaration (reference only)
export type NeuTreeTableDataRequest<K extends NeuTreeTableKey, F extends string> = NeuTreeTableRootsRequest<F> | NeuTreeTableChildrenRequest<K, F>;import type { NeuTreeTableKey } from '@neural-ui/core/tree-table';
import type { NeuTreeTableEditCancel } from '@neural-ui/core/tree-table';
// Public declaration (reference only)
export interface NeuTreeTableEditCancel<T, K extends NeuTreeTableKey> {
readonly key: K;
readonly reason: 'escape' | 'gesture' | 'hidden' | 'destroy';
readonly value: T;
}import type { NeuTreeTableEditState } from '@neural-ui/core/tree-table';
import type { NeuTreeTableKey } from '@neural-ui/core/tree-table';
import type { NeuTreeTableEditChange } from '@neural-ui/core/tree-table';
// Public declaration (reference only)
export interface NeuTreeTableEditChange<K extends NeuTreeTableKey> {
readonly next: NeuTreeTableEditState<K>;
readonly source: 'gesture' | 'keyboard' | 'commit' | 'cancel' | 'hidden';
}import type { NeuTreeTableKey } from '@neural-ui/core/tree-table';
import type { NeuTreeTableEditCommit } from '@neural-ui/core/tree-table';
// Public declaration (reference only)
export interface NeuTreeTableEditCommit<T, K extends NeuTreeTableKey, F extends string> {
readonly draft: Readonly<Partial<T>>;
readonly field: F | null;
readonly key: K;
readonly source: 'cell' | 'row';
readonly value: T;
}import type { NeuTreeTableKey } from '@neural-ui/core/tree-table';
import type { NeuTreeTableEditingOptions } from '@neural-ui/core/tree-table';
// Public declaration (reference only)
export interface NeuTreeTableEditingOptions<T, K extends NeuTreeTableKey, F extends string> {
readonly mode: 'none' | 'cell' | 'row';
readonly validate?: (context: {
readonly value: T;
readonly key: K;
readonly field: F | null;
readonly draft: Readonly<Partial<T>>;
}) => true | string;
}import type { NeuTreeTableCellContext } from '@neural-ui/core/tree-table';
import type { NeuTreeTableKey } from '@neural-ui/core/tree-table';
import type { NeuTreeTableEditorContext } from '@neural-ui/core/tree-table';
// Public declaration (reference only)
export interface NeuTreeTableEditorContext<T, K extends NeuTreeTableKey, F extends string> extends NeuTreeTableCellContext<T, K, F> {
readonly cancel: () => void;
readonly commit: () => void;
readonly draftValue: unknown;
readonly field: F | null;
readonly update: (value: unknown) => void;
}import type { NeuTreeTableKey } from '@neural-ui/core/tree-table';
import type { NeuTreeTableEditState } from '@neural-ui/core/tree-table';
// Public declaration (reference only)
export type NeuTreeTableEditState<K extends NeuTreeTableKey> = {
readonly kind: 'none';
} | {
readonly kind: 'cell';
readonly key: K;
readonly columnId: string;
} | {
readonly kind: 'row';
readonly key: K;
};import type { NeuTreeTableKey } from '@neural-ui/core/tree-table';
import type { NeuTreeTableExpandedKeysChange } from '@neural-ui/core/tree-table';
// Public declaration (reference only)
export interface NeuTreeTableExpandedKeysChange<K extends NeuTreeTableKey> {
readonly changedKey: K;
readonly next: readonly K[];
readonly source: 'toggle' | 'keyboard';
}import type { NeuTreeTableExportOptions } from '@neural-ui/core/tree-table';
// Public declaration (reference only)
export interface NeuTreeTableExportOptions {
readonly defaultFilename: string;
readonly formats: readonly ('csv' | 'json' | 'xlsx')[];
}import type { NeuTreeTableExportOutcome } from '@neural-ui/core/tree-table';
// Public declaration (reference only)
export type NeuTreeTableExportOutcome = {
readonly status: 'downloaded';
readonly filename: string;
readonly rowCount: number;
} | {
readonly status: 'delegated';
} | {
readonly status: 'unsupported';
readonly reason: string;
} | {
readonly status: 'failed';
readonly error: unknown;
};import type { NeuTreeTableQuery } from '@neural-ui/core/tree-table';
import type { NeuTreeTableExportRequest } from '@neural-ui/core/tree-table';
// Public declaration (reference only)
export interface NeuTreeTableExportRequest<F extends string> {
readonly filename?: string;
readonly format: 'csv' | 'json' | 'xlsx';
readonly query: NeuTreeTableQuery<F>;
readonly scope: 'visible' | 'loaded' | 'selected';
}import type { NeuTreeTableFeatureError } from '@neural-ui/core/tree-table';
// Public declaration (reference only)
export type NeuTreeTableFeatureError = {
readonly feature: 'hierarchy';
readonly code: 'cycle' | 'duplicate-key' | 'duplicate-parent' | 'missing-root' | 'missing-node' | 'duplicate-child' | 'orphan' | 'invalid-tree-column';
readonly error: unknown;
} | {
readonly feature: 'advanced-filter' | 'editor' | 'export';
readonly error: unknown;
};import type { NeuTreeFilterPredicate } from '@neural-ui/core/tree-table';
import type { NeuTreeFilterSurface } from '@neural-ui/core/tree-table';
import type { NeuTreeTableFilterOptions } from '@neural-ui/core/tree-table';
// Public declaration (reference only)
export interface NeuTreeTableFilterOptions<T, F extends string> {
readonly commit: 'immediate' | 'explicit';
readonly debounceMs: number;
readonly equals?: (left: unknown, right: unknown) => boolean;
readonly globalFields: readonly F[];
readonly predicates: Readonly<Record<string, NeuTreeFilterPredicate<T, F>>>;
readonly surfaces: readonly NeuTreeFilterSurface[];
}import type { NeuTreeTableKey } from '@neural-ui/core/tree-table';
import type { NeuTreeTableFocusTarget } from '@neural-ui/core/tree-table';
// Public declaration (reference only)
export type NeuTreeTableFocusTarget<K extends NeuTreeTableKey> = {
readonly kind: 'node';
readonly key: K;
} | {
readonly kind: 'cell';
readonly key: K;
readonly columnId: string;
} | {
readonly kind: 'first' | 'last';
};import type { NeuTreeTableColumn } from '@neural-ui/core/tree-table';
import type { NeuTreeTableHeaderContext } from '@neural-ui/core/tree-table';
// Public declaration (reference only)
export interface NeuTreeTableHeaderContext<T, F extends string> {
readonly column: NeuTreeTableColumn<T, F>;
readonly columnIndex: number;
}import type { NeuTreeChildRelation } from '@neural-ui/core/tree-table';
import type { NeuTreeRelation } from '@neural-ui/core/tree-table';
import type { NeuTreeTableKey } from '@neural-ui/core/tree-table';
import type { NeuTreeTableHierarchy } from '@neural-ui/core/tree-table';
// Public declaration (reference only)
export interface NeuTreeTableHierarchy<K extends NeuTreeTableKey> {
readonly children: readonly NeuTreeChildRelation<K>[];
readonly hierarchyRevision: number;
readonly queryRevision: number;
readonly roots: NeuTreeRelation<K>;
}import type { NeuTreeTableHierarchyOptions } from '@neural-ui/core/tree-table';
// Public declaration (reference only)
export interface NeuTreeTableHierarchyOptions {
readonly indentSize: number;
readonly treeColumnId: string;
}import type { NeuTreeTableInteractionOptions } from '@neural-ui/core/tree-table';
// Public declaration (reference only)
export interface NeuTreeTableInteractionOptions {
readonly announceChanges: boolean;
readonly contextMenuAction: boolean;
readonly navigation: 'row';
readonly wrapFocus: boolean;
}import type { NeuTreeTableKey } from '@neural-ui/core/tree-table';
// Public declaration (reference only)
export type NeuTreeTableKey = string | number;import type { NeuTreeTableLabels } from '@neural-ui/core/tree-table';
// Public declaration (reference only)
export interface NeuTreeTableLabels {
readonly ariaLabel: string;
readonly collapse: string;
readonly empty: string;
readonly error: string;
readonly expand: string;
readonly loading: string;
readonly pagination: string;
readonly retry: string;
readonly selection: string;
}import type { NeuTreeTableLayoutState } from '@neural-ui/core/tree-table';
import type { NeuTreeTableLayoutChange } from '@neural-ui/core/tree-table';
// Public declaration (reference only)
export interface NeuTreeTableLayoutChange {
readonly next: NeuTreeTableLayoutState;
readonly source: 'resize' | 'reorder' | 'visibility' | 'pin';
}import type { NeuTreeTableLayoutState } from '@neural-ui/core/tree-table';
// Public declaration (reference only)
export interface NeuTreeTableLayoutState {
readonly hidden: readonly string[];
readonly order: readonly string[];
readonly pinnedEnd: readonly string[];
readonly pinnedStart: readonly string[];
readonly widths: Readonly<Record<string, string>>;
}import type { NeuTreeRelationStatus } from '@neural-ui/core/tree-table';
import type { NeuTreeTableKey } from '@neural-ui/core/tree-table';
import type { NeuTreeTableNodeContext } from '@neural-ui/core/tree-table';
// Public declaration (reference only)
export interface NeuTreeTableNodeContext<T, K extends NeuTreeTableKey> {
readonly $implicit: T;
readonly childStatus: NeuTreeRelationStatus;
readonly depth: number;
readonly disabled: boolean;
readonly expanded: boolean;
readonly indeterminate: boolean;
readonly key: K;
readonly parentKey: K | null;
readonly path: readonly K[];
readonly selected: boolean;
readonly siblingCount: number | null;
readonly siblingIndex: number;
readonly toggleExpansion: () => void;
readonly toggleSelection: () => void;
readonly value: T;
}import type { NeuTreeTablePaginationOptions } from '@neural-ui/core/tree-table';
// Public declaration (reference only)
export interface NeuTreeTablePaginationOptions {
readonly enabled: boolean;
readonly pageSizeOptions: readonly number[];
readonly position: 'top' | 'bottom' | 'both';
readonly report: 'none' | 'roots';
}import type { NeuTreeFilterExpression } from '@neural-ui/core/tree-table';
import type { NeuTreeSortEntry } from '@neural-ui/core/tree-table';
import type { NeuTreeTableQuery } from '@neural-ui/core/tree-table';
// Public declaration (reference only)
export interface NeuTreeTableQuery<F extends string> {
readonly filters: NeuTreeFilterExpression<F> | null;
readonly page: number;
readonly pageSize: number;
readonly search: string;
readonly sort: readonly NeuTreeSortEntry<F>[];
}import type { NeuTreeTableRange } from '@neural-ui/core/tree-table';
// Public declaration (reference only)
export interface NeuTreeTableRange {
readonly end: number;
readonly start: number;
}import type { NeuTreeTableRange } from '@neural-ui/core/tree-table';
import type { NeuTreeTableRangeChange } from '@neural-ui/core/tree-table';
// Public declaration (reference only)
export interface NeuTreeTableRangeChange {
readonly projectionRevision: number;
readonly reason: 'scroll' | 'resize' | 'programmatic' | 'hierarchy';
readonly render: NeuTreeTableRange;
readonly visible: NeuTreeTableRange;
}import type { NeuTreeTableQuery } from '@neural-ui/core/tree-table';
import type { NeuTreeTableRequestBase } from '@neural-ui/core/tree-table';
// Public declaration (reference only)
export interface NeuTreeTableRequestBase<F extends string> {
readonly hierarchyRevision: number;
readonly query: NeuTreeTableQuery<F>;
readonly queryRevision: number;
readonly requestId: number;
}import type { NeuTreeTableKey } from '@neural-ui/core/tree-table';
import type { NeuTreeTableRetryTarget } from '@neural-ui/core/tree-table';
// Public declaration (reference only)
export type NeuTreeTableRetryTarget<K extends NeuTreeTableKey> = {
readonly kind: 'roots';
} | {
readonly kind: 'children';
readonly parentKey: K;
};import type { NeuTreeTableRequestBase } from '@neural-ui/core/tree-table';
import type { NeuTreeTableRootsRequest } from '@neural-ui/core/tree-table';
// Public declaration (reference only)
export interface NeuTreeTableRootsRequest<F extends string> extends NeuTreeTableRequestBase<F> {
readonly kind: 'roots';
readonly reason: 'initial' | 'query' | 'page' | 'retry';
readonly relationRevision: number;
}import type { NeuTreeTableKey } from '@neural-ui/core/tree-table';
import type { NeuTreeTableRowAction } from '@neural-ui/core/tree-table';
// Public declaration (reference only)
export interface NeuTreeTableRowAction<T, K extends NeuTreeTableKey> {
readonly key: K;
readonly source: 'click' | 'double-click' | 'keyboard' | 'context-menu';
readonly value: T;
}import type { NeuTreeTableRowOptions } from '@neural-ui/core/tree-table';
// Public declaration (reference only)
export interface NeuTreeTableRowOptions<T> {
readonly className?: (value: T) => string | readonly string[] | null;
}import type { NeuTreeTableKey } from '@neural-ui/core/tree-table';
import type { NeuTreeTableScrollTarget } from '@neural-ui/core/tree-table';
// Public declaration (reference only)
export type NeuTreeTableScrollTarget<K extends NeuTreeTableKey> = {
readonly kind: 'node';
readonly key: K;
readonly behavior?: ScrollBehavior;
} | {
readonly kind: 'index';
readonly index: number;
readonly behavior?: ScrollBehavior;
} | {
readonly kind: 'offset';
readonly offset: number;
readonly behavior?: ScrollBehavior;
};import type { NeuTreeTableKey } from '@neural-ui/core/tree-table';
import type { NeuTreeTableSelection } from '@neural-ui/core/tree-table';
// Public declaration (reference only)
export interface NeuTreeTableSelection<K extends NeuTreeTableKey> {
readonly keys: readonly K[];
readonly kind: 'keys';
}import type { NeuTreeTableKey } from '@neural-ui/core/tree-table';
import type { NeuTreeTableSelection } from '@neural-ui/core/tree-table';
import type { NeuTreeTableSelectionChange } from '@neural-ui/core/tree-table';
// Public declaration (reference only)
export interface NeuTreeTableSelectionChange<T, K extends NeuTreeTableKey> {
readonly addedKeys: readonly K[];
readonly loadedValues: readonly T[];
readonly next: NeuTreeTableSelection<K>;
readonly propagation: 'none' | 'loaded-subtree';
readonly removedKeys: readonly K[];
readonly source: 'row' | 'radio' | 'checkbox' | 'keyboard' | 'toggle-all';
}import type { NeuTreeTableSelectionOptions } from '@neural-ui/core/tree-table';
// Public declaration (reference only)
export type NeuTreeTableSelectionOptions<T> = {
readonly mode: 'none';
} | {
readonly mode: 'single';
readonly indicator: 'none' | 'radio';
readonly selectOnRowClick: boolean;
readonly allowClear: boolean;
readonly isNodeDisabled?: (value: T) => boolean;
} | {
readonly mode: 'multiple' | 'checkbox';
readonly indicator: 'none' | 'checkbox';
readonly selectOnRowClick: boolean;
readonly modifier: 'replace' | 'platform' | 'toggle';
readonly range: boolean;
readonly propagation: 'none' | 'loaded-subtree';
readonly toggleAllScope: 'visible' | 'loaded';
readonly isNodeDisabled?: (value: T) => boolean;
};import type { NeuTreeSortDirection } from '@neural-ui/core/tree-table';
import type { NeuTreeTableSortOptions } from '@neural-ui/core/tree-table';
// Public declaration (reference only)
export interface NeuTreeTableSortOptions {
readonly defaultDirection: NeuTreeSortDirection;
readonly mode: 'single' | 'multiple';
readonly removable: boolean;
readonly resetRootPageOnChange: boolean;
}import type { NeuTreeTableStateContext } from '@neural-ui/core/tree-table';
// Public declaration (reference only)
export interface NeuTreeTableStateContext {
readonly retry: () => void;
}import type { NeuTreeTableTemplateDirective } from '@neural-ui/core/tree-table';
// Public declaration (reference only)
export interface NeuTreeTableTemplateDirective<C> {
readonly templateRef: TemplateRef<C>;
}import type { NeuTreeTableVirtualizationOptions } from '@neural-ui/core/tree-table';
// Public declaration (reference only)
export type NeuTreeTableVirtualizationOptions = {
readonly enabled: false;
} | {
readonly enabled: true;
readonly itemSize: number;
readonly overscan: number;
};import type { NeuTreeTableKey } from '@neural-ui/core/tree-table';
import type { NeuTreeUnloadedRelation } from '@neural-ui/core/tree-table';
// Public declaration (reference only)
export interface NeuTreeUnloadedRelation<K extends NeuTreeTableKey> {
readonly appliedRequestId: number | null;
readonly keys: readonly K[];
readonly relationRevision: number;
readonly status: 'unloaded';
readonly total: number | null;
}import type { NeuTreeValueAccessor } from '@neural-ui/core/tree-table';
// Public declaration (reference only)
export type NeuTreeValueAccessor<T> = (value: T) => unknown;Appearance and tokens
Specific tokens
Token | Purpose | State / variant | Default / source | Fallback |
|---|---|---|---|---|
--neu-tree-table-cell-block | Base vertical padding; compact uses 60%, relaxed 140%. | Table cells | 0.625remComponent fallback | No token alias |
--neu-tree-table-cell-inline | Horizontal cell padding, independent of tree indentation. | Table cells | var(--neu-space-3)Component fallback | --neu-space-3 |
--neu-tree-table-selected-background | Selected-node row background, above alternating stripes. | Selected row | color-mix(in srgb, currentColor 9%, transparent)Component fallback | No token alias |
--neu-tree-table-virtual-block-size | Height of the virtualized hierarchy viewport. | Virtualization | 24remRoot declaration | No token alias |
Shared tokens used
Override these on a local wrapper to affect this example. An override on :root affects other components that use the same token.
Token | Purpose here | Other impact | Default / fallback |
|---|---|---|---|
--neu-border | Normal control and cell borders | Shared by other Core consumers; scope the override. | rgba(15, 23, 42, 0.08) |
--neu-focus-color | Visible keyboard-focus outline | Shared by other Core consumers; scope the override. | var(--neu-primary) |
--neu-surface | Main field, header or control surface | Shared by other Core consumers; scope the override. | #ffffff |
--neu-surface-2 | Secondary surfaces and alternating rows | Shared by other Core consumers; scope the override. | #f1f5f9 |
--neu-text | Main text and inherited icon color | Shared by other Core consumers; scope the override. | #0f172a |
--neu-text-muted | Secondary labels and supporting content | Shared by other Core consumers; scope the override. | #475569 |
--neu-space-1 | Spacing between content and controls | Shared by other Core consumers; scope the override. | 0.25rem |
--neu-space-3 | Spacing between content and controls | Shared by other Core consumers; scope the override. | 0.75rem |