组件

SelectList

SelectList 显示一个可滚动的文本选项列表,并用勾选标记标出当前选中的一项。行由核心根据你传入的字符串数组渲染,因此即使有上千个选项,开销也与可见的几行相当,滚动时不会运行任何 JS。

ui-select-list.tsx 在线编辑 在新标签页打开
// 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";

#用法

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 会填满父视图(flex: 1)。如果要把它放在滚动视图里或与其他内容并排,请给它一个固定高度的父视图:

<View style={{ height: 240, borderRadius: 12, overflow: "hidden" }}>
  <SelectList options={cities} onSelect={(i) => console.log(cities[i])} />
</View>

#受控与非受控

  • 受控:传入 value(选中项的下标,null 表示未选中),并在 onSelect 中更新它。勾选标记跟随 value;如果你不更新 value,勾选标记就不会移动。
  • 非受控:不传 value。列表自己记录选择,每次按下都会移动勾选标记,onSelect 照样会报告每次选择。

每次按下都会调用 onSelect,包括用户按下已经选中的那一项。

#行

每行至少 48 pt 高,左右内边距 16 pt,显示选项文本,选中行末尾有一个勾选标记(✓)。行与行之间有 1 pt 分隔线,按下时会高亮。

#属性

属性类型默认值说明
optionsstring[]必填选项,按顺序排列。
valuenumber | null无(非受控)由应用控制时,选中项的下标。
class、classList、style、testID、onLayout、ref作用于列表的根视图。

#事件

事件参数触发时机
onSelectnumber:选项的下标用户按下了某个选项。

#主题

部位主题键
行背景background
按下时的行list.active.background
文本foreground
勾选标记primary.background
分隔线border

参见主题。

#无障碍

每一行的角色都是 button,选中的行会报告为 selected(已选中)。屏幕阅读器朗读选项的文本。

#相关

  • ListView:由你自己渲染行。
  • Sheet:把 SelectList 放进底部面板,当作选择器使用。
  • ActionSheet:在系统对话框中显示少量操作。