/**
* @fileoverview StatefulButton — Button + loading state.
* @module packages/ui/components/composed/stateful-button
* @package ui
*
* Thin wrapper around {@link Button} that adds a single async-friendly axis:
* `loading`. While loading, the button is disabled, prepends a spinner, and
* optionally swaps its label for `loadingText`.
*
* Keeping these concerns out of the primitive lets the base Button stay
* purely presentational; consumers opt in to stateful behavior by reaching
* for this composed variant.
*
* @example
* import { StatefulButton } from "@saasflare/ui";
*
*
* Save changes
*
*
* @example // Inherits all base Button props
*
* Delete account
*
*/
import * as React from "react";
import { type ButtonProps } from "../ui/button";
/**
* Props for {@link StatefulButton}. Extends {@link ButtonProps} with two
* orthogonal stateful concerns. `asChild` is intentionally excluded — a
* Slot-rendered button cannot own its own DOM children, so the spinner /
* loading-text swap would be ambiguous. `isLoading` / `spinnerPlacement` are
* also excluded: `loading` is StatefulButton's single async-text flag and it
* delegates to the base Button's presentational `isLoading` internally, so
* exposing both would create two competing loading switches.
*/
interface StatefulButtonProps extends Omit {
/** Pending state: forces disabled, shows spinner, swaps label when `loadingText` is set. */
loading?: boolean;
/** Optional label to show in place of children while `loading` is true. */
loadingText?: React.ReactNode;
}
/**
* Button with built-in loading state.
*
* `loading` is the single source of truth for pending UI. It delegates to the
* base {@link Button}'s presentational `isLoading` flag (DRY — the spinner,
* disabled, `aria-busy`, and motion-gate logic live in one place):
* - sets `disabled` (Button OR-s `disabled || isLoading` internally)
* - sets `aria-busy="true"` for assistive tech
* - prepends an animated spinner before the label
* - replaces `children` with `loadingText` if provided (otherwise label stays)
*
* @component
* @layer composed
*
* @param {boolean} loading - Pending state.
* @param {React.ReactNode} loadingText - Optional override label while loading.
* @param disabled - Native disabled flag; OR-ed with `loading`.
* @param children - Default label, shown unless replaced by `loadingText` while loading.
* @param rest - Remaining {@link ButtonProps} (variant, intent, surface, radius, animated, iconWeight, …) forwarded to the underlying Button.
*/
declare function StatefulButton({ loading, loadingText, disabled, children, ...rest }: StatefulButtonProps): import("react/jsx-runtime").JSX.Element;
export { StatefulButton, type StatefulButtonProps };