kxd-react-route-cache
Version:
change color from react-route-cache for my project
186 lines (185 loc) • 8.54 kB
JavaScript
import React, { useCallback, useEffect, useRef, useState } from 'react';
import { useNavigate } from 'react-router-dom';
import { CloseCircleOutlined, LeftOutlined, RightOutlined, CloseOutlined } from '@ant-design/icons';
import { useSize } from 'ahooks';
import { Divider, Flex, Tooltip } from 'antd';
import { useKeepAliveContext } from '../context';
import { useKeepAlive } from '../hooks/use-keep-alive';
import '../index.scss';
export const RouterTabs = ({ theme = 'light', size = 'middle' }) => {
// 主题style
const styles = {
itemBg: theme === 'dark' ? '#001628' : '#fafafa',
itemActiveBg: theme === 'dark' ? '#1677ff' : '#fff',
itemColor: theme === 'dark' ? '#ffffffa6' : '#999',
itemHoverColor: theme === 'dark' ? '#fff' : '#197b8e',
itemActiveColor: theme === 'dark' ? '#fff' : '#197b8e',
iconBg: theme === 'dark' ? '#042c4d' : '#fff',
iconColor: theme === 'dark' ? '#ffffffa6' : '#999',
hoverIconColor: theme === 'dark' ? '#fff' : '#000',
};
// 尺寸style
const sizeStyle = {
fontSize: size === 'large' ? '16px' : '14px',
padding: size === 'small' ? '6px 16px' : '8px 16px',
};
const { tabs, active } = useKeepAliveContext();
const { close, closeAll } = useKeepAlive();
const navigate = useNavigate();
const [left, setLeft] = useState(0);
const tabsOuterRef = useRef();
const tabsInnerRef = useRef();
const [leftDisabled, setLeftDisabled] = useState(false);
const [rightDisabled, setRightDisabled] = useState(false);
const windowSize = useSize(document.querySelector('body'));
const [filterTabs, setFilterTabs] = useState([]);
useEffect(() => {
setFilterTabs(tabs
.filter((item) => item.label)
.map((item) => (Object.assign(Object.assign({}, item), { iconColor: styles.iconColor, itemColor: item.key === active ? styles.itemActiveColor : styles.itemColor }))));
}, [tabs, theme, active]);
useEffect(() => {
const { offsetWidth, scrollWidth } = tabsOuterRef.current;
setRightDisabled(left <= offsetWidth - scrollWidth);
setLeftDisabled(left >= 0);
if (offsetWidth === scrollWidth) {
setLeft(0);
}
}, [tabs, left, windowSize]);
const prev = (offset) => {
if (leftDisabled)
return;
let cur = 0;
if (offset) {
cur = left + offset;
}
else {
const children = tabsInnerRef.current.children;
for (let i = 0; i < children.length; i++) {
const tab = children[i];
if (cur >= left + tabsOuterRef.current.offsetWidth) {
cur -= tab.offsetWidth;
}
else {
break;
}
}
cur = cur - 3;
}
if (cur > 0) {
cur = 0;
}
setLeft(cur);
};
const next = (offset) => {
if (rightDisabled)
return;
let cur = 0;
if (offset) {
setLeft(left - offset);
}
else {
const children = tabsInnerRef.current.children;
for (let i = 0; i < children.length; i++) {
const tab = children[i];
if (cur - tab.offsetWidth > left - tabsOuterRef.current.offsetWidth) {
cur -= tab.offsetWidth;
}
else {
break;
}
}
setLeft(cur - 3);
}
};
const stop = useCallback((e) => {
e.preventDefault();
}, []);
const preventHTMLScroll = (prevent) => {
const body = document.querySelector('body');
if (prevent) {
if (!leftDisabled || !rightDisabled) {
body.addEventListener('wheel', stop, { passive: false });
}
}
else {
body.removeEventListener('wheel', stop);
}
};
return (React.createElement(Flex, { className: "router-tab-box", style: { background: styles.itemBg } },
React.createElement(LeftOutlined, { className: "router-tab-icon", style: { cursor: leftDisabled ? 'not-allowed' : 'pointer', color: styles.iconColor, background: styles.iconBg }, onClick: () => {
prev();
} }),
React.createElement("div", { ref: tabsOuterRef, onWheel: (e) => {
const deltaY = e.deltaY;
const offset = Math.abs(deltaY);
deltaY > 0 ? next(offset) : prev(offset);
}, onMouseEnter: () => {
preventHTMLScroll(true);
}, onMouseLeave: () => {
preventHTMLScroll(false);
}, style: {
flex: 1,
overflow: 'hidden',
position: 'relative',
} },
React.createElement("div", { ref: tabsInnerRef, style: {
whiteSpace: 'nowrap',
position: 'relative',
display: 'inline-block',
transition: 'left .5s ease',
left,
} }, filterTabs.map((item, index) => {
return (React.createElement("div", { style: { display: 'inline-block' }, key: item.key },
index !== 0 && React.createElement(Divider, { type: "vertical", className: "tab-item-divider" }),
React.createElement("div", { className: "tab-item", onClick: () => {
navigate(item.key);
}, style: {
backgroundColor: item.key === active ? styles.itemActiveBg : styles.itemBg,
padding: sizeStyle.padding,
fontSize: sizeStyle.fontSize,
}, onMouseEnter: (e) => {
setFilterTabs(filterTabs.map((tab) => {
if (tab.key === active) {
return tab;
}
else {
return Object.assign(Object.assign({}, tab), { itemColor: tab.key === item.key ? styles.itemHoverColor : styles.itemColor });
}
}));
}, onMouseLeave: (e) => {
setFilterTabs(filterTabs.map((tab) => {
if (tab.key === active) {
return tab;
}
else {
return Object.assign(Object.assign({}, tab), { itemColor: styles.itemColor });
}
}));
} },
React.createElement("span", { className: "tab-item-label", style: { color: item.itemColor } }, item.label),
filterTabs.length > 1 && (React.createElement(CloseOutlined, { className: "tab-item-icon", style: { color: item.iconColor }, onClick: (e) => {
e.stopPropagation();
close(item.key);
}, onMouseEnter: (e) => {
setFilterTabs(filterTabs.map((tab) => (Object.assign(Object.assign({}, tab), { iconColor: tab.key === item.key ? styles.hoverIconColor : styles.iconColor }))));
}, onMouseLeave: (e) => {
setFilterTabs(filterTabs.map((tab) => (Object.assign(Object.assign({}, tab), { iconColor: styles.iconColor }))));
} })))));
}))),
React.createElement(RightOutlined, { className: "router-tab-icon", style: {
cursor: rightDisabled ? 'not-allowed' : 'pointer',
color: styles.iconColor,
background: styles.iconBg,
}, onClick: () => {
next();
} }),
filterTabs.length > 1 && (React.createElement(Tooltip, { title: "\u70B9\u51FB\u5173\u95ED\u6240\u6709\u5176\u4ED6\u6807\u7B7E", placement: "left" },
React.createElement(CloseCircleOutlined, { style: {
flexBasis: 20,
padding: '0 8px',
background: styles.iconBg,
color: styles.iconColor,
zIndex: 2,
}, onClick: () => closeAll() })))));
};