Refactor #3965 - For Tree
parent
ba0b555d27
commit
0554604c00
|
@ -0,0 +1,213 @@
|
||||||
|
<script>
|
||||||
|
import BaseComponent from 'primevue/basecomponent';
|
||||||
|
import { useStyle } from 'primevue/usestyle';
|
||||||
|
|
||||||
|
const styles = `
|
||||||
|
.p-tree-container {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
list-style-type: none;
|
||||||
|
overflow: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.p-treenode-children {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
list-style-type: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.p-tree-wrapper {
|
||||||
|
overflow: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.p-treenode-selectable {
|
||||||
|
cursor: pointer;
|
||||||
|
user-select: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.p-tree-toggler {
|
||||||
|
cursor: pointer;
|
||||||
|
user-select: none;
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
overflow: hidden;
|
||||||
|
position: relative;
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.p-treenode-leaf > .p-treenode-content .p-tree-toggler {
|
||||||
|
visibility: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.p-treenode-content {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.p-tree-filter {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.p-tree-filter-container {
|
||||||
|
position: relative;
|
||||||
|
display: block;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.p-tree-filter-icon {
|
||||||
|
position: absolute;
|
||||||
|
top: 50%;
|
||||||
|
margin-top: -0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.p-tree-loading {
|
||||||
|
position: relative;
|
||||||
|
min-height: 4rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.p-tree .p-tree-loading-overlay {
|
||||||
|
position: absolute;
|
||||||
|
z-index: 1;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.p-tree-flex-scrollable {
|
||||||
|
display: flex;
|
||||||
|
flex: 1;
|
||||||
|
height: 100%;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
.p-tree-flex-scrollable .p-tree-wrapper {
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
const classes = {
|
||||||
|
root: ({ props }) => [
|
||||||
|
'p-tree p-component',
|
||||||
|
{
|
||||||
|
'p-tree-selectable': props.selectionMode != null,
|
||||||
|
'p-tree-loading': props.loading,
|
||||||
|
'p-tree-flex-scrollable': props.scrollHeight === 'flex'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
loadingOverlay: 'p-tree-loading-overlay p-component-overlay',
|
||||||
|
loadingIcon: 'p-tree-loading-icon',
|
||||||
|
filterContainer: 'p-tree-filter-container',
|
||||||
|
input: 'p-tree-filter p-inputtext p-component',
|
||||||
|
searchIcon: 'p-tree-filter-icon',
|
||||||
|
wrapper: 'p-tree-wrapper',
|
||||||
|
container: 'p-tree-container',
|
||||||
|
node: ({ treenode }) => ['p-treenode', { 'p-treenode-leaf': treenode.leaf }],
|
||||||
|
content: ({ treenode }) => [
|
||||||
|
'p-treenode-content',
|
||||||
|
treenode.node.styleClass,
|
||||||
|
{
|
||||||
|
'p-treenode-selectable': treenode.selectable,
|
||||||
|
'p-highlight': treenode.checkboxMode ? treenode.checked : treenode.selected
|
||||||
|
}
|
||||||
|
],
|
||||||
|
toggler: 'p-tree-toggler p-link',
|
||||||
|
togglerIcon: 'p-tree-toggler-icon',
|
||||||
|
checkboxContainer: 'p-checkbox p-component',
|
||||||
|
checkbox: ({ treenode }) => [
|
||||||
|
'p-checkbox-box',
|
||||||
|
{
|
||||||
|
'p-highlight': treenode.checked,
|
||||||
|
'p-indeterminate': treenode.partialChecked
|
||||||
|
}
|
||||||
|
],
|
||||||
|
checkboxIcon: 'p-checkbox-icon',
|
||||||
|
nodeIcon: ({ treenode }) => ['p-treenode-icon', treenode.node.icon],
|
||||||
|
label: 'p-treenode-label',
|
||||||
|
subgroup: 'p-treenode-children'
|
||||||
|
};
|
||||||
|
|
||||||
|
const { load: loadStyle, unload: unloadStyle } = useStyle(styles, { id: 'primevue_tree_style', manual: true });
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'BaseTree',
|
||||||
|
extends: BaseComponent,
|
||||||
|
props: {
|
||||||
|
value: {
|
||||||
|
type: null,
|
||||||
|
default: null
|
||||||
|
},
|
||||||
|
expandedKeys: {
|
||||||
|
type: null,
|
||||||
|
default: null
|
||||||
|
},
|
||||||
|
selectionKeys: {
|
||||||
|
type: null,
|
||||||
|
default: null
|
||||||
|
},
|
||||||
|
selectionMode: {
|
||||||
|
type: String,
|
||||||
|
default: null
|
||||||
|
},
|
||||||
|
metaKeySelection: {
|
||||||
|
type: Boolean,
|
||||||
|
default: true
|
||||||
|
},
|
||||||
|
loading: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
},
|
||||||
|
loadingIcon: {
|
||||||
|
type: String,
|
||||||
|
default: undefined
|
||||||
|
},
|
||||||
|
filter: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
},
|
||||||
|
filterBy: {
|
||||||
|
type: String,
|
||||||
|
default: 'label'
|
||||||
|
},
|
||||||
|
filterMode: {
|
||||||
|
type: String,
|
||||||
|
default: 'lenient'
|
||||||
|
},
|
||||||
|
filterPlaceholder: {
|
||||||
|
type: String,
|
||||||
|
default: null
|
||||||
|
},
|
||||||
|
filterLocale: {
|
||||||
|
type: String,
|
||||||
|
default: undefined
|
||||||
|
},
|
||||||
|
scrollHeight: {
|
||||||
|
type: String,
|
||||||
|
default: null
|
||||||
|
},
|
||||||
|
level: {
|
||||||
|
type: Number,
|
||||||
|
default: 0
|
||||||
|
},
|
||||||
|
'aria-labelledby': {
|
||||||
|
type: String,
|
||||||
|
default: null
|
||||||
|
},
|
||||||
|
'aria-label': {
|
||||||
|
type: String,
|
||||||
|
default: null
|
||||||
|
}
|
||||||
|
},
|
||||||
|
css: {
|
||||||
|
classes
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
isUnstyled: {
|
||||||
|
immediate: true,
|
||||||
|
handler(newValue) {
|
||||||
|
!newValue && loadStyle();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
|
@ -298,6 +298,11 @@ export interface TreeProps {
|
||||||
* @type {TreePassThroughOptions}
|
* @type {TreePassThroughOptions}
|
||||||
*/
|
*/
|
||||||
pt?: TreePassThroughOptions;
|
pt?: TreePassThroughOptions;
|
||||||
|
/**
|
||||||
|
* When enabled, it removes component related styles in the core.
|
||||||
|
* @defaultValue false
|
||||||
|
*/
|
||||||
|
unstyled?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -307,11 +312,21 @@ export interface TreeSlots {
|
||||||
/**
|
/**
|
||||||
* Custom loading icon template.
|
* Custom loading icon template.
|
||||||
*/
|
*/
|
||||||
loadingicon(): VNode[];
|
loadingicon(scope: {
|
||||||
|
/**
|
||||||
|
* Style class of the icon.
|
||||||
|
*/
|
||||||
|
class: string;
|
||||||
|
}): VNode[];
|
||||||
/**
|
/**
|
||||||
* Custom search icon template.
|
* Custom search icon template.
|
||||||
*/
|
*/
|
||||||
searchicon(): VNode[];
|
searchicon(scope: {
|
||||||
|
/**
|
||||||
|
* Style class of the icon.
|
||||||
|
*/
|
||||||
|
class: string;
|
||||||
|
}): VNode[];
|
||||||
/**
|
/**
|
||||||
* Custom toggler icon template.
|
* Custom toggler icon template.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -1,21 +1,21 @@
|
||||||
<template>
|
<template>
|
||||||
<div :class="containerClass" v-bind="ptm('root')">
|
<div :class="cx('root')" v-bind="ptm('root')">
|
||||||
<template v-if="loading">
|
<template v-if="loading">
|
||||||
<div class="p-tree-loading-overlay p-component-overlay" v-bind="ptm('loadingOverlay')">
|
<div :class="cx('loadingOverlay')" v-bind="ptm('loadingOverlay')">
|
||||||
<slot name="loadingicon">
|
<slot name="loadingicon" :class="cx('loadingIcon')">
|
||||||
<i v-if="loadingIcon" :class="['p-tree-loading-icon pi-spin', loadingIcon]" v-bind="ptm('loadingIcon')" />
|
<i v-if="loadingIcon" :class="[cx('loadingIcon'), 'pi-spin', loadingIcon]" v-bind="ptm('loadingIcon')" />
|
||||||
<SpinnerIcon v-else spin class="p-tree-loading-icon" v-bind="ptm('loadingIcon')" />
|
<SpinnerIcon v-else spin :class="cx('loadingIcon')" v-bind="ptm('loadingIcon')" />
|
||||||
</slot>
|
</slot>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<div v-if="filter" class="p-tree-filter-container" v-bind="ptm('filterContainer')">
|
<div v-if="filter" :class="cx('filterContainer')" v-bind="ptm('filterContainer')">
|
||||||
<input v-model="filterValue" type="text" autocomplete="off" class="p-tree-filter p-inputtext p-component" :placeholder="filterPlaceholder" @keydown="onFilterKeydown" v-bind="ptm('input')" />
|
<input v-model="filterValue" type="text" autocomplete="off" :class="cx('root')" :placeholder="filterPlaceholder" @keydown="onFilterKeydown" v-bind="ptm('input')" />
|
||||||
<slot name="searchicon">
|
<slot name="searchicon" :class="cx('searchIcon')">
|
||||||
<SearchIcon class="p-tree-filter-icon" v-bind="ptm('searchIcon')" />
|
<SearchIcon :class="cx('searchIcon')" v-bind="ptm('searchIcon')" />
|
||||||
</slot>
|
</slot>
|
||||||
</div>
|
</div>
|
||||||
<div class="p-tree-wrapper" :style="{ maxHeight: scrollHeight }" v-bind="ptm('wrapper')">
|
<div :class="cx('wrapper')" :style="{ maxHeight: scrollHeight }" v-bind="ptm('wrapper')">
|
||||||
<ul class="p-tree-container" role="tree" :aria-labelledby="ariaLabelledby" :aria-label="ariaLabel" v-bind="ptm('container')">
|
<ul :class="cx('container')" role="tree" :aria-labelledby="ariaLabelledby" :aria-label="ariaLabel" v-bind="ptm('container')">
|
||||||
<TreeNode
|
<TreeNode
|
||||||
v-for="(node, index) of valueToRender"
|
v-for="(node, index) of valueToRender"
|
||||||
:key="node.key"
|
:key="node.key"
|
||||||
|
@ -37,82 +37,16 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import BaseComponent from 'primevue/basecomponent';
|
|
||||||
import SearchIcon from 'primevue/icons/search';
|
import SearchIcon from 'primevue/icons/search';
|
||||||
import SpinnerIcon from 'primevue/icons/spinner';
|
import SpinnerIcon from 'primevue/icons/spinner';
|
||||||
import { ObjectUtils } from 'primevue/utils';
|
import { ObjectUtils } from 'primevue/utils';
|
||||||
|
import BaseTree from './BaseTree.vue';
|
||||||
import TreeNode from './TreeNode.vue';
|
import TreeNode from './TreeNode.vue';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'Tree',
|
name: 'Tree',
|
||||||
extends: BaseComponent,
|
extends: BaseTree,
|
||||||
emits: ['node-expand', 'node-collapse', 'update:expandedKeys', 'update:selectionKeys', 'node-select', 'node-unselect'],
|
emits: ['node-expand', 'node-collapse', 'update:expandedKeys', 'update:selectionKeys', 'node-select', 'node-unselect'],
|
||||||
props: {
|
|
||||||
value: {
|
|
||||||
type: null,
|
|
||||||
default: null
|
|
||||||
},
|
|
||||||
expandedKeys: {
|
|
||||||
type: null,
|
|
||||||
default: null
|
|
||||||
},
|
|
||||||
selectionKeys: {
|
|
||||||
type: null,
|
|
||||||
default: null
|
|
||||||
},
|
|
||||||
selectionMode: {
|
|
||||||
type: String,
|
|
||||||
default: null
|
|
||||||
},
|
|
||||||
metaKeySelection: {
|
|
||||||
type: Boolean,
|
|
||||||
default: true
|
|
||||||
},
|
|
||||||
loading: {
|
|
||||||
type: Boolean,
|
|
||||||
default: false
|
|
||||||
},
|
|
||||||
loadingIcon: {
|
|
||||||
type: String,
|
|
||||||
default: undefined
|
|
||||||
},
|
|
||||||
filter: {
|
|
||||||
type: Boolean,
|
|
||||||
default: false
|
|
||||||
},
|
|
||||||
filterBy: {
|
|
||||||
type: String,
|
|
||||||
default: 'label'
|
|
||||||
},
|
|
||||||
filterMode: {
|
|
||||||
type: String,
|
|
||||||
default: 'lenient'
|
|
||||||
},
|
|
||||||
filterPlaceholder: {
|
|
||||||
type: String,
|
|
||||||
default: null
|
|
||||||
},
|
|
||||||
filterLocale: {
|
|
||||||
type: String,
|
|
||||||
default: undefined
|
|
||||||
},
|
|
||||||
scrollHeight: {
|
|
||||||
type: String,
|
|
||||||
default: null
|
|
||||||
},
|
|
||||||
level: {
|
|
||||||
type: Number,
|
|
||||||
default: 0
|
|
||||||
},
|
|
||||||
'aria-labelledby': {
|
|
||||||
type: String,
|
|
||||||
default: null
|
|
||||||
},
|
|
||||||
'aria-label': {
|
|
||||||
type: String,
|
|
||||||
default: null
|
|
||||||
}
|
|
||||||
},
|
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
d_expandedKeys: this.expandedKeys || {},
|
d_expandedKeys: this.expandedKeys || {},
|
||||||
|
@ -275,16 +209,6 @@ export default {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
containerClass() {
|
|
||||||
return [
|
|
||||||
'p-tree p-component',
|
|
||||||
{
|
|
||||||
'p-tree-selectable': this.selectionMode != null,
|
|
||||||
'p-tree-loading': this.loading,
|
|
||||||
'p-tree-flex-scrollable': this.scrollHeight === 'flex'
|
|
||||||
}
|
|
||||||
];
|
|
||||||
},
|
|
||||||
filteredValue() {
|
filteredValue() {
|
||||||
let filteredNodes = [];
|
let filteredNodes = [];
|
||||||
const searchFields = this.filterBy.split(',');
|
const searchFields = this.filterBy.split(',');
|
||||||
|
@ -317,87 +241,3 @@ export default {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style>
|
|
||||||
.p-tree-container {
|
|
||||||
margin: 0;
|
|
||||||
padding: 0;
|
|
||||||
list-style-type: none;
|
|
||||||
overflow: auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
.p-treenode-children {
|
|
||||||
margin: 0;
|
|
||||||
padding: 0;
|
|
||||||
list-style-type: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.p-tree-wrapper {
|
|
||||||
overflow: auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
.p-treenode-selectable {
|
|
||||||
cursor: pointer;
|
|
||||||
user-select: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.p-tree-toggler {
|
|
||||||
cursor: pointer;
|
|
||||||
user-select: none;
|
|
||||||
display: inline-flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
overflow: hidden;
|
|
||||||
position: relative;
|
|
||||||
flex-shrink: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.p-treenode-leaf > .p-treenode-content .p-tree-toggler {
|
|
||||||
visibility: hidden;
|
|
||||||
}
|
|
||||||
|
|
||||||
.p-treenode-content {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.p-tree-filter {
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.p-tree-filter-container {
|
|
||||||
position: relative;
|
|
||||||
display: block;
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.p-tree-filter-icon {
|
|
||||||
position: absolute;
|
|
||||||
top: 50%;
|
|
||||||
margin-top: -0.5rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.p-tree-loading {
|
|
||||||
position: relative;
|
|
||||||
min-height: 4rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.p-tree .p-tree-loading-overlay {
|
|
||||||
position: absolute;
|
|
||||||
z-index: 1;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.p-tree-flex-scrollable {
|
|
||||||
display: flex;
|
|
||||||
flex: 1;
|
|
||||||
height: 100%;
|
|
||||||
flex-direction: column;
|
|
||||||
}
|
|
||||||
|
|
||||||
.p-tree-flex-scrollable .p-tree-wrapper {
|
|
||||||
flex: 1;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<template>
|
<template>
|
||||||
<li
|
<li
|
||||||
ref="currentNode"
|
ref="currentNode"
|
||||||
:class="containerClass"
|
:class="getCXOptions('node')"
|
||||||
role="treeitem"
|
role="treeitem"
|
||||||
:aria-label="label(node)"
|
:aria-label="label(node)"
|
||||||
:aria-selected="ariaSelected"
|
:aria-selected="ariaSelected"
|
||||||
|
@ -12,27 +12,28 @@
|
||||||
:aria-checked="ariaChecked"
|
:aria-checked="ariaChecked"
|
||||||
:tabindex="index === 0 ? 0 : -1"
|
:tabindex="index === 0 ? 0 : -1"
|
||||||
@keydown="onKeyDown"
|
@keydown="onKeyDown"
|
||||||
v-bind="getPTOptions('node')"
|
v-bind="level === 1 ? getPTOptions('node') : ptm('subgroup')"
|
||||||
|
data-pc-section="treeitem"
|
||||||
>
|
>
|
||||||
<div :class="contentClass" @click="onClick" @touchend="onTouchEnd" :style="node.style" v-bind="getPTOptions('content')">
|
<div :class="getCXOptions('content')" @click="onClick" @touchend="onTouchEnd" :style="node.style" v-bind="getPTOptions('content')">
|
||||||
<button v-ripple type="button" class="p-tree-toggler p-link" @click="toggle" tabindex="-1" aria-hidden="true" v-bind="getPTOptions('toggler')">
|
<button v-ripple type="button" :class="cx('toggler')" @click="toggle" tabindex="-1" aria-hidden="true" v-bind="getPTOptions('toggler')">
|
||||||
<component v-if="templates['togglericon']" :is="templates['togglericon']" :node="node" :expanded="expanded" class="p-tree-toggler-icon" />
|
<component v-if="templates['togglericon']" :is="templates['togglericon']" :node="node" :expanded="expanded" :class="cx('togglerIcon')" />
|
||||||
<component v-else-if="expanded" :is="node.expandedIcon ? 'span' : 'ChevronDownIcon'" class="p-tree-toggler-icon" v-bind="getPTOptions('togglerIcon')" />
|
<component v-else-if="expanded" :is="node.expandedIcon ? 'span' : 'ChevronDownIcon'" :class="cx('togglerIcon')" v-bind="getPTOptions('togglerIcon')" />
|
||||||
<component v-else :is="node.collapsedIcon ? 'span' : 'ChevronRightIcon'" class="p-tree-toggler-icon" v-bind="getPTOptions('togglerIcon')" />
|
<component v-else :is="node.collapsedIcon ? 'span' : 'ChevronRightIcon'" :class="cx('togglerIcon')" v-bind="getPTOptions('togglerIcon')" />
|
||||||
</button>
|
</button>
|
||||||
<div v-if="checkboxMode" class="p-checkbox p-component" aria-hidden="true" v-bind="getPTOptions('checkboxContainer')">
|
<div v-if="checkboxMode" :class="cx('checkboxContainer')" aria-hidden="true" v-bind="getPTOptions('checkboxContainer')">
|
||||||
<div :class="checkboxClass" role="checkbox" v-bind="getPTOptions('checkbox')">
|
<div :class="getCXOptions('checkbox')" role="checkbox" v-bind="getPTOptions('checkbox')">
|
||||||
<component v-if="templates['checkboxicon']" :is="templates['checkboxicon']" :checked="checked" :partialChecked="partialChecked" class="p-checkbox-icon" />
|
<component v-if="templates['checkboxicon']" :is="templates['checkboxicon']" :checked="checked" :partialChecked="partialChecked" :class="cx('checkboxIcon')" />
|
||||||
<component v-else :is="checked ? 'CheckIcon' : partialChecked ? 'MinusIcon' : null" class="p-checkbox-icon" v-bind="getPTOptions('checkboxIcon')" />
|
<component v-else :is="checked ? 'CheckIcon' : partialChecked ? 'MinusIcon' : null" :class="cx('checkboxIcon')" v-bind="getPTOptions('checkboxIcon')" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<span :class="icon" v-bind="getPTOptions('nodeIcon')"></span>
|
<span :class="getCXOptions('nodeIcon')" v-bind="getPTOptions('nodeIcon')"></span>
|
||||||
<span class="p-treenode-label" v-bind="getPTOptions('label')">
|
<span :class="cx('label')" v-bind="getPTOptions('label')">
|
||||||
<component v-if="templates[node.type] || templates['default']" :is="templates[node.type] || templates['default']" :node="node" />
|
<component v-if="templates[node.type] || templates['default']" :is="templates[node.type] || templates['default']" :node="node" />
|
||||||
<template v-else>{{ label(node) }}</template>
|
<template v-else>{{ label(node) }}</template>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<ul v-if="hasChildren && expanded" class="p-treenode-children" role="group" v-bind="ptm('subgroup')">
|
<ul v-if="hasChildren && expanded" :class="cx('subgroup')" role="group" v-bind="ptm('subgroup')">
|
||||||
<TreeNode
|
<TreeNode
|
||||||
v-for="childNode of node.children"
|
v-for="childNode of node.children"
|
||||||
:key="childNode.key"
|
:key="childNode.key"
|
||||||
|
@ -52,17 +53,17 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import BaseComponent from 'primevue/basecomponent';
|
|
||||||
import CheckIcon from 'primevue/icons/check';
|
import CheckIcon from 'primevue/icons/check';
|
||||||
import ChevronDownIcon from 'primevue/icons/chevrondown';
|
import ChevronDownIcon from 'primevue/icons/chevrondown';
|
||||||
import ChevronRightIcon from 'primevue/icons/chevronright';
|
import ChevronRightIcon from 'primevue/icons/chevronright';
|
||||||
import MinusIcon from 'primevue/icons/minus';
|
import MinusIcon from 'primevue/icons/minus';
|
||||||
import Ripple from 'primevue/ripple';
|
import Ripple from 'primevue/ripple';
|
||||||
import { DomHandler } from 'primevue/utils';
|
import { DomHandler } from 'primevue/utils';
|
||||||
|
import BaseTree from './BaseTree.vue';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'TreeNode',
|
name: 'TreeNode',
|
||||||
extends: BaseComponent,
|
extends: BaseTree,
|
||||||
emits: ['node-toggle', 'node-click', 'checkbox-change'],
|
emits: ['node-toggle', 'node-click', 'checkbox-change'],
|
||||||
props: {
|
props: {
|
||||||
node: {
|
node: {
|
||||||
|
@ -96,13 +97,6 @@ export default {
|
||||||
},
|
},
|
||||||
nodeTouched: false,
|
nodeTouched: false,
|
||||||
toggleClicked: false,
|
toggleClicked: false,
|
||||||
mounted() {
|
|
||||||
const hasTreeSelectParent = this.$refs.currentNode.closest('.p-treeselect-items-wrapper');
|
|
||||||
|
|
||||||
if (hasTreeSelectParent) {
|
|
||||||
this.setAllNodesTabIndexes();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
methods: {
|
methods: {
|
||||||
toggle() {
|
toggle() {
|
||||||
this.$emit('node-toggle', this.node);
|
this.$emit('node-toggle', this.node);
|
||||||
|
@ -123,8 +117,13 @@ export default {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
getCXOptions(key) {
|
||||||
|
return this.cx(key, {
|
||||||
|
treenode: this
|
||||||
|
});
|
||||||
|
},
|
||||||
onClick(event) {
|
onClick(event) {
|
||||||
if (this.toggleClicked || DomHandler.hasClass(event.target, 'p-tree-toggler') || DomHandler.hasClass(event.target.parentElement, 'p-tree-toggler')) {
|
if (this.toggleClicked || DomHandler.getAttribute(event.target, '[data-pc-section="toggler"]') || DomHandler.getAttribute(event.target.parentElement, '[data-pc-section="toggler"]')) {
|
||||||
this.toggleClicked = false;
|
this.toggleClicked = false;
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
@ -233,7 +232,7 @@ export default {
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
onArrowLeft(event) {
|
onArrowLeft(event) {
|
||||||
const togglerElement = DomHandler.findSingle(event.currentTarget, '.p-tree-toggler');
|
const togglerElement = DomHandler.findSingle(event.currentTarget, '[data-pc-section="toggler"]');
|
||||||
|
|
||||||
if (this.level === 0 && !this.expanded) {
|
if (this.level === 0 && !this.expanded) {
|
||||||
return false;
|
return false;
|
||||||
|
@ -261,7 +260,7 @@ export default {
|
||||||
this.setAllNodesTabIndexes();
|
this.setAllNodesTabIndexes();
|
||||||
},
|
},
|
||||||
setAllNodesTabIndexes() {
|
setAllNodesTabIndexes() {
|
||||||
const nodes = DomHandler.find(this.$refs.currentNode.closest('.p-tree-container'), '.p-treenode');
|
const nodes = DomHandler.find(this.$refs.currentNode.closest('[data-pc-section="container"]'), '[data-pc-section="treeitem"]');
|
||||||
|
|
||||||
const hasSelectedNode = [...nodes].some((node) => node.getAttribute('aria-selected') === 'true' || node.getAttribute('aria-checked') === 'true');
|
const hasSelectedNode = [...nodes].some((node) => node.getAttribute('aria-selected') === 'true' || node.getAttribute('aria-checked') === 'true');
|
||||||
|
|
||||||
|
@ -281,7 +280,7 @@ export default {
|
||||||
},
|
},
|
||||||
setTabIndexForSelectionMode(event, nodeTouched) {
|
setTabIndexForSelectionMode(event, nodeTouched) {
|
||||||
if (this.selectionMode !== null) {
|
if (this.selectionMode !== null) {
|
||||||
const elements = [...DomHandler.find(this.$refs.currentNode.parentElement, '.p-treenode')];
|
const elements = [...DomHandler.find(this.$refs.currentNode.parentElement, '[data-pc-section="node"]')];
|
||||||
|
|
||||||
event.currentTarget.tabIndex = nodeTouched === false ? -1 : 0;
|
event.currentTarget.tabIndex = nodeTouched === false ? -1 : 0;
|
||||||
|
|
||||||
|
@ -388,7 +387,7 @@ export default {
|
||||||
getParentNodeElement(nodeElement) {
|
getParentNodeElement(nodeElement) {
|
||||||
const parentNodeElement = nodeElement.parentElement.parentElement;
|
const parentNodeElement = nodeElement.parentElement.parentElement;
|
||||||
|
|
||||||
return DomHandler.hasClass(parentNodeElement, 'p-treenode') ? parentNodeElement : null;
|
return DomHandler.getAttribute(parentNodeElement, '[data-pc-section="node"]') ? parentNodeElement : null;
|
||||||
},
|
},
|
||||||
focusNode(element) {
|
focusNode(element) {
|
||||||
element.focus();
|
element.focus();
|
||||||
|
@ -397,7 +396,7 @@ export default {
|
||||||
return this.selectionMode === 'checkbox';
|
return this.selectionMode === 'checkbox';
|
||||||
},
|
},
|
||||||
isSameNode(event) {
|
isSameNode(event) {
|
||||||
return event.currentTarget && (event.currentTarget.isSameNode(event.target) || event.currentTarget.isSameNode(event.target.closest('.p-treenode')));
|
return event.currentTarget && (event.currentTarget.isSameNode(event.target) || event.currentTarget.isSameNode(event.target.closest('[data-pc-section="node"]')));
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
|
@ -416,25 +415,6 @@ export default {
|
||||||
selected() {
|
selected() {
|
||||||
return this.selectionMode && this.selectionKeys ? this.selectionKeys[this.node.key] === true : false;
|
return this.selectionMode && this.selectionKeys ? this.selectionKeys[this.node.key] === true : false;
|
||||||
},
|
},
|
||||||
containerClass() {
|
|
||||||
return ['p-treenode', { 'p-treenode-leaf': this.leaf }];
|
|
||||||
},
|
|
||||||
contentClass() {
|
|
||||||
return [
|
|
||||||
'p-treenode-content',
|
|
||||||
this.node.styleClass,
|
|
||||||
{
|
|
||||||
'p-treenode-selectable': this.selectable,
|
|
||||||
'p-highlight': this.checkboxMode ? this.checked : this.selected
|
|
||||||
}
|
|
||||||
];
|
|
||||||
},
|
|
||||||
icon() {
|
|
||||||
return ['p-treenode-icon', this.node.icon];
|
|
||||||
},
|
|
||||||
checkboxClass() {
|
|
||||||
return ['p-checkbox-box', { 'p-highlight': this.checked, 'p-indeterminate': this.partialChecked }];
|
|
||||||
},
|
|
||||||
checkboxMode() {
|
checkboxMode() {
|
||||||
return this.selectionMode === 'checkbox' && this.node.selectable !== false;
|
return this.selectionMode === 'checkbox' && this.node.selectable !== false;
|
||||||
},
|
},
|
||||||
|
|
Loading…
Reference in New Issue