Skip to content

Commit

Permalink
fix: mark offscreen slides inert (fix #304)
Browse files Browse the repository at this point in the history
  • Loading branch information
igordanchenko committed Sep 12, 2024
1 parent fa09bbe commit 7af43e1
Show file tree
Hide file tree
Showing 3 changed files with 24 additions and 6 deletions.
20 changes: 15 additions & 5 deletions src/modules/Carousel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,12 @@ import {
getSlideKey,
hasSlides,
isImageSlide,
makeInertWhen,
parseLengthPercentage,
} from "../utils.js";
import { ImageSlide } from "../components/index.js";
import { useController } from "./Controller/index.js";
import { useLightboxProps, useLightboxState } from "../contexts/index.js";
import { useDocumentContext, useLightboxProps, useLightboxState } from "../contexts/index.js";
import { CLASS_FLEX_CENTER, CLASS_SLIDE_WRAPPER, MODULE_CAROUSEL } from "../consts.js";

function cssPrefix(value?: string) {
Expand All @@ -36,14 +37,23 @@ function CarouselSlide({ slide, offset }: CarouselSlideProps) {
const containerRef = React.useRef<HTMLDivElement | null>(null);

const { currentIndex } = useLightboxState();
const { slideRect, close } = useController();
const { slideRect, close, focus } = useController();
const {
render,
carousel: { imageFit, imageProps },
on: { click: onClick },
controller: { closeOnBackdropClick },
styles: { slide: style },
} = useLightboxProps();
const { getOwnerDocument } = useDocumentContext();

const offscreen = offset !== 0;

React.useEffect(() => {
if (offscreen && containerRef.current?.contains(getOwnerDocument().activeElement)) {
focus();
}
}, [offscreen, focus, getOwnerDocument]);

const renderSlide = () => {
let rendered = render.slide?.({ slide, offset, rect: slideRect });
Expand All @@ -57,7 +67,7 @@ function CarouselSlide({ slide, offset }: CarouselSlideProps) {
rect={slideRect}
imageFit={imageFit}
imageProps={imageProps}
onClick={offset === 0 ? () => onClick?.({ index: currentIndex }) : undefined}
onClick={!offscreen ? () => onClick?.({ index: currentIndex }) : undefined}
/>
);
}
Expand Down Expand Up @@ -93,10 +103,10 @@ function CarouselSlide({ slide, offset }: CarouselSlideProps) {
ref={containerRef}
className={clsx(
cssClass(cssSlidePrefix()),
offset === 0 && cssClass(cssSlidePrefix("current")),
!offscreen && cssClass(cssSlidePrefix("current")),
cssClass(CLASS_FLEX_CENTER),
)}
aria-hidden={offset !== 0}
{...makeInertWhen(offscreen)}
onClick={handleBackdropClick}
style={style}
>
Expand Down
2 changes: 1 addition & 1 deletion src/modules/Portal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ export function Portal({ children, animation, styles, className, on, portal, clo
for (let i = 0; i < elements.length; i += 1) {
const element = elements[i];
if (["TEMPLATE", "SCRIPT", "STYLE"].indexOf(element.tagName) === -1 && element !== node) {
cleanup.current.push(setAttribute(element, "inert", "true"));
cleanup.current.push(setAttribute(element, "inert", ""));
cleanup.current.push(setAttribute(element, "aria-hidden", "true"));
}
}
Expand Down
8 changes: 8 additions & 0 deletions src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -157,3 +157,11 @@ export function calculatePreload(carousel: CarouselSettings, slides: Slide[], mi
Math.max(carousel.finite ? slides.length - 1 : Math.floor(slides.length / 2), minimum),
);
}

const isReact19 = Number(React.version.split(".")[0]) >= 19;

// this hack is necessary to support the upcoming breaking change in React 19 - https://github.com/facebook/react/pull/24730
export function makeInertWhen(condition: boolean) {
const legacyValue = condition ? "" : undefined;
return { inert: isReact19 ? condition : legacyValue };
}

0 comments on commit 7af43e1

Please sign in to comment.