@lion/ui 0.15.2 → 0.15.3
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/README.md +44 -9
- package/components/form-core/src/validate/LionValidationFeedback.js +2 -2
- package/components/form-core/src/validate/ValidateMixin.js +3 -3
- package/components/form-core/test/validate/lion-validation-feedback.test.js +2 -2
- package/components/form-core/test-suites/ValidateMixin.suite.js +23 -11
- package/components/form-core/translations/bg.js +4 -4
- package/components/form-core/translations/cs.js +4 -4
- package/components/form-core/translations/de.js +4 -4
- package/components/form-core/translations/en.js +4 -4
- package/components/form-core/translations/es.js +4 -4
- package/components/form-core/translations/fr.js +4 -4
- package/components/form-core/translations/hu.js +4 -4
- package/components/form-core/translations/it.js +4 -4
- package/components/form-core/translations/nl.js +4 -4
- package/components/form-core/translations/pl.js +4 -4
- package/components/form-core/translations/ro.js +4 -4
- package/components/form-core/translations/ru.js +4 -4
- package/components/form-core/translations/sk.js +4 -4
- package/components/form-core/translations/uk.js +4 -4
- package/components/form-core/translations/zh.js +4 -4
- package/components/input-stepper/src/LionInputStepper.js +48 -52
- package/components/input-stepper/test/lion-input-stepper.test.js +253 -41
- package/components/pagination/src/LionPagination.js +2 -1
- package/components/pagination/test/lion-pagination.test.js +41 -0
- package/components/validate-messages/translations/it.js +2 -2
- package/custom-elements.json +148 -170
- package/dist-types/components/form-core/test-suites/ValidateMixin.suite.d.ts.map +1 -1
- package/dist-types/components/input-stepper/src/LionInputStepper.d.ts +4 -20
- package/dist-types/components/input-stepper/src/LionInputStepper.d.ts.map +1 -1
- package/dist-types/components/input-stepper/test/lion-input-stepper.test.d.ts.map +1 -1
- package/dist-types/components/pagination/src/LionPagination.d.ts.map +1 -1
- package/dist-types/tsconfig.tsbuildinfo +1 -1
- package/docs/components/checkbox-group/overview.md +2 -2
- package/docs/components/checkbox-group/use-cases.md +3 -9
- package/docs/components/collapsible/overview.md +1 -1
- package/docs/components/combobox/overview.md +1 -1
- package/docs/components/combobox/use-cases.md +1 -1
- package/docs/components/dialog/overview.md +1 -1
- package/docs/components/fieldset/overview.md +5 -5
- package/docs/components/form/overview.md +3 -3
- package/docs/components/form/use-cases.md +2 -2
- package/docs/components/icon/use-cases.md +1 -1
- package/docs/components/input/overview.md +1 -1
- package/docs/components/input-amount/overview.md +3 -3
- package/docs/components/input-date/overview.md +3 -3
- package/docs/components/input-datepicker/overview.md +5 -5
- package/docs/components/input-email/overview.md +2 -2
- package/docs/components/input-file/overview.md +1 -1
- package/docs/components/input-iban/overview.md +2 -2
- package/docs/components/input-range/overview.md +2 -2
- package/docs/components/input-stepper/api-table.md +2 -3
- package/docs/components/input-stepper/overview.md +1 -1
- package/docs/components/input-tel/overview.md +1 -1
- package/docs/components/input-tel/use-cases.md +6 -6
- package/docs/components/input-tel-dropdown/overview.md +1 -1
- package/docs/components/listbox/use-cases.md +1 -1
- package/docs/components/radio-group/overview.md +3 -3
- package/docs/components/radio-group/use-cases.md +3 -9
- package/docs/components/select/overview.md +1 -1
- package/docs/components/select/use-cases.md +6 -6
- package/docs/components/select-rich/use-cases.md +2 -2
- package/docs/components/tabs/examples.md +1 -1
- package/docs/fundamentals/index.md +4 -4
- package/docs/fundamentals/node-tools/publish-docs/overview.md +3 -3
- package/docs/fundamentals/node-tools/rocket-preset-extend-lion-docs/overview.md +2 -2
- package/docs/fundamentals/rationales/accessibility.md +1 -1
- package/docs/fundamentals/systems/core/SlotMixin.md +1 -1
- package/docs/fundamentals/systems/core/overview.md +1 -1
- package/docs/fundamentals/systems/form/formatting-and-parsing.md +4 -4
- package/docs/fundamentals/systems/form/model-value.md +1 -1
- package/docs/fundamentals/systems/form/overview.md +28 -28
- package/docs/fundamentals/systems/form/validate.md +2 -2
- package/docs/fundamentals/systems/localize/overview.md +4 -4
- package/docs/fundamentals/systems/overlays/configuration.md +2 -2
- package/docs/fundamentals/systems/overlays/overview.md +5 -5
- package/docs/fundamentals/systems/overlays/use-cases.md +2 -2
- package/docs/fundamentals/tools/helpers/overview.md +1 -1
- package/docs/fundamentals/tools/singleton-manager/overview.md +4 -4
- package/docs/guides/how-to/create-a-custom-field.md +5 -5
- package/docs/guides/how-to/create-a-form.md +4 -4
- package/docs/guides/how-to/extend-a-native-input.md +2 -2
- package/docs/guides/index.md +8 -8
- package/docs/guides/principles/index.md +5 -5
- package/docs/guides/principles/styling.md +1 -1
- package/package.json +1 -1
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { expect, fixture as _fixture, nextFrame } from '@open-wc/testing';
|
|
2
|
+
import { nothing } from 'lit';
|
|
2
3
|
import { html } from 'lit/static-html.js';
|
|
3
4
|
import sinon from 'sinon';
|
|
4
5
|
import { formatNumber } from '@lion/ui/localize-no-side-effects.js';
|
|
@@ -17,6 +18,7 @@ const inputStepperWithAttrs = html`<lion-input-stepper
|
|
|
17
18
|
step="10"
|
|
18
19
|
min="100"
|
|
19
20
|
max="200"
|
|
21
|
+
label="Label"
|
|
20
22
|
></lion-input-stepper>`;
|
|
21
23
|
|
|
22
24
|
describe('<lion-input-stepper>', () => {
|
|
@@ -177,31 +179,6 @@ describe('<lion-input-stepper>', () => {
|
|
|
177
179
|
expect(counter).to.equal(1);
|
|
178
180
|
});
|
|
179
181
|
|
|
180
|
-
it('fires a leave event ("blur") on button clicks', async () => {
|
|
181
|
-
const blurSpy = sinon.spy();
|
|
182
|
-
const el = await fixture(html`
|
|
183
|
-
<lion-input-stepper @blur=${blurSpy} name="year" label="Years"></lion-input-stepper>
|
|
184
|
-
`);
|
|
185
|
-
|
|
186
|
-
expect(el.value).to.equal('');
|
|
187
|
-
const decrementButton = el.querySelector('[slot=prefix]');
|
|
188
|
-
decrementButton?.dispatchEvent(new Event('focus'));
|
|
189
|
-
decrementButton?.dispatchEvent(new Event('click'));
|
|
190
|
-
decrementButton?.dispatchEvent(new Event('blur'));
|
|
191
|
-
expect(el.value).to.equal('−1');
|
|
192
|
-
expect(blurSpy.calledOnce).to.be.true;
|
|
193
|
-
expect(el.touched).to.be.true;
|
|
194
|
-
|
|
195
|
-
el.touched = false;
|
|
196
|
-
const incrementButton = el.querySelector('[slot=suffix]');
|
|
197
|
-
incrementButton?.dispatchEvent(new Event('focus'));
|
|
198
|
-
incrementButton?.dispatchEvent(new Event('click'));
|
|
199
|
-
incrementButton?.dispatchEvent(new Event('blur'));
|
|
200
|
-
expect(el.value).to.equal('0');
|
|
201
|
-
expect(blurSpy.calledTwice).to.be.true;
|
|
202
|
-
expect(el.touched).to.be.true;
|
|
203
|
-
});
|
|
204
|
-
|
|
205
182
|
it('should update min and max attributes when min and max property change', async () => {
|
|
206
183
|
const el = await fixture(inputStepperWithAttrs);
|
|
207
184
|
el.min = 100;
|
|
@@ -358,6 +335,251 @@ describe('<lion-input-stepper>', () => {
|
|
|
358
335
|
await el.updateComplete;
|
|
359
336
|
expect(el.modelValue).to.equal(-13, 'Fail - : (-23 > 100 by 10; val 55)'); // -23 > -13 > -3 > 7
|
|
360
337
|
});
|
|
338
|
+
|
|
339
|
+
it('handles decimal step values correctly', async () => {
|
|
340
|
+
// Test with decimal step 0.1
|
|
341
|
+
let el = await fixture(
|
|
342
|
+
html`<lion-input-stepper step="0.1" min="0" max="9" value="5.55"></lion-input-stepper>`,
|
|
343
|
+
);
|
|
344
|
+
|
|
345
|
+
// Test increment with decimal step
|
|
346
|
+
let incrementButton = el.querySelector('[slot=suffix]');
|
|
347
|
+
incrementButton?.dispatchEvent(new Event('click'));
|
|
348
|
+
await el.updateComplete;
|
|
349
|
+
expect(el.modelValue).to.equal(5.6, 'Fail + : (0 > 9 by 0.1; val 5.55)');
|
|
350
|
+
|
|
351
|
+
// Test decrement with decimal step
|
|
352
|
+
let decrementButton = el.querySelector('[slot=prefix]');
|
|
353
|
+
decrementButton?.dispatchEvent(new Event('click'));
|
|
354
|
+
await el.updateComplete;
|
|
355
|
+
expect(el.modelValue).to.equal(5.5, 'Fail - : (0 > 9 by 0.1; val 5.6)');
|
|
356
|
+
|
|
357
|
+
// Test with value that needs alignment
|
|
358
|
+
el = await fixture(
|
|
359
|
+
html`<lion-input-stepper step="0.1" min="0" max="9" value="3.27"></lion-input-stepper>`,
|
|
360
|
+
);
|
|
361
|
+
|
|
362
|
+
// Should align to next step when incrementing
|
|
363
|
+
incrementButton = el.querySelector('[slot=suffix]');
|
|
364
|
+
incrementButton?.dispatchEvent(new Event('click'));
|
|
365
|
+
await el.updateComplete;
|
|
366
|
+
expect(el.modelValue).to.equal(3.3, 'Fail + alignment: (0 > 9 by 0.1; val 3.27)');
|
|
367
|
+
|
|
368
|
+
// Reset and test decrement alignment
|
|
369
|
+
el = await fixture(
|
|
370
|
+
html`<lion-input-stepper step="0.1" min="0" max="9" value="3.27"></lion-input-stepper>`,
|
|
371
|
+
);
|
|
372
|
+
|
|
373
|
+
// Should align to previous step when decrementing
|
|
374
|
+
decrementButton = el.querySelector('[slot=prefix]');
|
|
375
|
+
decrementButton?.dispatchEvent(new Event('click'));
|
|
376
|
+
await el.updateComplete;
|
|
377
|
+
expect(el.modelValue).to.equal(3.2, 'Fail - alignment: (0 > 9 by 0.1; val 3.27)');
|
|
378
|
+
});
|
|
379
|
+
});
|
|
380
|
+
});
|
|
381
|
+
|
|
382
|
+
describe('_destroyOutputContent method', () => {
|
|
383
|
+
beforeEach(() => {
|
|
384
|
+
// Ensure clean state for each test
|
|
385
|
+
sinon.restore();
|
|
386
|
+
});
|
|
387
|
+
|
|
388
|
+
it('should clear existing timer before setting a new one', async () => {
|
|
389
|
+
const el = await fixture(defaultInputStepper);
|
|
390
|
+
const clearTimeoutSpy = sinon.spy(window, 'clearTimeout');
|
|
391
|
+
|
|
392
|
+
// Set an initial timer
|
|
393
|
+
el.timer = setTimeout(() => {}, 1000);
|
|
394
|
+
const initialTimer = el.timer;
|
|
395
|
+
|
|
396
|
+
// Call _destroyOutputContent
|
|
397
|
+
el._destroyOutputContent();
|
|
398
|
+
|
|
399
|
+
expect(clearTimeoutSpy.calledWith(initialTimer)).to.be.true;
|
|
400
|
+
clearTimeoutSpy.restore();
|
|
401
|
+
});
|
|
402
|
+
|
|
403
|
+
it('should set __valueText to nothing and request update after timeout', async () => {
|
|
404
|
+
const el = await fixture(defaultInputStepper);
|
|
405
|
+
const requestUpdateSpy = sinon.spy(el, 'requestUpdate');
|
|
406
|
+
const clock = sinon.useFakeTimers();
|
|
407
|
+
|
|
408
|
+
// Set initial value text
|
|
409
|
+
el.__valueText = 'test value';
|
|
410
|
+
|
|
411
|
+
// Call _destroyOutputContent
|
|
412
|
+
el._destroyOutputContent();
|
|
413
|
+
|
|
414
|
+
// Fast forward time by 2000ms (default timeout)
|
|
415
|
+
clock.tick(2000);
|
|
416
|
+
|
|
417
|
+
await expect(el.__valueText).to.equal(nothing);
|
|
418
|
+
expect(requestUpdateSpy.calledOnce).to.be.true;
|
|
419
|
+
|
|
420
|
+
clock.restore();
|
|
421
|
+
requestUpdateSpy.restore();
|
|
422
|
+
});
|
|
423
|
+
|
|
424
|
+
it('should use custom timeout from data-self-destruct attribute', async () => {
|
|
425
|
+
const el = await fixture(html`
|
|
426
|
+
<lion-input-stepper name="test" label="Test"> </lion-input-stepper>
|
|
427
|
+
`);
|
|
428
|
+
|
|
429
|
+
await el.updateComplete;
|
|
430
|
+
|
|
431
|
+
// Get the output element and set custom self-destruct value
|
|
432
|
+
const outputElement = /** @type {HTMLElement} */ (
|
|
433
|
+
el.shadowRoot?.querySelector('.input-stepper__value')
|
|
434
|
+
);
|
|
435
|
+
if (outputElement) {
|
|
436
|
+
outputElement.dataset.selfDestruct = '5000';
|
|
437
|
+
}
|
|
438
|
+
|
|
439
|
+
const clock = sinon.useFakeTimers();
|
|
440
|
+
const requestUpdateSpy = sinon.spy(el, 'requestUpdate');
|
|
441
|
+
|
|
442
|
+
el.__valueText = 'test value';
|
|
443
|
+
el._destroyOutputContent();
|
|
444
|
+
|
|
445
|
+
// Should not trigger after default 2000ms
|
|
446
|
+
clock.tick(2000);
|
|
447
|
+
await expect(el.__valueText).to.equal('test value');
|
|
448
|
+
expect(requestUpdateSpy.called).to.be.false;
|
|
449
|
+
|
|
450
|
+
// Should trigger after custom 5000ms
|
|
451
|
+
clock.tick(3000); // Total 5000ms
|
|
452
|
+
await expect(el.__valueText).to.equal(nothing);
|
|
453
|
+
expect(requestUpdateSpy.calledOnce).to.be.true;
|
|
454
|
+
|
|
455
|
+
clock.restore();
|
|
456
|
+
requestUpdateSpy.restore();
|
|
457
|
+
});
|
|
458
|
+
|
|
459
|
+
it('should handle invalid data-self-destruct value by using default timeout', async () => {
|
|
460
|
+
const el = await fixture(html`
|
|
461
|
+
<lion-input-stepper name="test" label="Test"> </lion-input-stepper>
|
|
462
|
+
`);
|
|
463
|
+
|
|
464
|
+
await el.updateComplete;
|
|
465
|
+
|
|
466
|
+
// Get the output element and set invalid self-destruct value
|
|
467
|
+
const outputElement = /** @type {HTMLElement} */ (
|
|
468
|
+
el.shadowRoot?.querySelector('.input-stepper__value')
|
|
469
|
+
);
|
|
470
|
+
if (outputElement) {
|
|
471
|
+
outputElement.dataset.selfDestruct = 'invalid';
|
|
472
|
+
}
|
|
473
|
+
|
|
474
|
+
const clock = sinon.useFakeTimers();
|
|
475
|
+
const requestUpdateSpy = sinon.spy(el, 'requestUpdate');
|
|
476
|
+
|
|
477
|
+
el.__valueText = 'test value';
|
|
478
|
+
el._destroyOutputContent();
|
|
479
|
+
|
|
480
|
+
// Should use default 2000ms when invalid value is provided
|
|
481
|
+
clock.tick(2000);
|
|
482
|
+
await expect(el.__valueText).to.equal(nothing);
|
|
483
|
+
expect(requestUpdateSpy.calledOnce).to.be.true;
|
|
484
|
+
|
|
485
|
+
clock.restore();
|
|
486
|
+
requestUpdateSpy.restore();
|
|
487
|
+
});
|
|
488
|
+
|
|
489
|
+
it('should not set timeout if output element does not exist', async () => {
|
|
490
|
+
const el = await fixture(defaultInputStepper);
|
|
491
|
+
const setTimeoutSpy = sinon.spy(window, 'setTimeout');
|
|
492
|
+
|
|
493
|
+
// Mock shadowRoot to return null for querySelector
|
|
494
|
+
const originalQuerySelector = el.shadowRoot?.querySelector;
|
|
495
|
+
if (el.shadowRoot) {
|
|
496
|
+
el.shadowRoot.querySelector = () => null;
|
|
497
|
+
}
|
|
498
|
+
|
|
499
|
+
el._destroyOutputContent();
|
|
500
|
+
|
|
501
|
+
expect(setTimeoutSpy.called).to.be.false;
|
|
502
|
+
|
|
503
|
+
// Restore original querySelector
|
|
504
|
+
if (el.shadowRoot && originalQuerySelector) {
|
|
505
|
+
el.shadowRoot.querySelector = originalQuerySelector;
|
|
506
|
+
}
|
|
507
|
+
setTimeoutSpy.restore();
|
|
508
|
+
});
|
|
509
|
+
|
|
510
|
+
it('should only execute timeout callback if output element still has parent', async () => {
|
|
511
|
+
const el = await fixture(defaultInputStepper);
|
|
512
|
+
const clock = sinon.useFakeTimers();
|
|
513
|
+
const requestUpdateSpy = sinon.spy(el, 'requestUpdate');
|
|
514
|
+
|
|
515
|
+
el.__valueText = 'test value';
|
|
516
|
+
el._destroyOutputContent();
|
|
517
|
+
|
|
518
|
+
// Remove the output element from DOM before timeout
|
|
519
|
+
const outputElement = el.shadowRoot?.querySelector('.input-stepper__value');
|
|
520
|
+
if (outputElement && outputElement.parentNode) {
|
|
521
|
+
outputElement.parentNode.removeChild(outputElement);
|
|
522
|
+
}
|
|
523
|
+
|
|
524
|
+
// Fast forward time
|
|
525
|
+
clock.tick(2000);
|
|
526
|
+
|
|
527
|
+
// Should not have updated since element was removed
|
|
528
|
+
expect(requestUpdateSpy.called).to.be.false;
|
|
529
|
+
expect(el.__valueText).to.equal('test value');
|
|
530
|
+
|
|
531
|
+
clock.restore();
|
|
532
|
+
requestUpdateSpy.restore();
|
|
533
|
+
});
|
|
534
|
+
|
|
535
|
+
it('should be called when increment button is clicked', async () => {
|
|
536
|
+
const el = await fixture(defaultInputStepper);
|
|
537
|
+
const destroyOutputSpy = sinon.spy(el, '_destroyOutputContent');
|
|
538
|
+
|
|
539
|
+
const incrementButton = el.querySelector('[slot=suffix]');
|
|
540
|
+
incrementButton?.dispatchEvent(new Event('click'));
|
|
541
|
+
|
|
542
|
+
expect(destroyOutputSpy.calledOnce).to.be.true;
|
|
543
|
+
destroyOutputSpy.restore();
|
|
544
|
+
});
|
|
545
|
+
|
|
546
|
+
it('should be called when decrement button is clicked', async () => {
|
|
547
|
+
const el = await fixture(defaultInputStepper);
|
|
548
|
+
const destroyOutputSpy = sinon.spy(el, '_destroyOutputContent');
|
|
549
|
+
|
|
550
|
+
const decrementButton = el.querySelector('[slot=prefix]');
|
|
551
|
+
decrementButton?.dispatchEvent(new Event('click'));
|
|
552
|
+
|
|
553
|
+
expect(destroyOutputSpy.calledOnce).to.be.true;
|
|
554
|
+
destroyOutputSpy.restore();
|
|
555
|
+
});
|
|
556
|
+
|
|
557
|
+
it('should handle multiple rapid calls by clearing previous timers', async () => {
|
|
558
|
+
const el = await fixture(defaultInputStepper);
|
|
559
|
+
const clock = sinon.useFakeTimers();
|
|
560
|
+
const requestUpdateSpy = sinon.spy(el, 'requestUpdate');
|
|
561
|
+
|
|
562
|
+
el.__valueText = 'test value';
|
|
563
|
+
|
|
564
|
+
// Call _destroyOutputContent multiple times rapidly
|
|
565
|
+
el._destroyOutputContent();
|
|
566
|
+
clock.tick(1000); // 1 second
|
|
567
|
+
|
|
568
|
+
el._destroyOutputContent(); // This should clear the previous timer
|
|
569
|
+
clock.tick(1000); // Total 2 seconds from first call, 1 second from second call
|
|
570
|
+
|
|
571
|
+
// Should not have triggered yet since second call reset the timer
|
|
572
|
+
expect(el.__valueText).to.equal('test value');
|
|
573
|
+
expect(requestUpdateSpy.called).to.be.false;
|
|
574
|
+
|
|
575
|
+
clock.tick(1000); // Total 2 seconds from second call
|
|
576
|
+
|
|
577
|
+
// Should trigger now
|
|
578
|
+
await expect(el.__valueText).to.equal(nothing);
|
|
579
|
+
expect(requestUpdateSpy.calledOnce).to.be.true;
|
|
580
|
+
|
|
581
|
+
clock.restore();
|
|
582
|
+
requestUpdateSpy.restore();
|
|
361
583
|
});
|
|
362
584
|
});
|
|
363
585
|
|
|
@@ -448,30 +670,20 @@ describe('<lion-input-stepper>', () => {
|
|
|
448
670
|
expect(el._inputNode.getAttribute('aria-valuemax')).to.equal('1000');
|
|
449
671
|
});
|
|
450
672
|
|
|
451
|
-
it('
|
|
673
|
+
it('decrease button should have aria-label with the component label', async () => {
|
|
452
674
|
const el = await fixture(inputStepperWithAttrs);
|
|
453
|
-
const stepperValue = el.shadowRoot?.querySelector('.input-stepper__value');
|
|
454
675
|
const decrementButton = el.querySelector('[slot=prefix]');
|
|
455
676
|
|
|
456
|
-
decrementButton?.
|
|
457
|
-
expect(
|
|
458
|
-
expect(stepperValue?.getAttribute('aria-live')).to.equal('assertive');
|
|
459
|
-
|
|
460
|
-
decrementButton?.dispatchEvent(new Event('blur'));
|
|
461
|
-
expect(stepperValue?.hasAttribute('aria-live')).to.be.false;
|
|
677
|
+
expect(decrementButton?.hasAttribute('aria-label')).to.be.true;
|
|
678
|
+
expect(decrementButton?.getAttribute('aria-label')).to.equal('Decrease Label');
|
|
462
679
|
});
|
|
463
680
|
|
|
464
|
-
it('
|
|
681
|
+
it('increase button should have aria-label with the component label', async () => {
|
|
465
682
|
const el = await fixture(inputStepperWithAttrs);
|
|
466
|
-
const stepperValue = el.shadowRoot?.querySelector('.input-stepper__value');
|
|
467
683
|
const incrementButton = el.querySelector('[slot=suffix]');
|
|
468
684
|
|
|
469
|
-
incrementButton?.
|
|
470
|
-
expect(
|
|
471
|
-
expect(stepperValue?.getAttribute('aria-live')).to.equal('assertive');
|
|
472
|
-
|
|
473
|
-
incrementButton?.dispatchEvent(new Event('blur'));
|
|
474
|
-
expect(stepperValue?.hasAttribute('aria-live')).to.be.false;
|
|
685
|
+
expect(incrementButton?.hasAttribute('aria-label')).to.be.true;
|
|
686
|
+
expect(incrementButton?.getAttribute('aria-label')).to.equal('Increase Label');
|
|
475
687
|
});
|
|
476
688
|
});
|
|
477
689
|
});
|
|
@@ -196,7 +196,8 @@ export class LionPagination extends LocalizeMixin(LitElement) {
|
|
|
196
196
|
const finish = this.count;
|
|
197
197
|
// If there are more pages then we want to display we have to redo the list each time
|
|
198
198
|
// Else we can just return the same list every time.
|
|
199
|
-
|
|
199
|
+
// Allow up to 2 extra pages without ellipsis (e.g., count=6 or count=7 when visiblePages=5)
|
|
200
|
+
if (this.count > this.__visiblePages + 2) {
|
|
200
201
|
// Calculate left side of current page and right side
|
|
201
202
|
const pos3 = this.current - 1;
|
|
202
203
|
const pos4 = this.current;
|
|
@@ -164,4 +164,45 @@ describe('Pagination', () => {
|
|
|
164
164
|
expect(buttons[3].getAttribute('aria-current')).to.equal('false');
|
|
165
165
|
});
|
|
166
166
|
});
|
|
167
|
+
|
|
168
|
+
describe('Ellipsis display', () => {
|
|
169
|
+
it('should not show ellipsis when count is visiblePages + 1 (count=6, visiblePages=5)', async () => {
|
|
170
|
+
const el = await fixture(html` <lion-pagination count="6" current="1"></lion-pagination> `);
|
|
171
|
+
const navItems = Array.from(/** @type {ShadowRoot} */ (el.shadowRoot).querySelectorAll('li'));
|
|
172
|
+
// Check that no ellipsis is rendered (no <span> elements with '...')
|
|
173
|
+
const spans = Array.from(
|
|
174
|
+
/** @type {ShadowRoot} */ (el.shadowRoot).querySelectorAll('li span'),
|
|
175
|
+
);
|
|
176
|
+
expect(spans.length).to.equal(0);
|
|
177
|
+
|
|
178
|
+
// There should be 8 nav items: previous button + 6 page buttons + next button
|
|
179
|
+
expect(navItems.length).to.equal(8);
|
|
180
|
+
});
|
|
181
|
+
|
|
182
|
+
it('should not show ellipsis when count is visiblePages + 2 (count=7, visiblePages=5)', async () => {
|
|
183
|
+
const el = await fixture(html` <lion-pagination count="7" current="1"></lion-pagination> `);
|
|
184
|
+
// Check that no ellipsis is rendered (no <span> elements with '...')
|
|
185
|
+
const spans = Array.from(
|
|
186
|
+
/** @type {ShadowRoot} */ (el.shadowRoot).querySelectorAll('li span'),
|
|
187
|
+
);
|
|
188
|
+
expect(spans.length).to.equal(0);
|
|
189
|
+
|
|
190
|
+
// There should be 9 nav items: previous button + 7 page buttons + next button
|
|
191
|
+
const navItems = Array.from(/** @type {ShadowRoot} */ (el.shadowRoot).querySelectorAll('li'));
|
|
192
|
+
expect(navItems.length).to.equal(9);
|
|
193
|
+
});
|
|
194
|
+
|
|
195
|
+
it('should show ellipsis when count is visiblePages + 3 (count=8, visiblePages=5)', async () => {
|
|
196
|
+
const el = await fixture(html` <lion-pagination count="8" current="1"></lion-pagination> `);
|
|
197
|
+
// Check that ellipsis is rendered (should have <span> elements with '...')
|
|
198
|
+
const spans = Array.from(
|
|
199
|
+
/** @type {ShadowRoot} */ (el.shadowRoot).querySelectorAll('li span'),
|
|
200
|
+
);
|
|
201
|
+
expect(spans.length).to.be.greaterThan(0);
|
|
202
|
+
|
|
203
|
+
// Verify the ellipsis contains '...'
|
|
204
|
+
const ellipsisText = Array.from(spans).map(span => span.textContent);
|
|
205
|
+
expect(ellipsisText).to.include('...');
|
|
206
|
+
});
|
|
207
|
+
});
|
|
167
208
|
});
|
|
@@ -18,7 +18,7 @@ export default {
|
|
|
18
18
|
MaxDate: 'Inserire un(a) {fieldName} prima di {params, date, YYYYMMDD}.',
|
|
19
19
|
MinMaxDate:
|
|
20
20
|
'Inserire un(a) {fieldName} tra {params.min, date, YYYYMMDD} e {params.max, date, YYYYMMDD}.',
|
|
21
|
-
IsDateDisabled: "
|
|
21
|
+
IsDateDisabled: "Questa data non è disponibile, sceglierne un'altra.",
|
|
22
22
|
IsEmail: 'Inserire un valore valido per {fieldName} nel formato "name@example.com".',
|
|
23
23
|
MatchesOption:
|
|
24
24
|
'Nessun risultato corrispondente. Provare con una parola chiave o una categoria diversa.',
|
|
@@ -41,7 +41,7 @@ export default {
|
|
|
41
41
|
MaxDate: 'Inserire un(a) {fieldName} prima di {params, date, YYYYMMDD}.',
|
|
42
42
|
MinMaxDate:
|
|
43
43
|
'Inserire un(a) {fieldName} tra {params.min, date, YYYYMMDD} e {params.max, date, YYYYMMDD}.',
|
|
44
|
-
IsDateDisabled: "
|
|
44
|
+
IsDateDisabled: "Questa data non è disponibile, sceglierne un'altra.",
|
|
45
45
|
IsEmail: 'Inserire un valore valido per {fieldName} nel formato "name@example.com".',
|
|
46
46
|
MatchesOption:
|
|
47
47
|
'Nessun risultato corrispondente. Provare con una parola chiave o una categoria diversa.',
|