Refactor #3924 - For Tree
parent
6a4226a4e0
commit
e10c1cf988
|
@ -77,6 +77,12 @@ const TreeProps = [
|
||||||
type: 'string',
|
type: 'string',
|
||||||
default: 'null',
|
default: 'null',
|
||||||
description: 'Height of the scroll viewport in fixed units or the "flex" keyword for a dynamic size.'
|
description: 'Height of the scroll viewport in fixed units or the "flex" keyword for a dynamic size.'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'pt',
|
||||||
|
type: 'any',
|
||||||
|
default: 'null',
|
||||||
|
description: 'Uses to pass attributes to DOM elements inside the component.'
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|
|
@ -63,6 +63,7 @@ import { TextareaPassThroughOptions } from '../textarea';
|
||||||
import { TieredMenuPassThroughOptions } from '../tieredmenu';
|
import { TieredMenuPassThroughOptions } from '../tieredmenu';
|
||||||
import { ToastPassThroughOptions } from '../toast';
|
import { ToastPassThroughOptions } from '../toast';
|
||||||
import { ToolbarPassThroughOptions } from '../toolbar';
|
import { ToolbarPassThroughOptions } from '../toolbar';
|
||||||
|
import { TreePassThroughOptions } from '../tree';
|
||||||
import { VirtualScrollerPassThroughOptions } from '../virtualscroller';
|
import { VirtualScrollerPassThroughOptions } from '../virtualscroller';
|
||||||
|
|
||||||
interface PrimeVueConfiguration {
|
interface PrimeVueConfiguration {
|
||||||
|
@ -148,6 +149,7 @@ interface PrimeVuePTOptions {
|
||||||
tieredmenu?: TieredMenuPassThroughOptions;
|
tieredmenu?: TieredMenuPassThroughOptions;
|
||||||
toast?: ToastPassThroughOptions;
|
toast?: ToastPassThroughOptions;
|
||||||
toolbar?: ToolbarPassThroughOptions;
|
toolbar?: ToolbarPassThroughOptions;
|
||||||
|
tree?: TreePassThroughOptions;
|
||||||
virtualscroller?: VirtualScrollerPassThroughOptions;
|
virtualscroller?: VirtualScrollerPassThroughOptions;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -10,6 +10,16 @@
|
||||||
import { VNode } from 'vue';
|
import { VNode } from 'vue';
|
||||||
import { ClassComponent, GlobalComponentConstructor } from '../ts-helpers';
|
import { ClassComponent, GlobalComponentConstructor } from '../ts-helpers';
|
||||||
|
|
||||||
|
export declare type TreePassThroughOptionType = TreePassThroughAttributes | ((options: TreePassThroughMethodOptions) => TreePassThroughAttributes) | null | undefined;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Custom passthrough(pt) option method.
|
||||||
|
*/
|
||||||
|
export interface TreePassThroughMethodOptions {
|
||||||
|
props: TreeProps;
|
||||||
|
state: TreeState;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Custom TreeNode metadata.
|
* Custom TreeNode metadata.
|
||||||
*/
|
*/
|
||||||
|
@ -90,6 +100,106 @@ export interface TreeSelectionKeys {
|
||||||
[key: string]: any;
|
[key: string]: any;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Custom passthrough(pt) options.
|
||||||
|
* @see {@link TreeProps.pt}
|
||||||
|
*/
|
||||||
|
export interface TreePassThroughOptions {
|
||||||
|
/**
|
||||||
|
* Uses to pass attributes to the root's DOM element.
|
||||||
|
*/
|
||||||
|
root?: TreePassThroughOptionType;
|
||||||
|
/**
|
||||||
|
* Uses to pass attributes to the loading overlay's DOM element.
|
||||||
|
*/
|
||||||
|
loadingOverlay?: TreePassThroughOptionType;
|
||||||
|
/**
|
||||||
|
* Uses to pass attributes to the loading icon's DOM element.
|
||||||
|
*/
|
||||||
|
loadingIcon?: TreePassThroughOptionType;
|
||||||
|
/**
|
||||||
|
* Uses to pass attributes to the filter container's DOM element.
|
||||||
|
*/
|
||||||
|
filterContainer?: TreePassThroughOptionType;
|
||||||
|
/**
|
||||||
|
* Uses to pass attributes to the input's DOM element.
|
||||||
|
*/
|
||||||
|
input?: TreePassThroughOptionType;
|
||||||
|
/**
|
||||||
|
* Uses to pass attributes to the search icon's DOM element.
|
||||||
|
*/
|
||||||
|
searchIcon?: TreePassThroughOptionType;
|
||||||
|
/**
|
||||||
|
* Uses to pass attributes to the wrapper's DOM element.
|
||||||
|
*/
|
||||||
|
wrapper?: TreePassThroughOptionType;
|
||||||
|
/**
|
||||||
|
* Uses to pass attributes to the container's DOM element.
|
||||||
|
*/
|
||||||
|
container?: TreePassThroughOptionType;
|
||||||
|
/**
|
||||||
|
* Uses to pass attributes to the node's DOM element.
|
||||||
|
*/
|
||||||
|
node?: TreePassThroughOptionType;
|
||||||
|
/**
|
||||||
|
* Uses to pass attributes to the content's DOM element.
|
||||||
|
*/
|
||||||
|
content?: TreePassThroughOptionType;
|
||||||
|
/**
|
||||||
|
* Uses to pass attributes to the toggler's DOM element.
|
||||||
|
*/
|
||||||
|
toggler?: TreePassThroughOptionType;
|
||||||
|
/**
|
||||||
|
* Uses to pass attributes to the toggler icon's DOM element.
|
||||||
|
*/
|
||||||
|
togglerIcon?: TreePassThroughOptionType;
|
||||||
|
/**
|
||||||
|
* Uses to pass attributes to the checkbox container's DOM element.
|
||||||
|
*/
|
||||||
|
checkboxContainer?: TreePassThroughOptionType;
|
||||||
|
/**
|
||||||
|
* Uses to pass attributes to the checkbox's DOM element.
|
||||||
|
*/
|
||||||
|
checkbox?: TreePassThroughOptionType;
|
||||||
|
/**
|
||||||
|
* Uses to pass attributes to the checkbox icon's DOM element.
|
||||||
|
*/
|
||||||
|
checkboxIcon?: TreePassThroughOptionType;
|
||||||
|
/**
|
||||||
|
* Uses to pass attributes to the node icon's DOM element.
|
||||||
|
*/
|
||||||
|
nodeIcon?: TreePassThroughOptionType;
|
||||||
|
/**
|
||||||
|
* Uses to pass attributes to the label's DOM element.
|
||||||
|
*/
|
||||||
|
label?: TreePassThroughOptionType;
|
||||||
|
/**
|
||||||
|
* Uses to pass attributes to the subgroup's DOM element.
|
||||||
|
*/
|
||||||
|
subgroup?: TreePassThroughOptionType;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Custom passthrough attributes for each DOM elements
|
||||||
|
*/
|
||||||
|
export interface TreePassThroughAttributes {
|
||||||
|
[key: string]: any;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Defines current inline state in Tree component.
|
||||||
|
*/
|
||||||
|
export interface TreeState {
|
||||||
|
/**
|
||||||
|
* Current expanded keys state.
|
||||||
|
*/
|
||||||
|
d_expandedKeys: TreeExpandedKeys;
|
||||||
|
/**
|
||||||
|
* Current filter value state as a string.
|
||||||
|
*/
|
||||||
|
filterValue: string;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Defines valid properties in Tree component.
|
* Defines valid properties in Tree component.
|
||||||
*/
|
*/
|
||||||
|
@ -161,6 +271,11 @@ export interface TreeProps {
|
||||||
* Identifier of the underlying menu element.
|
* Identifier of the underlying menu element.
|
||||||
*/
|
*/
|
||||||
'aria-labelledby'?: string | undefined;
|
'aria-labelledby'?: string | undefined;
|
||||||
|
/**
|
||||||
|
* Uses to pass attributes to DOM elements inside the component.
|
||||||
|
* @type {TreePassThroughOptions}
|
||||||
|
*/
|
||||||
|
pt?: TreePassThroughOptions;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -1,21 +1,21 @@
|
||||||
<template>
|
<template>
|
||||||
<div :class="containerClass">
|
<div :class="containerClass" v-bind="ptm('root')">
|
||||||
<template v-if="loading">
|
<template v-if="loading">
|
||||||
<div class="p-tree-loading-overlay p-component-overlay">
|
<div class="p-tree-loading-overlay p-component-overlay" v-bind="ptm('loadingOverlay')">
|
||||||
<slot name="loadingicon">
|
<slot name="loadingicon">
|
||||||
<i v-if="loadingIcon" :class="['p-tree-loading-icon pi-spin', loadingIcon]" />
|
<i v-if="loadingIcon" :class="['p-tree-loading-icon pi-spin', loadingIcon]" v-bind="ptm('loadingIcon')" />
|
||||||
<SpinnerIcon v-else spin class="p-tree-loading-icon" />
|
<SpinnerIcon v-else spin class="p-tree-loading-icon" v-bind="ptm('loadingIcon')" />
|
||||||
</slot>
|
</slot>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<div v-if="filter" class="p-tree-filter-container">
|
<div v-if="filter" class="p-tree-filter-container" v-bind="ptm('filterContainer')">
|
||||||
<input v-model="filterValue" type="text" autocomplete="off" class="p-tree-filter p-inputtext p-component" :placeholder="filterPlaceholder" @keydown="onFilterKeydown" />
|
<input v-model="filterValue" type="text" autocomplete="off" class="p-tree-filter p-inputtext p-component" :placeholder="filterPlaceholder" @keydown="onFilterKeydown" v-bind="ptm('input')" />
|
||||||
<slot name="searchicon">
|
<slot name="searchicon">
|
||||||
<SearchIcon class="p-tree-filter-icon" />
|
<SearchIcon class="p-tree-filter-icon" v-bind="ptm('searchIcon')" />
|
||||||
</slot>
|
</slot>
|
||||||
</div>
|
</div>
|
||||||
<div class="p-tree-wrapper" :style="{ maxHeight: scrollHeight }">
|
<div class="p-tree-wrapper" :style="{ maxHeight: scrollHeight }" v-bind="ptm('wrapper')">
|
||||||
<ul class="p-tree-container" role="tree" :aria-labelledby="ariaLabelledby" :aria-label="ariaLabel">
|
<ul class="p-tree-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"
|
||||||
|
@ -29,6 +29,7 @@
|
||||||
:selectionMode="selectionMode"
|
:selectionMode="selectionMode"
|
||||||
:selectionKeys="selectionKeys"
|
:selectionKeys="selectionKeys"
|
||||||
@checkbox-change="onCheckboxChange"
|
@checkbox-change="onCheckboxChange"
|
||||||
|
:pt="pt"
|
||||||
></TreeNode>
|
></TreeNode>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
@ -36,6 +37,7 @@
|
||||||
</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';
|
||||||
|
@ -43,6 +45,7 @@ import TreeNode from './TreeNode.vue';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'Tree',
|
name: 'Tree',
|
||||||
|
extends: BaseComponent,
|
||||||
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: {
|
props: {
|
||||||
value: {
|
value: {
|
||||||
|
|
|
@ -12,26 +12,27 @@
|
||||||
:aria-checked="ariaChecked"
|
:aria-checked="ariaChecked"
|
||||||
:tabindex="index === 0 ? 0 : -1"
|
:tabindex="index === 0 ? 0 : -1"
|
||||||
@keydown="onKeyDown"
|
@keydown="onKeyDown"
|
||||||
|
v-bind="getPTOptions('node')"
|
||||||
>
|
>
|
||||||
<div :class="contentClass" @click="onClick" @touchend="onTouchEnd" :style="node.style">
|
<div :class="contentClass" @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">
|
<button v-ripple type="button" class="p-tree-toggler p-link" @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="p-tree-toggler-icon" />
|
||||||
<component v-else-if="expanded" :is="node.expandedIcon ? 'span' : 'ChevronDownIcon'" class="p-tree-toggler-icon" />
|
<component v-else-if="expanded" :is="node.expandedIcon ? 'span' : 'ChevronDownIcon'" class="p-tree-toggler-icon" v-bind="getPTOptions('togglerIcon')" />
|
||||||
<component v-else :is="node.collapsedIcon ? 'span' : 'ChevronRightIcon'" class="p-tree-toggler-icon" />
|
<component v-else :is="node.collapsedIcon ? 'span' : 'ChevronRightIcon'" class="p-tree-toggler-icon" v-bind="getPTOptions('togglerIcon')" />
|
||||||
</button>
|
</button>
|
||||||
<div v-if="checkboxMode" class="p-checkbox p-component" aria-hidden="true">
|
<div v-if="checkboxMode" class="p-checkbox p-component" aria-hidden="true" v-bind="getPTOptions('checkboxContainer')">
|
||||||
<div :class="checkboxClass" role="checkbox">
|
<div :class="checkboxClass" 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="p-checkbox-icon" />
|
||||||
<component v-else :is="checked ? 'CheckIcon' : partialChecked ? 'MinusIcon' : null" class="p-checkbox-icon" />
|
<component v-else :is="checked ? 'CheckIcon' : partialChecked ? 'MinusIcon' : null" class="p-checkbox-icon" v-bind="getPTOptions('checkboxIcon')" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<span :class="icon"></span>
|
<span :class="icon" v-bind="getPTOptions('nodeIcon')"></span>
|
||||||
<span class="p-treenode-label">
|
<span class="p-treenode-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">
|
<ul v-if="hasChildren && expanded" class="p-treenode-children" 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"
|
||||||
|
@ -44,12 +45,14 @@
|
||||||
:selectionMode="selectionMode"
|
:selectionMode="selectionMode"
|
||||||
:selectionKeys="selectionKeys"
|
:selectionKeys="selectionKeys"
|
||||||
@checkbox-change="propagateUp"
|
@checkbox-change="propagateUp"
|
||||||
|
:pt="pt"
|
||||||
/>
|
/>
|
||||||
</ul>
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
</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';
|
||||||
|
@ -59,6 +62,7 @@ import { DomHandler } from 'primevue/utils';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'TreeNode',
|
name: 'TreeNode',
|
||||||
|
extends: BaseComponent,
|
||||||
emits: ['node-toggle', 'node-click', 'checkbox-change'],
|
emits: ['node-toggle', 'node-click', 'checkbox-change'],
|
||||||
props: {
|
props: {
|
||||||
node: {
|
node: {
|
||||||
|
@ -110,6 +114,15 @@ export default {
|
||||||
onChildNodeToggle(node) {
|
onChildNodeToggle(node) {
|
||||||
this.$emit('node-toggle', node);
|
this.$emit('node-toggle', node);
|
||||||
},
|
},
|
||||||
|
getPTOptions(key) {
|
||||||
|
return this.ptm(key, {
|
||||||
|
context: {
|
||||||
|
expanded: this.expanded,
|
||||||
|
selected: this.selected,
|
||||||
|
checked: this.checked
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
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.hasClass(event.target, 'p-tree-toggler') || DomHandler.hasClass(event.target.parentElement, 'p-tree-toggler')) {
|
||||||
this.toggleClicked = false;
|
this.toggleClicked = false;
|
||||||
|
|
Loading…
Reference in New Issue