choerodon-ui
Version:
An enterprise-class UI design language and React-based implementation
255 lines (222 loc) • 8.38 kB
JavaScript
import _defineProperty from "@babel/runtime/helpers/defineProperty";
import _extends from "@babel/runtime/helpers/extends";
import _objectSpread from "@babel/runtime/helpers/objectSpread2";
import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
import _objectWithoutProperties from "@babel/runtime/helpers/objectWithoutProperties";
var _excluded = ["src", "downloadUrl", "previewUrl", "previewTarget", "lazy", "className", "width", "height", "prefixCls", "style", "sources", "alt", "title", "block", "preview", "modalProps", "objectFit", "objectPosition", "status", "border", "index", "onClick", "children", "onPreview"];
import React, { forwardRef, useCallback, useContext, useEffect, useImperativeHandle, useRef, useState } from 'react';
import classNames from 'classnames';
import ReactIntersectionObserver from 'react-intersection-observer';
import isNumber from 'lodash/isNumber';
import ConfigContext from '../../../es/config-provider/ConfigContext';
import { pxToRem } from '../../../es/_util/UnitConvertor';
import Icon from '../icon';
import objectFitPolyfill, { isObjectFitSupport } from '../_util/objectFitPolyfill';
import PictureContext, { PictureProvider } from './PictureContext';
import modalPreview from '../modal/preview';
function Picture(props, ref) {
var _classNames;
var src = props.src,
downloadUrl = props.downloadUrl,
previewUrl = props.previewUrl,
previewTarget = props.previewTarget,
lazy = props.lazy,
className = props.className,
width = props.width,
height = props.height,
prefixCls = props.prefixCls,
style = props.style,
sources = props.sources,
alt = props.alt,
title = props.title,
_props$block = props.block,
block = _props$block === void 0 ? true : _props$block,
_props$preview = props.preview,
preview = _props$preview === void 0 ? true : _props$preview,
modalProps = props.modalProps,
_props$objectFit = props.objectFit,
objectFit = _props$objectFit === void 0 ? 'fill' : _props$objectFit,
_props$objectPosition = props.objectPosition,
objectPosition = _props$objectPosition === void 0 ? 'center' : _props$objectPosition,
propStatus = props.status,
border = props.border,
index = props.index,
onClick = props.onClick,
children = props.children,
onPreview = props.onPreview,
rest = _objectWithoutProperties(props, _excluded);
var url = previewUrl || src;
var pictureRef = useRef({
src: url,
downloadUrl: downloadUrl
});
var context = useContext(PictureContext);
var _useContext = useContext(ConfigContext),
getProPrefixCls = _useContext.getProPrefixCls;
var customPrefixCls = getProPrefixCls('picture', prefixCls);
var imgRef = useRef(null);
var _useState = useState(propStatus || 'empty'),
_useState2 = _slicedToArray(_useState, 2),
status = _useState2[0],
setStatus = _useState2[1];
var _useState3 = useState(!lazy || !!propStatus),
_useState4 = _slicedToArray(_useState3, 2),
inView = _useState4[0],
setInView = _useState4[1];
var handlePreview = useCallback(function () {
if (preview && !previewTarget && status === 'loaded' && url) {
if (context && isNumber(index)) {
context.preview(index, modalProps);
} else {
modalPreview({
list: [{
src: url,
downloadUrl: downloadUrl
}]
}, modalProps);
}
if (onPreview) {
onPreview();
}
}
}, [context, index, preview, previewTarget, status, url, downloadUrl, onPreview]);
var handleClick = useCallback(function (e) {
handlePreview();
if (onClick) {
onClick(e);
}
}, [handlePreview, onClick]);
var wrapperStyle = _objectSpread({}, style);
var elementStyle = {
objectFit: objectFit,
objectPosition: objectPosition
};
if (typeof width !== 'undefined') {
var w = pxToRem(width) || 0;
elementStyle.width = w;
wrapperStyle.width = w;
}
if (typeof height !== 'undefined') {
var h = pxToRem(height) || 0;
elementStyle.height = h;
wrapperStyle.height = h;
}
useEffect(function () {
if (!propStatus && inView && src) {
var _img = new Image(width, height);
var onLoad = function onLoad() {
setStatus('loaded');
};
var onError = function onError() {
setStatus('error');
};
_img.addEventListener('load', onLoad, false);
_img.addEventListener('error', onError, false);
_img.src = src;
return function () {
_img.removeEventListener('load', onLoad, false);
_img.removeEventListener('error', onError, false);
};
}
}, [inView, src, propStatus]);
useEffect(function () {
if (propStatus) {
setStatus(propStatus);
}
}, [propStatus]);
useEffect(function () {
var current = imgRef.current;
if (current && !isObjectFitSupport() && objectFit && objectPosition) {
var onResize = function onResize() {
return objectFitPolyfill(current, objectFit, objectPosition);
};
onResize();
window.addEventListener('resize', onResize, false);
return function () {
return window.removeEventListener('resize', onResize, false);
};
}
}, [imgRef, objectFit, objectPosition]);
useEffect(function () {
if (preview && !previewTarget && context && isNumber(index) && url) {
var current = pictureRef.current;
current.src = url;
context.registerPicture(index, current);
return function () {
return context.unRegisterPicture(index, current);
};
}
}, [index, context, pictureRef, preview, previewTarget, url]);
useImperativeHandle(ref, function () {
return {
preview: handlePreview,
getImage: function getImage() {
return imgRef.current;
}
};
}, [handlePreview, imgRef]);
var renderSources = function renderSources() {
if (sources) {
return sources.map(function (source, i) {
return /*#__PURE__*/React.createElement("source", _extends({
key: String(i)
}, source));
});
}
};
var renderImg = function renderImg() {
if (children) {
return children;
}
switch (status) {
case 'loaded':
{
return /*#__PURE__*/React.createElement("img", _extends({
ref: imgRef,
style: elementStyle,
className: "".concat(customPrefixCls, "-img"),
src: src,
alt: alt || title,
title: title
}, rest));
}
case 'error':
return /*#__PURE__*/React.createElement("div", {
className: "".concat(customPrefixCls, "-icon")
}, /*#__PURE__*/React.createElement(Icon, {
type: "sentiment_dissatisfied"
}));
case 'empty':
default:
return /*#__PURE__*/React.createElement("div", {
className: "".concat(customPrefixCls, "-icon")
}, /*#__PURE__*/React.createElement(Icon, {
type: "photo_size_select_actual"
}));
}
};
var classString = classNames(customPrefixCls, (_classNames = {}, _defineProperty(_classNames, "".concat(customPrefixCls, "-border"), border), _defineProperty(_classNames, "".concat(customPrefixCls, "-block"), block), _defineProperty(_classNames, "".concat(customPrefixCls, "-preview"), preview && status === 'loaded'), _classNames), className);
var isPictureSupport = typeof HTMLPictureElement !== 'undefined';
var Cmp = isPictureSupport ? 'picture' : 'div';
var img = renderImg();
var picture = /*#__PURE__*/React.createElement(Cmp, {
className: classString,
style: wrapperStyle,
onClick: handleClick
}, isPictureSupport && renderSources(), preview && previewTarget ? /*#__PURE__*/React.createElement("a", {
target: previewTarget,
href: url
}, img) : img);
if (lazy && !propStatus && status !== 'loaded') {
return /*#__PURE__*/React.createElement(ReactIntersectionObserver, {
onChange: setInView
}, picture);
}
return picture;
}
var ForwardPicture = /*#__PURE__*/forwardRef(Picture);
ForwardPicture.Provider = PictureProvider;
ForwardPicture.Context = PictureContext;
ForwardPicture.displayName = 'Picture';
export default ForwardPicture;
//# sourceMappingURL=Picture.js.map