diff --git a/src/menu/MenuGroup.tsx b/src/menu/MenuGroup.tsx index 085b684e0b..a9d09f2a37 100644 --- a/src/menu/MenuGroup.tsx +++ b/src/menu/MenuGroup.tsx @@ -3,20 +3,29 @@ import classNames from 'classnames'; import { StyledProps, TNode } from '../common'; import { TdMenuGroupProps } from './type'; import useConfig from '../_util/useConfig'; +import { cacularPaddingLeft } from './_util/cacularPaddingLeft'; export interface MenuGroupProps extends TdMenuGroupProps, StyledProps { children?: TNode; + level: number; } -const MenuGroup = ({ title, children }: MenuGroupProps) => { +const MenuGroup = ({ title, children, level = 1 }: MenuGroupProps) => { const { classPrefix } = useConfig(); + const itemAndGroupPaddingBias = 28; + const menuPaddingLeft = cacularPaddingLeft(level - 1) - itemAndGroupPaddingBias; + return (
-
{title}
+
+ {title} +
{children}
); }; +MenuGroup.displayName = 'MenuGroup'; + export default MenuGroup; diff --git a/src/menu/SubMenu.tsx b/src/menu/SubMenu.tsx index fc7bf20edd..c494c3e8b2 100644 --- a/src/menu/SubMenu.tsx +++ b/src/menu/SubMenu.tsx @@ -8,7 +8,7 @@ import useRipple from '../_util/useRipple'; import { getSubMenuMaxHeight } from './_util/getSubMenuChildStyle'; import checkSubMenuChildrenActive from './_util/checkSubMenuChildrenActive'; import FakeArrow from '../common/FakeArrow'; -import { checkIsSubMenu } from './_util/checkMenuType'; +import { checkIsSubMenu, checkIsMenuGroup } from './_util/checkMenuType'; import { cacularPaddingLeft } from './_util/cacularPaddingLeft'; export interface SubMenuProps extends TdSubmenuProps, StyledProps {} @@ -187,14 +187,27 @@ const SubMenu: FC = (props) => { const { mode } = useContext(MenuContext); const { children, level = 1 } = props; - // 如果是第二层及以及的 subMenu 需要添加 notFirstLevelSubMenu 属性 - const childElement = React.Children.map(children, (item: React.ReactElement) => - checkIsSubMenu(item) - ? React.cloneElement(item, { + const changeItemLevel = (item: React.ReactElement) => { + if (checkIsSubMenu(item)) { + return React.cloneElement(item, { + level: level + 1, + }); + } + if (checkIsMenuGroup(item)) { + const groupChidren = React.Children.map(item.props.children, (item: React.ReactElement) => changeItemLevel(item)); + return React.cloneElement( + item, + { level: level + 1, - }) - : item, - ); + }, + groupChidren, + ); + } + return item; + }; + + // 如果是第二层及以及的 subMenu 需要添加 notFirstLevelSubMenu 属性 + const childElement = React.Children.map(children, (item: React.ReactElement) => changeItemLevel(item)); if (mode === 'accordion') return {childElement}; if (mode === 'title') return {childElement}; diff --git a/src/menu/__tests__/__snapshots__/menu.test.tsx.snap b/src/menu/__tests__/__snapshots__/menu.test.tsx.snap index c59c614321..20d37a908b 100644 --- a/src/menu/__tests__/__snapshots__/menu.test.tsx.snap +++ b/src/menu/__tests__/__snapshots__/menu.test.tsx.snap @@ -1047,6 +1047,7 @@ exports[`group-side.jsx 1`] = ` >
Classification A
@@ -1083,6 +1084,7 @@ exports[`group-side.jsx 1`] = ` >
Classification B
@@ -1110,6 +1112,7 @@ exports[`group-side.jsx 1`] = ` >
Classification C
@@ -1122,6 +1125,157 @@ exports[`group-side.jsx 1`] = ` 精准监控 +
  • +
    + + + + + + + 资源列表 + + + + + +
    + +
  • 精准监控 + 资源列表} icon={}> + + + + 三级菜单-1 + + 三级菜单-2 + 三级菜单-3 + + + + + 二级菜单-2 + + + ); diff --git a/src/menu/_util/checkMenuType.ts b/src/menu/_util/checkMenuType.ts index 4826305363..da018227ff 100644 --- a/src/menu/_util/checkMenuType.ts +++ b/src/menu/_util/checkMenuType.ts @@ -1,5 +1,6 @@ import MenuItem from '../MenuItem'; import SubMenu from '../SubMenu'; +import MenuGroup from '../MenuGroup'; import { MenuBlockType } from './type'; export const checkIsSubMenu = (child: React.ReactElement) => { @@ -11,3 +12,8 @@ export const checkIsMenuItem = (child: React.ReactElement) => { const { displayName } = child.type as typeof MenuItem | typeof SubMenu; return displayName === MenuBlockType.MenuItem; }; + +export const checkIsMenuGroup = (child: React.ReactElement) => { + const { displayName } = child.type as typeof MenuGroup; + return displayName === MenuBlockType.MenuGroup; +}; diff --git a/src/menu/_util/getSubMenuChildStyle.ts b/src/menu/_util/getSubMenuChildStyle.ts index 3ccc8aa233..c42239958e 100644 --- a/src/menu/_util/getSubMenuChildStyle.ts +++ b/src/menu/_util/getSubMenuChildStyle.ts @@ -1,11 +1,10 @@ import React from 'react'; -import SubMenu from '../SubMenu'; -import { MenuBlockType } from './type'; +import { checkIsSubMenu, checkIsMenuGroup } from './checkMenuType'; export const getSubMenuChildCount = (children: React.ReactNode) => { let count = 0; React.Children.forEach(children, (child: React.ReactElement) => { - if ((child.type as typeof SubMenu).displayName === MenuBlockType.SubMenu) { + if (checkIsSubMenu(child) || checkIsMenuGroup(child)) { count += getSubMenuChildCount(child.props.children) + 1; } else { count += 1; diff --git a/src/menu/_util/type.ts b/src/menu/_util/type.ts index c319e8afa7..62f78cc313 100644 --- a/src/menu/_util/type.ts +++ b/src/menu/_util/type.ts @@ -3,4 +3,5 @@ export enum MenuBlockType { MenuItem = 'MenuItem', SubMenu = 'SubMenu', MenuItemGroup = 'MenuItemGroup', + MenuGroup = 'MenuGroup', } diff --git a/test/ssr/__snapshots__/ssr.test.js.snap b/test/ssr/__snapshots__/ssr.test.js.snap index af30f16f74..a50a84d815 100644 --- a/test/ssr/__snapshots__/ssr.test.js.snap +++ b/test/ssr/__snapshots__/ssr.test.js.snap @@ -402,7 +402,7 @@ exports[`ssr snapshot test renders ./src/menu/_example/custom-side.jsx correctly exports[`ssr snapshot test renders ./src/menu/_example/double.jsx correctly 1`] = `"
    \\"logo\\"/
    • 菜单1
    • 菜单2
    • 菜单3
    • 菜单4
      子菜单1
      子菜单2
    \\"logo\\"/
    • 菜单1
    • 菜单2
    • 菜单3
    • 菜单4
      子菜单1
      子菜单2
    "`; -exports[`ssr snapshot test renders ./src/menu/_example/group-side.jsx correctly 1`] = `"
    \\"logo\\"/
      Classification A
    • 仪表盘
    • Classification B
    • 调度平台
    • 菜单内容二很长很长很长很长很长很长很长很长
    • Classification C
    • 精准监控
    "`; +exports[`ssr snapshot test renders ./src/menu/_example/group-side.jsx correctly 1`] = `"
    \\"logo\\"/
      Classification A
    • 仪表盘
    • Classification B
    • 调度平台
    • 菜单内容二很长很长很长很长很长很长很长很长
    • Classification C
    • 精准监控
    • 资源列表
        inner Classification D
      • 二级菜单-1
          inner Classification E
        • 三级菜单-1
        • 三级菜单-2
        • 三级菜单-3
      • inner Classification E
      • 二级菜单-2
    "`; exports[`ssr snapshot test renders ./src/menu/_example/multi-side.jsx correctly 1`] = `"
    • 仪表盘
    • 资源列表
      • 菜单二
    • 调度平台
      • 二级菜单-1
        • 三级菜单-1
        • 三级菜单-2
        • 三级菜单-3
      • 二级菜单-2
    • 精准监控
      • 二级菜单-1
      • 二级菜单-2
    • 根目录
    • 消息区
      • 二级菜单-1
      • 二级菜单-2
    • 仪表盘
    • 资源列表
      • 菜单二
    • 调度平台
      • 二级菜单-1
      • 二级菜单-2
    • 精准监控
      • 二级菜单-1
      • 二级菜单-2
    • 根目录
    • 消息区
      • 二级菜单-1
      • 二级菜单-2
    "`;