Skip to content

Commit 9fe1298

Browse files
katsuhira02DanilgHashTag
authored
CheckBox component add (#77)
Co-authored-by: Danil <[email protected]> Co-authored-by: Server Serverlesskiy <[email protected]>
1 parent 69cb7af commit 9fe1298

4 files changed

Lines changed: 110 additions & 2 deletions

File tree

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import * as React from 'react'
2+
import Svg, { SvgProps, Path } from 'react-native-svg'
3+
import { DARK } from '../../../constants'
4+
5+
interface Props extends SvgProps {
6+
color?: string
7+
}
8+
9+
export const Check = (props: Props) => {
10+
const { color, ...rest } = props
11+
const colorValue = color ?? DARK
12+
13+
return (
14+
<Svg width={15} height={12} fill="none" {...rest}>
15+
<Path d="M4.767 9.468 1.21 5.736 0 6.998 4.767 12 15 1.262 13.798 0 4.767 9.468Z" fill={colorValue} />
16+
</Svg>
17+
)
18+
}

src/components/CheckBox/index.tsx

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
import React, { FC, useEffect, useMemo, useState } from 'react'
2+
import { StyleSheet, Animated, Easing, Pressable } from 'react-native'
3+
import { Check } from './icons/Check'
4+
import { GRAY, PRIMARY, WHITE, DARK } from '../../constants'
5+
6+
export interface CheckBoxProps {
7+
value: boolean
8+
isPrimary: boolean
9+
onToggle: (value: boolean) => void
10+
}
11+
12+
const animationToggle = (value: boolean) => new Animated.Value(value ? 1 : 0)
13+
14+
export const CheckBox: FC<CheckBoxProps> = (props: CheckBoxProps) => {
15+
const { value, onToggle, isPrimary } = props
16+
const [timer] = useState<Animated.Value>(animationToggle(value))
17+
const [previousValue, setPreviousValue] = useState<boolean>(value)
18+
const onToggleHandler = React.useMemo(() => () => onToggle && onToggle(!value), [onToggle, value])
19+
const activeColor = isPrimary ? PRIMARY : WHITE
20+
21+
const startAnimation = useMemo(
22+
() => (value: boolean) => {
23+
Animated.timing(timer, {
24+
toValue: value ? 1 : 0,
25+
duration: 250,
26+
easing: Easing.out(Easing.circle),
27+
useNativeDriver: false
28+
}).start()
29+
},
30+
[timer]
31+
)
32+
33+
useEffect(() => {
34+
if (value !== previousValue) {
35+
startAnimation(value)
36+
setPreviousValue(value)
37+
}
38+
}, [value, previousValue, startAnimation, setPreviousValue])
39+
40+
const animatedBgStyle = timer.interpolate({
41+
inputRange: [0, 1],
42+
outputRange: ['transparent', activeColor]
43+
})
44+
const animatedBorderColorStyle = timer.interpolate({
45+
inputRange: [0, 1],
46+
outputRange: [GRAY, 'transparent']
47+
})
48+
const borderWidth = value ? 0 : 1
49+
const iconColor = !value ? 'transparent' : activeColor === PRIMARY ? WHITE : DARK
50+
51+
return (
52+
<Pressable onPress={onToggleHandler}>
53+
<Animated.View
54+
style={[
55+
styles.container,
56+
{
57+
backgroundColor: animatedBgStyle,
58+
borderColor: animatedBorderColorStyle,
59+
borderWidth
60+
}
61+
]}
62+
>
63+
<Check color={iconColor} />
64+
</Animated.View>
65+
</Pressable>
66+
)
67+
}
68+
69+
const styles = StyleSheet.create({
70+
container: {
71+
width: 20,
72+
height: 20,
73+
borderRadius: 4,
74+
alignItems: 'center',
75+
justifyContent: 'center'
76+
}
77+
})

src/components/index.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,7 @@ export * from './Text'
44
export * from './Switch'
55
export * from './Labels'
66
export * from './ButtonPhoto'
7+
export * from './CheckBox'
8+
export * from './ButtonIcon'
79
export * from './ButtonReview'
8-
export * from './ButtonIcon'
10+

src/index.tsx

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import React, { useState } from 'react'
22
import { StyleSheet, View } from 'react-native'
33
import { BLACK, WHITE } from './constants'
4-
import { Space, Text, ButtonReview } from './components'
4+
import { Space, Text, CheckBox, ButtonReview } from './components'
55

66
const styles = StyleSheet.create({
77
container: {
@@ -20,10 +20,21 @@ const styles = StyleSheet.create({
2020
export default function App({}) {
2121
const { container, textStyle } = styles
2222
const [isEnabled, setIsEnabled] = useState(false)
23+
const [redCheckBoxValue, setRedCheckBoxValue] = useState(false)
24+
const [whiteCheckBoxValue, setWhiteCheckBoxValue] = useState(false)
25+
2326
const toggleSwitch = () => setIsEnabled(previousState => !previousState)
27+
const toggleRedCheckBox = () => setRedCheckBoxValue(redCheckBoxValue => !redCheckBoxValue)
28+
const toggleWhiteCheckBox = () => setWhiteCheckBoxValue(whiteCheckBoxValue => !whiteCheckBoxValue)
2429

2530
return (
2631
<View style={container}>
32+
<Text h0 title="CheckBox" />
33+
<Space height={30} />
34+
<CheckBox isPrimary={false} value={redCheckBoxValue} onToggle={toggleRedCheckBox} />
35+
<Space height={30} />
36+
<CheckBox isPrimary={true} value={whiteCheckBoxValue} onToggle={toggleWhiteCheckBox} />
37+
<Space height={30} />
2738
<Text title="ButtonReview" h0 />
2839
<Space height={15} />
2940
<ButtonReview />

0 commit comments

Comments
 (0)