govuk_tech_docs 5.2.1 → 6.0.0.beta

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (169) hide show
  1. checksums.yaml +4 -4
  2. data/.github/dependabot.yml +59 -0
  3. data/.npmrc +1 -0
  4. data/.ruby-version +1 -0
  5. data/CHANGELOG.md +19 -0
  6. data/README.md +13 -4
  7. data/example/config/tech-docs.yml +1 -1
  8. data/govuk_tech_docs.gemspec +2 -2
  9. data/lib/assets/stylesheets/_core.scss +1 -0
  10. data/lib/assets/stylesheets/_govuk_tech_docs.scss +13 -15
  11. data/lib/assets/stylesheets/modules/_app-pane.scss +3 -3
  12. data/lib/assets/stylesheets/modules/_page-review.scss +4 -4
  13. data/lib/assets/stylesheets/modules/_search.scss +3 -3
  14. data/lib/assets/stylesheets/modules/_service-navigation.scss +5 -0
  15. data/lib/assets/stylesheets/modules/_technical-documentation.scss +7 -7
  16. data/lib/assets/stylesheets/modules/_toc.scss +13 -13
  17. data/lib/assets/stylesheets/palette/_syntax-highlighting.scss +9 -7
  18. data/lib/govuk_tech_docs/meta_tags.rb +1 -1
  19. data/lib/govuk_tech_docs/version.rb +1 -1
  20. data/lib/source/layouts/_header.erb +2 -16
  21. data/lib/source/layouts/_service_navigation.erb +27 -0
  22. data/lib/source/layouts/core.erb +7 -7
  23. data/node_modules/govuk-frontend/dist/govuk/_base.scss +1 -0
  24. data/node_modules/govuk-frontend/dist/govuk/all.bundle.js +183 -300
  25. data/node_modules/govuk-frontend/dist/govuk/all.bundle.mjs +184 -300
  26. data/node_modules/govuk-frontend/dist/govuk/all.mjs +0 -1
  27. data/node_modules/govuk-frontend/dist/govuk/assets/images/favicon.ico +0 -0
  28. data/node_modules/govuk-frontend/dist/govuk/assets/images/favicon.svg +1 -1
  29. data/node_modules/govuk-frontend/dist/govuk/assets/images/govuk-icon-180.png +0 -0
  30. data/node_modules/govuk-frontend/dist/govuk/assets/images/govuk-icon-192.png +0 -0
  31. data/node_modules/govuk-frontend/dist/govuk/assets/images/govuk-icon-512.png +0 -0
  32. data/node_modules/govuk-frontend/dist/govuk/assets/images/govuk-opengraph-image.png +0 -0
  33. data/node_modules/govuk-frontend/dist/govuk/common/configuration.mjs +29 -2
  34. data/node_modules/govuk-frontend/dist/govuk/common/govuk-frontend-version.mjs +1 -1
  35. data/node_modules/govuk-frontend/dist/govuk/common/index.mjs +4 -10
  36. data/node_modules/govuk-frontend/dist/govuk/components/accordion/_index.scss +18 -15
  37. data/node_modules/govuk-frontend/dist/govuk/components/accordion/accordion.bundle.js +14 -137
  38. data/node_modules/govuk-frontend/dist/govuk/components/accordion/accordion.bundle.mjs +14 -137
  39. data/node_modules/govuk-frontend/dist/govuk/components/accordion/accordion.mjs +4 -4
  40. data/node_modules/govuk-frontend/dist/govuk/components/back-link/_index.scss +2 -2
  41. data/node_modules/govuk-frontend/dist/govuk/components/breadcrumbs/_index.scss +2 -2
  42. data/node_modules/govuk-frontend/dist/govuk/components/button/_index.scss +18 -21
  43. data/node_modules/govuk-frontend/dist/govuk/components/button/button.bundle.js +7 -5
  44. data/node_modules/govuk-frontend/dist/govuk/components/button/button.bundle.mjs +7 -5
  45. data/node_modules/govuk-frontend/dist/govuk/components/character-count/_index.scss +2 -2
  46. data/node_modules/govuk-frontend/dist/govuk/components/character-count/character-count.bundle.js +30 -143
  47. data/node_modules/govuk-frontend/dist/govuk/components/character-count/character-count.bundle.mjs +30 -143
  48. data/node_modules/govuk-frontend/dist/govuk/components/character-count/character-count.mjs +20 -10
  49. data/node_modules/govuk-frontend/dist/govuk/components/checkboxes/_index.scss +7 -6
  50. data/node_modules/govuk-frontend/dist/govuk/components/checkboxes/checkboxes.bundle.js +10 -5
  51. data/node_modules/govuk-frontend/dist/govuk/components/checkboxes/checkboxes.bundle.mjs +10 -5
  52. data/node_modules/govuk-frontend/dist/govuk/components/cookie-banner/_index.scss +2 -5
  53. data/node_modules/govuk-frontend/dist/govuk/components/date-input/_index.scss +5 -0
  54. data/node_modules/govuk-frontend/dist/govuk/components/details/_index.scss +6 -4
  55. data/node_modules/govuk-frontend/dist/govuk/components/error-message/_index.scss +1 -1
  56. data/node_modules/govuk-frontend/dist/govuk/components/error-summary/_index.scss +4 -2
  57. data/node_modules/govuk-frontend/dist/govuk/components/error-summary/error-summary.bundle.js +8 -12
  58. data/node_modules/govuk-frontend/dist/govuk/components/error-summary/error-summary.bundle.mjs +8 -12
  59. data/node_modules/govuk-frontend/dist/govuk/components/error-summary/error-summary.mjs +2 -2
  60. data/node_modules/govuk-frontend/dist/govuk/components/exit-this-page/_index.scss +1 -1
  61. data/node_modules/govuk-frontend/dist/govuk/components/exit-this-page/exit-this-page.bundle.js +10 -133
  62. data/node_modules/govuk-frontend/dist/govuk/components/exit-this-page/exit-this-page.bundle.mjs +10 -133
  63. data/node_modules/govuk-frontend/dist/govuk/components/file-upload/_index.scss +30 -38
  64. data/node_modules/govuk-frontend/dist/govuk/components/file-upload/file-upload.bundle.js +46 -140
  65. data/node_modules/govuk-frontend/dist/govuk/components/file-upload/file-upload.bundle.mjs +46 -140
  66. data/node_modules/govuk-frontend/dist/govuk/components/file-upload/file-upload.mjs +36 -7
  67. data/node_modules/govuk-frontend/dist/govuk/components/footer/_index.scss +30 -27
  68. data/node_modules/govuk-frontend/dist/govuk/components/header/_index.scss +89 -449
  69. data/node_modules/govuk-frontend/dist/govuk/components/hint/_index.scss +1 -1
  70. data/node_modules/govuk-frontend/dist/govuk/components/input/_index.scss +14 -20
  71. data/node_modules/govuk-frontend/dist/govuk/components/inset-text/_index.scss +2 -1
  72. data/node_modules/govuk-frontend/dist/govuk/components/notification-banner/_index.scss +10 -8
  73. data/node_modules/govuk-frontend/dist/govuk/components/notification-banner/notification-banner.bundle.js +7 -5
  74. data/node_modules/govuk-frontend/dist/govuk/components/notification-banner/notification-banner.bundle.mjs +7 -5
  75. data/node_modules/govuk-frontend/dist/govuk/components/pagination/_index.scss +16 -11
  76. data/node_modules/govuk-frontend/dist/govuk/components/panel/_index.scss +4 -4
  77. data/node_modules/govuk-frontend/dist/govuk/components/password-input/_index.scss +2 -2
  78. data/node_modules/govuk-frontend/dist/govuk/components/password-input/password-input.bundle.js +10 -133
  79. data/node_modules/govuk-frontend/dist/govuk/components/password-input/password-input.bundle.mjs +10 -133
  80. data/node_modules/govuk-frontend/dist/govuk/components/phase-banner/_index.scss +12 -6
  81. data/node_modules/govuk-frontend/dist/govuk/components/radios/_index.scss +8 -7
  82. data/node_modules/govuk-frontend/dist/govuk/components/radios/radios.bundle.js +10 -5
  83. data/node_modules/govuk-frontend/dist/govuk/components/radios/radios.bundle.mjs +10 -5
  84. data/node_modules/govuk-frontend/dist/govuk/components/select/_index.scss +6 -11
  85. data/node_modules/govuk-frontend/dist/govuk/components/service-navigation/_index.scss +58 -74
  86. data/node_modules/govuk-frontend/dist/govuk/components/service-navigation/service-navigation.bundle.js +40 -7
  87. data/node_modules/govuk-frontend/dist/govuk/components/service-navigation/service-navigation.bundle.mjs +40 -7
  88. data/node_modules/govuk-frontend/dist/govuk/components/service-navigation/service-navigation.mjs +30 -2
  89. data/node_modules/govuk-frontend/dist/govuk/components/skip-link/_index.scss +8 -4
  90. data/node_modules/govuk-frontend/dist/govuk/components/skip-link/skip-link.bundle.js +12 -19
  91. data/node_modules/govuk-frontend/dist/govuk/components/skip-link/skip-link.bundle.mjs +12 -19
  92. data/node_modules/govuk-frontend/dist/govuk/components/skip-link/skip-link.mjs +3 -9
  93. data/node_modules/govuk-frontend/dist/govuk/components/summary-list/_index.scss +25 -21
  94. data/node_modules/govuk-frontend/dist/govuk/components/table/_index.scss +7 -8
  95. data/node_modules/govuk-frontend/dist/govuk/components/tabs/_index.scss +9 -6
  96. data/node_modules/govuk-frontend/dist/govuk/components/tabs/tabs.bundle.js +12 -13
  97. data/node_modules/govuk-frontend/dist/govuk/components/tabs/tabs.bundle.mjs +12 -13
  98. data/node_modules/govuk-frontend/dist/govuk/components/tabs/tabs.mjs +3 -3
  99. data/node_modules/govuk-frontend/dist/govuk/components/tag/_index.scss +66 -31
  100. data/node_modules/govuk-frontend/dist/govuk/components/task-list/_index.scss +7 -5
  101. data/node_modules/govuk-frontend/dist/govuk/components/textarea/_index.scss +5 -10
  102. data/node_modules/govuk-frontend/dist/govuk/components/warning-text/_index.scss +5 -4
  103. data/node_modules/govuk-frontend/dist/govuk/core/_index.scss +0 -1
  104. data/node_modules/govuk-frontend/dist/govuk/core/_lists.scss +2 -2
  105. data/node_modules/govuk-frontend/dist/govuk/core/_section-break.scss +2 -1
  106. data/node_modules/govuk-frontend/dist/govuk/core/_typography.scss +6 -20
  107. data/node_modules/govuk-frontend/dist/govuk/custom-properties/_breakpoints.scss +17 -0
  108. data/node_modules/govuk-frontend/dist/govuk/custom-properties/_frontend-version.scss +15 -0
  109. data/node_modules/govuk-frontend/dist/govuk/custom-properties/_functional-colours.scss +17 -0
  110. data/node_modules/govuk-frontend/dist/govuk/custom-properties/_index.scss +5 -0
  111. data/node_modules/govuk-frontend/dist/govuk/errors/index.mjs +5 -3
  112. data/node_modules/govuk-frontend/dist/govuk/govuk-frontend.min.js +1 -1
  113. data/node_modules/govuk-frontend/dist/govuk/helpers/_colour.scss +187 -72
  114. data/node_modules/govuk-frontend/dist/govuk/helpers/_focused.scss +41 -6
  115. data/node_modules/govuk-frontend/dist/govuk/helpers/_grid.scss +1 -1
  116. data/node_modules/govuk-frontend/dist/govuk/helpers/_links.scss +24 -40
  117. data/node_modules/govuk-frontend/dist/govuk/helpers/_media-queries.scss +172 -33
  118. data/node_modules/govuk-frontend/dist/govuk/helpers/_spacing.scss +1 -1
  119. data/node_modules/govuk-frontend/dist/govuk/helpers/_typography.scss +6 -30
  120. data/node_modules/govuk-frontend/dist/govuk/helpers/_visually-hidden.scss +4 -1
  121. data/node_modules/govuk-frontend/dist/govuk/i18n.mjs +5 -128
  122. data/node_modules/govuk-frontend/dist/govuk/init.mjs +53 -45
  123. data/node_modules/govuk-frontend/dist/govuk/objects/_button-group.scss +1 -1
  124. data/node_modules/govuk-frontend/dist/govuk/objects/_form-group.scss +2 -1
  125. data/node_modules/govuk-frontend/dist/govuk/objects/_main-wrapper.scss +1 -1
  126. data/node_modules/govuk-frontend/dist/govuk/objects/_template.scss +3 -7
  127. data/node_modules/govuk-frontend/dist/govuk/objects/_width-container.scss +2 -2
  128. data/node_modules/govuk-frontend/dist/govuk/overrides/_display.scss +1 -1
  129. data/node_modules/govuk-frontend/dist/govuk/overrides/_typography.scss +0 -2
  130. data/node_modules/govuk-frontend/dist/govuk/overrides/_width.scss +5 -5
  131. data/node_modules/govuk-frontend/dist/govuk/settings/_colours-applied.scss +3 -188
  132. data/node_modules/govuk-frontend/dist/govuk/settings/_colours-functional.scss +366 -0
  133. data/node_modules/govuk-frontend/dist/govuk/settings/_colours-organisations.scss +9 -255
  134. data/node_modules/govuk-frontend/dist/govuk/settings/_colours-palette.scss +117 -25
  135. data/node_modules/govuk-frontend/dist/govuk/settings/_custom-properties.scss +18 -0
  136. data/node_modules/govuk-frontend/dist/govuk/settings/_index.scss +3 -14
  137. data/node_modules/govuk-frontend/dist/govuk/settings/_media-queries.scss +0 -9
  138. data/node_modules/govuk-frontend/dist/govuk/settings/_typography-responsive.scss +12 -189
  139. data/node_modules/govuk-frontend/dist/govuk/tools/_index.scss +0 -1
  140. data/node_modules/govuk-frontend/dist/govuk/tools/_px-to-em.scss +4 -2
  141. data/node_modules/govuk-frontend/dist/govuk/tools/_px-to-rem.scss +2 -0
  142. data/package-lock.json +2461 -1150
  143. data/package.json +3 -3
  144. metadata +16 -30
  145. data/node_modules/govuk-frontend/dist/govuk/all.scss +0 -9
  146. data/node_modules/govuk-frontend/dist/govuk/assets/rebrand/images/favicon.ico +0 -0
  147. data/node_modules/govuk-frontend/dist/govuk/assets/rebrand/images/favicon.svg +0 -1
  148. data/node_modules/govuk-frontend/dist/govuk/assets/rebrand/images/govuk-crest.svg +0 -1
  149. data/node_modules/govuk-frontend/dist/govuk/assets/rebrand/images/govuk-icon-180.png +0 -0
  150. data/node_modules/govuk-frontend/dist/govuk/assets/rebrand/images/govuk-icon-192.png +0 -0
  151. data/node_modules/govuk-frontend/dist/govuk/assets/rebrand/images/govuk-icon-512.png +0 -0
  152. data/node_modules/govuk-frontend/dist/govuk/assets/rebrand/images/govuk-icon-mask.svg +0 -1
  153. data/node_modules/govuk-frontend/dist/govuk/assets/rebrand/images/govuk-opengraph-image.png +0 -0
  154. data/node_modules/govuk-frontend/dist/govuk/assets/rebrand/manifest.json +0 -39
  155. data/node_modules/govuk-frontend/dist/govuk/components/_all.scss +0 -10
  156. data/node_modules/govuk-frontend/dist/govuk/components/header/header.bundle.js +0 -233
  157. data/node_modules/govuk-frontend/dist/govuk/components/header/header.bundle.mjs +0 -225
  158. data/node_modules/govuk-frontend/dist/govuk/components/header/header.mjs +0 -89
  159. data/node_modules/govuk-frontend/dist/govuk/core/_all.scss +0 -10
  160. data/node_modules/govuk-frontend/dist/govuk/core/_govuk-frontend-properties.scss +0 -15
  161. data/node_modules/govuk-frontend/dist/govuk/helpers/_all.scss +0 -10
  162. data/node_modules/govuk-frontend/dist/govuk/objects/_all.scss +0 -10
  163. data/node_modules/govuk-frontend/dist/govuk/overrides/_all.scss +0 -9
  164. data/node_modules/govuk-frontend/dist/govuk/settings/_all.scss +0 -10
  165. data/node_modules/govuk-frontend/dist/govuk/tools/_all.scss +0 -10
  166. data/node_modules/govuk-frontend/dist/govuk/tools/_rebrand.scss +0 -65
  167. data/node_modules/govuk-frontend/dist/govuk/utilities/_all.scss +0 -10
  168. data/node_modules/govuk-frontend/dist/govuk/vendor/_sass-mq.scss +0 -349
  169. data/node_modules/govuk-frontend/dist/govuk-prototype-kit/functions.js +0 -25
@@ -1,11 +1,5 @@
1
- const version = '5.11.0';
1
+ const version = '6.0.0';
2
2
 
3
- function getFragmentFromUrl(url) {
4
- if (!url.includes('#')) {
5
- return undefined;
6
- }
7
- return url.split('#').pop();
8
- }
9
3
  function getBreakpoint(name) {
10
4
  const property = `--govuk-breakpoint-${name}`;
11
5
  const value = window.getComputedStyle(document.documentElement).getPropertyValue(property);
@@ -63,6 +57,9 @@ function isArray(option) {
63
57
  function isObject(option) {
64
58
  return !!option && typeof option === 'object' && !isArray(option);
65
59
  }
60
+ function isScope($scope) {
61
+ return !!$scope && ($scope instanceof Element || $scope instanceof Document);
62
+ }
66
63
  function formatErrorMessage(Component, message) {
67
64
  return `${Component.moduleName}: ${message}`;
68
65
  }
@@ -70,9 +67,6 @@ function formatErrorMessage(Component, message) {
70
67
  * @typedef ComponentWithModuleName
71
68
  * @property {string} moduleName - Name of the component
72
69
  */
73
- /**
74
- * @import { ObjectNested } from './configuration.mjs'
75
- */
76
70
 
77
71
  class GOVUKFrontendError extends Error {
78
72
  constructor(...args) {
@@ -101,7 +95,7 @@ class ConfigError extends GOVUKFrontendError {
101
95
  class ElementError extends GOVUKFrontendError {
102
96
  constructor(messageOrOptions) {
103
97
  let message = typeof messageOrOptions === 'string' ? messageOrOptions : '';
104
- if (typeof messageOrOptions === 'object') {
98
+ if (isObject(messageOrOptions)) {
105
99
  const {
106
100
  component,
107
101
  identifier,
@@ -110,7 +104,9 @@ class ElementError extends GOVUKFrontendError {
110
104
  } = messageOrOptions;
111
105
  message = identifier;
112
106
  message += element ? ` is not of type ${expectedType != null ? expectedType : 'HTMLElement'}` : ' not found';
113
- message = formatErrorMessage(component, message);
107
+ if (component) {
108
+ message = formatErrorMessage(component, message);
109
+ }
114
110
  }
115
111
  super(message);
116
112
  this.name = 'ElementError';
@@ -250,6 +246,30 @@ function normaliseDataset(Component, dataset) {
250
246
  }
251
247
  return out;
252
248
  }
249
+ function normaliseOptions(scopeOrOptions) {
250
+ let $scope = document;
251
+ let onError;
252
+ if (isObject(scopeOrOptions)) {
253
+ const options = scopeOrOptions;
254
+ if (isScope(options.scope) || options.scope === null) {
255
+ $scope = options.scope;
256
+ }
257
+ if (typeof options.onError === 'function') {
258
+ onError = options.onError;
259
+ }
260
+ }
261
+ if (isScope(scopeOrOptions)) {
262
+ $scope = scopeOrOptions;
263
+ } else if (scopeOrOptions === null) {
264
+ $scope = null;
265
+ } else if (typeof scopeOrOptions === 'function') {
266
+ onError = scopeOrOptions;
267
+ }
268
+ return {
269
+ scope: $scope,
270
+ onError
271
+ };
272
+ }
253
273
  function mergeConfigs(...configObjects) {
254
274
  const formattedConfigObject = {};
255
275
  for (const configObject of configObjects) {
@@ -344,6 +364,9 @@ function extractConfigByNamespace(schema, dataset, namespace) {
344
364
  * @template {Partial<Record<keyof ConfigurationType, unknown>>} [ConfigurationType=ObjectNested]
345
365
  * @typedef {typeof Component & ChildClass<ConfigurationType>} ChildClassConstructor<ConfigurationType>
346
366
  */
367
+ /**
368
+ * @import { CompatibleClass, Config, CreateAllOptions, OnErrorCallback } from '../init.mjs'
369
+ */
347
370
 
348
371
  class I18n {
349
372
  constructor(translations = {}, config = {}) {
@@ -358,7 +381,7 @@ class I18n {
358
381
  throw new Error('i18n: lookup key missing');
359
382
  }
360
383
  let translation = this.translations[lookupKey];
361
- if (typeof (options == null ? void 0 : options.count) === 'number' && typeof translation === 'object') {
384
+ if (typeof (options == null ? void 0 : options.count) === 'number' && isObject(translation)) {
362
385
  const translationPluralForm = translation[this.getPluralSuffix(lookupKey, options.count)];
363
386
  if (translationPluralForm) {
364
387
  translation = translationPluralForm;
@@ -400,8 +423,8 @@ class I18n {
400
423
  return 'other';
401
424
  }
402
425
  const translation = this.translations[lookupKey];
403
- const preferredForm = this.hasIntlPluralRulesSupport() ? new Intl.PluralRules(this.locale).select(count) : this.selectPluralFormUsingFallbackRules(count);
404
- if (typeof translation === 'object') {
426
+ const preferredForm = this.hasIntlPluralRulesSupport() ? new Intl.PluralRules(this.locale).select(count) : 'other';
427
+ if (isObject(translation)) {
405
428
  if (preferredForm in translation) {
406
429
  return preferredForm;
407
430
  } else if ('other' in translation) {
@@ -411,132 +434,7 @@ class I18n {
411
434
  }
412
435
  throw new Error(`i18n: Plural form ".other" is required for "${this.locale}" locale`);
413
436
  }
414
- selectPluralFormUsingFallbackRules(count) {
415
- count = Math.abs(Math.floor(count));
416
- const ruleset = this.getPluralRulesForLocale();
417
- if (ruleset) {
418
- return I18n.pluralRules[ruleset](count);
419
- }
420
- return 'other';
421
- }
422
- getPluralRulesForLocale() {
423
- const localeShort = this.locale.split('-')[0];
424
- for (const pluralRule in I18n.pluralRulesMap) {
425
- const languages = I18n.pluralRulesMap[pluralRule];
426
- if (languages.includes(this.locale) || languages.includes(localeShort)) {
427
- return pluralRule;
428
- }
429
- }
430
- }
431
437
  }
432
- I18n.pluralRulesMap = {
433
- arabic: ['ar'],
434
- chinese: ['my', 'zh', 'id', 'ja', 'jv', 'ko', 'ms', 'th', 'vi'],
435
- french: ['hy', 'bn', 'fr', 'gu', 'hi', 'fa', 'pa', 'zu'],
436
- german: ['af', 'sq', 'az', 'eu', 'bg', 'ca', 'da', 'nl', 'en', 'et', 'fi', 'ka', 'de', 'el', 'hu', 'lb', 'no', 'so', 'sw', 'sv', 'ta', 'te', 'tr', 'ur'],
437
- irish: ['ga'],
438
- russian: ['ru', 'uk'],
439
- scottish: ['gd'],
440
- spanish: ['pt-PT', 'it', 'es'],
441
- welsh: ['cy']
442
- };
443
- I18n.pluralRules = {
444
- arabic(n) {
445
- if (n === 0) {
446
- return 'zero';
447
- }
448
- if (n === 1) {
449
- return 'one';
450
- }
451
- if (n === 2) {
452
- return 'two';
453
- }
454
- if (n % 100 >= 3 && n % 100 <= 10) {
455
- return 'few';
456
- }
457
- if (n % 100 >= 11 && n % 100 <= 99) {
458
- return 'many';
459
- }
460
- return 'other';
461
- },
462
- chinese() {
463
- return 'other';
464
- },
465
- french(n) {
466
- return n === 0 || n === 1 ? 'one' : 'other';
467
- },
468
- german(n) {
469
- return n === 1 ? 'one' : 'other';
470
- },
471
- irish(n) {
472
- if (n === 1) {
473
- return 'one';
474
- }
475
- if (n === 2) {
476
- return 'two';
477
- }
478
- if (n >= 3 && n <= 6) {
479
- return 'few';
480
- }
481
- if (n >= 7 && n <= 10) {
482
- return 'many';
483
- }
484
- return 'other';
485
- },
486
- russian(n) {
487
- const lastTwo = n % 100;
488
- const last = lastTwo % 10;
489
- if (last === 1 && lastTwo !== 11) {
490
- return 'one';
491
- }
492
- if (last >= 2 && last <= 4 && !(lastTwo >= 12 && lastTwo <= 14)) {
493
- return 'few';
494
- }
495
- if (last === 0 || last >= 5 && last <= 9 || lastTwo >= 11 && lastTwo <= 14) {
496
- return 'many';
497
- }
498
- return 'other';
499
- },
500
- scottish(n) {
501
- if (n === 1 || n === 11) {
502
- return 'one';
503
- }
504
- if (n === 2 || n === 12) {
505
- return 'two';
506
- }
507
- if (n >= 3 && n <= 10 || n >= 13 && n <= 19) {
508
- return 'few';
509
- }
510
- return 'other';
511
- },
512
- spanish(n) {
513
- if (n === 1) {
514
- return 'one';
515
- }
516
- if (n % 1000000 === 0 && n !== 0) {
517
- return 'many';
518
- }
519
- return 'other';
520
- },
521
- welsh(n) {
522
- if (n === 0) {
523
- return 'zero';
524
- }
525
- if (n === 1) {
526
- return 'one';
527
- }
528
- if (n === 2) {
529
- return 'two';
530
- }
531
- if (n === 3) {
532
- return 'few';
533
- }
534
- if (n === 6) {
535
- return 'many';
536
- }
537
- return 'other';
538
- }
539
- };
540
438
 
541
439
  /**
542
440
  * Accordion component
@@ -737,11 +635,11 @@ class Accordion extends ConfigurableComponent {
737
635
  const ariaLabelParts = [];
738
636
  const $headingText = $section.querySelector(`.${this.sectionHeadingTextClass}`);
739
637
  if ($headingText) {
740
- ariaLabelParts.push(`${$headingText.textContent}`.trim());
638
+ ariaLabelParts.push($headingText.textContent.trim());
741
639
  }
742
640
  const $summary = $section.querySelector(`.${this.sectionSummaryClass}`);
743
641
  if ($summary) {
744
- ariaLabelParts.push(`${$summary.textContent}`.trim());
642
+ ariaLabelParts.push($summary.textContent.trim());
745
643
  }
746
644
  const ariaLabelMessage = expanded ? this.i18n.t('hideSectionAriaLabel') : this.i18n.t('showSectionAriaLabel');
747
645
  ariaLabelParts.push(ariaLabelMessage);
@@ -794,7 +692,7 @@ class Accordion extends ConfigurableComponent {
794
692
  if (id) {
795
693
  try {
796
694
  window.sessionStorage.setItem(id, isExpanded.toString());
797
- } catch (exception) {}
695
+ } catch (_unused) {}
798
696
  }
799
697
  }
800
698
  setInitialState($section) {
@@ -808,7 +706,7 @@ class Accordion extends ConfigurableComponent {
808
706
  if (state !== null) {
809
707
  this.setExpanded(state === 'true', $section);
810
708
  }
811
- } catch (exception) {}
709
+ } catch (_unused2) {}
812
710
  }
813
711
  }
814
712
  getButtonPunctuationEl() {
@@ -982,6 +880,7 @@ class CharacterCount extends ConfigurableComponent {
982
880
  var _ref, _this$config$maxwords;
983
881
  super($root, config);
984
882
  this.$textarea = void 0;
883
+ this.count = 0;
985
884
  this.$visibleCountMessage = void 0;
986
885
  this.$screenReaderCountMessage = void 0;
987
886
  this.lastInputTimestamp = null;
@@ -1017,7 +916,7 @@ class CharacterCount extends ConfigurableComponent {
1017
916
  });
1018
917
  }
1019
918
  this.$errorMessage = this.$root.querySelector('.govuk-error-message');
1020
- if (`${$textareaDescription.textContent}`.match(/^\s*$/)) {
919
+ if ($textareaDescription.textContent.match(/^\s*$/)) {
1021
920
  $textareaDescription.textContent = this.i18n.t('textareaDescription', {
1022
921
  count: this.maxLength
1023
922
  });
@@ -1037,15 +936,22 @@ class CharacterCount extends ConfigurableComponent {
1037
936
  $textareaDescription.classList.add('govuk-visually-hidden');
1038
937
  this.$textarea.removeAttribute('maxlength');
1039
938
  this.bindChangeEvents();
1040
- window.addEventListener('pageshow', () => this.updateCountMessage());
939
+ window.addEventListener('pageshow', () => {
940
+ if (this.$textarea.value !== this.$textarea.textContent) {
941
+ this.updateCount();
942
+ this.updateCountMessage();
943
+ }
944
+ });
945
+ this.updateCount();
1041
946
  this.updateCountMessage();
1042
947
  }
1043
948
  bindChangeEvents() {
1044
- this.$textarea.addEventListener('keyup', () => this.handleKeyUp());
949
+ this.$textarea.addEventListener('input', () => this.handleInput());
1045
950
  this.$textarea.addEventListener('focus', () => this.handleFocus());
1046
951
  this.$textarea.addEventListener('blur', () => this.handleBlur());
1047
952
  }
1048
- handleKeyUp() {
953
+ handleInput() {
954
+ this.updateCount();
1049
955
  this.updateVisibleCountMessage();
1050
956
  this.lastInputTimestamp = Date.now();
1051
957
  }
@@ -1072,7 +978,7 @@ class CharacterCount extends ConfigurableComponent {
1072
978
  this.updateScreenReaderCountMessage();
1073
979
  }
1074
980
  updateVisibleCountMessage() {
1075
- const remainingNumber = this.maxLength - this.count(this.$textarea.value);
981
+ const remainingNumber = this.maxLength - this.count;
1076
982
  const isError = remainingNumber < 0;
1077
983
  this.$visibleCountMessage.classList.toggle('govuk-character-count__message--disabled', !this.isOverThreshold());
1078
984
  if (!this.$errorMessage) {
@@ -1090,16 +996,18 @@ class CharacterCount extends ConfigurableComponent {
1090
996
  }
1091
997
  this.$screenReaderCountMessage.textContent = this.getCountMessage();
1092
998
  }
1093
- count(text) {
999
+ updateCount() {
1000
+ const text = this.$textarea.value;
1094
1001
  if (this.config.maxwords) {
1095
1002
  var _text$match;
1096
1003
  const tokens = (_text$match = text.match(/\S+/g)) != null ? _text$match : [];
1097
- return tokens.length;
1004
+ this.count = tokens.length;
1005
+ return;
1098
1006
  }
1099
- return text.length;
1007
+ this.count = text.length;
1100
1008
  }
1101
1009
  getCountMessage() {
1102
- const remainingNumber = this.maxLength - this.count(this.$textarea.value);
1010
+ const remainingNumber = this.maxLength - this.count;
1103
1011
  const countType = this.config.maxwords ? 'words' : 'characters';
1104
1012
  return this.formatCountMessage(remainingNumber, countType);
1105
1013
  }
@@ -1116,7 +1024,7 @@ class CharacterCount extends ConfigurableComponent {
1116
1024
  if (!this.config.threshold) {
1117
1025
  return true;
1118
1026
  }
1119
- const currentLength = this.count(this.$textarea.value);
1027
+ const currentLength = this.count;
1120
1028
  const maxLength = this.maxLength;
1121
1029
  const thresholdValue = maxLength * this.config.threshold / 100;
1122
1030
  return thresholdValue <= currentLength;
@@ -1377,7 +1285,7 @@ class ErrorSummary extends ConfigurableComponent {
1377
1285
  if (!($target instanceof HTMLAnchorElement)) {
1378
1286
  return false;
1379
1287
  }
1380
- const inputId = getFragmentFromUrl($target.href);
1288
+ const inputId = $target.hash.replace('#', '');
1381
1289
  if (!inputId) {
1382
1290
  return false;
1383
1291
  }
@@ -1690,7 +1598,6 @@ class FileUpload extends ConfigurableComponent {
1690
1598
  throw new ElementError(formatErrorMessage(FileUpload, 'File input (`<input type="file">`) attribute (`type`) is not `file`'));
1691
1599
  }
1692
1600
  this.$input = $input;
1693
- this.$input.setAttribute('hidden', 'true');
1694
1601
  if (!this.$input.id) {
1695
1602
  throw new ElementError({
1696
1603
  component: FileUpload,
@@ -1706,6 +1613,7 @@ class FileUpload extends ConfigurableComponent {
1706
1613
  $label.id = `${this.id}-label`;
1707
1614
  }
1708
1615
  this.$input.id = `${this.id}-input`;
1616
+ this.$input.setAttribute('hidden', 'true');
1709
1617
  const $button = document.createElement('button');
1710
1618
  $button.classList.add('govuk-file-upload-button');
1711
1619
  $button.type = 'button';
@@ -1772,7 +1680,7 @@ class FileUpload extends ConfigurableComponent {
1772
1680
  if (this.$button.disabled) return;
1773
1681
  if (event.target instanceof Node) {
1774
1682
  if (this.$root.contains(event.target)) {
1775
- if (event.dataTransfer && isContainingFiles(event.dataTransfer)) {
1683
+ if (event.dataTransfer && this.canDrop(event.dataTransfer)) {
1776
1684
  if (!this.$button.classList.contains('govuk-file-upload-button--dragging')) {
1777
1685
  this.showDraggingState();
1778
1686
  this.$announcements.innerText = this.i18n.t('enteredDropZone');
@@ -1794,12 +1702,30 @@ class FileUpload extends ConfigurableComponent {
1794
1702
  }
1795
1703
  onDrop(event) {
1796
1704
  event.preventDefault();
1797
- if (event.dataTransfer && isContainingFiles(event.dataTransfer)) {
1705
+ if (event.dataTransfer && this.canFillInput(event.dataTransfer)) {
1798
1706
  this.$input.files = event.dataTransfer.files;
1799
1707
  this.$input.dispatchEvent(new CustomEvent('change'));
1800
1708
  this.hideDraggingState();
1801
1709
  }
1802
1710
  }
1711
+ canFillInput(dataTransfer) {
1712
+ return this.matchesInputCapacity(dataTransfer.files.length);
1713
+ }
1714
+ canDrop(dataTransfer) {
1715
+ if (dataTransfer.items.length) {
1716
+ return this.matchesInputCapacity(countFileItems(dataTransfer.items));
1717
+ }
1718
+ if (dataTransfer.types.length) {
1719
+ return dataTransfer.types.includes('Files');
1720
+ }
1721
+ return true;
1722
+ }
1723
+ matchesInputCapacity(numberOfFiles) {
1724
+ if (this.$input.multiple) {
1725
+ return numberOfFiles > 0;
1726
+ }
1727
+ return numberOfFiles === 1;
1728
+ }
1803
1729
  onChange() {
1804
1730
  const fileCount = this.$input.files.length;
1805
1731
  if (fileCount === 0) {
@@ -1846,6 +1772,13 @@ class FileUpload extends ConfigurableComponent {
1846
1772
  this.$root.classList.toggle('govuk-drop-zone--disabled', this.$button.disabled);
1847
1773
  }
1848
1774
  }
1775
+
1776
+ /**
1777
+ * Counts the number of `DataTransferItem` whose kind is `file`
1778
+ *
1779
+ * @param {DataTransferItemList} list - The list
1780
+ * @returns {number} - The number of items whose kind is `file` in the list
1781
+ */
1849
1782
  FileUpload.moduleName = 'govuk-file-upload';
1850
1783
  FileUpload.defaults = Object.freeze({
1851
1784
  i18n: {
@@ -1867,10 +1800,14 @@ FileUpload.schema = Object.freeze({
1867
1800
  }
1868
1801
  }
1869
1802
  });
1870
- function isContainingFiles(dataTransfer) {
1871
- const hasNoTypesInfo = dataTransfer.types.length === 0;
1872
- const isDraggingFiles = dataTransfer.types.some(type => type === 'Files');
1873
- return hasNoTypesInfo || isDraggingFiles;
1803
+ function countFileItems(list) {
1804
+ let result = 0;
1805
+ for (let i = 0; i < list.length; i++) {
1806
+ if (list[i].kind === 'file') {
1807
+ result++;
1808
+ }
1809
+ }
1810
+ return result;
1874
1811
  }
1875
1812
 
1876
1813
  /**
@@ -1908,89 +1845,6 @@ function isContainingFiles(dataTransfer) {
1908
1845
  * @import { TranslationPluralForms } from '../../i18n.mjs'
1909
1846
  */
1910
1847
 
1911
- /**
1912
- * Header component
1913
- *
1914
- * @preserve
1915
- */
1916
- class Header extends Component {
1917
- /**
1918
- * Apply a matchMedia for desktop which will trigger a state sync if the
1919
- * browser viewport moves between states.
1920
- *
1921
- * @param {Element | null} $root - HTML element to use for header
1922
- */
1923
- constructor($root) {
1924
- super($root);
1925
- this.$menuButton = void 0;
1926
- this.$menu = void 0;
1927
- this.menuIsOpen = false;
1928
- this.mql = null;
1929
- const $menuButton = this.$root.querySelector('.govuk-js-header-toggle');
1930
- if (!$menuButton) {
1931
- return this;
1932
- }
1933
- this.$root.classList.add('govuk-header--with-js-navigation');
1934
- const menuId = $menuButton.getAttribute('aria-controls');
1935
- if (!menuId) {
1936
- throw new ElementError({
1937
- component: Header,
1938
- identifier: 'Navigation button (`<button class="govuk-js-header-toggle">`) attribute (`aria-controls`)'
1939
- });
1940
- }
1941
- const $menu = document.getElementById(menuId);
1942
- if (!$menu) {
1943
- throw new ElementError({
1944
- component: Header,
1945
- element: $menu,
1946
- identifier: `Navigation (\`<ul id="${menuId}">\`)`
1947
- });
1948
- }
1949
- this.$menu = $menu;
1950
- this.$menuButton = $menuButton;
1951
- this.setupResponsiveChecks();
1952
- this.$menuButton.addEventListener('click', () => this.handleMenuButtonClick());
1953
- }
1954
- setupResponsiveChecks() {
1955
- const breakpoint = getBreakpoint('desktop');
1956
- if (!breakpoint.value) {
1957
- throw new ElementError({
1958
- component: Header,
1959
- identifier: `CSS custom property (\`${breakpoint.property}\`) on pseudo-class \`:root\``
1960
- });
1961
- }
1962
- this.mql = window.matchMedia(`(min-width: ${breakpoint.value})`);
1963
- if ('addEventListener' in this.mql) {
1964
- this.mql.addEventListener('change', () => this.checkMode());
1965
- } else {
1966
- this.mql.addListener(() => this.checkMode());
1967
- }
1968
- this.checkMode();
1969
- }
1970
- checkMode() {
1971
- if (!this.mql || !this.$menu || !this.$menuButton) {
1972
- return;
1973
- }
1974
- if (this.mql.matches) {
1975
- this.$menu.removeAttribute('hidden');
1976
- this.$menuButton.setAttribute('hidden', '');
1977
- } else {
1978
- this.$menuButton.removeAttribute('hidden');
1979
- this.$menuButton.setAttribute('aria-expanded', this.menuIsOpen.toString());
1980
- if (this.menuIsOpen) {
1981
- this.$menu.removeAttribute('hidden');
1982
- } else {
1983
- this.$menu.setAttribute('hidden', '');
1984
- }
1985
- }
1986
- }
1987
- handleMenuButtonClick() {
1988
- this.menuIsOpen = !this.menuIsOpen;
1989
- this.checkMode();
1990
- }
1991
- }
1992
- Header.moduleName = 'govuk-header';
1993
-
1994
1848
  /**
1995
1849
  * Notification Banner component
1996
1850
  *
@@ -2322,9 +2176,9 @@ class ServiceNavigation extends Component {
2322
2176
  }
2323
2177
  if (this.mql.matches) {
2324
2178
  this.$menu.removeAttribute('hidden');
2325
- this.$menuButton.setAttribute('hidden', '');
2179
+ setAttributes(this.$menuButton, attributesForHidingButton);
2326
2180
  } else {
2327
- this.$menuButton.removeAttribute('hidden');
2181
+ removeAttributes(this.$menuButton, Object.keys(attributesForHidingButton));
2328
2182
  this.$menuButton.setAttribute('aria-expanded', this.menuIsOpen.toString());
2329
2183
  if (this.menuIsOpen) {
2330
2184
  this.$menu.removeAttribute('hidden');
@@ -2339,6 +2193,34 @@ class ServiceNavigation extends Component {
2339
2193
  }
2340
2194
  }
2341
2195
  ServiceNavigation.moduleName = 'govuk-service-navigation';
2196
+ const attributesForHidingButton = {
2197
+ hidden: '',
2198
+ 'aria-hidden': 'true'
2199
+ };
2200
+
2201
+ /**
2202
+ * Sets a group of attributes on the given element
2203
+ *
2204
+ * @param {Element} $element - The element to set the attribute on
2205
+ * @param {{[attributeName: string]: string}} attributes - The attributes to set
2206
+ */
2207
+ function setAttributes($element, attributes) {
2208
+ for (const attributeName in attributes) {
2209
+ $element.setAttribute(attributeName, attributes[attributeName]);
2210
+ }
2211
+ }
2212
+
2213
+ /**
2214
+ * Removes a list of attributes from the given element
2215
+ *
2216
+ * @param {Element} $element - The element to remove the attributes from
2217
+ * @param {string[]} attributeNames - The names of the attributes to remove
2218
+ */
2219
+ function removeAttributes($element, attributeNames) {
2220
+ for (const attributeName of attributeNames) {
2221
+ $element.removeAttribute(attributeName);
2222
+ }
2223
+ }
2342
2224
 
2343
2225
  /**
2344
2226
  * Skip link component
@@ -2358,16 +2240,10 @@ class SkipLink extends Component {
2358
2240
  super($root);
2359
2241
  const hash = this.$root.hash;
2360
2242
  const href = (_this$$root$getAttrib = this.$root.getAttribute('href')) != null ? _this$$root$getAttrib : '';
2361
- let url;
2362
- try {
2363
- url = new window.URL(this.$root.href);
2364
- } catch (error) {
2365
- throw new ElementError(`Skip link: Target link (\`href="${href}"\`) is invalid`);
2366
- }
2367
- if (url.origin !== window.location.origin || url.pathname !== window.location.pathname) {
2243
+ if (this.$root.origin !== window.location.origin || this.$root.pathname !== window.location.pathname) {
2368
2244
  return;
2369
2245
  }
2370
- const linkedElementId = getFragmentFromUrl(hash);
2246
+ const linkedElementId = hash.replace('#', '');
2371
2247
  if (!linkedElementId) {
2372
2248
  throw new ElementError(`Skip link: Target link (\`href="${href}"\`) has no hash fragment`);
2373
2249
  }
@@ -2523,7 +2399,7 @@ class Tabs extends Component {
2523
2399
  return this.$root.querySelector(`a.govuk-tabs__tab[href="${hash}"]`);
2524
2400
  }
2525
2401
  setAttributes($tab) {
2526
- const panelId = getFragmentFromUrl($tab.href);
2402
+ const panelId = $tab.hash.replace('#', '');
2527
2403
  if (!panelId) {
2528
2404
  return;
2529
2405
  }
@@ -2627,7 +2503,7 @@ class Tabs extends Component {
2627
2503
  this.createHistoryEntry($previousTab);
2628
2504
  }
2629
2505
  getPanel($tab) {
2630
- const panelId = getFragmentFromUrl($tab.href);
2506
+ const panelId = $tab.hash.replace('#', '');
2631
2507
  if (!panelId) {
2632
2508
  return null;
2633
2509
  }
@@ -2675,28 +2551,34 @@ Tabs.moduleName = 'govuk-tabs';
2675
2551
  * Use the `data-module` attributes to find, instantiate and init all of the
2676
2552
  * components provided as part of GOV.UK Frontend.
2677
2553
  *
2678
- * @param {Config & { scope?: Element, onError?: OnErrorCallback<CompatibleClass> }} [config] - Config for all components (with optional scope)
2554
+ * @param {Config | Element | Document | null} [scopeOrConfig] - Scope of the document to search within or config for all components (with optional scope)
2679
2555
  */
2680
- function initAll(config) {
2681
- var _config$scope;
2682
- config = typeof config !== 'undefined' ? config : {};
2683
- if (!isSupported()) {
2684
- if (config.onError) {
2685
- config.onError(new SupportError(), {
2556
+ function initAll(scopeOrConfig = {}) {
2557
+ const config = isObject(scopeOrConfig) ? scopeOrConfig : {};
2558
+ const options = normaliseOptions(scopeOrConfig);
2559
+ try {
2560
+ if (!isSupported()) {
2561
+ throw new SupportError();
2562
+ }
2563
+ if (options.scope === null) {
2564
+ throw new ElementError({
2565
+ element: options.scope,
2566
+ identifier: 'GOV.UK Frontend scope element (`$scope`)'
2567
+ });
2568
+ }
2569
+ } catch (error) {
2570
+ if (options.onError) {
2571
+ options.onError(error, {
2686
2572
  config
2687
2573
  });
2688
2574
  } else {
2689
- console.log(new SupportError());
2575
+ console.log(error);
2690
2576
  }
2691
2577
  return;
2692
2578
  }
2693
- const components = [[Accordion, config.accordion], [Button, config.button], [CharacterCount, config.characterCount], [Checkboxes], [ErrorSummary, config.errorSummary], [ExitThisPage, config.exitThisPage], [FileUpload, config.fileUpload], [Header], [NotificationBanner, config.notificationBanner], [PasswordInput, config.passwordInput], [Radios], [ServiceNavigation], [SkipLink], [Tabs]];
2694
- const options = {
2695
- scope: (_config$scope = config.scope) != null ? _config$scope : document,
2696
- onError: config.onError
2697
- };
2698
- components.forEach(([Component, config]) => {
2699
- createAll(Component, config, options);
2579
+ const components = [[Accordion, config.accordion], [Button, config.button], [CharacterCount, config.characterCount], [Checkboxes], [ErrorSummary, config.errorSummary], [ExitThisPage, config.exitThisPage], [FileUpload, config.fileUpload], [NotificationBanner, config.notificationBanner], [PasswordInput, config.passwordInput], [Radios], [ServiceNavigation], [SkipLink], [Tabs]];
2580
+ components.forEach(([Component, componentConfig]) => {
2581
+ createAll(Component, componentConfig, options);
2700
2582
  });
2701
2583
  }
2702
2584
 
@@ -2712,42 +2594,42 @@ function initAll(config) {
2712
2594
  * @template {CompatibleClass} ComponentClass
2713
2595
  * @param {ComponentClass} Component - class of the component to create
2714
2596
  * @param {ComponentConfig<ComponentClass>} [config] - Config supplied to component
2715
- * @param {OnErrorCallback<ComponentClass> | Element | Document | CreateAllOptions<ComponentClass> } [createAllOptions] - options for createAll including scope of the document to search within and callback function if error throw by component on init
2597
+ * @param {OnErrorCallback<ComponentClass> | Element | Document | null | CreateAllOptions<ComponentClass>} [scopeOrOptions] - options for createAll including scope of the document to search within and callback function if error throw by component on init
2716
2598
  * @returns {Array<InstanceType<ComponentClass>>} - array of instantiated components
2717
2599
  */
2718
- function createAll(Component, config, createAllOptions) {
2719
- let $scope = document;
2720
- let onError;
2721
- if (typeof createAllOptions === 'object') {
2722
- var _createAllOptions$sco;
2723
- createAllOptions = createAllOptions;
2724
- $scope = (_createAllOptions$sco = createAllOptions.scope) != null ? _createAllOptions$sco : $scope;
2725
- onError = createAllOptions.onError;
2726
- }
2727
- if (typeof createAllOptions === 'function') {
2728
- onError = createAllOptions;
2729
- }
2730
- if (createAllOptions instanceof HTMLElement) {
2731
- $scope = createAllOptions;
2732
- }
2733
- const $elements = $scope.querySelectorAll(`[data-module="${Component.moduleName}"]`);
2734
- if (!isSupported()) {
2735
- if (onError) {
2736
- onError(new SupportError(), {
2600
+ function createAll(Component, config, scopeOrOptions) {
2601
+ let $elements;
2602
+ const options = normaliseOptions(scopeOrOptions);
2603
+ try {
2604
+ var _options$scope;
2605
+ if (!isSupported()) {
2606
+ throw new SupportError();
2607
+ }
2608
+ if (options.scope === null) {
2609
+ throw new ElementError({
2610
+ element: options.scope,
2611
+ component: Component,
2612
+ identifier: 'Scope element (`$scope`)'
2613
+ });
2614
+ }
2615
+ $elements = (_options$scope = options.scope) == null ? void 0 : _options$scope.querySelectorAll(`[data-module="${Component.moduleName}"]`);
2616
+ } catch (error) {
2617
+ if (options.onError) {
2618
+ options.onError(error, {
2737
2619
  component: Component,
2738
2620
  config
2739
2621
  });
2740
2622
  } else {
2741
- console.log(new SupportError());
2623
+ console.log(error);
2742
2624
  }
2743
2625
  return [];
2744
2626
  }
2745
- return Array.from($elements).map($element => {
2627
+ return Array.from($elements != null ? $elements : []).map($element => {
2746
2628
  try {
2747
2629
  return typeof config !== 'undefined' ? new Component($element, config) : new Component($element);
2748
2630
  } catch (error) {
2749
- if (onError) {
2750
- onError(error, {
2631
+ if (options.onError) {
2632
+ options.onError(error, {
2751
2633
  element: $element,
2752
2634
  component: Component,
2753
2635
  config
@@ -2766,6 +2648,8 @@ function createAll(Component, config, createAllOptions) {
2766
2648
  * Config for all components via `initAll()`
2767
2649
  *
2768
2650
  * @typedef {object} Config
2651
+ * @property {Element | Document | null} [scope] - Scope of the document to search within
2652
+ * @property {OnErrorCallback<CompatibleClass>} [onError] - Initialisation error callback
2769
2653
  * @property {AccordionConfig} [accordion] - Accordion config
2770
2654
  * @property {ButtonConfig} [button] - Button config
2771
2655
  * @property {CharacterCountConfig} [characterCount] - Character Count config
@@ -2790,7 +2674,7 @@ function createAll(Component, config, createAllOptions) {
2790
2674
  /**
2791
2675
  * Component config keys, e.g. `accordion` and `characterCount`
2792
2676
  *
2793
- * @typedef {keyof Config} ConfigKey
2677
+ * @typedef {keyof Omit<Config, 'scope' | 'onError'>} ConfigKey
2794
2678
  */
2795
2679
  /**
2796
2680
  * @template {CompatibleClass} ComponentClass
@@ -2801,7 +2685,7 @@ function createAll(Component, config, createAllOptions) {
2801
2685
  * @typedef {object} ErrorContext
2802
2686
  * @property {Element} [element] - Element used for component module initialisation
2803
2687
  * @property {ComponentClass} [component] - Class of component
2804
- * @property {ComponentConfig<ComponentClass>} config - Config supplied to component
2688
+ * @property {Config | ComponentConfig<ComponentClass>} [config] - Config supplied to components
2805
2689
  */
2806
2690
  /**
2807
2691
  * @template {CompatibleClass} ComponentClass
@@ -2812,9 +2696,9 @@ function createAll(Component, config, createAllOptions) {
2812
2696
  /**
2813
2697
  * @template {CompatibleClass} ComponentClass
2814
2698
  * @typedef {object} CreateAllOptions
2815
- * @property {Element | Document} [scope] - scope of the document to search within
2699
+ * @property {Element | Document | null} [scope] - scope of the document to search within
2816
2700
  * @property {OnErrorCallback<ComponentClass>} [onError] - callback function if error throw by component on init
2817
2701
  */
2818
2702
 
2819
- export { Accordion, Button, CharacterCount, Checkboxes, Component, ConfigurableComponent, ErrorSummary, ExitThisPage, FileUpload, Header, NotificationBanner, PasswordInput, Radios, ServiceNavigation, SkipLink, Tabs, createAll, initAll, isSupported, version };
2703
+ export { Accordion, Button, CharacterCount, Checkboxes, Component, ConfigurableComponent, ErrorSummary, ExitThisPage, FileUpload, NotificationBanner, PasswordInput, Radios, ServiceNavigation, SkipLink, Tabs, createAll, initAll, isSupported, version };
2820
2704
  //# sourceMappingURL=all.bundle.mjs.map