1 | import * as React from 'react';
|
2 | import {
|
3 | StyleSheet,
|
4 | StyleProp,
|
5 | ViewStyle,
|
6 | GestureResponderEvent,
|
7 | } from 'react-native';
|
8 | import { withTheme } from '../../core/theming';
|
9 | import color from 'color';
|
10 | import IconButton from '../IconButton';
|
11 | import { ToggleButtonGroupContext } from './ToggleButtonGroup';
|
12 | import { black, white } from '../../styles/colors';
|
13 | import type { IconSource } from '../Icon';
|
14 |
|
15 | type Props = {
|
16 | |
17 |
|
18 |
|
19 | icon: IconSource;
|
20 | |
21 |
|
22 |
|
23 | size?: number;
|
24 | |
25 |
|
26 |
|
27 | color?: string;
|
28 | |
29 |
|
30 |
|
31 | disabled?: boolean;
|
32 | |
33 |
|
34 |
|
35 | accessibilityLabel?: string;
|
36 | |
37 |
|
38 |
|
39 | onPress?: (value?: GestureResponderEvent | string) => void;
|
40 | |
41 |
|
42 |
|
43 | value?: string;
|
44 | |
45 |
|
46 |
|
47 | status?: 'checked' | 'unchecked';
|
48 | style?: StyleProp<ViewStyle>;
|
49 | |
50 |
|
51 |
|
52 | theme: ReactNativePaper.Theme;
|
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 | const ToggleButton = ({
|
90 | icon,
|
91 | size,
|
92 | theme,
|
93 | accessibilityLabel,
|
94 | disabled,
|
95 | style,
|
96 | value,
|
97 | status,
|
98 | onPress,
|
99 | ...rest
|
100 | }: Props) => {
|
101 | const borderRadius = theme.roundness;
|
102 |
|
103 | return (
|
104 | <ToggleButtonGroupContext.Consumer>
|
105 | {(context: { value: string | null; onValueChange: Function } | null) => {
|
106 | let backgroundColor;
|
107 |
|
108 | const checked: boolean | null =
|
109 | (context && context.value === value) || status === 'checked';
|
110 |
|
111 | if (checked) {
|
112 | backgroundColor = theme.dark
|
113 | ? 'rgba(255, 255, 255, .12)'
|
114 | : 'rgba(0, 0, 0, .08)';
|
115 | } else {
|
116 | backgroundColor = 'transparent';
|
117 | }
|
118 |
|
119 | return (
|
120 | <IconButton
|
121 | borderless={false}
|
122 | icon={icon}
|
123 | onPress={(e?: GestureResponderEvent | string) => {
|
124 | if (onPress) {
|
125 | onPress(e);
|
126 | }
|
127 |
|
128 | if (context) {
|
129 | context.onValueChange(!checked ? value : null);
|
130 | }
|
131 | }}
|
132 | size={size}
|
133 | accessibilityLabel={accessibilityLabel}
|
134 | accessibilityState={{ disabled, selected: checked }}
|
135 | disabled={disabled}
|
136 | style={[
|
137 | styles.content,
|
138 | {
|
139 | backgroundColor,
|
140 | borderRadius,
|
141 | borderColor: color(theme.dark ? white : black)
|
142 | .alpha(0.29)
|
143 | .rgb()
|
144 | .string(),
|
145 | },
|
146 | style,
|
147 | ]}
|
148 | {...rest}
|
149 | />
|
150 | );
|
151 | }}
|
152 | </ToggleButtonGroupContext.Consumer>
|
153 | );
|
154 | };
|
155 |
|
156 | const styles = StyleSheet.create({
|
157 | content: {
|
158 | width: 42,
|
159 | height: 42,
|
160 | margin: 0,
|
161 | },
|
162 | });
|
163 |
|
164 | export default withTheme(ToggleButton);
|
165 |
|
166 |
|
167 | const ToggleButtonWithTheme = withTheme(ToggleButton);
|
168 |
|
169 | export { ToggleButtonWithTheme as ToggleButton };
|