Data Table
Data table. A <x-table> parent with nested <x-table.th> / <x-table.td> / <x-table.empty> cells owns the whole "table in a card" recipe: card face, header row, cell rhythm, row hover, last-row border removal, right-aligned tabular-nums numeric columns, edge padding aligned with x-card's p-lg, and an empty-state placeholder. Body rows stay plain <tr>, so @forelse and wire:key work unchanged. Three axes: size (sm/md/lg), card, hover.
Basic ledger — the table brings its own card face
| Workspace | Members | Seats | Plan | Alerts | |
|---|---|---|---|---|---|
| Acme Marketing | 18 | 5 / 10 | Active | ||
| Northwind Sales | 7 | 7 / 7 | Seats full | ||
| Globex Support | 42 | 31 / 50 | Active | ||
| Initech Research | 3 | 1 / 5 | Trial |
<x-table>
<x-slot:head>
<x-table.th>Workspace</x-table.th>
<x-table.th numeric>Members</x-table.th>
<x-table.th numeric>Seats</x-table.th>
<x-table.th>Plan</x-table.th>
<x-table.th align="right">Alerts</x-table.th>
<x-table.th action />
</x-slot:head>
<tr>
<x-table.td><span class="font-medium">Acme Marketing</span></x-table.td>
<x-table.td numeric muted>18</x-table.td>
<x-table.td numeric>
<span class="font-medium">5</span><span class="text-base-content/35"> / 10</span>
</x-table.td>
<x-table.td><x-badge color="success" appearance="soft" size="sm">Active</x-badge></x-table.td>
<x-table.td align="right"><x-toggle size="sm" :checked="true" /></x-table.td>
<x-table.td action><x-button size="xs" appearance="ghost">Edit</x-button></x-table.td>
</tr>
<tr>
<x-table.td><span class="font-medium">Northwind Sales</span></x-table.td>
<x-table.td numeric muted>7</x-table.td>
<x-table.td numeric>
<span class="font-medium">7</span><span class="text-base-content/35"> / 7</span>
</x-table.td>
<x-table.td><x-badge color="warning" appearance="soft" size="sm">Seats full</x-badge></x-table.td>
<x-table.td align="right"><x-toggle size="sm" /></x-table.td>
<x-table.td action><x-button size="xs" appearance="ghost">Edit</x-button></x-table.td>
</tr>
<tr>
<x-table.td><span class="font-medium">Globex Support</span></x-table.td>
<x-table.td numeric muted>42</x-table.td>
<x-table.td numeric>
<span class="font-medium">31</span><span class="text-base-content/35"> / 50</span>
</x-table.td>
<x-table.td><x-badge color="success" appearance="soft" size="sm">Active</x-badge></x-table.td>
<x-table.td align="right"><x-toggle size="sm" :checked="true" /></x-table.td>
<x-table.td action><x-button size="xs" appearance="ghost">Edit</x-button></x-table.td>
</tr>
<tr>
<x-table.td><span class="font-medium">Initech Research</span></x-table.td>
<x-table.td numeric muted>3</x-table.td>
<x-table.td numeric>
<span class="font-medium">1</span><span class="text-base-content/35"> / 5</span>
</x-table.td>
<x-table.td><x-badge color="neutral" appearance="soft" size="sm">Trial</x-badge></x-table.td>
<x-table.td align="right"><x-toggle size="sm" /></x-table.td>
<x-table.td action><x-button size="xs" appearance="ghost">Edit</x-button></x-table.td>
</tr>
</x-table>
<div class="rounded-[var(--radius-box)] tune-border border-base-content/10 bg-base-100 text-base-content overflow-x-auto">
<table class="w-full text-sm [&_th:first-child]:pl-lg [&_th:last-child]:pr-lg [&_td:first-child]:pl-lg [&_td:last-child]:pr-lg">
<thead>
<tr class="border-b-[length:var(--border)] border-base-content/10 text-left text-xs text-base-content/45">
<th class="py-sm px-sm font-medium align-middle">
Workspace
</th>
<th class="py-sm px-sm font-medium align-middle text-right whitespace-nowrap">
Members
</th>
<th class="py-sm px-sm font-medium align-middle text-right whitespace-nowrap">
Seats
</th>
<th class="py-sm px-sm font-medium align-middle">
Plan
</th>
<th class="py-sm px-sm font-medium align-middle text-right">
Alerts
</th>
<th class="py-sm px-sm font-medium align-middle text-right whitespace-nowrap"></th>
</tr>
</thead>
<tbody class="[&>tr]:border-b [&>tr]:border-base-content/10 [&>tr:last-child]:border-b-0 [&>tr]:transition-colors [&>tr:not(.pn-table-empty):hover]:bg-base-200/60">
<tr>
<td class="py-md px-sm align-middle">
<span class="font-medium">Acme Marketing</span>
</td>
<td class="py-md px-sm align-middle text-right whitespace-nowrap tabular-nums text-base-content/60">
18
</td>
<td class="py-md px-sm align-middle text-right whitespace-nowrap tabular-nums">
<span class="font-medium">5</span>
<span class="text-base-content/35">/ 10</span>
</td>
<td class="py-md px-sm align-middle">
<span class="inline-flex items-center font-medium tune-border whitespace-nowrap rounded-[var(--radius-selector)] text-xs leading-none px-2 py-0.5 gap-1 bg-success/15 text-success border-transparent">Active</span>
</td>
<td class="py-md px-sm align-middle text-right">
<label for="toggle_6a98fee094bab" class="block cursor-pointer"><span class="inline-flex items-center gap-3"><input type="checkbox" role="switch" id="toggle_6a98fee094bab" class="peer sr-only" checked>
<span class="h-5 w-9 relative inline-block shrink-0 border-[length:var(--border)] rounded-[var(--radius-field)] transition-colors peer-focus-visible:ring-2 peer-focus-visible:ring-offset-1 peer-focus-visible:ring-current peer-checked:[&_.xy-thumb]:translate-x-4 bg-base-300 border-base-content/10 peer-checked:bg-primary peer-checked:border-primary" aria-hidden="true"><span class="xy-thumb size-4 absolute top-1/2 left-0.5 -translate-y-1/2 rounded-[var(--radius-field)] bg-base-100 border-[length:var(--border)] border-base-content/10 shadow-[var(--shadow-field)] transition-transform pointer-events-none"></span></span></span></label>
</td>
<td class="py-md px-sm align-middle text-right whitespace-nowrap">
<button class="inline-flex items-center justify-center whitespace-nowrap font-medium tracking-wide transition-colors focus:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 rounded-[var(--radius-field)] border-[length:var(--border)] h-[var(--h-field-xs)] px-[var(--px-field-xs)] text-[length:var(--text-field-xs)] gap-1 bg-transparent text-base-content border-transparent hover:bg-base-200 focus-visible:ring-base-300 cursor-pointer">Edit</button>
</td>
</tr>
<tr>
<td class="py-md px-sm align-middle">
<span class="font-medium">Northwind Sales</span>
</td>
<td class="py-md px-sm align-middle text-right whitespace-nowrap tabular-nums text-base-content/60">
7
</td>
<td class="py-md px-sm align-middle text-right whitespace-nowrap tabular-nums">
<span class="font-medium">7</span>
<span class="text-base-content/35">/ 7</span>
</td>
<td class="py-md px-sm align-middle">
<span class="inline-flex items-center font-medium tune-border whitespace-nowrap rounded-[var(--radius-selector)] text-xs leading-none px-2 py-0.5 gap-1 bg-warning/15 text-warning border-transparent">Seats full</span>
</td>
<td class="py-md px-sm align-middle text-right">
<label for="toggle_6a98fee094e05" class="block cursor-pointer"><span class="inline-flex items-center gap-3"><input type="checkbox" role="switch" id="toggle_6a98fee094e05" class="peer sr-only">
<span class="h-5 w-9 relative inline-block shrink-0 border-[length:var(--border)] rounded-[var(--radius-field)] transition-colors peer-focus-visible:ring-2 peer-focus-visible:ring-offset-1 peer-focus-visible:ring-current peer-checked:[&_.xy-thumb]:translate-x-4 bg-base-300 border-base-content/10 peer-checked:bg-primary peer-checked:border-primary" aria-hidden="true"><span class="xy-thumb size-4 absolute top-1/2 left-0.5 -translate-y-1/2 rounded-[var(--radius-field)] bg-base-100 border-[length:var(--border)] border-base-content/10 shadow-[var(--shadow-field)] transition-transform pointer-events-none"></span></span></span></label>
</td>
<td class="py-md px-sm align-middle text-right whitespace-nowrap">
<button class="inline-flex items-center justify-center whitespace-nowrap font-medium tracking-wide transition-colors focus:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 rounded-[var(--radius-field)] border-[length:var(--border)] h-[var(--h-field-xs)] px-[var(--px-field-xs)] text-[length:var(--text-field-xs)] gap-1 bg-transparent text-base-content border-transparent hover:bg-base-200 focus-visible:ring-base-300 cursor-pointer">Edit</button>
</td>
</tr>
<tr>
<td class="py-md px-sm align-middle">
<span class="font-medium">Globex Support</span>
</td>
<td class="py-md px-sm align-middle text-right whitespace-nowrap tabular-nums text-base-content/60">
42
</td>
<td class="py-md px-sm align-middle text-right whitespace-nowrap tabular-nums">
<span class="font-medium">31</span>
<span class="text-base-content/35">/ 50</span>
</td>
<td class="py-md px-sm align-middle">
<span class="inline-flex items-center font-medium tune-border whitespace-nowrap rounded-[var(--radius-selector)] text-xs leading-none px-2 py-0.5 gap-1 bg-success/15 text-success border-transparent">Active</span>
</td>
<td class="py-md px-sm align-middle text-right">
<label for="toggle_6a98fee094ff4" class="block cursor-pointer"><span class="inline-flex items-center gap-3"><input type="checkbox" role="switch" id="toggle_6a98fee094ff4" class="peer sr-only" checked>
<span class="h-5 w-9 relative inline-block shrink-0 border-[length:var(--border)] rounded-[var(--radius-field)] transition-colors peer-focus-visible:ring-2 peer-focus-visible:ring-offset-1 peer-focus-visible:ring-current peer-checked:[&_.xy-thumb]:translate-x-4 bg-base-300 border-base-content/10 peer-checked:bg-primary peer-checked:border-primary" aria-hidden="true"><span class="xy-thumb size-4 absolute top-1/2 left-0.5 -translate-y-1/2 rounded-[var(--radius-field)] bg-base-100 border-[length:var(--border)] border-base-content/10 shadow-[var(--shadow-field)] transition-transform pointer-events-none"></span></span></span></label>
</td>
<td class="py-md px-sm align-middle text-right whitespace-nowrap">
<button class="inline-flex items-center justify-center whitespace-nowrap font-medium tracking-wide transition-colors focus:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 rounded-[var(--radius-field)] border-[length:var(--border)] h-[var(--h-field-xs)] px-[var(--px-field-xs)] text-[length:var(--text-field-xs)] gap-1 bg-transparent text-base-content border-transparent hover:bg-base-200 focus-visible:ring-base-300 cursor-pointer">Edit</button>
</td>
</tr>
<tr>
<td class="py-md px-sm align-middle">
<span class="font-medium">Initech Research</span>
</td>
<td class="py-md px-sm align-middle text-right whitespace-nowrap tabular-nums text-base-content/60">
3
</td>
<td class="py-md px-sm align-middle text-right whitespace-nowrap tabular-nums">
<span class="font-medium">1</span>
<span class="text-base-content/35">/ 5</span>
</td>
<td class="py-md px-sm align-middle">
<span class="inline-flex items-center font-medium tune-border whitespace-nowrap rounded-[var(--radius-selector)] text-xs leading-none px-2 py-0.5 gap-1 bg-base-content/15 text-base-content border-transparent">Trial</span>
</td>
<td class="py-md px-sm align-middle text-right">
<label for="toggle_6a98fee0951cf" class="block cursor-pointer"><span class="inline-flex items-center gap-3"><input type="checkbox" role="switch" id="toggle_6a98fee0951cf" class="peer sr-only">
<span class="h-5 w-9 relative inline-block shrink-0 border-[length:var(--border)] rounded-[var(--radius-field)] transition-colors peer-focus-visible:ring-2 peer-focus-visible:ring-offset-1 peer-focus-visible:ring-current peer-checked:[&_.xy-thumb]:translate-x-4 bg-base-300 border-base-content/10 peer-checked:bg-primary peer-checked:border-primary" aria-hidden="true"><span class="xy-thumb size-4 absolute top-1/2 left-0.5 -translate-y-1/2 rounded-[var(--radius-field)] bg-base-100 border-[length:var(--border)] border-base-content/10 shadow-[var(--shadow-field)] transition-transform pointer-events-none"></span></span></span></label>
</td>
<td class="py-md px-sm align-middle text-right whitespace-nowrap">
<button class="inline-flex items-center justify-center whitespace-nowrap font-medium tracking-wide transition-colors focus:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 rounded-[var(--radius-field)] border-[length:var(--border)] h-[var(--h-field-xs)] px-[var(--px-field-xs)] text-[length:var(--text-field-xs)] gap-1 bg-transparent text-base-content border-transparent hover:bg-base-200 focus-visible:ring-base-300 cursor-pointer">Edit</button>
</td>
</tr>
</tbody>
</table>
</div>
<x-table>
<x-slot:head>
<x-table.th>Workspace</x-table.th>
<x-table.th numeric>Members</x-table.th>
<x-table.th action />
</x-slot:head>
@forelse ($workspaces as $workspace)
<tr wire:key="workspace-{{ $workspace->id }}">
<x-table.td>{{ $workspace->name }}</x-table.td>
<x-table.td numeric>{{ $workspace->members_count }}</x-table.td>
<x-table.td action>
<x-button size="xs" appearance="ghost">Edit</x-button>
</x-table.td>
</tr>
@empty
<x-table.empty>No workspaces yet</x-table.empty>
@endforelse
</x-table>
Empty state — <x-table.empty> spans every column automatically
| Workspace | Members | Seats | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
No workspaces yet Create one to start inviting members. |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
<x-table>
<x-slot:head>
<x-table.th>Workspace</x-table.th>
<x-table.th numeric>Members</x-table.th>
<x-table.th numeric>Seats</x-table.th>
<x-table.th action />
</x-slot:head>
<x-table.empty>
<p class="text-sm text-base-content/55">No workspaces yet</p>
<p class="mt-2xs text-xs text-base-content/35">Create one to start inviting members.</p>
</x-table.empty>
</x-table>
<div class="rounded-[var(--radius-box)] tune-border border-base-content/10 bg-base-100 text-base-content overflow-x-auto">
<table class="w-full text-sm [&_th:first-child]:pl-lg [&_th:last-child]:pr-lg [&_td:first-child]:pl-lg [&_td:last-child]:pr-lg">
<thead>
<tr class="border-b-[length:var(--border)] border-base-content/10 text-left text-xs text-base-content/45">
<th class="py-sm px-sm font-medium align-middle">
Workspace
</th>
<th class="py-sm px-sm font-medium align-middle text-right whitespace-nowrap">
Members
</th>
<th class="py-sm px-sm font-medium align-middle text-right whitespace-nowrap">
Seats
</th>
<th class="py-sm px-sm font-medium align-middle text-right whitespace-nowrap"></th>
</tr>
</thead>
<tbody class="[&>tr]:border-b [&>tr]:border-base-content/10 [&>tr:last-child]:border-b-0 [&>tr]:transition-colors [&>tr:not(.pn-table-empty):hover]:bg-base-200/60">
<tr class="pn-table-empty">
<td colspan="999" class="py-xl px-lg text-center">
<p class="text-sm text-base-content/55">
No workspaces yet
</p>
<p class="mt-2xs text-xs text-base-content/35">
Create one to start inviting members.
</p>
</td>
</tr>
</tbody>
</table>
</div>
Density — size="sm" / size="lg"
size="sm"
| Workspace | Members |
|---|---|
| Acme Marketing | 18 |
| Northwind Sales | 7 |
| Globex Support | 42 |
size="lg"
| Workspace | Members |
|---|---|
| Acme Marketing | 18 |
| Northwind Sales | 7 |
| Globex Support | 42 |
<div class="grid gap-lg md:grid-cols-2 md:items-start">
<div class="space-y-xs">
<p class="text-xs font-medium text-base-content/50">size="sm"</p>
<x-table size="sm">
<x-slot:head>
<x-table.th>Workspace</x-table.th>
<x-table.th numeric>Members</x-table.th>
</x-slot:head>
<tr>
<x-table.td>Acme Marketing</x-table.td>
<x-table.td numeric>18</x-table.td>
</tr>
<tr>
<x-table.td>Northwind Sales</x-table.td>
<x-table.td numeric>7</x-table.td>
</tr>
<tr>
<x-table.td>Globex Support</x-table.td>
<x-table.td numeric>42</x-table.td>
</tr>
</x-table>
</div>
<div class="space-y-xs">
<p class="text-xs font-medium text-base-content/50">size="lg"</p>
<x-table size="lg">
<x-slot:head>
<x-table.th>Workspace</x-table.th>
<x-table.th numeric>Members</x-table.th>
</x-slot:head>
<tr>
<x-table.td>Acme Marketing</x-table.td>
<x-table.td numeric>18</x-table.td>
</tr>
<tr>
<x-table.td>Northwind Sales</x-table.td>
<x-table.td numeric>7</x-table.td>
</tr>
<tr>
<x-table.td>Globex Support</x-table.td>
<x-table.td numeric>42</x-table.td>
</tr>
</x-table>
</div>
</div>
<div class="grid gap-lg md:grid-cols-2 md:items-start">
<div class="space-y-xs">
<p class="text-xs font-medium text-base-content/50">
size="sm"
</p>
<div class="rounded-[var(--radius-box)] tune-border border-base-content/10 bg-base-100 text-base-content overflow-x-auto">
<table class="w-full text-xs [&_th:first-child]:pl-lg [&_th:last-child]:pr-lg [&_td:first-child]:pl-lg [&_td:last-child]:pr-lg">
<thead>
<tr class="border-b-[length:var(--border)] border-base-content/10 text-left text-xs text-base-content/45">
<th class="py-xs px-sm font-medium align-middle">
Workspace
</th>
<th class="py-xs px-sm font-medium align-middle text-right whitespace-nowrap">
Members
</th>
</tr>
</thead>
<tbody class="[&>tr]:border-b [&>tr]:border-base-content/10 [&>tr:last-child]:border-b-0 [&>tr]:transition-colors [&>tr:not(.pn-table-empty):hover]:bg-base-200/60">
<tr>
<td class="py-sm px-sm align-middle">
Acme Marketing
</td>
<td class="py-sm px-sm align-middle text-right whitespace-nowrap tabular-nums">
18
</td>
</tr>
<tr>
<td class="py-sm px-sm align-middle">
Northwind Sales
</td>
<td class="py-sm px-sm align-middle text-right whitespace-nowrap tabular-nums">
7
</td>
</tr>
<tr>
<td class="py-sm px-sm align-middle">
Globex Support
</td>
<td class="py-sm px-sm align-middle text-right whitespace-nowrap tabular-nums">
42
</td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="space-y-xs">
<p class="text-xs font-medium text-base-content/50">
size="lg"
</p>
<div class="rounded-[var(--radius-box)] tune-border border-base-content/10 bg-base-100 text-base-content overflow-x-auto">
<table class="w-full text-sm [&_th:first-child]:pl-lg [&_th:last-child]:pr-lg [&_td:first-child]:pl-lg [&_td:last-child]:pr-lg">
<thead>
<tr class="border-b-[length:var(--border)] border-base-content/10 text-left text-xs text-base-content/45">
<th class="py-sm px-sm font-medium align-middle">
Workspace
</th>
<th class="py-sm px-sm font-medium align-middle text-right whitespace-nowrap">
Members
</th>
</tr>
</thead>
<tbody class="[&>tr]:border-b [&>tr]:border-base-content/10 [&>tr:last-child]:border-b-0 [&>tr]:transition-colors [&>tr:not(.pn-table-empty):hover]:bg-base-200/60">
<tr>
<td class="py-lg px-sm align-middle">
Acme Marketing
</td>
<td class="py-lg px-sm align-middle text-right whitespace-nowrap tabular-nums">
18
</td>
</tr>
<tr>
<td class="py-lg px-sm align-middle">
Northwind Sales
</td>
<td class="py-lg px-sm align-middle text-right whitespace-nowrap tabular-nums">
7
</td>
</tr>
<tr>
<td class="py-lg px-sm align-middle">
Globex Support
</td>
<td class="py-lg px-sm align-middle text-right whitespace-nowrap tabular-nums">
42
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
Inside an existing card — <x-card :padding="false"> + <x-table :card="false">
Invoices this month
3 records| Invoice | Customer | Amount | |
|---|---|---|---|
| INV-2041 | Acme Marketing | $1,280.00 | |
| INV-2042 | Northwind Sales | $540.00 | |
| INV-2043 | Globex Support | $12,900.00 |
<x-card :padding="false">
<x-slot:header>
<div class="p-lg flex items-baseline justify-between">
<h2 class="text-sm font-semibold">Invoices this month</h2>
<span class="text-xs text-base-content/40">3 records</span>
</div>
</x-slot:header>
<x-table :card="false">
<x-slot:head>
<x-table.th>Invoice</x-table.th>
<x-table.th>Customer</x-table.th>
<x-table.th numeric>Amount</x-table.th>
<x-table.th action />
</x-slot:head>
<tr>
<x-table.td><span class="font-medium">INV-2041</span></x-table.td>
<x-table.td muted>Acme Marketing</x-table.td>
<x-table.td numeric>$1,280.00</x-table.td>
<x-table.td action><x-button size="xs" appearance="ghost">View</x-button></x-table.td>
</tr>
<tr>
<x-table.td><span class="font-medium">INV-2042</span></x-table.td>
<x-table.td muted>Northwind Sales</x-table.td>
<x-table.td numeric>$540.00</x-table.td>
<x-table.td action><x-button size="xs" appearance="ghost">View</x-button></x-table.td>
</tr>
<tr>
<x-table.td><span class="font-medium">INV-2043</span></x-table.td>
<x-table.td muted>Globex Support</x-table.td>
<x-table.td numeric>$12,900.00</x-table.td>
<x-table.td action><x-button size="xs" appearance="ghost">View</x-button></x-table.td>
</tr>
</x-table>
</x-card>
<div class="rounded-[var(--radius-box)] tune-border overflow-hidden bg-base-100 text-base-content border-base-content/10 flex flex-col">
<div class="-mx-[var(--border)] px-[var(--border)] border-b-[length:var(--border)] border-base-content/10">
<div class="p-lg flex items-baseline justify-between">
<h2 class="text-sm font-semibold">
Invoices this month
</h2><span class="text-xs text-base-content/40">3 records</span>
</div>
</div>
<div class="-mx-[var(--border)] px-[var(--border)] flex-1">
<div class="overflow-x-auto">
<table class="w-full text-sm [&_th:first-child]:pl-lg [&_th:last-child]:pr-lg [&_td:first-child]:pl-lg [&_td:last-child]:pr-lg">
<thead>
<tr class="border-b-[length:var(--border)] border-base-content/10 text-left text-xs text-base-content/45">
<th class="py-sm px-sm font-medium align-middle">
Invoice
</th>
<th class="py-sm px-sm font-medium align-middle">
Customer
</th>
<th class="py-sm px-sm font-medium align-middle text-right whitespace-nowrap">
Amount
</th>
<th class="py-sm px-sm font-medium align-middle text-right whitespace-nowrap"></th>
</tr>
</thead>
<tbody class="[&>tr]:border-b [&>tr]:border-base-content/10 [&>tr:last-child]:border-b-0 [&>tr]:transition-colors [&>tr:not(.pn-table-empty):hover]:bg-base-200/60">
<tr>
<td class="py-md px-sm align-middle">
<span class="font-medium">INV-2041</span>
</td>
<td class="py-md px-sm align-middle text-base-content/60">
Acme Marketing
</td>
<td class="py-md px-sm align-middle text-right whitespace-nowrap tabular-nums">
$1,280.00
</td>
<td class="py-md px-sm align-middle text-right whitespace-nowrap">
<button class="inline-flex items-center justify-center whitespace-nowrap font-medium tracking-wide transition-colors focus:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 rounded-[var(--radius-field)] border-[length:var(--border)] h-[var(--h-field-xs)] px-[var(--px-field-xs)] text-[length:var(--text-field-xs)] gap-1 bg-transparent text-base-content border-transparent hover:bg-base-200 focus-visible:ring-base-300 cursor-pointer">View</button>
</td>
</tr>
<tr>
<td class="py-md px-sm align-middle">
<span class="font-medium">INV-2042</span>
</td>
<td class="py-md px-sm align-middle text-base-content/60">
Northwind Sales
</td>
<td class="py-md px-sm align-middle text-right whitespace-nowrap tabular-nums">
$540.00
</td>
<td class="py-md px-sm align-middle text-right whitespace-nowrap">
<button class="inline-flex items-center justify-center whitespace-nowrap font-medium tracking-wide transition-colors focus:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 rounded-[var(--radius-field)] border-[length:var(--border)] h-[var(--h-field-xs)] px-[var(--px-field-xs)] text-[length:var(--text-field-xs)] gap-1 bg-transparent text-base-content border-transparent hover:bg-base-200 focus-visible:ring-base-300 cursor-pointer">View</button>
</td>
</tr>
<tr>
<td class="py-md px-sm align-middle">
<span class="font-medium">INV-2043</span>
</td>
<td class="py-md px-sm align-middle text-base-content/60">
Globex Support
</td>
<td class="py-md px-sm align-middle text-right whitespace-nowrap tabular-nums">
$12,900.00
</td>
<td class="py-md px-sm align-middle text-right whitespace-nowrap">
<button class="inline-flex items-center justify-center whitespace-nowrap font-medium tracking-wide transition-colors focus:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 rounded-[var(--radius-field)] border-[length:var(--border)] h-[var(--h-field-xs)] px-[var(--px-field-xs)] text-[length:var(--text-field-xs)] gap-1 bg-transparent text-base-content border-transparent hover:bg-base-200 focus-visible:ring-base-300 cursor-pointer">View</button>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
Turning the row hover off — :hover="false"
| Region | Signups |
|---|---|
| Europe | 1,204 |
| Asia Pacific | 982 |
<x-table :hover="false">
<x-slot:head>
<x-table.th>Region</x-table.th>
<x-table.th numeric>Signups</x-table.th>
</x-slot:head>
<tr>
<x-table.td>Europe</x-table.td>
<x-table.td numeric>1,204</x-table.td>
</tr>
<tr>
<x-table.td>Asia Pacific</x-table.td>
<x-table.td numeric>982</x-table.td>
</tr>
</x-table>
<div class="rounded-[var(--radius-box)] tune-border border-base-content/10 bg-base-100 text-base-content overflow-x-auto">
<table class="w-full text-sm [&_th:first-child]:pl-lg [&_th:last-child]:pr-lg [&_td:first-child]:pl-lg [&_td:last-child]:pr-lg">
<thead>
<tr class="border-b-[length:var(--border)] border-base-content/10 text-left text-xs text-base-content/45">
<th class="py-sm px-sm font-medium align-middle">
Region
</th>
<th class="py-sm px-sm font-medium align-middle text-right whitespace-nowrap">
Signups
</th>
</tr>
</thead>
<tbody class="[&>tr]:border-b [&>tr]:border-base-content/10 [&>tr:last-child]:border-b-0">
<tr>
<td class="py-md px-sm align-middle">
Europe
</td>
<td class="py-md px-sm align-middle text-right whitespace-nowrap tabular-nums">
1,204
</td>
</tr>
<tr>
<td class="py-md px-sm align-middle">
Asia Pacific
</td>
<td class="py-md px-sm align-middle text-right whitespace-nowrap tabular-nums">
982
</td>
</tr>
</tbody>
</table>
</div>
Props
| Prop | Default | Description |
|---|---|---|
size | md | Row density on <x-table>: sm (compact, text-xs body) / md / lg (roomy). Flows down to the cells — never pass it on a cell. |
card | true | true = the table owns its card face (border, radius, bg-base-100). Pass :card="false" to embed it in an existing <x-card :padding="false">. |
hover | true | Row hover highlight on body rows. The empty-state row is always excluded. |
numeric | false | On th/td: right-aligns. On td it also adds tabular-nums so digit columns line up. Use for counts, amounts, dates. |
action | false | On th/td: right-aligns; on td it also adds whitespace-nowrap. Use for the trailing button column (<x-table.th action /> for the header). |
muted | false | td only — dims the text (text-base-content/60) for secondary figures that should not compete with the key column. |
align | null | Explicit left / center / right override; wins over numeric and action. |
- Body rows are plain <tr> elements — divider, hover and last-row rules are injected from the parent, so loops and wire:key need no wrapper component.
- size flows from the parent to every cell via @aware; passing size on a cell has no effect.
- The shell already scrolls horizontally. Wrap in <x-table-scroll> only when you also want the fade and the scroll buttons.