Skip to Content

Tree

계층(Hierarchy) 구조의 데이터를 트리 형태로 출력하는 컴포넌트 (체크박스, 검색, Drag & Drop 지원)


개요

iCignal Tree는 Foundation Tree의 기본 기능에 체크박스, 검색, Drag & Drop, 전체 펼침/접기, 다국어 대응, 노출 조건 제어 등 확장 기능을 제공합니다.

주요 특징

  • 기본 트리 표시: 계층형 데이터를 트리 형태로 출력
  • 펼침/접힘 아이콘: 하위 노드 존재 시 표시, 미존재 시 숨김
  • 연결선(Lines): showLines로 노드 간 시각적 연결선 표시
  • 들여쓰기: depth별 indent 간격 조절
  • 포커스 상태: 선택된 노드 하이라이트
  • 체크박스: 노드별 체크박스 표시 및 indeterminate 상태
  • 전체 펼침: defaultExpandAll로 초기 로드 시 모든 노드 펼침
  • 레벨별 펼침: defaultExpandLevel로 지정 depth까지 펼침, defaultExpandedIds와 병합 가능
  • 검색: 노드명 기준 필터링, 경로 자동 펼침, 미포함 노드 숨김
  • Drag & Drop: 노드 이동, 위치 표시, 이동 제한 규칙
  • 다국어 대응: UI 텍스트 커스터마이징
  • 노출 조건 제어: disabled로 노드 비활성화
  • JSX Label: label에 ReactNode를 전달하여 커스텀 렌더링 (배지, 버튼 등)

사용 예시

기본 트리 표시

src
components
App.tsx
index.tsx
package.json
tsconfig.json

전체 펼침 (defaultExpandAll)

defaultExpandAll을 설정하면 초기 로드 시 모든 노드를 펼친 상태로 표시합니다.

src
components
Button.tsx
Input.tsx
App.tsx
index.tsx
public
favicon.ico
index.html
package.json

레벨별 펼침 (defaultExpandLevel)

defaultExpandLevel을 설정하면 지정한 depth까지만 펼친 상태로 표시합니다. 예를 들어 defaultExpandLevel={1}은 루트 레벨의 부모 노드만 펼치고, defaultExpandLevel={2}는 depth 0, 1의 부모 노드까지 펼칩니다.

defaultExpandLevel=1

src
components
pages
App.tsx
public
favicon.ico
index.html
package.json

defaultExpandLevel=2

src
components
Button.tsx
Input.tsx
pages
Home.tsx
About.tsx
App.tsx
public
favicon.ico
index.html
package.json

defaultExpandLevel + defaultExpandedIds 병합

defaultExpandLeveldefaultExpandedIds를 함께 사용하면 두 설정의 합집합(union)으로 병합됩니다. defaultExpandAll이 함께 설정된 경우 defaultExpandAll이 우선합니다.

defaultExpandLevel=1 + defaultExpandedIds=["components"]

src
components
Button.tsx
Input.tsx
pages
App.tsx
public
favicon.ico
index.html
package.json

체크박스 표시

Frontend
React
Vue
Angular
Backend
Node.js
Python

검색 기능

Frontend
React
Vue
Angular
Backend
Node.js
Python
Java
DevOps
Docker
Kubernetes

Drag & Drop

Frontend
React
Vue
Backend
Node.js
Python

다국어 대응

Frontend
React
Vue
Backend
Node.js

노출 조건 제어

프로젝트
활성 노드 1
비활성 노드
활성 노드 2
그룹 (비활성)

JSX Label

label에 문자열 대신 JSX를 전달할 수 있습니다. 검색 기능과 함께 사용할 경우 searchText를 지정하면 해당 텍스트로 검색됩니다.

개발팀
프론트엔드3명
Alice● online
Bob
Charlie
백엔드2명
Dave
Eve

JSX Label + Button

label에 버튼을 포함할 수 있습니다. 버튼 클릭 시 e.stopPropagation()으로 노드 선택 이벤트와 분리합니다.

프로젝트
components
button.tsx
input.tsx
utils
helpers.ts
constants.ts

API Reference

Props

PropTypeDefaultDescription
itemsTreeItem[]-트리 데이터 배열
titlestring-트리 제목
defaultExpandedIdsstring[][]초기 펼쳐진 노드 ID 목록
defaultExpandAllbooleanfalse초기 로드 시 모든 노드 펼침
defaultExpandLevelnumber-지정 depth까지 초기 펼침 (0부터 시작, defaultExpandedIds와 병합)
selectablebooleantrue노드 선택 가능 여부
multiplebooleanfalse다중 선택 모드
showCheckboxbooleanfalse체크박스 표시 여부
draggablebooleanfalseDrag & Drop 활성화
showLinesbooleantrue노드 간 연결선 표시 여부
showIconsbooleanfalse아이콘 표시 여부
showHeaderbooleantrue헤더(전체펼침/접기) 표시 여부
showSearchbooleantrue검색 필드 표시 여부
indentnumber20depth별 들여쓰기 간격 (px)
selectedIdsstring[]-선택된 노드 ID (제어 모드)
checkedIdsstring[]-체크된 노드 ID (제어 모드)
expandAllLabelstring"전체펼치기"전체 펼침 버튼 텍스트
collapseAllLabelstring"전체접기"전체 접기 버튼 텍스트
searchPlaceholderstring"Please input"검색 필드 플레이스홀더
classNamestring-추가 CSS 클래스

TreeItem

PropTypeDescription
idstring노드 고유 ID
labelReactNode노드 표시 콘텐츠 (문자열 또는 JSX)
searchTextstringlabel이 JSX일 때 검색에 사용할 텍스트
iconReactNode커스텀 아이콘
childrenTreeItem[]하위 노드 배열
disabledboolean비활성화 여부

TreeDropResult

PropTypeDescription
nodeIdstring이동한 노드 ID
targetNodeIdstring | null대상 노드 ID
targetIndexnumber대상 위치 인덱스

Events

EventTypeDescription
onSelectionChange(selectedIds: string[]) => void선택 변경 시 호출
onCheckedChange(checkedIds: string[]) => void체크 변경 시 호출
onItemsChange(items: TreeItem[]) => void노드 이동 후 호출
onDrop(result: TreeDropResult) => voidDrop 완료 시 호출

기본 사용법

import { Tree, type TreeItem } from "@vortex/ui-icignal" const items: TreeItem[] = [ { id: "root", label: "Root", children: [ { id: "child-1", label: "Child 1" }, { id: "child-2", label: "Child 2" }, ], }, ] <Tree items={items} selectable showCheckbox showSearch draggable />

접근성

권장 사항

  • ✅ 노드 클릭으로 선택/펼침 동작 수행
  • ✅ 포커스 상태가 시각적으로 구분됨
  • ✅ 체크박스를 통한 다중 선택 지원
  • ✅ 검색으로 원하는 노드에 빠르게 접근 가능
  • ✅ JSX label 내 버튼은 e.stopPropagation()으로 노드 이벤트와 분리
  • ❌ 깊은 중첩(5단계 이상)은 사용성 저하 주의

관련 컴포넌트

Last updated on