table-wc
Progressive enhancement wrapper for HTML tables. Adds sorting, filtering, pagination, row expansion, and selection.
Overview
The <table-wc> component wraps a standard HTML table to provide interactive features like column sorting, text filtering, pagination, expandable rows, row selection with bulk actions, responsive card layouts, and sticky headers/columns. All features are opt-in via data attributes and the table remains fully functional without JavaScript.
Basic Usage
Wrap any HTML table with <table-wc> and add data attributes to enable features. The table structure remains semantic and accessible.
Sorting
Add data-sort to any <th> element to make that column sortable. Click the column header to cycle through ascending, descending, and unsorted states.
Sort Types
| Value | Description |
|---|---|
string |
Alphabetical sorting (case-insensitive) |
number |
Numeric sorting (handles decimals and negatives) |
date |
Date sorting (parses common date formats) |
Custom Sort Values
Use data-sort-value on cells when the display value differs from the sort value (e.g., formatted currency or dates).
Filtering
Add data-filterable to the table to enable text filtering. A search input is automatically generated above the table. Rows that don't match the filter text are hidden.
Pagination
Add data-paginate="n" to the table to show only n rows per page. Pagination controls are automatically generated below the table.
Row Expansion
Create expandable rows by adding data-expandable to a row and following it with a data-expand-content row. A toggle button is automatically added to control the expansion.
Row Selection
Add checkboxes to rows for selection, with a "select all" checkbox in the header and a bulk actions bar that appears when rows are selected.
Responsive Card Mode
Add data-responsive="card" to transform the table into a card layout on narrow screens. Use data-label on cells to show column headers in card mode.
Sticky Headers and Columns
Use data-layout-sticky to keep headers or columns visible while scrolling.
Sticky Options
| Value | Description |
|---|---|
header |
Keeps the table header row fixed at the top |
column |
Keeps the first column fixed on horizontal scroll |
both |
Both header and first column are sticky |
Multiple Sticky Columns
Use data-sticky-column="n" to make the first n columns sticky.
Events
The component dispatches custom events for each interactive feature.
| Event | Detail | Description |
|---|---|---|
table:sort |
{ column: number, direction: "asc"|"desc"|null } |
Fired when a column is sorted. |
table:filter |
{ query: string, matchCount: number } |
Fired when the filter input changes. |
table:page |
{ page: number, totalPages: number } |
Fired when the page changes. |
table:expand |
{ row: HTMLTableRowElement, expanded: boolean } |
Fired when a row is expanded or collapsed. |
table:selection |
{ selectedRows: HTMLTableRowElement[], count: number } |
Fired when row selection changes. |
Public API
The component exposes methods for programmatic control.
| Method | Parameters | Returns | Description |
|---|---|---|---|
goToPage(n) |
n: number |
void |
Navigate to a specific page (1-indexed). |
setFilter(query) |
query: string |
void |
Programmatically set the filter text. |
refresh() |
- | void |
Re-apply sorting, filtering, and pagination. |
getSelectedRows() |
- | HTMLTableRowElement[] |
Get array of currently selected rows. |
Attributes Reference
Complete list of data attributes supported by table-wc.
Table Attributes
| Attribute | Value | Description |
|---|---|---|
data-filterable |
boolean | Enable text filtering with auto-generated search input. |
data-paginate |
number | Number of rows per page. Enables pagination controls. |
data-responsive |
card |
Transform to card layout on narrow screens. |
data-layout-sticky |
header | column | both |
Make header and/or first column sticky. |
data-sticky-column |
number | Number of columns to make sticky (default: 1). |
Header Cell Attributes
| Attribute | Value | Description |
|---|---|---|
data-sort |
string | number | date |
Enable sorting for this column with specified type. |
Data Cell Attributes
| Attribute | Value | Description |
|---|---|---|
data-sort-value |
string | Custom value used for sorting instead of cell text. |
data-label |
string | Label shown in responsive card mode. |
Row Attributes
| Attribute | Value | Description |
|---|---|---|
data-expandable |
boolean | Mark row as expandable (expects following expand-content row). |
data-expand-content |
boolean | Mark row as expansion content (hidden by default). |
data-selectable |
boolean | Enable row selection with checkbox. |
Action Attributes
| Attribute | Element | Description |
|---|---|---|
data-action="select-all" |
checkbox | Select/deselect all rows. |
data-action="select-row" |
checkbox | Select/deselect individual row. |
data-action="toggle-expand" |
button | Toggle row expansion. |
data-bulk-actions |
container | Container shown when rows are selected. |
data-selected-count |
element | Displays count of selected rows. |
Accessibility
Keyboard Navigation
| Key | Action |
|---|---|
| Tab | Move between interactive elements (sort headers, checkboxes, buttons) |
| Enter / Space | Activate sort, toggle checkbox, or expand/collapse row |
| Arrow Up/Down | Navigate between rows when focused on a row |
| Home / End | Jump to first/last page in pagination |
ARIA Attributes
aria-sorton sortable column headers indicates current sort directionaria-expandedon expand buttons indicates row expansion statearia-selectedon selectable rows indicates selection statearia-live="polite"on filter results announces match countaria-labelon pagination controls describes navigation
Reduced Motion
When prefers-reduced-motion: reduce is set, all transitions and animations are disabled. Sort indicators, row expansion, and pagination all function without motion effects.
Screen Reader Support
- Sort state changes are announced when columns are sorted
- Filter result counts are announced as users type
- Row expansion state is announced when toggled
- Selection count updates are announced on change