var __assign = (this && this.__assign) || function () {
    __assign = Object.assign || function(t) {
        for (var s, i = 1, n = arguments.length; i < n; i++) {
            s = arguments[i];
            for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
                t[p] = s[p];
        }
        return t;
    };
    return __assign.apply(this, arguments);
};
var __rest = (this && this.__rest) || function (s, e) {
    var t = {};
    for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
        t[p] = s[p];
    if (s != null && typeof Object.getOwnPropertySymbols === "function")
        for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
            if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
                t[p[i]] = s[p[i]];
        }
    return t;
};
import { Clear } from '@procore/core-icons/dist';
import { isNil } from 'ramda';
import React from 'react';
import { OverflowObserver } from '../../effects/OverflowObserver';
import { Box } from '../../layouts/Box';
import { addSubcomponents } from '../../utils/addSubcomponents';
import { MenuImperative } from '../MenuImperative';
import { Notation } from '../Notation';
import { OverlayTrigger, useOverlayTriggerContext } from '../OverlayTrigger';
import { Spinner } from '../Spinner';
import { Tooltip } from '../Tooltip';
import { StyledSelectArrow, StyledSelectArrowContainer, StyledSelectButton, StyledSelectButtonLabel, StyledSelectClearIcon, StyledSelectMenu, StyledSelectSpinner, } from './Select.styles';
function noop() { }
export var OptGroup = React.forwardRef(function (props, ref) { return (React.createElement(MenuImperative.Group, __assign({}, props, { clickable: false, ref: ref }))); });
export var Option = React.forwardRef(function (_a, ref) {
    var value = _a.value, props = __rest(_a, ["value"]);
    return (React.createElement(MenuImperative.Item, __assign({ ref: ref }, props, { item: value })));
});
export var Button = React.forwardRef(function Button(_a, ref) {
    var _b = _a.block, block = _b === void 0 ? false : _b, children = _a.children, clearRef = _a.clearRef, _c = _a.disabled, disabled = _c === void 0 ? false : _c, _d = _a.error, error = _d === void 0 ? false : _d, label = _a.label, _e = _a.loading, loading = _e === void 0 ? false : _e, onClear = _a.onClear, _f = _a.open, open = _f === void 0 ? false : _f, placeholder = _a.placeholder, qa = _a.qa, _g = _a.tabIndex, tabIndex = _g === void 0 ? 0 : _g, _h = _a.isMenuOpened, isMenuOpened = _h === void 0 ? false : _h, props = __rest(_a, ["block", "children", "clearRef", "disabled", "error", "label", "loading", "onClear", "open", "placeholder", "qa", "tabIndex", "isMenuOpened"]);
    var hasClearIcon = !disabled && !loading && Boolean(label);
    var content = children || label || placeholder;
    return (React.createElement(StyledSelectButton, __assign({ ref: ref, tabIndex: disabled ? -1 : tabIndex, role: "button", "$block": block, "$error": error, "$disabled": disabled, "$hasClearIcon": hasClearIcon, "$loading": loading, "$open": open, "$placeholder": !label }, props),
        React.createElement(OverflowObserver, null, function (_a) {
            var isOverflowingX = _a.isOverflowingX, overflowRef = _a.ref;
            var showTooltip = !disabled && isOverflowingX && !isMenuOpened;
            var trigger = (React.createElement(StyledSelectButtonLabel, { "data-qa": qa === null || qa === void 0 ? void 0 : qa.label, "$hoverable": showTooltip, ref: overflowRef }, content));
            return showTooltip ? (React.createElement(Tooltip, { trigger: "hover", overlay: content }, trigger)) : (trigger);
        }),
        onClear && (React.createElement(StyledSelectClearIcon, { ref: clearRef, "data-qa": (qa === null || qa === void 0 ? void 0 : qa.clear) || 'core-select-clear', size: "sm", variant: "tertiary", icon: React.createElement(Clear, null), onClick: onClear, onMouseDown: function (e) { return e.preventDefault(); }, tabIndex: -1 })),
        loading ? (React.createElement(StyledSelectSpinner, null,
            React.createElement(Spinner, { size: "xs" }))) : (React.createElement(StyledSelectArrowContainer, null,
            React.createElement(StyledSelectArrow, null)))));
});
var SelectMenu = React.forwardRef(function SelectMenu(_a, ref) {
    var onSearch_ = _a.onSearch, footer = _a.footer, emptyMessage = _a.emptyMessage, optionsRef = _a.optionsRef, children = _a.children, i18nScope = _a.i18nScope, _b = _a.onSelect, onSelect_ = _b === void 0 ? noop : _b, menuRef = _a.menuRef, props = __rest(_a, ["onSearch", "footer", "emptyMessage", "optionsRef", "children", "i18nScope", "onSelect", "menuRef"]);
    var ctx = useOverlayTriggerContext();
    var _c = React.useState(''), searchValue = _c[0], setSearchValue = _c[1];
    React.useEffect(function () {
        var _a;
        (_a = menuRef.current) === null || _a === void 0 ? void 0 : _a.highlightFirst();
    }, [menuRef, searchValue]);
    React.useEffect(function () {
        var _a, _b;
        (_a = menuRef.current) === null || _a === void 0 ? void 0 : _a.highlightSuggested();
        (_b = menuRef.current) === null || _b === void 0 ? void 0 : _b.highlightSelected();
    }, [menuRef]);
    function onSelect(selection) {
        onSelect_(selection);
        ctx.hide(selection.event);
    }
    function onSearch(event) {
        setSearchValue(event.target.value);
        onSearch_ === null || onSearch_ === void 0 ? void 0 : onSearch_(event);
    }
    return (React.createElement(StyledSelectMenu, { ref: ref, shadowStrength: 2 },
        React.createElement(MenuImperative, __assign({}, props, { ref: menuRef, onSelect: onSelect, circular: true }),
            onSearch_ && (React.createElement(MenuImperative.Search, { autoComplete: "false", autoFocus: true, i18nScope: i18nScope, onChange: onSearch })),
            React.Children.count(children) ? (React.createElement(MenuImperative.Options, { ref: optionsRef }, children)) : (React.createElement(Box, { padding: "md lg" },
                React.createElement(Notation, { variant: "pagination" }, emptyMessage))),
            footer && React.createElement(MenuImperative.Footer, null, footer))));
});
/**

 We use single selects to allow our users to choose a single option from a list,
 presented in a dropdown. We typically see these selects on forms.

 If you want users to select multiple options, use a multi select, group select,
 and tiered select if you want users to select from a tiered set of options,
 use a tiered select.

 @since 10.19.0

 @see [Storybook](https://procore.github.io/core/latest/?path=/story/select--basic-props)

 @see [Design Guidelines](https://design.procore.com/select)

 */
var Select_ = React.forwardRef(function Select(_a, forwardRef) {
    var _b = _a.afterHide, afterHide_ = _b === void 0 ? noop : _b, _c = _a.afterShow, afterShow_ = _c === void 0 ? noop : _c, _d = _a.beforeHide, beforeHide = _d === void 0 ? function () { return true; } : _d, _e = _a.beforeShow, beforeShow = _e === void 0 ? function () { return true; } : _e, _f = _a.block, block = _f === void 0 ? false : _f, children = _a.children, className = _a.className, _g = _a.disabled, disabled = _g === void 0 ? false : _g, _h = _a.emptyMessage, emptyMessage = _h === void 0 ? 'No results' : _h, _j = _a.error, error = _j === void 0 ? false : _j, footer = _a.footer, _k = _a.hideDelay, hideDelay = _k === void 0 ? 100 : _k, _l = _a.i18nScope, i18nScope = _l === void 0 ? 'core.select' : _l, _m = _a.label, label = _m === void 0 ? '' : _m, _o = _a.loading, loading = _o === void 0 ? false : _o, onClear_ = _a.onClear, _p = _a.onKeyDown, onKeyDown_ = _p === void 0 ? noop : _p, onScrollBottom = _a.onScrollBottom, onSearch = _a.onSearch, _q = _a.onSelect, onSelect = _q === void 0 ? noop : _q, optionsRef = _a.optionsRef, placeholder = _a.placeholder, _r = _a.placement, placement = _r === void 0 ? 'bottom-left' : _r, _s = _a.showDelay, showDelay = _s === void 0 ? 0 : _s, _t = _a.tabIndex, tabIndex = _t === void 0 ? 0 : _t, qa = _a.qa, props = __rest(_a, ["afterHide", "afterShow", "beforeHide", "beforeShow", "block", "children", "className", "disabled", "emptyMessage", "error", "footer", "hideDelay", "i18nScope", "label", "loading", "onClear", "onKeyDown", "onScrollBottom", "onSearch", "onSelect", "optionsRef", "placeholder", "placement", "showDelay", "tabIndex", "qa"]);
    var menuRef = React.useRef(null);
    var overlayTriggerRef = React.useRef(null);
    var ref = forwardRef || overlayTriggerRef;
    var _u = React.useState(false), isMenuOpened = _u[0], setIsMenuOpened = _u[1];
    var clearRef = React.useRef(null);
    function onKeyDown(e) {
        var _a, _b, _c;
        if (e.key === 'Up' || e.key === 'ArrowUp') {
            e.preventDefault();
            (_a = menuRef.current) === null || _a === void 0 ? void 0 : _a.prev();
        }
        else if (e.key === 'Down' || e.key === 'ArrowDown') {
            e.preventDefault();
            (_b = menuRef.current) === null || _b === void 0 ? void 0 : _b.next();
        }
        else if (e.key === 'Enter') {
            e.preventDefault();
            (_c = menuRef.current) === null || _c === void 0 ? void 0 : _c.select(e);
        }
        onKeyDown_(e);
    }
    function afterHide() {
        afterHide_();
        setIsMenuOpened(false);
        onSearch === null || onSearch === void 0 ? void 0 : onSearch({
            target: { value: '' },
        });
    }
    var onClear = React.useCallback(function (e) {
        var _a;
        onClear_ === null || onClear_ === void 0 ? void 0 : onClear_(e);
        // IE 11 fix
        // Return focus back to trigger instead of the clear button
        (_a = overlayTriggerRef === null || overlayTriggerRef === void 0 ? void 0 : overlayTriggerRef.current) === null || _a === void 0 ? void 0 : _a.focus();
    }, [onClear_]);
    function afterShow() {
        afterShow_();
        setIsMenuOpened(true);
    }
    return (React.createElement(OverlayTrigger, { afterHide: afterHide, afterShow: afterShow, beforeHide: function (e) {
            if (e.target === clearRef.current) {
                return false;
            }
            return beforeHide(e);
        }, beforeShow: beforeShow, canFlip: true, hideDelay: hideDelay, overlay: React.createElement(SelectMenu, { onSearch: onSearch, footer: footer, emptyMessage: emptyMessage, optionsRef: optionsRef, i18nScope: i18nScope, onSelect: onSelect, onScrollBottom: onScrollBottom, menuRef: menuRef }, children), placement: placement, ref: ref, showDelay: showDelay, trigger: disabled ? 'none' : 'click' },
        React.createElement(Button, __assign({}, props, { block: block, className: className, clearRef: clearRef, disabled: disabled, error: error, label: label, loading: loading, placeholder: placeholder, onKeyDown: onKeyDown, onClear: isNil(onClear_) ? onClear_ : onClear, isMenuOpened: isMenuOpened, tabIndex: tabIndex, qa: qa }))));
});
Select_.displayName = 'Select';
Button.displayName = 'Select.Button';
Option.displayName = 'Select.Option';
OptGroup.displayName = 'Select.OptGroup';
export var Select = addSubcomponents({
    Button: Button,
    Option: Option,
    OptGroup: OptGroup,
}, Select_);
export default Select;
//# sourceMappingURL=Select.js.map