UNPKG

rsuite

Version:

A suite of react components

522 lines (407 loc) 18.1 kB
"use strict"; var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard"); var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); exports.__esModule = true; exports.default = void 0; var _objectWithoutPropertiesLoose2 = _interopRequireDefault(require("@babel/runtime/helpers/objectWithoutPropertiesLoose")); var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends")); var _inheritsLoose2 = _interopRequireDefault(require("@babel/runtime/helpers/inheritsLoose")); var _isFunction2 = _interopRequireDefault(require("lodash/isFunction")); var _isNil2 = _interopRequireDefault(require("lodash/isNil")); var _omit2 = _interopRequireDefault(require("lodash/omit")); var _pick2 = _interopRequireDefault(require("lodash/pick")); var _isUndefined2 = _interopRequireDefault(require("lodash/isUndefined")); var React = _interopRequireWildcard(require("react")); var _propTypes = _interopRequireDefault(require("prop-types")); var _classnames = _interopRequireDefault(require("classnames")); var _shallowEqual = _interopRequireDefault(require("../utils/shallowEqual")); var _treeUtils = require("../utils/treeUtils"); var _utils = require("../utils"); var _Picker = require("../Picker"); var _DropdownMenu = _interopRequireWildcard(require("../Picker/DropdownMenu")); var _propTypes2 = require("../Picker/propTypes"); var SelectPicker = /*#__PURE__*/ function (_React$Component) { (0, _inheritsLoose2.default)(SelectPicker, _React$Component); function SelectPicker(props) { var _this; _this = _React$Component.call(this, props) || this; _this.positionRef = void 0; _this.menuContainerRef = void 0; _this.searchBarContainerRef = void 0; _this.toggleRef = void 0; _this.triggerRef = void 0; _this.getFocusableMenuItems = function () { var menuItems = _this.menuContainerRef.current.menuItems; if (!menuItems) { return []; } var items = Object.values(menuItems).map(function (item) { return item.props.getItemData(); }); return (0, _treeUtils.filterNodesOfTree)(items, function (item) { return _this.shouldDisplay(item); }); }; _this.getToggleInstance = function () { return _this.toggleRef.current; }; _this.getPositionInstance = function () { return _this.positionRef.current; }; _this.focusNextMenuItem = function () { var valueKey = _this.props.valueKey; _this.findNode(function (items, index) { var focusItem = items[index + 1]; if (!(0, _isUndefined2.default)(focusItem)) { _this.setState({ focusItemValue: focusItem[valueKey] }); } }); }; _this.focusPrevMenuItem = function () { var valueKey = _this.props.valueKey; _this.findNode(function (items, index) { var focusItem = items[index - 1]; if (!(0, _isUndefined2.default)(focusItem)) { _this.setState({ focusItemValue: focusItem[valueKey] }); } }); }; _this.selectFocusMenuItem = function (event) { var focusItemValue = _this.state.focusItemValue; var _this$props = _this.props, data = _this$props.data, valueKey = _this$props.valueKey; if (!focusItemValue) { return; } // Find active `MenuItem` by `value` var focusItem = (0, _treeUtils.findNodeOfTree)(data, function (item) { return (0, _shallowEqual.default)(item[valueKey], focusItemValue); }); _this.setState({ value: focusItemValue }); _this.handleSelect(focusItemValue, focusItem, event); _this.handleChange(focusItemValue, event); _this.handleCloseDropdown(); }; _this.handleKeyDown = function (event) { var _this$toggleRef, _this$toggleRef$curre, _this$toggleRef$curre2; var _this$state = _this.state, focusItemValue = _this$state.focusItemValue, active = _this$state.active; // enter if ((!focusItemValue || !active) && event.keyCode === 13) { _this.handleToggleDropdown(); } // delete if (event.keyCode === 8 && event.target === ((_this$toggleRef = _this.toggleRef) === null || _this$toggleRef === void 0 ? void 0 : (_this$toggleRef$curre = _this$toggleRef.current) === null || _this$toggleRef$curre === void 0 ? void 0 : (_this$toggleRef$curre2 = _this$toggleRef$curre.getToggleNode) === null || _this$toggleRef$curre2 === void 0 ? void 0 : _this$toggleRef$curre2.call(_this$toggleRef$curre))) { _this.handleClean(event); } if (!_this.menuContainerRef.current) { return; } (0, _Picker.onMenuKeyDown)(event, { down: _this.focusNextMenuItem, up: _this.focusPrevMenuItem, enter: _this.selectFocusMenuItem, esc: _this.handleCloseDropdown }); }; _this.handleItemSelect = function (value, item, event) { var nextState = { value: value, focusItemValue: value }; _this.setState(nextState); _this.handleSelect(value, item, event); _this.handleChange(value, event); _this.handleCloseDropdown(); }; _this.handleSelect = function (value, item, event) { var _this$props$onSelect, _this$props2, _this$toggleRef$curre3; (_this$props$onSelect = (_this$props2 = _this.props).onSelect) === null || _this$props$onSelect === void 0 ? void 0 : _this$props$onSelect.call(_this$props2, value, item, event); (_this$toggleRef$curre3 = _this.toggleRef.current) === null || _this$toggleRef$curre3 === void 0 ? void 0 : _this$toggleRef$curre3.onFocus(); }; _this.handleSearch = function (searchKeyword, event) { var _filteredData$; var _this$props3 = _this.props, onSearch = _this$props3.onSearch, valueKey = _this$props3.valueKey, data = _this$props3.data; var filteredData = (0, _treeUtils.filterNodesOfTree)(data, function (item) { return _this.shouldDisplay(item, searchKeyword); }); _this.setState({ searchKeyword: searchKeyword, focusItemValue: filteredData === null || filteredData === void 0 ? void 0 : (_filteredData$ = filteredData[0]) === null || _filteredData$ === void 0 ? void 0 : _filteredData$[valueKey] }); onSearch === null || onSearch === void 0 ? void 0 : onSearch(searchKeyword, event); }; _this.handleCloseDropdown = function () { var _this$triggerRef$curr, _this$triggerRef$curr2; (_this$triggerRef$curr = _this.triggerRef.current) === null || _this$triggerRef$curr === void 0 ? void 0 : (_this$triggerRef$curr2 = _this$triggerRef$curr.hide) === null || _this$triggerRef$curr2 === void 0 ? void 0 : _this$triggerRef$curr2.call(_this$triggerRef$curr); }; _this.handleOpenDropdown = function () { var _this$triggerRef$curr3, _this$triggerRef$curr4; (_this$triggerRef$curr3 = _this.triggerRef.current) === null || _this$triggerRef$curr3 === void 0 ? void 0 : (_this$triggerRef$curr4 = _this$triggerRef$curr3.show) === null || _this$triggerRef$curr4 === void 0 ? void 0 : _this$triggerRef$curr4.call(_this$triggerRef$curr3); }; _this.open = function () { var _this$handleOpenDropd, _this2; (_this$handleOpenDropd = (_this2 = _this).handleOpenDropdown) === null || _this$handleOpenDropd === void 0 ? void 0 : _this$handleOpenDropd.call(_this2); }; _this.close = function () { var _this$handleCloseDrop, _this3; (_this$handleCloseDrop = (_this3 = _this).handleCloseDropdown) === null || _this$handleCloseDrop === void 0 ? void 0 : _this$handleCloseDrop.call(_this3); }; _this.handleToggleDropdown = function () { var active = _this.state.active; if (active) { _this.handleCloseDropdown(); return; } _this.handleOpenDropdown(); }; _this.handleChange = function (value, event) { var _this$props$onChange, _this$props4; (_this$props$onChange = (_this$props4 = _this.props).onChange) === null || _this$props$onChange === void 0 ? void 0 : _this$props$onChange.call(_this$props4, value, event); }; _this.handleClean = function (event) { var _this$props5 = _this.props, disabled = _this$props5.disabled, cleanable = _this$props5.cleanable; if (disabled || !cleanable) { return; } var nextState = { value: null, focusItemValue: null }; _this.setState(nextState); _this.handleChange(null, event); }; _this.handleExit = function () { var _this$props$onClose, _this$props6; _this.setState({ searchKeyword: '', active: false }); (_this$props$onClose = (_this$props6 = _this.props).onClose) === null || _this$props$onClose === void 0 ? void 0 : _this$props$onClose.call(_this$props6); }; _this.handleOpen = function () { var _this$props$onOpen, _this$props7; var value = _this.getValue(); _this.setState({ active: true, focusItemValue: value }); (_this$props$onOpen = (_this$props7 = _this.props).onOpen) === null || _this$props$onOpen === void 0 ? void 0 : _this$props$onOpen.call(_this$props7); }; _this.addPrefix = function (name) { return (0, _utils.prefix)(_this.props.classPrefix)(name); }; var _value = props.value, defaultValue = props.defaultValue, groupBy = props.groupBy, _valueKey = props.valueKey, labelKey = props.labelKey; var nextValue = _value || defaultValue; _this.state = { value: nextValue, focusItemValue: nextValue, searchKeyword: '' }; _this.positionRef = React.createRef(); _this.menuContainerRef = React.createRef(); _this.toggleRef = React.createRef(); _this.triggerRef = React.createRef(); // for test _this.searchBarContainerRef = React.createRef(); if (groupBy === _valueKey || groupBy === labelKey) { throw Error('`groupBy` can not be equal to `valueKey` and `labelKey`'); } return _this; } var _proto = SelectPicker.prototype; _proto.getValue = function getValue() { var value = this.props.value; return (0, _isUndefined2.default)(value) ? this.state.value : value; }; /** * Index of keyword in `label` * @param {node} label */ _proto.shouldDisplay = function shouldDisplay(item, word) { var _this$props8 = this.props, searchBy = _this$props8.searchBy, labelKey = _this$props8.labelKey; var label = item === null || item === void 0 ? void 0 : item[labelKey]; var searchKeyword = typeof word === 'undefined' ? this.state.searchKeyword : word; if (typeof searchBy === 'function') { return searchBy(searchKeyword, label, item); } return (0, _Picker.shouldDisplay)(label, searchKeyword); }; _proto.findNode = function findNode(focus) { var items = this.getFocusableMenuItems(); var valueKey = this.props.valueKey; var focusItemValue = this.state.focusItemValue; for (var i = 0; i < items.length; i += 1) { if ((0, _shallowEqual.default)(focusItemValue, items[i][valueKey])) { focus(items, i); return; } } focus(items, -1); }; _proto.renderDropdownMenu = function renderDropdownMenu() { var _this4 = this; var _this$props9 = this.props, data = _this$props9.data, groupBy = _this$props9.groupBy, searchable = _this$props9.searchable, locale = _this$props9.locale, renderMenu = _this$props9.renderMenu, renderExtraFooter = _this$props9.renderExtraFooter, menuClassName = _this$props9.menuClassName, menuStyle = _this$props9.menuStyle, menuAutoWidth = _this$props9.menuAutoWidth, sort = _this$props9.sort, virtualized = _this$props9.virtualized; var focusItemValue = this.state.focusItemValue; var classes = (0, _classnames.default)(this.addPrefix('select-menu'), menuClassName); var filteredData = (0, _treeUtils.filterNodesOfTree)(data, function (item) { return _this4.shouldDisplay(item); }); // Create a tree structure data when set `groupBy` if (groupBy) { filteredData = (0, _utils.getDataGroupBy)(filteredData, groupBy, sort); } else if (typeof sort === 'function') { filteredData = filteredData.sort(sort(false)); } var menuProps = (0, _pick2.default)(this.props, Object.keys((0, _omit2.default)(_DropdownMenu.dropdownMenuPropTypes, ['className', 'style', 'classPrefix']))); var menu = filteredData.length ? React.createElement(_DropdownMenu.default, (0, _extends2.default)({}, menuProps, { classPrefix: this.addPrefix('select-menu'), dropdownMenuItemClassPrefix: this.addPrefix('select-menu-item'), dropdownMenuItemComponentClass: _Picker.DropdownMenuItem, ref: this.menuContainerRef, activeItemValues: [this.getValue()], focusItemValue: focusItemValue, data: filteredData, group: !(0, _isUndefined2.default)(groupBy), onSelect: this.handleItemSelect, virtualized: virtualized })) : React.createElement("div", { className: this.addPrefix('none') }, locale.noResultsText); return React.createElement(_Picker.MenuWrapper, { autoWidth: menuAutoWidth, className: classes, style: menuStyle, onKeyDown: this.handleKeyDown, getToggleInstance: this.getToggleInstance, getPositionInstance: this.getPositionInstance }, searchable && React.createElement(_Picker.SearchBar, { ref: this.searchBarContainerRef, placeholder: locale.searchPlaceholder, onChange: this.handleSearch, value: this.state.searchKeyword }), renderMenu ? renderMenu(menu) : menu, renderExtraFooter === null || renderExtraFooter === void 0 ? void 0 : renderExtraFooter()); }; _proto.render = function render() { var _this$props10 = this.props, data = _this$props10.data, valueKey = _this$props10.valueKey, labelKey = _this$props10.labelKey, placeholder = _this$props10.placeholder, renderValue = _this$props10.renderValue, disabled = _this$props10.disabled, cleanable = _this$props10.cleanable, locale = _this$props10.locale, toggleComponentClass = _this$props10.toggleComponentClass, style = _this$props10.style, onEntered = _this$props10.onEntered, onExited = _this$props10.onExited, onClean = _this$props10.onClean, positionRef = _this$props10.positionRef, rest = (0, _objectWithoutPropertiesLoose2.default)(_this$props10, ["data", "valueKey", "labelKey", "placeholder", "renderValue", "disabled", "cleanable", "locale", "toggleComponentClass", "style", "onEntered", "onExited", "onClean", "positionRef"]); var unhandled = (0, _utils.getUnhandledProps)(SelectPicker, rest); var value = this.getValue(); // Find active `MenuItem` by `value` var activeItem = (0, _treeUtils.findNodeOfTree)(data, function (item) { return (0, _shallowEqual.default)(item[valueKey], value); }); /** * 1.Have a value and the value is valid. * 2.Regardless of whether the value is valid, as long as renderValue is set, it is judged to have a value. */ var hasValue = !!activeItem || !(0, _isNil2.default)(value) && (0, _isFunction2.default)(renderValue); var selectedElement = placeholder; if (activeItem === null || activeItem === void 0 ? void 0 : activeItem[labelKey]) { selectedElement = activeItem[labelKey]; } if (!(0, _isNil2.default)(value) && (0, _isFunction2.default)(renderValue)) { selectedElement = renderValue(value, activeItem, selectedElement); if ((0, _isNil2.default)(selectedElement)) { hasValue = false; } } var classes = (0, _Picker.getToggleWrapperClassName)('select', this.addPrefix, this.props, hasValue); return React.createElement(_Picker.PickerToggleTrigger, { pickerProps: this.props, ref: this.triggerRef, positionRef: (0, _utils.mergeRefs)(this.positionRef, positionRef), onEntered: (0, _utils.createChainedFunction)(this.handleOpen, onEntered), onExited: (0, _utils.createChainedFunction)(this.handleExit, onExited), speaker: this.renderDropdownMenu() }, React.createElement("div", { className: classes, style: style, tabIndex: -1, role: "menu" }, React.createElement(_Picker.PickerToggle, (0, _extends2.default)({}, unhandled, { ref: this.toggleRef, onClean: (0, _utils.createChainedFunction)(this.handleClean, onClean), onKeyDown: this.handleKeyDown, componentClass: toggleComponentClass, cleanable: cleanable && !disabled, hasValue: hasValue, active: this.state.active }), selectedElement || locale.placeholder))); }; return SelectPicker; }(React.Component); SelectPicker.propTypes = (0, _extends2.default)({}, _propTypes2.listPickerPropTypes, { menuAutoWidth: _propTypes.default.bool, maxHeight: _propTypes.default.number, renderMenu: _propTypes.default.func, renderMenuItem: _propTypes.default.func, renderMenuGroup: _propTypes.default.func, onSelect: _propTypes.default.func, onGroupTitleClick: _propTypes.default.func, onSearch: _propTypes.default.func, /** * group by key in `data` */ groupBy: _propTypes.default.any, sort: _propTypes.default.func, searchable: _propTypes.default.bool, virtualized: _propTypes.default.bool, searchBy: _propTypes.default.func }); SelectPicker.defaultProps = (0, _extends2.default)({}, _propTypes2.listPickerDefaultProps, { searchable: true, menuAutoWidth: true, virtualized: true, maxHeight: 320, locale: { placeholder: 'Select', searchPlaceholder: 'Search', noResultsText: 'No results found' } }); var _default = (0, _utils.defaultProps)({ classPrefix: 'picker' })(SelectPicker); exports.default = _default; module.exports = exports.default;