Skip to content

Commit

Permalink
Merge pull request #627 from ZhaoRB/develop
Browse files Browse the repository at this point in the history
MenuGroup嵌套使用样式修复
  • Loading branch information
honkinglin authored Apr 14, 2022
2 parents 61eb5ca + dfafa7f commit d12ecf4
Show file tree
Hide file tree
Showing 8 changed files with 214 additions and 16 deletions.
13 changes: 11 additions & 2 deletions src/menu/MenuGroup.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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 (
<div className={classNames(`${classPrefix}-menu-group`)}>
<div className={classNames(`${classPrefix}-menu-group__title`)}>{title}</div>
<div className={classNames(`${classPrefix}-menu-group__title`)} style={{ paddingLeft: `${menuPaddingLeft}px` }}>
{title}
</div>
{children}
</div>
);
};

MenuGroup.displayName = 'MenuGroup';

export default MenuGroup;
29 changes: 21 additions & 8 deletions src/menu/SubMenu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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 {}
Expand Down Expand Up @@ -187,14 +187,27 @@ const SubMenu: FC<SubMenuWithCustomizeProps> = (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 <SubAccordion {...props}>{childElement}</SubAccordion>;
if (mode === 'title') return <SubTitleMenu {...props}>{childElement}</SubTitleMenu>;
Expand Down
154 changes: 154 additions & 0 deletions src/menu/__tests__/__snapshots__/menu.test.tsx.snap
Original file line number Diff line number Diff line change
Expand Up @@ -1047,6 +1047,7 @@ exports[`group-side.jsx 1`] = `
>
<div
class="t-menu-group__title"
style="padding-left: 16px;"
>
Classification A
</div>
Expand Down Expand Up @@ -1083,6 +1084,7 @@ exports[`group-side.jsx 1`] = `
>
<div
class="t-menu-group__title"
style="padding-left: 16px;"
>
Classification B
</div>
Expand Down Expand Up @@ -1110,6 +1112,7 @@ exports[`group-side.jsx 1`] = `
>
<div
class="t-menu-group__title"
style="padding-left: 16px;"
>
Classification C
</div>
Expand All @@ -1122,6 +1125,157 @@ exports[`group-side.jsx 1`] = `
精准监控
</span>
</li>
<li
class="t-submenu"
>
<div
class="t-menu__item"
>
<svg
class="t-icon t-icon-file"
fill="none"
height="1em"
viewBox="0 0 16 16"
width="1em"
>
<path
d="M3.5 1c-.48 0-1 .34-1 .92v12.16c0 .58.52.92 1 .92h9c.48 0 1-.34 1-.92V5.7a1 1 0 00-.3-.71L9.5 1.3a1 1 0 00-.7-.3H3.5zm5 1v4.01h4V14h-9V2h5zm1 .7l2.3 2.31H9.5v-2.3z"
fill="currentColor"
fill-opacity="0.9"
/>
</svg>
<span
class="t-menu__content"
>
<span>
资源列表
</span>
</span>
<svg
class="t-fake-arrow"
fill="none"
height="16"
viewBox="0 0 16 16"
width="16"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M3.75 5.7998L7.99274 10.0425L12.2361 5.79921"
stroke="black"
stroke-opacity="0.9"
stroke-width="1.3"
/>
</svg>
</div>
<ul
class="t-menu__sub"
style="max-height: 0; --padding-left: 44px;"
>
<div
class="t-menu-group"
>
<div
class="t-menu-group__title"
style="padding-left: 32px;"
>
inner Classification D
</div>
<li
class="t-submenu"
>
<div
class="t-menu__item"
>
<span
class="t-menu__content"
>
二级菜单-1
</span>
<svg
class="t-fake-arrow"
fill="none"
height="16"
viewBox="0 0 16 16"
width="16"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M3.75 5.7998L7.99274 10.0425L12.2361 5.79921"
stroke="black"
stroke-opacity="0.9"
stroke-width="1.3"
/>
</svg>
</div>
<ul
class="t-menu__sub"
style="max-height: 0; --padding-left: 60px;"
>
<div
class="t-menu-group"
>
<div
class="t-menu-group__title"
style="padding-left: 48px;"
>
inner Classification E
</div>
<li
class="t-menu__item t-menu__item--plain"
>
<span
class="t-menu__content"
>
三级菜单-1
</span>
</li>
</div>
<li
class="t-menu__item--plain t-submenu__item t-submenu__item--icon t-menu__item t-menu__item--plain"
>
<span
class="t-menu__content"
>
三级菜单-2
</span>
</li>
<li
class="t-menu__item--plain t-submenu__item t-submenu__item--icon t-menu__item t-menu__item--plain"
>
<span
class="t-menu__content"
>
三级菜单-3
</span>
</li>
</ul>
</li>
</div>
<div
class="t-menu-group"
>
<div
class="t-menu-group__title"
style="padding-left: 32px;"
>
inner Classification E
</div>
<li
class="t-menu__item t-menu__item--plain"
>
<span
class="t-menu__content"
>
<span>
二级菜单-2
</span>
</span>
</li>
</div>
</ul>
</li>
</div>
</ul>
<div
Expand Down
20 changes: 18 additions & 2 deletions src/menu/_example/group-side.jsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
// @ts-nocheck
import React, { useState } from 'react';
import { Menu } from 'tdesign-react';
import { ViewListIcon, ChartIcon } from 'tdesign-icons-react';
import { ViewListIcon, ChartIcon, FileIcon } from 'tdesign-icons-react';

const { MenuGroup, MenuItem } = Menu;
const { MenuGroup, MenuItem, SubMenu } = Menu;

function GroupSide() {
const [value, setValue] = useState('1');
Expand Down Expand Up @@ -38,6 +38,22 @@ function GroupSide() {
</MenuGroup>
<MenuGroup title="Classification C">
<MenuItem value="4">精准监控</MenuItem>
<SubMenu value="5" title={<span>资源列表</span>} icon={<FileIcon />}>
<MenuGroup title="inner Classification D">
<SubMenu value="2-1" title="二级菜单-1">
<MenuGroup title="inner Classification E">
<MenuItem value="3-1">三级菜单-1</MenuItem>
</MenuGroup>
<MenuItem value="3-2">三级菜单-2</MenuItem>
<MenuItem value="3-3">三级菜单-3</MenuItem>
</SubMenu>
</MenuGroup>
<MenuGroup title="inner Classification E">
<MenuItem value="2-2">
<span>二级菜单-2</span>
</MenuItem>
</MenuGroup>
</SubMenu>
</MenuGroup>
</Menu>
);
Expand Down
6 changes: 6 additions & 0 deletions src/menu/_util/checkMenuType.ts
Original file line number Diff line number Diff line change
@@ -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) => {
Expand All @@ -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;
};
5 changes: 2 additions & 3 deletions src/menu/_util/getSubMenuChildStyle.ts
Original file line number Diff line number Diff line change
@@ -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;
Expand Down
1 change: 1 addition & 0 deletions src/menu/_util/type.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,5 @@ export enum MenuBlockType {
MenuItem = 'MenuItem',
SubMenu = 'SubMenu',
MenuItemGroup = 'MenuItemGroup',
MenuGroup = 'MenuGroup',
}
Loading

0 comments on commit d12ecf4

Please sign in to comment.