import React, { useMemo } from 'react'
import { Layout, Menu } from 'antd'
import { MenuUnfoldOutlined, MenuFoldOutlined } from '@ant-design/icons'
import { RouteItem } from '@/config/routes'
import { useHistory, useLocation } from 'react-router-dom'
const { Sider } = Layout
const { SubMenu } = Menu
export const defaultRenderLogo = (logo: React.ReactNode): React.ReactNode => {
if (typeof logo === 'string') {
return
}
if (typeof logo === 'function') {
return logo()
}
return logo
}
const defaultRenderCollapsedButton = (collapsed?: boolean) =>
collapsed ? :
const defaultRenderLogoAndTitle = (
props: SiderMenuProps,
collapsed: boolean
): React.ReactNode => {
const { logo, title } = props
const logoDom = defaultRenderLogo(logo)
const titleDom =
{title}
return (
{logoDom}
{collapsed ? null : titleDom}
)
}
function clearMenuItem(menusData: RouteItem[]): RouteItem[] {
return menusData
.map((item) => {
const finalItem = { ...item }
if (finalItem.hideInMenu) {
return null
}
if (finalItem && finalItem?.children) {
if (finalItem.children.some((child) => child && !child.hideInMenu)) {
return {
...item,
children: clearMenuItem(finalItem.children),
}
}
delete finalItem.children
}
return finalItem
})
.filter(Boolean) as RouteItem[]
}
function renderMenu(menuData: RouteItem[]) {
return menuData.map((menu, index) => {
return (
{menu.children ? (
{renderMenu(menu.children)}
) : !menu.hideInMenu ? (
{menu.name || menu.path}
) : null}
)
})
}
export interface SiderMenuProps {
title?: string
logo?: string | React.ReactNode
routes: RouteItem[]
onCollapse?: Function
collapsed: boolean
theme?: 'light' | 'dark'
siderWidth?: string
style?: Record
links?: string[]
}
const SideBar: React.FC = (props) => {
const {
routes,
onCollapse,
theme = 'light',
siderWidth = 208,
style,
collapsed,
links,
} = props
const location = useLocation()
const selectedKey = location.pathname === '/' ? '/home' : location.pathname
const collapsedButtonRender = defaultRenderCollapsedButton
const menuData = clearMenuItem(routes)
const headerDom = defaultRenderLogoAndTitle(props, collapsed)
const renderMenuDom = useMemo(() => {
return renderMenu(menuData)
}, [menuData])
const history = useHistory()
return (
{
onCollapse?.(collapse)
}}
collapsedWidth={48}
style={{
overflow: 'hidden',
...style,
minHeight: '100%',
height: '100%',
}}
width={siderWidth}
className="menu-sider"
>
{headerDom}
)
}
export default SideBar