Lists
List/ListRow is the rows-of-selectable-things primitive behind every picker in Silo — branch switcher, worktrees, workspace folders, the Extensions page. It stretches to fill its parent, truncates long content instead of overflowing, and ships its keyboard behavior built in.
(Third row shows truncate="start" on a long path; the last row is an AddRow.)
import { List, ListRow, Badge } from "@silo-code/sdk";
<List aria-label="Workspace folders">
<ListRow
selected={folder.primary}
leading={<FolderIcon />}
trailing={<Badge tone="accent">primary</Badge>}
onSelect={() => choose(folder)}
>
{folder.path}
</ListRow>
</List>;List
| Prop | Type | Notes |
|---|---|---|
aria-label | string | required — it's a listbox |
onActivate | ((index: number) => void)? | Enter / double-click |
ListRow
| Prop | Type | Notes |
|---|---|---|
selected | boolean? | the selected row gets the active fill |
leading | ReactNode? | icon slot (dimmed, fixed) |
trailing | ReactNode? | badge(s) and/or IconButton size="sm"(s) — several are fine side by side |
truncate | "end" | "start" | default "end". Use "start" for paths, where the filename end matters most |
onSelect / onActivate | (() => void)? | click / Enter-or-double-click |
Layout behavior — guaranteed, don't fight it
- The list and its rows are full-width: they fill the parent and never push past its edge, however long the content. Row text truncates with an ellipsis;
trailingcontent (badges, icon buttons) never shrinks or gets pushed offscreen. truncate="start"ellipsizes the front (…agent/projects/xerro-edit) — the right choice for file paths.- When a row's content is genuinely likely to truncate, wrap it in
Tooltipwithdisabled={!isTruncated}so a hover reveals the full value — see the pattern inTooltip's docs.
Keyboard — built in, one tab stop
The whole list is a single tab stop. Once focused: ↑/↓ move a focus ring row to row, Space/Enter selects the focused row, and focus survives the re-render a selection triggers — a user can Space → arrow → Space indefinitely without the list dropping focus. Don't attach your own key handlers to rows.
AddRow
The ghost "+ Add Folder…" action that sits flush under a list — visually a row, semantically a button. No fill at rest, bg-hover on hover, pressed feedback like every other button.
<List aria-label="Folders">…</List>
<AddRow onClick={addFolder}>Add Folder…</AddRow>| Color | Token |
|---|---|
| Row hover / selected fill | --silo-list-hover-bg / --silo-list-active-bg |
| Row text / leading icon | --silo-color-text-hi / --silo-color-text-lo |
| Focus ring | --silo-color-accent |
Filter-above-list (the picker pattern) is a composition with SearchInput — see Building modals.