/* @oracle/oraclejet-preact: undefined */
'use strict';

var jsxRuntime = require('preact/jsx-runtime');
var hooks = require('preact/hooks');
var Floating = require('./Floating-79cbe5ad.js');
var Layer = require('./Layer-b60deb1b.js');
var compat = require('preact/compat');
require('./LayerHost-3cd73603.js');
var keyboardUtils = require('./keyboardUtils-b42fe7d5.js');
var useSelectCommon = require('./useSelectCommon-27afecfa.js');
var PRIVATE_SelectCommon_themes_dropdownStyles_css = require('./PRIVATE_SelectCommon/themes/dropdownStyles.css.js');
var useOutsideMousedown = require('./useOutsideMousedown-70f36cca.js');
var FormFieldContext = require('./FormFieldContext-69fe83d2.js');
require('./logger-2b636482.js');
require('./TabbableModeContext-e99d527e.js');


require('./UNSAFE_UserAssistance/themes/redwood/UserAssistanceVariants.css.js');
var InlineUserAssistance = require('./InlineUserAssistance-cfaa3d3e.js');
var Flex = require('./Flex-3a257bc3.js');


require('./UNSAFE_MessageBanner/themes/redwood/MessageBannerVariants.css.js');
require('preact');


require('./hooks/UNSAFE_useTooltip/themes/redwood/TooltipContentVariants.css.js');
require('./tooltipUtils-2bc15136.js');

require('./IconButton-7503293b.js');

require('./MessageFormattingUtils-539d75b0.js');
require('./TransitionGroup-b239d98f.js');
require('./MessagesContext-4e939750.js');



require('./UNSAFE_ComponentMessage/themes/redwood/ComponentMessageVariants.css.js');
require('./Popup-de16d915.js');
require('./UNSAFE_Separator/themes/SeparatorStyles.css.js');


require('./UNSAFE_Label/themes/redwood/LabelVariants.css.js');
require('./InputGroupContext-05f2a46f.js');

require('./UNSAFE_Popup/themes/redwood/PopupVariants.css.js');
var Link = require('./Link-cc34e4c1.js');
var useFocusWithin = require('./useFocusWithin-eb7f956a.js');
var useHover = require('./useHover-49b0430d.js');
var classNames = require('./classNames-c14c6ef3.js');
var Separator = require('./Separator-85962472.js');
var WindowOverlay = require('./WindowOverlay-85d999fa.js');
var PRIVATE_SelectCommon_themes_mobileDropdownStyles_css = require('./PRIVATE_SelectCommon/themes/mobileDropdownStyles.css.js');
var PRIVATE_SelectCommon_themes_selectMobileDropdownStyles_css = require('./PRIVATE_SelectCommon/themes/selectMobileDropdownStyles.css.js');
var stringUtils = require('./stringUtils-3e19c8af.js');
var Text = require('./Text-056f1ec5.js');
var TextFieldUtils = require('./TextFieldUtils-96baac38.js');
var UNSAFE_TextField_themes_FormControlUtilsStyles_css = require('./UNSAFE_TextField/themes/FormControlUtilsStyles.css.js');
var UNSAFE_TextField_themes_redwood_TextFieldInputTheme = require('./UNSAFE_TextField/themes/redwood/TextFieldInputTheme.js');
var useAccessibleContext = require('./useAccessibleContext-c49d8d1b.js');
var useComponentTheme = require('./useComponentTheme-082fc8e4.js');
var useFormFieldContext = require('./useFormFieldContext-4632eb73.js');
var useTabbableMode = require('./useTabbableMode-dbd254e8.js');
var formControlUtils = require('./formControlUtils-596c9dc3.js');
var textAlign = require('./textAlign-f41f49db.js');
var mergeInterpolations = require('./mergeInterpolations-6727b536.js');
var PRIVATE_SelectCommon_themes_SelectMobileFieldInputStyles_css = require('./PRIVATE_SelectCommon/themes/SelectMobileFieldInputStyles.css.js');

const DEFAULT_PLACEMENT = 'bottom-start';
// TODO: get dropdown y (mainAxis) offset from --oj-c-PRIVATE-DO-NOT-USE-private-core-global-dropdown-offset
const DROPDOWN_OFFSET = { mainAxis: 4, crossAxis: 0 };
const DROPDOWN_SIZE_OPTIONS = {
    isMaxHeightAdjusted: true,
    maxHeightCeiling: 400
};
const DROPDOWN_SHIFT_OPTIONS = {
    mainAxis: false
};
//TODO: Start consuming PRIVATE_Dropdown. JET-62565
function Dropdown({ anchorRef, children, dropdownRef, id, isOpen, onAutoDismiss, onPosition }) {
    const [placement, setPlacement] = hooks.useState(DEFAULT_PLACEMENT);
    const [prevIsOpen, setPrevIsOpen] = hooks.useState(isOpen);
    if (prevIsOpen !== isOpen) {
        // reset the placement to the default when the dropdown closes, not opens, so that it doesn't
        // initially open in the previous position and then move to the default position on the
        // rerender after the state is updated
        if (!isOpen) {
            setPlacement(DEFAULT_PLACEMENT);
        }
        setPrevIsOpen(isOpen);
    }
    const handlePosition = hooks.useCallback((positionData) => {
        // update the placement so that the dropdown stays where it is until there is a collision,
        // i.e. it no longer fits, instead of letting it try to move back to the default position
        // on every render
        setPlacement(positionData.placement);
        // call the callback that was passed in through props
        onPosition?.(positionData);
    }, [onPosition, setPlacement]);
    const handleAutoDismiss = hooks.useCallback((event) => {
        onAutoDismiss?.(event);
    }, [onAutoDismiss]);
    const handleKeyDown = hooks.useCallback((event) => {
        if (event.defaultPrevented || keyboardUtils.isControlOrFunctionKey(event)) {
            return;
        }
        switch (event.code) {
            case keyboardUtils.KEYS.ESC:
            case keyboardUtils.KEYS.TAB:
                handleAutoDismiss(event);
                break;
        }
    }, [handleAutoDismiss]);
    // use the mousedown event to be consistent with legacy JET and so that we're hiding the dropdown
    // on the same event where focus will transfer
    useOutsideMousedown.useOutsideMousedown({
        isDisabled: !isOpen,
        ref: [anchorRef, dropdownRef],
        handler: handleAutoDismiss
    });
    const inlineStyle = isOpen
        ? {
            minWidth: `${anchorRef.current?.offsetWidth}px`
        }
        : {};
    return !isOpen ? null : (jsxRuntime.jsx(Layer.Layer, { logicalParentRef: anchorRef, children: jsxRuntime.jsx(Floating.Floating, { anchorRef: anchorRef, sizeOptions: DROPDOWN_SIZE_OPTIONS, shiftOptions: DROPDOWN_SHIFT_OPTIONS, ref: dropdownRef, placement: placement, offsetValue: DROPDOWN_OFFSET, onPosition: handlePosition, children: jsxRuntime.jsx("div", { class: PRIVATE_SelectCommon_themes_dropdownStyles_css.dropdownStyles.base, id: id, style: inlineStyle, onKeyDown: handleKeyDown, onMouseDown: useSelectCommon.preventDefaultForCurrentTarget, children: children }) }) }));
}

function DropdownUserAssistance(props) {
    // Prevent the focus from transferring when the user clicks on an empty/non-clickable area
    // of the user assistance
    const handleMouseDown = hooks.useCallback((event) => {
        // Don't call preventDefault when the user clicks on the help source link, so that the
        // focus is allowed to transfer in that case.
        if (event.target?.tagName !== 'A') {
            event.preventDefault();
        }
    }, []);
    return (jsxRuntime.jsx(FormFieldContext.FormFieldContext.Provider, { value: { isFocused: true }, children: jsxRuntime.jsx("div", { class: PRIVATE_SelectCommon_themes_dropdownStyles_css.dropdownStyles.userAssistance, onMouseDown: handleMouseDown, children: jsxRuntime.jsx(InlineUserAssistance.InlineUserAssistance, { ...props }) }) }));
}

/**
 * This component renders a link that looks like a list item in a Select* component dropdown.
 * It fires an action when the user triggers it, and is intended to be used for launching
 * external application UI from within the dropdown, for example to provide advanced search or
 * add to list functionality.
 * The LinkItem would typically be shown in a fixed position above or below the list itself.
 */
const LinkItem = ({ children, isHighlighted, onAction }) => {
    const { isHover, hoverProps } = useHover.useHover();
    const { isFocused, focusProps } = useFocusWithin.useFocusWithin();
    const handleClick = hooks.useCallback((e) => {
        // prevent the link from actually navigating by preventing default and returning false
        e.preventDefault();
        onAction?.();
        return false;
    }, [onAction]);
    const rootClasses = classNames.classNames([
        PRIVATE_SelectCommon_themes_dropdownStyles_css.dropdownStyles.results.linkItemRoot,
        isFocused ? PRIVATE_SelectCommon_themes_dropdownStyles_css.dropdownStyles.results.linkItemFocus : undefined
    ]);
    const linkClasses = classNames.classNames([
        PRIVATE_SelectCommon_themes_dropdownStyles_css.dropdownStyles.results.extraItem,
        isHover || isFocused || isHighlighted ? PRIVATE_SelectCommon_themes_dropdownStyles_css.dropdownStyles.results.linkItemHighlight : undefined
    ]);
    return (jsxRuntime.jsx("div", { class: rootClasses, ...focusProps, children: jsxRuntime.jsx(Link.Link, { href: "#", onClick: handleClick, children: jsxRuntime.jsx("div", { class: linkClasses, ...hoverProps, children: children }) }) }));
};

function MobileDropdown({ 'aria-labelledby': ariaLabelledBy, children, id, isOpen }) {
    return !isOpen ? null : (jsxRuntime.jsx(Layer.Layer, { children: jsxRuntime.jsx(WindowOverlay.WindowOverlay, { children: jsxRuntime.jsx("div", { id: id, class: PRIVATE_SelectCommon_themes_mobileDropdownStyles_css.mobileDropdownStyles.base, role: "dialog", "aria-modal": "true", "aria-labelledby": ariaLabelledBy, children: jsxRuntime.jsx(Flex.Flex, { width: "100%", height: "100%", maxHeight: "100%", direction: "column", children: children }) }) }) }));
}

function SelectMobileDropdown({ children, footer, hasHeaderSeparator = true, header, id, isOpen, labelId }) {
    return (jsxRuntime.jsxs(MobileDropdown, { id: id, isOpen: isOpen, "aria-labelledby": labelId, children: [header, hasHeaderSeparator && jsxRuntime.jsx(Separator.Separator, {}), jsxRuntime.jsx("div", { class: PRIVATE_SelectCommon_themes_selectMobileDropdownStyles_css.selectMobileDropdownStyles.content, children: children }), jsxRuntime.jsx(Separator.Separator, {}), footer] }));
}

const interpolations = [...Object.values(textAlign.textInterpolations)];
const styleInterpolations = mergeInterpolations.mergeInterpolations(interpolations);
/**
 * This component is used for rendering the main field in mobile phones. This is a bit different from the
 * normal main field (TextFieldInput) that we use for desktop & tablet devices in the way that
 * a user will not be able to edit the value of this field. But, one can still have other functionalities
 * of having a placeholder, tab in & out of it, and other such functionalities of an enabled field.
 *
 * This also differs from ReadonlyTextFieldInput in the following ways:
 * 1. This will be rendered as div as well, but has a role of combobox set on it
 * 2. This will not be read as readonly input by the screen readers
 * 3. This has the stylings much similar to the TextFieldInput component
 * 4. This supports the use of placeholder and shows it when there is no value present
 * 5. This supports having the variant property and styles accordingly
 *
 * As such, this is very similar to the TextFieldInput except that this does not allow user input.
 * Note: we cannot use TextFieldInput with readonly set on it; even though it might provide us the
 * behavior we need, it will make the field as readonly and screen readers read the same about this
 * field. This will be an incorrect representation contextually as one can still edit the value by opening
 * the dropdown and changing the selection.
 */
const SelectMobileFieldInput = compat.forwardRef(({ 'aria-controls': ariaControls, 'aria-describedby': ariaDescribedBy, 'aria-expanded': ariaExpanded, 'aria-invalid': ariaInvalid, 'aria-label': ariaLabel, 'aria-labelledby': ariaLabelledBy, displayValue, hasEmptyLabel, hasInsideLabel = false, isRequired, onBlur, onFocus, placeholder, textAlign, variant = 'default' }, ref) => {
    // consume required contexts
    const { isDisabled, isFocused, hasValue = false } = useFormFieldContext.useFormFieldContext();
    const { isTabbable, tabbableModeProps } = useTabbableMode.useTabbableMode();
    // setup properties
    const myPlaceholder = TextFieldUtils.isInputPlaceholderShown(hasInsideLabel, hasValue, isFocused)
        ? placeholder
        : undefined;
    // Add unsafe API for specifying an external label which is added to ariaLabelledBy on the input,
    // only when labelEdge is 'none' and label is ''. Since ariaLabelledBy takes precedence over all other
    // kinds of labels, this helps to ensure we don't override a meaningful label.
    const { UNSAFE_ariaLabelledBy } = useAccessibleContext.useAccessibleContext();
    const mergedAriaLabelledBy = hasEmptyLabel
        ? stringUtils.l([ariaLabelledBy, UNSAFE_ariaLabelledBy])
        : ariaLabelledBy;
    // setup style classes
    const { class: styleInterpolationClasses } = styleInterpolations({ textAlign });
    const { classes: themeClasses } = useComponentTheme.useComponentTheme(UNSAFE_TextField_themes_redwood_TextFieldInputTheme.TextFieldInputRedwoodTheme, {
        type: 'notPassword',
        styleVariant: formControlUtils.isEmbeddedVariant(variant) ? 'embedded' : 'default',
        textarea: 'notTextArea',
        input: 'isInput',
        prefix: 'noPrefix',
        suffix: 'noSuffix',
        startContent: 'noStartContent',
        endContent: 'hasEndContent',
        insideLabel: hasInsideLabel ? 'hasInsideLabel' : 'noInsideLabel',
        value: hasValue ? 'hasValue' : 'noValue',
        focused: isFocused ? 'isFocused' : 'notFocused',
        disabled: isDisabled ? 'isDisabled' : 'notDisabled'
    });
    const rootDivStyleClasses = classNames.classNames([
        PRIVATE_SelectCommon_themes_SelectMobileFieldInputStyles_css.selectMobileFieldInputStyles.base,
        styleInterpolationClasses,
        themeClasses,
        // JET-72775 - Form control alignment in tables
        // When we are in legacy collection components, we want to inherit the text align
        // when it is not set explicitly.
        variant === 'legacyEmbedded' && textAlign === undefined && UNSAFE_TextField_themes_FormControlUtilsStyles_css.formControlInheritTextAlign
    ]);
    return (jsxRuntime.jsx("div", { "aria-autocomplete": "list", "aria-controls": ariaControls, "aria-describedby": ariaDescribedBy, "aria-expanded": ariaExpanded, "aria-invalid": ariaInvalid, "aria-label": ariaLabel, "aria-labelledby": mergedAriaLabelledBy, "aria-required": isRequired ? 'true' : undefined, class: rootDivStyleClasses, onBlur: onBlur, onFocus: onFocus, ref: ref, role: "combobox", ...(isTabbable && tabbableModeProps), children: jsxRuntime.jsx("div", { class: PRIVATE_SelectCommon_themes_SelectMobileFieldInputStyles_css.selectMobileFieldInputStyles.content, children: jsxRuntime.jsx(Text.Text, { variant: displayValue ? 'inherit' : 'secondary', children: displayValue || myPlaceholder }) }) }));
});

exports.Dropdown = Dropdown;
exports.DropdownUserAssistance = DropdownUserAssistance;
exports.LinkItem = LinkItem;
exports.MobileDropdown = MobileDropdown;
exports.SelectMobileDropdown = SelectMobileDropdown;
exports.SelectMobileFieldInput = SelectMobileFieldInput;
//# sourceMappingURL=SelectMobileFieldInput-cbf57541.js.map
