import { useEffect } from 'react' import { View, Pressable, StyleSheet } from 'react-native' import Animated, { useSharedValue, useAnimatedStyle, interpolate, Extrapolation, ReduceMotion, withSpring, } from 'react-native-reanimated' import { useReduceMotion, useTheme } from '../../hooks' import { platformFontWeightMedium } from '../../utils' import { Icon, Text } from '../display' interface JumpToBottomButtonProps { onPress: () => void visible: boolean } export const JumpToBottomButton = ({ onPress, visible }: JumpToBottomButtonProps) => { const styles = useStyles() const progress = useSharedValue(0) const reduceMotion = useReduceMotion() useEffect(() => { progress.value = withSpring(visible ? 1 : 0, { mass: 1, damping: 16, stiffness: 170, overshootClamping: false, reduceMotion: reduceMotion ? ReduceMotion.Always : ReduceMotion.Never, }) }, [visible, progress, reduceMotion]) const animatedStyle = useAnimatedStyle(() => { return { opacity: progress.value, transform: [ { translateY: interpolate(progress.value, [0, 1], [12, 0], Extrapolation.CLAMP), }, { scale: interpolate(progress.value, [0, 1], [0.9, 1], Extrapolation.CLAMP), }, ], } }) return ( [styles.button, pressed && styles.pressed]} > Jump to bottom ) } const useStyles = () => { const { colors } = useTheme() return StyleSheet.create({ container: { alignSelf: 'center', position: 'absolute', bottom: 16, zIndex: 2, }, button: { flexDirection: 'row', alignItems: 'center', gap: 6, paddingHorizontal: 12, paddingVertical: 6, borderRadius: 20, backgroundColor: colors.fillColorNeutral020, shadowColor: colors.fillColorNeutral000, shadowOffset: { width: 0, height: 1, }, shadowOpacity: 0.25, shadowRadius: 2.84, elevation: 5, }, text: { color: colors.fillColorNeutral100Inverted, fontWeight: platformFontWeightMedium, }, icon: { color: colors.fillColorNeutral100Inverted, fontSize: 14, }, pressed: { transform: [{ scale: 0.95 }], }, }) }