Skip to content

Commit

Permalink
starter 主题菜单
Browse files Browse the repository at this point in the history
  • Loading branch information
tangly1024 committed Nov 20, 2024
1 parent e3e78b6 commit 762c9e9
Show file tree
Hide file tree
Showing 4 changed files with 99 additions and 87 deletions.
9 changes: 6 additions & 3 deletions components/ui/dashboard/DashboardButton.js
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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>
)
Expand Down
2 changes: 1 addition & 1 deletion themes/starter/components/Header.js
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ export const Header = props => {
</SignedOut>
<SignedIn>
<UserButton />
<DashboardButton />
<DashboardButton className={'hidden md:block'} />
</SignedIn>
</>
)}
Expand Down
75 changes: 49 additions & 26 deletions themes/starter/components/MenuItem.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import Link from 'next/link'
import { useRouter } from 'next/router'
import { useState } from 'react'

/**
* 菜单链接
* @param {*} param0
Expand All @@ -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'
Expand All @@ -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>
)}
Expand Down
100 changes: 43 additions & 57 deletions themes/starter/components/MenuList.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,20 @@
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'

/**
* 响应式 折叠菜单
*/
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',
Expand Down Expand Up @@ -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>
)
}

0 comments on commit 762c9e9

Please sign in to comment.