iOS list
Inset list groups with labels, descriptions, leading symbols and independent trailing controls.
Preview
Connectivity
In action
When to use
Use it for
- Grouped settings, preferences and navigation rows.
- Omit onClick for rows containing an interactive trailing input.
Not for
- Nesting a switch or another interactive element inside an action row.
- Using a clickable row for plain informational content.
Install
Three ways in. They share one source, so the pixels match whichever you pick.
1. Import the package
npm install @noorddev/vlak-react
// once, next to your app's root
import "@noorddev/vlak-react/css";
import { IOSList, IOSListRow, IOSSwitch } from "@noorddev/vlak-react";Precompiled React and one stylesheet. No compiler to configure. Per-component imports work too: @noorddev/vlak-react/components/ios-list.
2. Vendor the source
npx @noorddev/vlak-cli add ios-list
The StyleX leaf lands in components/vlak/ with its dependencies, for your own compiler to own. See StyleX.
3. Through shadcn
npx shadcn add https://vlak.dev/r/ios-list.json
The same registry item, installed by shadcn's CLI.
CSS only
<link rel="stylesheet" href="node_modules/@noorddev/vlak/css/vlak.css" />
No React. Link vlak.css and use the markup and classes below.
React
import { IOSList, IOSListRow, IOSSwitch } from "@noorddev/vlak-react";
<IOSList title="Connections"><IOSListRow label={<label htmlFor="wifi">Wi-Fi</label>} trailing={<IOSSwitch id="wifi" defaultChecked />} /><IOSListRow label="Network details" disclosure onClick={() => console.log("Open network")} /></IOSList>Props
IOSList
An inset group of rows; controls remain separate focus targets.
| Prop | Type | Default | Description |
|---|---|---|---|
title | ReactNode | ||
footer | ReactNode |
Also accepts Omit<HTMLAttributes<HTMLElement>, "title">.
IOSListRow
Supply onClick for a native button, or omit it to hold a switch or other input.
| Prop | Type | Default | Description |
|---|---|---|---|
labelrequired | ReactNode | ||
description | ReactNode | ||
leading | ReactNode | ||
trailing | ReactNode | ||
disabled | boolean | ||
disclosure | boolean | false |
Also accepts Omit<HTMLAttributes<HTMLElement>, "children">.
Keyboard
| Keys | Does |
|---|---|
| Tab, Shift+Tab | Moves through action rows and the controls inside static rows. |
| Enter, Space | Activates a focused action row as a native button. |
Accessibility
- Group headings label their sections. Static rows are not unnecessary focus stops.
- Action rows use native buttons with disabled behavior and at least a 52px height.
Markup
<section class="rs-ios-list" aria-labelledby="settings-heading"><h3 class="rs-ios-list-title" id="settings-heading">Settings</h3><div class="rs-ios-list-group"><button class="rs-ios-list-row rs-ios-list-row-action" type="button"><span class="rs-ios-list-row-copy">General</span></button></div></section>