Refactor #3924 - For Paginator

pull/3938/head
Tuğçe Küçükoğlu 2023-05-08 12:35:25 +03:00
parent 751e627b63
commit ca57a6520f
13 changed files with 242 additions and 26 deletions

View File

@ -46,6 +46,12 @@ const PaginatorProps = [
type: 'boolean', type: 'boolean',
default: 'true', default: 'true',
description: 'Whether to show the paginator even there is only one page.' description: 'Whether to show the paginator even there is only one page.'
},
{
name: 'pt',
type: 'any',
default: 'null',
description: 'Uses to pass attributes to DOM elements inside the component.'
} }
]; ];

View File

@ -43,6 +43,7 @@ import { MenubarPassThroughOptions } from '../menubar';
import { MessagePassThroughOptions } from '../message'; import { MessagePassThroughOptions } from '../message';
import { MultiSelectPassThroughOptions } from '../multiselect'; import { MultiSelectPassThroughOptions } from '../multiselect';
import { OverlayPanelPassThroughOptions } from '../overlaypanel'; import { OverlayPanelPassThroughOptions } from '../overlaypanel';
import { PaginatorPassThroughOptions } from '../paginator';
import { PanelPassThroughOptions } from '../panel'; import { PanelPassThroughOptions } from '../panel';
import { PanelMenuPassThroughOptions } from '../panelmenu'; import { PanelMenuPassThroughOptions } from '../panelmenu';
import { PasswordPassThroughOptions } from '../password'; import { PasswordPassThroughOptions } from '../password';
@ -132,6 +133,7 @@ interface PrimeVuePTOptions {
message?: MessagePassThroughOptions; message?: MessagePassThroughOptions;
multiselect?: MultiSelectPassThroughOptions; multiselect?: MultiSelectPassThroughOptions;
overlaypanel?: OverlayPanelPassThroughOptions; overlaypanel?: OverlayPanelPassThroughOptions;
paginator?: PaginatorPassThroughOptions;
panel?: PanelPassThroughOptions; panel?: PanelPassThroughOptions;
panelmenu?: PanelMenuPassThroughOptions; panelmenu?: PanelMenuPassThroughOptions;
password?: PasswordPassThroughOptions; password?: PasswordPassThroughOptions;

View File

@ -1,9 +1,13 @@
<template> <template>
<span class="p-paginator-current">{{ text }}</span> <span class="p-paginator-current" v-bind="ptm('current')">{{ text }}</span>
</template> </template>
<script> <script>
import BaseComponent from 'primevue/basecomponent';
export default { export default {
name: 'CurrentPageReport', name: 'CurrentPageReport',
extends: BaseComponent,
props: { props: {
pageCount: { pageCount: {
type: Number, type: Number,

View File

@ -1,21 +1,32 @@
<template> <template>
<button v-ripple :class="containerClass" type="button"> <button v-ripple :class="containerClass" type="button" v-bind="getPTOptions('firstPageButton')">
<component :is="template || 'AngleDoubleLeftIcon'" class="p-paginator-icon" /> <component :is="template || 'AngleDoubleLeftIcon'" class="p-paginator-icon" v-bind="getPTOptions('firstPageIcon')" />
</button> </button>
</template> </template>
<script> <script>
import BaseComponent from 'primevue/basecomponent';
import AngleDoubleLeftIcon from 'primevue/icons/angledoubleleft'; import AngleDoubleLeftIcon from 'primevue/icons/angledoubleleft';
import Ripple from 'primevue/ripple'; import Ripple from 'primevue/ripple';
export default { export default {
name: 'FirstPageLink', name: 'FirstPageLink',
extends: BaseComponent,
props: { props: {
template: { template: {
type: Function, type: Function,
default: null default: null
} }
}, },
methods: {
getPTOptions(key) {
return this.ptm(key, {
context: {
disabled: this.$attrs.disabled
}
});
}
},
computed: { computed: {
containerClass() { containerClass() {
return [ return [

View File

@ -1,12 +1,14 @@
<template> <template>
<JTPDropdown :modelValue="page" :options="pageOptions" optionLabel="label" optionValue="value" @update:modelValue="onChange($event)" class="p-paginator-page-options" :disabled="disabled"></JTPDropdown> <JTPDropdown :modelValue="page" :options="pageOptions" optionLabel="label" optionValue="value" @update:modelValue="onChange($event)" class="p-paginator-page-options" :disabled="disabled" :pt="ptm('JTPDropdown')"></JTPDropdown>
</template> </template>
<script> <script>
import BaseComponent from 'primevue/basecomponent';
import Dropdown from 'primevue/dropdown'; import Dropdown from 'primevue/dropdown';
export default { export default {
name: 'JumpToPageDropdown', name: 'JumpToPageDropdown',
extends: BaseComponent,
emits: ['page-change'], emits: ['page-change'],
props: { props: {
page: Number, page: Number,

View File

@ -1,12 +1,14 @@
<template> <template>
<JTPInput ref="jtpInput" :modelValue="d_page" class="p-paginator-page-input" :aria-label="inputArialabel" :disabled="disabled" @update:modelValue="onChange"></JTPInput> <JTPInput ref="jtpInput" :modelValue="d_page" class="p-paginator-page-input" :aria-label="inputArialabel" :disabled="disabled" @update:modelValue="onChange" :pt="ptm('JTPInput')"></JTPInput>
</template> </template>
<script> <script>
import BaseComponent from 'primevue/basecomponent';
import InputNumber from 'primevue/inputnumber'; import InputNumber from 'primevue/inputnumber';
export default { export default {
name: 'JumpToPageInput', name: 'JumpToPageInput',
extends: BaseComponent,
inheritAttrs: false, inheritAttrs: false,
emits: ['page-change'], emits: ['page-change'],
props: { props: {

View File

@ -1,21 +1,32 @@
<template> <template>
<button v-ripple :class="containerClass" type="button"> <button v-ripple :class="containerClass" type="button" v-bind="getPTOptions('lastPageButton')">
<component :is="template || 'AngleDoubleRightIcon'" class="p-paginator-icon" /> <component :is="template || 'AngleDoubleRightIcon'" class="p-paginator-icon" v-bind="getPTOptions('lastPageIcon')" />
</button> </button>
</template> </template>
<script> <script>
import BaseComponent from 'primevue/basecomponent';
import AngleDoubleRightIcon from 'primevue/icons/angledoubleright'; import AngleDoubleRightIcon from 'primevue/icons/angledoubleright';
import Ripple from 'primevue/ripple'; import Ripple from 'primevue/ripple';
export default { export default {
name: 'LastPageLink', name: 'LastPageLink',
extends: BaseComponent,
props: { props: {
template: { template: {
type: Function, type: Function,
default: null default: null
} }
}, },
methods: {
getPTOptions(key) {
return this.ptm(key, {
context: {
disabled: this.$attrs.disabled
}
});
}
},
computed: { computed: {
containerClass() { containerClass() {
return [ return [

View File

@ -1,21 +1,32 @@
<template> <template>
<button v-ripple :class="containerClass" type="button"> <button v-ripple :class="containerClass" type="button" v-bind="getPTOptions('nextPageButton')">
<component :is="template || 'AngleRightIcon'" class="p-paginator-icon" /> <component :is="template || 'AngleRightIcon'" class="p-paginator-icon" v-bind="getPTOptions('nextPageIcon')" />
</button> </button>
</template> </template>
<script> <script>
import BaseComponent from 'primevue/basecomponent';
import AngleRightIcon from 'primevue/icons/angleright'; import AngleRightIcon from 'primevue/icons/angleright';
import Ripple from 'primevue/ripple'; import Ripple from 'primevue/ripple';
export default { export default {
name: 'NextPageLink', name: 'NextPageLink',
extends: BaseComponent,
props: { props: {
template: { template: {
type: Function, type: Function,
default: null default: null
} }
}, },
methods: {
getPTOptions(key) {
return this.ptm(key, {
context: {
disabled: this.$attrs.disabled
}
});
}
},
computed: { computed: {
containerClass() { containerClass() {
return [ return [

View File

@ -1,5 +1,5 @@
<template> <template>
<span class="p-paginator-pages"> <span class="p-paginator-pages" v-bind="ptm('pages')">
<button <button
v-for="pageLink of value" v-for="pageLink of value"
:key="pageLink" :key="pageLink"
@ -9,16 +9,20 @@
:aria-label="ariaPageLabel(pageLink)" :aria-label="ariaPageLabel(pageLink)"
:aria-current="pageLink - 1 === page ? 'page' : undefined" :aria-current="pageLink - 1 === page ? 'page' : undefined"
@click="onPageLinkClick($event, pageLink)" @click="onPageLinkClick($event, pageLink)"
v-bind="getPTOptions(pageLink - 1, 'pageButton')"
> >
{{ pageLink }} {{ pageLink }}
</button> </button>
</span> </span>
</template> </template>
<script> <script>
import BaseComponent from 'primevue/basecomponent';
import Ripple from 'primevue/ripple'; import Ripple from 'primevue/ripple';
export default { export default {
name: 'PageLinks', name: 'PageLinks',
extends: BaseComponent,
inheritAttrs: false, inheritAttrs: false,
emits: ['click'], emits: ['click'],
props: { props: {
@ -26,6 +30,13 @@ export default {
page: Number page: Number
}, },
methods: { methods: {
getPTOptions(pageLink, key) {
return this.ptm(key, {
context: {
active: pageLink === this.page
}
});
},
onPageLinkClick(event, pageLink) { onPageLinkClick(event, pageLink) {
this.$emit('click', { this.$emit('click', {
originalEvent: event, originalEvent: event,
@ -36,7 +47,6 @@ export default {
return this.$primevue.config.locale.aria ? this.$primevue.config.locale.aria.pageLabel.replace(/{page}/g, value) : undefined; return this.$primevue.config.locale.aria ? this.$primevue.config.locale.aria.pageLabel.replace(/{page}/g, value) : undefined;
} }
}, },
computed: {},
directives: { directives: {
ripple: Ripple ripple: Ripple
} }

View File

@ -8,8 +8,136 @@
* *
*/ */
import { VNode } from 'vue'; import { VNode } from 'vue';
import { DropdownPassThroughOptionType } from '../dropdown';
import { InputNumberPassThroughOptionType } from '../inputnumber';
import { ClassComponent, GlobalComponentConstructor } from '../ts-helpers'; import { ClassComponent, GlobalComponentConstructor } from '../ts-helpers';
export declare type PaginatorPassThroughOptionType = PaginatorPassThroughAttributes | ((options: PaginatorPassThroughMethodOptions) => PaginatorPassThroughAttributes) | null | undefined;
/**
* Custom passthrough(pt) option method.
*/
export interface PaginatorPassThroughMethodOptions {
props: PaginatorProps;
state: PaginatorState;
context: PaginatorContext;
}
/**
* Custom passthrough(pt) options.
* @see {@link PaginatorProps.pt}
*/
export interface PaginatorPassThroughOptions {
/**
* Uses to pass attributes to the root's DOM element.
*/
root?: PaginatorPassThroughOptionType;
/**
* Uses to pass attributes to the left's DOM element.
*/
left?: PaginatorPassThroughOptionType;
/**
* Uses to pass attributes to the first page button's DOM element.
*/
firstPageButton?: PaginatorPassThroughOptionType;
/**
* Uses to pass attributes to the first page icon's DOM element.
*/
firstPageIcon?: PaginatorPassThroughOptionType;
/**
* Uses to pass attributes to the prev page button's DOM element.
*/
prevPageButton?: PaginatorPassThroughOptionType;
/**
* Uses to pass attributes to the prev page icon's DOM element.
*/
prevPageIcon?: PaginatorPassThroughOptionType;
/**
* Uses to pass attributes to the next page button's DOM element.
*/
nextPageButton?: PaginatorPassThroughOptionType;
/**
* Uses to pass attributes to the next page icon's DOM element.
*/
nextPageIcon?: PaginatorPassThroughOptionType;
/**
* Uses to pass attributes to the last page button's DOM element.
*/
lastPageButton?: PaginatorPassThroughOptionType;
/**
* Uses to pass attributes to the last page icon's DOM element.
*/
lastPageIcon?: PaginatorPassThroughOptionType;
/**
* Uses to pass attributes to the pages's DOM element.
*/
pages?: PaginatorPassThroughOptionType;
/**
* Uses to pass attributes to the page button's DOM element.
*/
pageButton?: PaginatorPassThroughOptionType;
/**
* Uses to pass attributes to the current's DOM element.
*/
current?: PaginatorPassThroughOptionType;
/**
* Uses to pass attributes to the Dropdown component.
* @see {@link DropdownPassThroughOptionType}
*/
RPPDropdown?: DropdownPassThroughOptionType;
/**
* Uses to pass attributes to the Dropdown component.
* @see {@link DropdownPassThroughOptionType}
*/
JTPDropdown?: DropdownPassThroughOptionType;
/**
* Uses to pass attributes to the Dropdown component.
* @see {@link InputNumberPassThroughOptionType}
*/
JTPInput?: InputNumberPassThroughOptionType;
/**
* Uses to pass attributes to the end's DOM element.
*/
end?: PaginatorPassThroughOptionType;
}
/**
* Custom passthrough attributes for each DOM elements
*/
export interface PaginatorPassThroughAttributes {
[key: string]: any;
}
/**
* Defines current inline state in Paginator component.
*/
export interface PaginatorState {
/**
* Current index of first record as a number.
*/
d_first: number;
/**
* Current number of rows to display in new page as a number.
*/
d_rows: number;
}
/**
* Defines current options in Paginator component.
*/
export interface PaginatorContext {
/**
* Current active state as a boolean.
* @defaultValue false
*/
active: boolean;
/**
* Current disabled state of the button as a boolean.
* @defaultValue false
*/
disabled: boolean;
}
/** /**
* Paginator page state metadata. * Paginator page state metadata.
*/ */
@ -92,6 +220,11 @@ export interface PaginatorProps {
* @defaultValue true * @defaultValue true
*/ */
alwaysShow?: boolean | undefined; alwaysShow?: boolean | undefined;
/**
* Uses to pass attributes to DOM elements inside the component.
* @type {PaginatorPassThroughOptions}
*/
pt?: PaginatorPassThroughOptions;
} }
/** /**

View File

@ -1,15 +1,15 @@
<template> <template>
<nav v-if="alwaysShow ? true : pageLinks && pageLinks.length > 1"> <nav v-if="alwaysShow ? true : pageLinks && pageLinks.length > 1" v-bind="ptm('root')">
<div v-for="(value, key) in templateItems" :key="key" ref="paginator" class="p-paginator p-component" :class="getPaginatorClasses(key)"> <div v-for="(value, key) in templateItems" :key="key" ref="paginator" class="p-paginator p-component" :class="getPaginatorClasses(key)" v-bind="ptm('paginator')">
<div v-if="$slots.start" class="p-paginator-left-content"> <div v-if="$slots.start" class="p-paginator-left-content" v-bind="ptm('left')">
<slot name="start" :state="currentState"></slot> <slot name="start" :state="currentState"></slot>
</div> </div>
<template v-for="item in value" :key="item"> <template v-for="item in value" :key="item">
<FirstPageLink v-if="item === 'FirstPageLink'" :aria-label="getAriaLabel('firstPageLabel')" :template="$slots.firstpagelinkicon" @click="changePageToFirst($event)" :disabled="isFirstPage || empty" /> <FirstPageLink v-if="item === 'FirstPageLink'" :aria-label="getAriaLabel('firstPageLabel')" :template="$slots.firstpagelinkicon" @click="changePageToFirst($event)" :disabled="isFirstPage || empty" :pt="pt" />
<PrevPageLink v-else-if="item === 'PrevPageLink'" :aria-label="getAriaLabel('prevPageLabel')" :template="$slots.prevpagelinkicon" @click="changePageToPrev($event)" :disabled="isFirstPage || empty" /> <PrevPageLink v-else-if="item === 'PrevPageLink'" :aria-label="getAriaLabel('prevPageLabel')" :template="$slots.prevpagelinkicon" @click="changePageToPrev($event)" :disabled="isFirstPage || empty" :pt="pt" />
<NextPageLink v-else-if="item === 'NextPageLink'" :aria-label="getAriaLabel('nextPageLabel')" :template="$slots.nextpagelinkicon" @click="changePageToNext($event)" :disabled="isLastPage || empty" /> <NextPageLink v-else-if="item === 'NextPageLink'" :aria-label="getAriaLabel('nextPageLabel')" :template="$slots.nextpagelinkicon" @click="changePageToNext($event)" :disabled="isLastPage || empty" :pt="pt" />
<LastPageLink v-else-if="item === 'LastPageLink'" :aria-label="getAriaLabel('lastPageLabel')" :template="$slots.lastpagelinkicon" @click="changePageToLast($event)" :disabled="isLastPage || empty" /> <LastPageLink v-else-if="item === 'LastPageLink'" :aria-label="getAriaLabel('lastPageLabel')" :template="$slots.lastpagelinkicon" @click="changePageToLast($event)" :disabled="isLastPage || empty" :pt="pt" />
<PageLinks v-else-if="item === 'PageLinks'" :aria-label="getAriaLabel('pageLabel')" :value="pageLinks" :page="page" @click="changePageLink($event)" /> <PageLinks v-else-if="item === 'PageLinks'" :aria-label="getAriaLabel('pageLabel')" :value="pageLinks" :page="page" @click="changePageLink($event)" :pt="pt" />
<CurrentPageReport <CurrentPageReport
v-else-if="item === 'CurrentPageReport'" v-else-if="item === 'CurrentPageReport'"
aria-live="polite" aria-live="polite"
@ -20,12 +20,21 @@
:first="d_first" :first="d_first"
:rows="d_rows" :rows="d_rows"
:totalRecords="totalRecords" :totalRecords="totalRecords"
:pt="pt"
/> />
<RowsPerPageDropdown v-else-if="item === 'RowsPerPageDropdown' && rowsPerPageOptions" :aria-label="getAriaLabel('rowsPerPageLabel')" :rows="d_rows" :options="rowsPerPageOptions" @rows-change="onRowChange($event)" :disabled="empty" /> <RowsPerPageDropdown
<JumpToPageDropdown v-else-if="item === 'JumpToPageDropdown'" :aria-label="getAriaLabel('jumpToPageDropdownLabel')" :page="page" :pageCount="pageCount" @page-change="changePage($event)" :disabled="empty" /> v-else-if="item === 'RowsPerPageDropdown' && rowsPerPageOptions"
<JumpToPageInput v-else-if="item === 'JumpToPageInput'" :page="currentPage" @page-change="changePage($event)" :disabled="empty" /> :aria-label="getAriaLabel('rowsPerPageLabel')"
:rows="d_rows"
:options="rowsPerPageOptions"
@rows-change="onRowChange($event)"
:disabled="empty"
:pt="pt"
/>
<JumpToPageDropdown v-else-if="item === 'JumpToPageDropdown'" :aria-label="getAriaLabel('jumpToPageDropdownLabel')" :page="page" :pageCount="pageCount" @page-change="changePage($event)" :disabled="empty" :pt="pt" />
<JumpToPageInput v-else-if="item === 'JumpToPageInput'" :page="currentPage" @page-change="changePage($event)" :disabled="empty" :pt="pt" />
</template> </template>
<div v-if="$slots.end" class="p-paginator-right-content"> <div v-if="$slots.end" class="p-paginator-right-content" v-bind="ptm('end')">
<slot name="end" :state="currentState"></slot> <slot name="end" :state="currentState"></slot>
</div> </div>
</div> </div>
@ -33,6 +42,7 @@
</template> </template>
<script> <script>
import BaseComponent from 'primevue/basecomponent';
import { UniqueComponentId } from 'primevue/utils'; import { UniqueComponentId } from 'primevue/utils';
import CurrrentPageReport from './CurrentPageReport.vue'; import CurrrentPageReport from './CurrentPageReport.vue';
import FirstPageLink from './FirstPageLink.vue'; import FirstPageLink from './FirstPageLink.vue';
@ -46,6 +56,7 @@ import RowsPerPageDropdown from './RowsPerPageDropdown.vue';
export default { export default {
name: 'Paginator', name: 'Paginator',
extends: BaseComponent,
emits: ['update:first', 'update:rows', 'page'], emits: ['update:first', 'update:rows', 'page'],
props: { props: {
totalRecords: { totalRecords: {

View File

@ -1,21 +1,32 @@
<template> <template>
<button v-ripple :class="containerClass" type="button"> <button v-ripple :class="containerClass" type="button" v-bind="getPTOptions('prevPageButton')">
<component :is="template || 'AngleLeftIcon'" class="p-paginator-icon" /> <component :is="template || 'AngleLeftIcon'" class="p-paginator-icon" v-bind="getPTOptions('prevPageIcon')" />
</button> </button>
</template> </template>
<script> <script>
import BaseComponent from 'primevue/basecomponent';
import AngleLeftIcon from 'primevue/icons/angleleft'; import AngleLeftIcon from 'primevue/icons/angleleft';
import Ripple from 'primevue/ripple'; import Ripple from 'primevue/ripple';
export default { export default {
name: 'PrevPageLink', name: 'PrevPageLink',
extends: BaseComponent,
props: { props: {
template: { template: {
type: Function, type: Function,
default: null default: null
} }
}, },
methods: {
getPTOptions(key) {
return this.ptm(key, {
context: {
disabled: this.$attrs.disabled
}
});
}
},
computed: { computed: {
containerClass() { containerClass() {
return [ return [

View File

@ -1,12 +1,14 @@
<template> <template>
<RPPDropdown :modelValue="rows" :options="rowsOptions" optionLabel="label" optionValue="value" @update:modelValue="onChange($event)" class="p-paginator-rpp-options" :disabled="disabled"></RPPDropdown> <RPPDropdown :modelValue="rows" :options="rowsOptions" optionLabel="label" optionValue="value" @update:modelValue="onChange($event)" class="p-paginator-rpp-options" :disabled="disabled" :pt="ptm('RPPDropdown')"></RPPDropdown>
</template> </template>
<script> <script>
import BaseComponent from 'primevue/basecomponent';
import Dropdown from 'primevue/dropdown'; import Dropdown from 'primevue/dropdown';
export default { export default {
name: 'RowsPerPageDropdown', name: 'RowsPerPageDropdown',
extends: BaseComponent,
emits: ['rows-change'], emits: ['rows-change'],
props: { props: {
options: Array, options: Array,