Fixed #4886 - Tree / TreeTable: new loadingMode property

pull/4899/head
tugcekucukoglu 2023-11-28 11:46:39 +03:00
parent 098c7a5128
commit b2ad40adcc
10 changed files with 61 additions and 14 deletions

View File

@ -34,6 +34,10 @@ export default {
type: String, type: String,
default: undefined default: undefined
}, },
loadingMode: {
type: String,
default: 'mask'
},
filter: { filter: {
type: Boolean, type: Boolean,
default: false default: false

View File

@ -232,6 +232,11 @@ export interface TreeProps {
* @deprecated since v3.27.0. Use 'loadingicon' slot. * @deprecated since v3.27.0. Use 'loadingicon' slot.
*/ */
loadingIcon?: string | undefined; loadingIcon?: string | undefined;
/**
* Loading mode display.
* @defaultValue mask
*/
loadingMode?: 'mask' | 'icon' | undefined;
/** /**
* When specified, displays an input field to filter the items. * When specified, displays an input field to filter the items.
* @defaultValue false * @defaultValue false

View File

@ -1,6 +1,6 @@
<template> <template>
<div :class="cx('root')" v-bind="ptm('root')" data-pc-name="tree"> <div :class="cx('root')" v-bind="ptm('root')" data-pc-name="tree">
<template v-if="loading"> <template v-if="loading && loadingMode === 'mask'">
<div :class="cx('loadingOverlay')" v-bind="ptm('loadingOverlay')"> <div :class="cx('loadingOverlay')" v-bind="ptm('loadingOverlay')">
<slot name="loadingicon" :class="cx('loadingIcon')"> <slot name="loadingicon" :class="cx('loadingIcon')">
<i v-if="loadingIcon" :class="[cx('loadingIcon'), 'pi-spin', loadingIcon]" v-bind="ptm('loadingIcon')" /> <i v-if="loadingIcon" :class="[cx('loadingIcon'), 'pi-spin', loadingIcon]" v-bind="ptm('loadingIcon')" />
@ -29,6 +29,7 @@
:selectionMode="selectionMode" :selectionMode="selectionMode"
:selectionKeys="selectionKeys" :selectionKeys="selectionKeys"
@checkbox-change="onCheckboxChange" @checkbox-change="onCheckboxChange"
:loadingMode="loadingMode"
:pt="pt" :pt="pt"
:unstyled="unstyled" :unstyled="unstyled"
></TreeNode> ></TreeNode>

View File

@ -16,9 +16,15 @@
> >
<div :class="cx('content')" @click="onClick" @touchend="onTouchEnd" :style="node.style" v-bind="getPTOptions('content')" :data-p-highlight="checkboxMode ? checked : selected" :data-p-selectable="selectable"> <div :class="cx('content')" @click="onClick" @touchend="onTouchEnd" :style="node.style" v-bind="getPTOptions('content')" :data-p-highlight="checkboxMode ? checked : selected" :data-p-selectable="selectable">
<button v-ripple type="button" :class="cx('toggler')" @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')">
<template v-if="node.loading && loadingMode === 'icon'">
<component v-if="templates['nodetogglericon']" :is="templates['nodetogglericon']" :class="cx('nodetogglericon')" />
<SpinnerIcon v-else spin :class="cx('nodetogglericon')" v-bind="ptm('nodetogglericon')" />
</template>
<template v-else>
<component v-if="templates['togglericon']" :is="templates['togglericon']" :node="node" :expanded="expanded" :class="cx('togglerIcon')" /> <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="cx('togglerIcon')" 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="cx('togglerIcon')" v-bind="getPTOptions('togglerIcon')" /> <component v-else :is="node.collapsedIcon ? 'span' : 'ChevronRightIcon'" :class="cx('togglerIcon')" v-bind="getPTOptions('togglerIcon')" />
</template>
</button> </button>
<div v-if="checkboxMode" :class="cx('checkboxContainer')" aria-hidden="true" v-bind="getPTOptions('checkboxContainer')"> <div v-if="checkboxMode" :class="cx('checkboxContainer')" aria-hidden="true" v-bind="getPTOptions('checkboxContainer')">
<div :class="cx('checkbox')" role="checkbox" v-bind="getPTOptions('checkbox')" :data-p-checked="checked" :data-p-partialchecked="partialChecked"> <div :class="cx('checkbox')" role="checkbox" v-bind="getPTOptions('checkbox')" :data-p-checked="checked" :data-p-partialchecked="partialChecked">
@ -57,6 +63,7 @@ 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 SpinnerIcon from 'primevue/icons/spinner';
import Ripple from 'primevue/ripple'; import Ripple from 'primevue/ripple';
import { DomHandler } from 'primevue/utils'; import { DomHandler } from 'primevue/utils';
@ -74,6 +81,10 @@ export default {
type: null, type: null,
default: null default: null
}, },
loadingMode: {
type: String,
default: 'mask'
},
selectionKeys: { selectionKeys: {
type: null, type: null,
default: null default: null
@ -90,10 +101,7 @@ export default {
type: Number, type: Number,
default: null default: null
}, },
index: { index: null
type: Number,
default: null
}
}, },
nodeTouched: false, nodeTouched: false,
toggleClicked: false, toggleClicked: false,
@ -435,7 +443,8 @@ export default {
ChevronDownIcon: ChevronDownIcon, ChevronDownIcon: ChevronDownIcon,
ChevronRightIcon: ChevronRightIcon, ChevronRightIcon: ChevronRightIcon,
CheckIcon: CheckIcon, CheckIcon: CheckIcon,
MinusIcon: MinusIcon MinusIcon: MinusIcon,
SpinnerIcon: SpinnerIcon
}, },
directives: { directives: {
ripple: Ripple ripple: Ripple

View File

@ -113,6 +113,7 @@ const classes = {
], ],
toggler: 'p-tree-toggler p-link', toggler: 'p-tree-toggler p-link',
togglerIcon: 'p-tree-toggler-icon', togglerIcon: 'p-tree-toggler-icon',
nodeTogglerIcon: 'p-tree-node-toggler-icon',
checkboxContainer: 'p-checkbox p-component', checkboxContainer: 'p-checkbox p-component',
checkbox: ({ instance }) => [ checkbox: ({ instance }) => [
'p-checkbox-box', 'p-checkbox-box',

View File

@ -78,6 +78,10 @@ export default {
type: String, type: String,
default: undefined default: undefined
}, },
loadingMode: {
type: String,
default: 'mask'
},
rowHover: { rowHover: {
type: Boolean, type: Boolean,
default: false default: false

View File

@ -1,9 +1,15 @@
<template> <template>
<td :style="containerStyle" :class="containerClass" role="cell" v-bind="{ ...getColumnPT('root'), ...getColumnPT('bodyCell') }" :data-p-frozen-column="columnProp('frozen')"> <td :style="containerStyle" :class="containerClass" role="cell" v-bind="{ ...getColumnPT('root'), ...getColumnPT('bodyCell') }" :data-p-frozen-column="columnProp('frozen')">
<button v-if="columnProp('expander')" v-ripple type="button" :class="cx('rowToggler')" @click="toggle" :style="togglerStyle" tabindex="-1" v-bind="getColumnPT('rowToggler')" data-pc-group-section="rowactionbutton"> <button v-if="columnProp('expander')" v-ripple type="button" :class="cx('rowToggler')" @click="toggle" :style="togglerStyle" tabindex="-1" v-bind="getColumnPT('rowToggler')" data-pc-group-section="rowactionbutton">
<template v-if="node.loading && loadingMode === 'icon'">
<component v-if="templates['nodetogglericon']" :is="templates['nodetogglericon']" :class="cx('nodetogglericon')" />
<SpinnerIcon v-else spin :class="cx('nodetogglericon')" v-bind="ptm('nodetogglericon')" />
</template>
<template v-else>
<component v-if="column.children && column.children.rowtogglericon" :is="column.children && column.children.rowtogglericon" :node="node" :expanded="expanded" :class="cx('rowTogglerIcon')" /> <component v-if="column.children && column.children.rowtogglericon" :is="column.children && column.children.rowtogglericon" :node="node" :expanded="expanded" :class="cx('rowTogglerIcon')" />
<component v-else-if="expanded" :is="node.expandedIcon ? 'span' : 'ChevronDownIcon'" :class="cx('rowTogglerIcon')" v-bind="getColumnPT('rowTogglerIcon')" /> <component v-else-if="expanded" :is="node.expandedIcon ? 'span' : 'ChevronDownIcon'" :class="cx('rowTogglerIcon')" v-bind="getColumnPT('rowTogglerIcon')" />
<component v-else :is="node.collapsedIcon ? 'span' : 'ChevronRightIcon'" :class="cx('rowTogglerIcon')" v-bind="getColumnPT('rowTogglerIcon')" /> <component v-else :is="node.collapsedIcon ? 'span' : 'ChevronRightIcon'" :class="cx('rowTogglerIcon')" v-bind="getColumnPT('rowTogglerIcon')" />
</template>
</button> </button>
<div v-if="checkboxSelectionMode && columnProp('expander')" :class="cx('checkboxWrapper')" @click="toggleCheckbox" v-bind="getColumnCheckboxPT('checkboxWrapper')"> <div v-if="checkboxSelectionMode && columnProp('expander')" :class="cx('checkboxWrapper')" @click="toggleCheckbox" v-bind="getColumnCheckboxPT('checkboxWrapper')">
<div class="p-hidden-accessible" v-bind="getColumnPT('hiddenInputWrapper')" :data-p-hidden-accessible="true"> <div class="p-hidden-accessible" v-bind="getColumnPT('hiddenInputWrapper')" :data-p-hidden-accessible="true">
@ -28,6 +34,7 @@ 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 SpinnerIcon from 'primevue/icons/spinner';
import { DomHandler, ObjectUtils } from 'primevue/utils'; import { DomHandler, ObjectUtils } from 'primevue/utils';
import { mergeProps } from 'vue'; import { mergeProps } from 'vue';
@ -80,6 +87,10 @@ export default {
index: { index: {
type: Number, type: Number,
default: null default: null
},
loadingMode: {
type: String,
default: 'mask'
} }
}, },
data() { data() {
@ -208,7 +219,8 @@ export default {
ChevronRightIcon: ChevronRightIcon, ChevronRightIcon: ChevronRightIcon,
ChevronDownIcon: ChevronDownIcon, ChevronDownIcon: ChevronDownIcon,
CheckIcon: CheckIcon, CheckIcon: CheckIcon,
MinusIcon: MinusIcon MinusIcon: MinusIcon,
SpinnerIcon: SpinnerIcon
}, },
directives: { directives: {
ripple: Ripple ripple: Ripple

View File

@ -474,6 +474,11 @@ export interface TreeTableProps {
* @deprecated since v3.27.0. Use 'loadingicon' slot. * @deprecated since v3.27.0. Use 'loadingicon' slot.
*/ */
loadingIcon?: string | undefined; loadingIcon?: string | undefined;
/**
* Loading mode display.
* @defaultValue mask
*/
loadingMode?: 'mask' | 'icon' | undefined;
/** /**
* When enabled, background of the rows change on hover. * When enabled, background of the rows change on hover.
* @defaultValue false * @defaultValue false

View File

@ -1,6 +1,6 @@
<template> <template>
<div :class="cx('root')" data-scrollselectors=".p-treetable-scrollable-body" role="table" v-bind="ptm('root')" data-pc-name="treetable"> <div :class="cx('root')" data-scrollselectors=".p-treetable-scrollable-body" role="table" v-bind="ptm('root')" data-pc-name="treetable">
<div v-if="loading" :class="cx('loadingWrapper')" v-bind="ptm('loadingWrapper')"> <div v-if="loading && loadingMode === 'mask'" :class="cx('loadingWrapper')" v-bind="ptm('loadingWrapper')">
<div :class="cx('loadingOverlay')" v-bind="ptm('loadingOverlay')"> <div :class="cx('loadingOverlay')" v-bind="ptm('loadingOverlay')">
<slot name="loadingicon" :class="cx('loadingIcon')"> <slot name="loadingicon" :class="cx('loadingIcon')">
<component :is="loadingIcon ? 'span' : 'SpinnerIcon'" spin :class="[cx('loadingIcon'), loadingIcon]" v-bind="ptm('loadingIcon')" /> <component :is="loadingIcon ? 'span' : 'SpinnerIcon'" spin :class="[cx('loadingIcon'), loadingIcon]" v-bind="ptm('loadingIcon')" />
@ -94,6 +94,7 @@
:ariaSetSize="dataToRender.length" :ariaSetSize="dataToRender.length"
:ariaPosInset="index + 1" :ariaPosInset="index + 1"
:tabindex="setTabindex(node, index)" :tabindex="setTabindex(node, index)"
:loadingMode="loadingMode"
:templates="$slots" :templates="$slots"
@node-toggle="onNodeToggle" @node-toggle="onNodeToggle"
@node-click="onNodeClick" @node-click="onNodeClick"

View File

@ -33,6 +33,7 @@
@node-toggle="$emit('node-toggle', $event)" @node-toggle="$emit('node-toggle', $event)"
@checkbox-toggle="toggleCheckbox" @checkbox-toggle="toggleCheckbox"
:index="i" :index="i"
:loadingMode="loadingMode"
:pt="pt" :pt="pt"
></TTBodyCell> ></TTBodyCell>
</template> </template>
@ -115,6 +116,10 @@ export default {
type: Number, type: Number,
default: null default: null
}, },
loadingMode: {
type: String,
default: 'mask'
},
templates: { templates: {
type: Object, type: Object,
default: null default: null