Skip to content

Commit

Permalink
Add rotate icon and crop button in Lightbox (#48)
Browse files Browse the repository at this point in the history
  • Loading branch information
jonathan-waarneming-nl authored Jul 2, 2024
1 parent 4620299 commit a2415a2
Show file tree
Hide file tree
Showing 5 changed files with 477 additions and 9 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@observation.org/react-native-components",
"version": "1.38.0",
"version": "1.39.0",
"main": "src/index.ts",
"repository": "[email protected]:observation/react-native-components.git",
"author": "Observation.org",
Expand Down
28 changes: 20 additions & 8 deletions src/components/Lightbox.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ const getLightboxFooterComponent =
content?: React.ReactNode,
style?: LightboxStyle,
onPressDelete?: () => void,
onPressCrop?: () => void,
) =>
() => (
<SafeAreaView style={styles.lightboxFooterContainer}>
Expand All @@ -57,13 +58,22 @@ const getLightboxFooterComponent =
</View>
)}
{content && <View style={styles.footerItem}>{content}</View>}
{onPressDelete && (
{(onPressDelete || onPressCrop) && (
<View style={styles.buttonsContainer}>
<View style={styles.buttonContainer}>
<TouchableOpacity onPress={onPressDelete} hitSlop={hitSlop}>
<Icon name="trash-alt" color={theme.color.white} size={20} testID="delete-photo" />
</TouchableOpacity>
</View>
{onPressDelete && (
<View style={styles.buttonContainer}>
<TouchableOpacity onPress={onPressDelete} hitSlop={hitSlop}>
<Icon name="trash-alt" color={theme.color.white} size={20} testID="delete-photo" />
</TouchableOpacity>
</View>
)}
{onPressCrop && (
<View style={styles.buttonContainer}>
<TouchableOpacity onPress={onPressCrop} hitSlop={hitSlop}>
<Icon name="crop-alt" color={theme.color.white} size={20} testID="crop-photo" />
</TouchableOpacity>
</View>
)}
</View>
)}
</View>
Expand All @@ -78,18 +88,20 @@ type Props = {
index?: number
onClose: () => void
onDelete?: (imageIndex: number) => void
onCrop?: (imageIndex: number) => void
photos: string[]
title?: string
description?: string
content?: JSX.Element
style?: LightboxStyle
}

const Lightbox = ({ index, onClose, onDelete, photos, title, description, content, style }: Props) => {
const Lightbox = ({ index, onClose, onDelete, onCrop, photos, title, description, content, style }: Props) => {
const initialImageIndex = index ?? 0
const [currentImageIndex, setCurrentImageIndex] = useState<number>()

const onPressDelete = onDelete ? () => onDelete(currentImageIndex ?? initialImageIndex) : undefined
const onPressCrop = onCrop ? () => onCrop(currentImageIndex ?? initialImageIndex) : undefined

return (
<ImageView
Expand All @@ -100,7 +112,7 @@ const Lightbox = ({ index, onClose, onDelete, photos, title, description, conten
onImageIndexChange={setCurrentImageIndex}
onRequestClose={onClose}
HeaderComponent={getLightboxHeaderComponent(photos.length, onClose)}
FooterComponent={getLightboxFooterComponent(title, description, content, style, onPressDelete)}
FooterComponent={getLightboxFooterComponent(title, description, content, style, onPressDelete, onPressCrop)}
/>
)
}
Expand Down
21 changes: 21 additions & 0 deletions src/components/__tests__/Lightbox.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,15 @@ describe('Lightbox', () => {
expect(queryByTestId('delete-photo')).not.toBeNull()
expect(toJSON()).toMatchSnapshot()
})

test('With a crop button', () => {
const { toJSON, queryByTestId } = render(
<Lightbox photos={photos} index={0} onClose={onClose} onCrop={() => {}} />,
)

expect(queryByTestId('crop-photo')).not.toBeNull()
expect(toJSON()).toMatchSnapshot()
})
})

describe('Interaction', () => {
Expand All @@ -103,6 +112,18 @@ describe('Lightbox', () => {
expect(onDelete).toHaveBeenCalledWith(0)
})

test('Press crop button calls onCrop', async () => {
// GIVEN
const onCrop = jest.fn()
const { getByTestId } = render(<Lightbox photos={photos} index={0} onClose={onClose} onCrop={onCrop} />)

// WHEN
await fireEvent.press(getByTestId('crop-photo'))

// THEN
expect(onCrop).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')
Expand Down
Loading

0 comments on commit a2415a2

Please sign in to comment.