rsuite
Version:
A suite of react components
339 lines (276 loc) • 12.1 kB
JavaScript
"use strict";
var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard");
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
exports.__esModule = true;
exports.default = exports.dropdownMenuPropTypes = 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 _findIndex2 = _interopRequireDefault(require("lodash/findIndex"));
var _isNumber2 = _interopRequireDefault(require("lodash/isNumber"));
var _isString2 = _interopRequireDefault(require("lodash/isString"));
var _isUndefined2 = _interopRequireDefault(require("lodash/isUndefined"));
var React = _interopRequireWildcard(require("react"));
var _propTypes = _interopRequireDefault(require("prop-types"));
var _domLib = require("dom-lib");
var _classnames = _interopRequireDefault(require("classnames"));
var _List = _interopRequireDefault(require("react-virtualized/dist/commonjs/List"));
var _AutoSizer = _interopRequireDefault(require("react-virtualized/dist/commonjs/AutoSizer"));
var _shallowEqual = _interopRequireDefault(require("../utils/shallowEqual"));
var _utils = require("../utils");
var _DropdownMenuGroup = _interopRequireDefault(require("./DropdownMenuGroup"));
var _getDataGroupBy = require("../utils/getDataGroupBy");
var dropdownMenuPropTypes = {
classPrefix: _propTypes.default.string,
className: _propTypes.default.string,
dropdownMenuItemComponentClass: _propTypes.default.elementType,
dropdownMenuItemClassPrefix: _propTypes.default.string,
data: _propTypes.default.array,
group: _propTypes.default.bool,
disabledItemValues: _propTypes.default.array,
activeItemValues: _propTypes.default.array,
focusItemValue: _propTypes.default.any,
maxHeight: _propTypes.default.number,
valueKey: _propTypes.default.string,
labelKey: _propTypes.default.string,
style: _propTypes.default.object,
renderMenuItem: _propTypes.default.func,
renderMenuGroup: _propTypes.default.func,
onSelect: _propTypes.default.func,
onGroupTitleClick: _propTypes.default.func,
virtualized: _propTypes.default.bool,
listProps: _propTypes.default.object
};
exports.dropdownMenuPropTypes = dropdownMenuPropTypes;
var ROW_HEIGHT = 36;
var DropdownMenu =
/*#__PURE__*/
function (_React$Component) {
(0, _inheritsLoose2.default)(DropdownMenu, _React$Component);
function DropdownMenu(props) {
var _this;
_this = _React$Component.call(this, props) || this;
_this.menuBodyContainerRef = void 0;
_this.addPrefix = function (name) {
return (0, _utils.prefix)(_this.props.classPrefix)(name);
};
_this.handleSelect = function (item, value, event, checked) {
var _this$props$onSelect, _this$props;
(_this$props$onSelect = (_this$props = _this.props).onSelect) === null || _this$props$onSelect === void 0 ? void 0 : _this$props$onSelect.call(_this$props, value, item, event, checked);
};
_this.getItemData = function (itemData) {
return itemData;
};
_this.menuItems = {};
_this.bindMenuItems = function (disabled, key, ref) {
if (ref && !disabled) {
_this.menuItems[key] = ref;
}
};
_this.handleGroupTitleClick = function (key, event) {
var _this$props$onGroupTi, _this$props2;
var foldedGroupKeys = _this.state.foldedGroupKeys;
var nextGroupKeys = foldedGroupKeys.filter(function (item) {
return item !== key;
});
if (nextGroupKeys.length === foldedGroupKeys.length) {
nextGroupKeys.push(key);
}
_this.setState({
foldedGroupKeys: nextGroupKeys
});
(_this$props$onGroupTi = (_this$props2 = _this.props).onGroupTitleClick) === null || _this$props$onGroupTi === void 0 ? void 0 : _this$props$onGroupTi.call(_this$props2, event);
};
_this.menuBodyContainerRef = React.createRef();
_this.state = {
foldedGroupKeys: []
};
return _this;
}
var _proto = DropdownMenu.prototype;
_proto.componentDidMount = function componentDidMount() {
this.updateScrollPoistion();
};
_proto.componentDidUpdate = function componentDidUpdate(prevProps) {
if (!(0, _shallowEqual.default)(prevProps.focusItemValue, this.props.focusItemValue)) {
this.updateScrollPoistion();
}
};
_proto.updateScrollPoistion = function updateScrollPoistion() {
var container = this.menuBodyContainerRef.current;
var activeItem = container.querySelector("." + this.addPrefix('item-focus'));
if (!activeItem) {
activeItem = container.querySelector("." + this.addPrefix('item-active'));
}
if (!activeItem) {
return;
}
var position = (0, _domLib.getPosition)(activeItem, container);
var sTop = (0, _domLib.scrollTop)(container);
var sHeight = (0, _domLib.getHeight)(container);
if (sTop > position.top) {
(0, _domLib.scrollTop)(container, Math.max(0, position.top - 20));
} else if (position.top > sTop + sHeight) {
(0, _domLib.scrollTop)(container, Math.max(0, position.top - sHeight + 32));
}
};
_proto.getRowHeight = function getRowHeight(list, _ref) {
var index = _ref.index;
var item = list[index];
if (this.props.group && item[_getDataGroupBy.KEY_GROUP] && index !== 0) {
return 48;
}
return ROW_HEIGHT;
}
/**
* public: Provided to Picker calls, support keyboard operation to get focus.
*/
;
_proto.renderItem = function renderItem(list, _ref2) {
var index = _ref2.index,
style = _ref2.style;
var _this$props3 = this.props,
valueKey = _this$props3.valueKey,
labelKey = _this$props3.labelKey,
group = _this$props3.group,
renderMenuGroup = _this$props3.renderMenuGroup,
disabledItemValues = _this$props3.disabledItemValues,
activeItemValues = _this$props3.activeItemValues,
focusItemValue = _this$props3.focusItemValue,
renderMenuItem = _this$props3.renderMenuItem,
dropdownMenuItemClassPrefix = _this$props3.dropdownMenuItemClassPrefix,
DropdownMenuItem = _this$props3.dropdownMenuItemComponentClass;
var foldedGroupKeys = this.state.foldedGroupKeys;
var item = list[index];
var value = item[valueKey];
var label = item[labelKey];
if ((0, _isUndefined2.default)(label) && !item[_getDataGroupBy.KEY_GROUP]) {
throw Error("labelKey \"" + labelKey + "\" is not defined in \"data\" : " + index);
} // Use `value` in keys when If `value` is string or number
var itemKey = (0, _isString2.default)(value) || (0, _isNumber2.default)(value) ? value : index;
/**
* Render <DropdownMenuGroup>
* when if `group` is enabled
*/
if (group && item[_getDataGroupBy.KEY_GROUP]) {
var groupValue = item[_getDataGroupBy.KEY_GROUP_TITLE];
return React.createElement(_DropdownMenuGroup.default, {
style: style,
classPrefix: this.addPrefix('group'),
className: (0, _classnames.default)({
folded: foldedGroupKeys.some(function (key) {
return key === groupValue;
})
}),
key: "group-" + groupValue,
"data-key": "group-" + groupValue,
onClick: this.handleGroupTitleClick.bind(null, groupValue)
}, renderMenuGroup ? renderMenuGroup(groupValue, item) : groupValue);
} else if ((0, _isUndefined2.default)(value) && !(0, _isUndefined2.default)(item[_getDataGroupBy.KEY_GROUP])) {
throw Error("valueKey \"" + valueKey + "\" is not defined in \"data\" : " + index + " ");
}
var disabled = disabledItemValues === null || disabledItemValues === void 0 ? void 0 : disabledItemValues.some(function (disabledValue) {
return (0, _shallowEqual.default)(disabledValue, value);
});
var active = activeItemValues === null || activeItemValues === void 0 ? void 0 : activeItemValues.some(function (v) {
return (0, _shallowEqual.default)(v, value);
});
var focus = !(0, _isUndefined2.default)(focusItemValue) && (0, _shallowEqual.default)(focusItemValue, value);
return React.createElement(DropdownMenuItem, {
"data-key": itemKey,
style: style,
key: itemKey,
disabled: disabled,
active: active,
focus: focus,
value: value,
classPrefix: dropdownMenuItemClassPrefix,
getItemData: this.getItemData.bind(this, item),
ref: this.bindMenuItems.bind(this, disabled, itemKey),
onSelect: this.handleSelect.bind(this, item)
}, renderMenuItem ? renderMenuItem(label, item) : label);
};
_proto.renderMenuItems = function renderMenuItems() {
var _this2 = this;
this.menuItems = {};
var _this$props4 = this.props,
_this$props4$data = _this$props4.data,
data = _this$props4$data === void 0 ? [] : _this$props4$data,
group = _this$props4.group,
maxHeight = _this$props4.maxHeight,
activeItemValues = _this$props4.activeItemValues,
valueKey = _this$props4.valueKey,
virtualized = _this$props4.virtualized,
listProps = _this$props4.listProps;
var foldedGroupKeys = this.state.foldedGroupKeys;
var filteredItems = group ? data.filter(function (item) {
return !(foldedGroupKeys === null || foldedGroupKeys === void 0 ? void 0 : foldedGroupKeys.some(function (key) {
var _item$parent;
return key === ((_item$parent = item.parent) === null || _item$parent === void 0 ? void 0 : _item$parent[_getDataGroupBy.KEY_GROUP_TITLE]);
}));
}) : data;
var rowCount = filteredItems.length;
if (virtualized && rowCount * ROW_HEIGHT > maxHeight) {
return React.createElement(_AutoSizer.default, {
defaultHeight: maxHeight,
style: {
width: 'auto',
height: 'auto'
}
}, function (_ref3) {
var height = _ref3.height,
width = _ref3.width;
return React.createElement(_List.default, (0, _extends2.default)({}, listProps, {
width: width,
height: height || maxHeight,
scrollToIndex: (0, _findIndex2.default)(data, function (item) {
return item[valueKey] === (activeItemValues === null || activeItemValues === void 0 ? void 0 : activeItemValues[0]);
}),
rowCount: rowCount,
rowHeight: _this2.getRowHeight.bind(_this2, filteredItems),
rowRenderer: _this2.renderItem.bind(_this2, filteredItems)
}));
});
}
return React.createElement(React.Fragment, null, filteredItems.map(function (_item, index) {
return _this2.renderItem(filteredItems, {
index: index
});
}));
};
_proto.render = function render() {
var _this$props5 = this.props,
maxHeight = _this$props5.maxHeight,
className = _this$props5.className,
style = _this$props5.style,
group = _this$props5.group,
rest = (0, _objectWithoutPropertiesLoose2.default)(_this$props5, ["maxHeight", "className", "style", "group"]);
var classes = (0, _classnames.default)(className, this.addPrefix('items'), {
grouped: group
});
var unhandled = (0, _utils.getUnhandledProps)(DropdownMenu, rest);
var styles = (0, _extends2.default)({}, style, {
maxHeight: maxHeight
});
return React.createElement("div", (0, _extends2.default)({
role: "list",
className: classes,
ref: this.menuBodyContainerRef,
style: styles
}, unhandled), this.renderMenuItems());
};
return DropdownMenu;
}(React.Component);
DropdownMenu.propTypes = dropdownMenuPropTypes;
DropdownMenu.defaultProps = {
data: [],
activeItemValues: [],
disabledItemValues: [],
maxHeight: 320,
valueKey: 'value',
labelKey: 'label'
};
var _default = (0, _utils.defaultProps)({
classPrefix: 'dropdown-menu'
})(DropdownMenu);
exports.default = _default;