From 849d4906c1e32c0793736de1da001fb7cc702816 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alex=20Du=C5=BCy?= <91994767+alduzy@users.noreply.github.com> Date: Mon, 22 Apr 2024 10:02:14 +0200 Subject: [PATCH] added switch example (#5919) --- docs/blog/switch.md | 40 ++++++ docs/static/examples/Switch.js | 120 ++++++++++++++++++ .../recordings/examples/switch_android.mp4 | Bin 0 -> 292147 bytes .../static/recordings/examples/switch_ios.mov | Bin 0 -> 2360123 bytes 4 files changed, 160 insertions(+) create mode 100644 docs/blog/switch.md create mode 100644 docs/static/examples/Switch.js create mode 100644 docs/static/recordings/examples/switch_android.mp4 create mode 100644 docs/static/recordings/examples/switch_ios.mov diff --git a/docs/blog/switch.md b/docs/blog/switch.md new file mode 100644 index 00000000000..0fdd7c69044 --- /dev/null +++ b/docs/blog/switch.md @@ -0,0 +1,40 @@ +--- +slug: switch +title: Switch +--- + +A switch element is a user interface component that allows users to toggle between two or more states. It is commonly used to turn on/off a setting, enable/disable a feature, or select between options. + +import Switch from '@site/static/examples/Switch'; +import SwitchSrc from '!!raw-loader!@site/static/examples/Switch'; +import ExampleVideo from '@site/src/components/ExampleVideo'; +import CollapsibleCode from '@site/src/components/CollapsibleCode'; + +} /> + +The following implementation of a switch relies on [animatable values](/docs/fundamentals/glossary#animatable-value). Leveraging animatable values of color and position enables smooth transition between the two states. + +Switch + + + + + +We use the `useSharedValue` hook to store the dimensions of the element, which allows for precise calculation of position changes during the animation. The hook is there to prevent unnecessary re-renders. + + + +The values are updated during the `onLayout` event of the element. + + + +The **Switch** component can represent any boolean value passed as a prop. The state dynamically adjusts based on the `value` prop resulting in smooth transition animations. It enables passing any function using the `onPress` prop. The `duration` prop controls the duration of the animation. The `style` and `trackColors` props enable personalization. + +Switch + + diff --git a/docs/static/examples/Switch.js b/docs/static/examples/Switch.js new file mode 100644 index 00000000000..f8311bff928 --- /dev/null +++ b/docs/static/examples/Switch.js @@ -0,0 +1,120 @@ +import React from 'react'; +import { + Pressable, + SafeAreaView, + View, + StyleSheet, + Button, +} from 'react-native'; +import Animated, { + interpolate, + interpolateColor, + useAnimatedStyle, + useSharedValue, + withTiming, +} from 'react-native-reanimated'; + +const Switch = ({ + value, + onPress, + style, + duration = 400, + trackColors = { on: '#82cab2', off: '#fa7f7c' }, +}) => { + const height = useSharedValue(0); + const width = useSharedValue(0); + + const trackAnimatedStyle = useAnimatedStyle(() => { + const color = interpolateColor( + value.value, + [0, 1], + [trackColors.off, trackColors.on] + ); + const colorValue = withTiming(color, { duration }); + + return { + backgroundColor: colorValue, + borderRadius: height.value / 2, + }; + }); + + const thumbAnimatedStyle = useAnimatedStyle(() => { + const moveValue = interpolate( + Number(value.value), + [0, 1], + [0, width.value - height.value] + ); + const translateValue = withTiming(moveValue, { duration }); + + return { + transform: [{ translateX: translateValue }], + borderRadius: height.value / 2, + }; + }); + + return ( + + { + height.value = e.nativeEvent.layout.height; + width.value = e.nativeEvent.layout.width; + }} + style={[switchStyles.track, style, trackAnimatedStyle]}> + + + + ); +}; + +const switchStyles = StyleSheet.create({ + track: { + alignItems: 'flex-start', + width: 100, + height: 40, + padding: 5, + }, + thumb: { + height: '100%', + aspectRatio: 1, + backgroundColor: 'white', + }, +}); + +export default function App() { + const isOn = useSharedValue(false); + + const handlePress = () => { + isOn.value = !isOn.value; + }; + + return ( + + + +