Lynx

Menu

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

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

Installation

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

Usage

MenuContent는 긴 목록을 스크롤합니다. container를 지정하지 않으면 Lynx view 안에, 지정하면 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>
  );
}
  • MenuAnchor는 위치만 정하며 Menu를 열지 않습니다. open과 onOpenChange로 상태를 제어하세요.
  • MenuContent 안에 별도의 positioner나 scroll area를 추가하지 마세요.
  • MenuItem은 description, prefixIcon, suffixIcon을 지원합니다.

Props

Prop

Type

onOpenChange?((open: boolean, details: MenuOpenChangeDetails) => void) | undefined
size?"small" | "medium" | "responsive" | undefined
open?boolean | undefined
defaultOpen?boolean | undefined

Prop

Type

disabled?boolean | undefined

고유 prop이 없습니다. className, style, children을 받습니다.

Prop

Type

overlayLevel?4 | 2 | 1 | 3 | undefined

고유 prop이 없습니다. className, style, children을 받습니다.

고유 prop이 없습니다. className, style, children을 받습니다.

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
disabled?boolean | undefined

Examples

Trigger

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

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

Size

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

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

With Description

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

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

Tone

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

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

Disabled Items

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

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

Placement

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

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

Anchor

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

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

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

Match Width

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

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

Container

container를 지정하지 않으면 Menu 레이어는 Lynx view 안의 position: fixed view로 렌더링되고, z-index 99로 같은 화면의 형제 요소 위에 그려집니다. container="window"처럼 native container 이름을 지정하면 native overlay에 렌더링되어 Lynx view 밖의 host 화면까지 덮습니다. overlayLevel은 container를 지정했을 때 overlay의 표시 순서를 정합니다.

두 방식 모두 레이어 바깥을 탭하면 아래 화면에 탭을 전달하지 않고 "interactOutside" reason으로 닫힙니다.

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

onOpenChange details

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

  • 열림: "trigger"
  • 닫힘: "trigger", "interactOutside", "itemClick"
  • container를 지정한 native overlay가 닫힘을 요청한 경우(Android 뒤로 가기): "dismiss". container가 없으면 전달하지 않으며, Android 뒤로 가기는 Menu가 아니라 host 화면을 닫습니다.
Lynx 예제를 불러오는 중입니다.

웹 버전과의 차이

  • Trigger는 자식을 native view로 감싸며 asChild를 제공하지 않습니다. raw <text>처럼 이름을 만들 수 없는 자식에는 accessibility-label을 지정하세요.
  • 키보드 focus, typeahead, ESC 키 닫힘은 지원하지 않습니다.
  • 바깥 탭은 "interactOutside", native overlay의 닫기 요청은 "dismiss" reason으로 전달합니다.
  • Menu가 열려 있는 동안 화면 전체 레이어가 Anchor 밖의 탭을 받습니다.

Last updated on

목차