import { CSSProperties, forwardRef, ForwardRefExoticComponent, ReactNode, useCallback, useEffect, useImperativeHandle, useRef, useState, } from 'react' import classNames from 'classnames' import { CommonComponentProps } from '../../utils/types' import { useEvent } from '../../use' import { Swiper, SwiperRef } from '../swiper/Swiper' import { Popup, PopupProps } from '../popup/Popup' import { Icon } from '../icon/Icon' import ImagePreviewItem from './ImagePreviewItem' import './ImagePreview.scss' import { show } from './ImagePreviewImperative' export interface ImagePreviewProps extends CommonComponentProps { className?: string style?: CSSProperties children?: ReactNode images?: string[] defaultIndex?: number visible?: boolean defaultVisible?: boolean onVisible?: (visible: boolean) => void popupProps?: PopupProps } export interface ImagePreview extends ForwardRefExoticComponent { show: (props: ImagePreviewProps) => any } export interface ImagePreviewPropsRef {} export const ImagePreview = forwardRef( (props, ref) => { const { className, style, children, images = [], defaultIndex = 0, visible, defaultVisible, onVisible, popupProps = {}, ...restProps } = props const { placement = 'center-fade', ...restPopupProps } = popupProps const [index, setIndex] = useState(defaultIndex) const swiperRef = useRef() const handleChange = (index: number) => { setIndex(index) } const [innerVisible, setInnerVisible] = useState( visible ?? defaultVisible ?? false ) const setVisible = useEvent((show: boolean) => { // 非受控 if (visible == null) { setInnerVisible(show) } onVisible?.(show) }) // 受控 useEffect(() => { if (visible != null) { setInnerVisible(visible) } }, [visible]) useEffect(() => { if (innerVisible) { swiperRef.current?.swipeTo(defaultIndex, false) } }, [innerVisible]) const handleClose = () => { setVisible(false) } const [touchable, setTouchable] = useState(true) const handleItemProcessing = (processing: boolean) => { setTouchable(!processing) } const [swiping, setSwiping] = useState(false) const handleAnimateStart = useCallback(() => { setSwiping(true) }, []) const handleAnimateEnd = useCallback(() => { setSwiping(false) }, []) const [touching, setTouching] = useState(false) const handleTouchMove = useCallback(() => { setTouching(true) }, []) const handleTouchEnd = useCallback(() => { setTouching(false) }, []) useImperativeHandle(ref, () => ({})) const imagePreviewClass = classNames('s-image-preview', className) return (
{index + 1} / {images.length}
{images.map((url, i) => ( ))}
) } ) as ImagePreview ImagePreview.show = show export default ImagePreview