@ons/design-system 70.0.6 → 70.0.8

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 (308) hide show
  1. package/README.md +11 -17
  2. package/components/access-code/_macro.spec.js +145 -145
  3. package/components/access-code/access-code.dom.js +5 -5
  4. package/components/access-code/access-code.js +16 -16
  5. package/components/access-code/access-code.scss +22 -22
  6. package/components/access-code/access-code.spec.js +17 -17
  7. package/components/accordion/_macro.spec.js +154 -154
  8. package/components/accordion/accordion.dom.js +10 -10
  9. package/components/accordion/accordion.js +50 -50
  10. package/components/accordion/accordion.spec.js +104 -104
  11. package/components/address-input/_macro.spec.js +420 -420
  12. package/components/address-input/autosuggest.address.dom.js +5 -5
  13. package/components/address-input/autosuggest.address.error.js +77 -77
  14. package/components/address-input/autosuggest.address.js +357 -357
  15. package/components/address-input/autosuggest.address.setter.js +95 -95
  16. package/components/address-input/autosuggest.address.spec.js +668 -651
  17. package/components/address-input/example-address-input-editable.njk +1 -1
  18. package/components/address-input/example-address-input.njk +1 -1
  19. package/components/address-output/_address-output.scss +3 -3
  20. package/components/address-output/_macro.spec.js +84 -84
  21. package/components/autosuggest/_autosuggest.scss +114 -114
  22. package/components/autosuggest/_macro.spec.js +255 -255
  23. package/components/autosuggest/autosuggest.dom.js +5 -5
  24. package/components/autosuggest/autosuggest.helpers.js +11 -11
  25. package/components/autosuggest/autosuggest.helpers.spec.js +73 -73
  26. package/components/autosuggest/autosuggest.js +20 -20
  27. package/components/autosuggest/autosuggest.spec.js +542 -536
  28. package/components/autosuggest/autosuggest.ui.js +478 -475
  29. package/components/autosuggest/fuse-config.js +17 -17
  30. package/components/back-to-top/_back-to-top.scss +27 -27
  31. package/components/back-to-top/_macro.spec.js +49 -49
  32. package/components/back-to-top/back-to-top.dom.js +5 -5
  33. package/components/back-to-top/back-to-top.js +52 -52
  34. package/components/back-to-top/back-to-top.spec.js +106 -106
  35. package/components/back-to-top/example-back-to-top.njk +6 -6
  36. package/components/breadcrumbs/_breadcrumbs.scss +63 -65
  37. package/components/breadcrumbs/_macro.spec.js +91 -91
  38. package/components/browser-banner/_browser-banner.scss +23 -23
  39. package/components/browser-banner/_macro.spec.js +92 -92
  40. package/components/button/_button.scss +482 -483
  41. package/components/button/_macro.spec.js +363 -363
  42. package/components/button/button.dom.js +15 -15
  43. package/components/button/button.js +53 -53
  44. package/components/button/button.spec.js +248 -240
  45. package/components/call-to-action/_call-to-action.scss +5 -5
  46. package/components/call-to-action/_macro.spec.js +28 -28
  47. package/components/card/_card.scss +23 -23
  48. package/components/card/_macro.spec.js +180 -180
  49. package/components/char-check-limit/_macro.spec.js +48 -48
  50. package/components/char-check-limit/character-check.js +58 -58
  51. package/components/char-check-limit/character-check.spec.js +173 -173
  52. package/components/char-check-limit/character-limit.js +40 -40
  53. package/components/checkboxes/_checkbox-macro.spec.js +355 -355
  54. package/components/checkboxes/_checkbox.scss +180 -180
  55. package/components/checkboxes/_checkboxes.scss +37 -27
  56. package/components/checkboxes/_macro.spec.js +261 -261
  57. package/components/checkboxes/checkbox-with-autoselect.js +32 -32
  58. package/components/checkboxes/checkbox-with-fieldset.js +21 -21
  59. package/components/checkboxes/checkboxes-with-reveal.js +10 -10
  60. package/components/checkboxes/checkboxes.dom.js +27 -27
  61. package/components/checkboxes/checkboxes.spec.js +183 -183
  62. package/components/content-pagination/_content-pagination.scss +41 -41
  63. package/components/content-pagination/_macro.spec.js +159 -159
  64. package/components/cookies-banner/_cookies-banner.scss +22 -22
  65. package/components/cookies-banner/_macro.spec.js +177 -177
  66. package/components/cookies-banner/cookies-banner.dom.js +7 -7
  67. package/components/cookies-banner/cookies-banner.js +76 -76
  68. package/components/cookies-banner/cookies-banner.spec.js +72 -68
  69. package/components/date-input/_macro.spec.js +338 -338
  70. package/components/description-list/_description-list.scss +23 -23
  71. package/components/description-list/_macro.spec.js +144 -144
  72. package/components/details/_details.scss +109 -109
  73. package/components/details/_macro.spec.js +132 -132
  74. package/components/details/details.dom.js +6 -6
  75. package/components/details/details.js +60 -60
  76. package/components/details/details.spec.js +106 -106
  77. package/components/document-list/_macro.spec.js +444 -444
  78. package/components/document-list/document-list.scss +145 -149
  79. package/components/download-resources/_download-resources.scss +109 -108
  80. package/components/download-resources/download-resources.js +907 -900
  81. package/components/download-resources/download-resources.spec.js +461 -461
  82. package/components/duration/_macro.spec.js +291 -291
  83. package/components/error/_macro.spec.js +72 -72
  84. package/components/external-link/_external-link.scss +19 -19
  85. package/components/external-link/_macro.spec.js +68 -68
  86. package/components/feedback/_feedback.scss +31 -31
  87. package/components/feedback/_macro.spec.js +72 -72
  88. package/components/field/_field-group.scss +10 -10
  89. package/components/field/_field.scss +16 -16
  90. package/components/field/_macro.spec.js +80 -80
  91. package/components/fieldset/_fieldset.scss +27 -27
  92. package/components/fieldset/_macro.spec.js +161 -161
  93. package/components/footer/_footer.scss +45 -45
  94. package/components/footer/_macro.spec.js +452 -452
  95. package/components/header/_header.scss +202 -202
  96. package/components/header/_macro.spec.js +833 -829
  97. package/components/helpers/_grid.scss +4 -4
  98. package/components/hero/_hero.scss +48 -48
  99. package/components/hero/_macro.spec.js +59 -59
  100. package/components/icon/_icon.scss +44 -44
  101. package/components/icon/_macro.spec.js +110 -110
  102. package/components/image/_image.scss +11 -11
  103. package/components/image/_macro.spec.js +81 -81
  104. package/components/input/_input-type.scss +86 -89
  105. package/components/input/_input.scss +123 -124
  106. package/components/input/_macro.spec.js +604 -604
  107. package/components/input/character-check.dom.js +5 -5
  108. package/components/input/input.dom.js +5 -5
  109. package/components/input/input.js +10 -10
  110. package/components/input/input.spec.js +18 -18
  111. package/components/label/_label.scss +24 -24
  112. package/components/label/_macro.spec.js +173 -170
  113. package/components/language-selector/_macro.spec.js +97 -97
  114. package/components/language-selector/language.scss +7 -7
  115. package/components/list/_list.scss +84 -84
  116. package/components/list/_macro.njk +2 -2
  117. package/components/list/_macro.spec.js +583 -583
  118. package/components/message/_macro.njk +5 -5
  119. package/components/message/_macro.spec.js +74 -74
  120. package/components/message/_message.scss +39 -39
  121. package/components/message-list/_macro.spec.js +86 -86
  122. package/components/message-list/_message-list.scss +16 -16
  123. package/components/modal/_macro.spec.js +69 -69
  124. package/components/modal/_modal.scss +36 -36
  125. package/components/modal/modal.dom.js +6 -6
  126. package/components/modal/modal.js +89 -89
  127. package/components/modal/modal.spec.js +50 -50
  128. package/components/mutually-exclusive/_macro.spec.js +140 -140
  129. package/components/mutually-exclusive/mutually-exclusive.checkboxes.spec.js +188 -188
  130. package/components/mutually-exclusive/mutually-exclusive.date.spec.js +211 -211
  131. package/components/mutually-exclusive/mutually-exclusive.dom.js +5 -5
  132. package/components/mutually-exclusive/mutually-exclusive.duration.spec.js +210 -210
  133. package/components/mutually-exclusive/mutually-exclusive.email.spec.js +90 -90
  134. package/components/mutually-exclusive/mutually-exclusive.js +137 -137
  135. package/components/mutually-exclusive/mutually-exclusive.multiple-options.checkboxes.spec.js +197 -197
  136. package/components/mutually-exclusive/mutually-exclusive.number.spec.js +96 -96
  137. package/components/mutually-exclusive/mutually-exclusive.textarea.spec.js +102 -102
  138. package/components/navigation/_macro.spec.js +360 -354
  139. package/components/navigation/_navigation.scss +122 -123
  140. package/components/navigation/navigation.dom.js +35 -35
  141. package/components/navigation/navigation.js +49 -49
  142. package/components/navigation/navigation.spec.js +249 -249
  143. package/components/pagination/_macro.spec.js +342 -335
  144. package/components/pagination/_pagination.scss +58 -58
  145. package/components/panel/_macro.spec.js +372 -372
  146. package/components/panel/_panel.scss +200 -199
  147. package/components/password/_macro.spec.js +95 -95
  148. package/components/password/password.dom.js +5 -5
  149. package/components/password/password.js +10 -10
  150. package/components/password/password.spec.js +26 -26
  151. package/components/phase-banner/_macro.spec.js +86 -86
  152. package/components/phase-banner/_phase-banner.scss +16 -16
  153. package/components/question/_macro.spec.js +235 -235
  154. package/components/question/_question.scss +24 -24
  155. package/components/quote/_macro.spec.js +52 -52
  156. package/components/quote/_quote.scss +24 -24
  157. package/components/radios/_macro.spec.js +524 -524
  158. package/components/radios/_radio.scss +49 -48
  159. package/components/radios/_radios.scss +14 -20
  160. package/components/radios/check-radios.js +21 -21
  161. package/components/radios/clear-radios.js +45 -45
  162. package/components/radios/radio-with-fieldset.js +22 -22
  163. package/components/radios/radios.dom.js +32 -32
  164. package/components/radios/radios.spec.js +251 -251
  165. package/components/related-content/_macro.spec.js +109 -109
  166. package/components/related-content/_related-content.scss +12 -12
  167. package/components/related-content/_section-macro.spec.js +20 -20
  168. package/components/relationships/_macro.spec.js +94 -94
  169. package/components/relationships/_relationships.scss +9 -9
  170. package/components/relationships/relationships.dom.js +5 -5
  171. package/components/relationships/relationships.js +18 -18
  172. package/components/relationships/relationships.spec.js +71 -71
  173. package/components/reply/_macro.spec.js +47 -47
  174. package/components/reply/reply-input.js +15 -15
  175. package/components/reply/reply.dom.js +5 -5
  176. package/components/reply/reply.spec.js +57 -57
  177. package/components/section-navigation/_macro.spec.js +210 -210
  178. package/components/section-navigation/_section-navigation.scss +76 -76
  179. package/components/select/_macro.spec.js +166 -166
  180. package/components/share-page/_macro.spec.js +68 -68
  181. package/components/skip-to-content/_macro.spec.js +54 -54
  182. package/components/skip-to-content/_skip.scss +30 -30
  183. package/components/skip-to-content/skip-to-content.dom.js +6 -6
  184. package/components/skip-to-content/skip-to-content.js +7 -7
  185. package/components/skip-to-content/skip-to-content.spec.js +21 -21
  186. package/components/status/_macro.spec.js +53 -53
  187. package/components/status/_status.scss +32 -32
  188. package/components/summary/_macro.spec.js +551 -535
  189. package/components/summary/_summary.scss +191 -195
  190. package/components/table/_macro.spec.js +499 -499
  191. package/components/table/_table.scss +204 -201
  192. package/components/table/scrollable-table.dom.js +5 -5
  193. package/components/table/scrollable-table.js +60 -60
  194. package/components/table/sortable-table.dom.js +5 -5
  195. package/components/table/sortable-table.js +135 -135
  196. package/components/table/table.spec.js +144 -140
  197. package/components/table-of-contents/_macro.spec.js +125 -125
  198. package/components/table-of-contents/_toc.scss +9 -9
  199. package/components/table-of-contents/toc.dom.js +5 -5
  200. package/components/table-of-contents/toc.js +30 -30
  201. package/components/table-of-contents/toc.spec.js +88 -88
  202. package/components/tabs/_macro.spec.js +92 -92
  203. package/components/tabs/_tabs.scss +120 -115
  204. package/components/tabs/tabs.dom.js +5 -5
  205. package/components/tabs/tabs.js +266 -266
  206. package/components/tabs/tabs.spec.js +268 -268
  207. package/components/text-indent/_macro.spec.js +33 -33
  208. package/components/text-indent/_text-indent.scss +3 -3
  209. package/components/textarea/_macro.spec.js +238 -238
  210. package/components/textarea/textarea.dom.js +5 -5
  211. package/components/textarea/textarea.spec.js +78 -74
  212. package/components/timeline/_macro.spec.js +83 -83
  213. package/components/timeline/_timeline.scss +26 -26
  214. package/components/timeout-modal/_macro.spec.js +47 -47
  215. package/components/timeout-modal/timeout-modal.dom.js +9 -9
  216. package/components/timeout-modal/timeout-modal.js +66 -66
  217. package/components/timeout-modal/timeout-modal.spec.js +157 -157
  218. package/components/timeout-panel/_macro.spec.js +41 -41
  219. package/components/timeout-panel/timeout-panel.dom.js +8 -8
  220. package/components/timeout-panel/timeout-panel.spec.js +118 -118
  221. package/components/upload/_macro.spec.js +52 -52
  222. package/components/upload/_upload.scss +28 -28
  223. package/components/video/_macro.spec.js +42 -42
  224. package/components/video/_video.scss +16 -16
  225. package/components/video/video.dom.js +5 -5
  226. package/components/video/video.js +32 -32
  227. package/components/video/video.spec.js +103 -97
  228. package/css/main.css +1 -1
  229. package/favicons/android-chrome-192x192.png +0 -0
  230. package/favicons/android-chrome-512x512.png +0 -0
  231. package/favicons/apple-touch-icon.png +0 -0
  232. package/favicons/favicon-16x16.png +0 -0
  233. package/favicons/favicon-32x32.png +0 -0
  234. package/favicons/favicon.ico +0 -0
  235. package/favicons/manifest.json +25 -25
  236. package/favicons/maskable_icon.png +0 -0
  237. package/favicons/opengraph.png +0 -0
  238. package/favicons/twitter.png +0 -0
  239. package/img/large/alison-pritchard-featured.jpg +0 -0
  240. package/img/large/alison-pritchard.jpg +0 -0
  241. package/img/large/census-monuments-lights-featured.jpg +0 -0
  242. package/img/large/census-monuments-lights.jpg +0 -0
  243. package/img/large/mother-and-daughter-in-ireland.jpg +0 -0
  244. package/img/large/mum-and-child-healthcare-belfast.jpg +0 -0
  245. package/img/large/ons-award-winners.jpg +0 -0
  246. package/img/large/placeholder-card.png +0 -0
  247. package/img/large/placeholder-news-medium.png +0 -0
  248. package/img/large/placeholder-news.png +0 -0
  249. package/img/large/placeholder-portrait.png +0 -0
  250. package/img/large/students.jpg +0 -0
  251. package/img/large/woman-in-purple-dress-shirt.jpg +0 -0
  252. package/img/small/alison-pritchard-featured.jpg +0 -0
  253. package/img/small/alison-pritchard.jpg +0 -0
  254. package/img/small/census-monuments-lights-featured.jpg +0 -0
  255. package/img/small/census-monuments-lights.jpg +0 -0
  256. package/img/small/mother-and-daughter-in-ireland.jpg +0 -0
  257. package/img/small/mum-and-child-healthcare-belfast.jpg +0 -0
  258. package/img/small/ons-award-winners.jpg +0 -0
  259. package/img/small/placeholder-card.png +0 -0
  260. package/img/small/placeholder-news-medium.png +0 -0
  261. package/img/small/placeholder-news.png +0 -0
  262. package/img/small/placeholder-portrait.png +0 -0
  263. package/img/small/students.jpg +0 -0
  264. package/img/small/woman-in-purple-dress-shirt.jpg +0 -0
  265. package/js/abortable-fetch.js +23 -23
  266. package/js/analytics.js +53 -53
  267. package/js/cookies-functions.js +135 -135
  268. package/js/cookies-settings.dom.js +7 -7
  269. package/js/cookies-settings.js +77 -77
  270. package/js/cookies-settings.spec.js +106 -106
  271. package/js/domready.js +8 -8
  272. package/js/fetch.js +14 -14
  273. package/js/inpagelink.dom.js +5 -5
  274. package/js/inpagelink.js +19 -19
  275. package/js/polyfills.js +0 -1
  276. package/js/print-button.js +6 -6
  277. package/js/timeout.js +211 -211
  278. package/layout/_template.njk +5 -7
  279. package/package.json +131 -127
  280. package/scripts/main.es5.js +1 -1
  281. package/scripts/main.js +1 -1
  282. package/scss/base/_forms.scss +10 -10
  283. package/scss/base/_global.scss +45 -44
  284. package/scss/base/_typography.scss +20 -20
  285. package/scss/helpers/_functions.scss +18 -15
  286. package/scss/helpers/_mixins.scss +59 -53
  287. package/scss/helpers/_mq.scss +62 -65
  288. package/scss/objects/_container.scss +20 -20
  289. package/scss/objects/_page.scss +33 -33
  290. package/scss/objects/_spacing.scss +10 -10
  291. package/scss/overrides/hcm.scss +237 -237
  292. package/scss/overrides/rtl.scss +95 -95
  293. package/scss/print.scss +47 -47
  294. package/scss/utilities/_border.scss +7 -7
  295. package/scss/utilities/_colors.scss +6 -6
  296. package/scss/utilities/_display.scss +8 -8
  297. package/scss/utilities/_float.scss +7 -7
  298. package/scss/utilities/_grid.scss +144 -144
  299. package/scss/utilities/_highlight.scss +4 -4
  300. package/scss/utilities/_margin.scss +17 -17
  301. package/scss/utilities/_pad.scss +15 -15
  302. package/scss/utilities/_typography.scss +35 -33
  303. package/scss/utilities/_utilities.scss +8 -8
  304. package/scss/utilities/_visibility.scss +25 -25
  305. package/scss/vars/_colors.scss +116 -116
  306. package/scss/vars/_forms.scss +22 -22
  307. package/scss/vars/_grid.scss +11 -9
  308. package/scss/vars/_typography.scss +54 -54
@@ -6,693 +6,693 @@ import axe from '../../tests/helpers/axe';
6
6
  import { renderComponent, templateFaker } from '../../tests/helpers/rendering';
7
7
 
8
8
  const EXAMPLE_INPUT_MINIMAL = {
9
- id: 'example-id',
10
- name: 'example-name',
9
+ id: 'example-id',
10
+ name: 'example-name',
11
11
  };
12
12
 
13
13
  const EXAMPLE_INPUT_WITH_LABEL = {
14
- ...EXAMPLE_INPUT_MINIMAL,
15
- label: {
16
- id: 'example-input-label',
17
- text: 'Example input label',
18
- classes: 'extra-label-class',
19
- description: 'Example input label description',
20
- attributes: { a: 42 },
21
- inline: false,
22
- },
23
- accessiblePlaceholder: true,
14
+ ...EXAMPLE_INPUT_MINIMAL,
15
+ label: {
16
+ id: 'example-input-label',
17
+ text: 'Example input label',
18
+ classes: 'extra-label-class',
19
+ description: 'Example input label description',
20
+ attributes: { a: 42 },
21
+ inline: false,
22
+ },
23
+ accessiblePlaceholder: true,
24
24
  };
25
25
 
26
26
  const EXAMPLE_INPUT_WITH_ERROR = {
27
- ...EXAMPLE_INPUT_WITH_LABEL,
28
- error: {
29
- id: 'feedback-error',
30
- text: 'Enter your feedback',
31
- },
27
+ ...EXAMPLE_INPUT_WITH_LABEL,
28
+ error: {
29
+ id: 'feedback-error',
30
+ text: 'Enter your feedback',
31
+ },
32
32
  };
33
33
 
34
34
  const EXAMPLE_WITH_SEARCH = {
35
- ...EXAMPLE_INPUT_MINIMAL,
36
- accessiblePlaceholder: true,
37
- searchButton: {
38
- type: 'button',
39
- text: 'Search for address',
40
- id: 'search-for-address',
41
- attributes: { a: 42 },
42
- classes: 'extra-search-button-class',
43
- iconType: 'search',
44
- visuallyHideButtonText: true,
45
- },
35
+ ...EXAMPLE_INPUT_MINIMAL,
36
+ accessiblePlaceholder: true,
37
+ searchButton: {
38
+ type: 'button',
39
+ text: 'Search for address',
40
+ id: 'search-for-address',
41
+ attributes: { a: 42 },
42
+ classes: 'extra-search-button-class',
43
+ iconType: 'search',
44
+ visuallyHideButtonText: true,
45
+ },
46
46
  };
47
47
 
48
48
  const EXAMPLE_INPUT_WITH_CHARACTER_LIMIT = {
49
- ...EXAMPLE_INPUT_MINIMAL,
50
- minLength: 10,
51
- maxLength: 200,
52
- charCheckLimit: {
53
- limit: 200,
54
- charCountSingular: 'You have {x} character remaining',
55
- charCountPlural: 'You have {x} characters remaining',
56
- charCountOverLimitSingular: '{x} character too many',
57
- charCountOverLimitPlural: '{x} characters too many',
58
- },
49
+ ...EXAMPLE_INPUT_MINIMAL,
50
+ minLength: 10,
51
+ maxLength: 200,
52
+ charCheckLimit: {
53
+ limit: 200,
54
+ charCountSingular: 'You have {x} character remaining',
55
+ charCountPlural: 'You have {x} characters remaining',
56
+ charCountOverLimitSingular: '{x} character too many',
57
+ charCountOverLimitPlural: '{x} characters too many',
58
+ },
59
59
  };
60
60
 
61
61
  const EXAMPLE_INPUT_WITH_MUTUALLY_EXCLUSIVE_WITH_ERROR = {
62
- ...EXAMPLE_INPUT_WITH_ERROR,
63
- dontWrap: true,
64
- mutuallyExclusive: {
65
- or: 'Or',
66
- deselectMessage: 'Selecting this will clear your feedback',
67
- deselectGroupAdjective: 'cleared',
68
- deselectExclusiveOptionAdjective: 'deselected',
69
- exclusiveOptions: [
70
- {
71
- id: 'feedback-exclusive-option',
72
- name: 'no-feedback',
73
- value: 'no-feedback',
74
- label: {
75
- text: 'I dont want to provide feedback',
76
- },
77
- },
78
- ],
79
- },
62
+ ...EXAMPLE_INPUT_WITH_ERROR,
63
+ dontWrap: true,
64
+ mutuallyExclusive: {
65
+ or: 'Or',
66
+ deselectMessage: 'Selecting this will clear your feedback',
67
+ deselectGroupAdjective: 'cleared',
68
+ deselectExclusiveOptionAdjective: 'deselected',
69
+ exclusiveOptions: [
70
+ {
71
+ id: 'feedback-exclusive-option',
72
+ name: 'no-feedback',
73
+ value: 'no-feedback',
74
+ label: {
75
+ text: 'I dont want to provide feedback',
76
+ },
77
+ },
78
+ ],
79
+ },
80
80
  };
81
81
 
82
82
  describe('macro: input', () => {
83
- it('passes jest-axe checks', async () => {
84
- const $ = cheerio.load(renderComponent('input', EXAMPLE_INPUT_WITH_LABEL));
85
-
86
- const results = await axe($.html());
87
- expect(results).toHaveNoViolations();
88
- });
89
-
90
- it('has the provided `id` attribute', () => {
91
- const $ = cheerio.load(renderComponent('input', EXAMPLE_INPUT_MINIMAL));
92
-
93
- expect($('.ons-input').attr('id')).toBe('example-id');
94
- });
95
-
96
- it('has the provided `name` attribute', () => {
97
- const $ = cheerio.load(renderComponent('input', EXAMPLE_INPUT_MINIMAL));
98
-
99
- expect($('.ons-input').attr('name')).toBe('example-name');
100
- });
101
-
102
- it('has additionally provided `attributes`', () => {
103
- const $ = cheerio.load(
104
- renderComponent('input', {
105
- ...EXAMPLE_INPUT_MINIMAL,
106
- attributes: { a: '123', b: '456' },
107
- }),
108
- );
109
-
110
- expect($('.ons-input').attr('a')).toBe('123');
111
- expect($('.ons-input').attr('b')).toBe('456');
112
- });
113
-
114
- it('outputs number type in a way that works with more browsers', () => {
115
- const $ = cheerio.load(
116
- renderComponent('input', {
117
- ...EXAMPLE_INPUT_MINIMAL,
118
- type: 'number',
119
- }),
120
- );
121
-
122
- expect($('.ons-input').attr('type')).toBe('text');
123
- expect($('.ons-input').attr('pattern')).toBe('[0-9]*');
124
- expect($('.ons-input').attr('inputmode')).toBe('numeric');
125
- });
126
-
127
- it('has additionally provided style classes', () => {
128
- const $ = cheerio.load(
129
- renderComponent('input', {
130
- ...EXAMPLE_INPUT_MINIMAL,
131
- classes: 'extra-class another-extra-class',
132
- }),
133
- );
134
-
135
- expect($('.ons-input').hasClass('extra-class')).toBe(true);
136
- expect($('.ons-input').hasClass('another-extra-class')).toBe(true);
137
- });
138
-
139
- it('does not have "placeholder" modifier', () => {
140
- const $ = cheerio.load(renderComponent('input', EXAMPLE_INPUT_MINIMAL));
141
-
142
- expect($('.ons-input').hasClass('ons-input--placeholder')).toBe(false);
143
- });
144
-
145
- it('has "placeholder" modifier when `accessiblePlaceholder` is provided', () => {
146
- const $ = cheerio.load(renderComponent('input', EXAMPLE_INPUT_WITH_LABEL));
147
-
148
- expect($('.ons-input').hasClass('ons-input--placeholder')).toBe(true);
149
- });
150
-
151
- it('does not have `placeholder` attribute', () => {
152
- const $ = cheerio.load(renderComponent('input', EXAMPLE_INPUT_MINIMAL));
153
-
154
- expect($('.ons-input').attr('placeholder')).toBeUndefined();
155
- });
156
-
157
- it('has `placeholder` attribute when `placeholder` is provided', () => {
158
- const $ = cheerio.load(renderComponent('input', EXAMPLE_INPUT_WITH_LABEL));
159
-
160
- expect($('.ons-input').attr('placeholder')).toBe('Example input label');
161
- });
162
-
163
- it('does not have `min` attribute', () => {
164
- const $ = cheerio.load(renderComponent('input', EXAMPLE_INPUT_MINIMAL));
165
-
166
- expect($('.ons-input').attr('min')).toBeUndefined();
167
- });
168
-
169
- it('has `min` attribute when `min` is provided', () => {
170
- const $ = cheerio.load(
171
- renderComponent('input', {
172
- ...EXAMPLE_INPUT_MINIMAL,
173
- min: 10,
174
- }),
175
- );
176
-
177
- expect($('.ons-input').attr('min')).toBe('10');
178
- });
179
-
180
- it('does not have `max` attribute', () => {
181
- const $ = cheerio.load(renderComponent('input', EXAMPLE_INPUT_MINIMAL));
182
-
183
- expect($('.ons-input').attr('max')).toBeUndefined();
184
- });
185
-
186
- it('has `max` attribute when `max` is provided', () => {
187
- const $ = cheerio.load(
188
- renderComponent('input', {
189
- ...EXAMPLE_INPUT_MINIMAL,
190
- max: 100,
191
- }),
192
- );
193
-
194
- expect($('.ons-input').attr('max')).toBe('100');
195
- });
196
-
197
- it('does not have `value` attribute', () => {
198
- const $ = cheerio.load(renderComponent('input', EXAMPLE_INPUT_MINIMAL));
199
-
200
- expect($('.ons-input').attr('value')).toBeUndefined();
201
- });
202
-
203
- it('has `value` attribute when `value` is provided', () => {
204
- const $ = cheerio.load(
205
- renderComponent('input', {
206
- ...EXAMPLE_INPUT_MINIMAL,
207
- value: '100',
208
- }),
209
- );
210
-
211
- expect($('.ons-input').attr('value')).toBe('100');
212
- });
213
-
214
- it('does not have `accept` attribute', () => {
215
- const $ = cheerio.load(renderComponent('input', EXAMPLE_INPUT_MINIMAL));
216
-
217
- expect($('.ons-input').attr('accept')).toBeUndefined();
218
- });
219
-
220
- it('has `accept` attribute when `accept` is provided', () => {
221
- const $ = cheerio.load(
222
- renderComponent('input', {
223
- ...EXAMPLE_INPUT_MINIMAL,
224
- accept: 'image/*',
225
- }),
226
- );
227
-
228
- expect($('.ons-input').attr('accept')).toBe('image/*');
229
- });
230
-
231
- it('does not have `autocomplete` attribute', () => {
232
- const $ = cheerio.load(renderComponent('input', EXAMPLE_INPUT_MINIMAL));
233
-
234
- expect($('.ons-input').attr('autocomplete')).toBeUndefined();
235
- });
236
-
237
- it('has `autocomplete` attribute when `autocomplete` is provided', () => {
238
- const $ = cheerio.load(
239
- renderComponent('input', {
240
- ...EXAMPLE_INPUT_MINIMAL,
241
- autocomplete: 'on',
242
- }),
243
- );
244
-
245
- expect($('.ons-input').attr('autocomplete')).toBe('on');
246
- });
247
-
248
- it.each([['email'], ['tel'], ['text']])('outputs `type` attribute of "%s"', (type) => {
249
- const $ = cheerio.load(
250
- renderComponent('input', {
251
- ...EXAMPLE_INPUT_MINIMAL,
252
- type,
253
- }),
254
- );
255
-
256
- expect($('.ons-input').attr('type')).toBe(type);
257
- expect($('.ons-input').attr('pattern')).toBeUndefined();
258
- expect($('.ons-input').attr('inputmode')).toBeUndefined();
259
- });
260
-
261
- it.each([
262
- ['number', 10, 'ons-input-number--w-10'],
263
- ['tel', 20, 'ons-input-number--w-20'],
264
- ])('adds class "ons-input-number" when `type` is "%s"', (type, width, expectedClass) => {
265
- const $ = cheerio.load(
266
- renderComponent('input', {
267
- ...EXAMPLE_INPUT_MINIMAL,
268
- type,
269
- width,
270
- }),
271
- );
272
-
273
- expect($('.ons-input').hasClass(expectedClass)).toBe(true);
274
- });
275
-
276
- describe('listeners', () => {
277
- it('renders each listener', () => {
278
- const $ = cheerio.load(
279
- renderComponent('input', {
280
- ...EXAMPLE_INPUT_MINIMAL,
281
- listeners: {
282
- click: `alert('Input was clicked')`,
283
- keypress: `alert('Key was pressed')`,
284
- },
285
- }),
286
- );
287
-
288
- const script = $('script').html();
289
- expect(script).toContain(
290
- `document.getElementById("example-id").addEventListener('click', function(){ alert('Input was clicked') });`,
291
- );
292
- expect(script).toContain(
293
- `document.getElementById("example-id").addEventListener('keypress', function(){ alert('Key was pressed') });`,
294
- );
295
- });
296
- });
297
-
298
- it('renders field component', () => {
299
- const faker = templateFaker();
300
- const fieldSpy = faker.spy('field');
301
-
302
- faker.renderComponent('input', {
303
- ...EXAMPLE_INPUT_WITH_ERROR,
304
- fieldId: 'example-field-id',
305
- fieldClasses: 'extra-field-class',
306
- dontWrap: true,
307
- });
83
+ it('passes jest-axe checks', async () => {
84
+ const $ = cheerio.load(renderComponent('input', EXAMPLE_INPUT_WITH_LABEL));
308
85
 
309
- expect(fieldSpy.occurrences).toContainEqual({
310
- id: 'example-field-id',
311
- classes: 'extra-field-class',
312
- dontWrap: true,
313
- error: EXAMPLE_INPUT_WITH_ERROR.error,
314
- inline: false,
86
+ const results = await axe($.html());
87
+ expect(results).toHaveNoViolations();
315
88
  });
316
- });
317
89
 
318
- describe('label', () => {
319
- it('does not output a label when `label` is not provided', () => {
320
- const faker = templateFaker();
321
- const labelSpy = faker.spy('label');
90
+ it('has the provided `id` attribute', () => {
91
+ const $ = cheerio.load(renderComponent('input', EXAMPLE_INPUT_MINIMAL));
322
92
 
323
- faker.renderComponent('input', EXAMPLE_INPUT_MINIMAL);
324
-
325
- expect(labelSpy.occurrences.length).toBe(0);
93
+ expect($('.ons-input').attr('id')).toBe('example-id');
326
94
  });
327
95
 
328
- it('outputs a label when `label` is provided', () => {
329
- const faker = templateFaker();
330
- const labelSpy = faker.spy('label');
331
-
332
- faker.renderComponent('input', EXAMPLE_INPUT_WITH_LABEL);
96
+ it('has the provided `name` attribute', () => {
97
+ const $ = cheerio.load(renderComponent('input', EXAMPLE_INPUT_MINIMAL));
333
98
 
334
- expect(labelSpy.occurrences).toContainEqual({
335
- for: 'example-id',
336
- id: 'example-input-label',
337
- text: 'Example input label',
338
- classes: 'extra-label-class',
339
- description: 'Example input label description',
340
- attributes: { a: 42 },
341
- inline: false,
342
- accessiblePlaceholder: true,
343
- });
99
+ expect($('.ons-input').attr('name')).toBe('example-name');
344
100
  });
345
101
 
346
- it('outputs `aria-describedby` attribute referencing the label', () => {
347
- const $ = cheerio.load(renderComponent('input', EXAMPLE_INPUT_WITH_LABEL));
102
+ it('has additionally provided `attributes`', () => {
103
+ const $ = cheerio.load(
104
+ renderComponent('input', {
105
+ ...EXAMPLE_INPUT_MINIMAL,
106
+ attributes: { a: '123', b: '456' },
107
+ }),
108
+ );
348
109
 
349
- expect($('.ons-input').attr('aria-describedby')).toBe('example-input-label-description-hint');
110
+ expect($('.ons-input').attr('a')).toBe('123');
111
+ expect($('.ons-input').attr('b')).toBe('456');
350
112
  });
351
113
 
352
- it('outputs a default `aria-describedby` attribute referencing the label when label does not have an `id`', () => {
353
- const $ = cheerio.load(
354
- renderComponent('input', {
355
- ...EXAMPLE_INPUT_MINIMAL,
356
- label: {
357
- text: 'Example input label',
358
- description: 'Example input label description',
359
- },
360
- }),
361
- );
362
-
363
- expect($('.ons-input').attr('aria-describedby')).toBe('description-hint');
364
- });
365
- });
114
+ it('outputs number type in a way that works with more browsers', () => {
115
+ const $ = cheerio.load(
116
+ renderComponent('input', {
117
+ ...EXAMPLE_INPUT_MINIMAL,
118
+ type: 'number',
119
+ }),
120
+ );
366
121
 
367
- describe('prefix and suffix', () => {
368
- it('passes jest-axe checks', async () => {
369
- const $ = cheerio.load(
370
- renderComponent('input', {
371
- ...EXAMPLE_INPUT_MINIMAL,
372
- prefix: {
373
- id: 'example-prefix-id',
374
- title: 'Example prefix title',
375
- },
376
- }),
377
- );
378
-
379
- const results = await axe($.html());
380
- expect(results).toHaveNoViolations();
122
+ expect($('.ons-input').attr('type')).toBe('text');
123
+ expect($('.ons-input').attr('pattern')).toBe('[0-9]*');
124
+ expect($('.ons-input').attr('inputmode')).toBe('numeric');
381
125
  });
382
126
 
383
- it('adds `aria-labelledby` attribute when `prefix` is provided with `prefix.title`', () => {
384
- const $ = cheerio.load(
385
- renderComponent('input', {
386
- ...EXAMPLE_INPUT_MINIMAL,
387
- prefix: {
388
- id: 'example-prefix-id',
389
- title: 'Example prefix title',
390
- },
391
- }),
392
- );
393
-
394
- expect($('.ons-input').attr('aria-labelledby')).toBe('example-id example-prefix-id');
395
- });
127
+ it('has additionally provided style classes', () => {
128
+ const $ = cheerio.load(
129
+ renderComponent('input', {
130
+ ...EXAMPLE_INPUT_MINIMAL,
131
+ classes: 'extra-class another-extra-class',
132
+ }),
133
+ );
396
134
 
397
- it('adds `aria-labelledby` attribute when `prefix` is provided without `prefix.title`', () => {
398
- const $ = cheerio.load(
399
- renderComponent('input', {
400
- ...EXAMPLE_INPUT_MINIMAL,
401
- prefix: {
402
- id: 'example-prefix-id',
403
- },
404
- }),
405
- );
406
-
407
- expect($('.ons-input').attr('aria-labelledby')).toBe('example-prefix-id');
135
+ expect($('.ons-input').hasClass('extra-class')).toBe(true);
136
+ expect($('.ons-input').hasClass('another-extra-class')).toBe(true);
408
137
  });
409
138
 
410
- it('renders prefix element from `prefix.text`', () => {
411
- const $ = cheerio.load(
412
- renderComponent('input', {
413
- ...EXAMPLE_INPUT_MINIMAL,
414
- prefix: {
415
- id: 'example-prefix-id',
416
- title: 'Example prefix title',
417
- text: 'Example prefix text',
418
- },
419
- }),
420
- );
421
-
422
- expect($('.ons-input-type--prefix .ons-js-input-abbr').attr('id')).toBe('example-prefix-id');
423
- expect($('.ons-input-type--prefix .ons-js-input-abbr').attr('title')).toBe('Example prefix title');
424
- expect($('.ons-input-type--prefix .ons-js-input-abbr').text().trim()).toBe('Example prefix text');
425
- });
139
+ it('does not have "placeholder" modifier', () => {
140
+ const $ = cheerio.load(renderComponent('input', EXAMPLE_INPUT_MINIMAL));
426
141
 
427
- it('does not render prefix element when `prefix.id` not set', () => {
428
- const $ = cheerio.load(
429
- renderComponent('input', {
430
- ...EXAMPLE_INPUT_MINIMAL,
431
- prefix: {
432
- title: 'Example prefix title',
433
- text: 'Example prefix text',
434
- },
435
- }),
436
- );
437
-
438
- expect($('.ons-input-type--prefix').length).toBe(0);
142
+ expect($('.ons-input').hasClass('ons-input--placeholder')).toBe(false);
439
143
  });
440
144
 
441
- it('adds `aria-labelledby` attribute when `suffix` is provided', () => {
442
- const $ = cheerio.load(
443
- renderComponent('input', {
444
- ...EXAMPLE_INPUT_MINIMAL,
445
- suffix: {
446
- id: 'example-suffix-id',
447
- title: 'Example suffix title',
448
- },
449
- }),
450
- );
451
-
452
- expect($('.ons-input').attr('aria-labelledby')).toBe('example-id example-suffix-id');
453
- });
145
+ it('has "placeholder" modifier when `accessiblePlaceholder` is provided', () => {
146
+ const $ = cheerio.load(renderComponent('input', EXAMPLE_INPUT_WITH_LABEL));
454
147
 
455
- it('adds `aria-labelledby` attribute when `suffix` is provided without `suffix.title`', () => {
456
- const $ = cheerio.load(
457
- renderComponent('input', {
458
- ...EXAMPLE_INPUT_MINIMAL,
459
- suffix: {
460
- id: 'example-suffix-id',
461
- },
462
- }),
463
- );
464
-
465
- expect($('.ons-input').attr('aria-labelledby')).toBe('example-suffix-id');
148
+ expect($('.ons-input').hasClass('ons-input--placeholder')).toBe(true);
466
149
  });
467
150
 
468
- it('renders suffix element from `suffix.text`', () => {
469
- const $ = cheerio.load(
470
- renderComponent('input', {
471
- ...EXAMPLE_INPUT_MINIMAL,
472
- suffix: {
473
- id: 'example-suffix-id',
474
- title: 'Example suffix title',
475
- text: 'Example suffix text',
476
- },
477
- }),
478
- );
479
-
480
- expect($('.ons-js-input-abbr').attr('id')).toBe('example-suffix-id');
481
- expect($('.ons-js-input-abbr').attr('title')).toBe('Example suffix title');
482
- expect($('.ons-js-input-abbr').text().trim()).toBe('Example suffix text');
483
- });
151
+ it('does not have `placeholder` attribute', () => {
152
+ const $ = cheerio.load(renderComponent('input', EXAMPLE_INPUT_MINIMAL));
484
153
 
485
- it('does not render suffix element when `suffix.id` not set', () => {
486
- const $ = cheerio.load(
487
- renderComponent('input', {
488
- ...EXAMPLE_INPUT_MINIMAL,
489
- suffix: {
490
- title: 'Example suffix title',
491
- text: 'Example suffix text',
492
- },
493
- }),
494
- );
495
-
496
- expect($('.ons-input').length).toBe(0);
154
+ expect($('.ons-input').attr('placeholder')).toBeUndefined();
497
155
  });
498
156
 
499
- it('renders an `abbr` tag when `title` set', () => {
500
- const $ = cheerio.load(
501
- renderComponent('input', {
502
- ...EXAMPLE_INPUT_MINIMAL,
503
- suffix: {
504
- text: 'Example suffix text',
505
- title: 'Example suffix title',
506
- id: 'example-suffix-id',
507
- },
508
- }),
509
- );
510
-
511
- expect($('.ons-input + abbr').length).toBe(1);
512
- });
157
+ it('has `placeholder` attribute when `placeholder` is provided', () => {
158
+ const $ = cheerio.load(renderComponent('input', EXAMPLE_INPUT_WITH_LABEL));
513
159
 
514
- it('renders a `span` tag when `title` not set', () => {
515
- const $ = cheerio.load(
516
- renderComponent('input', {
517
- ...EXAMPLE_INPUT_MINIMAL,
518
- suffix: {
519
- text: 'Example suffix text',
520
- id: 'example-suffix-id',
521
- },
522
- }),
523
- );
524
-
525
- expect($('.ons-input + span').length).toBe(1);
160
+ expect($('.ons-input').attr('placeholder')).toBe('Example input label');
526
161
  });
527
- });
528
162
 
529
- describe('search', () => {
530
- it.each('outputs `type` attribute of "search"', () => {
531
- const $ = cheerio.load(renderComponent('input', EXAMPLE_WITH_SEARCH));
163
+ it('does not have `min` attribute', () => {
164
+ const $ = cheerio.load(renderComponent('input', EXAMPLE_INPUT_MINIMAL));
532
165
 
533
- expect($('.ons-input').attr('type')).toBe('search');
534
- expect($('.ons-input').attr('pattern')).toBeUndefined();
535
- expect($('.ons-input').attr('inputmode')).toBeUndefined();
166
+ expect($('.ons-input').attr('min')).toBeUndefined();
536
167
  });
537
168
 
538
- it('has the "ons-search__input" class', () => {
539
- const $ = cheerio.load(renderComponent('input', EXAMPLE_WITH_SEARCH));
169
+ it('has `min` attribute when `min` is provided', () => {
170
+ const $ = cheerio.load(
171
+ renderComponent('input', {
172
+ ...EXAMPLE_INPUT_MINIMAL,
173
+ min: 10,
174
+ }),
175
+ );
540
176
 
541
- expect($('.ons-input').hasClass('ons-search__input')).toBe(true);
542
- });
543
- });
544
-
545
- describe('with character limit', () => {
546
- it('passes jest-axe checks', async () => {
547
- const $ = cheerio.load(
548
- renderComponent('input', {
549
- ...EXAMPLE_INPUT_WITH_CHARACTER_LIMIT,
550
- label: {
551
- id: 'example-input-label',
552
- text: 'Example input label',
553
- },
554
- }),
555
- );
556
-
557
- const results = await axe($.html());
558
- expect(results).toHaveNoViolations();
177
+ expect($('.ons-input').attr('min')).toBe('10');
559
178
  });
560
179
 
561
- it('has the provided minimum length', () => {
562
- const $ = cheerio.load(renderComponent('input', EXAMPLE_INPUT_WITH_CHARACTER_LIMIT));
180
+ it('does not have `max` attribute', () => {
181
+ const $ = cheerio.load(renderComponent('input', EXAMPLE_INPUT_MINIMAL));
563
182
 
564
- expect($('.ons-input').attr('minlength')).toBe('10');
183
+ expect($('.ons-input').attr('max')).toBeUndefined();
565
184
  });
566
185
 
567
- it('has the provided maximum length', () => {
568
- const $ = cheerio.load(renderComponent('input', EXAMPLE_INPUT_WITH_CHARACTER_LIMIT));
186
+ it('has `max` attribute when `max` is provided', () => {
187
+ const $ = cheerio.load(
188
+ renderComponent('input', {
189
+ ...EXAMPLE_INPUT_MINIMAL,
190
+ max: 100,
191
+ }),
192
+ );
569
193
 
570
- expect($('.ons-input').attr('maxlength')).toBe('200');
194
+ expect($('.ons-input').attr('max')).toBe('100');
571
195
  });
572
196
 
573
- it('does not have `data-char-check-countdown` attribute when `charcheckCountdown` is not provided', () => {
574
- const $ = cheerio.load(renderComponent('input', EXAMPLE_INPUT_WITH_CHARACTER_LIMIT));
197
+ it('does not have `value` attribute', () => {
198
+ const $ = cheerio.load(renderComponent('input', EXAMPLE_INPUT_MINIMAL));
575
199
 
576
- expect($('.ons-input').attr('data-char-check-countdown')).toBe(undefined);
200
+ expect($('.ons-input').attr('value')).toBeUndefined();
577
201
  });
578
202
 
579
- it('has `data-char-check-countdown` attribute when `charcheckCountdown` is true', () => {
580
- const $ = cheerio.load(
581
- renderComponent('input', {
582
- ...EXAMPLE_INPUT_WITH_CHARACTER_LIMIT,
583
- charCheckLimit: {
584
- ...EXAMPLE_INPUT_WITH_CHARACTER_LIMIT.charCheckLimit,
585
- charcheckCountdown: true,
586
- },
587
- }),
588
- );
589
-
590
- expect($('.ons-input').attr('data-char-check-countdown')).toBe('true');
591
- });
592
-
593
- it('has data attribute which references the character limit component', () => {
594
- const $ = cheerio.load(renderComponent('input', EXAMPLE_INPUT_WITH_CHARACTER_LIMIT));
203
+ it('has `value` attribute when `value` is provided', () => {
204
+ const $ = cheerio.load(
205
+ renderComponent('input', {
206
+ ...EXAMPLE_INPUT_MINIMAL,
207
+ value: '100',
208
+ }),
209
+ );
595
210
 
596
- expect($('.ons-input').attr('data-char-check-ref')).toBe('example-id-check');
211
+ expect($('.ons-input').attr('value')).toBe('100');
597
212
  });
598
213
 
599
- it('has data attribute which defines limit for character check', () => {
600
- const $ = cheerio.load(renderComponent('input', EXAMPLE_INPUT_WITH_CHARACTER_LIMIT));
214
+ it('does not have `accept` attribute', () => {
215
+ const $ = cheerio.load(renderComponent('input', EXAMPLE_INPUT_MINIMAL));
601
216
 
602
- expect($('.ons-input').attr('data-char-check-num')).toBe('200');
217
+ expect($('.ons-input').attr('accept')).toBeUndefined();
603
218
  });
604
219
 
605
- it('has `aria-describedby` attribute which references the character limit component', () => {
606
- const $ = cheerio.load(renderComponent('input', EXAMPLE_INPUT_WITH_CHARACTER_LIMIT));
220
+ it('has `accept` attribute when `accept` is provided', () => {
221
+ const $ = cheerio.load(
222
+ renderComponent('input', {
223
+ ...EXAMPLE_INPUT_MINIMAL,
224
+ accept: 'image/*',
225
+ }),
226
+ );
607
227
 
608
- expect($('.ons-input').attr('aria-describedby')).toBe('example-id-check');
228
+ expect($('.ons-input').attr('accept')).toBe('image/*');
609
229
  });
610
230
 
611
- it('renders character limit component', () => {
612
- const faker = templateFaker();
613
- const charCheckLimitSpy = faker.spy('char-check-limit');
231
+ it('does not have `autocomplete` attribute', () => {
232
+ const $ = cheerio.load(renderComponent('input', EXAMPLE_INPUT_MINIMAL));
614
233
 
615
- faker.renderComponent('input', EXAMPLE_INPUT_WITH_CHARACTER_LIMIT);
616
-
617
- expect(charCheckLimitSpy.occurrences).toContainEqual({
618
- id: 'example-id-check',
619
- limit: 200,
620
- variant: 'check',
621
- charCountSingular: 'You have {x} character remaining',
622
- charCountPlural: 'You have {x} characters remaining',
623
- charCountOverLimitSingular: '{x} character too many',
624
- charCountOverLimitPlural: '{x} characters too many',
625
- });
234
+ expect($('.ons-input').attr('autocomplete')).toBeUndefined();
626
235
  });
627
- });
628
236
 
629
- describe('with error', () => {
630
- it('has the `error` modifier class', () => {
631
- const $ = cheerio.load(renderComponent('input', EXAMPLE_INPUT_WITH_ERROR));
237
+ it('has `autocomplete` attribute when `autocomplete` is provided', () => {
238
+ const $ = cheerio.load(
239
+ renderComponent('input', {
240
+ ...EXAMPLE_INPUT_MINIMAL,
241
+ autocomplete: 'on',
242
+ }),
243
+ );
632
244
 
633
- expect($('.ons-input').hasClass('ons-input--error')).toBe(true);
634
- });
635
- });
636
-
637
- describe('with post textbox link', () => {
638
- it('renders the expected link', () => {
639
- const $ = cheerio.load(
640
- renderComponent('input', {
641
- ...EXAMPLE_INPUT_MINIMAL,
642
- postTextboxLinkUrl: 'https://example.com/link',
643
- postTextboxLinkText: 'Example link',
644
- }),
645
- );
646
-
647
- expect($('a.ons-input__post-link').attr('href')).toBe('https://example.com/link');
648
- expect($('a.ons-input__post-link').text().trim()).toBe('Example link');
245
+ expect($('.ons-input').attr('autocomplete')).toBe('on');
649
246
  });
650
- });
651
247
 
652
- describe('mutually exclusive', () => {
653
- it('passes jest-axe checks', async () => {
654
- const $ = cheerio.load(renderComponent('input', EXAMPLE_INPUT_WITH_MUTUALLY_EXCLUSIVE_WITH_ERROR));
248
+ it.each([['email'], ['tel'], ['text']])('outputs `type` attribute of "%s"', (type) => {
249
+ const $ = cheerio.load(
250
+ renderComponent('input', {
251
+ ...EXAMPLE_INPUT_MINIMAL,
252
+ type,
253
+ }),
254
+ );
655
255
 
656
- const results = await axe($.html());
657
- expect(results).toHaveNoViolations();
256
+ expect($('.ons-input').attr('type')).toBe(type);
257
+ expect($('.ons-input').attr('pattern')).toBeUndefined();
258
+ expect($('.ons-input').attr('inputmode')).toBeUndefined();
658
259
  });
659
260
 
660
- it('has the `ons-js-exclusive-group-item` class', () => {
661
- const $ = cheerio.load(renderComponent('input', EXAMPLE_INPUT_WITH_MUTUALLY_EXCLUSIVE_WITH_ERROR));
261
+ it.each([
262
+ ['number', 10, 'ons-input-number--w-10'],
263
+ ['tel', 20, 'ons-input-number--w-20'],
264
+ ])('adds class "ons-input-number" when `type` is "%s"', (type, width, expectedClass) => {
265
+ const $ = cheerio.load(
266
+ renderComponent('input', {
267
+ ...EXAMPLE_INPUT_MINIMAL,
268
+ type,
269
+ width,
270
+ }),
271
+ );
662
272
 
663
- expect($('.ons-input').hasClass('ons-js-exclusive-group-item')).toBe(true);
273
+ expect($('.ons-input').hasClass(expectedClass)).toBe(true);
664
274
  });
665
275
 
666
- it('renders mutually exclusive component', () => {
667
- const faker = templateFaker();
668
- const mutuallyExclusiveSpy = faker.spy('mutually-exclusive');
669
-
670
- faker.renderComponent('input', {
671
- ...EXAMPLE_INPUT_WITH_MUTUALLY_EXCLUSIVE_WITH_ERROR,
672
- fieldId: 'example-field-id',
673
- fieldClasses: 'extra-field-class',
674
- legend: 'Legend text',
675
- legendClasses: 'extra-legend-class',
676
- description: 'Example description text',
677
- legendIsQuestionTitle: true,
678
- autosuggestResults: 'RESULTS',
679
- });
680
-
681
- expect(mutuallyExclusiveSpy.occurrences).toContainEqual({
682
- id: 'example-field-id',
683
- legend: 'Legend text',
684
- legendClasses: 'extra-legend-class ons-js-input-legend',
685
- description: 'Example description text',
686
- dontWrap: true,
687
- legendIsQuestionTitle: true,
688
- exclusiveOptions: EXAMPLE_INPUT_WITH_MUTUALLY_EXCLUSIVE_WITH_ERROR.mutuallyExclusive.exclusiveOptions,
689
- or: 'Or',
690
- deselectMessage: 'Selecting this will clear your feedback',
691
- deselectGroupAdjective: 'cleared',
692
- deselectExclusiveOptionAdjective: 'deselected',
693
- error: EXAMPLE_INPUT_WITH_MUTUALLY_EXCLUSIVE_WITH_ERROR.error,
694
- autosuggestResults: 'RESULTS',
695
- });
276
+ describe('listeners', () => {
277
+ it('renders each listener', () => {
278
+ const $ = cheerio.load(
279
+ renderComponent('input', {
280
+ ...EXAMPLE_INPUT_MINIMAL,
281
+ listeners: {
282
+ click: `alert('Input was clicked')`,
283
+ keypress: `alert('Key was pressed')`,
284
+ },
285
+ }),
286
+ );
287
+
288
+ const script = $('script').html();
289
+ expect(script).toContain(
290
+ `document.getElementById("example-id").addEventListener('click', function(){ alert('Input was clicked') });`,
291
+ );
292
+ expect(script).toContain(
293
+ `document.getElementById("example-id").addEventListener('keypress', function(){ alert('Key was pressed') });`,
294
+ );
295
+ });
296
+ });
297
+
298
+ it('renders field component', () => {
299
+ const faker = templateFaker();
300
+ const fieldSpy = faker.spy('field');
301
+
302
+ faker.renderComponent('input', {
303
+ ...EXAMPLE_INPUT_WITH_ERROR,
304
+ fieldId: 'example-field-id',
305
+ fieldClasses: 'extra-field-class',
306
+ dontWrap: true,
307
+ });
308
+
309
+ expect(fieldSpy.occurrences).toContainEqual({
310
+ id: 'example-field-id',
311
+ classes: 'extra-field-class',
312
+ dontWrap: true,
313
+ error: EXAMPLE_INPUT_WITH_ERROR.error,
314
+ inline: false,
315
+ });
316
+ });
317
+
318
+ describe('label', () => {
319
+ it('does not output a label when `label` is not provided', () => {
320
+ const faker = templateFaker();
321
+ const labelSpy = faker.spy('label');
322
+
323
+ faker.renderComponent('input', EXAMPLE_INPUT_MINIMAL);
324
+
325
+ expect(labelSpy.occurrences.length).toBe(0);
326
+ });
327
+
328
+ it('outputs a label when `label` is provided', () => {
329
+ const faker = templateFaker();
330
+ const labelSpy = faker.spy('label');
331
+
332
+ faker.renderComponent('input', EXAMPLE_INPUT_WITH_LABEL);
333
+
334
+ expect(labelSpy.occurrences).toContainEqual({
335
+ for: 'example-id',
336
+ id: 'example-input-label',
337
+ text: 'Example input label',
338
+ classes: 'extra-label-class',
339
+ description: 'Example input label description',
340
+ attributes: { a: 42 },
341
+ inline: false,
342
+ accessiblePlaceholder: true,
343
+ });
344
+ });
345
+
346
+ it('outputs `aria-describedby` attribute referencing the label', () => {
347
+ const $ = cheerio.load(renderComponent('input', EXAMPLE_INPUT_WITH_LABEL));
348
+
349
+ expect($('.ons-input').attr('aria-describedby')).toBe('example-input-label-description-hint');
350
+ });
351
+
352
+ it('outputs a default `aria-describedby` attribute referencing the label when label does not have an `id`', () => {
353
+ const $ = cheerio.load(
354
+ renderComponent('input', {
355
+ ...EXAMPLE_INPUT_MINIMAL,
356
+ label: {
357
+ text: 'Example input label',
358
+ description: 'Example input label description',
359
+ },
360
+ }),
361
+ );
362
+
363
+ expect($('.ons-input').attr('aria-describedby')).toBe('description-hint');
364
+ });
365
+ });
366
+
367
+ describe('prefix and suffix', () => {
368
+ it('passes jest-axe checks', async () => {
369
+ const $ = cheerio.load(
370
+ renderComponent('input', {
371
+ ...EXAMPLE_INPUT_MINIMAL,
372
+ prefix: {
373
+ id: 'example-prefix-id',
374
+ title: 'Example prefix title',
375
+ },
376
+ }),
377
+ );
378
+
379
+ const results = await axe($.html());
380
+ expect(results).toHaveNoViolations();
381
+ });
382
+
383
+ it('adds `aria-labelledby` attribute when `prefix` is provided with `prefix.title`', () => {
384
+ const $ = cheerio.load(
385
+ renderComponent('input', {
386
+ ...EXAMPLE_INPUT_MINIMAL,
387
+ prefix: {
388
+ id: 'example-prefix-id',
389
+ title: 'Example prefix title',
390
+ },
391
+ }),
392
+ );
393
+
394
+ expect($('.ons-input').attr('aria-labelledby')).toBe('example-id example-prefix-id');
395
+ });
396
+
397
+ it('adds `aria-labelledby` attribute when `prefix` is provided without `prefix.title`', () => {
398
+ const $ = cheerio.load(
399
+ renderComponent('input', {
400
+ ...EXAMPLE_INPUT_MINIMAL,
401
+ prefix: {
402
+ id: 'example-prefix-id',
403
+ },
404
+ }),
405
+ );
406
+
407
+ expect($('.ons-input').attr('aria-labelledby')).toBe('example-prefix-id');
408
+ });
409
+
410
+ it('renders prefix element from `prefix.text`', () => {
411
+ const $ = cheerio.load(
412
+ renderComponent('input', {
413
+ ...EXAMPLE_INPUT_MINIMAL,
414
+ prefix: {
415
+ id: 'example-prefix-id',
416
+ title: 'Example prefix title',
417
+ text: 'Example prefix text',
418
+ },
419
+ }),
420
+ );
421
+
422
+ expect($('.ons-input-type--prefix .ons-js-input-abbr').attr('id')).toBe('example-prefix-id');
423
+ expect($('.ons-input-type--prefix .ons-js-input-abbr').attr('title')).toBe('Example prefix title');
424
+ expect($('.ons-input-type--prefix .ons-js-input-abbr').text().trim()).toBe('Example prefix text');
425
+ });
426
+
427
+ it('does not render prefix element when `prefix.id` not set', () => {
428
+ const $ = cheerio.load(
429
+ renderComponent('input', {
430
+ ...EXAMPLE_INPUT_MINIMAL,
431
+ prefix: {
432
+ title: 'Example prefix title',
433
+ text: 'Example prefix text',
434
+ },
435
+ }),
436
+ );
437
+
438
+ expect($('.ons-input-type--prefix').length).toBe(0);
439
+ });
440
+
441
+ it('adds `aria-labelledby` attribute when `suffix` is provided', () => {
442
+ const $ = cheerio.load(
443
+ renderComponent('input', {
444
+ ...EXAMPLE_INPUT_MINIMAL,
445
+ suffix: {
446
+ id: 'example-suffix-id',
447
+ title: 'Example suffix title',
448
+ },
449
+ }),
450
+ );
451
+
452
+ expect($('.ons-input').attr('aria-labelledby')).toBe('example-id example-suffix-id');
453
+ });
454
+
455
+ it('adds `aria-labelledby` attribute when `suffix` is provided without `suffix.title`', () => {
456
+ const $ = cheerio.load(
457
+ renderComponent('input', {
458
+ ...EXAMPLE_INPUT_MINIMAL,
459
+ suffix: {
460
+ id: 'example-suffix-id',
461
+ },
462
+ }),
463
+ );
464
+
465
+ expect($('.ons-input').attr('aria-labelledby')).toBe('example-suffix-id');
466
+ });
467
+
468
+ it('renders suffix element from `suffix.text`', () => {
469
+ const $ = cheerio.load(
470
+ renderComponent('input', {
471
+ ...EXAMPLE_INPUT_MINIMAL,
472
+ suffix: {
473
+ id: 'example-suffix-id',
474
+ title: 'Example suffix title',
475
+ text: 'Example suffix text',
476
+ },
477
+ }),
478
+ );
479
+
480
+ expect($('.ons-js-input-abbr').attr('id')).toBe('example-suffix-id');
481
+ expect($('.ons-js-input-abbr').attr('title')).toBe('Example suffix title');
482
+ expect($('.ons-js-input-abbr').text().trim()).toBe('Example suffix text');
483
+ });
484
+
485
+ it('does not render suffix element when `suffix.id` not set', () => {
486
+ const $ = cheerio.load(
487
+ renderComponent('input', {
488
+ ...EXAMPLE_INPUT_MINIMAL,
489
+ suffix: {
490
+ title: 'Example suffix title',
491
+ text: 'Example suffix text',
492
+ },
493
+ }),
494
+ );
495
+
496
+ expect($('.ons-input').length).toBe(0);
497
+ });
498
+
499
+ it('renders an `abbr` tag when `title` set', () => {
500
+ const $ = cheerio.load(
501
+ renderComponent('input', {
502
+ ...EXAMPLE_INPUT_MINIMAL,
503
+ suffix: {
504
+ text: 'Example suffix text',
505
+ title: 'Example suffix title',
506
+ id: 'example-suffix-id',
507
+ },
508
+ }),
509
+ );
510
+
511
+ expect($('.ons-input + abbr').length).toBe(1);
512
+ });
513
+
514
+ it('renders a `span` tag when `title` not set', () => {
515
+ const $ = cheerio.load(
516
+ renderComponent('input', {
517
+ ...EXAMPLE_INPUT_MINIMAL,
518
+ suffix: {
519
+ text: 'Example suffix text',
520
+ id: 'example-suffix-id',
521
+ },
522
+ }),
523
+ );
524
+
525
+ expect($('.ons-input + span').length).toBe(1);
526
+ });
527
+ });
528
+
529
+ describe('search', () => {
530
+ it.each('outputs `type` attribute of "search"', () => {
531
+ const $ = cheerio.load(renderComponent('input', EXAMPLE_WITH_SEARCH));
532
+
533
+ expect($('.ons-input').attr('type')).toBe('search');
534
+ expect($('.ons-input').attr('pattern')).toBeUndefined();
535
+ expect($('.ons-input').attr('inputmode')).toBeUndefined();
536
+ });
537
+
538
+ it('has the "ons-search__input" class', () => {
539
+ const $ = cheerio.load(renderComponent('input', EXAMPLE_WITH_SEARCH));
540
+
541
+ expect($('.ons-input').hasClass('ons-search__input')).toBe(true);
542
+ });
543
+ });
544
+
545
+ describe('with character limit', () => {
546
+ it('passes jest-axe checks', async () => {
547
+ const $ = cheerio.load(
548
+ renderComponent('input', {
549
+ ...EXAMPLE_INPUT_WITH_CHARACTER_LIMIT,
550
+ label: {
551
+ id: 'example-input-label',
552
+ text: 'Example input label',
553
+ },
554
+ }),
555
+ );
556
+
557
+ const results = await axe($.html());
558
+ expect(results).toHaveNoViolations();
559
+ });
560
+
561
+ it('has the provided minimum length', () => {
562
+ const $ = cheerio.load(renderComponent('input', EXAMPLE_INPUT_WITH_CHARACTER_LIMIT));
563
+
564
+ expect($('.ons-input').attr('minlength')).toBe('10');
565
+ });
566
+
567
+ it('has the provided maximum length', () => {
568
+ const $ = cheerio.load(renderComponent('input', EXAMPLE_INPUT_WITH_CHARACTER_LIMIT));
569
+
570
+ expect($('.ons-input').attr('maxlength')).toBe('200');
571
+ });
572
+
573
+ it('does not have `data-char-check-countdown` attribute when `charcheckCountdown` is not provided', () => {
574
+ const $ = cheerio.load(renderComponent('input', EXAMPLE_INPUT_WITH_CHARACTER_LIMIT));
575
+
576
+ expect($('.ons-input').attr('data-char-check-countdown')).toBe(undefined);
577
+ });
578
+
579
+ it('has `data-char-check-countdown` attribute when `charcheckCountdown` is true', () => {
580
+ const $ = cheerio.load(
581
+ renderComponent('input', {
582
+ ...EXAMPLE_INPUT_WITH_CHARACTER_LIMIT,
583
+ charCheckLimit: {
584
+ ...EXAMPLE_INPUT_WITH_CHARACTER_LIMIT.charCheckLimit,
585
+ charcheckCountdown: true,
586
+ },
587
+ }),
588
+ );
589
+
590
+ expect($('.ons-input').attr('data-char-check-countdown')).toBe('true');
591
+ });
592
+
593
+ it('has data attribute which references the character limit component', () => {
594
+ const $ = cheerio.load(renderComponent('input', EXAMPLE_INPUT_WITH_CHARACTER_LIMIT));
595
+
596
+ expect($('.ons-input').attr('data-char-check-ref')).toBe('example-id-check');
597
+ });
598
+
599
+ it('has data attribute which defines limit for character check', () => {
600
+ const $ = cheerio.load(renderComponent('input', EXAMPLE_INPUT_WITH_CHARACTER_LIMIT));
601
+
602
+ expect($('.ons-input').attr('data-char-check-num')).toBe('200');
603
+ });
604
+
605
+ it('has `aria-describedby` attribute which references the character limit component', () => {
606
+ const $ = cheerio.load(renderComponent('input', EXAMPLE_INPUT_WITH_CHARACTER_LIMIT));
607
+
608
+ expect($('.ons-input').attr('aria-describedby')).toBe('example-id-check');
609
+ });
610
+
611
+ it('renders character limit component', () => {
612
+ const faker = templateFaker();
613
+ const charCheckLimitSpy = faker.spy('char-check-limit');
614
+
615
+ faker.renderComponent('input', EXAMPLE_INPUT_WITH_CHARACTER_LIMIT);
616
+
617
+ expect(charCheckLimitSpy.occurrences).toContainEqual({
618
+ id: 'example-id-check',
619
+ limit: 200,
620
+ variant: 'check',
621
+ charCountSingular: 'You have {x} character remaining',
622
+ charCountPlural: 'You have {x} characters remaining',
623
+ charCountOverLimitSingular: '{x} character too many',
624
+ charCountOverLimitPlural: '{x} characters too many',
625
+ });
626
+ });
627
+ });
628
+
629
+ describe('with error', () => {
630
+ it('has the `error` modifier class', () => {
631
+ const $ = cheerio.load(renderComponent('input', EXAMPLE_INPUT_WITH_ERROR));
632
+
633
+ expect($('.ons-input').hasClass('ons-input--error')).toBe(true);
634
+ });
635
+ });
636
+
637
+ describe('with post textbox link', () => {
638
+ it('renders the expected link', () => {
639
+ const $ = cheerio.load(
640
+ renderComponent('input', {
641
+ ...EXAMPLE_INPUT_MINIMAL,
642
+ postTextboxLinkUrl: 'https://example.com/link',
643
+ postTextboxLinkText: 'Example link',
644
+ }),
645
+ );
646
+
647
+ expect($('a.ons-input__post-link').attr('href')).toBe('https://example.com/link');
648
+ expect($('a.ons-input__post-link').text().trim()).toBe('Example link');
649
+ });
650
+ });
651
+
652
+ describe('mutually exclusive', () => {
653
+ it('passes jest-axe checks', async () => {
654
+ const $ = cheerio.load(renderComponent('input', EXAMPLE_INPUT_WITH_MUTUALLY_EXCLUSIVE_WITH_ERROR));
655
+
656
+ const results = await axe($.html());
657
+ expect(results).toHaveNoViolations();
658
+ });
659
+
660
+ it('has the `ons-js-exclusive-group-item` class', () => {
661
+ const $ = cheerio.load(renderComponent('input', EXAMPLE_INPUT_WITH_MUTUALLY_EXCLUSIVE_WITH_ERROR));
662
+
663
+ expect($('.ons-input').hasClass('ons-js-exclusive-group-item')).toBe(true);
664
+ });
665
+
666
+ it('renders mutually exclusive component', () => {
667
+ const faker = templateFaker();
668
+ const mutuallyExclusiveSpy = faker.spy('mutually-exclusive');
669
+
670
+ faker.renderComponent('input', {
671
+ ...EXAMPLE_INPUT_WITH_MUTUALLY_EXCLUSIVE_WITH_ERROR,
672
+ fieldId: 'example-field-id',
673
+ fieldClasses: 'extra-field-class',
674
+ legend: 'Legend text',
675
+ legendClasses: 'extra-legend-class',
676
+ description: 'Example description text',
677
+ legendIsQuestionTitle: true,
678
+ autosuggestResults: 'RESULTS',
679
+ });
680
+
681
+ expect(mutuallyExclusiveSpy.occurrences).toContainEqual({
682
+ id: 'example-field-id',
683
+ legend: 'Legend text',
684
+ legendClasses: 'extra-legend-class ons-js-input-legend',
685
+ description: 'Example description text',
686
+ dontWrap: true,
687
+ legendIsQuestionTitle: true,
688
+ exclusiveOptions: EXAMPLE_INPUT_WITH_MUTUALLY_EXCLUSIVE_WITH_ERROR.mutuallyExclusive.exclusiveOptions,
689
+ or: 'Or',
690
+ deselectMessage: 'Selecting this will clear your feedback',
691
+ deselectGroupAdjective: 'cleared',
692
+ deselectExclusiveOptionAdjective: 'deselected',
693
+ error: EXAMPLE_INPUT_WITH_MUTUALLY_EXCLUSIVE_WITH_ERROR.error,
694
+ autosuggestResults: 'RESULTS',
695
+ });
696
+ });
696
697
  });
697
- });
698
698
  });