Live demo — this example is server-driven; run the showcase locally for the interactive version.

Table

A grid of rows and columns for structured data. Use when every row has the same shape and column headers carry meaning. For list-shaped data without column headers, prefer Data list.

Examples

Basic

Default rows — three users with a name, status, role and edit action.

Name Status Role Actions
John Doe Active Admin
Jane Smith Inactive Editor
Bob Johnson Active Viewer

Plain

modifiers="pf-m-plain" — no borders or hover treatment, with a table <caption>.

Q2 releases by service
Service Version Released Owner
api-gateway 2.14.0 Apr 3 Platform
payments 1.9.2 May 12 Commerce
search 3.1.0 Jun 20 Discovery

Header tooltips and popovers

Header cells carry info tooltips and popovers via pf-v6-c-table__column-help; plus a centered column, secondary-row backgrounds and a colspan cell.

Repositories
Branches
Pull requests
Workspaces Last commit
one two three four five
one - 2 four - 2 five - 2
one - 3 two - 3 three - 3 four - 3 five - 3

Compact

compact=true — denser padding for info-heavy tables.

Name Status Role Last seen
John Doe Active Admin 2 minutes ago
Jane Smith Inactive Editor 3 days ago
Bob Johnson Active Viewer 1 hour ago
Alice Chen Active Admin just now
Diego Ramos Pending Viewer never

Compact expandable

compact=true expandable=true — dense rows that still expand to a detail row.

Pipeline Last run Duration
build-frontend Passed 4m 12s
312 tests, 0 failures. Artifacts published to the snapshot repository.
build-backend Failed 7m 45s
2 integration tests failed in the persistence module; see run #482 for logs.
nightly-e2e Passed 28m 03s
Full browser matrix green. Flake rate 0.4% over the last 30 runs.

Striped

striped=true — alternating row background for easier horizontal scanning.

Repository Branches Pull requests Workspaces
apollo 12 3 5
mercury 4 0 1
gemini 8 2 2
orion 21 5 9
artemis 3 1 0

Striped expandable

With striped=true expandable=true PF stripes whole odd <tbody> groups instead of odd rows.

Backup job Schedule Last result
postgres-daily 02:00 UTC Succeeded
42 GB snapshot in 11 minutes; verified restore on the standby cluster.
object-store-weekly Sun 04:00 UTC Succeeded
1.8 TB incremental to cold storage; 97% deduplication ratio.
config-hourly Hourly Failed
Vault token expired at 13:00; renewal issued and the 14:00 run recovered.

Striped multiple tbody

pf-m-striped / pf-m-striped-even set per tbody keep the stripe pattern continuous across body groups.

Production and staging deployments
Service Version Replicas Status
api-gateway (prod) 2.14.0 6 Running
payments (prod) 1.9.2 4 Running
search (prod) 3.1.0 3 Running
api-gateway (staging) 2.15.0-rc.1 2 Running
payments (staging) 1.10.0-rc.2 1 Crash-looping
search (staging) 3.2.0-rc.1 1 Running

Striped tr

pf-m-striped on individual rows for full manual control.

Rows striped one by one
Repository Branches Pull requests Workspaces
apollo 12 3 5
mercury 4 0 1
gemini 8 2 2
orion 21 5 9

Borderless

borderless=true — removes row dividers; pairs well with striped on dashboards.

Service Region Uptime
api-gateway us-east-1 99.99%
payments eu-west-1 99.97%
search ap-southeast-1 99.95%
notifications us-west-2 99.92%

Borderless compact

borderless=true compact=true — the densest, quietest layout.

Contact Team Location Last seen
Amelia Chen Platform Boston 5 minutes ago
Jordan Blake Commerce Toronto 1 hour ago
Priya Nair Discovery Bengaluru Yesterday
Tomás Rivera Design Madrid 3 days ago

Borderless expandable

borderless=true expandable=true — row expansion without row dividers.

Dataset Rows Updated
orders-2026 1.2M Hourly
Partitioned by order date; retained for 24 months. Sourced from the checkout event stream.
customers 840K Daily
Deduplicated nightly against the CRM export; PII columns are masked outside production.

Borderless compound expandable

Borderless with per-cell compound expansion toggles.

Registry Images Tags Visibility
registry.internal/platform Private
Most pulled: pha-runtime (2.1K/day), pha-gateway (900/day). 3 images unused for 90+ days.
Latest: 2.15.1, 2.15.0, 2.14.3. Untagged manifests are garbage-collected weekly.
registry.internal/sandbox Team
Scratch images for experiments; auto-deleted after 30 days of inactivity.
Tags follow the branch name; only main is retained past a week.

Sortable (HTMX)

Column headers post to /api/htmx/table-sort and swap the table; no client-side sorting logic.

Alice Chen Admin us-east-1
Bob Johnson Viewer eu-west-1
Diego Ramos Viewer ap-southeast-1
Jane Smith Editor eu-west-1
John Doe Admin us-west-2

Sortable — custom control

A toolbar select drives the sort instead of clickable headers — each choice hits /api/htmx/table-sort-custom and swaps the server-sorted table.

Sort column


Sort direction

Name Role Region
Alice ChenAdminus-east-1
Bob JohnsonViewereu-west-1
Diego RamosViewerap-southeast-1
Jane SmithEditoreu-west-1
John DoeAdminus-west-2

Expandable (Alpine)

Per-row toggle reveals a detail row beneath; state lives in x-data on the <tbody>.

Name Status Region
api-gateway Healthy us-east-1

12 healthy instances across 3 availability zones. Average latency 42ms. Last deployed 4 hours ago.

payments Degraded eu-west-1

8 healthy instances, 1 unhealthy. P99 latency 320ms (threshold 250ms). Oncall has been paged.

search Healthy ap-southeast-1

4 healthy instances. Index size 2.4 GB across 16 shards. No alerts.

Animated expandable

pf-m-animate-expand fades and slides the detail row; rows stay rendered so CSS can animate.

Service Status Region
api-gateway Healthy us-east-1
12 healthy instances across 3 availability zones. Average latency 42ms.
payments Degraded eu-west-1
8 healthy instances, 1 unhealthy. P99 latency 320ms (threshold 250ms).
search Healthy ap-southeast-1
Expandable row content has no padding.

Expandable with set width columns

pf-m-width-30/pf-m-width-20 on header cells fix column proportions while rows expand.

Incident Severity Opened
INC-2041 — checkout latency spike Major 09:14
Root cause traced to a cache stampede after the 09:05 deploy. Mitigated by rolling back.
INC-2042 — stale search results Minor 11:47
Indexer lag reached 40 minutes; queue drained after scaling consumers from 2 to 6.

Expandable with nested table

The expanded detail row hosts a compact, borderless inner table in a pf-m-no-background wrapper.

Deployment Environment Status
release-2.15 Production In progress
Step Finished Result
Database migration 14:02 Succeeded
Canary (5% traffic) 14:20 Succeeded
Full rollout Running
release-2.14 Production Complete
Step Finished Result
Database migration May 28, 10:14 Succeeded
Canary (5% traffic) May 28, 10:31 Succeeded
Full rollout May 28, 11:05 Succeeded

Selectable with checkboxes

A leading pf-v6-c-table__check control column with per-row checkboxes and a select-all in the header.

Name Status Role
John Doe Active Admin
Jane Smith Inactive Editor
Bob Johnson Active Viewer

Selectable with indeterminate state

Live tri-state select-all: checked when every row is selected, indeterminate when only some are.

Name Status Role
John Doe Active Admin
Jane Smith Inactive Editor
Bob Johnson Active Viewer

Selectable with radio

Single-row selection — radio inputs sharing one name in the pf-v6-c-table__check column, no select-all.

Name Status Role
John Doe Active Admin
Jane Smith Inactive Editor
Bob Johnson Active Viewer

Actions

A trailing pf-v6-c-table__action cell with a kebab overflow menu (Alpine); the last row shows the inline-action alternative.

Name Status Role
John Doe Active Admin
Jane Smith Inactive Editor
Bob Johnson Active Viewer

Overflow menu

A pf-v6-c-overflow-menu action cell: a button group on large screens that collapses to a kebab below lg.

Job Queue State
nightly-report batch Idle
index-rebuild maintenance Running

Empty state

A single full-width body cell (colspan) holding the empty-state component for a table with no rows.

Name Status Role

No results found

No results match the filter criteria. Clear all filters and try again.

Width and text modifiers

pf-m-width-{pct} pins a column's width; pf-m-truncate, pf-m-fit-content and pf-m-nowrap control cell text overflow.

Name (20%) Description (30%, truncate) Role (fit) Created (nowrap)
John Doe A very long description that will be truncated with an ellipsis when it exceeds the column width Administrator Jan 1, 2026
Jane Smith Another lengthy piece of descriptive text that demonstrates the truncation behaviour of the cell Editor Feb 14, 2026

Text control

Per-cell text behavior: pf-m-truncate, pf-m-break-word, pf-m-wrap, pf-m-fit-content and pf-m-nowrap.

Truncate (width 20%) Break word Wrapping table header text. This th text will wrap instead of truncate. Fit content No wrap
This text will truncate instead of wrap in table layout and wrap gracefully in grid layout. http://thisisaverylongurlthatneedstobreakusethebreakwordmodifier.org By default, thead cells will truncate and tbody cells will wrap. Use pf-m-wrap on a th to change its behavior. This cell's content will adjust itself to the parent th width. This modifier only affects table layouts. No wrap

Table text element

Wrapping cell content in pf-v6-c-table__text keeps text modifiers working in the grid layout and composes with PF layouts.

Cell content wrapped in the pf-v6-c-table__text element
Selector Result
td.pf-m-truncate
This cell contains a single table text wrapper and the cell applies pf-m-truncate, so the text truncates in table layout and stays controlled in grid layout.
pf-v6-l-stack
Multiple elements in a cell should be wrapped with a div or a PatternFly layout so the table's grid fallback doesn't stack them unexpectedly.

Long strings

No modifiers on purpose — a long string shrinks adjacent columns, the failure mode the width and text modifiers fix.

Repository Branches Pull requests Workspaces Last commit
Long lines of text will shrink adjacent column widths. 10 25 5 2 days ago
This example is not responsive. Adjacent tbody cells will shrink because this text is a longer string while adjacent text is short. Truncation can be overridden on th cells with pf-m-wrap, pf-m-nowrap or pf-m-fit-content. 10 25 5 2 days ago

Width constrained

pf-m-width-40 caps the column; the second body adds pf-m-truncate on the cell.

Width 40 Branches Pull requests Fit content th Last commit
Since this is a long string of text and the other cells contain short strings, the header's width is capped at 40% so it cannot crowd out the other columns. 10 25 5 2 days ago
This string will truncate in table mode only. It is just as long as the one above, but pf-m-truncate clips it to the column width instead of wrapping. 10 25 5 2 days ago

Hidden/visible breakpoints

Columns show and hide per breakpoint with pf-m-hidden(-on-*) / pf-m-visible-on-* — resize to see them swap.

Repository Branches Pull requests Workspaces Last commit
apollo 12 3 5 2 days ago
mercury 4 0 1 5 hours ago
gemini 8 2 2 1 hour ago

Favoritable

A leading pf-v6-c-table__favorite star column; pf-m-favorited colours the star (Alpine toggles it).

Name Status Role
John Doe Active Admin
Jane Smith Inactive Editor
Bob Johnson Active Viewer

Favorites sortable

The favorite column header is a live sort control — clicking it reorders rows by their current favorited state.

Name Status Role
John Doe Active Admin
Jane Smith Inactive Editor
Bob Johnson Active Viewer

Clickable rows

Clicking (or Enter/Space on) a row selects it — pf-m-selected on the grid-variant table highlights the current row.

Name Status Role
John Doe Active Admin
Jane Smith Inactive Editor
Bob Johnson Active Viewer

Clickable and expandable

Clicking a row selects its tbody; the toggle expands the detail row without changing the selection.

Cluster Nodes Status
prod-us-east 14 Ready
Kubernetes 1.31, 14/14 nodes ready. Control plane spread across 3 zones.
staging 6 Ready
Mirrors prod topology at reduced scale. Auto-sleeps outside business hours.
dev-sandbox 3 Degraded
1 node cordoned for a kernel upgrade; workloads rescheduled automatically.

Nested column headers

pf-m-nested-column-header groups sub-columns (pf-v6-c-table__subhead) under a shared parent header via rowspan/colspan.

Name Contact Employment
Email Phone Role Level
John Doe john@example.com 555-0100 Admin Senior
Jane Smith jane@example.com 555-0101 Editor Mid
Bob Johnson bob@example.com 555-0102 Viewer Junior

Nested headers and expandable rows

Control columns span both header rows (rowspan=2) while grouped columns keep their subheads; rows expand as usual.

Name Contact Role
Email Phone
John Doe john@example.com 555-0100 Admin
Joined March 2024. Manages the platform and infrastructure teams.
Jane Smith jane@example.com 555-0101 Editor
Joined August 2025. Owns the editorial calendar and content review.

Nested headers, sticky header

Both nested header rows pin while the body scrolls inside the bounded wrapper.

Name Contact Employment
Email Phone Role Level
John Doe john@example.com 555-0100 Admin Senior
Jane Smith jane@example.com 555-0101 Editor Mid
Bob Johnson bob@example.com 555-0102 Viewer Junior
Amelia Chen amelia@example.com 555-0103 Admin Senior
Jordan Blake jordan@example.com 555-0104 Editor Senior
Priya Nair priya@example.com 555-0105 Viewer Mid
Tomás Rivera tomas@example.com 555-0106 Editor Junior

Editable rows

Each row toggles between a read view and inline inputs; Save commits the draft, Cancel discards it (Alpine). The action cell uses pf-v6-c-table__inline-edit-action.

Name Role Edit

Compound expandable

Each cell is its own toggle (pf-v6-c-table__compound-expansion-toggle); opening one expands a detail row scoped to that cell, one per row at a time.

Repository Branches Pull requests Workspaces
node-1
10 branches across 3 teams; default is main.
5 open pull requests, 2 awaiting review.
3 active workspaces, 1 archived.

Compound expandable with nested table

A compound toggle cell whose detail row contains a nested compact table.

Repository Branches Pull requests Workspaces
pha-runtime 3 workspaces
Branch Last commit Status
main 2 hours ago Passing
develop 20 minutes ago Passing
feature/icons 3 days ago Failing
2 pull requests currently under review.
pha-deployment 1 workspace
Branch Last commit Status
main 1 day ago Passing
develop 4 hours ago Passing
1 pull request currently under review.

Animated compound expandable

pf-m-animate-expand with per-cell rows; switching between open cells is instant via pf-m-no-animate-expand.

Workspace Members Projects Last activity
siemur/test-space 20 minutes ago
Amelia, Jordan, Priya, Sam and Tomás have access; Amelia is the owner.
Projects: storefront, billing-service and design-tokens.
siemur/staging 2 days ago
Jordan and Priya have access; Jordan is the owner.
Projects: load-test-harness.

Sticky header and column

In a scroll wrapper, pf-m-sticky-header pins the header and pf-v6-c-table__sticky-cell pf-m-left pins the first column — scroll the table to see both.

Repository Branches Pull requests Workspaces Last commit Contributors Open issues Size
api-gateway 12 branches 4 open 2 active 2 hours ago 18 people 7 issues 1.2 GB
payments 8 branches 6 open 3 active 5 hours ago 11 people 14 issues 0.9 GB
search 5 branches 1 open 1 active 1 day ago 6 people 3 issues 2.4 GB
notifications 9 branches 3 open 2 active 3 hours ago 9 people 5 issues 0.4 GB
billing 7 branches 2 open 1 active 6 hours ago 8 people 9 issues 1.1 GB
analytics 14 branches 8 open 4 active 30 min ago 22 people 18 issues 3.8 GB
auth 6 branches 0 open 1 active 2 days ago 5 people 2 issues 0.6 GB

pf-m-sticky-footer pins the totals row to the bottom of the scroll container.

Multiple sticky columns

Two left columns pin while scrolling right; the second offsets its inset and carries pf-m-border-right.

Node Status Zone Kubernetes version CPU allocatable Memory allocatable Pods running Created Kernel
node-a1 Ready us-east-1a v1.31.2 7.5 cores 28 GiB 42 86 days ago 6.1.0-18
node-a2 Ready us-east-1b v1.31.2 7.5 cores 28 GiB 38 86 days ago 6.1.0-18
node-b1 NotReady us-east-1c v1.30.6 15 cores 60 GiB 0 12 days ago 6.1.0-17
node-b2 Ready us-east-1a v1.31.2 15 cores 60 GiB 61 12 days ago 6.1.0-18

Sticky right column

The trailing column pins to the right edge with pf-m-border-left marking the boundary.

Node Zone Kubernetes version CPU allocatable Memory allocatable Pods running Created Kernel Status
node-a1 us-east-1a v1.31.2 7.5 cores 28 GiB 42 86 days ago 6.1.0-18 Ready
node-a2 us-east-1b v1.31.2 7.5 cores 28 GiB 38 86 days ago 6.1.0-18 Ready
node-b1 us-east-1c v1.30.6 15 cores 60 GiB 0 12 days ago 6.1.0-17 NotReady
node-b2 us-east-1a v1.31.2 15 cores 60 GiB 61 12 days ago 6.1.0-18 Ready

Tree table

pf-m-tree-view with role="treegrid"; parent rows toggle their children, indented automatically by aria-level.

Name Type Detail
Application servers
Group 2 nodes
web-1
Server 2 vCPU · us-east-1
web-2
Server 2 vCPU · us-east-1
Databases
Group 1 node
db-primary
Server 8 vCPU · eu-west-1

Tree table with checkboxes

Row checkboxes with a live cascade: parents check their children and show indeterminate for partial selections.

Name Type Detail
Application servers
Group 2 nodes
web-1
Server 2 vCPU · us-east-1
web-2
Server 2 vCPU · us-east-1
Databases
Group 1 node
db-primary
Server 8 vCPU · eu-west-1

Tree table with checkboxes and icons

Adds a tree-view-icon per row — folders for parents (open while expanded) and leaves for children.

Name Type Detail
Application servers
Group 2 nodes
web-1
Server 2 vCPU · us-east-1
web-2
Server 2 vCPU · us-east-1

Tree with no children or indentation

pf-m-no-inset removes the indent; all rows are leaves so the role stays grid.

Name Type Detail
web-1
Server 2 vCPU · us-east-1
web-2
Server 2 vCPU · us-east-1
db-primary
Server 8 vCPU · eu-west-1
cache-1
Server 4 vCPU · us-east-1

Draggable rows

Drag a row by its grip to reorder; the dragged row shows pf-m-ghost-row and drops into place by the pointer's midpoint.

Name Status Role
John Doe Active Admin
Jane Smith Inactive Editor
Bob Johnson Active Viewer

A summary row in pf-v6-c-table__tfoot (PatternFly 6.6+) — the th uses scope="row" so assistive tech announces the total's label.

Cell with image alignment

Cell alignment defaults to baseline, which drifts next to images — the first cell tops-aligns a 36px brand icon against the text block with pf-m-align-self-flex-start inside a nowrap flex. Sort headers reorder the rows live; the ? buttons open column-help popovers.

Workspaces
Last commit

Repository 1

2.6.6 provided by Red Hat Inc
10 25 5 2 days ago

Repository 2

2.6.6 provided by Github
10 25 5 2 days ago

Repository 3

1.2.3 provided by Google
10 25 5 2 days ago

Container query with drawer

The drawer panel declares container-type: inline-size with container-name: pf-v6-contain-table, so its pf-m-grid-md table switches between stacked and grid layout from the panel's width; the main table (pf-m-grid-lg) responds to the viewport. Close and re-open the panel with the toolbar's Toggle drawer button.

Repositories Branches Pull requests Workspaces Last commit
10 25 5 2 days ago
8 12 3 5 days ago
4 5 2 30 days ago

Drawer as a container

Repositories Branches Pull requests Workspaces Last commit
10 25 5 2 days ago
8 12 3 5 days ago
4 5 2 30 days ago

Sticky header with base and stuck

The base/stuck sticky-header pattern inside an offset scroll container.

Repositories Branches Pull requests Workspaces
Repository 1 10 25 5
Repository 2 10 25 5
Repository 3 10 25 5
Repository 4 10 25 5
Repository 5 10 25 5
Repository 6 10 25 5
Repository 7 10 25 5
Repository 8 10 25 5
Repository 9 10 25 5
Repository 10 10 25 5
Repository 11 10 25 5
Repository 12 10 25 5

Composable (pure Qute)

Sticky header in a scrollable region, sort headers and row selection — assembled from the slot-mode shell plus the table-sort-th, table-check-th and table-check-td includes. No Java model: the sort headers render the states; wire their attrs to HTMX to make them live.

Last commit
Repository 1 1 2 days ago
Repository 2 2 2 days ago
Repository 3 3 2 days ago
Repository 4 4 2 days ago
Repository 5 5 2 days ago
Repository 6 6 2 days ago
Repository 7 7 2 days ago
Repository 8 8 2 days ago

Composable expandable (pure Qute)

Expandable rows from table-tbody-expandable + table-toggle-td + table-expandable-tr, each tbody owning its own Alpine open state.

Repository Branches
Repo one 10
Repo one starts expanded — its tbody passes expanded=true.
Repo two 3
A pf-m-no-padding detail cell.

Composable tree (pure Qute)

A treegrid built from table-tree-tr bricks; the tbody owns the expansion booleans that toggleVar and showExpr reference.

Name Size
Documents
4 items
Report.pdf
2 MB
Media
1 item
Intro.mp4
40 MB
Archive
Empty

Documentation

Table props

The runtime template has two modes. Pass a typed org.sitenetsoft.quarkus.pha.model.Table (built with Table.builder()) as the table parameter and the caption, header (sort buttons, selection inputs, expandable-row toggles), bodies, action cells and footer all render from the model — the examples above with a Java tab are built this way. Or omit it and hand-write thead/tbody markup in the content slot using bare elements (PF v6 styles them via descendant selectors), as the composition-heavy examples (tree tables, compound expansion, sticky layouts) still do.

Table table = Table.builder()
    .id("users").ariaLabel("Users")
    .column("Name")
    .column(TableColumn.of("Status").sortable("status"))
    .actionColumn()
    .sortEndpoint("/api/htmx/table-sort")
    .row("John Doe", "Active", TableCell.kebab("John Doe actions", "Edit", "Delete"))
    .row(Table.row("Jane Smith", "Inactive",
            TableCell.actions(TableAction.secondary("Edit"), TableAction.danger("Delete"))))
    .build();

Template side, with table in the template data: {#include components/data-display/table table=table /}. Shell-mode parameters below.

* required
Name Type Description
* id String DOM id on the <table>.
compact boolean Adds pf-m-compact for denser rows.
gridMd boolean Adds pf-m-grid-md — collapses to stacked cards below md.
striped boolean Adds pf-m-striped for alternating row background.
borderless boolean Adds pf-m-no-border-rows — removes between-row dividers.
expandable boolean Adds pf-m-expandable — opt-in for the expandable-row layout.
ariaLabel String Sets aria-label on the table for screen readers.
slot content Qute block <thead> and <tbody> rows — bare elements; PF v6 styles them via descendant selectors.

Usage

Table vs. Data list. Use Table when every row has the same shape and column headers carry the meaning of each cell. Use Data list when rows are list-shaped (variable inner layout, no shared column meaning).

Sorting. Server-side. The sort buttons send hx-get with the column + direction; the endpoint returns a new <table> with rows reordered and the right column flagged with aria-sort. No client-side sort logic — keeps a single source of truth.

Expandable rows. Each pair of rows lives inside its own <tbody> with x-data="{ open: false }". Toggle the pf-m-expanded class on the <tbody> and x-show on the detail row.