"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.UIComboBox = exports.UIComboBoxLoaderType = exports.UISelectableOptionMenuItemType = void 0;
const react_1 = __importDefault(require("react"));
const react_2 = require("@fluentui/react");
Object.defineProperty(exports, "UISelectableOptionMenuItemType", { enumerable: true, get: function () { return react_2.SelectableOptionMenuItemType; } });
const UIHighlightMenuOption_1 = require("../UIContextualMenu/UIHighlightMenuOption");
require("./UIComboBox.scss");
require("./Callout.scss");
const UILoader_1 = require("../UILoader");
const Icons_1 = require("../Icons");
const ValidationMessage_1 = require("../../helper/ValidationMessage");
const UILabel_1 = require("../UILabel");
const UIDropdown_1 = require("../UIDropdown");
const UICallout_1 = require("../UICallout");
const utilities_1 = require("../../utilities");
const types_1 = require("../types");
var UIComboBoxLoaderType;
(function (UIComboBoxLoaderType) {
    /**
     * Loader within dropdown list
     */
    UIComboBoxLoaderType["List"] = "List";
    /**
     * Loader within input
     */
    UIComboBoxLoaderType["Input"] = "Input";
})(UIComboBoxLoaderType || (exports.UIComboBoxLoaderType = UIComboBoxLoaderType = {}));
/**
 * UIComboBox component.
 *
 * @exports
 * @class {UIComboBox}
 * @extends {React.Component<UIComboBoxProps, UIComboBoxState>}
 */
class UIComboBox extends react_1.default.Component {
    /**
     * Initializes component properties.
     *
     * @param {UIComboBoxProps} props
     */
    constructor(props) {
        super(props);
        // Reference to fluent ui combobox
        this.comboBox = react_1.default.createRef();
        this.comboboxDomRef = react_1.default.createRef();
        this.menuDomRef = react_1.default.createRef();
        this.selectedElement = react_1.default.createRef();
        this.query = '';
        this.ignoreOpenKeys = ['Meta', 'Control', 'Shift', 'Tab', 'Alt', 'CapsLock'];
        this.isListHidden = false;
        this.calloutCollisionTransform = new UICallout_1.CalloutCollisionTransform(this.comboboxDomRef, this.menuDomRef);
        this.hiddenOptions = [];
        /**
         * Method called on combobox option resolvation.
         * We should not allow to add any custom option.
         *
         * @returns {IComboBoxOption[]} Array of combobox items.
         */
        this.onResolveOptions = () => {
            return this.props.options;
        };
        /**
         * Default renderer for combobox item when highlight mode is enabled.
         * We should pass highlight query within props and avoid rendering if it is hidden.
         *
         * @param {IComboBoxOption} props Combobox item props.
         * @param {Function} defaultRender Combobox item default renderer.
         * @returns {JSX.Element | null} Element to render.
         */
        this._onRenderItem = (props, defaultRender) => {
            if (defaultRender && props) {
                // Use data for custom onRender functions
                props.data = this.query;
                if (props.title === undefined) {
                    // Apply title by default if property not provided
                    // In older fluent-ui versions it was applied by default, but behavior changed in version '8.66.2'
                    props.title = props.text;
                }
                const selected = props.index !== undefined && this.getCurrentSelectedIndex() === props.index;
                return !props.hidden ? (react_1.default.createElement("div", { key: props.key, ref: selected ? this.selectedElement : undefined, className: `${selected ? 'ts-ComboBox--selected' : ''}` }, defaultRender(props))) : null;
            }
            return null;
        };
        /**
         * Method called on combobox item render.
         * We should pass query to it and avoid rendering if it is hidden.
         *
         * @param {IComboBoxOption} props Combobox item props.
         * @param {Function} defaultRender Combobox item default renderer.
         * @returns {JSX.Element | null} Element to render.
         */
        this.onRenderItem = (props, defaultRender) => {
            if (this.props.onRenderItem) {
                return this.props.onRenderItem(props, this._onRenderItem.bind(this, props, defaultRender));
            }
            return this._onRenderItem(props, defaultRender);
        };
        /**
         * Method to get current selected index.
         *
         * @returns {number | undefined} Selected item index.
         */
        this.getCurrentSelectedIndex = () => {
            const baseCombobox = this.comboBox.current;
            if (!baseCombobox) {
                return undefined;
            }
            if (baseCombobox.state.currentPendingValueValidIndex !== -1) {
                return baseCombobox.state.currentPendingValueValidIndex;
            }
            return baseCombobox.props.hoisted.selectedIndices ? baseCombobox.props.hoisted.selectedIndices[0] : undefined;
        };
        /**
         * Return a value for the placeholder.
         *
         * @returns {string}
         */
        this.getPlaceholder = () => {
            if (this.props.placeholder) {
                return this.props.placeholder;
            }
            else {
                // That string should be translated
                return 'Search or select from dropdown';
            }
        };
        /**
         * Default renderer for combobox item's option/label when highlight mode is enabled.
         * We should use different componenet which support highlighting - 'ComboboxSearchOption'.
         *
         * @param {IComboBoxOption} props Combobox item props.
         * @param {Function} defaultRender Combobox item default renderer.
         * @returns {JSX.Element | null} Element to render.
         */
        this._onRenderOption = (props, defaultRender) => {
            if (props && props.itemType !== react_2.SelectableOptionMenuItemType.Header) {
                return react_1.default.createElement(UIHighlightMenuOption_1.UIHighlightMenuOption, { text: props.text, query: this.query });
            }
            return defaultRender ? defaultRender(props) : null;
        };
        /**
         * Method called on combobox item's option/label render.
         * We should use different componenet which support highlighting - 'ComboboxSearchOption'.
         *
         * @param {IComboBoxOption} props Combobox item props.
         * @param {Function} defaultRender Combobox item default renderer.
         * @returns {JSX.Element | null} Element to render.
         */
        this.onRenderOption = (props, defaultRender) => {
            if (this.props.onRenderOption) {
                return this.props.onRenderOption(props, this._onRenderOption.bind(this, props, defaultRender));
            }
            return this._onRenderOption(props, defaultRender);
        };
        this.handleChange = (event, option) => {
            if (option && this.props.onHandleChange) {
                this.props.onHandleChange(option.key);
            }
        };
        /**
         * Custom render function for the combo box dropdown list.
         *
         * This method handles following cases:
         * 1. If a loading state is active (as determined by `isLoaderApplied`), it renders a loading indicator.
         * 2. If no options are available and a `noDataLabel` is provided via `externalSearchProps`, it shows a "no data" message.
         *
         * @param props The rendering props for the selectable, droppable list.
         * @param defaultRender The default rendering function provided by the ComboBox component.
         * @returns A JSX element representing the rendered list.
         */
        this.onRenderList = (props, defaultRender) => {
            const { onRenderList, externalSearchProps, options } = this.props;
            if (onRenderList) {
                return onRenderList(props, defaultRender);
            }
            const isLoading = this.isLoaderApplied(UIComboBoxLoaderType.List);
            if (isLoading) {
                const styles = {
                    label: {
                        fontSize: '11px',
                        fontWeight: 'normal'
                    }
                };
                return (react_1.default.createElement("div", { className: "option-loading" },
                    react_1.default.createElement(UILoader_1.UILoader, { label: "Loading", className: "uiLoaderXSmall", labelPosition: "right", styles: styles })));
            }
            else if (externalSearchProps?.noDataLabel && (!options.length || this.isListHidden)) {
                return react_1.default.createElement("div", { className: "option-no-data" }, externalSearchProps.noDataLabel);
            }
            return defaultRender?.(props);
        };
        this.onInput = this.onInput.bind(this);
        this.reserQuery = this.reserQuery.bind(this);
        this.onResolveOptions = this.onResolveOptions.bind(this);
        this.onRenderItem = this.onRenderItem.bind(this);
        this.onRenderOption = this.onRenderOption.bind(this);
        this.onKeyDown = this.onKeyDown.bind(this);
        this.onClick = this.onClick.bind(this);
        this.handleRefreshButton = this.handleRefreshButton.bind(this);
        this.onPendingValueChanged = this.onPendingValueChanged.bind(this);
        this.onMultiSelectChange = this.onMultiSelectChange.bind(this);
        this.onScrollToItem = this.onScrollToItem.bind(this);
        this.setFocus = this.setFocus.bind(this);
        this.onRenderIcon = this.onRenderIcon.bind(this);
        this.onRenderList = this.onRenderList.bind(this);
        this.onInputValueChange = this.onInputValueChange.bind(this);
        this.onExternalSearchDebounce = (0, utilities_1.debounce)((query) => this.props.externalSearchProps?.onExternalSearch?.(query), props.externalSearchProps?.debounceTime ?? 500);
        (0, react_2.initializeComponentRef)(this);
        this.state = {};
        this.collectHiddenOptionKeys(props.options);
    }
    /**
     * Method checks if the options or loading state have changed and a query exists, it updates the hidden options.
     *
     * @param nextProps - The incoming props to compare with current props.
     * @returns Always returns true to allow the component to re-render.
     */
    shouldComponentUpdate(nextProps) {
        const propsDiffers = nextProps.options !== this.props.options;
        if (propsDiffers) {
            this.collectHiddenOptionKeys(nextProps.options);
        }
        if ((propsDiffers || this.isLoaderChanged(this.props.isLoading, nextProps.isLoading)) && this.query) {
            // Filter options
            this.updateHiddenOptions(nextProps.options, nextProps.isLoading);
        }
        return true;
    }
    /**
     * Checks if the loading state has changed between the previous and new loader values.
     *
     * @param prevLoader The previous loading state.
     * @param newLoader The new loading state.
     * @returns True if the loading state has changed.
     */
    isLoaderChanged(prevLoader, newLoader) {
        return !!prevLoader !== !!newLoader;
    }
    /**
     * Updates hidden options.
     *
     * @param opts Current combobox options
     * @param isLoading Current combobox loading state
     */
    updateHiddenOptions(opts, isLoading) {
        this.isListHidden = true;
        let currentGroup;
        let isGroupVisible = false;
        const updateGroupVisibility = () => {
            if (currentGroup) {
                currentGroup.hidden = !isGroupVisible;
            }
        };
        for (const option of opts) {
            if (option.itemType === react_2.SelectableOptionMenuItemType.Header) {
                // Update visibility of previously processed group
                updateGroupVisibility();
                // Reset current group and visibility flag
                currentGroup = option;
                isGroupVisible = false;
            }
            else {
                // Handle selectable item
                let isVisible = this.isLoaderApplied(UIComboBoxLoaderType.List, isLoading) ||
                    this.isOptionVisibleByQuery(option, this.query);
                if (this.hiddenOptions.includes(option.key)) {
                    isVisible = false;
                }
                option.hidden = !isVisible;
                if (this.isListHidden && !option.hidden) {
                    this.isListHidden = false;
                }
                // Groups should be visible if at least one item is visible within group
                isGroupVisible = isVisible || isGroupVisible;
            }
        }
        updateGroupVisibility();
    }
    /**
     * Determines whether an option should be hidden based on the current search query.
     * Applies a custom filter if `customSearchFilter` is provided, otherwise uses the default
     * search logic to match the `text` property (and `key` if `searchByKeyEnabled` is enabled).
     *
     * @param option - The option to evaluate for visibility.
     * @param query - The current search query string.
     * @returns `true` if the option should be hidden, `false` if it should be visible.
     */
    isOptionVisibleByQuery(option, query) {
        let isVisible;
        if (this.props.customSearchFilter) {
            // Apply external custom search
            isVisible = this.props.customSearchFilter(query, option);
        }
        if (isVisible === undefined) {
            // Apply internal search
            isVisible = option.text.toLowerCase().includes(query);
            // Consider 'key' of option if property 'searchByKeyEnabled' is enabled
            if (this.props.searchByKeyEnabled && !isVisible) {
                isVisible = option.key.toString().toLowerCase().includes(query);
            }
        }
        return isVisible;
    }
    /**
     * Method prevents cursor from jumping to the end of input.
     *
     * @param {React.FormEvent<IComboBox>} event Combobox event object
     */
    setCaretPosition(event) {
        if ((0, utilities_1.isHTMLInputElement)(event.target)) {
            const input = event.target;
            const selectionEnd = input.selectionEnd;
            if (selectionEnd !== input.value.length) {
                window.requestAnimationFrame(() => {
                    input.selectionStart = selectionEnd;
                    input.selectionEnd = selectionEnd;
                });
            }
        }
    }
    /**
     * Method filters options and hides unmatched options.
     *
     * @param {React.FormEvent<IComboBox>} event Combobox event object
     */
    onInput(event) {
        this.isListHidden = false;
        if ((0, utilities_1.isHTMLInputElement)(event.target)) {
            this.setCaretPosition(event);
            const input = event.target;
            this.query = input.value.trimStart().toLowerCase();
            // Filter options
            const baseCombobox = this.comboBox.current;
            if (baseCombobox) {
                this.updateHiddenOptions(baseCombobox.props.hoisted.currentOptions);
            }
        }
    }
    /**
     * Method opens menu when user clicks on Combobox (input or button).
     *
     * @param event
     */
    onClick(event) {
        this.setCaretPosition(event);
        const baseCombobox = this.comboBox.current;
        const isOpen = baseCombobox?.state.isOpen;
        const isDisabled = this.props.disabled;
        if (this.props.openMenuOnClick && baseCombobox && !isOpen && !isDisabled) {
            baseCombobox.focus(true);
        }
    }
    /**
     * Method handles keydown event and does following.
     * 1. Fix for bug(in fluentui sources) regarding keyboard navigation when last item is not visible.
     * 2. Opens list when user enters any key.
     *
     * @param {React.FormEvent<HTMLInputElement>} event Keydown event
     */
    onKeyDown(event) {
        let handled = false;
        const baseCombobox = this.comboBox.current;
        const isOpen = baseCombobox?.state.isOpen;
        if (event.which === react_2.KeyCodes.down || event.which === react_2.KeyCodes.up) {
            handled = this._setCyclingNavigation(event.which === react_2.KeyCodes.down);
        }
        if (handled) {
            // Do not handle keydown of combobox
            event.preventDefault();
            event.stopPropagation();
        }
        else if (!this.ignoreOpenKeys.includes(event.key) && baseCombobox && !isOpen) {
            // Open dropdown list on first key press instead of showing it right after focus
            baseCombobox.focus(true);
        }
    }
    /**
     * Method resets search query.
     */
    reserQuery() {
        this.query = '';
        for (const option of this.props.options) {
            if (!this.hiddenOptions.includes(option.key)) {
                delete option.hidden;
            }
        }
        this.isListHidden = false;
        this.setState({
            isListHidden: this.isListHidden
        });
    }
    /**
     * Method which determines what is next visible item - it is used to fix bug in fluentui sources..
     *
     * @param {number} index Current index.
     * @param {boolean} forward Dirrection to look up.
     * @returns {ComboboxItemInfo | null} Combobox item object.
     */
    getNextVisibleItem(index, forward) {
        const limit = this.props.options.length;
        while (index >= 0 && index < limit) {
            if (this.props.options[index] && !this.props.options[index].hidden) {
                return {
                    option: this.props.options[index],
                    index
                };
            }
            index = index + (forward ? 1 : -1);
        }
        return null;
    }
    /**
     * Method is used as fix for bug(in fluentui sources) regarding keyboard navigation when last item is not visible.
     *
     * @param {boolean} forward Dirrection to look up.
     * @returns {boolean} Returs true if method changed navigation.
     */
    _setCyclingNavigation(forward) {
        const baseCombobox = this.comboBox.current;
        if (baseCombobox && baseCombobox.state.currentPendingValueValidIndex >= 0) {
            // Check if there exists any visible item in that direction
            let index = baseCombobox.state.currentPendingValueValidIndex;
            const limit = this.props.options.length - 1;
            index = index + (forward ? 1 : -1);
            let option = this.getNextVisibleItem(index, forward);
            if (option) {
                // Item exists - no need for custom logic as we are fixing issue in base control
                return false;
            }
            // Item was not found - make circular navigation
            option = this.getNextVisibleItem(forward ? 0 : limit, forward);
            if (option) {
                // We fixed issue in base combobox control -
                //   when last item is not visible and we navigate it
                baseCombobox.setState({
                    currentPendingValueValidIndex: option.index,
                    currentPendingValue: option.option.text
                });
                return true;
            }
        }
        return false;
    }
    /**
     * Method for property 'useComboBoxAsMenuMinWidth' - method resolves current dropdown width and updates state with latest value.
     * 'minWidth' from state is used to set callout size in render.
     */
    calculateMenuMinWidth() {
        const comboBoxWrapper = this.comboBox.current?._comboBoxWrapper.current;
        if (comboBoxWrapper &&
            this.props.useComboBoxAsMenuMinWidth &&
            comboBoxWrapper.clientWidth !== this.state.minWidth) {
            this.setState({
                minWidth: comboBoxWrapper.clientWidth
            });
        }
    }
    /**
     * Method called only when property 'highlight' is true.
     * Method called after each value live change - we need recheck if there is any visible item after search is done.
     * 1. If there no any visible item - we hide menu callout.
     * 2. If there is any visible item - we show menu callout.
     *
     * @param option Selected option.
     * @param index Selected option's index.
     * @param value Text value entered in input.
     */
    onPendingValueChanged(option, index, value) {
        if (this.state.isListHidden !== this.isListHidden) {
            this.setState({
                isListHidden: this.isListHidden
            });
        }
        if (this.props?.onPendingValueChanged) {
            this.props?.onPendingValueChanged(option, index, value);
        }
    }
    /**
     * Public method to close menu callout if it is open.
     */
    dismissMenu() {
        if (this.comboBox.current) {
            this.comboBox.current.dismissMenu();
        }
    }
    /**
     * Public method to set the focus on the combo box.
     */
    setFocus() {
        if (this.comboBox.current) {
            this.comboBox.current.focus();
        }
    }
    /**
     * Method called only when property 'onRefresh' has been defined.
     * It is called when click on the refresh buttonIcon.
     */
    handleRefreshButton() {
        const baseCombobox = this.comboBox.current;
        if (this.props.useComboBoxAsMenuMinWidth) {
            this.calculateMenuMinWidth();
        }
        if (this.props.onRefresh) {
            this.props.onRefresh();
            baseCombobox?.focus(true);
        }
    }
    /**
     * Handle multiselect change by avoiding 'blur' event.
     * Problem is that blur event uses suggested value and toggles selection for it.
     *
     * @param {React.FormEvent<IComboBox>} event on change
     * @param {IComboBoxOption} option changed option
     * @param {number} index option index
     * @param {string} value changed value
     */
    onMultiSelectChange(event, option, index, value) {
        // Ignore toggle if change triggered by blur
        if (this.props.onChange && event.type !== 'blur') {
            this.props.onChange(event, option, index, value);
        }
    }
    /**
     * Method is used to fix bug in fluent ui.
     * Bug is for multiselect combobox - when keyboard navigation is used, then scrollbar position is not updated to make selected option visible in viewport.
     */
    onScrollToItem() {
        // Multi select only
        const selectedElement = this.selectedElement.current;
        if (!this.props.multiSelect || !selectedElement) {
            return;
        }
        const offsetParent = selectedElement.offsetParent;
        if (offsetParent) {
            const size = offsetParent.clientHeight;
            const scrollSize = offsetParent.scrollHeight;
            if (scrollSize > size) {
                const elementTop = selectedElement.offsetTop;
                const elementBottom = elementTop + selectedElement.clientHeight;
                const scrollTop = offsetParent.scrollTop;
                const scrollBottom = scrollTop + size;
                if (!(elementTop >= scrollTop && elementBottom <= scrollBottom)) {
                    // Outline node is not visible in viewport
                    const diff = elementBottom > scrollBottom ? elementBottom - scrollBottom : elementTop - scrollTop;
                    offsetParent.scrollTop = scrollTop + diff;
                }
            }
        }
    }
    /**
     * Method returns class names string depending on props and component state.
     *
     * @param {InputValidationMessageInfo} messageInfo Error/warning message if applied
     * @returns {string} Class names of root combobox element.
     */
    getClassNames(messageInfo) {
        const { readOnly, disabled } = this.props;
        const errorSuffix = messageInfo.message ? ValidationMessage_1.MESSAGE_TYPES_CLASSNAME_MAP.get(messageInfo.type) : undefined;
        let classNames = `ts-ComboBox${messageInfo.message ? ' ts-ComboBox--' + errorSuffix : ''}`;
        if (readOnly && !disabled) {
            classNames += ' ts-ComboBox--readonly';
        }
        if (disabled) {
            classNames += ' ts-ComboBox--disabled';
        }
        if ((0, UIDropdown_1.isDropdownEmpty)(this.props)) {
            classNames += ' ts-ComboBox--empty';
        }
        return classNames;
    }
    /**
     * Method returns properties for Autofill component(combobox's inner compnent for text input).
     * Method handles 'highlight' and 'readOnly' properties.
     *
     * @returns {IAutofillProps} Properties for Autofill component.
     */
    getAutofillProps() {
        const { highlight, readOnly, disabled } = this.props;
        const autofill = {};
        // Handle search highligh
        if (highlight) {
            autofill.onKeyDownCapture = this.onKeyDown;
        }
        const tabIndex = 'tabIndex' in this.props ? this.props.tabIndex : undefined;
        // Handle readOnly property
        if (readOnly && !disabled) {
            autofill.readOnly = readOnly;
            autofill.tabIndex = tabIndex;
            // Adjust aria attributes for readonly
            autofill['aria-disabled'] = undefined;
            autofill['aria-readonly'] = true;
        }
        else if (disabled) {
            autofill.disabled = undefined;
            autofill.readOnly = true;
            autofill.tabIndex = tabIndex;
        }
        // This is a workaround for FluentUI not handling aria-invalid correctly for a ComboBox.
        // For the time being we add logic here to set aria-invalid based on the presence of
        // an errorMessage.
        autofill['aria-invalid'] = this.props.errorMessage !== undefined && this.props.errorMessage !== '';
        return autofill;
    }
    /**
     * Method returns if loader should be displayed for passed type.
     *
     * @param type Loader's place
     * @param isLoading Current combobox loading state
     * @returns True if loader should be displayed for passed type.
     */
    isLoaderApplied(type, isLoading = this.props.isLoading) {
        if (Array.isArray(isLoading)) {
            return isLoading.includes(type);
        }
        // Boolean value matches List option
        return !!isLoading && type === UIComboBoxLoaderType.List;
    }
    /**
     * Method renders dropdown expand icon.
     * Overwritten renderer to replace expand icon with loader when combobox has laoding property set.
     *
     * @param props Button properties
     * @param defaultRender Default icon renderer
     * @returns React element to render.
     */
    onRenderIcon(props, defaultRender) {
        if (this.isLoaderApplied(UIComboBoxLoaderType.Input)) {
            const styles = {
                label: {
                    fontSize: '11px',
                    fontWeight: 'normal'
                }
            };
            return react_1.default.createElement(UILoader_1.UILoader, { className: "uiLoaderXSmall", labelPosition: "right", styles: styles });
        }
        return defaultRender?.(props) ?? null;
    }
    /**
     * Called when the user types in to the input of the combo box.
     *
     * @param text The current input value typed by the user.
     */
    onInputValueChange(text) {
        const { onInputValueChange, externalSearchProps } = this.props;
        // Call external cb from props
        onInputValueChange?.(text);
        if (externalSearchProps) {
            const { onExternalSearch, onInputChange } = externalSearchProps;
            onInputChange?.(text);
            if (onExternalSearch) {
                this.onExternalSearchDebounce(text);
            }
        }
    }
    /**
     * Collects and stores the keys of all hidden combo box options.
     *
     * @param options The list of combo box options to scan for hidden entries.
     */
    collectHiddenOptionKeys(options) {
        this.hiddenOptions = [];
        for (const option of options) {
            if (option.hidden) {
                this.hiddenOptions.push(option.key);
            }
        }
    }
    /**
     * @returns {JSX.Element}
     */
    render() {
        const messageInfo = (0, ValidationMessage_1.getMessageInfo)(this.props);
        let disabled = this.props.isForceEnabled ? false : !this.props.options.length;
        if (this.props.readOnly) {
            disabled = true;
        }
        return (react_1.default.createElement("div", { ref: this.props.wrapperRef, className: this.getClassNames(messageInfo) },
            react_1.default.createElement(react_2.ComboBox, { componentRef: this.comboBox, ref: this.comboboxDomRef, disabled: disabled, iconButtonProps: {
                    iconProps: {
                        iconName: Icons_1.UiIcons.ArrowDown
                    },
                    onRenderIcon: this.onRenderIcon
                }, styles: {
                    label: {
                        ...UILabel_1.labelGlobalStyle,
                        ...(this.props.disabled && {
                            opacity: '0.4'
                        }),
                        ...(this.props.required && {
                            selectors: {
                                '::after': {
                                    content: types_1.REQUIRED_LABEL_INDICATOR,
                                    color: 'var(--vscode-inputValidation-errorBorder)',
                                    paddingRight: 12
                                }
                            }
                        })
                    },
                    errorMessage: [messageInfo.style]
                }, ...this.props, calloutProps: {
                    calloutMaxHeight: 200,
                    popupProps: {
                        ref: this.menuDomRef
                    },
                    className: 'ts-Callout ts-Callout-Dropdown',
                    styles: {
                        ...(this.props.useComboBoxAsMenuMinWidth && {
                            calloutMain: {
                                minWidth: this.state.minWidth,
                                display: this.state.isListHidden && !this.props.externalSearchProps?.noDataLabel
                                    ? 'none'
                                    : undefined
                            }
                        })
                    },
                    ...this.props.calloutProps,
                    ...(0, UIDropdown_1.getCalloutCollisionTransformationPropsForDropdown)(this, this.calloutCollisionTransform)
                }, ...(this.props.highlight && {
                    onInput: this.onInput,
                    onMenuDismissed: this.reserQuery,
                    onResolveOptions: this.onResolveOptions,
                    onRenderItem: this.onRenderItem,
                    onRenderOption: this.onRenderOption,
                    placeholder: this.getPlaceholder(),
                    onPendingValueChanged: this.onPendingValueChanged
                }), autofill: this.getAutofillProps(), ...(this.props.useComboBoxAsMenuMinWidth && {
                    // Use 'onMenuOpen', because there can be dynamic size of combobox
                    onMenuOpen: this.calculateMenuMinWidth.bind(this)
                }), ...(this.props.openMenuOnClick && {
                    onClick: this.onClick.bind(this)
                }), ...(this.props.onRefresh && {
                    onMenuOpen: this.handleRefreshButton,
                    onChange: this.handleChange
                }), onRenderList: this.onRenderList, ...(this.props.multiSelect && {
                    onScrollToItem: this.onScrollToItem,
                    ...(this.props.onChange && {
                        onChange: this.onMultiSelectChange
                    })
                }), errorMessage: messageInfo.message, onInputValueChange: this.onInputValueChange })));
    }
}
exports.UIComboBox = UIComboBox;
// Default values for public component properties
UIComboBox.defaultProps = { openMenuOnClick: true };
//# sourceMappingURL=UIComboBox.js.map