@primevue/mcp 4.5.5 → 5.0.0-rc.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE.md +45 -21
- package/README.md +48 -250
- package/data/components.json +47269 -0
- package/data/llms/components/accordion.md +629 -0
- package/data/llms/components/animateonscroll.md +165 -0
- package/data/llms/components/autocomplete.md +995 -0
- package/data/llms/components/avatar.md +264 -0
- package/data/llms/components/badge.md +200 -0
- package/data/llms/components/blockui.md +99 -0
- package/data/llms/components/breadcrumb.md +269 -0
- package/data/llms/components/button.md +902 -0
- package/data/llms/components/card.md +209 -0
- package/data/llms/components/carousel.md +506 -0
- package/data/llms/components/cascadeselect.md +1207 -0
- package/data/llms/components/chart.md +1022 -0
- package/data/llms/components/checkbox.md +401 -0
- package/data/llms/components/chip.md +206 -0
- package/data/llms/components/colorpicker.md +213 -0
- package/data/llms/components/commandmenu.md +660 -0
- package/data/llms/components/compare.md +407 -0
- package/data/llms/components/confirmdialog.md +343 -0
- package/data/llms/components/confirmpopup.md +252 -0
- package/data/llms/components/contextmenu.md +522 -0
- package/data/llms/components/datatable.md +5266 -0
- package/data/llms/components/dataview.md +569 -0
- package/data/llms/components/datepicker.md +964 -0
- package/data/llms/components/deferredcontent.md +96 -0
- package/data/llms/components/dialog.md +702 -0
- package/data/llms/components/divider.md +152 -0
- package/data/llms/components/dock.md +488 -0
- package/data/llms/components/drawer.md +469 -0
- package/data/llms/components/dynamicdialog.md +214 -0
- package/data/llms/components/editor.md +205 -0
- package/data/llms/components/fieldset.md +253 -0
- package/data/llms/components/fileupload.md +459 -0
- package/data/llms/components/floatlabel.md +144 -0
- package/data/llms/components/fluid.md +104 -0
- package/data/llms/components/focustrap.md +59 -0
- package/data/llms/components/forms.md +344 -0
- package/data/llms/components/galleria.md +1119 -0
- package/data/llms/components/gallery.md +1003 -0
- package/data/llms/components/iconfield.md +283 -0
- package/data/llms/components/iftalabel.md +96 -0
- package/data/llms/components/image.md +179 -0
- package/data/llms/components/imagecompare.md +108 -0
- package/data/llms/components/inplace.md +183 -0
- package/data/llms/components/inputcolor.md +869 -0
- package/data/llms/components/inputgroup.md +419 -0
- package/data/llms/components/inputmask.md +345 -0
- package/data/llms/components/inputnumber.md +551 -0
- package/data/llms/components/inputotp.md +345 -0
- package/data/llms/components/inputpassword.md +738 -0
- package/data/llms/components/inputtags.md +432 -0
- package/data/llms/components/inputtext.md +569 -0
- package/data/llms/components/installation.md +1 -0
- package/data/llms/components/keyfilter.md +116 -0
- package/data/llms/components/knob.md +318 -0
- package/data/llms/components/label.md +151 -0
- package/data/llms/components/laravel.md +53 -0
- package/data/llms/components/listbox.md +636 -0
- package/data/llms/components/mask.md +203 -0
- package/data/llms/components/mcp.md +39 -0
- package/data/llms/components/megamenu.md +563 -0
- package/data/llms/components/menu.md +651 -0
- package/data/llms/components/menubar.md +446 -0
- package/data/llms/components/message.md +497 -0
- package/data/llms/components/metergroup.md +281 -0
- package/data/llms/components/multiselect.md +752 -0
- package/data/llms/components/orderlist.md +224 -0
- package/data/llms/components/organizationchart.md +418 -0
- package/data/llms/components/paginator.md +221 -0
- package/data/llms/components/panel.md +321 -0
- package/data/llms/components/panelmenu.md +703 -0
- package/data/llms/components/password.md +657 -0
- package/data/llms/components/picklist.md +286 -0
- package/data/llms/components/popover.md +145 -0
- package/data/llms/components/progressbar.md +242 -0
- package/data/llms/components/progressspinner.md +104 -0
- package/data/llms/components/radiobutton.md +427 -0
- package/data/llms/components/rating.md +312 -0
- package/data/llms/components/ripple.md +91 -0
- package/data/llms/components/scrollarea.md +700 -0
- package/data/llms/components/scrollpanel.md +131 -0
- package/data/llms/components/scrolltop.md +87 -0
- package/data/llms/components/select.md +1251 -0
- package/data/llms/components/selectbutton.md +268 -0
- package/data/llms/components/sidebar.md +2232 -0
- package/data/llms/components/skeleton.md +302 -0
- package/data/llms/components/slider.md +416 -0
- package/data/llms/components/speeddial.md +402 -0
- package/data/llms/components/splitbutton.md +840 -0
- package/data/llms/components/splitter.md +447 -0
- package/data/llms/components/stepper.md +551 -0
- package/data/llms/components/styleclass.md +226 -0
- package/data/llms/components/tabs.md +609 -0
- package/data/llms/components/tag.md +178 -0
- package/data/llms/components/terminal.md +123 -0
- package/data/llms/components/textarea.md +519 -0
- package/data/llms/components/tieredmenu.md +578 -0
- package/data/llms/components/timeline.md +494 -0
- package/data/llms/components/toast.md +472 -0
- package/data/llms/components/togglebutton.md +276 -0
- package/data/llms/components/toggleswitch.md +271 -0
- package/data/llms/components/toolbar.md +140 -0
- package/data/llms/components/tooltip.md +160 -0
- package/data/llms/components/tree.md +1076 -0
- package/data/llms/components/treeselect.md +660 -0
- package/data/llms/components/treetable.md +2493 -0
- package/data/llms/components/virtualscroller.md +265 -0
- package/data/llms/guides/autoimport.md +28 -0
- package/data/llms/guides/cdn.md +72 -0
- package/data/llms/guides/configuration.md +158 -0
- package/data/llms/guides/customicons.md +67 -0
- package/data/llms/guides/guides/accessibility.md +27 -0
- package/data/llms/guides/guides/animations.md +119 -0
- package/data/llms/guides/guides/rtl.md +7 -0
- package/data/llms/guides/icons.md +136 -0
- package/data/llms/guides/installation.md +3 -0
- package/data/llms/guides/laravel.md +66 -0
- package/data/llms/guides/llms.md +15 -0
- package/data/llms/guides/mcp.md +104 -0
- package/data/llms/guides/migration/v4.md +15 -0
- package/data/llms/guides/migration/v5.md +15 -0
- package/data/llms/guides/nuxt.md +141 -0
- package/data/llms/guides/passthrough.md +137 -0
- package/data/llms/guides/primeclt.md +43 -0
- package/data/llms/guides/tailwind.md +151 -0
- package/data/llms/guides/theming/styled.md +497 -0
- package/data/llms/guides/theming/unstyled.md +57 -0
- package/data/llms/guides/uikit.md +3 -0
- package/data/llms/guides/vite.md +90 -0
- package/data/llms/llms-full.txt +54465 -0
- package/data/llms/llms.txt +132 -0
- package/data/llms/pages/accessibility.md +27 -0
- package/data/llms/pages/animations.md +119 -0
- package/data/llms/pages/autoimport.md +28 -0
- package/data/llms/pages/cdn.md +72 -0
- package/data/llms/pages/configuration.md +158 -0
- package/data/llms/pages/contribution.md +31 -0
- package/data/llms/pages/customicons.md +67 -0
- package/data/llms/pages/designer.md +79 -0
- package/data/llms/pages/dynamicimports.md +7 -0
- package/data/llms/pages/forms.md +63 -0
- package/data/llms/pages/guides/accessibility.md +27 -0
- package/data/llms/pages/guides/animations.md +119 -0
- package/data/llms/pages/guides/rtl.md +7 -0
- package/data/llms/pages/icons.md +136 -0
- package/data/llms/pages/installation.md +3 -0
- package/data/llms/pages/introduction.md +23 -0
- package/data/llms/pages/laravel.md +66 -0
- package/data/llms/pages/llms.md +15 -0
- package/data/llms/pages/mcp.md +104 -0
- package/data/llms/pages/migration/v4.md +15 -0
- package/data/llms/pages/migration/v5.md +15 -0
- package/data/llms/pages/nuxt.md +141 -0
- package/data/llms/pages/passthrough.md +137 -0
- package/data/llms/pages/primeclt.md +43 -0
- package/data/llms/pages/rtl.md +7 -0
- package/data/llms/pages/setup.md +3 -0
- package/data/llms/pages/styled.md +497 -0
- package/data/llms/pages/tailwind.md +151 -0
- package/data/llms/pages/theming/styled.md +497 -0
- package/data/llms/pages/theming/unstyled.md +57 -0
- package/data/llms/pages/uikit.md +3 -0
- package/data/llms/pages/unstyled.md +57 -0
- package/data/llms/pages/v4.md +15 -0
- package/data/llms/pages/v5.md +15 -0
- package/data/llms/pages/vite.md +90 -0
- package/data/manifest.json +11117 -0
- package/data/mcp-data.json +55940 -0
- package/dist/index.d.ts +17 -1
- package/dist/index.js +66066 -72541
- package/package.json +10 -12
|
@@ -0,0 +1,1076 @@
|
|
|
1
|
+
# Tree
|
|
2
|
+
|
|
3
|
+
Tree is used to display hierarchical data.
|
|
4
|
+
|
|
5
|
+
## Basic
|
|
6
|
+
|
|
7
|
+
Displays hierarchical data with expand and collapse support.
|
|
8
|
+
|
|
9
|
+
```vue
|
|
10
|
+
<template>
|
|
11
|
+
<div>
|
|
12
|
+
<Tree :value="nodes" class="w-full md:w-120"></Tree>
|
|
13
|
+
</div>
|
|
14
|
+
</template>
|
|
15
|
+
|
|
16
|
+
<script setup>
|
|
17
|
+
import { ref, onMounted } from 'vue';
|
|
18
|
+
import { NodeService } from '@/service/NodeService';
|
|
19
|
+
|
|
20
|
+
const nodes = ref(null);
|
|
21
|
+
|
|
22
|
+
onMounted(() => {
|
|
23
|
+
NodeService.getTreeNodes().then((data) => (nodes.value = data));
|
|
24
|
+
});
|
|
25
|
+
<\/script>
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
## Content
|
|
29
|
+
|
|
30
|
+
Custom node content is rendered through the nodeicon slot; the node payload exposes its children and expanded state so the right icon can be chosen.
|
|
31
|
+
|
|
32
|
+
```vue
|
|
33
|
+
<template>
|
|
34
|
+
<div>
|
|
35
|
+
<Tree v-model:expandedKeys="expandedKeys" :value="nodes" class="w-full md:w-120">
|
|
36
|
+
<template #nodeicon="slotProps">
|
|
37
|
+
<FolderOpen v-if="slotProps.node.children && slotProps.node.children.length && expandedKeys[slotProps.node.key]" :class="slotProps.class" />
|
|
38
|
+
<Folder v-else-if="slotProps.node.children && slotProps.node.children.length" :class="slotProps.class" />
|
|
39
|
+
<File v-else :class="slotProps.class" />
|
|
40
|
+
</template>
|
|
41
|
+
</Tree>
|
|
42
|
+
</div>
|
|
43
|
+
</template>
|
|
44
|
+
|
|
45
|
+
<script setup>
|
|
46
|
+
import { ref, onMounted } from 'vue';
|
|
47
|
+
import { NodeService } from '@/service/NodeService';
|
|
48
|
+
import File from '@primeicons/vue/file';
|
|
49
|
+
import Folder from '@primeicons/vue/folder';
|
|
50
|
+
import FolderOpen from '@primeicons/vue/folder-open';
|
|
51
|
+
|
|
52
|
+
const nodes = ref(null);
|
|
53
|
+
const expandedKeys = ref({ '0': true });
|
|
54
|
+
|
|
55
|
+
onMounted(() => {
|
|
56
|
+
NodeService.getTreeNodes().then((data) => (nodes.value = data));
|
|
57
|
+
});
|
|
58
|
+
<\/script>
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
## Toggle Indicator
|
|
62
|
+
|
|
63
|
+
Toggle icons are customized through the nodetoggleicon slot which receives the expanded state of the node.
|
|
64
|
+
|
|
65
|
+
```vue
|
|
66
|
+
<template>
|
|
67
|
+
<div>
|
|
68
|
+
<Tree v-model:expandedKeys="expandedKeys" :value="nodes" class="w-full md:w-120">
|
|
69
|
+
<template #nodetoggleicon="slotProps">
|
|
70
|
+
<MinusCircle v-if="slotProps.expanded" :class="slotProps.class" />
|
|
71
|
+
<PlusCircle v-else :class="slotProps.class" />
|
|
72
|
+
</template>
|
|
73
|
+
</Tree>
|
|
74
|
+
</div>
|
|
75
|
+
</template>
|
|
76
|
+
|
|
77
|
+
<script setup>
|
|
78
|
+
import { ref, onMounted } from 'vue';
|
|
79
|
+
import { NodeService } from '@/service/NodeService';
|
|
80
|
+
import MinusCircle from '@primeicons/vue/minus-circle';
|
|
81
|
+
import PlusCircle from '@primeicons/vue/plus-circle';
|
|
82
|
+
|
|
83
|
+
const nodes = ref(null);
|
|
84
|
+
const expandedKeys = ref({ '0': true });
|
|
85
|
+
|
|
86
|
+
onMounted(() => {
|
|
87
|
+
NodeService.getTreeNodes().then((data) => (nodes.value = data));
|
|
88
|
+
});
|
|
89
|
+
<\/script>
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
## Controlled
|
|
93
|
+
|
|
94
|
+
Tree state can be controlled programmatically with the expandedKeys property that defines the keys that are expanded. This property is a Map instance whose key is the key of a node and value is a boolean. Note that expandedKeys also supports two-way binding with the v-model directive.
|
|
95
|
+
|
|
96
|
+
```vue
|
|
97
|
+
<template>
|
|
98
|
+
<div>
|
|
99
|
+
<div class="flex flex-wrap gap-2 mb-6">
|
|
100
|
+
<Button type="button" @click="expandAll">
|
|
101
|
+
<Plus />
|
|
102
|
+
Expand All
|
|
103
|
+
</Button>
|
|
104
|
+
<Button type="button" @click="collapseAll">
|
|
105
|
+
<Minus />
|
|
106
|
+
Collapse All
|
|
107
|
+
</Button>
|
|
108
|
+
</div>
|
|
109
|
+
<Tree v-model:expandedKeys="expandedKeys" :value="nodes" class="w-full md:w-120"></Tree>
|
|
110
|
+
</div>
|
|
111
|
+
</template>
|
|
112
|
+
|
|
113
|
+
<script setup>
|
|
114
|
+
import Minus from '@primeicons/vue/minus';
|
|
115
|
+
import Plus from '@primeicons/vue/plus';
|
|
116
|
+
import { ref, onMounted } from 'vue';
|
|
117
|
+
import { NodeService } from '@/service/NodeService';
|
|
118
|
+
|
|
119
|
+
const nodes = ref(null);
|
|
120
|
+
const expandedKeys = ref({});
|
|
121
|
+
|
|
122
|
+
onMounted(() => {
|
|
123
|
+
NodeService.getTreeNodes().then((data) => (nodes.value = data));
|
|
124
|
+
});
|
|
125
|
+
|
|
126
|
+
const expandAll = () => {
|
|
127
|
+
for (let node of nodes.value) {
|
|
128
|
+
expandNode(node);
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
expandedKeys.value = { ...expandedKeys.value };
|
|
132
|
+
};
|
|
133
|
+
|
|
134
|
+
const collapseAll = () => {
|
|
135
|
+
expandedKeys.value = {};
|
|
136
|
+
};
|
|
137
|
+
|
|
138
|
+
const expandNode = (node) => {
|
|
139
|
+
if (node.children && node.children.length) {
|
|
140
|
+
expandedKeys.value[node.key] = true;
|
|
141
|
+
|
|
142
|
+
for (let child of node.children) {
|
|
143
|
+
expandNode(child);
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
};
|
|
147
|
+
<\/script>
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
## Single
|
|
151
|
+
|
|
152
|
+
Single node selection is configured by setting selectionMode as single along with selectionKeys property to manage the selection value binding.
|
|
153
|
+
|
|
154
|
+
```vue
|
|
155
|
+
<template>
|
|
156
|
+
<div>
|
|
157
|
+
<Tree v-model:selectionKeys="selectedKey" :value="nodes" selectionMode="single" class="w-full md:w-120"></Tree>
|
|
158
|
+
</div>
|
|
159
|
+
</template>
|
|
160
|
+
|
|
161
|
+
<script setup>
|
|
162
|
+
import { ref, onMounted } from 'vue';
|
|
163
|
+
import { NodeService } from '@/service/NodeService';
|
|
164
|
+
|
|
165
|
+
const nodes = ref(null);
|
|
166
|
+
const selectedKey = ref(null);
|
|
167
|
+
|
|
168
|
+
onMounted(() => {
|
|
169
|
+
NodeService.getTreeNodes().then((data) => (nodes.value = data));
|
|
170
|
+
});
|
|
171
|
+
<\/script>
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
## Multiple
|
|
175
|
+
|
|
176
|
+
More than one node is selectable by setting selectionMode to multiple . By default in multiple selection mode, metaKey press (e.g. ⌘ ) is not necessary to add to existing selections. When the optional metaKeySelection is present, behavior is changed in a way that selecting a new node requires meta key to be present. Note that in touch enabled devices, Tree always ignores metaKey. In multiple selection mode, value binding should be a key-value pair where key is the node key and value is a boolean to indicate selection.
|
|
177
|
+
|
|
178
|
+
```vue
|
|
179
|
+
<template>
|
|
180
|
+
<div>
|
|
181
|
+
<div class="flex items-center mb-6 gap-2">
|
|
182
|
+
<ToggleSwitch v-model="checked" inputId="input-metakey" />
|
|
183
|
+
<label for="input-metakey">MetaKey</label>
|
|
184
|
+
</div>
|
|
185
|
+
<Tree v-model:selectionKeys="selectedKeys" :value="nodes" selectionMode="multiple" :metaKeySelection="checked" class="w-full md:w-120"></Tree>
|
|
186
|
+
</div>
|
|
187
|
+
</template>
|
|
188
|
+
|
|
189
|
+
<script setup>
|
|
190
|
+
import { ref, onMounted } from 'vue';
|
|
191
|
+
import { NodeService } from '@/service/NodeService';
|
|
192
|
+
|
|
193
|
+
const nodes = ref(null);
|
|
194
|
+
const selectedKeys = ref(null);
|
|
195
|
+
const checked = ref(false);
|
|
196
|
+
|
|
197
|
+
onMounted(() => {
|
|
198
|
+
NodeService.getTreeNodes().then((data) => (nodes.value = data));
|
|
199
|
+
});
|
|
200
|
+
<\/script>
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
## Checkbox
|
|
204
|
+
|
|
205
|
+
Selection of multiple nodes via checkboxes is enabled by configuring selectionMode as checkbox . In checkbox selection mode, value binding should be a key-value pair where key is the node key and value is an object that has checked and partialChecked properties to represent the checked state of a node object to indicate selection.
|
|
206
|
+
|
|
207
|
+
```vue
|
|
208
|
+
<template>
|
|
209
|
+
<div>
|
|
210
|
+
<Tree v-model:selectionKeys="selectedKey" :value="nodes" selectionMode="checkbox" class="w-full md:w-120"></Tree>
|
|
211
|
+
</div>
|
|
212
|
+
</template>
|
|
213
|
+
|
|
214
|
+
<script setup>
|
|
215
|
+
import { ref, onMounted } from 'vue';
|
|
216
|
+
import { NodeService } from '@/service/NodeService';
|
|
217
|
+
|
|
218
|
+
const nodes = ref(null);
|
|
219
|
+
const selectedKey = ref(null);
|
|
220
|
+
|
|
221
|
+
onMounted(() => {
|
|
222
|
+
NodeService.getTreeNodes().then((data) => (nodes.value = data));
|
|
223
|
+
});
|
|
224
|
+
<\/script>
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
## Select All
|
|
228
|
+
|
|
229
|
+
A header checkbox can be added to toggle the selection of every node at once. Its checked and indeterminate states are derived from the current selectionKeys .
|
|
230
|
+
|
|
231
|
+
```vue
|
|
232
|
+
<template>
|
|
233
|
+
<Tree v-model:selectionKeys="selectionKeys" v-model:expandedKeys="expandedKeys" :value="nodes" selectionMode="checkbox" class="w-full md:w-120">
|
|
234
|
+
<template #header>
|
|
235
|
+
<div class="flex items-center gap-2 px-2">
|
|
236
|
+
<Checkbox :modelValue="isAllSelected" :indeterminate="isSomeSelected" binary inputId="tree-select-all" @update:modelValue="toggleAll" />
|
|
237
|
+
<label for="tree-select-all" class="font-medium">Select All</label>
|
|
238
|
+
</div>
|
|
239
|
+
</template>
|
|
240
|
+
</Tree>
|
|
241
|
+
</template>
|
|
242
|
+
|
|
243
|
+
<script setup>
|
|
244
|
+
import { ref, computed, onMounted } from 'vue';
|
|
245
|
+
import { NodeService } from '@/service/NodeService';
|
|
246
|
+
|
|
247
|
+
const nodes = ref(null);
|
|
248
|
+
const selectionKeys = ref({});
|
|
249
|
+
const expandedKeys = ref({ '0': true });
|
|
250
|
+
|
|
251
|
+
onMounted(() => {
|
|
252
|
+
NodeService.getTreeNodes().then((data) => (nodes.value = data));
|
|
253
|
+
});
|
|
254
|
+
|
|
255
|
+
const collectKeys = (list) => {
|
|
256
|
+
return (list || []).reduce((keys, node) => {
|
|
257
|
+
keys.push(node.key);
|
|
258
|
+
|
|
259
|
+
if (node.children) keys.push(...collectKeys(node.children));
|
|
260
|
+
|
|
261
|
+
return keys;
|
|
262
|
+
}, []);
|
|
263
|
+
};
|
|
264
|
+
|
|
265
|
+
const selectedCount = computed(() => Object.values(selectionKeys.value).filter((entry) => entry?.checked).length);
|
|
266
|
+
const partialCount = computed(() => Object.values(selectionKeys.value).filter((entry) => entry?.partialChecked).length);
|
|
267
|
+
const totalCount = computed(() => collectKeys(nodes.value).length);
|
|
268
|
+
|
|
269
|
+
const isAllSelected = computed(() => totalCount.value > 0 && selectedCount.value === totalCount.value);
|
|
270
|
+
const isSomeSelected = computed(() => (selectedCount.value > 0 || partialCount.value > 0) && !isAllSelected.value);
|
|
271
|
+
|
|
272
|
+
const toggleAll = () => {
|
|
273
|
+
if (isAllSelected.value) {
|
|
274
|
+
selectionKeys.value = {};
|
|
275
|
+
} else {
|
|
276
|
+
selectionKeys.value = collectKeys(nodes.value).reduce((acc, key) => {
|
|
277
|
+
acc[key] = { checked: true, partialChecked: false };
|
|
278
|
+
|
|
279
|
+
return acc;
|
|
280
|
+
}, {});
|
|
281
|
+
}
|
|
282
|
+
};
|
|
283
|
+
<\/script>
|
|
284
|
+
```
|
|
285
|
+
|
|
286
|
+
## Keyboard
|
|
287
|
+
|
|
288
|
+
Tree has full keyboard support; arrow keys navigate between nodes, right and left expand and collapse a node and space toggles the selection of the focused node.
|
|
289
|
+
|
|
290
|
+
```vue
|
|
291
|
+
<template>
|
|
292
|
+
<div class="flex flex-col gap-3 w-full md:w-120">
|
|
293
|
+
<div class="flex items-center justify-between gap-3 p-3 rounded-md border border-surface-200 dark:border-surface-700 bg-surface-50 dark:bg-surface-900">
|
|
294
|
+
<span class="text-sm text-surface-500 dark:text-surface-400">
|
|
295
|
+
<kbd class="px-1.5 py-0.5 text-xs rounded bg-surface-200 dark:bg-surface-700">↑</kbd>
|
|
296
|
+
<kbd class="px-1.5 py-0.5 text-xs rounded bg-surface-200 dark:bg-surface-700">↓</kbd> navigate,
|
|
297
|
+
<kbd class="px-1.5 py-0.5 text-xs rounded bg-surface-200 dark:bg-surface-700">→</kbd> expand,
|
|
298
|
+
<kbd class="px-1.5 py-0.5 text-xs rounded bg-surface-200 dark:bg-surface-700">←</kbd> collapse,
|
|
299
|
+
<kbd class="px-1.5 py-0.5 text-xs rounded bg-surface-200 dark:bg-surface-700">Space</kbd> select
|
|
300
|
+
</span>
|
|
301
|
+
<div class="flex items-center gap-2">
|
|
302
|
+
<span class="text-sm font-medium">Selected</span>
|
|
303
|
+
<Badge :severity="selectedCount ? 'info' : 'secondary'">{{ selectedCount }}</Badge>
|
|
304
|
+
</div>
|
|
305
|
+
</div>
|
|
306
|
+
<Tree v-model:selectionKeys="selectionKeys" v-model:expandedKeys="expandedKeys" :value="nodes" selectionMode="multiple" class="w-full">
|
|
307
|
+
<template #nodeicon="slotProps">
|
|
308
|
+
<Folder v-if="slotProps.node.children && slotProps.node.children.length" :class="slotProps.class" />
|
|
309
|
+
<File v-else :class="slotProps.class" />
|
|
310
|
+
</template>
|
|
311
|
+
</Tree>
|
|
312
|
+
</div>
|
|
313
|
+
</template>
|
|
314
|
+
|
|
315
|
+
<script setup>
|
|
316
|
+
import { ref, computed, onMounted } from 'vue';
|
|
317
|
+
import { NodeService } from '@/service/NodeService';
|
|
318
|
+
import File from '@primeicons/vue/file';
|
|
319
|
+
import Folder from '@primeicons/vue/folder';
|
|
320
|
+
|
|
321
|
+
const nodes = ref(null);
|
|
322
|
+
const selectionKeys = ref({});
|
|
323
|
+
const expandedKeys = ref({ '0': true });
|
|
324
|
+
|
|
325
|
+
const selectedCount = computed(() => Object.values(selectionKeys.value).filter(Boolean).length);
|
|
326
|
+
|
|
327
|
+
onMounted(() => {
|
|
328
|
+
NodeService.getTreeNodes().then((data) => (nodes.value = data));
|
|
329
|
+
});
|
|
330
|
+
<\/script>
|
|
331
|
+
```
|
|
332
|
+
|
|
333
|
+
## Filter
|
|
334
|
+
|
|
335
|
+
Filtering enables searching through the nodes using the built-in filter property.
|
|
336
|
+
|
|
337
|
+
```vue
|
|
338
|
+
<template>
|
|
339
|
+
<Tree :value="nodes" :filter="true" filterPlaceholder="Search" class="w-full md:w-120" :pt="{ emptyMessage: { class: 'mt-2' } }">
|
|
340
|
+
<template #empty>No options found.</template>
|
|
341
|
+
</Tree>
|
|
342
|
+
</template>
|
|
343
|
+
|
|
344
|
+
<script setup>
|
|
345
|
+
import { ref, onMounted } from 'vue';
|
|
346
|
+
import { NodeService } from '@/service/NodeService';
|
|
347
|
+
|
|
348
|
+
const nodes = ref(null);
|
|
349
|
+
|
|
350
|
+
onMounted(() => {
|
|
351
|
+
NodeService.getTreeNodes().then(data => nodes.value = data);
|
|
352
|
+
});
|
|
353
|
+
<\/script>
|
|
354
|
+
```
|
|
355
|
+
|
|
356
|
+
## Lazy
|
|
357
|
+
|
|
358
|
+
Lazy loading is demonstrated in this example where nodes are loaded on demand when a node is expanded.
|
|
359
|
+
|
|
360
|
+
```vue
|
|
361
|
+
<template>
|
|
362
|
+
<Tree :value="nodes" @node-expand="onNodeExpand" loadingMode="icon" class="w-full md:w-120">
|
|
363
|
+
<template #nodetoggleicon="{ node, expanded }">
|
|
364
|
+
<Spinner v-if="node.loading" class="animate-spin" />
|
|
365
|
+
<MinusCircle v-else-if="expanded" />
|
|
366
|
+
<PlusCircle v-else />
|
|
367
|
+
</template>
|
|
368
|
+
<template #nodeicon="{ node }">
|
|
369
|
+
<File v-if="node.leaf" class="mr-2" />
|
|
370
|
+
<FolderOpen v-else-if="node.expanded" class="mr-2" />
|
|
371
|
+
<Folder v-else class="mr-2" />
|
|
372
|
+
</template>
|
|
373
|
+
</Tree>
|
|
374
|
+
</template>
|
|
375
|
+
|
|
376
|
+
<script setup>
|
|
377
|
+
import { ref, onMounted } from 'vue';
|
|
378
|
+
import File from '@primeicons/vue/file';
|
|
379
|
+
import Folder from '@primeicons/vue/folder';
|
|
380
|
+
import FolderOpen from '@primeicons/vue/folder-open';
|
|
381
|
+
import MinusCircle from '@primeicons/vue/minus-circle';
|
|
382
|
+
import PlusCircle from '@primeicons/vue/plus-circle';
|
|
383
|
+
import Spinner from '@primeicons/vue/spinner';
|
|
384
|
+
|
|
385
|
+
const nodes = ref(null);
|
|
386
|
+
|
|
387
|
+
onMounted(() => {
|
|
388
|
+
nodes.value = initiateNodes();
|
|
389
|
+
|
|
390
|
+
setTimeout(() => {
|
|
391
|
+
nodes.value.map((node) => (node.loading = false));
|
|
392
|
+
}, 2000);
|
|
393
|
+
});
|
|
394
|
+
|
|
395
|
+
const onNodeExpand = (node) => {
|
|
396
|
+
if (!node.children) {
|
|
397
|
+
node.loading = true;
|
|
398
|
+
|
|
399
|
+
setTimeout(() => {
|
|
400
|
+
let _node = { ...node };
|
|
401
|
+
|
|
402
|
+
_node.children = [];
|
|
403
|
+
|
|
404
|
+
for (let i = 0; i < 3; i++) {
|
|
405
|
+
_node.children.push({
|
|
406
|
+
key: node.key + '-' + i,
|
|
407
|
+
label: 'Lazy ' + node.label + '-' + i
|
|
408
|
+
});
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
let _nodes = { ...nodes.value };
|
|
412
|
+
|
|
413
|
+
_nodes[parseInt(node.key, 10)] = { ..._node, loading: false };
|
|
414
|
+
|
|
415
|
+
nodes.value = _nodes;
|
|
416
|
+
}, 500);
|
|
417
|
+
}
|
|
418
|
+
};
|
|
419
|
+
|
|
420
|
+
const initiateNodes = () => {
|
|
421
|
+
return [
|
|
422
|
+
{
|
|
423
|
+
key: '0',
|
|
424
|
+
label: 'Node 0',
|
|
425
|
+
leaf: false,
|
|
426
|
+
loading: true
|
|
427
|
+
},
|
|
428
|
+
{
|
|
429
|
+
key: '1',
|
|
430
|
+
label: 'Node 1',
|
|
431
|
+
leaf: false,
|
|
432
|
+
loading: true
|
|
433
|
+
},
|
|
434
|
+
{
|
|
435
|
+
key: '2',
|
|
436
|
+
label: 'Node 2',
|
|
437
|
+
leaf: false,
|
|
438
|
+
loading: true
|
|
439
|
+
}
|
|
440
|
+
];
|
|
441
|
+
};
|
|
442
|
+
<\/script>
|
|
443
|
+
```
|
|
444
|
+
|
|
445
|
+
## Overlay
|
|
446
|
+
|
|
447
|
+
While data is being fetched, a loading overlay with a spinner can be displayed over the Tree by enabling the loading property.
|
|
448
|
+
|
|
449
|
+
```vue
|
|
450
|
+
<template>
|
|
451
|
+
<div class="w-full md:w-120 flex flex-col gap-3">
|
|
452
|
+
<Button size="small" :disabled="loading" class="self-end" @click="refresh">
|
|
453
|
+
<Refresh />
|
|
454
|
+
Refresh
|
|
455
|
+
</Button>
|
|
456
|
+
<Tree v-model:expandedKeys="expandedKeys" :value="nodes" :loading="loading" class="w-full">
|
|
457
|
+
<template #nodeicon="slotProps">
|
|
458
|
+
<Folder v-if="slotProps.node.children && slotProps.node.children.length" :class="slotProps.class" />
|
|
459
|
+
<File v-else :class="slotProps.class" />
|
|
460
|
+
</template>
|
|
461
|
+
<template #loadingicon>
|
|
462
|
+
<Spinner :size="32" class="animate-spin text-primary" />
|
|
463
|
+
</template>
|
|
464
|
+
</Tree>
|
|
465
|
+
</div>
|
|
466
|
+
</template>
|
|
467
|
+
|
|
468
|
+
<script setup>
|
|
469
|
+
import { ref, onMounted } from 'vue';
|
|
470
|
+
import { NodeService } from '@/service/NodeService';
|
|
471
|
+
import File from '@primeicons/vue/file';
|
|
472
|
+
import Folder from '@primeicons/vue/folder';
|
|
473
|
+
import Refresh from '@primeicons/vue/refresh';
|
|
474
|
+
import Spinner from '@primeicons/vue/spinner';
|
|
475
|
+
|
|
476
|
+
const nodes = ref(null);
|
|
477
|
+
const loading = ref(false);
|
|
478
|
+
const expandedKeys = ref({ '0': true });
|
|
479
|
+
|
|
480
|
+
onMounted(() => {
|
|
481
|
+
NodeService.getTreeNodes().then((data) => (nodes.value = data));
|
|
482
|
+
});
|
|
483
|
+
|
|
484
|
+
const refresh = () => {
|
|
485
|
+
loading.value = true;
|
|
486
|
+
|
|
487
|
+
setTimeout(() => {
|
|
488
|
+
NodeService.getTreeNodes().then((data) => {
|
|
489
|
+
nodes.value = data;
|
|
490
|
+
loading.value = false;
|
|
491
|
+
});
|
|
492
|
+
}, 1500);
|
|
493
|
+
};
|
|
494
|
+
<\/script>
|
|
495
|
+
```
|
|
496
|
+
|
|
497
|
+
## Skeleton
|
|
498
|
+
|
|
499
|
+
Skeleton placeholders can be rendered for each row while the data is being fetched by displaying a set of empty nodes with a custom node template.
|
|
500
|
+
|
|
501
|
+
```vue
|
|
502
|
+
<template>
|
|
503
|
+
<div class="w-full md:w-120 flex flex-col gap-3">
|
|
504
|
+
<Button size="small" :disabled="loading" class="self-end" @click="refresh">
|
|
505
|
+
<Refresh />
|
|
506
|
+
Refresh
|
|
507
|
+
</Button>
|
|
508
|
+
<Tree v-model:expandedKeys="expandedKeys" :value="loading ? placeholders : nodes" class="w-full">
|
|
509
|
+
<template #nodeicon="slotProps">
|
|
510
|
+
<Skeleton v-if="loading" shape="circle" size="1rem" />
|
|
511
|
+
<Folder v-else-if="slotProps.node.children && slotProps.node.children.length" :class="slotProps.class" />
|
|
512
|
+
<File v-else :class="slotProps.class" />
|
|
513
|
+
</template>
|
|
514
|
+
<template #default="slotProps">
|
|
515
|
+
<Skeleton v-if="loading" class="w-40!" borderRadius="4px" />
|
|
516
|
+
<span v-else>{{ slotProps.node.label }}</span>
|
|
517
|
+
</template>
|
|
518
|
+
</Tree>
|
|
519
|
+
</div>
|
|
520
|
+
</template>
|
|
521
|
+
|
|
522
|
+
<script setup>
|
|
523
|
+
import { ref } from 'vue';
|
|
524
|
+
import { NodeService } from '@/service/NodeService';
|
|
525
|
+
import File from '@primeicons/vue/file';
|
|
526
|
+
import Folder from '@primeicons/vue/folder';
|
|
527
|
+
import Refresh from '@primeicons/vue/refresh';
|
|
528
|
+
|
|
529
|
+
const nodes = ref(null);
|
|
530
|
+
const loading = ref(true);
|
|
531
|
+
const expandedKeys = ref({ '0': true });
|
|
532
|
+
const placeholders = Array.from({ length: 6 }, (_, i) => ({ key: \`skeleton-\${i}\`, label: '', leaf: true }));
|
|
533
|
+
|
|
534
|
+
const refresh = () => {
|
|
535
|
+
loading.value = true;
|
|
536
|
+
|
|
537
|
+
setTimeout(() => {
|
|
538
|
+
NodeService.getTreeNodes().then((data) => {
|
|
539
|
+
nodes.value = data;
|
|
540
|
+
loading.value = false;
|
|
541
|
+
});
|
|
542
|
+
}, 1500);
|
|
543
|
+
};
|
|
544
|
+
|
|
545
|
+
refresh();
|
|
546
|
+
<\/script>
|
|
547
|
+
```
|
|
548
|
+
|
|
549
|
+
## Empty
|
|
550
|
+
|
|
551
|
+
A custom placeholder can be displayed when there are no nodes to show using the empty slot.
|
|
552
|
+
|
|
553
|
+
```vue
|
|
554
|
+
<template>
|
|
555
|
+
<Tree :value="nodes" class="w-full md:w-120">
|
|
556
|
+
<template #nodeicon="slotProps">
|
|
557
|
+
<Folder :class="slotProps.class" />
|
|
558
|
+
</template>
|
|
559
|
+
<template #empty>
|
|
560
|
+
<div class="flex flex-col items-center justify-center gap-3 py-10 text-center">
|
|
561
|
+
<div class="w-14 h-14 rounded-full bg-surface-100 dark:bg-surface-800 flex items-center justify-center">
|
|
562
|
+
<Folder class="w-7 h-7 text-surface-400 dark:text-surface-500" />
|
|
563
|
+
</div>
|
|
564
|
+
<div>
|
|
565
|
+
<p class="m-0 font-semibold text-surface-900 dark:text-surface-0">No folders yet</p>
|
|
566
|
+
<p class="mt-1 text-sm text-surface-500 dark:text-surface-400">Create your first folder to start building a tree.</p>
|
|
567
|
+
</div>
|
|
568
|
+
<Button size="small" @click="addNode">
|
|
569
|
+
<Plus />
|
|
570
|
+
New Folder
|
|
571
|
+
</Button>
|
|
572
|
+
</div>
|
|
573
|
+
</template>
|
|
574
|
+
</Tree>
|
|
575
|
+
</template>
|
|
576
|
+
|
|
577
|
+
<script setup>
|
|
578
|
+
import { ref } from 'vue';
|
|
579
|
+
import Folder from '@primeicons/vue/folder';
|
|
580
|
+
import Plus from '@primeicons/vue/plus';
|
|
581
|
+
|
|
582
|
+
const nodes = ref([]);
|
|
583
|
+
|
|
584
|
+
const addNode = () => {
|
|
585
|
+
nodes.value.push({ key: \`root-\${nodes.value.length}\`, label: \`New Folder \${nodes.value.length + 1}\` });
|
|
586
|
+
};
|
|
587
|
+
<\/script>
|
|
588
|
+
```
|
|
589
|
+
|
|
590
|
+
## Single
|
|
591
|
+
|
|
592
|
+
Drag&Drop based reordering is enabled by adding the draggableNodes and droppableNodes properties and definining a two-way model binding to the value option. The optional @node-drop event is available to get notified about the new tree state.
|
|
593
|
+
|
|
594
|
+
```vue
|
|
595
|
+
<template>
|
|
596
|
+
<div>
|
|
597
|
+
<Tree v-model:value="nodes" class="w-full md:w-120" draggableNodes droppableNodes></Tree>
|
|
598
|
+
</div>
|
|
599
|
+
</template>
|
|
600
|
+
|
|
601
|
+
<script setup>
|
|
602
|
+
import File from '@primeicons/vue/file';
|
|
603
|
+
import Folder from '@primeicons/vue/folder';
|
|
604
|
+
import { ref } from 'vue';
|
|
605
|
+
|
|
606
|
+
const nodes = ref([
|
|
607
|
+
{
|
|
608
|
+
key: '0',
|
|
609
|
+
label: '.github',
|
|
610
|
+
data: '.github folder',
|
|
611
|
+
icon: Folder,
|
|
612
|
+
children: [
|
|
613
|
+
{
|
|
614
|
+
key: '0-0',
|
|
615
|
+
label: 'workflows',
|
|
616
|
+
data: 'workflows folder',
|
|
617
|
+
icon: Folder,
|
|
618
|
+
children: [
|
|
619
|
+
{
|
|
620
|
+
key: '0-0-0',
|
|
621
|
+
label: 'node.js.yml',
|
|
622
|
+
data: 'node.js.yml file',
|
|
623
|
+
icon: File
|
|
624
|
+
}
|
|
625
|
+
]
|
|
626
|
+
}
|
|
627
|
+
]
|
|
628
|
+
},
|
|
629
|
+
{
|
|
630
|
+
key: '1',
|
|
631
|
+
label: '.vscode',
|
|
632
|
+
data: '.vscode folder',
|
|
633
|
+
icon: Folder,
|
|
634
|
+
children: [
|
|
635
|
+
{
|
|
636
|
+
key: '1-0',
|
|
637
|
+
label: 'extensions.json',
|
|
638
|
+
data: 'extensions.json file',
|
|
639
|
+
icon: File
|
|
640
|
+
}
|
|
641
|
+
]
|
|
642
|
+
},
|
|
643
|
+
{
|
|
644
|
+
key: '2',
|
|
645
|
+
label: 'public',
|
|
646
|
+
data: 'public folder',
|
|
647
|
+
icon: Folder,
|
|
648
|
+
children: [
|
|
649
|
+
{
|
|
650
|
+
key: '2-0',
|
|
651
|
+
label: 'vite.svg',
|
|
652
|
+
data: 'vite.svg file',
|
|
653
|
+
icon: File
|
|
654
|
+
}
|
|
655
|
+
]
|
|
656
|
+
},
|
|
657
|
+
{
|
|
658
|
+
key: '3',
|
|
659
|
+
label: 'src',
|
|
660
|
+
data: 'src folder',
|
|
661
|
+
icon: Folder,
|
|
662
|
+
children: [
|
|
663
|
+
{
|
|
664
|
+
key: '3-0',
|
|
665
|
+
label: 'assets',
|
|
666
|
+
data: 'assets folder',
|
|
667
|
+
icon: Folder,
|
|
668
|
+
children: [
|
|
669
|
+
{
|
|
670
|
+
key: '3-0-0',
|
|
671
|
+
label: 'vue.svg',
|
|
672
|
+
data: 'vue.svg file',
|
|
673
|
+
icon: File
|
|
674
|
+
}
|
|
675
|
+
]
|
|
676
|
+
},
|
|
677
|
+
{
|
|
678
|
+
key: '3-1',
|
|
679
|
+
label: 'components',
|
|
680
|
+
data: 'components folder',
|
|
681
|
+
icon: Folder,
|
|
682
|
+
children: [
|
|
683
|
+
{
|
|
684
|
+
key: '3-1-0',
|
|
685
|
+
label: 'HelloWorld.vue',
|
|
686
|
+
data: 'HelloWorld.vue file',
|
|
687
|
+
icon: File
|
|
688
|
+
}
|
|
689
|
+
]
|
|
690
|
+
},
|
|
691
|
+
{
|
|
692
|
+
key: '3-2',
|
|
693
|
+
label: 'App.vue',
|
|
694
|
+
data: 'App.vue file',
|
|
695
|
+
icon: File
|
|
696
|
+
},
|
|
697
|
+
{
|
|
698
|
+
key: '3-3',
|
|
699
|
+
label: 'main.js',
|
|
700
|
+
data: 'main.js file',
|
|
701
|
+
icon: File
|
|
702
|
+
},
|
|
703
|
+
{
|
|
704
|
+
key: '3-4',
|
|
705
|
+
label: 'style.css',
|
|
706
|
+
data: 'style.css file',
|
|
707
|
+
icon: File
|
|
708
|
+
}
|
|
709
|
+
]
|
|
710
|
+
},
|
|
711
|
+
{
|
|
712
|
+
key: '4',
|
|
713
|
+
label: 'index.html',
|
|
714
|
+
data: 'index.html file',
|
|
715
|
+
icon: File
|
|
716
|
+
},
|
|
717
|
+
{
|
|
718
|
+
key: '5',
|
|
719
|
+
label: 'package.json',
|
|
720
|
+
data: 'package.json file',
|
|
721
|
+
icon: File
|
|
722
|
+
},
|
|
723
|
+
{
|
|
724
|
+
key: '6',
|
|
725
|
+
label: 'vite.config.js',
|
|
726
|
+
data: 'vite.config.js file',
|
|
727
|
+
icon: File
|
|
728
|
+
}
|
|
729
|
+
]);
|
|
730
|
+
<\/script>
|
|
731
|
+
```
|
|
732
|
+
|
|
733
|
+
## Multiple
|
|
734
|
+
|
|
735
|
+
Nodes can be transferred between multiple trees as well. The draggableScope and droppableScope properties defines keys to restrict the actions between trees. In this example, nodes can only be transferred from start to the end.
|
|
736
|
+
|
|
737
|
+
```vue
|
|
738
|
+
<template>
|
|
739
|
+
<div class="flex flex-col md:flex-row gap-4">
|
|
740
|
+
<Tree v-model:value="value1" class="flex-1 border border-surface rounded-lg" draggableNodes droppableNodes draggableScope="first" droppableScope="none">
|
|
741
|
+
<template #empty> No Items Left </template>
|
|
742
|
+
</Tree>
|
|
743
|
+
<Tree v-model:value="value2" class="flex-1 border border-surface rounded-lg" draggableNodes droppableNodes draggableScope="second" droppableScope="first">
|
|
744
|
+
<template #empty>
|
|
745
|
+
<span class="text-sm text-surface-500"> Drag Nodes Here </span>
|
|
746
|
+
</template>
|
|
747
|
+
</Tree>
|
|
748
|
+
<Tree v-model:value="value3" class="flex-1 border border-surface rounded-lg" draggableNodes droppableNodes :droppableScope="['first', 'second']">
|
|
749
|
+
<template #empty>
|
|
750
|
+
<span class="text-sm text-surface-500"> Drag Nodes Here </span>
|
|
751
|
+
</template>
|
|
752
|
+
</Tree>
|
|
753
|
+
</div>
|
|
754
|
+
</template>
|
|
755
|
+
|
|
756
|
+
<script setup>
|
|
757
|
+
import File from '@primeicons/vue/file';
|
|
758
|
+
import Folder from '@primeicons/vue/folder';
|
|
759
|
+
import { ref } from 'vue';
|
|
760
|
+
|
|
761
|
+
const value1 = ref([
|
|
762
|
+
{
|
|
763
|
+
key: '0-0',
|
|
764
|
+
label: '.github',
|
|
765
|
+
data: '.github folder',
|
|
766
|
+
icon: Folder,
|
|
767
|
+
children: [
|
|
768
|
+
{
|
|
769
|
+
key: '0-0-0',
|
|
770
|
+
label: 'workflows',
|
|
771
|
+
data: 'workflows folder',
|
|
772
|
+
icon: Folder,
|
|
773
|
+
children: [
|
|
774
|
+
{
|
|
775
|
+
key: '0-0-0-0',
|
|
776
|
+
label: 'node.js.yml',
|
|
777
|
+
data: 'node.js.yml file',
|
|
778
|
+
icon: File
|
|
779
|
+
}
|
|
780
|
+
]
|
|
781
|
+
}
|
|
782
|
+
]
|
|
783
|
+
},
|
|
784
|
+
{
|
|
785
|
+
key: '0-1',
|
|
786
|
+
label: '.vscode',
|
|
787
|
+
data: '.vscode folder',
|
|
788
|
+
icon: Folder,
|
|
789
|
+
children: [
|
|
790
|
+
{
|
|
791
|
+
key: '0-1-0',
|
|
792
|
+
label: 'extensions.json',
|
|
793
|
+
data: 'extensions.json file',
|
|
794
|
+
icon: File
|
|
795
|
+
}
|
|
796
|
+
]
|
|
797
|
+
},
|
|
798
|
+
{
|
|
799
|
+
key: '0-2',
|
|
800
|
+
label: 'public',
|
|
801
|
+
data: 'public folder',
|
|
802
|
+
icon: Folder,
|
|
803
|
+
children: [
|
|
804
|
+
{
|
|
805
|
+
key: '0-2-0',
|
|
806
|
+
label: 'vite.svg',
|
|
807
|
+
data: 'vite.svg file',
|
|
808
|
+
icon: File
|
|
809
|
+
}
|
|
810
|
+
]
|
|
811
|
+
},
|
|
812
|
+
{
|
|
813
|
+
key: '0-3',
|
|
814
|
+
label: 'src',
|
|
815
|
+
data: 'src folder',
|
|
816
|
+
icon: Folder,
|
|
817
|
+
children: [
|
|
818
|
+
{
|
|
819
|
+
key: '0-3-0',
|
|
820
|
+
label: 'assets',
|
|
821
|
+
data: 'assets folder',
|
|
822
|
+
icon: Folder,
|
|
823
|
+
children: [
|
|
824
|
+
{
|
|
825
|
+
key: '0-3-0-0',
|
|
826
|
+
label: 'vue.svg',
|
|
827
|
+
data: 'vue.svg file',
|
|
828
|
+
icon: File
|
|
829
|
+
}
|
|
830
|
+
]
|
|
831
|
+
},
|
|
832
|
+
{
|
|
833
|
+
key: '0-3-1',
|
|
834
|
+
label: 'components',
|
|
835
|
+
data: 'components folder',
|
|
836
|
+
icon: Folder,
|
|
837
|
+
children: [
|
|
838
|
+
{
|
|
839
|
+
key: '0-3-1-0',
|
|
840
|
+
label: 'HelloWorld.vue',
|
|
841
|
+
data: 'HelloWorld.vue file',
|
|
842
|
+
icon: File
|
|
843
|
+
}
|
|
844
|
+
]
|
|
845
|
+
},
|
|
846
|
+
{
|
|
847
|
+
key: '0-3-2',
|
|
848
|
+
label: 'App.vue',
|
|
849
|
+
data: 'App.vue file',
|
|
850
|
+
icon: File
|
|
851
|
+
},
|
|
852
|
+
{
|
|
853
|
+
key: '0-3-3',
|
|
854
|
+
label: 'main.js',
|
|
855
|
+
data: 'main.js file',
|
|
856
|
+
icon: File
|
|
857
|
+
},
|
|
858
|
+
{
|
|
859
|
+
key: '0-3-4',
|
|
860
|
+
label: 'style.css',
|
|
861
|
+
data: 'style.css file',
|
|
862
|
+
icon: File
|
|
863
|
+
}
|
|
864
|
+
]
|
|
865
|
+
},
|
|
866
|
+
{
|
|
867
|
+
key: '0-4',
|
|
868
|
+
label: 'index.html',
|
|
869
|
+
data: 'index.html file',
|
|
870
|
+
icon: File
|
|
871
|
+
},
|
|
872
|
+
{
|
|
873
|
+
key: '0-5',
|
|
874
|
+
label: 'package.json',
|
|
875
|
+
data: 'package.json file',
|
|
876
|
+
icon: File
|
|
877
|
+
},
|
|
878
|
+
{
|
|
879
|
+
key: '0-6',
|
|
880
|
+
label: 'vite.config.js',
|
|
881
|
+
data: 'vite.config.js file',
|
|
882
|
+
icon: File
|
|
883
|
+
}
|
|
884
|
+
]);
|
|
885
|
+
|
|
886
|
+
const value2 = ref([
|
|
887
|
+
{
|
|
888
|
+
key: '1-0',
|
|
889
|
+
label: '/etc',
|
|
890
|
+
icon: Folder
|
|
891
|
+
}
|
|
892
|
+
]);
|
|
893
|
+
|
|
894
|
+
const value3 = ref([]);
|
|
895
|
+
|
|
896
|
+
<\/script>
|
|
897
|
+
```
|
|
898
|
+
|
|
899
|
+
## Events
|
|
900
|
+
|
|
901
|
+
An event is provided for each type of user interaction such as expand, collapse and selection.
|
|
902
|
+
|
|
903
|
+
```vue
|
|
904
|
+
<template>
|
|
905
|
+
<div>
|
|
906
|
+
<Toast />
|
|
907
|
+
<Tree v-model:selectionKeys="selectedKey" :value="nodes" selectionMode="single" :metaKeySelection="false"
|
|
908
|
+
@nodeSelect="onNodeSelect" @nodeUnselect="onNodeUnselect" @nodeExpand="onNodeExpand" @nodeCollapse="onNodeCollapse" class="w-full md:w-120"></Tree>
|
|
909
|
+
</div>
|
|
910
|
+
</template>
|
|
911
|
+
|
|
912
|
+
<script setup>
|
|
913
|
+
import { ref, onMounted } from 'vue';
|
|
914
|
+
import { NodeService } from '@/service/NodeService';
|
|
915
|
+
import { useToast } from "primevue/usetoast";
|
|
916
|
+
|
|
917
|
+
const nodes = ref(null);
|
|
918
|
+
const selectedKey = ref(null);
|
|
919
|
+
const toast = useToast();
|
|
920
|
+
|
|
921
|
+
onMounted(() => {
|
|
922
|
+
NodeService.getTreeNodes().then((data) => (nodes.value = data));
|
|
923
|
+
});
|
|
924
|
+
|
|
925
|
+
const onNodeSelect = (node) => {
|
|
926
|
+
toast.add({ severity: 'success', summary: 'Node Selected', detail: node.label, life: 3000 });
|
|
927
|
+
};
|
|
928
|
+
|
|
929
|
+
const onNodeUnselect = (node) => {
|
|
930
|
+
toast.add({ severity: 'warn', summary: 'Node Unselected', detail: node.label, life: 3000 });
|
|
931
|
+
};
|
|
932
|
+
|
|
933
|
+
const onNodeExpand = (node) => {
|
|
934
|
+
toast.add({ severity: 'info', summary: 'Node Expanded', detail: node.label, life: 3000 });
|
|
935
|
+
};
|
|
936
|
+
|
|
937
|
+
const onNodeCollapse = (node) => {
|
|
938
|
+
toast.add({ severity: 'info', summary: 'Node Collapsed', detail: node.label, life: 3000 });
|
|
939
|
+
};
|
|
940
|
+
<\/script>
|
|
941
|
+
```
|
|
942
|
+
|
|
943
|
+
## Accessibility
|
|
944
|
+
|
|
945
|
+
Screen Reader Value to describe the component can either be provided with aria-labelledby or aria-label props. The root list element has a tree role whereas each list item has a treeitem role along with aria-label , aria-selected and aria-expanded attributes. In checkbox selection, aria-checked is used instead of aria-selected . The container element of a treenode has the group role. Checkbox and toggle icons are hidden from screen readers as their parent element with treeitem role and attributes are used instead for readers and keyboard support. The aria-setsize , aria-posinset and aria-level attributes are calculated implicitly and added to each treeitem. Keyboard Support Key Function tab Moves focus to the first selected node when focus enters the component, if there is none then first element receives the focus. If focus is already inside the component, moves focus to the next focusable element in the page tab sequence. shift + tab Moves focus to the last selected node when focus enters the component, if there is none then first element receives the focus. If focus is already inside the component, moves focus to the previous focusable element in the page tab sequence. enter Selects the focused treenode. space Selects the focused treenode. down arrow Moves focus to the next treenode. up arrow Moves focus to the previous treenode. right arrow If node is closed, opens the node otherwise moves focus to the first child node. left arrow If node is open, closes the node otherwise moves focus to the parent node.
|
|
946
|
+
|
|
947
|
+
## Tree API
|
|
948
|
+
|
|
949
|
+
### Props
|
|
950
|
+
|
|
951
|
+
| Name |Type |Default |Description |
|
|
952
|
+
| --- | --- | --- | --- |
|
|
953
|
+
| value | TreeNode[] | - | An array of treenodes. |
|
|
954
|
+
| expandedKeys | TreeExpandedKeys | - | A map of keys to represent the expansion state in controlled mode. |
|
|
955
|
+
| selectionKeys | TreeSelectionKeys | - | A map of keys to control the selection state. |
|
|
956
|
+
| selectionMode | HintedString<"single" \| "multiple" \| "checkbox"> | - | Defines the selection mode. |
|
|
957
|
+
| metaKeySelection | boolean | false | Defines how multiple items can be selected, when true metaKey needs to be pressed to select or unselect an item and when set to false selection of each item can be toggled individually. On touch enabled devices, metaKeySelection is turned off automatically. |
|
|
958
|
+
| loading | boolean | false | Whether to display loading indicator. |
|
|
959
|
+
| loadingIcon | string | - | Icon to display when tree is loading. |
|
|
960
|
+
| loadingMode | HintedString<"icon" \| "mask"> | mask | Loading mode display. |
|
|
961
|
+
| filter | boolean | false | When specified, displays an input field to filter the items. |
|
|
962
|
+
| filterBy | string \| Function | label | When filtering is enabled, filterBy decides which field or fields (comma separated) to search against. A callable taking a TreeNode can be provided instead of a list of field names. |
|
|
963
|
+
| filterMode | HintedString<"lenient" \| "strict"> | lenient | Mode for filtering. |
|
|
964
|
+
| filterPlaceholder | string | - | Placeholder text to show when filter input is empty. |
|
|
965
|
+
| filterLocale | string | - | Locale to use in filtering. The default locale is the host environment's current locale. |
|
|
966
|
+
| highlightOnSelect | boolean | false | Highlights automatically the first item. |
|
|
967
|
+
| scrollHeight | HintedString<"flex"> | - | Height of the scroll viewport in fixed units or the 'flex' keyword for a dynamic size. |
|
|
968
|
+
| draggableNodes | boolean | null | Whether the nodes are draggable. |
|
|
969
|
+
| droppableNodes | boolean | null | Whether the nodes are droppable. |
|
|
970
|
+
| draggableScope | string \| string[] | null | Scope of the draggable nodes to match a droppableScope. |
|
|
971
|
+
| droppableScope | string \| string[] | null | Scope of the droppable nodes to match a draggableScope. |
|
|
972
|
+
| validateDrop | boolean | false | When enabled, drop can be accepted or rejected based on condition defined at node-drop. |
|
|
973
|
+
| ariaLabel | string | - | Defines a string value that labels an interactive element. |
|
|
974
|
+
| ariaLabelledby | string | - | Identifier of the underlying menu element. |
|
|
975
|
+
| dt | any | - | It generates scoped CSS variables using design tokens for the component. |
|
|
976
|
+
| pt | PassThrough<TreePassThroughOptions<any>> | - | Used to pass attributes to DOM elements inside the component. |
|
|
977
|
+
| ptOptions | any | - | Used to configure passthrough(pt) options of the component. |
|
|
978
|
+
| unstyled | boolean | false | When enabled, it removes component related styles in the core. |
|
|
979
|
+
|
|
980
|
+
### Slots
|
|
981
|
+
|
|
982
|
+
| Name |Parameters |Description |
|
|
983
|
+
| --- | --- | --- |
|
|
984
|
+
| [key: string] | Function | |
|
|
985
|
+
|
|
986
|
+
### Pass Through Options
|
|
987
|
+
|
|
988
|
+
| Name |Type |Description |
|
|
989
|
+
| --- | --- | --- |
|
|
990
|
+
| root | TreePassThroughOptionType<T> | Used to pass attributes to the root's DOM element. |
|
|
991
|
+
| pcFilterContainer | any | Used to pass attributes to the IconField component. |
|
|
992
|
+
| pcFilterInput | any | Used to pass attributes to the InputText component. |
|
|
993
|
+
| pcFilterIconContainer | any | Used to pass attributes to the InputIcon component. |
|
|
994
|
+
| filterIcon | TreePassThroughOptionType<T> | Used to pass attributes to the filter icon's DOM element. |
|
|
995
|
+
| wrapper | TreePassThroughOptionType<T> | Used to pass attributes to the wrapper's DOM element. |
|
|
996
|
+
| rootChildren | TreePassThroughOptionType<T> | Used to pass attributes to the root children's DOM element. |
|
|
997
|
+
| node | TreePassThroughOptionType<T> | Used to pass attributes to the node's DOM element. |
|
|
998
|
+
| nodeContent | TreePassThroughOptionType<T> | Used to pass attributes to the node content's DOM element. |
|
|
999
|
+
| nodeToggleButton | TreePassThroughOptionType<T> | Used to pass attributes to the node toggle button's DOM element. |
|
|
1000
|
+
| nodeToggleIcon | TreePassThroughOptionType<T> | Used to pass attributes to the node toggle icon's DOM element. |
|
|
1001
|
+
| pcNodeCheckbox | TreePassThroughOptionType<T> | Used to pass attributes to the checkbox's DOM element. |
|
|
1002
|
+
| nodeIcon | TreePassThroughOptionType<T> | Used to pass attributes to the node icon's DOM element. |
|
|
1003
|
+
| nodeLabel | TreePassThroughOptionType<T> | Used to pass attributes to the node label's DOM element. |
|
|
1004
|
+
| nodeChildren | TreePassThroughOptionType<T> | Used to pass attributes to the node children's DOM element. |
|
|
1005
|
+
| mask | TreePassThroughOptionType<T> | Used to pass attributes to the mask's DOM element. |
|
|
1006
|
+
| loadingIcon | TreePassThroughOptionType<T> | Used to pass attributes to the loading icon's DOM element. |
|
|
1007
|
+
| emptyMessage | TreePassThroughOptionType<T> | Used to pass attributes to the empty message's DOM element. |
|
|
1008
|
+
| dropPoint | TreePassThroughOptionType<T> | Used to pass attributes to the drop point's DOM element. |
|
|
1009
|
+
| hooks | any | Used to manage all lifecycle hooks. |
|
|
1010
|
+
|
|
1011
|
+
### Theming
|
|
1012
|
+
|
|
1013
|
+
### CSS Classes
|
|
1014
|
+
|
|
1015
|
+
| Class |Description |
|
|
1016
|
+
| --- | --- |
|
|
1017
|
+
| p-tree | Class name of the root element |
|
|
1018
|
+
| p-tree-mask | Class name of the mask element |
|
|
1019
|
+
| p-tree-loading-icon | Class name of the loading icon element |
|
|
1020
|
+
| p-tree-filter-input | Class name of the filter input element |
|
|
1021
|
+
| p-tree-root | Class name of the wrapper element |
|
|
1022
|
+
| p-tree-root-children | Class name of the root children element |
|
|
1023
|
+
| p-tree-node | Class name of the node element |
|
|
1024
|
+
| p-tree-node-content | Class name of the node content element |
|
|
1025
|
+
| p-tree-node-toggle-button | Class name of the node toggle button element |
|
|
1026
|
+
| p-tree-node-toggle-icon | Class name of the node toggle icon element |
|
|
1027
|
+
| p-tree-node-checkbox | Class name of the node checkbox element |
|
|
1028
|
+
| p-tree-node-icon | Class name of the node icon element |
|
|
1029
|
+
| p-tree-node-label | Class name of the node label element |
|
|
1030
|
+
| p-tree-node-children | Class name of the node children element |
|
|
1031
|
+
|
|
1032
|
+
### Design Tokens
|
|
1033
|
+
|
|
1034
|
+
| Token |CSS Variable |Description |
|
|
1035
|
+
| --- | --- | --- |
|
|
1036
|
+
| tree.background | --p-tree-background | Background of root |
|
|
1037
|
+
| tree.color | --p-tree-color | Color of root |
|
|
1038
|
+
| tree.padding | --p-tree-padding | Padding of root |
|
|
1039
|
+
| tree.gap | --p-tree-gap | Gap of root |
|
|
1040
|
+
| tree.indent | --p-tree-indent | Indent of root |
|
|
1041
|
+
| tree.transition.duration | --p-tree-transition-duration | Transition duration of root |
|
|
1042
|
+
| tree.node.padding | --p-tree-node-padding | Padding of node |
|
|
1043
|
+
| tree.node.border.radius | --p-tree-node-border-radius | Border radius of node |
|
|
1044
|
+
| tree.node.hover.background | --p-tree-node-hover-background | Hover background of node |
|
|
1045
|
+
| tree.node.selected.background | --p-tree-node-selected-background | Selected background of node |
|
|
1046
|
+
| tree.node.color | --p-tree-node-color | Color of node |
|
|
1047
|
+
| tree.node.hover.color | --p-tree-node-hover-color | Hover color of node |
|
|
1048
|
+
| tree.node.selected.color | --p-tree-node-selected-color | Selected color of node |
|
|
1049
|
+
| tree.node.focus.ring.width | --p-tree-node-focus-ring-width | Focus ring width of node |
|
|
1050
|
+
| tree.node.focus.ring.style | --p-tree-node-focus-ring-style | Focus ring style of node |
|
|
1051
|
+
| tree.node.focus.ring.color | --p-tree-node-focus-ring-color | Focus ring color of node |
|
|
1052
|
+
| tree.node.focus.ring.offset | --p-tree-node-focus-ring-offset | Focus ring offset of node |
|
|
1053
|
+
| tree.node.focus.ring.shadow | --p-tree-node-focus-ring-shadow | Focus ring shadow of node |
|
|
1054
|
+
| tree.node.gap | --p-tree-node-gap | Gap of node |
|
|
1055
|
+
| tree.node.icon.color | --p-tree-node-icon-color | Color of node icon |
|
|
1056
|
+
| tree.node.icon.hover.color | --p-tree-node-icon-hover-color | Hover color of node icon |
|
|
1057
|
+
| tree.node.icon.selected.color | --p-tree-node-icon-selected-color | Selected color of node icon |
|
|
1058
|
+
| tree.node.label.font.weight | --p-tree-node-label-font-weight | Font weight of node label |
|
|
1059
|
+
| tree.node.label.font.size | --p-tree-node-label-font-size | Font size of node label |
|
|
1060
|
+
| tree.node.label.selected.font.weight | --p-tree-node-label-selected-font-weight | Font weight of a selected node label |
|
|
1061
|
+
| tree.node.toggle.button.border.radius | --p-tree-node-toggle-button-border-radius | Border radius of node toggle button |
|
|
1062
|
+
| tree.node.toggle.button.size | --p-tree-node-toggle-button-size | Size of node toggle button |
|
|
1063
|
+
| tree.node.toggle.button.hover.background | --p-tree-node-toggle-button-hover-background | Hover background of node toggle button |
|
|
1064
|
+
| tree.node.toggle.button.selected.hover.background | --p-tree-node-toggle-button-selected-hover-background | Selected hover background of node toggle button |
|
|
1065
|
+
| tree.node.toggle.button.color | --p-tree-node-toggle-button-color | Color of node toggle button |
|
|
1066
|
+
| tree.node.toggle.button.hover.color | --p-tree-node-toggle-button-hover-color | Hover color of node toggle button |
|
|
1067
|
+
| tree.node.toggle.button.selected.hover.color | --p-tree-node-toggle-button-selected-hover-color | Selected hover color of node toggle button |
|
|
1068
|
+
| tree.node.toggle.button.focus.ring.width | --p-tree-node-toggle-button-focus-ring-width | Focus ring width of node toggle button |
|
|
1069
|
+
| tree.node.toggle.button.focus.ring.style | --p-tree-node-toggle-button-focus-ring-style | Focus ring style of node toggle button |
|
|
1070
|
+
| tree.node.toggle.button.focus.ring.color | --p-tree-node-toggle-button-focus-ring-color | Focus ring color of node toggle button |
|
|
1071
|
+
| tree.node.toggle.button.focus.ring.offset | --p-tree-node-toggle-button-focus-ring-offset | Focus ring offset of node toggle button |
|
|
1072
|
+
| tree.node.toggle.button.focus.ring.shadow | --p-tree-node-toggle-button-focus-ring-shadow | Focus ring shadow of node toggle button |
|
|
1073
|
+
| tree.loading.icon.size | --p-tree-loading-icon-size | Size of loading icon |
|
|
1074
|
+
| tree.filter.margin | --p-tree-filter-margin | Margin of filter |
|
|
1075
|
+
|
|
1076
|
+
## Tree Node API
|