/* Copyright 2026 Marimo. All rights reserved. */ import React, { type JSX, type PropsWithChildren, useEffect } from "react"; import { Keyboard, Navigation, Pagination, Virtual, Zoom, } from "swiper/modules"; import { Swiper, type SwiperRef, SwiperSlide } from "swiper/react"; import { Button } from "@/components/ui/button"; import { useEventListener } from "@/hooks/useEventListener"; import { useIframeCapabilities } from "@/hooks/useIframeCapabilities"; import { cn } from "@/utils/cn"; import "./swiper-slides.css"; import "./slides.css"; interface SlidesComponentProps { className?: string; forceKeyboardNavigation?: boolean; index?: string | null; height?: string | number | null; wrapAround?: boolean; activeIndex?: number | null; onActiveIndexChange?: (index: number) => void; } const SlidesComponent = ({ className, children, height, forceKeyboardNavigation = false, wrapAround = false, activeIndex, onActiveIndexChange, }: PropsWithChildren): JSX.Element => { const el = React.useRef(null); const [isFullscreen, setIsFullscreen] = React.useState(false); const { hasFullscreen } = useIframeCapabilities(); useEffect(() => { if (activeIndex != null && el.current?.swiper.realIndex !== activeIndex) { if (wrapAround) { el.current?.swiper.slideToLoop(activeIndex); } else { el.current?.swiper.slideTo(activeIndex); } } }, [activeIndex, wrapAround]); useEventListener(document, "fullscreenchange", () => { if (document.fullscreenElement) { el.current?.swiper.keyboard.enable(); } else { el.current?.swiper.keyboard.disable(); } setIsFullscreen(!!document.fullscreenElement); }); useEffect(() => { requestAnimationFrame(() => { window.dispatchEvent(new Event("resize")); }); }, [isFullscreen]); const modules = wrapAround // virtual is incompatible with loop ? [Keyboard, Pagination, Zoom, Navigation] : [Virtual, Keyboard, Pagination, Zoom, Navigation]; return ( onActiveIndexChange?.(swiper.realIndex)} > {React.Children.map(children, (child, index) => { if (child == null) { return null; } return (
{ // If the target is from a marimo element, stop propagation if ( e.target instanceof HTMLElement && e.target.tagName.toLocaleLowerCase().startsWith("marimo-") ) { e.stopPropagation(); } }} className={cn( "h-full w-full flex box-border overflow-y-auto overflow-x-hidden", isFullscreen ? "p-20" : "p-6 pb-12", )} >
{child}
); })} {hasFullscreen && ( )}
); }; export default SlidesComponent;