diff --git a/packages/components/src/LightBox/LightBox.pom.tsx b/packages/components/src/LightBox/LightBox.pom.tsx new file mode 100644 index 0000000000..58e58d92e3 --- /dev/null +++ b/packages/components/src/LightBox/LightBox.pom.tsx @@ -0,0 +1,23 @@ +import { screen, within } from "@testing-library/react"; + +export function getCloseButton(): HTMLElement { + return screen.getByLabelText("Close"); +} + +export function getNextButton(): HTMLElement | null { + return screen.queryByLabelText("Next image"); +} + +export function getPreviousButton(): HTMLElement | null { + return screen.queryByLabelText("Previous image"); +} + +export function getThumbnailBar(): HTMLElement | null { + return screen.queryByTestId("ATL-Thumbnail-Bar"); +} + +export function getThumbnailByAlt(alt: string): HTMLElement { + const thumbnailBar = screen.getByTestId("ATL-Thumbnail-Bar"); + + return within(thumbnailBar).getByAltText(alt); +} diff --git a/packages/components/src/LightBox/LightBox.test.tsx b/packages/components/src/LightBox/LightBox.test.tsx index feda829fad..82c01ded1d 100644 --- a/packages/components/src/LightBox/LightBox.test.tsx +++ b/packages/components/src/LightBox/LightBox.test.tsx @@ -2,6 +2,8 @@ import React from "react"; import { fireEvent, render, screen } from "@testing-library/react"; import { BREAKPOINT_SIZES, mockViewportWidth } from "@jobber/hooks"; import { LightBox } from "."; +import { slideVariants } from "./LightBox"; +import * as POM from "./LightBox.pom"; const { setViewportWidth } = mockViewportWidth(); @@ -67,7 +69,7 @@ describe("LightBox", () => { expect(handleClose).toHaveBeenCalledTimes(1); }); - const { getByLabelText } = render( + render( { />, ); - fireEvent.click(getByLabelText("Close")); + fireEvent.click(POM.getCloseButton()); }); test("displays the image title of the selected imageIndex", () => { @@ -123,7 +125,7 @@ describe("LightBox", () => { { title: "title", caption: "caption", - url: "", + url: "https://example.com/photo.jpg", }, ], onRequestClose: jest.fn(), @@ -164,8 +166,8 @@ describe("LightBox", () => { onRequestClose={jest.fn()} />, ); - expect(screen.queryByLabelText("Previous image")).toBeInTheDocument(); - expect(screen.queryByLabelText("Next image")).toBeInTheDocument(); + expect(POM.getPreviousButton()).toBeInTheDocument(); + expect(POM.getNextButton()).toBeInTheDocument(); }); test("doesn't display the next and previous buttons when only one image", () => { @@ -183,8 +185,26 @@ describe("LightBox", () => { onRequestClose={jest.fn()} />, ); - expect(screen.queryByLabelText("Previous image")).toBeNull(); - expect(screen.queryByLabelText("Next image")).toBeNull(); + expect(POM.getPreviousButton()).toBeNull(); + expect(POM.getNextButton()).toBeNull(); + }); + }); + + describe("slideVariants", () => { + it("enter slides in from the right when direction is forward", () => { + expect(slideVariants.enter({ current: 1 })).toEqual({ x: "150%" }); + }); + + it("enter slides in from the left when direction is backward", () => { + expect(slideVariants.enter({ current: -1 })).toEqual({ x: "-150%" }); + }); + + it("exit slides out to the left when direction is forward", () => { + expect(slideVariants.exit({ current: 1 })).toEqual({ x: "-150%" }); + }); + + it("exit slides out to the right when direction is backward", () => { + expect(slideVariants.exit({ current: -1 })).toEqual({ x: "150%" }); }); }); @@ -216,7 +236,7 @@ describe("LightBox", () => { expect( screen.queryByAltText("alt of unselected image"), ).toBeInTheDocument(); - expect(screen.queryByTestId("ATL-Thumbnail-Bar")).toBeInTheDocument(); + expect(POM.getThumbnailBar()).toBeInTheDocument(); }); test("doesn't display when there is only one image", () => { @@ -236,7 +256,7 @@ describe("LightBox", () => { onRequestClose={handleClose} />, ); - expect(screen.queryByTestId("thumbnail-bar")).not.toBeInTheDocument(); + expect(POM.getThumbnailBar()).not.toBeInTheDocument(); }); test("displays the selected image thumbnail and caption when imageclicked", () => { @@ -269,8 +289,7 @@ describe("LightBox", () => { screen.queryByText(destinationImageCaption), ).not.toBeInTheDocument(); - const destinationImage = screen.getByAltText(destinationImageAlt); - fireEvent.click(destinationImage); + fireEvent.click(POM.getThumbnailByAlt(destinationImageAlt)); const imagesWithAlt = screen.getAllByAltText(destinationImageAlt); expect(imagesWithAlt).toHaveLength(2); diff --git a/packages/components/src/LightBox/LightBox.tsx b/packages/components/src/LightBox/LightBox.tsx index 56fbeb45aa..9f4573b485 100644 --- a/packages/components/src/LightBox/LightBox.tsx +++ b/packages/components/src/LightBox/LightBox.tsx @@ -71,20 +71,16 @@ const swipePower = (offset: number, velocity: number) => { return Math.abs(offset) * velocity; }; -const variants = { - enter: (direction: number) => { - return { - x: direction > 0 ? "150%" : "-150%", - }; - }, +export const slideVariants = { + enter: (directionRef: React.RefObject) => ({ + x: directionRef.current > 0 ? "150%" : "-150%", + }), center: { x: 0, }, - exit: (direction: number) => { - return { - x: direction < 0 ? "150%" : "-150%", - }; - }, + exit: (directionRef: React.RefObject) => ({ + x: directionRef.current < 0 ? "150%" : "-150%", + }), }; const imageTransition = { @@ -105,7 +101,7 @@ export function LightBox({ onRequestClose, }: LightBoxProps) { const [currentImageIndex, setCurrentImageIndex] = useState(imageIndex); - const [direction, setDirection] = useState(0); + const directionRef = useRef(0); const [mouseIsStationary, setMouseIsStationary] = useState(true); const lightboxRef = useFocusTrap(open); const selectedThumbnailRef = useRef(null); @@ -192,9 +188,9 @@ export function LightBox({