feat(directory): add a fast navigation menu

This commit is contained in:
Haoyu Xu
2023-06-23 12:28:35 -04:00
parent 0209cf538d
commit eea45abbd6
4 changed files with 101 additions and 19 deletions

View File

@@ -24,6 +24,17 @@ export default function Dropdown(props) {
<ul className={classes.menu} style={props.activeColor}> <ul className={classes.menu} style={props.activeColor}>
{ {
props.menu.map((item) => { props.menu.map((item) => {
if (item.type === 'group') {
return (
<section
key={item.name}
className={classes.group}
>
<section className={classes.line} />
<section className={classes.text}>{item.name}</section>
</section>
)
}
return ( return (
<li <li
key={item.name} key={item.name}

View File

@@ -3,7 +3,7 @@
display: inline-block; display: inline-block;
user-select: none; user-select: none;
z-index: 2; z-index: 2;
padding: 0.5rem; padding: 0.5em;
cursor: pointer; cursor: pointer;
.text { .text {
@@ -14,13 +14,14 @@
} }
.content { .content {
padding-right: 0.5rem; padding-right: 0.5em;
height: 1em;
} }
.icon { .icon {
position: absolute; position: absolute;
bottom: 0.5rem; bottom: 0.5em;
right: -0.1rem; right: -0.1em;
width: 0.5em; width: 0.5em;
height: 0.5em; height: 0.5em;
display: inline-block; display: inline-block;
@@ -37,33 +38,47 @@
position: absolute; position: absolute;
background-color: var(--root-background-color); background-color: var(--root-background-color);
width: max-content; width: max-content;
max-height: 61.8vh;
max-width: 61.8vw;
z-index: -1; z-index: -1;
top: 2rem; top: 2em;
right: 0; right: 0;
gap: 0.5rem; gap: 0.5rem;
display: flex; display: flex;
align-items: center; align-items: stretch;
flex-direction: column; flex-direction: column;
flex-wrap: nowrap; flex-wrap: nowrap;
transition: all cubic-bezier(0.65, 0.05, 0.36, 1) 0.3s; transition: all cubic-bezier(0.65, 0.05, 0.36, 1) 0.3s;
overflow: hidden; overflow: auto;
padding: 0.5rem; padding: 0.5rem;
border: 1px solid var(--border-color); border: 1px solid var(--border-color);
visibility: hidden; visibility: hidden;
color: var(--link-highlight-color); color: var(--link-highlight-color);
cursor: auto; cursor: auto;
.group {
font-family: "Bender";
font-weight: bold;
font-size: 24px;
display: flex;
flex-direction: row;
flex-wrap: nowrap;
align-items: center;
justify-content: space-between;
width: 100%;
.line {
height: 1px;
flex-grow: 1;
background-color: var(--text-color);
margin: 0.5rem;
}
}
.item { .item {
cursor: pointer; cursor: pointer;
padding: 0.5rem; padding: 0.5rem;
font-size: 1rem; font-size: 1rem;
width: max-content;
height: max-content;
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
flex-wrap: nowrap;
transition: color cubic-bezier(0.65, 0.05, 0.36, 1) 0.3s; transition: color cubic-bezier(0.65, 0.05, 0.36, 1) 0.3s;
&:hover, &:hover,

View File

@@ -10,7 +10,8 @@ import {
Link, Link,
NavLink, NavLink,
useNavigate, useNavigate,
ScrollRestoration ScrollRestoration,
useLocation,
} from "react-router-dom"; } from "react-router-dom";
import classes from '@/scss/root/Root.module.scss' import classes from '@/scss/root/Root.module.scss'
import header from '@/scss/root/header.module.scss' import header from '@/scss/root/header.module.scss'
@@ -130,7 +131,7 @@ export default function Root() {
{headerTabs} {headerTabs}
</section> </section>
</section> </section>
<HeaderReturnButton /> <HeaderButton />
<Outlet /> <Outlet />
<ScrollRestoration /> <ScrollRestoration />
</main> </main>
@@ -278,10 +279,58 @@ HeaderTabsElement.propTypes = {
item: PropTypes.object.isRequired, item: PropTypes.object.isRequired,
} }
function HeaderReturnButton() { function HeaderButton() {
const navigate = useNavigate() const navigate = useNavigate()
let location = useLocation();
const { operators } = useConfig()
const { language } = useLanguage()
return useMemo(() => { const fastNavigateDict = useMemo(() => {
const dict = {}
operators.forEach((item) => {
if (!(item.date in dict)) {
dict[item.date] = []
}
dict[item.date].push({
codename: item.codename,
link: item.link,
})
})
return dict
}, [operators])
const fastNavigateList = useMemo(() => {
const list = []
for (const [key, value] of Object.entries(fastNavigateDict)) {
list.push({
name: key,
value: null,
type: "group",
})
value.forEach((item) => {
list.push({
name: item.codename[language],
value: item.link,
type: "item",
})
})
}
return list
}, [fastNavigateDict, language])
if (location.pathname === routes.find((item) => item.index).path) {
return (
<Border>
<Dropdown
menu={fastNavigateList}
onClick={(item) => {
navigate(item.value)
}}
className={classes['operator-fast-navigate']}
/>
</Border>
)
} else {
return ( return (
<Border> <Border>
<ReturnButton <ReturnButton
@@ -290,5 +339,5 @@ function HeaderReturnButton() {
/> />
</Border> </Border>
) )
}, [navigate]) }
} }

View File

@@ -76,6 +76,13 @@
} }
} }
.operator-fast-navigate {
position: absolute;
right: -3rem;
bottom: -2rem;
font-size: 32px;
}
.return-button { .return-button {
position: absolute; position: absolute;
right: -4rem; right: -4rem;