@ons/design-system 50.0.1 → 51.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 (164) hide show
  1. package/README.md +35 -13
  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 +3 -1
  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/checkboxes.spec.js +208 -0
  36. package/components/code-highlight/_macro.spec.js +56 -0
  37. package/components/code-highlight/code-highlight.spec.js +18 -0
  38. package/components/collapsible/_macro.spec.js +204 -0
  39. package/components/collapsible/collapsible.js +2 -1
  40. package/components/collapsible/collapsible.spec.js +236 -0
  41. package/components/content-pagination/_macro.spec.js +199 -0
  42. package/components/cookies-banner/_macro.njk +1 -1
  43. package/components/cookies-banner/_macro.spec.js +171 -0
  44. package/components/cookies-banner/cookies-banner.spec.js +90 -0
  45. package/components/date-input/_macro.njk +6 -3
  46. package/components/date-input/_macro.spec.js +286 -0
  47. package/components/document-list/_macro.njk +3 -5
  48. package/components/document-list/_macro.spec.js +491 -0
  49. package/components/download-resources/download-resources.spec.js +540 -0
  50. package/components/duration/_macro.njk +7 -6
  51. package/components/duration/_macro.spec.js +251 -0
  52. package/components/error/_macro.spec.js +97 -0
  53. package/components/external-link/_macro.spec.js +60 -0
  54. package/components/feedback/_macro.njk +5 -3
  55. package/components/feedback/_macro.spec.js +122 -0
  56. package/components/field/_macro.njk +2 -2
  57. package/components/field/_macro.spec.js +97 -0
  58. package/components/fieldset/_macro.njk +3 -3
  59. package/components/fieldset/_macro.spec.js +173 -0
  60. package/components/footer/_macro.njk +11 -48
  61. package/components/footer/_macro.spec.js +549 -0
  62. package/components/header/_macro.njk +2 -2
  63. package/components/header/_macro.spec.js +562 -0
  64. package/components/hero/_hero.scss +0 -3
  65. package/components/hero/_macro.njk +4 -4
  66. package/components/hero/_macro.spec.js +224 -0
  67. package/components/icons/_macro.njk +15 -15
  68. package/components/icons/_macro.spec.js +140 -0
  69. package/components/images/_macro.njk +1 -1
  70. package/components/images/_macro.spec.js +121 -0
  71. package/components/input/_input-type.scss +12 -5
  72. package/components/input/_macro.njk +4 -5
  73. package/components/input/_macro.spec.js +658 -0
  74. package/components/label/_macro.spec.js +189 -0
  75. package/components/language-selector/_macro.spec.js +129 -0
  76. package/components/lists/_list.scss +4 -0
  77. package/components/lists/_macro.njk +4 -7
  78. package/components/lists/_macro.spec.js +618 -0
  79. package/components/message/_macro.spec.js +137 -0
  80. package/components/message-list/_macro.njk +7 -7
  81. package/components/message-list/_macro.spec.js +159 -0
  82. package/components/metadata/_macro.spec.js +167 -0
  83. package/components/modal/_macro.njk +6 -6
  84. package/components/modal/_macro.spec.js +87 -0
  85. package/components/modal/modal.spec.js +59 -0
  86. package/components/mutually-exclusive/_macro.njk +1 -1
  87. package/components/mutually-exclusive/_macro.spec.js +182 -0
  88. package/components/mutually-exclusive/mutually-exclusive.checkboxes.spec.js +203 -0
  89. package/components/mutually-exclusive/mutually-exclusive.date.spec.js +142 -0
  90. package/components/mutually-exclusive/mutually-exclusive.duration.spec.js +141 -0
  91. package/components/mutually-exclusive/mutually-exclusive.email.spec.js +117 -0
  92. package/components/mutually-exclusive/mutually-exclusive.multiple-options.checkboxes.spec.js +213 -0
  93. package/components/mutually-exclusive/mutually-exclusive.number.spec.js +125 -0
  94. package/components/mutually-exclusive/mutually-exclusive.textarea.spec.js +131 -0
  95. package/components/navigation/_macro.njk +6 -6
  96. package/components/navigation/_macro.spec.js +327 -0
  97. package/components/navigation/navigation.dom.js +1 -1
  98. package/components/navigation/navigation.spec.js +232 -0
  99. package/components/pagination/_macro.njk +1 -1
  100. package/components/pagination/_macro.spec.js +411 -0
  101. package/components/panel/_macro.njk +6 -6
  102. package/components/panel/_macro.spec.js +423 -0
  103. package/components/password/_macro.spec.js +137 -0
  104. package/components/password/password.spec.js +40 -0
  105. package/components/phase-banner/_macro.spec.js +73 -0
  106. package/components/promotional-banner/_macro.spec.js +97 -0
  107. package/components/question/_macro.njk +25 -33
  108. package/components/question/_macro.spec.js +309 -0
  109. package/components/quote/_macro.spec.js +81 -0
  110. package/components/radios/_macro.njk +3 -6
  111. package/components/radios/_macro.spec.js +575 -0
  112. package/components/radios/radios.spec.js +180 -0
  113. package/components/related-content/_macro.njk +1 -0
  114. package/components/related-content/_macro.spec.js +142 -0
  115. package/components/relationships/_macro.spec.js +108 -0
  116. package/components/relationships/relationships.spec.js +84 -0
  117. package/components/reply/_macro.njk +2 -2
  118. package/components/reply/_macro.spec.js +69 -0
  119. package/components/reply/reply.spec.js +78 -0
  120. package/components/search/_macro.njk +14 -12
  121. package/components/search/_macro.spec.js +44 -0
  122. package/components/search/_search.scss +7 -7
  123. package/components/section-navigation/_macro.njk +7 -2
  124. package/components/section-navigation/_macro.spec.js +206 -0
  125. package/components/select/_macro.njk +3 -3
  126. package/components/select/_macro.spec.js +203 -0
  127. package/components/select/select.spec.js +56 -0
  128. package/components/share-page/_macro.njk +2 -2
  129. package/components/share-page/_macro.spec.js +110 -0
  130. package/components/skip-to-content/_macro.spec.js +57 -0
  131. package/components/skip-to-content/skip-to-content.spec.js +44 -0
  132. package/components/status/_macro.spec.js +77 -0
  133. package/components/summary/_macro.njk +5 -5
  134. package/components/summary/_macro.spec.js +472 -0
  135. package/components/table/_macro.njk +2 -2
  136. package/components/table/_macro.spec.js +557 -0
  137. package/components/table/table.spec.js +155 -0
  138. package/components/table-of-contents/_macro.njk +35 -35
  139. package/components/table-of-contents/_macro.spec.js +178 -0
  140. package/components/table-of-contents/toc.js +29 -25
  141. package/components/table-of-contents/toc.spec.js +61 -0
  142. package/components/tabs/_macro.njk +1 -1
  143. package/components/tabs/_macro.spec.js +79 -0
  144. package/components/tabs/tabs.spec.js +162 -0
  145. package/components/text-indent/_macro.spec.js +52 -0
  146. package/components/textarea/_macro.njk +5 -3
  147. package/components/textarea/_macro.spec.js +300 -0
  148. package/components/textarea/textarea.spec.js +98 -0
  149. package/components/timeline/_macro.njk +3 -3
  150. package/components/timeline/_macro.spec.js +81 -0
  151. package/components/timeout-modal/_macro.spec.js +68 -0
  152. package/components/timeout-modal/timeout-modal.spec.js +226 -0
  153. package/components/timeout-panel/_macro.njk +0 -1
  154. package/components/timeout-panel/_macro.spec.js +54 -0
  155. package/components/timeout-panel/timeout-panel.dom.js +1 -2
  156. package/components/timeout-panel/timeout-panel.spec.js +161 -0
  157. package/components/upload/_macro.spec.js +75 -0
  158. package/components/video/_macro.spec.js +34 -0
  159. package/css/census.css +1 -1
  160. package/css/main.css +1 -1
  161. package/js/cookies-settings.spec.js +154 -0
  162. package/package.json +10 -23
  163. package/scripts/main.es5.js +1 -1
  164. package/scripts/main.js +1 -1
@@ -0,0 +1,575 @@
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_RADIOS_MINIMAL = {
9
+ name: 'example-radios-name',
10
+ legend: 'Legend text',
11
+ radios: [],
12
+ };
13
+
14
+ const EXAMPLE_RADIO_ITEM = {
15
+ id: 'example-item-id',
16
+ value: 'plain',
17
+ label: {
18
+ classes: 'extra-label-class',
19
+ text: 'Example item',
20
+ description: 'An example description.',
21
+ },
22
+ };
23
+
24
+ const EXAMPLE_RADIO_ITEM_INPUT = {
25
+ id: 'example-item-input',
26
+ name: 'example-item-input',
27
+ value: 'input',
28
+ label: {
29
+ text: 'Example item with input',
30
+ },
31
+ other: {
32
+ id: 'example-text-input',
33
+ name: 'example-text-input-name',
34
+ type: 'text',
35
+ label: {
36
+ text: 'Enter your own answer',
37
+ },
38
+ required: false,
39
+ classes: 'extra-textbox-class',
40
+ width: 42,
41
+ value: '42',
42
+ attributes: { a: 42 },
43
+ },
44
+ };
45
+
46
+ const EXAMPLE_RADIO_ITEM_SELECT = {
47
+ id: 'example-item-select',
48
+ name: 'example-item-select',
49
+ value: 'select',
50
+ label: {
51
+ text: 'Example item with select',
52
+ },
53
+ other: {
54
+ otherType: 'select',
55
+ id: 'example-select',
56
+ name: 'example-select-name',
57
+ label: {
58
+ text: 'Enter your own answer',
59
+ },
60
+ classes: 'extra-select-class',
61
+ options: [
62
+ { text: 'First', value: '1' },
63
+ { text: 'Second', value: '2' },
64
+ ],
65
+ value: '1',
66
+ },
67
+ };
68
+
69
+ const EXAMPLE_RADIO_ITEM_CHECKBOXES = {
70
+ id: 'example-item-checkboxes',
71
+ name: 'example-item-checkboxes',
72
+ value: 'checkboxes',
73
+ label: {
74
+ text: 'Example item with checkboxes',
75
+ },
76
+ other: {
77
+ otherType: 'checkboxes',
78
+ selectAllChildren: true,
79
+ id: 'example-checkboxes',
80
+ name: 'example-checkboxes-name',
81
+ legend: 'Select preferred times of day',
82
+ legendClasses: 'extra-legend-class',
83
+ attributes: { a: 42 },
84
+ checkboxes: [
85
+ {
86
+ value: 'morning',
87
+ id: 'morning',
88
+ label: {
89
+ text: 'Morning',
90
+ },
91
+ },
92
+ {
93
+ value: 'afternoon',
94
+ id: 'afternoon',
95
+ label: {
96
+ text: 'Afternoon',
97
+ },
98
+ },
99
+ ],
100
+ autoSelect: {
101
+ selectAllText: 'Select all',
102
+ unselectAllText: 'Unselect all',
103
+ context: 'checkboxes',
104
+ },
105
+ },
106
+ };
107
+
108
+ const EXAMPLE_RADIO_ITEM_RADIOS = {
109
+ id: 'example-item-radios',
110
+ name: 'example-item-radios',
111
+ value: 'radios',
112
+ label: {
113
+ text: 'Example item with radios',
114
+ },
115
+ other: {
116
+ otherType: 'radios',
117
+ id: 'example-radios',
118
+ name: 'example-radios-name',
119
+ legend: 'Select preferred times of day',
120
+ legendClasses: 'extra-legend-class',
121
+ attributes: { a: 42 },
122
+ radios: [EXAMPLE_RADIO_ITEM],
123
+ },
124
+ };
125
+
126
+ describe('macro: radios', () => {
127
+ it.each([
128
+ ['plain', EXAMPLE_RADIO_ITEM],
129
+ ['input', EXAMPLE_RADIO_ITEM_INPUT],
130
+ ['select', EXAMPLE_RADIO_ITEM_SELECT],
131
+ ['checkboxes', EXAMPLE_RADIO_ITEM_CHECKBOXES],
132
+ ['radios', EXAMPLE_RADIO_ITEM_RADIOS],
133
+ ])('passes jest-axe checks with a %s item', async (_, radioItem) => {
134
+ const $ = cheerio.load(
135
+ renderComponent('radios', {
136
+ ...EXAMPLE_RADIOS_MINIMAL,
137
+ radios: [radioItem],
138
+ }),
139
+ );
140
+
141
+ const results = await axe($.html());
142
+ expect(results).toHaveNoViolations();
143
+ });
144
+
145
+ it('renders `fieldset` component with the expected parameters', () => {
146
+ const faker = templateFaker();
147
+ const fieldsetSpy = faker.spy('fieldset');
148
+
149
+ faker.renderComponent('radios', {
150
+ ...EXAMPLE_RADIOS_MINIMAL,
151
+ id: 'example-id',
152
+ classes: 'extra-class',
153
+ legendClasses: 'extra-legend-class',
154
+ description: 'An example description.',
155
+ dontWrap: true,
156
+ legendIsQuestionTitle: false,
157
+ error: {
158
+ id: 'example-error-id',
159
+ text: 'An unexpected error occurred.',
160
+ },
161
+ });
162
+
163
+ expect(fieldsetSpy.occurrences[0]).toEqual({
164
+ id: 'example-id',
165
+ classes: 'extra-class',
166
+ legend: 'Legend text',
167
+ legendClasses: 'extra-legend-class',
168
+ description: 'An example description.',
169
+ dontWrap: true,
170
+ legendIsQuestionTitle: false,
171
+ error: {
172
+ id: 'example-error-id',
173
+ text: 'An unexpected error occurred.',
174
+ },
175
+ });
176
+ });
177
+
178
+ describe('radio item', () => {
179
+ it('renders `or` label before last radio item', () => {
180
+ const $ = cheerio.load(
181
+ renderComponent('radios', {
182
+ ...EXAMPLE_RADIOS_MINIMAL,
183
+ radios: [EXAMPLE_RADIO_ITEM, EXAMPLE_RADIO_ITEM_INPUT, EXAMPLE_RADIO_ITEM_SELECT],
184
+ or: 'Or',
185
+ }),
186
+ );
187
+
188
+ const label = $('.ons-radios__item + br + .ons-radios__item + br + .ons-radios__label');
189
+ expect(label.text().trim()).toBe('Or');
190
+ });
191
+
192
+ it('is of the "radio" input type', () => {
193
+ const $ = cheerio.load(
194
+ renderComponent('radios', {
195
+ ...EXAMPLE_RADIOS_MINIMAL,
196
+ radios: [EXAMPLE_RADIO_ITEM],
197
+ }),
198
+ );
199
+
200
+ expect($('.ons-radio__input').attr('type')).toBe('radio');
201
+ });
202
+
203
+ it('has the provided `id` attribute', () => {
204
+ const $ = cheerio.load(
205
+ renderComponent('radios', {
206
+ ...EXAMPLE_RADIOS_MINIMAL,
207
+ radios: [EXAMPLE_RADIO_ITEM],
208
+ }),
209
+ );
210
+
211
+ expect($('.ons-radio__input').attr('id')).toBe('example-item-id');
212
+ });
213
+
214
+ it('has additionally provided attributes', () => {
215
+ const $ = cheerio.load(
216
+ renderComponent('radios', {
217
+ ...EXAMPLE_RADIOS_MINIMAL,
218
+ inputClasses: 'extra-input-class another-extra-input-class',
219
+ radios: [
220
+ {
221
+ ...EXAMPLE_RADIO_ITEM,
222
+ attributes: { a: '123', b: '456' },
223
+ },
224
+ ],
225
+ }),
226
+ );
227
+
228
+ expect($('.ons-radio__input').attr('a')).toBe('123');
229
+ expect($('.ons-radio__input').attr('b')).toBe('456');
230
+ });
231
+
232
+ it('has the provided `name` attribute', () => {
233
+ const $ = cheerio.load(
234
+ renderComponent('radios', {
235
+ ...EXAMPLE_RADIOS_MINIMAL,
236
+ radios: [EXAMPLE_RADIO_ITEM],
237
+ }),
238
+ );
239
+
240
+ expect($('.ons-radio__input').attr('name')).toBe('example-radios-name');
241
+ });
242
+
243
+ it('has the provided `value` attribute', () => {
244
+ const $ = cheerio.load(
245
+ renderComponent('radios', {
246
+ ...EXAMPLE_RADIOS_MINIMAL,
247
+ radios: [EXAMPLE_RADIO_ITEM],
248
+ }),
249
+ );
250
+
251
+ expect($('.ons-radio__input').attr('value')).toBe('plain');
252
+ });
253
+
254
+ it('does not have a `checked` attribute', () => {
255
+ const $ = cheerio.load(
256
+ renderComponent('radios', {
257
+ ...EXAMPLE_RADIOS_MINIMAL,
258
+ radios: [EXAMPLE_RADIO_ITEM],
259
+ }),
260
+ );
261
+
262
+ expect($('.ons-radio__input').attr('checked')).toBeUndefined();
263
+ });
264
+
265
+ it('has a `checked` attribute when `checked` parameter is provided', () => {
266
+ const $ = cheerio.load(
267
+ renderComponent('radios', {
268
+ ...EXAMPLE_RADIOS_MINIMAL,
269
+ radios: [
270
+ {
271
+ ...EXAMPLE_RADIO_ITEM,
272
+ checked: true,
273
+ },
274
+ ],
275
+ }),
276
+ );
277
+
278
+ expect($('.ons-radio__input').attr('checked')).toBe('checked');
279
+ });
280
+
281
+ it('has a `checked` attribute when `value` parameter matches root `value` parameter', () => {
282
+ const $ = cheerio.load(
283
+ renderComponent('radios', {
284
+ ...EXAMPLE_RADIOS_MINIMAL,
285
+ value: 'plain',
286
+ radios: [EXAMPLE_RADIO_ITEM],
287
+ }),
288
+ );
289
+
290
+ expect($('.ons-radio__input').attr('checked')).toBe('checked');
291
+ });
292
+
293
+ it('has additionally provided style classes (from `inputClasses` parameter)', () => {
294
+ const $ = cheerio.load(
295
+ renderComponent('radios', {
296
+ ...EXAMPLE_RADIOS_MINIMAL,
297
+ inputClasses: 'extra-input-class another-extra-input-class',
298
+ radios: [EXAMPLE_RADIO_ITEM],
299
+ }),
300
+ );
301
+
302
+ expect($('.ons-radio__input').hasClass('extra-input-class')).toBe(true);
303
+ expect($('.ons-radio__input').hasClass('another-extra-input-class')).toBe(true);
304
+ });
305
+
306
+ it('has additionally provided style classes (from `radio.classes` parameter)', () => {
307
+ const $ = cheerio.load(
308
+ renderComponent('radios', {
309
+ ...EXAMPLE_RADIOS_MINIMAL,
310
+ radios: [
311
+ {
312
+ ...EXAMPLE_RADIO_ITEM,
313
+ classes: 'extra-item-class another-extra-item-class',
314
+ },
315
+ ],
316
+ }),
317
+ );
318
+
319
+ expect($('.ons-radio__input').hasClass('extra-item-class')).toBe(true);
320
+ expect($('.ons-radio__input').hasClass('another-extra-item-class')).toBe(true);
321
+ });
322
+
323
+ it('renders a border around each item by default', () => {
324
+ const $ = cheerio.load(
325
+ renderComponent('radios', {
326
+ ...EXAMPLE_RADIOS_MINIMAL,
327
+ radios: [EXAMPLE_RADIO_ITEM],
328
+ }),
329
+ );
330
+
331
+ expect($('.ons-radios__item').hasClass('ons-radios__item--no-border')).toBe(false);
332
+ expect($('.ons-radio').hasClass('ons-radio--no-border')).toBe(false);
333
+ });
334
+
335
+ it('does not render a border around each item when `borderless` is `false`', () => {
336
+ const $ = cheerio.load(
337
+ renderComponent('radios', {
338
+ ...EXAMPLE_RADIOS_MINIMAL,
339
+ radios: [EXAMPLE_RADIO_ITEM],
340
+ borderless: true,
341
+ }),
342
+ );
343
+
344
+ expect($('.ons-radios__item').hasClass('ons-radios__item--no-border')).toBe(true);
345
+ expect($('.ons-radio').hasClass('ons-radio--no-border')).toBe(true);
346
+ });
347
+
348
+ it('does not mark radio with a class indicating that all child options should be selected', () => {
349
+ const $ = cheerio.load(
350
+ renderComponent('radios', {
351
+ ...EXAMPLE_RADIOS_MINIMAL,
352
+ radios: [EXAMPLE_RADIO_ITEM],
353
+ }),
354
+ );
355
+
356
+ expect($('.ons-radio__input').hasClass('ons-js-select-all-children')).toBe(false);
357
+ });
358
+
359
+ it('marks radio with a class indicating that all child options should be selected', () => {
360
+ const $ = cheerio.load(
361
+ renderComponent('radios', {
362
+ ...EXAMPLE_RADIOS_MINIMAL,
363
+ radios: [EXAMPLE_RADIO_ITEM_CHECKBOXES],
364
+ }),
365
+ );
366
+
367
+ expect($('.ons-radio__input').hasClass('ons-js-select-all-children')).toBe(true);
368
+ });
369
+
370
+ it('does not mark radio with a class indicating that there is an `other` input', () => {
371
+ const $ = cheerio.load(
372
+ renderComponent('radios', {
373
+ ...EXAMPLE_RADIOS_MINIMAL,
374
+ radios: [EXAMPLE_RADIO_ITEM],
375
+ }),
376
+ );
377
+
378
+ expect($('.ons-js-other').hasClass('ons-js-select-all-children')).toBe(false);
379
+ });
380
+
381
+ it('marks radio with a class indicating that there is an `other` input', () => {
382
+ const $ = cheerio.load(
383
+ renderComponent('radios', {
384
+ ...EXAMPLE_RADIOS_MINIMAL,
385
+ radios: [EXAMPLE_RADIO_ITEM_CHECKBOXES],
386
+ }),
387
+ );
388
+
389
+ expect($('.ons-js-other').hasClass('ons-js-select-all-children')).toBe(true);
390
+ });
391
+
392
+ it('renders label for the radio item', () => {
393
+ const faker = templateFaker();
394
+ const labelSpy = faker.spy('label');
395
+
396
+ faker.renderComponent('radios', {
397
+ ...EXAMPLE_RADIOS_MINIMAL,
398
+ radios: [EXAMPLE_RADIO_ITEM],
399
+ });
400
+
401
+ expect(labelSpy.occurrences).toContainEqual({
402
+ id: 'example-item-id-label',
403
+ for: 'example-item-id',
404
+ inputType: 'radio',
405
+ text: 'Example item',
406
+ classes: 'ons-radio__label extra-label-class',
407
+ description: 'An example description.',
408
+ });
409
+ });
410
+
411
+ it('wraps `other` component without a class indicating that it is open', () => {
412
+ const $ = cheerio.load(
413
+ renderComponent('radios', {
414
+ ...EXAMPLE_RADIOS_MINIMAL,
415
+ radios: [EXAMPLE_RADIO_ITEM_INPUT],
416
+ }),
417
+ );
418
+
419
+ expect($('.ons-radio__other').hasClass('ons-radio__other--open')).toBe(false);
420
+ expect($('.ons-radio__other').attr('id')).toBe('example-item-input-other-wrap');
421
+ expect($('.ons-radio__input').attr('aria-controls')).toBe('example-item-input-other-wrap');
422
+ expect($('.ons-radio__input').attr('aria-haspopup')).toBe('true');
423
+ });
424
+
425
+ it('wraps `other` component with class indicating that it is open', () => {
426
+ const $ = cheerio.load(
427
+ renderComponent('radios', {
428
+ ...EXAMPLE_RADIOS_MINIMAL,
429
+ radios: [
430
+ {
431
+ ...EXAMPLE_RADIO_ITEM_INPUT,
432
+ other: {
433
+ ...EXAMPLE_RADIO_ITEM_INPUT.other,
434
+ open: true,
435
+ },
436
+ },
437
+ ],
438
+ }),
439
+ );
440
+
441
+ expect($('.ons-radio__other').hasClass('ons-radio__other--open')).toBe(true);
442
+ expect($('.ons-radio__other').attr('id')).toBe('example-item-input-other-wrap');
443
+ expect($('.ons-radio__input').attr('aria-controls')).toBeUndefined();
444
+ expect($('.ons-radio__input').attr('aria-haspopup')).toBeUndefined();
445
+ });
446
+
447
+ it('renders other "input" component for item', () => {
448
+ const faker = templateFaker();
449
+ const inputSpy = faker.spy('input');
450
+
451
+ faker.renderComponent('radios', {
452
+ ...EXAMPLE_RADIOS_MINIMAL,
453
+ radios: [EXAMPLE_RADIO_ITEM_INPUT],
454
+ });
455
+
456
+ expect(inputSpy.occurrences).toContainEqual({
457
+ id: 'example-text-input',
458
+ name: 'example-text-input-name',
459
+ type: 'text',
460
+ label: {
461
+ id: 'example-text-input-label',
462
+ text: 'Enter your own answer',
463
+ classes: 'ons-u-fw-n',
464
+ },
465
+ required: false,
466
+ classes: 'extra-textbox-class',
467
+ width: 42,
468
+ attributes: EXAMPLE_RADIO_ITEM_INPUT.other.attributes,
469
+ dontWrap: true,
470
+ value: '42',
471
+ });
472
+ });
473
+
474
+ it('renders other "select" component for item', () => {
475
+ const faker = templateFaker();
476
+ const selectSpy = faker.spy('select');
477
+
478
+ faker.renderComponent('radios', {
479
+ ...EXAMPLE_RADIOS_MINIMAL,
480
+ radios: [EXAMPLE_RADIO_ITEM_SELECT],
481
+ });
482
+
483
+ expect(selectSpy.occurrences).toContainEqual({
484
+ id: 'example-select',
485
+ name: 'example-select-name',
486
+ label: {
487
+ id: 'example-select-label',
488
+ text: 'Enter your own answer',
489
+ classes: 'ons-u-fw-n',
490
+ },
491
+ classes: 'extra-select-class',
492
+ dontWrap: true,
493
+ options: EXAMPLE_RADIO_ITEM_SELECT.other.options,
494
+ value: '1',
495
+ });
496
+ });
497
+
498
+ it('renders other "checkboxes" component for item', () => {
499
+ const faker = templateFaker();
500
+ const checkboxesSpy = faker.spy('checkboxes');
501
+
502
+ faker.renderComponent('radios', {
503
+ ...EXAMPLE_RADIOS_MINIMAL,
504
+ radios: [EXAMPLE_RADIO_ITEM_CHECKBOXES],
505
+ });
506
+
507
+ expect(checkboxesSpy.occurrences).toContainEqual({
508
+ id: 'example-checkboxes',
509
+ name: 'example-checkboxes-name',
510
+ checked: undefined,
511
+ borderless: true,
512
+ legend: 'Select preferred times of day',
513
+ legendClasses: 'extra-legend-class',
514
+ attributes: { a: 42 },
515
+ classes: 'ons-js-other-fieldset',
516
+ checkboxes: EXAMPLE_RADIO_ITEM_CHECKBOXES.other.checkboxes,
517
+ autoSelect: EXAMPLE_RADIO_ITEM_CHECKBOXES.other.autoSelect,
518
+ selectAllChildren: true,
519
+ });
520
+ });
521
+
522
+ it('renders other "radios" component for item', () => {
523
+ const faker = templateFaker();
524
+ const radiosSpy = faker.spy('radios');
525
+
526
+ faker.renderComponent('radios', {
527
+ ...EXAMPLE_RADIOS_MINIMAL,
528
+ radios: [EXAMPLE_RADIO_ITEM_RADIOS],
529
+ });
530
+
531
+ expect(radiosSpy.occurrences).toContainEqual({
532
+ id: 'example-radios',
533
+ name: 'example-radios-name',
534
+ borderless: true,
535
+ legend: 'Select preferred times of day',
536
+ legendClasses: 'extra-legend-class ons-u-mb-xs',
537
+ attributes: { a: 42 },
538
+ classes: 'ons-js-other-fieldset',
539
+ radios: EXAMPLE_RADIO_ITEM_RADIOS.other.radios,
540
+ });
541
+ });
542
+ });
543
+
544
+ describe('clear radios button', () => {
545
+ const params = {
546
+ ...EXAMPLE_RADIOS_MINIMAL,
547
+ clearRadios: {
548
+ text: 'Clear selection',
549
+ name: 'clear-radios-button',
550
+ ariaClearText: 'You can clear your answer using the clear selection button after the radio inputs',
551
+ ariaClearedText: 'You have cleared your answer',
552
+ },
553
+ };
554
+
555
+ it('renders `button` component', () => {
556
+ const faker = templateFaker();
557
+ const buttonSpy = faker.spy('button');
558
+
559
+ faker.renderComponent('radios', params);
560
+
561
+ expect(buttonSpy.occurrences[0]).toHaveProperty('text', 'Clear selection');
562
+ expect(buttonSpy.occurrences[0]).toHaveProperty('name', 'clear-radios-button');
563
+ expect(buttonSpy.occurrences[0]).toHaveProperty('type', 'submit');
564
+ });
565
+
566
+ it('renders a visually hidden element for aria alerts', () => {
567
+ const $ = cheerio.load(renderComponent('radios', params));
568
+
569
+ expect($('span[role=alert]').hasClass('ons-u-vh')).toBe(true);
570
+ expect($('span[role=alert]').attr('aria-live')).toBe('polite');
571
+ expect($('span[role=alert]').attr('data-clear')).toBe(params.clearRadios.ariaClearText);
572
+ expect($('span[role=alert]').attr('data-cleared')).toBe(params.clearRadios.ariaClearedText);
573
+ });
574
+ });
575
+ });