import React__default, { useState, useEffect, useRef } from 'react';
import { useShowClear } from '@jobber/hooks';
import { AnimatePresence, motion } from 'framer-motion';
import { tokens } from '@jobber/design';
import classnames from 'classnames';
import { B as Button } from './Button-es.js';
import { I as Icon } from './Icon-es.js';
import { T as Text } from './Text-es.js';
import { u as useFormFieldFocus } from './useFormFieldFocus-es.js';
import { I as InputValidation } from './InputValidation-es.js';

var formFieldStyles = {"container":"YL-mNv-Bl6g-","wrapper":"_8lhbGTQ-hhg-","disabled":"Tz9LK9ABKMk-","horizontalWrapper":"b5mv1x1H7YE-","textarea":"hGr6YW4AeLM-","safari":"QBCWi9GBgMs-","timeInputLabel":"_0pmqVa2zSE4-","small":"Sw5O4I0lMJg-","miniLabel":"F1t76G6bDKo-","large":"_9tjyT9QUtP8-","text":"QmMiyoAWp-g-","invalid":"XWDSfe6weSY-","inline":"SaORbL7SYWY-","center":"ozy2UoT2vsg-","right":"_3TJdT91YD3c-","maxLength":"W6GrMqLy2qk-","inputWrapper":"-LmjnYRU0r0-","childrenWrapper":"yVXYv6hkuOA-","input":"vtSDcuzNr9Q-","emptyPhoneNumber":"MVhuQuzUBUs-","label":"Dgk00tzlODA-","select":"NwQGiWBWIsc-","externalLabel":"Qb8zQ8n-8vc-","postfix":"yTDzs9h1otI-","affixIcon":"m0YpdssD2dY-","suffix":"_-3mMnjSh6ok-","affixLabel":"-Wzcb0pBh5I-","description":"DHX5ijY3xIw-","toolbar":"AL-2brNI7dk-","spinning":"_8Rzv7CcDW80-"};

/**
 * @internal Reach out to UX Foundations if using this component since it is possible it might change
 */
function AffixLabel({ label, variation = "prefix", labelRef, }) {
    const affixLabelClass = classnames(formFieldStyles.affixLabel, {
        [formFieldStyles.suffix]: variation === "suffix",
    });
    if (!label)
        return null;
    return (React__default.createElement("div", { ref: labelRef, className: affixLabelClass }, label));
}
function AffixIcon({ icon, onClick, ariaLabel, variation = "prefix", size, }) {
    const affixIconClass = classnames(formFieldStyles.affixIcon, {
        [formFieldStyles.suffix]: variation === "suffix",
    });
    const iconSize = size === "small" ? "small" : "base";
    if (!icon)
        return null;
    return (React__default.createElement("div", { className: affixIconClass }, onClick ? (React__default.createElement(Button
    /**
     * We can cast the ariaLabel here as a `Suffix`
     * requires an ariaLabel if there is an action
     */
    , { 
        /**
         * We can cast the ariaLabel here as a `Suffix`
         * requires an ariaLabel if there is an action
         */
        ariaLabel: ariaLabel, icon: icon, onClick: onClick, variation: "subtle", type: "tertiary", size: iconSize })) : (React__default.createElement(Icon, { name: icon, size: iconSize, color: "greyBlue" }))));
}

function FormFieldDescription({ id, description, visible = true, }) {
    if (!visible)
        return null;
    const useStringFormat = !description || typeof description === "string";
    return (React__default.createElement("div", { id: id, className: formFieldStyles.description }, useStringFormat ? (React__default.createElement(Text, { size: "small", variation: "subdued" }, description)) : (description)));
}

var styles = {"clearInput":"YmRTd-KeXv4-","spinning":"B25z9B8I3gs-"};

function ClearAction({ onClick, visible, }) {
    if (!visible)
        return null;
    return (React__default.createElement("button", { className: styles.clearInput, onClick: onClick, type: "button", "aria-label": "Clear input", "data-testid": "ATL-FormField-clearButton" },
        React__default.createElement(Icon, { name: "remove", size: "small" })));
}

function useToolbar(props) {
    const isToolbarVisible = props.toolbar !== undefined &&
        (props.toolbarVisibility === "always" || props.focused);
    const toolbarAnimationEnd = { opacity: 0, height: 0 };
    const toolbarAnimationStart = { opacity: 1, height: "auto" };
    return {
        isToolbarVisible,
        toolbarAnimationEnd,
        toolbarAnimationStart,
    };
}

function useIsSafari() {
    return (globalThis === null || globalThis === void 0 ? void 0 : globalThis.navigator)
        ? /^((?!chrome|android).)*safari/i.test(navigator.userAgent)
        : false;
}

/**
 * Hook for getting the correct styles for the FormField and its children
 */
function useFormFieldWrapperStyles({ size, align, placeholder, value, invalid, error, max, prefixRef, suffixRef, maxLength, type, disabled, inline, showMiniLabel = true, }) {
    const isSafari = useIsSafari();
    const wrapperClasses = classnames(formFieldStyles.wrapper, size && formFieldStyles[size], align && formFieldStyles[align], {
        [formFieldStyles.miniLabel]: (showMiniLabel && placeholder && value !== "") ||
            (placeholder && type === "select") ||
            // Naively assume that if the the type is tel, it is the InputPhoneNumber
            (placeholder && type === "tel"),
        [formFieldStyles.text]: type === "textarea" || type === "text",
        [formFieldStyles.textarea]: type === "textarea",
        [formFieldStyles.safari]: isSafari && type === "textarea",
        [formFieldStyles.select]: type === "select",
        [formFieldStyles.invalid]: invalid !== null && invalid !== void 0 ? invalid : error,
        [formFieldStyles.disabled]: disabled,
        [formFieldStyles.maxLength]: maxLength,
        [formFieldStyles.timeInputLabel]: placeholder && type === "time" && value === "",
    });
    const containerClasses = classnames(formFieldStyles.container, {
        [formFieldStyles.inline]: inline,
    });
    const wrapperInlineStyle = {
        ["--formField-maxLength"]: maxLength || max,
    };
    const [labelStyle, setLabelStyle] = useState({
        paddingLeft: undefined,
        paddingRight: undefined,
    });
    useEffect(() => {
        var _a, _b;
        setLabelStyle(getAffixPaddding({
            value,
            type,
            prefixWidth: ((_a = prefixRef === null || prefixRef === void 0 ? void 0 : prefixRef.current) === null || _a === void 0 ? void 0 : _a.offsetWidth) || 0,
            suffixWidth: ((_b = suffixRef === null || suffixRef === void 0 ? void 0 : suffixRef.current) === null || _b === void 0 ? void 0 : _b.offsetWidth) || 0,
        }));
    }, [value]);
    return {
        inputStyle: formFieldStyles.input,
        wrapperClasses,
        containerClasses,
        wrapperInlineStyle,
        labelStyle,
        setLabelStyle,
    };
}
function getAffixPaddding({ value, type, prefixWidth, suffixWidth, }) {
    const hasValue = value !== "";
    const newPadding = {
        paddingLeft: undefined,
        paddingRight: undefined,
    };
    // Naively assume that if the the type is tel, it is the InputPhoneNumber
    if (type === "tel")
        return newPadding;
    if (prefixWidth && !hasValue) {
        newPadding.paddingLeft = offset(prefixWidth);
    }
    if (suffixWidth && !hasValue) {
        newPadding.paddingRight = offset(suffixWidth);
    }
    function offset(width) {
        return `calc(${width}px + var(--space-smallest)`;
    }
    return newPadding;
}

function FormFieldWrapper({ align, description, descriptionIdentifier, placeholder, value, children, invalid, error, size, prefix, suffix, max, maxLength, type, disabled, inline, identifier, clearable, onClear, readonly, toolbar, toolbarVisibility = "while-editing", showMiniLabel = true, wrapperRef, }) {
    const prefixRef = useRef(null);
    const suffixRef = useRef(null);
    const { wrapperClasses, containerClasses, wrapperInlineStyle, labelStyle } = useFormFieldWrapperStyles({
        align,
        max,
        maxLength,
        prefixRef,
        suffixRef,
        placeholder,
        value,
        invalid,
        error,
        type,
        disabled,
        inline,
        size,
        showMiniLabel,
    });
    const { focused } = useFormFieldFocus({ wrapperRef });
    const showClear = useShowClear({
        clearable,
        multiline: type === "textarea",
        focused,
        hasValue: Boolean(value),
        disabled,
        readonly,
    });
    const { isToolbarVisible, toolbarAnimationEnd, toolbarAnimationStart } = useToolbar({
        focused,
        toolbar,
        toolbarVisibility,
    });
    return (React__default.createElement("div", { className: containerClasses },
        React__default.createElement("div", { className: wrapperClasses, style: wrapperInlineStyle, "data-testid": "Form-Field-Wrapper", ref: wrapperRef },
            React__default.createElement(FormFieldInputHorizontalWrapper, null,
                React__default.createElement(AffixIcon, Object.assign({}, prefix, { size: size })),
                React__default.createElement(FormFieldInputWrapperStyles, null,
                    (showMiniLabel || !value) && (React__default.createElement(FormFieldLabel, { htmlFor: identifier, style: (prefixRef === null || prefixRef === void 0 ? void 0 : prefixRef.current) || (suffixRef === null || suffixRef === void 0 ? void 0 : suffixRef.current)
                            ? labelStyle
                            : undefined }, placeholder)),
                    React__default.createElement(AffixLabel, Object.assign({}, prefix, { labelRef: prefixRef })),
                    React__default.createElement(FormFieldWrapperMain, null, children),
                    React__default.createElement(AffixLabel, Object.assign({}, suffix, { labelRef: suffixRef, variation: "suffix" }))),
                React__default.createElement(ClearAction, { onClick: onClear, visible: showClear }),
                React__default.createElement(AffixIcon, Object.assign({}, suffix, { variation: "suffix", size: size }))),
            React__default.createElement(FormFieldWrapperToolbar, { toolbarVisibility: toolbarVisibility, isToolbarVisible: isToolbarVisible, toolbarAnimationEnd: toolbarAnimationEnd, toolbarAnimationStart: toolbarAnimationStart, toolbar: toolbar })),
        React__default.createElement(FormFieldDescription, { visible: !!description && !inline, id: descriptionIdentifier, description: description }),
        React__default.createElement(InputValidation, { message: error, visible: !!error && !inline })));
}
/**
 * @internal Reach out to UX Foundations if using this component since it is possible it might change
 */
function FormFieldInputHorizontalWrapper({ children, }) {
    return React__default.createElement("div", { className: formFieldStyles.horizontalWrapper }, children);
}
/**
 * @internal Reach out to UX Foundations if using this component since it is possible it might change
 */
function FormFieldInputWrapperStyles({ children, }) {
    return React__default.createElement("div", { className: formFieldStyles.inputWrapper }, children);
}
/**
 * @internal Reach out to UX Foundations if using this component since it is possible it might change
 */
function FormFieldWrapperMain({ children, tabIndex = -1, }) {
    return (React__default.createElement("div", { className: formFieldStyles.childrenWrapper, tabIndex: tabIndex }, children));
}
function FormFieldLabel({ children, htmlFor, style, external = false, }) {
    if (!children)
        return null;
    return (React__default.createElement("label", { className: external ? formFieldStyles.externalLabel : formFieldStyles.label, htmlFor: htmlFor, style: style }, children));
}
/**
 * @internal Reach out to UX Foundations if using this component since it is possible it might change
 */
function FormFieldWrapperToolbar({ toolbar, isToolbarVisible, toolbarAnimationEnd, toolbarAnimationStart, toolbarVisibility, }) {
    return (React__default.createElement(AnimatePresence, { initial: toolbarVisibility === "always" ? false : true }, isToolbarVisible && (React__default.createElement(motion.div, { key: "toolbar", initial: toolbarAnimationEnd, animate: toolbarAnimationStart, exit: toolbarAnimationEnd, transition: {
            duration: tokens["timing-base"] / 1000,
            ease: "easeInOut",
        }, tabIndex: -1 },
        React__default.createElement("div", { className: formFieldStyles.toolbar, "data-testid": "ATL-InputText-Toolbar" }, toolbar)))));
}

export { AffixIcon as A, FormFieldInputHorizontalWrapper as F, FormFieldInputWrapperStyles as a, FormFieldLabel as b, FormFieldWrapper as c, FormFieldWrapperMain as d, FormFieldWrapperToolbar as e, AffixLabel as f, formFieldStyles as g, useFormFieldWrapperStyles as u };
