Skip to content

Commit

Permalink
fix(paginator): fixed a bug where focus was lost when disabling the p…
Browse files Browse the repository at this point in the history
…age buttons dynamically (#398)
  • Loading branch information
DRiFTy17 authored Oct 4, 2023
1 parent 9b6fdff commit ea3bcf0
Show file tree
Hide file tree
Showing 2 changed files with 99 additions and 0 deletions.
59 changes: 59 additions & 0 deletions src/lib/paginator/paginator-adapter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,7 @@ export class PaginatorAdapter extends BaseAdapter<IPaginatorComponent> implement
}

public disableFirstPageButton(): void {
this._handleFocusMove('first');
this._firstPageButton.setAttribute('disabled', 'disabled');
}

Expand All @@ -193,6 +194,7 @@ export class PaginatorAdapter extends BaseAdapter<IPaginatorComponent> implement
}

public disablePreviousPageButton(): void {
this._handleFocusMove('previous');
this._previousPageButton.setAttribute('disabled', 'disabled');
}

Expand All @@ -201,6 +203,7 @@ export class PaginatorAdapter extends BaseAdapter<IPaginatorComponent> implement
}

public disableNextPageButton(): void {
this._handleFocusMove('next');
this._nextPageButton.setAttribute('disabled', 'disabled');
}

Expand All @@ -209,6 +212,7 @@ export class PaginatorAdapter extends BaseAdapter<IPaginatorComponent> implement
}

public disablePageSizeSelect(): void {
this._handleFocusMove('page-size');
this._pageSizeSelect.setAttribute('disabled', 'disabled');
}

Expand All @@ -225,6 +229,7 @@ export class PaginatorAdapter extends BaseAdapter<IPaginatorComponent> implement
}

public disableLastPageButton(): void {
this._handleFocusMove('last');
this._lastPageButton.setAttribute('disabled', 'disabled');
}

Expand Down Expand Up @@ -256,4 +261,58 @@ export class PaginatorAdapter extends BaseAdapter<IPaginatorComponent> implement
break;
}
}

private _handleFocusMove(from: 'first' | 'last' | 'previous' | 'next' | 'page-size'): void {
switch (from) {
case 'first':
this._tryFocus([
this._nextPageButton,
this._lastPageButton,
this._previousPageButton,
this._pageSizeSelect
]);
break;
case 'last':
this._tryFocus([
this._previousPageButton,
this._firstPageButton,
this._nextPageButton,
this._pageSizeSelect
]);
break;
case 'previous':
this._tryFocus([
this._nextPageButton,
this._lastPageButton,
this._firstPageButton,
this._pageSizeSelect
]);
break;
case 'next':
this._tryFocus([
this._previousPageButton,
this._firstPageButton,
this._lastPageButton,
this._pageSizeSelect
]);
break;
case 'page-size':
this._tryFocus([
this._nextPageButton,
this._lastPageButton,
this._firstPageButton,
this._previousPageButton
]);
break;
}
}

private _tryFocus(elements: Array<HTMLButtonElement | ISelectComponent>): void {
for (const el of elements) {
if (el && el.isConnected && !el.disabled) {
el.focus();
return;
}
}
}
}
40 changes: 40 additions & 0 deletions src/test/spec/paginator/paginator.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,46 @@ describe('PaginatorComponent', function(this: ITestContext) {
expect(this.context.nextPageButton.hasAttribute('disabled')).toBe(true);
});

it('should move focus to previous page button when next page button is disabled', function(this: ITestContext) {
this.context = setupTestContext();
this.context.paginator.total = 100;
this.context.paginator.pageIndex = 2;
this.context.nextPageButton.click();

expect(this.context.nextPageButton.hasAttribute('disabled')).toBe(true);
expect(this.context.previousPageButton.matches(':focus')).toBe(true);
});

it('should move focus to next page button when previous page button is disabled', function(this: ITestContext) {
this.context = setupTestContext();
this.context.paginator.total = 100;
this.context.paginator.pageIndex = 1;
this.context.previousPageButton.click();

expect(this.context.previousPageButton.hasAttribute('disabled')).toBe(true);
expect(this.context.nextPageButton.matches(':focus')).toBe(true);
});

it('should move focus to next page button when first page button is disabled', function(this: ITestContext) {
this.context = setupTestContext(true, true);
this.context.paginator.total = 100;
this.context.paginator.pageIndex = 1;
this.context.firstPageButton.click();

expect(this.context.firstPageButton.hasAttribute('disabled')).toBe(true);
expect(this.context.nextPageButton.matches(':focus')).toBe(true);
});

it('should move focus to previous page button when last page button is disabled', function(this: ITestContext) {
this.context = setupTestContext(true, true);
this.context.paginator.total = 100;
this.context.paginator.pageIndex = 2;
this.context.lastPageButton.click();

expect(this.context.lastPageButton.hasAttribute('disabled')).toBe(true);
expect(this.context.previousPageButton.matches(':focus')).toBe(true);
});

it('should emit change event when clicking next page button', function(this: ITestContext) {
this.context = setupTestContext();
this.context.paginator.total = 100;
Expand Down

0 comments on commit ea3bcf0

Please sign in to comment.