forked from mrzachnugent/react-native-reusables
-
Notifications
You must be signed in to change notification settings - Fork 0
/
toggle.tsx
98 lines (94 loc) · 2.22 KB
/
toggle.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
import { useColorScheme } from 'nativewind';
import React from 'react';
import { Pressable, StyleSheet, View } from 'react-native';
import { Button, buttonVariants } from '~/components/ui/button';
import { cn } from '~/lib/utils';
interface ToggleProps {
defaultValue?: boolean;
value?: boolean;
onChange?: React.Dispatch<React.SetStateAction<boolean>>;
variant?: 'default' | 'outline';
}
const Toggle = React.forwardRef<
React.ElementRef<typeof Button>,
Omit<
React.ComponentPropsWithoutRef<typeof Button>,
'variant' | 'onPress' | 'children'
> &
ToggleProps & {
children?: React.ReactNode;
}
>(
(
{
defaultValue,
value,
onChange,
className,
size,
textClass,
children,
variant = 'default',
...props
},
ref
) => {
const { colorScheme } = useColorScheme();
const [isChecked, setChecked] = React.useState(false);
return (
<Pressable
ref={ref}
onPress={() => {
if (onChange) {
onChange((prev) => !prev);
return;
}
setChecked((prev) => !prev);
}}
role='switch'
accessibilityState={{ selected: value || isChecked }}
{...props}
>
{({ pressed }) => (
<View
className={cn(
'border bg-background',
pressed ? 'opacity-70' : '',
value || isChecked ? 'border-border' : 'border-transparent',
buttonVariants({
variant:
value || isChecked
? 'secondary'
: variant === 'default'
? 'ghost'
: 'outline',
size,
className,
})
)}
style={
(value || isChecked) &&
colorScheme === 'dark' &&
styles.shadowDark
}
>
{children}
</View>
)}
</Pressable>
);
}
);
export { Toggle };
const styles = StyleSheet.create({
shadowDark: {
shadowColor: '#FFFFFF',
shadowOffset: {
width: 0,
height: 2,
},
shadowOpacity: 0.05,
shadowRadius: 8,
elevation: 2,
},
});