feat(directory): add a fast navigation menu
This commit is contained in:
@@ -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}
|
||||||
|
|||||||
@@ -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,
|
||||||
|
|||||||
@@ -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])
|
}
|
||||||
}
|
}
|
||||||
@@ -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;
|
||||||
|
|||||||
Reference in New Issue
Block a user