Skip to content

Commit

Permalink
fix: pass img common props to preview img (#247)
Browse files Browse the repository at this point in the history
* fix: pass img common props to preview img

* test: add test case
  • Loading branch information
linxianxi authored Jun 7, 2023
1 parent 717d34b commit caf5ebc
Show file tree
Hide file tree
Showing 5 changed files with 117 additions and 68 deletions.
60 changes: 33 additions & 27 deletions src/Image.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,18 @@ const ImageInternal: CompoundedComponent<ImageProps> = ({

const isLoaded = React.useRef(false);

const imgCommonProps = {
crossOrigin,
decoding,
draggable,
loading,
referrerPolicy,
sizes,
srcSet,
useMap,
alt,
};

const onLoad = () => {
setStatus('normal');
};
Expand Down Expand Up @@ -189,14 +201,18 @@ const ImageInternal: CompoundedComponent<ImageProps> = ({
// 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(() => {
Expand All @@ -213,29 +229,6 @@ const ImageInternal: CompoundedComponent<ImageProps> = ({
});

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 (
<>
Expand All @@ -251,10 +244,22 @@ const ImageInternal: CompoundedComponent<ImageProps> = ({
>
<img
{...imgCommonProps}
className={cn(
`${prefixCls}-img`,
{
[`${prefixCls}-img-placeholder`]: placeholder === true,
},
className,
)}
style={{
height,
...style,
}}
ref={getImgRef}
{...(isError && fallback ? { src: fallback } : { onLoad, src: imgSrc })}
width={width}
height={height}
onError={onError}
/>

{status === 'loading' && (
Expand All @@ -268,7 +273,7 @@ const ImageInternal: CompoundedComponent<ImageProps> = ({
<div
className={cn(`${prefixCls}-mask`, maskClassName)}
style={{
display: imgCommonProps.style?.display === 'none' ? 'none' : undefined,
display: style?.display === 'none' ? 'none' : undefined,
}}
>
{previewMask}
Expand All @@ -288,6 +293,7 @@ const ImageInternal: CompoundedComponent<ImageProps> = ({
icons={icons}
scaleStep={scaleStep}
rootClassName={rootClassName}
imgCommonProps={imgCommonProps}
toolbarRender={toolbarRender}
{...dialogProps}
/>
Expand Down
26 changes: 14 additions & 12 deletions src/Preview.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,10 @@ export type toolbarRenderType = {
};
current: number;
total: number;
}
};

export interface PreviewProps extends Omit<IDialogPropTypes, 'onClose'> {
imgCommonProps?: React.ImgHTMLAttributes<HTMLImageElement>;
onClose?: (e: React.SyntheticEvent<Element>) => void;
src?: string;
alt?: string;
Expand Down Expand Up @@ -70,6 +71,7 @@ const Preview: React.FC<PreviewProps> = props => {
scaleStep = 0.5,
transitionName = 'zoom',
maskTransitionName = 'fade',
imgCommonProps,
toolbarRender,
...restProps
} = props;
Expand All @@ -82,11 +84,10 @@ const Preview: React.FC<PreviewProps> = 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 } =
Expand Down Expand Up @@ -138,7 +139,7 @@ const Preview: React.FC<PreviewProps> = props => {
if (currentPreviewIndex > 0) {
setEnableTransition(false);
resetTransform();
setCurrent(previewUrlsKeys[currentPreviewIndex - 1]);
setCurrent(previewDataKeys[currentPreviewIndex - 1]);
}
};

Expand All @@ -148,7 +149,7 @@ const Preview: React.FC<PreviewProps> = props => {
if (currentPreviewIndex < previewGroupCount - 1) {
setEnableTransition(false);
resetTransform();
setCurrent(previewUrlsKeys[currentPreviewIndex + 1]);
setCurrent(previewDataKeys[currentPreviewIndex + 1]);
}
};

Expand Down Expand Up @@ -225,18 +226,18 @@ const Preview: React.FC<PreviewProps> = 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,
Expand Down Expand Up @@ -302,14 +303,15 @@ const Preview: React.FC<PreviewProps> = props => {
>
<div className={`${prefixCls}-img-wrapper`}>
<img
{...imgCommonProps}
width={props.width}
height={props.height}
onWheel={onWheel}
onMouseDown={onMouseDown}
onDoubleClick={onDoubleClick}
ref={imgRef}
className={`${prefixCls}-img`}
src={combinationSrc}
src={src}
alt={alt}
style={{
transform: `translate3d(${transform.x}px, ${transform.y}px, 0) scale3d(${
Expand Down
57 changes: 28 additions & 29 deletions src/PreviewGroup.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,27 +24,28 @@ export interface GroupConsumerProps {
children?: React.ReactNode;
}

interface PreviewUrl {
url: string;
interface PreviewData {
src: string;
imgCommonProps: React.ImgHTMLAttributes<HTMLImageElement>;
canPreview: boolean;
}

export interface GroupConsumerValue extends GroupConsumerProps {
isPreviewGroup?: boolean;
previewUrls: Map<number, string>;
setPreviewUrls: React.Dispatch<React.SetStateAction<Map<number, PreviewUrl>>>;
previewData: Map<number, PreviewData>;
setPreviewData: React.Dispatch<React.SetStateAction<Map<number, PreviewData>>>;
current: number;
setCurrent: React.Dispatch<React.SetStateAction<number>>;
setShowPreview: React.Dispatch<React.SetStateAction<boolean>>;
setMousePosition: React.Dispatch<React.SetStateAction<null | { x: number; y: number }>>;
registerImage: (id: number, url: string, canPreview?: boolean) => () => void;
registerImage: (id: number, data: PreviewData) => () => void;
rootClassName?: string;
}

/* istanbul ignore next */
export const context = React.createContext<GroupConsumerValue>({
previewUrls: new Map(),
setPreviewUrls: () => null,
previewData: new Map(),
setPreviewData: () => null,
current: null,
setCurrent: () => null,
setShowPreview: () => null,
Expand Down Expand Up @@ -78,49 +79,44 @@ const Group: React.FC<GroupConsumerProps> = ({
toolbarRender = undefined,
...dialogProps
} = typeof preview === 'object' ? preview : {};
const [previewUrls, setPreviewUrls] = useState<Map<number, PreviewUrl>>(new Map());
const previewUrlsKeys = Array.from(previewUrls.keys());
const [previewData, setPreviewData] = useState<Map<number, PreviewData>>(new Map());
const previewDataKeys = Array.from(previewData.keys());
const prevCurrent = React.useRef<number | undefined>();
const [current, setCurrent] = useMergedState<number>(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;
},
});
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;
},
});

const [mousePosition, setMousePosition] = useState<null | { x: number; y: number }>(null);
const isControlled = previewVisible !== undefined;

const currentControlledKey = previewUrlsKeys[currentIndex];
const canPreviewUrls = new Map<number, string>(
Array.from(previewUrls)
.filter(([, { canPreview }]) => !!canPreview)
.map(([id, { url }]) => [id, url]),
const currentControlledKey = previewDataKeys[currentIndex];
const canPreviewData = new Map<number, PreviewData>(
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;
Expand All @@ -142,12 +138,14 @@ const Group: React.FC<GroupConsumerProps> = ({
}
}, [currentControlledKey, isControlled, isShowPreview]);

const canPreviewCurrentData = canPreviewData.get(current);

return (
<Provider
value={{
isPreviewGroup: true,
previewUrls: canPreviewUrls,
setPreviewUrls,
previewData: canPreviewData,
setPreviewData,
current,
setCurrent,
setShowPreview,
Expand All @@ -162,7 +160,8 @@ const Group: React.FC<GroupConsumerProps> = ({
prefixCls={previewPrefixCls}
onClose={onPreviewClose}
mousePosition={mousePosition}
src={canPreviewUrls.get(current)}
imgCommonProps={canPreviewCurrentData?.imgCommonProps}
src={canPreviewCurrentData?.src}
icons={icons}
getContainer={getContainer}
countRender={countRender}
Expand Down
19 changes: 19 additions & 0 deletions tests/preview.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -768,6 +768,25 @@ describe('Preview', () => {
);
});

it('pass img common props to previewed image', () => {
const { container } = render(
<Image
src="https://zos.alipayobjects.com/rmsportal/jkjgkEfvpUPVyRjUImniVslZfWPnJuuZ.png"
referrerPolicy="no-referrer"
/>,
);

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(
<Image
Expand Down
23 changes: 23 additions & 0 deletions tests/previewGroup.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -216,4 +216,27 @@ describe('PreviewGroup', () => {
transform: 'translate3d(0px, 0px, 0) scale3d(1, 1, 1) rotate(0deg)',
});
});

it('pass img common props to previewed image', () => {
const { container } = render(
<Image.PreviewGroup>
<Image src="src1" referrerPolicy='no-referrer' />
<Image src="src2" referrerPolicy='origin' />
</Image.PreviewGroup>,
);

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');
});
});

1 comment on commit caf5ebc

@vercel
Copy link

@vercel vercel bot commented on caf5ebc Jun 7, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.