Accessible name for the grid.
API reference
Every property, method and event on <bm-treelistview>, version 0.13.0.
Generated from the component's own source, so it cannot fall behind it.
Attributes are strings; properties carry real values. Anything typed as an array, an object or a function has to be set as a property —
grid.columns = […], notcolumns="…". Cards below are marked property only where there is no attribute.
Properties 94
Let the user select a rectangular range of cells.
Requires cellNavigation. Shift+arrow and Shift+click extend the range;
Ctrl/Cmd+C copies just that rectangle rather than whole rows.
Enable Ctrl/Cmd+C copying of the selection.
Enable dragging column headers to reorder them.
Enable column resize handles.
Emit tlvContextMenu on right-click instead of showing the browser menu.
Enable row drag and drop.
Enable the global filter.
Enable grouping, including the group panel drop target.
Enable multi-column sorting via Shift-click.
Allow multi-cell paste from the clipboard with Ctrl/Cmd+V.
Off by default: pasting writes to many cells at once, and a grid that silently accepts a spreadsheet block is a grid that can lose a lot of data to one stray keystroke. Turn it on deliberately.
Enable header-click sorting.
Enable jump-to-row when typing a printable character.
Keep an undo history of edits and pastes, reachable with Ctrl/Cmd+Z and Ctrl/Cmd+Shift+Z (or Ctrl+Y).
Announce selection, sorting and filtering changes to screen readers.
Ticking a parent's checkbox ticks every selectable descendant, and a parent shows a partial (indeterminate) state when only some of its descendants are ticked.
Defaults to false so existing applications keep the flat behaviour they
were written against. New tree applications almost always want it on.
Move focus by cell rather than by row.
With this on, the arrow keys walk cells, Tab steps through them in reading
order, and Shift+arrow extends a rectangular range. Expansion moves to the
tree column: Right opens a closed row, Left closes an open one, exactly as
the APG treegrid pattern prescribes - and +/- still work anywhere.
Off by default, because row navigation is the right model for a grid used as a list or a picker, and changing it under existing applications would be a breaking change in everything but name.
Custom cell renderers, keyed by column id. Property-only (functions cannot be expressed as HTML attributes).
Glyph for an expanded parent.
Active per-column filters.
Column definitions. Accepts an array or a JSON string, so the grid can be configured entirely from markup.
Outer drop shadow on the component.
Rules that decide how a cell or a row looks, from what it contains.
Evaluated in order; the first match wins. Merging several matches would mean arbitrating between one rule that says red and another that says green, and any answer to that is arbitrary - ordered rules put the decision with whoever wrote the list.
Accepts an array or a JSON string, so it can be set from markup.
ISO 4217 currency code. Columns may override it individually.
Fetch rows from the server instead of holding them all in memory.
The grid calls this with the user's current sort, filters, grouping and the row range it needs, and renders whatever comes back.
With a data source attached the grid stops sorting, filtering, grouping and paginating locally. Everything the request describes is the application's job. Doing both would apply each operation twice - a server returning the top 20 by revenue would have them re-sorted into the local page's own order - and produce subtly wrong pages nobody can explain.
How many rows to ask the data source for at a time.
Requests are aligned to blocks of this size rather than to the exact visible range, so scrolling by one row does not fire a new request for a range shifted by one. Aligned blocks repeat, and repeat means cacheable.
Wait this many milliseconds after the query changes before asking the server.
Typing in the filter box would otherwise fire a request per keystroke.
Row height and padding preset.
Height of a detail panel, in pixels.
A fixed height rather than auto: the row virtualiser positions rows from a uniform height, and a panel that measured itself would put every row below it in the wrong place until the measurement landed.
Render an expandable detail panel beneath a row.
Return an HTML string or an element. Returning undefined means "no
detail for this row", so a grid can have detail on some rows and not
others without a second flag.
grid.detailRenderer = ({ node }) => `<dl>...</dl>`;
Framework users can instead leave this unset, listen for
tlvDetailAttach, and mount their own component into the container
element the event carries - that is the same hook React, Angular and Vue
all understand, so the wrappers need no special case.
Writing direction. auto inherits from the page, which is almost always
what you want; set it explicitly to force one grid to differ.
Master switch for inline editing. Columns still need editable: true.
Message shown when there are no rows to display.
Show an error banner. Empty hides it.
Glyph for a collapsed parent.
Clicking anywhere on a row also toggles its expansion.
Placeholder shown in the global filter box.
Global filter text. Two-way.
Footer label before the selected row count.
Footer label before the visible row count.
Keep the tree column (and checkbox column) fixed during horizontal scroll.
Active grouping.
Prompt shown in an empty group panel.
Highlight the parts of a cell that matched the filter.
Row data. Accepts an array or a JSON string.
Glyph for a leaf row. Empty renders nothing.
Show the loading overlay and set aria-busy.
Message shown beside the loading spinner.
BCP 47 locale used for dates, numbers and text collation.
Translations for everything the grid says.
Only the keys you supply are overridden; the rest fall back to English.
Values are template strings with {named} placeholders, or - where a
count is involved - an object of CLDR plural forms (one, other, and
whichever others your language uses), selected with Intl.PluralRules
against locale.
tree nests and indents rows; list flattens the hierarchy.
Extra rows rendered above and below the viewport.
The current zero-based page. Two-way.
Show one fixed-size page at a time instead of scrolling the whole list.
Zero - the default - means no paging.
Whether a parent row displays an aggregate of the leaves beneath it, for
columns that declare an aggregate.
off- parents show only their own values.whenEmpty- a rolled-up value fills in a parent that has no value of its own, and deliberate parent-level figures are left alone.always- the roll-up wins, for datasets where parents are containers.
Save and restore user state in localStorage.
Render every row while the browser is printing, even when virtualisation is on.
A virtualised grid otherwise prints only the handful of rows that happen to be in the DOM, which produces a report that is quietly missing most of its data - the worst kind of wrong.
Row action buttons. Rendered only by a column with kind: 'actions'.
Include row action buttons in the tab order.
Label prefix for each row checkbox.
Row height in pixels while virtualised. Must match the rendered height.
Drop shadow on the hovered row.
Label for the header select-all checkbox.
The selected row in single mode. Two-way: updated as the user selects.
The selected rows in multiple/checkbox mode. Two-way.
Move the selection along with keyboard focus.
true reproduces v0.1 behaviour and is convenient for a master/detail
layout. false is better for multiple selection, where a user needs to
move focus past rows without selecting them.
How rows may be selected.
Show a per-column filter row beneath the header.
Show a column-chooser button in the header's trailing corner.
Show the global filter box.
Show the footer status bar.
Show the drop target for grouping columns, above the header.
Show the column header row.
Include the selected-row count in the footer.
Show the toolbar, which exposes the toolbar-left/toolbar-right slots.
Show a totals row at the bottom, populated from each column's aggregate.
Show shimmering placeholder rows while loading is true, instead of a
single line of text.
Primary sort column. Two-way. Mirrors sortModel[0].
Primary sort direction. Two-way. Mirrors sortModel[0].
Full multi-column sort. Takes precedence over sortColumnId when set.
Storage key used when persistState is on.
Keep the header visible while the body scrolls vertically.
Colour theme. auto follows the operating system's light/dark setting.
Leading label of the totals row.
Explicitly nominate the tree column. Defaults to the first column.
Show the full text as a tooltip on cells whose content is cut off.
Measured on hover rather than on every paint: a truncation test is a layout read, and doing one per cell per render would cost more than the feature is worth on a large grid.
How many undo steps to retain. One edit or one paste is one step.
Row-level validation, applied after the edited column's own validator accepts the value.
Receives the row as it would be once the edit commits, so a rule that
compares fields - "end date must be after start date" - can read the whole
row without reconstructing it. Return true/nothing to accept, a string
to reject, or a Promise of either for a check that needs the network.
Shown beside a cell while an async validator is running.
Where saved views are kept, in localStorage.
Unset means views live in memory only and are gone on reload - explicit rather than silently writing to a key the application did not choose.
Render only the rows near the viewport.
Render only the columns near the horizontal viewport.
Worth turning on somewhere past thirty or forty columns. Pinned columns and
a frozen tree column are always rendered whatever this says - they are
position: sticky and are meant to stay on screen exactly when their
natural offset is not.
Turn virtualisation on automatically once the pipeline produces more than
this many rows. 0 disables the automatic behaviour.
This exists because virtualisation is a trade: it makes 100,000 rows possible and makes 30 rows marginally worse (fixed row heights, an extra scroll listener). A threshold gets both.
Alternating row background.
Methods 61
Apply a saved view by id or name.
Resize one column to fit its widest visible content.
Honours the column's own minWidth and maxWidth, and emits
tlvColumnResize exactly as a drag would, so persistence and application
listeners cannot tell the two apart.
Only rendered rows are measured. With virtual scrolling on, the rows outside the viewport have no DOM to measure, so this fits what is on screen - the same thing a spreadsheet does when you double-click a column edge. Call it again after scrolling if you want a different sample.
Auto-fit every visible column in one pass.
Open the editor on a cell.
Abandon the open editor.
Drop the cell selection.
Throw the undo history away.
Called automatically whenever data arrives from outside the grid, because
an entry recorded against rows that have since been replaced would undo
to values the user never saw. See the note at the top of core/history.ts.
Delete the persisted snapshot from localStorage.
Clear the selection.
Collapse every node.
Collapse every group.
Commit the open editor.
Copy the selected rectangle to the clipboard as TSV.
Copy rows to the clipboard as TSV, which is what spreadsheets paste best.
Remove a saved view.
Serialise and download in one step.
Download the visible rows as CSV. Kept for compatibility.
Expand every expandable node.
Expand every group.
Expand every ancestor of a node so it becomes visible, then scroll to it.
Serialise the grid to a string.
The grid as a real .xlsx workbook.
Separate from exportData() because the result is binary: numbers arrive
as numbers, dates as dates, and the header row is frozen, none of which a
string can carry.
Focus a cell programmatically, and optionally extend the range to it.
The current cell selection, for applications that want to act on it.
The current column display order, by id.
Whether there is anything to undo or redo, for driving your own toolbar.
Which rows currently show a detail panel.
Where the pager is, for driving your own controls.
How many rows the pipeline produced, including group headers.
The currently selected nodes, in visible order.
A serialisable snapshot of the user's current view configuration.
Every saved view.
The nodes currently visible, in display order. Group headers are excluded.
The visible rows as CSV. Kept for compatibility; exportData is more capable.
Go to a page.
Clamped rather than rejected: a filter can remove most of the rows while the user sits on page 40, and the reasonable answer is the last page.
Move one column to a new index.
Read the clipboard and paste it.
Kept separate from pasteFromText() because reading the clipboard needs a
permission the application may not have, and may reject. An application
that already holds the text - from its own paste handler, say - should
call pasteFromText() and skip the permission entirely.
Paste a block of clipboard text into the grid.
The anchor defaults to the last cell the user edited, then to the active row's first editable column - the honest answer to "where am I?" while the grid still navigates by row rather than by cell.
Read-only cells inside the block are skipped rather than blocking the
paste, and a block that runs past the last row or column is trimmed rather
than wrapped. Both are reported in tlvPaste.
The whole paste is one undo step.
Resolves once the grid has rendered for the first time.
Use this before calling any other method on a freshly created element:
const grid = document.createElement('bm-treelistview');
document.body.appendChild(grid);
await customElements.whenDefined('bm-treelistview');
await grid.ready();
await grid.setData(columns, items);
Prefer this over Stencil's componentOnReady(), which exists only in the
lazy build and is absent from the single-file runtime.
Step forward again.
Force the pipeline to recompute.
Only needed when an application mutates a node object it passed in, rather than supplying a new array. Doing that is discouraged - it defeats the revision-based caching - but it happens, and this is the escape hatch.
Reset every column to its defined width.
Restore a snapshot produced by getState().
Save the current arrangement under a name.
Saving over a name already in use replaces it, which is what "save" means to a user - the alternative is a menu that fills with "Report (2)".
Selection and expansion are deliberately not part of a view: both describe rows, and rows come and go.
Scroll a row index into view.
Scroll a row into view by node id.
Select every selectable visible row.
Select one row by id, replacing the current selection.
Replace the per-column filters.
Set the column display order. Unlisted columns keep their relative place.
Show or hide a column.
Replace the columns and rows in one call.
Preferred over setting the props separately: it applies both in a single update, so the pipeline runs once instead of twice and there is no frame where new rows are laid out against old columns.
Set the global filter text.
Replace the grouping. Pass an empty array to ungroup.
Replace the rows, leaving the columns alone.
Replace the multi-column sort.
Replace the whole list, e.g. with views loaded from a server.
Open or close a row's detail panel.
Separate from row expansion on purpose: a row can have children and a detail panel, and collapsing the subtree should not close the panel the user opened to read.
Step back through the edit history.
Update one row's cell values in place.
Merges into the existing cells rather than replacing them, so a partial
update is safe. Cheaper than replacing the whole dataset because it reuses
every untouched branch.
Attach lazily-loaded children to a node.
Marks the node as loaded and expands it, so the spinner an application
showed on tlvLazyLoad resolves into content in one step.
Events 30
A row action button was clicked.
The focused cell moved.
Keyboard focus moved to a different row.
A cell edit was abandoned or rejected by a validator.
A cell edit was accepted. The component has already applied it optimistically;
persist it, and call setData() or updateNode() to revert on failure.
A cell editor opened.
The selected cell rectangle changed.
The per-column filters changed.
A column was dragged to a new position.
A column finished being resized.
A row was right-clicked and allowContextMenu is on.
Rows were copied to the clipboard.
The data source rejected a request.
A detail panel was rendered and is ready to be filled.
Carries the container element, so a framework can mount its own component into it rather than handing the grid an HTML string.
A detail panel was opened or closed.
The global filter text changed.
The grouping changed.
The undo/redo stack moved.
Emitted on every commit, undo, redo and clear, so an application can keep its own Undo button's enabled state in step without polling.
A node with unloaded children was expanded. Respond by fetching them and
calling updateNodeChildren(node.id, children).
A node was collapsed.
A row was dropped onto another row. The application performs the move.
A node was expanded.
The page changed.
A clipboard block was pasted into the grid.
A row was double-clicked, or activated with Enter.
A window of rows was painted. Useful for telemetry and tests.
The selection changed. Detail is a node in single mode, an array otherwise.
The sort changed.
Any persistable state changed. Fires whether or not persistState is on.
The saved views list changed.
CSS parts
The component uses Shadow DOM, so host page CSS cannot reach inside it. ::part() is the
sanctioned way through.
bm-treelistview::part(header-cell) { text-transform: uppercase; }
bm-treelistview::part(row-selected) { outline: 2px solid #2563eb; }
| Part | |
|---|---|
band-cell | |
band-title | |
body | |
cell | |
cell-content | |
checkbox | |
checkbox-cell | |
checkbox-header-cell | |
column-menu | |
column-menu-button | |
column-menu-item | |
demo-badge | |
demo-limit-notice | |
detail-panel | |
detail-row | |
editor-checking | |
editor-error | |
editor-wrap | |
empty | |
error | |
expander | |
expander-icon | |
filter-bar | |
filter-cell | |
filter-input | |
filter-operator | |
filter-row | |
filter-value | |
footer | |
footer-item | |
footer-mode | |
group-aggregates | |
group-cell | |
group-chip | |
group-expander | |
group-heading | |
group-label | |
group-panel | |
group-row | |
header | |
header-bands | |
header-cell | |
header-title | |
loading | |
node-icon | |
pager | |
pager-button | |
resize-handle | |
row | |
scroll | |
select-all-checkbox | |
shell | |
skeleton | |
sort-indicator | |
table | |
toolbar | |
toolbar-button | |
toolbar-left | |
toolbar-right | |
totals-cell | |
totals-row |
Slots
| Slot | |
|---|---|
empty | |
error | |
footer | |
loading | |
toolbar-left | |
toolbar-right |
CSS custom properties
Prefer these over ::part() where they cover what you need — they survive upgrades that a
selector into internal structure may not. See Theming.
| Property |
|---|