Refactor #3832 Refactor #3833 - For DataTable & Column

pull/3861/head
Tuğçe Küçükoğlu 2023-04-13 17:42:33 +03:00
parent bb65e68636
commit b82c553747
12 changed files with 314 additions and 73 deletions

View File

@ -289,6 +289,50 @@ const ColumnSlots = [
{ {
name: 'filterapply', name: 'filterapply',
description: "Custom content for the filter menu's apply section" description: "Custom content for the filter menu's apply section"
},
{
name: 'rowtogglericon',
description: 'Custom row toggler icon template.'
},
{
name: 'roweditoriniticon',
description: 'Custom row editor init icon template.'
},
{
name: 'roweditorsaveicon',
description: 'Custom row editor save icon template.'
},
{
name: 'roweditorcancelicon',
description: 'Custom row editor cancel icon template.'
},
{
name: 'filtericon',
description: 'Custom filter icon template.'
},
{
name: 'filterclearicon',
description: 'Custom filter clear icon template.'
},
{
name: 'filterremoveicon',
description: 'Custom filter remove icon template.'
},
{
name: 'filteraddicon',
description: 'Custom filter add icon template.'
},
{
name: 'sorticon',
description: 'Custom sort icon template.'
},
{
name: 'headercheckboxicon',
description: 'Custom header checkbox icon template.'
},
{
name: 'rowcheckboxicon',
description: 'Custom row checkbox icon template.'
} }
]; ];

View File

@ -1120,31 +1120,43 @@ const DataTableEvents = [
const DataTableSlots = [ const DataTableSlots = [
{ {
name: 'header', name: 'header',
description: "Custom content for the component's header" description: "Custom content for the component's header."
}, },
{ {
name: 'paginatorstart', name: 'paginatorstart',
description: "Custom content for the component paginator's left side" description: "Custom content for the component paginator's left side."
}, },
{ {
name: 'paginatorend', name: 'paginatorend',
description: "Custom content for the component paginator's right side" description: "Custom content for the component paginator's right side."
}, },
{ {
name: 'footer', name: 'footer',
description: "Custom content for the component's footer" description: "Custom content for the component's footer."
}, },
{ {
name: 'groupheader', name: 'groupheader',
description: "Custom content for the component's subgroup header" description: "Custom content for the component's subgroup header."
}, },
{ {
name: 'groupfooter', name: 'groupfooter',
description: "Custom content for the component's subgroup footer" description: "Custom content for the component's subgroup footer."
}, },
{ {
name: 'expansion', name: 'loadingicon',
description: "Custom content for the component's expanded content" description: 'Custom loading icon template.'
},
{
name: 'reorderindicatorupicon',
description: 'Custom reorder indicator up icon template.'
},
{
name: 'reorderindicatordownicon',
description: 'Custom reorder indicator down icon template.'
},
{
name: 'rowgrouptogglericon',
description: 'Custom rowgroup toggler icon template.'
} }
]; ];

View File

@ -486,6 +486,78 @@ export interface ColumnSlots {
*/ */
loadingOptions: ColumnLoadingOptions; loadingOptions: ColumnLoadingOptions;
}): VNode[]; }): VNode[];
/**
* Custom row toggler icon template.
* @param {Object} scope - row toggler icon slot's params.
*/
rowtogglericon(scope: {
/**
* Current row expanded state.
*/
rowExpanded: boolean;
}): VNode[];
/**
* Custom row checkbox icon template.
* @param {Object} scope - header row icon slot's params.
*/
rowcheckboxicon(scope: {
/**
* Current check state.
*/
checked: boolean;
}): VNode[];
/**
* Custom row editor init icon template.
*/
roweditoriniticon(): VNode[];
/**
* Custom row editor save icon template.
*/
roweditorsaveicon(): VNode[];
/**
* Custom row editor cancel icon template.
*/
roweditorcancelicon(): VNode[];
/**
* Custom filter icon template.
*/
filtericon(): VNode[];
/**
* Custom filter clear icon template.
*/
filterclearicon(): VNode[];
/**
* Custom filter remove icon template.
*/
filterremoveicon(): VNode[];
/**
* Custom filter add icon template.
*/
filteraddicon(): VNode[];
/**
* Custom sort icon template.
* @param {Object} scope - sort icon slot's params.
*/
sorticon(scope: {
/**
* Current sort state.
*/
sorted: boolean;
/**
* Current sort order state.
*/
sortOrder: boolean;
}): VNode[];
/**
* Custom header checkbox icon template.
* @param {Object} scope - header checkbox icon slot's params.
*/
headercheckboxicon(scope: {
/**
* Current check state.
*/
checked: boolean;
}): VNode[];
} }
export interface ColumnEmits {} export interface ColumnEmits {}

View File

@ -19,25 +19,34 @@
<component v-else-if="column.children && column.children.body && !column.children.editor && d_editing" :is="column.children.body" :data="editingRowData" :column="column" :field="field" :index="rowIndex" :frozenRow="frozenRow" /> <component v-else-if="column.children && column.children.body && !column.children.editor && d_editing" :is="column.children.body" :data="editingRowData" :column="column" :field="field" :index="rowIndex" :frozenRow="frozenRow" />
<template v-else-if="columnProp('selectionMode')"> <template v-else-if="columnProp('selectionMode')">
<DTRadioButton v-if="columnProp('selectionMode') === 'single'" :value="rowData" :name="name" :checked="selected" @change="toggleRowWithRadio($event, rowIndex)" /> <DTRadioButton v-if="columnProp('selectionMode') === 'single'" :value="rowData" :name="name" :checked="selected" @change="toggleRowWithRadio($event, rowIndex)" />
<DTCheckbox v-else-if="columnProp('selectionMode') === 'multiple'" :value="rowData" :checked="selected" :aria-selected="selected ? true : undefined" @change="toggleRowWithCheckbox($event, rowIndex)" /> <DTCheckbox
v-else-if="columnProp('selectionMode') === 'multiple'"
:value="rowData"
:checked="selected"
:rowCheckboxIconTemplate="column.children && column.children.rowcheckboxicon"
:aria-selected="selected ? true : undefined"
@change="toggleRowWithCheckbox($event, rowIndex)"
/>
</template> </template>
<template v-else-if="columnProp('rowReorder')"> <template v-else-if="columnProp('rowReorder')">
<i :class="['p-datatable-reorderablerow-handle', columnProp('rowReorderIcon') || 'pi pi-bars']"></i> <component :is="column.children && column.children.rowreordericon ? column.children.rowreordericon : columnProp('rowReorderIcon') ? 'i' : 'BarsIcon'" :class="['p-datatable-reorderablerow-handle', columnProp('rowReorderIcon')]" />
</template> </template>
<template v-else-if="columnProp('expander')"> <template v-else-if="columnProp('expander')">
<button v-ripple class="p-row-toggler p-link" type="button" :aria-expanded="isRowExpanded" :aria-controls="ariaControls" :aria-label="expandButtonAriaLabel" @click="toggleRow"> <button v-ripple class="p-row-toggler p-link" type="button" :aria-expanded="isRowExpanded" :aria-controls="ariaControls" :aria-label="expandButtonAriaLabel" @click="toggleRow">
<span :class="rowTogglerIcon"></span> <component v-if="column.children && column.children.rowtogglericon" :is="column.children.rowtogglericon" :rowExpanded="isRowExpanded" />
<component v-else-if="column.children && !column.children.rowtogglericon && isRowExpanded" :is="expandedRowIcon ? 'span' : 'ChevronDownIcon'" class="p-row-toggler-icon" />
<component v-else-if="column.children && !column.children.rowtogglericon && !isRowExpanded" :is="collapsedRowIcon ? 'span' : 'ChevronRightIcon'" class="p-row-toggler-icon" />
</button> </button>
</template> </template>
<template v-else-if="editMode === 'row' && columnProp('rowEditor')"> <template v-else-if="editMode === 'row' && columnProp('rowEditor')">
<button v-if="!d_editing" v-ripple class="p-row-editor-init p-link" type="button" :aria-label="initButtonAriaLabel" @click="onRowEditInit"> <button v-if="!d_editing" v-ripple class="p-row-editor-init p-link" type="button" :aria-label="initButtonAriaLabel" @click="onRowEditInit">
<span class="p-row-editor-init-icon pi pi-fw pi-pencil"></span> <component :is="(column.children && !column.children.roweditoriniticon) || 'PencilIcon'" class="p-row-editor-init-icon pi-fw" />
</button> </button>
<button v-if="d_editing" v-ripple class="p-row-editor-save p-link" type="button" :aria-label="saveButtonAriaLabel" @click="onRowEditSave"> <button v-if="d_editing" v-ripple class="p-row-editor-save p-link" type="button" :aria-label="saveButtonAriaLabel" @click="onRowEditSave">
<span class="p-row-editor-save-icon pi pi-fw pi-check"></span> <component :is="(column.children && !column.children.roweditorsaveicon) || 'CheckIcon'" class="p-row-editor-save-icon pi-fw" />
</button> </button>
<button v-if="d_editing" v-ripple class="p-row-editor-cancel p-link" type="button" :aria-label="cancelButtonAriaLabel" @click="onRowEditCancel"> <button v-if="d_editing" v-ripple class="p-row-editor-cancel p-link" type="button" :aria-label="cancelButtonAriaLabel" @click="onRowEditCancel">
<span class="p-row-editor-cancel-icon pi pi-fw pi-times"></span> <component :is="(column.children && !column.children.roweditorcancelicon) || 'TimesIcon'" class="p-row-editor-cancel-icon pi-fw" />
</button> </button>
</template> </template>
<template v-else>{{ resolveFieldData() }}</template> <template v-else>{{ resolveFieldData() }}</template>
@ -45,6 +54,12 @@
</template> </template>
<script> <script>
import BarsIcon from 'primevue/icon/bars';
import CheckIcon from 'primevue/icon/check';
import ChevronDownIcon from 'primevue/icon/chevrondown';
import ChevronRightIcon from 'primevue/icon/chevronright';
import PencilIcon from 'primevue/icon/pencil';
import TimesIcon from 'primevue/icon/times';
import OverlayEventBus from 'primevue/overlayeventbus'; import OverlayEventBus from 'primevue/overlayeventbus';
import Ripple from 'primevue/ripple'; import Ripple from 'primevue/ripple';
import { DomHandler, ObjectUtils } from 'primevue/utils'; import { DomHandler, ObjectUtils } from 'primevue/utils';
@ -75,9 +90,9 @@ export default {
type: Number, type: Number,
default: null default: null
}, },
rowTogglerIcon: { isRowExpanded: {
type: Array, type: Boolean,
default: null default: false
}, },
selected: { selected: {
type: Boolean, type: Boolean,
@ -110,6 +125,14 @@ export default {
name: { name: {
type: String, type: String,
default: null default: null
},
expandedRowIcon: {
type: String,
default: null
},
collapsedRowIcon: {
type: String,
default: null
} }
}, },
documentEditListener: null, documentEditListener: null,
@ -118,8 +141,7 @@ export default {
data() { data() {
return { return {
d_editing: this.editing, d_editing: this.editing,
styleObject: {}, styleObject: {}
isRowExpanded: false
}; };
}, },
watch: { watch: {
@ -162,7 +184,6 @@ export default {
return ObjectUtils.resolveFieldData(this.rowData, this.field); return ObjectUtils.resolveFieldData(this.rowData, this.field);
}, },
toggleRow(event) { toggleRow(event) {
this.isRowExpanded = !this.isRowExpanded;
this.$emit('row-toggle', { this.$emit('row-toggle', {
originalEvent: event, originalEvent: event,
data: this.rowData data: this.rowData
@ -453,7 +474,13 @@ export default {
}, },
components: { components: {
DTRadioButton: RowRadioButton, DTRadioButton: RowRadioButton,
DTCheckbox: RowCheckbox DTCheckbox: RowCheckbox,
ChevronDownIcon: ChevronDownIcon,
ChevronRightIcon: ChevronRightIcon,
BarsIcon: BarsIcon,
PencilIcon: PencilIcon,
CheckIcon: CheckIcon,
TimesIcon: TimesIcon
}, },
directives: { directives: {
ripple: Ripple ripple: Ripple

View File

@ -16,9 +16,11 @@
@click="toggleMenu()" @click="toggleMenu()"
@keydown="onToggleButtonKeyDown($event)" @keydown="onToggleButtonKeyDown($event)"
> >
<span class="pi pi-filter-icon pi-filter"></span> <component :is="filterIconTemplate || 'FilterIcon'" />
</button>
<button v-if="showClearButton && display === 'row'" :class="{ 'p-hidden-space': !hasRowFilter() }" type="button" class="p-column-filter-clear-button p-link" @click="clearFilter()">
<component :is="filterClearIconTemplate || 'FilterSlashIcon'" />
</button> </button>
<button v-if="showClearButton && display === 'row'" :class="{ 'p-hidden-space': !hasRowFilter() }" type="button" class="p-column-filter-clear-button p-link" @click="clearFilter()"><span class="pi pi-filter-slash"></span></button>
<Portal> <Portal>
<transition name="p-connected-overlay" @enter="onOverlayEnter" @leave="onOverlayLeave" @after-leave="onOverlayAfterLeave"> <transition name="p-connected-overlay" @enter="onOverlayEnter" @leave="onOverlayLeave" @after-leave="onOverlayAfterLeave">
<div <div
@ -78,19 +80,20 @@
></CFDropdown> ></CFDropdown>
<component v-if="display === 'menu'" :is="filterElement" :field="field" :filterModel="fieldConstraint" :filterCallback="filterCallback" /> <component v-if="display === 'menu'" :is="filterElement" :field="field" :filterModel="fieldConstraint" :filterCallback="filterCallback" />
<div> <div>
<CFButton <CFButton v-if="showRemoveIcon" type="button" class="p-column-filter-remove-button p-button-text p-button-danger p-button-sm" @click="removeConstraint(i)" :label="removeRuleButtonLabel">
v-if="showRemoveIcon" <template #icon>
type="button" <component :is="filterRemoveIconTemplate || 'TrashIcon'" class="p-button-icon-left" />
icon="pi pi-trash" </template>
class="p-column-filter-remove-button p-button-text p-button-danger p-button-sm" </CFButton>
@click="removeConstraint(i)"
:label="removeRuleButtonLabel"
></CFButton>
</div> </div>
</div> </div>
</div> </div>
<div v-if="isShowAddConstraint" class="p-column-filter-add-rule"> <div v-if="isShowAddConstraint" class="p-column-filter-add-rule">
<CFButton type="button" :label="addRuleButtonLabel" icon="pi pi-plus" class="p-column-filter-add-button p-button-text p-button-sm" @click="addConstraint()"></CFButton> <CFButton type="button" :label="addRuleButtonLabel" iconPos="left" class="p-column-filter-add-button p-button-text p-button-sm" @click="addConstraint()">
<template #icon>
<component :is="filterAddIconTemplate || 'PlusIcon'" class="p-button-icon-left" />
</template>
</CFButton>
</div> </div>
<div class="p-column-filter-buttonbar"> <div class="p-column-filter-buttonbar">
<CFButton v-if="!filterClearTemplate && showClearButton" type="button" class="p-button-outlined p-button-sm" :label="clearButtonLabel" @click="clearFilter"></CFButton> <CFButton v-if="!filterClearTemplate && showClearButton" type="button" class="p-button-outlined p-button-sm" :label="clearButtonLabel" @click="clearFilter"></CFButton>
@ -113,6 +116,10 @@ import { FilterOperator } from 'primevue/api';
import Button from 'primevue/button'; import Button from 'primevue/button';
import Dropdown from 'primevue/dropdown'; import Dropdown from 'primevue/dropdown';
import FocusTrap from 'primevue/focustrap'; import FocusTrap from 'primevue/focustrap';
import FilterIcon from 'primevue/icon/filter';
import FilterSlashIcon from 'primevue/icon/filterslash';
import PlusIcon from 'primevue/icon/plus';
import TrashIcon from 'primevue/icon/trash';
import OverlayEventBus from 'primevue/overlayeventbus'; import OverlayEventBus from 'primevue/overlayeventbus';
import Portal from 'primevue/portal'; import Portal from 'primevue/portal';
import { ConnectedOverlayScrollHandler, DomHandler, UniqueComponentId, ZIndexUtils } from 'primevue/utils'; import { ConnectedOverlayScrollHandler, DomHandler, UniqueComponentId, ZIndexUtils } from 'primevue/utils';
@ -174,6 +181,10 @@ export default {
filterFooterTemplate: null, filterFooterTemplate: null,
filterClearTemplate: null, filterClearTemplate: null,
filterApplyTemplate: null, filterApplyTemplate: null,
filterIconTemplate: null,
filterAddIconTemplate: null,
filterRemoveIconTemplate: null,
filterClearIconTemplate: null,
filters: { filters: {
type: Object, type: Object,
default: null default: null
@ -590,7 +601,11 @@ export default {
components: { components: {
CFDropdown: Dropdown, CFDropdown: Dropdown,
CFButton: Button, CFButton: Button,
Portal: Portal Portal: Portal,
FilterSlashIcon: FilterSlashIcon,
FilterIcon: FilterIcon,
TrashIcon: TrashIcon,
PlusIcon: PlusIcon
}, },
directives: { directives: {
focustrap: FocusTrap focustrap: FocusTrap

View File

@ -611,7 +611,6 @@ export interface DataTableProps {
loading?: boolean | undefined; loading?: boolean | undefined;
/** /**
* The icon to show while indicating data load is in progress. * The icon to show while indicating data load is in progress.
* @defaultValue pi pi-spinner
*/ */
loadingIcon?: string | undefined; loadingIcon?: string | undefined;
/** /**
@ -730,12 +729,10 @@ export interface DataTableProps {
expandedRows?: any[] | DataTableExpandedRows | null; expandedRows?: any[] | DataTableExpandedRows | null;
/** /**
* Icon of the row toggler to display the row as expanded. * Icon of the row toggler to display the row as expanded.
* @defaultValue pi-chevron-down
*/ */
expandedRowIcon?: string | undefined; expandedRowIcon?: string | undefined;
/** /**
* Icon of the row toggler to display the row as collapsed. * Icon of the row toggler to display the row as collapsed.
* @defaultValue pi-chevron-right
*/ */
collapsedRowIcon?: string | undefined; collapsedRowIcon?: string | undefined;
/** /**
@ -900,6 +897,28 @@ export interface DataTableSlots {
*/ */
index: number; index: number;
}): VNode[]; }): VNode[];
/**
* Custom loading icon template.
*/
loadingicon(): VNode[];
/**
* Custom reorder indicator up icon template.
*/
reorderindicatorupicon(): VNode[];
/**
* Custom reorder indicator down icon template.
*/
reorderindicatordownicon(): VNode[];
/**
* Custom rowgroup toggler icon template.
* @param {Object} scope - rowgroup toggler icon slot's params.
*/
rowgrouptogglericon(scope: {
/**
* Current rowgroup's expanded state.
*/
expanded: boolean;
}): VNode[];
} }
/** /**
* Defines valid emits in Datatable component. * Defines valid emits in Datatable component.

View File

@ -3,7 +3,7 @@
<slot></slot> <slot></slot>
<div v-if="loading" class="p-datatable-loading-overlay p-component-overlay"> <div v-if="loading" class="p-datatable-loading-overlay p-component-overlay">
<slot v-if="$slots.loading" name="loading"></slot> <slot v-if="$slots.loading" name="loading"></slot>
<i v-else :class="loadingIconClass"></i> <component v-else :is="$slots.loadingicon ? $slots.loadingicon : loadingIcon ? 'i' : 'SpinnerIcon'" spin :class="['p-datatable-loading-icon', loadingIcon]" />
</div> </div>
<div v-if="$slots.header" class="p-datatable-header"> <div v-if="$slots.header" class="p-datatable-header">
<slot name="header"></slot> <slot name="header"></slot>
@ -62,6 +62,7 @@
:filtersStore="filters" :filtersStore="filters"
:filterDisplay="filterDisplay" :filterDisplay="filterDisplay"
:filterInputProps="filterInputProps" :filterInputProps="filterInputProps"
:headerCheckboxIconTemplate="$slots.headercheckboxicon"
@column-click="onColumnHeaderClick($event)" @column-click="onColumnHeaderClick($event)"
@column-mousedown="onColumnHeaderMouseDown($event)" @column-mousedown="onColumnHeaderMouseDown($event)"
@filter-change="onFilterChange" @filter-change="onFilterChange"
@ -215,13 +216,20 @@
</template> </template>
</DTPaginator> </DTPaginator>
<div ref="resizeHelper" class="p-column-resizer-helper" style="display: none"></div> <div ref="resizeHelper" class="p-column-resizer-helper" style="display: none"></div>
<span v-if="reorderableColumns" ref="reorderIndicatorUp" class="pi pi-arrow-down p-datatable-reorder-indicator-up" style="position: absolute; display: none" /> <span v-if="reorderableColumns" ref="reorderIndicatorUp" class="p-datatable-reorder-indicator-up" style="position: absolute; display: none">
<span v-if="reorderableColumns" ref="reorderIndicatorDown" class="pi pi-arrow-up p-datatable-reorder-indicator-down" style="position: absolute; display: none" /> <component :is="$slots.reorderindicatorupicon || 'ArrowDownIcon'" />
</span>
<span v-if="reorderableColumns" ref="reorderIndicatorDown" class="p-datatable-reorder-indicator-down" style="position: absolute; display: none">
<component :is="$slots.reorderindicatordownicon || 'ArrowUpIcon'" />
</span>
</div> </div>
</template> </template>
<script> <script>
import { FilterMatchMode, FilterOperator, FilterService } from 'primevue/api'; import { FilterMatchMode, FilterOperator, FilterService } from 'primevue/api';
import ArrowDownIcon from 'primevue/icon/arrowdown';
import ArrowUpIcon from 'primevue/icon/arrowup';
import SpinnerIcon from 'primevue/icon/spinner';
import Paginator from 'primevue/paginator'; import Paginator from 'primevue/paginator';
import { DomHandler, ObjectUtils, UniqueComponentId } from 'primevue/utils'; import { DomHandler, ObjectUtils, UniqueComponentId } from 'primevue/utils';
import VirtualScroller from 'primevue/virtualscroller'; import VirtualScroller from 'primevue/virtualscroller';
@ -330,7 +338,7 @@ export default {
}, },
loadingIcon: { loadingIcon: {
type: String, type: String,
default: 'pi pi-spinner' default: undefined
}, },
sortField: { sortField: {
type: [String, Function], type: [String, Function],
@ -434,11 +442,11 @@ export default {
}, },
expandedRowIcon: { expandedRowIcon: {
type: String, type: String,
default: 'pi-chevron-down' default: undefined
}, },
collapsedRowIcon: { collapsedRowIcon: {
type: String, type: String,
default: 'pi-chevron-right' default: undefined
}, },
rowGroupMode: { rowGroupMode: {
type: String, type: String,
@ -2251,9 +2259,6 @@ export default {
sorted() { sorted() {
return this.d_sortField || (this.d_multiSortMeta && this.d_multiSortMeta.length > 0); return this.d_sortField || (this.d_multiSortMeta && this.d_multiSortMeta.length > 0);
}, },
loadingIconClass() {
return ['p-datatable-loading-icon pi-spin', this.loadingIcon];
},
allRowsSelected() { allRowsSelected() {
if (this.selectAll !== null) { if (this.selectAll !== null) {
return this.selectAll; return this.selectAll;
@ -2278,7 +2283,10 @@ export default {
DTTableHeader: TableHeader, DTTableHeader: TableHeader,
DTTableBody: TableBody, DTTableBody: TableBody,
DTTableFooter: TableFooter, DTTableFooter: TableFooter,
DTVirtualScroller: VirtualScroller DTVirtualScroller: VirtualScroller,
ArrowDownIcon: ArrowDownIcon,
ArrowUpIcon: ArrowUpIcon,
SpinnerIcon: SpinnerIcon
} }
}; };
</script> </script>

View File

@ -19,9 +19,11 @@
<div class="p-column-header-content"> <div class="p-column-header-content">
<component v-if="column.children && column.children.header" :is="column.children.header" :column="column" /> <component v-if="column.children && column.children.header" :is="column.children.header" :column="column" />
<span v-if="columnProp('header')" class="p-column-title">{{ columnProp('header') }}</span> <span v-if="columnProp('header')" class="p-column-title">{{ columnProp('header') }}</span>
<span v-if="columnProp('sortable')" :class="sortableColumnIcon"></span> <span v-if="columnProp('sortable')">
<component :is="(column.children && column.children.sorticon) || findSortIcon" :sorted="sortableColumnIcon[1].sorted" :sortOrder="sortableColumnIcon[1].sortOrder" class="p-sortable-column-icon pi-fw" />
</span>
<span v-if="isMultiSorted()" class="p-sortable-column-badge">{{ getBadgeValue() }}</span> <span v-if="isMultiSorted()" class="p-sortable-column-badge">{{ getBadgeValue() }}</span>
<DTHeaderCheckbox v-if="columnProp('selectionMode') === 'multiple' && filterDisplay !== 'row'" :checked="allRowsSelected" @change="onHeaderCheckboxChange" :disabled="empty" /> <DTHeaderCheckbox v-if="columnProp('selectionMode') === 'multiple' && filterDisplay !== 'row'" :checked="allRowsSelected" @change="onHeaderCheckboxChange" :disabled="empty" :headerCheckboxIconTemplate="headerCheckboxIconTemplate" />
<DTColumnFilter <DTColumnFilter
v-if="filterDisplay === 'menu' && column.children && column.children.filter" v-if="filterDisplay === 'menu' && column.children && column.children.filter"
:field="columnProp('filterField') || columnProp('field')" :field="columnProp('filterField') || columnProp('field')"
@ -33,6 +35,10 @@
:filterFooterTemplate="column.children && column.children.filterfooter" :filterFooterTemplate="column.children && column.children.filterfooter"
:filterClearTemplate="column.children && column.children.filterclear" :filterClearTemplate="column.children && column.children.filterclear"
:filterApplyTemplate="column.children && column.children.filterapply" :filterApplyTemplate="column.children && column.children.filterapply"
:filterIconTemplate="column.children && column.children.filtericon"
:filterAddIconTemplate="column.children && column.children.filteraddicon"
:filterRemoveIconTemplate="column.children && column.children.filterremoveicon"
:filterClearIconTemplate="column.children && column.children.filterclearicon"
:filters="filters" :filters="filters"
:filtersStore="filtersStore" :filtersStore="filtersStore"
:filterInputProps="filterInputProps" :filterInputProps="filterInputProps"
@ -58,6 +64,9 @@
</template> </template>
<script> <script>
import SortAltIcon from 'primevue/icon/sortalt';
import SortAmountDownIcon from 'primevue/icon/sortamountdown';
import SortAmountUpAltIcon from 'primevue/icon/sortamountupalt';
import { DomHandler, ObjectUtils } from 'primevue/utils'; import { DomHandler, ObjectUtils } from 'primevue/utils';
import ColumnFilter from './ColumnFilter.vue'; import ColumnFilter from './ColumnFilter.vue';
import HeaderCheckbox from './HeaderCheckbox.vue'; import HeaderCheckbox from './HeaderCheckbox.vue';
@ -146,6 +155,10 @@ export default {
filterInputProps: { filterInputProps: {
type: null, type: null,
default: null default: null
},
headerCheckboxIconTemplate: {
type: null,
default: null
} }
}, },
data() { data() {
@ -284,20 +297,28 @@ export default {
} }
return [ return [
'p-sortable-column-icon pi pi-fw',
{ {
'pi-sort-alt': !sorted, SortAltIcon: !sorted,
'pi-sort-amount-up-alt': sorted && sortOrder > 0, SortAmountUpAltIcon: sorted && sortOrder > 0,
'pi-sort-amount-down': sorted && sortOrder < 0 SortAmountDownIcon: sorted && sortOrder < 0
},
{
sorted,
sortOrder
} }
]; ];
}, },
findSortIcon() {
const sortIcon = this.sortableColumnIcon[0];
return Object.keys(sortIcon).find((key) => sortIcon[key] === true);
},
ariaSort() { ariaSort() {
if (this.columnProp('sortable')) { if (this.columnProp('sortable')) {
const sortIcon = this.sortableColumnIcon; const sortIcon = this.sortableColumnIcon[0];
if (sortIcon[1]['pi-sort-amount-down']) return 'descending'; if (sortIcon['SortAmountDownIcon']) return 'descending';
else if (sortIcon[1]['pi-sort-amount-up-alt']) return 'ascending'; else if (sortIcon['SortAmountUpAltIcon']) return 'ascending';
else return 'none'; else return 'none';
} else { } else {
return null; return null;
@ -306,7 +327,10 @@ export default {
}, },
components: { components: {
DTHeaderCheckbox: HeaderCheckbox, DTHeaderCheckbox: HeaderCheckbox,
DTColumnFilter: ColumnFilter DTColumnFilter: ColumnFilter,
SortAltIcon: SortAltIcon,
SortAmountUpAltIcon: SortAmountUpAltIcon,
SortAmountDownIcon: SortAmountDownIcon
} }
}; };
</script> </script>

View File

@ -4,12 +4,13 @@
<input ref="input" type="checkbox" :checked="checked" :disabled="disabled" :tabindex="disabled ? null : '0'" :aria-label="headerCheckboxAriaLabel" @focus="onFocus($event)" @blur="onBlur($event)" /> <input ref="input" type="checkbox" :checked="checked" :disabled="disabled" :tabindex="disabled ? null : '0'" :aria-label="headerCheckboxAriaLabel" @focus="onFocus($event)" @blur="onBlur($event)" />
</div> </div>
<div ref="box" :class="['p-checkbox-box p-component', { 'p-highlight': checked, 'p-disabled': disabled, 'p-focus': focused }]"> <div ref="box" :class="['p-checkbox-box p-component', { 'p-highlight': checked, 'p-disabled': disabled, 'p-focus': focused }]">
<span :class="['p-checkbox-icon', { 'pi pi-check': checked }]"></span> <component :is="headerCheckboxIconTemplate || 'CheckIcon'" :checked="checked" class="p-checkbox-icon" />
</div> </div>
</div> </div>
</template> </template>
<script> <script>
import CheckIcon from 'primevue/icon/check';
import { DomHandler } from 'primevue/utils'; import { DomHandler } from 'primevue/utils';
export default { export default {
@ -17,7 +18,11 @@ export default {
emits: ['change'], emits: ['change'],
props: { props: {
checked: null, checked: null,
disabled: null disabled: null,
headerCheckboxIconTemplate: {
type: null,
default: null
}
}, },
data() { data() {
return { return {
@ -46,6 +51,9 @@ export default {
headerCheckboxAriaLabel() { headerCheckboxAriaLabel() {
return this.$primevue.config.locale.aria ? (this.checked ? this.$primevue.config.locale.aria.selectAll : this.$primevue.config.locale.aria.unselectAll) : undefined; return this.$primevue.config.locale.aria ? (this.checked ? this.$primevue.config.locale.aria.selectAll : this.$primevue.config.locale.aria.unselectAll) : undefined;
} }
},
components: {
CheckIcon: CheckIcon
} }
}; };
</script> </script>

View File

@ -4,12 +4,13 @@
<input ref="input" type="checkbox" :checked="checked" :disabled="$attrs.disabled" :tabindex="$attrs.disabled ? null : '0'" :aria-label="checkboxAriaLabel" @focus="onFocus($event)" @blur="onBlur($event)" @keydown="onKeydown" /> <input ref="input" type="checkbox" :checked="checked" :disabled="$attrs.disabled" :tabindex="$attrs.disabled ? null : '0'" :aria-label="checkboxAriaLabel" @focus="onFocus($event)" @blur="onBlur($event)" @keydown="onKeydown" />
</div> </div>
<div ref="box" :class="['p-checkbox-box p-component', { 'p-highlight': checked, 'p-disabled': $attrs.disabled, 'p-focus': focused }]"> <div ref="box" :class="['p-checkbox-box p-component', { 'p-highlight': checked, 'p-disabled': $attrs.disabled, 'p-focus': focused }]">
<span :class="['p-checkbox-icon', { 'pi pi-check': checked }]"></span> <component :is="rowCheckboxIconTemplate || 'CheckIcon'" :checked="checked" class="p-checkbox-icon" />
</div> </div>
</div> </div>
</template> </template>
<script> <script>
import CheckIcon from 'primevue/icon/check';
import { DomHandler } from 'primevue/utils'; import { DomHandler } from 'primevue/utils';
export default { export default {
@ -17,7 +18,11 @@ export default {
emits: ['change'], emits: ['change'],
props: { props: {
value: null, value: null,
checked: null checked: null,
rowCheckboxIconTemplate: {
type: null,
default: null
}
}, },
data() { data() {
return { return {
@ -60,6 +65,9 @@ export default {
checkboxAriaLabel() { checkboxAriaLabel() {
return this.$primevue.config.locale.aria ? (this.checked ? this.$primevue.config.locale.aria.selectRow : this.$primevue.config.locale.aria.unselectRow) : undefined; return this.$primevue.config.locale.aria ? (this.checked ? this.$primevue.config.locale.aria.selectRow : this.$primevue.config.locale.aria.unselectRow) : undefined;
} }
},
components: {
CheckIcon: CheckIcon
} }
}; };
</script> </script>

View File

@ -11,7 +11,9 @@
> >
<td :colspan="columnsLength - 1"> <td :colspan="columnsLength - 1">
<button v-if="expandableRowGroups" class="p-row-toggler p-link" @click="onRowGroupToggle($event, rowData)" type="button"> <button v-if="expandableRowGroups" class="p-row-toggler p-link" @click="onRowGroupToggle($event, rowData)" type="button">
<span :class="rowGroupTogglerIcon(rowData)"></span> <component v-if="templates['rowgrouptogglericon']" :is="templates['rowgrouptogglericon']" :expanded="isRowGroupExpanded(rowData)" />
<component v-else-if="!templates['rowgrouptogglericon'] && isRowGroupExpanded(rowData)" :is="expandedRowIcon ? 'span' : 'ChevronDownIcon'" class="p-row-toggler-icon" />
<component v-else-if="!templates['rowgrouptogglericon'] && !isRowGroupExpanded(rowData)" :is="collapsedRowIcon ? 'span' : 'ChevronRightIcon'" class="p-row-toggler-icon" />
</button> </button>
<component :is="templates['groupheader']" :data="rowData" :index="getRowIndex(index)" /> <component :is="templates['groupheader']" :data="rowData" :index="getRowIndex(index)" />
</td> </td>
@ -45,7 +47,6 @@
:rowIndex="getRowIndex(index)" :rowIndex="getRowIndex(index)"
:index="i" :index="i"
:selected="isSelected(rowData)" :selected="isSelected(rowData)"
:rowTogglerIcon="columnProp(col, 'expander') ? rowTogglerIcon(rowData) : null"
:frozenRow="frozenRow" :frozenRow="frozenRow"
:rowspan="rowGroupMode === 'rowspan' ? calculateRowGroupSize(value, col, getRowIndex(index)) : null" :rowspan="rowGroupMode === 'rowspan' ? calculateRowGroupSize(value, col, getRowIndex(index)) : null"
:editMode="editMode" :editMode="editMode"
@ -55,6 +56,9 @@
:virtualScrollerContentProps="virtualScrollerContentProps" :virtualScrollerContentProps="virtualScrollerContentProps"
:ariaControls="expandedRowId + '_' + index + '_expansion'" :ariaControls="expandedRowId + '_' + index + '_expansion'"
:name="nameAttributeSelector" :name="nameAttributeSelector"
:isRowExpanded="isRowExpanded(rowData)"
:expandedRowIcon="expandedRowIcon"
:collapsedRowIcon="collapsedRowIcon"
@radio-change="onRadioChange($event)" @radio-change="onRadioChange($event)"
@checkbox-change="onCheckboxChange($event)" @checkbox-change="onCheckboxChange($event)"
@row-toggle="onRowToggle($event)" @row-toggle="onRowToggle($event)"
@ -89,6 +93,8 @@
</template> </template>
<script> <script>
import ChevronDownIcon from 'primevue/icon/chevrondown';
import ChevronRightIcon from 'primevue/icon/chevronright';
import { DomHandler, ObjectUtils, UniqueComponentId } from 'primevue/utils'; import { DomHandler, ObjectUtils, UniqueComponentId } from 'primevue/utils';
import BodyCell from './BodyCell.vue'; import BodyCell from './BodyCell.vue';
@ -389,16 +395,6 @@ export default {
return null; return null;
} }
}, },
rowTogglerIcon(rowData) {
const icon = this.isRowExpanded(rowData) ? this.expandedRowIcon : this.collapsedRowIcon;
return ['p-row-toggler-icon pi', icon];
},
rowGroupTogglerIcon(rowData) {
const icon = this.isRowGroupExpanded(rowData) ? this.expandedRowIcon : this.collapsedRowIcon;
return ['p-row-toggler-icon pi', icon];
},
isGrouped(column) { isGrouped(column) {
if (this.groupRowsBy && this.columnProp(column, 'field')) { if (this.groupRowsBy && this.columnProp(column, 'field')) {
if (Array.isArray(this.groupRowsBy)) return this.groupRowsBy.indexOf(column.props.field) > -1; if (Array.isArray(this.groupRowsBy)) return this.groupRowsBy.indexOf(column.props.field) > -1;
@ -593,7 +589,9 @@ export default {
} }
}, },
components: { components: {
DTBodyCell: BodyCell DTBodyCell: BodyCell,
ChevronDownIcon: ChevronDownIcon,
ChevronRightIcon: ChevronRightIcon
} }
}; };
</script> </script>

View File

@ -35,6 +35,7 @@
@constraint-add="$emit('constraint-add', $event)" @constraint-add="$emit('constraint-add', $event)"
@constraint-remove="$emit('constraint-remove', $event)" @constraint-remove="$emit('constraint-remove', $event)"
@apply-click="$emit('apply-click', $event)" @apply-click="$emit('apply-click', $event)"
:headerCheckboxIconTemplate="headerCheckboxIconTemplate"
/> />
</template> </template>
</tr> </tr>
@ -104,6 +105,7 @@
@constraint-add="$emit('constraint-add', $event)" @constraint-add="$emit('constraint-add', $event)"
@constraint-remove="$emit('constraint-remove', $event)" @constraint-remove="$emit('constraint-remove', $event)"
@apply-click="$emit('apply-click', $event)" @apply-click="$emit('apply-click', $event)"
:headerCheckboxIconTemplate="headerCheckboxIconTemplate"
/> />
</template> </template>
</tr> </tr>
@ -205,6 +207,10 @@ export default {
filterInputProps: { filterInputProps: {
type: null, type: null,
default: null default: null
},
headerCheckboxIconTemplate: {
type: null,
default: null
} }
}, },
methods: { methods: {