Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Revert "ui: improve the expansion and collapse of sider menu (#767)" #813

Merged
merged 1 commit into from
Nov 25, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 13 additions & 9 deletions ui/dashboardApp/layout/main/Sider/Banner.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import React, { useMemo } from 'react'
import { MenuFoldOutlined, MenuUnfoldOutlined } from '@ant-design/icons'
import { MenuUnfoldOutlined, MenuFoldOutlined } from '@ant-design/icons'
import { useSize } from '@umijs/hooks'
import Flexbox from '@g07cha/flexbox-react'
import { useSpring, animated } from 'react-spring'
import { useClientRequest } from '@lib/utils/useClientRequest'
import client, { InfoInfoResponse } from '@lib/client'

Expand Down Expand Up @@ -45,14 +46,14 @@ export default function ToggleBanner({
onToggle,
}) {
const [bannerSize, bannerRef] = useSize<HTMLDivElement>()
const bannerStyle = {
const transBanner = useSpring({
opacity: collapsed ? 0 : 1,
height: collapsed ? toggleHeight : bannerSize.height || 0,
}
const buttonStyle = {
})
const transButton = useSpring({
left: collapsed ? 0 : fullWidth - toggleWidth,
width: collapsed ? collapsedWidth : toggleWidth,
}
})

const { data, isLoading } = useClientRequest((reqConfig) =>
client.getInstance().infoGet(reqConfig)
Expand All @@ -67,7 +68,10 @@ export default function ToggleBanner({

return (
<div className={styles.banner} onClick={onToggle}>
<div style={bannerStyle}>
<animated.div
style={transBanner}
className={styles.bannerLeftAnimationWrapper}
>
<div
ref={bannerRef}
className={styles.bannerLeft}
Expand All @@ -86,14 +90,14 @@ export default function ToggleBanner({
</div>
</Flexbox>
</div>
</div>
<div style={buttonStyle} className={styles.bannerRight}>
</animated.div>
<animated.div style={transButton} className={styles.bannerRight}>
{collapsed ? (
<MenuUnfoldOutlined style={{ margin: 'auto' }} />
) : (
<MenuFoldOutlined style={{ margin: 'auto' }} />
)}
</div>
</animated.div>
</div>
)
}
7 changes: 3 additions & 4 deletions ui/dashboardApp/layout/main/Sider/index.module.less
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,10 @@

@sider-background: #f7f7fa;

.wrapper {
transition: width 444ms ease;
}

.sider {
position: fixed;
left: 0;
top: 0;
height: 100%;
z-index: 1;
background: linear-gradient(@sider-background, #ebeffa);
Expand Down
55 changes: 25 additions & 30 deletions ui/dashboardApp/layout/main/Sider/index.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import React, { useCallback, useMemo, useState } from 'react'
import { BugOutlined, ExperimentOutlined } from '@ant-design/icons'
import React, { useState, useMemo } from 'react'
import { ExperimentOutlined, BugOutlined } from '@ant-design/icons'
import { Layout, Menu } from 'antd'
import { Link } from 'react-router-dom'
import { useEventListener } from '@umijs/hooks'
import { useTranslation } from 'react-i18next'
import { useSpring, animated } from 'react-spring'
import client from '@lib/client'

import Banner from './Banner'
Expand All @@ -17,9 +18,10 @@ function useAppMenuItem(registry, appId, title?: string) {
return null
}
return (
<Menu.Item key={appId} icon={app.icon ? <app.icon /> : null}>
<Menu.Item key={appId}>
<Link to={app.indexRoute} id={appId}>
{title ? title : t(`${appId}.nav_title`, appId)}
{app.icon ? <app.icon /> : null}
<span>{title ? title : t(`${appId}.nav_title`, appId)}</span>
</Link>
</Menu.Item>
)
Expand All @@ -36,12 +38,6 @@ function useActiveAppId(registry) {
return appId
}

function triggerResizeEvent() {
const event = document.createEvent('HTMLEvents')
event.initEvent('resize', true, false)
window.dispatchEvent(event)
}

function Sider({
registry,
fullWidth,
Expand All @@ -65,8 +61,12 @@ function Sider({
const debugSubMenu = (
<Menu.SubMenu
key="debug"
icon={<BugOutlined />}
title={t('nav.sider.debug')}
title={
<span>
<BugOutlined />
<span>{t('nav.sider.debug')}</span>
</span>
}
>
{debugSubMenuItems}
</Menu.SubMenu>
Expand All @@ -79,8 +79,12 @@ function Sider({
const experimentalSubMenu = (
<Menu.SubMenu
key="experimental"
icon={<ExperimentOutlined />}
title={t('nav.sider.experimental')}
title={
<span>
<ExperimentOutlined />
<span>{t('nav.sider.experimental')}</span>
</span>
}
>
{experimentalSubMenuItems}
</Menu.SubMenu>
Expand Down Expand Up @@ -112,9 +116,9 @@ function Sider({
useAppMenuItem(registry, 'user_profile', displayName),
]

const siderStyle = {
const transSider = useSpring({
width: collapsed ? collapsedWidth : fullWidth,
}
})

const defaultOpenKeys = useMemo(() => {
if (defaultCollapsed) {
Expand All @@ -124,17 +128,8 @@ function Sider({
}
}, [defaultCollapsed])

const wrapperRef = useCallback((wrapper) => {
if (wrapper !== null) {
wrapper.addEventListener('transitionend', (e) => {
if (e.target !== wrapper || e.propertyName !== 'width') return
triggerResizeEvent()
})
}
}, [])

return (
<div className={styles.wrapper} style={siderStyle} ref={wrapperRef}>
<animated.div style={transSider}>
<Layout.Sider
className={styles.sider}
width={fullWidth}
Expand All @@ -153,7 +148,7 @@ function Sider({
/>
<Menu
subMenuOpenDelay={animationDelay}
subMenuCloseDelay={animationDelay + 0.1}
subMenuCloseDelay={animationDelay}
mode="inline"
selectedKeys={[activeAppId]}
style={{ flexGrow: 1 }}
Expand All @@ -162,15 +157,15 @@ function Sider({
{menuItems}
</Menu>
<Menu
subMenuOpenDelay={animationDelay}
subMenuCloseDelay={animationDelay}
subMenuOpenDelay={animationDelay + 200}
subMenuCloseDelay={animationDelay + 200}
mode="inline"
selectedKeys={[activeAppId]}
>
{extraMenuItems}
</Menu>
</Layout.Sider>
</div>
</animated.div>
)
}

Expand Down
24 changes: 10 additions & 14 deletions ui/dashboardApp/layout/main/index.module.less
Original file line number Diff line number Diff line change
@@ -1,28 +1,14 @@
@import '~antd/es/style/themes/default.less';

.container {
display: flex;
position: fixed;
top: 0;
bottom: 0;
right: 0;
left: 0;
height: 100vh;
width: 100vw;
}

.content {
position: relative;

flex: 1;

z-index: 3;
background: #fff;
min-height: 100vh;
box-shadow: 0 0 30px rgba(#000, 0.15);

overflow-x: hidden;
overflow-y: auto;

&:before,
&:after {
Expand All @@ -31,3 +17,13 @@
display: table;
}
}

.contentBack {
position: fixed;
z-index: 2;
background: #fff;
top: 0;
height: 100%;
right: 0;
box-shadow: 0 0 30px rgba(#000, 0.15);
}
65 changes: 62 additions & 3 deletions ui/dashboardApp/layout/main/index.tsx
Original file line number Diff line number Diff line change
@@ -1,21 +1,62 @@
import React, { useCallback, useState } from 'react'
import React, { useState, useCallback, useEffect } from 'react'
import { Root } from '@lib/components'
import { useLocalStorageState } from '@umijs/hooks'
import { HashRouter as Router } from 'react-router-dom'
import { animated, useSpring } from 'react-spring'
import { useSpring, animated } from 'react-spring'

import Sider from './Sider'
import styles from './index.module.less'

const siderWidth = 260
const siderCollapsedWidth = 80
const collapsedContentOffset = siderCollapsedWidth - siderWidth
const contentOffsetTrigger = collapsedContentOffset * 0.99

function triggerResizeEvent() {
const event = document.createEvent('HTMLEvents')
event.initEvent('resize', true, false)
window.dispatchEvent(event)
}

const useContentLeftOffset = (collapsed) => {
const [offset, setOffset] = useState(siderWidth)
const onAnimationStart = useCallback(() => {
if (!collapsed) {
setOffset(siderWidth)
}
}, [collapsed])
const onAnimationFrame = useCallback(
({ x }) => {
if (collapsed && x < contentOffsetTrigger) {
setOffset(siderCollapsedWidth)
}
},
[collapsed]
)
useEffect(triggerResizeEvent, [offset])
return {
contentLeftOffset: offset,
onAnimationStart,
onAnimationFrame,
}
}

export default function App({ registry }) {
const [collapsed, setCollapsed] = useLocalStorageState(
'layout.sider.collapsed',
false
)
const [defaultCollapsed] = useState(collapsed)
const {
contentLeftOffset,
onAnimationStart,
onAnimationFrame,
} = useContentLeftOffset(collapsed)
const transContentBack = useSpring({
x: collapsed ? collapsedContentOffset : 0,
onStart: onAnimationStart,
onFrame: onAnimationFrame,
})
const transContainer = useSpring({
opacity: 1,
from: { opacity: 0 },
Expand Down Expand Up @@ -43,9 +84,27 @@ export default function App({ registry }) {
collapsedWidth={siderCollapsedWidth}
animationDelay={0}
/>
<animated.div
className={styles.contentBack}
style={{
left: `${siderWidth}px`,
transform: transContentBack.x.interpolate(
(x) => `translate3d(${x}px, 0, 0)`
),
}}
></animated.div>
</>
)}
<div className={styles.content}>
<div
className={styles.content}
style={
appOptions.hideNav
? {}
: {
marginLeft: contentLeftOffset,
}
}
>
<div id="__spa_content__"></div>
</div>
</animated.div>
Expand Down