@triptease/tt-paginator 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/package.json +3 -0
- package/dist/cjs/src/TtPaginator.js +95 -0
- package/dist/cjs/src/TtPaginator.js.map +1 -0
- package/dist/cjs/src/index.js +21 -0
- package/dist/cjs/src/index.js.map +1 -0
- package/dist/cjs/src/page-range.js +25 -0
- package/dist/cjs/src/page-range.js.map +1 -0
- package/dist/cjs/src/styles.js +24 -0
- package/dist/cjs/src/styles.js.map +1 -0
- package/dist/cjs/src/tt-paginator.js +11 -0
- package/dist/cjs/src/tt-paginator.js.map +1 -0
- package/dist/cjs/src/types.js +3 -0
- package/dist/cjs/src/types.js.map +1 -0
- package/dist/esm/src/Styles.d.ts +1 -0
- package/dist/esm/src/Styles.js +21 -0
- package/dist/esm/src/Styles.js.map +1 -0
- package/dist/esm/src/TtPaginator.d.ts +18 -0
- package/dist/esm/src/TtPaginator.js +91 -0
- package/dist/esm/src/TtPaginator.js.map +1 -0
- package/dist/esm/src/index.d.ts +2 -0
- package/dist/esm/src/index.js +3 -0
- package/dist/esm/src/index.js.map +1 -0
- package/dist/esm/src/page-range.d.ts +1 -0
- package/dist/esm/src/page-range.js +22 -0
- package/dist/esm/src/page-range.js.map +1 -0
- package/dist/esm/src/style.d.ts +1 -0
- package/dist/esm/src/style.js +2 -0
- package/dist/esm/src/style.js.map +1 -0
- package/dist/esm/src/tt-paginator.d.ts +2 -0
- package/dist/esm/src/tt-paginator.js +8 -0
- package/dist/esm/src/tt-paginator.js.map +1 -0
- package/dist/esm/src/types.d.ts +29 -0
- package/dist/esm/src/types.js +2 -0
- package/dist/esm/src/types.js.map +1 -0
- package/package.json +53 -0
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
exports.TtPaginator = void 0;
|
|
10
|
+
const lit_1 = require("lit");
|
|
11
|
+
const decorators_js_1 = require("lit/decorators.js");
|
|
12
|
+
const page_range_js_1 = require("./page-range.js");
|
|
13
|
+
const styles_js_1 = require("./styles.js");
|
|
14
|
+
class TtPaginator extends lit_1.LitElement {
|
|
15
|
+
constructor() {
|
|
16
|
+
super(...arguments);
|
|
17
|
+
this.totalRows = 0;
|
|
18
|
+
this.pageSize = 10;
|
|
19
|
+
this.currentPage = 1;
|
|
20
|
+
}
|
|
21
|
+
get totalPages() {
|
|
22
|
+
return Math.ceil(this.totalRows / this.pageSize);
|
|
23
|
+
}
|
|
24
|
+
willUpdate(changed) {
|
|
25
|
+
if (changed.has('totalRows') || changed.has('pageSize')) {
|
|
26
|
+
this.currentPage = 1;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
handleKeyDown(e) {
|
|
30
|
+
const keyMap = {
|
|
31
|
+
ArrowRight: this.currentPage + 1,
|
|
32
|
+
ArrowLeft: this.currentPage - 1,
|
|
33
|
+
Home: 1,
|
|
34
|
+
End: this.totalPages,
|
|
35
|
+
};
|
|
36
|
+
const targetPage = keyMap[e.key];
|
|
37
|
+
if (targetPage === undefined)
|
|
38
|
+
return;
|
|
39
|
+
e.preventDefault();
|
|
40
|
+
this.goToPage(targetPage);
|
|
41
|
+
}
|
|
42
|
+
render() {
|
|
43
|
+
if (this.totalPages <= 1)
|
|
44
|
+
return lit_1.nothing;
|
|
45
|
+
const range = (0, page_range_js_1.computePageRange)(this.currentPage, this.totalPages);
|
|
46
|
+
return (0, lit_1.html) `
|
|
47
|
+
<nav role="navigation" aria-label="Pagination" @keydown=${this.handleKeyDown}>
|
|
48
|
+
${this.renderNavButton('Go to first page', 'First', 1, this.currentPage === 1)}
|
|
49
|
+
${this.renderNavButton('Go to previous page', 'Previous', this.currentPage - 1, this.currentPage === 1)}
|
|
50
|
+
${range.map((page) => (0, lit_1.html) `
|
|
51
|
+
<button
|
|
52
|
+
data-page=${page}
|
|
53
|
+
data-theme=${page === this.currentPage ? 'primary' : 'secondary'}
|
|
54
|
+
aria-label="Go to page ${page}"
|
|
55
|
+
aria-current=${page === this.currentPage ? 'page' : 'false'}
|
|
56
|
+
@click=${() => this.goToPage(page)}
|
|
57
|
+
>
|
|
58
|
+
${page}
|
|
59
|
+
</button>
|
|
60
|
+
`)}
|
|
61
|
+
${this.renderNavButton('Go to next page', 'Next', this.currentPage + 1, this.currentPage === this.totalPages)}
|
|
62
|
+
${this.renderNavButton('Go to last page', 'Last', this.totalPages, this.currentPage === this.totalPages)}
|
|
63
|
+
</nav>
|
|
64
|
+
`;
|
|
65
|
+
}
|
|
66
|
+
renderNavButton(label, text, targetPage, disabled) {
|
|
67
|
+
return (0, lit_1.html) `
|
|
68
|
+
<button data-theme="tertiary" aria-label=${label} ?disabled=${disabled} @click=${() => this.goToPage(targetPage)}>
|
|
69
|
+
${text}
|
|
70
|
+
</button>
|
|
71
|
+
`;
|
|
72
|
+
}
|
|
73
|
+
goToPage(page) {
|
|
74
|
+
if (page < 1 || page > this.totalPages || page === this.currentPage)
|
|
75
|
+
return;
|
|
76
|
+
this.currentPage = page;
|
|
77
|
+
this.dispatchEvent(new CustomEvent('page-change', {
|
|
78
|
+
detail: { page: this.currentPage },
|
|
79
|
+
bubbles: true,
|
|
80
|
+
composed: true,
|
|
81
|
+
}));
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
exports.TtPaginator = TtPaginator;
|
|
85
|
+
TtPaginator.styles = styles_js_1.styles;
|
|
86
|
+
__decorate([
|
|
87
|
+
(0, decorators_js_1.property)({ type: Number, attribute: 'total-rows' })
|
|
88
|
+
], TtPaginator.prototype, "totalRows", void 0);
|
|
89
|
+
__decorate([
|
|
90
|
+
(0, decorators_js_1.property)({ type: Number, attribute: 'page-size' })
|
|
91
|
+
], TtPaginator.prototype, "pageSize", void 0);
|
|
92
|
+
__decorate([
|
|
93
|
+
(0, decorators_js_1.state)()
|
|
94
|
+
], TtPaginator.prototype, "currentPage", void 0);
|
|
95
|
+
//# sourceMappingURL=TtPaginator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TtPaginator.js","sourceRoot":"","sources":["../../../src/TtPaginator.ts"],"names":[],"mappings":"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","sourcesContent":["import { html, LitElement, nothing } from 'lit';\nimport { property, state } from 'lit/decorators.js';\nimport { computePageRange } from './page-range.js';\nimport { styles } from './styles.js';\n\nexport class TtPaginator extends LitElement {\n static styles = styles;\n\n @property({ type: Number, attribute: 'total-rows' })\n totalRows = 0;\n\n @property({ type: Number, attribute: 'page-size' })\n pageSize = 10;\n\n @state()\n private currentPage = 1;\n\n private get totalPages() {\n return Math.ceil(this.totalRows / this.pageSize);\n }\n\n protected willUpdate(changed: Map<string, unknown>) {\n if (changed.has('totalRows') || changed.has('pageSize')) {\n this.currentPage = 1;\n }\n }\n\n private handleKeyDown(e: KeyboardEvent) {\n const keyMap: Record<string, number> = {\n ArrowRight: this.currentPage + 1,\n ArrowLeft: this.currentPage - 1,\n Home: 1,\n End: this.totalPages,\n };\n\n const targetPage = keyMap[e.key];\n if (targetPage === undefined) return;\n\n e.preventDefault();\n this.goToPage(targetPage);\n }\n\n render() {\n if (this.totalPages <= 1) return nothing;\n\n const range = computePageRange(this.currentPage, this.totalPages);\n\n return html`\n <nav role=\"navigation\" aria-label=\"Pagination\" @keydown=${this.handleKeyDown}>\n ${this.renderNavButton('Go to first page', 'First', 1, this.currentPage === 1)}\n ${this.renderNavButton('Go to previous page', 'Previous', this.currentPage - 1, this.currentPage === 1)}\n ${range.map(\n (page) => html`\n <button\n data-page=${page}\n data-theme=${page === this.currentPage ? 'primary' : 'secondary'}\n aria-label=\"Go to page ${page}\"\n aria-current=${page === this.currentPage ? 'page' : 'false'}\n @click=${() => this.goToPage(page)}\n >\n ${page}\n </button>\n `\n )}\n ${this.renderNavButton('Go to next page', 'Next', this.currentPage + 1, this.currentPage === this.totalPages)}\n ${this.renderNavButton('Go to last page', 'Last', this.totalPages, this.currentPage === this.totalPages)}\n </nav>\n `;\n }\n\n private renderNavButton(label: string, text: string, targetPage: number, disabled: boolean) {\n return html`\n <button data-theme=\"tertiary\" aria-label=${label} ?disabled=${disabled} @click=${() => this.goToPage(targetPage)}>\n ${text}\n </button>\n `;\n }\n\n private goToPage(page: number) {\n if (page < 1 || page > this.totalPages || page === this.currentPage) return;\n this.currentPage = page;\n this.dispatchEvent(\n new CustomEvent('page-change', {\n detail: { page: this.currentPage },\n bubbles: true,\n composed: true,\n })\n );\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'tt-paginator': TtPaginator;\n }\n}\n"]}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
exports.TtPaginator = void 0;
|
|
18
|
+
var tt_paginator_js_1 = require("./tt-paginator.js");
|
|
19
|
+
Object.defineProperty(exports, "TtPaginator", { enumerable: true, get: function () { return tt_paginator_js_1.TtPaginator; } });
|
|
20
|
+
__exportStar(require("./types.js"), exports);
|
|
21
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;AAAA,qDAAgD;AAAvC,8GAAA,WAAW,OAAA;AACpB,6CAA2B","sourcesContent":["export { TtPaginator } from './tt-paginator.js';\nexport * from './types.js';\n"]}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.computePageRange = computePageRange;
|
|
4
|
+
const WINDOW_SIZE = 5;
|
|
5
|
+
function computePageRange(currentPage, totalPages) {
|
|
6
|
+
if (totalPages <= 0)
|
|
7
|
+
return [];
|
|
8
|
+
const clamped = Math.max(1, Math.min(currentPage, totalPages));
|
|
9
|
+
if (totalPages <= WINDOW_SIZE) {
|
|
10
|
+
return Array.from({ length: totalPages }, (_, i) => i + 1);
|
|
11
|
+
}
|
|
12
|
+
const half = Math.floor(WINDOW_SIZE / 2);
|
|
13
|
+
let start = clamped - half;
|
|
14
|
+
let end = clamped + half;
|
|
15
|
+
if (start < 1) {
|
|
16
|
+
start = 1;
|
|
17
|
+
end = WINDOW_SIZE;
|
|
18
|
+
}
|
|
19
|
+
else if (end > totalPages) {
|
|
20
|
+
end = totalPages;
|
|
21
|
+
start = totalPages - WINDOW_SIZE + 1;
|
|
22
|
+
}
|
|
23
|
+
return Array.from({ length: end - start + 1 }, (_, i) => start + i);
|
|
24
|
+
}
|
|
25
|
+
//# sourceMappingURL=page-range.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"page-range.js","sourceRoot":"","sources":["../../../src/page-range.ts"],"names":[],"mappings":";;AAEA,4CAsBC;AAxBD,MAAM,WAAW,GAAG,CAAC,CAAC;AAEtB,SAAgB,gBAAgB,CAAC,WAAmB,EAAE,UAAkB;IACtE,IAAI,UAAU,IAAI,CAAC;QAAE,OAAO,EAAE,CAAC;IAE/B,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,WAAW,EAAE,UAAU,CAAC,CAAC,CAAC;IAE/D,IAAI,UAAU,IAAI,WAAW,EAAE,CAAC;QAC9B,OAAO,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,UAAU,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;IAC7D,CAAC;IAED,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,WAAW,GAAG,CAAC,CAAC,CAAC;IACzC,IAAI,KAAK,GAAG,OAAO,GAAG,IAAI,CAAC;IAC3B,IAAI,GAAG,GAAG,OAAO,GAAG,IAAI,CAAC;IAEzB,IAAI,KAAK,GAAG,CAAC,EAAE,CAAC;QACd,KAAK,GAAG,CAAC,CAAC;QACV,GAAG,GAAG,WAAW,CAAC;IACpB,CAAC;SAAM,IAAI,GAAG,GAAG,UAAU,EAAE,CAAC;QAC5B,GAAG,GAAG,UAAU,CAAC;QACjB,KAAK,GAAG,UAAU,GAAG,WAAW,GAAG,CAAC,CAAC;IACvC,CAAC;IAED,OAAO,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,GAAG,GAAG,KAAK,GAAG,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC;AACtE,CAAC","sourcesContent":["const WINDOW_SIZE = 5;\n\nexport function computePageRange(currentPage: number, totalPages: number): number[] {\n if (totalPages <= 0) return [];\n\n const clamped = Math.max(1, Math.min(currentPage, totalPages));\n\n if (totalPages <= WINDOW_SIZE) {\n return Array.from({ length: totalPages }, (_, i) => i + 1);\n }\n\n const half = Math.floor(WINDOW_SIZE / 2);\n let start = clamped - half;\n let end = clamped + half;\n\n if (start < 1) {\n start = 1;\n end = WINDOW_SIZE;\n } else if (end > totalPages) {\n end = totalPages;\n start = totalPages - WINDOW_SIZE + 1;\n }\n\n return Array.from({ length: end - start + 1 }, (_, i) => start + i);\n}\n"]}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.styles = void 0;
|
|
4
|
+
const lit_1 = require("lit");
|
|
5
|
+
const lit_2 = require("@triptease/stylesheet/lit");
|
|
6
|
+
exports.styles = [
|
|
7
|
+
lit_2.styles,
|
|
8
|
+
(0, lit_1.css) `
|
|
9
|
+
:host {
|
|
10
|
+
display: block;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
nav {
|
|
14
|
+
display: flex;
|
|
15
|
+
align-items: center;
|
|
16
|
+
gap: var(--space-scale-0-5);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
button {
|
|
20
|
+
min-width: 2rem;
|
|
21
|
+
}
|
|
22
|
+
`,
|
|
23
|
+
];
|
|
24
|
+
//# sourceMappingURL=styles.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"styles.js","sourceRoot":"","sources":["../../../src/styles.ts"],"names":[],"mappings":";;;AAAA,6BAA0B;AAC1B,mDAAiE;AAEpD,QAAA,MAAM,GAAG;IACpB,YAAU;IACV,IAAA,SAAG,EAAA;;;;;;;;;;;;;;GAcF;CACF,CAAC","sourcesContent":["import { css } from 'lit';\nimport { styles as baseStyles } from '@triptease/stylesheet/lit';\n\nexport const styles = [\n baseStyles,\n css`\n :host {\n display: block;\n }\n\n nav {\n display: flex;\n align-items: center;\n gap: var(--space-scale-0-5);\n }\n\n button {\n min-width: 2rem;\n }\n `,\n];\n"]}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.TtPaginator = void 0;
|
|
4
|
+
const TtPaginator_js_1 = require("./TtPaginator.js");
|
|
5
|
+
Object.defineProperty(exports, "TtPaginator", { enumerable: true, get: function () { return TtPaginator_js_1.TtPaginator; } });
|
|
6
|
+
if (typeof window !== 'undefined') {
|
|
7
|
+
if (!window.customElements.get('tt-paginator')) {
|
|
8
|
+
window.customElements.define('tt-paginator', TtPaginator_js_1.TtPaginator);
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
//# sourceMappingURL=tt-paginator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tt-paginator.js","sourceRoot":"","sources":["../../../src/tt-paginator.ts"],"names":[],"mappings":";;;AAAA,qDAA+C;AAQtC,4FARA,4BAAW,OAQA;AANpB,IAAI,OAAO,MAAM,KAAK,WAAW,EAAE,CAAC;IAClC,IAAI,CAAC,MAAM,CAAC,cAAc,CAAC,GAAG,CAAC,cAAc,CAAC,EAAE,CAAC;QAC/C,MAAM,CAAC,cAAc,CAAC,MAAM,CAAC,cAAc,EAAE,4BAAW,CAAC,CAAC;IAC5D,CAAC;AACH,CAAC","sourcesContent":["import { TtPaginator } from './TtPaginator.js';\n\nif (typeof window !== 'undefined') {\n if (!window.customElements.get('tt-paginator')) {\n window.customElements.define('tt-paginator', TtPaginator);\n }\n}\n\nexport { TtPaginator };\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/types.ts"],"names":[],"mappings":"","sourcesContent":["import { TtPaginator } from './TtPaginator.js';\n\ninterface TtPaginatorExternalAttributes {\n 'total-rows'?: number;\n 'page-size'?: number;\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'tt-paginator': TtPaginator;\n }\n namespace JSX {\n interface IntrinsicElements {\n 'tt-paginator': TtPaginatorExternalAttributes & { style?: string };\n }\n }\n\n namespace React {\n namespace JSX {\n interface IntrinsicElements {\n 'tt-paginator': TtPaginatorExternalAttributes & {\n key?: string;\n ref?: React.Ref<unknown>;\n style?: React.CSSProperties;\n };\n }\n }\n }\n}\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const styles: import("lit").CSSResult[];
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { css } from 'lit';
|
|
2
|
+
import { styles as baseStyles } from '@triptease/stylesheet/lit';
|
|
3
|
+
export const styles = [
|
|
4
|
+
baseStyles,
|
|
5
|
+
css `
|
|
6
|
+
:host {
|
|
7
|
+
display: block;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
nav {
|
|
11
|
+
display: flex;
|
|
12
|
+
align-items: center;
|
|
13
|
+
gap: var(--space-scale-0-5);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
button {
|
|
17
|
+
min-width: 2rem;
|
|
18
|
+
}
|
|
19
|
+
`,
|
|
20
|
+
];
|
|
21
|
+
//# sourceMappingURL=styles.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"styles.js","sourceRoot":"","sources":["../../../src/styles.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,KAAK,CAAC;AAC1B,OAAO,EAAE,MAAM,IAAI,UAAU,EAAE,MAAM,2BAA2B,CAAC;AAEjE,MAAM,CAAC,MAAM,MAAM,GAAG;IACpB,UAAU;IACV,GAAG,CAAA;;;;;;;;;;;;;;GAcF;CACF,CAAC","sourcesContent":["import { css } from 'lit';\nimport { styles as baseStyles } from '@triptease/stylesheet/lit';\n\nexport const styles = [\n baseStyles,\n css`\n :host {\n display: block;\n }\n\n nav {\n display: flex;\n align-items: center;\n gap: var(--space-scale-0-5);\n }\n\n button {\n min-width: 2rem;\n }\n `,\n];\n"]}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { LitElement, nothing } from 'lit';
|
|
2
|
+
export declare class TtPaginator extends LitElement {
|
|
3
|
+
static styles: import("lit").CSSResult[];
|
|
4
|
+
totalRows: number;
|
|
5
|
+
pageSize: number;
|
|
6
|
+
private currentPage;
|
|
7
|
+
private get totalPages();
|
|
8
|
+
protected willUpdate(changed: Map<string, unknown>): void;
|
|
9
|
+
private handleKeyDown;
|
|
10
|
+
render(): typeof nothing | import("lit-html").TemplateResult<1>;
|
|
11
|
+
private renderNavButton;
|
|
12
|
+
private goToPage;
|
|
13
|
+
}
|
|
14
|
+
declare global {
|
|
15
|
+
interface HTMLElementTagNameMap {
|
|
16
|
+
'tt-paginator': TtPaginator;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
2
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
|
+
};
|
|
7
|
+
import { html, LitElement, nothing } from 'lit';
|
|
8
|
+
import { property, state } from 'lit/decorators.js';
|
|
9
|
+
import { computePageRange } from './page-range.js';
|
|
10
|
+
import { styles } from './styles.js';
|
|
11
|
+
export class TtPaginator extends LitElement {
|
|
12
|
+
constructor() {
|
|
13
|
+
super(...arguments);
|
|
14
|
+
this.totalRows = 0;
|
|
15
|
+
this.pageSize = 10;
|
|
16
|
+
this.currentPage = 1;
|
|
17
|
+
}
|
|
18
|
+
get totalPages() {
|
|
19
|
+
return Math.ceil(this.totalRows / this.pageSize);
|
|
20
|
+
}
|
|
21
|
+
willUpdate(changed) {
|
|
22
|
+
if (changed.has('totalRows') || changed.has('pageSize')) {
|
|
23
|
+
this.currentPage = 1;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
handleKeyDown(e) {
|
|
27
|
+
const keyMap = {
|
|
28
|
+
ArrowRight: this.currentPage + 1,
|
|
29
|
+
ArrowLeft: this.currentPage - 1,
|
|
30
|
+
Home: 1,
|
|
31
|
+
End: this.totalPages,
|
|
32
|
+
};
|
|
33
|
+
const targetPage = keyMap[e.key];
|
|
34
|
+
if (targetPage === undefined)
|
|
35
|
+
return;
|
|
36
|
+
e.preventDefault();
|
|
37
|
+
this.goToPage(targetPage);
|
|
38
|
+
}
|
|
39
|
+
render() {
|
|
40
|
+
if (this.totalPages <= 1)
|
|
41
|
+
return nothing;
|
|
42
|
+
const range = computePageRange(this.currentPage, this.totalPages);
|
|
43
|
+
return html `
|
|
44
|
+
<nav role="navigation" aria-label="Pagination" @keydown=${this.handleKeyDown}>
|
|
45
|
+
${this.renderNavButton('Go to first page', 'First', 1, this.currentPage === 1)}
|
|
46
|
+
${this.renderNavButton('Go to previous page', 'Previous', this.currentPage - 1, this.currentPage === 1)}
|
|
47
|
+
${range.map((page) => html `
|
|
48
|
+
<button
|
|
49
|
+
data-page=${page}
|
|
50
|
+
data-theme=${page === this.currentPage ? 'primary' : 'secondary'}
|
|
51
|
+
aria-label="Go to page ${page}"
|
|
52
|
+
aria-current=${page === this.currentPage ? 'page' : 'false'}
|
|
53
|
+
@click=${() => this.goToPage(page)}
|
|
54
|
+
>
|
|
55
|
+
${page}
|
|
56
|
+
</button>
|
|
57
|
+
`)}
|
|
58
|
+
${this.renderNavButton('Go to next page', 'Next', this.currentPage + 1, this.currentPage === this.totalPages)}
|
|
59
|
+
${this.renderNavButton('Go to last page', 'Last', this.totalPages, this.currentPage === this.totalPages)}
|
|
60
|
+
</nav>
|
|
61
|
+
`;
|
|
62
|
+
}
|
|
63
|
+
renderNavButton(label, text, targetPage, disabled) {
|
|
64
|
+
return html `
|
|
65
|
+
<button data-theme="tertiary" aria-label=${label} ?disabled=${disabled} @click=${() => this.goToPage(targetPage)}>
|
|
66
|
+
${text}
|
|
67
|
+
</button>
|
|
68
|
+
`;
|
|
69
|
+
}
|
|
70
|
+
goToPage(page) {
|
|
71
|
+
if (page < 1 || page > this.totalPages || page === this.currentPage)
|
|
72
|
+
return;
|
|
73
|
+
this.currentPage = page;
|
|
74
|
+
this.dispatchEvent(new CustomEvent('page-change', {
|
|
75
|
+
detail: { page: this.currentPage },
|
|
76
|
+
bubbles: true,
|
|
77
|
+
composed: true,
|
|
78
|
+
}));
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
TtPaginator.styles = styles;
|
|
82
|
+
__decorate([
|
|
83
|
+
property({ type: Number, attribute: 'total-rows' })
|
|
84
|
+
], TtPaginator.prototype, "totalRows", void 0);
|
|
85
|
+
__decorate([
|
|
86
|
+
property({ type: Number, attribute: 'page-size' })
|
|
87
|
+
], TtPaginator.prototype, "pageSize", void 0);
|
|
88
|
+
__decorate([
|
|
89
|
+
state()
|
|
90
|
+
], TtPaginator.prototype, "currentPage", void 0);
|
|
91
|
+
//# sourceMappingURL=TtPaginator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TtPaginator.js","sourceRoot":"","sources":["../../../src/TtPaginator.ts"],"names":[],"mappings":"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","sourcesContent":["import { html, LitElement, nothing } from 'lit';\nimport { property, state } from 'lit/decorators.js';\nimport { computePageRange } from './page-range.js';\nimport { styles } from './styles.js';\n\nexport class TtPaginator extends LitElement {\n static styles = styles;\n\n @property({ type: Number, attribute: 'total-rows' })\n totalRows = 0;\n\n @property({ type: Number, attribute: 'page-size' })\n pageSize = 10;\n\n @state()\n private currentPage = 1;\n\n private get totalPages() {\n return Math.ceil(this.totalRows / this.pageSize);\n }\n\n protected willUpdate(changed: Map<string, unknown>) {\n if (changed.has('totalRows') || changed.has('pageSize')) {\n this.currentPage = 1;\n }\n }\n\n private handleKeyDown(e: KeyboardEvent) {\n const keyMap: Record<string, number> = {\n ArrowRight: this.currentPage + 1,\n ArrowLeft: this.currentPage - 1,\n Home: 1,\n End: this.totalPages,\n };\n\n const targetPage = keyMap[e.key];\n if (targetPage === undefined) return;\n\n e.preventDefault();\n this.goToPage(targetPage);\n }\n\n render() {\n if (this.totalPages <= 1) return nothing;\n\n const range = computePageRange(this.currentPage, this.totalPages);\n\n return html`\n <nav role=\"navigation\" aria-label=\"Pagination\" @keydown=${this.handleKeyDown}>\n ${this.renderNavButton('Go to first page', 'First', 1, this.currentPage === 1)}\n ${this.renderNavButton('Go to previous page', 'Previous', this.currentPage - 1, this.currentPage === 1)}\n ${range.map(\n (page) => html`\n <button\n data-page=${page}\n data-theme=${page === this.currentPage ? 'primary' : 'secondary'}\n aria-label=\"Go to page ${page}\"\n aria-current=${page === this.currentPage ? 'page' : 'false'}\n @click=${() => this.goToPage(page)}\n >\n ${page}\n </button>\n `\n )}\n ${this.renderNavButton('Go to next page', 'Next', this.currentPage + 1, this.currentPage === this.totalPages)}\n ${this.renderNavButton('Go to last page', 'Last', this.totalPages, this.currentPage === this.totalPages)}\n </nav>\n `;\n }\n\n private renderNavButton(label: string, text: string, targetPage: number, disabled: boolean) {\n return html`\n <button data-theme=\"tertiary\" aria-label=${label} ?disabled=${disabled} @click=${() => this.goToPage(targetPage)}>\n ${text}\n </button>\n `;\n }\n\n private goToPage(page: number) {\n if (page < 1 || page > this.totalPages || page === this.currentPage) return;\n this.currentPage = page;\n this.dispatchEvent(\n new CustomEvent('page-change', {\n detail: { page: this.currentPage },\n bubbles: true,\n composed: true,\n })\n );\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'tt-paginator': TtPaginator;\n }\n}\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,cAAc,YAAY,CAAC","sourcesContent":["export { TtPaginator } from './tt-paginator.js';\nexport * from './types.js';\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function computePageRange(currentPage: number, totalPages: number): number[];
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
const WINDOW_SIZE = 5;
|
|
2
|
+
export function computePageRange(currentPage, totalPages) {
|
|
3
|
+
if (totalPages <= 0)
|
|
4
|
+
return [];
|
|
5
|
+
const clamped = Math.max(1, Math.min(currentPage, totalPages));
|
|
6
|
+
if (totalPages <= WINDOW_SIZE) {
|
|
7
|
+
return Array.from({ length: totalPages }, (_, i) => i + 1);
|
|
8
|
+
}
|
|
9
|
+
const half = Math.floor(WINDOW_SIZE / 2);
|
|
10
|
+
let start = clamped - half;
|
|
11
|
+
let end = clamped + half;
|
|
12
|
+
if (start < 1) {
|
|
13
|
+
start = 1;
|
|
14
|
+
end = WINDOW_SIZE;
|
|
15
|
+
}
|
|
16
|
+
else if (end > totalPages) {
|
|
17
|
+
end = totalPages;
|
|
18
|
+
start = totalPages - WINDOW_SIZE + 1;
|
|
19
|
+
}
|
|
20
|
+
return Array.from({ length: end - start + 1 }, (_, i) => start + i);
|
|
21
|
+
}
|
|
22
|
+
//# sourceMappingURL=page-range.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"page-range.js","sourceRoot":"","sources":["../../../src/page-range.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,GAAG,CAAC,CAAC;AAEtB,MAAM,UAAU,gBAAgB,CAAC,WAAmB,EAAE,UAAkB;IACtE,IAAI,UAAU,IAAI,CAAC;QAAE,OAAO,EAAE,CAAC;IAE/B,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,WAAW,EAAE,UAAU,CAAC,CAAC,CAAC;IAE/D,IAAI,UAAU,IAAI,WAAW,EAAE,CAAC;QAC9B,OAAO,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,UAAU,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;IAC7D,CAAC;IAED,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,WAAW,GAAG,CAAC,CAAC,CAAC;IACzC,IAAI,KAAK,GAAG,OAAO,GAAG,IAAI,CAAC;IAC3B,IAAI,GAAG,GAAG,OAAO,GAAG,IAAI,CAAC;IAEzB,IAAI,KAAK,GAAG,CAAC,EAAE,CAAC;QACd,KAAK,GAAG,CAAC,CAAC;QACV,GAAG,GAAG,WAAW,CAAC;IACpB,CAAC;SAAM,IAAI,GAAG,GAAG,UAAU,EAAE,CAAC;QAC5B,GAAG,GAAG,UAAU,CAAC;QACjB,KAAK,GAAG,UAAU,GAAG,WAAW,GAAG,CAAC,CAAC;IACvC,CAAC;IAED,OAAO,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,GAAG,GAAG,KAAK,GAAG,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC;AACtE,CAAC","sourcesContent":["const WINDOW_SIZE = 5;\n\nexport function computePageRange(currentPage: number, totalPages: number): number[] {\n if (totalPages <= 0) return [];\n\n const clamped = Math.max(1, Math.min(currentPage, totalPages));\n\n if (totalPages <= WINDOW_SIZE) {\n return Array.from({ length: totalPages }, (_, i) => i + 1);\n }\n\n const half = Math.floor(WINDOW_SIZE / 2);\n let start = clamped - half;\n let end = clamped + half;\n\n if (start < 1) {\n start = 1;\n end = WINDOW_SIZE;\n } else if (end > totalPages) {\n end = totalPages;\n start = totalPages - WINDOW_SIZE + 1;\n }\n\n return Array.from({ length: end - start + 1 }, (_, i) => start + i);\n}\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"style.js","sourceRoot":"","sources":["../../../src/style.ts"],"names":[],"mappings":"","sourcesContent":[""]}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { TtPaginator } from './TtPaginator.js';
|
|
2
|
+
if (typeof window !== 'undefined') {
|
|
3
|
+
if (!window.customElements.get('tt-paginator')) {
|
|
4
|
+
window.customElements.define('tt-paginator', TtPaginator);
|
|
5
|
+
}
|
|
6
|
+
}
|
|
7
|
+
export { TtPaginator };
|
|
8
|
+
//# sourceMappingURL=tt-paginator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tt-paginator.js","sourceRoot":"","sources":["../../../src/tt-paginator.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAE/C,IAAI,OAAO,MAAM,KAAK,WAAW,EAAE,CAAC;IAClC,IAAI,CAAC,MAAM,CAAC,cAAc,CAAC,GAAG,CAAC,cAAc,CAAC,EAAE,CAAC;QAC/C,MAAM,CAAC,cAAc,CAAC,MAAM,CAAC,cAAc,EAAE,WAAW,CAAC,CAAC;IAC5D,CAAC;AACH,CAAC;AAED,OAAO,EAAE,WAAW,EAAE,CAAC","sourcesContent":["import { TtPaginator } from './TtPaginator.js';\n\nif (typeof window !== 'undefined') {\n if (!window.customElements.get('tt-paginator')) {\n window.customElements.define('tt-paginator', TtPaginator);\n }\n}\n\nexport { TtPaginator };\n"]}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { TtPaginator } from './TtPaginator.js';
|
|
2
|
+
interface TtPaginatorExternalAttributes {
|
|
3
|
+
'total-rows'?: number;
|
|
4
|
+
'page-size'?: number;
|
|
5
|
+
}
|
|
6
|
+
declare global {
|
|
7
|
+
interface HTMLElementTagNameMap {
|
|
8
|
+
'tt-paginator': TtPaginator;
|
|
9
|
+
}
|
|
10
|
+
namespace JSX {
|
|
11
|
+
interface IntrinsicElements {
|
|
12
|
+
'tt-paginator': TtPaginatorExternalAttributes & {
|
|
13
|
+
style?: string;
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
namespace React {
|
|
18
|
+
namespace JSX {
|
|
19
|
+
interface IntrinsicElements {
|
|
20
|
+
'tt-paginator': TtPaginatorExternalAttributes & {
|
|
21
|
+
key?: string;
|
|
22
|
+
ref?: React.Ref<unknown>;
|
|
23
|
+
style?: React.CSSProperties;
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/types.ts"],"names":[],"mappings":"","sourcesContent":["import { TtPaginator } from './TtPaginator.js';\n\ninterface TtPaginatorExternalAttributes {\n 'total-rows'?: number;\n 'page-size'?: number;\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'tt-paginator': TtPaginator;\n }\n namespace JSX {\n interface IntrinsicElements {\n 'tt-paginator': TtPaginatorExternalAttributes & { style?: string };\n }\n }\n\n namespace React {\n namespace JSX {\n interface IntrinsicElements {\n 'tt-paginator': TtPaginatorExternalAttributes & {\n key?: string;\n ref?: React.Ref<unknown>;\n style?: React.CSSProperties;\n };\n }\n }\n }\n}\n"]}
|
package/package.json
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@triptease/tt-paginator",
|
|
3
|
+
"description": "Numeric pagination web component",
|
|
4
|
+
"license": "MIT",
|
|
5
|
+
"author": "@triptease",
|
|
6
|
+
"version": "1.0.1",
|
|
7
|
+
"type": "module",
|
|
8
|
+
"main": "dist/esm/src/index.js",
|
|
9
|
+
"module": "dist/esm/src/index.js",
|
|
10
|
+
"exports": {
|
|
11
|
+
".": {
|
|
12
|
+
"types": "./dist/esm/src/index.d.ts",
|
|
13
|
+
"import": "./dist/esm/src/index.js",
|
|
14
|
+
"require": "./dist/cjs/src/index.js"
|
|
15
|
+
},
|
|
16
|
+
"./types": {
|
|
17
|
+
"types": "./dist/esm/src/types.d.ts",
|
|
18
|
+
"import": "./dist/esm/src/types.js",
|
|
19
|
+
"require": "./dist/cjs/src/types.js"
|
|
20
|
+
}
|
|
21
|
+
},
|
|
22
|
+
"files": [
|
|
23
|
+
"dist/esm",
|
|
24
|
+
"dist/cjs"
|
|
25
|
+
],
|
|
26
|
+
"scripts": {
|
|
27
|
+
"analyze": "cem analyze --litelement",
|
|
28
|
+
"build": "yarn build:node && yarn build:web && yarn analyze --exclude dist",
|
|
29
|
+
"build:esm": "tsc",
|
|
30
|
+
"build:cjs": "tsc -p tsconfig.cjs.json && node ../../scripts/create-cjs-package.mjs",
|
|
31
|
+
"build:node": "yarn build:esm && yarn build:cjs",
|
|
32
|
+
"build:node:watch": "tsc --watch",
|
|
33
|
+
"build:web": "node ../../scripts/esbuild.mjs",
|
|
34
|
+
"prepublish": "tsc && yarn analyze --exclude dist",
|
|
35
|
+
"test": "yarn playwright install && vitest run --config=./vitest.browser.config.mjs",
|
|
36
|
+
"test:watch": "vitest --config=./vitest.browser.config.mjs"
|
|
37
|
+
},
|
|
38
|
+
"dependencies": {
|
|
39
|
+
"@triptease/stylesheet": "2.1.0",
|
|
40
|
+
"lit": "^3.1.4"
|
|
41
|
+
},
|
|
42
|
+
"devDependencies": {
|
|
43
|
+
"@custom-elements-manifest/analyzer": "^0.10.3",
|
|
44
|
+
"concurrently": "^8.2.2",
|
|
45
|
+
"playwright": "^1.57.0",
|
|
46
|
+
"tslib": "^2.6.3",
|
|
47
|
+
"typescript": "^5.5.3"
|
|
48
|
+
},
|
|
49
|
+
"customElements": "custom-elements.json",
|
|
50
|
+
"publishConfig": {
|
|
51
|
+
"access": "public"
|
|
52
|
+
}
|
|
53
|
+
}
|