| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210 | 
							- /* eslint-disable jsx-a11y/click-events-have-key-events */
 
- /* eslint-disable jsx-a11y/no-static-element-interactions */
 
- import React from "react";
 
- import BaseComponent from "../_base/baseComponent";
 
- import { ImageProps, ImageStates } from "./interface";
 
- import PropTypes from "prop-types";
 
- import { cssClasses } from "@douyinfe/semi-foundation/image/constants";
 
- import cls from "classnames";
 
- import { IconUploadError, IconEyeOpened } from "@douyinfe/semi-icons";
 
- import PreviewInner from "./previewInner";
 
- import "@douyinfe/semi-foundation/image/image.scss";
 
- import { PreviewContext, PreviewContextProps } from "./previewContext";
 
- import ImageFoundation, { ImageAdapter } from "@douyinfe/semi-foundation/image/imageFoundation";
 
- import LocaleConsumer from "../locale/localeConsumer";
 
- import { Locale } from "../locale/interface";
 
- import { isObject } from "lodash";
 
- import Skeleton from "../skeleton";
 
- const prefixCls = cssClasses.PREFIX;
 
- export default class Image extends BaseComponent<ImageProps, ImageStates> {
 
-     static isSemiImage = true;
 
-     static contextType = PreviewContext;
 
-     static propTypes = {
 
-         style: PropTypes.object,
 
-         className: PropTypes.string,
 
-         src: PropTypes.string,
 
-         width: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
 
-         height: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
 
-         alt: PropTypes.string,
 
-         placeholder: PropTypes.node,
 
-         fallback: PropTypes.oneOfType([PropTypes.string, PropTypes.node]),
 
-         preview: PropTypes.oneOfType([PropTypes.bool, PropTypes.object]),
 
-         onLoad: PropTypes.func,
 
-         onError: PropTypes.func,
 
-         crossOrigin: PropTypes.string,
 
-         imageID: PropTypes.number,
 
-     }
 
-     static defaultProps = {
 
-         preview: true,
 
-     };
 
-     get adapter(): ImageAdapter<ImageProps, ImageStates> {
 
-         return {
 
-             ...super.adapter,
 
-             getIsInGroup: () => this.isInGroup(),
 
-         };
 
-     }
 
-     context: PreviewContextProps;
 
-     foundation: ImageFoundation;
 
-     constructor(props: ImageProps) {
 
-         super(props);
 
-         this.state = {
 
-             src: "",
 
-             loadStatus: "loading",
 
-             previewVisible: false,
 
-         };
 
-         this.foundation = new ImageFoundation(this.adapter);
 
-     }
 
-     static getDerivedStateFromProps(props: ImageProps, state: ImageStates) {
 
-         const willUpdateStates: Partial<ImageStates> = {};
 
-         if (props.src !== state.src) {
 
-             willUpdateStates.src = props.src;
 
-             willUpdateStates.loadStatus = "loading";
 
-         }
 
-         return willUpdateStates;
 
-     }
 
-     isInGroup() {
 
-         return Boolean(this.context && this.context.isGroup);
 
-     }
 
-     isLazyLoad() {
 
-         if (this.context) {
 
-             return this.context.lazyLoad;
 
-         }
 
-         return false;
 
-     }
 
-     handleClick = (e) => {
 
-         this.foundation.handleClick(e);
 
-     };
 
-     handleLoaded = (e) => {
 
-         this.foundation.handleLoaded(e);
 
-     }
 
-     handleError = (e) => {
 
-         this.foundation.handleError(e);
 
-     }
 
-     handlePreviewVisibleChange = (visible: boolean) => {
 
-         this.foundation.handlePreviewVisibleChange(visible);
 
-     }
 
-     renderDefaultLoading = () => {
 
-         const { width, height } = this.props;
 
-         return (
 
-             <Skeleton.Image style={{ width, height }} />
 
-         );
 
-     };
 
-     renderDefaultError = () => {
 
-         const prefixClsName = `${prefixCls}-status`;
 
-         return (
 
-             <div className={prefixClsName}>
 
-                 <IconUploadError size={"extra-large"} />
 
-             </div>
 
-         );
 
-     };
 
-     renderLoad = () => {
 
-         const prefixClsName = `${prefixCls}-status`;
 
-         const { placeholder } = this.props;
 
-         return (
 
-             placeholder ? (
 
-                 <div className={prefixClsName}> 
 
-                     {placeholder}
 
-                 </div>
 
-             ) : this.renderDefaultLoading()
 
-         );
 
-     }
 
-     renderError = () => {
 
-         const { fallback } = this.props;
 
-         const prefixClsName = `${prefixCls}-status`;
 
-         const fallbackNode = typeof fallback === "string" ? (<img style={{ width: "100%", height: "100%" }}src={fallback} alt="fallback"/>) : fallback;
 
-         return (
 
-             fallback ? (
 
-                 <div className={prefixClsName}>
 
-                     {fallbackNode}
 
-                 </div>
 
-             ) :this.renderDefaultError()
 
-         );
 
-     }
 
-     renderExtra = () => {
 
-         const { loadStatus } = this.state;
 
-         return (
 
-             <div className={`${prefixCls}-overlay`}>
 
-                 {loadStatus === "error" && this.renderError()}
 
-                 {loadStatus === "loading" && this.renderLoad()}
 
-             </div>
 
-         );
 
-     }
 
-     getLocalTextByKey = (key: string) => (
 
-         <LocaleConsumer<Locale["Image"]> componentName="Image" >
 
-             {(locale: Locale["Image"]) => locale[key]}
 
-         </LocaleConsumer>
 
-     );
 
-     renderMask = () => (<div className={`${prefixCls}-mask`}>
 
-         <div className={`${prefixCls}-mask-info`}>
 
-             <IconEyeOpened size="extra-large"/>
 
-             <span className={`${prefixCls}-mask-info-text`}>{this.getLocalTextByKey("preview")}</span>
 
-         </div>
 
-     </div>)
 
-     render() {
 
-         const { src, loadStatus, previewVisible } = this.state;
 
-         const { width, height, alt, style, className, crossOrigin, preview } = this.props;
 
-         const outerStyle = Object.assign({ width, height }, style);
 
-         const outerCls = cls(prefixCls, className);
 
-         const canPreview = loadStatus === "success" && preview && !this.isInGroup();
 
-         const showPreviewCursor = preview && loadStatus === "success";
 
-         const previewSrc = isObject(preview) ? ((preview as any).src ?? src) : src;
 
-         const previewProps = isObject(preview) ? preview : {};
 
-         return ( 
 
-             // eslint-disable jsx-a11y/no-static-element-interactions
 
-             // eslint-disable jsx-a11y/click-events-have-key-events
 
-             <div
 
-                 style={outerStyle}
 
-                 className={outerCls}
 
-                 onClick={this.handleClick}
 
-             >
 
-                 <img
 
-                     src={this.isInGroup() && this.isLazyLoad() ? undefined : src}
 
-                     data-src={src}
 
-                     alt={alt}
 
-                     className={cls(`${prefixCls}-img`, {
 
-                         [`${prefixCls}-img-preview`]: showPreviewCursor,
 
-                         [`${prefixCls}-img-error`]: loadStatus === "error",
 
-                     })}
 
-                     width={width}
 
-                     height={height}
 
-                     crossOrigin={crossOrigin}
 
-                     onError={this.handleError}
 
-                     onLoad={this.handleLoaded}
 
-                 />
 
-                 {loadStatus !== "success" && this.renderExtra()}
 
-                 {canPreview && 
 
-                     <PreviewInner
 
-                         {...previewProps}
 
-                         src={previewSrc}
 
-                         visible={previewVisible}
 
-                         onVisibleChange={this.handlePreviewVisibleChange}
 
-                     />
 
-                 }
 
-             </div>
 
-         );
 
-     } 
 
- }
 
 
  |