rc-data-table
Sortable-header enhancer for a native <table>, following the
WAI-ARIA sortable table example.
- Package
@rcarls/rc-data-table- Element
<rc-data-table>- Native dependency
- Requires a native table child; each sortable th holds a native button or link
- State model
- Controlled or uncontrolled sort key and direction
- Main events
rc-data-table-sort
Installation
- npm
- Yarn
- pnpm
npm install @rcarls/rc-webcomponents@next
yarn add @rcarls/rc-webcomponents@next
pnpm add @rcarls/rc-webcomponents@next
import '@rcarls/rc-webcomponents/rc-data-table/define';
Usage
Author the table, and put each sortable column's header text in a native <button> inside a
<th data-rc-sort-key="...">:
<rc-data-table sort-key="name" sort-direction="ascending">
<table>
<caption>
Plants. Column headers with buttons are sortable.
</caption>
<thead>
<tr>
<th scope="col" data-rc-sort-key="name"><button type="button">Name</button></th>
<th scope="col" data-rc-sort-key="price" data-rc-sort-first="descending">
<button type="button">Price</button>
</th>
<th scope="col">Notes</th>
</tr>
</thead>
<tbody>
<!-- rows, in the current sort order -->
</tbody>
</table>
</rc-data-table>
The button is part of the markup, not added at upgrade, so a framework that renders the
table keeps owning every node. A header can be a link to a server-sorted URL instead, such
as <a href="?sort=name&dir=descending">, which sorts the table with no JavaScript at all.
data-rc-sort-first="descending" makes a column, such as a price or date, sort descending
the first time it is chosen.
Live demo
The element never sorts rows
rc-data-table reflects the sort state and reports requests; the consumer sorts the data
and re-renders <tbody>. Activating a header fires rc-data-table-sort with
{ key, direction, previousKey, previousDirection }. Activating the sorted column again
flips its direction.
- Uncontrolled: the element moves
aria-sortitself; set the initial state withdefault-sort-keyanddefault-sort-direction. - Controlled: set
sort-keyandsort-direction, and write them from the event when the new order is rendered.
The event is cancelable. Canceling it also cancels the click, so a header link does not navigate.
Accessibility
aria-sortis set only on the sorted column's header and removed from the others, rather than set tonone.- Each sortable column shows a CSS indicator with a distinct shape for unsorted, ascending, and descending. The indicators are generated content with empty alternative text, so they are not part of the button's name.
- Say in the
<caption>that column headers with buttons sort the table. The element warns in development when a sortable table has no caption. - Screen readers announce sort changes inconsistently. Set
announceto have the element announce "Sorted by Name, ascending" through a polite live region. - While the table is wider than its container, the element becomes a focusable group named by the caption, so keyboard users can scroll it.
Theming
The default demo mode shows the component without a package theme. The Material theme keeps the Material 2 data table metrics in Material 3 color and type roles. Use the shared preview controls to compare themes.
API
Properties
| Property | Markup | Type | Default | Description |
|---|---|---|---|---|
announce | announce | boolean | false | Announces each user sort through a polite live region. |
messages | JS property only | Partial<RCDataTableMessages> | undefined | Not specified | Built-in text overrides; unset keys fall back to registered text, then English. |
sortKey | sort-key | string | undefined | Not specified | Current sort column. Host writes are silent; assign `undefined` to release control. |
sortDirection | sort-direction | RCDataTableSortDirection | Not specified | Current sort direction. Host writes are silent. |
defaultSortKey | default-sort-key | string | undefined | Not specified | Initial sort column for uncontrolled use. |
defaultSortDirection | default-sort-direction | RCDataTableSortDirection | Not specified | Initial sort direction for uncontrolled use. |
Events
| Event | Detail type | Description |
|---|---|---|
rc-data-table-sort | No detail type documented | Fired when the user activates a sortable column header. Cancelable; canceling it also cancels the click, so a header link does not navigate. |
CSS Custom Properties
| Property | Default | Description |
|---|---|---|
--rc-data-table-cell-padding-block | Not specified | Cell block padding. Defers to the user agent when unset. |
--rc-data-table-cell-padding-inline | Not specified | Cell inline padding. Defers to the user agent when unset. |
--rc-data-table-sort-indicator-gap | 0.25em | Space between a header label and its sort indicator. |
--rc-data-table-sort-none | '\25C7' | Indicator for a sortable column that is not sorted. |
--rc-data-table-sort-ascending | '\25B2' | Indicator for an ascending column. |
--rc-data-table-sort-descending | '\25BC' | Indicator for a descending column. |