From d2fabfe8299fe5270290a8a183b457c6a5896e32 Mon Sep 17 00:00:00 2001 From: vagusx Date: Wed, 15 May 2024 10:38:00 +0800 Subject: [PATCH 1/5] fix: support PreviewGroup#items locating when clicking image --- docs/demo/previewgroup-items.md | 8 ++++++++ docs/examples/controlledWithGroup.tsx | 4 +++- docs/examples/previewgroup-items.tsx | 20 ++++++++++++++++++++ src/Image.tsx | 2 +- src/PreviewGroup.tsx | 14 +++++++++----- src/hooks/usePreviewItems.ts | 12 ++++++++++-- src/interface.ts | 4 +++- tests/previewGroup.test.tsx | 22 ++++++++++++++++++++++ 8 files changed, 76 insertions(+), 10 deletions(-) create mode 100644 docs/demo/previewgroup-items.md create mode 100644 docs/examples/previewgroup-items.tsx diff --git a/docs/demo/previewgroup-items.md b/docs/demo/previewgroup-items.md new file mode 100644 index 00000000..47dbaae8 --- /dev/null +++ b/docs/demo/previewgroup-items.md @@ -0,0 +1,8 @@ +--- +title: previewGroupItems +nav: + title: Demo + path: /demo +--- + + diff --git a/docs/examples/controlledWithGroup.tsx b/docs/examples/controlledWithGroup.tsx index 2a653949..0d205f60 100644 --- a/docs/examples/controlledWithGroup.tsx +++ b/docs/examples/controlledWithGroup.tsx @@ -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 (
@@ -25,7 +26,8 @@ export default function Base() { onVisibleChange: value => { setVisible(value); }, - current: 1, + current, + onChange: c => setCurrent(c), }} > + + + ); +} diff --git a/src/Image.tsx b/src/Image.tsx index 39dc1853..56674f4f 100644 --- a/src/Image.tsx +++ b/src/Image.tsx @@ -168,7 +168,7 @@ const ImageInternal: CompoundedComponent = props => { const onPreview: React.MouseEventHandler = e => { const { left, top } = getOffset(e.target); if (groupContext) { - groupContext.onPreview(imageId, left, top); + groupContext.onPreview(imageId, src, left, top); } else { setMousePosition({ x: left, diff --git a/src/PreviewGroup.tsx b/src/PreviewGroup.tsx index 22fd7ae8..76e75a36 100644 --- a/src/PreviewGroup.tsx +++ b/src/PreviewGroup.tsx @@ -67,7 +67,7 @@ const Group: React.FC = ({ } = typeof preview === 'object' ? preview : ({} as PreviewGroupPreview); // ========================== Items =========================== - const [mergedItems, register] = usePreviewItems(items); + const [mergedItems, register, from] = usePreviewItems(items); // ========================= Preview ========================== // >>> Index @@ -91,15 +91,19 @@ const Group: React.FC = ({ const [mousePosition, setMousePosition] = useState(null); const onPreviewFromImage = React.useCallback( - (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], ); // Reset current when reopen diff --git a/src/hooks/usePreviewItems.ts b/src/hooks/usePreviewItems.ts index ac652589..eb317a62 100644 --- a/src/hooks/usePreviewItems.ts +++ b/src/hooks/usePreviewItems.ts @@ -5,6 +5,7 @@ import type { ImageElementProps, InternalItem, PreviewImageElementProps, + PreviewItemsFrom, RegisterImage, } from '../interface'; @@ -15,7 +16,7 @@ export type Items = Omit[]; */ 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>({}); @@ -36,6 +37,7 @@ export default function usePreviewItems( // items const mergedItems = React.useMemo(() => { + // use `items` first if (items) { return items.map(item => { if (typeof item === 'string') { @@ -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) { @@ -60,5 +63,10 @@ export default function usePreviewItems( }, []); }, [items, images]); - return [mergedItems, registerImage]; + // from + const from = React.useMemo(() => { + return items ? 'items' : 'context'; + }, [items]); + + return [mergedItems, registerImage, from]; } diff --git a/src/interface.ts b/src/interface.ts index d5ff43d4..a0efc295 100644 --- a/src/interface.ts +++ b/src/interface.ts @@ -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'; diff --git a/tests/previewGroup.test.tsx b/tests/previewGroup.test.tsx index 38226802..1936e6eb 100644 --- a/tests/previewGroup.test.tsx +++ b/tests/previewGroup.test.tsx @@ -44,6 +44,28 @@ describe('PreviewGroup', () => { expect(onChange).toHaveBeenCalledWith(2, 1); }); + it('default current should works', () => { + const { rerender } = render( + + + , + ); + + fireEvent.click(document.querySelector('.first-img')); + + expect(document.querySelector('.rc-image-preview-img')).toHaveAttribute('src', 'src2'); + + rerender( + + + , + ); + + fireEvent.click(document.querySelector('.first-img')); + + expect(document.querySelector('.rc-image-preview-img')).toHaveAttribute('src', 'src3'); + }); + it('Mount and UnMount', () => { const { container, unmount } = render( From 7907e2531a60cfe77dd27a3489dc335622ee45eb Mon Sep 17 00:00:00 2001 From: vagusx Date: Wed, 15 May 2024 11:15:21 +0800 Subject: [PATCH 2/5] fix: use fromItems boolean --- src/PreviewGroup.tsx | 8 ++++---- src/hooks/usePreviewItems.ts | 10 ++-------- src/interface.ts | 2 -- tests/previewGroup.test.tsx | 2 +- 4 files changed, 7 insertions(+), 15 deletions(-) diff --git a/src/PreviewGroup.tsx b/src/PreviewGroup.tsx index 76e75a36..828129e3 100644 --- a/src/PreviewGroup.tsx +++ b/src/PreviewGroup.tsx @@ -67,7 +67,7 @@ const Group: React.FC = ({ } = typeof preview === 'object' ? preview : ({} as PreviewGroupPreview); // ========================== Items =========================== - const [mergedItems, register, from] = usePreviewItems(items); + const [mergedItems, register, fromItems] = usePreviewItems(items); // ========================= Preview ========================== // >>> Index @@ -92,9 +92,9 @@ const Group: React.FC = ({ const onPreviewFromImage = React.useCallback( (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); + const index = fromItems + ? mergedItems.findIndex(item => typeof item === 'string' ? item === imageSrc : item.data.src === imageSrc) + : mergedItems.findIndex(item => item.id === id); setCurrent(index < 0 ? 0 : index); diff --git a/src/hooks/usePreviewItems.ts b/src/hooks/usePreviewItems.ts index eb317a62..9a33172f 100644 --- a/src/hooks/usePreviewItems.ts +++ b/src/hooks/usePreviewItems.ts @@ -5,7 +5,6 @@ import type { ImageElementProps, InternalItem, PreviewImageElementProps, - PreviewItemsFrom, RegisterImage, } from '../interface'; @@ -16,7 +15,7 @@ export type Items = Omit[]; */ export default function usePreviewItems( items?: GroupConsumerProps['items'], -): [items: Items, registerImage: RegisterImage, from: PreviewItemsFrom] { +): [items: Items, registerImage: RegisterImage, fromItems: boolean] { // Context collection image data const [images, setImages] = React.useState>({}); @@ -63,10 +62,5 @@ export default function usePreviewItems( }, []); }, [items, images]); - // from - const from = React.useMemo(() => { - return items ? 'items' : 'context'; - }, [items]); - - return [mergedItems, registerImage, from]; + return [mergedItems, registerImage, Boolean(items)]; } diff --git a/src/interface.ts b/src/interface.ts index a0efc295..42120a73 100644 --- a/src/interface.ts +++ b/src/interface.ts @@ -27,5 +27,3 @@ export type InternalItem = PreviewImageElementProps & { export type RegisterImage = (id: string, data: PreviewImageElementProps) => VoidFunction; export type OnGroupPreview = (id: string, imageSrc: string, mouseX: number, mouseY: number) => void; - -export type PreviewItemsFrom = 'items' | 'context'; diff --git a/tests/previewGroup.test.tsx b/tests/previewGroup.test.tsx index 1936e6eb..883d4c6a 100644 --- a/tests/previewGroup.test.tsx +++ b/tests/previewGroup.test.tsx @@ -44,7 +44,7 @@ describe('PreviewGroup', () => { expect(onChange).toHaveBeenCalledWith(2, 1); }); - it('default current should works', () => { + it('items should works', () => { const { rerender } = render( From 03bdb730b7a10a923effde8a5daba87dd0059097 Mon Sep 17 00:00:00 2001 From: vagusx Date: Wed, 15 May 2024 11:49:22 +0800 Subject: [PATCH 3/5] fix: types --- src/PreviewGroup.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/PreviewGroup.tsx b/src/PreviewGroup.tsx index 828129e3..39013831 100644 --- a/src/PreviewGroup.tsx +++ b/src/PreviewGroup.tsx @@ -93,7 +93,7 @@ const Group: React.FC = ({ const onPreviewFromImage = React.useCallback( (id, imageSrc, mouseX, mouseY) => { const index = fromItems - ? mergedItems.findIndex(item => typeof item === 'string' ? item === imageSrc : item.data.src === imageSrc) + ? mergedItems.findIndex(item => item.data.src === imageSrc) : mergedItems.findIndex(item => item.id === id); setCurrent(index < 0 ? 0 : index); From f11a624af61c7a9ac81989c2c4c0322ecbd6e789 Mon Sep 17 00:00:00 2001 From: vagusx Date: Wed, 15 May 2024 11:55:33 +0800 Subject: [PATCH 4/5] fix: boolean --- src/hooks/usePreviewItems.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hooks/usePreviewItems.ts b/src/hooks/usePreviewItems.ts index 9a33172f..a335eb78 100644 --- a/src/hooks/usePreviewItems.ts +++ b/src/hooks/usePreviewItems.ts @@ -62,5 +62,5 @@ export default function usePreviewItems( }, []); }, [items, images]); - return [mergedItems, registerImage, Boolean(items)]; + return [mergedItems, registerImage, !!items]; } From c46cdb3adec6ccc465a7c3d2d2a757651c61e95e Mon Sep 17 00:00:00 2001 From: vagusx Date: Wed, 15 May 2024 14:40:44 +0800 Subject: [PATCH 5/5] fix: update --- src/PreviewGroup.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/PreviewGroup.tsx b/src/PreviewGroup.tsx index 39013831..d6f647e9 100644 --- a/src/PreviewGroup.tsx +++ b/src/PreviewGroup.tsx @@ -103,7 +103,7 @@ const Group: React.FC = ({ setKeepOpenIndex(true); }, - [mergedItems, items?.length], + [mergedItems, fromItems], ); // Reset current when reopen