diff --git a/package.json b/package.json
index e85120c..39de291 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "@observation.org/react-native-components",
- "version": "1.31.0",
+ "version": "1.32.0",
"main": "src/index.ts",
"repository": "git@github.com:observation/react-native-components.git",
"author": "Observation.org",
diff --git a/src/components/Lightbox.tsx b/src/components/Lightbox.tsx
index 0b96da6..d0db34d 100644
--- a/src/components/Lightbox.tsx
+++ b/src/components/Lightbox.tsx
@@ -1,4 +1,4 @@
-import React from 'react'
+import React, { useState } from 'react'
import { SafeAreaView, StyleSheet, Text, TextStyle, TouchableOpacity, View } from 'react-native'
import ImageView from '@observation.org/react-native-image-viewing'
@@ -10,34 +10,40 @@ import font from '../styles/font'
import textStyle from '../styles/text'
import theme from '../styles/theme'
+const hitSlop = { top: 16, left: 16, bottom: 16, right: 16 }
+
const getLightboxHeaderComponent =
(numberOfPages: number, onClose: () => void) =>
- ({ imageIndex }: { imageIndex: number }) => {
- const hitSlop = { top: 16, left: 16, bottom: 16, right: 16 }
- return (
-
-
-
-
-
-
-
- onClose()} hitSlop={hitSlop}>
-
-
-
+ ({ imageIndex }: { imageIndex: number }) => (
+
+
+
+
+
-
- )
- }
+
+ onClose()} hitSlop={hitSlop}>
+
+
+
+
+
+ )
const getLightboxFooterComponent =
- (title?: string, description?: string, content?: React.ReactNode, style?: LightboxStyle) => () => (
+ (
+ title?: string,
+ description?: string,
+ content?: React.ReactNode,
+ style?: LightboxStyle,
+ onPressDelete?: () => void,
+ ) =>
+ () => (
{title && (
@@ -51,6 +57,15 @@ const getLightboxFooterComponent =
)}
{content && {content}}
+ {onPressDelete && (
+
+
+
+
+
+
+
+ )}
)
@@ -62,6 +77,7 @@ type LightboxStyle = {
type Props = {
index?: number
onClose: () => void
+ onDelete?: (imageIndex: number) => void
photos: string[]
title?: string
description?: string
@@ -69,17 +85,25 @@ type Props = {
style?: LightboxStyle
}
-const Lightbox = ({ index, onClose, photos, title, description, content, style }: Props) => (
- ({ uri: photo }))}
- imageIndex={index ?? 0}
- visible={index !== undefined}
- swipeToCloseEnabled={false}
- onRequestClose={onClose}
- HeaderComponent={getLightboxHeaderComponent(photos.length, onClose)}
- FooterComponent={getLightboxFooterComponent(title, description, content, style)}
- />
-)
+const Lightbox = ({ index, onClose, onDelete, photos, title, description, content, style }: Props) => {
+ const initialImageIndex = index ?? 0
+ const [currentImageIndex, setCurrentImageIndex] = useState()
+
+ const onPressDelete = onDelete ? () => onDelete(currentImageIndex ?? initialImageIndex) : undefined
+
+ return (
+ ({ uri: photo }))}
+ imageIndex={initialImageIndex}
+ visible={index !== undefined}
+ swipeToCloseEnabled={false}
+ onImageIndexChange={setCurrentImageIndex}
+ onRequestClose={onClose}
+ HeaderComponent={getLightboxHeaderComponent(photos.length, onClose)}
+ FooterComponent={getLightboxFooterComponent(title, description, content, style, onPressDelete)}
+ />
+ )
+}
export default Lightbox
@@ -123,4 +147,13 @@ const styles = StyleSheet.create({
...textStyle.body,
color: theme.color.white,
},
+ buttonsContainer: {
+ flexDirection: 'row',
+ marginVertical: theme.margin.large,
+ marginHorizontal: theme.margin.common,
+ },
+ buttonContainer: {
+ flex: 0.5,
+ alignItems: 'center',
+ },
})
diff --git a/src/components/__tests__/Lightbox.test.tsx b/src/components/__tests__/Lightbox.test.tsx
index 407573b..1d58f26 100644
--- a/src/components/__tests__/Lightbox.test.tsx
+++ b/src/components/__tests__/Lightbox.test.tsx
@@ -15,6 +15,15 @@ const content = Jan de Vogelaar
let onClose: () => void
+let mockOnImageIndexChange = jest.fn()
+jest.mock('@observation.org/react-native-image-viewing', () => {
+ const actualModule = jest.requireActual('@observation.org/react-native-image-viewing')
+ return (props: any) => {
+ mockOnImageIndexChange = props.onImageIndexChange as any
+ return actualModule.default(props)
+ }
+})
+
describe('Lightbox', () => {
beforeEach(() => {
onClose = jest.fn()
@@ -59,6 +68,15 @@ describe('Lightbox', () => {
expect(toJSON()).toMatchSnapshot()
})
+
+ test('With a delete button', () => {
+ const { toJSON, queryByTestId } = render(
+ {}} />,
+ )
+
+ expect(queryByTestId('delete-photo')).not.toBeNull()
+ expect(toJSON()).toMatchSnapshot()
+ })
})
describe('Interaction', () => {
@@ -70,7 +88,34 @@ describe('Lightbox', () => {
await fireEvent.press(getByTestId('close-lightbox'))
// THEN
- expect(onClose).toBeCalled()
+ expect(onClose).toHaveBeenCalled()
+ })
+
+ test('Press delete button calls onDelete', async () => {
+ // GIVEN
+ const onDelete = jest.fn()
+ const { getByTestId } = render()
+
+ // WHEN
+ await fireEvent.press(getByTestId('delete-photo'))
+
+ // THEN
+ expect(onDelete).toHaveBeenCalledWith(0)
+ })
+
+ test('When swiping to the second photo and pressing the delete button, onDelete is called with the second photo', async () => {
+ // GIVEN
+ jest.mock('@observation.org/react-native-image-viewing', () => 'ImageCarousel')
+
+ const onDelete = jest.fn()
+ const { getByTestId } = render()
+
+ // WHEN
+ mockOnImageIndexChange(1)
+ await fireEvent.press(getByTestId('delete-photo'))
+
+ // THEN
+ expect(onDelete).toHaveBeenCalledWith(1)
})
})
})
diff --git a/src/components/__tests__/__snapshots__/Lightbox.test.tsx.snap b/src/components/__tests__/__snapshots__/Lightbox.test.tsx.snap
index 4beea4c..e9939df 100644
--- a/src/components/__tests__/__snapshots__/Lightbox.test.tsx.snap
+++ b/src/components/__tests__/__snapshots__/Lightbox.test.tsx.snap
@@ -1598,3 +1598,434 @@ exports[`Lightbox Rendering Second photo 1`] = `
`;
+
+exports[`Lightbox Rendering With a delete button 1`] = `
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+`;