UNPKG

@geezee/react-ui

Version:

Modern and minimalist React UI library.

127 lines (113 loc) 4.55 kB
import _extends from "@babel/runtime/helpers/esm/extends"; import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray"; import _objectWithoutProperties from "@babel/runtime/helpers/esm/objectWithoutProperties"; import _JSXStyle from "styled-jsx/style"; import React, { useEffect, useRef, useState } from 'react'; import useTheme from '../styles/use-theme'; import ImageSkeleton from './image.skeleton'; import useRealShape from '../utils/use-real-shape'; import useCurrentState from '../utils/use-current-state'; import useResize from '../utils/use-resize'; var defaultProps = { disableSkeleton: false, disableAutoResize: false, className: '', scale: '100%', maxDelay: 3000 }; var Image = function Image(_ref) { var src = _ref.src, width = _ref.width, height = _ref.height, disableSkeleton = _ref.disableSkeleton, className = _ref.className, scale = _ref.scale, maxDelay = _ref.maxDelay, disableAutoResize = _ref.disableAutoResize, props = _objectWithoutProperties(_ref, ["src", "width", "height", "disableSkeleton", "className", "scale", "maxDelay", "disableAutoResize"]); var showAnimation = !disableSkeleton && width && height; var w = width ? "".concat(width, "px") : 'auto'; var h = height ? "".concat(height, "px") : 'auto'; var theme = useTheme(); var _useState = useState(true), _useState2 = _slicedToArray(_useState, 2), loading = _useState2[0], setLoading = _useState2[1]; var _useState3 = useState(true), _useState4 = _slicedToArray(_useState3, 2), showSkeleton = _useState4[0], setShowSkeleton = _useState4[1]; var _useCurrentState = useCurrentState(h), _useCurrentState2 = _slicedToArray(_useCurrentState, 3), zoomHeight = _useCurrentState2[0], setZoomHeight = _useCurrentState2[1], zoomHeightRef = _useCurrentState2[2]; var imageRef = useRef(null); var _useRealShape = useRealShape(imageRef), _useRealShape2 = _slicedToArray(_useRealShape, 2), shape = _useRealShape2[0], updateShape = _useRealShape2[1]; var imageLoaded = function imageLoaded() { if (!showAnimation) return; setLoading(false); }; useEffect(function () { if (!showAnimation) return; if (!imageRef.current) return; if (imageRef.current.complete) { setLoading(false); setShowSkeleton(false); } }); useEffect(function () { var timer = setTimeout(function () { if (showAnimation) { setShowSkeleton(false); } clearTimeout(timer); }, maxDelay); return function () { return clearTimeout(timer); }; }, [loading]); /** * On mobile devices, the render witdth may be less than CSS width value. * If the image is scaled, set the height manually. * This is to ensure the aspect ratio of the image. * * If the image is auto width, ignore all. */ useEffect(function () { if (disableAutoResize) return; var notLoaded = shape.width === 0; var isAutoZoom = zoomHeightRef.current === 'auto'; if (notLoaded || !width || !height) return; if (shape.width < width) { !isAutoZoom && setZoomHeight('auto'); } else { isAutoZoom && setZoomHeight(h); } }, [shape, width]); useResize(function () { if (disableAutoResize) return; updateShape(); }); return /*#__PURE__*/React.createElement("div", { className: _JSXStyle.dynamic([["286606564", [w, zoomHeight, theme.expressiveness.R2, scale, scale]]]) + " " + "image ".concat(className) }, showSkeleton && showAnimation && /*#__PURE__*/React.createElement(ImageSkeleton, { opacity: loading ? 0.5 : 0 }), /*#__PURE__*/React.createElement("img", _extends({ ref: imageRef, width: width, height: height, onLoad: imageLoaded, src: src }, props, { className: _JSXStyle.dynamic([["286606564", [w, zoomHeight, theme.expressiveness.R2, scale, scale]]]) + " " + (props && props.className != null && props.className || "") })), /*#__PURE__*/React.createElement(_JSXStyle, { id: "286606564", dynamic: [w, zoomHeight, theme.expressiveness.R2, scale, scale] }, ".image.__jsx-style-dynamic-selector{width:".concat(w, ";height:").concat(zoomHeight, ";margin:0 auto;position:relative;border-radius:").concat(theme.expressiveness.R2, ";overflow:hidden;max-width:100%;}img.__jsx-style-dynamic-selector{width:").concat(scale, ";height:").concat(scale, ";object-fit:scale-down;display:block;}"))); }; Image.defaultProps = defaultProps; export default React.memo(Image);