Skip to content

Table

Native table with an optional interactive adapter.

Browsers
Chrome 123+Firefox 121+Safari 17.5+
Tier
0
Bundle compressed
617 B
Forced layout budget
0 ms
Axe budget
0
SSR compatible
Yes
Published contract
Test harness

Playground

Table

Native table example

Team members
NameRoleStatus
Alice ChenAdminActive
Bob SmithEditorActive
Carol LeeViewerInvited
3 members · 2 active

Sort, filter and expand

RoleDetails
Alice ChenAdmin
Bob SmithEditor
Carol LeeViewer
3 members · 0 selected

Sticky headers, footer and columns

Member 1Editormember1@example.comActive
Member 2Editormember2@example.comActive
Member 3Editormember3@example.comActive
Member 4Editormember4@example.comActive
Member 5Editormember5@example.comActive
Member 6Editormember6@example.comActive
Member 7Editormember7@example.comActive
Member 8Editormember8@example.comActive
Member 9Editormember9@example.comActive
Member 10Editormember10@example.comActive
Member 11Editormember11@example.comActive
Member 12Editormember12@example.comActive
Member 13Editormember13@example.comActive
Member 14Editormember14@example.comActive
Member 15Editormember15@example.comActive
Member 16Editormember16@example.comActive
Member 17Editormember17@example.comActive
Member 18Editormember18@example.comActive
Member 19Editormember19@example.comActive
Member 20Editormember20@example.comActive
Member 21Editormember21@example.comActive
Member 22Editormember22@example.comActive
Member 23Editormember23@example.comActive
Member 24Editormember24@example.comActive
24 members

API

Table.Root (native)

PropTypeDefaultDescription
layout"auto" | "fixed""auto"Native table layout. Selection, sorting and expansion use the explicit TableClient entry.
size"sm" | "md" | "lg"—Cell spacing from the selected stylesheet.
variant"solid" | "outline" | "ghost"—Surface variant from the selected stylesheet.
renderReactElement | ((props, state) => ReactElement)—Replace the rendered element while keeping behavior and accessibility wiring.

Table.Footer

PropTypeDefaultDescription
stickyboolean—Pins the footer to the block end of the scroll container.
renderReactElement | ((props, state) => ReactElement)—Replace the rendered element while keeping behavior and accessibility wiring.

Table.RowHeader / Table.Cell / Table.ColumnHeader

PropTypeDefaultDescription
align"start" | "center" | "end""start"Logical text alignment for this cell.
sticky"start" | "end"—Pins a cell to the logical inline edge. For adjacent sticky cells set --uiify-table-sticky-offset on each cell.
renderReactElement | ((props, state) => ReactElement)—Replace the rendered element while keeping behavior and accessibility wiring.

TableClient.ExpandTrigger / TableClient.ExpandedRow

PropTypeDefaultDescription
rowId*string—Shared row key connecting the expansion button to its native <tr>. Put a <td colSpan={columnCount}> inside the expanded row.

TableClient.Root — @gunkin/uiify/components/table/client

PropTypeDefaultDescription
aria-labelstring—Accessible name for the table when no visible caption or heading names it.
aria-labelledbystring—Id of the element that labels the table.
selectionMode"none" | "single" | "multiple""none"Whether rows can be selected, and how many at a time; "none" renders a plain static table with no grid role.
selectionBehavior"toggle" | "replace"—Whether clicking a row adds it to the selection or replaces the current selection.
defaultSelectedKeysIterable<string>—Row ids selected initially, leaving the selection uncontrolled inside the component.
selectedKeysIterable<string>—Row ids selected right now, making the selection controlled by the caller.
onSelectionChange(selectedKeys: Set<string>) => void—Called with the new set of selected row ids whenever the selection changes.
defaultSortDescriptorSortDescriptor | null—Column and direction sorted initially, leaving the sort state uncontrolled inside the component.
sortDescriptorSortDescriptor | null—Column and direction sorted right now, making the sort controlled.
onSortChange(descriptor: SortDescriptor | null) => void—Called with the new sort descriptor, or null, when a sortable column header is activated.
expandedKeys / defaultExpandedKeysIterable<string>—Controlled or initial expanded row keys.
onExpandedChange(keys: Set<string>) => void—Reports expansion requests. Controlled rows wait for the updated keys.
renderReactElement | ((props, state) => ReactElement)—Replace the rendered element while keeping behavior and accessibility wiring.

Table.Header

PropTypeDefaultDescription
stickybooleanfalsePins this section to the scroll container; Header uses block start and Footer uses block end.
renderReactElement | ((props, state) => ReactElement)—Replace the rendered element while keeping behavior and accessibility wiring.

Table.Body

PropTypeDefaultDescription
childrenReactNode—The rows of the table body.
renderReactElement | ((props, state) => ReactElement)—Replace the rendered element while keeping behavior and accessibility wiring.

Table.Row

PropTypeDefaultDescription
id*string—Stable row id used as the selection key and as the element id.
disabledbooleanfalsePrevents the row from being selected or focused by keyboard.
selectedboolean—Marks the row selected in the server-rendered markup before the selection store takes over.
renderReactElement | ((props, state) => ReactElement)—Replace the rendered element while keeping behavior and accessibility wiring.

Table.ColumnHeader

PropTypeDefaultDescription
id*string—Column id that sort descriptors refer to.
allowsSortingbooleanfalseMakes the header toggle sorting for its column and publish aria-sort.
sortDirection"ascending" | "descending" | null—Sort direction rendered for this column, used for the initial server markup when sorting is allowed.
onClickReact.MouseEventHandler<HTMLTableCellElement>—Runs before sorting; preventDefault() vetoes the sort change.
childrenReactNode—The header label.
renderReactElement | ((props, state) => ReactElement)—Replace the rendered element while keeping behavior and accessibility wiring.

Table.Cell

PropTypeDefaultDescription
childrenReactNode—The cell contents.
renderReactElement | ((props, state) => ReactElement)—Replace the rendered element while keeping behavior and accessibility wiring.

Table.Caption

PropTypeDefaultDescription
childrenReactNode—The caption text describing the table.
renderReactElement | ((props, state) => ReactElement)—Replace the rendered element while keeping behavior and accessibility wiring.

Table.RowSelect

PropTypeDefaultDescription
rowId*string—Id of the row this checkbox selects and deselects.

Keyboard

KeyAction
TabFocus sort, selection and expansion controls in TableClient
Enter / SpaceActivate a focused sort or expansion button; toggle a checkbox
Arrow keysMove between selectable body rows in TableClient

Accessibility

The default Table renders native <table>, <caption>, <thead>, <tbody> and <tfoot> without client JavaScript; use ColumnHeader and RowHeader for header semantics. The /client entry adds sorting, selection, keyboard row navigation and controlled expansion, exposed through aria-sort, aria-expanded and aria-controls. ExpandedRow is a native <tr>; put a Cell with colSpan inside it. Filtering and ordering stay with the consumer.

Styling hooks

data-uiify-tabledata-partdata-layoutdata-sizedata-variantdata-stickydata-selecteddata-disabled--uiify-table-sticky-offset