refactor(ideContainer): 侧边栏样式和结构重构

- 重新设计了侧边栏的样式,增加了滚动条和过渡效果
- 优化了菜单项的展示方式,支持图标和文本- 移除了折叠功能,简化了侧边栏的结构
- 使用自定义样式替代了 arco-design 的 Sider 组件
master
钟良源 5 months ago
parent afa5de1030
commit 8061bd169a

@ -1,21 +1,16 @@
import React, { useEffect, useState } from 'react';
import styles from './style/sideBar.module.less';
import { Layout, Menu } from '@arco-design/web-react';
import { IconApps, IconMenuFold, IconMenuUnfold } from '@arco-design/web-react/icon';
import { IconApps } from '@arco-design/web-react/icon';
import { GlobalState } from '@/store';
import { useSelector } from 'react-redux';
import getUrlParams from '@/utils/getUrlParams';
import { menuData, menuData2 } from './config/menuData';
const Sider = Layout.Sider;
const MenuItem = Menu.Item;
const SubMenu = Menu.SubMenu;
interface MenuItemType {
title: string;
children?: MenuItemType[];
path?: string;
icon?: React.ReactNode;
}
interface SideBarProps {
@ -26,21 +21,15 @@ interface SideBarProps {
const SideBar: React.FC<SideBarProps> = ({ onMenuSelect, selectedKey, identity }) => {
const urlParams = getUrlParams();
const [collapsed, setCollapsed] = useState<boolean>(false);
const [menu, setMenu] = useState([]);
const { userInfo, settings, userLoading } = useSelector(
const [menu, setMenu] = useState<MenuItemType[]>([]);
const { settings } = useSelector(
(state: GlobalState) => state
);
const navbarHeight = 60;
const menuWidth = collapsed ? 48 : settings?.menuWidth;
const showNavbar = settings?.navbar && urlParams.navbar !== false;
const paddingTop = showNavbar ? { paddingTop: navbarHeight } : {};
function toggleCollapse() {
setCollapsed((collapsed) => !collapsed);
}
const sideBarStyle = { ...paddingTop, height: '100%' };
function getMenuData(): MenuItemType[] {
switch (identity) {
@ -57,56 +46,33 @@ const SideBar: React.FC<SideBarProps> = ({ onMenuSelect, selectedKey, identity }
setMenu(getMenuData());
}, [identity]);
// 递归渲染菜单项
const renderMenuItems = (items: MenuItemType[], parentKey = '') => {
return items.map((item, index) => {
const currentKey = (parentKey ? `${parentKey}_${index}` : `${index}`);
if (!item.children) {
return (
<MenuItem
key={currentKey}
return (
<div
className={styles.sider}
style={sideBarStyle}
>
<div className={styles['menu-container']}>
{menu.map((item, index) => (
<div
key={index}
className={`${styles['menu-item']} ${selectedKey === `${index}` ? styles['menu-item-active'] : ''}`}
onClick={() => {
onMenuSelect?.({ currentPath: item.path, currentKey });
onMenuSelect?.({ currentPath: item.path, currentKey: `${index}` });
}}
>
{item.title}
</MenuItem>
);
}
return (
<SubMenu key={currentKey} title={item.title}>
{renderMenuItems(item.children, currentKey)}
</SubMenu>
);
});
};
return (
<>
<Layout>
<Sider
className={styles.sider}
width={menuWidth}
collapsed={collapsed}
onCollapse={setCollapsed}
trigger={null}
collapsible
breakpoint="xl"
style={paddingTop}>
<Menu
selectedKeys={selectedKey ? [selectedKey] : ['0']}
>
{renderMenuItems(menu)}
</Menu>
{/*<div className={styles['collapse-btn']} onClick={toggleCollapse}>*/}
{/* {collapsed ? <IconMenuUnfold /> : <IconMenuFold />}*/}
{/*</div>*/}
</Sider>
</Layout>
</>
<div className={styles['menu-item-content']}>
<span className={styles['menu-item-icon']}>
{item.icon || <IconApps />}
</span>
<span className={styles['menu-item-text']}>
{item.title}
</span>
</div>
</div>
))}
</div>
</div>
);
};
export default SideBar;
export default SideBar;

@ -1,28 +1,65 @@
.sider {
position: fixed;
width: 60px;
height: 100%;
overflow-y: auto;
box-shadow: 0 2px 5px 0 rgba(0, 0, 0, 0.08);
z-index: 99;
transition: all 0.3s ease-in-out;
position: fixed;
top: 0;
left: 0;
z-index: 99;
box-sizing: border-box;
background-color: var(--color-bg-2);
}
.menu-container {
height: calc(100% - 40px); // 为底部留出空间
overflow-y: auto;
}
.collapse-btn {
height: 24px;
width: 24px;
background-color: var(--color-fill-1);
color: var(--color-text-3);
border-radius: 2px;
cursor: pointer;
display: flex;
justify-content: center;
align-items: center;
// 位置
position: absolute;
bottom: 12px;
right: 12px;
.menu-item {
padding: 12px 4px;
text-align: center;
cursor: pointer;
transition: all 0.3s ease-in-out;
position: relative;
display: flex;
flex-direction: column;
align-items: center;
&:hover {
background-color: var(--color-fill-3);
}
&:hover {
background-color: var(--color-fill-2);
}
&-active {
background-color: var(--color-fill-2);
color: rgb(var(--primary-6));
}
}
.menu-item-content {
display: flex;
flex-direction: column;
align-items: center;
width: 100%;
}
.menu-item-icon {
display: flex;
align-items: center;
justify-content: center;
font-size: 20px;
min-width: 16px;
margin-bottom: 10px;
}
.menu-item-text {
font-size: 14px;
text-align: center;
overflow: hidden;
display: -webkit-box;
-webkit-line-clamp: 4;
-webkit-box-orient: vertical;
line-height: 1.2;
width: 100%;
padding: 0 5px;
}
Loading…
Cancel
Save