primevue 4.3.8 → 4.4.0
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/autocomplete/AutoComplete.vue +18 -3
- package/autocomplete/BaseAutoComplete.vue +4 -0
- package/autocomplete/index.d.ts +20 -0
- package/autocomplete/index.mjs +34 -7
- package/autocomplete/index.mjs.map +1 -1
- package/autocomplete/style/index.d.ts +4 -0
- package/autocomplete/style/index.mjs +3 -1
- package/autocomplete/style/index.mjs.map +1 -1
- package/cascadeselect/CascadeSelect.vue +1 -1
- package/cascadeselect/index.mjs +1 -1
- package/cascadeselect/index.mjs.map +1 -1
- package/checkbox/Checkbox.vue +15 -2
- package/checkbox/index.mjs +14 -2
- package/checkbox/index.mjs.map +1 -1
- package/colorpicker/ColorPicker.vue +5 -6
- package/colorpicker/index.mjs +5 -5
- package/colorpicker/index.mjs.map +1 -1
- package/column/index.d.ts +2 -2
- package/confirmdialog/ConfirmDialog.vue +1 -1
- package/confirmdialog/index.d.ts +5 -0
- package/confirmdialog/index.mjs +3 -2
- package/confirmdialog/index.mjs.map +1 -1
- package/datatable/BodyCell.vue +1 -1
- package/datatable/ColumnFilter.vue +1 -1
- package/datatable/DataTable.vue +6 -3
- package/datatable/HeaderCheckbox.vue +3 -3
- package/datatable/index.mjs +19 -9
- package/datatable/index.mjs.map +1 -1
- package/datepicker/BaseDatePicker.vue +8 -0
- package/datepicker/DatePicker.vue +200 -82
- package/datepicker/index.d.ts +25 -0
- package/datepicker/index.mjs +263 -155
- package/datepicker/index.mjs.map +1 -1
- package/datepicker/style/index.d.ts +4 -0
- package/datepicker/style/index.mjs +5 -2
- package/datepicker/style/index.mjs.map +1 -1
- package/dialog/Dialog.vue +1 -1
- package/dialog/index.d.ts +5 -0
- package/dialog/index.mjs +2 -1
- package/dialog/index.mjs.map +1 -1
- package/drawer/BaseDrawer.vue +4 -0
- package/drawer/Drawer.vue +4 -4
- package/drawer/index.d.ts +5 -0
- package/drawer/index.mjs +8 -4
- package/drawer/index.mjs.map +1 -1
- package/editor/Editor.vue +5 -1
- package/editor/index.mjs +5 -0
- package/editor/index.mjs.map +1 -1
- package/fileupload/FileUpload.vue +2 -2
- package/fileupload/index.mjs +2 -2
- package/fileupload/index.mjs.map +1 -1
- package/image/index.d.ts +5 -11
- package/inputmask/InputMask.vue +1 -2
- package/inputmask/index.mjs +1 -1
- package/inputmask/index.mjs.map +1 -1
- package/inputnumber/BaseInputNumber.vue +4 -0
- package/inputnumber/InputNumber.vue +33 -5
- package/inputnumber/index.d.ts +20 -0
- package/inputnumber/index.mjs +48 -7
- package/inputnumber/index.mjs.map +1 -1
- package/inputnumber/style/index.mjs +1 -0
- package/inputnumber/style/index.mjs.map +1 -1
- package/inputotp/InputOtp.vue +7 -3
- package/inputotp/index.mjs +6 -3
- package/inputotp/index.mjs.map +1 -1
- package/keyfilter/index.mjs +14 -1
- package/keyfilter/index.mjs.map +1 -1
- package/listbox/Listbox.vue +8 -14
- package/listbox/index.mjs +13 -19
- package/listbox/index.mjs.map +1 -1
- package/multiselect/MultiSelect.vue +15 -12
- package/multiselect/index.mjs +21 -18
- package/multiselect/index.mjs.map +1 -1
- package/package.json +5 -5
- package/panel/Panel.vue +1 -1
- package/panel/index.d.ts +4 -0
- package/panel/index.mjs +2 -1
- package/panel/index.mjs.map +1 -1
- package/password/BasePassword.vue +4 -0
- package/password/Password.vue +12 -1
- package/password/index.d.ts +20 -0
- package/password/index.mjs +23 -1
- package/password/index.mjs.map +1 -1
- package/password/style/index.d.ts +4 -0
- package/password/style/index.mjs +1 -0
- package/password/style/index.mjs.map +1 -1
- package/select/Select.vue +5 -4
- package/select/index.mjs +6 -5
- package/select/index.mjs.map +1 -1
- package/tab/Tab.vue +0 -1
- package/tab/index.mjs +0 -1
- package/tab/index.mjs.map +1 -1
- package/togglebutton/BaseToggleButton.vue +0 -4
- package/togglebutton/index.d.ts +0 -5
- package/togglebutton/index.mjs +0 -4
- package/togglebutton/index.mjs.map +1 -1
- package/tooltip/index.mjs +5 -1
- package/tooltip/index.mjs.map +1 -1
- package/tree/BaseTree.vue +16 -0
- package/tree/Tree.vue +179 -4
- package/tree/TreeNode.vue +225 -3
- package/tree/index.d.ts +65 -0
- package/tree/index.mjs +499 -22
- package/tree/index.mjs.map +1 -1
- package/tree/style/index.mjs +9 -4
- package/tree/style/index.mjs.map +1 -1
- package/treenode/index.d.ts +12 -0
- package/treeselect/TreeSelect.vue +2 -2
- package/treeselect/index.mjs +2 -2
- package/treeselect/index.mjs.map +1 -1
- package/treetable/TreeTable.vue +15 -1
- package/treetable/index.d.ts +58 -4
- package/treetable/index.mjs +19 -6
- package/treetable/index.mjs.map +1 -1
- package/umd/primevue.min.js +1 -1
- package/vetur-attributes.json +0 -4
- package/vetur-tags.json +0 -1
- package/web-types.json +1 -11
package/tree/Tree.vue
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<div :class="cx('root')" :data-p="containerDataP" v-bind="ptmi('root')">
|
|
2
|
+
<div :class="cx('root')" @dragover="onDragOver" @dragenter="onDragEnter" @dragleave="onDragLeave" @drop="onDrop" :data-p="containerDataP" v-bind="ptmi('root')">
|
|
3
3
|
<template v-if="loading && loadingMode === 'mask'">
|
|
4
4
|
<div :class="cx('mask')" v-bind="ptm('mask')">
|
|
5
5
|
<slot name="loadingicon" :class="cx('loadingIcon')">
|
|
@@ -19,11 +19,12 @@
|
|
|
19
19
|
</IconField>
|
|
20
20
|
<div :class="cx('wrapper')" :style="{ maxHeight: scrollHeight }" :data-p="wrapperDataP" v-bind="ptm('wrapper')">
|
|
21
21
|
<slot name="header" :value="value" :expandedKeys="expandedKeys" :selectionKeys="selectionKeys" />
|
|
22
|
-
<ul :class="cx('rootChildren')" role="tree" :aria-labelledby="ariaLabelledby" :aria-label="ariaLabel" v-bind="ptm('rootChildren')">
|
|
22
|
+
<ul v-if="!empty" :class="cx('rootChildren')" role="tree" :aria-labelledby="ariaLabelledby" :aria-label="ariaLabel" v-bind="ptm('rootChildren')">
|
|
23
23
|
<TreeNode
|
|
24
24
|
v-for="(node, index) of valueToRender"
|
|
25
25
|
:key="node.key"
|
|
26
26
|
:node="node"
|
|
27
|
+
:rootNodes="valueToRender"
|
|
27
28
|
:templates="$slots"
|
|
28
29
|
:level="level + 1"
|
|
29
30
|
:index="index"
|
|
@@ -34,10 +35,19 @@
|
|
|
34
35
|
:selectionKeys="selectionKeys"
|
|
35
36
|
@checkbox-change="onCheckboxChange"
|
|
36
37
|
:loadingMode="loadingMode"
|
|
38
|
+
:draggableScope="draggableScope"
|
|
39
|
+
:dragdrop="dragdrop"
|
|
40
|
+
:validateDrop="validateDrop"
|
|
41
|
+
@node-drop="onNodeDrop"
|
|
37
42
|
:unstyled="unstyled"
|
|
38
43
|
:pt="pt"
|
|
39
44
|
></TreeNode>
|
|
40
45
|
</ul>
|
|
46
|
+
<div v-else :class="cx('emptyMessage')" v-bind="ptm('emptyMessage')">
|
|
47
|
+
<slot name="empty">
|
|
48
|
+
{{ emptyMessageText }}
|
|
49
|
+
</slot>
|
|
50
|
+
</div>
|
|
41
51
|
<slot name="footer" :value="value" :expandedKeys="expandedKeys" :selectionKeys="selectionKeys" />
|
|
42
52
|
</div>
|
|
43
53
|
</div>
|
|
@@ -52,24 +62,62 @@ import IconField from 'primevue/iconfield';
|
|
|
52
62
|
import InputIcon from 'primevue/inputicon';
|
|
53
63
|
import InputText from 'primevue/inputtext';
|
|
54
64
|
import BaseTree from './BaseTree.vue';
|
|
65
|
+
import { useTreeDragDropService } from './TreeDragDropService';
|
|
55
66
|
import TreeNode from './TreeNode.vue';
|
|
56
67
|
|
|
57
68
|
export default {
|
|
58
69
|
name: 'Tree',
|
|
59
70
|
extends: BaseTree,
|
|
60
71
|
inheritAttrs: false,
|
|
61
|
-
emits: ['node-expand', 'node-collapse', 'update:expandedKeys', 'update:selectionKeys', 'node-select', 'node-unselect', 'filter'],
|
|
72
|
+
emits: ['node-expand', 'node-collapse', 'update:expandedKeys', 'update:selectionKeys', 'node-select', 'node-unselect', 'filter', 'node-drop', 'update:value'],
|
|
62
73
|
data() {
|
|
63
74
|
return {
|
|
64
75
|
d_expandedKeys: this.expandedKeys || {},
|
|
65
|
-
filterValue: null
|
|
76
|
+
filterValue: null,
|
|
77
|
+
dragNode: null,
|
|
78
|
+
dragNodeSubNodes: null,
|
|
79
|
+
dragNodeIndex: null,
|
|
80
|
+
dragNodeScope: null,
|
|
81
|
+
dragHover: null
|
|
66
82
|
};
|
|
67
83
|
},
|
|
84
|
+
dragDropService: null,
|
|
85
|
+
dragStartCleanup: null,
|
|
86
|
+
dragStopCleanup: null,
|
|
68
87
|
watch: {
|
|
69
88
|
expandedKeys(newValue) {
|
|
70
89
|
this.d_expandedKeys = newValue;
|
|
71
90
|
}
|
|
72
91
|
},
|
|
92
|
+
mounted() {
|
|
93
|
+
if (this.dragdrop) {
|
|
94
|
+
this.dragDropService = useTreeDragDropService();
|
|
95
|
+
|
|
96
|
+
this.dragStartCleanup = this.dragDropService.onDragStart((event) => {
|
|
97
|
+
this.dragNode = event.node;
|
|
98
|
+
this.dragNodeSubNodes = event.subNodes;
|
|
99
|
+
this.dragNodeIndex = event.index;
|
|
100
|
+
this.dragNodeScope = event.scope;
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
this.dragStopCleanup = this.dragDropService.onDragStop(() => {
|
|
104
|
+
this.dragNode = null;
|
|
105
|
+
this.dragNodeSubNodes = null;
|
|
106
|
+
this.dragNodeIndex = null;
|
|
107
|
+
this.dragNodeScope = null;
|
|
108
|
+
this.dragHover = false;
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
},
|
|
112
|
+
beforeUnmount() {
|
|
113
|
+
if (this.dragStartCleanup) {
|
|
114
|
+
this.dragStartCleanup();
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
if (this.dragStopCleanup) {
|
|
118
|
+
this.dragStopCleanup();
|
|
119
|
+
}
|
|
120
|
+
},
|
|
73
121
|
methods: {
|
|
74
122
|
onNodeToggle(node) {
|
|
75
123
|
const key = node.key;
|
|
@@ -220,6 +268,127 @@ export default {
|
|
|
220
268
|
}
|
|
221
269
|
|
|
222
270
|
return matched;
|
|
271
|
+
},
|
|
272
|
+
onNodeDrop(event) {
|
|
273
|
+
this.$emit('node-drop', event);
|
|
274
|
+
},
|
|
275
|
+
allowDrop(dragNode, dropNode, dragNodeScope) {
|
|
276
|
+
if (!dragNode) {
|
|
277
|
+
//prevent random html elements to be dragged
|
|
278
|
+
return false;
|
|
279
|
+
} else if (this.isValidDragScope(dragNodeScope)) {
|
|
280
|
+
let allow = true;
|
|
281
|
+
|
|
282
|
+
if (dropNode) {
|
|
283
|
+
if (dragNode === dropNode) {
|
|
284
|
+
allow = false;
|
|
285
|
+
} else {
|
|
286
|
+
let parent = dropNode.parent;
|
|
287
|
+
|
|
288
|
+
while (parent != null) {
|
|
289
|
+
if (parent === dragNode) {
|
|
290
|
+
allow = false;
|
|
291
|
+
|
|
292
|
+
break;
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
parent = parent.parent;
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
return allow;
|
|
301
|
+
} else {
|
|
302
|
+
return false;
|
|
303
|
+
}
|
|
304
|
+
},
|
|
305
|
+
allowNodeDrop(dropNode) {
|
|
306
|
+
return this.allowDrop(this.dragNode, dropNode, this.dragNodeScope);
|
|
307
|
+
},
|
|
308
|
+
isValidDragScope(dragScope) {
|
|
309
|
+
let dropScope = this.droppableScope;
|
|
310
|
+
|
|
311
|
+
if (dropScope !== null) {
|
|
312
|
+
if (typeof dropScope === 'string') {
|
|
313
|
+
if (typeof dragScope === 'string') return dropScope === dragScope;
|
|
314
|
+
else if (Array.isArray(dragScope)) return dragScope.indexOf(dropScope) != -1;
|
|
315
|
+
} else if (Array.isArray(dropScope)) {
|
|
316
|
+
if (typeof dragScope === 'string') {
|
|
317
|
+
return dropScope.indexOf(dragScope) != -1;
|
|
318
|
+
} else if (Array.isArray(dragScope)) {
|
|
319
|
+
for (let s of dropScope) {
|
|
320
|
+
for (let ds of dragScope) {
|
|
321
|
+
if (s === ds) {
|
|
322
|
+
return true;
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
return false;
|
|
329
|
+
} else {
|
|
330
|
+
return true;
|
|
331
|
+
}
|
|
332
|
+
},
|
|
333
|
+
onDragOver(event) {
|
|
334
|
+
if (this.dragdrop && (!this.value || this.value.length === 0)) {
|
|
335
|
+
event.dataTransfer.dropEffect = 'move';
|
|
336
|
+
event.preventDefault();
|
|
337
|
+
}
|
|
338
|
+
},
|
|
339
|
+
onDragEnter() {
|
|
340
|
+
if (this.dragdrop && this.allowDrop(this.dragNode, null, this.dragNodeScope)) {
|
|
341
|
+
this.dragHover = true;
|
|
342
|
+
}
|
|
343
|
+
},
|
|
344
|
+
onDragLeave(event) {
|
|
345
|
+
if (this.dragdrop) {
|
|
346
|
+
let rect = event.currentTarget.getBoundingClientRect();
|
|
347
|
+
|
|
348
|
+
if (event.x > rect.left + rect.width || event.x < rect.left || event.y > rect.top + rect.height || event.y < rect.top) {
|
|
349
|
+
this.dragHover = false;
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
},
|
|
353
|
+
processTreeDrop(dragNode, dragNodeIndex) {
|
|
354
|
+
this.dragNodeSubNodes.splice(dragNodeIndex, 1);
|
|
355
|
+
const newValue = [...(this.value || []), dragNode];
|
|
356
|
+
this.$emit('update:value', newValue);
|
|
357
|
+
|
|
358
|
+
this.dragDropService.stopDrag({
|
|
359
|
+
node: dragNode
|
|
360
|
+
});
|
|
361
|
+
},
|
|
362
|
+
onDrop(event) {
|
|
363
|
+
if (this.dragdrop && (!this.value || this.value.length === 0)) {
|
|
364
|
+
event.preventDefault();
|
|
365
|
+
let dragNode = this.dragNode;
|
|
366
|
+
|
|
367
|
+
if (this.allowDrop(dragNode, null, this.dragNodeScope)) {
|
|
368
|
+
let dragNodeIndex = this.dragNodeIndex;
|
|
369
|
+
|
|
370
|
+
if (this.validateDrop) {
|
|
371
|
+
this.$emit('node-drop', {
|
|
372
|
+
originalEvent: event,
|
|
373
|
+
dragNode: dragNode,
|
|
374
|
+
dropNode: null,
|
|
375
|
+
index: dragNodeIndex,
|
|
376
|
+
accept: () => {
|
|
377
|
+
this.processTreeDrop(dragNode, dragNodeIndex);
|
|
378
|
+
}
|
|
379
|
+
});
|
|
380
|
+
} else {
|
|
381
|
+
this.$emit('node-drop', {
|
|
382
|
+
originalEvent: event,
|
|
383
|
+
dragNode: dragNode,
|
|
384
|
+
dropNode: null,
|
|
385
|
+
index: dragNodeIndex
|
|
386
|
+
});
|
|
387
|
+
|
|
388
|
+
this.processTreeDrop(dragNode, dragNodeIndex);
|
|
389
|
+
}
|
|
390
|
+
}
|
|
391
|
+
}
|
|
223
392
|
}
|
|
224
393
|
},
|
|
225
394
|
computed: {
|
|
@@ -247,6 +416,12 @@ export default {
|
|
|
247
416
|
if (this.filterValue && this.filterValue.trim().length > 0) return this.filteredValue;
|
|
248
417
|
else return this.value;
|
|
249
418
|
},
|
|
419
|
+
empty() {
|
|
420
|
+
return !this.valueToRender || this.valueToRender.length === 0;
|
|
421
|
+
},
|
|
422
|
+
emptyMessageText() {
|
|
423
|
+
return this.$primevue.config?.locale?.emptyMessage || '';
|
|
424
|
+
},
|
|
250
425
|
containerDataP() {
|
|
251
426
|
return cn({
|
|
252
427
|
loading: this.loading,
|
package/tree/TreeNode.vue
CHANGED
|
@@ -14,7 +14,22 @@
|
|
|
14
14
|
@keydown="onKeyDown"
|
|
15
15
|
v-bind="getPTOptions('node')"
|
|
16
16
|
>
|
|
17
|
-
<div
|
|
17
|
+
<div v-if="isPrevDropPointActive" :class="cx('dropPoint')" aria-hidden="true" />
|
|
18
|
+
<div
|
|
19
|
+
:class="cx('nodeContent')"
|
|
20
|
+
:style="node.style"
|
|
21
|
+
:draggable="isDraggable"
|
|
22
|
+
@click="onClick"
|
|
23
|
+
@touchend="onTouchEnd"
|
|
24
|
+
@dragstart="onNodeDragStart"
|
|
25
|
+
@dragover="onNodeDragOver"
|
|
26
|
+
@dragleave="onNodeDragLeave"
|
|
27
|
+
@dragend="onNodeDragEnd"
|
|
28
|
+
@drop="onNodeDrop"
|
|
29
|
+
v-bind="getPTOptions('nodeContent')"
|
|
30
|
+
:data-p-selected="checkboxMode ? checked : selected"
|
|
31
|
+
:data-p-selectable="selectable"
|
|
32
|
+
>
|
|
18
33
|
<button v-ripple type="button" :class="cx('nodeToggleButton')" @click="toggle" tabindex="-1" :data-p-leaf="leaf" v-bind="getPTOptions('nodeToggleButton')">
|
|
19
34
|
<template v-if="node.loading && loadingMode === 'icon'">
|
|
20
35
|
<!-- TODO: nodetogglericon deprecated since v4.0-->
|
|
@@ -50,11 +65,14 @@
|
|
|
50
65
|
<template v-else>{{ label(node) }}</template>
|
|
51
66
|
</span>
|
|
52
67
|
</div>
|
|
68
|
+
<div v-if="isNextDropPointActive" :class="cx('dropPoint')" aria-hidden="true" />
|
|
53
69
|
<ul v-if="hasChildren && expanded" :class="cx('nodeChildren')" role="group" v-bind="ptm('nodeChildren')">
|
|
54
70
|
<TreeNode
|
|
55
71
|
v-for="(childNode, index) of node.children"
|
|
56
72
|
:key="childNode.key"
|
|
57
73
|
:node="childNode"
|
|
74
|
+
:parentNode="node"
|
|
75
|
+
:rootNodes="rootNodes"
|
|
58
76
|
:templates="templates"
|
|
59
77
|
:level="level + 1"
|
|
60
78
|
:index="index"
|
|
@@ -65,6 +83,10 @@
|
|
|
65
83
|
:selectionMode="selectionMode"
|
|
66
84
|
:selectionKeys="selectionKeys"
|
|
67
85
|
@checkbox-change="propagateUp"
|
|
86
|
+
:draggableScope="draggableScope"
|
|
87
|
+
:dragdrop="dragdrop"
|
|
88
|
+
:validateDrop="validateDrop"
|
|
89
|
+
@node-drop="onChildNodeDrop"
|
|
68
90
|
:unstyled="unstyled"
|
|
69
91
|
:pt="pt"
|
|
70
92
|
/>
|
|
@@ -73,7 +95,7 @@
|
|
|
73
95
|
</template>
|
|
74
96
|
|
|
75
97
|
<script>
|
|
76
|
-
import { find, findSingle, getAttribute } from '@primeuix/utils
|
|
98
|
+
import { find, findSingle, getAttribute, getOuterHeight, getOuterWidth } from '@primeuix/utils';
|
|
77
99
|
import BaseComponent from '@primevue/core/basecomponent';
|
|
78
100
|
import CheckIcon from '@primevue/icons/check';
|
|
79
101
|
import ChevronDownIcon from '@primevue/icons/chevrondown';
|
|
@@ -87,12 +109,20 @@ export default {
|
|
|
87
109
|
name: 'TreeNode',
|
|
88
110
|
hostName: 'Tree',
|
|
89
111
|
extends: BaseComponent,
|
|
90
|
-
emits: ['node-toggle', 'node-click', 'checkbox-change'],
|
|
112
|
+
emits: ['node-toggle', 'node-click', 'checkbox-change', 'node-drop'],
|
|
91
113
|
props: {
|
|
92
114
|
node: {
|
|
93
115
|
type: null,
|
|
94
116
|
default: null
|
|
95
117
|
},
|
|
118
|
+
parentNode: {
|
|
119
|
+
type: null,
|
|
120
|
+
default: null
|
|
121
|
+
},
|
|
122
|
+
rootNodes: {
|
|
123
|
+
type: Array,
|
|
124
|
+
default: null
|
|
125
|
+
},
|
|
96
126
|
expandedKeys: {
|
|
97
127
|
type: null,
|
|
98
128
|
default: null
|
|
@@ -117,10 +147,34 @@ export default {
|
|
|
117
147
|
type: Number,
|
|
118
148
|
default: null
|
|
119
149
|
},
|
|
150
|
+
draggableScope: {
|
|
151
|
+
type: [String, Array],
|
|
152
|
+
default: null
|
|
153
|
+
},
|
|
154
|
+
dragdrop: {
|
|
155
|
+
type: Boolean,
|
|
156
|
+
default: null
|
|
157
|
+
},
|
|
158
|
+
validateDrop: {
|
|
159
|
+
type: Boolean,
|
|
160
|
+
default: false
|
|
161
|
+
},
|
|
120
162
|
index: null
|
|
121
163
|
},
|
|
122
164
|
nodeTouched: false,
|
|
123
165
|
toggleClicked: false,
|
|
166
|
+
inject: {
|
|
167
|
+
$pcTree: {
|
|
168
|
+
default: undefined
|
|
169
|
+
}
|
|
170
|
+
},
|
|
171
|
+
data() {
|
|
172
|
+
return {
|
|
173
|
+
isPrevDropPointHovered: false,
|
|
174
|
+
isNextDropPointHovered: false,
|
|
175
|
+
isNodeDropHovered: false
|
|
176
|
+
};
|
|
177
|
+
},
|
|
124
178
|
mounted() {
|
|
125
179
|
this.setAllNodesTabIndexes();
|
|
126
180
|
},
|
|
@@ -288,6 +342,147 @@ export default {
|
|
|
288
342
|
onTabKey() {
|
|
289
343
|
this.setAllNodesTabIndexes();
|
|
290
344
|
},
|
|
345
|
+
onChildNodeDrop(event) {
|
|
346
|
+
this.$emit('node-click', event);
|
|
347
|
+
},
|
|
348
|
+
insertNodeOnDrop() {
|
|
349
|
+
const { dragNode, dragNodeIndex, dragNodeSubNodes, dragDropService } = this.$pcTree;
|
|
350
|
+
|
|
351
|
+
if (!this.node || dragNodeIndex == null || !dragNode || !dragNodeSubNodes) {
|
|
352
|
+
return;
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
const position = this.dropPosition;
|
|
356
|
+
const subNodes = this.subNodes || [];
|
|
357
|
+
const index = this.index || 0;
|
|
358
|
+
const dropIndex = dragNodeSubNodes === subNodes ? (dragNodeIndex > index ? index : index - 1) : index;
|
|
359
|
+
|
|
360
|
+
dragNodeSubNodes.splice(dragNodeIndex, 1);
|
|
361
|
+
|
|
362
|
+
if (position < 0) {
|
|
363
|
+
// insert before a Node
|
|
364
|
+
subNodes.splice(dropIndex, 0, dragNode);
|
|
365
|
+
} else if (position > 0) {
|
|
366
|
+
// insert after a Node
|
|
367
|
+
subNodes.splice(dropIndex + 1, 0, dragNode);
|
|
368
|
+
} else {
|
|
369
|
+
// insert as child of a Node
|
|
370
|
+
this.node.children = this.node.children || [];
|
|
371
|
+
this.node.children.push(dragNode);
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
dragDropService.stopDrag({
|
|
375
|
+
node: dragNode,
|
|
376
|
+
subNodes,
|
|
377
|
+
index: dragNodeIndex
|
|
378
|
+
});
|
|
379
|
+
},
|
|
380
|
+
onNodeDrop(event) {
|
|
381
|
+
event.preventDefault();
|
|
382
|
+
event.stopPropagation();
|
|
383
|
+
|
|
384
|
+
if (this.isDroppable) {
|
|
385
|
+
const { dragNode } = this.$pcTree;
|
|
386
|
+
const position = this.dropPosition;
|
|
387
|
+
const isValidDrop = position !== 0 || (position === 0 && this.isNodeDroppable);
|
|
388
|
+
|
|
389
|
+
if (isValidDrop) {
|
|
390
|
+
if (this.validateDrop) {
|
|
391
|
+
this.$emit('node-drop', {
|
|
392
|
+
originalEvent: event,
|
|
393
|
+
dragNode: dragNode,
|
|
394
|
+
dropNode: this.node,
|
|
395
|
+
index: this.index,
|
|
396
|
+
accept: () => {
|
|
397
|
+
this.insertNodeOnDrop();
|
|
398
|
+
}
|
|
399
|
+
});
|
|
400
|
+
} else {
|
|
401
|
+
this.insertNodeOnDrop();
|
|
402
|
+
this.$emit('node-drop', {
|
|
403
|
+
originalEvent: event,
|
|
404
|
+
dragNode: dragNode,
|
|
405
|
+
dropNode: this.node,
|
|
406
|
+
index: this.index
|
|
407
|
+
});
|
|
408
|
+
}
|
|
409
|
+
}
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
this.isPrevDropPointHovered = false;
|
|
413
|
+
this.isNextDropPointHovered = false;
|
|
414
|
+
this.isNodeDropHovered = false;
|
|
415
|
+
},
|
|
416
|
+
onNodeDragStart(event) {
|
|
417
|
+
if (this.isNodeDraggable) {
|
|
418
|
+
event.dataTransfer?.setData('text', 'data');
|
|
419
|
+
|
|
420
|
+
const target = event.currentTarget;
|
|
421
|
+
const dragEl = target.cloneNode(true);
|
|
422
|
+
const toggler = dragEl.querySelector('[data-pc-section="nodetogglebutton"]');
|
|
423
|
+
const checkbox = dragEl.querySelector('[data-pc-name="pcnodecheckbox"]');
|
|
424
|
+
|
|
425
|
+
target.setAttribute('data-p-dragging', 'true');
|
|
426
|
+
dragEl.style.width = getOuterWidth(target) + 'px';
|
|
427
|
+
dragEl.style.height = getOuterHeight(target) + 'px';
|
|
428
|
+
dragEl.setAttribute('data-pc-section', 'drag-image');
|
|
429
|
+
toggler.style.visibility = 'hidden';
|
|
430
|
+
checkbox?.remove();
|
|
431
|
+
document.body.appendChild(dragEl);
|
|
432
|
+
event.dataTransfer?.setDragImage(dragEl, 0, 0);
|
|
433
|
+
|
|
434
|
+
setTimeout(() => document.body.removeChild(dragEl), 0);
|
|
435
|
+
|
|
436
|
+
this.$pcTree.dragDropService.startDrag({
|
|
437
|
+
node: this.node,
|
|
438
|
+
subNodes: this.subNodes,
|
|
439
|
+
index: this.index,
|
|
440
|
+
scope: this.draggableScope
|
|
441
|
+
});
|
|
442
|
+
} else {
|
|
443
|
+
event.preventDefault();
|
|
444
|
+
}
|
|
445
|
+
},
|
|
446
|
+
onNodeDragOver(event) {
|
|
447
|
+
event.dataTransfer.dropEffect = 'move';
|
|
448
|
+
|
|
449
|
+
if (this.isDroppable) {
|
|
450
|
+
const nodeElement = event.currentTarget;
|
|
451
|
+
const rect = nodeElement.getBoundingClientRect();
|
|
452
|
+
const y = event.clientY - rect.top;
|
|
453
|
+
|
|
454
|
+
this.isPrevDropPointHovered = false;
|
|
455
|
+
this.isNextDropPointHovered = false;
|
|
456
|
+
this.isNodeDropHovered = false;
|
|
457
|
+
|
|
458
|
+
if (y < rect.height * 0.25) {
|
|
459
|
+
this.isPrevDropPointHovered = true;
|
|
460
|
+
} else if (y > rect.height * 0.75) {
|
|
461
|
+
this.isNextDropPointHovered = true;
|
|
462
|
+
} else if (this.isNodeDroppable) {
|
|
463
|
+
this.isNodeDropHovered = true;
|
|
464
|
+
}
|
|
465
|
+
}
|
|
466
|
+
|
|
467
|
+
if (this.dragdrop) {
|
|
468
|
+
event.preventDefault();
|
|
469
|
+
event.stopPropagation();
|
|
470
|
+
}
|
|
471
|
+
},
|
|
472
|
+
onNodeDragLeave() {
|
|
473
|
+
this.isPrevDropPointHovered = false;
|
|
474
|
+
this.isNextDropPointHovered = false;
|
|
475
|
+
this.isNodeDropHovered = false;
|
|
476
|
+
},
|
|
477
|
+
onNodeDragEnd(event) {
|
|
478
|
+
event.currentTarget?.removeAttribute('data-p-dragging');
|
|
479
|
+
|
|
480
|
+
this.$pcTree.dragDropService.stopDrag({
|
|
481
|
+
node: this.node,
|
|
482
|
+
subNodes: this.subNodes,
|
|
483
|
+
index: this.index
|
|
484
|
+
});
|
|
485
|
+
},
|
|
291
486
|
setAllNodesTabIndexes() {
|
|
292
487
|
const nodes = find(this.$refs.currentNode.closest('[data-pc-section="rootchildren"]'), '[role="treeitem"]');
|
|
293
488
|
|
|
@@ -458,6 +653,33 @@ export default {
|
|
|
458
653
|
},
|
|
459
654
|
ariaSelected() {
|
|
460
655
|
return this.checkboxMode ? this.checked : undefined;
|
|
656
|
+
},
|
|
657
|
+
isPrevDropPointActive() {
|
|
658
|
+
return this.isPrevDropPointHovered && this.isDroppable;
|
|
659
|
+
},
|
|
660
|
+
isNextDropPointActive() {
|
|
661
|
+
return this.isNextDropPointHovered && this.isDroppable;
|
|
662
|
+
},
|
|
663
|
+
dropPosition() {
|
|
664
|
+
return this.isPrevDropPointActive ? -1 : this.isNextDropPointActive ? 1 : 0;
|
|
665
|
+
},
|
|
666
|
+
subNodes() {
|
|
667
|
+
return this.parentNode ? this.parentNode.children : this.rootNodes;
|
|
668
|
+
},
|
|
669
|
+
isDraggable() {
|
|
670
|
+
return this.dragdrop;
|
|
671
|
+
},
|
|
672
|
+
isDroppable() {
|
|
673
|
+
return this.dragdrop && this.$pcTree.allowNodeDrop(this.node);
|
|
674
|
+
},
|
|
675
|
+
isNodeDraggable() {
|
|
676
|
+
return this.node?.draggable !== false && this.isDraggable;
|
|
677
|
+
},
|
|
678
|
+
isNodeDroppable() {
|
|
679
|
+
return this.node?.droppable !== false && this.isDroppable;
|
|
680
|
+
},
|
|
681
|
+
isNodeDropActive() {
|
|
682
|
+
return this.isNodeDropHovered && this.isNodeDroppable;
|
|
461
683
|
}
|
|
462
684
|
},
|
|
463
685
|
components: {
|
package/tree/index.d.ts
CHANGED
|
@@ -97,6 +97,29 @@ export interface TreeFilterEvent {
|
|
|
97
97
|
value: string;
|
|
98
98
|
}
|
|
99
99
|
|
|
100
|
+
/**
|
|
101
|
+
* Custom node drop event.
|
|
102
|
+
* @see {@link TreeEmitsOptions.node-drop}
|
|
103
|
+
*/
|
|
104
|
+
export interface TreeNodeDropEvent {
|
|
105
|
+
/**
|
|
106
|
+
* Original event
|
|
107
|
+
*/
|
|
108
|
+
originalEvent: Event;
|
|
109
|
+
/**
|
|
110
|
+
* Dragged node
|
|
111
|
+
*/
|
|
112
|
+
dragNode: TreeNode;
|
|
113
|
+
/**
|
|
114
|
+
* Dropped node
|
|
115
|
+
*/
|
|
116
|
+
dropNode: TreeNode;
|
|
117
|
+
/**
|
|
118
|
+
* Index of the dropped node
|
|
119
|
+
*/
|
|
120
|
+
index: number;
|
|
121
|
+
}
|
|
122
|
+
|
|
100
123
|
/**
|
|
101
124
|
* Custom passthrough(pt) options.
|
|
102
125
|
* @see {@link TreeProps.pt}
|
|
@@ -173,6 +196,14 @@ export interface TreePassThroughOptions<T = any> {
|
|
|
173
196
|
* Used to pass attributes to the loading icon's DOM element.
|
|
174
197
|
*/
|
|
175
198
|
loadingIcon?: TreePassThroughOptionType<T>;
|
|
199
|
+
/**
|
|
200
|
+
* Used to pass attributes to the empty message's DOM element.
|
|
201
|
+
*/
|
|
202
|
+
emptyMessage?: TreePassThroughOptionType<T>;
|
|
203
|
+
/**
|
|
204
|
+
* Used to pass attributes to the drop point's DOM element.
|
|
205
|
+
*/
|
|
206
|
+
dropPoint?: TreePassThroughOptionType<T>;
|
|
176
207
|
/**
|
|
177
208
|
* Used to manage all lifecycle hooks.
|
|
178
209
|
* @see {@link BaseComponent.ComponentHooks}
|
|
@@ -312,6 +343,26 @@ export interface TreeProps {
|
|
|
312
343
|
* Height of the scroll viewport in fixed units or the 'flex' keyword for a dynamic size.
|
|
313
344
|
*/
|
|
314
345
|
scrollHeight?: HintedString<'flex'> | undefined;
|
|
346
|
+
/**
|
|
347
|
+
* Whether the nodes are draggable and droppable.
|
|
348
|
+
* @defaultValue null
|
|
349
|
+
*/
|
|
350
|
+
dragdrop?: boolean | undefined;
|
|
351
|
+
/**
|
|
352
|
+
* Scope of the draggable nodes to match a droppableScope.
|
|
353
|
+
* @defaultValue null
|
|
354
|
+
*/
|
|
355
|
+
draggableScope?: string | string[] | undefined;
|
|
356
|
+
/**
|
|
357
|
+
* Scope of the droppable nodes to match a draggableScope.
|
|
358
|
+
* @defaultValue null
|
|
359
|
+
*/
|
|
360
|
+
droppableScope?: string | string[] | undefined;
|
|
361
|
+
/**
|
|
362
|
+
* When enabled, drop can be accepted or rejected based on condition defined at node-drop.
|
|
363
|
+
* @defaultValue false
|
|
364
|
+
*/
|
|
365
|
+
validateDrop?: boolean | undefined;
|
|
315
366
|
/**
|
|
316
367
|
* Defines a string value that labels an interactive element.
|
|
317
368
|
*/
|
|
@@ -501,6 +552,10 @@ export interface TreeSlots {
|
|
|
501
552
|
*/
|
|
502
553
|
selectionKeys: TreeSelectionKeys;
|
|
503
554
|
}): VNode[];
|
|
555
|
+
/**
|
|
556
|
+
* Custom empty template.
|
|
557
|
+
*/
|
|
558
|
+
empty(): VNode[];
|
|
504
559
|
/**
|
|
505
560
|
* Optional slots.
|
|
506
561
|
* @todo
|
|
@@ -512,6 +567,11 @@ export interface TreeSlots {
|
|
|
512
567
|
* Defines valid emits in Tree component.
|
|
513
568
|
*/
|
|
514
569
|
export interface TreeEmitsOptions {
|
|
570
|
+
/**
|
|
571
|
+
* Emitted when the value change.
|
|
572
|
+
* @param {TreeNode} value - New value.
|
|
573
|
+
*/
|
|
574
|
+
'update:value'(value: TreeNode[]): void;
|
|
515
575
|
/**
|
|
516
576
|
* Emitted when the expanded keys change.
|
|
517
577
|
* @param {TreeNode} value - New expanded keys.
|
|
@@ -542,6 +602,11 @@ export interface TreeEmitsOptions {
|
|
|
542
602
|
* @param {TreeNode} node - Node instance.
|
|
543
603
|
*/
|
|
544
604
|
'node-collapse'(node: TreeNode): void;
|
|
605
|
+
/**
|
|
606
|
+
* Callback to invoke when a node is collapsed.
|
|
607
|
+
* @param {TreeNode} node - Node instance.
|
|
608
|
+
*/
|
|
609
|
+
'node-drop'(node: TreeNodeDropEvent): void;
|
|
545
610
|
/**
|
|
546
611
|
* Callback to invoke on filter input.
|
|
547
612
|
* @param {TreeFilterEvent} event - Custom filter event.
|