'use strict';

var tslib_es6 = require('./tslib.es6-cjs.js');
var React = require('react');
var classnames = require('classnames');
var ActivityIndicator = require('./ActivityIndicator-cjs.js');
var Button = require('./Button-cjs.js');
var Icon = require('./Icon-cjs.js');
var useRenderElement = require('./useRenderElement-cjs.js');
var FieldDescription = require('./FieldDescription-cjs.js');
var NumberFieldInput = require('./NumberFieldInput-cjs.js');

var styles = {"container":"_6HZLFIOZh4s-","inline":"_-6ndFYNKKaM-","wrapper":"c20czk-FSyY-","disabled":"_-2INirAxaU4-","small":"NsFBA5oqRAA-","large":"ExKqck-6xVs-","center":"UWiqNi57G8g-","right":"po25PZwJpe4-","inputWrapper":"k9dAO6d010o-","input":"D-PmE-l-hZU-","stepper":"t42w4ZDiDyI-","loadingIndicator":"NLptJ1t9Pj4-","label":"Ggk3aaMcIJU-","hideLabel":"C7d6qmoZiKU-","affixLabel":"_4u1JHjUYvkY-","prefix":"rEWH41rUUEE-","suffix":"_4-iNl6jdfmM-","affixIcon":"_5-Iw-2c-wXk-","compoundAffix":"tZjZRRcAShY-","affixLabelText":"mbEcqyBQoEg-","stepperButton":"zzrCzYF-8u0-","belowField":"_0mcAZAtwQ2o-","description":"xxp2uGc-B6o-","fieldError":"q-WsOi6joGo-","spinning":"d0TEiLWObKU-"};

/**
 * Default formatting used only when the consumer does not pass `format`.
 * Base UI rounds committed values to `maximumFractionDigits`, so this cap also
 * scrubs IEEE-754 step drift (keeps `3.14 + 1` from committing
 * `4.140000000000001`). 12 sits below that noise floor while keeping more
 * precision than a numeric field needs.
 */
const DEFAULT_FORMAT = {
    useGrouping: false,
    maximumFractionDigits: 12,
};
const InputNumberExperimentalContext = React.createContext(null);
function useInputNumberExperimentalContext(consumer) {
    const context = React.useContext(InputNumberExperimentalContext);
    if (context === null) {
        throw new Error(`<InputNumberExperimental.${consumer}> must be used inside <InputNumberExperimental.Wrapper>.`);
    }
    return context;
}
function InputNumberExperimentalWrapper(_a) {
    var { ref } = _a, props = tslib_es6.__rest(_a, ["ref"]);
    const { align, autoComplete, children, className, disabled, format, id: idProp, inline, inputMode, invalid, loading, max, min, name, onBlur, onEnter, onFocus, onKeyDown, onKeyUp, onValueChange, onValueCommitted, readOnly, showMiniLabel = true, size = "default", step = 1, style, value, } = props;
    const generatedId = React.useId();
    const id = idProp !== null && idProp !== void 0 ? idProp : generatedId;
    const innerInputRef = React.useRef(null);
    React.useImperativeHandle(ref, () => ({
        focus: () => { var _a; return (_a = innerInputRef.current) === null || _a === void 0 ? void 0 : _a.focus(); },
        blur: () => { var _a; return (_a = innerInputRef.current) === null || _a === void 0 ? void 0 : _a.blur(); },
    }), []);
    const handleValueCommitted = React.useCallback((newValue) => onValueCommitted === null || onValueCommitted === void 0 ? void 0 : onValueCommitted(newValue), [onValueCommitted]);
    const handleValueChange = React.useCallback((newValue) => onValueChange === null || onValueChange === void 0 ? void 0 : onValueChange(newValue), [onValueChange]);
    const handleKeyDown = React.useCallback((event) => {
        onKeyDown === null || onKeyDown === void 0 ? void 0 : onKeyDown(event);
        if (event.key === "Enter" &&
            !event.shiftKey &&
            !event.ctrlKey &&
            !event.metaKey) {
            onEnter === null || onEnter === void 0 ? void 0 : onEnter(event);
            // Commit on Enter. Base UI commits on blur, not Enter, so round-trip
            // focus to fire onValueCommitted via blur and restore focus immediately.
            const target = event.currentTarget;
            target.blur();
            target.focus();
        }
    }, [onKeyDown, onEnter]);
    // `handleKeyDown` transitively tracks `onKeyDown`/`onEnter` via its own deps,
    // so they are intentionally not listed separately here.
    const contextValue = React.useMemo(() => ({
        align,
        autoComplete,
        disabled,
        format,
        id,
        innerInputRef,
        inputMode,
        loading,
        max,
        min,
        onBlur,
        onFocus,
        onKeyDown: handleKeyDown,
        onKeyUp,
        onValueChange: handleValueChange,
        onValueCommitted: handleValueCommitted,
        readOnly,
        showMiniLabel,
        showStepper: !disabled && !readOnly,
        size,
        step,
        value,
    }), [
        align,
        autoComplete,
        disabled,
        format,
        id,
        inputMode,
        loading,
        max,
        min,
        onBlur,
        onFocus,
        handleKeyDown,
        onKeyUp,
        handleValueChange,
        handleValueCommitted,
        readOnly,
        showMiniLabel,
        size,
        step,
        value,
    ]);
    const rootProps = useRenderElement.mergeProps({ className: classnames(styles.container, inline && styles.inline) }, { className, style });
    return (React.createElement(FieldDescription.FieldRoot, Object.assign({}, rootProps, { disabled: disabled, invalid: invalid || undefined, name: name }),
        React.createElement(InputNumberExperimentalContext.Provider, { value: contextValue }, children)));
}
function InputNumberExperimentalGroup({ children, className, style, }) {
    var _a, _b;
    const ctx = useInputNumberExperimentalContext("Group");
    const groupProps = useRenderElement.mergeProps({
        className: classnames(styles.wrapper, ctx.align && styles[ctx.align], ctx.disabled && styles.disabled, ctx.size !== "default" && styles[ctx.size]),
    }, { className, style });
    return (React.createElement(NumberFieldInput.NumberFieldRoot, { allowOutOfRange: true, format: (_a = ctx.format) !== null && _a !== void 0 ? _a : DEFAULT_FORMAT, id: ctx.id, max: ctx.max, min: ctx.min, onValueChange: ctx.onValueChange, onValueCommitted: ctx.onValueCommitted, readOnly: ctx.readOnly, step: ctx.step, value: (_b = ctx.value) !== null && _b !== void 0 ? _b : null },
        React.createElement(NumberFieldInput.NumberFieldGroup, Object.assign({}, groupProps), children)));
}
function InputNumberExperimentalFooter({ children, className, style, }) {
    useInputNumberExperimentalContext("Footer");
    const rootProps = useRenderElement.mergeProps({ className: styles.belowField }, { className, style });
    return React.createElement("div", Object.assign({}, rootProps), children);
}
function InputNumberExperimentalInput({ children, className, style, }) {
    const ctx = useInputNumberExperimentalContext("Input");
    const rootProps = useRenderElement.mergeProps({
        className: classnames(styles.inputWrapper, !ctx.showMiniLabel && styles.hideLabel, ctx.size !== "default" && styles[ctx.size], ctx.disabled && styles.disabled),
    }, { className, style });
    return (React.createElement("div", Object.assign({}, rootProps),
        React.createElement(NumberFieldInput.NumberFieldInput, { "aria-busy": ctx.loading || undefined, autoComplete: resolveAutoComplete(ctx.autoComplete), className: styles.input, inputMode: ctx.inputMode, onBlur: ctx.onBlur, onFocus: ctx.onFocus, onKeyDown: ctx.onKeyDown, onKeyUp: ctx.onKeyUp, placeholder: " ", ref: ctx.innerInputRef }),
        children));
}
function InputNumberExperimentalLabel({ children, className, style, }) {
    const ctx = useInputNumberExperimentalContext("Label");
    if (!children)
        return null;
    return (React.createElement(FieldDescription.FieldLabel, { className: classnames(styles.label, className), htmlFor: ctx.id, style: style }, children));
}
function InputNumberExperimentalDescription({ children, className, style, }) {
    useInputNumberExperimentalContext("Description");
    if (!children)
        return null;
    return (React.createElement(FieldDescription.FieldDescription, { className: classnames(styles.description, className), style: style }, children));
}
function InputNumberExperimentalError({ children, className, style, }) {
    useInputNumberExperimentalContext("Error");
    if (!children)
        return null;
    return (React.createElement(FieldDescription.FieldError, { className: classnames(styles.fieldError, className), match: true, role: "alert", style: style }, children));
}
function InputNumberExperimentalLoading({ children, className, style, }) {
    useInputNumberExperimentalContext("Loading");
    const rootProps = useRenderElement.mergeProps({ className: styles.loadingIndicator }, { className, style });
    return (React.createElement("div", Object.assign({}, rootProps), children !== null && children !== void 0 ? children : React.createElement(ActivityIndicator.ActivityIndicator, { size: "small" })));
}
function InputNumberExperimentalStepper({ children, incrementLabel, decrementLabel, className, style, }) {
    const ctx = useInputNumberExperimentalContext("Stepper");
    if (ctx.loading || !ctx.showStepper) {
        return null;
    }
    const rootProps = useRenderElement.mergeProps({ className: styles.stepper }, { className, style });
    return (React.createElement("div", Object.assign({}, rootProps), children !== null && children !== void 0 ? children : (React.createElement(React.Fragment, null,
        React.createElement(InputNumberExperimentalIncrement, { ariaLabel: incrementLabel }),
        React.createElement(InputNumberExperimentalDecrement, { ariaLabel: decrementLabel })))));
}
function InputNumberExperimentalIncrement({ children, ariaLabel, className, style, }) {
    useInputNumberExperimentalContext("Increment");
    const rootProps = useRenderElement.mergeProps({ className: styles.stepperButton }, { className, style });
    return (React.createElement(NumberFieldInput.NumberFieldIncrement, Object.assign({ "aria-label": ariaLabel !== null && ariaLabel !== void 0 ? ariaLabel : "Increase value" }, rootProps), children !== null && children !== void 0 ? children : (React.createElement(Icon.Icon, { name: "arrowUp", size: "small", customColor: "currentColor" }))));
}
function InputNumberExperimentalDecrement({ children, ariaLabel, className, style, }) {
    useInputNumberExperimentalContext("Decrement");
    const rootProps = useRenderElement.mergeProps({ className: styles.stepperButton }, { className, style });
    return (React.createElement(NumberFieldInput.NumberFieldDecrement, Object.assign({ "aria-label": ariaLabel !== null && ariaLabel !== void 0 ? ariaLabel : "Decrease value" }, rootProps), children !== null && children !== void 0 ? children : (React.createElement(Icon.Icon, { name: "arrowDown", size: "small", customColor: "currentColor" }))));
}
function InputNumberExperimentalAffixCompound({ variation, label, icon, onClick, ariaLabel, children, className, style, }) {
    const ctx = useInputNumberExperimentalContext("Affix");
    if (!icon && !label && !children) {
        return null;
    }
    const rootProps = useRenderElement.mergeProps({
        className: classnames(styles.compoundAffix, variation === "suffix" && styles.suffix),
    }, { className, style });
    return (React.createElement("div", Object.assign({}, rootProps),
        icon && (React.createElement(AffixIconContent, { icon: icon, size: ctx.size, onClick: onClick, ariaLabel: ariaLabel })),
        label && React.createElement("span", { className: styles.affixLabelText }, label),
        children));
}
/**
 * Renders the prop-driven `prefix`/`suffix` affixes for the sugar component.
 * Icons sit outside the input area; labels render next to the typed value
 * (suffix mirrors the order). The composable `.Affix` part is the alternative
 * when composing the field directly.
 */
function renderDefaultAffix(variation, affix, size) {
    const icon = affix.icon && (React.createElement(AffixIconSlot, { variation: variation, icon: affix.icon, size: size, ariaLabel: "ariaLabel" in affix ? affix.ariaLabel : undefined, onClick: "onClick" in affix ? affix.onClick : undefined }));
    const affixLabel = affix.label && (React.createElement(AffixLabelSlot, { variation: variation, label: affix.label }));
    return variation === "prefix" ? (React.createElement(React.Fragment, null,
        icon,
        affixLabel)) : (React.createElement(React.Fragment, null,
        affixLabel,
        icon));
}
function AffixIconSlot({ variation, icon, size, onClick, ariaLabel, }) {
    return (React.createElement("div", { className: classnames(styles.affixIcon, variation === "suffix" && styles.suffix) },
        React.createElement(AffixIconContent, { icon: icon, size: size, onClick: onClick, ariaLabel: ariaLabel })));
}
function AffixIconContent({ icon, size, onClick, ariaLabel, }) {
    const iconSize = size === "small" ? "small" : "base";
    if (onClick) {
        return (React.createElement(Button.Button, { ariaLabel: ariaLabel !== null && ariaLabel !== void 0 ? ariaLabel : "Action", icon: icon, onClick: onClick, size: iconSize, type: "tertiary", variation: "subtle" }));
    }
    return React.createElement(Icon.Icon, { name: icon, size: iconSize, color: "greyBlue" });
}
function AffixLabelSlot({ variation, label }) {
    return (React.createElement("div", { className: classnames(styles.affixLabel, variation === "prefix" && styles.prefix, variation === "suffix" && styles.suffix) }, label));
}
function resolveAutoComplete(autoComplete) {
    if (autoComplete === false)
        return "off";
    if (autoComplete === true || autoComplete === undefined)
        return undefined;
    return autoComplete;
}
/**
 * Sugar layer: composes the parts from props. This is the same composition a
 * consumer would write by hand with `<InputNumberExperimental.Wrapper>` and the
 * parts — to customize a single piece, copy this tree and swap that part.
 */
function InputNumberExperimental(_a) {
    var _b;
    var { ref } = _a, props = tslib_es6.__rest(_a, ["ref"]);
    const { label, description, error, prefix, suffix } = props, config = tslib_es6.__rest(props, ["label", "description", "error", "prefix", "suffix"]);
    const size = (_b = config.size) !== null && _b !== void 0 ? _b : "default";
    return (React.createElement(InputNumberExperimentalWrapper, Object.assign({}, config, { invalid: config.invalid || Boolean(error), ref: ref }),
        React.createElement(InputNumberExperimentalGroup, null,
            prefix && renderDefaultAffix("prefix", prefix, size),
            React.createElement(InputNumberExperimentalInput, null,
                React.createElement(InputNumberExperimentalLabel, null, label),
                config.loading ? (React.createElement(InputNumberExperimentalLoading, null)) : (React.createElement(InputNumberExperimentalStepper, { incrementLabel: `Increase ${label !== null && label !== void 0 ? label : "value"}`, decrementLabel: `Decrease ${label !== null && label !== void 0 ? label : "value"}` }))),
            suffix && renderDefaultAffix("suffix", suffix, size)),
        (description || error) && (React.createElement(InputNumberExperimentalFooter, null,
            React.createElement(InputNumberExperimentalDescription, null, description),
            React.createElement(InputNumberExperimentalError, null, error)))));
}
InputNumberExperimentalWrapper.displayName = "InputNumberExperimental.Wrapper";
InputNumberExperimental.displayName = "InputNumberExperimental";
InputNumberExperimentalGroup.displayName = "InputNumberExperimental.Group";
InputNumberExperimentalFooter.displayName = "InputNumberExperimental.Footer";
InputNumberExperimentalInput.displayName = "InputNumberExperimental.Input";
InputNumberExperimentalLabel.displayName = "InputNumberExperimental.Label";
InputNumberExperimentalDescription.displayName =
    "InputNumberExperimental.Description";
InputNumberExperimentalError.displayName = "InputNumberExperimental.Error";
InputNumberExperimentalLoading.displayName = "InputNumberExperimental.Loading";
InputNumberExperimentalStepper.displayName = "InputNumberExperimental.Stepper";
InputNumberExperimentalIncrement.displayName =
    "InputNumberExperimental.Increment";
InputNumberExperimentalDecrement.displayName =
    "InputNumberExperimental.Decrement";
InputNumberExperimentalAffixCompound.displayName =
    "InputNumberExperimental.Affix";
InputNumberExperimental.Wrapper = InputNumberExperimentalWrapper;
InputNumberExperimental.Group = InputNumberExperimentalGroup;
InputNumberExperimental.Footer = InputNumberExperimentalFooter;
InputNumberExperimental.Input = InputNumberExperimentalInput;
InputNumberExperimental.Label = InputNumberExperimentalLabel;
InputNumberExperimental.Description = InputNumberExperimentalDescription;
InputNumberExperimental.Error = InputNumberExperimentalError;
InputNumberExperimental.Loading = InputNumberExperimentalLoading;
InputNumberExperimental.Stepper = InputNumberExperimentalStepper;
InputNumberExperimental.Increment = InputNumberExperimentalIncrement;
InputNumberExperimental.Decrement = InputNumberExperimentalDecrement;
InputNumberExperimental.Affix = InputNumberExperimentalAffixCompound;

exports.InputNumberExperimental = InputNumberExperimental;
