Menu

항목, 그룹과 하위 메뉴로 관련된 작업을 구성합니다.

Live preview
컴포넌트를 조작하면 여기에 결과가 표시됩니다.
코드 보기
HTML
<div style="display:inline-flex;align-self:center;margin:70px 0">
  <sy-button>작업 메뉴<sy-menu
      trigger="click"
      position="bottomLeft"
      direction="right"
      id="sample"
    >
      <sy-menu-item value="edit">편집</sy-menu-item>
      <sy-menu-item value="copy">복제</sy-menu-item>
      <sy-menu-item value="archive" disabled>보관</sy-menu-item>
    </sy-menu>
  </sy-button>
</div>

사용 가이드

#

특정 대상에 대한 명령이나 문맥 메뉴를 제공합니다. 앱 전체 탐색에는 Navigation을 사용하세요.

명령 묶음

menu-group으로 관련 항목을 구분하고 각 항목에 value를 지정합니다.

하위 명령

menu-sub로 단계가 필요한 하위 메뉴를 구성합니다. checkable로 선택 상태를 표시할 수 있습니다.

예제

#

작업 목록

항목을 선택하면 메뉴가 닫히고 선택 결과를 전달합니다.

코드 보기
HTML
<div style="display:inline-flex;align-self:center;margin:70px 0">
  <sy-button>작업 메뉴<sy-menu trigger="click" id="sample">
      <sy-menu-item value="edit">편집</sy-menu-item>
      <sy-menu-item value="copy">복제</sy-menu-item>
      <sy-menu-item value="archive" disabled>보관</sy-menu-item>
    </sy-menu>
  </sy-button>
</div>

메뉴 그룹

작업 성격에 따라 제목으로 구분합니다.

코드 보기
HTML
<div style="display:inline-flex;align-self:center;margin:70px 0">
  <sy-button>작업 메뉴<sy-menu trigger="click" id="sample">
      <sy-menu-group title="프로젝트">
        <sy-menu-item value="edit">편집</sy-menu-item>
        <sy-menu-item value="copy">복제</sy-menu-item>
        <sy-menu-item value="archive" disabled>보관</sy-menu-item>
      </sy-menu-group>
      <sy-menu-group title="도움말">
        <sy-menu-item value="guide">사용 가이드</sy-menu-item>
      </sy-menu-group>
    </sy-menu>
  </sy-button>
</div>

하위 메뉴

단계가 필요한 작업을 하위 목록으로 묶습니다.

코드 보기
HTML
<div style="display:inline-flex;align-self:center;margin:70px 0">
  <sy-button>작업 메뉴<sy-menu trigger="click" id="sample">
      <sy-menu-item value="edit">편집</sy-menu-item>
      <sy-menu-item value="copy">복제</sy-menu-item>
      <sy-menu-item value="archive" disabled>보관</sy-menu-item>
      <sy-menu-sub title="내보내기" trigger="click">
        <sy-menu-item value="csv">CSV</sy-menu-item>
        <sy-menu-item value="json">JSON</sy-menu-item>
      </sy-menu-sub>
    </sy-menu>
  </sy-button>
</div>

체크 목록

여러 옵션의 체크 상태를 유지합니다.

코드 보기
HTML
<div style="display:inline-flex;align-self:center;margin:70px 0">
  <sy-button>작업 메뉴<sy-menu
      trigger="click"
      checkable
      id="sample"
    >
      <sy-menu-item value="edit">편집</sy-menu-item>
      <sy-menu-item value="copy">복제</sy-menu-item>
      <sy-menu-item value="archive" disabled>보관</sy-menu-item>
    </sy-menu>
  </sy-button>
</div>

컨텍스트 메뉴

트리거를 오른쪽 클릭해 메뉴를 엽니다.

코드 보기
HTML
<div style="display:inline-flex;align-self:center;margin:70px 0">
  <sy-button>작업 메뉴<sy-menu trigger="contextmenu" id="sample">
      <sy-menu-item value="edit">편집</sy-menu-item>
      <sy-menu-item value="copy">복제</sy-menu-item>
      <sy-menu-item value="archive" disabled>보관</sy-menu-item>
    </sy-menu>
  </sy-button>
</div>

앱에서 메뉴 제어

열기·닫기와 선택 해제를 호출할 수 있습니다.

코드 보기
HTML
<div style="display:inline-flex;align-self:center;margin:70px 0">
  <sy-button>작업 메뉴<sy-menu trigger="click" id="sample">
      <sy-menu-item value="edit">편집</sy-menu-item>
      <sy-menu-item value="copy">복제</sy-menu-item>
      <sy-menu-item value="archive" disabled>보관</sy-menu-item>
    </sy-menu>
  </sy-button>
</div>
<div class="demo-actions"
  style="display:flex;flex-wrap:wrap;gap:8px;margin-top:16px"
>
  <sy-button id="action-0" size="small">열기</sy-button>
  <sy-button id="action-1" size="small">닫기</sy-button>
  <sy-button id="action-2" size="small">선택 해제</sy-button>
</div>
<output id="demo-result" aria-live="polite"></output>

<script type="module">
  const describeResult = value => JSON.stringify(value, (_key, item) => {
    if (item instanceof File) return {
      name: item.name,
      size: item.size,
      type: item.type
    };
    if (item instanceof Element) return `<${item.localName}>`;
    return item;
  }) ?? '완료';
  const actionTarget0 = document.querySelector("#sample");
  document.querySelector('#action-0').addEventListener('click', async () => {
    const result = await actionTarget0.setOpen();
    document.querySelector('#demo-result').textContent = describeResult(result);
  });
  const actionTarget1 = document.querySelector("#sample");
  document.querySelector('#action-1').addEventListener('click', async () => {
    const result = await actionTarget1.setClose();
    document.querySelector('#demo-result').textContent = describeResult(result);
  });
  const actionTarget2 = document.querySelector("#sample");
  document.querySelector('#action-2').addEventListener('click', async () => {
    const result = await actionTarget2.clearSelectedItem();
    document.querySelector('#demo-result').textContent = describeResult(result);
  });
</script>

이벤트와 전달 값

컴포넌트를 조작하고 최근 이벤트의 이름과 detail 값을 확인하세요. 코드에는 이 컴포넌트와 하위 구성 요소가 보내는 이벤트의 구독 방법이 모두 포함되어 있습니다.

코드 보기
HTML
<div style="display:inline-flex;align-self:center;margin:70px 0">
  <sy-button>작업 메뉴<sy-menu
      trigger="click"
      position="bottomLeft"
      direction="right"
      id="sample"
    >
      <sy-menu-item value="edit">편집</sy-menu-item>
      <sy-menu-item value="copy">복제</sy-menu-item>
      <sy-menu-item value="archive" disabled>보관</sy-menu-item>
    </sy-menu>
  </sy-button>
</div>
<output id="demo-events" aria-live="polite">컴포넌트를 조작하면 최근 이벤트와 전달 값이 표시됩니다.
</output>

<script type="module">
  const describeResult = value => JSON.stringify(value, (_key, item) => {
    if (item instanceof File) return {
      name: item.name,
      size: item.size,
      type: item.type
    };
    if (item instanceof Element) return `<${item.localName}>`;
    return item;
  }) ?? '완료';
  for (const name of ["opened", "itemSelected", "itemChecked"]) {
    document.addEventListener(name, event => {
      document.querySelector('#demo-events').textContent =
        `${event.target.localName} · ${name}: ${describeResult(event.detail)}`;
    });
  }
</script>

열림 전환과 메뉴 상태

toggle은 열림 상태를 전환하고 close는 닫습니다. 지연 닫기와 트리거 너비 조회도 제공됩니다. 항목 선택 활성화 후 선택 결과를 확인하세요.

코드 보기
HTML
<div style="display:inline-flex;align-self:center;margin:70px 0">
  <sy-button>작업 메뉴<sy-menu
      trigger="click"
      position="bottomLeft"
      direction="right"
      id="sample"
    >
      <sy-menu-item value="edit">편집</sy-menu-item>
      <sy-menu-item value="copy">복제</sy-menu-item>
      <sy-menu-item value="archive" disabled>보관</sy-menu-item>
    </sy-menu>
  </sy-button>
</div>
<div class="demo-actions"
  style="display:flex;flex-wrap:wrap;gap:8px;margin-top:16px"
>
  <sy-button id="action-0" size="small">열기 전환</sy-button>
  <sy-button id="action-1" size="small">닫기</sy-button>
  <sy-button id="action-2" size="small">지연 닫기</sy-button>
  <sy-button id="action-3" size="small">트리거 너비</sy-button>
  <sy-button id="action-4" size="small">항목 선택 활성화</sy-button>
</div>
<output id="demo-result" aria-live="polite"></output>

<script type="module">
  const describeResult = value => JSON.stringify(value, (_key, item) => {
    if (item instanceof File) return {
      name: item.name,
      size: item.size,
      type: item.type
    };
    if (item instanceof Element) return `<${item.localName}>`;
    return item;
  }) ?? '완료';
  const component1 = document.querySelector("#sample");
  Object.assign(component1, {});
  const actionTarget0 = document.querySelector("#sample");
  document.querySelector('#action-0').addEventListener('click', async () => {
    const result = await actionTarget0.toggle();
    document.querySelector('#demo-result').textContent = describeResult(result);
  });
  const actionTarget1 = document.querySelector("#sample");
  document.querySelector('#action-1').addEventListener('click', async () => {
    const result = await actionTarget1.close();
    document.querySelector('#demo-result').textContent = describeResult(result);
  });
  const actionTarget2 = document.querySelector("#sample");
  document.querySelector('#action-2').addEventListener('click', async () => {
    const result = await actionTarget2.delayedMenuClose();
    document.querySelector('#demo-result').textContent = describeResult(result);
  });
  const actionTarget3 = document.querySelector("#sample");
  document.querySelector('#action-3').addEventListener('click', async () => {
    const result = await actionTarget3.getTriggerWidth();
    document.querySelector('#demo-result').textContent = describeResult(result);
  });
  const actionTarget4 = document.querySelector("#sample");
  document.querySelector('#action-4').addEventListener('click', async () => {
    const result = await actionTarget4.setSelectableAllItems();
    document.querySelector('#demo-result').textContent = describeResult(result);
  });
</script>

API reference

#

이름에 마우스를 올리거나 키보드로 선택하면 적용 코드를 확인할 수 있습니다. 터치 화면에서는 이름을 누르세요.

<sy-menu>

Properties

Attribute / PropertyTypeDefaultDescription
booleanfalse작업 메뉴를 표시합니다.
booleanfalse체크박스로 복수 항목을 선택합니다.
'topLeft' | 'topRight' | 'bottomLeft' | 'bottomRight''bottomLeft'메뉴를 트리거에 맞추는 모서리입니다.
'click' | 'hover' | 'contextmenu''hover'목록 또는 팝업을 여는 사용자 동작입니다.
'left' | 'right''right'하위 메뉴를 펼치는 방향입니다.
booleanfalse사용자 조작과 키보드 포커스를 차단합니다.

Events

EventDetailDescription
CustomEvent<boolean>목록을 열면 발생합니다.
CustomEvent<any>이벤트의 detail에서 결과를 확인하세요.
CustomEvent<any>이벤트의 detail에서 결과를 확인하세요.

Methods

MethodReturnsDescription
Promise<void>하위 메뉴를 펼칩니다.
Promise<void>항목을 닫습니다.
Promise<void>현재 펼침 상태를 전환합니다.
Promise<void>열린 패널을 닫습니다.
Promise<number | null>Returns the trigger element's measured width, or `null` when the menu has no DOM trigger (e.g. inside a dropdown wrapper) or the trigger is not currently rendered. Used by `<sy-menu-item loading>` as the fallback width when there are no non-loading siblings to inherit sizing from.
Promise<void>지연 후 메뉴를 닫습니다.
Promise<void>메뉴의 모든 항목을 선택 가능한 상태로 설정합니다.
Promise<void>메뉴 항목의 선택 표시를 해제합니다.

Slots

SlotDescription
컴포넌트의 본문 또는 자식 항목입니다.

<sy-menu-item>

Properties

Attribute / PropertyTypeDefaultDescription
booleanfalse사용자 조작과 키보드 포커스를 차단합니다.
string''현재 값 또는 항목의 식별 값입니다.
booleanfalse선택 또는 체크된 상태입니다.
booleanfalse항목 선택 표시를 허용합니다.
booleanfalse항목 앞에 체크박스를 표시합니다.
booleanfalse처리 중임을 표시합니다.

Events

EventDetailDescription
CustomEvent<{ value: string; label: string }>이벤트의 detail에서 결과를 확인하세요.
CustomEvent<{ value: string; label: string; checked: boolean }>이벤트의 detail에서 결과를 확인하세요.

Slots

SlotDescription
컴포넌트의 본문 또는 자식 항목입니다.

<sy-menu-sub>

Properties

Attribute / PropertyTypeDefaultDescription
booleanfalse사용자 조작과 키보드 포커스를 차단합니다.
booleanfalse하위 메뉴를 표시합니다.
string''하위 메뉴를 여는 제목입니다.
'click' | 'hover''hover'목록 또는 팝업을 여는 사용자 동작입니다.

Slots

SlotDescription
컴포넌트의 본문 또는 자식 항목입니다.

<sy-menu-group>

Properties

Attribute / PropertyTypeDefaultDescription
string''작업 묶음의 제목입니다.

Slots

SlotDescription
컴포넌트의 본문 또는 자식 항목입니다.