Skip to content
Source
Sign inSign up

ListRow.tsx

66 lines2.2 KB

1import { Platform, View } from "react-native";
2​
3import { useResolveClassNames } from "uniwind";
4import { SymbolView } from "./AppSymbol";
5import { ListRowLayout, type ListRowContentProps } from "./ListRowLayout";
6import { RadioIndicator } from "./RadioIndicator";
7import { RowPressable } from "./RowPressable";
8​
9export function ListRow(
10 props: ListRowContentProps & {
11 readonly onPress: () => void;
12 /** Marks the row as the chosen option while it still navigates. */
13 readonly selected?: boolean;
14 },
15) {
16 const rippleStyle = useResolveClassNames("bg-subtle-strong");
17 return (
18 <RowPressable
19 accessibilityRole="button"
20 accessibilityLabel={[props.label, props.description, props.detail].filter(Boolean).join(", ")}
21 accessibilityState={{
22 disabled: Boolean(props.disabled),
23 ...(props.selected === undefined ? {} : { checked: props.selected }),
24 }}
25 disabled={props.disabled}
26 onPress={props.onPress}
27 android_ripple={{ color: rippleStyle.backgroundColor }}
28 unstable_pressDelay={Platform.OS === "android" ? 50 : undefined}
29 className="bg-grouped-card"
30 >
31 <ListRowLayout
32 {...props}
33 accessory={
34 <View className="flex-row items-center gap-3">
35 {props.selected === undefined ? null : (
36 <View
37 accessibilityElementsHidden
38 importantForAccessibility="no-hide-descendants"
39 className="size-6 items-center justify-center"
40 >
41 {Platform.OS === "android" ? (
42 <RadioIndicator selected={props.selected} />
43 ) : props.selected ? (
44 <SymbolView
45 name="checkmark"
46 size={18}
47 tintColorClassName="accent-primary-text"
48 type="monochrome"
49 weight="semibold"
50 />
51 ) : null}
52 </View>
53 )}
54 <SymbolView
55 name="chevron.right"
56 size={16}
57 tintColorClassName="accent-chevron"
58 type="monochrome"
59 weight="semibold"
60 />
61 </View>
62 }
63 />
64 </RowPressable>
65 );