@schukai/monster 4.39.0 → 4.40.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/CHANGELOG.md +21 -0
- package/package.json +1 -1
- package/source/components/accessibility/locale-select.mjs +1 -1
- package/source/components/datatable/pagination.mjs +515 -496
- package/source/components/form/select.mjs +270 -128
- package/source/components/form/style/select.pcss +11 -1
- package/source/components/form/stylesheet/select.mjs +7 -14
@@ -13,9 +13,9 @@
|
|
13
13
|
*/
|
14
14
|
|
15
15
|
import {
|
16
|
-
|
17
|
-
|
18
|
-
|
16
|
+
assembleMethodSymbol,
|
17
|
+
CustomElement,
|
18
|
+
registerCustomElement,
|
19
19
|
} from "../../dom/customelement.mjs";
|
20
20
|
import { findElementWithSelectorUpwards, getWindow } from "../../dom/util.mjs";
|
21
21
|
import { DeadMansSwitch } from "../../util/deadmansswitch.mjs";
|
@@ -82,288 +82,335 @@ const debounceSizeSymbol = Symbol("debounceSize");
|
|
82
82
|
* @summary The Pagination component is used to show the current page and the total number of pages.
|
83
83
|
*/
|
84
84
|
class Pagination extends CustomElement {
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
|
85
|
+
/**
|
86
|
+
*/
|
87
|
+
constructor() {
|
88
|
+
super();
|
89
|
+
this[datasourceLinkedElementSymbol] = null;
|
90
|
+
}
|
91
|
+
|
92
|
+
/**
|
93
|
+
* This method is called by the `instanceof` operator.
|
94
|
+
* @return {symbol}
|
95
|
+
*/
|
96
|
+
static get [instanceSymbol]() {
|
97
|
+
return Symbol.for("@schukai/monster/components/pagination");
|
98
|
+
}
|
99
|
+
|
100
|
+
/**
|
101
|
+
* To set the options via the HTML tag, the attribute `data-monster-options` must be used.
|
102
|
+
* @see {@link https://monsterjs.org/en/doc/#configurate-a-monster-control}
|
103
|
+
*
|
104
|
+
* The individual configuration values can be found in the table.
|
105
|
+
*
|
106
|
+
* @property {Object} templates Template definitions
|
107
|
+
* @property {string} templates.main Main template
|
108
|
+
* @property {Object} datasource Datasource configuration
|
109
|
+
* @property {string} datasource.selector Datasource selector
|
110
|
+
* @property {Object} labels Label definitions
|
111
|
+
* @property {string} labels.page Page label
|
112
|
+
* @property {string} labels.description Description label
|
113
|
+
* @property {string} labels.previous Previous label
|
114
|
+
* @property {string} labels.next Next label
|
115
|
+
* @property {string} labels.of Of label
|
116
|
+
* @property {string} href Href
|
117
|
+
* @property {number} currentPage Current page
|
118
|
+
* @property {number} pages Pages
|
119
|
+
* @property {number} objectsPerPage Objects per page
|
120
|
+
* @property {Object} mapping Mapping
|
121
|
+
* @property {string} mapping.pages Pages mapping
|
122
|
+
* @property {string} mapping.objectsPerPage Objects per page mapping
|
123
|
+
* @property {string} mapping.currentPage Current page mapping
|
124
|
+
*/
|
125
|
+
get defaults() {
|
126
|
+
return Object.assign(
|
127
|
+
{},
|
128
|
+
super.defaults,
|
129
|
+
{
|
130
|
+
templates: {
|
131
|
+
main: getTemplate(),
|
132
|
+
},
|
133
|
+
|
134
|
+
datasource: {
|
135
|
+
selector: null,
|
136
|
+
},
|
137
|
+
|
138
|
+
labels: getTranslations(),
|
139
|
+
|
140
|
+
callbacks: {
|
141
|
+
click: null,
|
142
|
+
},
|
143
|
+
|
144
|
+
href: "page-${page}",
|
145
|
+
|
146
|
+
pages: null,
|
147
|
+
objectsPerPage: 20,
|
148
|
+
currentPage: null,
|
149
|
+
|
150
|
+
mapping: {
|
151
|
+
pages: "sys.pagination.pages",
|
152
|
+
objectsPerPage: "sys.pagination.objectsPerPage",
|
153
|
+
currentPage: "sys.pagination.currentPage",
|
154
|
+
},
|
155
|
+
|
156
|
+
/* @private */
|
157
|
+
pagination: {
|
158
|
+
items: [],
|
159
|
+
},
|
160
|
+
},
|
161
|
+
initOptionsFromArguments.call(this),
|
162
|
+
);
|
163
|
+
}
|
164
|
+
/**
|
165
|
+
* Sets the pagination state directly, without requiring a datasource.
|
166
|
+
* This is useful for controlling the component programmatically.
|
167
|
+
*
|
168
|
+
* @param {object} state - The state object for the pagination.
|
169
|
+
* @param {number} state.currentPage - The current active page number.
|
170
|
+
* @param {number} state.totalPages - The total number of available pages.
|
171
|
+
* @return {void}
|
172
|
+
*/
|
173
|
+
setPaginationState({ currentPage, totalPages }) {
|
174
|
+
if (typeof currentPage !== "number" || typeof totalPages !== "number") {
|
175
|
+
console.error(
|
176
|
+
"setPaginationState requires currentPage and totalPages to be numbers.",
|
177
|
+
);
|
178
|
+
return;
|
179
|
+
}
|
180
|
+
|
181
|
+
// 1. Update the component's internal options with the new values.
|
182
|
+
this.setOption("currentPage", currentPage);
|
183
|
+
this.setOption("pages", totalPages);
|
184
|
+
|
185
|
+
// 2. Call the existing buildPagination function to recalculate the links.
|
186
|
+
const pagination = buildPagination.call(
|
187
|
+
this,
|
188
|
+
this.getOption("currentPage"),
|
189
|
+
this.getOption("pages"),
|
190
|
+
);
|
191
|
+
|
192
|
+
// 3. Preserve the responsive visibility of page numbers.
|
193
|
+
if (this?.[sizeDataSymbol]?.showNumbers !== true) {
|
194
|
+
pagination.items = [];
|
195
|
+
}
|
196
|
+
|
197
|
+
// 4. Set the 'pagination' option, which will trigger the component to re-render.
|
198
|
+
this.setOption("pagination", pagination);
|
199
|
+
}
|
200
|
+
/**
|
201
|
+
*
|
202
|
+
* @return {string}
|
203
|
+
*/
|
204
|
+
static getTag() {
|
205
|
+
return "monster-pagination";
|
206
|
+
}
|
207
|
+
|
208
|
+
/**
|
209
|
+
* @return {void}
|
210
|
+
*/
|
211
|
+
disconnectedCallback() {
|
212
|
+
super.disconnectedCallback();
|
213
|
+
if (this?.[resizeObserverSymbol] instanceof ResizeObserver) {
|
214
|
+
this[resizeObserverSymbol].disconnect();
|
215
|
+
}
|
216
|
+
if (this?.[debounceSizeSymbol] instanceof DeadMansSwitch) {
|
217
|
+
try {
|
218
|
+
this[debounceSizeSymbol].defuse();
|
219
|
+
delete this[debounceSizeSymbol];
|
220
|
+
} catch (e) {
|
221
|
+
// already fired
|
222
|
+
}
|
223
|
+
}
|
224
|
+
}
|
225
|
+
|
226
|
+
/**
|
227
|
+
* @return {void}
|
228
|
+
*/
|
229
|
+
connectedCallback() {
|
230
|
+
super.connectedCallback();
|
231
|
+
|
232
|
+
const parentNode = this.parentNode;
|
233
|
+
if (!parentNode) {
|
234
|
+
return;
|
235
|
+
}
|
236
|
+
|
237
|
+
try {
|
238
|
+
handleDataSourceChanges.call(this);
|
239
|
+
} catch (e) {
|
240
|
+
addAttributeToken(this, ATTRIBUTE_ERRORMESSAGE, e?.message || `${e}`);
|
241
|
+
}
|
242
|
+
|
243
|
+
requestAnimationFrame(() => {
|
244
|
+
const parentParentNode = parentNode?.parentNode || parentNode;
|
245
|
+
|
246
|
+
const parentWidth = parentParentNode.offsetWidth;
|
247
|
+
const ownWidth = this.offsetWidth;
|
248
|
+
|
249
|
+
this[sizeDataSymbol] = {
|
250
|
+
last: {
|
251
|
+
parentWidth: 0,
|
252
|
+
},
|
253
|
+
showNumbers: ownWidth < parentWidth,
|
254
|
+
};
|
255
|
+
|
256
|
+
this[resizeObserverSymbol] = new ResizeObserver(() => {
|
257
|
+
if (this[debounceSizeSymbol] instanceof DeadMansSwitch) {
|
258
|
+
try {
|
259
|
+
this[debounceSizeSymbol].touch();
|
260
|
+
return;
|
261
|
+
} catch (e) {
|
262
|
+
delete this[debounceSizeSymbol];
|
263
|
+
}
|
264
|
+
}
|
265
|
+
|
266
|
+
this[debounceSizeSymbol] = new DeadMansSwitch(250, () => {
|
267
|
+
queueMicrotask(() => {
|
268
|
+
const parentWidth = parentParentNode.offsetWidth;
|
269
|
+
const ownWidth = this.clientWidth;
|
270
|
+
|
271
|
+
if (this[sizeDataSymbol]?.last?.parentWidth === parentWidth) {
|
272
|
+
return;
|
273
|
+
}
|
274
|
+
|
275
|
+
this[sizeDataSymbol].last = {
|
276
|
+
parentWidth: parentWidth,
|
277
|
+
};
|
278
|
+
|
279
|
+
this[sizeDataSymbol].showNumbers = ownWidth <= parentWidth;
|
280
|
+
handleDataSourceChanges.call(this);
|
281
|
+
});
|
282
|
+
});
|
283
|
+
});
|
284
|
+
|
285
|
+
this[resizeObserverSymbol].observe(this?.parentNode?.parentNode);
|
286
|
+
});
|
287
|
+
}
|
288
|
+
|
289
|
+
/**
|
290
|
+
* @return {void}
|
291
|
+
*/
|
292
|
+
[assembleMethodSymbol]() {
|
293
|
+
super[assembleMethodSymbol]();
|
294
|
+
|
295
|
+
initControlReferences.call(this);
|
296
|
+
initEventHandler.call(this);
|
297
|
+
|
298
|
+
const selector = this.getOption("datasource.selector", "");
|
299
|
+
|
300
|
+
if (isString(selector)) {
|
301
|
+
const element = findElementWithSelectorUpwards(this, selector);
|
302
|
+
if (element === null) {
|
303
|
+
throw new Error("the selector must match exactly one element");
|
304
|
+
}
|
305
|
+
|
306
|
+
if (!(element instanceof Datasource)) {
|
307
|
+
throw new TypeError("the element must be a datasource");
|
308
|
+
}
|
309
|
+
|
310
|
+
this[datasourceLinkedElementSymbol] = element;
|
311
|
+
element.datasource.attachObserver(
|
312
|
+
new Observer(handleDataSourceChanges.bind(this)),
|
313
|
+
);
|
314
|
+
|
315
|
+
element.attachObserver(new Observer(handleDataSourceChanges.bind(this)));
|
316
|
+
|
317
|
+
handleDataSourceChanges.call(this);
|
318
|
+
}
|
319
|
+
}
|
320
|
+
|
321
|
+
/**
|
322
|
+
* @private
|
323
|
+
* @return {CSSStyleSheet}
|
324
|
+
*/
|
325
|
+
static getControlCSSStyleSheet() {
|
326
|
+
return PaginationStyleSheet;
|
327
|
+
}
|
328
|
+
|
329
|
+
/**
|
330
|
+
* @return {CSSStyleSheet[]}
|
331
|
+
*/
|
332
|
+
static getCSSStyleSheet() {
|
333
|
+
return [this.getControlCSSStyleSheet(), DisplayStyleSheet, ThemeStyleSheet];
|
334
|
+
}
|
288
335
|
}
|
289
336
|
|
290
337
|
function getTranslations() {
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
|
306
|
-
|
307
|
-
|
308
|
-
|
309
|
-
|
310
|
-
|
311
|
-
|
312
|
-
|
313
|
-
|
314
|
-
|
315
|
-
|
316
|
-
|
317
|
-
|
318
|
-
|
319
|
-
|
320
|
-
|
321
|
-
|
322
|
-
|
323
|
-
|
324
|
-
|
325
|
-
|
326
|
-
|
327
|
-
|
328
|
-
|
329
|
-
|
330
|
-
|
331
|
-
|
332
|
-
|
333
|
-
|
334
|
-
|
335
|
-
|
336
|
-
|
337
|
-
|
338
|
-
|
339
|
-
|
340
|
-
|
341
|
-
|
342
|
-
|
343
|
-
|
344
|
-
|
345
|
-
|
346
|
-
|
347
|
-
|
348
|
-
|
349
|
-
|
350
|
-
|
351
|
-
|
352
|
-
|
353
|
-
|
354
|
-
|
355
|
-
|
356
|
-
|
357
|
-
|
358
|
-
|
359
|
-
|
360
|
-
|
361
|
-
|
362
|
-
|
363
|
-
|
364
|
-
|
365
|
-
|
366
|
-
|
338
|
+
const locale = getLocaleOfDocument();
|
339
|
+
switch (locale.language) {
|
340
|
+
case "de":
|
341
|
+
return {
|
342
|
+
page: "${page}",
|
343
|
+
description: "Seite ${page}",
|
344
|
+
previous: "Vorherige",
|
345
|
+
next: "Nächste",
|
346
|
+
of: "von",
|
347
|
+
};
|
348
|
+
case "fr":
|
349
|
+
return {
|
350
|
+
page: "${page}",
|
351
|
+
description: "Page ${page}",
|
352
|
+
previous: "Précédent",
|
353
|
+
next: "Suivant",
|
354
|
+
of: "de",
|
355
|
+
};
|
356
|
+
case "sp":
|
357
|
+
return {
|
358
|
+
page: "${page}",
|
359
|
+
description: "Página ${page}",
|
360
|
+
previous: "Anterior",
|
361
|
+
next: "Siguiente",
|
362
|
+
of: "de",
|
363
|
+
};
|
364
|
+
case "it":
|
365
|
+
return {
|
366
|
+
page: "${page}",
|
367
|
+
description: "Pagina ${page}",
|
368
|
+
previous: "Precedente",
|
369
|
+
next: "Successivo",
|
370
|
+
of: "di",
|
371
|
+
};
|
372
|
+
case "pl":
|
373
|
+
return {
|
374
|
+
page: "${page}",
|
375
|
+
description: "Strona ${page}",
|
376
|
+
previous: "Poprzednia",
|
377
|
+
next: "Następna",
|
378
|
+
of: "z",
|
379
|
+
};
|
380
|
+
case "no":
|
381
|
+
return {
|
382
|
+
page: "${page}",
|
383
|
+
description: "Side ${page}",
|
384
|
+
previous: "Forrige",
|
385
|
+
next: "Neste",
|
386
|
+
of: "av",
|
387
|
+
};
|
388
|
+
case "dk":
|
389
|
+
return {
|
390
|
+
page: "${page}",
|
391
|
+
description: "Side ${page}",
|
392
|
+
previous: "Forrige",
|
393
|
+
next: "Næste",
|
394
|
+
of: "af",
|
395
|
+
};
|
396
|
+
case "sw":
|
397
|
+
return {
|
398
|
+
page: "${page}",
|
399
|
+
description: "Sida ${page}",
|
400
|
+
previous: "Föregående",
|
401
|
+
next: "Nästa",
|
402
|
+
of: "av",
|
403
|
+
};
|
404
|
+
default:
|
405
|
+
case "en":
|
406
|
+
return {
|
407
|
+
page: "${page}",
|
408
|
+
description: "Page ${page}",
|
409
|
+
previous: "Previous",
|
410
|
+
next: "Next",
|
411
|
+
of: "of",
|
412
|
+
};
|
413
|
+
}
|
367
414
|
}
|
368
415
|
|
369
416
|
/**
|
@@ -372,89 +419,57 @@ function getTranslations() {
|
|
372
419
|
* @throws {Error} no shadow-root is defined
|
373
420
|
*/
|
374
421
|
function initControlReferences() {
|
375
|
-
|
376
|
-
|
377
|
-
|
422
|
+
if (!this.shadowRoot) {
|
423
|
+
throw new Error("no shadow-root is defined");
|
424
|
+
}
|
378
425
|
|
379
|
-
|
380
|
-
|
381
|
-
|
426
|
+
this[paginationElementSymbol] = this.shadowRoot.querySelector(
|
427
|
+
"[data-monster-role=pagination]",
|
428
|
+
);
|
382
429
|
}
|
383
430
|
|
431
|
+
/**
|
432
|
+
* @private
|
433
|
+
*/
|
384
434
|
/**
|
385
435
|
* @private
|
386
436
|
*/
|
387
437
|
function initEventHandler() {
|
388
|
-
|
389
|
-
|
390
|
-
|
391
|
-
|
392
|
-
|
393
|
-
|
394
|
-
|
395
|
-
|
396
|
-
|
397
|
-
|
398
|
-
|
399
|
-
|
400
|
-
|
401
|
-
|
402
|
-
|
403
|
-
|
404
|
-
|
405
|
-
|
406
|
-
|
407
|
-
|
408
|
-
|
409
|
-
|
410
|
-
|
411
|
-
|
412
|
-
|
413
|
-
|
414
|
-
|
415
|
-
|
416
|
-
|
417
|
-
|
418
|
-
|
419
|
-
|
420
|
-
|
421
|
-
|
422
|
-
|
423
|
-
}
|
424
|
-
|
425
|
-
let page = null;
|
426
|
-
|
427
|
-
if (!element.hasAttribute("data-page-no")) {
|
428
|
-
return;
|
429
|
-
}
|
430
|
-
|
431
|
-
page = element.getAttribute("data-page-no");
|
432
|
-
|
433
|
-
if (
|
434
|
-
!page ||
|
435
|
-
page === "" ||
|
436
|
-
page === "…" ||
|
437
|
-
page === null ||
|
438
|
-
page === undefined ||
|
439
|
-
page === "undefined" ||
|
440
|
-
page === "null"
|
441
|
-
) {
|
442
|
-
return;
|
443
|
-
}
|
444
|
-
|
445
|
-
if (typeof datasource.setParameters !== "function") {
|
446
|
-
return;
|
447
|
-
}
|
448
|
-
|
449
|
-
event.preventDefault();
|
450
|
-
datasource.setParameters({ page });
|
451
|
-
|
452
|
-
if (typeof datasource.reload !== "function") {
|
453
|
-
return;
|
454
|
-
}
|
455
|
-
|
456
|
-
datasource.reload();
|
457
|
-
});
|
438
|
+
const self = this;
|
439
|
+
|
440
|
+
self[paginationElementSymbol].addEventListener("click", function (event) {
|
441
|
+
let element =
|
442
|
+
findTargetElementFromEvent(event, ATTRIBUTE_ROLE, "pagination-item") ||
|
443
|
+
findTargetElementFromEvent(event, ATTRIBUTE_ROLE, "pagination-next") ||
|
444
|
+
findTargetElementFromEvent(event, ATTRIBUTE_ROLE, "pagination-prev");
|
445
|
+
|
446
|
+
if (
|
447
|
+
!(element instanceof HTMLElement) ||
|
448
|
+
!element.hasAttribute("data-page-no")
|
449
|
+
) {
|
450
|
+
return;
|
451
|
+
}
|
452
|
+
|
453
|
+
const page = element.getAttribute("data-page-no");
|
454
|
+
|
455
|
+
if (!page || page === "…" || page === "null" || page === "undefined") {
|
456
|
+
return;
|
457
|
+
}
|
458
|
+
|
459
|
+
event.preventDefault();
|
460
|
+
|
461
|
+
const datasource = self[datasourceLinkedElementSymbol];
|
462
|
+
const clickCallback = self.getOption("callbacks.click");
|
463
|
+
|
464
|
+
if (datasource && typeof datasource.setParameters === "function") {
|
465
|
+
datasource.setParameters({ page });
|
466
|
+
if (typeof datasource.reload === "function") {
|
467
|
+
datasource.reload();
|
468
|
+
}
|
469
|
+
} else if (typeof clickCallback === "function") {
|
470
|
+
clickCallback(parseInt(page, 10), event);
|
471
|
+
}
|
472
|
+
});
|
458
473
|
}
|
459
474
|
|
460
475
|
/**
|
@@ -470,52 +485,52 @@ function initEventHandler() {
|
|
470
485
|
* @throws {Error} the datasource could not be initialized
|
471
486
|
*/
|
472
487
|
function initOptionsFromArguments() {
|
473
|
-
|
474
|
-
|
475
|
-
|
476
|
-
|
477
|
-
|
488
|
+
const options = {};
|
489
|
+
const selector = this.getAttribute(ATTRIBUTE_DATASOURCE_SELECTOR);
|
490
|
+
if (selector) {
|
491
|
+
options.datasource = { selector: selector };
|
492
|
+
}
|
478
493
|
|
479
|
-
|
494
|
+
return options;
|
480
495
|
}
|
481
496
|
|
482
497
|
/**
|
483
498
|
* @private
|
484
499
|
*/
|
485
500
|
function handleDataSourceChanges() {
|
486
|
-
|
487
|
-
|
488
|
-
|
489
|
-
|
490
|
-
|
491
|
-
|
492
|
-
|
493
|
-
|
494
|
-
|
495
|
-
|
496
|
-
|
497
|
-
|
498
|
-
|
499
|
-
|
500
|
-
|
501
|
-
|
502
|
-
|
503
|
-
|
504
|
-
|
505
|
-
|
506
|
-
|
507
|
-
|
508
|
-
|
509
|
-
|
510
|
-
|
511
|
-
|
512
|
-
|
513
|
-
|
514
|
-
|
515
|
-
|
516
|
-
|
517
|
-
|
518
|
-
|
501
|
+
let pagination;
|
502
|
+
|
503
|
+
if (!this[datasourceLinkedElementSymbol]) {
|
504
|
+
return;
|
505
|
+
}
|
506
|
+
|
507
|
+
const mapping = this.getOption("mapping");
|
508
|
+
const pf = new Pathfinder(this[datasourceLinkedElementSymbol].data);
|
509
|
+
|
510
|
+
for (const key in mapping) {
|
511
|
+
const path = mapping[key];
|
512
|
+
|
513
|
+
if (pf.exists(path)) {
|
514
|
+
const value = pf.getVia(path);
|
515
|
+
this.setOption(key, value);
|
516
|
+
}
|
517
|
+
|
518
|
+
const o = this[datasourceLinkedElementSymbol].getOption(path);
|
519
|
+
if (o !== undefined && o !== null) {
|
520
|
+
this.setOption(key, o);
|
521
|
+
}
|
522
|
+
}
|
523
|
+
|
524
|
+
pagination = buildPagination.call(
|
525
|
+
this,
|
526
|
+
this.getOption("currentPage"),
|
527
|
+
this.getOption("pages"),
|
528
|
+
);
|
529
|
+
if (this?.[sizeDataSymbol]?.showNumbers !== true) {
|
530
|
+
pagination.items = [];
|
531
|
+
}
|
532
|
+
|
533
|
+
this.setOption("pagination", pagination);
|
519
534
|
}
|
520
535
|
|
521
536
|
/**
|
@@ -525,97 +540,97 @@ function handleDataSourceChanges() {
|
|
525
540
|
* @return {object}
|
526
541
|
*/
|
527
542
|
function buildPagination(current, max) {
|
528
|
-
|
529
|
-
|
530
|
-
|
531
|
-
|
532
|
-
|
533
|
-
|
534
|
-
|
535
|
-
|
536
|
-
|
537
|
-
|
538
|
-
|
539
|
-
|
540
|
-
|
541
|
-
|
542
|
-
|
543
|
-
|
544
|
-
|
545
|
-
|
546
|
-
|
547
|
-
|
548
|
-
|
549
|
-
|
550
|
-
|
551
|
-
|
552
|
-
|
553
|
-
|
554
|
-
|
555
|
-
|
556
|
-
|
557
|
-
|
558
|
-
|
559
|
-
|
560
|
-
|
561
|
-
|
562
|
-
|
563
|
-
|
564
|
-
|
565
|
-
|
566
|
-
|
567
|
-
|
568
|
-
|
569
|
-
|
570
|
-
|
571
|
-
|
572
|
-
|
573
|
-
|
574
|
-
|
575
|
-
|
576
|
-
|
577
|
-
|
578
|
-
|
579
|
-
|
580
|
-
|
581
|
-
|
582
|
-
|
583
|
-
|
584
|
-
|
585
|
-
|
586
|
-
|
587
|
-
|
588
|
-
|
589
|
-
|
590
|
-
|
591
|
-
|
592
|
-
|
593
|
-
|
594
|
-
|
595
|
-
|
596
|
-
|
597
|
-
|
598
|
-
|
599
|
-
|
600
|
-
|
601
|
-
|
602
|
-
|
603
|
-
|
604
|
-
|
605
|
-
|
606
|
-
|
607
|
-
|
608
|
-
|
609
|
-
|
610
|
-
|
611
|
-
|
612
|
-
|
613
|
-
|
614
|
-
|
615
|
-
|
616
|
-
|
617
|
-
|
618
|
-
|
543
|
+
current = parseInt(current, 10);
|
544
|
+
max = parseInt(max, 10);
|
545
|
+
|
546
|
+
let prev = current === 1 ? null : current - 1;
|
547
|
+
let next = current === max ? null : current + 1;
|
548
|
+
const itemList = [1];
|
549
|
+
|
550
|
+
if (current > 4) itemList.push(-1);
|
551
|
+
|
552
|
+
const r = 2;
|
553
|
+
const r1 = current - r;
|
554
|
+
const r2 = current + r;
|
555
|
+
|
556
|
+
for (let i = r1 > 2 ? r1 : 2; i <= Math.min(max, r2); i++) itemList.push(i);
|
557
|
+
|
558
|
+
if (r2 + 1 < max) itemList.push(-1);
|
559
|
+
if (r2 < max) itemList.push(max);
|
560
|
+
|
561
|
+
let prevClass = "";
|
562
|
+
|
563
|
+
if (prev === null) {
|
564
|
+
prevClass = " disabled";
|
565
|
+
}
|
566
|
+
|
567
|
+
let nextClass = "";
|
568
|
+
if (next === null) {
|
569
|
+
nextClass = " disabled";
|
570
|
+
}
|
571
|
+
|
572
|
+
const items = itemList.map((item) => {
|
573
|
+
let p = `${item}`;
|
574
|
+
|
575
|
+
if (item === -1) {
|
576
|
+
item = null;
|
577
|
+
p = "…";
|
578
|
+
}
|
579
|
+
|
580
|
+
const c = `${current}`;
|
581
|
+
|
582
|
+
const obj = {
|
583
|
+
pageNo: item, // as integer
|
584
|
+
page: p, // as string
|
585
|
+
current: p === c,
|
586
|
+
class: (p === c ? "current" : "").trim(),
|
587
|
+
};
|
588
|
+
|
589
|
+
if (item === null) {
|
590
|
+
obj.class += " disabled".trim();
|
591
|
+
}
|
592
|
+
|
593
|
+
const formatter = new Formatter(obj);
|
594
|
+
|
595
|
+
obj.description = formatter.format(this.getOption("labels.description"));
|
596
|
+
obj.label = formatter.format(this.getOption("labels.page"));
|
597
|
+
obj.href =
|
598
|
+
item === null
|
599
|
+
? "#"
|
600
|
+
: p === c
|
601
|
+
? "#"
|
602
|
+
: p === "1"
|
603
|
+
? "#"
|
604
|
+
: `#${formatter.format(this.getOption("href"))}`;
|
605
|
+
return obj;
|
606
|
+
});
|
607
|
+
|
608
|
+
const nextNo = next;
|
609
|
+
next = `${next}`;
|
610
|
+
|
611
|
+
const nextHref =
|
612
|
+
next === "null"
|
613
|
+
? "#"
|
614
|
+
: `#${new Formatter({ page: next }).format(this.getOption("href"))}`;
|
615
|
+
const prevNo = prev;
|
616
|
+
prev = `${prev}`;
|
617
|
+
const prevHref =
|
618
|
+
prev === "null"
|
619
|
+
? "#"
|
620
|
+
: `#${new Formatter({ page: prev }).format(this.getOption("href"))}`;
|
621
|
+
|
622
|
+
return {
|
623
|
+
current,
|
624
|
+
nextNo,
|
625
|
+
next,
|
626
|
+
nextClass,
|
627
|
+
nextHref,
|
628
|
+
prevNo,
|
629
|
+
prev,
|
630
|
+
prevClass,
|
631
|
+
prevHref,
|
632
|
+
items,
|
633
|
+
};
|
619
634
|
}
|
620
635
|
|
621
636
|
/**
|
@@ -623,10 +638,12 @@ function buildPagination(current, max) {
|
|
623
638
|
* @return {string}
|
624
639
|
*/
|
625
640
|
function getTemplate() {
|
626
|
-
|
627
|
-
|
641
|
+
// language=HTML
|
642
|
+
return `
|
643
|
+
|
628
644
|
<template id="items">
|
629
|
-
<li><a
|
645
|
+
<li part="item"><a part="link"
|
646
|
+
data-monster-attributes="class path:items.class,
|
630
647
|
href path:items.href,
|
631
648
|
aria-label path:items.description,
|
632
649
|
disabled path:items.disabled:?disabled:undefined,
|
@@ -636,19 +653,21 @@ function getTemplate() {
|
|
636
653
|
data-monster-replace="path:items.label"></a></li>
|
637
654
|
</template>
|
638
655
|
|
639
|
-
<div data-monster-role="control">
|
640
|
-
<nav data-monster-role="pagination" role="navigation" aria-label="pagination">
|
656
|
+
<div data-monster-role="control" part="control">
|
657
|
+
<nav data-monster-role="pagination" role="navigation" aria-label="pagination" part="nav">
|
641
658
|
<ul class="pagination-list" data-monster-insert="items path:pagination.items"
|
642
|
-
data-monster-select-this="true">
|
643
|
-
<li part="
|
659
|
+
data-monster-select-this="true" part="list">
|
660
|
+
<li part="prev" data-monster-role="pagination-prev"><a
|
644
661
|
data-monster-role="pagination-prev"
|
662
|
+
part="prev-link"
|
645
663
|
data-monster-attributes="
|
646
664
|
class path:pagination.prevClass | prefix: previous,
|
647
665
|
data-page-no path:pagination.prevNo,
|
648
666
|
href path:pagination.prevHref | prefix: #"
|
649
667
|
data-monster-replace="path:labels.previous">Previous</a></li>
|
650
|
-
<li part="
|
668
|
+
<li part="next" data-monster-role="pagination-next"><a
|
651
669
|
data-monster-role="pagination-next"
|
670
|
+
part="next-link"
|
652
671
|
data-monster-attributes="class path:pagination.nextClass | prefix: next,
|
653
672
|
data-page-no path:pagination.nextNo,
|
654
673
|
href path:pagination.nextHref | prefix: #"
|