Image.js 6.98 KB
import _objectSpread from "@babel/runtime/helpers/esm/objectSpread2";
import _defineProperty from "@babel/runtime/helpers/esm/defineProperty";
import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray";
import _typeof from "@babel/runtime/helpers/esm/typeof";
import _objectWithoutProperties from "@babel/runtime/helpers/esm/objectWithoutProperties";
import * as React from 'react';
import { useState } from 'react';
import cn from 'classnames';
import { getOffset } from "rc-util/es/Dom/css";
import useMergedState from "rc-util/es/hooks/useMergedState";
import Preview from './Preview';
import PreviewGroup, { context } from './PreviewGroup';

var ImageInternal = function ImageInternal(_ref) {
  var src = _ref.src,
      alt = _ref.alt,
      onInitialPreviewClose = _ref.onPreviewClose,
      _ref$prefixCls = _ref.prefixCls,
      prefixCls = _ref$prefixCls === void 0 ? 'rc-image' : _ref$prefixCls,
      _ref$previewPrefixCls = _ref.previewPrefixCls,
      previewPrefixCls = _ref$previewPrefixCls === void 0 ? "".concat(prefixCls, "-preview") : _ref$previewPrefixCls,
      placeholder = _ref.placeholder,
      fallback = _ref.fallback,
      width = _ref.width,
      height = _ref.height,
      style = _ref.style,
      _ref$preview = _ref.preview,
      preview = _ref$preview === void 0 ? true : _ref$preview,
      className = _ref.className,
      onClick = _ref.onClick,
      wrapperClassName = _ref.wrapperClassName,
      wrapperStyle = _ref.wrapperStyle,
      crossOrigin = _ref.crossOrigin,
      decoding = _ref.decoding,
      loading = _ref.loading,
      referrerPolicy = _ref.referrerPolicy,
      sizes = _ref.sizes,
      srcSet = _ref.srcSet,
      useMap = _ref.useMap,
      otherProps = _objectWithoutProperties(_ref, ["src", "alt", "onPreviewClose", "prefixCls", "previewPrefixCls", "placeholder", "fallback", "width", "height", "style", "preview", "className", "onClick", "wrapperClassName", "wrapperStyle", "crossOrigin", "decoding", "loading", "referrerPolicy", "sizes", "srcSet", "useMap"]);

  var isCustomPlaceholder = placeholder && placeholder !== true;

  var _ref2 = _typeof(preview) === 'object' ? preview : {},
      _ref2$visible = _ref2.visible,
      visible = _ref2$visible === void 0 ? undefined : _ref2$visible,
      _ref2$onVisibleChange = _ref2.onVisibleChange,
      onVisibleChange = _ref2$onVisibleChange === void 0 ? onInitialPreviewClose : _ref2$onVisibleChange,
      _ref2$getContainer = _ref2.getContainer,
      getContainer = _ref2$getContainer === void 0 ? undefined : _ref2$getContainer;

  var isControlled = visible !== undefined;

  var _useMergedState = useMergedState(!!visible, {
    value: visible,
    onChange: onVisibleChange
  }),
      _useMergedState2 = _slicedToArray(_useMergedState, 2),
      isShowPreview = _useMergedState2[0],
      setShowPreview = _useMergedState2[1];

  var _useState = useState(isCustomPlaceholder ? 'loading' : 'normal'),
      _useState2 = _slicedToArray(_useState, 2),
      status = _useState2[0],
      setStatus = _useState2[1];

  var _useState3 = useState(null),
      _useState4 = _slicedToArray(_useState3, 2),
      mousePosition = _useState4[0],
      setMousePosition = _useState4[1];

  var isError = status === 'error';

  var _React$useContext = React.useContext(context),
      isPreviewGroup = _React$useContext.isPreviewGroup,
      previewUrls = _React$useContext.previewUrls,
      setPreviewUrls = _React$useContext.setPreviewUrls,
      setCurrent = _React$useContext.setCurrent,
      setGroupShowPreview = _React$useContext.setShowPreview,
      setGroupMousePosition = _React$useContext.setMousePosition;

  var groupIndexRef = React.useRef(0);

  var onLoad = function onLoad() {
    setStatus('normal');
  };

  var onError = function onError() {
    setStatus('error');

    if (isPreviewGroup) {
      previewUrls.splice(groupIndexRef.current);
      setPreviewUrls(previewUrls);
    }
  };

  var onPreview = function onPreview(e) {
    if (!isControlled) {
      var _getOffset = getOffset(e.target),
          left = _getOffset.left,
          top = _getOffset.top;

      if (isPreviewGroup) {
        setCurrent(src);
        setGroupMousePosition({
          x: left,
          y: top
        });
      } else {
        setMousePosition({
          x: left,
          y: top
        });
      }
    }

    if (isPreviewGroup) {
      setGroupShowPreview(true);
    } else {
      setShowPreview(true);
    }

    if (onClick) onClick(e);
  };

  var onPreviewClose = function onPreviewClose(e) {
    e.stopPropagation();
    setShowPreview(false);

    if (!isControlled) {
      setMousePosition(null);
    }
  };

  var getImgRef = function getImgRef(img) {
    if (status !== 'loading') return;

    if ((img === null || img === void 0 ? void 0 : img.complete) && (img.naturalWidth || img.naturalHeight)) {
      onLoad();
    }
  };

  React.useEffect(function () {
    if (isPreviewGroup && previewUrls.indexOf(src) < 0) {
      groupIndexRef.current = previewUrls.length;
      previewUrls.push(src);
      setPreviewUrls(previewUrls);
    }
  }, [previewUrls]);
  React.useEffect(function () {
    if (isCustomPlaceholder) {
      setStatus('loading');
    }

    return function () {
      setPreviewUrls(previewUrls.filter(function (url) {
        return url !== src;
      }));
    };
  }, [src]);
  var wrappperClass = cn(prefixCls, wrapperClassName, _defineProperty({}, "".concat(prefixCls, "-error"), isError));
  var mergedSrc = isError && fallback ? fallback : src;
  var imgCommonProps = {
    crossOrigin: crossOrigin,
    decoding: decoding,
    loading: loading,
    referrerPolicy: referrerPolicy,
    sizes: sizes,
    srcSet: srcSet,
    useMap: useMap,
    alt: alt,
    className: cn("".concat(prefixCls, "-img"), _defineProperty({}, "".concat(prefixCls, "-img-placeholder"), placeholder === true), className),
    style: _objectSpread({
      height: height
    }, style)
  };
  return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("div", Object.assign({}, otherProps, {
    className: wrappperClass,
    onClick: preview && !isError ? onPreview : onClick,
    style: _objectSpread({
      width: width,
      height: height
    }, wrapperStyle)
  }), isError && fallback ? /*#__PURE__*/React.createElement("img", Object.assign({}, imgCommonProps, {
    src: fallback
  })) : /*#__PURE__*/React.createElement("img", Object.assign({}, imgCommonProps, {
    onLoad: onLoad,
    onError: onError,
    src: src,
    ref: getImgRef
  })), status === 'loading' && /*#__PURE__*/React.createElement("div", {
    "aria-hidden": "true",
    className: "".concat(prefixCls, "-placeholder")
  }, placeholder)), !isPreviewGroup && preview && !isError && /*#__PURE__*/React.createElement(Preview, {
    "aria-hidden": !isShowPreview,
    visible: isShowPreview,
    prefixCls: previewPrefixCls,
    onClose: onPreviewClose,
    mousePosition: mousePosition,
    src: mergedSrc,
    alt: alt,
    getContainer: getContainer
  }));
};

ImageInternal.PreviewGroup = PreviewGroup;
ImageInternal.displayName = 'Image';
export default ImageInternal;