feat(pagination): add types
This commit is contained in:
parent
278798636c
commit
0ed995ad06
4 changed files with 59 additions and 24 deletions
5
.changeset/ninety-vans-cheer.md
Normal file
5
.changeset/ninety-vans-cheer.md
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
'@lion/pagination': minor
|
||||
---
|
||||
|
||||
Add types for pagination package.
|
||||
|
|
@ -1,11 +1,16 @@
|
|||
import { LitElement, html, css } from '@lion/core';
|
||||
import { LocalizeMixin } from '@lion/localize';
|
||||
|
||||
/**
|
||||
* @typedef {import('lit-html').TemplateResult} TemplateResult
|
||||
*/
|
||||
|
||||
/**
|
||||
* `LionPagination` is a class for custom Pagination element (`<lion-pagination>` web component).
|
||||
*
|
||||
* @customElement lion-pagination
|
||||
* @extends LitElement
|
||||
*/
|
||||
// @ts-expect-error https://github.com/microsoft/TypeScript/issues/40110
|
||||
export class LionPagination extends LocalizeMixin(LitElement) {
|
||||
static get styles() {
|
||||
return css`
|
||||
|
|
@ -32,7 +37,7 @@ export class LionPagination extends LocalizeMixin(LitElement) {
|
|||
static get localizeNamespaces() {
|
||||
return [
|
||||
{
|
||||
'lion-pagination': locale => {
|
||||
'lion-pagination': /** @param {string} locale */ locale => {
|
||||
switch (locale) {
|
||||
case 'bg-BG':
|
||||
return import('../translations/bg.js');
|
||||
|
|
@ -92,6 +97,7 @@ export class LionPagination extends LocalizeMixin(LitElement) {
|
|||
};
|
||||
}
|
||||
|
||||
/** @param {number} value */
|
||||
set current(value) {
|
||||
if (value !== this.current) {
|
||||
const oldValue = this.current;
|
||||
|
|
@ -101,8 +107,9 @@ export class LionPagination extends LocalizeMixin(LitElement) {
|
|||
}
|
||||
}
|
||||
|
||||
/** @returns {number} */
|
||||
get current() {
|
||||
return this.__current;
|
||||
return this.__current || 0;
|
||||
}
|
||||
|
||||
constructor() {
|
||||
|
|
@ -144,6 +151,7 @@ export class LionPagination extends LocalizeMixin(LitElement) {
|
|||
|
||||
/**
|
||||
* Go to the specific page
|
||||
* @param {number} pageNumber
|
||||
* @public
|
||||
*/
|
||||
goto(pageNumber) {
|
||||
|
|
@ -175,7 +183,7 @@ export class LionPagination extends LocalizeMixin(LitElement) {
|
|||
|
||||
/**
|
||||
* Calculate nav list based on current page selection.
|
||||
* @returns {Array}
|
||||
* @returns {(number|'...')[]}
|
||||
* @private
|
||||
*/
|
||||
__calculateNavList() {
|
||||
|
|
@ -190,29 +198,27 @@ export class LionPagination extends LocalizeMixin(LitElement) {
|
|||
const pos5 = this.current + 1;
|
||||
// if pos 3 is lower than 4 we have a predefined list of elements
|
||||
if (pos4 <= 4) {
|
||||
const list = Array(this.__visiblePages)
|
||||
.fill()
|
||||
.map((_, idx) => start + idx);
|
||||
const list = /** @type {(number|'...')[]} */ ([...Array(this.__visiblePages)].map(
|
||||
(_, idx) => start + idx,
|
||||
));
|
||||
list.push('...');
|
||||
list.push(this.count);
|
||||
return list;
|
||||
}
|
||||
// if we are close to the end of the list with the current page then we have again a predefined list
|
||||
if (finish - pos4 <= 3) {
|
||||
const list = [];
|
||||
const list = /** @type {(number|'...')[]} */ ([]);
|
||||
list.push(1);
|
||||
list.push('...');
|
||||
const listRemaining = Array(this.__visiblePages)
|
||||
.fill()
|
||||
.map((_, idx) => this.count - this.__visiblePages + 1 + idx);
|
||||
const listRemaining = [...Array(this.__visiblePages)].map(
|
||||
(_, idx) => this.count - this.__visiblePages + 1 + idx,
|
||||
);
|
||||
return list.concat(listRemaining);
|
||||
}
|
||||
|
||||
return [start, '...', pos3, pos4, pos5, '...', finish];
|
||||
}
|
||||
return Array(finish - start + 1)
|
||||
.fill()
|
||||
.map((_, idx) => start + idx);
|
||||
return [...Array(finish - start + 1)].map((_, idx) => start + idx);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -266,7 +272,7 @@ export class LionPagination extends LocalizeMixin(LitElement) {
|
|||
|
||||
/**
|
||||
* Render navigation list
|
||||
* @returns {TemplateResult} nav list template
|
||||
* @returns {TemplateResult[]} nav list template
|
||||
* @protected
|
||||
*/
|
||||
_renderNavList() {
|
||||
|
|
|
|||
|
|
@ -1,8 +1,15 @@
|
|||
import { html, fixture, expect } from '@open-wc/testing';
|
||||
import { html, fixture as _fixture, expect } from '@open-wc/testing';
|
||||
import sinon from 'sinon';
|
||||
|
||||
import '../lion-pagination.js';
|
||||
|
||||
/**
|
||||
* @typedef {import('../src/LionPagination').LionPagination} LionPagination
|
||||
* @typedef {import('lit-html').TemplateResult} TemplateResult
|
||||
*/
|
||||
|
||||
const fixture = /** @type {(arg: TemplateResult) => Promise<LionPagination>} */ (_fixture);
|
||||
|
||||
describe('Pagination', () => {
|
||||
it('has states for count and current', async () => {
|
||||
const el = await fixture(html` <lion-pagination count="4"></lion-pagination> `);
|
||||
|
|
@ -17,34 +24,44 @@ describe('Pagination', () => {
|
|||
|
||||
it('disables the previous button if on first page', async () => {
|
||||
const el = await fixture(html` <lion-pagination count="4"></lion-pagination> `);
|
||||
const buttons = Array.from(el.shadowRoot.querySelectorAll('button'));
|
||||
const buttons = Array.from(
|
||||
/** @type {ShadowRoot} */ (el.shadowRoot).querySelectorAll('button'),
|
||||
);
|
||||
expect(buttons[0]).to.has.attribute('disabled');
|
||||
});
|
||||
|
||||
it('disables the next button if on last page', async () => {
|
||||
const el = await fixture(html` <lion-pagination count="4" current="4"></lion-pagination> `);
|
||||
const buttons = Array.from(el.shadowRoot.querySelectorAll('button'));
|
||||
const buttons = Array.from(
|
||||
/** @type {ShadowRoot} */ (el.shadowRoot).querySelectorAll('button'),
|
||||
);
|
||||
expect(buttons[buttons.length - 1]).to.has.attribute('disabled');
|
||||
});
|
||||
|
||||
describe('User interaction', () => {
|
||||
it('can go to previous page with previous button', async () => {
|
||||
const el = await fixture(html` <lion-pagination count="6" current="2"></lion-pagination> `);
|
||||
const buttons = Array.from(el.shadowRoot.querySelectorAll('button'));
|
||||
const buttons = Array.from(
|
||||
/** @type {ShadowRoot} */ (el.shadowRoot).querySelectorAll('button'),
|
||||
);
|
||||
buttons[0].click();
|
||||
expect(el.current).to.equal(1);
|
||||
});
|
||||
|
||||
it('can go to next page with next button', async () => {
|
||||
const el = await fixture(html` <lion-pagination count="6" current="2"></lion-pagination> `);
|
||||
const buttons = Array.from(el.shadowRoot.querySelectorAll('button'));
|
||||
const buttons = Array.from(
|
||||
/** @type {ShadowRoot} */ (el.shadowRoot).querySelectorAll('button'),
|
||||
);
|
||||
buttons[buttons.length - 1].click();
|
||||
expect(el.current).to.equal(3);
|
||||
});
|
||||
|
||||
it('goes to the page when clicking on its button', async () => {
|
||||
const el = await fixture(html` <lion-pagination count="6" current="2"></lion-pagination> `);
|
||||
const buttons = Array.from(el.shadowRoot.querySelectorAll('button'));
|
||||
const buttons = Array.from(
|
||||
/** @type {ShadowRoot} */ (el.shadowRoot).querySelectorAll('button'),
|
||||
);
|
||||
buttons[5].click();
|
||||
expect(el.current).to.equal(5);
|
||||
});
|
||||
|
|
@ -54,7 +71,9 @@ describe('Pagination', () => {
|
|||
const el = await fixture(html`
|
||||
<lion-pagination count="6" current="2" @current-changed=${changeSpy}></lion-pagination>
|
||||
`);
|
||||
const buttons = Array.from(el.shadowRoot.querySelectorAll('button'));
|
||||
const buttons = Array.from(
|
||||
/** @type {ShadowRoot} */ (el.shadowRoot).querySelectorAll('button'),
|
||||
);
|
||||
const previous = buttons[0];
|
||||
const next = buttons[buttons.length - 1];
|
||||
const page5 = buttons[5];
|
||||
|
|
@ -77,7 +96,9 @@ describe('Pagination', () => {
|
|||
const el = await fixture(html`
|
||||
<lion-pagination count="6" current="2" @current-changed=${changeSpy}></lion-pagination>
|
||||
`);
|
||||
const page2 = el.shadowRoot.querySelector("button[aria-current='true']");
|
||||
const page2 = /** @type {HTMLElement} */ (el.shadowRoot?.querySelector(
|
||||
"button[aria-current='true']",
|
||||
));
|
||||
page2.click();
|
||||
expect(changeSpy).to.not.be.called;
|
||||
expect(el.current).to.equal(2);
|
||||
|
|
@ -111,7 +132,9 @@ describe('Pagination', () => {
|
|||
describe('Accessibility', () => {
|
||||
it('sets aria-current to the current page', async () => {
|
||||
const el = await fixture(html` <lion-pagination count="3"></lion-pagination> `);
|
||||
const buttons = Array.from(el.shadowRoot.querySelectorAll('button'));
|
||||
const buttons = Array.from(
|
||||
/** @type {ShadowRoot} */ (el.shadowRoot).querySelectorAll('button'),
|
||||
);
|
||||
// button[0] is the previous button
|
||||
expect(buttons[1].getAttribute('aria-current')).to.equal('true');
|
||||
expect(buttons[2].getAttribute('aria-current')).to.equal('false');
|
||||
|
|
|
|||
|
|
@ -34,6 +34,7 @@
|
|||
"packages/listbox/src/*.js",
|
||||
"packages/localize/**/*.js",
|
||||
"packages/overlays/**/*.js",
|
||||
"packages/pagination/**/*.js",
|
||||
"packages/radio-group/**/*.js",
|
||||
"packages/singleton-manager/**/*.js",
|
||||
"packages/tabs/**/*.js",
|
||||
|
|
|
|||
Loading…
Reference in a new issue