Menu

접근 가능한 드롭다운 메뉴를 만드는 컴포넌트예요. 하위 메뉴·라디오 항목·체크박스 항목·컨텍스트 메뉴 등 다양한 메뉴 패턴을 지원해요.

출처: 문서

본문

사용법 (Usage)

import { Menu } from "@chakra-ui/react"
<Menu.Root>
  <Menu.Trigger />
  <Menu.Positioner>
    <Menu.Content>
      <Menu.Item />

      <Menu.ItemGroup>
        <Menu.Item />
      </Menu.ItemGroup>

      <Menu.Separator />
      <Menu.Arrow />

      <Menu.CheckboxItem>
        <Menu.ItemIndicator />
      </Menu.CheckboxItem>

      <Menu.RadioItemGroup>
        <Menu.RadioItem>
          <Menu.ItemIndicator />
        </Menu.RadioItem>
      </Menu.RadioItemGroup>
    </Menu.Content>
  </Menu.Positioner>
</Menu.Root>

예제 (Examples)

제어 (Controlled)

open과 onOpenChange prop을 사용해 메뉴의 표시 여부를 제어해요.

스토어 (Store)

메뉴를 제어하는 또 다른 방법은 RootProvider 컴포넌트와 useMenu 스토어 훅을 사용하는 것이에요.

이렇게 하면 메뉴 외부에서도 상태와 메서드에 접근할 수 있어요.

명령 (Command)

Menu.ItemCommand 컴포넌트를 사용해 메뉴 안에 명령을 표시해요.

컨텍스트 메뉴 (Context menu)

Menu.ContextTrigger 컴포넌트를 사용해 컨텍스트 메뉴를 만들어요.

그룹 (Group)

Menu.ItemGroup 컴포넌트를 사용해 관련 메뉴 항목을 그룹화해요.

위험 항목 (Danger Item)

항목을 삭제하는 데 사용되는 메뉴 항목에 스타일을 적용하는 예시예요.

하위 메뉴 (Submenu)

하위 메뉴를 만드는 예시예요.

Menu.Item 컴포넌트에 asChild prop을 전달해 링크를 렌더링해요.

커스텀 라우터 링크를 사용할 때는 Menu.Root 컴포넌트에 navigate prop을 설정해야 해요.

"use client"

import { Menu } from "@chakra-ui/react"
import { useNavigate } from "react-router-dom"

const Demo = () => {
  const navigate = useNavigate()
  return (
    <Menu.Root navigate={({ value, node }) => navigate(`/${value}`)}>
      {/* ... */}
    </Menu.Root>
  )
}

라디오 항목 (Radio Items)

메뉴에 라디오 항목을 만드는 예시예요.

체크박스 항목 (Checkbox Items)

메뉴에 체크박스 항목을 만드는 예시예요.

아이콘과 명령 (Icon and Command)

아이콘과 명령을 포함하도록 메뉴를 구성해요.

배치 (Placement)

positioning.placement prop을 사용해 메뉴의 배치를 제어해요.

아바타 (Avatar)

Menu를 Avatar 컴포넌트와 조합해 아바타 아래에 메뉴를 표시하는 예시예요.

앵커 포인트 (Anchor Point)

positioning.anchorPoint prop을 사용해 메뉴의 앵커 포인트를 제어해요.

DOM 요소의 getBoundingClientRect에서 유도하거나, DOMRect.fromRect({ x: 0, y: 0, width: 1, height: 1 }) 같은 것을 사용해 새 rect를 만들 수 있어요.

혼합 레이아웃 (Mixed Layout)

메뉴 항목의 혼합 레이아웃을 만드는 예시예요. 이 레이아웃에서 위쪽 가로 메뉴는 공통 메뉴 항목을 포함해요.

오버플로 (Overflow)

메뉴 항목 목록이 길 때 Menu.Content에 maxH prop을 설정해 스크롤 가능한 메뉴를 만들어요.

:::note

콘텐츠는 기본 maxHeight: "var(--available-height)"를 가지는데, 이는 뷰포트 기준 콘텐츠의 최대 사용 가능 높이예요.

:::

분리 시 숨기기 (Hide When Detached)

메뉴가 스크롤되는 컨테이너에 렌더링될 때 positioning.hideWhenDetached를 true로 설정하면 트리거가 뷰에서 스크롤 아웃될 때 메뉴를 숨겨요.

다이얼로그에서 열기 (Open From Dialog)

Dialog 안에서 Menu를 사용할 때는 Menu.Positioner를 문서 body로 포탈하지 않아야 해요.

-<Portal>
  <Menu.Positioner>
    <Menu.Content>
      {/* ... */}
    </Menu.Content>
  </Menu.Positioner>
-</Portal>

Dialog에 scrollBehavior="inside"를 설정했다면:

  • 메뉴가 다이얼로그에 잘리지 않도록 메뉴 위치 지정을 fixed로 설정하세요.
  • 트리거가 뷰에서 스크롤 아웃될 때 메뉴를 숨기도록 hideWhenDetached를 true로 설정하세요.
<Menu.Root positioning={{ strategy: "fixed", hideWhenDetached: true }}>
  {/* ... */}
</Menu.Root>

다이얼로그에서 열기 (중첩) (Open from Dialog (Nested))

Menu 항목이 또 다른 Menu를 포함하는 Dialog를 열 때, 이벤트 버블링으로 인한 예상치 못한 닫힘 동작을 피하려면 createOverlay를 사용해요.

가이드 (Guide)

강조된 항목 스타일링 (Styling highlighted items)

키보드 내비게이션으로 항목을 호버하거나 포커스할 때 _highlighted prop을 사용해 메뉴 항목에 스타일을 적용해요.

<Menu.Item _highlighted={{ bg: "blue.500", color: "white" }}>
  Custom highlighted item
</Menu.Item>

열린 상태 스타일링 (Styling open state)

메뉴가 열렸을 때 _open prop을 사용해 메뉴 트리거에 스타일을 적용해요.

<Menu.Trigger asChild>
  <Button _open={{ bg: "blue.500", color: "white" }}>Menu</Button>
</Menu.Trigger>

Props

Root

Menu 컴포넌트의 Root 부분에 대한 prop 테이블 (대화형 문서 참고).

Item

Menu 컴포넌트의 Item 부분에 대한 prop 테이블 (대화형 문서 참고).

더 알아보기 (Learn more)