UNPKG

choerodon-ui

Version:

An enterprise-class UI design language and React-based implementation

255 lines (222 loc) 8.38 kB
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