data-table

Progressive enhancement wrapper for HTML tables. Adds sorting, filtering, pagination, row expansion, and selection.

Overview

The <data-table> 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 <data-table> 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-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
data-table:sort { column: number, direction: "asc"|"desc"|null } Fired when a column is sorted.
data-table:filter { query: string, count: number } Fired when the filter input changes.
data-table:page { page: number } Fired when the page changes.
data-table:expand { row: HTMLTableRowElement, expanded: boolean } Fired when a row is expanded or collapsed.
data-table:selection { count: number, rows: HTMLTableRowElement[] } 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

Host Attributes

AttributeValuesDefaultDescription
data-filterablebooleanEnable text search filtering
data-paginatenumberEnable pagination with N rows per page

Required Structure

ElementRequiredDescription
<table>yesStandard HTML table — the component enhances it in place

Child Attributes

AttributeOnValuesDescription
data-sortth"string", "number", "date"Enable sorting on this column with the specified comparator
data-sort-valuetdstringCustom sort value overriding cell text
data-filter-valuetdstringCustom filter value overriding cell text
data-expandabletrbooleanMark row as expandable (followed by a data-expand-content row)
data-expand-contenttrbooleanHidden row revealed when its preceding expandable row is toggled
data-selectabletrbooleanMark row as selectable via checkbox

CSS-Only Attributes

These attributes are handled by CSS styling, not JavaScript logic.

AttributeOnValueDescription
data-responsive<table>cardTransform to card layout on narrow screens.
data-sticky<table>header | column | bothMake header and/or first column sticky.
data-sticky-column<table>numberNumber of columns to make sticky (default: 1).
data-label<td>stringLabel shown in responsive card mode.
data-filter-value<td>stringCustom value for filtering instead of cell text.

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-sort on sortable column headers indicates current sort direction
  • aria-expanded on expand buttons indicates row expansion state
  • aria-selected on selectable rows indicates selection state
  • aria-live="polite" on filter results announces match count
  • aria-label on 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