Tree

PRO

계층 구조를 펼쳐 탐색하고 항목을 선택·편집합니다.

Live preview
컴포넌트를 조작하면 여기에 결과가 표시됩니다.
코드 보기
HTML
<sy-tree
  expandable
  checkable
  clickable
  searchterm=""
  id="sample"
></sy-tree>

<script type="module">
  const component1 = document.querySelector("#sample");
  Object.assign(component1, {
    "nodes": [{
        "value": "project",
        "label": "프로젝트",
        "expanded": true,
        "appendable": true,
        "children": [{
            "value": "core",
            "label": "Design System",
            "editable": true,
            "removable": true
          },
          {
            "value": "charts",
            "label": "Charts",
            "editable": true,
            "removable": true
          },
          {
            "value": "grid",
            "label": "Grid",
            "disabled": true
          }
        ]
      },
      {
        "value": "docs",
        "label": "문서",
        "appendable": true,
        "children": [{
          "value": "guide",
          "label": "가이드"
        }]
      }
    ]
  });
</script>

사용 가이드

#

파일·조직처럼 계층 데이터를 탐색하고 관리할 때 사용합니다. 폼의 선택값으로 입력받으려면 Tree Select가 알맞습니다.

  1. 트리 구성

    nodes에 고유한 value, label, children을 제공합니다.

  2. 조작 범위 설정

    expandable·clickable·checkable을 켜고 각 노드에서 조작을 더 제한할 수 있습니다.

  3. 변경 사항 저장

    nodesChanged를 받아 앱에서 저장하세요. 예제의 변경은 로컬 화면에만 반영됩니다.

예제

#

계층 탐색

부모 항목을 펼쳐 자식 항목을 확인합니다.

코드 보기
HTML
<sy-tree
  expandable
  clickable
  id="sample"
></sy-tree>

<script type="module">
  const component1 = document.querySelector("#sample");
  Object.assign(component1, {
    "nodes": [{
        "value": "project",
        "label": "프로젝트",
        "expanded": true,
        "appendable": true,
        "children": [{
            "value": "core",
            "label": "Design System",
            "editable": true,
            "removable": true
          },
          {
            "value": "charts",
            "label": "Charts",
            "editable": true,
            "removable": true
          },
          {
            "value": "grid",
            "label": "Grid",
            "disabled": true
          }
        ]
      },
      {
        "value": "docs",
        "label": "문서",
        "appendable": true,
        "children": [{
          "value": "guide",
          "label": "가이드"
        }]
      }
    ]
  });
</script>

계층 체크

부모와 자식의 체크 상태가 연동됩니다.

코드 보기
HTML
<sy-tree
  expandable
  checkable
  id="sample"
></sy-tree>
<div class="demo-actions"
  style="display:flex;flex-wrap:wrap;gap:8px;margin-top:16px"
>
  <sy-button id="action-0" size="small">Design System 체크</sy-button>
  <sy-button id="action-1" 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, {
    "nodes": [{
        "value": "project",
        "label": "프로젝트",
        "expanded": true,
        "appendable": true,
        "children": [{
            "value": "core",
            "label": "Design System",
            "editable": true,
            "removable": true
          },
          {
            "value": "charts",
            "label": "Charts",
            "editable": true,
            "removable": true
          },
          {
            "value": "grid",
            "label": "Grid",
            "disabled": true
          }
        ]
      },
      {
        "value": "docs",
        "label": "문서",
        "appendable": true,
        "children": [{
          "value": "guide",
          "label": "가이드"
        }]
      }
    ]
  });
  const actionTarget0 = document.querySelector("#sample");
  document.querySelector('#action-0').addEventListener('click', async () => {
    const result = await actionTarget0.setCheckState("core", true);
    document.querySelector('#demo-result').textContent = describeResult(result);
  });
  const actionTarget1 = document.querySelector("#sample");
  document.querySelector('#action-1').addEventListener('click', async () => {
    const result = await actionTarget1.clearAllSelectedItem();
    document.querySelector('#demo-result').textContent = describeResult(result);
  });
</script>

추가·수정·삭제

노드에 허용한 동작만 표시합니다. 새로고침하면 원래 예제로 돌아옵니다.

코드 보기
HTML
<sy-tree
  expandable
  editable
  expandall
  id="sample"
></sy-tree>

<script type="module">
  const component1 = document.querySelector("#sample");
  Object.assign(component1, {
    "nodes": [{
        "value": "project",
        "label": "프로젝트",
        "expanded": true,
        "appendable": true,
        "children": [{
            "value": "core",
            "label": "Design System",
            "editable": true,
            "removable": true
          },
          {
            "value": "charts",
            "label": "Charts",
            "editable": true,
            "removable": true
          },
          {
            "value": "grid",
            "label": "Grid",
            "disabled": true
          }
        ]
      },
      {
        "value": "docs",
        "label": "문서",
        "appendable": true,
        "children": [{
          "value": "guide",
          "label": "가이드"
        }]
      }
    ]
  });
</script>

노드 이동

드래그로 순서를 바꾸며 변경된 nodes를 이벤트로 확인합니다.

코드 보기
HTML
<sy-tree
  expandable
  draggable="true"
  expandall
  line
  id="sample"
></sy-tree>

<script type="module">
  const component1 = document.querySelector("#sample");
  Object.assign(component1, {
    "nodes": [{
        "value": "project",
        "label": "프로젝트",
        "expanded": true,
        "appendable": true,
        "children": [{
            "value": "core",
            "label": "Design System",
            "editable": true,
            "removable": true
          },
          {
            "value": "charts",
            "label": "Charts",
            "editable": true,
            "removable": true
          },
          {
            "value": "grid",
            "label": "Grid",
            "disabled": true
          }
        ]
      },
      {
        "value": "docs",
        "label": "문서",
        "appendable": true,
        "children": [{
          "value": "guide",
          "label": "가이드"
        }]
      }
    ]
  });
</script>

앱에서 추가와 제거

고유 키를 지정해 노드를 추가하거나 제거합니다.

코드 보기
HTML
<sy-tree expandable id="sample"></sy-tree>
<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>
</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, {
    "nodes": [{
        "value": "project",
        "label": "프로젝트",
        "expanded": true,
        "appendable": true,
        "children": [{
            "value": "core",
            "label": "Design System",
            "editable": true,
            "removable": true
          },
          {
            "value": "charts",
            "label": "Charts",
            "editable": true,
            "removable": true
          },
          {
            "value": "grid",
            "label": "Grid",
            "disabled": true
          }
        ]
      },
      {
        "value": "docs",
        "label": "문서",
        "appendable": true,
        "children": [{
          "value": "guide",
          "label": "가이드"
        }]
      }
    ]
  });
  const actionTarget0 = document.querySelector("#sample");
  document.querySelector('#action-0').addEventListener('click', async () => {
    const result = await actionTarget0.manualAddChildNode("docs", "설치 안내", "installation");
    document.querySelector('#demo-result').textContent = describeResult(result);
  });
  const actionTarget1 = document.querySelector("#sample");
  document.querySelector('#action-1').addEventListener('click', async () => {
    const result = await actionTarget1.manualRemoveNode("installation");
    document.querySelector('#demo-result').textContent = describeResult(result);
  });
</script>

이벤트와 전달 값

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

코드 보기
HTML
<sy-tree
  expandable
  checkable
  clickable
  searchterm=""
  id="sample"
></sy-tree>
<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;
  }) ?? '완료';
  const component1 = document.querySelector("#sample");
  Object.assign(component1, {
    "nodes": [{
        "value": "project",
        "label": "프로젝트",
        "expanded": true,
        "appendable": true,
        "children": [{
            "value": "core",
            "label": "Design System",
            "editable": true,
            "removable": true
          },
          {
            "value": "charts",
            "label": "Charts",
            "editable": true,
            "removable": true
          },
          {
            "value": "grid",
            "label": "Grid",
            "disabled": true
          }
        ]
      },
      {
        "value": "docs",
        "label": "문서",
        "appendable": true,
        "children": [{
          "value": "guide",
          "label": "가이드"
        }]
      }
    ]
  });
  for (const name of ["nodesChanged", "itemChecked", "itemSelected", "expandChanged",
      "checkChanged", "itemAdded", "itemRemoved", "itemEdited", "itemUpdating",
      "itemUpdatingReset", "itemDrop", "draggingEvent"
    ]) {
    document.addEventListener(name, event => {
      document.querySelector('#demo-events').textContent =
        `${event.target.localName} · ${name}: ${describeResult(event.detail)}`;
    });
  }
</script>

선택 노드 지정

selectedValue에 노드의 value를 지정하면 해당 항목의 선택 상태를 표현합니다. 항목을 눌러 선택 이벤트도 확인하세요.

코드 보기
HTML
<sy-tree
  expandable
  checkable
  clickable
  searchterm=""
  selectedvalue="core"
  id="sample"
></sy-tree>

<script type="module">
  const component1 = document.querySelector("#sample");
  Object.assign(component1, {
    "nodes": [{
        "value": "project",
        "label": "프로젝트",
        "expanded": true,
        "appendable": true,
        "children": [{
            "value": "core",
            "label": "Design System",
            "editable": true,
            "removable": true
          },
          {
            "value": "charts",
            "label": "Charts",
            "editable": true,
            "removable": true
          },
          {
            "value": "grid",
            "label": "Grid",
            "disabled": true
          }
        ]
      },
      {
        "value": "docs",
        "label": "문서",
        "appendable": true,
        "children": [{
          "value": "guide",
          "label": "가이드"
        }]
      }
    ]
  });
  const component2 = document.querySelector("#sample");
  Object.assign(component2, {
    "selectedValue": "core",
    "clickable": true
  });
</script>

앱에서 추가·삭제 승인

manualAdd와 manualRemove를 켜면 컴포넌트가 요청 이벤트를 보내고 앱의 처리를 기다립니다. 아래 결과에서 요청을 확인한 뒤 실제 앱에서는 데이터를 저장하고 트리 데이터도 갱신하세요.

코드 보기
HTML
<sy-tree
  expandable
  checkable
  clickable
  editable
  searchterm=""
  manualadd
  manualremove
  nodewidth="260"
  id="sample"
></sy-tree>

<script type="module">
  const component1 = document.querySelector("#sample");
  Object.assign(component1, {
    "nodes": [{
        "value": "project",
        "label": "프로젝트",
        "expanded": true,
        "appendable": true,
        "children": [{
            "value": "core",
            "label": "Design System",
            "editable": true,
            "removable": true
          },
          {
            "value": "charts",
            "label": "Charts",
            "editable": true,
            "removable": true
          },
          {
            "value": "grid",
            "label": "Grid",
            "disabled": true
          }
        ]
      },
      {
        "value": "docs",
        "label": "문서",
        "appendable": true,
        "children": [{
          "value": "guide",
          "label": "가이드"
        }]
      }
    ]
  });
  const component2 = document.querySelector("#sample");
  Object.assign(component2, {
    "editable": true,
    "manualAdd": true,
    "manualRemove": true,
    "nodeWidth": 260
  });
</script>

계층 구조 탐색

체크박스 없이 연결선을 표시하고 계층 구조를 펼쳐 보여줍니다.

코드 보기
HTML
<sy-tree
  expandable
  clickable
  expandall
  line
  searchterm=""
  id="sample"
></sy-tree>

<script type="module">
  const component1 = document.querySelector("#sample");
  Object.assign(component1, {
    "nodes": [{
        "value": "project",
        "label": "프로젝트",
        "expanded": true,
        "appendable": true,
        "children": [{
            "value": "core",
            "label": "Design System",
            "editable": true,
            "removable": true
          },
          {
            "value": "charts",
            "label": "Charts",
            "editable": true,
            "removable": true
          },
          {
            "value": "grid",
            "label": "Grid",
            "disabled": true
          }
        ]
      },
      {
        "value": "docs",
        "label": "문서",
        "appendable": true,
        "children": [{
          "value": "guide",
          "label": "가이드"
        }]
      }
    ]
  });
  const component2 = document.querySelector("#sample");
  Object.assign(component2, {
    "expandAll": true,
    "line": true,
    "checkable": false,
    "editable": false
  });
</script>

API reference

#

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

<sy-tree>

Properties

Attribute / PropertyTypeDefaultDescription
TreeNode[][]label·value·children으로 구성한 트리 노드 배열입니다.

객체·배열 값은 JavaScript 프로퍼티로 전달합니다.

booleanfalse체크박스로 복수 항목을 선택합니다.
booleanfalse사용자 선택을 허용하고 selected 이벤트를 전달합니다.
booleanfalse노드를 드래그해 이동할 수 있게 합니다.
booleanfalse노드 이름 편집을 허용합니다.
booleanfalse트리 가지의 펼침 제어를 허용합니다.
booleanfalse모든 트리 가지를 처음부터 펼칩니다.
booleanfalse추가 요청 후 앱에서 manualAddChildNode를 호출합니다.
booleanfalse삭제 요청 후 앱에서 manualRemoveNode를 호출합니다.
booleanfalse부모·자식 사이 연결선을 표시합니다.
number | nullnull트리 노드의 표시 너비입니다.
string''선택한 노드의 고유 키입니다.
string''후보 필터링과 강조에 사용할 검색어입니다.
booleanfalseTree Select와의 내부 결합에 사용합니다. 일반 Select에서는 기본값을 유지하세요.

Events

EventDetailDescription
CustomEvent<TreeNodesChangedDetail>이벤트의 detail에서 결과를 확인하세요.
CustomEvent<TreeItemCheckedDetail>이벤트의 detail에서 결과를 확인하세요.
CustomEvent<TreeItemSelectedDetail>이벤트의 detail에서 결과를 확인하세요.

Methods

MethodReturnsDescription
Promise<void>지정한 트리 노드의 체크 상태를 변경합니다.
Promise<void>트리의 체크 선택을 모두 해제합니다.
Promise<void>부모 노드 아래에 새 자식을 추가합니다.
Promise<void>고유 키로 트리 노드를 제거합니다.
Promise<TreeNode | null>전달한 노드 배열에서 고유 키에 해당하는 노드를 찾습니다.

<sy-tree-item>

Properties

Attribute / PropertyTypeDefaultDescription
booleanfalse자식 추가 동작을 표시합니다.
booleanfalse체크박스로 복수 항목을 선택합니다.
booleanfalse선택 또는 켜짐 상태입니다.
booleanfalse사용자 선택을 허용하고 selected 이벤트를 전달합니다.
booleanfalse사용자 조작과 키보드 포커스를 차단합니다.
booleanfalse해당 노드의 드래그 이동을 허용합니다.
booleanfalse드래그 중인 상태입니다. 부모가 관리합니다.
'none' | 'valid' | 'invalid''none'드롭 가능 여부를 표시합니다. 부모가 관리합니다.
booleanfalse이름 수정을 허용합니다.
booleanfalse트리 가지의 펼침 제어를 허용합니다.
booleanfalse자식을 펼친 상태입니다.
booleanfalse노드 이동을 제한합니다.
booleanfalse자식 노드가 있는지 표시합니다.
string'New item'새 노드 이름 입력의 안내 문구입니다.
string''아이콘 표시 또는 아이콘 콘텐츠를 지정합니다. 컴포넌트별 형식을 확인하세요.
booleanfalse일부 항목만 선택된 중간 상태입니다.
booleanfalse다른 노드 아래에 있는 상태입니다. 부모가 관리합니다.
booleanfalse현재 이름을 수정 중인지 표시합니다.
string''항목을 설명하는 레이블입니다.
number0계층 깊이입니다. 부모가 관리합니다.
booleanfalse노드 삭제 동작을 허용합니다.
any[][]자식 노드 배열입니다. 부모가 전달합니다.

객체·배열 값은 JavaScript 프로퍼티로 전달합니다.

string''노드 옆 태그 문구입니다.
"gray" | "purple" | "blue" | "green" | "cyan" | "yellow" | "orange" | "red" | undefinedundefined노드 옆 태그 색상입니다.
string''현재 값 또는 항목의 식별 값입니다.
string''후보 필터링과 강조에 사용할 검색어입니다.
string''현재 선택 노드의 고유 키입니다.
number | nullnull트리 노드의 표시 너비입니다.
booleanfalse부모·자식 사이 연결선을 표시합니다.

Events

EventDetailDescription
CustomEvent<{ value: string; label: string; expanded: boolean }>이벤트의 detail에서 결과를 확인하세요.
CustomEvent<{ value: string; label: string; checked: boolean }>이벤트의 detail에서 결과를 확인하세요.
CustomEvent<{ parentValue: string; childLabel: string; childValue: string; childLevel: number }>이벤트의 detail에서 결과를 확인하세요.
CustomEvent<{ value: string; label: string }>이벤트의 detail에서 결과를 확인하세요.
CustomEvent<{ value: string; label: string }>이벤트의 detail에서 결과를 확인하세요.
CustomEvent<any>이벤트의 detail에서 결과를 확인하세요.
CustomEvent<any>이벤트의 detail에서 결과를 확인하세요.
CustomEvent<{ targetKey: string; draggedKey: string; dropPosition: string; targetLevel: number }>이벤트의 detail에서 결과를 확인하세요.
CustomEvent<{ value: string; label: string; checked: boolean }>이벤트의 detail에서 결과를 확인하세요.
CustomEvent<string>이벤트의 detail에서 결과를 확인하세요.

Methods

MethodReturnsDescription
Promise<void>Layout only, and called fire-and-forget by the parent tree, so it never rejects: a no-op before the item started, and it still runs while frozen.