Refactor #3832 Refactor #3833 - For Tree

pull/3853/head
Tuğçe Küçükoğlu 2023-04-07 09:49:49 +03:00
parent 7a5860f97b
commit 20726d35e1
4 changed files with 79 additions and 20 deletions

View File

@ -127,11 +127,31 @@ const TreeEvents = [
} }
]; ];
const TreeSlots = [
{
name: 'loadingicon',
description: 'Custom loading icon template.'
},
{
name: 'searchicon',
description: 'Custom search icon template.'
},
{
name: 'togglericon',
description: 'Custom toggler icon template.'
},
{
name: 'checkboxicon',
description: 'Custom checkbox icon template.'
}
];
module.exports = { module.exports = {
tree: { tree: {
name: 'Tree', name: 'Tree',
description: 'Tree is used to display hierarchical data.', description: 'Tree is used to display hierarchical data.',
props: TreeProps, props: TreeProps,
events: TreeEvents events: TreeEvents,
slots: TreeSlots
} }
}; };

View File

@ -168,15 +168,45 @@ export interface TreeProps {
*/ */
export interface TreeSlots { export interface TreeSlots {
/** /**
* Optional slots. * Custom loading icon template.
* @todo
*/ */
[key: string]: (scope: { loadingicon(): VNode[];
/**
* Custom search icon template.
*/
searchicon(): VNode[];
/**
* Custom toggler icon template.
*/
togglericon(scope: {
/** /**
* Tree node instance * Tree node instance
*/ */
node: TreeNode; node: TreeNode;
}) => VNode[]; /**
* Expanded state of the node
*/
expanded: boolean;
}): VNode[];
/**
* Custom checkbox icon
*/
checkboxicon(scope: {
/**
* Check state of the node
*/
checked: boolean;
/**
* Partial check state of the node
*/
partialChecked: boolean;
}): VNode[];
/**
* Optional slots.
* @todo
*/
[key: string]: (node: any) => VNode[];
} }
/** /**

View File

@ -2,12 +2,16 @@
<div :class="containerClass"> <div :class="containerClass">
<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">
<i :class="loadingIconClass" /> <slot name="loadingicon">
<component :is="loadingIcon ? 'i' : 'SpinnerIcon'" spin :class="['p-tree-loading-icon', loadingIcon]" />
</slot>
</div> </div>
</template> </template>
<div v-if="filter" class="p-tree-filter-container"> <div v-if="filter" class="p-tree-filter-container">
<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" />
<span class="p-tree-filter-icon pi pi-search"></span> <slot name="searchicon">
<SearchIcon class="p-tree-filter-icon" />
</slot>
</div> </div>
<div class="p-tree-wrapper" :style="{ maxHeight: scrollHeight }"> <div class="p-tree-wrapper" :style="{ maxHeight: scrollHeight }">
<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">
@ -31,6 +35,8 @@
</template> </template>
<script> <script>
import SearchIcon from 'primevue/icon/search';
import SpinnerIcon from 'primevue/icon/spinner';
import { ObjectUtils } from 'primevue/utils'; import { ObjectUtils } from 'primevue/utils';
import TreeNode from './TreeNode.vue'; import TreeNode from './TreeNode.vue';
@ -64,7 +70,7 @@ export default {
}, },
loadingIcon: { loadingIcon: {
type: String, type: String,
default: 'pi pi-spinner' default: undefined
}, },
filter: { filter: {
type: Boolean, type: Boolean,
@ -275,9 +281,6 @@ export default {
} }
]; ];
}, },
loadingIconClass() {
return ['p-tree-loading-icon pi-spin', this.loadingIcon];
},
filteredValue() { filteredValue() {
let filteredNodes = []; let filteredNodes = [];
const searchFields = this.filterBy.split(','); const searchFields = this.filterBy.split(',');
@ -304,7 +307,9 @@ export default {
} }
}, },
components: { components: {
TreeNode: TreeNode TreeNode: TreeNode,
SearchIcon: SearchIcon,
SpinnerIcon: SpinnerIcon
} }
}; };
</script> </script>

View File

@ -15,11 +15,11 @@
> >
<div :class="contentClass" @click="onClick" @touchend="onTouchEnd" :style="node.style"> <div :class="contentClass" @click="onClick" @touchend="onTouchEnd" :style="node.style">
<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">
<span :class="toggleIcon"></span> <component :is="templates['togglericon'] ? templates['togglericon'] : expanded ? node.expandedIcon || 'ChevronDownIcon' : node.collapsedIcon || 'ChevronRightIcon'" :node="node" :expanded="expanded" class="p-tree-toggler-icon pi-fw" />
</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">
<div :class="checkboxClass" role="checkbox"> <div :class="checkboxClass" role="checkbox">
<span :class="checkboxIcon"></span> <component :is="templates['checkboxicon'] ? templates['checkboxicon'] : checked ? 'CheckIcon' : partialChecked ? 'MinusIcon' : null" :checked="checked" :partialChecked="partialChecked" class="p-checkbox-icon" />
</div> </div>
</div> </div>
<span :class="icon"></span> <span :class="icon"></span>
@ -47,6 +47,10 @@
</template> </template>
<script> <script>
import CheckIcon from 'primevue/icon/check';
import ChevronDownIcon from 'primevue/icon/chevrondown';
import ChevronRightIcon from 'primevue/icon/chevronright';
import MinusIcon from 'primevue/icon/minus';
import Ripple from 'primevue/ripple'; import Ripple from 'primevue/ripple';
import { DomHandler } from 'primevue/utils'; import { DomHandler } from 'primevue/utils';
@ -408,15 +412,9 @@ export default {
icon() { icon() {
return ['p-treenode-icon', this.node.icon]; return ['p-treenode-icon', this.node.icon];
}, },
toggleIcon() {
return ['p-tree-toggler-icon pi pi-fw', this.expanded ? this.node.expandedIcon || 'pi-chevron-down' : this.node.collapsedIcon || 'pi-chevron-right'];
},
checkboxClass() { checkboxClass() {
return ['p-checkbox-box', { 'p-highlight': this.checked, 'p-indeterminate': this.partialChecked }]; return ['p-checkbox-box', { 'p-highlight': this.checked, 'p-indeterminate': this.partialChecked }];
}, },
checkboxIcon() {
return ['p-checkbox-icon', { 'pi pi-check': this.checked, 'pi pi-minus': this.partialChecked }];
},
checkboxMode() { checkboxMode() {
return this.selectionMode === 'checkbox' && this.node.selectable !== false; return this.selectionMode === 'checkbox' && this.node.selectable !== false;
}, },
@ -433,6 +431,12 @@ export default {
return this.checkboxMode ? this.checked : undefined; return this.checkboxMode ? this.checked : undefined;
} }
}, },
components: {
ChevronDownIcon: ChevronDownIcon,
ChevronRightIcon: ChevronRightIcon,
CheckIcon: CheckIcon,
MinusIcon: MinusIcon
},
directives: { directives: {
ripple: Ripple ripple: Ripple
} }