diff --git a/example/storybook-nativewind/src/components/ImageViewer/ImageViewer.tsx b/example/storybook-nativewind/src/components/ImageViewer/ImageViewer.tsx
index 40d2baee0..394892c95 100644
--- a/example/storybook-nativewind/src/components/ImageViewer/ImageViewer.tsx
+++ b/example/storybook-nativewind/src/components/ImageViewer/ImageViewer.tsx
@@ -10,7 +10,11 @@ import {
import { Icon, CloseIcon } from '@/components/ui/icon';
const ImageViewerBasic = ({ ...props }: any) => {
- const Images = [{ id: 1, url: 'https://picsum.photos/1000/1000' }];
+ const Images = [
+ { id: 1, url: 'https://picsum.photos/1000/1000', title: 'Image 1' },
+ { id: 2, url: 'https://picsum.photos/1000/1000', title: 'Image 2' },
+ { id: 3, url: 'https://picsum.photos/1000/1000', title: 'Image 3' },
+ ];
const [visible, setVisible] = useState(false);
return (
<>
@@ -29,14 +33,14 @@ const ImageViewerBasic = ({ ...props }: any) => {
>
(
-
+ renderImages={({ item }) => (
+
)}
+ keyExtractor={(item, index) => item.id + '-' + index}
>
-
+
diff --git a/example/storybook-nativewind/src/components/ImageViewer/index.nw.stories.mdx b/example/storybook-nativewind/src/components/ImageViewer/index.nw.stories.mdx
index 8aac1d23b..2a47bdcd0 100644
--- a/example/storybook-nativewind/src/components/ImageViewer/index.nw.stories.mdx
+++ b/example/storybook-nativewind/src/components/ImageViewer/index.nw.stories.mdx
@@ -24,7 +24,7 @@ import {
Icon,
Center,
} from '../../core-components/nativewind';
-import {
+import {
Pressable,
Image
} from 'react-native';
@@ -60,23 +60,29 @@ This is an illustration of **ImageViewer** component.
const Images = [{ id: 1, url: 'https://picsum.photos/1000/1000' }];
return (
- setVisible(true)}>
-
-
- setVisible(false)}>
-
- ()} >
-
-
-
-
-
-
-
+ setVisible(true)}>
+
+
+ setVisible(false)}>
+
+ (
+
+ )}
+ keyExtractor={(item, index) => item.id + '-' + index}
+ >
+
+
+
+
+
+
+
);
}
`,
@@ -306,6 +312,27 @@ The `ImageViewerContent` component is responsible for rendering the images withi
Yes
+
+
+
+ keyExtractor
+
+
+
+
+ (item: any, index: number) => string
+
+
+
+ -
+
+
+ Function to extract the key for each image item
+
+
+ Yes
+
+
@@ -350,23 +377,29 @@ import { Center } from '@/components/ui/center';
const Images = [{ id: 1, url: 'https://picsum.photos/1000/1000' }];
return (
- setVisible(true)}>
-
-
- setVisible(false)}>
-
- ()} >
-
-
-
-
-
-
-
+ setVisible(true)}>
+
+
+ setVisible(false)}>
+
+ (
+
+ )}
+ keyExtractor={(item, index) => item.id + '-' + index}
+ >
+
+
+
+
+
+
+
);
}
`,
diff --git a/packages/unstyled/image-viewer/README.md b/packages/unstyled/image-viewer/README.md
index e971c9abf..f1edbcf15 100644
--- a/packages/unstyled/image-viewer/README.md
+++ b/packages/unstyled/image-viewer/README.md
@@ -70,6 +70,7 @@ export default () => (
renderImages={(item) => (
)}
+ keyExtractor={(item, index) => `${item.id}-${index}`}
/>
@@ -88,10 +89,11 @@ export default () => (
### ImageViewerContent
-| Prop | Type | Default | Description |
-| ------------ | ------------------------ | ------- | ---------------------------------- |
-| images | Array | - | Array of image objects to display |
-| renderImages | (item: any) => ReactNode | - | Function to render each image item |
+| Prop | Type | Default | Description |
+| ------------ | ------------------------------------ | ------- | ----------------------------------------------- |
+| images | Array | - | Array of image objects to display |
+| renderImages | (item: any) => ReactNode | - | Function to render each image item |
+| keyExtractor | (item: any, index: number) => string | - | Function to extract the key for each image item |
More guides on how to get started are available [here](https://ui.gluestack.io/docs/components/media-and-icons/image-viewer).
diff --git a/packages/unstyled/image-viewer/src/ImageViewer.tsx b/packages/unstyled/image-viewer/src/ImageViewer.tsx
index b2ae941e8..0de94c9c0 100644
--- a/packages/unstyled/image-viewer/src/ImageViewer.tsx
+++ b/packages/unstyled/image-viewer/src/ImageViewer.tsx
@@ -1,6 +1,6 @@
import React, { forwardRef } from 'react';
import { ImageViewerContext } from './ImageViewerContext';
-import type { ImageViewerProps } from './types';
+import type { InterfaceImageViewerProps } from './types';
const ImageViewer = (StyledRoot: any) =>
forwardRef(
@@ -10,7 +10,7 @@ const ImageViewer = (StyledRoot: any) =>
isOpen,
onClose,
...props
- }: ImageViewerProps & { children: React.ReactNode },
+ }: InterfaceImageViewerProps & { children: React.ReactNode },
ref?: any
) => {
const [scale, setScale] = React.useState(1);
diff --git a/packages/unstyled/image-viewer/src/ImageViewerContent.tsx b/packages/unstyled/image-viewer/src/ImageViewerContent.tsx
index 24ff15e8c..3d44dbe0e 100644
--- a/packages/unstyled/image-viewer/src/ImageViewerContent.tsx
+++ b/packages/unstyled/image-viewer/src/ImageViewerContent.tsx
@@ -8,7 +8,7 @@ import {
withTiming,
} from 'react-native-reanimated';
import { Dimensions, StatusBar } from 'react-native';
-import type { ImageViewerContentProps } from './types';
+import type { InterfaceImageViewerContentProps } from './types';
const { width: SCREEN_WIDTH, height: SCREEN_HEIGHT } = Dimensions.get('window');
const DOUBLE_TAP_DELAY = 300;
@@ -24,8 +24,9 @@ const ImageViewerContent = (
{
images,
renderImages,
+ keyExtractor,
children,
- }: ImageViewerContentProps & { children: React.ReactNode },
+ }: InterfaceImageViewerContentProps & { children: React.ReactNode },
ref?: any
) => {
const { onClose, setScale }: any = useContext(ImageViewerContext);
@@ -45,7 +46,7 @@ const ImageViewerContent = (
.onUpdate((event: any) => {
// Apply the new scale based on the saved scale value
const newScale = savedScale.value * event.scale;
- scale.value = Math.min(Math.max(newScale, 0.5), 3);
+ scale.value = Math.min(Math.max(newScale, 0.5), 10);
focalX.value = event.focalX;
focalY.value = event.focalY;
})
@@ -147,7 +148,7 @@ const ImageViewerContent = (
);
const animatedStyle = useAnimatedStyle(() => {
- setScale(scale.value);
+ runOnJS(setScale)(scale.value);
if (scale.value <= 1) {
}
return {
@@ -165,7 +166,16 @@ const ImageViewerContent = (
{children}
- {images.map(renderImages)}
+ {images.slice(0, 1).map((item: any, index: number) => {
+ const RenderImage = renderImages;
+ return (
+
+ );
+ })}
diff --git a/packages/unstyled/image-viewer/src/types.ts b/packages/unstyled/image-viewer/src/types.ts
index 57e5347e2..1d01468c7 100644
--- a/packages/unstyled/image-viewer/src/types.ts
+++ b/packages/unstyled/image-viewer/src/types.ts
@@ -1,27 +1,52 @@
export interface ImageViewerContext {
+ /**
+ * Callback invoked when the ImageViewer is closed.
+ */
onClose: () => void;
+ /**
+ * If true, the ImageViewer will open. Useful for controllable state behavior.
+ */
isOpen: boolean | undefined;
+ /**
+ * The current scale of the Image.
+ */
scale: number | undefined;
+ /**
+ * Callback function to set the scale of the Image to be used in backdrop for adjusting the opacity.
+ */
setScale: (scale: number) => void;
}
-export interface ImageViewerProps {
+export interface InterfaceImageViewerProps {
/**
- * If true, the modal will open. Useful for controllable state behavior.
+ * If true, the ImageViewer will open. Useful for controllable state behavior.
*/
- isOpen?: boolean;
+ isOpen: boolean;
/**
- * Callback invoked when the modal is closed.
+ * Callback invoked when the ImageViewer is closed.
*/
onClose?: any;
- /**
- * If true, the modal will be opened by default.
- */
}
-export interface ImageViewerContentProps {
- images: any;
- renderImages: (item: any) => React.ReactNode;
+export interface InterfaceImageViewerContentProps {
+ /**
+ * The images to display in the ImageViewer.
+ */
+ images: Array;
+ /**
+ * Callback React.ReactNode function to render the images.
+ */
+ renderImages: ({
+ item,
+ index,
+ }: {
+ item: any;
+ index: number;
+ }) => React.ReactNode;
+ /**
+ * Callback function to extract the key for the images.
+ */
+ keyExtractor: (item: any, index: number) => React.Attributes['key'];
}
export type IImageViewerComponentType<
@@ -31,10 +56,12 @@ export type IImageViewerComponentType<
ImageViewerBackdropProps
> = React.ForwardRefExoticComponent<
React.PropsWithoutRef &
+ InterfaceImageViewerProps &
React.RefAttributes
> & {
Content: React.ForwardRefExoticComponent<
React.PropsWithoutRef &
+ InterfaceImageViewerContentProps &
React.RefAttributes
>;
CloseButton: React.ForwardRefExoticComponent<