/* @oracle/oraclejet-preact: undefined */
import { jsx, jsxs } from 'preact/jsx-runtime';
import { useState, useCallback } from 'preact/hooks';
import { F as Floating } from './Floating-4a82db94.js';
import { L as Layer } from './Layer-535577b5.js';
import { forwardRef } from 'preact/compat';
import './LayerHost-7931b424.js';
import { i as isControlOrFunctionKey, K as KEYS } from './keyboardUtils-986fe923.js';
import { c as preventDefaultForCurrentTarget } from './useSelectCommon-a3c69d60.js';
import { dropdownStyles } from './PRIVATE_SelectCommon/themes/dropdownStyles.css.js';
import { u as useOutsideMousedown } from './useOutsideMousedown-c45c22c0.js';
import { F as FormFieldContext } from './FormFieldContext-47ca0c20.js';
import './logger-c92f309c.js';
import './TabbableModeContext-7d8ad946.js';
import './UserAssistanceStyles.styles.css';
import './UNSAFE_UserAssistance/themes/redwood/UserAssistanceBaseTheme.styles.css';
import './UNSAFE_UserAssistance/themes/redwood/UserAssistanceVariants.css.js';
import { a as InlineUserAssistance } from './InlineUserAssistance-890293dd.js';
import { F as Flex } from './Flex-03129963.js';
import './MessageBannerStyles.styles.css';
import './UNSAFE_MessageBanner/themes/redwood/MessageBannerBaseTheme.styles.css';
import './UNSAFE_MessageBanner/themes/redwood/MessageBannerVariants.css.js';
import 'preact';
import './TooltipContentStyles.styles.css';
import './hooks/UNSAFE_useTooltip/themes/redwood/TooltipContentBaseTheme.styles.css';
import './hooks/UNSAFE_useTooltip/themes/redwood/TooltipContentVariants.css.js';
import './tooltipUtils-af0abd38.js';
import './IconStyle.styles.css';
import './IconButton-7f91481c.js';
import './MessageStyles.styles.css';
import './MessageFormattingUtils-cdb25115.js';
import './TransitionGroup-5fd80dc9.js';
import './MessagesContext-76544845.js';
import './HiddenAccessibleStyles.styles.css';
import './ComponentMessageStyles.styles.css';
import './UNSAFE_ComponentMessage/themes/redwood/ComponentMessageBaseTheme.styles.css';
import './UNSAFE_ComponentMessage/themes/redwood/ComponentMessageVariants.css.js';
import './Popup-992b6c27.js';
import './UNSAFE_Separator/themes/SeparatorStyles.css.js';
import './LabelStyles.styles.css';
import './UNSAFE_Label/themes/redwood/LabelBaseTheme.styles.css';
import './UNSAFE_Label/themes/redwood/LabelVariants.css.js';
import './InputGroupContext-20bdbd6e.js';
import './UNSAFE_Popup/themes/redwood/PopupBaseTheme.styles.css';
import './UNSAFE_Popup/themes/redwood/PopupVariants.css.js';
import { L as Link } from './Link-8503aab2.js';
import { u as useFocusWithin } from './useFocusWithin-30b1e2d8.js';
import { u as useHover } from './useHover-85077adb.js';
import { c as classNames } from './classNames-4e12b00d.js';
import { S as Separator } from './Separator-93c70737.js';
import { W as WindowOverlay } from './WindowOverlay-7264c44a.js';
import { mobileDropdownStyles } from './PRIVATE_SelectCommon/themes/mobileDropdownStyles.css.js';
import { selectMobileDropdownStyles } from './PRIVATE_SelectCommon/themes/selectMobileDropdownStyles.css.js';
import { l } from './stringUtils-0fe25200.js';
import { T as Text } from './Text-834eb35e.js';
import { i as isInputPlaceholderShown } from './TextFieldUtils-8232bca7.js';
import { formControlInheritTextAlign } from './UNSAFE_TextField/themes/FormControlUtilsStyles.css.js';
import { TextFieldInputRedwoodTheme } from './UNSAFE_TextField/themes/redwood/TextFieldInputTheme.js';
import { u as useAccessibleContext } from './useAccessibleContext-5744de8b.js';
import { u as useComponentTheme } from './useComponentTheme-d2f9e47f.js';
import { u as useFormFieldContext } from './useFormFieldContext-daf7a676.js';
import { u as useTabbableMode } from './useTabbableMode-090ed4b5.js';
import { i as isEmbeddedVariant } from './formControlUtils-84e2af0e.js';
import { t as textInterpolations } from './textAlign-ad252afa.js';
import { m as mergeInterpolations } from './mergeInterpolations-30cd9a69.js';
import { selectMobileFieldInputStyles } from './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] = useState(DEFAULT_PLACEMENT);
    const [prevIsOpen, setPrevIsOpen] = 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 = 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 = useCallback((event) => {
        onAutoDismiss?.(event);
    }, [onAutoDismiss]);
    const handleKeyDown = useCallback((event) => {
        if (event.defaultPrevented || isControlOrFunctionKey(event)) {
            return;
        }
        switch (event.code) {
            case KEYS.ESC:
            case 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({
        isDisabled: !isOpen,
        ref: [anchorRef, dropdownRef],
        handler: handleAutoDismiss
    });
    const inlineStyle = isOpen
        ? {
            minWidth: `${anchorRef.current?.offsetWidth}px`
        }
        : {};
    return !isOpen ? null : (jsx(Layer, { logicalParentRef: anchorRef, children: jsx(Floating, { anchorRef: anchorRef, sizeOptions: DROPDOWN_SIZE_OPTIONS, shiftOptions: DROPDOWN_SHIFT_OPTIONS, ref: dropdownRef, placement: placement, offsetValue: DROPDOWN_OFFSET, onPosition: handlePosition, children: jsx("div", { class: dropdownStyles.base, id: id, style: inlineStyle, onKeyDown: handleKeyDown, onMouseDown: 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 = 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 (jsx(FormFieldContext.Provider, { value: { isFocused: true }, children: jsx("div", { class: dropdownStyles.userAssistance, onMouseDown: handleMouseDown, children: jsx(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();
    const { isFocused, focusProps } = useFocusWithin();
    const handleClick = useCallback((e) => {
        // prevent the link from actually navigating by preventing default and returning false
        e.preventDefault();
        onAction?.();
        return false;
    }, [onAction]);
    const rootClasses = classNames([
        dropdownStyles.results.linkItemRoot,
        isFocused ? dropdownStyles.results.linkItemFocus : undefined
    ]);
    const linkClasses = classNames([
        dropdownStyles.results.extraItem,
        isHover || isFocused || isHighlighted ? dropdownStyles.results.linkItemHighlight : undefined
    ]);
    return (jsx("div", { class: rootClasses, ...focusProps, children: jsx(Link, { href: "#", onClick: handleClick, children: jsx("div", { class: linkClasses, ...hoverProps, children: children }) }) }));
};

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

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

const interpolations = [...Object.values(textInterpolations)];
const styleInterpolations = 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 = 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();
    const { isTabbable, tabbableModeProps } = useTabbableMode();
    // setup properties
    const myPlaceholder = 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();
    const mergedAriaLabelledBy = hasEmptyLabel
        ? l([ariaLabelledBy, UNSAFE_ariaLabelledBy])
        : ariaLabelledBy;
    // setup style classes
    const { class: styleInterpolationClasses } = styleInterpolations({ textAlign });
    const { classes: themeClasses } = useComponentTheme(TextFieldInputRedwoodTheme, {
        type: 'notPassword',
        styleVariant: 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([
        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 && formControlInheritTextAlign
    ]);
    return (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: jsx("div", { class: selectMobileFieldInputStyles.content, children: jsx(Text, { variant: displayValue ? 'inherit' : 'secondary', children: displayValue || myPlaceholder }) }) }));
});

export { Dropdown as D, LinkItem as L, MobileDropdown as M, SelectMobileDropdown as S, DropdownUserAssistance as a, SelectMobileFieldInput as b };
//# sourceMappingURL=SelectMobileFieldInput-345c4d45.js.map
