import React, { forwardRef, ForwardRefRenderFunction, useImperativeHandle, useState, useEffect, } from 'react'; import { View, StyleSheet, Text, TouchableOpacity } from 'react-native'; import createStyles from './styles/tour.style'; import { useTheme } from '../Theme/Theme'; import { TourProps, TourRef } from './interface'; import Mask from '../Mask'; import Reactangle from './Reactangle'; import { useLocale } from '../Locale/locale'; import TourStep from './TourStep'; import { TourStepProps } from '@xrnjs/ui'; import { renderTextLikeJSX } from '../../core/helpers/index'; import { Fill, Size } from '../Button/enum'; import Button from '../Button/index'; import { IconXLeftsmall1, IconXRightsmall1, } from '../../icons'; const Tour: ForwardRefRenderFunction = (props, ref) => { const { visible = false, onBackdropPress, onTargetPress, statusBarTranslucent = true, steps, arrow = true, arrowColor, placement, onSkip, onFinish, mask = true, maskColor, maskOpacity, onChange, current: cusCurrent, skip = false, indicatorsStyle: cusIndicatorsStyle, indicatorsRender: cusIndicatorsRender, footerRender: cusFooterRender, } = props; const locale = useLocale().Tour; const [current, setCurrent] = useState(0); const finalCurrent = cusCurrent ?? current; const stepsNum = steps?.length || 0; const step = (steps?.[finalCurrent] || {}) as TourStepProps; const [stepLayout, setStepLayout] = useState(step?.layout); const token = useTheme(); const styles = createStyles(token); // 关闭蒙层 const handleClose = () => { onBackdropPress?.(); }; // current变化处理 const handleChange = (stepIndex: number) => { if (stepIndex >= stepsNum) { onFinish?.(); return; } if (stepIndex < 0) return; //没有上一步了 onChange?.(stepIndex); if (cusCurrent !== undefined) return; // 受控的话完全由业务控制 setCurrent(stepIndex); }; // 跳过 const handleSkip = () => { skip && onSkip?.(); }; const handlePre = () => handleChange(finalCurrent - 1); const handleNext = () => handleChange(finalCurrent + 1); const setpFooterIndicatorsRender = () => { const { indicatorsRender, indicatorsStyle, skip: stepSkip } = step; const finalIndicatorsRender = indicatorsRender || cusIndicatorsRender; const finalSkip = stepSkip ?? skip; const skipStr = finalSkip ? locale.skip : ''; return finalIndicatorsRender ? ( finalIndicatorsRender?.(finalCurrent) ) : ( {`${skipStr}(${finalCurrent + 1}/${stepsNum})`} ); }; const disbalePrev = finalCurrent <= 0; const setpFooterBtnsRender = () => { const { nextButton, prevButton } = step; const prevColor = disbalePrev ? token['--color-text-2'] : token['--color-text-5']; const prevBtn = prevButton !== undefined ? ( renderTextLikeJSX(prevButton, styles.prevBtn) ) : ( ) : (