@duskmoon-dev/el-pagination 0.4.0

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.
@@ -0,0 +1,362 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __getOwnPropNames = Object.getOwnPropertyNames;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
5
+ var __moduleCache = /* @__PURE__ */ new WeakMap;
6
+ var __toCommonJS = (from) => {
7
+ var entry = __moduleCache.get(from), desc;
8
+ if (entry)
9
+ return entry;
10
+ entry = __defProp({}, "__esModule", { value: true });
11
+ if (from && typeof from === "object" || typeof from === "function")
12
+ __getOwnPropNames(from).map((key) => !__hasOwnProp.call(entry, key) && __defProp(entry, key, {
13
+ get: () => from[key],
14
+ enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
15
+ }));
16
+ __moduleCache.set(from, entry);
17
+ return entry;
18
+ };
19
+ var __export = (target, all) => {
20
+ for (var name in all)
21
+ __defProp(target, name, {
22
+ get: all[name],
23
+ enumerable: true,
24
+ configurable: true,
25
+ set: (newValue) => all[name] = () => newValue
26
+ });
27
+ };
28
+
29
+ // src/index.ts
30
+ var exports_src = {};
31
+ __export(exports_src, {
32
+ register: () => register,
33
+ ElDmPagination: () => ElDmPagination
34
+ });
35
+ module.exports = __toCommonJS(exports_src);
36
+
37
+ // src/el-dm-pagination.ts
38
+ var import_el_core = require("@duskmoon-dev/el-core");
39
+ var styles = import_el_core.css`
40
+ :host {
41
+ display: inline-flex;
42
+ vertical-align: middle;
43
+ }
44
+
45
+ :host([hidden]) {
46
+ display: none !important;
47
+ }
48
+
49
+ .pagination {
50
+ display: flex;
51
+ align-items: center;
52
+ gap: 0.25rem;
53
+ font-family: inherit;
54
+ }
55
+
56
+ .pagination-btn {
57
+ display: inline-flex;
58
+ align-items: center;
59
+ justify-content: center;
60
+ border: 1px solid var(--color-border, #d1d5db);
61
+ background: var(--color-surface, #ffffff);
62
+ color: var(--color-text, #374151);
63
+ cursor: pointer;
64
+ font-family: inherit;
65
+ font-weight: 500;
66
+ transition:
67
+ background-color 0.15s ease,
68
+ border-color 0.15s ease,
69
+ color 0.15s ease;
70
+ border-radius: var(--radius-md, 0.375rem);
71
+ min-width: 2rem;
72
+ height: 2rem;
73
+ padding: 0 0.5rem;
74
+ font-size: 0.875rem;
75
+ line-height: 1;
76
+ }
77
+
78
+ .pagination-btn:hover:not(:disabled) {
79
+ background: var(--color-surface-hover, #f3f4f6);
80
+ border-color: var(--color-border-hover, #9ca3af);
81
+ }
82
+
83
+ .pagination-btn:focus-visible {
84
+ outline: 2px solid var(--color-primary, #3b82f6);
85
+ outline-offset: 2px;
86
+ }
87
+
88
+ .pagination-btn:disabled {
89
+ opacity: 0.5;
90
+ cursor: not-allowed;
91
+ }
92
+
93
+ .pagination-btn.active {
94
+ background: var(--color-primary, #3b82f6);
95
+ border-color: var(--color-primary, #3b82f6);
96
+ color: var(--color-primary-contrast, #ffffff);
97
+ }
98
+
99
+ .pagination-btn.nav-btn {
100
+ padding: 0 0.375rem;
101
+ }
102
+
103
+ .pagination-btn.nav-btn svg {
104
+ width: 1em;
105
+ height: 1em;
106
+ }
107
+
108
+ .ellipsis {
109
+ display: inline-flex;
110
+ align-items: center;
111
+ justify-content: center;
112
+ min-width: 2rem;
113
+ height: 2rem;
114
+ color: var(--color-text-muted, #6b7280);
115
+ font-size: 0.875rem;
116
+ user-select: none;
117
+ }
118
+
119
+ /* Size variants */
120
+ :host([size='xs']) .pagination-btn {
121
+ min-width: 1.5rem;
122
+ height: 1.5rem;
123
+ padding: 0 0.25rem;
124
+ font-size: 0.75rem;
125
+ border-radius: var(--radius-sm, 0.25rem);
126
+ }
127
+
128
+ :host([size='xs']) .ellipsis {
129
+ min-width: 1.5rem;
130
+ height: 1.5rem;
131
+ font-size: 0.75rem;
132
+ }
133
+
134
+ :host([size='sm']) .pagination-btn {
135
+ min-width: 1.75rem;
136
+ height: 1.75rem;
137
+ padding: 0 0.375rem;
138
+ font-size: 0.8125rem;
139
+ }
140
+
141
+ :host([size='sm']) .ellipsis {
142
+ min-width: 1.75rem;
143
+ height: 1.75rem;
144
+ font-size: 0.8125rem;
145
+ }
146
+
147
+ :host([size='lg']) .pagination-btn {
148
+ min-width: 2.5rem;
149
+ height: 2.5rem;
150
+ padding: 0 0.75rem;
151
+ font-size: 1rem;
152
+ }
153
+
154
+ :host([size='lg']) .ellipsis {
155
+ min-width: 2.5rem;
156
+ height: 2.5rem;
157
+ font-size: 1rem;
158
+ }
159
+
160
+ /* Color variants */
161
+ :host([color='secondary']) .pagination-btn.active {
162
+ background: var(--color-secondary, #8b5cf6);
163
+ border-color: var(--color-secondary, #8b5cf6);
164
+ color: var(--color-secondary-contrast, #ffffff);
165
+ }
166
+
167
+ :host([color='secondary']) .pagination-btn:focus-visible {
168
+ outline-color: var(--color-secondary, #8b5cf6);
169
+ }
170
+
171
+ :host([color='neutral']) .pagination-btn.active {
172
+ background: var(--color-neutral, #6b7280);
173
+ border-color: var(--color-neutral, #6b7280);
174
+ color: var(--color-neutral-contrast, #ffffff);
175
+ }
176
+
177
+ :host([color='neutral']) .pagination-btn:focus-visible {
178
+ outline-color: var(--color-neutral, #6b7280);
179
+ }
180
+ `;
181
+ var ICONS = {
182
+ first: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor"><path fill-rule="evenodd" d="M15.79 14.77a.75.75 0 01-1.06.02l-4.5-4.25a.75.75 0 010-1.08l4.5-4.25a.75.75 0 111.04 1.08L11.832 10l3.938 3.71a.75.75 0 01.02 1.06zm-6 0a.75.75 0 01-1.06.02l-4.5-4.25a.75.75 0 010-1.08l4.5-4.25a.75.75 0 111.04 1.08L5.832 10l3.938 3.71a.75.75 0 01.02 1.06z" clip-rule="evenodd"/></svg>`,
183
+ prev: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor"><path fill-rule="evenodd" d="M12.79 5.23a.75.75 0 01-.02 1.06L8.832 10l3.938 3.71a.75.75 0 11-1.04 1.08l-4.5-4.25a.75.75 0 010-1.08l4.5-4.25a.75.75 0 011.06.02z" clip-rule="evenodd"/></svg>`,
184
+ next: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor"><path fill-rule="evenodd" d="M7.21 14.77a.75.75 0 01.02-1.06L11.168 10 7.23 6.29a.75.75 0 111.04-1.08l4.5 4.25a.75.75 0 010 1.08l-4.5 4.25a.75.75 0 01-1.06-.02z" clip-rule="evenodd"/></svg>`,
185
+ last: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor"><path fill-rule="evenodd" d="M4.21 5.23a.75.75 0 011.06-.02l4.5 4.25a.75.75 0 010 1.08l-4.5 4.25a.75.75 0 11-1.04-1.08L8.168 10 4.23 6.29a.75.75 0 01-.02-1.06zm6 0a.75.75 0 011.06-.02l4.5 4.25a.75.75 0 010 1.08l-4.5 4.25a.75.75 0 11-1.04-1.08L14.168 10l-3.938-3.71a.75.75 0 01-.02-1.06z" clip-rule="evenodd"/></svg>`
186
+ };
187
+
188
+ class ElDmPagination extends import_el_core.BaseElement {
189
+ static properties = {
190
+ total: { type: Number, reflect: true, default: 1 },
191
+ current: { type: Number, reflect: true, default: 1 },
192
+ siblings: { type: Number, reflect: true, default: 1 },
193
+ boundaries: { type: Number, reflect: true, default: 1 },
194
+ size: { type: String, reflect: true },
195
+ color: { type: String, reflect: true }
196
+ };
197
+ constructor() {
198
+ super();
199
+ this.attachStyles(styles);
200
+ }
201
+ connectedCallback() {
202
+ super.connectedCallback();
203
+ this.addEventListener("click", this._handleClick.bind(this));
204
+ this.addEventListener("keydown", this._handleKeydown.bind(this));
205
+ }
206
+ _getPageRange() {
207
+ const total = Math.max(1, this.total);
208
+ const current = Math.min(Math.max(1, this.current), total);
209
+ const siblings = Math.max(0, this.siblings);
210
+ const boundaries = Math.max(0, this.boundaries);
211
+ const totalPageNumbers = boundaries * 2 + siblings * 2 + 3;
212
+ if (total <= totalPageNumbers) {
213
+ return Array.from({ length: total }, (_, i) => i + 1);
214
+ }
215
+ const leftSiblingIndex = Math.max(current - siblings, boundaries + 1);
216
+ const rightSiblingIndex = Math.min(current + siblings, total - boundaries);
217
+ const showLeftEllipsis = leftSiblingIndex > boundaries + 2;
218
+ const showRightEllipsis = rightSiblingIndex < total - boundaries - 1;
219
+ const pages = [];
220
+ for (let i = 1;i <= boundaries; i++) {
221
+ pages.push(i);
222
+ }
223
+ if (showLeftEllipsis) {
224
+ pages.push("ellipsis");
225
+ } else if (boundaries + 1 < leftSiblingIndex) {
226
+ pages.push(boundaries + 1);
227
+ }
228
+ for (let i = leftSiblingIndex;i <= rightSiblingIndex; i++) {
229
+ if (i > boundaries && i <= total - boundaries) {
230
+ pages.push(i);
231
+ }
232
+ }
233
+ if (showRightEllipsis) {
234
+ pages.push("ellipsis");
235
+ } else if (rightSiblingIndex < total - boundaries) {
236
+ pages.push(total - boundaries);
237
+ }
238
+ for (let i = total - boundaries + 1;i <= total; i++) {
239
+ if (i > 0 && !pages.includes(i)) {
240
+ pages.push(i);
241
+ }
242
+ }
243
+ return pages;
244
+ }
245
+ _goToPage(page) {
246
+ const newPage = Math.min(Math.max(1, page), this.total);
247
+ if (newPage !== this.current) {
248
+ this.current = newPage;
249
+ this.emit("change", { page: newPage });
250
+ }
251
+ }
252
+ _handleClick(event) {
253
+ const target = event.target;
254
+ const button = target.closest("button");
255
+ if (!button || button.disabled)
256
+ return;
257
+ const action = button.dataset.action;
258
+ const page = button.dataset.page;
259
+ if (action === "first") {
260
+ this._goToPage(1);
261
+ } else if (action === "prev") {
262
+ this._goToPage(this.current - 1);
263
+ } else if (action === "next") {
264
+ this._goToPage(this.current + 1);
265
+ } else if (action === "last") {
266
+ this._goToPage(this.total);
267
+ } else if (page) {
268
+ this._goToPage(parseInt(page, 10));
269
+ }
270
+ }
271
+ _handleKeydown(event) {
272
+ switch (event.key) {
273
+ case "ArrowLeft":
274
+ event.preventDefault();
275
+ this._goToPage(this.current - 1);
276
+ break;
277
+ case "ArrowRight":
278
+ event.preventDefault();
279
+ this._goToPage(this.current + 1);
280
+ break;
281
+ case "Home":
282
+ event.preventDefault();
283
+ this._goToPage(1);
284
+ break;
285
+ case "End":
286
+ event.preventDefault();
287
+ this._goToPage(this.total);
288
+ break;
289
+ }
290
+ }
291
+ render() {
292
+ const total = Math.max(1, this.total);
293
+ const current = Math.min(Math.max(1, this.current), total);
294
+ const pages = this._getPageRange();
295
+ const isFirstPage = current === 1;
296
+ const isLastPage = current === total;
297
+ let pagesHtml = "";
298
+ let ellipsisCount = 0;
299
+ for (const page of pages) {
300
+ if (page === "ellipsis") {
301
+ ellipsisCount++;
302
+ pagesHtml += `
303
+ <span class="ellipsis" part="ellipsis" aria-hidden="true">...</span>
304
+ `;
305
+ } else {
306
+ const isActive = page === current;
307
+ pagesHtml += `
308
+ <button
309
+ class="pagination-btn${isActive ? " active" : ""}"
310
+ part="page"
311
+ data-page="${page}"
312
+ aria-label="Page ${page}"
313
+ aria-current="${isActive ? "page" : "false"}"
314
+ >${page}</button>
315
+ `;
316
+ }
317
+ }
318
+ return `
319
+ <nav class="pagination" part="container" role="navigation" aria-label="Pagination">
320
+ <button
321
+ class="pagination-btn nav-btn"
322
+ part="button"
323
+ data-action="first"
324
+ aria-label="Go to first page"
325
+ ${isFirstPage ? "disabled" : ""}
326
+ >${ICONS.first}</button>
327
+ <button
328
+ class="pagination-btn nav-btn"
329
+ part="button"
330
+ data-action="prev"
331
+ aria-label="Go to previous page"
332
+ ${isFirstPage ? "disabled" : ""}
333
+ >${ICONS.prev}</button>
334
+ ${pagesHtml}
335
+ <button
336
+ class="pagination-btn nav-btn"
337
+ part="button"
338
+ data-action="next"
339
+ aria-label="Go to next page"
340
+ ${isLastPage ? "disabled" : ""}
341
+ >${ICONS.next}</button>
342
+ <button
343
+ class="pagination-btn nav-btn"
344
+ part="button"
345
+ data-action="last"
346
+ aria-label="Go to last page"
347
+ ${isLastPage ? "disabled" : ""}
348
+ >${ICONS.last}</button>
349
+ </nav>
350
+ `;
351
+ }
352
+ }
353
+
354
+ // src/index.ts
355
+ function register() {
356
+ if (!customElements.get("el-dm-pagination")) {
357
+ customElements.define("el-dm-pagination", ElDmPagination);
358
+ }
359
+ }
360
+
361
+ //# debugId=780D3D2CA6D67FB664756E2164756E21
362
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1,11 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/el-dm-pagination.ts", "../../src/index.ts"],
4
+ "sourcesContent": [
5
+ "/**\n * DuskMoon Pagination Element\n *\n * A customizable pagination component for page navigation.\n * Supports first/last, previous/next buttons, and page number display with ellipsis.\n *\n * @element el-dm-pagination\n *\n * @attr {number} total - Total number of pages\n * @attr {number} current - Current active page (1-indexed)\n * @attr {number} siblings - Number of pages to show around current page\n * @attr {number} boundaries - Number of pages to show at start/end\n * @attr {string} size - Button size: xs, sm, md, lg\n * @attr {string} color - Color variant: primary, secondary, neutral\n *\n * @csspart container - The pagination container\n * @csspart button - Navigation buttons (first, prev, next, last)\n * @csspart page - Page number buttons\n * @csspart ellipsis - Ellipsis indicators\n *\n * @fires change - Fired when the current page changes, detail: { page: number }\n */\n\nimport { BaseElement, css } from '@duskmoon-dev/el-core';\n\nexport type PaginationSize = 'xs' | 'sm' | 'md' | 'lg';\nexport type PaginationColor = 'primary' | 'secondary' | 'neutral';\n\nconst styles = css`\n :host {\n display: inline-flex;\n vertical-align: middle;\n }\n\n :host([hidden]) {\n display: none !important;\n }\n\n .pagination {\n display: flex;\n align-items: center;\n gap: 0.25rem;\n font-family: inherit;\n }\n\n .pagination-btn {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n border: 1px solid var(--color-border, #d1d5db);\n background: var(--color-surface, #ffffff);\n color: var(--color-text, #374151);\n cursor: pointer;\n font-family: inherit;\n font-weight: 500;\n transition:\n background-color 0.15s ease,\n border-color 0.15s ease,\n color 0.15s ease;\n border-radius: var(--radius-md, 0.375rem);\n min-width: 2rem;\n height: 2rem;\n padding: 0 0.5rem;\n font-size: 0.875rem;\n line-height: 1;\n }\n\n .pagination-btn:hover:not(:disabled) {\n background: var(--color-surface-hover, #f3f4f6);\n border-color: var(--color-border-hover, #9ca3af);\n }\n\n .pagination-btn:focus-visible {\n outline: 2px solid var(--color-primary, #3b82f6);\n outline-offset: 2px;\n }\n\n .pagination-btn:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n }\n\n .pagination-btn.active {\n background: var(--color-primary, #3b82f6);\n border-color: var(--color-primary, #3b82f6);\n color: var(--color-primary-contrast, #ffffff);\n }\n\n .pagination-btn.nav-btn {\n padding: 0 0.375rem;\n }\n\n .pagination-btn.nav-btn svg {\n width: 1em;\n height: 1em;\n }\n\n .ellipsis {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n min-width: 2rem;\n height: 2rem;\n color: var(--color-text-muted, #6b7280);\n font-size: 0.875rem;\n user-select: none;\n }\n\n /* Size variants */\n :host([size='xs']) .pagination-btn {\n min-width: 1.5rem;\n height: 1.5rem;\n padding: 0 0.25rem;\n font-size: 0.75rem;\n border-radius: var(--radius-sm, 0.25rem);\n }\n\n :host([size='xs']) .ellipsis {\n min-width: 1.5rem;\n height: 1.5rem;\n font-size: 0.75rem;\n }\n\n :host([size='sm']) .pagination-btn {\n min-width: 1.75rem;\n height: 1.75rem;\n padding: 0 0.375rem;\n font-size: 0.8125rem;\n }\n\n :host([size='sm']) .ellipsis {\n min-width: 1.75rem;\n height: 1.75rem;\n font-size: 0.8125rem;\n }\n\n :host([size='lg']) .pagination-btn {\n min-width: 2.5rem;\n height: 2.5rem;\n padding: 0 0.75rem;\n font-size: 1rem;\n }\n\n :host([size='lg']) .ellipsis {\n min-width: 2.5rem;\n height: 2.5rem;\n font-size: 1rem;\n }\n\n /* Color variants */\n :host([color='secondary']) .pagination-btn.active {\n background: var(--color-secondary, #8b5cf6);\n border-color: var(--color-secondary, #8b5cf6);\n color: var(--color-secondary-contrast, #ffffff);\n }\n\n :host([color='secondary']) .pagination-btn:focus-visible {\n outline-color: var(--color-secondary, #8b5cf6);\n }\n\n :host([color='neutral']) .pagination-btn.active {\n background: var(--color-neutral, #6b7280);\n border-color: var(--color-neutral, #6b7280);\n color: var(--color-neutral-contrast, #ffffff);\n }\n\n :host([color='neutral']) .pagination-btn:focus-visible {\n outline-color: var(--color-neutral, #6b7280);\n }\n`;\n\n// SVG icons for navigation buttons\nconst ICONS = {\n first: `<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 20 20\" fill=\"currentColor\"><path fill-rule=\"evenodd\" d=\"M15.79 14.77a.75.75 0 01-1.06.02l-4.5-4.25a.75.75 0 010-1.08l4.5-4.25a.75.75 0 111.04 1.08L11.832 10l3.938 3.71a.75.75 0 01.02 1.06zm-6 0a.75.75 0 01-1.06.02l-4.5-4.25a.75.75 0 010-1.08l4.5-4.25a.75.75 0 111.04 1.08L5.832 10l3.938 3.71a.75.75 0 01.02 1.06z\" clip-rule=\"evenodd\"/></svg>`,\n prev: `<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 20 20\" fill=\"currentColor\"><path fill-rule=\"evenodd\" d=\"M12.79 5.23a.75.75 0 01-.02 1.06L8.832 10l3.938 3.71a.75.75 0 11-1.04 1.08l-4.5-4.25a.75.75 0 010-1.08l4.5-4.25a.75.75 0 011.06.02z\" clip-rule=\"evenodd\"/></svg>`,\n next: `<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 20 20\" fill=\"currentColor\"><path fill-rule=\"evenodd\" d=\"M7.21 14.77a.75.75 0 01.02-1.06L11.168 10 7.23 6.29a.75.75 0 111.04-1.08l4.5 4.25a.75.75 0 010 1.08l-4.5 4.25a.75.75 0 01-1.06-.02z\" clip-rule=\"evenodd\"/></svg>`,\n last: `<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 20 20\" fill=\"currentColor\"><path fill-rule=\"evenodd\" d=\"M4.21 5.23a.75.75 0 011.06-.02l4.5 4.25a.75.75 0 010 1.08l-4.5 4.25a.75.75 0 11-1.04-1.08L8.168 10 4.23 6.29a.75.75 0 01-.02-1.06zm6 0a.75.75 0 011.06-.02l4.5 4.25a.75.75 0 010 1.08l-4.5 4.25a.75.75 0 11-1.04-1.08L14.168 10l-3.938-3.71a.75.75 0 01-.02-1.06z\" clip-rule=\"evenodd\"/></svg>`,\n};\n\nexport class ElDmPagination extends BaseElement {\n static properties = {\n total: { type: Number, reflect: true, default: 1 },\n current: { type: Number, reflect: true, default: 1 },\n siblings: { type: Number, reflect: true, default: 1 },\n boundaries: { type: Number, reflect: true, default: 1 },\n size: { type: String, reflect: true },\n color: { type: String, reflect: true },\n };\n\n /** Total number of pages */\n declare total: number;\n\n /** Current active page (1-indexed) */\n declare current: number;\n\n /** Number of pages shown around the current page */\n declare siblings: number;\n\n /** Number of pages shown at the start and end */\n declare boundaries: number;\n\n /** Button size: xs, sm, md, lg */\n declare size: PaginationSize;\n\n /** Color variant: primary, secondary, neutral */\n declare color: PaginationColor;\n\n constructor() {\n super();\n this.attachStyles(styles);\n }\n\n connectedCallback(): void {\n super.connectedCallback();\n this.addEventListener('click', this._handleClick.bind(this));\n this.addEventListener('keydown', this._handleKeydown.bind(this));\n }\n\n /**\n * Calculate the range of page numbers to display\n */\n private _getPageRange(): (number | 'ellipsis')[] {\n const total = Math.max(1, this.total);\n const current = Math.min(Math.max(1, this.current), total);\n const siblings = Math.max(0, this.siblings);\n const boundaries = Math.max(0, this.boundaries);\n\n // If total pages fit without ellipsis\n const totalPageNumbers = boundaries * 2 + siblings * 2 + 3; // boundaries + siblings + current + 2 ellipsis spots\n if (total <= totalPageNumbers) {\n return Array.from({ length: total }, (_, i) => i + 1);\n }\n\n const leftSiblingIndex = Math.max(current - siblings, boundaries + 1);\n const rightSiblingIndex = Math.min(current + siblings, total - boundaries);\n\n const showLeftEllipsis = leftSiblingIndex > boundaries + 2;\n const showRightEllipsis = rightSiblingIndex < total - boundaries - 1;\n\n const pages: (number | 'ellipsis')[] = [];\n\n // Add left boundary pages\n for (let i = 1; i <= boundaries; i++) {\n pages.push(i);\n }\n\n // Add left ellipsis or connecting page\n if (showLeftEllipsis) {\n pages.push('ellipsis');\n } else if (boundaries + 1 < leftSiblingIndex) {\n pages.push(boundaries + 1);\n }\n\n // Add sibling pages and current page\n for (let i = leftSiblingIndex; i <= rightSiblingIndex; i++) {\n if (i > boundaries && i <= total - boundaries) {\n pages.push(i);\n }\n }\n\n // Add right ellipsis or connecting page\n if (showRightEllipsis) {\n pages.push('ellipsis');\n } else if (rightSiblingIndex < total - boundaries) {\n pages.push(total - boundaries);\n }\n\n // Add right boundary pages\n for (let i = total - boundaries + 1; i <= total; i++) {\n if (i > 0 && !pages.includes(i)) {\n pages.push(i);\n }\n }\n\n return pages;\n }\n\n /**\n * Navigate to a specific page\n */\n private _goToPage(page: number): void {\n const newPage = Math.min(Math.max(1, page), this.total);\n if (newPage !== this.current) {\n this.current = newPage;\n this.emit('change', { page: newPage });\n }\n }\n\n /**\n * Handle click events on pagination buttons\n */\n private _handleClick(event: Event): void {\n const target = event.target as HTMLElement;\n const button = target.closest('button');\n\n if (!button || button.disabled) return;\n\n const action = button.dataset.action;\n const page = button.dataset.page;\n\n if (action === 'first') {\n this._goToPage(1);\n } else if (action === 'prev') {\n this._goToPage(this.current - 1);\n } else if (action === 'next') {\n this._goToPage(this.current + 1);\n } else if (action === 'last') {\n this._goToPage(this.total);\n } else if (page) {\n this._goToPage(parseInt(page, 10));\n }\n }\n\n /**\n * Handle keyboard navigation\n */\n private _handleKeydown(event: KeyboardEvent): void {\n switch (event.key) {\n case 'ArrowLeft':\n event.preventDefault();\n this._goToPage(this.current - 1);\n break;\n case 'ArrowRight':\n event.preventDefault();\n this._goToPage(this.current + 1);\n break;\n case 'Home':\n event.preventDefault();\n this._goToPage(1);\n break;\n case 'End':\n event.preventDefault();\n this._goToPage(this.total);\n break;\n }\n }\n\n render(): string {\n const total = Math.max(1, this.total);\n const current = Math.min(Math.max(1, this.current), total);\n const pages = this._getPageRange();\n\n const isFirstPage = current === 1;\n const isLastPage = current === total;\n\n let pagesHtml = '';\n let ellipsisCount = 0;\n\n for (const page of pages) {\n if (page === 'ellipsis') {\n ellipsisCount++;\n pagesHtml += `\n <span class=\"ellipsis\" part=\"ellipsis\" aria-hidden=\"true\">...</span>\n `;\n } else {\n const isActive = page === current;\n pagesHtml += `\n <button\n class=\"pagination-btn${isActive ? ' active' : ''}\"\n part=\"page\"\n data-page=\"${page}\"\n aria-label=\"Page ${page}\"\n aria-current=\"${isActive ? 'page' : 'false'}\"\n >${page}</button>\n `;\n }\n }\n\n return `\n <nav class=\"pagination\" part=\"container\" role=\"navigation\" aria-label=\"Pagination\">\n <button\n class=\"pagination-btn nav-btn\"\n part=\"button\"\n data-action=\"first\"\n aria-label=\"Go to first page\"\n ${isFirstPage ? 'disabled' : ''}\n >${ICONS.first}</button>\n <button\n class=\"pagination-btn nav-btn\"\n part=\"button\"\n data-action=\"prev\"\n aria-label=\"Go to previous page\"\n ${isFirstPage ? 'disabled' : ''}\n >${ICONS.prev}</button>\n ${pagesHtml}\n <button\n class=\"pagination-btn nav-btn\"\n part=\"button\"\n data-action=\"next\"\n aria-label=\"Go to next page\"\n ${isLastPage ? 'disabled' : ''}\n >${ICONS.next}</button>\n <button\n class=\"pagination-btn nav-btn\"\n part=\"button\"\n data-action=\"last\"\n aria-label=\"Go to last page\"\n ${isLastPage ? 'disabled' : ''}\n >${ICONS.last}</button>\n </nav>\n `;\n }\n}\n",
6
+ "/**\n * @duskmoon-dev/el-pagination\n *\n * DuskMoon Pagination custom element\n */\n\nimport { ElDmPagination } from './el-dm-pagination.js';\n\nexport { ElDmPagination };\n\n/**\n * Register the el-dm-pagination custom element\n *\n * @example\n * ```ts\n * import { register } from '@duskmoon-dev/el-pagination';\n * register();\n * ```\n */\nexport function register(): void {\n if (!customElements.get('el-dm-pagination')) {\n customElements.define('el-dm-pagination', ElDmPagination);\n }\n}\n"
7
+ ],
8
+ "mappings": "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",
9
+ "debugId": "780D3D2CA6D67FB664756E2164756E21",
10
+ "names": []
11
+ }