zent
Version:
一套前端设计语言和基于React的实现
164 lines (163 loc) • 6.92 kB
JavaScript
import { __assign, __extends } from "tslib";
import { jsx as _jsx } from "react/jsx-runtime";
import { createRef, Component } from 'react';
import { MenuListItem, handleItemClick } from './MenuListItem';
var menuListPaddingTop = 0;
var MenuList = (function (_super) {
__extends(MenuList, _super);
function MenuList(props) {
var _this = _super.call(this, props) || this;
_this.refMenuScrollContainer = createRef();
_this.refMenuItemList = createRef();
_this.onKeyDown = function (e) {
switch (e.key) {
case 'Escape':
_this.close();
break;
case 'ArrowDown':
e.preventDefault();
if (_this.state.open) {
_this.moveFocusIndexDown();
}
break;
case 'ArrowUp': {
e.preventDefault();
if (_this.state.open) {
_this.moveFocusIndexUp();
}
break;
}
case 'Enter': {
if (_this.state.open) {
_this.selectCurrentFocusIndex(e);
}
break;
}
default:
}
};
_this.setFocusIndex = function (focusIdx, autoScroll) {
if (autoScroll === void 0) { autoScroll = true; }
_this.setState({
focusIdx: focusIdx == null ? null : _this.getItemIdxInItems(focusIdx),
autoScrollFocusIdx: autoScroll ? focusIdx : null,
});
};
_this.getItemIdxInItems = function (idx) {
var items = _this.props.items;
var targetIdx = idx % items.length;
if (targetIdx < 0) {
targetIdx += items.length;
}
return targetIdx;
};
_this.getValidItemIdx = function (idx, searchDown) {
if (searchDown === void 0) { searchDown = true; }
var items = _this.props.items;
if (!(items && items.length) ||
items.every(function (item) { return item.isDivider && item.isGroup; }) ||
typeof idx !== 'number' ||
Number.isNaN(idx)) {
return null;
}
var targetIdx = _this.getItemIdxInItems(idx);
var item = items[targetIdx];
if (!item || item.isDivider || item.isGroup || item.disabled) {
var initialIdx = targetIdx;
targetIdx = _this.getItemIdxInItems(searchDown ? targetIdx + 1 : targetIdx - 1);
item = items[targetIdx];
while (!item ||
((item.isDivider || item.isGroup || item.disabled) &&
targetIdx !== initialIdx)) {
targetIdx = _this.getItemIdxInItems(searchDown ? targetIdx + 1 : targetIdx - 1);
item = items[targetIdx];
}
}
return targetIdx;
};
_this.getTopMenu = function () {
return _this;
};
_this.moveFocusIndex = function (offset) {
var focusIdx = _this.state.focusIdx;
if (focusIdx !== null) {
_this.setFocusIndex(_this.getValidItemIdx(focusIdx + offset, offset > 0));
}
else {
_this.setFocusIndex(_this.getValidItemIdx(0));
}
};
_this.moveFocusIndexDown = function () {
_this.getTopMenu().moveFocusIndex(1);
};
_this.moveFocusIndexUp = function () {
_this.getTopMenu().moveFocusIndex(-1);
};
_this.selectCurrentFocusIndex = function (e) {
var ins = _this.getTopMenu();
var focusIdx = ins.state.focusIdx;
if (focusIdx !== null) {
var _a = _this.props, items = _a.items, onRequestClose = _a.onRequestClose;
var item = items[focusIdx];
handleItemClick({ item: item, event: e, onRequestClose: onRequestClose });
}
};
_this.close = function () {
_this.setState({
open: false,
});
};
_this.renderItems = function (items) {
if (items === void 0) { items = []; }
var onRequestClose = _this.props.onRequestClose;
var focusIdx = _this.state.focusIdx;
return items.map(function (item, index) {
return (_jsx(MenuListItem, { index: index, item: item, onRequestClose: onRequestClose, focusTo: _this.setFocusIndex, hover: focusIdx === index }, item.value === undefined ? index : item.value));
});
};
_this.state = {
focusIdx: null,
};
return _this;
}
MenuList.prototype.componentDidUpdate = function () {
this.autoScroll();
};
MenuList.prototype.autoScroll = function () {
var itemsLength = (this.props.items || []).length;
var _a = this.state, focusIdx = _a.focusIdx, autoScrollFocusIdx = _a.autoScrollFocusIdx;
var menuListNode = this.refMenuItemList.current;
var scrollContainer = this.refMenuScrollContainer.current;
if (itemsLength &&
focusIdx !== null &&
focusIdx === autoScrollFocusIdx &&
menuListNode &&
scrollContainer) {
var focusedItemNode = menuListNode.childNodes[this.state.focusIdx];
if (!focusedItemNode) {
return;
}
var itemOffsetTop = focusedItemNode.offsetTop;
var itemOffsetHeight = focusedItemNode.offsetHeight;
var containerOffsetHeight = scrollContainer.offsetHeight;
var containerScrollTop = scrollContainer.scrollTop;
if (containerOffsetHeight + containerScrollTop <
itemOffsetTop + itemOffsetHeight) {
scrollContainer.scrollTop =
itemOffsetTop +
itemOffsetHeight -
containerOffsetHeight -
menuListPaddingTop;
}
else if (containerScrollTop > itemOffsetTop) {
scrollContainer.scrollTop = itemOffsetTop - menuListPaddingTop;
}
}
};
MenuList.prototype.render = function () {
var items = this.props.items;
return (_jsx("div", __assign({ ref: this.refMenuScrollContainer, className: "zent-popup-menu", tabIndex: 0, onKeyDown: this.onKeyDown, "data-zv": '10.0.17' }, { children: items && items.length ? (_jsx("ul", __assign({ ref: this.refMenuItemList, "data-zv": '10.0.17' }, { children: this.renderItems(items) }), void 0)) : null }), void 0));
};
return MenuList;
}(Component));
export default MenuList;