text: define(["require", "exports", "tslib", "react", "../../Utilities", "../../Callout", "../../Checkbox", "../../Button", "../../common/DirectionalHint", "./Dropdown.types", "./utilities/DropdownSizePosCache", "../../FocusZone", "../../Icon", "../../Label", "../../KeytipData", "../../Panel", "../../utilities/decorators/withResponsiveMode", "../../utilities/selectableOption/SelectableOption.types"], function (require, exports, tslib_1, React, Utilities_1, Callout_1, Checkbox_1, Button_1, DirectionalHint_1, Dropdown_types_1, DropdownSizePosCache_1, FocusZone_1, Icon_1, Label_1, KeytipData_1, Panel_1, withResponsiveMode_1, SelectableOption_types_1) {
      "use strict";
      Object.defineProperty(exports, "__esModule", { value: true });
      var getClassNames = Utilities_1.classNamesFunction();
      var DropdownBase = /** @class */ (function (_super) {
          tslib_1.__extends(DropdownBase, _super);
          function DropdownBase(props) {
              var _this = _super.call(this, props) || this;
              _this._host = React.createRef();
              _this._focusZone = React.createRef();
              _this._dropDown = React.createRef();
              _this._scrollIdleDelay = 250 /* ms */;
              _this._sizePosCache = new DropdownSizePosCache_1.DropdownSizePosCache();
              /** Render text in dropdown input */
              _this._onRenderTitle = function (item) {
                  var _a = _this.props.multiSelectDelimiter, multiSelectDelimiter = _a === void 0 ? ', ' : _a;
                  var displayTxt = item.map(function (i) { return i.text; }).join(multiSelectDelimiter);
                  return React.createElement("span", null, displayTxt);
              };
              /** Render placeholder text in dropdown input */
              _this._onRenderPlaceholder = function (props) {
                  if (!_this._placeholder) {
                      return null;
                  }
                  return React.createElement("span", null, _this._placeholder);
              };
              /** Render Callout or Panel container and pass in list */
              _this._onRenderContainer = function (props) {
                  var _a = _this.props, responsiveMode = _a.responsiveMode, calloutProps = _a.calloutProps, panelProps = _a.panelProps, dropdownWidth = _a.dropdownWidth;
                  var isSmall = responsiveMode <= withResponsiveMode_1.ResponsiveMode.medium;
                  var panelStyles = _this._classNames.subComponentStyles
                      ? _this._classNames.subComponentStyles.panel
                      : undefined;
                  return isSmall ? (React.createElement(Panel_1.Panel, tslib_1.__assign({ isOpen: true, isLightDismiss: true, onDismissed: _this._onDismiss, hasCloseButton: false, styles: panelStyles }, panelProps), _this._renderFocusableList(props))) : (React.createElement(Callout_1.Callout, tslib_1.__assign({ isBeakVisible: false, gapSpace: 0, doNotLayer: false, directionalHintFixed: false, directionalHint: DirectionalHint_1.DirectionalHint.bottomLeftEdge }, calloutProps, { className: _this._classNames.callout, target: _this._dropDown.current, onDismiss: _this._onDismiss, onScroll: _this._onScroll, onPositioned: _this._onPositioned, calloutWidth: dropdownWidth || (_this._dropDown.current ? _this._dropDown.current.clientWidth : 0) }), _this._renderFocusableList(props)));
              };
              /** Render Caret Down Icon */
              _this._onRenderCaretDown = function (props) {
                  return React.createElement(Icon_1.Icon, { className: _this._classNames.caretDown, iconName: "ChevronDown" });
              };
              /** Render List of items */
              _this._onRenderList = function (props) {
                  var _a = _this.props.onRenderItem, onRenderItem = _a === void 0 ? _this._onRenderItem : _a;
                  return React.createElement(React.Fragment, null, _this.props.options.map(function (item, index) { return onRenderItem(tslib_1.__assign({}, item, { index: index }), _this._onRenderItem); }));
              };
              _this._onRenderItem = function (item) {
                  switch (item.itemType) {
                      case SelectableOption_types_1.SelectableOptionMenuItemType.Divider:
                          return _this._renderSeparator(item);
                      case SelectableOption_types_1.SelectableOptionMenuItemType.Header:
                          return _this._renderHeader(item);
                      default:
                          return _this._renderOption(item);
                  }
              };
              _this._renderOption = function (item) {
                  var _a = _this.props.onRenderOption, onRenderOption = _a === void 0 ? _this._onRenderOption : _a;
                  var _b = _this.state.selectedIndices, selectedIndices = _b === void 0 ? [] : _b;
                  var id = _this._id;
                  var isItemSelected = item.index !== undefined && selectedIndices ? selectedIndices.indexOf(item.index) > -1 : false;
                  // select the right className based on the combination of selected/disabled
                  var itemClassName = isItemSelected && item.disabled === true // predicate: both selected and disabled
                      ? _this._classNames.dropdownItemSelectedAndDisabled
                      : isItemSelected // predicate: selected only
                          ? _this._classNames.dropdownItemSelected
                          : item.disabled === true // predicate: disabled only
                              ? _this._classNames.dropdownItemDisabled
                              : _this._classNames.dropdownItem;
                  return !_this.props.multiSelect ? (React.createElement(Button_1.CommandButton, { id: id + '-list' + item.index, key: item.key, "data-index": item.index, "data-is-focusable": !item.disabled, disabled: item.disabled, className: itemClassName, onClick: _this._onItemClick(item), onMouseEnter: _this._onItemMouseEnter.bind(_this, item), onMouseLeave: _this._onMouseItemLeave.bind(_this, item), onMouseMove: _this._onItemMouseMove.bind(_this, item), role: "option", "aria-selected": isItemSelected ? 'true' : 'false', ariaLabel: item.ariaLabel, title: item.title ? item.title : item.text }, onRenderOption(item, _this._onRenderOption))) : (React.createElement(Checkbox_1.Checkbox, { id: id + '-list' + item.index, key: item.key, "data-index": item.index, "data-is-focusable": !item.disabled, disabled: item.disabled, onChange: _this._onItemClick(item), inputProps: {
                          onMouseEnter: _this._onItemMouseEnter.bind(_this, item),
                          onMouseLeave: _this._onMouseItemLeave.bind(_this, item),
                          onMouseMove: _this._onItemMouseMove.bind(_this, item)
                      }, label: item.text, title: item.title ? item.title : item.text, onRenderLabel: _this._onRenderLabel.bind(_this, item), className: itemClassName, role: "option", "aria-selected": isItemSelected ? 'true' : 'false', checked: isItemSelected }));
              };
              /** Render content of item (i.e. text/icon inside of button) */
              _this._onRenderOption = function (item) {
                  return React.createElement("span", { className: _this._classNames.dropdownOptionText }, item.text);
              };
              /** Render custom label for drop down item */
              _this._onRenderLabel = function (item) {
                  var _a = _this.props.onRenderOption, onRenderOption = _a === void 0 ? _this._onRenderOption : _a;
                  return onRenderOption(item, _this._onRenderOption);
              };
              _this._onPositioned = function (positions) {
                  if (_this._focusZone.current) {
                      // Focusing an element can trigger a reflow. Making this wait until there is an animation
                      // frame can improve perf significantly.
                      _this._async.requestAnimationFrame(function () {
                          var selectedIndices = _this.state.selectedIndices;
                          if (selectedIndices && selectedIndices[0] && !_this.props.options[selectedIndices[0]].disabled) {
                              var element = Utilities_1.getDocument().querySelector("#" + _this._id + "-list" + selectedIndices[0]);
                              _this._focusZone.current.focusElement(element);
                          }
                          else {
                              _this._focusZone.current.focus();
                          }
                      });
                  }
                  if (!_this.state.calloutRenderEdge || _this.state.calloutRenderEdge !== positions.targetEdge) {
                      _this.setState({
                          calloutRenderEdge: positions.targetEdge
                      });
                  }
              };
              _this._onItemClick = function (item) {
                  return function (event) {
                      if (!item.disabled) {
                          _this.setSelectedIndex(event, item.index);
                          if (!_this.props.multiSelect) {
                              // only close the callout when it's in single-select mode
                              _this.setState({
                                  isOpen: false
                              });
                          }
                      }
                  };
              };
              /**
               * Scroll handler for the callout to make sure the mouse events
               * for updating focus are not interacting during scroll
               */
              _this._onScroll = function () {
                  if (!_this._isScrollIdle && _this._scrollIdleTimeoutId !== undefined) {
                      _this._async.clearTimeout(_this._scrollIdleTimeoutId);
                      _this._scrollIdleTimeoutId = undefined;
                  }
                  else {
                      _this._isScrollIdle = false;
                  }
                  _this._scrollIdleTimeoutId = _this._async.setTimeout(function () {
                      _this._isScrollIdle = true;
                  }, _this._scrollIdleDelay);
              };
              _this._onMouseItemLeave = function (item, ev) {
                  if (_this._shouldIgnoreMouseEvent()) {
                      return;
                  }
                  /**
                   * IE11 focus() method forces parents to scroll to top of element.
                   * Edge and IE expose a setActive() function for focusable divs that
                   * sets the page focus but does not scroll the parent element.
                   */
                  if (_this._host.current) {
                      if (_this._host.current.setActive) {
                          try {
                              _this._host.current.setActive();
                          }
                          catch (e) {
                              /* no-op */
                          }
                      }
                      else {
                          _this._host.current.focus();
                      }
                  }
              };
              _this._onDismiss = function () {
                  _this.setState({ isOpen: false });
                  if (_this._dropDown.current) {
                      _this._dropDown.current.focus();
                  }
              };
              _this._onDropdownBlur = function (ev) {
                  // If Dropdown disabled do not proceed with this logic.
                  var disabled = _this._isDisabled();
                  if (disabled) {
                      return;
                  }
                  // hasFocus tracks whether the root element has focus so always update the state.
                  _this.setState({ hasFocus: false });
                  if (_this.state.isOpen) {
                      // Do not onBlur when the callout is opened
                      return;
                  }
                  if (_this.props.onBlur) {
                      _this.props.onBlur(ev);
                  }
              };
              _this._onDropdownKeyDown = function (ev) {
                  // If Dropdown disabled do not process any keyboard events.
                  var disabled = _this._isDisabled();
                  if (disabled) {
                      return;
                  }
                  // Take note if we are processing an alt (option) or meta (command) keydown.
                  // See comment in _shouldHandleKeyUp for reasoning.
                  _this._lastKeyDownWasAltOrMeta = _this._isAltOrMeta(ev);
                  if (_this.props.onKeyDown) {
                      _this.props.onKeyDown(ev);
                      if (ev.defaultPrevented) {
                          return;
                      }
                  }
                  var newIndex;
                  var selectedIndex = _this.state.selectedIndices.length ? _this.state.selectedIndices[0] : -1;
                  var containsExpandCollapseModifier = ev.altKey || ev.metaKey;
                  var isOpen = _this.state.isOpen;
                  switch (ev.which) {
                      case Utilities_1.KeyCodes.enter:
                          _this.setState({
                              isOpen: !isOpen
                          });
                          break;
                      case Utilities_1.KeyCodes.escape:
                          if (!isOpen) {
                              return;
                          }
                          _this.setState({
                              isOpen: false
                          });
                          break;
                      case Utilities_1.KeyCodes.up:
                          if (containsExpandCollapseModifier) {
                              if (isOpen) {
                                  _this.setState({ isOpen: false });
                                  break;
                              }
                              return;
                          }
                          if (_this.props.multiSelect) {
                              _this.setState({ isOpen: true });
                          }
                          else if (!_this._isDisabled()) {
                              newIndex = _this._moveIndex(ev, -1, selectedIndex - 1, selectedIndex);
                          }
                          break;
                      case Utilities_1.KeyCodes.down:
                          if (containsExpandCollapseModifier) {
                              ev.stopPropagation();
                              ev.preventDefault();
                          }
                          if ((containsExpandCollapseModifier && !isOpen) || _this.props.multiSelect) {
                              _this.setState({ isOpen: true });
                          }
                          else if (!_this._isDisabled()) {
                              newIndex = _this._moveIndex(ev, 1, selectedIndex + 1, selectedIndex);
                          }
                          break;
                      case Utilities_1.KeyCodes.home:
                          if (!_this.props.multiSelect) {
                              newIndex = _this._moveIndex(ev, 1, 0, selectedIndex);
                          }
                          break;
                      case Utilities_1.KeyCodes.end:
                          if (!_this.props.multiSelect) {
                              newIndex = _this._moveIndex(ev, -1, _this.props.options.length - 1, selectedIndex);
                          }
                          break;
                      case Utilities_1.KeyCodes.space:
                          // event handled in _onDropdownKeyUp
                          break;
                      default:
                          return;
                  }
                  if (newIndex !== selectedIndex) {
                      ev.stopPropagation();
                      ev.preventDefault();
                  }
              };
              _this._onDropdownKeyUp = function (ev) {
                  // If Dropdown disabled do not process any keyboard events.
                  var disabled = _this._isDisabled();
                  if (disabled) {
                      return;
                  }
                  var shouldHandleKey = _this._shouldHandleKeyUp(ev);
                  var isOpen = _this.state.isOpen;
                  if (_this.props.onKeyUp) {
                      _this.props.onKeyUp(ev);
                      if (ev.preventDefault) {
                          return;
                      }
                  }
                  switch (ev.which) {
                      case Utilities_1.KeyCodes.space:
                          _this.setState({
                              isOpen: !isOpen
                          });
                          break;
                      default:
                          if (shouldHandleKey && isOpen) {
                              _this.setState({ isOpen: false });
                          }
                          return;
                  }
                  ev.stopPropagation();
                  ev.preventDefault();
              };
              _this._onZoneKeyDown = function (ev) {
                  var elementToFocus;
                  // Take note if we are processing an alt (option) or meta (command) keydown.
                  // See comment in _shouldHandleKeyUp for reasoning.
                  _this._lastKeyDownWasAltOrMeta = _this._isAltOrMeta(ev);
                  var containsExpandCollapseModifier = ev.altKey || ev.metaKey;
                  switch (ev.which) {
                      case Utilities_1.KeyCodes.up:
                          if (containsExpandCollapseModifier) {
                              _this.setState({ isOpen: false });
                          }
                          else {
                              if (_this._host.current) {
                                  elementToFocus = Utilities_1.getLastFocusable(_this._host.current, _this._host.current.lastChild, true);
                              }
                          }
                          break;
                      // All directional keystrokes should be canceled when the zone is rendered.
                      // This avoids the body scroll from reacting and thus dismissing the dropdown.
                      case Utilities_1.KeyCodes.home:
                      case Utilities_1.KeyCodes.end:
                      case Utilities_1.KeyCodes.pageUp:
                      case Utilities_1.KeyCodes.pageDown:
                          break;
                      case Utilities_1.KeyCodes.down:
                          if (!containsExpandCollapseModifier && _this._host.current) {
                              elementToFocus = Utilities_1.getFirstFocusable(_this._host.current, _this._host.current.firstChild, true);
                          }
                          break;
                      case Utilities_1.KeyCodes.escape:
                          _this.setState({ isOpen: false });
                          break;
                      case Utilities_1.KeyCodes.tab:
                          _this.setState({ isOpen: false });
                          return;
                      default:
                          return;
                  }
                  if (elementToFocus) {
                      elementToFocus.focus();
                  }
                  ev.stopPropagation();
                  ev.preventDefault();
              };
              _this._onZoneKeyUp = function (ev) {
                  var shouldHandleKey = _this._shouldHandleKeyUp(ev);
                  if (shouldHandleKey && _this.state.isOpen) {
                      _this.setState({ isOpen: false });
                      ev.preventDefault();
                  }
              };
              _this._onDropdownClick = function (ev) {
                  if (_this.props.onClick) {
                      _this.props.onClick(ev);
                      if (ev.preventDefault) {
                          return;
                      }
                  }
                  var isOpen = _this.state.isOpen;
                  var disabled = _this._isDisabled();
                  if (!disabled) {
                      _this.setState({
                          isOpen: !isOpen
                      });
                  }
              };
              _this._onFocus = function (ev) {
                  var _a = _this.state, isOpen = _a.isOpen, selectedIndices = _a.selectedIndices;
                  var multiSelect = _this.props.multiSelect;
                  var disabled = _this._isDisabled();
                  if (!disabled) {
                      if (!isOpen && selectedIndices.length === 0 && !multiSelect) {
                          // Per aria
                          _this._moveIndex(ev, 1, 0, -1);
                      }
                      if (_this.props.onFocus) {
                          _this.props.onFocus(ev);
                      }
                      _this.setState({ hasFocus: true });
                  }
              };
              /**
               * Because the isDisabled prop is deprecated, we have had to repeat this logic all over the place.
               * This helper method avoids all the repetition.
               */
              _this._isDisabled = function () {
                  var disabled = _this.props.disabled;
                  var isDisabled = _this.props.isDisabled;
                  // Remove this deprecation workaround at 1.0.0
                  if (isDisabled !== undefined) {
                      disabled = isDisabled;
                  }
                  return disabled;
              };
              _this._warnDeprecations({
                  isDisabled: 'disabled',
                  onChanged: 'onChange',
                  placeHolder: 'placeholder'
              });
              _this._warnMutuallyExclusive({
                  defaultSelectedKey: 'selectedKey',
                  defaultSelectedKeys: 'selectedKeys',
                  selectedKeys: 'selectedKey',
                  multiSelect: 'defaultSelectedKey',
                  selectedKey: 'multiSelect'
              });
              _this._id = props.id || Utilities_1.getId('Dropdown');
              _this._isScrollIdle = true;
              var selectedIndices;
              if (_this.props.multiSelect) {
                  var selectedKeys = props.defaultSelectedKeys !== undefined ? props.defaultSelectedKeys : props.selectedKeys;
                  selectedIndices = _this._getSelectedIndexes(props.options, selectedKeys);
              }
              else {
                  var selectedKey = props.defaultSelectedKey !== undefined ? props.defaultSelectedKey : props.selectedKey;
                  selectedIndices = _this._getSelectedIndexes(props.options, selectedKey);
                  _this._sizePosCache.updateOptions(props.options);
              }
              _this.state = {
                  isOpen: false,
                  selectedIndices: selectedIndices,
                  hasFocus: false,
                  calloutRenderEdge: undefined
              };
              return _this;
          }
          DropdownBase.prototype.componentWillReceiveProps = function (newProps) {
              // In controlled component usage where selectedKey is provided, update the selectedIndex
              // state if the key or options change.
              var selectedKeyProp;
              // this does a shallow compare (assumes options are pure), for the purposes of determining whether
              // defaultSelectedKey/defaultSelectedKeys are respected.
              var didOptionsChange = newProps.options !== this.props.options;
              if (newProps.multiSelect) {
                  if (didOptionsChange && newProps.defaultSelectedKeys !== undefined) {
                      selectedKeyProp = 'defaultSelectedKeys';
                  }
                  else {
                      selectedKeyProp = 'selectedKeys';
                  }
              }
              else {
                  if (didOptionsChange && newProps.defaultSelectedKey !== undefined) {
                      selectedKeyProp = 'defaultSelectedKey';
                  }
                  else {
                      selectedKeyProp = 'selectedKey';
                  }
              }
              if (newProps[selectedKeyProp] !== undefined && (newProps[selectedKeyProp] !== this.props[selectedKeyProp] || didOptionsChange)) {
                  this.setState({
                      selectedIndices: this._getSelectedIndexes(newProps.options, newProps[selectedKeyProp])
                  });
              }
              if (newProps.options !== this.props.options && // preexisting code assumes purity of the options...
                  !newProps.multiSelect // only relevant in single selection
              ) {
                  this._sizePosCache.updateOptions(newProps.options);
              }
          };
          DropdownBase.prototype.componentDidUpdate = function (prevProps, prevState) {
              if (prevState.isOpen === true && this.state.isOpen === false) {
                  this._gotMouseMove = false;
                  if (this._dropDown.current) {
                      this._dropDown.current.focus();
                  }
                  if (this.props.onDismiss) {
                      this.props.onDismiss();
                  }
              }
          };
          DropdownBase.prototype.render = function () {
              var _this = this;
              var id = this._id;
              var _a = this.props, className = _a.className, label = _a.label, options = _a.options, ariaLabel = _a.ariaLabel, required = _a.required, errorMessage = _a.errorMessage, multiSelect = _a.multiSelect, keytipProps = _a.keytipProps, propStyles = _a.styles, theme = _a.theme, panelProps = _a.panelProps, calloutProps = _a.calloutProps, _b = _a.onRenderTitle, onRenderTitle = _b === void 0 ? this._onRenderTitle : _b, _c = _a.onRenderContainer, onRenderContainer = _c === void 0 ? this._onRenderContainer : _c, _d = _a.onRenderPlaceHolder, onRenderPlaceHolder = _d === void 0 ? this._onRenderPlaceholder : _d, _e = _a.onRenderCaretDown, onRenderCaretDown = _e === void 0 ? this._onRenderCaretDown : _e;
              var _f = this.state, isOpen = _f.isOpen, selectedIndices = _f.selectedIndices, hasFocus = _f.hasFocus, calloutRenderEdge = _f.calloutRenderEdge;
              var selectedOptions = this._getAllSelectedOptions(options, selectedIndices);
              var divProps = Utilities_1.getNativeProps(this.props, Utilities_1.divProperties);
              var disabled = this._isDisabled();
              var optionId = id + '-option';
              var ariaAttrs = multiSelect || disabled
                  ? {
                      role: undefined,
                      ariaActiveDescendant: undefined,
                      childRole: undefined,
                      ariaSetSize: undefined,
                      ariaPosInSet: undefined,
                      ariaSelected: undefined
                  }
                  : // single select
                      {
                          role: 'listbox',
                          ariaActiveDescendant: isOpen && selectedIndices.length === 1 && selectedIndices[0] >= 0 ? this._id + '-list' + selectedIndices[0] : optionId,
                          childRole: 'option',
                          ariaSetSize: this._sizePosCache.optionSetSize,
                          ariaPosInSet: this._sizePosCache.positionInSet(selectedIndices[0]),
                          ariaSelected: selectedIndices[0] === undefined ? undefined : true
                      };
              this._classNames = getClassNames(propStyles, {
                  theme: theme,
                  className: className,
                  hasError: Boolean(errorMessage && errorMessage.length > 0),
                  isOpen: isOpen,
                  required: required,
                  disabled: disabled,
                  isRenderingPlaceholder: !selectedOptions.length,
                  panelClassName: !!panelProps ? panelProps.className : undefined,
                  calloutClassName: !!calloutProps ? calloutProps.className : undefined,
                  calloutRenderEdge: calloutRenderEdge
              });
              var labelStyles = this._classNames.subComponentStyles
                  ? this._classNames.subComponentStyles.label
                  : undefined;
              return (React.createElement("div", { className: this._classNames.root },
                  label && (React.createElement(Label_1.Label, { className: this._classNames.label, id: id + '-label', htmlFor: id, required: required, styles: labelStyles }, label)),
                  React.createElement(KeytipData_1.KeytipData, { keytipProps: keytipProps, disabled: disabled }, function (keytipAttributes) { return (React.createElement("div", tslib_1.__assign({}, keytipAttributes, { "data-is-focusable": !disabled, ref: _this._dropDown, id: id, tabIndex: disabled ? -1 : 0, "aria-expanded": isOpen ? 'true' : 'false', role: ariaAttrs.role, "aria-label": ariaLabel, "aria-labelledby": label && !ariaLabel ? id + '-label' : undefined, "aria-describedby": Utilities_1.mergeAriaAttributeValues(optionId, keytipAttributes['aria-describedby']), "aria-activedescendant": isOpen ? ariaAttrs.ariaActiveDescendant : undefined, "aria-required": required, "aria-disabled": disabled, "aria-owns": isOpen ? id + '-list' : undefined }, divProps, { className: _this._classNames.dropdown, onBlur: _this._onDropdownBlur, onKeyDown: _this._onDropdownKeyDown, onKeyUp: _this._onDropdownKeyUp, onClick: _this._onDropdownClick, onFocus: _this._onFocus }),
                      React.createElement("span", { id: optionId, className: _this._classNames.title, "aria-atomic": true, role: ariaAttrs.childRole, "aria-live": !hasFocus || disabled || multiSelect || isOpen ? 'off' : 'assertive', "aria-label": selectedOptions.length ? selectedOptions[0].text : _this._placeholder, "aria-setsize": ariaAttrs.ariaSetSize, "aria-posinset": ariaAttrs.ariaPosInSet, "aria-selected": ariaAttrs.ariaSelected }, // If option is selected render title, otherwise render the placeholder text
                      selectedOptions.length
                          ? onRenderTitle(selectedOptions, _this._onRenderTitle)
                          : onRenderPlaceHolder(_this.props, _this._onRenderPlaceholder)),
                      React.createElement("span", { className: _this._classNames.caretDownWrapper }, onRenderCaretDown(_this.props, _this._onRenderCaretDown)))); }),
                  isOpen && onRenderContainer(this.props, this._onRenderContainer),
                  errorMessage && errorMessage.length > 0 && React.createElement("div", { className: this._classNames.errorMessage }, errorMessage)));
          };
          DropdownBase.prototype.focus = function (shouldOpenOnFocus) {
              if (this._dropDown.current && this._dropDown.current.tabIndex !== -1) {
                  this._dropDown.current.focus();
                  if (shouldOpenOnFocus) {
                      this.setState({
                          isOpen: true
                      });
                  }
              }
          };
          DropdownBase.prototype.setSelectedIndex = function (event, index) {
              var _a = this.props, onChange = _a.onChange, onChanged = _a.onChanged, options = _a.options, selectedKey = _a.selectedKey, selectedKeys = _a.selectedKeys, multiSelect = _a.multiSelect, notifyOnReselect = _a.notifyOnReselect;
              var _b = this.state.selectedIndices, selectedIndices = _b === void 0 ? [] : _b;
              var checked = selectedIndices ? selectedIndices.indexOf(index) > -1 : false;
              index = Math.max(0, Math.min(options.length - 1, index));
              if (!multiSelect && !notifyOnReselect && index === selectedIndices[0]) {
                  return;
              }
              else if (!multiSelect && selectedKey === undefined) {
                  // Set the selected option if this is an uncontrolled component
                  this.setState({
                      selectedIndices: [index]
                  });
              }
              else if (multiSelect && selectedKeys === undefined) {
                  var newIndexes = selectedIndices ? this._copyArray(selectedIndices) : [];
                  if (checked) {
                      var position = newIndexes.indexOf(index);
                      if (position > -1) {
                          // unchecked the current one
                          newIndexes.splice(position, 1);
                      }
                  }
                  else {
                      // add the new selected index into the existing one
                      newIndexes.push(index);
                  }
                  this.setState({
                      selectedIndices: newIndexes
                  });
              }
              if (onChange) {
                  // for single-select, option passed in will always be selected.
                  // for multi-select, flip the checked value
                  var changedOpt = multiSelect ? tslib_1.__assign({}, options[index], { selected: !checked }) : options[index];
                  onChange(event, changedOpt, index);
              }
              if (onChanged) {
                  // for single-select, option passed in will always be selected.
                  // for multi-select, flip the checked value
                  var changedOpt = multiSelect ? tslib_1.__assign({}, options[index], { selected: !checked }) : options[index];
                  onChanged(changedOpt, index);
              }
          };
          Object.defineProperty(DropdownBase.prototype, "_placeholder", {
              /** Get either props.placeholder (new name) or props.placeHolder (old name) */
              get: function () {
                  return this.props.placeholder || this.props.placeHolder;
              },
              enumerable: true,
              configurable: true
          });
          DropdownBase.prototype._copyArray = function (array) {
              var newArray = [];
              for (var _i = 0, array_1 = array; _i < array_1.length; _i++) {
                  var element = array_1[_i];
                  newArray.push(element);
              }
              return newArray;
          };
          /**
           * Finds the next valid Dropdown option and sets the selected index to it.
           * @param stepValue Value of how many items the function should traverse.  Should be -1 or 1.
           * @param index Index of where the search should start
           * @param selectedIndex The selectedIndex Dropdown's state
           * @returns The next valid dropdown option's index
           */
          DropdownBase.prototype._moveIndex = function (event, stepValue, index, selectedIndex) {
              var options = this.props.options;
              // Return selectedIndex if nothing has changed or options is empty
              if (selectedIndex === index || options.length === 0) {
                  return selectedIndex;
              }
              // Set starting index to 0 if index is < 0
              if (index < 0) {
                  index = 0;
              }
              // Set starting index to last option index if greater than options.length
              if (index >= options.length) {
                  index = options.length - 1;
              }
              var stepCounter = 0;
              // If current index is a header or divider, or disabled, increment by step
              while (options[index].itemType === Dropdown_types_1.DropdownMenuItemType.Header ||
                  options[index].itemType === Dropdown_types_1.DropdownMenuItemType.Divider ||
                  options[index].disabled) {
                  // If stepCounter exceeds length of options, then return selectedIndex (-1)
                  if (stepCounter >= options.length) {
                      return selectedIndex;
                  }
                  // If index + stepValue is out of bounds, wrap around
                  if (index + stepValue < 0) {
                      index = options.length;
                  }
                  else if (index + stepValue >= options.length) {
                      index = -1;
                  }
                  index = index + stepValue;
                  stepCounter++;
              }
              this.setSelectedIndex(event, index);
              return index;
          };
          /** Wrap item list in a FocusZone */
          DropdownBase.prototype._renderFocusableList = function (props) {
              var _a = props.onRenderList, onRenderList = _a === void 0 ? this._onRenderList : _a, label = props.label;
              var id = this._id;
              return (React.createElement("div", { className: this._classNames.dropdownItemsWrapper, onKeyDown: this._onZoneKeyDown, onKeyUp: this._onZoneKeyUp, ref: this._host, tabIndex: 0 },
                  React.createElement(FocusZone_1.FocusZone, { ref: this._focusZone, direction: FocusZone_1.FocusZoneDirection.vertical, id: id + '-list', className: this._classNames.dropdownItems, "aria-labelledby": label ? id + '-label' : undefined, role: "listbox" }, onRenderList(props, this._onRenderList))));
          };
          DropdownBase.prototype._renderSeparator = function (item) {
              var index = item.index, key = item.key;
              if (index > 0) {
                  return React.createElement("div", { role: "separator", key: key, className: this._classNames.dropdownDivider });
              }
              return null;
          };
          DropdownBase.prototype._renderHeader = function (item) {
              var _a = this.props.onRenderOption, onRenderOption = _a === void 0 ? this._onRenderOption : _a;
              var key = item.key;
              return (React.createElement("div", { key: key, className: this._classNames.dropdownItemHeader }, onRenderOption(item, this._onRenderOption)));
          };
          DropdownBase.prototype._onItemMouseEnter = function (item, ev) {
              if (this._shouldIgnoreMouseEvent()) {
                  return;
              }
              var targetElement = ev.currentTarget;
              targetElement.focus();
          };
          DropdownBase.prototype._onItemMouseMove = function (item, ev) {
              var targetElement = ev.currentTarget;
              this._gotMouseMove = true;
              if (!this._isScrollIdle || document.activeElement === targetElement) {
                  return;
              }
              targetElement.focus();
          };
          DropdownBase.prototype._shouldIgnoreMouseEvent = function () {
              return !this._isScrollIdle || !this._gotMouseMove;
          };
          /** Get all selected indexes for multi-select mode */
          DropdownBase.prototype._getSelectedIndexes = function (options, selectedKey) {
              if (selectedKey === undefined) {
                  if (this.props.multiSelect) {
                      return this._getAllSelectedIndices(options);
                  }
                  var selectedIndex = this._getSelectedIndex(options, null);
                  return selectedIndex !== -1 ? [selectedIndex] : [];
              }
              else if (!Array.isArray(selectedKey)) {
                  return [this._getSelectedIndex(options, selectedKey)];
              }
              var selectedIndices = [];
              for (var _i = 0, selectedKey_1 = selectedKey; _i < selectedKey_1.length; _i++) {
                  var key = selectedKey_1[_i];
                  selectedIndices.push(this._getSelectedIndex(options, key));
              }
              return selectedIndices;
          };
          /** Get all selected options for multi-select mode */
          DropdownBase.prototype._getAllSelectedOptions = function (options, selectedIndices) {
              var selectedOptions = [];
              for (var _i = 0, selectedIndices_1 = selectedIndices; _i < selectedIndices_1.length; _i++) {
                  var index = selectedIndices_1[_i];
                  var option = options[index];
                  if (option) {
                      selectedOptions.push(option);
                  }
              }
              return selectedOptions;
          };
          DropdownBase.prototype._getAllSelectedIndices = function (options) {
              return options.map(function (option, index) { return (option.selected ? index : -1); }).filter(function (index) { return index !== -1; });
          };
          DropdownBase.prototype._getSelectedIndex = function (options, selectedKey) {
              return Utilities_1.findIndex(options, function (option) {
                  // tslint:disable-next-line:triple-equals
                  if (selectedKey != null) {
                      return option.key === selectedKey;
                  }
                  else {
                      return !!option.isSelected || !!option.selected;
                  }
              });
          };
          /**
           * Returns true if the key for the event is alt (Mac option) or meta (Mac command).
           */
          DropdownBase.prototype._isAltOrMeta = function (ev) {
              return ev.which === Utilities_1.KeyCodes.alt || ev.key === 'Meta';
          };
          /**
           * We close the menu on key up only if ALL of the following are true:
           * - Most recent key down was alt or meta (command)
           * - The alt/meta key down was NOT followed by some other key (such as down/up arrow to
           *   expand/collapse the menu)
           * - We're not on a Mac (or iOS)
           *
           * This is because on Windows, pressing alt moves focus to the application menu bar or similar,
           * closing any open context menus. There is not a similar behavior on Macs.
           */
          DropdownBase.prototype._shouldHandleKeyUp = function (ev) {
              var keyPressIsAltOrMetaAlone = this._lastKeyDownWasAltOrMeta && this._isAltOrMeta(ev);
              this._lastKeyDownWasAltOrMeta = false;
              return !!keyPressIsAltOrMetaAlone && !(Utilities_1.isMac() || Utilities_1.isIOS());
          };
          DropdownBase.defaultProps = {
              options: []
          };
          DropdownBase = tslib_1.__decorate([
              withResponsiveMode_1.withResponsiveMode
          ], DropdownBase);
          return DropdownBase;
      }(Utilities_1.BaseComponent));
      exports.DropdownBase = DropdownBase;
  });
  //# sourceMappingURL=Dropdown.base.js.map