Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: support PreviewGroup#items locating when clicking image #344

Merged
merged 5 commits into from
May 15, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions docs/demo/previewgroup-items.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
title: previewGroupItems
nav:
title: Demo
path: /demo
---

<code src="../examples/previewgroup-items.tsx"></code>
4 changes: 3 additions & 1 deletion docs/examples/controlledWithGroup.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { defaultIcons } from './common';

export default function Base() {
const [visible, setVisible] = React.useState(false);
const [current, setCurrent] = React.useState(1);
return (
<div>
<div>
Expand All @@ -25,7 +26,8 @@ export default function Base() {
onVisibleChange: value => {
setVisible(value);
},
current: 1,
current,
onChange: c => setCurrent(c),
}}
>
<Image
Expand Down
20 changes: 20 additions & 0 deletions docs/examples/previewgroup-items.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import Image from 'rc-image';
import * as React from 'react';
import '../../assets/index.less';

export default function Base() {
return (
<Image.PreviewGroup
items={[
'https://gw.alipayobjects.com/zos/antfincdn/aPkFc8Sj7n/method-draw-image.svg',
'https://gw.alipayobjects.com/zos/rmsportal/KDpgvguMpGfqaHPjicRK.svg',
'https://zos.alipayobjects.com/rmsportal/jkjgkEfvpUPVyRjUImniVslZfWPnJuuZ.png',
]}
>
<Image
width={200}
src="https://zos.alipayobjects.com/rmsportal/jkjgkEfvpUPVyRjUImniVslZfWPnJuuZ.png"
/>
</Image.PreviewGroup>
);
}
2 changes: 1 addition & 1 deletion src/Image.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,7 @@ const ImageInternal: CompoundedComponent<ImageProps> = props => {
const onPreview: React.MouseEventHandler<HTMLDivElement> = e => {
const { left, top } = getOffset(e.target);
if (groupContext) {
groupContext.onPreview(imageId, left, top);
groupContext.onPreview(imageId, src, left, top);
} else {
setMousePosition({
x: left,
Expand Down
14 changes: 9 additions & 5 deletions src/PreviewGroup.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ const Group: React.FC<GroupConsumerProps> = ({
} = typeof preview === 'object' ? preview : ({} as PreviewGroupPreview);

// ========================== Items ===========================
const [mergedItems, register] = usePreviewItems(items);
const [mergedItems, register, from] = usePreviewItems(items);
vagusX marked this conversation as resolved.
Show resolved Hide resolved

// ========================= Preview ==========================
// >>> Index
Expand All @@ -91,15 +91,19 @@ const Group: React.FC<GroupConsumerProps> = ({
const [mousePosition, setMousePosition] = useState<null | { x: number; y: number }>(null);

const onPreviewFromImage = React.useCallback<OnGroupPreview>(
(id, mouseX, mouseY) => {
const index = mergedItems.findIndex(item => item.id === id);
(id, imageSrc, mouseX, mouseY) => {
const index = from === 'context'
? mergedItems.findIndex(item => item.id === id)
: mergedItems.findIndex(item => typeof item === 'string' ? item === imageSrc : item.data.src === imageSrc);

setCurrent(index < 0 ? 0 : index);

setShowPreview(true);
setMousePosition({ x: mouseX, y: mouseY });
setCurrent(index < 0 ? 0 : index);

setKeepOpenIndex(true);
},
[mergedItems],
[mergedItems, items?.length],
vagusX marked this conversation as resolved.
Show resolved Hide resolved
);

// Reset current when reopen
Expand Down
12 changes: 10 additions & 2 deletions src/hooks/usePreviewItems.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import type {
ImageElementProps,
InternalItem,
PreviewImageElementProps,
PreviewItemsFrom,
RegisterImage,
} from '../interface';

Expand All @@ -15,7 +16,7 @@ export type Items = Omit<InternalItem, 'canPreview'>[];
*/
export default function usePreviewItems(
items?: GroupConsumerProps['items'],
): [items: Items, registerImage: RegisterImage] {
): [items: Items, registerImage: RegisterImage, from: PreviewItemsFrom] {
// Context collection image data
const [images, setImages] = React.useState<Record<number, PreviewImageElementProps>>({});

Expand All @@ -36,6 +37,7 @@ export default function usePreviewItems(

// items
const mergedItems = React.useMemo<Items>(() => {
// use `items` first
if (items) {
return items.map(item => {
if (typeof item === 'string') {
Expand All @@ -51,6 +53,7 @@ export default function usePreviewItems(
});
}

// use registered images secondly
return Object.keys(images).reduce((total: Items, id) => {
const { canPreview, data } = images[id];
if (canPreview) {
Expand All @@ -60,5 +63,10 @@ export default function usePreviewItems(
}, []);
}, [items, images]);

return [mergedItems, registerImage];
// from
const from = React.useMemo<PreviewItemsFrom>(() => {
return items ? 'items' : 'context';
}, [items]);

return [mergedItems, registerImage, from];
}
4 changes: 3 additions & 1 deletion src/interface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,6 @@ export type InternalItem = PreviewImageElementProps & {

export type RegisterImage = (id: string, data: PreviewImageElementProps) => VoidFunction;

export type OnGroupPreview = (id: string, mouseX: number, mouseY: number) => void;
export type OnGroupPreview = (id: string, imageSrc: string, mouseX: number, mouseY: number) => void;

export type PreviewItemsFrom = 'items' | 'context';
22 changes: 22 additions & 0 deletions tests/previewGroup.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,28 @@ describe('PreviewGroup', () => {
expect(onChange).toHaveBeenCalledWith(2, 1);
});

it('default current should works', () => {
const { rerender } = render(
<Image.PreviewGroup items={['src1', 'src2', 'src3']}>
<Image src="src2" className="first-img" />
</Image.PreviewGroup>,
);

fireEvent.click(document.querySelector('.first-img'));

expect(document.querySelector('.rc-image-preview-img')).toHaveAttribute('src', 'src2');

rerender(
<Image.PreviewGroup items={['src1', 'src2', 'src3']}>
<Image src="src3" className="first-img" />
</Image.PreviewGroup>,
);

fireEvent.click(document.querySelector('.first-img'));

expect(document.querySelector('.rc-image-preview-img')).toHaveAttribute('src', 'src3');
});

it('Mount and UnMount', () => {
const { container, unmount } = render(
<Image.PreviewGroup>
Expand Down