Overview
Dense list and permissions-style tables: percentage-based columns, truncation with tooltips, +N overflow tags, and row actions.
Table views
User directory
Mirrors the user-management table: sortable headers, avatars, truncated labels, +N tag with scrollable tooltip, em dash for empty cells, and a kebab action.
| Name | Label group | Label | Role | Last login | Actions | |
|---|---|---|---|---|---|---|
|
Elizabeth Brown
Elizabeth Brown
|
elizabeth.brown@wmg.com
elizabeth.brown@wmg.com
|
Elizabeth Coverag…
Elizabeth Coverage Group Name
+2
|
— |
Ops admin
Full role description for Ops admin appears here.
|
2 days ago
Last successful login: Feb 4, 2026 · 9:42 AM UTC
|
|
|
Susan Davis
Susan Davis
|
susan.davis@yahoo.com
susan.davis@yahoo.com
|
— |
Radiance Records
Radiance Records
|
Label admin
Manages label roster and metadata.
|
1 day ago
Last successful login: Feb 5, 2026 · 4:10 PM UTC
|
|
|
Morgan Kim
|
morgan.kim@partner.io |
Global Marketing
+5
|
— |
Release manager
Coordinates release windows across territories.
|
Last year |
Bulk selection
Reserve the leading column for checkboxes (select all in the header). Keeps scan lines aligned with the table above.
| Name | Status | ||
|---|---|---|---|
|
Avery Lee
|
avery@label.com | Active | |
|
Jordan Smith
|
jordan@label.com | Pending |
Empty state
| Title | Owner | Updated |
|---|---|---|
|
No rows yet |
||
Usage
Dense list and permissions-style tables: percentage-based columns, truncation with tooltips, +N overflow tags, and row actions. Reference User management (overflow), Table specs (layout & tooltips), and Table specs (checklist) in Figma.
Code
Copy snippets into your app. Import /tokens/wmg-chords.css and dashboard/design-system.css (or your product bundle) so the classes below resolve. Font Awesome 6 is used where icons appear in demos.
HTML
Static markup matching the Overview demo. Adjust copy, labels, and ARIA attributes for your product context.
<h2 class="section-title" id="h-tv">Table views</h2>
<h3 class="section-subtitle">User directory</h3>
<p class="section-desc tv-section-note">
Mirrors the user-management table: sortable headers, avatars, truncated labels, +N tag with scrollable tooltip, em dash for empty cells, and a
kebab action.
</p>
<div class="demo-panel">
<div class="table-scroll table-scroll--tv">
<table class="ds-table ds-table--tv ds-table--zebra">
<colgroup>
<col class="tv-col tv-col--name" />
<col class="tv-col tv-col--email" />
<col class="tv-col tv-col--lg" />
<col class="tv-col tv-col--label" />
<col class="tv-col tv-col--role" />
<col class="tv-col tv-col--login" />
<col class="tv-col tv-col--actions" />
</colgroup>
<thead>
<tr>
<th scope="col">
<span class="tv-th">Name <i class="fa-solid fa-sort tv-th__sort" aria-hidden="true"></i></span>
</th>
<th scope="col">
<span class="tv-th">Email <i class="fa-solid fa-sort tv-th__sort" aria-hidden="true"></i></span>
</th>
<th scope="col">
<span class="tv-th">Label group <i class="fa-solid fa-sort tv-th__sort" aria-hidden="true"></i></span>
</th>
<th scope="col">
<span class="tv-th">Label <i class="fa-solid fa-sort tv-th__sort" aria-hidden="true"></i></span>
</th>
<th scope="col">
<span class="tv-th">Role <i class="fa-solid fa-sort tv-th__sort" aria-hidden="true"></i></span>
</th>
<th scope="col">
<span class="tv-th">
Last login <i class="fa-solid fa-sort tv-th__sort" aria-hidden="true"></i>
<button type="button" class="tv-info-btn" aria-label="About last login" tabindex="0">
<i class="fa-solid fa-circle-info" aria-hidden="true"></i>
</button>
</span>
</th>
<th scope="col" class="ds-table-actions"><span class="visually-hidden">Actions</span></th>
</tr>
</thead>
<tbody>
<tr>
<td>
<div class="tv-user">
<span class="tv-avatar-sm" aria-hidden="true">EB</span>
<span class="tooltip-wrap">
<span class="tv-truncate tooltip-trigger">Elizabeth Brown</span>
<span class="tooltip-bubble tooltip-bubble--table" role="tooltip">Elizabeth Brown</span>
</span>
</div>
</td>
<td>
<div class="tooltip-wrap">
<span class="tv-truncate tooltip-trigger">elizabeth.brown@wmg.com</span>
<span class="tooltip-bubble tooltip-bubble--table" role="tooltip">elizabeth.brown@wmg.com</span>
</div>
</td>
<td>
<div class="tv-cell-cluster">
<span class="tooltip-wrap">
<span class="tv-truncate tooltip-trigger">Elizabeth Coverag…</span>
<span class="tooltip-bubble tooltip-bubble--table" role="tooltip">Elizabeth Coverage Group Name</span>
</span>
<span class="tooltip-wrap tooltip-wrap--interactive">
<span class="tv-tag-more tooltip-trigger" tabindex="0">+2</span>
<span class="tooltip-bubble tooltip-bubble--table tv-tooltip-more" role="tooltip">
<ul class="tv-tooltip-list">
<li>ADA North America</li>
<li>ADA South America</li>
</ul>
</span>
</span>
</div>
</td>
<td><span class="tv-empty-dash">—</span></td>
<td>
<div class="tv-cell-cluster">
<span class="tv-truncate">Ops admin</span>
<span class="tooltip-wrap">
<button type="button" class="tv-info-btn" aria-label="Role details" tabindex="0">
<i class="fa-solid fa-circle-info" aria-hidden="true"></i>
</button>
<span class="tooltip-bubble tooltip-bubble--table" role="tooltip">Full role description for Ops admin appears here.</span>
</span>
</div>
</td>
<td>
<div class="tv-cell-cluster">
<span class="tv-truncate">2 days ago</span>
<span class="tooltip-wrap">
<button type="button" class="tv-info-btn" aria-label="Last login detail" tabindex="0">
<i class="fa-solid fa-circle-info" aria-hidden="true"></i>
</button>
<span class="tooltip-bubble tooltip-bubble--table" role="tooltip">Last successful login: Feb 4, 2026 · 9:42 AM UTC</span>
</span>
</div>
</td>
<td class="ds-table-actions">
<button type="button" class="tv-row-action" aria-label="Row actions for Elizabeth Brown">
<i class="fa-solid fa-ellipsis-vertical" aria-hidden="true"></i>
</button>
</td>
</tr>
<tr>
<td>
<div class="tv-user">
<span class="tv-avatar-sm" aria-hidden="true">SD</span>
<span class="tooltip-wrap">
<span class="tv-truncate tooltip-trigger">Susan Davis</span>
<span class="tooltip-bubble tooltip-bubble--table" role="tooltip">Susan Davis</span>
</span>
</div>
</td>
<td>
<div class="tooltip-wrap">
<span class="tv-truncate tooltip-trigger">susan.davis@yahoo.com</span>
<span class="tooltip-bubble tooltip-bubble--table" role="tooltip">susan.davis@yahoo.com</span>
</div>
</td>
<td><span class="tv-empty-dash">—</span></td>
<td>
<div class="tooltip-wrap">
<span class="tv-truncate tooltip-trigger">Radiance Records</span>
<span class="tooltip-bubble tooltip-bubble--table" role="tooltip">Radiance Records</span>
</div>
</td>
<td>
<div class="tv-cell-cluster">
<span class="tv-truncate">Label admin</span>
<span class="tooltip-wrap">
<button type="button" class="tv-info-btn" aria-label="Role details" tabindex="0">
<i class="fa-solid fa-circle-info" aria-hidden="true"></i>
</button>
<span class="tooltip-bubble tooltip-bubble--table" role="tooltip">Manages label roster and metadata.</span>
</span>
</div>
</td>
<td>
<div class="tv-cell-cluster">
<span class="tv-truncate">1 day ago</span>
<span class="tooltip-wrap">
<button type="button" class="tv-info-btn" aria-label="Last login detail" tabindex="0">
<i class="fa-solid fa-circle-info" aria-hidden="true"></i>
</button>
<span class="tooltip-bubble tooltip-bubble--table" role="tooltip">Last successful login: Feb 5, 2026 · 4:10 PM UTC</span>
</span>
</div>
</td>
<td class="ds-table-actions">
<button type="button" class="tv-row-action" aria-label="Row actions for Susan Davis">
<i class="fa-solid fa-ellipsis-vertical" aria-hidden="true"></i>
</button>
</td>
</tr>
<tr>
<td>
<div class="tv-user">
<span class="tv-avatar-sm" aria-hidden="true">MK</span>
<span class="tv-truncate">Morgan Kim</span>
</div>
</td>
<td><span class="tv-truncate">morgan.kim@partner.io</span></td>
<td>
<div class="tv-cell-cluster">
<span class="tv-truncate">Global Marketing</span>
<span class="tooltip-wrap tooltip-wrap--interactive">
<span class="tv-tag-more tooltip-trigger" tabindex="0">+5</span>
<span class="tooltip-bubble tooltip-bubble--table tv-tooltip-more" role="tooltip">
<ul class="tv-tooltip-list">
<li>EU West</li>
<li>EU Central</li>
<li>US East</li>
<li>US West</li>
<li>APAC</li>
</ul>
</span>
</span>
</div>
</td>
<td><span class="tv-empty-dash">—</span></td>
<td>
<div class="tv-cell-cluster">
<span class="tv-truncate">Release manager</span>
<span class="tooltip-wrap">
<button type="button" class="tv-info-btn" aria-label="Role details" tabindex="0">
<i class="fa-solid fa-circle-info" aria-hidden="true"></i>
</button>
<span class="tooltip-bubble tooltip-bubble--table" role="tooltip">Coordinates release windows across territories.</span>
</span>
</div>
</td>
<td><span class="tv-truncate">Last year</span></td>
<td class="ds-table-actions">
<button type="button" class="tv-row-action" aria-label="Row actions for Morgan Kim">
<i class="fa-solid fa-ellipsis-vertical" aria-hidden="true"></i>
</button>
</td>
</tr>
</tbody>
</table>
</div>
</div>
<h3 class="section-subtitle">Bulk selection</h3>
<p class="section-desc">Reserve the leading column for checkboxes (select all in the header). Keeps scan lines aligned with the table above.</p>
<div class="demo-panel">
<div class="table-scroll table-scroll--tv">
<table class="ds-table ds-table--tv ds-table--zebra">
<colgroup>
<col style="width: 5%" />
<col style="width: 25%" />
<col style="width: 38%" />
<col style="width: 32%" />
</colgroup>
<thead>
<tr>
<th scope="col">
<input type="checkbox" class="tv-checkbox" aria-label="Select all rows" />
</th>
<th scope="col"><span class="tv-th">Name <i class="fa-solid fa-sort tv-th__sort" aria-hidden="true"></i></span></th>
<th scope="col"><span class="tv-th">Email <i class="fa-solid fa-sort tv-th__sort" aria-hidden="true"></i></span></th>
<th scope="col"><span class="tv-th">Status</span></th>
</tr>
</thead>
<tbody>
<tr>
<td><input type="checkbox" class="tv-checkbox" aria-label="Select row 1" /></td>
<td>
<div class="tv-user">
<span class="tv-avatar-sm" aria-hidden="true">A</span>
<span class="tv-truncate">Avery Lee</span>
</div>
</td>
<td><span class="tv-truncate">avery@label.com</span></td>
<td><span class="s-badge s-badge--success"><span class="dot" aria-hidden="true"></span>Active</span></td>
</tr>
<tr>
<td><input type="checkbox" class="tv-checkbox" aria-label="Select row 2" /></td>
<td>
<div class="tv-user">
<span class="tv-avatar-sm" aria-hidden="true">J</span>
<span class="tv-truncate">Jordan Smith</span>
</div>
</td>
<td><span class="tv-truncate">jordan@label.com</span></td>
<td><span class="s-badge s-badge--warning"><span class="dot" aria-hidden="true"></span>Pending</span></td>
</tr>
</tbody>
</table>
</div>
</div>
<h3 class="section-subtitle">Empty state</h3>
<div class="demo-panel">
<div class="table-scroll table-scroll--tv">
<table class="ds-table ds-table--tv">
<thead>
<tr>
<th scope="col"><span class="tv-th">Title</span></th>
<th scope="col"><span class="tv-th">Owner</span></th>
<th scope="col"><span class="tv-th">Updated</span></th>
</tr>
</thead>
<tbody>
<tr class="tv-row-empty">
<td colspan="3">
<div class="tv-empty-inline">
<p>No rows yet</p>
<button type="button" class="btn btn-sm btn-primary">Import data</button>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
React (TypeScript)
Use the same structure as the HTML block with className instead of class. Keep token/CSS imports in your app shell.
import type { ReactNode } from "react";
/** Mirror the HTML demo: replace class=> className, self-close void elements, keep WMG Chords global CSS loaded. */
export function TableViewsExample(): ReactNode {
return (
<>
{/* TODO: paste JSX equivalent of the HTML tab */}
</>
);
}
Markdown (AI & docs)
Single bundle for Cursor, ChatGPT, or Confluence: rules plus a fenced HTML block you can extend.
# WMG Chords — Table views
Use with AI tools or internal docs. Tokens: `/tokens/wmg-chords.css`; components: `dashboard/design-system.css`.
## HTML
```html
<h2 class="section-title" id="h-tv">Table views</h2>
<h3 class="section-subtitle">User directory</h3>
<p class="section-desc tv-section-note">
Mirrors the user-management table: sortable headers, avatars, truncated labels, +N tag with scrollable tooltip, em dash for empty cells, and a
kebab action.
</p>
<div class="demo-panel">
<div class="table-scroll table-scroll--tv">
<table class="ds-table ds-table--tv ds-table--zebra">
<colgroup>
<col class="tv-col tv-col--name" />
<col class="tv-col tv-col--email" />
<col class="tv-col tv-col--lg" />
<col class="tv-col tv-col--label" />
<col class="tv-col tv-col--role" />
<col class="tv-col tv-col--login" />
<col class="tv-col tv-col--actions" />
</colgroup>
<thead>
<tr>
<th scope="col">
<span class="tv-th">Name <i class="fa-solid fa-sort tv-th__sort" aria-hidden="true"></i></span>
</th>
<th scope="col">
<span class="tv-th">Email <i class="fa-solid fa-sort tv-th__sort" aria-hidden="true"></i></span>
</th>
<th scope="col">
<span class="tv-th">Label group <i class="fa-solid fa-sort tv-th__sort" aria-hidden="true"></i></span>
</th>
<th scope="col">
<span class="tv-th">Label <i class="fa-solid fa-sort tv-th__sort" aria-hidden="true"></i></span>
</th>
<th scope="col">
<span class="tv-th">Role <i class="fa-solid fa-sort tv-th__sort" aria-hidden="true"></i></span>
</th>
<th scope="col">
<span class="tv-th">
Last login <i class="fa-solid fa-sort tv-th__sort" aria-hidden="true"></i>
<button type="button" class="tv-info-btn" aria-label="About last login" tabindex="0">
<i class="fa-solid fa-circle-info" aria-hidden="true"></i>
</button>
</span>
</th>
<th scope="col" class="ds-table-actions"><span class="visually-hidden">Actions</span></th>
</tr>
</thead>
<tbody>
<tr>
<td>
<div class="tv-user">
<span class="tv-avatar-sm" aria-hidden="true">EB</span>
<span class="tooltip-wrap">
<span class="tv-truncate tooltip-trigger">Elizabeth Brown</span>
<span class="tooltip-bubble tooltip-bubble--table" role="tooltip">Elizabeth Brown</span>
</span>
</div>
</td>
<td>
<div class="tooltip-wrap">
<span class="tv-truncate tooltip-trigger">elizabeth.brown@wmg.com</span>
<span class="tooltip-bubble tooltip-bubble--table" role="tooltip">elizabeth.brown@wmg.com</span>
</div>
</td>
<td>
<div class="tv-cell-cluster">
<span class="tooltip-wrap">
<span class="tv-truncate tooltip-trigger">Elizabeth Coverag…</span>
<span class="tooltip-bubble tooltip-bubble--table" role="tooltip">Elizabeth Coverage Group Name</span>
</span>
<span class="tooltip-wrap tooltip-wrap--interactive">
<span class="tv-tag-more tooltip-trigger" tabindex="0">+2</span>
<span class="tooltip-bubble tooltip-bubble--table tv-tooltip-more" role="tooltip">
<ul class="tv-tooltip-list">
<li>ADA North America</li>
<li>ADA South America</li>
</ul>
</span>
</span>
</div>
</td>
<td><span class="tv-empty-dash">—</span></td>
<td>
<div class="tv-cell-cluster">
<span class="tv-truncate">Ops admin</span>
<span class="tooltip-wrap">
<button type="button" class="tv-info-btn" aria-label="Role details" tabindex="0">
<i class="fa-solid fa-circle-info" aria-hidden="true"></i>
</button>
<span class="tooltip-bubble tooltip-bubble--table" role="tooltip">Full role description for Ops admin appears here.</span>
</span>
</div>
</td>
<td>
<div class="tv-cell-cluster">
<span class="tv-truncate">2 days ago</span>
<span class="tooltip-wrap">
<button type="button" class="tv-info-btn" aria-label="Last login detail" tabindex="0">
<i class="fa-solid fa-circle-info" aria-hidden="true"></i>
</button>
<span class="tooltip-bubble tooltip-bubble--table" role="tooltip">Last successful login: Feb 4, 2026 · 9:42 AM UTC</span>
</span>
</div>
</td>
<td class="ds-table-actions">
<button type="button" class="tv-row-action" aria-label="Row actions for Elizabeth Brown">
<i class="fa-solid fa-ellipsis-vertical" aria-hidden="true"></i>
</button>
</td>
</tr>
<tr>
<td>
<div class="tv-user">
<span class="tv-avatar-sm" aria-hidden="true">SD</span>
<span class="tooltip-wrap">
<span class="tv-truncate tooltip-trigger">Susan Davis</span>
<span class="tooltip-bubble tooltip-bubble--table" role="tooltip">Susan Davis</span>
</span>
</div>
</td>
<td>
<div class="tooltip-wrap">
<span class="tv-truncate tooltip-trigger">susan.davis@yahoo.com</span>
<span class="tooltip-bubble tooltip-bubble--table" role="tooltip">susan.davis@yahoo.com</span>
</div>
</td>
<td><span class="tv-empty-dash">—</span></td>
<td>
<div class="tooltip-wrap">
<span class="tv-truncate tooltip-trigger">Radiance Records</span>
<span class="tooltip-bubble tooltip-bubble--table" role="tooltip">Radiance Records</span>
</div>
</td>
<td>
<div class="tv-cell-cluster">
<span class="tv-truncate">Label admin</span>
<span class="tooltip-wrap">
<button type="button" class="tv-info-btn" aria-label="Role details" tabindex="0">
<i class="fa-solid fa-circle-info" aria-hidden="true"></i>
</button>
<span class="tooltip-bubble tooltip-bubble--table" role="tooltip">Manages label roster and metadata.</span>
</span>
</div>
</td>
<td>
<div class="tv-cell-cluster">
<span class="tv-truncate">1 day ago</span>
<span class="tooltip-wrap">
<button type="button" class="tv-info-btn" aria-label="Last login detail" tabindex="0">
<i class="fa-solid fa-circle-info" aria-hidden="true"></i>
</button>
<span class="tooltip-bubble tooltip-bubble--table" role="tooltip">Last successful login: Feb 5, 2026 · 4:10 PM UTC</span>
</span>
</div>
</td>
<td class="ds-table-actions">
<button type="button" class="tv-row-action" aria-label="Row actions for Susan Davis">
<i class="fa-solid fa-ellipsis-vertical" aria-hidden="true"></i>
</button>
</td>
</tr>
<tr>
<td>
<div class="tv-user">
<span class="tv-avatar-sm" aria-hidden="true">MK</span>
<span class="tv-truncate">Morgan Kim</span>
</div>
</td>
<td><span class="tv-truncate">morgan.kim@partner.io</span></td>
<td>
<div class="tv-cell-cluster">
<span class="tv-truncate">Global Marketing</span>
<span class="tooltip-wrap tooltip-wrap--interactive">
<span class="tv-tag-more tooltip-trigger" tabindex="0">+5</span>
<span class="tooltip-bubble tooltip-bubble--table tv-tooltip-more" role="tooltip">
<ul class="tv-tooltip-list">
<li>EU West</li>
<li>EU Central</li>
<li>US East</li>
<li>US West</li>
<li>APAC</li>
</ul>
</span>
</span>
</div>
</td>
<td><span class="tv-empty-dash">—</span></td>
<td>
<div class="tv-cell-cluster">
<span class="tv-truncate">Release manager</span>
<span class="tooltip-wrap">
<button type="button" class="tv-info-btn" aria-label="Role details" tabindex="0">
<i class="fa-solid fa-circle-info" aria-hidden="true"></i>
</button>
<span class="tooltip-bubble tooltip-bubble--table" role="tooltip">Coordinates release windows across territories.</span>
</span>
</div>
</td>
<td><span class="tv-truncate">Last year</span></td>
<td class="ds-table-actions">
<button type="button" class="tv-row-action" aria-label="Row actions for Morgan Kim">
<i class="fa-solid fa-ellipsis-vertical" aria-hidden="true"></i>
</button>
</td>
</tr>
</tbody>
</table>
</div>
</div>
<h3 class="section-subtitle">Bulk selection</h3>
<p class="section-desc">Reserve the leading column for checkboxes (select all in the header). Keeps scan lines aligned with the table above.</p>
<div class="demo-panel">
<div class="table-scroll table-scroll--tv">
<table class="ds-table ds-table--tv ds-table--zebra">
<colgroup>
<col style="width: 5%" />
<col style="width: 25%" />
<col style="width: 38%" />
<col style="width: 32%" />
</colgroup>
<thead>
<tr>
<th scope="col">
<input type="checkbox" class="tv-checkbox" aria-label="Select all rows" />
</th>
<th scope="col"><span class="tv-th">Name <i class="fa-solid fa-sort tv-th__sort" aria-hidden="true"></i></span></th>
<th scope="col"><span class="tv-th">Email <i class="fa-solid fa-sort tv-th__sort" aria-hidden="true"></i></span></th>
<th scope="col"><span class="tv-th">Status</span></th>
</tr>
</thead>
<tbody>
<tr>
<td><input type="checkbox" class="tv-checkbox" aria-label="Select row 1" /></td>
<td>
<div class="tv-user">
<span class="tv-avatar-sm" aria-hidden="true">A</span>
<span class="tv-truncate">Avery Lee</span>
</div>
</td>
<td><span class="tv-truncate">avery@label.com</span></td>
<td><span class="s-badge s-badge--success"><span class="dot" aria-hidden="true"></span>Active</span></td>
</tr>
<tr>
<td><input type="checkbox" class="tv-checkbox" aria-label="Select row 2" /></td>
<td>
<div class="tv-user">
<span class="tv-avatar-sm" aria-hidden="true">J</span>
<span class="tv-truncate">Jordan Smith</span>
</div>
</td>
<td><span class="tv-truncate">jordan@label.com</span></td>
<td><span class="s-badge s-badge--warning"><span class="dot" aria-hidden="true"></span>Pending</span></td>
</tr>
</tbody>
</table>
</div>
</div>
<h3 class="section-subtitle">Empty state</h3>
<div class="demo-panel">
<div class="table-scroll table-scroll--tv">
<table class="ds-table ds-table--tv">
<thead>
<tr>
<th scope="col"><span class="tv-th">Title</span></th>
<th scope="col"><span class="tv-th">Owner</span></th>
<th scope="col"><span class="tv-th">Updated</span></th>
</tr>
</thead>
<tbody>
<tr class="tv-row-empty">
<td colspan="3">
<div class="tv-empty-inline">
<p>No rows yet</p>
<button type="button" class="btn btn-sm btn-primary">Import data</button>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
```