mirror of
https://github.com/d0zingcat/NotionNext.git
synced 2026-05-14 15:09:22 +00:00
starter 主题菜单
This commit is contained in:
@@ -5,9 +5,12 @@ import { useRouter } from 'next/router'
|
||||
* 跳转仪表盘的按钮
|
||||
* @returns
|
||||
*/
|
||||
export default function DashboardButton() {
|
||||
export default function DashboardButton({ className }) {
|
||||
const { asPath } = useRouter()
|
||||
const enableDashboardButton = siteConfig('ENABLE_DASHBOARD_BUTTON', false)
|
||||
const enableDashboardButton = siteConfig(
|
||||
'ENABLE_DASHBOARD_BUTTON',
|
||||
process.env.PUBLIC_NEXT_ENABLE_DASHBOARD_BUTTON
|
||||
)
|
||||
|
||||
if (!enableDashboardButton) {
|
||||
return null
|
||||
@@ -20,7 +23,7 @@ export default function DashboardButton() {
|
||||
return (
|
||||
<button
|
||||
type='button'
|
||||
className='text-white bg-gray-800 hover:bg-gray-900 hover:ring-4 hover:ring-gray-300 focus:outline-none focus:ring-4 focus:ring-gray-300 font-medium rounded-lg text-sm px-5 py-2 me-2 dark:bg-gray-800 dark:hover:bg-gray-700 dark:focus:ring-gray-700 dark:border-gray-700'>
|
||||
className={`${className || ''} text-white bg-gray-800 hover:bg-gray-900 hover:ring-4 hover:ring-gray-300 focus:outline-none focus:ring-4 focus:ring-gray-300 font-medium rounded-lg text-sm px-5 py-2 me-2 dark:bg-gray-800 dark:hover:bg-gray-700 dark:focus:ring-gray-700 dark:border-gray-700`}>
|
||||
<Link href='/dashboard'>仪表盘</Link>
|
||||
</button>
|
||||
)
|
||||
|
||||
@@ -88,7 +88,7 @@ export const Header = props => {
|
||||
</SignedOut>
|
||||
<SignedIn>
|
||||
<UserButton />
|
||||
<DashboardButton />
|
||||
<DashboardButton className={'hidden md:block'} />
|
||||
</SignedIn>
|
||||
</>
|
||||
)}
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
import Link from 'next/link'
|
||||
import { useRouter } from 'next/router'
|
||||
import { useState } from 'react'
|
||||
|
||||
/**
|
||||
* 菜单链接
|
||||
* @param {*} param0
|
||||
@@ -8,28 +10,47 @@ import { useRouter } from 'next/router'
|
||||
export const MenuItem = ({ link }) => {
|
||||
const hasSubMenu = link?.subMenus?.length > 0
|
||||
const router = useRouter()
|
||||
|
||||
// 管理子菜单的展开状态
|
||||
const [isSubMenuOpen, setIsSubMenuOpen] = useState(false)
|
||||
|
||||
const toggleSubMenu = () => {
|
||||
setIsSubMenuOpen(prev => !prev) // 切换子菜单状态
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
{/* MenuItem */}
|
||||
{/* 普通 MenuItem */}
|
||||
{!hasSubMenu && (
|
||||
<li className='group relative whitespace-nowrap'>
|
||||
<Link
|
||||
href={link?.href}
|
||||
target={link?.target}
|
||||
className={`ud-menu-scroll mx-8 flex py-2 text-base font-medium text-dark group-hover:text-primary dark:text-white lg:mr-0 lg:inline-flex lg:px-0 lg:py-6 ${router.route === '/' ? 'lg:text-white lg:group-hover:text-white' : ''} lg:group-hover:opacity-70`}>
|
||||
className={`ud-menu-scroll mx-8 flex py-2 text-base font-medium text-dark group-hover:text-primary dark:text-white lg:mr-0 lg:inline-flex lg:px-0 lg:py-6 ${
|
||||
router.route === '/'
|
||||
? 'lg:text-white lg:group-hover:text-white'
|
||||
: ''
|
||||
} lg:group-hover:opacity-70`}>
|
||||
{link?.icon && <i className={link.icon + ' mr-2 my-auto'} />}
|
||||
{link?.name}
|
||||
</Link>
|
||||
</li>
|
||||
)}
|
||||
|
||||
{/* 有子菜单的 MenuItem */}
|
||||
{hasSubMenu && (
|
||||
<li className='submenu-item group relative whitespace-nowrap'>
|
||||
{/* 有子菜单的MenuItem */}
|
||||
<a
|
||||
className={`relative mx-8 flex items-center justify-between py-2 text-base font-medium text-dark group-hover:text-primary dark:text-white lg:ml-8 lg:mr-0 lg:inline-flex lg:py-6 lg:pl-0 lg:pr-4 ${router.route === '/' ? 'lg:text-white lg:group-hover:text-white' : ''} lg:group-hover:opacity-70 xl:ml-10`}>
|
||||
{link?.icon && <i className={link.icon + ' mr-2 my-auto'} />}
|
||||
{link?.name}
|
||||
<button
|
||||
onClick={toggleSubMenu}
|
||||
className={`cursor-pointer relative w-full px-8 flex items-center justify-between py-2 text-base font-medium text-dark group-hover:text-primary dark:text-white lg:ml-8 lg:mr-0 lg:inline-flex lg:py-6 lg:pl-0 lg:pr-4 ${
|
||||
router.route === '/'
|
||||
? 'lg:text-white lg:group-hover:text-white'
|
||||
: ''
|
||||
} lg:group-hover:opacity-70 xl:ml-10`}>
|
||||
<span>
|
||||
{link?.icon && <i className={link.icon + ' mr-2 my-auto'} />}
|
||||
{link?.name}
|
||||
</span>
|
||||
|
||||
<svg
|
||||
className='ml-2 fill-current'
|
||||
@@ -40,26 +61,28 @@ export const MenuItem = ({ link }) => {
|
||||
xmlns='http://www.w3.org/2000/svg'>
|
||||
<path d='M7.99999 14.9C7.84999 14.9 7.72499 14.85 7.59999 14.75L1.84999 9.10005C1.62499 8.87505 1.62499 8.52505 1.84999 8.30005C2.07499 8.07505 2.42499 8.07505 2.64999 8.30005L7.99999 13.525L13.35 8.25005C13.575 8.02505 13.925 8.02505 14.15 8.25005C14.375 8.47505 14.375 8.82505 14.15 9.05005L8.39999 14.7C8.27499 14.825 8.14999 14.9 7.99999 14.9Z' />
|
||||
</svg>
|
||||
</a>
|
||||
</button>
|
||||
|
||||
<div className='submenu border dark:border-gray-600 relative left-0 top-full hidden w-[250px] rounded-sm bg-white p-4 transition-[top] duration-300 group-hover:opacity-100 dark:bg-dark-2 lg:invisible lg:absolute lg:top-[110%] lg:block lg:opacity-0 lg:shadow-lg lg:group-hover:visible lg:group-hover:top-full'>
|
||||
{link.subMenus.map((sLink, index) => {
|
||||
return (
|
||||
<Link
|
||||
key={index}
|
||||
href={sLink.href}
|
||||
target={link?.target}
|
||||
className='block rounded px-4 py-[10px] text-sm text-body-color hover:text-primary dark:text-dark-6 dark:hover:text-primary'>
|
||||
{/* 子菜单SubMenuItem */}
|
||||
<span className='text-md ml-2 whitespace-nowrap'>
|
||||
{link?.icon && (
|
||||
<i className={sLink.icon + ' mr-2 my-auto'} />
|
||||
)}{' '}
|
||||
{sLink.title}
|
||||
</span>
|
||||
</Link>
|
||||
)
|
||||
})}
|
||||
{/* 子菜单 */}
|
||||
<div
|
||||
className={`submenu dark:border-gray-600 relative left-0 top-full w-[250px] rounded-sm bg-white p-4 transition-all duration-300 dark:bg-dark-2 lg:absolute lg:shadow-lg ${
|
||||
isSubMenuOpen
|
||||
? 'block opacity-100 visible'
|
||||
: 'hidden opacity-0 invisible'
|
||||
}`}>
|
||||
{link.subMenus.map((sLink, index) => (
|
||||
<Link
|
||||
key={index}
|
||||
href={sLink.href}
|
||||
target={link?.target}
|
||||
className='block rounded px-4 py-[10px] text-sm text-body-color hover:text-primary dark:text-dark-6 dark:hover:text-primary'>
|
||||
{/* 子菜单 SubMenuItem */}
|
||||
<span className='text-md ml-2 whitespace-nowrap'>
|
||||
{link?.icon && <i className={sLink.icon + ' mr-2 my-auto'} />}{' '}
|
||||
{sLink.title}
|
||||
</span>
|
||||
</Link>
|
||||
))}
|
||||
</div>
|
||||
</li>
|
||||
)}
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
import BLOG from '@/blog.config'
|
||||
import { siteConfig } from '@/lib/config'
|
||||
import { useGlobal } from '@/lib/global'
|
||||
import { useEffect } from 'react'
|
||||
import { useRouter } from 'next/router'
|
||||
import { useEffect, useState } from 'react'
|
||||
import { MenuItem } from './MenuItem'
|
||||
|
||||
/**
|
||||
* 响应式 折叠菜单
|
||||
*/
|
||||
@@ -9,6 +12,9 @@ export const MenuList = props => {
|
||||
const { customNav, customMenu } = props
|
||||
const { locale } = useGlobal()
|
||||
|
||||
const [showMenu, setShowMenu] = useState(false) // 控制菜单展开/收起状态
|
||||
const router = useRouter()
|
||||
|
||||
let links = [
|
||||
{
|
||||
icon: 'fas fa-archive',
|
||||
@@ -40,68 +46,48 @@ export const MenuList = props => {
|
||||
links = customNav.concat(links)
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
// ===== responsive navbar
|
||||
const navbarToggler = document.querySelector('#navbarToggler')
|
||||
const navbarCollapse = document.querySelector('#navbarCollapse')
|
||||
|
||||
// 点击弹出菜单
|
||||
navbarToggler?.addEventListener('click', () => {
|
||||
navbarToggler?.classList.toggle('navbarTogglerActive')
|
||||
navbarCollapse?.classList.toggle('hidden')
|
||||
})
|
||||
|
||||
//= ==== close navbar-collapse when a clicked
|
||||
document
|
||||
.querySelectorAll('#navbarCollapse ul li:not(.submenu-item) a')
|
||||
.forEach(e =>
|
||||
e.addEventListener('click', () => {
|
||||
navbarToggler?.classList.remove('navbarTogglerActive')
|
||||
navbarCollapse?.classList.add('hidden')
|
||||
})
|
||||
)
|
||||
|
||||
// ===== Sub-menu
|
||||
const submenuItems = document.querySelectorAll('.submenu-item')
|
||||
submenuItems.forEach(el => {
|
||||
el.querySelector('a')?.addEventListener('click', () => {
|
||||
el.querySelector('.submenu')?.classList.toggle('hidden')
|
||||
})
|
||||
})
|
||||
}, [])
|
||||
|
||||
// 如果 开启自定义菜单,则覆盖Page生成的菜单
|
||||
if (siteConfig('CUSTOM_MENU')) {
|
||||
if (siteConfig('CUSTOM_MENU', BLOG.CUSTOM_MENU)) {
|
||||
links = customMenu
|
||||
}
|
||||
|
||||
// if (!links || links.length === 0) {
|
||||
// return null
|
||||
// }
|
||||
if (!links || links.length === 0) {
|
||||
return null
|
||||
}
|
||||
|
||||
const toggleMenu = () => {
|
||||
setShowMenu(!showMenu) // 切换菜单状态
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
setShowMenu(false)
|
||||
}, [router])
|
||||
|
||||
return (
|
||||
<>
|
||||
<div>
|
||||
{/* 移动端菜单切换按钮 */}
|
||||
<button
|
||||
id='navbarToggler'
|
||||
className='absolute right-4 top-1/2 block -translate-y-1/2 rounded-lg px-3 py-[6px] ring-primary focus:ring-2 lg:hidden'>
|
||||
<span className='relative my-[6px] block h-[2px] w-[30px] bg-white duration-200 transition-all'></span>
|
||||
<span className='relative my-[6px] block h-[2px] w-[30px] bg-white duration-200 transition-all'></span>
|
||||
<span className='relative my-[6px] block h-[2px] w-[30px] bg-white duration-200 transition-all'></span>
|
||||
</button>
|
||||
<div>
|
||||
{/* 移动端菜单切换按钮 */}
|
||||
<button
|
||||
id='navbarToggler'
|
||||
onClick={toggleMenu}
|
||||
className={`absolute right-4 top-1/2 block -translate-y-1/2 rounded-lg px-3 py-[6px] ring-primary focus:ring-2 lg:hidden ${
|
||||
showMenu ? 'navbarTogglerActive' : ''
|
||||
}`}>
|
||||
<span className='relative my-[6px] block h-[2px] w-[30px] bg-white duration-200 transition-all'></span>
|
||||
<span className='relative my-[6px] block h-[2px] w-[30px] bg-white duration-200 transition-all'></span>
|
||||
<span className='relative my-[6px] block h-[2px] w-[30px] bg-white duration-200 transition-all'></span>
|
||||
</button>
|
||||
|
||||
{/* 响应式菜单 */}
|
||||
<nav
|
||||
id='navbarCollapse'
|
||||
className='absolute right-4 top-full hidden w-full max-w-[250px] rounded-lg bg-white py-5 shadow-lg dark:bg-dark-2 lg:static lg:block lg:w-full lg:max-w-full lg:bg-transparent lg:px-4 lg:py-0 lg:shadow-none dark:lg:bg-transparent xl:px-6'>
|
||||
<ul className='blcok lg:flex 2xl:ml-20'>
|
||||
{links?.map((link, index) => (
|
||||
<MenuItem key={index} link={link} />
|
||||
))}
|
||||
</ul>
|
||||
</nav>
|
||||
</div>
|
||||
</>
|
||||
<nav
|
||||
id='navbarCollapse'
|
||||
className={`absolute right-4 top-full w-full max-w-[250px] rounded-lg bg-white py-5 shadow-lg dark:bg-dark-2 lg:static lg:block lg:w-full lg:max-w-full lg:bg-transparent lg:px-4 lg:py-0 lg:shadow-none dark:lg:bg-transparent xl:px-6 ${
|
||||
showMenu ? '' : 'hidden'
|
||||
}`}>
|
||||
<ul className='blcok lg:flex 2xl:ml-20'>
|
||||
{links?.map((link, index) => (
|
||||
<MenuItem key={index} link={link} />
|
||||
))}
|
||||
</ul>
|
||||
</nav>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user