Skip to main content
Urbicon UI

Row Selection

Checkbox selection for one row or many, with a select-all across every filtered page. The table owns the selected set until you pass selectedIds.

Selection Modes

selectionMode switches on a checkbox column. "multi" lets the user mark any number of rows and adds a select-all checkbox to the header; "single" keeps one row at a time — selecting a row clears the one before.

Select-all covers every row that matches the current search and filters, on every page — not just the rows on screen. While only part of that set is selected, the checkbox shows as indeterminate.

The selection is a set of ids, keyed by item.id with the row's position as fallback. Sorting, paging and filtering change what is on screen, not the set — a selected row that moves to another page stays selected. onSelectionChange reports the selected items — the rows themselves, not their ids.

Live — select-all spans both pages

Name
Role
Department
Location
Emma Wilson
Staff Engineer
Platform
Berlin
Liam Chen
Product Designer
Design
Hamburg
Sofia Martinez
Engineering Manager
Platform
Munich
James Park
Frontend Developer
Product
Remote

0 selected

<script>
  let selected = $state([]);
</script>

<Table
  {items}
  {columns}
  selectionMode="multi"
  onSelectionChange={(items) => (selected = items)}
/>

<p>{selected.length} selected</p>

A row you only show somewhere else — the master/detail pattern — is not a selection. activeRowId highlights it without bringing the checkbox column along.

Selecting by Row Click

In "single" mode a click anywhere on the row selects it — the checkbox is not the only target. With onRowClick or expandable rows a click already means something else, so only the checkbox selects. rowClickSelects decides explicitly, in either mode.

Single select — click the row

Name
Role
Department
Location
Emma Wilson
Staff Engineer
Platform
Berlin
Liam Chen
Product Designer
Design
Hamburg
Sofia Martinez
Engineering Manager
Platform
Munich
James Park
Frontend Developer
Product
Remote
<Table
  {items}
  {columns}
  selectionMode="single"
  onSelectionChange={(items) => handleSelect(items[0])}
/>

Controlled Selection

The table owns the selection until you pass selectedIds — then your code does. Take it over when the set has a life outside the table: preselected from the URL, cleared after a bulk action, shared with another view. If all you need is a starting value, initialSelectedIds seeds the table-owned selection once; later changes to the prop are ignored.

selectedIds drives the table; clicks keep arriving through onSelectionChange as items, and the write-back maps them to ids. An empty array is a valid value — nothing selected; undefined hands the selection back to the table. A controlled selection is never written to storage — prefs.persistSelection restores only a table-owned one.

Controlled — buttons and checkboxes write the same set

2 selected
Name
Role
Department
Location
Emma Wilson
Staff Engineer
Platform
Berlin
Liam Chen
Product Designer
Design
Hamburg
Sofia Martinez
Engineering Manager
Platform
Munich
James Park
Frontend Developer
Product
Remote
Aisha Patel
Data Scientist
Data
Berlin
Noah Kim
DevOps Engineer
Platform
Hamburg
<script>
  let selectedIds = $state<Array<string | number>>([]);
</script>

<Table
  {items}
  {columns}
  selectionMode="multi"
  {selectedIds}
  onSelectionChange={(items) => (selectedIds = items.map((item) => item.id))}
/>

<Button onclick={() => (selectedIds = [])}>Clear selection</Button>

Write every change back

When onSelectionChange does not feed selectedIds, clicks still change the screen, nothing warns — and the next change to the prop throws the user's clicks away.