@sms-frontend/components
Version:
SMS Design React UI Library.
167 lines (166 loc) • 7.6 kB
JavaScript
;
var __assign = (this && this.__assign) || function () {
__assign = Object.assign || function(t) {
for (var s, i = 1, n = arguments.length; i < n; i++) {
s = arguments[i];
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
t[p] = s[p];
}
return t;
};
return __assign.apply(this, arguments);
};
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
var __read = (this && this.__read) || function (o, n) {
var m = typeof Symbol === "function" && o[Symbol.iterator];
if (!m) return o;
var i = m.call(o), r, ar = [], e;
try {
while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
}
catch (error) { e = { error: error }; }
finally {
try {
if (r && !r.done && (m = i["return"])) m.call(i);
}
finally { if (e) throw e.error; }
}
return ar;
};
var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
if (ar || !(i in from)) {
if (!ar) ar = Array.prototype.slice.call(from, 0, i);
ar[i] = from[i];
}
}
return to.concat(ar || Array.prototype.slice.call(from));
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
var react_1 = __importStar(require("react"));
var resize_observer_polyfill_1 = __importDefault(require("resize-observer-polyfill"));
var sub_menu_1 = __importDefault(require("./sub-menu"));
var style_1 = require("../_util/style");
var context_1 = __importDefault(require("./context"));
var OVERFLOW_THRESHOLD = 10;
function getNodeWidth(node) {
return node && +node.getBoundingClientRect().width.toFixed(2);
}
function translatePxToNumber(str) {
var result = Number(str.replace('px', ''));
return isNaN(result) ? 0 : result;
}
var OverflowWrap = function (props) {
var children = props.children;
var prefixCls = (0, react_1.useContext)(context_1.default).prefixCls;
var refUl = (0, react_1.useRef)(null);
var refResizeObserver = (0, react_1.useRef)(null);
var _a = __read((0, react_1.useState)(null), 2), lastVisibleIndex = _a[0], setLastVisibleIndex = _a[1];
var overflowSubMenuClass = prefixCls + "-overflow-sub-menu";
var overflowMenuItemClass = prefixCls + "-overflow-hidden-menu-item";
var overflowSubMenuMirrorClass = prefixCls + "-overflow-sub-menu-mirror";
(0, react_1.useEffect)(function () {
var ulElement = refUl.current;
computeLastVisibleIndex();
refResizeObserver.current = new resize_observer_polyfill_1.default(function (entries) {
entries.forEach(computeLastVisibleIndex);
});
refResizeObserver.current.observe(ulElement);
return function () {
if (refResizeObserver.current) {
refResizeObserver.current.disconnect();
}
};
}, [children]);
function computeLastVisibleIndex() {
if (!refUl.current) {
return;
}
var ulElement = refUl.current;
var maxWidth = getNodeWidth(ulElement) - OVERFLOW_THRESHOLD;
var childNodeList = [].slice.call(ulElement.children);
var menuItemIndex = 0;
var currentItemRight = 0;
var overflowSubMenuWidth = 0;
// 注意 childrenNodeList.length !== React.Children.count(children) 所以需要用 menuItemIndex 来标记真实的 MenuItem 下标
for (var i = 0; i < childNodeList.length; i++) {
var node = childNodeList[i];
var classNames = node.className.split(' ');
var isOverflowSubMenu = classNames.indexOf(overflowSubMenuClass) > -1;
var isOverflowSubMenuMirror = classNames.indexOf(overflowSubMenuMirrorClass) > -1;
// 忽略 overflowSubMenu 的宽度,其宽度测量交由 overflowSubMenuMirror
if (isOverflowSubMenu) {
continue;
}
var nodeWidth = getNodeWidth(node) +
translatePxToNumber((0, style_1.getStyle)(node, 'marginLeft')) +
translatePxToNumber((0, style_1.getStyle)(node, 'marginRight'));
if (isOverflowSubMenuMirror) {
overflowSubMenuWidth = nodeWidth;
continue;
}
currentItemRight += nodeWidth;
// 将要溢出的菜单项
if (currentItemRight > maxWidth) {
setLastVisibleIndex(
// 判断如果将最后一个菜单项换为 ... 是否会超出宽度
menuItemIndex - (currentItemRight - nodeWidth + overflowSubMenuWidth <= maxWidth ? 1 : 2));
return;
}
menuItemIndex++;
}
// 全部可见
setLastVisibleIndex(null);
}
var renderOverflowSubMenu = function (children, isMirror) {
if (isMirror === void 0) { isMirror = false; }
return (react_1.default.createElement(sub_menu_1.default, __assign({ title: react_1.default.createElement("span", null, "\u00B7\u00B7\u00B7"), key: "arco-menu-overflow-sub-menu" + (isMirror ? '-mirror' : ''), className: isMirror ? overflowSubMenuMirrorClass : overflowSubMenuClass }, props, { children: children })));
};
var renderChildren = function () {
var overflowSubMenu = null;
var overflowSubMenuMirror = renderOverflowSubMenu(null, true);
var originMenuItems = react_1.default.Children.map(children, function (child, index) {
var item = child;
if (lastVisibleIndex !== null) {
if (index > lastVisibleIndex) {
item = react_1.default.cloneElement(child, {
className: overflowMenuItemClass,
});
}
if (index === lastVisibleIndex + 1) {
var overflowedItems = react_1.default.Children.toArray(children)
.slice(lastVisibleIndex + 1)
.map(function (child) {
return react_1.default.cloneElement(child, { key: child.props._key });
});
overflowSubMenu = renderOverflowSubMenu(overflowedItems);
}
}
return item;
});
return __spreadArray(__spreadArray([overflowSubMenuMirror], __read(originMenuItems), false), [overflowSubMenu], false);
};
return (react_1.default.createElement("div", { className: prefixCls + "-overflow-wrap", ref: refUl }, renderChildren()));
};
exports.default = OverflowWrap;