@lion/ui 0.15.2 → 0.15.4

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.
Files changed (169) hide show
  1. package/README.md +46 -11
  2. package/components/combobox/src/LionCombobox.js +4 -1
  3. package/components/combobox/test/lion-combobox-integrations.test.js +23 -0
  4. package/components/combobox/test/lion-combobox.test.js +20 -0
  5. package/components/core/src/ScopedStylesController.js +7 -10
  6. package/components/core/test-helpers/getCachedFixture.js +55 -0
  7. package/components/form-core/src/validate/LionValidationFeedback.js +2 -2
  8. package/components/form-core/src/validate/ValidateMixin.js +3 -3
  9. package/components/form-core/test/validate/lion-validation-feedback.test.js +2 -2
  10. package/components/form-core/test-suites/ValidateMixin.suite.js +23 -11
  11. package/components/form-core/translations/bg.js +4 -4
  12. package/components/form-core/translations/cs.js +4 -4
  13. package/components/form-core/translations/de.js +4 -4
  14. package/components/form-core/translations/en.js +4 -4
  15. package/components/form-core/translations/es.js +4 -4
  16. package/components/form-core/translations/fr.js +4 -4
  17. package/components/form-core/translations/hu.js +4 -4
  18. package/components/form-core/translations/it.js +4 -4
  19. package/components/form-core/translations/nl.js +4 -4
  20. package/components/form-core/translations/pl.js +4 -4
  21. package/components/form-core/translations/ro.js +4 -4
  22. package/components/form-core/translations/ru.js +4 -4
  23. package/components/form-core/translations/sk.js +4 -4
  24. package/components/form-core/translations/uk.js +4 -4
  25. package/components/form-core/translations/zh.js +4 -4
  26. package/components/input-amount/src/parsers.js +3 -2
  27. package/components/input-amount/test/parsers.test.js +6 -0
  28. package/components/input-amount-dropdown/src/currencyUtil.js +1 -1
  29. package/components/input-file/src/localizeNamespaceLoader.js +4 -0
  30. package/components/input-file/translations/bg.js +5 -0
  31. package/components/input-file/translations/cs.js +5 -0
  32. package/components/input-file/translations/es.js +5 -0
  33. package/components/input-file/translations/fr.js +5 -0
  34. package/components/input-file/translations/hu.js +5 -0
  35. package/components/input-file/translations/id-ID.js +5 -0
  36. package/components/input-file/translations/id.js +19 -0
  37. package/components/input-file/translations/it.js +5 -0
  38. package/components/input-file/translations/pl.js +5 -0
  39. package/components/input-file/translations/ro.js +5 -0
  40. package/components/input-file/translations/sk.js +5 -0
  41. package/components/input-file/translations/uk.js +5 -0
  42. package/components/input-file/translations/zh.js +5 -0
  43. package/components/input-stepper/src/LionInputStepper.js +48 -52
  44. package/components/input-stepper/test/lion-input-stepper-integrations.test.js +2 -19
  45. package/components/input-stepper/test/lion-input-stepper.test.js +2 -476
  46. package/components/input-stepper/test-suites/lion-input-stepper.integration.suite.js +19 -0
  47. package/components/input-stepper/test-suites/lion-input-stepper.suite.js +673 -0
  48. package/components/listbox/src/ListboxMixin.js +0 -1
  49. package/components/listbox/test-suites/ListboxMixin.suite.js +71 -2
  50. package/components/overlays/src/OverlayController.js +3 -0
  51. package/components/overlays/src/OverlaysManager.js +9 -2
  52. package/components/overlays/test/OverlayController.test.js +22 -9
  53. package/components/overlays/test/OverlaysManager.test.js +16 -0
  54. package/components/pagination/src/LionPagination.js +2 -1
  55. package/components/pagination/test/lion-pagination.test.js +41 -0
  56. package/components/validate-messages/translations/it.js +2 -2
  57. package/custom-elements.json +281 -179
  58. package/dist-types/components/combobox/src/LionCombobox.d.ts.map +1 -1
  59. package/dist-types/components/core/src/ScopedStylesController.d.ts +1 -2
  60. package/dist-types/components/core/src/ScopedStylesController.d.ts.map +1 -1
  61. package/dist-types/components/core/test-helpers/getCachedFixture.d.ts +14 -0
  62. package/dist-types/components/core/test-helpers/getCachedFixture.d.ts.map +1 -0
  63. package/dist-types/components/form-core/test-suites/ValidateMixin.suite.d.ts.map +1 -1
  64. package/dist-types/components/form-integrations/test/helpers/helpers.d.ts +3 -3
  65. package/dist-types/components/form-integrations/test/helpers/helpers.d.ts.map +1 -1
  66. package/dist-types/components/input-amount/src/parsers.d.ts.map +1 -1
  67. package/dist-types/components/input-file/src/localizeNamespaceLoader.d.ts +1 -1
  68. package/dist-types/components/input-file/src/localizeNamespaceLoader.d.ts.map +1 -1
  69. package/dist-types/components/input-file/translations/bg-BG.d.ts +5 -0
  70. package/dist-types/components/input-file/translations/bg.d.ts +5 -0
  71. package/dist-types/components/input-file/translations/cs-CZ.d.ts +5 -0
  72. package/dist-types/components/input-file/translations/cs.d.ts +5 -0
  73. package/dist-types/components/input-file/translations/es-ES.d.ts +5 -0
  74. package/dist-types/components/input-file/translations/es.d.ts +5 -0
  75. package/dist-types/components/input-file/translations/fr-BE.d.ts +5 -0
  76. package/dist-types/components/input-file/translations/fr-FR.d.ts +5 -0
  77. package/dist-types/components/input-file/translations/fr.d.ts +5 -0
  78. package/dist-types/components/input-file/translations/hu-HU.d.ts +5 -0
  79. package/dist-types/components/input-file/translations/hu.d.ts +5 -0
  80. package/dist-types/components/input-file/translations/id-ID.d.ts +20 -0
  81. package/dist-types/components/input-file/translations/id-ID.d.ts.map +1 -0
  82. package/dist-types/components/input-file/translations/id.d.ts +20 -0
  83. package/dist-types/components/input-file/translations/id.d.ts.map +1 -0
  84. package/dist-types/components/input-file/translations/it-IT.d.ts +5 -0
  85. package/dist-types/components/input-file/translations/it.d.ts +5 -0
  86. package/dist-types/components/input-file/translations/pl-PL.d.ts +5 -0
  87. package/dist-types/components/input-file/translations/pl.d.ts +5 -0
  88. package/dist-types/components/input-file/translations/ro-RO.d.ts +5 -0
  89. package/dist-types/components/input-file/translations/ro.d.ts +5 -0
  90. package/dist-types/components/input-file/translations/sk-SK.d.ts +5 -0
  91. package/dist-types/components/input-file/translations/sk.d.ts +5 -0
  92. package/dist-types/components/input-file/translations/uk-UA.d.ts +5 -0
  93. package/dist-types/components/input-file/translations/uk.d.ts +5 -0
  94. package/dist-types/components/input-file/translations/zh-CN.d.ts +5 -0
  95. package/dist-types/components/input-file/translations/zh.d.ts +5 -0
  96. package/dist-types/components/input-stepper/src/LionInputStepper.d.ts +4 -20
  97. package/dist-types/components/input-stepper/src/LionInputStepper.d.ts.map +1 -1
  98. package/dist-types/components/input-stepper/test/lion-input-stepper.test.d.ts +1 -2
  99. package/dist-types/components/input-stepper/test/lion-input-stepper.test.d.ts.map +1 -1
  100. package/dist-types/components/input-stepper/test-suites/lion-input-stepper.integration.suite.d.ts +3 -0
  101. package/dist-types/components/input-stepper/test-suites/lion-input-stepper.integration.suite.d.ts.map +1 -0
  102. package/dist-types/components/input-stepper/test-suites/lion-input-stepper.suite.d.ts +4 -0
  103. package/dist-types/components/input-stepper/test-suites/lion-input-stepper.suite.d.ts.map +1 -0
  104. package/dist-types/components/listbox/src/ListboxMixin.d.ts.map +1 -1
  105. package/dist-types/components/listbox/test-suites/ListboxMixin.suite.d.ts.map +1 -1
  106. package/dist-types/components/overlays/src/OverlayController.d.ts.map +1 -1
  107. package/dist-types/components/overlays/src/OverlaysManager.d.ts +4 -1
  108. package/dist-types/components/overlays/src/OverlaysManager.d.ts.map +1 -1
  109. package/dist-types/components/pagination/src/LionPagination.d.ts.map +1 -1
  110. package/dist-types/exports/input-stepper-suites.d.ts +6 -0
  111. package/dist-types/exports/input-stepper-suites.d.ts.map +1 -0
  112. package/dist-types/tsconfig.tsbuildinfo +1 -1
  113. package/docs/components/checkbox-group/overview.md +2 -2
  114. package/docs/components/checkbox-group/use-cases.md +3 -9
  115. package/docs/components/collapsible/overview.md +1 -1
  116. package/docs/components/combobox/overview.md +1 -1
  117. package/docs/components/combobox/use-cases.md +1 -1
  118. package/docs/components/dialog/overview.md +1 -1
  119. package/docs/components/fieldset/overview.md +5 -5
  120. package/docs/components/form/overview.md +3 -3
  121. package/docs/components/form/use-cases.md +2 -2
  122. package/docs/components/icon/use-cases.md +1 -1
  123. package/docs/components/input/overview.md +1 -1
  124. package/docs/components/input-amount/overview.md +3 -3
  125. package/docs/components/input-date/overview.md +3 -3
  126. package/docs/components/input-datepicker/overview.md +5 -5
  127. package/docs/components/input-email/overview.md +2 -2
  128. package/docs/components/input-file/overview.md +1 -1
  129. package/docs/components/input-iban/overview.md +2 -2
  130. package/docs/components/input-range/overview.md +2 -2
  131. package/docs/components/input-stepper/api-table.md +2 -3
  132. package/docs/components/input-stepper/overview.md +1 -1
  133. package/docs/components/input-tel/overview.md +1 -1
  134. package/docs/components/input-tel/use-cases.md +6 -6
  135. package/docs/components/input-tel-dropdown/overview.md +1 -1
  136. package/docs/components/listbox/use-cases.md +1 -1
  137. package/docs/components/radio-group/overview.md +3 -3
  138. package/docs/components/radio-group/use-cases.md +3 -9
  139. package/docs/components/select/overview.md +1 -1
  140. package/docs/components/select/use-cases.md +6 -6
  141. package/docs/components/select-rich/use-cases.md +2 -2
  142. package/docs/components/tabs/examples.md +1 -1
  143. package/docs/fundamentals/index.md +4 -4
  144. package/docs/fundamentals/node-tools/publish-docs/overview.md +3 -3
  145. package/docs/fundamentals/node-tools/rocket-preset-extend-lion-docs/overview.md +2 -2
  146. package/docs/fundamentals/rationales/accessibility.md +1 -1
  147. package/docs/fundamentals/systems/core/SlotMixin.md +2 -2
  148. package/docs/fundamentals/systems/core/api-table.md +3 -4
  149. package/docs/fundamentals/systems/core/overview.md +1 -1
  150. package/docs/fundamentals/systems/form/formatting-and-parsing.md +4 -4
  151. package/docs/fundamentals/systems/form/model-value.md +1 -1
  152. package/docs/fundamentals/systems/form/overview.md +28 -28
  153. package/docs/fundamentals/systems/form/validate.md +38 -30
  154. package/docs/fundamentals/systems/localize/overview.md +4 -4
  155. package/docs/fundamentals/systems/overlays/api-table.md +1 -1
  156. package/docs/fundamentals/systems/overlays/configuration.md +2 -2
  157. package/docs/fundamentals/systems/overlays/overview.md +5 -5
  158. package/docs/fundamentals/systems/overlays/use-cases.md +2 -2
  159. package/docs/fundamentals/tools/helpers/overview.md +1 -1
  160. package/docs/fundamentals/tools/singleton-manager/overview.md +4 -4
  161. package/docs/guides/how-to/create-a-custom-field.md +5 -5
  162. package/docs/guides/how-to/create-a-form.md +4 -4
  163. package/docs/guides/how-to/extend-a-native-input.md +2 -2
  164. package/docs/guides/index.md +8 -8
  165. package/docs/guides/principles/index.md +5 -5
  166. package/docs/guides/principles/styling.md +1 -1
  167. package/exports/input-stepper-suites.js +11 -0
  168. package/input-stepper-suites.js +11 -0
  169. package/package.json +1 -1
@@ -1,477 +1,3 @@
1
- import { expect, fixture as _fixture, nextFrame } from '@open-wc/testing';
2
- import { html } from 'lit/static-html.js';
3
- import sinon from 'sinon';
4
- import { formatNumber } from '@lion/ui/localize-no-side-effects.js';
5
- import '@lion/ui/define/lion-input-stepper.js';
1
+ import { runInputStepperSuite } from '../test-suites/lion-input-stepper.suite.js';
6
2
 
7
- /**
8
- * @typedef {import('../src/LionInputStepper.js').LionInputStepper} LionInputStepper
9
- * @typedef {import('lit').TemplateResult} TemplateResult
10
- */
11
- const fixture = /** @type {(arg: TemplateResult|string) => Promise<LionInputStepper>} */ (_fixture);
12
-
13
- const defaultInputStepper = html`
14
- <lion-input-stepper name="year" label="Years"></lion-input-stepper>
15
- `;
16
- const inputStepperWithAttrs = html`<lion-input-stepper
17
- step="10"
18
- min="100"
19
- max="200"
20
- ></lion-input-stepper>`;
21
-
22
- describe('<lion-input-stepper>', () => {
23
- describe('Stepper', () => {
24
- it('has a type text', async () => {
25
- const el = await fixture(defaultInputStepper);
26
- expect(el._inputNode.type).to.equal('text');
27
- });
28
-
29
- it('has a default min and max of Infinity', async () => {
30
- const el = await fixture(defaultInputStepper);
31
- expect(el.getAttribute('min')).to.equal('Infinity');
32
- expect(el.getAttribute('max')).to.equal('Infinity');
33
- });
34
-
35
- it('has a default step of 1', async () => {
36
- const el = await fixture(defaultInputStepper);
37
- expect(el.getAttribute('step')).to.equal('1');
38
- });
39
-
40
- it('can set a step with which the value increases', async () => {
41
- const el = await fixture(defaultInputStepper);
42
- el.step = 10;
43
- await el.updateComplete;
44
- expect(el.value).to.equal('');
45
- expect(el.getAttribute('step')).to.equal('10');
46
-
47
- const incrementButton = el.querySelector('[slot=suffix]');
48
- incrementButton?.dispatchEvent(new Event('click'));
49
- expect(el.value).to.equal('10');
50
- });
51
- });
52
-
53
- describe('Formatter', () => {
54
- it('uses formatNumber for formatting', async () => {
55
- const el = await fixture(defaultInputStepper);
56
- expect(el.formatter).to.equal(formatNumber);
57
- });
58
-
59
- it('formatNumber uses locale provided in formatOptions', async () => {
60
- let el = await fixture(html`
61
- <lion-input-stepper
62
- .formatOptions="${{ locale: 'en-GB' }}"
63
- .modelValue="${1234.56}"
64
- ></lion-input-stepper>
65
- `);
66
- expect(el.formattedValue).to.equal('1,234.56');
67
- el = await fixture(html`
68
- <lion-input-stepper
69
- .formatOptions="${{ locale: 'nl-NL' }}"
70
- .modelValue="${1234.56}"
71
- ></lion-input-stepper>
72
- `);
73
- expect(el.formattedValue).to.equal('1.234,56');
74
- });
75
-
76
- it('supports overriding decimalSeparator in formatOptions', async () => {
77
- const el = await fixture(
78
- html`<lion-input-stepper
79
- .formatOptions="${{ locale: 'nl-NL', decimalSeparator: '.' }}"
80
- .modelValue="${12.34}"
81
- ></lion-input-stepper>`,
82
- );
83
- expect(el.formattedValue).to.equal('12.34');
84
- });
85
-
86
- it('supports overriding groupSeparator in formatOptions', async () => {
87
- const el = await fixture(
88
- html`<lion-input-stepper
89
- .formatOptions="${{ locale: 'nl-NL', groupSeparator: ',', decimalSeparator: '.' }}"
90
- .modelValue="${1234.56}"
91
- ></lion-input-stepper>`,
92
- );
93
- expect(el.formattedValue).to.equal('1,234.56');
94
- });
95
- });
96
-
97
- describe('User interaction', () => {
98
- it('should increment the value to 1 on [ArrowUp]', async () => {
99
- const el = await fixture(defaultInputStepper);
100
- expect(el.value).to.equal('');
101
- el.dispatchEvent(new KeyboardEvent('keydown', { key: 'ArrowUp' }));
102
- await el.updateComplete;
103
- expect(el.value).to.equal('1');
104
- });
105
-
106
- it('should increment the value to minValue on [ArrowUp] if value is below min', async () => {
107
- const el = await fixture(inputStepperWithAttrs);
108
- expect(el.value).to.equal('');
109
- el.dispatchEvent(new KeyboardEvent('keydown', { key: 'ArrowUp' }));
110
- await el.updateComplete;
111
- expect(el.value).to.equal('100');
112
- });
113
-
114
- it('should decrement the value to -1 on [ArrowDown]', async () => {
115
- const el = await fixture(defaultInputStepper);
116
- expect(el.value).to.equal('');
117
- el.dispatchEvent(new KeyboardEvent('keydown', { key: 'ArrowDown' }));
118
- await el.updateComplete;
119
- expect(el.value).to.equal('−1');
120
- });
121
-
122
- it('should increment the value to minValue on [ArrowDown] if value is below min', async () => {
123
- const el = await fixture(inputStepperWithAttrs);
124
- el.modelValue = 600;
125
- el.dispatchEvent(new KeyboardEvent('keydown', { key: 'ArrowDown' }));
126
- await el.updateComplete;
127
- expect(el.value).to.equal('200');
128
- });
129
-
130
- it('should increment the value to 1 on + button click', async () => {
131
- const el = await fixture(defaultInputStepper);
132
- expect(el.value).to.equal('');
133
- const incrementButton = el.querySelector('[slot=suffix]');
134
- incrementButton?.dispatchEvent(new Event('click'));
135
- expect(el.value).to.equal('1');
136
- });
137
-
138
- it('should decrement the value to -1 on - button click', async () => {
139
- const el = await fixture(defaultInputStepper);
140
- expect(el.value).to.equal('');
141
- const decrementButton = el.querySelector('[slot=prefix]');
142
- decrementButton?.dispatchEvent(new Event('click'));
143
- expect(el.value).to.equal('−1');
144
- });
145
-
146
- it('fires one "user-input-changed" event on + button click', async () => {
147
- let counter = 0;
148
- const el = await fixture(html`
149
- <lion-input-stepper
150
- name="year"
151
- label="Years"
152
- @user-input-changed="${() => {
153
- counter += 1;
154
- }}"
155
- >
156
- </lion-input-stepper>
157
- `);
158
- const incrementButton = el.querySelector('[slot=suffix]');
159
- incrementButton?.dispatchEvent(new Event('click'));
160
- expect(counter).to.equal(1);
161
- });
162
-
163
- it('fires one "user-input-changed" event on - button click', async () => {
164
- let counter = 0;
165
- const el = await fixture(html`
166
- <lion-input-stepper
167
- name="year"
168
- label="Years"
169
- @user-input-changed="${() => {
170
- counter += 1;
171
- }}"
172
- >
173
- </lion-input-stepper>
174
- `);
175
- const decrementButton = el.querySelector('[slot=prefix]');
176
- decrementButton?.dispatchEvent(new Event('click'));
177
- expect(counter).to.equal(1);
178
- });
179
-
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
- it('should update min and max attributes when min and max property change', async () => {
206
- const el = await fixture(inputStepperWithAttrs);
207
- el.min = 100;
208
- el.max = 200;
209
- await nextFrame();
210
- expect(el._inputNode.min).to.equal(el.min.toString());
211
- expect(el._inputNode.max).to.equal(el.max.toString());
212
- });
213
-
214
- it('should remove the disabled attribute of the decrement button when the min property changes to below the modelvalue', async () => {
215
- const el = await fixture(inputStepperWithAttrs);
216
- const decrementButton = el.querySelector('[slot=prefix]');
217
- el.modelValue = 100;
218
- await nextFrame();
219
- expect(decrementButton?.getAttribute('disabled')).to.equal('true');
220
- el.min = 99;
221
- await nextFrame();
222
- expect(decrementButton?.getAttribute('disabled')).to.equal(null);
223
- });
224
-
225
- it('should add the disabled attribute of the decrement button when the min property changes to the modelvalue', async () => {
226
- const el = await fixture(inputStepperWithAttrs);
227
- const decrementButton = el.querySelector('[slot=prefix]');
228
- el.modelValue = 101;
229
- await nextFrame();
230
- expect(decrementButton?.getAttribute('disabled')).to.equal(null);
231
- el.min = 101;
232
- await nextFrame();
233
- expect(decrementButton?.getAttribute('disabled')).to.equal('true');
234
- });
235
-
236
- it('should remove the disabled attribute of the increment button when the max property changes to above the modelvalue', async () => {
237
- const el = await fixture(inputStepperWithAttrs);
238
- const incrementButton = el.querySelector('[slot=suffix]');
239
- el.modelValue = 200;
240
- await nextFrame();
241
- expect(incrementButton?.getAttribute('disabled')).to.equal('true');
242
- el.max = 201;
243
- await nextFrame();
244
- expect(incrementButton?.getAttribute('disabled')).to.equal(null);
245
- });
246
-
247
- it('should add the disabled attribute of the increment button when the max property changes to the modelvalue', async () => {
248
- const el = await fixture(inputStepperWithAttrs);
249
- const incrementButton = el.querySelector('[slot=suffix]');
250
- el.modelValue = 199;
251
- await nextFrame();
252
- expect(incrementButton?.getAttribute('disabled')).to.equal(null);
253
- el.max = 199;
254
- await nextFrame();
255
- expect(incrementButton?.getAttribute('disabled')).to.equal('true');
256
- });
257
-
258
- it('should react to changes in the modelValue by adjusting the disabled state of the button', async () => {
259
- const el = await fixture(inputStepperWithAttrs);
260
- const incrementButton = el.querySelector('[slot=suffix]');
261
- el.modelValue = 199;
262
- await nextFrame();
263
- expect(incrementButton?.getAttribute('disabled')).to.equal(null);
264
- el.modelValue = 200;
265
- await nextFrame();
266
- expect(incrementButton?.getAttribute('disabled')).to.equal('true');
267
- });
268
-
269
- describe('It align to steps', () => {
270
- it('aligns the value to the nearest step when incrementing', async () => {
271
- let el = await fixture(
272
- html`<lion-input-stepper step="10" min="0" max="100" value="55"></lion-input-stepper>`,
273
- );
274
- let incrementButton = el.querySelector('[slot=suffix]');
275
- incrementButton?.dispatchEvent(new Event('click'));
276
- await el.updateComplete;
277
- expect(el.modelValue).to.equal(60, 'Fail + : (0 > 100 by 10; val 55)');
278
-
279
- // min 1
280
- el = await fixture(
281
- html`<lion-input-stepper step="10" min="1" max="100" value="55"></lion-input-stepper>`,
282
- );
283
- incrementButton = el.querySelector('[slot=suffix]');
284
- incrementButton?.dispatchEvent(new Event('click'));
285
- await el.updateComplete;
286
- expect(el.modelValue).to.equal(61, 'Fail + : (1 > 100 by 10; val 55)');
287
-
288
- // min 34
289
- el = await fixture(
290
- html`<lion-input-stepper step="10" min="34" max="100" value="55"></lion-input-stepper>`,
291
- );
292
- incrementButton = el.querySelector('[slot=suffix]');
293
- incrementButton?.dispatchEvent(new Event('click'));
294
- await el.updateComplete;
295
- expect(el.modelValue).to.equal(64, 'Fail + : (34 > 100 by 10; val 55)');
296
-
297
- // min -23
298
- el = await fixture(
299
- html`<lion-input-stepper step="10" min="-23" max="100" value="55"></lion-input-stepper>`,
300
- );
301
- incrementButton = el.querySelector('[slot=suffix]');
302
- incrementButton?.dispatchEvent(new Event('click'));
303
- await el.updateComplete;
304
- expect(el.modelValue).to.equal(57, 'Fail + : (-23 > 100 by 10; val 55)'); // -23 > -13 > -3 > 7 > ... > 57
305
-
306
- // min -23
307
- el = await fixture(
308
- html`<lion-input-stepper step="10" min="-23" max="100" value="-9"></lion-input-stepper>`,
309
- );
310
- incrementButton = el.querySelector('[slot=suffix]');
311
- incrementButton?.dispatchEvent(new Event('click'));
312
- await el.updateComplete;
313
- expect(el.modelValue).to.equal(-3, 'Fail + : (-23 > 100 by 10; val 55)'); // -23 > -13 > -3 > 7
314
- });
315
-
316
- it('aligns the value to the nearest step when decrementing', async () => {
317
- let el = await fixture(
318
- html`<lion-input-stepper step="10" min="0" max="100" value="55"></lion-input-stepper>`,
319
- );
320
- let decrementButton = el.querySelector('[slot=prefix]');
321
- decrementButton?.dispatchEvent(new Event('click'));
322
- await el.updateComplete;
323
- expect(el.modelValue).to.equal(50, 'Fail - : (0 > 100 by 10; val 55)');
324
-
325
- // min 1
326
- el = await fixture(
327
- html`<lion-input-stepper step="10" min="1" max="100" value="55"></lion-input-stepper>`,
328
- );
329
- decrementButton = el.querySelector('[slot=prefix]');
330
- decrementButton?.dispatchEvent(new Event('click'));
331
- await el.updateComplete;
332
- expect(el.modelValue).to.equal(51, 'Fail - : (1 > 100 by 10; val 55)');
333
-
334
- // min 34
335
- el = await fixture(
336
- html`<lion-input-stepper step="10" min="34" max="100" value="55"></lion-input-stepper>`,
337
- );
338
- decrementButton = el.querySelector('[slot=prefix]');
339
- decrementButton?.dispatchEvent(new Event('click'));
340
- await el.updateComplete;
341
- expect(el.modelValue).to.equal(54, 'Fail - : (34 > 100 by 10; val 55)');
342
-
343
- // min -23
344
- el = await fixture(
345
- html`<lion-input-stepper step="10" min="-23" max="100" value="55"></lion-input-stepper>`,
346
- );
347
- decrementButton = el.querySelector('[slot=prefix]');
348
- decrementButton?.dispatchEvent(new Event('click'));
349
- await el.updateComplete;
350
- expect(el.modelValue).to.equal(47, 'Fail - : (-23 > 100 by 10; val 55)'); // -23 > -13 > -3 > 7 > ... > 47
351
-
352
- // min -23
353
- el = await fixture(
354
- html`<lion-input-stepper step="10" min="-23" max="100" value="-9"></lion-input-stepper>`,
355
- );
356
- decrementButton = el.querySelector('[slot=prefix]');
357
- decrementButton?.dispatchEvent(new Event('click'));
358
- await el.updateComplete;
359
- expect(el.modelValue).to.equal(-13, 'Fail - : (-23 > 100 by 10; val 55)'); // -23 > -13 > -3 > 7
360
- });
361
- });
362
- });
363
-
364
- describe('Accessibility', () => {
365
- it('is a11y AXE accessible', async () => {
366
- const el = await fixture(defaultInputStepper);
367
- await expect(el).to.be.accessible();
368
- });
369
-
370
- it('is accessible when disabled', async () => {
371
- const el = await fixture(`<lion-input-stepper label="rsvp" disabled></lion-input-stepper>`);
372
- await expect(el).to.be.accessible();
373
- });
374
-
375
- it('has role="spinbutton"', async () => {
376
- const el = await fixture(defaultInputStepper);
377
- expect(el._inputNode.hasAttribute('role')).to.be.true;
378
- expect(el._inputNode.getAttribute('role')).to.equal('spinbutton');
379
- });
380
-
381
- it('updates aria-valuenow when stepper is changed', async () => {
382
- const el = await fixture(defaultInputStepper);
383
- el.modelValue = 1;
384
-
385
- await el.updateComplete;
386
- expect(el._inputNode.hasAttribute('aria-valuenow')).to.be.true;
387
- expect(el._inputNode.getAttribute('aria-valuenow')).to.equal('1');
388
-
389
- el.modelValue = '';
390
- await el.updateComplete;
391
- expect(el._inputNode.hasAttribute('aria-valuenow')).to.be.false;
392
- });
393
-
394
- it('updates aria-valuetext when stepper is changed', async () => {
395
- // VoiceOver announces percentages once the valuemin or valuemax are used.
396
- // This can be fixed by setting valuetext to the same value as valuenow
397
- // https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Attributes/aria-valuenow
398
- const el = await fixture(defaultInputStepper);
399
- el.modelValue = 1;
400
- await el.updateComplete;
401
-
402
- expect(el._inputNode.hasAttribute('aria-valuetext')).to.be.true;
403
- expect(el._inputNode.getAttribute('aria-valuetext')).to.equal('1');
404
-
405
- el.modelValue = '';
406
- await el.updateComplete;
407
- expect(el._inputNode.hasAttribute('aria-valuetext')).to.be.false;
408
- });
409
-
410
- it('can give aria-valuetext to override default value as a human-readable text alternative', async () => {
411
- const values = {
412
- 1: 'first',
413
- 2: 'second',
414
- 3: 'third',
415
- };
416
- const el = await fixture(html`
417
- <lion-input-stepper min="1" max="3" .valueTextMapping="${values}"></lion-input-stepper>
418
- `);
419
- el.modelValue = 1;
420
- await el.updateComplete;
421
- expect(el._inputNode.hasAttribute('aria-valuetext')).to.be.true;
422
- expect(el._inputNode.getAttribute('aria-valuetext')).to.equal('first');
423
- });
424
-
425
- it('updates aria-valuemin when stepper is changed', async () => {
426
- const el = await fixture(inputStepperWithAttrs);
427
- const incrementButton = el.querySelector('[slot=suffix]');
428
- incrementButton?.dispatchEvent(new Event('click'));
429
- expect(el._inputNode.hasAttribute('aria-valuemin')).to.be.true;
430
- expect(el._inputNode.getAttribute('aria-valuemin')).to.equal('100');
431
-
432
- el.min = 0;
433
- await el.updateComplete;
434
- expect(el._inputNode.hasAttribute('aria-valuemin')).to.be.true;
435
- expect(el._inputNode.getAttribute('aria-valuemin')).to.equal('0');
436
- });
437
-
438
- it('updates aria-valuemax when stepper is changed', async () => {
439
- const el = await fixture(inputStepperWithAttrs);
440
- const incrementButton = el.querySelector('[slot=suffix]');
441
- incrementButton?.dispatchEvent(new Event('click'));
442
- expect(el._inputNode.hasAttribute('aria-valuemax')).to.be.true;
443
- expect(el._inputNode.getAttribute('aria-valuemax')).to.equal('200');
444
-
445
- el.max = 1000;
446
- await el.updateComplete;
447
- expect(el._inputNode.hasAttribute('aria-valuemax')).to.be.true;
448
- expect(el._inputNode.getAttribute('aria-valuemax')).to.equal('1000');
449
- });
450
-
451
- it('when decrease button gets focus, it sets aria-live to input-stepper__value', async () => {
452
- const el = await fixture(inputStepperWithAttrs);
453
- const stepperValue = el.shadowRoot?.querySelector('.input-stepper__value');
454
- const decrementButton = el.querySelector('[slot=prefix]');
455
-
456
- decrementButton?.dispatchEvent(new Event('focus'));
457
- expect(stepperValue?.hasAttribute('aria-live')).to.be.true;
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;
462
- });
463
-
464
- it('when increase button gets focus, it sets aria-live to input-stepper__value', async () => {
465
- const el = await fixture(inputStepperWithAttrs);
466
- const stepperValue = el.shadowRoot?.querySelector('.input-stepper__value');
467
- const incrementButton = el.querySelector('[slot=suffix]');
468
-
469
- incrementButton?.dispatchEvent(new Event('focus'));
470
- expect(stepperValue?.hasAttribute('aria-live')).to.be.true;
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;
475
- });
476
- });
477
- });
3
+ runInputStepperSuite();
@@ -0,0 +1,19 @@
1
+ import { defineCE } from '@open-wc/testing';
2
+ import {
3
+ runInteractionStateMixinSuite,
4
+ runFormatMixinSuite,
5
+ } from '@lion/ui/form-core-test-suites.js';
6
+ import { LionInputStepper } from '../src/LionInputStepper.js';
7
+
8
+ export const runInputStepperIntegrationSuite = (klass = LionInputStepper) => {
9
+ const tagString = defineCE(class extends klass {});
10
+ runInteractionStateMixinSuite({
11
+ tagString,
12
+ allowedModelValueTypes: [Number],
13
+ });
14
+
15
+ runFormatMixinSuite({
16
+ tagString,
17
+ modelValueType: Number,
18
+ });
19
+ };