diff --git a/README.md b/README.md index 8a710a4..f1c665e 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ Lightweight React lightbox component. This is a trimmed-down version of the [yet-another-react-lightbox](https://github.com/igordanchenko/yet-another-react-lightbox) -that provides essential lightbox features and slick UX with just 4.4KB bundle +that provides essential lightbox features and slick UX with just 4.6KB bundle size. ## Overview diff --git a/src/components/Carousel.tsx b/src/components/Carousel.tsx index 1ee432d..44f9516 100644 --- a/src/components/Carousel.tsx +++ b/src/components/Carousel.tsx @@ -1,19 +1,52 @@ +import { useEffect, useRef } from "react"; + +import ImageSlide from "./ImageSlide"; import { useZoom, useZoomInternal } from "./Zoom"; import { useLightboxContext } from "./LightboxContext"; -import ImageSlide from "./ImageSlide"; import { cssClass, isImageSlide, round } from "../utils"; -import { SlideImage } from "../types"; +import { RenderSlideProps, SlideImage } from "../types"; + +function CarouselSlide({ slide, rect, current }: Pick) { + const ref = useRef(null); + + const { zoom, offsetX, offsetY } = useZoom(); + const { styles, render: { slide: renderSlide, slideHeader, slideFooter } = {} } = useLightboxContext(); + + useEffect(() => { + if (!current && ref.current?.contains(document.activeElement)) { + ref.current.closest('[tabindex="-1"]')?.focus(); + } + }, [current]); + + const context = { slide, rect, current, zoom: round(current ? zoom : 1, 3) }; + + return ( + + ); +} export default function Carousel() { - const { - slides, - index, - styles, - carousel: { preload = 2 } = {}, - render: { slide: renderSlide, slideHeader, slideFooter } = {}, - } = useLightboxContext(); - const { rect, zoom, offsetX, offsetY } = useZoom(); + const { slides, index, styles, carousel: { preload = 2 } = {} } = useLightboxContext(); const { setCarouselRef } = useZoomInternal(); + const { rect } = useZoom(); return (
@@ -24,29 +57,14 @@ export default function Carousel() { if (slideIndex < 0 || slideIndex >= slides.length) return null; const slide = slides[slideIndex]; - const current = slideIndex === index; - const context = { slide, rect, current, zoom: round(current ? zoom : 1, 3) }; return ( - + ); })}
diff --git a/test/Lightbox.spec.tsx b/test/Lightbox.spec.tsx index 32d2df4..a6c75b0 100644 --- a/test/Lightbox.spec.tsx +++ b/test/Lightbox.spec.tsx @@ -12,6 +12,7 @@ import { expectToBeZoomedIn, expectToBeZoomedOut, getCloseButton, + getController, getCurrentSlide, getCurrentSlideImage, getNextButton, @@ -438,4 +439,20 @@ describe("Lightbox", () => { renderLightbox({ carousel: { preload: 0 } }); expect(getSlidesCount()).toBe(1); }); + + it("transfers focus from offscreen slides", () => { + const { getByTestId } = renderLightbox({ + slides: [{ type: "custom-slide" }, ...slides], + render: { + slide: ({ slide }) => (slide.type === "custom-slide" ? : undefined), + }, + }); + + const target = getByTestId("custom-slide-input"); + target.focus(); + expect(document.activeElement).toBe(target); + + clickButtonNext(); + expect(document.activeElement).toBe(getController()); + }); });