组件
Group
Group 把若干行放进一个圆角框里,行与行之间以细线分隔,就像设置页中的一个分区。每个 JSX 子元素成为一行。可以在框上方加一句简短的标题说明,在下方加一段解释文字。
// Group: settings-style rows; each child becomes a row with a divider.
import { mount, signal, Text, View } from "nsh";
import { Group, Stepper } from "nsh/ui/mobile";
function Row(props: { label: string; value: string; onPress?: () => void }) {
return (
<View onPress={props.onPress} style={{ flexDirection: "row", justifyContent: "space-between" }}>
<Text>{props.label}</Text>
<Text style={{ color: "#737373" }}>{props.value}</Text>
</View>
);
}
function App() {
const notifications = signal(true);
const size = signal(16);
return (
<View style={{ flex: 1, backgroundColor: "#f5f5f5", padding: 16, paddingTop: 24, gap: 24 }}>
<Group header={<Text>ACCOUNT</Text>}>
<Row label="Name" value="Ada Lovelace" />
<Row label="E-mail" value="ada@example.com" />
</Group>
<Group
header={<Text>PREFERENCES</Text>}
footer={<Text>Tap the first row to toggle it. Rows are the app's JSX; the group adds the box and the dividers.</Text>}
>
<Row
label="Notifications"
value={notifications() ? "On" : "Off"}
onPress={() => notifications.set(!notifications())}
/>
<View style={{ flexDirection: "row", alignItems: "center", justifyContent: "space-between" }}>
<Text>{`Text size ${size()}`}</Text>
<Stepper value={size()} min={12} max={24} onChange={(v) => size.set(v)} />
</View>
</Group>
</View>
);
}
mount(App);import { Group } from "nsh/ui/mobile";
#用法
import { mount, signal, Text, View } from "nsh";
import { Group } from "nsh/ui/mobile";
function App() {
const sounds = signal(true);
return (
<View style={{ flex: 1, backgroundColor: "#f5f5f5", padding: 16, paddingTop: 48 }}>
<Group
header={<Text>NOTIFICATIONS</Text>}
footer={<Text>Sounds play for new messages only.</Text>}
>
<Text>Show previews</Text>
<View
onPress={() => sounds.set(!sounds())}
style={{ flexDirection: "row", justifyContent: "space-between" }}
>
<Text>Sounds</Text>
<Text>{sounds() ? "On" : "Off"}</Text>
</View>
</Group>
</View>
);
}
mount(App);
#行
Group 把每个子元素包进一行:水平内边距 16 pt,垂直内边距 12 pt,最小高度 44 pt(舒适触控目标的最小尺寸)。内容垂直居中。除第一行外,每一行顶部都有一条 1 pt 的分隔线。
行的内容就是你传入的内容:要在一行里放标签和值,就放一个 flexDirection: "row" 的 <View>;要让这一行可按,就在该视图上加 onPress。子元素增加或删除时(比如通过 <If> 或 <Each>),分组会相应更新行和分隔线。
<Group header={<Text>DEVICES</Text>}>
<Each of={devices()}>
{(device) => (
<View style={{ flexDirection: "row", justifyContent: "space-between" }}>
<Text>{device().name}</Text>
<Text style={{ color: "#737373" }}>{device().status}</Text>
</View>
)}
</Each>
</Group>
#标题说明与脚注
标题说明距左侧 16 pt,使用小号(text-sm)的弱化文字;脚注使用更小号(text-xs)的弱化文字。标题说明、圆角框和脚注之间间距 8 pt。两者都是可选的。
#Props
| Prop | 类型 | 默认值 | 说明 |
|---|---|---|---|
header | JSX.Element | 无 | 框的上方:一句简短的标题说明。 |
footer | JSX.Element | 无 | 框的下方:解释文字。 |
children | JSX.Element | 无 | 各行,每个子元素一行。 |
class、classList、style、testID、onLayout、ref | 作用于分组的根视图(容纳标题说明、圆角框和脚注的那一列)。 |
Group 没有事件。
#主题
| 部位 | 主题键 |
|---|---|
| 圆角框 | group_box.background,圆角半径 radius.lg |
| 行文字颜色 | group_box.foreground |
| 分隔线 | border |
| 标题说明与脚注文字 | muted.foreground |
参见主题。
#无障碍
Group 不添加任何角色或标签,每一行的内容按你写的样子被朗读。如果某一行可按,请给它的视图设置 accessibilityRole(例如 "button"),必要时再加上 accessibilityLabel。参见无障碍。