컨텍스트 메뉴

DayFlow UI를 위한 조합 가능한 포털 기반 컨텍스트 메뉴입니다. 중첩 하위 메뉴, 레이블, 구분선, 내장 색상 선택기를 지원합니다. 바깥쪽 클릭, 스크롤, 창 크기 변경, Escape 입력 시 자동으로 닫힙니다.

설치

npm install @dayflow/ui-context-menu
pnpm add @dayflow/ui-context-menu
yarn add @dayflow/ui-context-menu
bun add @dayflow/ui-context-menu

이미 Tailwind CSS를 쓰는 프로젝트라면 컴포넌트 전용 번들을 가져오세요:

@import '@dayflow/ui-context-menu/dist/styles.components.css';
@import 'tailwindcss';

Tailwind CSS를 쓰지 않는 프로젝트라면 전체 스타일시트를 가져오세요:

import {
  ContextMenu,
  ContextMenuItem,
  ContextMenuSeparator,
  ContextMenuLabel,
  ContextMenuSub,
  ContextMenuSubTrigger,
  ContextMenuSubContent,
  ContextMenuColorPicker,
} from '@dayflow/ui-context-menu';
import '@dayflow/ui-context-menu/dist/styles.css';

기본 사용법

contextmenu 이벤트에서 얻은 커서 위치에 ContextMenu를 렌더링하세요.

import { useState } from 'react';
import {
  ContextMenu,
  ContextMenuItem,
  ContextMenuSeparator,
} from '@dayflow/ui-context-menu';

function MyComponent() {
  const [menu, setMenu] = useState<{ x: number; y: number } | null>(null);

  const handleContextMenu = (e: React.MouseEvent) => {
    e.preventDefault();
    setMenu({ x: e.clientX, y: e.clientY });
  };

  return (
    <div onContextMenu={handleContextMenu}>
      Right-click here
      {menu && (
        <ContextMenu x={menu.x} y={menu.y} onClose={() => setMenu(null)}>
          <ContextMenuItem onClick={() => console.log('Edit')}>
            Edit
          </ContextMenuItem>
          <ContextMenuItem onClick={() => console.log('Copy')}>
            Copy
          </ContextMenuItem>
          <ContextMenuSeparator />
          <ContextMenuItem onClick={() => console.log('Delete')} danger>
            Delete
          </ContextMenuItem>
        </ContextMenu>
      )}
    </div>
  );
}

레이블과 아이콘 사용하기

<ContextMenu x={x} y={y} onClose={onClose}>
  <ContextMenuLabel>Actions</ContextMenuLabel>
  <ContextMenuItem icon={<PencilIcon />} onClick={() => onEdit()}>
    Edit Event
  </ContextMenuItem>
  <ContextMenuItem icon={<CopyIcon />} onClick={() => onDuplicate()}>
    Duplicate
  </ContextMenuItem>
  <ContextMenuSeparator />
  <ContextMenuItem icon={<TrashIcon />} onClick={() => onDelete()} danger>
    Delete
  </ContextMenuItem>
</ContextMenu>

중첩 하위 메뉴

항목을 ContextMenuSub로 감싸면 마우스를 올렸을 때 열리는 하위 메뉴가 만들어집니다. 하위 메뉴는 화면 밖으로 넘치지 않도록 위치를 자동으로 조정합니다.

<ContextMenu x={x} y={y} onClose={onClose}>
  <ContextMenuItem onClick={() => onEdit()}>Edit</ContextMenuItem>
  <ContextMenuSub>
    <ContextMenuSubTrigger>Move to</ContextMenuSubTrigger>
    <ContextMenuSubContent>
      <ContextMenuItem onClick={() => onMove('work')}>Work</ContextMenuItem>
      <ContextMenuItem onClick={() => onMove('personal')}>
        Personal
      </ContextMenuItem>
    </ContextMenuSubContent>
  </ContextMenuSub>
  <ContextMenuSeparator />
  <ContextMenuItem danger onClick={() => onDelete()}>
    Delete
  </ContextMenuItem>
</ContextMenu>

색상 선택기

ContextMenuColorPicker는 미리 정의된 색상 견본 한 줄과, 선택적으로 "사용자 지정 색상" 동작을 렌더링합니다.

<ContextMenu x={x} y={y} onClose={onClose}>
  <ContextMenuLabel>Calendar Color</ContextMenuLabel>
  <ContextMenuColorPicker
    selectedColor={currentColor}
    onSelect={color => {
      updateCalendarColor(color);
      onClose();
    }}
    onCustomColor={() => openColorDialog()}
    customColorLabel='Custom color...'
  />
</ContextMenu>

비활성 항목

<ContextMenuItem onClick={() => onPaste()} disabled={!hasClipboard}>
  Paste
</ContextMenuItem>

API 레퍼런스

ContextMenu

Prop타입설명
xnumber가로 위치입니다(예: event.clientX)
ynumber세로 위치입니다(예: event.clientY)
onClose() => void메뉴를 닫아야 할 때 호출됩니다
childrenComponentChildren메뉴 항목입니다
classNamestring메뉴 컨테이너에 추가할 CSS 클래스입니다

ContextMenuItem

Prop타입기본값설명
onClick() => void클릭 핸들러입니다
childrenComponentChildren항목의 레이블입니다
iconComponentChildren레이블 왼쪽에 표시되는 아이콘입니다
dangerbooleanfalse항목을 파괴적 동작을 뜻하는 빨간색으로 표시합니다
disabledbooleanfalse항목을 상호작용할 수 없게 만듭니다

ContextMenuColorPicker

Prop타입기본값설명
selectedColorstring현재 선택된 색상입니다(hex)
onSelect(color: string) => void색상 견본을 클릭했을 때 호출됩니다
onCustomColor() => void사용자 지정 색상 줄을 클릭했을 때 호출됩니다
customColorLabelstring"Custom Color"사용자 지정 색상 동작의 레이블입니다

그 밖의 export

컴포넌트설명
ContextMenuSeparator가로 구분선입니다
ContextMenuLabel상호작용하지 않는 구획 제목입니다
ContextMenuSub하위 메뉴의 열림 상태를 관리하는 래퍼입니다
ContextMenuSubTrigger마우스를 올리면 하위 메뉴를 여는 행입니다
ContextMenuSubContent떠 있는 하위 메뉴 패널입니다

이 페이지의 내용