import React from "react"; import { useControllableState } from "@radix-ui/react-use-controllable-state"; import { styled } from "../theme"; import type * as WPDS from "../theme"; type CarouselContextProps = { page: number; setPage: (page: number) => void; totalPages?: number; setTotalPages: React.Dispatch>; itemsPerPage: number | "auto"; titleId?: string; setTitleId: (id: string) => void; activeId?: string; setActiveId: (id: string) => void; isTransitioning: boolean; setIsTransitioning: (transition: boolean) => void; }; export const CarouselContext = React.createContext({} as CarouselContextProps); const NAME = "CarouselRoot"; const Container = styled("div", { maxWidth: "100%", }); type Controlled = { /** Controlled value for the current page */ page: number; defaultPage?: never; }; type Uncontrolled = { page?: never; /** Uncontrolled value for the initial page shown */ defaultPage?: number; }; type ControlledOrUncontrolled = Controlled | Uncontrolled; export type CarouselRootProps = { css?: WPDS.CSS; /** number of items to move when the page changes @defaut auto*/ itemsPerPage?: number | "auto"; /** callback for page change */ onPageChange?: () => void; /** callback for internal focus */ onDescendantFocus?: (id: string) => void; /* TODO :: do we need these? onScroll={event => {}} // default `undefined` onDragScroll={event => {}} // default `undefined` */ } & ControlledOrUncontrolled & React.ComponentPropsWithRef; export const CarouselRoot = React.forwardRef( ( { page: pageProp, defaultPage, onPageChange, itemsPerPage = "auto", onDescendantFocus = () => undefined, children, ...props }, ref ) => { const [page = 0, setPage] = useControllableState({ prop: pageProp, defaultProp: defaultPage, onChange: onPageChange, }); const [totalPages, setTotalPages] = React.useState(); const [titleId, setTitleId] = React.useState(); const [activeId, setActiveId] = React.useState(); const [isTransitioning, setIsTransitioning] = React.useState(false); const prevId = React.useRef(); React.useEffect(() => { if (activeId && prevId.current !== activeId) { onDescendantFocus(activeId); prevId.current = activeId; } }, [activeId, onDescendantFocus]); return ( {children} ); } ); CarouselRoot.displayName = NAME;