@ons/design-system 70.0.7 → 70.0.9

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 (454) hide show
  1. package/README.md +11 -17
  2. package/components/access-code/_macro.njk +31 -25
  3. package/components/access-code/_macro.spec.js +145 -145
  4. package/components/access-code/access-code.dom.js +5 -5
  5. package/components/access-code/access-code.js +16 -16
  6. package/components/access-code/access-code.scss +22 -22
  7. package/components/access-code/access-code.spec.js +17 -17
  8. package/components/access-code/example-access-code-error.njk +49 -37
  9. package/components/access-code/example-access-code.njk +40 -30
  10. package/components/accordion/_macro.njk +7 -6
  11. package/components/accordion/_macro.spec.js +154 -154
  12. package/components/accordion/accordion.dom.js +10 -10
  13. package/components/accordion/accordion.js +50 -50
  14. package/components/accordion/accordion.spec.js +104 -104
  15. package/components/accordion/example-accordion-open.njk +0 -1
  16. package/components/address-input/_macro.njk +23 -11
  17. package/components/address-input/_macro.spec.js +420 -420
  18. package/components/address-input/autosuggest.address.dom.js +5 -5
  19. package/components/address-input/autosuggest.address.error.js +77 -77
  20. package/components/address-input/autosuggest.address.js +354 -359
  21. package/components/address-input/autosuggest.address.setter.js +95 -95
  22. package/components/address-input/autosuggest.address.spec.js +668 -651
  23. package/components/address-input/example-address-input-editable.njk +52 -50
  24. package/components/address-input/example-address-input-manual.njk +23 -21
  25. package/components/address-input/example-address-input.njk +40 -38
  26. package/components/address-output/_address-output.scss +3 -3
  27. package/components/address-output/_macro.njk +6 -6
  28. package/components/address-output/_macro.spec.js +84 -84
  29. package/components/autosuggest/_autosuggest.scss +114 -114
  30. package/components/autosuggest/_macro.njk +57 -37
  31. package/components/autosuggest/_macro.spec.js +255 -255
  32. package/components/autosuggest/autosuggest.dom.js +5 -5
  33. package/components/autosuggest/autosuggest.helpers.js +11 -11
  34. package/components/autosuggest/autosuggest.helpers.spec.js +73 -73
  35. package/components/autosuggest/autosuggest.js +20 -20
  36. package/components/autosuggest/autosuggest.spec.js +542 -536
  37. package/components/autosuggest/autosuggest.ui.js +478 -475
  38. package/components/autosuggest/example-autosuggest-country-multiple.njk +26 -26
  39. package/components/autosuggest/example-autosuggest-country.njk +24 -24
  40. package/components/autosuggest/fuse-config.js +17 -17
  41. package/components/back-to-top/_back-to-top.scss +27 -27
  42. package/components/back-to-top/_macro.spec.js +49 -49
  43. package/components/back-to-top/back-to-top.dom.js +5 -5
  44. package/components/back-to-top/back-to-top.js +52 -52
  45. package/components/back-to-top/back-to-top.spec.js +106 -106
  46. package/components/back-to-top/example-back-to-top.njk +183 -6
  47. package/components/back-to-top/example-full-page-back-to-top.njk +135 -123
  48. package/components/breadcrumbs/_breadcrumbs.scss +63 -65
  49. package/components/breadcrumbs/_macro.njk +12 -4
  50. package/components/breadcrumbs/_macro.spec.js +91 -91
  51. package/components/browser-banner/_browser-banner.scss +23 -23
  52. package/components/browser-banner/_macro.njk +6 -3
  53. package/components/browser-banner/_macro.spec.js +92 -92
  54. package/components/button/_button.scss +525 -491
  55. package/components/button/_macro.njk +63 -62
  56. package/components/button/_macro.spec.js +363 -363
  57. package/components/button/button.dom.js +15 -15
  58. package/components/button/button.js +53 -53
  59. package/components/button/button.spec.js +248 -240
  60. package/components/button/example-button-ghost.njk +1 -0
  61. package/components/call-to-action/_call-to-action.scss +5 -5
  62. package/components/call-to-action/_macro.njk +7 -5
  63. package/components/call-to-action/_macro.spec.js +28 -28
  64. package/components/call-to-action/example-call-to-action-default.njk +3 -2
  65. package/components/card/_card.scss +23 -23
  66. package/components/card/_macro.njk +26 -10
  67. package/components/card/_macro.spec.js +180 -180
  68. package/components/card/example-card-set-with-images.njk +31 -29
  69. package/components/card/example-card-set-with-lists.njk +58 -56
  70. package/components/card/example-card-set.njk +28 -26
  71. package/components/card/example-card.njk +9 -7
  72. package/components/char-check-limit/_macro.njk +1 -3
  73. package/components/char-check-limit/_macro.spec.js +48 -48
  74. package/components/char-check-limit/character-check.js +58 -58
  75. package/components/char-check-limit/character-check.spec.js +173 -173
  76. package/components/char-check-limit/character-limit.js +40 -40
  77. package/components/checkboxes/_checkbox-macro.njk +19 -15
  78. package/components/checkboxes/_checkbox-macro.spec.js +355 -355
  79. package/components/checkboxes/_checkbox.scss +180 -180
  80. package/components/checkboxes/_checkboxes.scss +37 -27
  81. package/components/checkboxes/_macro.njk +81 -72
  82. package/components/checkboxes/_macro.spec.js +261 -261
  83. package/components/checkboxes/checkbox-with-autoselect.js +32 -32
  84. package/components/checkboxes/checkbox-with-fieldset.js +21 -21
  85. package/components/checkboxes/checkboxes-with-reveal.js +10 -10
  86. package/components/checkboxes/checkboxes.dom.js +27 -27
  87. package/components/checkboxes/checkboxes.spec.js +183 -183
  88. package/components/checkboxes/example-checkboxes-disabled.njk +30 -30
  89. package/components/checkboxes/example-checkboxes-error.njk +0 -1
  90. package/components/checkboxes/example-checkboxes-with-descriptions.njk +7 -5
  91. package/components/checkboxes/example-checkboxes-with-hidden-label.njk +162 -170
  92. package/components/checkboxes/example-checkboxes-with-revealed-checkboxes-expanded.njk +81 -81
  93. package/components/checkboxes/example-checkboxes-with-revealed-checkboxes.njk +79 -79
  94. package/components/checkboxes/example-checkboxes-with-revealed-select-expanded.njk +7 -5
  95. package/components/checkboxes/example-checkboxes-with-revealed-select.njk +7 -5
  96. package/components/checkboxes/example-checkboxes-with-revealed-text-input-expanded.njk +7 -5
  97. package/components/checkboxes/example-checkboxes-with-revealed-text-input.njk +7 -5
  98. package/components/checkboxes/example-checkboxes-with-select-all-button.njk +7 -5
  99. package/components/checkboxes/example-checkboxes-with-visible-text-input.njk +7 -5
  100. package/components/checkboxes/example-checkboxes.njk +7 -5
  101. package/components/content-pagination/_content-pagination.scss +41 -41
  102. package/components/content-pagination/_macro.njk +34 -32
  103. package/components/content-pagination/_macro.spec.js +159 -159
  104. package/components/content-pagination/example-content-pagination.njk +17 -17
  105. package/components/cookies-banner/_cookies-banner.scss +22 -22
  106. package/components/cookies-banner/_macro.njk +19 -6
  107. package/components/cookies-banner/_macro.spec.js +177 -177
  108. package/components/cookies-banner/cookies-banner.dom.js +7 -7
  109. package/components/cookies-banner/cookies-banner.js +76 -76
  110. package/components/cookies-banner/cookies-banner.spec.js +72 -68
  111. package/components/cookies-banner/example-cookies-banner-cymraeg.njk +2 -1
  112. package/components/cookies-banner/example-cookies-banner.njk +3 -4
  113. package/components/date-input/_macro.njk +71 -63
  114. package/components/date-input/_macro.spec.js +338 -338
  115. package/components/date-input/example-date-input-error-for-single-field.njk +0 -1
  116. package/components/date-input/example-date-input-error.njk +0 -1
  117. package/components/description-list/_description-list.scss +23 -23
  118. package/components/description-list/_macro.njk +20 -11
  119. package/components/description-list/_macro.spec.js +144 -144
  120. package/components/details/_details.scss +109 -109
  121. package/components/details/_macro.njk +18 -11
  122. package/components/details/_macro.spec.js +132 -132
  123. package/components/details/details.dom.js +6 -6
  124. package/components/details/details.js +60 -60
  125. package/components/details/details.spec.js +106 -106
  126. package/components/details/example-details-with-warning.njk +15 -10
  127. package/components/document-list/_macro.njk +102 -93
  128. package/components/document-list/_macro.spec.js +444 -444
  129. package/components/document-list/document-list.scss +145 -149
  130. package/components/document-list/example-document-list-article-featured.njk +27 -25
  131. package/components/document-list/example-document-list-articles.njk +55 -53
  132. package/components/document-list/example-document-list-downloads.njk +49 -47
  133. package/components/document-list/example-document-list-search-result-featured.njk +19 -17
  134. package/components/document-list/example-document-list-search-results.njk +60 -58
  135. package/components/download-resources/_download-resources.scss +109 -108
  136. package/components/download-resources/download-resources.js +907 -900
  137. package/components/download-resources/download-resources.spec.js +461 -461
  138. package/components/duration/_macro.njk +61 -55
  139. package/components/duration/_macro.spec.js +291 -291
  140. package/components/duration/example-duration-error-for-single-field.njk +28 -26
  141. package/components/duration/example-duration-single-field.njk +23 -19
  142. package/components/duration/example-duration.njk +33 -29
  143. package/components/error/_macro.njk +8 -6
  144. package/components/error/_macro.spec.js +72 -72
  145. package/components/external-link/_external-link.scss +19 -19
  146. package/components/external-link/_macro.njk +7 -5
  147. package/components/external-link/_macro.spec.js +68 -68
  148. package/components/external-link/example-external-link.njk +9 -6
  149. package/components/feedback/_feedback.scss +31 -31
  150. package/components/feedback/_macro.njk +7 -5
  151. package/components/feedback/_macro.spec.js +72 -72
  152. package/components/field/_field-group.scss +10 -10
  153. package/components/field/_field.scss +16 -16
  154. package/components/field/_macro.njk +2 -2
  155. package/components/field/_macro.spec.js +80 -80
  156. package/components/fieldset/_fieldset.scss +27 -27
  157. package/components/fieldset/_macro.njk +23 -16
  158. package/components/fieldset/_macro.spec.js +161 -161
  159. package/components/footer/_footer.scss +45 -45
  160. package/components/footer/_macro.njk +28 -21
  161. package/components/footer/_macro.spec.js +452 -452
  162. package/components/footer/example-footer-cymraeg.njk +2 -1
  163. package/components/footer/example-footer-default.njk +3 -4
  164. package/components/footer/example-footer-transactional.njk +2 -1
  165. package/components/footer/example-footer-warning.njk +2 -1
  166. package/components/footer/example-footer-with-alternative-organisation.njk +2 -1
  167. package/components/footer/example-footer-with-coat-of-arms.njk +2 -1
  168. package/components/footer/example-footer-with-copyright.njk +2 -1
  169. package/components/footer/example-footer.njk +2 -1
  170. package/components/header/_header.scss +207 -202
  171. package/components/header/_macro.njk +183 -141
  172. package/components/header/_macro.spec.js +833 -829
  173. package/components/header/example-header-default.njk +2 -1
  174. package/components/header/example-header-external-for-survey-with-description.njk +2 -1
  175. package/components/header/example-header-external-for-surveys.njk +2 -1
  176. package/components/header/example-header-external-welsh.njk +7 -7
  177. package/components/header/example-header-external-with-navigation-and-search.njk +3 -2
  178. package/components/header/example-header-external-with-navigation.njk +2 -1
  179. package/components/header/example-header-external-with-service-links.njk +2 -1
  180. package/components/header/example-header-external-with-sub-navigation-removed.njk +2 -1
  181. package/components/header/example-header-external-with-sub-navigation.njk +3 -2
  182. package/components/header/example-header-internal.njk +2 -1
  183. package/components/header/example-header-multiple-logos.njk +2 -1
  184. package/components/header/{example-header-neutral-for-multicoloured-logo.njk → example-header-neutral.njk} +2 -1
  185. package/components/helpers/_grid.scss +4 -4
  186. package/components/helpers/grid.njk +17 -16
  187. package/components/hero/_hero.scss +48 -48
  188. package/components/hero/_macro.njk +6 -11
  189. package/components/hero/_macro.spec.js +59 -59
  190. package/components/hero/example-hero-dark.njk +2 -1
  191. package/components/hero/example-hero-default.njk +2 -1
  192. package/components/icon/_icon.scss +44 -44
  193. package/components/icon/_macro.njk +601 -168
  194. package/components/icon/_macro.spec.js +110 -110
  195. package/components/image/_image.scss +11 -11
  196. package/components/image/_macro.njk +7 -5
  197. package/components/image/_macro.spec.js +81 -81
  198. package/components/input/_input-type.scss +86 -89
  199. package/components/input/_input.scss +123 -124
  200. package/components/input/_macro.njk +114 -95
  201. package/components/input/_macro.spec.js +604 -604
  202. package/components/input/character-check.dom.js +5 -5
  203. package/components/input/example-input-search-with-character-check.njk +1 -1
  204. package/components/input/example-input-search-with-placeholder.njk +1 -1
  205. package/components/input/example-input-search.njk +1 -1
  206. package/components/input/input.dom.js +5 -5
  207. package/components/input/input.js +10 -10
  208. package/components/input/input.spec.js +18 -18
  209. package/components/label/_label.scss +24 -24
  210. package/components/label/_macro.njk +32 -26
  211. package/components/label/_macro.spec.js +173 -170
  212. package/components/language-selector/_macro.njk +11 -2
  213. package/components/language-selector/_macro.spec.js +97 -97
  214. package/components/language-selector/language.scss +7 -7
  215. package/components/list/_list.scss +110 -97
  216. package/components/list/_macro.njk +93 -73
  217. package/components/list/_macro.spec.js +583 -583
  218. package/components/message/_macro.njk +20 -7
  219. package/components/message/_macro.spec.js +74 -74
  220. package/components/message/_message.scss +39 -39
  221. package/components/message-list/_macro.njk +26 -20
  222. package/components/message-list/_macro.spec.js +86 -86
  223. package/components/message-list/_message-list.scss +16 -16
  224. package/components/modal/_macro.njk +11 -12
  225. package/components/modal/_macro.spec.js +69 -69
  226. package/components/modal/_modal.scss +36 -36
  227. package/components/modal/modal.dom.js +6 -6
  228. package/components/modal/modal.js +89 -89
  229. package/components/modal/modal.spec.js +50 -50
  230. package/components/multiple-input-fields/_macro.njk +30 -28
  231. package/components/mutually-exclusive/_macro.njk +20 -13
  232. package/components/mutually-exclusive/_macro.spec.js +140 -140
  233. package/components/mutually-exclusive/example-mutually-exclusive-checkboxes.njk +6 -4
  234. package/components/mutually-exclusive/example-mutually-exclusive-date.njk +7 -5
  235. package/components/mutually-exclusive/example-mutually-exclusive-duration.njk +44 -40
  236. package/components/mutually-exclusive/example-mutually-exclusive-email.njk +7 -5
  237. package/components/mutually-exclusive/example-mutually-exclusive-multiple-options.njk +6 -4
  238. package/components/mutually-exclusive/example-mutually-exclusive-number.njk +6 -4
  239. package/components/mutually-exclusive/example-mutually-exclusive-textarea.njk +6 -4
  240. package/components/mutually-exclusive/mutually-exclusive.checkboxes.spec.js +188 -188
  241. package/components/mutually-exclusive/mutually-exclusive.date.spec.js +211 -211
  242. package/components/mutually-exclusive/mutually-exclusive.dom.js +5 -5
  243. package/components/mutually-exclusive/mutually-exclusive.duration.spec.js +210 -210
  244. package/components/mutually-exclusive/mutually-exclusive.email.spec.js +90 -90
  245. package/components/mutually-exclusive/mutually-exclusive.js +137 -137
  246. package/components/mutually-exclusive/mutually-exclusive.multiple-options.checkboxes.spec.js +197 -197
  247. package/components/mutually-exclusive/mutually-exclusive.number.spec.js +96 -96
  248. package/components/mutually-exclusive/mutually-exclusive.textarea.spec.js +102 -102
  249. package/components/navigation/_macro.njk +133 -67
  250. package/components/navigation/_macro.spec.js +360 -354
  251. package/components/navigation/_navigation.scss +112 -122
  252. package/components/navigation/navigation.dom.js +35 -35
  253. package/components/navigation/navigation.js +49 -49
  254. package/components/navigation/navigation.spec.js +249 -249
  255. package/components/pagination/_macro.njk +42 -20
  256. package/components/pagination/_macro.spec.js +342 -335
  257. package/components/pagination/_pagination.scss +58 -58
  258. package/components/panel/_macro.njk +27 -16
  259. package/components/panel/_macro.spec.js +372 -372
  260. package/components/panel/_panel.scss +200 -199
  261. package/components/panel/example-panel-bare.njk +6 -4
  262. package/components/panel/example-panel-with-announcement.njk +7 -4
  263. package/components/panel/example-panel-with-error-summary.njk +6 -4
  264. package/components/panel/example-panel-with-warning.njk +5 -3
  265. package/components/password/_macro.njk +7 -5
  266. package/components/password/_macro.spec.js +95 -95
  267. package/components/password/password.dom.js +5 -5
  268. package/components/password/password.js +10 -10
  269. package/components/password/password.spec.js +26 -26
  270. package/components/phase-banner/_macro.njk +3 -3
  271. package/components/phase-banner/_macro.spec.js +86 -86
  272. package/components/phase-banner/_phase-banner.scss +16 -16
  273. package/components/phase-banner/example-phase-banner-alpha.njk +2 -1
  274. package/components/phase-banner/example-phase-banner-beta.njk +4 -3
  275. package/components/question/_macro.njk +62 -47
  276. package/components/question/_macro.spec.js +235 -235
  277. package/components/question/_question.scss +24 -24
  278. package/components/question/example-question-ccs.njk +40 -35
  279. package/components/question/example-question-fieldset.njk +84 -80
  280. package/components/question/example-question-interviewer-note.njk +27 -24
  281. package/components/question/example-question-no-fieldset.njk +39 -33
  282. package/components/quote/_macro.njk +3 -1
  283. package/components/quote/_macro.spec.js +52 -52
  284. package/components/quote/_quote.scss +24 -24
  285. package/components/radios/_macro.njk +54 -36
  286. package/components/radios/_macro.spec.js +545 -524
  287. package/components/radios/_radio.scss +49 -48
  288. package/components/radios/_radios.scss +14 -20
  289. package/components/radios/check-radios.js +21 -21
  290. package/components/radios/clear-radios.js +45 -45
  291. package/components/radios/example-radios-with-clear-button-expanded.njk +6 -4
  292. package/components/radios/example-radios-with-clear-button.njk +6 -4
  293. package/components/radios/example-radios-with-descriptions.njk +7 -5
  294. package/components/radios/example-radios-with-revealed-select-expanded.njk +6 -4
  295. package/components/radios/example-radios-with-revealed-select.njk +6 -4
  296. package/components/radios/example-radios-with-revealed-text-area-expanded.njk +7 -5
  297. package/components/radios/example-radios-with-revealed-text-area.njk +7 -5
  298. package/components/radios/example-radios-with-revealed-text-input-expanded.njk +7 -5
  299. package/components/radios/example-radios-with-revealed-text-input.njk +7 -5
  300. package/components/radios/example-radios-with-separator.njk +6 -4
  301. package/components/radios/example-radios-with-visible-text-input.njk +7 -5
  302. package/components/radios/example-radios-without-border.njk +0 -1
  303. package/components/radios/example-radios.njk +7 -5
  304. package/components/radios/radio-with-fieldset.js +22 -22
  305. package/components/radios/radios.dom.js +32 -32
  306. package/components/radios/radios.spec.js +251 -251
  307. package/components/related-content/_macro.njk +10 -11
  308. package/components/related-content/_macro.spec.js +109 -109
  309. package/components/related-content/_related-content.scss +12 -12
  310. package/components/related-content/_section-macro.njk +7 -7
  311. package/components/related-content/_section-macro.spec.js +20 -20
  312. package/components/related-content/example-related-content-general.njk +5 -3
  313. package/components/related-content/example-related-content-multiple-rows-of-links.njk +51 -49
  314. package/components/related-content/example-related-content-social-media.njk +40 -38
  315. package/components/relationships/_macro.njk +10 -8
  316. package/components/relationships/_macro.spec.js +94 -94
  317. package/components/relationships/_relationships.scss +9 -9
  318. package/components/relationships/example-relationships-error.njk +176 -168
  319. package/components/relationships/example-relationships-you.njk +169 -163
  320. package/components/relationships/example-relationships.njk +167 -161
  321. package/components/relationships/relationships.dom.js +5 -5
  322. package/components/relationships/relationships.js +18 -18
  323. package/components/relationships/relationships.spec.js +71 -71
  324. package/components/reply/_macro.spec.js +47 -47
  325. package/components/reply/reply-input.js +15 -15
  326. package/components/reply/reply.dom.js +5 -5
  327. package/components/reply/reply.spec.js +57 -57
  328. package/components/section-navigation/_macro.njk +34 -12
  329. package/components/section-navigation/_macro.spec.js +210 -210
  330. package/components/section-navigation/_section-navigation.scss +76 -76
  331. package/components/select/_macro.njk +21 -18
  332. package/components/select/_macro.spec.js +166 -166
  333. package/components/share-page/_macro.njk +10 -5
  334. package/components/share-page/_macro.spec.js +68 -68
  335. package/components/skip-to-content/_macro.njk +1 -1
  336. package/components/skip-to-content/_macro.spec.js +54 -54
  337. package/components/skip-to-content/_skip.scss +30 -30
  338. package/components/skip-to-content/example-skip-to-content.njk +1 -0
  339. package/components/skip-to-content/skip-to-content.dom.js +6 -6
  340. package/components/skip-to-content/skip-to-content.js +7 -7
  341. package/components/skip-to-content/skip-to-content.spec.js +21 -21
  342. package/components/status/_macro.njk +1 -1
  343. package/components/status/_macro.spec.js +53 -53
  344. package/components/status/_status.scss +32 -32
  345. package/components/summary/_macro.njk +53 -23
  346. package/components/summary/_macro.spec.js +551 -535
  347. package/components/summary/_summary.scss +191 -195
  348. package/components/summary/example-summary-household-no-rows.njk +18 -16
  349. package/components/summary/example-summary-household.njk +75 -73
  350. package/components/summary/example-summary-hub-minimal.njk +74 -72
  351. package/components/summary/example-summary-hub.njk +169 -167
  352. package/components/table/_macro.njk +72 -45
  353. package/components/table/_macro.spec.js +499 -499
  354. package/components/table/_table.scss +204 -201
  355. package/components/table/scrollable-table.dom.js +5 -5
  356. package/components/table/scrollable-table.js +60 -60
  357. package/components/table/sortable-table.dom.js +5 -5
  358. package/components/table/sortable-table.js +135 -135
  359. package/components/table/table.spec.js +144 -140
  360. package/components/table-of-contents/_macro.njk +34 -32
  361. package/components/table-of-contents/_macro.spec.js +125 -125
  362. package/components/table-of-contents/_toc.scss +9 -9
  363. package/components/table-of-contents/example-table-of-contents-grouped.njk +1 -1
  364. package/components/table-of-contents/example-table-of-contents-single.njk +1 -1
  365. package/components/table-of-contents/example-table-of-contents-sticky-full-page.njk +79 -38
  366. package/components/table-of-contents/example-table-of-contents-sticky.njk +50 -13
  367. package/components/table-of-contents/toc.dom.js +5 -5
  368. package/components/table-of-contents/toc.js +30 -30
  369. package/components/table-of-contents/toc.spec.js +88 -88
  370. package/components/tabs/_macro.njk +12 -6
  371. package/components/tabs/_macro.spec.js +92 -92
  372. package/components/tabs/_tabs.scss +120 -115
  373. package/components/tabs/example-tabs-details.njk +5 -6
  374. package/components/tabs/tabs.dom.js +5 -5
  375. package/components/tabs/tabs.js +266 -266
  376. package/components/tabs/tabs.spec.js +268 -268
  377. package/components/text-indent/_macro.njk +1 -3
  378. package/components/text-indent/_macro.spec.js +33 -33
  379. package/components/text-indent/_text-indent.scss +3 -3
  380. package/components/textarea/_macro.njk +49 -46
  381. package/components/textarea/_macro.spec.js +227 -238
  382. package/components/textarea/textarea.dom.js +5 -5
  383. package/components/textarea/textarea.spec.js +78 -74
  384. package/components/timeline/_macro.njk +4 -6
  385. package/components/timeline/_macro.spec.js +83 -83
  386. package/components/timeline/_timeline.scss +26 -26
  387. package/components/timeout-modal/_macro.njk +21 -19
  388. package/components/timeout-modal/_macro.spec.js +47 -47
  389. package/components/timeout-modal/example-timeout-modal.njk +16 -14
  390. package/components/timeout-modal/timeout-modal.dom.js +9 -9
  391. package/components/timeout-modal/timeout-modal.js +66 -66
  392. package/components/timeout-modal/timeout-modal.spec.js +157 -157
  393. package/components/timeout-panel/_macro.njk +19 -17
  394. package/components/timeout-panel/_macro.spec.js +41 -41
  395. package/components/timeout-panel/example-panel-with-timeout-warning.njk +13 -11
  396. package/components/timeout-panel/timeout-panel.dom.js +8 -8
  397. package/components/timeout-panel/timeout-panel.spec.js +118 -118
  398. package/components/upload/_macro.njk +20 -16
  399. package/components/upload/_macro.spec.js +52 -52
  400. package/components/upload/_upload.scss +28 -28
  401. package/components/video/_macro.njk +16 -2
  402. package/components/video/_macro.spec.js +42 -42
  403. package/components/video/_video.scss +16 -16
  404. package/components/video/example-video.njk +2 -2
  405. package/components/video/video.dom.js +5 -5
  406. package/components/video/video.js +32 -32
  407. package/components/video/video.spec.js +103 -97
  408. package/css/main.css +1 -1
  409. package/favicons/manifest.json +25 -25
  410. package/js/abortable-fetch.js +23 -23
  411. package/js/analytics.js +53 -53
  412. package/js/cookies-functions.js +135 -135
  413. package/js/cookies-settings.dom.js +7 -7
  414. package/js/cookies-settings.js +77 -77
  415. package/js/cookies-settings.spec.js +106 -106
  416. package/js/domready.js +8 -8
  417. package/js/fetch.js +14 -14
  418. package/js/inpagelink.dom.js +5 -5
  419. package/js/inpagelink.js +19 -19
  420. package/js/polyfills.js +0 -1
  421. package/js/print-button.js +6 -6
  422. package/js/timeout.js +211 -211
  423. package/layout/_dsTemplate.njk +22 -20
  424. package/layout/_template.njk +63 -51
  425. package/package.json +132 -128
  426. package/scripts/main.es5.js +1 -1
  427. package/scripts/main.js +1 -1
  428. package/scss/base/_forms.scss +10 -10
  429. package/scss/base/_global.scss +45 -44
  430. package/scss/base/_typography.scss +20 -20
  431. package/scss/helpers/_functions.scss +18 -15
  432. package/scss/helpers/_mixins.scss +59 -53
  433. package/scss/helpers/_mq.scss +62 -65
  434. package/scss/objects/_container.scss +20 -20
  435. package/scss/objects/_page.scss +33 -33
  436. package/scss/objects/_spacing.scss +10 -10
  437. package/scss/overrides/hcm.scss +237 -237
  438. package/scss/overrides/rtl.scss +95 -95
  439. package/scss/print.scss +47 -47
  440. package/scss/utilities/_border.scss +7 -7
  441. package/scss/utilities/_colors.scss +6 -6
  442. package/scss/utilities/_display.scss +8 -8
  443. package/scss/utilities/_float.scss +7 -7
  444. package/scss/utilities/_grid.scss +144 -144
  445. package/scss/utilities/_highlight.scss +4 -4
  446. package/scss/utilities/_margin.scss +17 -17
  447. package/scss/utilities/_pad.scss +15 -15
  448. package/scss/utilities/_typography.scss +35 -33
  449. package/scss/utilities/_utilities.scss +8 -8
  450. package/scss/utilities/_visibility.scss +25 -25
  451. package/scss/vars/_colors.scss +116 -116
  452. package/scss/vars/_forms.scss +22 -22
  453. package/scss/vars/_grid.scss +11 -9
  454. package/scss/vars/_typography.scss +54 -54
@@ -2,678 +2,684 @@ import { getNodeAttributes, PuppeteerEndpointFaker } from '../../tests/helpers/p
2
2
  import { renderComponent, setTestPage } from '../../tests/helpers/rendering';
3
3
 
4
4
  const EXAMPLE_AUTOSUGGEST = {
5
- id: 'country-of-birth',
6
- input: {
7
- label: {
8
- text: 'Current name of country',
9
- description: 'Enter your own answer or select from suggestions',
10
- id: 'country-of-birth-label',
11
- classes: 'extra-label-class',
5
+ id: 'country-of-birth',
6
+ input: {
7
+ label: {
8
+ text: 'Current name of country',
9
+ description: 'Enter your own answer or select from suggestions',
10
+ id: 'country-of-birth-label',
11
+ classes: 'extra-label-class',
12
+ },
13
+ autocomplete: 'off',
12
14
  },
13
- autocomplete: 'off',
14
- },
15
- instructions: 'Use up and down keys to navigate.',
16
- ariaYouHaveSelected: 'You have selected',
17
- ariaMinChars: 'Enter 3 or more characters for suggestions.',
18
- minChars: 3,
19
- ariaResultsLabel: 'Country suggestions',
20
- ariaOneResult: 'There is one suggestion available.',
21
- ariaNResults: 'There are {n} suggestions available.',
22
- ariaLimitedResults: 'Type more characters to improve your search',
23
- moreResults: 'Continue entering to improve suggestions',
24
- resultsTitle: 'Suggestions',
25
- resultsTitleId: 'country-of-birth-suggestions',
26
- noResults: 'No suggestions found.',
27
- typeMore: 'Continue entering to get suggestions',
28
- autosuggestData: '/test/fake/api/countries',
15
+ instructions: 'Use up and down keys to navigate.',
16
+ ariaYouHaveSelected: 'You have selected',
17
+ ariaMinChars: 'Enter 3 or more characters for suggestions.',
18
+ minChars: 3,
19
+ ariaResultsLabel: 'Country suggestions',
20
+ ariaOneResult: 'There is one suggestion available.',
21
+ ariaNResults: 'There are {n} suggestions available.',
22
+ ariaLimitedResults: 'Type more characters to improve your search',
23
+ moreResults: 'Continue entering to improve suggestions',
24
+ resultsTitle: 'Suggestions',
25
+ resultsTitleId: 'country-of-birth-suggestions',
26
+ noResults: 'No suggestions found.',
27
+ typeMore: 'Continue entering to get suggestions',
28
+ autosuggestData: '/test/fake/api/countries',
29
29
  };
30
30
  const EXAMPLE_AUTOSUGGEST_WITH_LANGUAGE = {
31
- id: 'country-of-birth',
32
- label: {
33
- text: 'Current name of country',
34
- description: 'Enter your own answer or select from suggestions',
35
- id: 'country-of-birth-label',
36
- classes: 'extra-label-class',
37
- },
38
- autocomplete: 'off',
39
- instructions: 'Use up and down keys to navigate.',
40
- ariaYouHaveSelected: 'You have selected',
41
- ariaMinChars: 'Enter 3 or more characters for suggestions.',
42
- minChars: 3,
43
- ariaResultsLabel: 'Country suggestions',
44
- ariaOneResult: 'There is one suggestion available.',
45
- ariaNResults: 'There are {n} suggestions available.',
46
- ariaLimitedResults: 'Type more characters to improve your search',
47
- moreResults: 'Continue entering to improve suggestions',
48
- resultsTitle: 'Suggestions',
49
- resultsTitleId: 'country-of-birth-suggestions',
50
- noResults: 'No suggestions found.',
51
- typeMore: 'Continue entering to get suggestions',
52
- autosuggestData: '/test/fake/api/countries',
53
- language: 'en-gb',
31
+ id: 'country-of-birth',
32
+ label: {
33
+ text: 'Current name of country',
34
+ description: 'Enter your own answer or select from suggestions',
35
+ id: 'country-of-birth-label',
36
+ classes: 'extra-label-class',
37
+ },
38
+ autocomplete: 'off',
39
+ instructions: 'Use up and down keys to navigate.',
40
+ ariaYouHaveSelected: 'You have selected',
41
+ ariaMinChars: 'Enter 3 or more characters for suggestions.',
42
+ minChars: 3,
43
+ ariaResultsLabel: 'Country suggestions',
44
+ ariaOneResult: 'There is one suggestion available.',
45
+ ariaNResults: 'There are {n} suggestions available.',
46
+ ariaLimitedResults: 'Type more characters to improve your search',
47
+ moreResults: 'Continue entering to improve suggestions',
48
+ resultsTitle: 'Suggestions',
49
+ resultsTitleId: 'country-of-birth-suggestions',
50
+ noResults: 'No suggestions found.',
51
+ typeMore: 'Continue entering to get suggestions',
52
+ autosuggestData: '/test/fake/api/countries',
53
+ language: 'en-gb',
54
54
  };
55
55
 
56
56
  describe('script: autosuggest', () => {
57
- const apiFaker = new PuppeteerEndpointFaker('/test/fake/api');
58
-
59
- apiFaker.setOverride('/countries', {
60
- data: [
61
- { en: 'England' },
62
- { en: 'Wales' },
63
- { en: 'Scotland' },
64
- { en: 'United States of America' },
65
- { en: 'United States Virgin Islands' },
66
- { en: 'Åland Islands' },
67
- ],
68
- });
69
-
70
- beforeAll(async () => {
71
- await apiFaker.setup(page);
72
- });
73
-
74
- beforeEach(async () => {
75
- await apiFaker.reset();
76
- });
77
-
78
- describe('when the component initialises', () => {
79
- it('the input should be given the correct aria attributes', async () => {
80
- await setTestPage('/test', renderComponent('autosuggest', EXAMPLE_AUTOSUGGEST));
81
-
82
- const attributes = await getNodeAttributes(page, '.ons-js-autosuggest-input');
83
- expect(attributes['aria-autocomplete']).toBe('list');
84
- expect(attributes['aria-controls']).toBe('country-of-birth-listbox');
85
- expect(attributes['aria-describedby']).toBe('country-of-birth-instructions');
86
- expect(attributes['aria-haspopup']).toBe('true');
87
- expect(attributes['aria-owns']).toBe('country-of-birth-listbox');
88
- expect(attributes['aria-expanded']).toBe('false');
89
- expect(attributes['role']).toBe('combobox');
57
+ const apiFaker = new PuppeteerEndpointFaker('/test/fake/api');
58
+
59
+ apiFaker.setOverride('/countries', {
60
+ data: [
61
+ { en: 'England' },
62
+ { en: 'Wales' },
63
+ { en: 'Scotland' },
64
+ { en: 'United States of America' },
65
+ { en: 'United States Virgin Islands' },
66
+ { en: 'Åland Islands' },
67
+ ],
90
68
  });
91
69
 
92
- it('the autocomplete attribute be set to be not set to on', async () => {
93
- await setTestPage('/test', renderComponent('autosuggest', EXAMPLE_AUTOSUGGEST));
70
+ beforeAll(async () => {
71
+ await apiFaker.setup(page);
72
+ });
94
73
 
95
- const attributes = await getNodeAttributes(page, '.ons-js-autosuggest-input');
96
- expect(attributes['autocomplete']).not.toBe('on');
74
+ beforeEach(async () => {
75
+ await apiFaker.reset();
97
76
  });
98
77
 
99
- it('the instructions, listbox, and status should become visible', async () => {
100
- await setTestPage('/test', renderComponent('autosuggest', EXAMPLE_AUTOSUGGEST));
78
+ describe('when the component initialises', () => {
79
+ it('the input should be given the correct aria attributes', async () => {
80
+ await setTestPage('/test', renderComponent('autosuggest', EXAMPLE_AUTOSUGGEST));
101
81
 
102
- const instructionsDisplayStyle = await page.$eval('.ons-js-autosuggest-instructions', (node) => getComputedStyle(node).display);
103
- expect(instructionsDisplayStyle).toBe('block');
104
- const listboxDisplayStyle = await page.$eval('.ons-js-autosuggest-listbox', (node) => getComputedStyle(node).display);
105
- expect(listboxDisplayStyle).toBe('block');
106
- const statusDisplayStyle = await page.$eval('.ons-js-autosuggest-aria-status', (node) => getComputedStyle(node).display);
107
- expect(statusDisplayStyle).toBe('block');
108
- });
109
- });
82
+ const attributes = await getNodeAttributes(page, '.ons-js-autosuggest-input');
83
+ expect(attributes['aria-autocomplete']).toBe('list');
84
+ expect(attributes['aria-controls']).toBe('country-of-birth-listbox');
85
+ expect(attributes['aria-describedby']).toBe('country-of-birth-instructions');
86
+ expect(attributes['aria-haspopup']).toBe('true');
87
+ expect(attributes['aria-owns']).toBe('country-of-birth-listbox');
88
+ expect(attributes['aria-expanded']).toBe('false');
89
+ expect(attributes['role']).toBe('combobox');
90
+ });
110
91
 
111
- describe('when the user presses the "Down" arrow key', () => {
112
- it('navigates to the first suggestion initially', async () => {
113
- await setTestPage('/test', renderComponent('autosuggest', EXAMPLE_AUTOSUGGEST));
92
+ it('the autocomplete attribute be set to be not set to on', async () => {
93
+ await setTestPage('/test', renderComponent('autosuggest', EXAMPLE_AUTOSUGGEST));
94
+
95
+ const attributes = await getNodeAttributes(page, '.ons-js-autosuggest-input');
96
+ expect(attributes['autocomplete']).not.toBe('on');
97
+ });
114
98
 
115
- await page.type('.ons-js-autosuggest-input', 'Unite', { delay: 20 });
116
- await page.keyboard.press('ArrowDown');
99
+ it('the instructions, listbox, and status should become visible', async () => {
100
+ await setTestPage('/test', renderComponent('autosuggest', EXAMPLE_AUTOSUGGEST));
117
101
 
118
- const selectedOption = await page.$eval('.ons-autosuggest__option--focused', (node) => node.textContent);
119
- expect(selectedOption.trim()).toBe('United States of America');
102
+ const instructionsDisplayStyle = await page.$eval('.ons-js-autosuggest-instructions', (node) => getComputedStyle(node).display);
103
+ expect(instructionsDisplayStyle).toBe('block');
104
+ const listboxDisplayStyle = await page.$eval('.ons-js-autosuggest-listbox', (node) => getComputedStyle(node).display);
105
+ expect(listboxDisplayStyle).toBe('block');
106
+ const statusDisplayStyle = await page.$eval('.ons-js-autosuggest-aria-status', (node) => getComputedStyle(node).display);
107
+ expect(statusDisplayStyle).toBe('block');
108
+ });
120
109
  });
121
110
 
122
- it('navigates to the suggestion below the current suggestion', async () => {
123
- await setTestPage('/test', renderComponent('autosuggest', EXAMPLE_AUTOSUGGEST));
111
+ describe('when the user presses the "Down" arrow key', () => {
112
+ it('navigates to the first suggestion initially', async () => {
113
+ await setTestPage('/test', renderComponent('autosuggest', EXAMPLE_AUTOSUGGEST));
124
114
 
125
- await page.type('.ons-js-autosuggest-input', 'Unite', { delay: 20 });
126
- await page.keyboard.press('ArrowDown');
127
- await page.keyboard.press('ArrowDown');
115
+ await page.type('.ons-js-autosuggest-input', 'Unite', { delay: 20 });
116
+ await page.keyboard.press('ArrowDown');
128
117
 
129
- const selectedOption = await page.$eval('.ons-autosuggest__option--focused', (node) => node.textContent);
130
- expect(selectedOption.trim()).toBe('United States Virgin Islands');
131
- });
118
+ const selectedOption = await page.$eval('.ons-autosuggest__option--focused', (node) => node.textContent);
119
+ expect(selectedOption.trim()).toBe('United States of America');
120
+ });
132
121
 
133
- it('marks suggestion as being selected', async () => {
134
- await setTestPage('/test', renderComponent('autosuggest', EXAMPLE_AUTOSUGGEST));
122
+ it('navigates to the suggestion below the current suggestion', async () => {
123
+ await setTestPage('/test', renderComponent('autosuggest', EXAMPLE_AUTOSUGGEST));
135
124
 
136
- await page.type('.ons-js-autosuggest-input', 'Unite', { delay: 20 });
137
- await page.keyboard.press('ArrowDown');
138
- await page.keyboard.press('ArrowDown');
125
+ await page.type('.ons-js-autosuggest-input', 'Unite', { delay: 20 });
126
+ await page.keyboard.press('ArrowDown');
127
+ await page.keyboard.press('ArrowDown');
139
128
 
140
- const ariaSelectedValue = await page.$eval('.ons-autosuggest__option--focused', (node) => node.getAttribute('aria-selected'));
141
- expect(ariaSelectedValue).toBe('true');
129
+ const selectedOption = await page.$eval('.ons-autosuggest__option--focused', (node) => node.textContent);
130
+ expect(selectedOption.trim()).toBe('United States Virgin Islands');
131
+ });
142
132
 
143
- const selectedOptionId = await page.$eval('.ons-autosuggest__option--focused', (node) => node.getAttribute('id'));
144
- const ariaActiveDescendant = await page.$eval('.ons-js-autosuggest-input', (node) => node.getAttribute('aria-activedescendant'));
145
- expect(ariaActiveDescendant).toBe(selectedOptionId);
146
- });
133
+ it('marks suggestion as being selected', async () => {
134
+ await setTestPage('/test', renderComponent('autosuggest', EXAMPLE_AUTOSUGGEST));
147
135
 
148
- it('sets aria status to a message showing the selected result', async () => {
149
- await setTestPage('/test', renderComponent('autosuggest', EXAMPLE_AUTOSUGGEST));
136
+ await page.type('.ons-js-autosuggest-input', 'Unite', { delay: 20 });
137
+ await page.keyboard.press('ArrowDown');
138
+ await page.keyboard.press('ArrowDown');
150
139
 
151
- await page.type('.ons-js-autosuggest-input', 'Eng', { delay: 20 });
152
- await page.keyboard.press('ArrowDown');
140
+ const ariaSelectedValue = await page.$eval('.ons-autosuggest__option--focused', (node) => node.getAttribute('aria-selected'));
141
+ expect(ariaSelectedValue).toBe('true');
153
142
 
154
- const statusMessage = await page.$eval('.ons-js-autosuggest-aria-status', (node) => node.textContent);
155
- expect(statusMessage.trim()).toBe('England');
156
- });
143
+ const selectedOptionId = await page.$eval('.ons-autosuggest__option--focused', (node) => node.getAttribute('id'));
144
+ const ariaActiveDescendant = await page.$eval('.ons-js-autosuggest-input', (node) =>
145
+ node.getAttribute('aria-activedescendant'),
146
+ );
147
+ expect(ariaActiveDescendant).toBe(selectedOptionId);
148
+ });
157
149
 
158
- it('does not mark other suggestions as being selected', async () => {
159
- await setTestPage('/test', renderComponent('autosuggest', EXAMPLE_AUTOSUGGEST));
150
+ it('sets aria status to a message showing the selected result', async () => {
151
+ await setTestPage('/test', renderComponent('autosuggest', EXAMPLE_AUTOSUGGEST));
160
152
 
161
- await page.type('.ons-js-autosuggest-input', 'Unite', { delay: 20 });
162
- await page.keyboard.press('ArrowDown');
163
- await page.keyboard.press('ArrowDown');
153
+ await page.type('.ons-js-autosuggest-input', 'Eng', { delay: 20 });
154
+ await page.keyboard.press('ArrowDown');
164
155
 
165
- const selectedSuggestionCount = await page.$$eval('.ons-autosuggest__option[aria-selected=true]', (nodes) => nodes.length);
166
- expect(selectedSuggestionCount).toBe(1);
167
- });
156
+ const statusMessage = await page.$eval('.ons-js-autosuggest-aria-status', (node) => node.textContent);
157
+ expect(statusMessage.trim()).toBe('England');
158
+ });
168
159
 
169
- it('does not affect suggestion selection when already on last item', async () => {
170
- await setTestPage('/test', renderComponent('autosuggest', EXAMPLE_AUTOSUGGEST));
160
+ it('does not mark other suggestions as being selected', async () => {
161
+ await setTestPage('/test', renderComponent('autosuggest', EXAMPLE_AUTOSUGGEST));
171
162
 
172
- await page.type('.ons-js-autosuggest-input', 'Unite', { delay: 20 });
173
- await page.keyboard.press('ArrowDown');
174
- await page.keyboard.press('ArrowDown');
175
- await page.keyboard.press('ArrowDown');
163
+ await page.type('.ons-js-autosuggest-input', 'Unite', { delay: 20 });
164
+ await page.keyboard.press('ArrowDown');
165
+ await page.keyboard.press('ArrowDown');
176
166
 
177
- const selectedOption = await page.$eval('.ons-autosuggest__option--focused', (node) => node.textContent);
178
- expect(selectedOption.trim()).toBe('United States Virgin Islands');
179
- });
167
+ const selectedSuggestionCount = await page.$$eval('.ons-autosuggest__option[aria-selected=true]', (nodes) => nodes.length);
168
+ expect(selectedSuggestionCount).toBe(1);
169
+ });
180
170
 
181
- // The down arrow will typically move caret to the end of an input field. This should
182
- // not occur when suggestions are presented.
183
- it('does not interfere with text input', async () => {
184
- await setTestPage('/test', renderComponent('autosuggest', EXAMPLE_AUTOSUGGEST));
171
+ it('does not affect suggestion selection when already on last item', async () => {
172
+ await setTestPage('/test', renderComponent('autosuggest', EXAMPLE_AUTOSUGGEST));
185
173
 
186
- await page.type('.ons-js-autosuggest-input', 'nited', { delay: 20 });
187
- // Move to start of input to verify if the down arrow moves the caret to the end.
188
- await page.keyboard.press('Home');
189
- await page.keyboard.press('ArrowDown');
190
- await page.keyboard.press('U');
174
+ await page.type('.ons-js-autosuggest-input', 'Unite', { delay: 20 });
175
+ await page.keyboard.press('ArrowDown');
176
+ await page.keyboard.press('ArrowDown');
177
+ await page.keyboard.press('ArrowDown');
191
178
 
192
- const inputValue = await page.$eval('.ons-js-autosuggest-input', (node) => node.value);
193
- expect(inputValue).toBe('United');
194
- });
195
- });
179
+ const selectedOption = await page.$eval('.ons-autosuggest__option--focused', (node) => node.textContent);
180
+ expect(selectedOption.trim()).toBe('United States Virgin Islands');
181
+ });
196
182
 
197
- describe('when the user presses the "Up" arrow key', () => {
198
- it('navigates to the first suggestion initially', async () => {
199
- await setTestPage('/test', renderComponent('autosuggest', EXAMPLE_AUTOSUGGEST));
183
+ // The down arrow will typically move caret to the end of an input field. This should
184
+ // not occur when suggestions are presented.
185
+ it('does not interfere with text input', async () => {
186
+ await setTestPage('/test', renderComponent('autosuggest', EXAMPLE_AUTOSUGGEST));
200
187
 
201
- await page.type('.ons-js-autosuggest-input', 'Unite', { delay: 20 });
202
- await page.keyboard.press('ArrowUp');
188
+ await page.type('.ons-js-autosuggest-input', 'nited', { delay: 20 });
189
+ // Move to start of input to verify if the down arrow moves the caret to the end.
190
+ await page.keyboard.press('Home');
191
+ await page.keyboard.press('ArrowDown');
192
+ await page.keyboard.press('U');
203
193
 
204
- const selectedOption = await page.$eval('.ons-autosuggest__option--focused', (node) => node.textContent);
205
- expect(selectedOption.trim()).toBe('United States of America');
194
+ const inputValue = await page.$eval('.ons-js-autosuggest-input', (node) => node.value);
195
+ expect(inputValue).toBe('United');
196
+ });
206
197
  });
207
198
 
208
- it('navigates to the suggestion above the current suggestion', async () => {
209
- await setTestPage('/test', renderComponent('autosuggest', EXAMPLE_AUTOSUGGEST));
199
+ describe('when the user presses the "Up" arrow key', () => {
200
+ it('navigates to the first suggestion initially', async () => {
201
+ await setTestPage('/test', renderComponent('autosuggest', EXAMPLE_AUTOSUGGEST));
210
202
 
211
- await page.type('.ons-js-autosuggest-input', 'Unite', { delay: 20 });
212
- await page.keyboard.press('ArrowDown');
213
- await page.keyboard.press('ArrowDown');
214
- await page.keyboard.press('ArrowUp');
203
+ await page.type('.ons-js-autosuggest-input', 'Unite', { delay: 20 });
204
+ await page.keyboard.press('ArrowUp');
215
205
 
216
- const selectedOption = await page.$eval('.ons-autosuggest__option--focused', (node) => node.textContent);
217
- expect(selectedOption.trim()).toBe('United States of America');
218
- });
206
+ const selectedOption = await page.$eval('.ons-autosuggest__option--focused', (node) => node.textContent);
207
+ expect(selectedOption.trim()).toBe('United States of America');
208
+ });
219
209
 
220
- it('marks suggestion as being selected', async () => {
221
- await setTestPage('/test', renderComponent('autosuggest', EXAMPLE_AUTOSUGGEST));
210
+ it('navigates to the suggestion above the current suggestion', async () => {
211
+ await setTestPage('/test', renderComponent('autosuggest', EXAMPLE_AUTOSUGGEST));
222
212
 
223
- await page.type('.ons-js-autosuggest-input', 'Unite', { delay: 20 });
224
- await page.keyboard.press('ArrowDown');
225
- await page.keyboard.press('ArrowDown');
226
- await page.keyboard.press('ArrowUp');
213
+ await page.type('.ons-js-autosuggest-input', 'Unite', { delay: 20 });
214
+ await page.keyboard.press('ArrowDown');
215
+ await page.keyboard.press('ArrowDown');
216
+ await page.keyboard.press('ArrowUp');
227
217
 
228
- const ariaSelectedValue = await page.$eval('.ons-autosuggest__option--focused', (node) => node.getAttribute('aria-selected'));
229
- expect(ariaSelectedValue).toBe('true');
218
+ const selectedOption = await page.$eval('.ons-autosuggest__option--focused', (node) => node.textContent);
219
+ expect(selectedOption.trim()).toBe('United States of America');
220
+ });
230
221
 
231
- const selectedOptionId = await page.$eval('.ons-autosuggest__option--focused', (node) => node.getAttribute('id'));
232
- const ariaActiveDescendant = await page.$eval('.ons-js-autosuggest-input', (node) => node.getAttribute('aria-activedescendant'));
233
- expect(ariaActiveDescendant).toBe(selectedOptionId);
234
- });
222
+ it('marks suggestion as being selected', async () => {
223
+ await setTestPage('/test', renderComponent('autosuggest', EXAMPLE_AUTOSUGGEST));
235
224
 
236
- it('does not mark other suggestions as being selected', async () => {
237
- await setTestPage('/test', renderComponent('autosuggest', EXAMPLE_AUTOSUGGEST));
225
+ await page.type('.ons-js-autosuggest-input', 'Unite', { delay: 20 });
226
+ await page.keyboard.press('ArrowDown');
227
+ await page.keyboard.press('ArrowDown');
228
+ await page.keyboard.press('ArrowUp');
238
229
 
239
- await page.type('.ons-js-autosuggest-input', 'Unite', { delay: 20 });
240
- await page.keyboard.press('ArrowDown');
241
- await page.keyboard.press('ArrowDown');
242
- await page.keyboard.press('ArrowUp');
230
+ const ariaSelectedValue = await page.$eval('.ons-autosuggest__option--focused', (node) => node.getAttribute('aria-selected'));
231
+ expect(ariaSelectedValue).toBe('true');
243
232
 
244
- const selectedSuggestionCount = await page.$$eval('.ons-autosuggest__option[aria-selected=true]', (nodes) => nodes.length);
245
- expect(selectedSuggestionCount).toBe(1);
246
- });
233
+ const selectedOptionId = await page.$eval('.ons-autosuggest__option--focused', (node) => node.getAttribute('id'));
234
+ const ariaActiveDescendant = await page.$eval('.ons-js-autosuggest-input', (node) =>
235
+ node.getAttribute('aria-activedescendant'),
236
+ );
237
+ expect(ariaActiveDescendant).toBe(selectedOptionId);
238
+ });
247
239
 
248
- it('does not affect suggestion selection when already on first item', async () => {
249
- await setTestPage('/test', renderComponent('autosuggest', EXAMPLE_AUTOSUGGEST));
240
+ it('does not mark other suggestions as being selected', async () => {
241
+ await setTestPage('/test', renderComponent('autosuggest', EXAMPLE_AUTOSUGGEST));
250
242
 
251
- await page.type('.ons-js-autosuggest-input', 'Unite', { delay: 20 });
252
- await page.keyboard.press('ArrowUp');
253
- await page.keyboard.press('ArrowUp');
243
+ await page.type('.ons-js-autosuggest-input', 'Unite', { delay: 20 });
244
+ await page.keyboard.press('ArrowDown');
245
+ await page.keyboard.press('ArrowDown');
246
+ await page.keyboard.press('ArrowUp');
254
247
 
255
- const selectedOption = await page.$eval('.ons-autosuggest__option--focused', (node) => node.textContent);
256
- expect(selectedOption.trim()).toBe('United States of America');
257
- });
248
+ const selectedSuggestionCount = await page.$$eval('.ons-autosuggest__option[aria-selected=true]', (nodes) => nodes.length);
249
+ expect(selectedSuggestionCount).toBe(1);
250
+ });
251
+
252
+ it('does not affect suggestion selection when already on first item', async () => {
253
+ await setTestPage('/test', renderComponent('autosuggest', EXAMPLE_AUTOSUGGEST));
254
+
255
+ await page.type('.ons-js-autosuggest-input', 'Unite', { delay: 20 });
256
+ await page.keyboard.press('ArrowUp');
257
+ await page.keyboard.press('ArrowUp');
258
+
259
+ const selectedOption = await page.$eval('.ons-autosuggest__option--focused', (node) => node.textContent);
260
+ expect(selectedOption.trim()).toBe('United States of America');
261
+ });
258
262
 
259
- // The down arrow will typically move caret to the start of an input field. This
260
- // should not occur when suggestions are presented.
261
- it('does not interfere with text input', async () => {
262
- await setTestPage('/test', renderComponent('autosuggest', EXAMPLE_AUTOSUGGEST));
263
+ // The down arrow will typically move caret to the start of an input field. This
264
+ // should not occur when suggestions are presented.
265
+ it('does not interfere with text input', async () => {
266
+ await setTestPage('/test', renderComponent('autosuggest', EXAMPLE_AUTOSUGGEST));
263
267
 
264
- await page.type('.ons-js-autosuggest-input', 'Unite', { delay: 20 });
265
- await page.keyboard.press('ArrowUp');
266
- await page.keyboard.press('d');
268
+ await page.type('.ons-js-autosuggest-input', 'Unite', { delay: 20 });
269
+ await page.keyboard.press('ArrowUp');
270
+ await page.keyboard.press('d');
267
271
 
268
- const inputValue = await page.$eval('.ons-js-autosuggest-input', (node) => node.value);
269
- expect(inputValue).toBe('United');
272
+ const inputValue = await page.$eval('.ons-js-autosuggest-input', (node) => node.value);
273
+ expect(inputValue).toBe('United');
274
+ });
270
275
  });
271
- });
272
276
 
273
- describe('when the user presses the "Enter" key', () => {
274
- it('accepts the selected suggestion', async () => {
275
- await setTestPage('/test', renderComponent('autosuggest', EXAMPLE_AUTOSUGGEST));
277
+ describe('when the user presses the "Enter" key', () => {
278
+ it('accepts the selected suggestion', async () => {
279
+ await setTestPage('/test', renderComponent('autosuggest', EXAMPLE_AUTOSUGGEST));
276
280
 
277
- await page.type('.ons-js-autosuggest-input', 'Unite', { delay: 20 });
278
- await page.keyboard.press('ArrowDown');
279
- await page.keyboard.press('ArrowDown');
280
- await page.keyboard.press('Enter');
281
+ await page.type('.ons-js-autosuggest-input', 'Unite', { delay: 20 });
282
+ await page.keyboard.press('ArrowDown');
283
+ await page.keyboard.press('ArrowDown');
284
+ await page.keyboard.press('Enter');
281
285
 
282
- const inputValue = await page.$eval('.ons-js-autosuggest-input', (node) => node.value);
283
- expect(inputValue).toBe('United States Virgin Islands');
286
+ const inputValue = await page.$eval('.ons-js-autosuggest-input', (node) => node.value);
287
+ expect(inputValue).toBe('United States Virgin Islands');
288
+ });
284
289
  });
285
- });
286
290
 
287
- describe('when the user blurs the input', () => {
288
- it('suggestions should remain visible for 300ms', async () => {
289
- await setTestPage('/test', renderComponent('autosuggest', EXAMPLE_AUTOSUGGEST));
291
+ describe('when the user blurs the input', () => {
292
+ it('suggestions should remain visible for 300ms', async () => {
293
+ await setTestPage('/test', renderComponent('autosuggest', EXAMPLE_AUTOSUGGEST));
290
294
 
291
- await page.type('.ons-js-autosuggest-input', 'Unite', { delay: 20 });
292
- await page.keyboard.press('Tab');
295
+ await page.type('.ons-js-autosuggest-input', 'Unite', { delay: 20 });
296
+ await page.keyboard.press('Tab');
293
297
 
294
- const suggestionCountSample1 = await page.$$eval('.ons-autosuggest__option', (nodes) => nodes.length);
295
- expect(suggestionCountSample1).toBe(2);
298
+ const suggestionCountSample1 = await page.$$eval('.ons-autosuggest__option', (nodes) => nodes.length);
299
+ expect(suggestionCountSample1).toBe(2);
296
300
 
297
- await page.waitForTimeout(200);
298
- const suggestionCountSample2 = await page.$$eval('.ons-autosuggest__option', (nodes) => nodes.length);
299
- expect(suggestionCountSample2).toBe(2);
301
+ await page.waitForTimeout(200);
302
+ const suggestionCountSample2 = await page.$$eval('.ons-autosuggest__option', (nodes) => nodes.length);
303
+ expect(suggestionCountSample2).toBe(2);
300
304
 
301
- await page.waitForTimeout(320);
302
- const suggestionCountSample3 = await page.$$eval('.ons-autosuggest__option', (nodes) => nodes.length);
303
- expect(suggestionCountSample3).toBe(0);
304
- });
305
+ await page.waitForTimeout(320);
306
+ const suggestionCountSample3 = await page.$$eval('.ons-autosuggest__option', (nodes) => nodes.length);
307
+ expect(suggestionCountSample3).toBe(0);
308
+ });
305
309
 
306
- it('clears innerHTML of listbox', async () => {
307
- await setTestPage('/test', renderComponent('autosuggest', EXAMPLE_AUTOSUGGEST));
310
+ it('clears innerHTML of listbox', async () => {
311
+ await setTestPage('/test', renderComponent('autosuggest', EXAMPLE_AUTOSUGGEST));
308
312
 
309
- await page.type('.ons-js-autosuggest-input', 'Unite', { delay: 20 });
310
- await page.keyboard.press('Tab');
311
- await page.waitForTimeout(320);
313
+ await page.type('.ons-js-autosuggest-input', 'Unite', { delay: 20 });
314
+ await page.keyboard.press('Tab');
315
+ await page.waitForTimeout(320);
312
316
 
313
- const listboxInnerHTML = await page.$eval('.ons-js-autosuggest-listbox', (node) => node.innerHTML);
314
- expect(listboxInnerHTML).toBe('');
315
- });
317
+ const listboxInnerHTML = await page.$eval('.ons-js-autosuggest-listbox', (node) => node.innerHTML);
318
+ expect(listboxInnerHTML).toBe('');
319
+ });
316
320
 
317
- it('clears `has-results` modifier of autosuggest component', async () => {
318
- await setTestPage('/test', renderComponent('autosuggest', EXAMPLE_AUTOSUGGEST));
321
+ it('clears `has-results` modifier of autosuggest component', async () => {
322
+ await setTestPage('/test', renderComponent('autosuggest', EXAMPLE_AUTOSUGGEST));
319
323
 
320
- await page.type('.ons-js-autosuggest-input', 'Unite', { delay: 20 });
321
- await page.keyboard.press('Tab');
322
- await page.waitForTimeout(320);
324
+ await page.type('.ons-js-autosuggest-input', 'Unite', { delay: 20 });
325
+ await page.keyboard.press('Tab');
326
+ await page.waitForTimeout(320);
323
327
 
324
- const hasClass = await page.$eval('.ons-autosuggest', (node) => node.classList.contains('ons-autosuggest--has-results'));
325
- expect(hasClass).toBe(false);
326
- });
328
+ const hasClass = await page.$eval('.ons-autosuggest', (node) => node.classList.contains('ons-autosuggest--has-results'));
329
+ expect(hasClass).toBe(false);
330
+ });
327
331
 
328
- it('clears aria attributes of input element', async () => {
329
- await setTestPage('/test', renderComponent('autosuggest', EXAMPLE_AUTOSUGGEST));
332
+ it('clears aria attributes of input element', async () => {
333
+ await setTestPage('/test', renderComponent('autosuggest', EXAMPLE_AUTOSUGGEST));
330
334
 
331
- await page.type('.ons-js-autosuggest-input', 'Unite', { delay: 20 });
332
- await page.keyboard.press('Tab');
333
- await page.waitForTimeout(320);
335
+ await page.type('.ons-js-autosuggest-input', 'Unite', { delay: 20 });
336
+ await page.keyboard.press('Tab');
337
+ await page.waitForTimeout(320);
334
338
 
335
- const attributes = await getNodeAttributes(page, '.ons-js-autosuggest-input');
336
- expect(attributes['aria-activedescendant']).toBeUndefined();
337
- expect(attributes['aria-expanded']).toBe('false');
339
+ const attributes = await getNodeAttributes(page, '.ons-js-autosuggest-input');
340
+ expect(attributes['aria-activedescendant']).toBeUndefined();
341
+ expect(attributes['aria-expanded']).toBe('false');
342
+ });
338
343
  });
339
- });
340
344
 
341
- describe('when the user clicks on a result', () => {
342
- it('accepts the suggestion', async () => {
343
- await setTestPage('/test', renderComponent('autosuggest', EXAMPLE_AUTOSUGGEST));
345
+ describe('when the user clicks on a result', () => {
346
+ it('accepts the suggestion', async () => {
347
+ await setTestPage('/test', renderComponent('autosuggest', EXAMPLE_AUTOSUGGEST));
344
348
 
345
- await page.type('.ons-js-autosuggest-input', 'Unite', { delay: 20 });
346
- await page.click('.ons-autosuggest__option:nth-child(2)');
349
+ await page.type('.ons-js-autosuggest-input', 'Unite', { delay: 20 });
350
+ await page.click('.ons-autosuggest__option:nth-child(2)');
347
351
 
348
- const inputValue = await page.$eval('.ons-js-autosuggest-input', (node) => node.value);
349
- expect(inputValue).toBe('United States Virgin Islands');
352
+ const inputValue = await page.$eval('.ons-js-autosuggest-input', (node) => node.value);
353
+ expect(inputValue).toBe('United States Virgin Islands');
354
+ });
350
355
  });
351
- });
352
356
 
353
- describe('when the user inputs text', () => {
354
- it('does not show suggestions when input length < minimum characters', async () => {
355
- await setTestPage('/test', renderComponent('autosuggest', EXAMPLE_AUTOSUGGEST));
357
+ describe('when the user inputs text', () => {
358
+ it('does not show suggestions when input length < minimum characters', async () => {
359
+ await setTestPage('/test', renderComponent('autosuggest', EXAMPLE_AUTOSUGGEST));
356
360
 
357
- await page.type('.ons-js-autosuggest-input', 'En', { delay: 20 });
361
+ await page.type('.ons-js-autosuggest-input', 'En', { delay: 20 });
358
362
 
359
- const suggestionCount = await page.$$eval('.ons-autosuggest__option', (nodes) => nodes.length);
360
- expect(suggestionCount).toBe(0);
361
- });
363
+ const suggestionCount = await page.$$eval('.ons-autosuggest__option', (nodes) => nodes.length);
364
+ expect(suggestionCount).toBe(0);
365
+ });
362
366
 
363
- it('shows suggestions when input length >= minimum characters', async () => {
364
- await setTestPage('/test', renderComponent('autosuggest', EXAMPLE_AUTOSUGGEST));
367
+ it('shows suggestions when input length >= minimum characters', async () => {
368
+ await setTestPage('/test', renderComponent('autosuggest', EXAMPLE_AUTOSUGGEST));
365
369
 
366
- await page.type('.ons-js-autosuggest-input', 'Eng', { delay: 20 });
370
+ await page.type('.ons-js-autosuggest-input', 'Eng', { delay: 20 });
367
371
 
368
- const suggestionCount = await page.$$eval('.ons-autosuggest__option', (nodes) => nodes.length);
369
- expect(suggestionCount).toBe(1);
370
- });
372
+ const suggestionCount = await page.$$eval('.ons-autosuggest__option', (nodes) => nodes.length);
373
+ expect(suggestionCount).toBe(1);
374
+ });
371
375
 
372
- it('gets the language if set', async () => {
373
- await setTestPage('/test', renderComponent('autosuggest', EXAMPLE_AUTOSUGGEST_WITH_LANGUAGE));
376
+ it('gets the language if set', async () => {
377
+ await setTestPage('/test', renderComponent('autosuggest', EXAMPLE_AUTOSUGGEST_WITH_LANGUAGE));
374
378
 
375
- await page.type('.ons-js-autosuggest-input', 'Eng', { delay: 20 });
379
+ await page.type('.ons-js-autosuggest-input', 'Eng', { delay: 20 });
376
380
 
377
- const attributes = await getNodeAttributes(page, '.ons-js-autosuggest');
378
- expect(attributes['data-lang']).toBe('en-gb');
381
+ const attributes = await getNodeAttributes(page, '.ons-js-autosuggest');
382
+ expect(attributes['data-lang']).toBe('en-gb');
383
+ });
379
384
  });
380
- });
381
385
 
382
- describe('when the mouse moves over a result and a suggestion is focused', () => {
383
- it('removes the focused class', async () => {
384
- await setTestPage('/test', renderComponent('autosuggest', EXAMPLE_AUTOSUGGEST));
386
+ describe('when the mouse moves over a result and a suggestion is focused', () => {
387
+ it('removes the focused class', async () => {
388
+ await setTestPage('/test', renderComponent('autosuggest', EXAMPLE_AUTOSUGGEST));
385
389
 
386
- await page.type('.ons-js-autosuggest-input', 'state', { delay: 20 });
387
- await page.keyboard.press('ArrowDown');
388
- await page.hover('.ons-autosuggest__option:nth-child(2)');
390
+ await page.type('.ons-js-autosuggest-input', 'state', { delay: 20 });
391
+ await page.keyboard.press('ArrowDown');
392
+ await page.hover('.ons-autosuggest__option:nth-child(2)');
389
393
 
390
- const focusedClassCount = await page.$$eval('.ons-autosuggest__option--focused', (nodes) => nodes.length);
391
- expect(focusedClassCount).toBe(0);
392
- });
393
- });
394
-
395
- describe('when the mouse moves off a result and a suggestion was focused', () => {
396
- it('restores the focused class', async () => {
397
- await setTestPage(
398
- '/test',
399
- `
400
- ${renderComponent('autosuggest', EXAMPLE_AUTOSUGGEST)}
401
- <a id="dummy">Dummy</a>
402
- `,
403
- );
404
-
405
- await page.type('.ons-js-autosuggest-input', 'state', { delay: 20 });
406
- await page.keyboard.press('ArrowDown');
407
- await page.hover('.ons-autosuggest__option:nth-child(2)');
408
- await page.hover('#dummy');
409
-
410
- const focusedClassCount = await page.$$eval('.ons-autosuggest__option--focused', (nodes) => nodes.length);
411
- expect(focusedClassCount).toBe(1);
394
+ const focusedClassCount = await page.$$eval('.ons-autosuggest__option--focused', (nodes) => nodes.length);
395
+ expect(focusedClassCount).toBe(0);
396
+ });
412
397
  });
413
- });
414
398
 
415
- describe('when there are results', () => {
416
- it('un-highlights a previously highlighted suggestion', async () => {
417
- await setTestPage('/test', renderComponent('autosuggest', EXAMPLE_AUTOSUGGEST));
399
+ describe('when the mouse moves off a result and a suggestion was focused', () => {
400
+ it('restores the focused class', async () => {
401
+ await setTestPage(
402
+ '/test',
403
+ `
404
+ ${renderComponent('autosuggest', EXAMPLE_AUTOSUGGEST)}
405
+ <a id="dummy">Dummy</a>
406
+ `,
407
+ );
418
408
 
419
- await page.type('.ons-js-autosuggest-input', 'Unite', { delay: 20 });
420
- await page.keyboard.press('ArrowDown');
421
- await page.type('.ons-js-autosuggest-input', 'd', { delay: 20 });
409
+ await page.type('.ons-js-autosuggest-input', 'state', { delay: 20 });
410
+ await page.keyboard.press('ArrowDown');
411
+ await page.hover('.ons-autosuggest__option:nth-child(2)');
412
+ await page.hover('#dummy');
422
413
 
423
- const focusedNodeCount = await page.$$eval('.ons-autosuggest__option--focused', (nodes) => nodes.length);
424
- expect(focusedNodeCount).toBe(0);
414
+ const focusedClassCount = await page.$$eval('.ons-autosuggest__option--focused', (nodes) => nodes.length);
415
+ expect(focusedClassCount).toBe(1);
416
+ });
425
417
  });
426
418
 
427
- it('decorates input element with `aria-expanded` attribute', async () => {
428
- await setTestPage('/test', renderComponent('autosuggest', EXAMPLE_AUTOSUGGEST));
419
+ describe('when there are results', () => {
420
+ it('un-highlights a previously highlighted suggestion', async () => {
421
+ await setTestPage('/test', renderComponent('autosuggest', EXAMPLE_AUTOSUGGEST));
429
422
 
430
- await page.type('.ons-js-autosuggest-input', 'Unite', { delay: 20 });
423
+ await page.type('.ons-js-autosuggest-input', 'Unite', { delay: 20 });
424
+ await page.keyboard.press('ArrowDown');
425
+ await page.type('.ons-js-autosuggest-input', 'd', { delay: 20 });
431
426
 
432
- const ariaExpandedValue = await page.$eval('.ons-js-autosuggest-input', (node) => node.getAttribute('aria-expanded'));
433
- expect(ariaExpandedValue).toBe('true');
434
- });
427
+ const focusedNodeCount = await page.$$eval('.ons-autosuggest__option--focused', (nodes) => nodes.length);
428
+ expect(focusedNodeCount).toBe(0);
429
+ });
435
430
 
436
- it('emboldens matched suggestion text', async () => {
437
- await setTestPage('/test', renderComponent('autosuggest', EXAMPLE_AUTOSUGGEST));
431
+ it('decorates input element with `aria-expanded` attribute', async () => {
432
+ await setTestPage('/test', renderComponent('autosuggest', EXAMPLE_AUTOSUGGEST));
438
433
 
439
- await page.type('.ons-js-autosuggest-input', 'Unite', { delay: 20 });
434
+ await page.type('.ons-js-autosuggest-input', 'Unite', { delay: 20 });
440
435
 
441
- const emboldened = await page.$$eval('.ons-autosuggest__option strong', (nodes) => nodes.map((node) => node.textContent));
442
- expect(emboldened).toEqual(['Unite', 'Unite']);
443
- });
436
+ const ariaExpandedValue = await page.$eval('.ons-js-autosuggest-input', (node) => node.getAttribute('aria-expanded'));
437
+ expect(ariaExpandedValue).toBe('true');
438
+ });
444
439
 
445
- it('does not embolden anything when suggestion does not contain query text', async () => {
446
- await setTestPage('/test', renderComponent('autosuggest', EXAMPLE_AUTOSUGGEST));
440
+ it('emboldens matched suggestion text', async () => {
441
+ await setTestPage('/test', renderComponent('autosuggest', EXAMPLE_AUTOSUGGEST));
447
442
 
448
- await page.type('.ons-js-autosuggest-input', 'tland', { delay: 20 });
443
+ await page.type('.ons-js-autosuggest-input', 'Unite', { delay: 20 });
449
444
 
450
- const matchCount = await page.$$eval('.ons-autosuggest__option', (nodes) => nodes.length);
451
- expect(matchCount).toBe(2);
452
- const emboldened = await page.$$eval('.ons-autosuggest__option strong', (nodes) => nodes.map((node) => node.textContent));
453
- expect(emboldened).toEqual(['tland']);
454
- });
445
+ const emboldened = await page.$$eval('.ons-autosuggest__option strong', (nodes) => nodes.map((node) => node.textContent));
446
+ expect(emboldened).toEqual(['Unite', 'Unite']);
447
+ });
455
448
 
456
- it('sets aria status to a message asking for more characters to be input', async () => {
457
- await setTestPage('/test', renderComponent('autosuggest', EXAMPLE_AUTOSUGGEST));
449
+ it('does not embolden anything when suggestion does not contain query text', async () => {
450
+ await setTestPage('/test', renderComponent('autosuggest', EXAMPLE_AUTOSUGGEST));
458
451
 
459
- await page.type('.ons-js-autosuggest-input', 'st', { delay: 20 });
452
+ await page.type('.ons-js-autosuggest-input', 'tland', { delay: 20 });
460
453
 
461
- const statusMessage = await page.$eval('.ons-js-autosuggest-aria-status', (node) => node.textContent);
462
- expect(statusMessage.trim()).toBe('Enter 3 or more characters for suggestions.');
463
- });
454
+ const matchCount = await page.$$eval('.ons-autosuggest__option', (nodes) => nodes.length);
455
+ expect(matchCount).toBe(2);
456
+ const emboldened = await page.$$eval('.ons-autosuggest__option strong', (nodes) => nodes.map((node) => node.textContent));
457
+ expect(emboldened).toEqual(['tland']);
458
+ });
464
459
 
465
- it('sets aria status to a message indicating a count of one suggestion', async () => {
466
- await setTestPage('/test', renderComponent('autosuggest', EXAMPLE_AUTOSUGGEST));
460
+ it('sets aria status to a message asking for more characters to be input', async () => {
461
+ await setTestPage('/test', renderComponent('autosuggest', EXAMPLE_AUTOSUGGEST));
467
462
 
468
- await page.type('.ons-js-autosuggest-input', 'Engla', { delay: 20 });
463
+ await page.type('.ons-js-autosuggest-input', 'st', { delay: 20 });
469
464
 
470
- const statusMessage = await page.$eval('.ons-js-autosuggest-aria-status', (node) => node.textContent);
471
- expect(statusMessage.trim()).toBe('There is one suggestion available.');
472
- });
465
+ const statusMessage = await page.$eval('.ons-js-autosuggest-aria-status', (node) => node.textContent);
466
+ expect(statusMessage.trim()).toBe('Enter 3 or more characters for suggestions.');
467
+ });
468
+
469
+ it('sets aria status to a message indicating a count of one suggestion', async () => {
470
+ await setTestPage('/test', renderComponent('autosuggest', EXAMPLE_AUTOSUGGEST));
471
+
472
+ await page.type('.ons-js-autosuggest-input', 'Engla', { delay: 20 });
473
473
 
474
- it('sets aria status to a message indicating the count of suggestions', async () => {
475
- await setTestPage('/test', renderComponent('autosuggest', EXAMPLE_AUTOSUGGEST));
474
+ const statusMessage = await page.$eval('.ons-js-autosuggest-aria-status', (node) => node.textContent);
475
+ expect(statusMessage.trim()).toBe('There is one suggestion available.');
476
+ });
477
+
478
+ it('sets aria status to a message indicating the count of suggestions', async () => {
479
+ await setTestPage('/test', renderComponent('autosuggest', EXAMPLE_AUTOSUGGEST));
476
480
 
477
- await page.type('.ons-js-autosuggest-input', 'sta', { delay: 20 });
481
+ await page.type('.ons-js-autosuggest-input', 'sta', { delay: 20 });
478
482
 
479
- const statusMessage = await page.$eval('.ons-js-autosuggest-aria-status', (node) => node.textContent);
480
- expect(statusMessage.trim()).toBe('There are 2 suggestions available.');
483
+ const statusMessage = await page.$eval('.ons-js-autosuggest-aria-status', (node) => node.textContent);
484
+ expect(statusMessage.trim()).toBe('There are 2 suggestions available.');
485
+ });
481
486
  });
482
- });
483
487
 
484
- describe('when there are no results', () => {
485
- describe('where `noResults` content is provided', () => {
486
- it('outputs `noResults` content', async () => {
487
- await setTestPage('/test', renderComponent('autosuggest', EXAMPLE_AUTOSUGGEST));
488
+ describe('when there are no results', () => {
489
+ describe('where `noResults` content is provided', () => {
490
+ it('outputs `noResults` content', async () => {
491
+ await setTestPage('/test', renderComponent('autosuggest', EXAMPLE_AUTOSUGGEST));
488
492
 
489
- await page.type('.ons-js-autosuggest-input', 'abc', { delay: 20 });
493
+ await page.type('.ons-js-autosuggest-input', 'abc', { delay: 20 });
490
494
 
491
- const noResultsContent = await page.$eval('.ons-autosuggest__option--no-results', (node) => node.textContent);
492
- expect(noResultsContent).toBe('No suggestions found.');
493
- });
495
+ const noResultsContent = await page.$eval('.ons-autosuggest__option--no-results', (node) => node.textContent);
496
+ expect(noResultsContent).toBe('No suggestions found.');
497
+ });
494
498
 
495
- it('decorates input element with `aria-expanded` attribute', async () => {
496
- await setTestPage('/test', renderComponent('autosuggest', EXAMPLE_AUTOSUGGEST));
499
+ it('decorates input element with `aria-expanded` attribute', async () => {
500
+ await setTestPage('/test', renderComponent('autosuggest', EXAMPLE_AUTOSUGGEST));
497
501
 
498
- await page.type('.ons-js-autosuggest-input', 'abc', { delay: 20 });
502
+ await page.type('.ons-js-autosuggest-input', 'abc', { delay: 20 });
499
503
 
500
- const ariaExpandedValue = await page.$eval('.ons-js-autosuggest-input', (node) => node.getAttribute('aria-expanded'));
501
- expect(ariaExpandedValue).toBe('true');
502
- });
504
+ const ariaExpandedValue = await page.$eval('.ons-js-autosuggest-input', (node) => node.getAttribute('aria-expanded'));
505
+ expect(ariaExpandedValue).toBe('true');
506
+ });
503
507
 
504
- it('sets aria status to a message indicating that query is too short for suggestions', async () => {
505
- await setTestPage('/test', renderComponent('autosuggest', EXAMPLE_AUTOSUGGEST));
508
+ it('sets aria status to a message indicating that query is too short for suggestions', async () => {
509
+ await setTestPage('/test', renderComponent('autosuggest', EXAMPLE_AUTOSUGGEST));
506
510
 
507
- await page.type('.ons-js-autosuggest-input', 'ab', { delay: 20 });
511
+ await page.type('.ons-js-autosuggest-input', 'ab', { delay: 20 });
508
512
 
509
- const statusMessage = await page.$eval('.ons-js-autosuggest-aria-status', (node) => node.textContent);
510
- expect(statusMessage.trim()).toBe('Enter 3 or more characters for suggestions.');
511
- });
513
+ const statusMessage = await page.$eval('.ons-js-autosuggest-aria-status', (node) => node.textContent);
514
+ expect(statusMessage.trim()).toBe('Enter 3 or more characters for suggestions.');
515
+ });
512
516
 
513
- it('sets aria status to a message indicating the zero count of suggestions', async () => {
514
- await setTestPage('/test', renderComponent('autosuggest', EXAMPLE_AUTOSUGGEST));
517
+ it('sets aria status to a message indicating the zero count of suggestions', async () => {
518
+ await setTestPage('/test', renderComponent('autosuggest', EXAMPLE_AUTOSUGGEST));
515
519
 
516
- await page.type('.ons-js-autosuggest-input', 'abc', { delay: 20 });
520
+ await page.type('.ons-js-autosuggest-input', 'abc', { delay: 20 });
517
521
 
518
- const statusMessage = await page.$eval('.ons-js-autosuggest-aria-status', (node) => node.textContent);
519
- expect(statusMessage.trim()).toBe('No suggestions found.: "abc"');
520
- });
521
- });
522
+ const statusMessage = await page.$eval('.ons-js-autosuggest-aria-status', (node) => node.textContent);
523
+ expect(statusMessage.trim()).toBe('No suggestions found.: "abc"');
524
+ });
525
+ });
522
526
 
523
- describe('where `noResults` content is not provided', () => {
524
- it('has an empty listbox', async () => {
525
- await setTestPage(
526
- '/test',
527
- renderComponent('autosuggest', {
528
- ...EXAMPLE_AUTOSUGGEST,
529
- noResults: undefined,
530
- }),
531
- );
532
-
533
- await page.type('.ons-js-autosuggest-input', 'abc', { delay: 20 });
534
-
535
- const matchCount = await page.$$eval('.ons-autosuggest__option', (nodes) => nodes.length);
536
- expect(matchCount).toBe(0);
537
- });
538
-
539
- it('decorates input element with `aria-expanded` attribute', async () => {
540
- await setTestPage(
541
- '/test',
542
- renderComponent('autosuggest', {
543
- ...EXAMPLE_AUTOSUGGEST,
544
- noResults: undefined,
545
- }),
546
- );
547
-
548
- await page.type('.ons-js-autosuggest-input', 'abc', { delay: 20 });
549
-
550
- const ariaExpandedValue = await page.$eval('.ons-js-autosuggest-input', (node) => node.getAttribute('aria-expanded'));
551
- expect(ariaExpandedValue).toBe('false');
552
- });
527
+ describe('where `noResults` content is not provided', () => {
528
+ it('has an empty listbox', async () => {
529
+ await setTestPage(
530
+ '/test',
531
+ renderComponent('autosuggest', {
532
+ ...EXAMPLE_AUTOSUGGEST,
533
+ noResults: undefined,
534
+ }),
535
+ );
536
+
537
+ await page.type('.ons-js-autosuggest-input', 'abc', { delay: 20 });
538
+
539
+ const matchCount = await page.$$eval('.ons-autosuggest__option', (nodes) => nodes.length);
540
+ expect(matchCount).toBe(0);
541
+ });
542
+
543
+ it('decorates input element with `aria-expanded` attribute', async () => {
544
+ await setTestPage(
545
+ '/test',
546
+ renderComponent('autosuggest', {
547
+ ...EXAMPLE_AUTOSUGGEST,
548
+ noResults: undefined,
549
+ }),
550
+ );
551
+
552
+ await page.type('.ons-js-autosuggest-input', 'abc', { delay: 20 });
553
+
554
+ const ariaExpandedValue = await page.$eval('.ons-js-autosuggest-input', (node) => node.getAttribute('aria-expanded'));
555
+ expect(ariaExpandedValue).toBe('false');
556
+ });
557
+ });
553
558
  });
554
- });
555
559
 
556
- describe('when there are no results due to an error', () => {
557
- describe('when the status code is 400', () => {
558
- beforeEach(async () => {
559
- apiFaker.setTemporaryOverride('/countries', {
560
- status: 400,
561
- data: {},
562
- });
560
+ describe('when there are no results due to an error', () => {
561
+ describe('when the status code is 400', () => {
562
+ beforeEach(async () => {
563
+ apiFaker.setTemporaryOverride('/countries', {
564
+ status: 400,
565
+ data: {},
566
+ });
563
567
 
564
- await setTestPage('/test', renderComponent('autosuggest', EXAMPLE_AUTOSUGGEST));
568
+ await setTestPage('/test', renderComponent('autosuggest', EXAMPLE_AUTOSUGGEST));
565
569
 
566
- await page.focus('.ons-js-autosuggest-input');
567
- await page.type('.ons-js-autosuggest-input', 'tes', { delay: 20 });
568
- });
570
+ await page.focus('.ons-js-autosuggest-input');
571
+ await page.type('.ons-js-autosuggest-input', 'tes', { delay: 20 });
572
+ });
569
573
 
570
- it('shows the type more message', async () => {
571
- const listItemCount = await page.$$eval('.ons-js-autosuggest-listbox > *', (nodes) => nodes.length);
572
- expect(listItemCount).toBe(1);
573
- const noResultsText = await page.$eval('.ons-autosuggest__option--no-results', (node) => node.innerText);
574
- expect(noResultsText.trim()).toBe('Continue entering to get suggestions');
575
- });
576
- });
574
+ it('shows the type more message', async () => {
575
+ const listItemCount = await page.$$eval('.ons-js-autosuggest-listbox > *', (nodes) => nodes.length);
576
+ expect(listItemCount).toBe(1);
577
+ const noResultsText = await page.$eval('.ons-autosuggest__option--no-results', (node) => node.innerText);
578
+ expect(noResultsText.trim()).toBe('Continue entering to get suggestions');
579
+ });
580
+ });
577
581
 
578
- describe.each([
579
- ['when the status code is greater than 400', {}, 401],
580
- ['when there is no status code', null, undefined],
581
- ])('%s', (_, fakeAutosuggestData, fakeStatusCode) => {
582
- beforeEach(async () => {
583
- apiFaker.setTemporaryOverride('/countries', {
584
- status: fakeStatusCode,
585
- data: fakeAutosuggestData,
586
- });
587
-
588
- await setTestPage(
589
- '/test',
590
- renderComponent('autosuggest', {
591
- ...EXAMPLE_AUTOSUGGEST,
592
- errorTitle: 'There is a problem with your answer',
593
- errorMessage: 'Enter an address ',
594
- errorMessageAPI: 'Sorry, there is a problem.',
595
- }),
596
- );
597
-
598
- await page.type('.ons-js-autosuggest-input', 'tes', { delay: 20 });
599
- });
600
-
601
- it('shows the API error message', async () => {
602
- const resultsItemCount = await page.$$eval('.ons-js-autosuggest-results > *', (nodes) => nodes.length);
603
- expect(resultsItemCount).toBe(1);
604
- const warningText = await page.$eval('.ons-autosuggest__warning', (node) => node.textContent);
605
- expect(warningText.trim()).toBe('!Sorry, there is a problem.');
606
- });
607
-
608
- it('the list and results element should be removed from the page', async () => {
609
- const hasListBox = await page.$eval('.ons-autosuggest', (node) => node.classList.contains('.ons-js-autosuggest-listbox'));
610
- const hasResultsTitle = await page.$eval('.ons-autosuggest', (node) => node.classList.contains('.ons-autosuggest__results-title'));
611
-
612
- expect(hasListBox).toBe(false);
613
- expect(hasResultsTitle).toBe(false);
614
- });
615
-
616
- it('the input should be disabled', async () => {
617
- const hasDisabledAttribute = await page.$eval('.ons-js-autosuggest-input', (node) => node.hasAttribute('disabled'));
618
- expect(hasDisabledAttribute).toBe(true);
619
- });
620
-
621
- it('the input value should be empty', async () => {
622
- const inputValue = await page.$eval('.ons-js-autosuggest-input', (node) => node.value);
623
- expect(inputValue).toBe('');
624
- });
625
-
626
- it('the label class should be added', async () => {
627
- const hasClass = await page.$eval('.ons-label', (node) => node.classList.contains('ons-u-lighter'));
628
- expect(hasClass).toBe(true);
629
- });
630
-
631
- it('the aria status should be set', async () => {
632
- const statusMessage = await page.$eval('.ons-js-autosuggest-aria-status', (node) => node.textContent);
633
- expect(statusMessage.trim()).toBe('Sorry, there is a problem.');
634
- });
635
- });
636
- });
637
-
638
- describe('when the component initialises with the allowMultiple parameter', () => {
639
- describe('when a result is selected', () => {
640
- it('the input value should contain a comma when focused', async () => {
641
- await setTestPage(
642
- '/test',
643
- renderComponent('autosuggest', {
644
- ...EXAMPLE_AUTOSUGGEST,
645
- allowMultiple: true,
646
- }),
647
- );
648
-
649
- await page.type('.ons-js-autosuggest-input', 'England', { delay: 20 });
650
- await page.keyboard.press('ArrowUp');
651
- await page.keyboard.press('Enter');
652
- // Defocus the autosuggest input.
653
- await page.keyboard.press('Tab');
654
- await page.focus('.ons-js-autosuggest-input');
655
-
656
- const inputValue = await page.$eval('.ons-js-autosuggest-input', (node) => node.value);
657
- expect(inputValue).toBe('England, ');
658
- });
582
+ describe.each([
583
+ ['when the status code is greater than 400', {}, 401],
584
+ ['when there is no status code', null, undefined],
585
+ ])('%s', (_, fakeAutosuggestData, fakeStatusCode) => {
586
+ beforeEach(async () => {
587
+ apiFaker.setTemporaryOverride('/countries', {
588
+ status: fakeStatusCode,
589
+ data: fakeAutosuggestData,
590
+ });
591
+
592
+ await setTestPage(
593
+ '/test',
594
+ renderComponent('autosuggest', {
595
+ ...EXAMPLE_AUTOSUGGEST,
596
+ errorTitle: 'There is a problem with your answer',
597
+ errorMessage: 'Enter an address ',
598
+ errorMessageAPI: 'Sorry, there is a problem.',
599
+ }),
600
+ );
601
+
602
+ await page.type('.ons-js-autosuggest-input', 'tes', { delay: 20 });
603
+ });
604
+
605
+ it('shows the API error message', async () => {
606
+ const resultsItemCount = await page.$$eval('.ons-js-autosuggest-results > *', (nodes) => nodes.length);
607
+ expect(resultsItemCount).toBe(1);
608
+ const warningText = await page.$eval('.ons-autosuggest__warning', (node) => node.textContent);
609
+ expect(warningText.trim()).toBe('!Sorry, there is a problem.');
610
+ });
611
+
612
+ it('the list and results element should be removed from the page', async () => {
613
+ const hasListBox = await page.$eval('.ons-autosuggest', (node) => node.classList.contains('.ons-js-autosuggest-listbox'));
614
+ const hasResultsTitle = await page.$eval('.ons-autosuggest', (node) =>
615
+ node.classList.contains('.ons-autosuggest__results-title'),
616
+ );
617
+
618
+ expect(hasListBox).toBe(false);
619
+ expect(hasResultsTitle).toBe(false);
620
+ });
621
+
622
+ it('the input should be disabled', async () => {
623
+ const hasDisabledAttribute = await page.$eval('.ons-js-autosuggest-input', (node) => node.hasAttribute('disabled'));
624
+ expect(hasDisabledAttribute).toBe(true);
625
+ });
626
+
627
+ it('the input value should be empty', async () => {
628
+ const inputValue = await page.$eval('.ons-js-autosuggest-input', (node) => node.value);
629
+ expect(inputValue).toBe('');
630
+ });
631
+
632
+ it('the label class should be added', async () => {
633
+ const hasClass = await page.$eval('.ons-label', (node) => node.classList.contains('ons-u-lighter'));
634
+ expect(hasClass).toBe(true);
635
+ });
636
+
637
+ it('the aria status should be set', async () => {
638
+ const statusMessage = await page.$eval('.ons-js-autosuggest-aria-status', (node) => node.textContent);
639
+ expect(statusMessage.trim()).toBe('Sorry, there is a problem.');
640
+ });
641
+ });
659
642
  });
660
643
 
661
- describe('when the user blurs the input', () => {
662
- it('the input value should not contain a comma', async () => {
663
- await setTestPage(
664
- '/test',
665
- renderComponent('autosuggest', {
666
- ...EXAMPLE_AUTOSUGGEST,
667
- allowMultiple: true,
668
- }),
669
- );
670
-
671
- await page.type('.ons-js-autosuggest-input', 'England, ', { delay: 20 });
672
- await page.keyboard.press('Tab');
673
-
674
- const inputValue = await page.$eval('.ons-js-autosuggest-input', (node) => node.value);
675
- expect(inputValue).toBe('England');
676
- });
644
+ describe('when the component initialises with the allowMultiple parameter', () => {
645
+ describe('when a result is selected', () => {
646
+ it('the input value should contain a comma when focused', async () => {
647
+ await setTestPage(
648
+ '/test',
649
+ renderComponent('autosuggest', {
650
+ ...EXAMPLE_AUTOSUGGEST,
651
+ allowMultiple: true,
652
+ }),
653
+ );
654
+
655
+ await page.type('.ons-js-autosuggest-input', 'England', { delay: 20 });
656
+ await page.keyboard.press('ArrowUp');
657
+ await page.keyboard.press('Enter');
658
+ // Defocus the autosuggest input.
659
+ await page.keyboard.press('Tab');
660
+ await page.focus('.ons-js-autosuggest-input');
661
+
662
+ const inputValue = await page.$eval('.ons-js-autosuggest-input', (node) => node.value);
663
+ expect(inputValue).toBe('England, ');
664
+ });
665
+ });
666
+
667
+ describe('when the user blurs the input', () => {
668
+ it('the input value should not contain a comma', async () => {
669
+ await setTestPage(
670
+ '/test',
671
+ renderComponent('autosuggest', {
672
+ ...EXAMPLE_AUTOSUGGEST,
673
+ allowMultiple: true,
674
+ }),
675
+ );
676
+
677
+ await page.type('.ons-js-autosuggest-input', 'England, ', { delay: 20 });
678
+ await page.keyboard.press('Tab');
679
+
680
+ const inputValue = await page.$eval('.ons-js-autosuggest-input', (node) => node.value);
681
+ expect(inputValue).toBe('England');
682
+ });
683
+ });
677
684
  });
678
- });
679
685
  });