"use strict";

var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
exports.__esModule = true;
exports.default = void 0;
var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
var _objectWithoutProperties2 = _interopRequireDefault(require("@babel/runtime/helpers/objectWithoutProperties"));
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
var _react = _interopRequireWildcard(require("react"));
var _uniqueId = _interopRequireDefault(require("lodash/uniqueId"));
var _DropdownBaseSt = require("./DropdownBase.st.css.js");
var _DropdownLayout = _interopRequireDefault(require("../DropdownLayout"));
var _PopoverNext = _interopRequireDefault(require("../PopoverNext"));
var _context = require("../WixDesignSystemProvider/context");
var _Drawer = _interopRequireDefault(require("../Drawer"));
var _excluded = ["onShow", "onHide"];
var _jsxFileName = "/home/builduser/work/57e038ea7326c1ec/packages/wix-design-system/dist/cjs/DropdownBase/DropdownBase.tsx";
function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function _interopRequireWildcard(e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (var _t in e) "default" !== _t && {}.hasOwnProperty.call(e, _t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, _t)) && (i.get || i.set) ? o(f, _t, i) : f[_t] = e[_t]); return f; })(e, t); }
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { (0, _defineProperty2.default)(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
class DropdownBase extends _react.PureComponent {
  constructor(_props) {
    var _ref, _this$props$selectedI, _this;
    super(_props);
    _this = this;
    this.triggerElementRef = void 0;
    this.uniqueId = (0, _uniqueId.default)('DropdownBase');
    this._dropdownLayoutRef = null;
    this._shouldCloseOnMouseLeave = false;
    this.state = {
      open: this.props.open,
      selectedId: (_ref = (_this$props$selectedI = this.props.selectedId) !== null && _this$props$selectedI !== void 0 ? _this$props$selectedI : this.props.initialSelectedId) !== null && _ref !== void 0 ? _ref : -1,
      activeDescendantId: undefined,
      listAutoFocus: false
    };
    /**
     * Return `true` if the `open` prop is being controlled
     */
    this._isControllingOpen = function () {
      var props = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : _this.props;
      return typeof props.open !== 'undefined';
    };
    /**
     * Return `true` if the selection behaviour is being controlled
     */
    this._isControllingSelection = function () {
      var props = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : _this.props;
      return typeof props.selectedId !== 'undefined' && typeof props.onSelect !== 'undefined';
    };
    this._setIsOpen = (isOpen, _, newState) => {
      if (!this._isControllingOpen()) {
        this.setState(_objectSpread(_objectSpread({}, newState), {}, {
          open: isOpen,
          listAutoFocus: false
        }));
      }
    };
    this._handleClickOutside = () => {
      var {
        onClickOutside
      } = this.props;
      onClickOutside && onClickOutside();
    };
    this._handlePopoverMouseEnter = renderedTrigger => {
      var {
        onMouseEnter
      } = this.props;
      if (/*#__PURE__*/_react.default.isValidElement(renderedTrigger) && renderedTrigger.props.onMouseEnter) {
        renderedTrigger.props.onMouseEnter();
      }
      onMouseEnter && onMouseEnter();
    };
    this._handlePopoverMouseLeave = renderedTrigger => {
      var {
        onMouseLeave
      } = this.props;
      if (this._shouldCloseOnMouseLeave) {
        this._shouldCloseOnMouseLeave = false;
        this.setState({
          open: false,
          activeDescendantId: undefined
        });
      }
      if (/*#__PURE__*/_react.default.isValidElement(renderedTrigger) && renderedTrigger.props.onMouseLeave) {
        renderedTrigger.props.onMouseLeave();
      }
      onMouseLeave && onMouseLeave();
    };
    this._handleSelect = selectedOption => {
      var newState = {};
      this._close();
      if (!this._isControllingSelection()) {
        newState.selectedId = selectedOption.id;
      }
      this.setState(newState, () => {
        var {
          onSelect
        } = this.props;
        onSelect && onSelect(selectedOption);
      });
    };
    this._handleOptionMarked = (_option, optionElementId) => {
      this.setState({
        activeDescendantId: optionElementId
      });
    };
    this._open = () => {
      this._setIsOpen(true);
    };
    this._close = () => {
      this._setIsOpen(false);
    };
    this._handleClose = () => {
      if (this.state.open) {
        this._close();
      }
      if (this.triggerElementRef && this.triggerElementRef.current && this.triggerElementRef.current.focus) {
        this.triggerElementRef.current.focus();
      }
    };
    this._getSelectedOption = selectedId => {
      var _this$props$options;
      return (_this$props$options = this.props.options) == null ? void 0 : _this$props$options.find(_ref2 => {
        var {
          id
        } = _ref2;
        return id === selectedId;
      });
    };
    /**
     * Determine if a certain key should open the DropdownLayout
     */
    this._isOpenKey = key => {
      return ['Enter', ' ', 'ArrowDown'].includes(key);
    };
    this._isClosingKey = key => {
      if (this._isDialogMode()) {
        return ['Escape'].includes(key);
      }
      return ['Tab', 'Escape'].includes(key);
    };
    /**
     * A common `keydown` event that can be used for the target elements. It will automatically
     * delegate the event to the underlying <DropdownLayout/>, and will determine when to open the
     * dropdown depending on the pressed key.
     */
    this._handleKeyDown = e => {
      if (this._isControllingOpen()) {
        return;
      }
      var isHandledByDropdownLayout = this._delegateKeyDown(e);
      if (!isHandledByDropdownLayout) {
        if (this._isOpenKey(e.key) && !this.state.open) {
          this.setState({
            listAutoFocus: true
          });
          this._open();
          e.preventDefault();
        } else if (this._isClosingKey(e.key) && this.state.open) {
          // Fallback: handle closing keys when DropdownLayout doesn't process them
          // This happens in action list mode where DropdownLayout returns false immediately
          // for container-level keydown events (listType !== ListType.select check)
          this._close();
        }
      }
      // Prevent trigger element events when dropdown is open.
      if (this.state.open && (e.key === 'Enter' || e.key === ' ') && !this._isEventFromFixedRegion(e)) {
        e.preventDefault();
      }
    };
    /*
     * Delegate the event to the DropdownLayout. It'll handle the navigation, option selection and
     * closing of the dropdown.
     */
    this._delegateKeyDown = e => {
      if (!this._dropdownLayoutRef) {
        return false;
      }
      return this._dropdownLayoutRef._onSelectListKeyDown(e);
    };
    this._setDropdownLayoutRef = ref => {
      var _this$_dropdownLayout;
      this._dropdownLayoutRef = ref;
      this.setState({
        activeDescendantId: (_this$_dropdownLayout = this._dropdownLayoutRef) == null ? void 0 : _this$_dropdownLayout.getActiveDescendentElementId()
      });
    };
    this._handleOutsideClick = (_, reason) => {
      if (reason === 'outside-press') {
        this._setIsOpen(false, reason);
        return;
      }
    };
    this._isDialogMode = () => {
      /** This component has two modes:
       *  1. Menu mode: when fixedHeader or fixedFooter is not present - https://www.w3.org/WAI/ARIA/apg/patterns/menubar/
       *  2. Dialog mode: when fixedHeader or fixedFooter is present - https://www.w3.org/WAI/ARIA/apg/patterns/dialog-modal/
       */
      var {
        fixedHeader,
        fixedFooter
      } = this.props;
      return Boolean(fixedHeader || fixedFooter);
    };
    this._isEventFromFixedRegion = event => {
      var target = event.target;
      var region = target.closest('[data-dropdown-region]');
      if (!region) {
        return false;
      }
      var regionValue = region.getAttribute('data-dropdown-region');
      return regionValue === 'header' || regionValue === 'footer';
    };
    this.triggerElementRef = /*#__PURE__*/_react.default.createRef();
  }
  UNSAFE_componentWillReceiveProps(nextProps) {
    // Keep internal state updated if needed
    if (this._isControllingOpen(nextProps) && this.props.open !== nextProps.open) {
      this.setState({
        open: nextProps.open
      });
    }
    if (this._isControllingSelection(nextProps) && this.props.selectedId !== nextProps.selectedId) {
      this.setState({
        selectedId: nextProps.selectedId
      });
    }
  }
  _renderChildren(renderedTrigger) {
    var {
      children
    } = this.props;
    if (!children) {
      return null;
    }
    return /*#__PURE__*/_react.default.isValidElement(children) ? children : /*#__PURE__*/_react.default.isValidElement(renderedTrigger) ? /*#__PURE__*/_react.default.cloneElement(renderedTrigger, _objectSpread(_objectSpread({}, renderedTrigger.props.onMouseEnter ? {
      onMouseEnter: () => {}
    } : {}), renderedTrigger.props.onMouseLeave ? {
      onMouseLeave: () => {}
    } : {})) : renderedTrigger;
  }
  _renderDropdownLayout() {
    var {
      options,
      maxHeight,
      overflow,
      focusOnSelectedOption,
      infiniteScroll,
      loadMore,
      hasMore,
      focusOnOption,
      markedOption,
      scrollToOption,
      onMouseDown,
      listType,
      autoFocus,
      fixedHeader,
      fixedFooter
    } = this.props;
    var {
      selectedId
    } = this.state;
    return /*#__PURE__*/_react.default.createElement(_DropdownLayout.default, {
      dataHook: "dropdown-base-dropdownlayout",
      className: _DropdownBaseSt.classes.list,
      ref: this._setDropdownLayoutRef,
      selectedId: selectedId,
      options: options,
      maxHeightPixels: maxHeight,
      onSelect: this._handleSelect,
      onOptionMarked: this._handleOptionMarked,
      onClose: this._handleClose,
      inContainer: true,
      visible: true,
      overflow: overflow,
      focusOnSelectedOption: focusOnSelectedOption,
      infiniteScroll: infiniteScroll,
      loadMore: loadMore,
      hasMore: hasMore,
      focusOnOption: focusOnOption,
      markedOption: markedOption,
      scrollToOption: scrollToOption,
      onMouseDown: onMouseDown,
      listType: listType
      // In dialog mode, FloatingFocusManager handles initial focus
      // In menu mode, DropdownLayout focuses the first option
      ,
      autoFocus: this._isDialogMode() ? false : autoFocus || this.state.listAutoFocus,
      fixedHeader: fixedHeader,
      fixedFooter: fixedFooter,
      listboxId: "".concat(this.uniqueId, "-listbox"),
      __self: this,
      __source: {
        fileName: _jsxFileName,
        lineNumber: 326,
        columnNumber: 7
      }
    });
  }
  render() {
    var {
      dataHook,
      placement,
      appendTo,
      showArrow,
      zIndex,
      moveBy,
      minWidth,
      maxWidth,
      width,
      fixed,
      flip,
      dynamicWidth,
      fluid,
      animate,
      className,
      listType,
      popoverContentClassName,
      onMouseEnter,
      onMouseLeave,
      selectedId,
      children
    } = this.props;
    var {
      open,
      activeDescendantId
    } = this.state;
    var _this$props = this.props,
      {
        onShow,
        onHide
      } = _this$props,
      popoverProps = (0, _objectWithoutProperties2.default)(_this$props, _excluded);
    var renderedTrigger = typeof children === 'function' ? children({
      toggle: Boolean(open) ? this._close : this._open,
      open: this._open,
      close: this._close,
      isOpen: Boolean(open),
      ref: this.triggerElementRef,
      delegateKeyDown: this._delegateKeyDown,
      selectedOption: this._getSelectedOption(selectedId),
      listboxId: "".concat(this.uniqueId, "-listbox"),
      activeDescendantId
    }) : children;
    return /*#__PURE__*/_react.default.createElement(_context.WixDesignSystemContext.Consumer, {
      __self: this,
      __source: {
        fileName: _jsxFileName,
        lineNumber: 403,
        columnNumber: 7
      }
    }, _ref3 => {
      var {
        mobile
      } = _ref3;
      return mobile ? /*#__PURE__*/_react.default.createElement("div", {
        __self: this,
        __source: {
          fileName: _jsxFileName,
          lineNumber: 406,
          columnNumber: 13
        }
      }, /*#__PURE__*/_react.default.createElement("div", {
        __self: this,
        __source: {
          fileName: _jsxFileName,
          lineNumber: 407,
          columnNumber: 15
        }
      }, this._renderChildren(renderedTrigger)), /*#__PURE__*/_react.default.createElement(_Drawer.default, {
        dataHook: dataHook,
        open: Boolean(open),
        onClose: isOpen => this._setIsOpen(isOpen),
        zIndex: zIndex,
        __self: this,
        __source: {
          fileName: _jsxFileName,
          lineNumber: 408,
          columnNumber: 15
        }
      }, /*#__PURE__*/_react.default.createElement("div", {
        className: _DropdownBaseSt.classes.drawerContent,
        __self: this,
        __source: {
          fileName: _jsxFileName,
          lineNumber: 414,
          columnNumber: 17
        }
      }, this._renderDropdownLayout()))) : /*#__PURE__*/_react.default.createElement(_PopoverNext.default, (0, _extends2.default)({
        dataListType: listType,
        onOpenChange: this._handleOutsideClick,
        animate: animate,
        dataHook: dataHook,
        open: open
      }, popoverProps, {
        // backward compatible for migration stylable 1 to stylable 3
        placement: placement,
        dynamicWidth: dynamicWidth,
        appendTo: appendTo,
        showArrow: showArrow,
        zIndex: zIndex,
        moveBy: moveBy,
        onKeyDown: this._handleKeyDown,
        onMouseEnter: onMouseEnter || !!(/*#__PURE__*/_react.default.isValidElement(renderedTrigger) && renderedTrigger.props.onMouseEnter) ? () => this._handlePopoverMouseEnter(renderedTrigger) : undefined,
        onMouseLeave: onMouseLeave || !!(/*#__PURE__*/_react.default.isValidElement(renderedTrigger) && renderedTrigger.props.onMouseLeave) ? () => this._handlePopoverMouseLeave(renderedTrigger) : undefined,
        onClickOutside: this._handleClickOutside,
        fixed: fixed,
        flip: flip,
        fluid: fluid,
        onHide: onHide,
        onShow: onShow,
        focusManagerEnabled: this._isDialogMode(),
        className: (0, _DropdownBaseSt.st)(_DropdownBaseSt.classes.root, {
          withWidth: Boolean(minWidth || maxWidth)
        }, className),
        minWidth: minWidth,
        maxWidth: maxWidth,
        width: width,
        __self: this,
        __source: {
          fileName: _jsxFileName,
          lineNumber: 420,
          columnNumber: 13
        }
      }), /*#__PURE__*/_react.default.createElement(_PopoverNext.default.Trigger, {
        className: _DropdownBaseSt.classes.trigger,
        __self: this,
        __source: {
          fileName: _jsxFileName,
          lineNumber: 470,
          columnNumber: 15
        }
      }, /*#__PURE__*/_react.default.createElement("div", {
        __self: this,
        __source: {
          fileName: _jsxFileName,
          lineNumber: 471,
          columnNumber: 17
        }
      }, this._renderChildren(renderedTrigger))), /*#__PURE__*/_react.default.createElement(_PopoverNext.default.Content, {
        className: (0, _DropdownBaseSt.st)(_DropdownBaseSt.classes.content, popoverContentClassName, {
          withWidth: Boolean(minWidth || maxWidth)
        }),
        __self: this,
        __source: {
          fileName: _jsxFileName,
          lineNumber: 474,
          columnNumber: 15
        }
      }, /*#__PURE__*/_react.default.createElement("div", {
        style: {
          minWidth,
          maxWidth
        },
        __self: this,
        __source: {
          fileName: _jsxFileName,
          lineNumber: 479,
          columnNumber: 17
        }
      }, this._renderDropdownLayout())));
    });
  }
}
DropdownBase.displayName = 'DropdownBase';
DropdownBase.defaultProps = {
  placement: 'bottom',
  appendTo: 'parent',
  showArrow: false,
  maxHeight: '260px',
  dynamicWidth: true,
  minWidth: 192,
  fluid: false,
  animate: false,
  listType: 'select',
  onShow: () => {},
  onHide: () => {},
  onMouseEnter: () => {},
  onMouseLeave: () => {}
};
var _default = exports.default = DropdownBase;
//# sourceMappingURL=DropdownBase.js.map