Tree View
포커스와 선택을 나눠 유지하면서 펼칠 수 있는 계층을 탐색합니다.
용법
계층 펼치기
각 폴더의 펼침 상태를 따로 유지하면서 실제 프로젝트 계층을 탐색합니다.
<!-- Tree View / Expanded -->
<script setup lang="ts">
import { ref } from 'vue'
import { TreeViewDisclosure, TreeViewGroup, TreeViewItem, TreeViewRoot } from '@sectile/vue/tree-view'
const nodes = [
{ id: 'atlas', parentID: null },
{ id: 'apps', parentID: 'atlas' },
{ id: 'dashboard', parentID: 'apps' },
{ id: 'overview', parentID: 'dashboard' },
{ id: 'settings', parentID: 'dashboard' },
{ id: 'packages', parentID: 'atlas' },
{ id: 'tokens', parentID: 'packages' },
]
const expandedValues = ref(['atlas', 'apps', 'dashboard', 'packages'])
</script>
<template>
<TreeViewRoot
:nodes="nodes"
v-model:expanded-values="expandedValues"
:default-value="['settings']"
label="Atlas project files"
>
<TreeViewItem value="atlas"><TreeViewDisclosure for="atlas" as="button">Toggle</TreeViewDisclosure>Atlas workspace</TreeViewItem>
<TreeViewGroup for="atlas">
<TreeViewItem value="apps"><TreeViewDisclosure for="apps" as="button">Toggle</TreeViewDisclosure>Applications</TreeViewItem>
<TreeViewGroup for="apps">
<TreeViewItem value="dashboard"><TreeViewDisclosure for="dashboard" as="button">Toggle</TreeViewDisclosure>Dashboard</TreeViewItem>
<TreeViewGroup for="dashboard">
<TreeViewItem value="overview">Overview.vue</TreeViewItem>
<TreeViewItem value="settings">Settings.vue</TreeViewItem>
</TreeViewGroup>
</TreeViewGroup>
<TreeViewItem value="packages"><TreeViewDisclosure for="packages" as="button">Toggle</TreeViewDisclosure>Packages</TreeViewItem>
<TreeViewGroup for="packages"><TreeViewItem value="tokens">tokens.ts</TreeViewItem></TreeViewGroup>
</TreeViewGroup>
</TreeViewRoot>
</template>접힌 상태
원본 계층은 유지한 채 하위 항목을 숨겼다가 다시 펼칩니다.
<!-- Tree View / Collapsed -->
<script setup lang="ts">
import { ref } from 'vue'
import { TreeViewDisclosure, TreeViewGroup, TreeViewItem, TreeViewRoot } from '@sectile/vue/tree-view'
const nodes = [
{ id: 'atlas', parentID: null },
{ id: 'apps', parentID: 'atlas' },
{ id: 'dashboard', parentID: 'apps' },
{ id: 'overview', parentID: 'dashboard' },
{ id: 'settings', parentID: 'dashboard' },
{ id: 'packages', parentID: 'atlas' },
{ id: 'tokens', parentID: 'packages' },
]
const expandedValues = ref(['atlas', 'apps', 'dashboard', 'packages'])
</script>
<template>
<TreeViewRoot
:nodes="nodes"
v-model:expanded-values="expandedValues"
:default-value="['settings']"
label="Atlas project files"
>
<TreeViewItem value="atlas"><TreeViewDisclosure for="atlas" as="button">Toggle</TreeViewDisclosure>Atlas workspace</TreeViewItem>
<TreeViewGroup for="atlas">
<TreeViewItem value="apps"><TreeViewDisclosure for="apps" as="button">Toggle</TreeViewDisclosure>Applications</TreeViewItem>
<TreeViewGroup for="apps">
<TreeViewItem value="dashboard"><TreeViewDisclosure for="dashboard" as="button">Toggle</TreeViewDisclosure>Dashboard</TreeViewItem>
<TreeViewGroup for="dashboard">
<TreeViewItem value="overview">Overview.vue</TreeViewItem>
<TreeViewItem value="settings">Settings.vue</TreeViewItem>
</TreeViewGroup>
</TreeViewGroup>
<TreeViewItem value="packages"><TreeViewDisclosure for="packages" as="button">Toggle</TreeViewDisclosure>Packages</TreeViewItem>
<TreeViewGroup for="packages"><TreeViewItem value="tokens">tokens.ts</TreeViewItem></TreeViewGroup>
</TreeViewGroup>
</TreeViewRoot>
</template>여러 항목 선택
폴더 펼침 상태를 유지하면서 검토할 파일 여러 개를 선택합니다.
<!-- Tree View / Multiple -->
<script setup lang="ts">
import { ref } from 'vue'
import { TreeViewDisclosure, TreeViewGroup, TreeViewItem, TreeViewRoot } from '@sectile/vue/tree-view'
const nodes = [
{ id: 'atlas', parentID: null },
{ id: 'apps', parentID: 'atlas' },
{ id: 'dashboard', parentID: 'apps' },
{ id: 'overview', parentID: 'dashboard' },
{ id: 'settings', parentID: 'dashboard' },
{ id: 'packages', parentID: 'atlas' },
{ id: 'tokens', parentID: 'packages' },
]
const expandedValues = ref(['atlas', 'apps', 'dashboard', 'packages'])
</script>
<template>
<TreeViewRoot
:nodes="nodes"
selection-mode="multiple"
v-model:expanded-values="expandedValues"
:default-value="['overview', 'settings', 'tokens']"
label="Files selected for review"
v-slot="{ value }"
>
<output>{{ value.length }} files selected</output>
<TreeViewItem value="atlas"><TreeViewDisclosure for="atlas" as="button">Toggle</TreeViewDisclosure>Atlas workspace</TreeViewItem>
<TreeViewGroup for="atlas">
<TreeViewItem value="apps"><TreeViewDisclosure for="apps" as="button">Toggle</TreeViewDisclosure>Applications</TreeViewItem>
<TreeViewGroup for="apps">
<TreeViewItem value="dashboard"><TreeViewDisclosure for="dashboard" as="button">Toggle</TreeViewDisclosure>Dashboard</TreeViewItem>
<TreeViewGroup for="dashboard">
<TreeViewItem value="overview">Overview.vue</TreeViewItem>
<TreeViewItem value="settings">Settings.vue</TreeViewItem>
</TreeViewGroup>
</TreeViewGroup>
<TreeViewItem value="packages"><TreeViewDisclosure for="packages" as="button">Toggle</TreeViewDisclosure>Packages</TreeViewItem>
<TreeViewGroup for="packages"><TreeViewItem value="tokens">tokens.ts</TreeViewItem></TreeViewGroup>
</TreeViewGroup>
</TreeViewRoot>
</template>비활성 항목
비활성화된 항목을 계층에 표시하되 포커스와 선택 대상에서는 제외합니다.
<!-- Tree View / Unavailable -->
<script setup lang="ts">
import { ref } from 'vue'
import { TreeViewDisclosure, TreeViewGroup, TreeViewItem, TreeViewRoot } from '@sectile/vue/tree-view'
const nodes = [
{ id: 'atlas', parentID: null },
{ id: 'apps', parentID: 'atlas' },
{ id: 'dashboard', parentID: 'apps' },
{ id: 'overview', parentID: 'dashboard' },
{ id: 'settings', parentID: 'dashboard' },
{ id: 'packages', parentID: 'atlas' },
{ id: 'tokens', parentID: 'packages' },
]
const expandedValues = ref(['atlas', 'apps', 'dashboard', 'packages'])
</script>
<template>
<TreeViewRoot
:nodes="nodes"
v-model:expanded-values="expandedValues"
:default-value="['settings']"
label="Atlas project files"
>
<TreeViewItem value="atlas"><TreeViewDisclosure for="atlas" as="button">Toggle</TreeViewDisclosure>Atlas workspace</TreeViewItem>
<TreeViewGroup for="atlas">
<TreeViewItem value="apps"><TreeViewDisclosure for="apps" as="button">Toggle</TreeViewDisclosure>Applications</TreeViewItem>
<TreeViewGroup for="apps">
<TreeViewItem value="dashboard"><TreeViewDisclosure for="dashboard" as="button">Toggle</TreeViewDisclosure>Dashboard</TreeViewItem>
<TreeViewGroup for="dashboard">
<TreeViewItem value="overview">Overview.vue</TreeViewItem>
<TreeViewItem value="settings">Settings.vue</TreeViewItem>
</TreeViewGroup>
</TreeViewGroup>
<TreeViewItem value="packages"><TreeViewDisclosure for="packages" as="button">Toggle</TreeViewDisclosure>Packages</TreeViewItem>
<TreeViewGroup for="packages"><TreeViewItem value="tokens">tokens.ts</TreeViewItem></TreeViewGroup>
</TreeViewGroup>
</TreeViewRoot>
</template>외부 상태 관리
현재 값은 부모가 관리하고, 허용된 변경을 컴포넌트에 다시 전달합니다.
<!-- Tree View / Controlled -->
<script setup lang="ts">
import { ref } from 'vue'
import { TreeViewDisclosure, TreeViewGroup, TreeViewItem, TreeViewRoot } from '@sectile/vue/tree-view'
const nodes = [
{ id: 'atlas', parentID: null },
{ id: 'apps', parentID: 'atlas' },
{ id: 'dashboard', parentID: 'apps' },
{ id: 'overview', parentID: 'dashboard' },
{ id: 'settings', parentID: 'dashboard' },
{ id: 'packages', parentID: 'atlas' },
{ id: 'tokens', parentID: 'packages' },
]
const expandedValues = ref(['atlas', 'apps', 'dashboard', 'packages'])
</script>
<template>
<TreeViewRoot
:nodes="nodes"
v-model:expanded-values="expandedValues"
:default-value="['settings']"
label="Atlas project files"
>
<TreeViewItem value="atlas"><TreeViewDisclosure for="atlas" as="button">Toggle</TreeViewDisclosure>Atlas workspace</TreeViewItem>
<TreeViewGroup for="atlas">
<TreeViewItem value="apps"><TreeViewDisclosure for="apps" as="button">Toggle</TreeViewDisclosure>Applications</TreeViewItem>
<TreeViewGroup for="apps">
<TreeViewItem value="dashboard"><TreeViewDisclosure for="dashboard" as="button">Toggle</TreeViewDisclosure>Dashboard</TreeViewItem>
<TreeViewGroup for="dashboard">
<TreeViewItem value="overview">Overview.vue</TreeViewItem>
<TreeViewItem value="settings">Settings.vue</TreeViewItem>
</TreeViewGroup>
</TreeViewGroup>
<TreeViewItem value="packages"><TreeViewDisclosure for="packages" as="button">Toggle</TreeViewDisclosure>Packages</TreeViewItem>
<TreeViewGroup for="packages"><TreeViewItem value="tokens">tokens.ts</TreeViewItem></TreeViewGroup>
</TreeViewGroup>
</TreeViewRoot>
</template>API
Vue 패키지: @sectile/vue/tree-view
TreeViewRootTreeViewGroupTreeViewItemTreeViewDisclosure
Props
TreeViewRootProps
as이 파트가 렌더링할 요소 또는 컴포넌트입니다.
asChild하나뿐인 자식 요소에 파트 속성을 직접 합칠지 여부입니다.
defaultExpandedValues컴포넌트가 관리하는 처음 펼친 값 목록입니다.
defaultHighlightedValue컴포넌트가 관리하는 처음 강조 값입니다.
defaultValue컴포넌트가 값을 관리할 때 사용할 초깃값입니다.
disabled사용자 조작을 막을지 여부입니다.
disabledItems포커스와 선택 대상에서 제외할 항목 값입니다.
expandedValues하위 항목을 표시할 외부 제어 값 목록입니다.
highlightedValue키보드 조작 대상으로 강조된 현재 값입니다.
label보조 기술이 읽는 컨트롤 이름입니다.
modelValue부모가 상태를 관리할 때 사용할 현재 값입니다.
nodes계층을 구성할 평면 노드 목록입니다.
policies검증, 이동, 선택 동작을 조정하는 정책입니다.
readonly값 확인만 허용하는 읽기 전용 상태 여부입니다.
selectionMode하나 또는 여러 값을 선택할지 정합니다.
TreeViewPartProps
as이 파트가 렌더링할 요소 또는 컴포넌트입니다.
asChild하나뿐인 자식 요소에 파트 속성을 직접 합칠지 여부입니다.
TreeViewGroupProps
as이 파트가 렌더링할 요소 또는 컴포넌트입니다.
asChild하나뿐인 자식 요소에 파트 속성을 직접 합칠지 여부입니다.
for이 컴포넌트가 연결할 관련 파트의 값 또는 ID입니다.
슬롯
TreeViewRootSlotProps
disabled사용자 조작을 막을지 여부입니다.
expandedValues하위 항목을 표시 중인 값 목록입니다.
highlightedValue조작 대상으로 강조된 현재 값입니다.
readonly값 확인만 허용하는 읽기 전용 상태 여부입니다.
value이 계약이 노출하는 현재 값입니다.
TreeViewItemSlotProps
disabled사용자 조작을 막을지 여부입니다.
expanded하위 항목이 보이는지 여부입니다.
expandedValues하위 항목을 표시 중인 값 목록입니다.
highlighted조작 대상으로 강조된 항목인지 여부입니다.
highlightedValue조작 대상으로 강조된 현재 값입니다.
readonly값 확인만 허용하는 읽기 전용 상태 여부입니다.
selected현재 선택된 항목인지 여부입니다.
selectedValues현재 선택된 값입니다.
value이 계약이 노출하는 현재 값입니다.
이벤트
TreeViewRoot
update:expandedValues새 펼침 값 목록을 요청할 때 발생합니다.
update:highlightedValue새 강조 값을 요청할 때 발생합니다.
update:modelValue컴포넌트가 외부 제어 값의 변경을 요청할 때 발생합니다.
기타 타입
TreeViewPolicies
| 이름 | 타입 | 필수 |
|---|---|---|
eligible | (id: ID) => boolean | — |
TreeViewEligiblePredicate
type TreeViewEligiblePredicate<ID extends string = string> = NonNullable<TreeViewPolicies<ID>['eligible']>TreeViewValueChangeHandler
type TreeViewValueChangeHandler = (value: readonly string[]) => voidTreeViewExpandedValuesChangeHandler
type TreeViewExpandedValuesChangeHandler = (value: readonly string[]) => voidTreeViewHighlightedValueChangeHandler
type TreeViewHighlightedValueChangeHandler = (value: string | null) => voidTreeNodeInput
| 이름 | 타입 | 필수 |
|---|---|---|
id | ID | 필수 |
parentID | ID | null | 필수 |
TreeViewSelectionMode
type TreeViewSelectionMode = 'single' | 'multiple'파트
공통 범위: [data-scope="tree-view"]. 컴포넌트 내부로 스타일을 제한할 때 파트 선택자와 함께 사용합니다.
| 파트 | 선택자 | 역할 | 추가 속성 |
|---|---|---|---|
root | [data-part="root"] | 컴포넌트 경계와 내부 파트를 묶습니다. | — |
group | [data-part="group"] | 관련 하위 항목을 묶습니다. | — |
item | [data-part="item"] | 선택하거나 실행할 수 있는 항목 하나입니다. | — |
disclosure | [data-part="disclosure"] | 하위 콘텐츠를 펼치거나 접습니다. | — |
키보드 동작
| 키 | 동작 |
|---|---|
| Arrow Up / Arrow Down | 보이는 트리 항목 사이를 이동합니다. |
| Arrow Right | 가지를 펼치거나 첫 번째 자식으로 이동합니다. |
| Arrow Left | 가지를 접거나 부모로 이동합니다. |
| Enter / Space | 현재 항목을 선택하거나 실행합니다. |
접근성
트리 항목이 단계·펼침·선택·비활성 상태를 노출하고 하나의 이동 탭 위치를 사용합니다.
관련 WAI-ARIA 패턴에서 호스트 접근성 규칙을 확인할 수 있습니다.
