UNPKG

responsive-breadcrumb

Version:
161 lines (148 loc) 8.85 kB
'use strict'; var React = require('react'); function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; } var React__default = /*#__PURE__*/_interopDefaultLegacy(React); var ELLIPSIS_BUTTON_WIDTH = 40; var MIN_DISPLAY_WIDTH = 80; function calcFixedItemWidth(items, parentEleWidth) { var totalWidth = items.reduce(function (acc, curr) { return acc + curr.width; }, 0); for (var _i = 0, items_1 = items; _i < items_1.length; _i++) { var item = items_1[_i]; if (item.width <= MIN_DISPLAY_WIDTH) continue; var gap = totalWidth - parentEleWidth; var reduce = item.width - MIN_DISPLAY_WIDTH; if (gap > reduce) { item.idealWidth = MIN_DISPLAY_WIDTH; totalWidth -= reduce; if (totalWidth <= parentEleWidth) break; } else { item.idealWidth = item.width - gap; break; } } return items; } function calcBreadcrumb(items, parentEleWidth) { var totalWidth = items.reduce(function (acc, curr) { return acc + curr.width; }, 0); if (totalWidth <= parentEleWidth) { return items; } if (items.length <= 3) { return calcFixedItemWidth(items, parentEleWidth); } var first = items.shift(); var lastOne = items.pop(); var lastTwo = items.pop(); var displayItems = [first, lastTwo, lastOne]; var existWidth = displayItems.reduce(function (acc, curr) { return acc + curr.width; }, 0); var remaindWidth = parentEleWidth - existWidth - ELLIPSIS_BUTTON_WIDTH; if (remaindWidth <= 0) { displayItems = calcFixedItemWidth(displayItems, parentEleWidth - ELLIPSIS_BUTTON_WIDTH); items.forEach(function (item) { return (item.omit = true); }); return displayItems.concat(items); } var totalRestWidth = items.reduce(function (acc, curr) { return acc + curr.width; }, 0); for (var _i = 0, items_2 = items; _i < items_2.length; _i++) { var item = items_2[_i]; totalRestWidth -= item.width; item.omit = true; if (totalRestWidth <= remaindWidth) break; } return displayItems.concat(items); } function styleInject(css, ref) { if (ref === void 0) ref = {}; var insertAt = ref.insertAt; if (!css || typeof document === 'undefined') { return; } var head = document.head || document.getElementsByTagName('head')[0]; var style = document.createElement('style'); style.type = 'text/css'; if (insertAt === 'top') { if (head.firstChild) { head.insertBefore(style, head.firstChild); } else { head.appendChild(style); } } else { head.appendChild(style); } if (style.styleSheet) { style.styleSheet.cssText = css; } else { style.appendChild(document.createTextNode(css)); } } var css_248z = ".responsive_breadcrumb {\n display: flex;\n align-items: center;\n white-space: nowrap;\n}\n\n.rb_item {\n display: flex;\n align-items: center;\n color: #858e99;\n cursor: pointer;\n}\n\n.rb_item .rb_name {\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.rb_last_item {\n color: #263035;\n cursor: default;\n}\n\n.rb_separator {\n margin: 0 4px;\n}\n\n.rb_omit_wrapper {\n position: relative;\n}\n\n.rb_omit_wrapper:hover .rb_omit_list {\n display: block;\n}\n\n.rb_omit_list {\n display: none;\n position: absolute;\n padding: 4px;\n max-width: 200px;\n white-space: nowrap;\n background-color: #fff;\n box-shadow: 0px 9px 28px 8px rgba(87, 98, 114, 0.05),\n 0px 6px 10px rgba(87, 98, 114, 0.05),\n 0px 3px 6px -4px rgba(87, 98, 114, 0.05);\n border-radius: 4px;\n transform: translate(-50%, 0px);\n animation: raise-up 0.3s;\n}\n\n.rb_omit_item {\n padding: 6px;\n color: #858e99;\n border-radius: 4px;\n cursor: pointer;\n overflow: hidden;\n text-overflow: ellipsis;\n transition: background-color 0.2s;\n}\n\n.rb_omit_item:hover {\n background-color: #f3f4f5;\n}\n\n.clone_list {\n position: fixed;\n top: 99px;\n left: 0;\n /* opacity: 0; */\n}\n\n@keyframes raise-up {\n 0% {\n transform: translate(-50%, -12px) scaleY(0.9);\n }\n}\n"; styleInject(css_248z); function Breadcrumb(props) { var className = props.className, items = props.items, _a = props.separator, separator = _a === void 0 ? '>' : _a, onClick = props.onClick; var clsName = className ? "responsive_breadcrumb ".concat(className) : 'responsive_breadcrumb'; var breadcrumbRef = React.useRef(null); var cloneListRef = React.useRef(null); var calcedItemList = React.useRef([]); var _b = React.useState([]), breadcrumbList = _b[0], setBreadcrumbList = _b[1]; var lastIndex = breadcrumbList.length - 1; React.useEffect(function () { cloneListRef.current.style.display = 'flex'; calcedItemList.current = []; calcBreadcrumbList(items); }, [items]); function calcBreadcrumbList(items) { if (!cloneListRef.current) return; var parent = breadcrumbRef.current.parentElement; var children = cloneListRef.current.children; var itemDatas = []; var localItems = items.concat(); for (var i = 0; i < children.length; i++) { itemDatas.push({ index: i, width: children[i].clientWidth }); } calcedItemList.current = calcBreadcrumb(itemDatas, parent.clientWidth).sort(function (a, b) { return a.index - b.index; }); if (calcedItemList.current.some(function (item) { return item.omit; })) { var omitList = calcedItemList.current.filter(function (item) { return item.omit; }); var startIndex = omitList[0].index; var lastIndex_1 = omitList[omitList.length - 1].index; localItems.splice(startIndex, lastIndex_1 - startIndex + 1, { name: '...', key: 'omit-list', omitList: localItems.slice(startIndex, lastIndex_1 + 1) }); calcedItemList.current.splice(startIndex, lastIndex_1 - startIndex + 1, {}); } setBreadcrumbList(localItems); cloneListRef.current.style.display = 'none'; } return (React__default["default"].createElement("div", { className: clsName, ref: breadcrumbRef }, React__default["default"].createElement("div", { className: "".concat(clsName, " clone_list"), ref: cloneListRef }, items.map(function (item, index) { var key = item.key, name = item.name; var itemKey = key || name || index; var isLastItem = index === lastIndex; return (React__default["default"].createElement("div", { className: isLastItem ? 'rb_item rb_last_item' : 'rb_item', key: itemKey }, React__default["default"].createElement("span", { className: "rb_name" }, name), isLastItem ? null : React__default["default"].createElement("div", { className: "rb_separator" }, separator))); })), breadcrumbList.map(function (item, index) { var _a; var key = item.key, name = item.name, omitList = item.omitList; var itemKey = key || name || index; var isLastItem = index === lastIndex; var idealWidth = (_a = calcedItemList.current[index]) === null || _a === void 0 ? void 0 : _a.idealWidth; if (Array.isArray(omitList)) { return (React__default["default"].createElement("div", { className: "rb_item", key: itemKey }, React__default["default"].createElement("div", { className: "rb_omit_wrapper" }, React__default["default"].createElement("span", { className: "rb_name" }, name), React__default["default"].createElement("div", { className: "rb_omit_list" }, omitList.map(function (omitItem) { return (React__default["default"].createElement("div", { className: "rb_omit_item", key: omitItem.key || omitItem.name, title: omitItem.name, onClick: function () { return onClick(omitItem); } }, omitItem.name)); }))), React__default["default"].createElement("div", { className: "rb_separator" }, separator))); } return (React__default["default"].createElement("div", { className: isLastItem ? 'rb_item rb_last_item' : 'rb_item', key: itemKey, title: name, style: idealWidth ? { width: idealWidth } : undefined, onClick: isLastItem ? undefined : function () { return onClick(item); } }, React__default["default"].createElement("span", { className: "rb_name" }, name), isLastItem ? null : React__default["default"].createElement("div", { className: "rb_separator" }, separator))); }))); } module.exports = Breadcrumb;