UNPKG

wix-style-react

Version:
1,006 lines (1,001 loc) • 33.4 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); exports.__esModule = true; exports.default = exports.DIVIDER_OPTION_VALUE = void 0; exports.optionValidator = optionValidator; var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends")); var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty")); var _objectWithoutProperties2 = _interopRequireDefault(require("@babel/runtime/helpers/objectWithoutProperties")); var _propTypes = _interopRequireDefault(require("prop-types")); var _react = _interopRequireDefault(require("react")); var _Loader = _interopRequireDefault(require("../Loader/Loader")); var _InfiniteScroll = _interopRequireDefault(require("../utils/InfiniteScroll")); var _scrollIntoView = _interopRequireDefault(require("../utils/scrollIntoView")); var _DataAttr = require("./DataAttr"); var _DropdownLayoutSt = require("./DropdownLayout.st.css"); var _filterObject = require("../utils/filterObject"); var _reactDom = _interopRequireDefault(require("react-dom")); var _ListItemSection = require("../ListItemSection"); var _ListItemSelect = require("../ListItemSelect"); var _ListItemAction = require("../ListItemAction"); var _StringUtils = require("../utils/StringUtils"); var _excluded = ["id", "value", "disabled", "optionTitle", "title"]; var _jsxFileName = "/home/builduser/work/a9c1ac8876d5057c/packages/wix-style-react/dist/cjs/DropdownLayout/DropdownLayout.js"; 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; } var MOUSE_EVENTS_SUPPORTED = ['mouseup', 'touchend']; var KEY = { arrowLeft: 'ArrowLeft', arrowUp: 'ArrowUp', arrowRight: 'ArrowRight', arrowDown: 'ArrowDown', escape: 'Escape', tab: 'Tab', enter: 'Enter', space: ' ', home: 'Home', end: 'End' }; var ListType = { action: 'action', select: 'select' }; var modulu = (n, m) => { var remain = n % m; return remain >= 0 ? remain : remain + m; }; var getUnit = value => (0, _StringUtils.isString)(value) ? value : "".concat(value, "px"); var NOT_HOVERED_INDEX = -1; var DIVIDER_OPTION_VALUE = exports.DIVIDER_OPTION_VALUE = '-'; class DropdownLayout extends _react.default.PureComponent { constructor(props) { super(props); this.focusableItemsIdsList = []; this.savedOnClicks = []; this.children = {}; // Deprecated this._onMouseEventsHandler = e => { if (!this._checkIfEventOnElements(e, [_reactDom.default.findDOMNode(this)])) { this._onClickOutside(e); } }; this._onClickOutside = event => { var { visible, onClickOutside } = this.props; if (visible && onClickOutside) { onClickOutside(event); } }; this._onSelect = (index, e) => { var { options, onSelect, listType } = this.props; if (listType !== ListType.select) { e.stopPropagation(); this._onClose(); return; } var chosenOption = options[index]; if (chosenOption) { var sameOptionWasPicked = chosenOption.id === this.state.selectedId; if (onSelect) { e.stopPropagation(); onSelect(chosenOption, sameOptionWasPicked); } } if (!this._isControlled()) { this.setState({ selectedId: chosenOption && chosenOption.id }); } return !!onSelect && chosenOption; }; this._onActionClick = e => { var onClick = this.savedOnClicks.find(_ref => { var { id } = _ref; return id === e.id; }).onClick; onClick && onClick(e); }; this._saveOnClicks = () => { this.savedOnClicks = this.props.options.map(_ref2 => { var { id, onClick } = _ref2; return { id, onClick }; }); }; this._onMouseEnter = index => { if (this._isSelectableOption(this.props.options[index])) { this._markOption(index); } }; this._onMouseLeave = () => this._markOption(NOT_HOVERED_INDEX); this._focusOnOption = () => { var { focusOnOption, options } = this.props; var markedIndex = options.findIndex(option => option.id === focusOnOption); if (markedIndex !== -1) { this._markOptionAtIndex(markedIndex); } else { // Remove focus this._markOption(markedIndex); } }; this._markOptionAtIndex = markedIndex => { var { infiniteScroll } = this.props; this._markOption(markedIndex); var menuElement = this.options; var hoveredElement = infiniteScroll ? this.options.childNodes[0].childNodes[markedIndex] : this.options.childNodes[markedIndex]; (0, _scrollIntoView.default)(menuElement, hoveredElement); }; /** * Handle keydown events for the DropdownLayout, mostly for accessibility * * @param {SyntheticEvent} event - The keydown event triggered by React * @returns {boolean} - Whether the event was handled by the component */ this._onSelectListKeyDown = event => { if (!this.props.visible || this.props.isComposing || this.props.listType !== ListType.select) { return false; } switch (event.key) { case KEY.arrowDown: { this._markNextStep(1); event.preventDefault(); break; } case KEY.arrowUp: { this._markNextStep(-1); event.preventDefault(); break; } case KEY.space: case KEY.enter: { if (!this._onSelect(this.state.hovered, event)) { return false; } break; } case KEY.tab: { if (this.props.closeOnSelect) { return this._onSelect(this.state.hovered, event); } else { if (this._onSelect(this.state.hovered, event)) { event.preventDefault(); return true; } else { return false; } } } case KEY.escape: { this._onClose(); break; } default: { return false; } } event.stopPropagation(); return true; }; this._focus = (focusedItemId, e) => { e && e.preventDefault(); var element = this.children[focusedItemId]; if (!element) { return; } var native = element.focus; var focusableHOC = element.wrappedComponentRef; var callback = native ? element.focus : focusableHOC ? focusableHOC.innerComponentRef.focus : () => ({}); this.setState({ focusedItemId }, () => callback()); }; this._handleActionListNavigation = (event, id) => { var length = this.focusableItemsIdsList.length; var focusedItemId = this.state.focusedItemId; var { key } = event; var currentMenuItemIndex = this.focusableItemsIdsList.indexOf(id); var firstMenuItem = this.focusableItemsIdsList[0]; var lastMenuItem = this.focusableItemsIdsList[length - 1]; if (key === KEY.arrowLeft || key === KEY.arrowUp) { focusedItemId = id === 0 ? lastMenuItem : this.focusableItemsIdsList[currentMenuItemIndex - 1]; } if (key === KEY.arrowRight || key === KEY.arrowDown) { focusedItemId = currentMenuItemIndex === length - 1 ? firstMenuItem : this.focusableItemsIdsList[currentMenuItemIndex + 1]; } if (key === KEY.home) { focusedItemId = firstMenuItem; } if (key === KEY.end) { focusedItemId = lastMenuItem; } if (focusedItemId !== this.state.focusedItemId) { this._focus(focusedItemId, event); } }; this._onActionListKeyDown = (event, id) => { if (this.props.listType !== ListType.action) { return; } var { key } = event; if (key === KEY.space || key === KEY.enter) { event.preventDefault(); this._onActionClick({ id: this.state.focusedItemId }); this._onClose(); } else if (key === KEY.escape || key === KEY.tab) { this._onClose(); } else { this._handleActionListNavigation(event, id); } event.stopPropagation(); }; this._onClose = () => { this._markOption(NOT_HOVERED_INDEX); if (this.props.onClose) { this.props.onClose(); } }; this._wrapWithInfiniteScroll = scrollableElement => { if (!this.options) { this.loadedWithUndefinedOptions = true; } return /*#__PURE__*/_react.default.createElement(_InfiniteScroll.default, { useWindow: true, dataHook: _DataAttr.DATA_HOOKS.INFINITE_SCROLL_CONTAINER, scrollElement: this.options, loadMore: this.props.loadMore, hasMore: this.props.hasMore, data: this.props.options, loader: /*#__PURE__*/_react.default.createElement("div", { className: _DropdownLayoutSt.classes.loader, __self: this, __source: { fileName: _jsxFileName, lineNumber: 541, columnNumber: 11 } }, /*#__PURE__*/_react.default.createElement(_Loader.default, { dataHook: _DataAttr.DROPDOWN_LAYOUT_LOADER, size: "small", __self: this, __source: { fileName: _jsxFileName, lineNumber: 542, columnNumber: 13 } })), __self: this, __source: { fileName: _jsxFileName, lineNumber: 533, columnNumber: 7 } }, scrollableElement); }; /** for testing purposes only */ this._getDataAttributes = () => { var { visible, dropDirectionUp } = this.props; var { selectedId } = this.state; return (0, _filterObject.filterObject)({ 'data-hook': _DataAttr.DATA_HOOKS.CONTENT_CONTAINER, [_DataAttr.DATA_SHOWN]: visible, [_DataAttr.DATA_SELECTED_OPTION_ID]: selectedId === 0 ? "".concat(selectedId) : selectedId, [_DataAttr.DATA_DIRECTION]: dropDirectionUp ? _DataAttr.DROPDOWN_LAYOUT_DIRECTIONS.UP : _DataAttr.DROPDOWN_LAYOUT_DIRECTIONS.DOWN }, (key, value) => !!value); }; // For testing purposes only this._getItemDataAttr = _ref3 => { var { hovered, selected, disabled } = _ref3; var { itemHeight, selectedHighlight } = this.props; return (0, _filterObject.filterObject)({ [_DataAttr.DATA_OPTION.DISABLED]: disabled, [_DataAttr.DATA_OPTION.SELECTED]: selected && selectedHighlight, [_DataAttr.DATA_OPTION.HOVERED]: hovered, /* deprecated */ [_DataAttr.DATA_OPTION.SIZE]: itemHeight }, (key, value) => !!value); }; this.containerRef = /*#__PURE__*/_react.default.createRef(); this.state = { hovered: NOT_HOVERED_INDEX, selectedId: props.selectedId, focusedItemId: null }; } componentDidMount() { if (this.loadedWithUndefinedOptions && this.options) { this.forceUpdate(); } var { focusOnSelectedOption, scrollToOption, autoFocus } = this.props; if (focusOnSelectedOption) { this._focusOnSelectedOption(); } else if (this.props.hasOwnProperty('focusOnOption')) { this._focusOnOption(); } if (scrollToOption) { this._scrollToOption(); } this._markOptionByProperty(this.props); // Deprecated MOUSE_EVENTS_SUPPORTED.forEach(eventName => { document.addEventListener(eventName, this._onMouseEventsHandler, true); }); this._boundEvents = MOUSE_EVENTS_SUPPORTED; if (autoFocus) { this._focusFirstOption(); } } componentWillUnmount() { if (this._boundEvents && typeof document !== 'undefined') { this._boundEvents.forEach(eventName => { document.removeEventListener(eventName, this._onMouseEventsHandler, true); }); } } componentDidUpdate(prevProps) { var { focusOnOption } = this.props; if (prevProps.focusOnOption !== focusOnOption) { this._focusOnOption(); } } UNSAFE_componentWillReceiveProps(nextProps) { if (this.props.visible !== nextProps.visible) { this._markOption(NOT_HOVERED_INDEX); } if (this.props.selectedId !== nextProps.selectedId) { this.setState({ selectedId: nextProps.selectedId }); } // make sure the same item is hovered if options changed if (this.state.hovered !== NOT_HOVERED_INDEX && (!nextProps.options[this.state.hovered] || this.props.options[this.state.hovered].id !== nextProps.options[this.state.hovered].id)) { this._markOption(this._findIndex(nextProps.options, item => item.id === this.props.options[this.state.hovered].id)); } this._markOptionByProperty(nextProps); } _focusFirstOption() { this._focus(this.focusableItemsIdsList[0]); } // Deprecated _checkIfEventOnElements(e, elem) { var current = e.target; while (current.parentNode) { if (elem.indexOf(current) > -1) { return true; } current = current.parentNode; } return current !== document; } // Deprecated _renderTopArrow() { var { withArrow, visible } = this.props; return withArrow && visible ? /*#__PURE__*/_react.default.createElement("div", { "data-hook": _DataAttr.DATA_HOOKS.TOP_ARROW, className: _DropdownLayoutSt.classes.arrow, __self: this, __source: { fileName: _jsxFileName, lineNumber: 175, columnNumber: 7 } }) : null; } _convertOptionToListItemSectionBuilder(_ref4) { var { option, idx } = _ref4; var { value, id, title: isTitle } = option; if (value === DIVIDER_OPTION_VALUE) { return (0, _ListItemSection.listItemSectionBuilder)({ dataHook: _DataAttr.OPTION_DATA_HOOKS.DIVIDER, id: id || idx, type: 'divider' }); } if (isTitle) { return (0, _ListItemSection.listItemSectionBuilder)({ dataHook: _DataAttr.OPTION_DATA_HOOKS.TITLE, id, type: 'subheader', title: value }); } } _convertOptionToListItemActionBuilder(_ref5) { var { option, idx } = _ref5; var { id, value, disabled, optionTitle, title } = option, rest = (0, _objectWithoutProperties2.default)(option, _excluded); return (0, _ListItemAction.listItemActionBuilder)(_objectSpread({ id: id !== undefined ? id : idx, ref: _ref6 => this.children[id] = _ref6, tabIndex: id === this.state.focusedItemId && !disabled ? '0' : '-1', disabled, title: optionTitle, role: 'menuitem' }, rest)); } _isControlled() { return typeof this.props.selectedId !== 'undefined' && typeof this.props.onSelect !== 'undefined'; } _focusOnSelectedOption() { if (this.selectedOption) { this.options.scrollTop = Math.max(this.selectedOption.offsetTop - this.selectedOption.offsetHeight, 0); } } _setSelectedOptionNode(optionNode, option) { if (option.id === this.state.selectedId) { this.selectedOption = optionNode; } } _markOption(index, options) { var { onOptionMarked } = this.props; options = options || this.props.options; this.setState({ hovered: index }); onOptionMarked && onOptionMarked(options[index] || null); } _getMarkedIndex() { var { options } = this.props; var useHoverIndex = this.state.hovered > NOT_HOVERED_INDEX; var useSelectedIdIndex = typeof this.state.selectedId !== 'undefined'; var markedIndex; if (useHoverIndex) { markedIndex = this.state.hovered; } else if (useSelectedIdIndex) { markedIndex = options.findIndex(option => option.id === this.state.selectedId); } else { markedIndex = NOT_HOVERED_INDEX; } return markedIndex; } _markNextStep(step) { var { options } = this.props; if (!options.some(this._isSelectableOption)) { return; } var markedIndex = this._getMarkedIndex(); do { markedIndex = Math.abs(modulu(Math.max(markedIndex + step, -1), options.length)); } while (!this._isSelectableOption(options[markedIndex])); this._markOptionAtIndex(markedIndex); } _scrollToOption() { var { scrollToOption, options } = this.props; var optionIndex = options.findIndex(option => option.id === scrollToOption); var optionNode = this.options.childNodes[optionIndex]; if (!optionNode) { return; } this.options.scrollTop = Math.max(optionNode.offsetTop - optionNode.offsetHeight, 0); } _renderNode(node) { return node ? /*#__PURE__*/_react.default.createElement("div", { __self: this, __source: { fileName: _jsxFileName, lineNumber: 524, columnNumber: 19 } }, node) : null; } _convertCustomOptionToBuilder(_ref7) { var { option } = _ref7; var { value: _value, id, disabled, overrideOptionStyle, overrideStyle } = option; if (overrideStyle) { return { id, disabled, overrideStyle, value: () => /*#__PURE__*/_react.default.createElement("div", { "data-hook": _DataAttr.DATA_HOOKS.OPTION, __self: this, __source: { fileName: _jsxFileName, lineNumber: 578, columnNumber: 22 } }, _value) }; } if (overrideOptionStyle) { return { id, disabled, overrideOptionStyle, value: () => /*#__PURE__*/_react.default.createElement("div", { "data-hook": _DataAttr.DATA_HOOKS.OPTION, __self: this, __source: { fileName: _jsxFileName, lineNumber: 587, columnNumber: 22 } }, _value) }; } } _convertOptionToListItemSelectBuilder(_ref8) { var { option } = _ref8; var { value, id, disabled } = option; var { selectedId } = this.state; var { itemHeight, selectedHighlight } = this.props; return (0, _ListItemSelect.listItemSelectBuilder)({ id, title: /*#__PURE__*/_react.default.createElement("div", { "data-hook": _DataAttr.DATA_HOOKS.OPTION, __self: this, __source: { fileName: _jsxFileName, lineNumber: 599, columnNumber: 14 } }, value), disabled, selected: id === selectedId && selectedHighlight, className: (0, _DropdownLayoutSt.st)(_DropdownLayoutSt.classes.selectableOption, { itemHeight }) }); } _isBuilderOption(_ref9) { var { option } = _ref9; var { value } = option; return typeof value === 'function'; } _isCustomOption(_ref0) { var { option } = _ref0; var { overrideOptionStyle, overrideStyle } = option; return overrideOptionStyle || overrideStyle; } _isActionOption(_ref1) { var { option } = _ref1; return option.value === ListType.action; } _isItemSection(_ref10) { var { option } = _ref10; var { value, title: isTitle } = option; return value === DIVIDER_OPTION_VALUE || isTitle; } _convertOptionToBuilder(option, idx) { if (this._isBuilderOption({ option })) { return option; } else if (this._isActionOption({ option })) { return this._convertOptionToListItemActionBuilder({ option, idx }); } else if (this._isItemSection({ option })) { return this._convertOptionToListItemSectionBuilder({ option, idx }); } else if (this._isCustomOption({ option })) { return this._convertCustomOptionToBuilder({ option }); } else { return this._convertOptionToListItemSelectBuilder({ option }); } } _renderOption(_ref11) { var { option, idx } = _ref11; var builderOption = this._convertOptionToBuilder(option, idx); var content = this._renderOptionContent({ option: builderOption, idx, hasLink: !!option.linkTo }); var isActionItem = this.props.listType === ListType.action; return option.linkTo ? /*#__PURE__*/_react.default.createElement("a", { className: _DropdownLayoutSt.classes.linkItem, key: idx, "data-hook": _DataAttr.DATA_HOOKS.LINK_ITEM, href: option.linkTo, role: isActionItem ? undefined : 'option', "aria-selected": isActionItem || option.disabled ? undefined : option.id === this.state.selectedId, "aria-hidden": option.disabled, __self: this, __source: { fileName: _jsxFileName, lineNumber: 651, columnNumber: 7 } }, content) : content; } _renderOptionContent(_ref12) { var { option, idx, hasLink } = _ref12; var { itemHeight, selectedHighlight, listType } = this.props; var { selectedId, hovered } = this.state; var { id, disabled, overrideStyle, overrideOptionStyle } = option; var optionState = { selected: id === selectedId, hovered: idx === hovered, disabled }; if (!disabled) { this.focusableItemsIdsList = [...this.focusableItemsIdsList, id]; } var isActionItem = listType === ListType.action; return /*#__PURE__*/_react.default.createElement("div", (0, _extends2.default)({ "aria-selected": hasLink || isActionItem || disabled ? undefined : optionState.selected, "aria-hidden": disabled }, this._getItemDataAttr(_objectSpread({}, optionState)), { role: hasLink || isActionItem ? undefined : 'option', className: overrideOptionStyle ? null : (0, _DropdownLayoutSt.st)(_DropdownLayoutSt.classes.option, _objectSpread(_objectSpread({}, optionState), {}, { selected: optionState.selected && selectedHighlight, itemHeight, overrideStyle })), ref: node => this._setSelectedOptionNode(node, option), onClick: !disabled ? e => this._onSelect(idx, e) : null, key: idx, onMouseEnter: () => this._onMouseEnter(idx), onMouseLeave: this._onMouseLeave, "data-hook": "dropdown-item-".concat(id), onKeyDown: e => this._onActionListKeyDown(e, id), __self: this, __source: { fileName: _jsxFileName, lineNumber: 706, columnNumber: 7 } }), option.value(optionState)); } _markOptionByProperty(props) { if (this.state.hovered === NOT_HOVERED_INDEX && props.markedOption) { var selectableOptions = props.options.filter(this._isSelectableOption); if (selectableOptions.length) { var idToMark = props.markedOption === true ? selectableOptions[0].id : props.markedOption; this._markOption(this._findIndex(props.options, item => item.id === idToMark), props.options); } } } _findIndex(arr, predicate) { return (Array.isArray(arr) ? arr : []).findIndex(predicate); } _isSelectableOption(option) { return option && option.value !== DIVIDER_OPTION_VALUE && !option.disabled && !option.title; } _renderOptions() { this.focusableItemsIdsList = []; this._saveOnClicks(); return this.props.options.map((option, idx) => this._renderOption({ option, idx })); } render() { var { className, visible, dropDirectionUp, tabIndex, onMouseEnter, onMouseLeave, onMouseDown, fixedHeader, withArrow, fixedFooter, inContainer, overflow, maxHeightPixels, minWidthPixels, infiniteScroll, dataHook, listType } = this.props; var renderedOptions = this._renderOptions(); return /*#__PURE__*/_react.default.createElement("div", { "data-list-type": listType, "data-hook": dataHook, className: (0, _DropdownLayoutSt.st)(_DropdownLayoutSt.classes.root, { visible, withArrow, direction: dropDirectionUp ? _DataAttr.DROPDOWN_LAYOUT_DIRECTIONS.UP : _DataAttr.DROPDOWN_LAYOUT_DIRECTIONS.DOWN, containerStyles: !inContainer }, className), tabIndex: tabIndex, onKeyDown: this._onSelectListKeyDown, onMouseEnter: onMouseEnter, onMouseLeave: onMouseLeave, onMouseDown: onMouseDown, ref: this.containerRef, __self: this, __source: { fileName: _jsxFileName, lineNumber: 798, columnNumber: 7 } }, /*#__PURE__*/_react.default.createElement("div", (0, _extends2.default)({}, this._getDataAttributes(), { className: _DropdownLayoutSt.classes.contentContainer, style: { overflow, maxHeight: getUnit(maxHeightPixels), minWidth: getUnit(minWidthPixels) }, __self: this, __source: { fileName: _jsxFileName, lineNumber: 820, columnNumber: 9 } }), this._renderNode(fixedHeader), /*#__PURE__*/_react.default.createElement("div", { className: _DropdownLayoutSt.classes.options, style: { maxHeight: getUnit(parseInt(maxHeightPixels, 10) - 35), overflow }, ref: _options => this.options = _options, "data-hook": _DataAttr.DATA_HOOKS.DROPDOWN_LAYOUT_OPTIONS, role: listType === ListType.select ? 'listbox' : 'menu', __self: this, __source: { fileName: _jsxFileName, lineNumber: 830, columnNumber: 11 } }, infiniteScroll ? this._wrapWithInfiniteScroll(renderedOptions) : renderedOptions), this._renderNode(fixedFooter)), this._renderTopArrow()); } } var optionPropTypes = _propTypes.default.shape({ id: _propTypes.default.oneOfType([_propTypes.default.string, _propTypes.default.number]).isRequired, value: _propTypes.default.oneOfType([_propTypes.default.node, _propTypes.default.string, _propTypes.default.func]).isRequired, disabled: _propTypes.default.bool, /** @deprecated*/ overrideStyle: _propTypes.default.bool, /** @deprecated*/ title: _propTypes.default.bool, overrideOptionStyle: _propTypes.default.bool, /* the string displayed within the input when the option is selected */ label: _propTypes.default.string }); function optionValidator(props, propName, componentName) { var option = props[propName]; // Notice: We don't use Proptypes.oneOf() to check for either option OR divider, because then the failure message would be less informative. if (typeof option === 'object' && option.value === DIVIDER_OPTION_VALUE) { return; } var optionError = _propTypes.default.checkPropTypes({ option: optionPropTypes }, { option }, 'option', componentName); if (optionError) { return optionError; } } DropdownLayout.propTypes = { /** A single CSS class name to be appended to the root element. */ className: _propTypes.default.string, /** @deprecated */ dropDirectionUp: _propTypes.default.bool, /** Scroll view to the selected option on opening the dropdown */ focusOnSelectedOption: _propTypes.default.bool, /** Callback function called whenever the user press the `Escape` keyboard.*/ onClose: _propTypes.default.func, /** Callback function called whenever the user selects a different option in the list */ onSelect: _propTypes.default.func, /** Callback function called whenever an option becomes focused (hovered/active). Receives the relevant option object from the original props.options array. */ onOptionMarked: _propTypes.default.func, /** Set overflow of container */ overflow: _propTypes.default.string, /** Should show or hide the component */ visible: _propTypes.default.bool, /** Array of objects: * - id `<string / number>` *required*: the id of the option, should be unique. * - value `<function / string / node>` *required*: can be a string, react element or a builder function. * - disabled `<bool>` *default value- false*: whether this option is disabled or not * - linkTo `<string>`: when provided the option will be an anchor to the given value * - title `<bool>` *default value- false* **deprecated**: please use `listItemSectionBuilder` for rendering a title. * - overrideStyle `<bool>` *default value- false* **deprecated**: please use `overrideOptionStyle` for override option styles. * - overrideOptionStyle `<bool>` *default value- false* - when set to `true`, the option will be responsible to its own styles. No styles will be applied from the DropdownLayout itself. * - label `<string>`: the string displayed within an input when the option is selected. This is used when using `<DropdownLayout/>` with an `<Input/>`. */ options: _propTypes.default.arrayOf(optionValidator), /** The id of the selected option in the list */ selectedId: _propTypes.default.oneOfType([_propTypes.default.string, _propTypes.default.number]), /** Specifies the tab order of the component. */ tabIndex: _propTypes.default.number, /** @deprecated Do not use this prop. */ onClickOutside: _propTypes.default.func, /** A fixed header to the list */ fixedHeader: _propTypes.default.node, /** A fixed footer to the list */ fixedFooter: _propTypes.default.node, /** Set the max height of the dropdownLayout in pixels */ maxHeightPixels: _propTypes.default.oneOfType([_propTypes.default.string, _propTypes.default.number]), /** Set the min width of the dropdownLayout in pixels */ minWidthPixels: _propTypes.default.oneOfType([_propTypes.default.string, _propTypes.default.number]), /** @deprecated Do not use this prop. */ withArrow: _propTypes.default.bool, /** Closes DropdownLayout on option selection */ closeOnSelect: _propTypes.default.bool, /** Callback function called whenever the user entered with the mouse to the dropdown layout.*/ onMouseEnter: _propTypes.default.func, /** Callback function called whenever the user exited with the mouse from the dropdown layout.*/ onMouseLeave: _propTypes.default.func, /** @deprecated Do not use this prop. */ itemHeight: _propTypes.default.oneOf(['small', 'big']), /** Whether the selected option will be highlighted when dropdown reopened. */ selectedHighlight: _propTypes.default.bool, /** Whether the `<DropdownLayout/>` is in a container component. If `true`, some styles such as shadows, positioning and padding will be added the the component contentContainer. */ inContainer: _propTypes.default.bool, /** Set this prop for lazy loading of the dropdown layout items.*/ infiniteScroll: _propTypes.default.bool, /** A callback called when more items are requested to be rendered. */ loadMore: _propTypes.default.func, /** Whether there are more items to be loaded. */ hasMore: _propTypes.default.bool, /** Sets the default hover behavior when: * 1. `false` means no default * 2. `true` means to hover the first selectable option * 3. Any number/string represents the id of option to hover */ markedOption: _propTypes.default.oneOfType([_propTypes.default.bool, _propTypes.default.string, _propTypes.default.number]), /** Marks (not selects) and scrolls view to the option on opening the dropdown by option id */ focusOnOption: _propTypes.default.oneOfType([_propTypes.default.string, _propTypes.default.number]), /** Scrolls to the specified option when dropdown is opened without marking it */ scrollToOption: _propTypes.default.oneOfType([_propTypes.default.number, _propTypes.default.string]), /** Defines type of behavior applied in list */ listType: _propTypes.default.oneOf([ListType.action, ListType.select]), /** Specifies whether first list item should be focused */ autoFocus: _propTypes.default.bool }; DropdownLayout.defaultProps = { options: [], tabIndex: 0, maxHeightPixels: 260, closeOnSelect: true, itemHeight: 'small', selectedHighlight: true, inContainer: false, infiniteScroll: false, loadMore: null, hasMore: false, markedOption: false, overflow: 'auto', listType: ListType.select }; DropdownLayout.displayName = 'DropdownLayout'; DropdownLayout.NONE_SELECTED_ID = NOT_HOVERED_INDEX; var _default = exports.default = DropdownLayout; //# sourceMappingURL=DropdownLayout.js.map