/** * @fileoverview Stepper — a controlled/uncontrolled multi-step wizard. Pairs the * existing visual `Steps`/`Step` indicator with content `StepperPanel`s and a * built-in `StepperNav` (Back / Next / Finish). State is driven by the headless * `useStepper` hook — bring your own instance via `stepper={...}` (controlled) * or let `Stepper` own one (uncontrolled). Panel transitions use JS motion * (Pattern A) gated by `useSaasflareMotion`. * @author Saasflare™ * @module packages/ui/components/ui/stepper * @package ui * * @component * @example * import { Stepper, StepperPanel } from "@saasflare/ui"; * * * Account fields… * Profile fields… * All set! * */ import { type ReactNode } from "react"; import { type SaasflareComponentProps } from "../../providers"; import { type UseStepperReturn } from "../../hooks/use-stepper"; /** * One step descriptor for the Stepper indicator (mirrors the visual `Step`). * * @example * const items: StepperItem[] = [{ title: "Plan" }, { title: "Add-ons", optional: true }]; */ export interface StepperItem { /** Title shown in the indicator. */ title: string; /** Optional sub-description. */ description?: string; /** Optional icon replacing the number. */ icon?: ReactNode; /** Marks the step skippable. */ optional?: boolean; } /** * Props for {@link Stepper}. * * @example * */ export interface StepperProps extends SaasflareComponentProps { /** Step metadata for the indicator. Length defines the step count. */ items: ReadonlyArray; /** Indicator layout (forwarded to `Steps`). Default: `"horizontal"` */ direction?: "horizontal" | "vertical"; /** Linear mode forwarded to the internal hook. Default: `true` */ linear?: boolean; /** Bring-your-own hook instance (controlled). When omitted, Stepper owns one. */ stepper?: UseStepperReturn; /** Initial step when Stepper owns the hook (uncontrolled). Default: `0` */ defaultStep?: number; /** Global validation gate (uncontrolled mode only). */ validate?: (step: number) => boolean | string | void | Promise; /** Fired on finish (uncontrolled mode only). */ onComplete?: () => void; /** `"unmount"` = only active panel in DOM; `"keepMounted"` = all panels mounted, inactive hidden. Default: `"unmount"` */ mountMode?: "unmount" | "keepMounted"; /** Hide the built-in ``. Default: `false` */ hideNav?: boolean; /** Panel children — one `` per step, in order. */ children: ReactNode; /** Class for the root. */ className?: string; } /** * Content panel for a single step. Renders only when active (or stays mounted * and hidden in `keepMounted` mode). * * @example * */ export interface StepperPanelProps { /** 0-based index this panel maps to. */ value: number; /** Panel content. */ children: ReactNode; /** Class for the panel. */ className?: string; } /** * Built-in navigation row (Back / Next / Finish). Auto-rendered unless `hideNav`. * * @example * */ export interface StepperNavProps { /** Override Back label. Default: `"Back"` */ backLabel?: ReactNode; /** Override Next label. Default: `"Next"` */ nextLabel?: ReactNode; /** Override Finish (last-step Next) label. Default: `"Finish"` */ finishLabel?: ReactNode; /** Show a "Skip" button on optional steps. Default: `true` */ allowSkip?: boolean; /** Class for the nav row. */ className?: string; } /** * Render-prop access to the active Stepper's hook (for custom footers/headers). * * @example * {(s) =>

Step {s.activeStep + 1} of {s.count}

}
*/ export interface StepperContentProps { /** Render-prop receiving the active stepper instance. */ children: (stepper: UseStepperReturn) => ReactNode; } /** * Primary multi-step wizard. Resolves theme axes via {@link useSaasflareProps} * and emits `data-surface`/`data-radius`/`data-animated` on its root. Owns a * {@link useStepper} instance unless one is supplied via `stepper`. * * Indicator step circles become focusable triggers only in non-linear mode * (roving tabindex, Arrow/Home/End/Enter/Space); in linear mode they are * non-interactive and `aria-disabled` to enforce order. On step change, focus * moves to the newly active panel (skipped on initial mount). * * @component * @layer ui * * @param {ReadonlyArray} items - Indicator metadata; length = step count. * @param {string} direction - Indicator layout: "horizontal" | "vertical". * @param {boolean} linear - Forbid forward jumps past incomplete required steps. * @param {UseStepperReturn} stepper - External hook instance (controlled). * @param {string} mountMode - "unmount" | "keepMounted". * * @example * * A * B * * * @example * // Controlled: drive an external hook instance * const s = useStepper({ count: 3 }); * */ export declare function Stepper({ items, direction, linear, stepper: externalStepper, defaultStep, validate, onComplete, mountMode, hideNav, children, className, surface, radius, animated, iconWeight, }: StepperProps): import("react/jsx-runtime").JSX.Element; /** * Content panel for a single step. As a child of {@link Stepper} it is a data * carrier: `Stepper` reads its `value`, `children`, and `className` and renders * the matching region itself (so it can apply motion + ARIA). Rendering one * standalone simply outputs its children in a labelled region. * * @component * @example * Step one content */ export declare function StepperPanel(props: StepperPanelProps): ReactNode; /** * Built-in navigation row: Back, an optional Skip (on optional steps), and a * Next button that becomes Finish on the last step. Reads the active stepper * from context and inherits the wizard's theme axes. Next is disabled while an * async gate is validating. * * @component * @example * * …panels… * * */ export declare function StepperNav({ backLabel, nextLabel, finishLabel, allowSkip, className, }: StepperNavProps): ReactNode; /** * Render-prop escape hatch exposing the active Stepper's hook instance, for * custom headers/footers/summaries outside the built-in nav. * * @component * @example * * …panels… * * {(s) =>

{s.activeStep + 1}/{s.count}

} *
*
*/ export declare function StepperContent({ children }: StepperContentProps): ReactNode;