Data Table Component Breakdown
Overview
The dd-data-table component is an accessible table with a caption, scoped header cells, and optional status cells that embed the dd-badge component. It wraps the table in a keyboard-focusable horizontal scroll region and supports optional column sorting and an empty state.
This component is ideal for report data, comparison grids, and audit result listings. In WordPress, configure it via a repeater of rows and a header definition, with a status column mapped to badge severities. In Drupal, use a Views table or a Paragraph type with structured field data.
Basic Usage
Wrap a semantic <table> with a <caption> and <th scope> headers inside the dd-data-table container. Status cells embed a dd-badge, and sortable columns use native header buttons. The scroll region and sorting behaviour are wired up by the component JS.
Preview
| ID | Finding | ||
|---|---|---|---|
| SEO-001 | Critical | Missing <title> tag | 2h |
| SEO-002 | Warning | Thin meta description | 1h |
Code
<!-- The scroll region's tabindex/role/aria-label are added by JS only when the
table overflows; data-label supplies the accessible name. -->
<div class="dd-data-table">
<div class="dd-data-table__scroll" data-label="Prioritized remediation tasks">
<table class="dd-data-table__table" id="task-table">
<caption class="dd-data-table__caption">Prioritized remediation tasks</caption>
<thead>
<tr>
<th scope="col" class="dd-data-table__th" data-align="start">ID</th>
<th scope="col" class="dd-data-table__th" data-align="start" aria-sort="none">
<button type="button" class="dd-data-table__sort" data-sort-key="priority">Priority<span class="dd-data-table__sort-ind" aria-hidden="true"></span></button>
</th>
<th scope="col" class="dd-data-table__th" data-align="start">Finding</th>
<th scope="col" class="dd-data-table__th" data-align="end" aria-sort="none">
<button type="button" class="dd-data-table__sort" data-sort-key="effort">Effort<span class="dd-data-table__sort-ind" aria-hidden="true"></span></button>
</th>
</tr>
</thead>
<tbody>
<tr class="dd-data-table__row">
<th scope="row" class="dd-data-table__td" data-align="start">SEO-001</th>
<td class="dd-data-table__td"><span class="dd-badge -critical"><span class="dd-badge__label">Critical</span></span></td>
<td class="dd-data-table__td">Missing <title> tag</td>
<td class="dd-data-table__td" data-align="end">2h</td>
</tr>
<tr class="dd-data-table__row">
<th scope="row" class="dd-data-table__td" data-align="start">SEO-002</th>
<td class="dd-data-table__td"><span class="dd-badge -warning"><span class="dd-badge__label">Warning</span></span></td>
<td class="dd-data-table__td">Thin meta description</td>
<td class="dd-data-table__td" data-align="end">1h</td>
</tr>
</tbody>
</table>
</div>
</div>
Provide an empty state row when there is no data to display.
CSS Modifiers (from _dd_data_table.scss)
The SCSS file defines the table layout, cell padding, scroll region, and focus styling. Key modifiers include:
- -dense: Reduces cell padding for compact, data-heavy tables.
- No modifier: Default comfortable spacing for standard readability.
Framework files
- source/js/components/_dd_data_table.js (scroll region and sort)
- source/scss/components/_dd_data_table.scss (styles)
Accessibility and Best Practices
The <caption> names the table, and header cells use <th scope> for correct association. The scroll region receives tabindex="0", role="region", and an aria-label from the JS only when it actually overflows, so keyboard users can scroll without adding an empty tab stop otherwise. Sortable headers are native <button> elements with aria-sort set on the <th> (exactly one column non-none at a time), and sorting is fully keyboard-operable. The focus ring uses a high-contrast dark colour rather than the brand green so it stays visible on all cell backgrounds.