[WebUI]Tailwind + nextjs(Mega Menu) – 6

πŸ‘‰πŸ» λ©”κ°€λ©”λ‰΄λŠ” κΈ°λ³Έ 메뉴λ₯Ό 마우슀 μ„ νƒν•˜λ©΄ μ•„λž˜μ— λ©”λ‰΄νŒ¨λ„μ΄ λ‚˜νƒ€λ‚©λ‹ˆλ‹€.
A mega menu is one where a menu panel appears below the main menu item when you select it with your mouse.

πŸ‘‰πŸ» 메가메뉴λ₯Ό μ‚¬μš©ν•˜λ©΄ 더 λ§Žμ€ 링크 ν•­λͺ©μ„ μ‚¬μš©ν•  수 μžˆμŠ΅λ‹ˆλ‹€.
Using a mega menu allows for a greater number of link items.

πŸ“ 디렉토리 ꡬ쑰 / Directory structure

tailwindcss-nextjs/
└── app/
    β”œβ”€β”€ layout.tsx
    β”œβ”€β”€ page.tsx (root, /)
    β”œβ”€β”€ globals.css
    β”œβ”€β”€ favicon.ico
    β”‚
    β”œβ”€β”€ ui/                              ← UI Components
    β”‚   β”œβ”€β”€ page.tsx                     ← /ui
    β”‚   └── _components/
    β”‚       β”œβ”€β”€ button.tsx               ← Button
    β”‚       β”œβ”€β”€ dropdown.tsx             ← Select/Dropdown
    β”‚       └── navigation/
    β”‚           β”œβ”€β”€ HorizontalNavMenu.tsx  ← Horizontal Nav Menu
    β”‚           └── MegaMenu.tsx           ← Mega Menu
    β”‚
    β”œβ”€β”€ megamenu/                        
    β”‚   β”œβ”€β”€ page.tsx                     ← /megamenu -> Main route
    β”‚   └── 2b/page.tsx -> page.tsx      ← /megamenu/2b
    β”‚
    β”œβ”€β”€ button-css/ , button-tailwind/
    β”œβ”€β”€ card-css/ , card-tailwind/
    └── form-css/ , form-tailwind/

πŸ“ 메뉴 μ»΄ν¬λ„ŒνŠΈ / Menu Component

βœ”οΈ MegaMenu.tsx

1)메뉴 데이터(λ°°μ—΄) / Menu data (array)

const MEGA_DATA = [
  {
    title: 'μΉ΄ν…Œμ½”λ¦¬/Category',
    id: 'category',
    columns: [
      {
        heading: 'κ²Œμž„/Game',
        links: [
          { label: '2B', desc: 'Nier:Automata', href: '/megamenu/2b' },
          { label: '9S', desc: 'Nier:Automata', href: '/megamenu/branding' },
          { label: 'μ•„μ„œλͺ¨κ±΄/Arthor Morgan', desc: 'Red Dead Redemption2', href: '/megamenu/branding' },
        ],
      },
      {
        heading: 'μŒμ•…/Music',
        links: [
          { label: 'Spotify', desc: 'Spotify', href: '/megamenu/web' },
          { label: 'Apple Music', desc: 'Apple Music', href: '/megamenu/ui' },
        ],
      },
      {
        heading: '개발/Development',
        links: [
          { label: 'μ½”ν‹€λ¦°/Kotlin', desc: 'Android', href: '/megamenu/sns' },
          { label: 'μŠ€μœ„ν”„νŠΈ/Swift', desc: 'IOS', href: '/megamenu/seo' },
        ],
      },
    ],
    banner: { title: 'Freelifemakers 1.2 ', desc: 'μƒˆλ‘œμš΄ UI 라이브러리/New UI Library', href: '/megamenu/new' },
  },
  { title: 'SNS', href: 'https://freelifemakers.org', id: 'sns' },
  { title: 'μ›Ήμ‚¬μ΄νŠΈ/website', href: 'https://freelifemakers.org', id: 'website' },
]

A.화면에 μ‹€μ œλ‘œ ν‘œμ‹œλ˜λŠ” λ©”λ‰΄λΆ€λΆ„μž…λ‹ˆλ‹€.
This is the part of the menu that is actually displayed on the screen.

2)PC용 메뉴 μž…λ‹ˆλ‹€. / This is the menu for PC.

        {/* PC - 메가메뉴 메인 / Mega menu main */}
        <nav className="hidden md:flex items-center h-16">
          {MEGA_DATA.map((item) => (
            <div
              key={item.id}
              className="h-16 flex items-center"
              onMouseEnter={() => setOpenId(item.id)}
              onMouseLeave={() => setOpenId(null)}
            >
              {item.columns ? (
                <button className={`px-4 text-sm font-medium ${openId === item.id ? 'text-black font-bold' : 'text-gray-600'}`}>
                  {item.title} {openId === item.id ? 'β–²' : 'β–Ό'}
                </button>
              ) : (
                <Link href={item.href!} className="px-4 text-sm font-medium text-gray-600">
                  {item.title}
                </Link>
              )}
            </div>
          ))}
        </nav>

A.MEGA_DATA의 데이터λ₯Ό mapν•¨μˆ˜λ‘œ κΊΌλ‚΄μ„œ 좜λ ₯ν•©λ‹ˆλ‹€.(MEGA_DATA.map((item) =>)
Extract the data from MEGA_DATA using the map function and output it.

B.λ²„νŠΌμ„ ν΄λ¦­ν•˜λ©΄ μ‚Όκ°ν˜• λͺ¨μ–‘이 λ°”λ€λ‹ˆλ‹€.
Clicking the button changes the shape of the triangle.

{item.title} {openId === item.id ? 'β–²' : 'β–Ό'}

C.item.colums에 아무 값이 μ—†μœΌλ©΄ 링크가 ν‘œμ‹œλ©λ‹ˆλ‹€.
If there are no values ​​in item.columns, a link is displayed.

 <Link href={item.href!} className="px-4 text-sm font-medium text-gray-600">
    {item.title}
 </Link>

2)PC용 λ©”λ‰΄νŒ¨λ„ / Menu panel for PC

            {MEGA_DATA.find(i => i.id === openId)!.columns!.map((col) => (
              <div key={col.heading}>
                <h4 className="font-bold text-sm mb-3">{col.heading}</h4>
                <div className="flex flex-col gap-3">
                  {col.links.map((link) => (
                    <Link key={link.label} href={link.href} className="group">
                      <div className="text-sm font-medium group-hover:text-black">{link.label}</div>
                      <div className="text-xs text-gray-400">{link.desc}</div>
                    </Link>
                  ))}
                </div>
              </div>
            ))}

A.메뉴λ₯Ό ν΄λ¦­ν•˜λ©΄ λ‚˜νƒ€λ‚˜λŠ” 메뉴 νŒ¨λ„μž…λ‹ˆλ‹€.
This is the menu panel that appears when you click the menu.

B.MEGA_DATA에 μžˆλŠ” 정보λ₯Ό col.links.map((link) => (… …)둜 κΊΌλ‚΄μ„œ 화면에 좜λ ₯ν•©λ‹ˆλ‹€.
Extract the information from MEGA_DATA using col.links.map((link) => (... ...)) and display it on the screen.

3)λͺ¨λ°”일 메뉴 λ²„νŠΌ / Mobile menu button

<button onPointerUp={() => setMobileOpen(v => !v)} className="md:hidden w-11 h-11 bg-gray-100 rounded-full">
    {mobileOpen ? 'βœ•' : '☰'}
</button>

A.md(768px)보닀 화면이 μž‘μ•„μ§€λ©΄ λ²„νŠΌμ΄ λ‚˜νƒ€λ‚©λ‹ˆλ‹€.
The button appears when the screen size becomes smaller than md(768px).

4)λͺ¨λ°”일 메뉴 νŒ¨λ„ / Mobile Menu Panel

      {mobileOpen && (
        <div className="md:hidden absolute top-16 left-0 w-full bg-white border-t px-6 py-6 flex flex-col gap-6 shadow-xl">
          {MEGA_DATA.map(item => (
            <div key={item.id}>
              {item.columns ? (
                <>
                  <div className="font-bold mb-2">{item.title}</div>
                  <div className="ml-4 flex flex-col gap-2">
                    {item.columns.flatMap(c => c.links).map(l => (
                      <Link key={l.label} href={l.href} onClick={() => setMobileOpen(false)} className="text-sm text-gray-600 py-1">{l.label}</Link>
                    ))}
                  </div>
                </>
              ) : (
                <Link href={item.href!} onClick={() => setMobileOpen(false)} className="font-bold">{item.title}</Link>
              )}
            </div>
          ))}
        </div>
      )}

A.화면이 768px보닀 μž‘μ€ 경우만 보여지고 λͺ¨λ°”일 메뉴 λ²„νŠΌμ„ ν΄λ¦­ν•˜λ©΄ 화면에 λ³΄μ—¬μ§‘λ‹ˆλ‹€.
It is displayed only when the screen width is less than 768px, and it appears on the screen when the mobile menu button is clicked.


πŸ“ 라우트 / Route

βœ”οΈ/megamenu

— http://localhost:3000/megamenu

import { MegaMenu } from '../ui/_components/navigation/MegaMenu'

export default function MegaMenuPage() {
  return (
    <>
      <MegaMenu />
      <main className="mx-auto max-w-6xl px-6 py-20">
        <h1 className="text-4xl font-bold">Mega Menu / 메가메뉴</h1>
        <p className="text-gray-500 mt-2">메뉴에 마우슀 올리면 메뉴 νŒ¨λ„μ΄ 펼쳐짐,PC버전</p>
        <p className="text-gray-500 mt-2">Hover your mouse over the menu to expand the menu panel, PC version</p>
        <p className="text-gray-500 mt-1">λͺ¨λ°”μΌμ—μ„œλŠ” 햄버거 메뉴 μ•ˆμ— μΉ΄ν…Œκ³ λ¦¬λ³„λ‘œ 펼쳐짐.</p>
        <p className="text-gray-500 mt-1">On mobile, categories are displayed in an expandable format within the hamburger menu.</p>
      </main>
    </>
  )
}

1) μœ„μ˜ μ£Όμ†Œλ₯Ό μ‹€ν–‰μ‹œ 메가메뉴λ₯Ό μ‹€ν–‰ν•˜λŠ” μ½”λ“œμž…λ‹ˆλ‹€.
This is the code that triggers the mega menu when the address above is accessed.

2)Layout.tsxλŠ” λ§Œλ“€μ§€μ•Šκ³  νŽ˜μ΄μ§€λ§ˆλ‹€ <MegaMenu />μ½”λ“œλ₯Ό μž…λ ₯ν•΄μ•Όν•©λ‹ˆλ‹€.
You should not create a Layout.tsx file; instead, you must include the code on every page.

3)/megamenu/2b λΌμš°νŠΈκ°€ μžˆλŠ”λ° 이 뢀뢄에도 λ™μΌν•˜κ²Œ <MegaMenu />μ½”λ“œκ°€ μžˆμŠ΅λ‹ˆλ‹€.
There is a route at /megamenu/2b, which also contains the code.

1./megamenu
export default function MegaMenuPage() {
  return (
    <>
      <MegaMenu />
      <main className="mx-auto max-w-6xl px-6 py-20">
        <h1 className="text-4xl font-bold">Mega Menu / 메가메뉴</h1>
        <p className="text-gray-500 mt-2">메뉴에 마우슀 올리면 메뉴 νŒ¨λ„μ΄ 펼쳐짐,PC버전</p>
        <p className="text-gray-500 mt-2">Hover your mouse over the menu to expand the menu panel, PC version</p>
        <p className="text-gray-500 mt-1">λͺ¨λ°”μΌμ—μ„œλŠ” 햄버거 메뉴 μ•ˆμ— μΉ΄ν…Œκ³ λ¦¬λ³„λ‘œ 펼쳐짐.</p>
        <p className="text-gray-500 mt-1">On mobile, categories are displayed in an expandable format within the hamburger menu.</p>
      </main>
    </>
  )
}

2./megamenu/2b
export default function Page() {
  return (
    <>
      <MegaMenu />
      <main className="mx-auto max-w-6xl px-6 py-20">
        <h1 className="text-3xl font-bold">2B</h1>
        <p className="text-gray-500 mt-2">μ—¬κΈ°λŠ” /megamenu/2B νŽ˜μ΄μ§€.</p>
        <p className="text-gray-500 mt-2">This is the /megamenu/2B page.</p>
      </main>
    </>
  )
}

πŸ“ ν…ŒμŠ€νŠΈ / Test

βœ”οΈ PC

PC ScreenShot
PC ScreenShot

βœ”οΈ Mobile

λ§ˆνƒœλ³΅μŒ 21μž₯ 22절 / Matthew 21: 22

“λ„ˆν¬κ°€ 기도할 λ•Œμ— 무엇이든지 λ―Ώκ³  κ΅¬ν•˜λŠ” 것은 λ‹€ λ°›μœΌλ¦¬λΌ ν•˜μ‹œλ‹ˆλΌ”

“And everything you ask in prayer, believing, you will receive.”

Leave a Reply