-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathRadioGroup.tsx
104 lines (95 loc) · 2.95 KB
/
RadioGroup.tsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
import React, { ComponentProps } from "react";
import { Divider } from "../divider";
import { ListItemRadio, ListItemRadioWithAmount } from "../listitems";
export type RadioItem<T> = {
id: T;
value: string;
description?: string | React.ReactNode;
disabled?: boolean;
startImage?: ComponentProps<typeof ListItemRadio>["startImage"];
loadingProps?: ComponentProps<typeof ListItemRadio>["loadingProps"];
};
export type RadioItemWithAmount<T> = {
id: T;
label: string;
formattedAmountString: string;
} & (
| {
isSuggested?: false;
}
| {
isSuggested: true;
suggestReason: string;
}
);
type CommonProps<T> = {
selectedItem?: T;
onPress: (selected: T) => void;
};
type RadioListItemProps<T> = {
type: "radioListItem";
items: ReadonlyArray<RadioItem<T>>;
} & CommonProps<T>;
type RadioListItemWithAmountProps<T> = {
type: "radioListItemWithAmount";
items: ReadonlyArray<RadioItemWithAmount<T>>;
} & CommonProps<T>;
type Props<T> = RadioListItemProps<T> | RadioListItemWithAmountProps<T>;
/**
* A list of radio buttons.
* The management of the selection is demanded and derived by the `selectedItem` prop.
* The item with the `id` equal to the `selectedItem` is the active one.
*/
const RadioListItem = <T,>(props: RadioListItemProps<T>) => (
<>
{props.items.map((item, index) => (
<React.Fragment key={`radio_item_${item.id}`}>
<ListItemRadio
testID={`RadioItemTestID_${item.id}`}
value={item.value}
description={item.description}
startImage={item.startImage}
disabled={item.disabled}
loadingProps={item.loadingProps}
onValueChange={() => props.onPress(item.id)}
selected={props.selectedItem === item.id}
/>
{index < props.items.length - 1 && <Divider />}
</React.Fragment>
))}
</>
);
const RadioListItemWithAmount = <T,>(
props: RadioListItemWithAmountProps<T>
) => (
<>
{props.items.map((item, index) => (
<React.Fragment key={`radio_item_${item.id}`}>
{item.isSuggested ? (
<ListItemRadioWithAmount
label={item.label}
formattedAmountString={item.formattedAmountString}
suggestReason={item.suggestReason}
isSuggested={item.isSuggested}
onValueChange={() => props.onPress(item.id)}
selected={props.selectedItem === item.id}
/>
) : (
<ListItemRadioWithAmount
label={item.label}
formattedAmountString={item.formattedAmountString}
onValueChange={() => props.onPress(item.id)}
selected={props.selectedItem === item.id}
/>
)}
{index < props.items.length - 1 && <Divider />}
</React.Fragment>
))}
</>
);
export const RadioGroup = <T,>(props: Props<T>) => (
<>
{props.type === "radioListItem" && RadioListItem(props)}
{props.type === "radioListItemWithAmount" && RadioListItemWithAmount(props)}
</>
);