import type { FocusEvent, KeyboardEvent, ReactNode } from "react";
import type { IconNames } from "../../Icon";
/**
 * Affix descriptor used by the `prefix` and `suffix` props on
 * `<InputNumberExperimental>` for the default (drop-in) render.
 *
 * At least one of `label` or `icon` should be provided. Icons render outside
 * the input area (in the field's outer padding zone), labels render inside the
 * input wrapper directly adjacent to the typed value (matching V1).
 *
 * `onClick` and `ariaLabel` are not allowed in this shape; if you need a
 * clickable action, use `InputNumberExperimentalSuffix` instead (only valid
 * for `suffix`).
 */
export interface InputNumberExperimentalAffix {
    readonly label?: string;
    readonly icon?: IconNames;
    readonly ariaLabel?: never;
    readonly onClick?: never;
}
/**
 * Suffix variant that turns the suffix icon into a clickable action button.
 * Mirrors V1's `Suffix` type. The `?: never` fields make this a discriminated
 * union with `InputNumberExperimentalAffix`.
 */
export interface InputNumberExperimentalSuffix {
    readonly label?: string;
    readonly icon: IconNames;
    readonly ariaLabel: string;
    onClick(): void;
}
/**
 * Tagged union for the `suffix` prop. Discriminated by whether `onClick` is set:
 * - omit `onClick` → behaves like `InputNumberExperimentalAffix`
 * - set `onClick`  → requires `icon` and `ariaLabel` (clickable action button)
 */
export type InputNumberExperimentalSuffixProp = InputNumberExperimentalAffix | InputNumberExperimentalSuffix;
export type InputNumberExperimentalAutocomplete = boolean | "on" | "off" | "one-time-code" | "address-line1" | "address-line2";
export type InputNumberExperimentalSize = "small" | "default" | "large";
export interface InputNumberExperimentalProps {
    readonly align?: "center" | "right";
    readonly autocomplete?: InputNumberExperimentalAutocomplete;
    /**
     * Optional compound children. When children include any
     * `<InputNumberExperimental.Input | .Affix | .Stepper>`, the component renders
     * them inside `NumberField.Root`/`NumberField.Group` and ignores `prefix`/`suffix`
     * props. Without compound children, the component renders the default
     * composition (input + animated mini-label + optional prefix/suffix + stepper).
     */
    readonly children?: ReactNode;
    readonly description?: ReactNode;
    readonly disabled?: boolean;
    /** When set, renders a styled error message below the field. */
    readonly error?: string;
    readonly id?: string;
    /** Shrink-wrap the field to its content (auto width). */
    readonly inline?: boolean;
    /** Style the error border without showing an error message. */
    readonly invalid?: boolean;
    readonly keyboard?: "numeric" | "decimal";
    readonly max?: number;
    readonly maxLength?: number;
    readonly min?: number;
    readonly name?: string;
    readonly onBlur?: (event?: FocusEvent<HTMLInputElement>) => void;
    /**
     * Fires when the user **commits** a value — on blur, Enter, stepper press,
     * or arrow-key step. Mirrors the V1 / V2 `InputNumber` `onChange` timing so
     * consumers doing side effects (network requests, redraws) only fire on
     * completed input rather than on every keystroke.
     *
     * - Emits `number` for parseable committed input.
     * - Emits `undefined` when the field is committed empty.
     */
    readonly onChange?: (newValue: number | undefined) => void;
    /**
     * Derived from `onKeyDown` — fires when the user presses Enter without
     * any modifier keys (Shift/Ctrl/Meta).
     */
    readonly onEnter?: (event: KeyboardEvent<HTMLInputElement>) => void;
    readonly onFocus?: (event?: FocusEvent<HTMLInputElement>) => void;
    readonly onKeyDown?: (event: KeyboardEvent<HTMLInputElement>) => void;
    readonly onKeyUp?: (event: KeyboardEvent<HTMLInputElement>) => void;
    readonly placeholder?: string;
    readonly prefix?: InputNumberExperimentalAffix;
    readonly readonly?: boolean;
    /** Default `true`. When `false`, the floating mini-label is hidden. */
    readonly showMiniLabel?: boolean;
    readonly size?: InputNumberExperimentalSize;
    readonly suffix?: InputNumberExperimentalSuffixProp;
    /**
     * Value of the field. Controlled-only — pair with `onChange` and drive from
     * outside state.
     *
     * - `number` — controlled with that value.
     * - `null` (or `undefined`) — controlled with an empty value. Useful for
     *   controlled forms whose form-state default is empty/cleared.
     */
    readonly value?: number | null;
}
export interface InputNumberExperimentalRef {
    blur(): void;
    focus(): void;
}
export interface InputNumberExperimentalInputProps {
    /**
     * Overrides the floating mini-label text. Falls back to the root component's
     * `placeholder` prop when omitted.
     */
    readonly placeholder?: string;
}
export interface InputNumberExperimentalAffixCompound {
    readonly variation: "prefix" | "suffix";
    readonly label?: string;
    readonly icon?: IconNames;
    readonly ariaLabel?: never;
    readonly onClick?: never;
}
export interface InputNumberExperimentalAffixCompoundClickable {
    readonly variation: "prefix" | "suffix";
    readonly label?: string;
    readonly icon: IconNames;
    readonly ariaLabel: string;
    onClick(): void;
}
/**
 * Compound `.Affix` props. Discriminated by whether `onClick` is set:
 * - omit `onClick` -> behaves like `InputNumberExperimentalAffixCompound`
 * - set `onClick`  -> requires `icon` and `ariaLabel` (clickable icon-button)
 *
 * Unlike the default `prefix`/`suffix` API, the compound version does not
 * structurally split label and icon; compose two `.Affix` elements or fall
 * back to the default API when you need that.
 */
export type InputNumberExperimentalAffixCompoundProps = InputNumberExperimentalAffixCompound | InputNumberExperimentalAffixCompoundClickable;
export interface InputNumberExperimentalStepperCompoundProps {
    /**
     * Override the increment button's accessible label.
     * Defaults to `Increase ${placeholder ?? "value"}`.
     */
    readonly incrementLabel?: string;
    /**
     * Override the decrement button's accessible label.
     * Defaults to `Decrease ${placeholder ?? "value"}`.
     */
    readonly decrementLabel?: string;
}
