Skip to content

Commit

Permalink
feat(menu&popper): #2575
Browse files Browse the repository at this point in the history
  • Loading branch information
zyprepare committed Aug 31, 2023
1 parent 0bd0b2f commit ccb1eec
Show file tree
Hide file tree
Showing 8 changed files with 241 additions and 6 deletions.
5 changes: 5 additions & 0 deletions .changeset/moody-jars-admire.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@hi-ui/popper": minor
---

feat: 增加 animationType API
5 changes: 5 additions & 0 deletions .changeset/smooth-phones-build.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@hi-ui/menu": minor
---

feat: 增加 render 和 extraHeader API
17 changes: 13 additions & 4 deletions packages/ui/menu/src/Menu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,8 @@ export const Menu = forwardRef<HTMLDivElement | null, MenuProps>(
overlayClassName,
onCollapse,
footerRender,
render,
extraHeader,
onClick,
...rest
},
Expand Down Expand Up @@ -234,6 +236,8 @@ export const Menu = forwardRef<HTMLDivElement | null, MenuProps>(

return (
<div ref={useMergeRefs(ref, setContainerElement)} role={role} className={cls} {...rest}>
{extraHeader}

<MenuContext.Provider
value={{
placement,
Expand All @@ -260,6 +264,7 @@ export const Menu = forwardRef<HTMLDivElement | null, MenuProps>(
<MenuItem
hidden={!showVertical && index >= tagMaxCount}
{...item}
render={render}
key={item.id}
level={1}
raw={item}
Expand Down Expand Up @@ -355,6 +360,14 @@ export interface MenuProps extends Omit<HiBaseHTMLProps<'div'>, 'onClick'> {
* 底部渲染器
*/
footerRender?: (props: MenuFooterRenderProps) => React.ReactNode
/**
* 自定义渲染菜单项
*/
render?: (menuItem: MenuDataItem) => React.ReactNode
/**
* 额外的头部内容
*/
extraHeader?: React.ReactNode
}

if (__DEV__) {
Expand All @@ -365,10 +378,6 @@ if (__DEV__) {
* Mini 模式下渲染 item
*/
const renderMenuItemMini = (menu: MenuDataItem) => {
// if (typeof menu.icon !== 'undefined') {
// return menu.icon
// }

if (typeof menu.title === 'string') {
return menu.title.substring(0, 1)
}
Expand Down
7 changes: 7 additions & 0 deletions packages/ui/menu/src/MenuItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,7 @@ export const MenuItem = forwardRef<HTMLLIElement | null, MenuItemProps>(
level={level + 1}
parentIds={_parentIds}
raw={child}
render={render}
/>
))}
</ul>
Expand Down Expand Up @@ -199,6 +200,7 @@ export const MenuItem = forwardRef<HTMLLIElement | null, MenuItemProps>(
level={level + 1}
parentIds={_parentIds}
raw={child}
render={render}
/>
)
})}
Expand Down Expand Up @@ -226,6 +228,7 @@ export const MenuItem = forwardRef<HTMLLIElement | null, MenuItemProps>(
level={level + 1}
parentIds={_parentIds}
raw={child}
render={render}
/>
))}
</ul>
Expand Down Expand Up @@ -257,6 +260,7 @@ export const MenuItem = forwardRef<HTMLLIElement | null, MenuItemProps>(
level={level + 1}
parentIds={_parentIds}
raw={child}
render={render}
/>
))}
</ul>
Expand All @@ -283,6 +287,7 @@ export const MenuItem = forwardRef<HTMLLIElement | null, MenuItemProps>(
level={level + 1}
parentIds={_parentIds}
raw={child}
render={render}
/>
))}
</ul>
Expand Down Expand Up @@ -360,6 +365,7 @@ export const MenuItem = forwardRef<HTMLLIElement | null, MenuItemProps>(
level={level + 1}
parentIds={_parentIds}
raw={child}
render={render}
/>
))}
</ul>
Expand All @@ -386,6 +392,7 @@ export const MenuItem = forwardRef<HTMLLIElement | null, MenuItemProps>(
level={level + 1}
parentIds={_parentIds}
raw={child}
render={render}
/>
))}
</ul>
Expand Down
1 change: 1 addition & 0 deletions packages/ui/menu/stories/index.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ export * from './fat.stories'
export * from './vertical-fat.stories'
export * from './expand-all.stories'
export * from './footer-render.stories'
export * from './render.stories'

export default {
title: 'Navigation/Menu',
Expand Down
107 changes: 107 additions & 0 deletions packages/ui/menu/stories/render.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
import React from 'react'
import Menu, { MenuDataItem } from '../src'
import {
RightOutlined,
AppStoreOutlined,
UserOutlined,
SunOutlined,
PadOutlined,
SearchOutlined,
} from '@hi-ui/icons'
import Popper from '@hi-ui/popper'
import Search from '@hi-ui/search'

/**
* @title 自定义渲染
*/
export const Render = () => {
const menuData = [
{
title: '首页',
id: 1,
icon: <AppStoreOutlined />,
},
{
title: '小米MIX',
id: 2,
icon: <UserOutlined />,
},
{
title: '手机',
id: 3,
icon: <SunOutlined />,
},
{
title: '电脑',
id: 4,
icon: <PadOutlined />,
},
]

const menuRef = React.useRef<HTMLDivElement | null>(null)
const [currentMenu, setCurrentMenu] = React.useState<MenuDataItem>(menuData[0])
const [visible, setVisible] = React.useState(false)

return (
<>
<h1>Render</h1>
<div
className="menu-render__wrap"
style={{ background: '#f5f7fa', padding: 20, minWidth: 600 }}
>
<Menu
ref={menuRef}
showCollapse
extraHeader={
<div style={{ padding: '10px 0' }}>
<Search prefix={<SearchOutlined />} append={null} />
</div>
}
defaultExpandedIds={[3]}
render={(item) => {
return (
<div
style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}
>
{item.title}
<RightOutlined style={{ marginLeft: 4 }} />
</div>
)
}}
onClick={(id, data) => {
console.log('click', id, data)

setCurrentMenu(data)
setVisible(true)
}}
data={menuData}
/>
{/* 如果不需要阴影,可以设置 className 去覆盖样式 */}
<Popper
className="menu-render__popper"
visible={visible}
attachEl={menuRef.current}
placement="right"
gutterGap={0}
flip={false}
animationType="scaleX"
onClose={() => {
setVisible(false)
}}
onOutsideClick={() => console.log('onOutsideClick')}
>
<div
style={{
width: 200,
height: menuRef.current?.getBoundingClientRect().height,
padding: 10,
boxSizing: 'border-box',
}}
>
菜单:{currentMenu.title}
</div>
</Popper>
</div>
</>
)
}
7 changes: 6 additions & 1 deletion packages/ui/popper/src/Popper.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ export const Popper = forwardRef<HTMLDivElement | null, PopperProps>(
onExited,
// portal
container,
animationType = 'scale',
disabledPortal = false,
...rest
},
Expand Down Expand Up @@ -116,7 +117,7 @@ export const Popper = forwardRef<HTMLDivElement | null, PopperProps>(
return (
<Portal container={container} disabled={disabledPortal}>
<CSSTransition
classNames={`${prefixCls}--motion`}
classNames={`${prefixCls}--motion-${animationType}`}
in={transitionVisible}
appear
// @DesignToken
Expand Down Expand Up @@ -181,6 +182,10 @@ export interface PopperProps extends HiBaseHTMLProps<'div'>, UsePopperProps {
* 指定 portal 的容器
*/
container?: (() => HTMLElement | null) | HTMLElement | null
/**
* 动画类型
*/
animationType?: 'scale' | 'scaleX' | 'scaleY'
}

if (__DEV__) {
Expand Down
98 changes: 97 additions & 1 deletion packages/ui/popper/src/styles/popper.scss
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,103 @@ $prefix: '#{$component-prefix}-popper' !default;
box-sizing: border-box;
}

&--motion {
&--motion-scaleX {
&-enter {
.#{$prefix}__container {
opacity: 0;
transform: scale(0, 1);
}
}

&-enter-active {
.#{$prefix}__container {
opacity: 1;
transform: scale(1, 1);
}
}

&-enter-done {
.#{$prefix}__container {
opacity: 1;
transform: scale(1, 1);
}
}

&-exit {
.#{$prefix}__container {
opacity: 1;
transform: scale(1, 1) translateX(100%);
}
}

&-exit-active {
.#{$prefix}__container {
opacity: 0;
transform: scale(0, 1);
}
}

&-exit-done {
// 即使保留dom,但是需要 hidden 不可点击
visibility: hidden;

.#{$prefix}__container {
opacity: 0;
transform: scale(0, 1);
transition-property: none;
}
}
}

&--motion-scaleY {
&-enter {
.#{$prefix}__container {
opacity: 0;
transform: scale(1, 0);
}
}

&-enter-active {
.#{$prefix}__container {
opacity: 1;
transform: scale(1, 1);
}
}

&-enter-done {
.#{$prefix}__container {
opacity: 1;
transform: scale(1, 1);
}
}

&-exit {
.#{$prefix}__container {
opacity: 1;
transform: scale(1, 1) translateX(100%);
}
}

&-exit-active {
.#{$prefix}__container {
opacity: 0;
transform: scale(1, 0);
}
}

&-exit-done {
// 即使保留dom,但是需要 hidden 不可点击
visibility: hidden;

.#{$prefix}__container {
opacity: 0;
transform: scale(1, 0);
transition-property: none;
}
}
}

&--motion-scale {
&-enter {
.#{$prefix}__container {
opacity: 0;
Expand Down

0 comments on commit ccb1eec

Please sign in to comment.