@ons/design-system 50.0.0 → 52.0.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.
Files changed (166) hide show
  1. package/README.md +35 -15
  2. package/components/access-code/_macro.njk +1 -1
  3. package/components/access-code/_macro.spec.js +162 -0
  4. package/components/access-code/uac.spec.js +26 -0
  5. package/components/accordion/_macro.spec.js +224 -0
  6. package/components/accordion/accordion.spec.js +134 -0
  7. package/components/address-input/_macro.njk +1 -1
  8. package/components/address-input/_macro.spec.js +465 -0
  9. package/components/address-input/autosuggest.address.js +5 -4
  10. package/components/address-input/autosuggest.address.setter.js +9 -3
  11. package/components/address-input/autosuggest.address.spec.js +733 -0
  12. package/components/address-output/_macro.njk +6 -6
  13. package/components/address-output/_macro.spec.js +122 -0
  14. package/components/autosuggest/_macro.njk +1 -1
  15. package/components/autosuggest/_macro.spec.js +229 -0
  16. package/components/autosuggest/autosuggest.helpers.js +2 -3
  17. package/components/autosuggest/autosuggest.helpers.spec.js +85 -0
  18. package/components/autosuggest/autosuggest.js +4 -2
  19. package/components/autosuggest/autosuggest.spec.js +625 -0
  20. package/components/autosuggest/autosuggest.ui.js +6 -2
  21. package/components/breadcrumbs/_macro.spec.js +129 -0
  22. package/components/button/_macro.njk +5 -5
  23. package/components/button/_macro.spec.js +446 -0
  24. package/components/button/button.spec.js +290 -0
  25. package/components/call-to-action/_macro.njk +3 -1
  26. package/components/call-to-action/_macro.spec.js +52 -0
  27. package/components/card/_macro.njk +26 -19
  28. package/components/card/_macro.spec.js +261 -0
  29. package/components/char-check-limit/_macro.spec.js +73 -0
  30. package/components/char-check-limit/character-check.spec.js +196 -0
  31. package/components/char-check-limit/character-limit.js +1 -1
  32. package/components/checkboxes/_checkbox-macro.spec.js +419 -0
  33. package/components/checkboxes/_macro.njk +1 -3
  34. package/components/checkboxes/_macro.spec.js +306 -0
  35. package/components/checkboxes/checkbox-with-autoselect.js +2 -1
  36. package/components/checkboxes/checkboxes.spec.js +208 -0
  37. package/components/code-highlight/_macro.spec.js +56 -0
  38. package/components/code-highlight/code-highlight.spec.js +18 -0
  39. package/components/collapsible/_macro.spec.js +204 -0
  40. package/components/collapsible/collapsible.js +2 -1
  41. package/components/collapsible/collapsible.spec.js +236 -0
  42. package/components/content-pagination/_macro.spec.js +199 -0
  43. package/components/cookies-banner/_macro.njk +1 -1
  44. package/components/cookies-banner/_macro.spec.js +171 -0
  45. package/components/cookies-banner/cookies-banner.spec.js +90 -0
  46. package/components/date-input/_macro.njk +6 -3
  47. package/components/date-input/_macro.spec.js +286 -0
  48. package/components/document-list/_macro.njk +3 -5
  49. package/components/document-list/_macro.spec.js +491 -0
  50. package/components/download-resources/download-resources.spec.js +540 -0
  51. package/components/duration/_macro.njk +7 -6
  52. package/components/duration/_macro.spec.js +251 -0
  53. package/components/error/_macro.spec.js +97 -0
  54. package/components/external-link/_macro.spec.js +60 -0
  55. package/components/feedback/_macro.njk +5 -3
  56. package/components/feedback/_macro.spec.js +122 -0
  57. package/components/field/_macro.njk +2 -2
  58. package/components/field/_macro.spec.js +97 -0
  59. package/components/fieldset/_macro.njk +3 -3
  60. package/components/fieldset/_macro.spec.js +173 -0
  61. package/components/footer/_macro.njk +12 -49
  62. package/components/footer/_macro.spec.js +549 -0
  63. package/components/header/_macro.njk +3 -3
  64. package/components/header/_macro.spec.js +562 -0
  65. package/components/hero/_hero.scss +0 -3
  66. package/components/hero/_macro.njk +4 -4
  67. package/components/hero/_macro.spec.js +224 -0
  68. package/components/icons/_macro.njk +15 -15
  69. package/components/icons/_macro.spec.js +140 -0
  70. package/components/images/_macro.njk +1 -1
  71. package/components/images/_macro.spec.js +121 -0
  72. package/components/input/_input-type.scss +12 -5
  73. package/components/input/_macro.njk +4 -5
  74. package/components/input/_macro.spec.js +658 -0
  75. package/components/label/_macro.spec.js +189 -0
  76. package/components/language-selector/_macro.spec.js +129 -0
  77. package/components/lists/_list.scss +4 -0
  78. package/components/lists/_macro.njk +4 -7
  79. package/components/lists/_macro.spec.js +618 -0
  80. package/components/message/_macro.spec.js +137 -0
  81. package/components/message-list/_macro.njk +7 -7
  82. package/components/message-list/_macro.spec.js +159 -0
  83. package/components/metadata/_macro.spec.js +167 -0
  84. package/components/modal/_macro.njk +6 -6
  85. package/components/modal/_macro.spec.js +87 -0
  86. package/components/modal/modal.js +0 -16
  87. package/components/modal/modal.spec.js +59 -0
  88. package/components/mutually-exclusive/_macro.njk +2 -2
  89. package/components/mutually-exclusive/_macro.spec.js +184 -0
  90. package/components/mutually-exclusive/mutually-exclusive.checkboxes.spec.js +203 -0
  91. package/components/mutually-exclusive/mutually-exclusive.date.spec.js +142 -0
  92. package/components/mutually-exclusive/mutually-exclusive.duration.spec.js +141 -0
  93. package/components/mutually-exclusive/mutually-exclusive.email.spec.js +117 -0
  94. package/components/mutually-exclusive/mutually-exclusive.multiple-options.checkboxes.spec.js +213 -0
  95. package/components/mutually-exclusive/mutually-exclusive.number.spec.js +125 -0
  96. package/components/mutually-exclusive/mutually-exclusive.textarea.spec.js +131 -0
  97. package/components/navigation/_macro.njk +6 -6
  98. package/components/navigation/_macro.spec.js +327 -0
  99. package/components/navigation/navigation.dom.js +1 -1
  100. package/components/navigation/navigation.spec.js +232 -0
  101. package/components/pagination/_macro.njk +1 -1
  102. package/components/pagination/_macro.spec.js +411 -0
  103. package/components/panel/_macro.njk +6 -6
  104. package/components/panel/_macro.spec.js +423 -0
  105. package/components/password/_macro.spec.js +137 -0
  106. package/components/password/password.spec.js +40 -0
  107. package/components/phase-banner/_macro.spec.js +73 -0
  108. package/components/promotional-banner/_macro.spec.js +97 -0
  109. package/components/question/_macro.njk +16 -22
  110. package/components/question/_macro.spec.js +309 -0
  111. package/components/quote/_macro.spec.js +81 -0
  112. package/components/radios/_macro.njk +3 -6
  113. package/components/radios/_macro.spec.js +575 -0
  114. package/components/radios/radios.spec.js +180 -0
  115. package/components/related-content/_macro.njk +1 -0
  116. package/components/related-content/_macro.spec.js +142 -0
  117. package/components/relationships/_macro.spec.js +108 -0
  118. package/components/relationships/relationships.spec.js +84 -0
  119. package/components/reply/_macro.njk +2 -2
  120. package/components/reply/_macro.spec.js +69 -0
  121. package/components/reply/reply.spec.js +78 -0
  122. package/components/search/_macro.njk +14 -12
  123. package/components/search/_macro.spec.js +44 -0
  124. package/components/search/_search.scss +7 -7
  125. package/components/section-navigation/_macro.njk +7 -2
  126. package/components/section-navigation/_macro.spec.js +206 -0
  127. package/components/select/_macro.njk +3 -3
  128. package/components/select/_macro.spec.js +203 -0
  129. package/components/select/select.spec.js +56 -0
  130. package/components/share-page/_macro.njk +2 -2
  131. package/components/share-page/_macro.spec.js +110 -0
  132. package/components/skip-to-content/_macro.spec.js +57 -0
  133. package/components/skip-to-content/skip-to-content.spec.js +44 -0
  134. package/components/status/_macro.spec.js +77 -0
  135. package/components/summary/_macro.njk +5 -5
  136. package/components/summary/_macro.spec.js +472 -0
  137. package/components/table/_macro.njk +2 -2
  138. package/components/table/_macro.spec.js +557 -0
  139. package/components/table/table.spec.js +155 -0
  140. package/components/table-of-contents/_macro.njk +35 -35
  141. package/components/table-of-contents/_macro.spec.js +178 -0
  142. package/components/table-of-contents/toc.js +29 -25
  143. package/components/table-of-contents/toc.spec.js +61 -0
  144. package/components/tabs/_macro.njk +1 -1
  145. package/components/tabs/_macro.spec.js +79 -0
  146. package/components/tabs/tabs.spec.js +162 -0
  147. package/components/text-indent/_macro.spec.js +52 -0
  148. package/components/textarea/_macro.njk +5 -3
  149. package/components/textarea/_macro.spec.js +300 -0
  150. package/components/textarea/textarea.spec.js +98 -0
  151. package/components/timeline/_macro.njk +3 -3
  152. package/components/timeline/_macro.spec.js +81 -0
  153. package/components/timeout-modal/_macro.spec.js +68 -0
  154. package/components/timeout-modal/timeout-modal.spec.js +226 -0
  155. package/components/timeout-panel/_macro.njk +0 -1
  156. package/components/timeout-panel/_macro.spec.js +54 -0
  157. package/components/timeout-panel/timeout-panel.dom.js +1 -2
  158. package/components/timeout-panel/timeout-panel.spec.js +161 -0
  159. package/components/upload/_macro.spec.js +75 -0
  160. package/components/video/_macro.spec.js +34 -0
  161. package/css/census.css +1 -1
  162. package/css/main.css +1 -1
  163. package/js/cookies-settings.spec.js +154 -0
  164. package/package.json +10 -23
  165. package/scripts/main.es5.js +1 -1
  166. package/scripts/main.js +2 -2
@@ -0,0 +1,618 @@
1
+ /** @jest-environment jsdom */
2
+
3
+ import * as cheerio from 'cheerio';
4
+
5
+ import axe from '../../tests/helpers/axe';
6
+ import { renderComponent, templateFaker } from '../../tests/helpers/rendering';
7
+
8
+ const EXAMPLE_LIST_TEXT_ITEMS = {
9
+ itemsList: [{ text: 'First item' }, { text: 'Second item' }],
10
+ };
11
+
12
+ const EXAMPLE_ITEM_TEXT = {
13
+ text: 'Text item with <strong>markup</strong>',
14
+ };
15
+
16
+ const EXAMPLE_ITEM_ARTICLE_TITLE = {
17
+ title: 'Article title',
18
+ };
19
+
20
+ const EXAMPLE_ITEM_NAVIGATION_TITLE = {
21
+ title: 'Long article title',
22
+ navigationTitle: 'Nav friendly title',
23
+ };
24
+
25
+ describe('macro: lists', () => {
26
+ describe('list element', () => {
27
+ it('has `id` attribute when provided', () => {
28
+ const $ = cheerio.load(
29
+ renderComponent('lists', {
30
+ ...EXAMPLE_LIST_TEXT_ITEMS,
31
+ id: 'example-id',
32
+ }),
33
+ );
34
+
35
+ expect($('.ons-list').attr('id')).toBe('example-id');
36
+ });
37
+
38
+ it('has additionally provided style classes', () => {
39
+ const $ = cheerio.load(
40
+ renderComponent('lists', {
41
+ ...EXAMPLE_LIST_TEXT_ITEMS,
42
+ classes: 'extra-class another-extra-class',
43
+ }),
44
+ );
45
+
46
+ expect($('.ons-list').hasClass('extra-class')).toBe(true);
47
+ expect($('.ons-list').hasClass('another-extra-class')).toBe(true);
48
+ });
49
+
50
+ it('has provided variant style class when one variant is provided', () => {
51
+ const $ = cheerio.load(
52
+ renderComponent('lists', {
53
+ ...EXAMPLE_LIST_TEXT_ITEMS,
54
+ variants: 'dashed',
55
+ }),
56
+ );
57
+
58
+ expect($('.ons-list').hasClass('ons-list--dashed')).toBe(true);
59
+ });
60
+
61
+ it('has provided variant style classes when multiple variants are provided', () => {
62
+ const $ = cheerio.load(
63
+ renderComponent('lists', {
64
+ ...EXAMPLE_LIST_TEXT_ITEMS,
65
+ variants: ['dashed', 'inline'],
66
+ }),
67
+ );
68
+
69
+ expect($('.ons-list').hasClass('ons-list--dashed')).toBe(true);
70
+ expect($('.ons-list').hasClass('ons-list--inline')).toBe(true);
71
+ });
72
+
73
+ it('assumes the "bare" variant with a prefix modifier class when the first list item has a prefix', () => {
74
+ const $ = cheerio.load(
75
+ renderComponent('lists', {
76
+ itemsList: [{ text: 'Item text', prefix: 'Abc' }],
77
+ }),
78
+ );
79
+
80
+ expect($('.ons-list').hasClass('ons-list--bare')).toBe(true);
81
+ expect($('.ons-list').hasClass('ons-list--prefix')).toBe(true);
82
+ });
83
+
84
+ it('assumes the "bare" variant with a suffix modifier class when the first list item has a suffix', () => {
85
+ const $ = cheerio.load(
86
+ renderComponent('lists', {
87
+ itemsList: [{ text: 'Item text', suffix: 'Abc' }],
88
+ }),
89
+ );
90
+
91
+ expect($('.ons-list').hasClass('ons-list--bare')).toBe(true);
92
+ expect($('.ons-list').hasClass('ons-list--suffix')).toBe(true);
93
+ });
94
+
95
+ it('assumes the "bare" variant with a icons modifier class when the first list item has an icon', () => {
96
+ const $ = cheerio.load(
97
+ renderComponent('lists', {
98
+ ...EXAMPLE_LIST_TEXT_ITEMS,
99
+ iconPosition: 'before',
100
+ iconType: 'check',
101
+ }),
102
+ );
103
+
104
+ expect($('.ons-list').hasClass('ons-list--bare')).toBe(true);
105
+ expect($('.ons-list').hasClass('ons-list--icons')).toBe(true);
106
+ });
107
+
108
+ it('renders a <ul> element by default', () => {
109
+ const $ = cheerio.load(renderComponent('lists', EXAMPLE_LIST_TEXT_ITEMS));
110
+
111
+ expect($('.ons-list')[0].tagName).toBe('ul');
112
+ });
113
+
114
+ it('renders a custom element when a custom `element` is provided', () => {
115
+ const $ = cheerio.load(
116
+ renderComponent('lists', {
117
+ ...EXAMPLE_LIST_TEXT_ITEMS,
118
+ element: 'div',
119
+ }),
120
+ );
121
+
122
+ expect($('.ons-list')[0].tagName).toBe('div');
123
+ });
124
+
125
+ it('renders a <ol> element when specified', () => {
126
+ const $ = cheerio.load(
127
+ renderComponent('lists', {
128
+ ...EXAMPLE_LIST_TEXT_ITEMS,
129
+ element: 'ol',
130
+ }),
131
+ );
132
+
133
+ expect($('.ons-list')[0].tagName).toBe('ol');
134
+ });
135
+
136
+ it('has the expected quantity of <li> elements when a <ol> element is specified', () => {
137
+ const $ = cheerio.load(
138
+ renderComponent('lists', {
139
+ ...EXAMPLE_LIST_TEXT_ITEMS,
140
+ element: 'ol',
141
+ }),
142
+ );
143
+
144
+ expect($('.ons-list li').length).toBe(2);
145
+ });
146
+
147
+ describe('when <ol> is specified but there is only one list item', () => {
148
+ const $ = cheerio.load(
149
+ renderComponent('lists', {
150
+ element: 'ol',
151
+ itemsList: [{ text: 'Only item' }],
152
+ }),
153
+ );
154
+
155
+ it('renders a <p> element', () => {
156
+ expect($('.ons-list')[0].tagName).toBe('p');
157
+ });
158
+
159
+ it('has `ons-list--p` modifier class', () => {
160
+ expect($('.ons-list').hasClass('ons-list--p')).toBe(true);
161
+ });
162
+
163
+ it('does not output any <li> elements', () => {
164
+ expect($('.ons-list li').length).toBe(0);
165
+ });
166
+ });
167
+
168
+ it('has additionally provided `attributes`', () => {
169
+ const $ = cheerio.load(
170
+ renderComponent('lists', {
171
+ ...EXAMPLE_LIST_TEXT_ITEMS,
172
+ attributes: {
173
+ a: 123,
174
+ b: 456,
175
+ },
176
+ }),
177
+ );
178
+
179
+ expect($('.ons-list').attr('a')).toBe('123');
180
+ expect($('.ons-list').attr('b')).toBe('456');
181
+ });
182
+ });
183
+
184
+ describe.each([
185
+ ['text', EXAMPLE_ITEM_TEXT, 'Text item with <strong>markup</strong>'],
186
+ ['article title', EXAMPLE_ITEM_ARTICLE_TITLE, 'Article title'],
187
+ ['navigation title', EXAMPLE_ITEM_NAVIGATION_TITLE, 'Nav friendly title'],
188
+ ])('with %s', (_, item, expectedItemText) => {
189
+ describe('content without link', () => {
190
+ it('passes jest-axe checks', async () => {
191
+ const $ = cheerio.load(
192
+ renderComponent('lists', {
193
+ itemsList: [item],
194
+ }),
195
+ );
196
+
197
+ const results = await axe($.html());
198
+ expect(results).toHaveNoViolations();
199
+ });
200
+
201
+ it('renders the expected list item text', () => {
202
+ const $ = cheerio.load(
203
+ renderComponent('lists', {
204
+ itemsList: [item],
205
+ }),
206
+ );
207
+
208
+ expect($.html()).toContain(expectedItemText);
209
+ });
210
+
211
+ it('does not render a hyperlink element', () => {
212
+ const $ = cheerio.load(
213
+ renderComponent('lists', {
214
+ itemsList: [item],
215
+ }),
216
+ );
217
+
218
+ expect($('a').length).toBe(0);
219
+ });
220
+ });
221
+
222
+ describe('content with an internal link', () => {
223
+ it('passes jest-axe checks', async () => {
224
+ const $ = cheerio.load(
225
+ renderComponent('lists', {
226
+ itemsList: [
227
+ {
228
+ ...item,
229
+ url: '/internal-link',
230
+ },
231
+ ],
232
+ }),
233
+ );
234
+
235
+ const results = await axe($.html());
236
+ expect(results).toHaveNoViolations();
237
+ });
238
+
239
+ it('renders a hyperlink element', () => {
240
+ const $ = cheerio.load(
241
+ renderComponent('lists', {
242
+ itemsList: [
243
+ {
244
+ ...item,
245
+ url: '/internal-link',
246
+ },
247
+ ],
248
+ }),
249
+ );
250
+
251
+ expect($('.ons-list__link').is('a')).toBe(true);
252
+ expect($('.ons-list__link').attr('href')).toBe('/internal-link');
253
+ });
254
+
255
+ it('does not render a hyperlink element for current item', () => {
256
+ const $ = cheerio.load(
257
+ renderComponent('lists', {
258
+ itemsList: [
259
+ {
260
+ ...item,
261
+ url: '/internal-link',
262
+ current: true,
263
+ },
264
+ ],
265
+ }),
266
+ );
267
+
268
+ expect($('a').length).toBe(0);
269
+ });
270
+
271
+ it('supports the `inPageLink` variant', () => {
272
+ const $ = cheerio.load(
273
+ renderComponent('lists', {
274
+ itemsList: [
275
+ {
276
+ ...item,
277
+ url: '/internal-link',
278
+ variants: 'inPageLink',
279
+ },
280
+ ],
281
+ }),
282
+ );
283
+
284
+ expect($('.ons-list__link').hasClass('ons-js-inpagelink')).toBe(true);
285
+ });
286
+
287
+ it('has additionally provided style classes', () => {
288
+ const $ = cheerio.load(
289
+ renderComponent('lists', {
290
+ itemsList: [
291
+ {
292
+ ...item,
293
+ url: '/internal-link',
294
+ classes: 'extra-class another-extra-class',
295
+ },
296
+ ],
297
+ }),
298
+ );
299
+
300
+ expect($('.ons-list__link').hasClass('extra-class')).toBe(true);
301
+ expect($('.ons-list__link').hasClass('another-extra-class')).toBe(true);
302
+ });
303
+
304
+ it('has the provided `target` attribute', () => {
305
+ const $ = cheerio.load(
306
+ renderComponent('lists', {
307
+ itemsList: [
308
+ {
309
+ ...item,
310
+ url: '/internal-link',
311
+ target: '_blank',
312
+ },
313
+ ],
314
+ }),
315
+ );
316
+
317
+ expect($('.ons-list__link').attr('target')).toBe('_blank');
318
+ });
319
+
320
+ it('renders visually hidden screen reader message when target is "_blank"', () => {
321
+ const $ = cheerio.load(
322
+ renderComponent('lists', {
323
+ itemsList: [
324
+ {
325
+ ...item,
326
+ url: '/internal-link',
327
+ target: '_blank',
328
+ screenreaderMessage: 'opens in a new tab',
329
+ },
330
+ ],
331
+ }),
332
+ );
333
+
334
+ expect($('.ons-list__link .ons-u-vh').text()).toBe('opens in a new tab');
335
+ });
336
+
337
+ it('renders a default visually hidden screen reader message when target is "_blank"', () => {
338
+ const $ = cheerio.load(
339
+ renderComponent('lists', {
340
+ itemsList: [
341
+ {
342
+ ...item,
343
+ url: '/internal-link',
344
+ target: '_blank',
345
+ },
346
+ ],
347
+ }),
348
+ );
349
+
350
+ expect($('.ons-list__link .ons-u-vh').text()).toBe('this link will open in a new tab');
351
+ });
352
+
353
+ it('has additionally provided `attributes`', () => {
354
+ const $ = cheerio.load(
355
+ renderComponent('lists', {
356
+ itemsList: [
357
+ {
358
+ ...item,
359
+ url: '/internal-link',
360
+ attributes: {
361
+ a: 123,
362
+ b: 456,
363
+ },
364
+ },
365
+ ],
366
+ }),
367
+ );
368
+
369
+ expect($('.ons-list__link').attr('a')).toBe('123');
370
+ expect($('.ons-list__link').attr('b')).toBe('456');
371
+ });
372
+
373
+ it('renders visually hidden prefix', () => {
374
+ const $ = cheerio.load(
375
+ renderComponent('lists', {
376
+ itemsList: [
377
+ {
378
+ ...item,
379
+ url: '/internal-link',
380
+ prefix: 'item prefix',
381
+ },
382
+ ],
383
+ }),
384
+ );
385
+
386
+ expect($('.ons-list__link .ons-u-vh').text()).toBe('item prefix');
387
+ });
388
+ });
389
+
390
+ describe('content with an external link', () => {
391
+ it('passes jest-axe checks', async () => {
392
+ const $ = cheerio.load(
393
+ renderComponent('lists', {
394
+ itemsList: [
395
+ {
396
+ ...item,
397
+ url: 'https://example.com/external-link',
398
+ external: true,
399
+ },
400
+ ],
401
+ }),
402
+ );
403
+
404
+ const results = await axe($.html());
405
+ expect(results).toHaveNoViolations();
406
+ });
407
+
408
+ it('uses the `external-link` component to render external links', () => {
409
+ const faker = templateFaker();
410
+ const externalLinkSpy = faker.spy('external-link');
411
+
412
+ faker.renderComponent('lists', {
413
+ itemsList: [
414
+ {
415
+ ...item,
416
+ url: 'https://example.com/external-link',
417
+ external: true,
418
+ },
419
+ ],
420
+ });
421
+
422
+ expect(externalLinkSpy.occurrences[0]).toEqual({
423
+ url: 'https://example.com/external-link',
424
+ linkText: expectedItemText,
425
+ });
426
+ });
427
+
428
+ it('does not use the `external-link` component to render the current item', () => {
429
+ const faker = templateFaker();
430
+ const externalLinkSpy = faker.spy('external-link');
431
+
432
+ faker.renderComponent('lists', {
433
+ itemsList: [
434
+ {
435
+ ...item,
436
+ url: 'https://example.com/external-link',
437
+ external: true,
438
+ current: true,
439
+ },
440
+ ],
441
+ });
442
+
443
+ expect(externalLinkSpy.occurrences.length).toBe(0);
444
+ });
445
+ });
446
+ });
447
+
448
+ describe('prefix', () => {
449
+ it('renders item `prefix` content', () => {
450
+ const $ = cheerio.load(
451
+ renderComponent('lists', {
452
+ itemsList: [
453
+ {
454
+ prefix: '[PREFIX]',
455
+ text: 'Item text',
456
+ },
457
+ ],
458
+ }),
459
+ );
460
+
461
+ expect(
462
+ $('.ons-list__prefix')
463
+ .text()
464
+ .trim(),
465
+ ).toBe('[PREFIX].');
466
+ });
467
+
468
+ it('marks `prefix` content as visually hidden when list element is not <ol>', () => {
469
+ const $ = cheerio.load(
470
+ renderComponent('lists', {
471
+ itemsList: [
472
+ {
473
+ prefix: '[PREFIX]',
474
+ text: 'Item text',
475
+ },
476
+ ],
477
+ }),
478
+ );
479
+
480
+ expect($('.ons-list__prefix').attr('aria-hidden')).toBe('true');
481
+ });
482
+
483
+ it('does not mark `prefix` content as visually hidden when list element is <ol>', () => {
484
+ const $ = cheerio.load(
485
+ renderComponent('lists', {
486
+ element: 'ol',
487
+ itemsList: [
488
+ {
489
+ prefix: '[PREFIX]',
490
+ text: 'Item text 1',
491
+ },
492
+ {
493
+ prefix: '[PREFIX]',
494
+ text: 'Item text 2',
495
+ },
496
+ ],
497
+ }),
498
+ );
499
+
500
+ expect($('.ons-list__prefix').attr('aria-hidden')).toBeUndefined();
501
+ });
502
+ });
503
+
504
+ describe('suffix', () => {
505
+ it('renders item `suffix` content', () => {
506
+ const $ = cheerio.load(
507
+ renderComponent('lists', {
508
+ itemsList: [
509
+ {
510
+ suffix: '[SUFFIX]',
511
+ text: 'Item text',
512
+ },
513
+ ],
514
+ }),
515
+ );
516
+
517
+ expect(
518
+ $('.ons-list__suffix')
519
+ .text()
520
+ .trim(),
521
+ ).toBe('[SUFFIX]');
522
+ });
523
+
524
+ it('marks `suffix` content as visually hidden when list element is not <ol>', () => {
525
+ const $ = cheerio.load(
526
+ renderComponent('lists', {
527
+ itemsList: [
528
+ {
529
+ suffix: '[SUFFIX]',
530
+ text: 'Item text',
531
+ },
532
+ ],
533
+ }),
534
+ );
535
+
536
+ expect($('.ons-list__suffix').attr('aria-hidden')).toBe('true');
537
+ });
538
+
539
+ it('does not mark `suffix` content as visually hidden when list element is <ol>', () => {
540
+ const $ = cheerio.load(
541
+ renderComponent('lists', {
542
+ element: 'ol',
543
+ itemsList: [
544
+ {
545
+ suffix: '[SUFFIX]',
546
+ text: 'Item text 1',
547
+ },
548
+ {
549
+ suffix: '[SUFFIX]',
550
+ text: 'Item text 2',
551
+ },
552
+ ],
553
+ }),
554
+ );
555
+
556
+ expect($('.ons-list__suffix').attr('aria-hidden')).toBeUndefined();
557
+ });
558
+ });
559
+
560
+ describe('icons', () => {
561
+ it.each([['before'], ['after']])('renders default icon on list items when icon is positioned %s', iconPosition => {
562
+ const faker = templateFaker();
563
+ const iconsSpy = faker.spy('icons');
564
+
565
+ faker.renderComponent('lists', {
566
+ ...EXAMPLE_LIST_TEXT_ITEMS,
567
+ iconPosition,
568
+ iconType: 'check',
569
+ iconSize: 'xl',
570
+ });
571
+
572
+ expect(iconsSpy.occurrences[0]).toEqual({ iconType: 'check', iconSize: 'xl' });
573
+ expect(iconsSpy.occurrences[1]).toEqual({ iconType: 'check', iconSize: 'xl' });
574
+ });
575
+
576
+ it.each([['before'], ['after']])('renders a custom icon on specific list items when icon is positioned %s', iconPosition => {
577
+ const faker = templateFaker();
578
+ const iconsSpy = faker.spy('icons');
579
+
580
+ faker.renderComponent('lists', {
581
+ itemsList: [{ text: 'First item' }, { text: 'Second item', iconType: 'print' }, { text: 'Third item' }],
582
+ iconPosition,
583
+ iconType: 'check',
584
+ iconSize: 'xxl',
585
+ });
586
+
587
+ expect(iconsSpy.occurrences[0]).toEqual({ iconType: 'check', iconSize: 'xxl' });
588
+ expect(iconsSpy.occurrences[1]).toEqual({ iconType: 'print', iconSize: 'xxl' });
589
+ expect(iconsSpy.occurrences[2]).toEqual({ iconType: 'check', iconSize: 'xxl' });
590
+ });
591
+
592
+ it('renders the icon before the item text', () => {
593
+ const $ = cheerio.load(
594
+ renderComponent('lists', {
595
+ itemsList: [{ text: '<span id="first">First item</span>' }, { text: '<span id="second">Second item</span>' }],
596
+ iconPosition: 'before',
597
+ iconType: 'check',
598
+ iconSize: 'xl',
599
+ }),
600
+ );
601
+
602
+ expect($('.ons-list__prefix + #first').length).toBe(1);
603
+ });
604
+
605
+ it('renders the icon after the item text', () => {
606
+ const $ = cheerio.load(
607
+ renderComponent('lists', {
608
+ itemsList: [{ text: '<span id="first">First item</span>' }, { text: '<span id="second">Second item</span>' }],
609
+ iconPosition: 'after',
610
+ iconType: 'check',
611
+ iconSize: 'xl',
612
+ }),
613
+ );
614
+
615
+ expect($('#first + .ons-list__suffix').length).toBe(1);
616
+ });
617
+ });
618
+ });