Components - Tree Select

comment

  • 기본 구조: tree-select-layout 클래스를 사용하여 계층 구조의 체크박스 트리 구성. 왼쪽에 트리 선택 영역, 오른쪽에 선택된 항목 리스트 표시
  • 필수 속성:
    • data-id: 각 체크박스의 고유 식별자 (필수)
    • data-parent: 부모 항목의 data-id 값 (자식 항목에만 필요)
    • data-level: 계층 레벨 (1, 2, 3, 4)
    • id="treeContainer": 트리 패널 컨테이너 (필수)
    • id="selectedList": 선택된 항목 리스트 컨테이너 (필수)
  • 초기 체크 옵션: data-tree-initial-checked 속성에 초기로 체크할 항목의 data-id 값을 쉼표 또는 공백으로 구분하여 지정. 예: data-tree-initial-checked="item1, item2, item3"
  • 계층 구조: 최대 4단계까지 지원하며, 각 레벨은 data-level 속성으로 구분. 부모-자식 관계는 data-parent 속성으로 연결. 각 레벨은 .column 클래스를 가진 컬럼으로 구성
  • Indeterminate 상태: 일부 자식만 선택된 경우 부모 체크박스가 자동으로 indeterminate 상태로 표시. 부모 체크박스 클릭 시 모든 자식이 함께 체크/해제되며, 자식 체크박스 상태에 따라 부모의 checked/indeterminate 상태 자동 반영
  • 선택 순서 추적: 리프 노드(자식이 없는 항목)의 선택 순서가 추적되어 선택된 항목 리스트에 순서대로 표시. 중간 노드(부모 노드)는 선택된 항목 리스트에 표시되지 않음
  • 자동 높이 동기화: 각 컬럼의 행 높이가 자동으로 동기화되어 테이블 형태로 정렬. 부모 항목의 높이는 자식 항목들의 높이 합으로 자동 계산
  • 초기화 버튼: js-reset-button 클래스를 가진 버튼으로 모든 선택 초기화. 버튼 클릭 시 모든 체크박스 해제 및 선택된 항목 리스트 비움
  • 컨테이너 격리: 각 컨테이너 내부의 체크박스만 처리되며, 다른 컨테이너의 값은 포함되지 않음. 여러 tree-select를 동시에 사용 가능하며, 각각 독립적으로 동작
  • JavaScript 초기화: 페이지 로드 시 initAllTreeSelects() 함수가 자동으로 호출되어 모든 tree-select-layout 요소 초기화. 모달이 열릴 때도 자동 초기화. 수동으로 initTreeSelect(containerElement, options) 함수를 호출하여 초기화 가능. data-tree-select-initialized="true" 속성으로 중복 초기화 방지
  • 접근성: role="grid", role="row", role="columnheader", role="gridcell", role="list", aria-live="polite", aria-atomic="true" 등 ARIA 속성 설정
  • 경로 표시: 선택된 항목 리스트에 표시되는 경로는 부모를 역으로 추적하여 생성. 예: "1차 카테고리 > 2차 카테고리 > 3차 카테고리" 형식으로 표시
Tree Select - Case 1: 기본 구조

HTML 구조

<div class="tree-select-layout">
  <!-- 왼쪽: 트리 선택 영역 -->
  <div class="tree-select-layout__left" role="grid">
    <div class="tree-header" role="row">
      <div class="column-header" role="columnheader">1차 카테고리</div>
      <div class="column-header" role="columnheader">2차 카테고리</div>
      <div class="column-header" role="columnheader">3차 카테고리</div>
    </div>

    <div class="tree-panel" id="treeContainer">
      <!-- data-level="1" -->
      <div class="column">
        <ul class="column-list">
          <li role="gridcell">
            <label class="ui-checkbox">
              <input type="checkbox" class="ui-checkbox__input" data-id="category1" data-level="1" />
              <span class="ui-checkbox__box"></span>
              <span class="ui-checkbox__label">카테고리 1</span>
            </label>
          </li>
        </ul>
      </div>

      <!-- data-level="2" -->
      <div class="column">
        <ul class="column-list">
          <li role="gridcell">
            <label class="ui-checkbox">
              <input type="checkbox" class="ui-checkbox__input" data-id="sub1-1" data-parent="category1" data-level="2" />
              <span class="ui-checkbox__box"></span>
              <span class="ui-checkbox__label">하위 1-1</span>
            </label>
          </li>
        </ul>
      </div>

      <!-- data-level="3" -->
      <div class="column">
        <ul class="column-list">
          <li role="gridcell">
            <label class="ui-checkbox">
              <input type="checkbox" class="ui-checkbox__input" data-id="item1-1-1" data-parent="sub1-1" data-level="3" />
              <span class="ui-checkbox__box"></span>
              <span class="ui-checkbox__label">항목 1-1-1</span>
            </label>
          </li>
        </ul>
      </div>
    </div>
  </div>

  <!-- 가운데 화살표 -->
  <div class="tree-select-layout__arrow"></div>

  <!-- 오른쪽: 선택된 항목 리스트 -->
  <div class="tree-select-layout__right">
    <div class="selected-panel">
      <div class="panel-header">
        <span class="panel-title">선택된 항목</span>
        <button type="button" class="button-reset js-reset-button">초기화</button>
      </div>
      <ul class="selected-list" id="selectedList" role="list" aria-live="polite" aria-atomic="true"></ul>
    </div>
  </div>
</div>
Tree Select - Case 2: 초기 체크 옵션

HTML 구조

<!-- 초기 체크 옵션: data-tree-initial-checked 속성에 data-id 값 지정 -->
<div class="tree-select-layout" data-tree-initial-checked="item1-1-1, item1-2-1">
  <!-- ... 트리 구조 ... -->
</div>

<!-- 또는 공백으로 구분 -->
<div class="tree-select-layout" data-tree-initial-checked="item1-1-1 item1-2-1">
  <!-- ... 트리 구조 ... -->
</div>