import { Component } from '@angular/core';
import { WrTable, WrTableCell, WrTableExpand, WrTableGroupHeader } from 'ngwr/table';
@Component({ imports: [WrTable, WrTableCell, WrTableExpand, WrTableGroupHeader] })
export class MyComponent {}Table
Rows of data with sorting, filtering, paging and custom cells.
Installation
Import the class, and @use the entry point in your global styles: without it the component renders unstyled.
Basic usage
Columns are a record keyed by row property; rows are plain objects.
<wr-table [columns]="columns" [items]="rows" />Sort + filter + custom cell
[(sort)] holds the sort, filterChange reports the filter, and [wrTableCell] replaces a column's cells.
<wr-table [columns]="columns" [items]="rows" [(sort)]="sort" (filterChange)="onFilter($event)">
<ng-template wrTableCell="role" let-value>
<wr-tag [color]="value === 'admin' ? 'danger' : 'info'">{{ value }}</wr-tag>
</ng-template>
</wr-table>One column carrying both controls
One column can have both sortable and filterItems. With a mouse, both controls are below the 24px minimum target size.
const columns: WrTableColumns = {
name: { title: 'Name', sortable: true },
email: { title: 'Email' },
role: {
title: 'Role',
sortable: true,
filterItems: [
{ title: 'Admin', value: 'admin' },
{ title: 'Editor', value: 'editor' },
{ title: 'Viewer', value: 'viewer' },
],
},
};
<wr-table [columns]="columns" [items]="rows()" [(sort)]="sort" (filterChange)="onFilter($event)" />Sorting is state, not a sort
The table never reorders items: sort them yourself from sort().
protected readonly sort = signal<readonly WrTableSortState[]>([]);
protected readonly rows = computed(() => {
const rules = this.sort();
if (rules.length === 0) return this.source();
return [...this.source()].sort((a, b) => {
for (const { key, direction } of rules) {
if (!direction) continue;
const cmp = String(a[key] ?? '').localeCompare(String(b[key] ?? ''));
if (cmp !== 0) return direction === 'asc' ? cmp : -cmp;
}
return 0;
});
});
// Server-side, send it with the request instead.
effect(() => {
const [primary] = this.sort();
this.load({ sortBy: primary?.key, order: primary?.direction });
});sortis an array, one entry per sorted column; the first entry is the primary key.- Only the primary column announces
aria-sort. With several sorted columns, each shows its place in the order as a number. Since v15. - Only the sort button sorts, not the whole header. In tests,
getSortDirection()readsaria-sort;getSortIndicator()andgetSortOrder()read every sorted column. - Sorting does not reset
page. Reset it in your sort handler if you want.
What a cell template can read
let-value is the cell value and let-row="item" the row. A bare let-row binds the value again.
<ng-template wrTableCell="role" let-value let-row="item" let-col="column">
{{ col.title }}: {{ value }} — {{ row.email }}
</ng-template>Row actions
Give the action column a key no row property uses and an empty title, and read the row with let-row="item".
const columns: WrTableColumns = {
name: { title: 'Name' },
email: { title: 'Email' },
actions: { title: '', width: 96 },
};
<wr-table [columns]="columns" [items]="rows">
<ng-template wrTableCell="actions" let-row="item">
<wr-btn size="sm" color="danger" outlined (click)="remove(row)">Delete</wr-btn>
</ng-template>
</wr-table>Loading, empty — and error
[loading] shows a spinner and emptyLabel the empty text. There is no error input: show a <wr-alert> beside the table.
<wr-table [columns]="columns" [items]="rows()" [loading]="loading()" emptyLabel="No users yet" />
<!-- An error goes beside the table. -->
@if (error(); as message) {
<wr-alert type="danger" title="Could not load users" [message]="message" />
}
<wr-table [columns]="columns" [items]="rows()" [loading]="loading()" />Pagination
[pageSize] pages the rows and adds a pager. Add [total] to page on the server.
<wr-table [columns]="columns" [items]="rows" [pageSize]="5" [(page)]="page" />Server-side paging — what to bind, what fires
With [total], the table shows items as given. Listen to (pageChange), or bind [(page)].
<wr-table
[columns]="columns"
[items]="pageRows()"
[total]="total()"
[pageSize]="20"
[page]="page()"
(pageChange)="onPage($event)"
[(sort)]="sort"
/>protected onPage(page: number): void {
this.page.set(page);
this.load(); // limit: 20, skip: (page - 1) * 20
}[pageSize]is still required: without it no pager renders.- The pager has no range label or size changer. For those, leave
pageSizeat 0 and add your own<wr-pagination>.
Virtual scroll
Set virtualScroll and viewportHeight; all rows share one height.
<wr-table
virtualScroll
[rowHeight]="41"
[viewportHeight]="440"
[columns]="columns"
[items]="rows"
/>- Grouping, tree rows, expandable rows,
responsiveand a pager turn it off. - For SSR, set
rowHeight: 41 atmd, 32 atsm, 48 atlg, 55 attouch.
Row selection
Set rowSelection to 'multiple' or 'single', rowKey to a property or function, and bind [(selection)] to the selected keys.
<wr-table
rowSelection="multiple"
rowKey="email"
[(selection)]="selected"
[columns]="columns"
[items]="rows"
/>- Each row's checkbox is named by an action word and the row's first cell: "Select row Roman". The same goes for the expand and tree toggles, and the group controls take the group's label. Since v15.
selectRowLabeland the other*Labelinputs set the action word.
Expandable rows
<ng-template wrTableExpand let-row> adds a detail panel per row. Set rowKey and bind [(expanded)].
<wr-table rowKey="email" [(expanded)]="expanded" [columns]="columns" [items]="rows">
<ng-template wrTableExpand let-row>
<p>{{ row.name }} — {{ row.email }}</p>
</ng-template>
</wr-table>Summary row
A column's summary adds a footer row: 'sum', 'avg', 'count', 'min', 'max', or a function of the rows and a context.
const columns: WrTableColumns = {
product: { title: 'Product', summary: () => 'Total' },
price: { title: 'Price', summary: 'avg' },
qty: { title: 'Qty', summary: 'sum' },
};Row grouping
Set groupBy to a property or function; [(collapsedGroups)] holds the collapsed groups. Grouping runs after paging, so sort by the same key or set pageSize to 0.
<wr-table
groupBy="role"
[(collapsedGroups)]="collapsed"
[columns]="columns"
[items]="rows"
/>Group subtotals
groupSummary adds a subtotal row under each group. A summary function's second argument says which row it computes: scope is 'group' or 'total'. Set pageSize to 0 with it, since the footer totals every row.
const columns: WrTableColumns = {
// One function feeds the group rows and the grand total; the context says which.
region: { title: 'Region', summary: (rows, { scope }) => (scope === 'group' ? 'Subtotal' : 'Total') },
rep: { title: 'Rep' },
deals: { title: 'Deals', summary: 'sum' },
revenue: { title: 'Revenue', summary: 'sum' },
};
<wr-table groupBy="region" groupSummary [columns]="columns" [items]="rows" />Custom group header
<ng-template wrTableGroupHeader> replaces the group label. It gets value, count, collapsed, toggle() and more.
<wr-table groupBy="role" [columns]="columns" [items]="rows">
<ng-template wrTableGroupHeader let-value let-count="count">
<wr-tag color="primary" transparent>{{ value }}</wr-tag>
<small>{{ count }} users</small>
</ng-template>
</wr-table>CSV export
exportCsv() downloads the current items, so one page in server mode. toCsv() returns the text; { selectedOnly: true } exports the selection.
<wr-table #table [columns]="columns" [items]="rows" />
<wr-btn (click)="table.exportCsv({ filename: 'users.csv' })">Export CSV</wr-btn>Pinned columns
pin: 'left' or pin: 'right' keeps a column in place while the rest scrolls sideways.
const columns: WrTableColumns = {
name: { title: 'Name', pin: 'left' },
email: { title: 'Email' },
role: { title: 'Role' },
// …more columns in between…
status: { title: 'Status', pin: 'right' },
};Resizable columns
resizable: true adds a drag handle to the header; width sets the starting width in px.
const columns: WrTableColumns = {
name: { title: 'Name', resizable: true },
email: { title: 'Email', resizable: true, width: 240 },
role: { title: 'Role', resizable: true },
};Reorderable columns
With reorderable, headers can be dragged; [(columnOrder)] holds the order. Pinned columns do not move.
<wr-table reorderable [(columnOrder)]="order" [columns]="columns" [items]="rows" />Narrow container (stacked cards)
With responsive, rows become labelled cards when the table's own box is narrow.
<div style="width: 360px"><wr-table responsive [columns]="columns" [items]="rows" /></div>Tree rows
Set childrenKey and items become the roots. rowKey and [(expanded)] work as for expandable rows; treeColumn picks the indented column.
<wr-table
rowKey="id"
childrenKey="reports"
treeColumn="name"
rowSelection="multiple"
[columns]="orgColumns"
[items]="org"
[(expanded)]="openRows"
[(selection)]="picked"
/>- The rows take the keyboard: Tab reaches one row, Up and Down move, Right opens a row or steps into it, Left closes it or climbs to the parent, Home and End jump. Enter and Space select the row when
rowSelectionis set. Tab moves on into the row's own controls. Since v15. pageSizepages the roots. Select all selects only the rows on screen.- Tree rows do not combine with
groupBy,[wrTableExpand]orvirtualScroll.
Types
type WrTableColumns = Record<string, WrTableColumn>;
interface WrTableColumn {
title: string;
sortable?: boolean;
filterItems?: readonly WrTableFilterItem[];
pin?: 'left' | 'right';
resizable?: boolean;
width?: number;
summary?: WrTableSummary;
class?: WrClassInput;
}
interface WrTableFilterItem<T = unknown> {
title: string;
value: T;
selected?: boolean;
}
interface WrTableSortState {
key: string;
direction: 'asc' | 'desc' | null;
}
interface WrTableCsvOptions {
filename?: string;
selectedOnly?: boolean;
delimiter?: string;
escapeFormulas?: boolean;
}
interface WrTableGroupContext {
value: unknown;
label: string;
rows: readonly Record<string, unknown>[];
count: number;
collapsed: boolean;
index: number;
toggle: () => void;
}
type WrTableSummary =
| 'sum' | 'avg' | 'count' | 'min' | 'max'
| ((rows: readonly Record<string, unknown>[], context: WrTableSummaryContext) => unknown);
type WrTableSummaryContext =
| { scope: 'total'; group: null }
| { scope: 'group'; group: WrTableGroupContext };| Name | Description | Type | Default |
|---|---|---|---|
WrTableColumns | Column map — keys are row property names. | Record<string, WrTableColumn> | — |
WrTableColumn | A single column definition. | interface | — |
titlerequired | Heading shown in the header. | string | — |
sortable | Show a clickable sort indicator. | boolean | false |
filterItems | Non-empty list shows a filter dropdown. | readonly WrTableFilterItem[] | — |
pin | Freeze the column against the 'left' or 'right' edge while the rest scrolls. | 'left' | 'right' | — |
resizable | Add a drag handle on the header edge to resize. | boolean | false |
width | Initial column width in px (overridden by a drag). | number | — |
summary | Footer aggregate — 'sum' / 'avg' / 'count' / 'min' / 'max', or (rows, context) => value. | WrTableSummary | — |
class | Extra classes on this column's header cell and every body cell under it. Not the summary row. | WrClassInput | — |
WrTableFilterItem | One entry in a column filter. | interface | — |
titlerequired | Visible label. | string | — |
valuerequired | Value matched against the cell. | T | — |
selected | Pre-check the entry. | boolean | false |
WrTableSortState | Emitted by (sortChange). | { key: string; direction: WrTableSortDirection } | — |
WrTableCsvOptions | Argument of exportCsv() / toCsv(). | interface | — |
filename | Download filename. | string | 'table.csv' |
selectedOnly | Export only the selected rows (needs rowSelection). | boolean | false |
delimiter | Field delimiter — use ';' where Excel expects it. | string | ',' |
escapeFormulas | Prefix values starting with = + - @ so spreadsheets keep them as text. | boolean | true |
WrTableGroupContext | Passed to a wrTableGroupHeader template (also the built-in band context). | interface | — |
value | The value groupBy returned; also the collapse identity. | unknown | — |
label | Default label — String(value), or '—' for empty. | string | — |
rows | The group's rows on the current page. | readonly Record<string, unknown>[] | — |
count | rows.length — page-scoped row count. | number | — |
collapsed | Whether the group is currently collapsed. | boolean | — |
index | 0-based index of the group on the current page. | number | — |
toggle | Collapse / expand this group. | () => void | — |
WrTableSummaryContext | A summary function's second argument: which footer row it computes. Since v15. | { scope: 'total'; group: null } | { scope: 'group'; group: WrTableGroupContext } | — |
scope | 'total' for the footer row, 'group' for a subtotal under a group. | 'total' | 'group' | — |
group | The group being subtotalled; null for the total. | WrTableGroupContext | null | — |
API
| Name | Description | Type | Default |
|---|---|---|---|
columnsrequired | Column definitions, keyed by row property name. | WrTableColumns | — |
items | Row items. null/undefined renders the empty state; use [loading] for the spinner. Typed WrTableRow (= object) rather than Record<string, unknown>, so an array of an interface binds as readily as an array of a type — see {@link WrTableRow} for why those two are not the same to TypeScript. | readonly WrTableRow[] | null | undefined | null |
loading | Show the loading spinner overlay. | boolean | false |
responsive | Collapse each row to a labelled card when the table's own box is too narrow for columns (a container query on its own width, not the viewport). Every cell shows its column title as a label. | boolean | false |
reorderable | Enable drag-to-reorder on the column headers. | boolean | false |
columnOrder | Two-way bindable column order — an array of column keys. Reflects and drives the header order: the table falls back to declaration order for any key not listed, and updates this on drag. Bind it to persist a user's arrangement. | readonly string[] | [] |
rowSelection | Row selection with a leading checkbox column — 'multiple' adds a select-all header; 'single' keeps one row selected. | 'single' | 'multiple' | null | null (off) |
rowClass | Extra CSS classes per body row, from the row and its drawn index. The <tr> is ngwr's own element and there is no template slot that renders as one, so this is the only way to mark a row — overdue, unsaved, over budget — without a rule that has to re-derive the condition in CSS. It does NOT touch the detail row an expanded row opens, the group header or the summary row: each of those is a sibling <tr> with its own meaning, and a row predicate that painted them too would stripe a table's totals. | WrTableRowClass | null | null |
rowKey | How to identify a row for selection — a property name or a function. Unset uses the row object itself (fine for a stable row array). | string | ((row: Record<string, unknown>) => unknown) | null | null |
selection | Two-way bindable selected row keys. | readonly unknown[] | [] |
expanded | Two-way bindable expanded row keys (needs a [wrTableExpand] template). | readonly unknown[] | [] |
groupBy | Group rows under collapsible band headers — a row property name, or a function returning the group value. null (default) renders the table exactly as before. Grouping runs AFTER pagination: it buckets the rows on the current page in first-appearance order (it never re-sorts your data — same contract as [(sort)]), so a group straddling a page boundary shows a band on both pages, and per-group counts / subtotals are page-scoped. Sort items by the same key upstream to keep groups whole, or pair with pageSize = 0. Group values are compared by identity (Map/Set, SameValueZero) — return a primitive, exactly as for rowKey. Objects / Dates bucket by reference. | string | ((row: Record<string, unknown>) => unknown) | null | null |
childrenKey | Render the rows as a hierarchy: names the property (or computes the array) holding each row's children. items then means the ROOTS, and the forest is flattened depth-first into the same <tbody> — child rows are ordinary <tr>s going through the same cell loop, so column pin / resize / drag-reorder and [wrTableCell] templates keep working at every depth. Open state reuses the expanded model and row identity reuses rowKey, so a tree needs no second key space. Everything collapsed is the default. Mutually exclusive with groupBy — a forest has no flat list to bucket, so grouping wins and the hierarchy is ignored while it is set. Also mutually exclusive with [wrTableExpand] detail rows: both own the row's disclosure affordance. pageSize pages the ROOTS; a root brings its open descendants with it. The function form RETURNS WrTableRows, matching [items]: a return is covariant, so an array of interface-typed children satisfies it. Declared as records it did not, and a forest that bound to [items] could not hand its children back out. The PARAMETER stays Record<string, unknown> — that side is contravariant, and widening it would reject the callbacks that compile today while leaving row['reports'] unindexable. See {@link WrTableRow}. | string | ((row: Record<string, unknown>) => readonly WrTableRow[] | null | undefined) | null | null |
treeColumn | Which column carries the indent and the expand toggle. Keyed, not positional, so it survives a columnOrder drag. Defaults to whichever column renders first. | string | null | null |
toggleRowLabel | The action word that names a parent row's expand toggle. The row's own label cell is joined to it, so the toggle reads "Toggle child rows Engineering" rather than one name shared by every row. Falls back to table.toggleRow. | string | null | null |
collapsedGroups | Two-way bindable collapsed group values (the values groupBy returns). Keyed by value, so a collapsed group stays collapsed across page changes and re-sorts. Empty (the default) shows every group expanded. | readonly unknown[] | [] |
groupSummary | Render an aggregate row under each group using the same column.summary definitions as the grand footer, computed over that group's rows on the current page. No-op unless at least one column defines a summary. The grand <tfoot> is unaffected and still aggregates the whole client dataset — with client-side pagination the two describe different scopes, so pair grouping with pageSize = 0 when you need them to reconcile. A summary FUNCTION tells the two apart by its second argument, { scope: 'group' | 'total' } — see WrTableSummaryContext. | boolean | false |
showGroupCount | Show the page-scoped row-count badge in each group band. | boolean | true |
sort | Two-way bindable sort array. Order in array = application order. | readonly WrTableSortState[] | [] |
emptyLabel | Text shown when there are no rows. Falls back to table.empty. | string | null | null |
sortLabel | Accessible name of a column's sort button. Falls back to table.sort. | string | null | null |
selectAllLabel | Accessible name of the select-all checkbox. Falls back to table.selectAll. | string | null | null |
selectRowLabel | The action word that names a row's select checkbox. The row's label cell is joined to it through aria-labelledby — "Select row Ada" — since one name repeated down every row tells a screen reader nothing about which row a box belongs to. Falls back to table.selectRow. | string | null | null |
expandRowLabel | The action word that names a row's detail toggle, joined to the row's label cell like selectRowLabel. Falls back to table.expandRow. | string | null | null |
selectGroupLabel | The action word that names a group band's select checkbox. The group's label is joined to it — "Select group EMEA". Falls back to table.selectGroup. | string | null | null |
toggleGroupLabel | The action word that names a group band's collapse toggle, joined to the group's label like selectGroupLabel. Falls back to table.toggleGroup. | string | null | null |
loadingLabel | Accessible name of the loading overlay. Falls back to table.loading. | string | null | null |
(filterChange) | Fires whenever a column's filter selection changes. | WrTableFilterChange | — |
pageSize | Rows per page. Set to 0 (default) to disable client-side pagination and render every row at once. | number | 0 |
page | Two-way bindable 1-based current page. | number | 1 |
total | Total row count for server-side pagination — when set, the table shows the pager but does NOT slice items (you provide the current page's slice yourself and react to (page) changes). Spelled total / page to match <wr-pagination>, which is the control this input renders. The two used to disagree about both words — totalItems / page here against total / currentPage there — which is a real cost for two components designed to sit on one screen. null rather than 0 is the difference that remains, and it carries meaning: it is the OFF switch for server mode, where the pager's own total is a count and 0 means an empty list. | number | null | null |
virtualScroll | Window the <tbody> so a table of thousands of rows keeps only ~one viewport of <tr>s in the DOM. Opt-in and OFF by default — a table without it renders byte-identically to today. Engages ONLY on the flat, fixed-height tier: it silently falls back to the full render whenever a variable-height layout is active — groupBy, tree rows (childrenKey), a [wrTableExpand] template, responsive card mode, or a visible pager (pageSize > 0 / total). While on, it forces fixed layout for stable column widths and assumes a uniform row height (see rowHeight). Intended as static config. Give columns an explicit width so the frozen layout is exact (a virtualized table always renders fixed-layout); toggling it off at runtime leaves the frozen widths in place as column minimums. | boolean | false |
rowHeight | Uniform body-row height in px used to map scroll offset to row index. 0 (default) measures the first rendered row once — matching the density at that point — and reuses it; pass an explicit value to remove the post-hydration measure and make SSR pixel-exact (recommended if the density can change at runtime). Read only when virtualScroll is on. Keep virtualized cells single-line and no taller than this — a taller custom [wrTableCell] template drifts the window. | number | 0 |
viewportHeight | Height of the scroll viewport when virtualScroll is on — a number (px) or any CSS length ('70vh'). Applied as max-height on .wr-table__scroll (a short table shrinks to fit; a long one caps and scrolls). A numeric px value lets the server prerender the exact first window. | number | string | 480 |
overscan | Extra rows kept rendered above and below the viewport as scroll headroom. | number | 6 |
Templates
| Name | Description | Type | Default |
|---|---|---|---|
<ng-template wrTableExpand> | Detail template revealed when a row expands (let-row). | directive | — |
<ng-template wrTableGroupHeader> | Custom band label template (let-value, let-count, let-toggle, …). | directive | — |
[wrTableCell] | Per-column cell template. The attribute value is the column key; import WrTableCell. | directive | — |
let-value | The cell value, item[columnKey]. | unknown | — |
let-row="item" | The whole row. A bare let-row binds the cell value instead. | Record<string, unknown> | — |
let-col="column" | The column definition. | WrTableColumn | — |
Methods
Call them through a template reference.
| Name | Description | Type | Default |
|---|---|---|---|
expandAllRows() / collapseAllRows() | Open or close every parent in a tree-mode forest. No-ops when childrenKey is unset. | () => void | — |
exportCsv(options?) | Download the rows as a CSV file (options: filename, selectedOnly, delimiter). | (WrTableCsvOptions) => void | — |
toCsv(options?) | Return the table as a CSV string instead of downloading. | (WrTableCsvOptions) => string | — |
collapseAllGroups() / expandAllGroups() | Collapse or expand every group on the current page. | () => void | — |
scrollToRow(index, behavior?) | Scroll a row index to the top of the virtual viewport. | (number, ScrollBehavior) => void | — |
<wr-table-filter>
| Name | Description | Type | Default |
|---|---|---|---|
filterLabel | Accessible name of the filter trigger. Falls back to table.filter. | string | null | null |
column | The column this filter belongs to, for the trigger's accessible name. Without it every filter trigger in a header row announced the same "Filter column", so a screen-reader user tabbing the row heard the same button three times and could not tell which column each one narrowed. The caret and the funnel sit beside the column title, so sighted readers had the context all along; an aria-label REPLACES content, so nobody else did. | string | '' |
noMatchesLabel | Text shown when the search finds nothing. Falls back to table.noMatches. | string | null | null |
searchLabel | Placeholder AND accessible name of the search box. Falls back to table.search. One string for both because the box has no visible label: the placeholder was its only name, so a hard-coded literal left the control unnamed in every other language rather than merely untranslated. | string | null | null |
resetLabel | Label of the clear-selection button. Falls back to table.reset. | string | null | null |
itemsrequired | The values the column can be filtered by. Shown as a checkbox list, so pass the distinct values rather than one entry per row. | readonly WrTableFilterItem[] | — |
(selectionChange) | Fires whenever the selection changes. | readonly WrTableFilterItem[] | — |
<wr-table-sort>
| Name | Description | Type | Default |
|---|---|---|---|
direction | Which way the column is currently sorted, or null for unsorted — the three states the indicator cycles through. Drive it from the table's sort state. | WrTableSortDirection | null |
CSS variables
Set these on the component's selector or a wrapper, not on :root: the defaults are declared on ngwr/table's own element.
| Variable | Default | Declared on |
|---|---|---|
--wr-table-bg | var(--wr-color-surface) | .wr-table |
--wr-table-border | var(--wr-border-base) | .wr-table |
--wr-table-card-cell-gap | var(--wr-space-lg) | .wr-table |
--wr-table-card-cell-padding-x | var(--wr-space-lg) | .wr-table |
--wr-table-card-cell-padding-y | var(--wr-space-xs) | .wr-table |
--wr-table-card-row-padding-y | var(--wr-space-sm) | .wr-table |
--wr-table-detail-padding | var(--wr-space-lg) | .wr-table |
--wr-table-empty-padding | var(--wr-space-xl) | .wr-table |
--wr-table-expand-btn-padding | var(--wr-space-xs) | .wr-table |
--wr-table-expand-btn-radius | var(--wr-border-radius-sm) | .wr-table |
--wr-table-filter-check-border | var(--wr-border-base) | .wr-table-filter__panel |
--wr-table-filter-check-radius | var(--wr-border-radius-sm) | .wr-table-filter__panel |
--wr-table-filter-count-font-weight | var(--wr-font-weight-semibold) | .wr-table-filter |
--wr-table-filter-count-padding-x | var(--wr-space-xs) | .wr-table-filter |
--wr-table-filter-count-radius | var(--wr-border-radius-pill) | .wr-table-filter |
--wr-table-filter-empty-font-size | var(--wr-text-sm) | .wr-table-filter__panel |
--wr-table-filter-empty-padding-x | var(--wr-space-sm) | .wr-table-filter__panel |
--wr-table-filter-empty-padding-y | var(--wr-space-md) | .wr-table-filter__panel |
--wr-table-filter-item-font-size | var(--wr-text-sm) | .wr-table-filter__panel |
--wr-table-filter-item-gap | var(--wr-space-sm) | .wr-table-filter__panel |
--wr-table-filter-item-padding | var(--wr-space-sm) | .wr-table-filter__panel |
--wr-table-filter-item-radius | var(--wr-border-radius-sm) | .wr-table-filter__panel |
--wr-table-filter-panel-font-family | var(--wr-font-family-base) | .wr-table-filter__panel |
--wr-table-filter-panel-gap | var(--wr-space-sm) | .wr-table-filter__panel |
--wr-table-filter-panel-padding | var(--wr-space-sm) | .wr-table-filter__panel |
--wr-table-filter-reset-font-size | var(--wr-text-sm) | .wr-table-filter__panel |
--wr-table-filter-reset-padding | var(--wr-space-sm) | .wr-table-filter__panel |
--wr-table-filter-reset-radius | var(--wr-border-radius-sm) | .wr-table-filter__panel |
--wr-table-filter-search-border | var(--wr-border-base) | .wr-table-filter__panel |
--wr-table-filter-search-font-size | var(--wr-text-sm) | .wr-table-filter__panel |
--wr-table-filter-search-padding | var(--wr-space-sm) | .wr-table-filter__panel |
--wr-table-filter-search-radius | var(--wr-border-radius-sm) | .wr-table-filter__panel |
--wr-table-filter-trigger-gap | var(--wr-space-xs) | .wr-table-filter |
--wr-table-font-family | var(--wr-font-family-base) | .wr-table |
--wr-table-font-size | var(--wr-text-sm) | .wr-table |
--wr-table-foot-cell-font-weight | var(--wr-font-weight-semibold) | .wr-table |
--wr-table-group-bg | var(--wr-color-fill-subtle) | .wr-table |
--wr-table-group-count-font-size | var(--wr-text-xs) | .wr-table |
--wr-table-group-count-font-weight | var(--wr-font-weight-medium) | .wr-table |
--wr-table-group-count-padding-x | var(--wr-space-sm) | .wr-table |
--wr-table-group-count-radius | var(--wr-border-radius-pill) | .wr-table |
--wr-table-group-inner-gap | var(--wr-space-sm) | .wr-table |
--wr-table-group-toggle-font-weight | var(--wr-font-weight-semibold) | .wr-table |
--wr-table-group-toggle-gap | var(--wr-space-sm) | .wr-table |
--wr-table-head-bg | var(--wr-color-fill) | .wr-table |
--wr-table-head-font-size | var(--wr-text-xs) | .wr-table |
--wr-table-head-font-weight | var(--wr-font-weight-semibold) | .wr-table |
--wr-table-head-letter-spacing | var(--wr-tracking-normal) | .wr-table |
--wr-table-head-transform | none | .wr-table |
--wr-table-line-height | var(--wr-text-sm-leading) | .wr-table |
--wr-table-pager-padding | var(--wr-space-md) | .wr-table |
--wr-table-pin-shadow-ink | light-dark(rgb(0 0 0 / 18%), rgb(0 0 0 / 45%)) | .wr-table |
--wr-table-radius | var(--wr-border-radius-base) | .wr-table |
--wr-table-resize-handle-bg | var(--wr-border-base) | .wr-table |
--wr-table-row-hover | var(--wr-color-fill-subtle) | .wr-table |
--wr-table-sort-order-font-size | var(--wr-table-head-font-size) | .wr-table |
--wr-table-sort-order-font-weight | var(--wr-font-weight-semibold) | .wr-table |
--wr-table-tree-lead-margin-end | var(--wr-space-xs) | .wr-table +1 variant override |
--wr-table-tree-toggle-radius | var(--wr-border-radius-sm) | .wr-table |
Dependencies
| Angular CDK | drag-drop |
|---|---|
| Built on | Checkbox, Dropdown, Pagination, Spinner |
See also
Component TreeA nested list to browse and select from, inline or as a dropdown picker.Component ListA list of rows with leading, body and trailing slots.Component DescriptionsA read-only list of labels and their values.Component EmptyA placeholder for a view with no data.Guide Mobile & responsiveMake ngwr layouts work on touch screens and narrow containers.Component CheckboxA checkbox for one boolean, or a group of them for an array.Component DropdownA menu that opens from any trigger.Component PaginationPage navigation for a long list.