"use strict";

var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports["default"] = void 0;

var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck"));

var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass"));

var _assertThisInitialized2 = _interopRequireDefault(require("@babel/runtime/helpers/assertThisInitialized"));

var _inherits2 = _interopRequireDefault(require("@babel/runtime/helpers/inherits"));

var _possibleConstructorReturn2 = _interopRequireDefault(require("@babel/runtime/helpers/possibleConstructorReturn"));

var _getPrototypeOf2 = _interopRequireDefault(require("@babel/runtime/helpers/getPrototypeOf"));

var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));

var _react = _interopRequireDefault(require("react"));

var _propTypes = _interopRequireDefault(require("prop-types"));

var _Button = _interopRequireDefault(require("@material-ui/core/Button"));

var _InputLabel = _interopRequireDefault(require("@material-ui/core/InputLabel"));

var _Menu = _interopRequireDefault(require("@material-ui/core/Menu"));

var _MenuItem = _interopRequireDefault(require("@material-ui/core/MenuItem"));

var _ArrowDropDown = _interopRequireDefault(require("@material-ui/icons/ArrowDropDown"));

var _ArrowDropUp = _interopRequireDefault(require("@material-ui/icons/ArrowDropUp"));

var _Close = _interopRequireDefault(require("@material-ui/icons/Close"));

var _Check = _interopRequireDefault(require("@material-ui/icons/Check"));

var _styles = require("@material-ui/core/styles");

var _classnames = _interopRequireDefault(require("classnames"));

var _renderUi = require("../../render-ui");

var _mathRendering = require("../../../math-rendering");

function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }

function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { (0, _defineProperty2["default"])(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }

function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = (0, _getPrototypeOf2["default"])(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = (0, _getPrototypeOf2["default"])(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return (0, _possibleConstructorReturn2["default"])(this, result); }; }

function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }

var Dropdown = /*#__PURE__*/function (_React$Component) {
  (0, _inherits2["default"])(Dropdown, _React$Component);

  var _super = _createSuper(Dropdown);

  function Dropdown(props) {
    var _this;

    (0, _classCallCheck2["default"])(this, Dropdown);
    _this = _super.call(this, props);
    (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "handleClick", function (event) {
      return _this.setState({
        anchorEl: event.currentTarget
      });
    });
    (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "handleClose", function () {
      var value = _this.props.value;

      _this.setState({
        anchorEl: null,
        previewValue: null,
        highlightedOptionId: null
      }); // clear displayed preview if no selection


      if (!value && _this.previewRef.current) {
        _this.previewRef.current.innerHTML = '';
      }
    });
    (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "handleHighlight", function (index) {
      var highlightedOptionId = "dropdown-option-".concat(_this.props.id, "-").concat(index); // preview on hover if nothing selected

      var stateUpdate = {
        highlightedOptionId: highlightedOptionId
      };

      if (!_this.props.value) {
        stateUpdate.previewValue = _this.props.choices[index].value;
      }

      _this.setState(stateUpdate);
    });
    (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "handleSelect", function (value, index) {
      _this.props.onChange(_this.props.id, value);

      _this.handleHighlight(index);

      _this.handleClose();
    });
    (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "handleHover", function (index) {
      var selectedValue = _this.props.value;
      if (selectedValue) return;
      var highlightedOptionId = "dropdown-option-".concat(_this.props.id, "-").concat(index);
      var previewValue = _this.state.previewValue;

      _this.setState({
        highlightedOptionId: highlightedOptionId,
        previewValue: previewValue
      }, function () {
        // On hover, preview the math-rendered content inside the button if no value is selected.
        var ref = _this.elementRefs[index];
        var preview = _this.previewRef.current;

        if (ref && preview) {
          preview.innerHTML = ref.innerHTML;
        }
      });
    });
    _this.state = {
      anchorEl: null,
      highlightedOptionId: null,
      menuWidth: null,
      previewValue: null
    };
    _this.hiddenRef = /*#__PURE__*/_react["default"].createRef();
    _this.buttonRef = /*#__PURE__*/_react["default"].createRef();
    _this.previewRef = /*#__PURE__*/_react["default"].createRef();
    _this.elementRefs = [];
    return _this;
  }

  (0, _createClass2["default"])(Dropdown, [{
    key: "componentDidMount",
    value: function componentDidMount() {
      // measure hidden menu width once
      if (this.hiddenRef.current && this.state.menuWidth === null) {
        this.setState({
          menuWidth: this.hiddenRef.current.clientWidth
        });
      }
    }
  }, {
    key: "componentDidUpdate",
    value: function componentDidUpdate(prevProps, prevState) {
      var hiddenEl = this.hiddenRef.current;
      var dropdownJustOpened = !prevState.anchorEl && this.state.anchorEl;

      if (dropdownJustOpened) {
        this.elementRefs.forEach(function (ref) {
          if (!ref) return;
          var containsLatex = ref.querySelector('[data-latex], [data-raw]');
          var hasMathJax = ref.querySelector('mjx-container');
          var mathHandled = ref.querySelector('[data-math-handled="true"]');

          if (containsLatex && (!mathHandled || !hasMathJax)) {
            (0, _mathRendering.renderMath)(ref);
          }
        });
      }

      if (hiddenEl) {
        var newWidth = hiddenEl.clientWidth;

        if (newWidth !== this.state.menuWidth) {
          this.elementRefs.forEach(function (ref) {
            if (ref) (0, _mathRendering.renderMath)(ref);
          });
          (0, _mathRendering.renderMath)(hiddenEl);
          this.setState({
            menuWidth: newWidth
          });
        }
      }
    }
  }, {
    key: "getLabel",
    value: function getLabel(choices, value) {
      var found = (choices || []).find(function (choice) {
        return choice.value === value;
      });
      return found ? found.label.trim() : undefined;
    }
  }, {
    key: "render",
    value: function render() {
      var _this2 = this;

      var _this$props = this.props,
          classes = _this$props.classes,
          id = _this$props.id,
          correct = _this$props.correct,
          disabled = _this$props.disabled,
          value = _this$props.value,
          choices = _this$props.choices,
          showCorrectAnswer = _this$props.showCorrectAnswer,
          singleQuery = _this$props.singleQuery,
          correctValue = _this$props.correctValue;
      var anchorEl = this.state.anchorEl;
      var open = Boolean(anchorEl);
      var buttonId = "dropdown-button-".concat(id);
      var menuId = "dropdown-menu-".concat(id);
      var valueDisplayId = "dropdown-value-".concat(id); // Determine the class for disabled state, view mode and evaluate mode

      var disabledClass; // Reset elementRefs before each render to avoid stale references

      this.elementRefs = [];

      if (disabled && correct !== undefined) {
        disabledClass = correct || showCorrectAnswer ? classes.disabledCorrect : classes.disabledIncorrect;
      } // Create distinct, visually hidden labels for each dropdown


      var incrementedId = parseInt(id, 10) + 1;
      var labelId = singleQuery ? 'Query-label' : "Query-label-".concat(incrementedId);
      var labelText = singleQuery ? 'Query' : "Query ".concat(incrementedId); // Changed from Select to Button for dropdown to enhance accessibility. This modification offers explicit control over aria attributes and focuses management, ensuring the dropdown is compliant with accessibility standards. The use of Button and Menu components allows for better handling of keyboard interactions and provides accessible labels and menus, aligning with WCAG guidelines and improving usability for assistive technology users.

      var correctnessIcon = null;

      if (disabled && correct !== undefined) {
        correctnessIcon = correct || showCorrectAnswer ? /*#__PURE__*/_react["default"].createElement(_Check["default"], {
          className: (0, _classnames["default"])(classes.correctnessIndicatorIcon, classes.correctIcon)
        }) : /*#__PURE__*/_react["default"].createElement(_Close["default"], {
          className: (0, _classnames["default"])(classes.correctnessIndicatorIcon, classes.incorrectIcon)
        });
      }

      return /*#__PURE__*/_react["default"].createElement(_react["default"].Fragment, null, /*#__PURE__*/_react["default"].createElement("div", {
        ref: this.hiddenRef,
        style: {
          position: 'absolute',
          visibility: 'hidden',
          top: 0,
          left: 0
        }
      }, (choices || []).map(function (c, index) {
        return /*#__PURE__*/_react["default"].createElement(_MenuItem["default"], {
          key: index,
          classes: {
            root: classes.menuRoot,
            selected: classes.selected
          }
        }, /*#__PURE__*/_react["default"].createElement("span", {
          className: classes.label,
          dangerouslySetInnerHTML: {
            __html: c.label
          }
        }));
      })), /*#__PURE__*/_react["default"].createElement(_InputLabel["default"], {
        className: classes.srOnly,
        id: labelId
      }, labelText), /*#__PURE__*/_react["default"].createElement(_Button["default"], {
        ref: this.buttonRef,
        style: _objectSpread(_objectSpread({}, this.state.menuWidth && {
          minWidth: "calc(".concat(this.state.menuWidth, "px + 8px)")
        }), {}, {
          borderWidth: open ? '2px' : '1px',
          transition: 'border-width 0.2s ease-in-out'
        }),
        "aria-controls": open ? menuId : undefined,
        "aria-haspopup": "listbox",
        "aria-expanded": open ? 'true' : undefined,
        "aria-activedescendant": this.state.highlightedOptionId,
        onClick: this.handleClick,
        classes: {
          root: classes.root,
          disabled: disabledClass
        },
        disabled: disabled,
        id: buttonId,
        role: "combobox",
        "aria-label": "Select an option for ".concat(labelText),
        "aria-labelledby": valueDisplayId
      }, correctnessIcon, /*#__PURE__*/_react["default"].createElement("span", {
        id: valueDisplayId,
        ref: this.previewRef,
        className: classes.label,
        dangerouslySetInnerHTML: {
          __html: correctValue ? correctValue : open && this.state.previewValue ? this.getLabel(choices, this.state.previewValue) : this.getLabel(choices, value) || ''
        }
      }), open ? /*#__PURE__*/_react["default"].createElement(_ArrowDropUp["default"], null) : /*#__PURE__*/_react["default"].createElement(_ArrowDropDown["default"], null)), /*#__PURE__*/_react["default"].createElement(_Menu["default"], {
        id: menuId,
        anchorEl: anchorEl,
        className: classes.selectMenu,
        keepMounted: true,
        open: open,
        onClose: this.handleClose,
        getContentAnchorEl: null,
        anchorOrigin: {
          vertical: 'bottom',
          horizontal: 'left'
        },
        transformOrigin: {
          vertical: 'top',
          horizontal: 'left'
        },
        PaperProps: this.state.menuWidth ? {
          style: {
            minWidth: this.state.menuWidth,
            padding: '4px'
          }
        } : undefined,
        MenuListProps: {
          'aria-labelledby': buttonId,
          role: 'listbox',
          disablePadding: true
        }
      }, (choices || []).map(function (c, index) {
        var optionId = "dropdown-option-".concat(id, "-").concat(index);
        return /*#__PURE__*/_react["default"].createElement(_MenuItem["default"], {
          id: optionId,
          classes: {
            root: classes.menuRoot,
            selected: classes.selected
          },
          key: "".concat(c.label, "-").concat(index),
          value: c.value,
          onClick: function onClick() {
            return _this2.handleSelect(c.value, index);
          },
          role: "option",
          "aria-selected": _this2.state.highlightedOptionId === optionId ? 'true' : undefined,
          onMouseOver: function onMouseOver() {
            return _this2.handleHover(index);
          }
        }, /*#__PURE__*/_react["default"].createElement("span", {
          ref: function ref(_ref) {
            return _this2.elementRefs[index] = _ref;
          },
          className: classes.label,
          dangerouslySetInnerHTML: {
            __html: c.label
          }
        }), /*#__PURE__*/_react["default"].createElement("span", {
          className: classes.selectedIndicator,
          dangerouslySetInnerHTML: {
            __html: c.value === value ? ' &check;' : ''
          }
        }));
      })));
    }
  }]);
  return Dropdown;
}(_react["default"].Component);

(0, _defineProperty2["default"])(Dropdown, "propTypes", {
  id: _propTypes["default"].string,
  value: _propTypes["default"].string,
  disabled: _propTypes["default"].bool,
  onChange: _propTypes["default"].func,
  classes: _propTypes["default"].object,
  correct: _propTypes["default"].bool,
  choices: _propTypes["default"].arrayOf(_propTypes["default"].shape({
    value: _propTypes["default"].string,
    label: _propTypes["default"].string
  })),
  showCorrectAnswer: _propTypes["default"].bool,
  singleQuery: _propTypes["default"].bool,
  correctValue: _propTypes["default"].string
});

var styles = function styles() {
  return {
    root: {
      color: _renderUi.color.text(),
      border: "1px solid ".concat(_renderUi.color.borderGray()),
      borderRadius: '4px',
      justifyContent: 'space-between',
      backgroundColor: _renderUi.color.background(),
      position: 'relative',
      height: '45px',
      width: 'fit-content',
      margin: '2px',
      textTransform: 'none',
      '& span': {
        paddingRight: '5px'
      },
      '& svg': {
        position: 'absolute',
        right: 0,
        top: 'calc(50% - 12px)',
        pointerEvents: 'none',
        color: _renderUi.color.text(),
        marginLeft: '5px'
      }
    },
    disabledCorrect: {
      borderWidth: '2px',
      borderColor: _renderUi.color.correct(),
      color: "".concat(_renderUi.color.text(), " !important")
    },
    disabledIncorrect: {
      borderWidth: '2px',
      borderColor: _renderUi.color.incorrectWithIcon(),
      color: "".concat(_renderUi.color.text(), " !important")
    },
    selectMenu: {
      backgroundColor: _renderUi.color.background(),
      border: "1px solid ".concat(_renderUi.color.correct(), " !important"),
      '&:hover': {
        border: "1px solid ".concat(_renderUi.color.text(), " "),
        borderColor: 'initial'
      },
      '&:focus': {
        border: "1px solid ".concat(_renderUi.color.text()),
        borderColor: 'initial'
      },
      // remove default padding on the inner list
      '& .MuiList-root': {
        padding: 0
      }
    },
    selected: {
      color: "".concat(_renderUi.color.text(), " !important"),
      backgroundColor: "".concat(_renderUi.color.background(), " !important"),
      '&:hover': {
        color: _renderUi.color.text(),
        backgroundColor: "".concat(_renderUi.color.dropdownBackground(), " !important")
      }
    },
    menuRoot: {
      color: _renderUi.color.text(),
      backgroundColor: _renderUi.color.background(),
      '&:focus': {
        color: _renderUi.color.text(),
        backgroundColor: _renderUi.color.background()
      },
      '&:hover': {
        color: _renderUi.color.text(),
        backgroundColor: _renderUi.color.dropdownBackground()
      },
      boxSizing: 'border-box',
      padding: '25px',
      borderRadius: '4px'
    },
    label: {
      fontSize: 'max(1rem, 14px)'
    },
    selectedIndicator: {
      fontSize: 'max(1rem, 14px)',
      position: 'absolute',
      right: '10px'
    },
    srOnly: {
      position: 'absolute',
      left: '-10000px',
      top: 'auto',
      width: '1px',
      height: '1px',
      overflow: 'hidden'
    },
    correctnessIndicatorIcon: {
      color: "".concat(_renderUi.color.white(), " !important"),
      position: 'absolute',
      top: '-8px !important',
      left: '-8px',
      marginLeft: '0 !important',
      borderRadius: '50%',
      fontSize: '16px',
      padding: '2px'
    },
    correctIcon: {
      backgroundColor: _renderUi.color.correct()
    },
    incorrectIcon: {
      backgroundColor: _renderUi.color.incorrectWithIcon()
    }
  };
};

var _default = (0, _styles.withStyles)(styles)(Dropdown);

exports["default"] = _default;
//# sourceMappingURL=dropdown.js.map