diff --git a/src/Image.tsx b/src/Image.tsx index 893193ca..c4cd8c9f 100644 --- a/src/Image.tsx +++ b/src/Image.tsx @@ -129,6 +129,18 @@ const ImageInternal: CompoundedComponent = ({ const isLoaded = React.useRef(false); + const imgCommonProps = { + crossOrigin, + decoding, + draggable, + loading, + referrerPolicy, + sizes, + srcSet, + useMap, + alt, + }; + const onLoad = () => { setStatus('normal'); }; @@ -189,14 +201,18 @@ const ImageInternal: CompoundedComponent = ({ // Resolve https://github.com/ant-design/ant-design/issues/28881 // Only need unRegister when component unMount React.useEffect(() => { - const unRegister = registerImage(currentId, src); + const unRegister = registerImage(currentId, { + src, + imgCommonProps, + canPreview, + }); return unRegister; }, []); React.useEffect(() => { - registerImage(currentId, src, canPreview); - }, [src, canPreview]); + registerImage(currentId, { src, imgCommonProps, canPreview }); + }, [src, canPreview, JSON.stringify(imgCommonProps)]); // Keep order end React.useEffect(() => { @@ -213,29 +229,6 @@ const ImageInternal: CompoundedComponent = ({ }); const mergedSrc = isError && fallback ? fallback : src; - const imgCommonProps = { - crossOrigin, - decoding, - draggable, - loading, - referrerPolicy, - sizes, - srcSet, - useMap, - onError, - alt, - className: cn( - `${prefixCls}-img`, - { - [`${prefixCls}-img-placeholder`]: placeholder === true, - }, - className, - ), - style: { - height, - ...style, - }, - }; return ( <> @@ -251,10 +244,22 @@ const ImageInternal: CompoundedComponent = ({ > {status === 'loading' && ( @@ -268,7 +273,7 @@ const ImageInternal: CompoundedComponent = ({
{previewMask} @@ -288,6 +293,7 @@ const ImageInternal: CompoundedComponent = ({ icons={icons} scaleStep={scaleStep} rootClassName={rootClassName} + imgCommonProps={imgCommonProps} toolbarRender={toolbarRender} {...dialogProps} /> diff --git a/src/Preview.tsx b/src/Preview.tsx index 0447cec1..4760b7d8 100644 --- a/src/Preview.tsx +++ b/src/Preview.tsx @@ -33,9 +33,10 @@ export type toolbarRenderType = { }; current: number; total: number; -} +}; export interface PreviewProps extends Omit { + imgCommonProps?: React.ImgHTMLAttributes; onClose?: (e: React.SyntheticEvent) => void; src?: string; alt?: string; @@ -70,6 +71,7 @@ const Preview: React.FC = props => { scaleStep = 0.5, transitionName = 'zoom', maskTransitionName = 'fade', + imgCommonProps, toolbarRender, ...restProps } = props; @@ -82,11 +84,10 @@ const Preview: React.FC = props => { transformY: 0, }); const [isMoving, setMoving] = useState(false); - const { previewUrls, current, isPreviewGroup, setCurrent } = useContext(context); - const previewGroupCount = previewUrls.size; - const previewUrlsKeys = Array.from(previewUrls.keys()); - const currentPreviewIndex = previewUrlsKeys.indexOf(current); - const combinationSrc = isPreviewGroup ? previewUrls.get(current) : src; + const { previewData, current, isPreviewGroup, setCurrent } = useContext(context); + const previewGroupCount = previewData.size; + const previewDataKeys = Array.from(previewData.keys()); + const currentPreviewIndex = previewDataKeys.indexOf(current); const showLeftOrRightSwitches = isPreviewGroup && previewGroupCount > 1; const showOperationsProgress = isPreviewGroup && previewGroupCount >= 1; const { transform, resetTransform, updateTransform, dispatchZoomChange } = @@ -138,7 +139,7 @@ const Preview: React.FC = props => { if (currentPreviewIndex > 0) { setEnableTransition(false); resetTransform(); - setCurrent(previewUrlsKeys[currentPreviewIndex - 1]); + setCurrent(previewDataKeys[currentPreviewIndex - 1]); } }; @@ -148,7 +149,7 @@ const Preview: React.FC = props => { if (currentPreviewIndex < previewGroupCount - 1) { setEnableTransition(false); resetTransform(); - setCurrent(previewUrlsKeys[currentPreviewIndex + 1]); + setCurrent(previewDataKeys[currentPreviewIndex + 1]); } }; @@ -225,18 +226,18 @@ const Preview: React.FC = props => { if (event.keyCode === KeyCode.LEFT) { if (currentPreviewIndex > 0) { - setCurrent(previewUrlsKeys[currentPreviewIndex - 1]); + setCurrent(previewDataKeys[currentPreviewIndex - 1]); } } else if (event.keyCode === KeyCode.RIGHT) { if (currentPreviewIndex < previewGroupCount - 1) { - setCurrent(previewUrlsKeys[currentPreviewIndex + 1]); + setCurrent(previewDataKeys[currentPreviewIndex + 1]); } } }, [ currentPreviewIndex, previewGroupCount, - previewUrlsKeys, + previewDataKeys, setCurrent, showLeftOrRightSwitches, visible, @@ -302,6 +303,7 @@ const Preview: React.FC = props => { >
= props => { onDoubleClick={onDoubleClick} ref={imgRef} className={`${prefixCls}-img`} - src={combinationSrc} + src={src} alt={alt} style={{ transform: `translate3d(${transform.x}px, ${transform.y}px, 0) scale3d(${ diff --git a/src/PreviewGroup.tsx b/src/PreviewGroup.tsx index 76c91e47..ad017d9a 100644 --- a/src/PreviewGroup.tsx +++ b/src/PreviewGroup.tsx @@ -24,27 +24,28 @@ export interface GroupConsumerProps { children?: React.ReactNode; } -interface PreviewUrl { - url: string; +interface PreviewData { + src: string; + imgCommonProps: React.ImgHTMLAttributes; canPreview: boolean; } export interface GroupConsumerValue extends GroupConsumerProps { isPreviewGroup?: boolean; - previewUrls: Map; - setPreviewUrls: React.Dispatch>>; + previewData: Map; + setPreviewData: React.Dispatch>>; current: number; setCurrent: React.Dispatch>; setShowPreview: React.Dispatch>; setMousePosition: React.Dispatch>; - registerImage: (id: number, url: string, canPreview?: boolean) => () => void; + registerImage: (id: number, data: PreviewData) => () => void; rootClassName?: string; } /* istanbul ignore next */ export const context = React.createContext({ - previewUrls: new Map(), - setPreviewUrls: () => null, + previewData: new Map(), + setPreviewData: () => null, current: null, setCurrent: () => null, setShowPreview: () => null, @@ -78,13 +79,13 @@ const Group: React.FC = ({ toolbarRender = undefined, ...dialogProps } = typeof preview === 'object' ? preview : {}; - const [previewUrls, setPreviewUrls] = useState>(new Map()); - const previewUrlsKeys = Array.from(previewUrls.keys()); + const [previewData, setPreviewData] = useState>(new Map()); + const previewDataKeys = Array.from(previewData.keys()); const prevCurrent = React.useRef(); const [current, setCurrent] = useMergedState(undefined, { onChange: (val, prev) => { if (prevCurrent.current !== undefined) { - onChange?.(getSafeIndex(previewUrlsKeys, val), getSafeIndex(previewUrlsKeys, prev)); + onChange?.(getSafeIndex(previewDataKeys, val), getSafeIndex(previewDataKeys, prev)); } prevCurrent.current = prev; }, @@ -92,7 +93,7 @@ const Group: React.FC = ({ const [isShowPreview, setShowPreview] = useMergedState(!!previewVisible, { value: previewVisible, onChange: (val, prevVal) => { - onPreviewVisibleChange?.(val, prevVal, getSafeIndex(previewUrlsKeys, current)); + onPreviewVisibleChange?.(val, prevVal, getSafeIndex(previewDataKeys, current)); prevCurrent.current = val ? current : undefined; }, }); @@ -100,27 +101,22 @@ const Group: React.FC = ({ const [mousePosition, setMousePosition] = useState(null); const isControlled = previewVisible !== undefined; - const currentControlledKey = previewUrlsKeys[currentIndex]; - const canPreviewUrls = new Map( - Array.from(previewUrls) - .filter(([, { canPreview }]) => !!canPreview) - .map(([id, { url }]) => [id, url]), + const currentControlledKey = previewDataKeys[currentIndex]; + const canPreviewData = new Map( + Array.from(previewData).filter(([, { canPreview }]) => !!canPreview), ); - const registerImage = (id: number, url: string, canPreview: boolean = true) => { + const registerImage = (id: number, data: PreviewData) => { const unRegister = () => { - setPreviewUrls(oldPreviewUrls => { - const clonePreviewUrls = new Map(oldPreviewUrls); - const deleteResult = clonePreviewUrls.delete(id); - return deleteResult ? clonePreviewUrls : oldPreviewUrls; + setPreviewData(oldPreviewData => { + const clonePreviewData = new Map(oldPreviewData); + const deleteResult = clonePreviewData.delete(id); + return deleteResult ? clonePreviewData : oldPreviewData; }); }; - setPreviewUrls(oldPreviewUrls => { - return new Map(oldPreviewUrls).set(id, { - url, - canPreview, - }); + setPreviewData(oldPreviewData => { + return new Map(oldPreviewData).set(id, data); }); return unRegister; @@ -142,12 +138,14 @@ const Group: React.FC = ({ } }, [currentControlledKey, isControlled, isShowPreview]); + const canPreviewCurrentData = canPreviewData.get(current); + return ( = ({ prefixCls={previewPrefixCls} onClose={onPreviewClose} mousePosition={mousePosition} - src={canPreviewUrls.get(current)} + imgCommonProps={canPreviewCurrentData?.imgCommonProps} + src={canPreviewCurrentData?.src} icons={icons} getContainer={getContainer} countRender={countRender} diff --git a/tests/preview.test.tsx b/tests/preview.test.tsx index 07ec9a4b..479da0ae 100644 --- a/tests/preview.test.tsx +++ b/tests/preview.test.tsx @@ -768,6 +768,25 @@ describe('Preview', () => { ); }); + it('pass img common props to previewed image', () => { + const { container } = render( + , + ); + + fireEvent.click(container.querySelector('.rc-image')); + act(() => { + jest.runAllTimers(); + }); + + expect(document.querySelector('.rc-image-preview-img')).toHaveAttribute( + 'referrerPolicy', + 'no-referrer', + ); + }); + it('toolbarRender', () => { const { container } = render( { transform: 'translate3d(0px, 0px, 0) scale3d(1, 1, 1) rotate(0deg)', }); }); + + it('pass img common props to previewed image', () => { + const { container } = render( + + + + , + ); + + fireEvent.click(container.querySelector('.rc-image')); + act(() => { + jest.runAllTimers(); + }); + + expect(document.querySelector('.rc-image-preview-img')).toHaveAttribute('referrerPolicy', 'no-referrer'); + + fireEvent.click(document.querySelector('.rc-image-preview-switch-right')); + act(() => { + jest.runAllTimers(); + }); + + expect(document.querySelector('.rc-image-preview-img')).toHaveAttribute('referrerPolicy', 'origin'); + }); });