UNPKG

mh-rn-component

Version:

122 lines (120 loc) 3.3 kB
import React, { useEffect, useState } from 'react' import { Animated, View, Text, StyleSheet, TouchableWithoutFeedback, Easing, StyleProp, ViewStyle, ScrollView } from 'react-native'; import Overlay from '../Overlay' // import { useHeaderHeight } from '@react-navigation/elements' import Icon from '../Icon' import { ToastType } from "./types" export interface Props extends ToastType { show?: boolean onChange?: (value: any) => void } const Toast = ({ message = "成功", show = false, icon, iconSize = 48, overlayNeed = true, //* 是否需要遮罩层 默认true overlay = false, closeOnClickOverlay = true, duration = 2000, color = "#fff", position = "middle", loading = false, ...rest }: Props) => { const onChange = (value?: boolean) => { rest?.onChange && (rest.id ? rest?.onChange(rest.id) : rest?.onChange(false)) } // 隐藏 2000s后隐藏 const hide = () => { if (duration === 0) { return } const tt = setTimeout(() => { onChange() clearTimeout(tt) }, Number(duration)) } const turn = new Animated.Value(0) useEffect(() => { hide() }, [show]) useEffect(() => { Animated.loop( Animated.timing(turn, { toValue: 1, duration: 1000, easing: Easing.linear, useNativeDriver: false, }), { iterations: -1 } ).start(); // turn.setValue(360) }, [loading]) const lodingDom = () => { return ( <TouchableWithoutFeedback> <Animated.View style={{ transform: [{ rotateZ: turn.interpolate({ inputRange: [0, 1], outputRange: ['0deg', '360deg'], }), },] }}> <Icon color={color} name={icon} size={Number(iconSize)}></Icon> </Animated.View> </TouchableWithoutFeedback> ) } return ( <> {overlayNeed ? <Overlay show={show} onChange={() => closeOnClickOverlay && onChange(false)} style={[!overlay && { backgroundColor: '', }]}> <View style={StyleSheet.flatten([styles.toast, position !== "middle" && styles[`position_${position}`]])}> {loading && lodingDom()} {(!loading && icon) && <Icon color={color} name={icon} size={Number(iconSize)}></Icon>} <Text style={{ color: color }}>{message}</Text> </View> </Overlay> : <View pointerEvents="none" style={[styles.no_overlay_toast, { display: show ? 'flex' : 'none' }]}> <View style={[styles.toast]}> {loading && lodingDom()} {(!loading && icon) && <Icon color={color} name={icon} size={Number(iconSize)}></Icon>} <Text style={{ color: color }}>{message}</Text> </View> </View>} </> ) } const styles = StyleSheet.create({ toast: { borderRadius: 6, padding: 16, overflow: "hidden", backgroundColor: 'rgba(0, 0, 0, .4)', minWidth: 96, alignItems: "center", position: "absolute", }, no_overlay_toast: { width: '100%', height: '100%', flex: 1, alignItems: "center", justifyContent: "center", position: "absolute", top: 0, left: 0, }, position_top: { top: "10%", }, position_bottom: { bottom: "10%", } }) export default Toast