react-native-molecules 0.5.0-beta.27 → 0.5.0-beta.29
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/components/ActivityIndicator/ActivityIndicator.tsx +1 -1
- package/components/Button/utils.ts +1 -1
- package/components/Checkbox/Checkbox.tsx +124 -88
- package/components/Checkbox/CheckboxBase.ios.tsx +2 -4
- package/components/Checkbox/CheckboxBase.tsx +3 -10
- package/components/Checkbox/context.tsx +14 -0
- package/components/Checkbox/index.tsx +11 -4
- package/components/Checkbox/types.ts +63 -29
- package/components/Checkbox/utils.ts +25 -83
- package/components/IconButton/IconButton.tsx +16 -17
- package/components/IconButton/types.ts +8 -0
- package/components/IconButton/utils.ts +25 -0
- package/components/Menu/Menu.tsx +31 -20
- package/components/Menu/index.tsx +2 -1
- package/components/Radio/Radio.tsx +188 -0
- package/components/Radio/RadioBase.ios.tsx +69 -0
- package/components/{RadioButton/RadioButtonAndroid.tsx → Radio/RadioBase.tsx} +27 -63
- package/components/Radio/context.tsx +23 -0
- package/components/Radio/index.tsx +20 -0
- package/components/Radio/types.ts +101 -0
- package/components/Radio/utils.ts +115 -0
- package/package.json +1 -1
- package/components/RadioButton/RadioButton.tsx +0 -138
- package/components/RadioButton/RadioButtonGroup.tsx +0 -97
- package/components/RadioButton/RadioButtonIOS.tsx +0 -92
- package/components/RadioButton/RadioButtonItem.tsx +0 -232
- package/components/RadioButton/index.ts +0 -22
- package/components/RadioButton/utils.ts +0 -165
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { getRegisteredComponentWithFallback } from '../../core';
|
|
2
|
+
// @component ./Radio.tsx
|
|
3
|
+
import RadioControl, {
|
|
4
|
+
RadioGroup as RadioGroupComponent,
|
|
5
|
+
RadioLabel,
|
|
6
|
+
RadioRow as RadioRowComponent,
|
|
7
|
+
} from './Radio';
|
|
8
|
+
|
|
9
|
+
const RadioDefault = Object.assign(RadioControl, {
|
|
10
|
+
Label: RadioLabel,
|
|
11
|
+
Group: RadioGroupComponent,
|
|
12
|
+
Row: RadioRowComponent,
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
export const Radio = getRegisteredComponentWithFallback('Radio', RadioDefault);
|
|
16
|
+
export const RadioGroup = RadioGroupComponent;
|
|
17
|
+
export const RadioRow = RadioRowComponent;
|
|
18
|
+
|
|
19
|
+
export type { RadioGroupProps, RadioLabelProps, RadioProps, RadioRowProps } from './types';
|
|
20
|
+
export { radioRowStyles, radioStyles } from './utils';
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import type { PropsWithoutRef, ReactNode } from 'react';
|
|
2
|
+
import type { TextProps, ViewProps } from 'react-native';
|
|
3
|
+
|
|
4
|
+
import type { TouchableRippleProps } from '../TouchableRipple';
|
|
5
|
+
|
|
6
|
+
export type Size = 'sm' | 'md' | 'lg';
|
|
7
|
+
export type States = 'disabled' | 'checked' | 'hovered' | 'checkedAndHovered';
|
|
8
|
+
|
|
9
|
+
export type RadioGroupProps = ViewProps & {
|
|
10
|
+
/**
|
|
11
|
+
* Value of the currently selected radio.
|
|
12
|
+
*/
|
|
13
|
+
value?: string;
|
|
14
|
+
/**
|
|
15
|
+
* Default selected value (uncontrolled).
|
|
16
|
+
*/
|
|
17
|
+
defaultValue?: string;
|
|
18
|
+
/**
|
|
19
|
+
* Called when the selected value changes.
|
|
20
|
+
*/
|
|
21
|
+
onValueChange?: (value: string) => void;
|
|
22
|
+
/**
|
|
23
|
+
* Disables every radio in the group.
|
|
24
|
+
*/
|
|
25
|
+
disabled?: boolean;
|
|
26
|
+
/**
|
|
27
|
+
* Size applied to every radio in the group.
|
|
28
|
+
*/
|
|
29
|
+
size?: Size;
|
|
30
|
+
/**
|
|
31
|
+
* Radio rows / radios.
|
|
32
|
+
*/
|
|
33
|
+
children: ReactNode;
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
export type RadioRowProps = ViewProps & {
|
|
37
|
+
/**
|
|
38
|
+
* Value this row represents within the enclosing RadioGroup.
|
|
39
|
+
*/
|
|
40
|
+
value: string;
|
|
41
|
+
/**
|
|
42
|
+
* Disables this row (control + label).
|
|
43
|
+
*/
|
|
44
|
+
disabled?: boolean;
|
|
45
|
+
/**
|
|
46
|
+
* Radio control and Radio.Label, in any order.
|
|
47
|
+
*/
|
|
48
|
+
children: ReactNode;
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* The radio control (the circle). Use inside a RadioRow, or standalone under a RadioGroup with `value`.
|
|
53
|
+
*/
|
|
54
|
+
export type RadioProps = Omit<TouchableRippleProps, 'children'> & {
|
|
55
|
+
/**
|
|
56
|
+
* Required only when used standalone under a RadioGroup (not inside a RadioRow).
|
|
57
|
+
*/
|
|
58
|
+
value?: string;
|
|
59
|
+
/**
|
|
60
|
+
* Whether the radio is disabled.
|
|
61
|
+
*/
|
|
62
|
+
disabled?: boolean;
|
|
63
|
+
/**
|
|
64
|
+
* Size of the radio. Falls back to the row/group size.
|
|
65
|
+
*/
|
|
66
|
+
size?: Size;
|
|
67
|
+
/**
|
|
68
|
+
* Custom color for the checked radio.
|
|
69
|
+
*/
|
|
70
|
+
color?: string;
|
|
71
|
+
/**
|
|
72
|
+
* Custom color for the unchecked radio.
|
|
73
|
+
*/
|
|
74
|
+
uncheckedColor?: string;
|
|
75
|
+
/**
|
|
76
|
+
* Props for the state layer.
|
|
77
|
+
*/
|
|
78
|
+
stateLayerProps?: PropsWithoutRef<ViewProps>;
|
|
79
|
+
/**
|
|
80
|
+
* testID to be used on tests.
|
|
81
|
+
*/
|
|
82
|
+
testID?: string;
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
export type RadioLabelProps = TextProps & {
|
|
86
|
+
children: ReactNode;
|
|
87
|
+
};
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* Internal props for the platform control (RadioBase).
|
|
91
|
+
*/
|
|
92
|
+
export type RadioBaseProps = Omit<TouchableRippleProps, 'children'> & {
|
|
93
|
+
checked: boolean;
|
|
94
|
+
disabled?: boolean;
|
|
95
|
+
size?: Size;
|
|
96
|
+
color?: string;
|
|
97
|
+
uncheckedColor?: string;
|
|
98
|
+
onPress?: () => void;
|
|
99
|
+
stateLayerProps?: PropsWithoutRef<ViewProps>;
|
|
100
|
+
testID?: string;
|
|
101
|
+
};
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
import { StyleSheet } from 'react-native-unistyles';
|
|
2
|
+
|
|
3
|
+
import { getRegisteredComponentStylesWithFallback } from '../../core';
|
|
4
|
+
|
|
5
|
+
export const ANIMATION_DURATION = 100;
|
|
6
|
+
|
|
7
|
+
export const iconSizeMap = {
|
|
8
|
+
sm: 20,
|
|
9
|
+
md: 24,
|
|
10
|
+
lg: 28,
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
const radioStylesDefault = StyleSheet.create(theme => ({
|
|
14
|
+
root: {},
|
|
15
|
+
|
|
16
|
+
container: {
|
|
17
|
+
borderRadius: theme.shapes.corner.full as unknown as number,
|
|
18
|
+
alignItems: 'center',
|
|
19
|
+
justifyContent: 'center',
|
|
20
|
+
|
|
21
|
+
variants: {
|
|
22
|
+
size: {
|
|
23
|
+
sm: { padding: 4 },
|
|
24
|
+
md: { padding: 6 },
|
|
25
|
+
lg: { padding: 8 },
|
|
26
|
+
},
|
|
27
|
+
},
|
|
28
|
+
},
|
|
29
|
+
radioContainer: {
|
|
30
|
+
alignItems: 'center',
|
|
31
|
+
justifyContent: 'center',
|
|
32
|
+
},
|
|
33
|
+
radio: {
|
|
34
|
+
borderColor: theme.colors.onSurfaceVariant,
|
|
35
|
+
|
|
36
|
+
variants: {
|
|
37
|
+
state: {
|
|
38
|
+
checked: { borderColor: theme.colors.primary },
|
|
39
|
+
checkedAndHovered: { borderColor: theme.colors.primary },
|
|
40
|
+
hovered: {},
|
|
41
|
+
disabled: { borderColor: theme.colors.onSurfaceDisabled },
|
|
42
|
+
},
|
|
43
|
+
size: {
|
|
44
|
+
sm: { height: 16, width: 16, borderRadius: 8 },
|
|
45
|
+
md: { height: 20, width: 20, borderRadius: 10 },
|
|
46
|
+
lg: { height: 24, width: 24, borderRadius: 12 },
|
|
47
|
+
},
|
|
48
|
+
},
|
|
49
|
+
},
|
|
50
|
+
dot: {
|
|
51
|
+
backgroundColor: theme.colors.onSurfaceVariant,
|
|
52
|
+
|
|
53
|
+
variants: {
|
|
54
|
+
state: {
|
|
55
|
+
checked: { backgroundColor: theme.colors.primary },
|
|
56
|
+
checkedAndHovered: { backgroundColor: theme.colors.primary },
|
|
57
|
+
hovered: {},
|
|
58
|
+
disabled: { backgroundColor: theme.colors.onSurfaceDisabled },
|
|
59
|
+
},
|
|
60
|
+
size: {
|
|
61
|
+
sm: { height: 8, width: 8, borderRadius: 4 },
|
|
62
|
+
md: { height: 10, width: 10, borderRadius: 5 },
|
|
63
|
+
lg: { height: 12, width: 12, borderRadius: 6 },
|
|
64
|
+
},
|
|
65
|
+
},
|
|
66
|
+
},
|
|
67
|
+
icon: {
|
|
68
|
+
backgroundColor: theme.colors.onSurfaceVariant,
|
|
69
|
+
|
|
70
|
+
variants: {
|
|
71
|
+
state: {
|
|
72
|
+
checked: { backgroundColor: theme.colors.primary },
|
|
73
|
+
checkedAndHovered: { backgroundColor: theme.colors.primary },
|
|
74
|
+
hovered: {},
|
|
75
|
+
disabled: { backgroundColor: theme.colors.onSurfaceDisabled },
|
|
76
|
+
},
|
|
77
|
+
},
|
|
78
|
+
},
|
|
79
|
+
stateLayer: {
|
|
80
|
+
variants: {
|
|
81
|
+
state: {
|
|
82
|
+
hovered: { backgroundColor: theme.colors.stateLayer.hover.onSurface },
|
|
83
|
+
checkedAndHovered: { backgroundColor: theme.colors.stateLayer.hover.primary },
|
|
84
|
+
},
|
|
85
|
+
},
|
|
86
|
+
},
|
|
87
|
+
}));
|
|
88
|
+
|
|
89
|
+
const radioRowStylesDefault = StyleSheet.create(theme => ({
|
|
90
|
+
row: {
|
|
91
|
+
flexDirection: 'row',
|
|
92
|
+
alignItems: 'center',
|
|
93
|
+
},
|
|
94
|
+
label: {
|
|
95
|
+
flexShrink: 1,
|
|
96
|
+
flexGrow: 1,
|
|
97
|
+
color: theme.colors.onSurface,
|
|
98
|
+
...theme.typescale.bodyLarge,
|
|
99
|
+
|
|
100
|
+
variants: {
|
|
101
|
+
state: {
|
|
102
|
+
checked: {},
|
|
103
|
+
checkedAndHovered: {},
|
|
104
|
+
hovered: {},
|
|
105
|
+
disabled: { color: theme.colors.onSurfaceDisabled },
|
|
106
|
+
},
|
|
107
|
+
},
|
|
108
|
+
},
|
|
109
|
+
}));
|
|
110
|
+
|
|
111
|
+
export const radioStyles = getRegisteredComponentStylesWithFallback('Radio', radioStylesDefault);
|
|
112
|
+
export const radioRowStyles = getRegisteredComponentStylesWithFallback(
|
|
113
|
+
'Radio_Row',
|
|
114
|
+
radioRowStylesDefault,
|
|
115
|
+
);
|
package/package.json
CHANGED
|
@@ -1,138 +0,0 @@
|
|
|
1
|
-
import { forwardRef, memo, useContext, useMemo } from 'react';
|
|
2
|
-
import { Platform } from 'react-native';
|
|
3
|
-
|
|
4
|
-
import RadioButtonAndroid from './RadioButtonAndroid';
|
|
5
|
-
import { RadioButtonContext } from './RadioButtonGroup';
|
|
6
|
-
import RadioButtonIOS from './RadioButtonIOS';
|
|
7
|
-
import { handlePress, isChecked } from './utils';
|
|
8
|
-
|
|
9
|
-
export type Props = {
|
|
10
|
-
/**
|
|
11
|
-
* Value of the radio button
|
|
12
|
-
*/
|
|
13
|
-
value: string;
|
|
14
|
-
/**
|
|
15
|
-
* Status of radio button.
|
|
16
|
-
*/
|
|
17
|
-
status?: 'checked' | 'unchecked';
|
|
18
|
-
/**
|
|
19
|
-
* Whether radio is disabled.
|
|
20
|
-
*/
|
|
21
|
-
disabled?: boolean;
|
|
22
|
-
/**
|
|
23
|
-
* Function to execute on press.
|
|
24
|
-
*/
|
|
25
|
-
onPress?: () => void;
|
|
26
|
-
/**
|
|
27
|
-
* Custom color for unchecked radio.
|
|
28
|
-
*/
|
|
29
|
-
uncheckedColor?: string;
|
|
30
|
-
/**
|
|
31
|
-
* Custom color for radio.
|
|
32
|
-
*/
|
|
33
|
-
color?: string;
|
|
34
|
-
/**
|
|
35
|
-
* testID to be used on tests.
|
|
36
|
-
*/
|
|
37
|
-
testID?: string;
|
|
38
|
-
};
|
|
39
|
-
|
|
40
|
-
/**
|
|
41
|
-
* Radio buttons allow the selection a single option from a set.
|
|
42
|
-
*
|
|
43
|
-
* <div class="screenshots">
|
|
44
|
-
* <figure>
|
|
45
|
-
* <img src="screenshots/radio-enabled.android.png" />
|
|
46
|
-
* <figcaption>Android (enabled)</figcaption>
|
|
47
|
-
* </figure>
|
|
48
|
-
* <figure>
|
|
49
|
-
* <img src="screenshots/radio-disabled.android.png" />
|
|
50
|
-
* <figcaption>Android (disabled)</figcaption>
|
|
51
|
-
* </figure>
|
|
52
|
-
* <figure>
|
|
53
|
-
* <img src="screenshots/radio-enabled.ios.png" />
|
|
54
|
-
* <figcaption>iOS (enabled)</figcaption>
|
|
55
|
-
* </figure>
|
|
56
|
-
* <figure>
|
|
57
|
-
* <img src="screenshots/radio-disabled.ios.png" />
|
|
58
|
-
* <figcaption>iOS (disabled)</figcaption>
|
|
59
|
-
* </figure>
|
|
60
|
-
* </div>
|
|
61
|
-
*
|
|
62
|
-
* ## Usage
|
|
63
|
-
* ```js
|
|
64
|
-
* import * as React from 'react';
|
|
65
|
-
* import { View } from 'react-native';
|
|
66
|
-
* import { RadioButton } from 'react-native-paper';
|
|
67
|
-
*
|
|
68
|
-
* const MyComponent = () => {
|
|
69
|
-
* const [checked, setChecked] = React.useState('first');
|
|
70
|
-
*
|
|
71
|
-
* return (
|
|
72
|
-
* <View>
|
|
73
|
-
* <RadioButton
|
|
74
|
-
* value="first"
|
|
75
|
-
* status={ checked === 'first' ? 'checked' : 'unchecked' }
|
|
76
|
-
* onPress={() => setChecked('first')}
|
|
77
|
-
* />
|
|
78
|
-
* <RadioButton
|
|
79
|
-
* value="second"
|
|
80
|
-
* status={ checked === 'second' ? 'checked' : 'unchecked' }
|
|
81
|
-
* onPress={() => setChecked('second')}
|
|
82
|
-
* />
|
|
83
|
-
* </View>
|
|
84
|
-
* );
|
|
85
|
-
* };
|
|
86
|
-
*
|
|
87
|
-
* export default MyComponent;
|
|
88
|
-
* ```
|
|
89
|
-
*/
|
|
90
|
-
|
|
91
|
-
const Button = Platform.OS === 'ios' ? RadioButtonIOS : RadioButtonAndroid;
|
|
92
|
-
|
|
93
|
-
const RadioButton = ({ value, status, disabled, onPress, testID, ...rest }: Props, ref: any) => {
|
|
94
|
-
const context = useContext(RadioButtonContext);
|
|
95
|
-
|
|
96
|
-
const checked = useMemo(
|
|
97
|
-
() =>
|
|
98
|
-
isChecked({
|
|
99
|
-
contextValue: context?.value,
|
|
100
|
-
status,
|
|
101
|
-
value,
|
|
102
|
-
}) === 'checked',
|
|
103
|
-
[context?.value, status, value],
|
|
104
|
-
);
|
|
105
|
-
const onRadioPress = useMemo(
|
|
106
|
-
() =>
|
|
107
|
-
disabled
|
|
108
|
-
? undefined
|
|
109
|
-
: () => {
|
|
110
|
-
handlePress({
|
|
111
|
-
onPress,
|
|
112
|
-
onValueChange: context?.onValueChange,
|
|
113
|
-
value,
|
|
114
|
-
});
|
|
115
|
-
},
|
|
116
|
-
[disabled, onPress, context?.onValueChange, value],
|
|
117
|
-
);
|
|
118
|
-
|
|
119
|
-
const accessibilityState = useMemo(() => ({ disabled, checked }), [checked, disabled]);
|
|
120
|
-
|
|
121
|
-
return (
|
|
122
|
-
<Button
|
|
123
|
-
{...rest}
|
|
124
|
-
checked={checked}
|
|
125
|
-
onPress={onRadioPress}
|
|
126
|
-
status={status}
|
|
127
|
-
disabled={disabled}
|
|
128
|
-
borderless
|
|
129
|
-
accessibilityRole="radio"
|
|
130
|
-
accessibilityState={accessibilityState}
|
|
131
|
-
accessibilityLiveRegion="polite"
|
|
132
|
-
testID={testID}
|
|
133
|
-
ref={ref}
|
|
134
|
-
/>
|
|
135
|
-
);
|
|
136
|
-
};
|
|
137
|
-
|
|
138
|
-
export default memo(forwardRef(RadioButton));
|
|
@@ -1,97 +0,0 @@
|
|
|
1
|
-
import { useControlledValue } from '@react-native-molecules/utils/hooks';
|
|
2
|
-
import { createContext, memo, type ReactNode, useMemo } from 'react';
|
|
3
|
-
import { View, type ViewProps } from 'react-native';
|
|
4
|
-
|
|
5
|
-
export type Props = ViewProps & {
|
|
6
|
-
/**
|
|
7
|
-
* Function to execute on selection change.
|
|
8
|
-
*/
|
|
9
|
-
onValueChange?: (value: string) => void;
|
|
10
|
-
/**
|
|
11
|
-
* Value of the currently selected radio button.
|
|
12
|
-
*/
|
|
13
|
-
value?: string;
|
|
14
|
-
/**
|
|
15
|
-
* Default selected radio button
|
|
16
|
-
*/
|
|
17
|
-
defaultValue?: string;
|
|
18
|
-
/**
|
|
19
|
-
* React elements containing radio buttons.
|
|
20
|
-
*/
|
|
21
|
-
children: ReactNode;
|
|
22
|
-
};
|
|
23
|
-
|
|
24
|
-
export type RadioButtonContextType = {
|
|
25
|
-
value: string;
|
|
26
|
-
onValueChange: (item: string) => void;
|
|
27
|
-
};
|
|
28
|
-
|
|
29
|
-
export const RadioButtonContext = createContext<RadioButtonContextType>(null as any);
|
|
30
|
-
|
|
31
|
-
/**
|
|
32
|
-
* Radio button group allows to control a group of radio buttons.
|
|
33
|
-
*
|
|
34
|
-
* <div class="screenshots">
|
|
35
|
-
* <figure>
|
|
36
|
-
* <img class="medium" src="screenshots/radio-button-group-android.gif" />
|
|
37
|
-
* <figcaption>Android</figcaption>
|
|
38
|
-
* </figure>
|
|
39
|
-
* <figure>
|
|
40
|
-
* <img class="medium" src="screenshots/radio-button-group-ios.gif" />
|
|
41
|
-
* <figcaption>iOS</figcaption>
|
|
42
|
-
* </figure>
|
|
43
|
-
* </div>
|
|
44
|
-
*
|
|
45
|
-
* ## Usage
|
|
46
|
-
* ```js
|
|
47
|
-
* import * as React from 'react';
|
|
48
|
-
* import { View } from 'react-native';
|
|
49
|
-
* import { RadioButton, Text } from 'react-native-paper';
|
|
50
|
-
*
|
|
51
|
-
* const MyComponent = () => {
|
|
52
|
-
* const [value, setValue] = React.useState('first');
|
|
53
|
-
*
|
|
54
|
-
* return (
|
|
55
|
-
* <RadioButton.Group onValueChange={newValue => setValue(newValue)} value={value}>
|
|
56
|
-
* <View>
|
|
57
|
-
* <Text>First</Text>
|
|
58
|
-
* <RadioButton value="first" />
|
|
59
|
-
* </View>
|
|
60
|
-
* <View>
|
|
61
|
-
* <Text>Second</Text>
|
|
62
|
-
* <RadioButton value="second" />
|
|
63
|
-
* </View>
|
|
64
|
-
* </RadioButton.Group>
|
|
65
|
-
* );
|
|
66
|
-
* };
|
|
67
|
-
*
|
|
68
|
-
* export default MyComponent;
|
|
69
|
-
*```
|
|
70
|
-
*/
|
|
71
|
-
const RadioButtonGroup = ({
|
|
72
|
-
value: valueProp,
|
|
73
|
-
defaultValue,
|
|
74
|
-
onValueChange: onValueChangeProp,
|
|
75
|
-
children,
|
|
76
|
-
...rest
|
|
77
|
-
}: Props) => {
|
|
78
|
-
const [value, onValueChange] = useControlledValue({
|
|
79
|
-
value: valueProp,
|
|
80
|
-
defaultValue,
|
|
81
|
-
onChange: onValueChangeProp,
|
|
82
|
-
});
|
|
83
|
-
|
|
84
|
-
const contextValue = useMemo(() => ({ value, onValueChange }), [onValueChange, value]);
|
|
85
|
-
|
|
86
|
-
return (
|
|
87
|
-
<RadioButtonContext.Provider value={contextValue}>
|
|
88
|
-
<View accessibilityRole="radiogroup" {...rest}>
|
|
89
|
-
{children}
|
|
90
|
-
</View>
|
|
91
|
-
</RadioButtonContext.Provider>
|
|
92
|
-
);
|
|
93
|
-
};
|
|
94
|
-
|
|
95
|
-
RadioButtonGroup.displayName = 'RadioButton_Group';
|
|
96
|
-
|
|
97
|
-
export default memo(RadioButtonGroup);
|
|
@@ -1,92 +0,0 @@
|
|
|
1
|
-
import { forwardRef, memo, useMemo } from 'react';
|
|
2
|
-
import { StyleSheet, View } from 'react-native';
|
|
3
|
-
|
|
4
|
-
import { resolveStateVariant } from '../../utils';
|
|
5
|
-
import { tokenStylesParser } from '../../utils/tokenStylesParser';
|
|
6
|
-
import { Icon } from '../Icon';
|
|
7
|
-
import { TouchableRipple, type TouchableRippleProps } from '../TouchableRipple';
|
|
8
|
-
import { DEFAULT_ICON_SIZE, radioButtonStyles } from './utils';
|
|
9
|
-
|
|
10
|
-
export type Props = Omit<TouchableRippleProps, 'children'> & {
|
|
11
|
-
/**
|
|
12
|
-
* Status of radio button.
|
|
13
|
-
*/
|
|
14
|
-
status?: 'checked' | 'unchecked';
|
|
15
|
-
/**
|
|
16
|
-
* Whether radio is disabled.
|
|
17
|
-
*/
|
|
18
|
-
disabled?: boolean;
|
|
19
|
-
/**
|
|
20
|
-
* Custom color for unchecked radio.
|
|
21
|
-
*/
|
|
22
|
-
uncheckedColor?: string;
|
|
23
|
-
/**
|
|
24
|
-
* Custom color for radio.
|
|
25
|
-
*/
|
|
26
|
-
color?: string;
|
|
27
|
-
/**
|
|
28
|
-
* testID to be used on tests.
|
|
29
|
-
*/
|
|
30
|
-
testID?: string;
|
|
31
|
-
/**
|
|
32
|
-
* passed from RadioButton component
|
|
33
|
-
*/
|
|
34
|
-
checked: boolean;
|
|
35
|
-
onPress: (() => void) | undefined;
|
|
36
|
-
};
|
|
37
|
-
|
|
38
|
-
const RadioButtonIOS = (
|
|
39
|
-
{
|
|
40
|
-
disabled,
|
|
41
|
-
style,
|
|
42
|
-
color: colorProp,
|
|
43
|
-
checked,
|
|
44
|
-
onPress,
|
|
45
|
-
uncheckedColor: uncheckedColorProp,
|
|
46
|
-
...rest
|
|
47
|
-
}: Props,
|
|
48
|
-
ref: any,
|
|
49
|
-
) => {
|
|
50
|
-
const state = resolveStateVariant({
|
|
51
|
-
disabled: !!disabled,
|
|
52
|
-
checked,
|
|
53
|
-
});
|
|
54
|
-
radioButtonStyles.useVariants({
|
|
55
|
-
state: state as any,
|
|
56
|
-
});
|
|
57
|
-
|
|
58
|
-
const { containerStyle, iconContainerStyle, iconStyle } = useMemo(() => {
|
|
59
|
-
const _color = tokenStylesParser.getColor(checked ? colorProp : uncheckedColorProp);
|
|
60
|
-
|
|
61
|
-
return {
|
|
62
|
-
containerStyle: [styles.container, radioButtonStyles.root, style],
|
|
63
|
-
iconContainerStyle: { opacity: checked ? 1 : 0 },
|
|
64
|
-
iconStyle: [radioButtonStyles.icon, _color],
|
|
65
|
-
};
|
|
66
|
-
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
67
|
-
}, [checked, colorProp, style, state, uncheckedColorProp]);
|
|
68
|
-
|
|
69
|
-
return (
|
|
70
|
-
<TouchableRipple {...rest} ref={ref} onPress={onPress} style={containerStyle}>
|
|
71
|
-
<View style={iconContainerStyle}>
|
|
72
|
-
<Icon
|
|
73
|
-
allowFontScaling={false}
|
|
74
|
-
name="check"
|
|
75
|
-
size={DEFAULT_ICON_SIZE}
|
|
76
|
-
style={iconStyle}
|
|
77
|
-
/>
|
|
78
|
-
</View>
|
|
79
|
-
</TouchableRipple>
|
|
80
|
-
);
|
|
81
|
-
};
|
|
82
|
-
|
|
83
|
-
RadioButtonIOS.displayName = 'RadioButton_IOS';
|
|
84
|
-
|
|
85
|
-
const styles = StyleSheet.create({
|
|
86
|
-
container: {
|
|
87
|
-
borderRadius: 18,
|
|
88
|
-
padding: 6,
|
|
89
|
-
},
|
|
90
|
-
});
|
|
91
|
-
|
|
92
|
-
export default memo(forwardRef(RadioButtonIOS));
|