diff --git a/src/lib/paginator/paginator-adapter.ts b/src/lib/paginator/paginator-adapter.ts index 844bfbba4..20885d416 100644 --- a/src/lib/paginator/paginator-adapter.ts +++ b/src/lib/paginator/paginator-adapter.ts @@ -5,40 +5,43 @@ import { ISelectComponent, ISelectOption } from '../select'; import { IPaginatorComponent } from './paginator'; import { PaginatorAlternativeAlignment, PAGINATOR_CONSTANTS } from './paginator-constants'; +export type PaginatorFieldIdentifier = 'first' | 'last' | 'previous' | 'next' | 'page-size'; + export interface IPaginatorAdapter extends IBaseAdapter { - setLabel: (value: string) => void; - setPageSizeOptions: (options: ISelectOption[]) => void; - setPageSize: (value: number) => void; - setRangeLabel: (value: string) => void; + setLabel(value: string): void; + setPageSizeOptions(options: ISelectOption[]): void; + setPageSize(value: number): void; + setRangeLabel(value: string): void; hasFirstPageButton(): boolean; showFirstPageButton(): void; hideFirstPageButton(): void; hasLastPageButton(): boolean; showLastPageButton(): void; hideLastPageButton(): void; - attachPageSizeChangeListener: (listener: (evt: CustomEvent) => void) => void; - attachFirstPageListener: (listener: (evt: Event) => void) => void; - attachPreviousPageListener: (listener: (evt: Event) => void) => void; - attachNextPageListener: (listener: (evt: Event) => void) => void; - attachLastPageListener: (listener: (evt: Event) => void) => void; - detachPageSizeChangeListener: (listener: (evt: CustomEvent) => void) => void; - detachFirstPageListener: (listener: (evt: Event) => void) => void; - detachPreviousPageListener: (listener: (evt: Event) => void) => void; - detachNextPageListener: (listener: (evt: Event) => void) => void; - detachLastPageListener: (listener: (evt: Event) => void) => void; - disableFirstPageButton: () => void; - enableFirstPageButton: () => void; - disablePreviousPageButton: () => void; - enablePreviousPageButton: () => void; - disableNextPageButton: () => void; - enableNextPageButton: () => void; + attachPageSizeChangeListener(listener: (evt: CustomEvent) => void): void; + attachFirstPageListener(listener: (evt: Event) => void): void; + attachPreviousPageListener(listener: (evt: Event) => void): void; + attachNextPageListener(listener: (evt: Event) => void): void; + attachLastPageListener(listener: (evt: Event) => void): void; + detachPageSizeChangeListener(listener: (evt: CustomEvent) => void): void; + detachFirstPageListener(listener: (evt: Event) => void): void; + detachPreviousPageListener(listener: (evt: Event) => void): void; + detachNextPageListener(listener: (evt: Event) => void): void; + detachLastPageListener(listener: (evt: Event) => void): void; + disableFirstPageButton(): void; + enableFirstPageButton(): void; + disablePreviousPageButton(): void; + enablePreviousPageButton(): void; + disableNextPageButton(): void; + enableNextPageButton(): void; disablePageSizeSelect(): void; enablePageSizeSelect(): void; setPageSizeVisibility(visible: boolean): void; - disableLastPageButton: () => void; - enableLastPageButton: () => void; - setAlternative: (alternative: boolean) => void; - setAlignment: (alignment: PaginatorAlternativeAlignment) => void; + disableLastPageButton(): void; + enableLastPageButton(): void; + setAlternative(alternative: boolean): void; + setAlignment(alignment: PaginatorAlternativeAlignment): void; + handleFocusMove(from: PaginatorFieldIdentifier): void; } /** @@ -185,7 +188,6 @@ export class PaginatorAdapter extends BaseAdapter implement } public disableFirstPageButton(): void { - this._handleFocusMove('first'); this._firstPageButton.setAttribute('disabled', 'disabled'); } @@ -194,7 +196,6 @@ export class PaginatorAdapter extends BaseAdapter implement } public disablePreviousPageButton(): void { - this._handleFocusMove('previous'); this._previousPageButton.setAttribute('disabled', 'disabled'); } @@ -203,7 +204,6 @@ export class PaginatorAdapter extends BaseAdapter implement } public disableNextPageButton(): void { - this._handleFocusMove('next'); this._nextPageButton.setAttribute('disabled', 'disabled'); } @@ -212,7 +212,6 @@ export class PaginatorAdapter extends BaseAdapter implement } public disablePageSizeSelect(): void { - this._handleFocusMove('page-size'); this._pageSizeSelect.setAttribute('disabled', 'disabled'); } @@ -229,7 +228,6 @@ export class PaginatorAdapter extends BaseAdapter implement } public disableLastPageButton(): void { - this._handleFocusMove('last'); this._lastPageButton.setAttribute('disabled', 'disabled'); } @@ -262,7 +260,11 @@ export class PaginatorAdapter extends BaseAdapter implement } } - private _handleFocusMove(from: 'first' | 'last' | 'previous' | 'next' | 'page-size'): void { + public handleFocusMove(from: PaginatorFieldIdentifier): void { + if (!this._component.matches(':focus')) { + return; // We can only move focus elsewhere within the element if the element already contains focus + } + switch (from) { case 'first': this._tryFocus([ diff --git a/src/lib/paginator/paginator-foundation.ts b/src/lib/paginator/paginator-foundation.ts index 1bed84c2b..f0bd56144 100644 --- a/src/lib/paginator/paginator-foundation.ts +++ b/src/lib/paginator/paginator-foundation.ts @@ -1,8 +1,7 @@ import { coerceNumber, ICustomElementFoundation, isArray, isDefined } from '@tylertech/forge-core'; -import { IPaginatorAdapter } from './paginator-adapter'; +import { IPaginatorAdapter, PaginatorFieldIdentifier } from './paginator-adapter'; import { PaginatorAlternativeAlignment, PAGINATOR_CONSTANTS, IPaginatorChangeEvent } from './paginator-constants'; -import { ISelectOption, ISelectComponent } from '../select'; - +import { ISelectOption } from '../select'; export interface IPaginatorFoundation extends ICustomElementFoundation { pageIndex: number; @@ -11,230 +10,44 @@ export interface IPaginatorFoundation extends ICustomElementFoundation { total: number; pageSizeOptions: number[] | boolean; pageSizeLabel: string; - initialize(): void; } -/** - * The foundation class behind the `` component. - */ export class PaginatorFoundation { - // Backing models private _pageIndex = PAGINATOR_CONSTANTS.numbers.DEFAULT_PAGE_INDEX; private _pageSize = PAGINATOR_CONSTANTS.numbers.DEFAULT_PAGE_SIZE; private _offset = 0; private _total = PAGINATOR_CONSTANTS.numbers.DEFAULT_TOTAL; - private _pageSizeOptions: ISelectOption[] = []; + private _pageSizeOptions: ISelectOption[] = PAGINATOR_CONSTANTS.numbers.DEFAULT_PAGE_SIZE_OPTIONS.map(o => ({ label: `${o}`, value: `${o}` })); private _label = PAGINATOR_CONSTANTS.strings.DEFAULT_LABEL; private _firstLast = false; private _first = false; private _disabled = false; private _alternative: boolean; private _alignment: PaginatorAlternativeAlignment = 'space-between'; + private _rangeLabel: string; - // Listeners private _firstPageListener: (evt: Event) => void; private _previousPageListener: (evt: Event) => void; private _nextPageListener: (evt: Event) => void; private _lastPageListener: (evt: Event) => void; private _pageSizeListener: (evt: Event) => void; - // State variables - private _rangeLabel: string; - constructor(private _adapter: IPaginatorAdapter) { - // Create listeners - this._pageSizeListener = (evt: CustomEvent) => this._onPageSizeChanged(evt); + this._pageSizeListener = (evt: CustomEvent) => this._onPageSizeChanged(evt); this._firstPageListener = (evt: Event) => this._onFirstPage(evt); this._previousPageListener = (evt: Event) => this._onPreviousPage(evt); this._nextPageListener = (evt: Event) => this._onNextPage(evt); this._lastPageListener = (evt: Event) => this._onLastPage(evt); - - this._pageSizeOptions = PAGINATOR_CONSTANTS.numbers.DEFAULT_PAGE_SIZE_OPTIONS.map(o => ({ label: o.toString(), value: o.toString() })); - } - - /** The zero-based page index. Default is 0. */ - public set pageIndex(value: number) { - if (this._pageIndex !== value) { - if (isDefined(value)) { - this._pageIndex = value; - this._update(); - this._adapter.setHostAttribute(PAGINATOR_CONSTANTS.attributes.PAGE_INDEX, this._pageIndex.toString()); - } else { - this._adapter.removeHostAttribute(PAGINATOR_CONSTANTS.attributes.PAGE_INDEX); - } - } - } - public get pageIndex(): number { - return this._pageIndex; - } - - /** Number of items to display on a page. By default set to 25. */ - public set pageSize(value: number) { - if (this._pageSize !== value) { - this._pageSize = value; - this._adapter.setPageSize(this._pageSize); - this._update(); - this._adapter.setHostAttribute(PAGINATOR_CONSTANTS.attributes.PAGE_SIZE, this._pageSize.toString()); - } - } - public get pageSize(): number { - return this._pageSize; - } - - /** Sets page index by providing the number of items to skip. */ - public set offset(value: number) { - if (this._offset !== value) { - this._offset = value; - this._computePageIndexFromOffset(value); - } - } - public get offset(): number { - return this._offset; - } - - /** The total number of items to be paginated. Default is 0. */ - public set total(value: number) { - if (this._total !== value) { - this._total = value; - - if (this._offset > 0 && this._total > 0) { - this._computePageIndexFromOffset(this._offset); - } - - this._update(); - this._adapter.setHostAttribute(PAGINATOR_CONSTANTS.attributes.TOTAL, this._total.toString()); - } - } - public get total(): number { - return this._total; - } - - /** The set of provided page size options to display to the user. */ - public set pageSizeOptions(options: number[] | boolean) { - if (isArray(options)) { - this._pageSizeOptions = (options as number[]) - .map(o => ({ label: o.toString(), value: o.toString() })) - .sort((a, b) => coerceNumber(a.value) - coerceNumber(b.value)); - this._adapter.setPageSizeOptions(this._pageSizeOptions); - this._adapter.attachPageSizeChangeListener(this._pageSizeListener); - this._adapter.setPageSizeVisibility(true); - if (isDefined(this._pageSize) && this._pageSizeOptions.length && !this._pageSizeOptions.find(o => coerceNumber(o.value) === this._pageSize)) { - this.pageSize = coerceNumber(this._pageSizeOptions[0].value); - } - } else if (options.toString().toLowerCase() === 'false') { - this._adapter.detachPageSizeChangeListener(this._pageSizeListener); - this._adapter.setPageSizeVisibility(false); - } - } - public get pageSizeOptions(): number[] | boolean { - return this._pageSizeOptions.map(o => Number(o.value)); - } - - /** A label for the paginator. Default is "Rows per page:". */ - public set label(value: string) { - if (this._label !== value) { - this._label = value; - this._adapter.setLabel(this._label); - this._adapter.setHostAttribute(PAGINATOR_CONSTANTS.attributes.LABEL, isDefined(this._label) ? this._label.toString() : ''); - } - } - public get label(): string { - return this._label; - } - - /** Whether to show the first page and last page buttons. Default is false. */ - public set firstLast(value: boolean) { - if (this._firstLast !== value) { - this._firstLast = value; - this._toggleFirstLastButtons(); - - if (this._firstLast) { - this._adapter.setHostAttribute(PAGINATOR_CONSTANTS.attributes.FIRST_LAST); - } else { - this._adapter.removeHostAttribute(PAGINATOR_CONSTANTS.attributes.FIRST_LAST); - } - } - } - public get firstLast(): boolean { - return this._firstLast; - } - - /** Whether to show the first page button. Default is false. */ - public set first(value: boolean) { - if (this._first !== value) { - this._first = value; - this._toggleFirstButton(); - - if (this._first) { - this._adapter.setHostAttribute(PAGINATOR_CONSTANTS.attributes.FIRST); - } else { - this._adapter.removeHostAttribute(PAGINATOR_CONSTANTS.attributes.FIRST); - } - } - } - - public get first(): boolean { - return this._first; - } - - /** Whether the paginator is disabled. Default is false. */ - public set disabled(value: boolean) { - if (this._disabled !== value) { - this._disabled = value; - this._update(); - - if (this._disabled) { - this._adapter.setHostAttribute(PAGINATOR_CONSTANTS.attributes.DISABLED); - } else { - this._adapter.removeHostAttribute(PAGINATOR_CONSTANTS.attributes.DISABLED); - } - } - } - public get disabled(): boolean { - return this._disabled; - } - - public get alternative(): boolean { - return this._alternative; - } - public set alternative(value: boolean) { - if (value !== this._alternative) { - this._alternative = value; - this._applyAlternative(); - } - } - - public get alignment(): PaginatorAlternativeAlignment { - return this._alignment; - } - public set alignment(value: PaginatorAlternativeAlignment) { - if (value !== this._alignment) { - this._alignment = value; - this._applyAlternativeAlignment(); - } } - private _applyAlternativeAlignment(): void { - this._adapter.setHostAttribute(PAGINATOR_CONSTANTS.attributes.ALIGNMENT, this._alignment); - this._adapter.setAlignment(this._alignment); - } - - private _applyAlternative(): void { - this._adapter.toggleHostAttribute(PAGINATOR_CONSTANTS.attributes.ALTERNATIVE, this._alternative); - this._adapter.setAlternative(this._alternative); - this._applyAlternativeAlignment(); - } - - /** - * Intializes the internal state when the component loads. - */ public initialize(): void { - this._update(); + this._updateRangeLabel(); this._adapter.setLabel(this._label); this._adapter.setPageSizeOptions(this._pageSizeOptions); this._adapter.setPageSize(this._pageSize); this._attachListeners(); this._toggleFirstLastButtons(); + this._syncInteractionState(); } public disconnect(): void { @@ -257,10 +70,6 @@ export class PaginatorFoundation { this._adapter.detachLastPageListener(this._lastPageListener); } - /** - * Handles clicking the first page button. - * @param evt The click event. - */ private _onFirstPage(evt: Event): void { evt.stopPropagation(); @@ -271,14 +80,10 @@ export class PaginatorFoundation { const firstPage = 0; const canPage = this._emitChangeEvent(PAGINATOR_CONSTANTS.strings.FIRST_PAGE, { pageIndex: firstPage }); if (canPage) { - this.pageIndex = firstPage; + this._applyPageIndex(firstPage, { fromField: 'first' }); } } - /** - * Handles clicking the previous page button. - * @param evt The click event. - */ private _onPreviousPage(evt: Event): void { evt.stopPropagation(); @@ -289,14 +94,10 @@ export class PaginatorFoundation { const prevPage = this._pageIndex - 1; const canPage = this._emitChangeEvent(PAGINATOR_CONSTANTS.strings.PREVIOUS_PAGE, { pageIndex: prevPage }); if (canPage) { - this.pageIndex = prevPage; + this._applyPageIndex(prevPage, { fromField: 'previous' }); } } - /** - * Handles clicking the next page button. - * @param evt The click event. - */ private _onNextPage(evt: Event): void { evt.stopPropagation(); @@ -307,14 +108,10 @@ export class PaginatorFoundation { const nextPage = this._pageIndex + 1; const canPage = this._emitChangeEvent(PAGINATOR_CONSTANTS.strings.NEXT_PAGE, { pageIndex: nextPage }); if (canPage) { - this.pageIndex = nextPage; + this._applyPageIndex(nextPage, { fromField: 'next' }); } } - /** - * Handles clicking the last page button. - * @param evt The click event. - */ private _onLastPage(evt: Event): void { evt.stopPropagation(); @@ -325,22 +122,18 @@ export class PaginatorFoundation { const lastPage = this._getMaxPages(); const canPage = this._emitChangeEvent(PAGINATOR_CONSTANTS.strings.LAST_PAGE, { pageIndex: lastPage }); if (canPage) { - this.pageIndex = lastPage; + this._applyPageIndex(lastPage, { fromField: 'last' }); } } - /** - * Handles selecting a new item in the page size options. - * @param evt The select custom event. - */ private _onPageSizeChanged(evt: CustomEvent): void { evt.stopPropagation(); const pageSize = Number(evt.detail); const canPage = this._emitChangeEvent(PAGINATOR_CONSTANTS.strings.PAGE_SIZE, { pageIndex: 0, pageSize }); if (canPage) { - this.pageIndex = 0; - this.pageSize = pageSize; + this._applyPageIndex(0, { fromField: 'page-size' }); + this._applyPageSize(pageSize); } else { evt.preventDefault(); } @@ -352,74 +145,58 @@ export class PaginatorFoundation { return this._adapter.emitHostEvent(PAGINATOR_CONSTANTS.events.CHANGE, detail, true, true); } - /** - * Returns the max number of pages based on our current parameters. - */ private _getMaxPages(): number { return Math.ceil(this._total / this._pageSize) - 1; } - /** - * Updates our internal state as well as updating the UI. - */ - private _update(): void { - this._offset = this._pageIndex * this._pageSize; - - // Create and update the range label + private _updateRangeLabel(): void { if (this.pageSize > 1) { const startIndex = this._pageIndex * this._pageSize; const indexStart = Math.floor(startIndex / this._pageSize) || 0; const pageStart = (indexStart * this._pageSize) + 1; const pageEnd = startIndex < this._total ? Math.min(startIndex + this._pageSize, this._total) : startIndex + this._pageSize; - this._rangeLabel = `${pageStart}-${pageEnd} ${PAGINATOR_CONSTANTS.strings.RANGE_SEPARATOR_LABEL} ${this._total}`; } else { this._rangeLabel = `${this._pageIndex + 1} ${PAGINATOR_CONSTANTS.strings.RANGE_SEPARATOR_LABEL} ${this._total}`; } - this._adapter.setRangeLabel(this._rangeLabel); + } - if (this.disabled) { - this._adapter.disablePageSizeSelect(); - this._adapter.disableFirstPageButton(); - this._adapter.disablePreviousPageButton(); - this._adapter.disableNextPageButton(); - this._adapter.disableLastPageButton(); - } else { - this._adapter.enablePageSizeSelect(); - // Check if first page button needs to be enabled/disabled - if (this._hasFirstPage()) { - this._adapter.enableFirstPageButton(); - } else { - this._adapter.disableFirstPageButton(); + private _syncInteractionState(fromField: PaginatorFieldIdentifier | null = null): void { + this._adapter.enableFirstPageButton(); + this._adapter.enablePreviousPageButton(); + this._adapter.enableNextPageButton(); + this._adapter.enableLastPageButton(); + + if (!this._hasFirstPage()) { + if (fromField) { + this._adapter.handleFocusMove(fromField); } + this._adapter.disableFirstPageButton(); + } - // Check if previous page button needs to be enabled/disabled - if (this._hasPreviousPage()) { - this._adapter.enablePreviousPageButton(); - } else { - this._adapter.disablePreviousPageButton(); + if (!this._hasPreviousPage()) { + if (fromField) { + this._adapter.handleFocusMove(fromField); } + this._adapter.disablePreviousPageButton(); + } - // Check if next page button needs to be enabled/disabled - if (this._hasNextPage()) { - this._adapter.enableNextPageButton(); - } else { - this._adapter.disableNextPageButton(); + if (!this._hasNextPage()) { + if (fromField) { + this._adapter.handleFocusMove(fromField); } + this._adapter.disableNextPageButton(); + } - // Check if last page button needs to be enabled/disabled - if (this._hasLastPage()) { - this._adapter.enableLastPageButton(); - } else { - this._adapter.disableLastPageButton(); + if (!this._hasLastPage()) { + if (fromField) { + this._adapter.handleFocusMove(fromField); } + this._adapter.disableLastPageButton(); } } - /** - * Toggle showing/hiding first and last buttons based on the show first/last buttons flag. - */ private _toggleFirstLastButtons(): void { this._toggleFirstButton(); if (this._firstLast) { @@ -433,9 +210,6 @@ export class PaginatorFoundation { } } - /** - * Toggle showing/hiding first button based on the show first or first/last buttons flags. - */ private _toggleFirstButton(): void { if (this._first || this._firstLast) { if (!this._adapter.hasFirstPageButton()) { @@ -448,28 +222,20 @@ export class PaginatorFoundation { } } - /** Checks if a first page exists. */ private _hasFirstPage(): boolean { - // same as has previous page return this._hasPreviousPage(); } - /** - * Checks if a previous page exists. - */ private _hasPreviousPage(): boolean { - return this._pageIndex >= 1 && this._pageSize !== 0; + return this._pageIndex > 0 && this._pageSize > 0; } - /** Checks if a next page exists */ private _hasNextPage(): boolean { const maxPages = this._getMaxPages(); - return this._pageIndex < maxPages && this._pageSize !== 0; + return this._pageIndex < maxPages && this._pageSize > 0; } - /** Checks if a last page exists. */ private _hasLastPage(): boolean { - // same as has next page return this._hasNextPage(); } @@ -482,6 +248,191 @@ export class PaginatorFoundation { } } const clampedValue = Math.min(Math.max(value, 0), this._total); - this.pageIndex = Math.floor(clampedValue / this._pageSize); + const pageIndex = Math.floor(clampedValue / this._pageSize); + this._applyPageIndex(pageIndex); + } + + private _computeOffset(): void { + if (this._total > 0) { + this._offset = this._pageIndex * this._pageSize; + } + } + + private _applyPageIndex(value: number, { fromField = null }: { fromField?: PaginatorFieldIdentifier | null } = {}): void { + this._pageIndex = value; + this._computeOffset(); + this._updateRangeLabel(); + this._syncInteractionState(fromField); + this._adapter.toggleHostAttribute(PAGINATOR_CONSTANTS.attributes.PAGE_INDEX, this._pageIndex != null, this._pageIndex.toString()); + } + + private _applyPageSize(value: number): void { + this._pageSize = value; + this._adapter.setPageSize(this._pageSize); + this._computeOffset(); + this._updateRangeLabel(); + this._syncInteractionState(); + } + + private _applyTotal(value: number): void { + this._total = value; + this._updateRangeLabel(); + + if (this._offset > 0 && this._total > 0) { + this._computePageIndexFromOffset(this._offset); + } + + this._syncInteractionState(); + } + + private _applyAlternativeAlignment(): void { + this._adapter.setHostAttribute(PAGINATOR_CONSTANTS.attributes.ALIGNMENT, this._alignment); + this._adapter.setAlignment(this._alignment); + } + + private _applyDisabled(disabled: boolean): void { + this._disabled = disabled; + if (disabled) { + this._adapter.disablePageSizeSelect(); + this._adapter.disableFirstPageButton(); + this._adapter.disablePreviousPageButton(); + this._adapter.disableNextPageButton(); + this._adapter.disableLastPageButton(); + } else { + this._adapter.enablePageSizeSelect(); + this._syncInteractionState(); + } + } + + public get pageIndex(): number { + return this._pageIndex; + } + public set pageIndex(value: number) { + if (this._pageIndex !== value) { + if (isDefined(value)) { + this._applyPageIndex(value); + } else { + this._adapter.removeHostAttribute(PAGINATOR_CONSTANTS.attributes.PAGE_INDEX); + } + } + } + + public get pageSize(): number { + return this._pageSize; + } + public set pageSize(value: number) { + if (this._pageSize !== value) { + this._applyPageSize(value); + this._adapter.setHostAttribute(PAGINATOR_CONSTANTS.attributes.PAGE_SIZE, `${this._pageSize}`); + } + } + + public get offset(): number { + return this._offset; + } + public set offset(value: number) { + if (this._offset !== value) { + this._offset = value; + this._computePageIndexFromOffset(value); + } + } + + public get total(): number { + return this._total; + } + public set total(value: number) { + if (this._total !== value) { + this._applyTotal(value); + this._adapter.setHostAttribute(PAGINATOR_CONSTANTS.attributes.TOTAL, `${this._total}`); + } + } + + public get pageSizeOptions(): number[] | boolean { + return this._pageSizeOptions.map(o => Number(o.value)); + } + public set pageSizeOptions(options: number[] | boolean) { + if (isArray(options)) { + this._pageSizeOptions = (options as number[]) + .map(o => ({ label: o.toString(), value: o.toString() })) + .sort((a, b) => coerceNumber(a.value) - coerceNumber(b.value)); + this._adapter.setPageSizeOptions(this._pageSizeOptions); + this._adapter.attachPageSizeChangeListener(this._pageSizeListener); + this._adapter.setPageSizeVisibility(true); + if (isDefined(this._pageSize) && this._pageSizeOptions.length && !this._pageSizeOptions.find(o => coerceNumber(o.value) === this._pageSize)) { + const pageSize = coerceNumber(this._pageSizeOptions[0].value); + this._applyPageSize(pageSize); + } + } else if (options.toString().toLowerCase() === 'false') { + this._adapter.detachPageSizeChangeListener(this._pageSizeListener); + this._adapter.setPageSizeVisibility(false); + } + } + + public get label(): string { + return this._label; + } + public set label(value: string) { + if (this._label !== value) { + this._label = value; + this._adapter.setLabel(this._label); + this._adapter.setHostAttribute(PAGINATOR_CONSTANTS.attributes.LABEL, isDefined(this._label) ? this._label.toString() : ''); + } + } + + public get firstLast(): boolean { + return this._firstLast; + } + public set firstLast(value: boolean) { + value = Boolean(value); + if (this._firstLast !== value) { + this._firstLast = value; + this._toggleFirstLastButtons(); + this._adapter.toggleHostAttribute(PAGINATOR_CONSTANTS.attributes.FIRST_LAST, this._firstLast); + } + } + + public get first(): boolean { + return this._first; + } + public set first(value: boolean) { + value = Boolean(value); + if (this._first !== value) { + this._first = value; + this._toggleFirstButton(); + this._adapter.toggleHostAttribute(PAGINATOR_CONSTANTS.attributes.FIRST, this._first); + } + } + + public get disabled(): boolean { + return this._disabled; + } + public set disabled(value: boolean) { + value = Boolean(value); + if (this._disabled !== value) { + this._applyDisabled(value); + this._adapter.toggleHostAttribute(PAGINATOR_CONSTANTS.attributes.DISABLED, this._disabled); + } + } + + public get alternative(): boolean { + return this._alternative; + } + public set alternative(value: boolean) { + if (value !== this._alternative) { + this._alternative = value; + this._adapter.setAlternative(this._alternative); + this._applyAlternativeAlignment(); + this._adapter.toggleHostAttribute(PAGINATOR_CONSTANTS.attributes.ALTERNATIVE, this._alternative); + } + } + + public get alignment(): PaginatorAlternativeAlignment { + return this._alignment; + } + public set alignment(value: PaginatorAlternativeAlignment) { + if (value !== this._alignment) { + this._alignment = value; + this._applyAlternativeAlignment(); + } } } diff --git a/src/lib/paginator/paginator.ts b/src/lib/paginator/paginator.ts index f6723d31c..836eb055d 100644 --- a/src/lib/paginator/paginator.ts +++ b/src/lib/paginator/paginator.ts @@ -37,8 +37,6 @@ declare global { } /** - * The custom element class behind the `` component. - * * @tag forge-paginator */ @CustomElement({ diff --git a/src/test/spec/paginator/paginator.spec.ts b/src/test/spec/paginator/paginator.spec.ts index c1ec3790c..6baec5be3 100644 --- a/src/test/spec/paginator/paginator.spec.ts +++ b/src/test/spec/paginator/paginator.spec.ts @@ -118,6 +118,7 @@ describe('PaginatorComponent', function(this: ITestContext) { this.context = setupTestContext(); this.context.paginator.total = 100; this.context.paginator.pageIndex = 2; + this.context.nextPageButton.focus(); this.context.nextPageButton.click(); expect(this.context.nextPageButton.hasAttribute('disabled')).toBe(true); @@ -128,6 +129,7 @@ describe('PaginatorComponent', function(this: ITestContext) { this.context = setupTestContext(); this.context.paginator.total = 100; this.context.paginator.pageIndex = 1; + this.context.previousPageButton.focus(); this.context.previousPageButton.click(); expect(this.context.previousPageButton.hasAttribute('disabled')).toBe(true); @@ -138,6 +140,7 @@ describe('PaginatorComponent', function(this: ITestContext) { this.context = setupTestContext(true, true); this.context.paginator.total = 100; this.context.paginator.pageIndex = 1; + this.context.firstPageButton.focus(); this.context.firstPageButton.click(); expect(this.context.firstPageButton.hasAttribute('disabled')).toBe(true); @@ -148,6 +151,7 @@ describe('PaginatorComponent', function(this: ITestContext) { this.context = setupTestContext(true, true); this.context.paginator.total = 100; this.context.paginator.pageIndex = 2; + this.context.lastPageButton.focus(); this.context.lastPageButton.click(); expect(this.context.lastPageButton.hasAttribute('disabled')).toBe(true); @@ -423,9 +427,9 @@ describe('PaginatorComponent', function(this: ITestContext) { const pageSizeOptions = [5, 10, 25]; this.context.paginator.pageSizeOptions = pageSizeOptions; this.context.paginator.pageSize = 25; - + expect(this.context.paginator.total).toBe(0); - + this.context.paginator.offset = 25; expect(this.context.paginator.pageIndex).toBe(0); @@ -439,7 +443,6 @@ describe('PaginatorComponent', function(this: ITestContext) { this.context.paginator.pageSizeOptions = pageSizeOptions; this.context.paginator.pageSize = 25; this.context.paginator.total = 100; - expect(this.context.paginator.pageIndex).toBe(0); expect(this.context.paginator.offset).toBe(0); @@ -449,7 +452,6 @@ describe('PaginatorComponent', function(this: ITestContext) { expect(this.context.paginator.offset).toBe(25); this.context.paginator.pageIndex = 3; - expect(this.context.paginator.pageIndex).toBe(3); expect(this.context.paginator.offset).toBe(75);