Components
SelectList
SelectList shows a scrolling list of text options and marks the chosen one with a check mark. The core renders the
rows from your array of strings, so a list of thousands of options costs about as much as the visible rows, and no
JS runs while scrolling.
// SelectList: 500 options, one chosen; controlled and uncontrolled.
import { mount, signal, Text, View } from "nsh";
import { Button, SelectList } from "nsh/ui/mobile";
const cities = Array.from({ length: 500 }, (_, i) => `City ${i + 1}`);
const sizes = ["Small", "Medium", "Large"];
function App() {
const city = signal<number | null>(2);
const lastSize = signal("none");
return (
<View style={{ flex: 1, backgroundColor: "#f5f5f5", padding: 16, paddingTop: 24, gap: 12 }}>
<Text style={{ fontSize: 22, fontWeight: "700" }}>SelectList</Text>
<Text style={{ color: "#737373" }}>{`Controlled: ${city() === null ? "none" : cities[city()!]}`}</Text>
<Button
variant="secondary"
title="Choose the next city"
onPress={() => city.set(city() === null ? 0 : (city()! + 1) % cities.length)}
/>
<View style={{ flex: 1, borderRadius: 12, overflow: "hidden" }}>
<SelectList options={cities} value={city()} onSelect={(i) => city.set(i)} />
</View>
<Text style={{ color: "#737373" }}>{`Uncontrolled, last chosen: ${lastSize()}`}</Text>
<View style={{ height: 144, borderRadius: 12, overflow: "hidden" }}>
<SelectList options={sizes} onSelect={(i) => lastSize.set(sizes[i])} />
</View>
</View>
);
}
mount(App);import { SelectList } from "nsh/ui/mobile";
#Usage
import { mount, signal, Text, View } from "nsh";
import { SelectList } from "nsh/ui/mobile";
const languages = ["English", "Deutsch", "Español", "Français", "日本語", "中文"];
function App() {
const chosen = signal<number | null>(0);
return (
<View style={{ flex: 1, paddingTop: 48 }}>
<Text style={{ padding: 16 }}>{`Language: ${chosen() === null ? "none" : languages[chosen()!]}`}</Text>
<SelectList options={languages} value={chosen()} onSelect={(i) => chosen.set(i)} />
</View>
);
}
mount(App);
SelectList fills its parent (flex: 1). To show it inside a scroll view or next to other content, give it a parent
with a fixed height:
<View style={{ height: 240, borderRadius: 12, overflow: "hidden" }}>
<SelectList options={cities} onSelect={(i) => console.log(cities[i])} />
</View>
#Controlled and uncontrolled
- Controlled: pass
value(the chosen index, ornullfor none) and update it inonSelect. The check mark followsvalue. If you do not updatevalue, the check mark does not move. - Uncontrolled: leave out
value. The list keeps the choice itself and moves the check mark on each press.onSelectstill reports each choice.
onSelect is called on every press, also when the user presses the option that is already chosen.
#Rows
Each row is at least 48 pt tall, with 16 pt horizontal padding, the option’s text, and a check mark (✓) at the end of the chosen row. Rows are separated by 1 pt dividers and highlighted while pressed.
#Props
| Prop | Type | Default | Description |
|---|---|---|---|
options | string[] | required | The options, in order. |
value | number | null | none (uncontrolled) | The index of the chosen option, when the app controls it. |
class, classList, style, testID, onLayout, ref | Applied to the list’s root view. |
#Events
| Event | Payload | When |
|---|---|---|
onSelect | number: the option’s index | The user pressed an option. |
#Theming
| Part | Theme key |
|---|---|
| Row background | background |
| Row while pressed | list.active.background |
| Text | foreground |
| Check mark | primary.background |
| Dividers | border |
See Theming.
#Accessibility
Each row has the button role, and the chosen row is reported as selected. Screen readers read the option’s text.
#Related
- ListView: rows you render yourself.
- Sheet: show a SelectList in a bottom sheet as a picker.
- ActionSheet: a short list of actions in a system dialog.