Optimize submenu in ToolsFramework
This commit is contained in:
@@ -18,6 +18,10 @@
|
||||
}
|
||||
}
|
||||
|
||||
::-webkit-scrollbar {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.scrollbar {
|
||||
position: absolute;
|
||||
z-index: 1000;
|
||||
|
||||
@@ -12,10 +12,6 @@ body {
|
||||
background-color: constants.$origin-color;
|
||||
user-select: none;
|
||||
|
||||
.hide-scrollbar-selection {
|
||||
height: 100% !important;
|
||||
}
|
||||
|
||||
.title {
|
||||
font-size: 2em;
|
||||
text-align: center;
|
||||
@@ -26,9 +22,20 @@ body {
|
||||
}
|
||||
|
||||
.content {
|
||||
> ul {
|
||||
> li {
|
||||
display: flex;
|
||||
min-height: 0;
|
||||
flex-direction: column;
|
||||
|
||||
.toolsMenu {
|
||||
min-height: 0;
|
||||
|
||||
.hide-scrollbar-mask {
|
||||
flex: 1;
|
||||
}
|
||||
}
|
||||
|
||||
ul {
|
||||
> li {
|
||||
&.item {
|
||||
position: relative;
|
||||
margin: 4px 14px;
|
||||
@@ -61,17 +68,16 @@ body {
|
||||
|
||||
&.active {
|
||||
color: constants.$origin-color;
|
||||
background-color: constants.$main-color;
|
||||
background-color: constants.$main-color !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.submenu {
|
||||
display: block;
|
||||
position: absolute;
|
||||
display: none;
|
||||
position: fixed;
|
||||
padding-left: 20px;
|
||||
left: 100%;
|
||||
top: 0;
|
||||
z-index: 10000;
|
||||
|
||||
.content {
|
||||
display: flex;
|
||||
@@ -105,8 +111,10 @@ body {
|
||||
}
|
||||
|
||||
&:hover {
|
||||
a {
|
||||
background-color: constants.$background-color;
|
||||
.menu-bt {
|
||||
a {
|
||||
background-color: constants.$background-color;
|
||||
}
|
||||
}
|
||||
|
||||
.submenu {
|
||||
@@ -130,6 +138,7 @@ body {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.separate {
|
||||
height: 0;
|
||||
margin: 10px 5px;
|
||||
|
||||
@@ -6,125 +6,159 @@ import { toolsJsonObjects } from '@/router/tools.tsx'
|
||||
import HideScrollbar from '@/components/common/HideScrollbar.tsx'
|
||||
|
||||
const ToolsFramework: React.FC = () => {
|
||||
const [submenuTop, setSubmenuTop] = useState(0)
|
||||
const [submenuLeft, setSubmenuLeft] = useState(0)
|
||||
|
||||
const showSubmenu = (e: React.MouseEvent) => {
|
||||
const parentElement = e.currentTarget.parentElement
|
||||
if (parentElement && parentElement.childElementCount === 2) {
|
||||
const parentClientRect = parentElement.getBoundingClientRect()
|
||||
if (parentClientRect.top <= screen.height / 2) {
|
||||
setSubmenuTop(parentClientRect.top)
|
||||
} else {
|
||||
setSubmenuTop(
|
||||
parentClientRect.top -
|
||||
(parentElement.lastElementChild?.clientHeight ?? 0) +
|
||||
e.currentTarget.clientHeight
|
||||
)
|
||||
}
|
||||
setSubmenuLeft(parentClientRect.right)
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<FitFullScreen className={'flex-horizontal'}>
|
||||
<div className={'left-panel'}>
|
||||
<div className={'title'}>氮工具</div>
|
||||
<div style={{ marginTop: '0' }} className={'separate'} />
|
||||
<HideScrollbar isShowVerticalScrollbar={true} isShowHorizontalScrollbar={true}>
|
||||
<div className={'content'}>
|
||||
<ul>
|
||||
<li className={'item'}>
|
||||
<div className={'menu-bt'}>
|
||||
<NavLink
|
||||
to={''}
|
||||
end
|
||||
className={({ isActive, isPending }) =>
|
||||
isPending ? 'pending' : isActive ? 'active' : ''
|
||||
}
|
||||
>
|
||||
<div className={'icon-box'}>
|
||||
<Icon
|
||||
className={'icon'}
|
||||
component={toolsJsonObjects[0].icon}
|
||||
/>
|
||||
</div>
|
||||
<span className={'text'}>
|
||||
{toolsJsonObjects[0].name}
|
||||
</span>
|
||||
</NavLink>
|
||||
</div>
|
||||
</li>
|
||||
<li className={'item'}>
|
||||
<div className={'menu-bt'}>
|
||||
<NavLink
|
||||
to={'all'}
|
||||
className={({ isActive, isPending }) =>
|
||||
isPending ? ' pending' : isActive ? ' active' : ''
|
||||
}
|
||||
>
|
||||
<div className={'icon-box'}>
|
||||
<Icon
|
||||
className={'icon'}
|
||||
component={toolsJsonObjects[1].icon}
|
||||
/>
|
||||
</div>
|
||||
<span className={'text'}>
|
||||
{toolsJsonObjects[1].name}
|
||||
</span>
|
||||
</NavLink>
|
||||
</div>
|
||||
</li>
|
||||
<li>
|
||||
<div className={'separate'} />
|
||||
</li>
|
||||
{toolsJsonObjects.map((tool) => {
|
||||
return tool.menu &&
|
||||
tool.id !== 'tools' &&
|
||||
tool.id !== 'tools-all' ? (
|
||||
<li className={'item'} key={tool.id}>
|
||||
<div className={'menu-bt'}>
|
||||
<NavLink
|
||||
to={tool.path}
|
||||
className={({ isActive, isPending }) =>
|
||||
isPending
|
||||
? 'pending'
|
||||
: isActive
|
||||
? 'active'
|
||||
: ''
|
||||
}
|
||||
<div className={'content'}>
|
||||
<ul>
|
||||
<li className={'item'}>
|
||||
<div className={'menu-bt'}>
|
||||
<NavLink
|
||||
to={''}
|
||||
end
|
||||
className={({ isActive, isPending }) =>
|
||||
isPending ? 'pending' : isActive ? 'active' : ''
|
||||
}
|
||||
>
|
||||
<div className={'icon-box'}>
|
||||
<Icon
|
||||
className={'icon'}
|
||||
component={toolsJsonObjects[0].icon}
|
||||
/>
|
||||
</div>
|
||||
<span className={'text'}>{toolsJsonObjects[0].name}</span>
|
||||
</NavLink>
|
||||
</div>
|
||||
</li>
|
||||
<li className={'item'}>
|
||||
<div className={'menu-bt'}>
|
||||
<NavLink
|
||||
to={'all'}
|
||||
className={({ isActive, isPending }) =>
|
||||
isPending ? ' pending' : isActive ? ' active' : ''
|
||||
}
|
||||
>
|
||||
<div className={'icon-box'}>
|
||||
<Icon
|
||||
className={'icon'}
|
||||
component={toolsJsonObjects[1].icon}
|
||||
/>
|
||||
</div>
|
||||
<span className={'text'}>{toolsJsonObjects[1].name}</span>
|
||||
</NavLink>
|
||||
</div>
|
||||
</li>
|
||||
<li>
|
||||
<div className={'separate'} />
|
||||
</li>
|
||||
</ul>
|
||||
<div className={'toolsMenu'}>
|
||||
<HideScrollbar
|
||||
isShowVerticalScrollbar={true}
|
||||
isShowHorizontalScrollbar={true}
|
||||
scrollbarWidth={2}
|
||||
>
|
||||
<ul>
|
||||
{toolsJsonObjects.map((tool) => {
|
||||
return tool.menu &&
|
||||
tool.id !== 'tools' &&
|
||||
tool.id !== 'tools-all' ? (
|
||||
<li className={'item'} key={tool.id}>
|
||||
<div
|
||||
className={'menu-bt'}
|
||||
onMouseEnter={showSubmenu}
|
||||
>
|
||||
<div className={'icon-box'}>
|
||||
{tool.icon ? (
|
||||
<Icon
|
||||
className={'icon'}
|
||||
component={tool.icon}
|
||||
/>
|
||||
) : undefined}
|
||||
</div>
|
||||
<span className={'text'}>{tool.name}</span>
|
||||
</NavLink>
|
||||
</div>
|
||||
{tool.children ? (
|
||||
<ul className={'submenu'}>
|
||||
<div className={'content'}>
|
||||
{tool.children.map((subTool) => {
|
||||
return subTool.menu ? (
|
||||
<li
|
||||
className={'item'}
|
||||
key={subTool.id}
|
||||
>
|
||||
<NavLink
|
||||
to={`${tool.path}/${subTool.path}`}
|
||||
className={({
|
||||
isActive,
|
||||
isPending
|
||||
}) =>
|
||||
isPending
|
||||
? 'pending'
|
||||
: isActive
|
||||
? 'active'
|
||||
: ''
|
||||
}
|
||||
<NavLink
|
||||
to={tool.path}
|
||||
className={({ isActive, isPending }) =>
|
||||
isPending
|
||||
? 'pending'
|
||||
: isActive
|
||||
? 'active'
|
||||
: ''
|
||||
}
|
||||
>
|
||||
<div className={'icon-box'}>
|
||||
{tool.icon ? (
|
||||
<Icon
|
||||
className={'icon'}
|
||||
component={tool.icon}
|
||||
/>
|
||||
) : undefined}
|
||||
</div>
|
||||
<span className={'text'}>{tool.name}</span>
|
||||
</NavLink>
|
||||
</div>
|
||||
{tool.children ? (
|
||||
<ul
|
||||
className={'submenu'}
|
||||
style={{
|
||||
top: submenuTop,
|
||||
left: submenuLeft
|
||||
}}
|
||||
>
|
||||
<div className={'content'}>
|
||||
{tool.children.map((subTool) => {
|
||||
return subTool.menu ? (
|
||||
<li
|
||||
className={'item'}
|
||||
key={subTool.id}
|
||||
>
|
||||
<span className={'text'}>
|
||||
{subTool.name}
|
||||
</span>
|
||||
</NavLink>
|
||||
</li>
|
||||
) : undefined
|
||||
})}
|
||||
</div>
|
||||
</ul>
|
||||
) : undefined}
|
||||
</li>
|
||||
) : undefined
|
||||
})}
|
||||
</ul>
|
||||
<NavLink
|
||||
to={`${tool.path}/${subTool.path}`}
|
||||
className={({
|
||||
isActive,
|
||||
isPending
|
||||
}) =>
|
||||
isPending
|
||||
? 'pending'
|
||||
: isActive
|
||||
? 'active'
|
||||
: ''
|
||||
}
|
||||
>
|
||||
<span
|
||||
className={'text'}
|
||||
>
|
||||
{subTool.name}
|
||||
</span>
|
||||
</NavLink>
|
||||
</li>
|
||||
) : undefined
|
||||
})}
|
||||
</div>
|
||||
</ul>
|
||||
) : undefined}
|
||||
</li>
|
||||
) : undefined
|
||||
})}
|
||||
</ul>
|
||||
</HideScrollbar>
|
||||
</div>
|
||||
</HideScrollbar>
|
||||
|
||||
</div>
|
||||
<div className={'title'}>氮工具</div>
|
||||
</div>
|
||||
<div className={'right-panel'}></div>
|
||||
|
||||
@@ -259,7 +259,23 @@ export const toolsJsonObjects: ToolsJsonObject[] = [
|
||||
name: '翻译--10-',
|
||||
icon: React.lazy(() => import('~icons/fatweb/jenkins.jsx')),
|
||||
menu: true,
|
||||
auth: false
|
||||
auth: false,
|
||||
children: [
|
||||
{
|
||||
path: '1-1',
|
||||
id: '1-1',
|
||||
name: '翻译1-',
|
||||
menu: true,
|
||||
auth: false
|
||||
},
|
||||
{
|
||||
path: '2-1',
|
||||
id: '2-1',
|
||||
name: '翻译2-',
|
||||
menu: true,
|
||||
auth: false
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
|
||||
|
||||
Reference in New Issue
Block a user