Skip to main content
Neural UIv2.0.0Documentation
View v1 GitHub

Table

Display flat records, then add selection, sorting or editing while your application owns the data and state.

Category
Data and hierarchy
Import
@neural-ui/core/table
Selector
neu-table
import { NeuTableComponent } from '@neural-ui/core/table';

Display data

Pass records through data, describe visible fields with columns, and provide a stable rowKey. The key identifies a record across updates; do not use its current row position. This example supplies three customer orders and their column definitions.

Use Table for flat records. Choose TreeTable when rows have parentโ€“child relationships, or Tree when hierarchy does not need columns.

Display data
Customer
Amount (โ‚ฌ)
Region
Atlas 240 EU
Birch 180 US
Cedar 420 EU

Configurator

Try appearance, selection, sorting, global search, column filters, pagination, editing, row details and column actions. Each option updates the preview and its configuration code. Expand a group to explore its controls. Options that depend on another feature become available when you enable it.

Configurator

Preview

6 rows; page 1; 0 selected; sort: none
Atlas 240 EU
Birch 180 US
Cedar 420 EU

Your configuration code

This snippet updates when you change options. The Code tab includes the complete component, data and templates.

template.html
<neu-table
  [data]="records()"
  [columns]="columns()"
  [rowKey]="rowKey"
  [appearance]='{
    "density": "normal",
    "borders": "rows",
    "striped": false,
    "stickyHeader": false,
    "responsive": "contained-scroll"
  }'
  [selectionOptions]='{
    "mode": "none"
  }'
  [sortOptions]='{
    "mode": "single",
    "removable": true,
    "defaultDirection": "asc",
    "resetPageOnChange": true
  }'
  [filterOptions]='{
    "surfaces": [],
    "globalFields": [],
    "predicates": {},
    "debounceMs": 0,
    "commit": "immediate"
  }'
  [paginationOptions]='{
    "enabled": true,
    "pageSizeOptions": [
      3,
      6,
      10
    ],
    "position": "bottom",
    "report": "range",
    "showPageJump": false
  }'
  [columnOptions]='{
    "reorderable": false,
    "resizable": false,
    "hideable": false,
    "pinnable": false
  }'
  [editingOptions]='{
    "mode": "none",
    "activation": "click",
    "commitOnBlur": false
  }'
  [expansionOptions]='{
    "enabled": false,
    "toggleOnRowClick": false
  }'
  [interactionOptions]='{
    "navigation": "native",
    "wrapFocus": false,
    "announceChanges": true
  }'
  [query]="query()"
  (queryChange)="query.set($event)"
  [selection]="selection()"
  (selectionChange)="selection.set($event.next)"
  [layout]="layout()"
  (layoutChange)="layout.set($event.next)"
  [editState]="editState()"
  (editStateChange)="editState.set($event.next)"
  (editCommit)="save($event)"
  [expandedKeys]="expanded()"
  (expandedKeysChange)="expanded.set($event.next)"
>
  <!-- Include the editor and detail templates from the complete example. -->
</neu-table>

Feature examples

Explore one feature at a time. Each example has its own state and complete source. The selected feature is included in the URL so you can share it or return to it directly.

Selection

Enable selection with selectionOptions and supply the selected keys through selection. selectionChange proposes next; applying it updates the checkboxes. The component does not replace your input.

This example selects loaded records only. Use all-matching selection only when your application can preserve the query scope and excluded keys across server pages.

Selection
Customer
Amount (โ‚ฌ)
Region
Atlas 240 EU
Birch 180 US
Cedar 420 EU

Selected ids: โ€”

Accessibility and keyboard

Core supplies table structure and controls for enabled features. Your application supplies meaningful column headings, useful cell content and names for custom template controls. Keep interactive cell content keyboard reachable and do not communicate selection or errors by color alone.

Use focusCell when application navigation needs a specific rendered cell; check its boolean result. scrollTo can bring a row into view. Test custom editors, row details and remote loading messages as part of your application's keyboard flow.

Key
Action
Tab / Shift+Tab Move between enabled controls and interactive template content.
Enter / Space Activate the focused native control, such as sorting or expansion.
Enter / Escape In the example editor, commit or cancel the draft.

API

Inputs configure the table and supply application-owned state. Change outputs propose updates; they are not two-way models. Expand the referenced interfaces to inspect every option and event payload. Public methods act on the current table instance; they do not replace data or perform networking.

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
appearanceNeuTableAppearance{ density: 'normal', borders: 'rows', striped: false, stickyHeader: false, responsive: 'contained-scroll', }[appearance]Density, borders, stripes, sticky heading and contained-scroll or stacked responsive layout.
columnOptionsNeuTableColumnOptions{}[columnOptions]Opt into column resizing, reordering, hiding or pinning. All controls are off by default. Apply layoutChange.next to layout to accept changes.
columnsreadonly NeuTableColumn<T, F>[][][columns]Column ids, headings, value fields and optional sorting, filtering or editing descriptors.
datareadonly T[][][data]Records to render. In remote mode supply the response rows, not an assumed complete dataset.
dataModeNeuTableDataMode'client'[dataMode]client processes loaded records; remote delegates data loading to the application.
editingOptionsNeuTableEditingOptions<T, K, F>{ mode: 'none' }[editingOptions]Editing mode, activation gesture, optional validation and blur commit behavior.
editStateNeuTableEditState<K>{ kind: 'none', }[editState]Applied active cell or row editing session, or kind none.
expandedKeysreadonly K[][][expandedKeys]Applied keys whose row-detail regions are expanded.
expansionOptionsNeuTableExpansionOptions<T>{ enabled: false, toggleOnRowClick: false, }[expansionOptions]Enable details, restrict expandable rows and optionally toggle on row click.
filterOptionsNeuTableFilterOptions<T, F>{ surfaces: [], globalFields: [], predicates: {}, debounceMs: 0, commit: 'immediate', }[filterOptions]Filter surfaces, global fields, custom predicates, debounce and commit strategy.
groupingNeuTableGroupingState<F> | nullnull[grouping]Applied grouping fields and expanded group ids; null disables grouping.
groupingOptionsNeuTableGroupingOptions<T, F>{ mode: 'subheader', scope: 'loaded', }[groupingOptions]Loaded-data group rendering mode and optional value/aggregate functions.
interactionOptionsNeuTableInteractionOptions{ navigation: 'native', wrapFocus: false, announceChanges: false, }[interactionOptions]Native, row or cell keyboard navigation, focus wrapping and change announcements.
labelsNeuTableLabels{ ariaLabel: 'Data table', empty: 'No data', loading: 'Loading', error: 'Unable to load data', retry: 'Retry', selection: 'Selection', pagination: 'Pagination', }[labels]Localized table control and state messages.
layoutNeuTableLayoutState{ order: [], hidden: [], widths: {}, pinnedStart: [], pinnedEnd: [], }[layout]Applied column order, visibility, widths and start/end pinning.
metadataNeuTableMetadata{ totalItems: null, loading: false, error: null, queryRevision: 0, appliedRequestId: null, }[metadata]Remote total, loading/error state and response identity (queryRevision and appliedRequestId).
paginationOptionsNeuTablePaginationOptions{ enabled: false, pageSizeOptions: [], position: 'bottom', report: 'none', showPageJump: false, }[paginationOptions]Enable and position pagination, choose page sizes and the visible report.
queryNeuTableQuery<F>{ page: 0, pageSize: 25, search: '', sort: [], filters: null, }[query]Applied page, page size, search, sort and filter expression. Apply queryChange to accept changes.
rowKeyNeuRowKey<T, K>Required[rowKey]Required function returning a stable unique key for each record.
rowOptionsNeuTableRowOptions<T, K>{ reorderable: false, }[rowOptions]Row disabled state, classes, pinning and reorder availability.
rowTrackByNeuRowTrackBy<T> | undefinedNo default[rowTrackBy]Optional Angular row identity function; it does not replace rowKey's state identity.
selectionNeuTableSelection<K, F>{ kind: 'keys', keys: [], }[selection]Applied selected keys or all-matching scope with exclusions.
selectionOptionsNeuTableSelectionOptions<T>{ mode: 'none' }[selectionOptions]Selection mode, indicators, row-click behavior, modifiers, ranges and select-all scope.
sortOptionsNeuTableSortOptions{ mode: 'single', removable: true, defaultDirection: 'asc', resetPageOnChange: true, }[sortOptions]Single or multiple sorting, default direction, removal and page-reset behavior.
virtualizationOptionsNeuTableVirtualizationOptions{ enabled: false }[virtualizationOptions]Enable fixed-height row virtualization with itemSize and overscan; remote requests may use requestStep.

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
dataRequestNeuTableDataRequest<F>(dataRequest)="onDataRequest($event)"Requests application-owned loading with query, revisions, request id and optional range.
editCancelNeuTableEditCancel<T, K>(editCancel)="onEditCancel($event)"Reports cancellation of an editing session; do not persist a draft.
editCommitNeuTableEditCommit<T, K, F>(editCommit)="onEditCommit($event)"Emitted when an edit is saved. Contains key (row) and changes (field and new value). Validate and apply changes to data in your handler; Table does not mutate or persist your records.
editStateChangeNeuTableEditChange<K>(editStateChange)="onEditStateChange($event)"Emits next when an editing session starts or ends. Update editState with $event.next to open or close the editor.
expandedKeysChangeNeuTableExpandedKeysChange<K>(expandedKeysChange)="onExpandedKeysChange($event)"Emits next with expanded detail keys and the changed row. Update expandedKeys with $event.next.
exportRequestNeuTableExportRequest<F>(exportRequest)="onExportRequest($event)"Requests an application-handled export when it cannot be generated from the available data.
featureErrorNeuTableFeatureError(featureError)="onFeatureError($event)"Reports the failed feature, its cause and whether recovery is possible.
groupingChangeNeuTableGroupingChange<F>(groupingChange)="onGroupingChange($event)"Emits next when a group expands or collapses. Update grouping with $event.next to retain its state.
layoutChangeNeuTableLayoutChange(layoutChange)="onLayoutChange($event)"Emits next with column order, widths, visibility and pinning. Update layout with $event.next.
queryChangeNeuTableQuery<F>(queryChange)="onQueryChange($event)"Emits the complete query when the page, search, sort or filters change. Update query with $event: query.set($event).
rangeChangeNeuTableRangeChange(rangeChange)="onRangeChange($event)"Reports visible/rendered virtual ranges and the cause of the change.
rowActionNeuTableRowAction<T, K>(rowAction)="onRowAction($event)"Reports activation of a row action with its row and key.
rowReorderNeuTableRowMove<K>(rowReorder)="onRowReorder($event)"Proposes a row move. Your application changes the record order after accepting it.
selectionChangeNeuTableSelectionChange<T, K, F>(selectionChange)="onSelectionChange($event)"Emits next with the new selection, added or removed keys and the source. Update selection with $event.next: selection.set($event.next).

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
NeuTableCaptionDirective

Above the table

View example
Public template directive (entrypoint)

A heading identifies this data set.

ng-template[neuTableCaption]

Context used: โ€”

NeuTableCellDirective

Body cell

View example
Public template directive (entrypoint)

Customer names or planned hours use your own presentation.

ng-template[neuTableCell]

Context used: $implicit

NeuTableEditorDirective

Custom cell editor

View example
Public template directive (entrypoint)

Use the rowโ€™s pencil, edit the customer, then save or cancel using its actions.

ng-template[neuTableEditor]

Context used: valueSignal, setValue, commit, cancel, errors

NeuTableEmptyDirective

Empty data area

View example
Public template directive (entrypoint)

Choose Empty in the example to see this message.

ng-template[neuTableEmpty]

Context used: โ€”

NeuTableErrorDirective

Failed data area

View example
Public template directive (entrypoint)

Choose Error, then use Retry to request the data again.

ng-template[neuTableError]

Context used: retry

NeuTableFilterDirective

Column filter in a row or menu

View example
Public template directive (entrypoint)

Type a customer name to filter the rows. Clear restores them; apply and clear propose queryChange, which the application accepts.

ng-template[neuTableFilter]

Context used: column, sort, value, rule, apply(value, rule?), clear()

NeuTableFooterDirective

Column footer

View example
Public template directive (entrypoint)

A label appears below the data in the specified column.

ng-template[neuTableFooter]

Context used: โ€”

NeuTableGroupFooterDirective

After each group

View example
Public template directive (entrypoint)

The group footer counts its records.

ng-template[neuTableGroupFooter]

Context used: rows

NeuTableGroupHeaderDirective

Before each group

View example
Public template directive (entrypoint)

Enable grouping to see the region and number of orders.

ng-template[neuTableGroupHeader]

Context used: value, rows

NeuTableHeaderDirective

Column heading

View example
Public template directive (entrypoint)

The heading uses the column label with custom markup.

ng-template[neuTableHeader]

Context used: column

NeuTableLoadingDirective

Loading data area

View example
Public template directive (entrypoint)

Choose Loading to display a status message.

ng-template[neuTableLoading]

Context used: โ€”

NeuTablePaginatorDirective

Enabled top/bottom paginator

View example
Public template directive (entrypoint)

Previous and Next use the applied page and filtered total. Page is zero-based; remote totals and pageCount can be null. Actions propose queryChange without mutating application state.

ng-template[neuTablePaginator]

Context used: page, pageSize, humanPage, pageCount, total, rangeStart, rangeEnd, canFirst, canPrevious, canNext, canLast, pageSizeOptions, changePage(page), changePageSize(size)

NeuTableRowDetailDirective

Below an expanded row

View example
Public template directive (entrypoint)

Expand a row to see its order details.

ng-template[neuTableRowDetail]

Context used: $implicit

NeuTableSummaryDirective

Below the table

View example
Public template directive (entrypoint)

An application-owned total accompanies the table.

ng-template[neuTableSummary]

Context used: โ€”

NeuTableToolbarDirective

Before the rows

View example
Public template directive (entrypoint)

Instructions or application actions accompany the data.

ng-template[neuTableToolbar]

Context used: โ€”

Each example demonstrates a different template. Switch between Demo and Code to inspect its implementation, imports and state.

Table caption

NeuTableCaptionDirective

Table caption
Customer orders
Customer
Amount (โ‚ฌ)
Region
Atlas 240 EU
Birch 180 US
Cedar 420 EU

Table actions

NeuTableToolbarDirective

Table actions
Manage orders
Customer
Amount (โ‚ฌ)
Region
Atlas 240 EU
Birch 180 US
Cedar 420 EU

Result summary

NeuTableSummaryDirective

Result summary
Customer
Amount (โ‚ฌ)
Region
Atlas 240 EU
Birch 180 US
Cedar 420 EU

Displayed orders: 3 ยท Total amount: 840 โ‚ฌ

Column header

NeuTableHeaderDirective

Column header
Customer Business account
Amount (โ‚ฌ)
Region
Atlas 240 EU
Birch 180 US
Cedar 420 EU

Cell content

NeuTableCellDirective

Cell content
Customer
Amount (โ‚ฌ)
Region
AtlasOrder #101 240 EU
BirchOrder #102 180 US
CedarOrder #103 420 EU

Custom filter

NeuTableFilterDirective

Custom filter
Customer
Amount (โ‚ฌ)
Region
Atlas 240 EU
Birch 180 US
Cedar 420 EU

Custom editor

NeuTableEditorDirective

Custom editor

Use the rowโ€™s pencil to edit its customer. Save changes or cancel using that rowโ€™s actions.

Customer
Amount (โ‚ฌ)
Region
Edit
Atlas 240 EU
Birch 180 US
Cedar 420 EU

Row detail

NeuTableRowDetailDirective

Row detail
Expansion
Customer
Amount (โ‚ฌ)
Region
Atlas 240 EU
Order detail #101
Amount (โ‚ฌ)
Region
240 EU
Birch 180 US
Cedar 420 EU

Group header

NeuTableGroupHeaderDirective

Group header

Expand a region to see its orders.

Customer
Amount (โ‚ฌ)
Region

Empty state

NeuTableEmptyDirective

Empty state
Customer
Amount (โ‚ฌ)
Region
No orders yet

New orders will appear here.

Loading state

NeuTableLoadingDirective

Loading state
Customer
Amount (โ‚ฌ)
Region
Loading ordersโ€ฆ

Retrieving your results.

Error state and retry

NeuTableErrorDirective

Error state and retry
Customer
Amount (โ‚ฌ)
Region

Custom pagination

NeuTablePaginatorDirective

Custom pagination
Customer
Amount (โ‚ฌ)
Region
Atlas 240 EU
Birch 180 US
Cedar 420 EU

Public methods

Name
Contract
exportexport(request: NeuTableExportRequest<F>): Promise<NeuTableExportOutcome>;

Create an export from the requested scope. Inspect the outcome; a delegated export requires application handling. The Export example shows the complete call and result.

example.ts
await table()?.export({ format: 'csv', scope: 'view' });
focusCellfocusCell(target: { readonly key: K; readonly columnId: string; }): boolean;

Move focus to a rendered cell by stable row key and column id. The boolean result reports whether focus could be placed.

example.ts
table()?.focusCell({ key: 101, columnId: 'customer' });
retryDataretryData(): void;

Request another attempt for the current remote query. Handle dataRequest in the application; this method does not fetch data itself.

example.ts
table()?.retryData();
scrollToscrollTo(target: { readonly index?: number; readonly key?: K; }): Promise<void>;

Scroll to a row by index or key. Await completion when a subsequent action depends on the row being visible.

example.ts
await table()?.scrollTo({ key: 101 });

Public Types

Open a type to inspect its definition and interface fields.

Appearance and tokens

Use appearance to choose density, borders, stripes, sticky headings and responsive layout. The configurator above demonstrates these options independently of column actions and keyboard navigation. Public CSS tokens let you customize surfaces, text, spacing and focus within a scope.

Specific tokens

Token
Purpose
State / variant
Default / source
Fallback
--neu-table-cell-block Vertical cell padding at normal density. density="normal" 0.625remRoot declarationNo token alias
--neu-table-cell-block-compact Vertical cell padding at compact density. density="compact" 0.375remRoot declarationNo token alias
--neu-table-cell-block-relaxed Vertical cell padding at relaxed density. density="relaxed" 0.875remRoot declarationNo token alias
--neu-table-cell-inline Horizontal cell padding. Table cells var(--neu-space-3)Root declaration--neu-space-3
--neu-table-group-background Background of group heading rows. Group heading color-mix(in srgb, currentColor 4%, transparent)Root declarationNo token alias
--neu-table-header-height Header cell height; wrapped content can require more room. Column heading 44pxRoot declarationNo token alias
--neu-table-max-height Maximum non-virtual viewport height; taller data scrolls inside it. Non-virtual viewport 480pxRoot declarationNo token alias
--neu-table-selected-background Selected-row background, taking precedence over stripes. Selected row color-mix(in srgb, currentColor 9%, transparent)Root declarationNo token alias
--neu-table-space-sm Spacing in table controls and action groups. Controls and actions var(--neu-space-2)Root declaration--neu-space-2
--neu-table-space-xs Small gaps between adjacent table controls. Controls and actions var(--neu-space-1)Root declaration--neu-space-1
--neu-table-state-block Vertical padding of empty, loading and error content. Empty / loading / error var(--neu-space-6)Root declaration--neu-space-6
--neu-table-sticky-offset Top offset of the header when stickyHeader is enabled. stickyHeader 0pxRoot declarationNo token alias
--neu-table-stripe-background Alternating-row background when striped is enabled. striped color-mix(in srgb, currentColor 4%, transparent)Root declarationNo token alias
--neu-table-virtual-block-size Height of the virtualized scroll viewport. Virtualization 24remRoot declarationNo 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-border-hover Control borders on hover Shared by other Core consumers; scope the override. rgba(15, 23, 42, 0.16)
--neu-focus-color Visible keyboard-focus outline Shared by other Core consumers; scope the override. var(--neu-primary)
--neu-primary Brand color for active controls and emphasis Shared by other Core consumers; scope the override. #007aff
--neu-primary-soft Subtle selected or active surface Shared by other Core consumers; scope the override. var(--neu-primary-50)
--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