import type * as React from 'react'; import type { PrimitivePropsWithRef } from '../utils/primitive.cjs'; /** Shape returned by the exported `useCarouselContext` hook; distributed from {@link Carousel} to its parts via context. */ export interface CarouselContextValue { value: number; setValue: (index: number) => void; orientation: 'horizontal' | 'vertical'; loop: boolean; /** Every registered slide's id, in DOM order — the order a derived Indicators list must draw its dots in. */ itemIds: string[]; /** Registers one slide, placing its id by the element's DOM position rather than by when it mounted. */ registerItem: (id: string, element: HTMLElement | null) => void; /** Removes a slide's id from the registry when it unmounts. */ unregisterItem: (id: string) => void; /** How many slides are visible at once. */ slidesPerPage: number; /** How many slides one Previous/Next step (or Arrow keypress) moves. */ slidesPerMove: number; /** Highest index the carousel can rest at — `max(0, count - slidesPerPage)`, so the last page stays full. */ maxIndex: number; /** Moves to `index`, clamped into `[0, maxIndex]`, ignoring out-of-range values rather than throwing. */ scrollToIndex: (index: number) => void; /** Stepper forward by `slidesPerMove`, wrapping to the start when `loop` is set. */ next: () => void; /** Stepper back by `slidesPerMove`, wrapping to the last page when `loop` is set. */ previous: () => void; /** Whether `next()` has somewhere to go — false at the last page of a non-looping carousel, and with no slides. */ canScrollNext: boolean; /** Whether `previous()` has somewhere to go — false at the first slide of a non-looping carousel, and with no slides. */ canScrollPrev: boolean; /** * User's autoplay intent, not live timer state — hover and a hidden page suspend the timer without flipping it, but focus entering the carousel does. */ playing: boolean; /** Starts or stops autoplay — what `CarouselPlayPause` calls. */ setPlaying: (playing: boolean) => void; } /** * Props for {@link Carousel}, which tracks a controllable current-slide index * over slides supplied as `items` or as children, with optional derived * controls, indicators and an autoplay pause button — there is no * track/transform sliding and no swipe gesture. */ export interface CarouselProps extends PrimitivePropsWithRef<'div'> { /** * Manually-composed parts — `CarouselContent`, `CarouselItem`, etc. — for full control over the anatomy; omitted, the carousel derives it from `items` and related props. * @default undefined — the carousel derives its anatomy. */ children?: React.ReactNode | undefined; /** * Index of the first visible slide for controlled usage, paired with `onValueChange`. * @default undefined — uncontrolled, tracks its own active window internally. */ value?: number | undefined; /** * Initial index of the first slide in the active window, for uncontrolled usage. * @default 0 */ defaultValue?: number | undefined; /** * Fires with the new active index whenever the slide changes, controlled or not. * @default undefined — no-op if omitted. */ onValueChange?: ((index: number) => void) | undefined; /** * Layout axis, exposed as `data-orientation` and used to pick Arrow * Left/Right vs Arrow Up/Down for keyboard navigation. * @default 'horizontal' */ orientation?: 'horizontal' | 'vertical' | undefined; /** * Whether stepping past the last slide wraps to the first (and vice versa for `CarouselPrevious`); when `false`, both disable themselves at the ends. * @default false */ loop?: boolean | undefined; /** * How many slides are visible at once, from `value` up to `value + slidesPerPage - 1`; values below 1 are treated as 1. * @default 1 */ slidesPerPage?: number | undefined; /** * How many slides one Previous/Next step (or Arrow keypress) advances by; set equal to `slidesPerPage` for page-at-a-time paging. * @default 1 */ slidesPerMove?: number | undefined; /** * Gap between slides, published as the `--skdx-carousel-spacing` custom property; a number is treated as pixels, a string used verbatim. * @default undefined — the property is not set, and your CSS decides. */ spacing?: number | string | undefined; /** * Auto-advances on a timer; off by default (WCAG 2.2.2), never starts under `prefers-reduced-motion`, and pairs with `CarouselPlayPause` to pause. * @default false */ autoplay?: boolean | undefined; /** * Milliseconds to wait between automatic slide advances. * @default 5000 */ autoplayInterval?: number | undefined; /** * Data the derived anatomy renders one `CarouselItem` slide per, instead of * hand-written children. Ignored when `children` is given. * @default undefined — no slides render. */ items?: T[] | undefined; /** * Renders one derived slide's content, in place of its `String(item)` * fallback. Ignored when `children` is given. * @default undefined — each slide renders `String(item)`. */ renderItem?: ((item: T, index: number) => React.ReactNode) | undefined; /** * Whether the derived anatomy renders a `CarouselIndicators` strip, one dot * per item. Ignored when `children` is given. * @default false */ showIndicators?: boolean | undefined; /** * Accessible names for derived indicator dots, one per `items` entry in order; a shorter list falls back to the positional default for the rest. * @default undefined */ indicatorLabels?: readonly string[] | undefined; /** * Renders derived `CarouselPrevious` / `CarouselNext` controls; `CarouselPlayPause` renders whenever `autoplay` is set, independent of this. * @default true */ showControls?: boolean | undefined; } /** Props for {@link CarouselContent}, the wrapper around the slide `CarouselItem`s. */ export interface CarouselContentProps extends PrimitivePropsWithRef<'div'> { } /** Props for a single {@link CarouselItem} slide. */ export interface CarouselItemProps extends PrimitivePropsWithRef<'div'> { } /** Props for {@link CarouselPrevious}, the button that steps to the previous slide. */ export interface CarouselPreviousProps extends PrimitivePropsWithRef<'button'> { } /** Props for {@link CarouselNext}, the button that steps to the next slide. */ export interface CarouselNextProps extends PrimitivePropsWithRef<'button'> { } /** Props for {@link CarouselPlayPause}, the autoplay pause/resume control. */ export interface CarouselPlayPauseProps extends PrimitivePropsWithRef<'button'> { } /** Props for {@link CarouselIndicators}, the `role="group"` strip of slide dots. */ export interface CarouselIndicatorsProps extends PrimitivePropsWithRef<'div'> { } /** Props for a single {@link CarouselIndicator} dot. */ export interface CarouselIndicatorProps extends PrimitivePropsWithRef<'button'> { /** Zero-based slide index this dot jumps to when pressed. */ index: number; /** * Accessible name for this dot, replacing the positional default "Go to slide N"; a consumer's own `aria-label` takes precedence. * @default undefined */ label?: string | undefined; } /** Props for {@link CarouselProgress}, the "slide 2 of 5" position readout. */ export interface CarouselProgressProps extends Omit, 'children'> { /** * Formats the position text from the 1-based current slide and total count, consumer-supplied for translation. * @default (current, total) => `Slide ${current} of ${total}` */ format?: ((current: number, total: number) => string) | undefined; /** * With `asChild`, the element the formatted text is cloned onto, replacing its own children with the readout. * @default undefined */ children?: React.ReactElement | undefined; }