Lynx

Menu

사용자가 취할 수 있는 선택지나 액션 리스트를 제공하는 컴포넌트입니다.

Engine ≥ 3.9<overlay>
Lynx 예제를 불러오는 중입니다.

Installation

npx @seed-design/cli@latest add ui:menu

Usage

Menu는 Root, Trigger, Content와 Group으로 구성합니다. MenuContent는 native overlay, 위치 계산, 표시 수명, 긴 목록의 세로 스크롤을 함께 처리합니다.

import { ActionButton } from "@seed-design/lynx-react";

import {
  MenuContent,
  MenuGroup,
  MenuGroupLabel,
  MenuItem,
  MenuRoot,
  MenuTrigger,
} from "@/components/ui/menu";

export function App() {
  return (
    <MenuRoot>
      <MenuTrigger>
        <ActionButton variant="neutralSolid">열기</ActionButton>
      </MenuTrigger>
      <MenuContent>
        <MenuGroup>
          <MenuGroupLabel>작업</MenuGroupLabel>
          <MenuItem label="항목 1" />
          <MenuItem label="항목 2" />
        </MenuGroup>
        <MenuGroup>
          <MenuItem label="항목 3" />
        </MenuGroup>
      </MenuContent>
    </MenuRoot>
  );
}
  • MenuRoot는 열림 상태와 위치를 관리합니다.
  • MenuTrigger는 닫힌 Menu를 탭으로 엽니다.
  • MenuAnchor는 위치 기준점만 제공합니다. 열림 상태는 openonOpenChange로 제어합니다.
  • MenuContent는 overlay와 스크롤 가능한 메뉴 목록을 렌더링합니다. 자식에 별도 PositionerScrollArea를 추가하지 않습니다.
  • MenuGroupMenuGroupLabel은 관련된 항목을 묶고 제목을 표시합니다.
  • MenuItemlabel, 선택적 description, prefixIcon, suffixIcon을 한 항목으로 조립합니다.

Props

Prop

Type

open?boolean | undefined
defaultOpen?boolean | undefined
onOpenChange?((open: boolean, details: MenuOpenChangeDetails) => void) | undefined
disabled?boolean | undefined
placement?Placement | undefined
gutter?number | undefined
overflowPadding?number | undefined
matchReferenceWidth?boolean | undefined
size?"small" | "medium" | "responsive" | undefined
style?CSSProperties | undefined
children?React.ReactNode
className?string | undefined

Prop

Type

disabled?boolean | undefined
style?CSSProperties | undefined
children?React.ReactNode
className?string | undefined
bindtap?EventHandler<BaseTouchEvent<Target>> | undefined
main-thread:bindtap?EventHandler<BaseTouchEvent<Element>> | undefined

Prop

Type

style?CSSProperties | undefined
children?React.ReactNode
className?string | undefined

Prop

Type

style?CSSProperties | undefined
children?React.ReactNode
className?string | undefined

Prop

Type

style?CSSProperties | undefined
children?React.ReactNode
className?string | undefined

Prop

Type

style?CSSProperties | undefined
children?React.ReactNode
className?string | undefined

Prop

Type

labelReact.ReactNode
description?React.ReactNode
prefixIcon?React.ReactElement<LynxIconElementProps, string | React.JSXElementConstructor<any>> | undefined
suffixIcon?React.ReactElement<LynxIconElementProps, string | React.JSXElementConstructor<any>> | undefined
className?string | undefined
bindtap?EventHandler<BaseTouchEvent<Target>> | undefined
main-thread:bindtap?EventHandler<BaseTouchEvent<Element>> | undefined
disabled?boolean | undefined
style?CSSProperties | undefined

Examples

Trigger

MenuTrigger를 탭하면 닫힌 Menu가 열립니다. MenuItem을 탭하거나 바깥 영역을 탭하면 닫힙니다.

Lynx 예제를 불러오는 중입니다.

Size

size로 Menu의 크기를 정합니다. 기본값은 "medium"입니다. "responsive"는 현재 화면 너비를 기준으로 "small" 또는 "medium"으로 바뀝니다.

Lynx 예제를 불러오는 중입니다.

With Description

MenuItemdescription에 항목의 부가 설명을 전달합니다.

Lynx 예제를 불러오는 중입니다.

Tone

MenuItemtone="critical"로 삭제처럼 주의가 필요한 액션을 표시합니다.

Lynx 예제를 불러오는 중입니다.

Disabled Items

disabled 항목은 탭해도 bindtap이 실행되지 않고 Menu를 닫지 않습니다.

Lynx 예제를 불러오는 중입니다.

Placement

MenuRootplacement로 Menu를 기준 요소의 12개 방향에 배치합니다. 기본값은 "bottom"입니다. 화면 가장자리에서 공간이 부족하면 native runtime이 반대쪽으로 뒤집거나 경계 안으로 이동합니다.

Lynx 예제를 불러오는 중입니다.

Anchor

MenuAnchor는 Menu 위치만 정하고 탭으로 열고 닫지는 않습니다. 이 예제처럼 openonOpenChange로 상태를 제어할 수 있습니다.

Lynx 예제를 불러오는 중입니다.

Native overlay가 열려 있는 동안에는 Anchor 바깥의 Switch를 탭할 수 없습니다. 이 예제는 Menu가 닫힌 상태에서 Switch로 열고, 항목을 선택해 닫는 흐름을 보여줍니다. overlay 바깥 탭을 무시하는 제어는 onOpenChange에서 details.reason === "interactOutside"를 걸러 구현합니다.

Match Width

matchReferenceWidth를 사용하면 Menu 너비가 Trigger 또는 Anchor 너비와 같아집니다.

Lynx 예제를 불러오는 중입니다.

onOpenChange details

onOpenChange의 두 번째 인자인 details에는 상태를 바꾼 이유와 native event가 들어옵니다.

  • 열림: "trigger"
  • 닫힘: "trigger", "interactOutside", "itemClick"
  • native overlay가 닫힘을 요청한 경우: "dismiss"
Lynx 예제를 불러오는 중입니다.

웹 버전과의 차이

Lynx Menu는 native overlay 위에 렌더링합니다. HTML DOM, asChild, 키보드 포커스, typeahead, ESC 키 닫힘은 지원하지 않습니다. 따라서 escapeKeyDowncascadeDismiss reason도 제공하지 않습니다. 화면과 앱 수준에서 필요한 키보드 접근성은 host의 native 접근성 흐름으로 확인하세요.

항목Lynx
Trigger 조합asChild 지원자식을 감싸는 native Trigger를 사용
위치와 목록DOM positioner와 scroll areaMenuContent가 native overlay, 위치, 스크롤을 함께 처리
바깥 상호작용DOM pointer와 키보드바깥 탭은 interactOutside, native dismissal은 dismiss
키보드ESC, focus, typeahead 지원미지원
Anchor가 열린 동안의 제어바깥 제어를 계속 조합 가능fullscreen overlay가 Anchor 밖의 탭을 가림

Last updated on

목차