defra_ruby_template 6.4.0 → 6.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (180) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +73 -19
  3. data/Rakefile +10 -33
  4. data/lib/defra_ruby_template/version.rb +1 -1
  5. data/node_modules/govuk-frontend/dist/govuk/all.bundle.js +202 -137
  6. data/node_modules/govuk-frontend/dist/govuk/all.bundle.js.map +1 -1
  7. data/node_modules/govuk-frontend/dist/govuk/all.bundle.mjs +202 -137
  8. data/node_modules/govuk-frontend/dist/govuk/all.bundle.mjs.map +1 -1
  9. data/node_modules/govuk-frontend/dist/govuk/common/closest-attribute-value.mjs.map +1 -1
  10. data/node_modules/govuk-frontend/dist/govuk/common/configuration.mjs +5 -1
  11. data/node_modules/govuk-frontend/dist/govuk/common/configuration.mjs.map +1 -1
  12. data/node_modules/govuk-frontend/dist/govuk/common/create-element.mjs +13 -0
  13. data/node_modules/govuk-frontend/dist/govuk/common/create-element.mjs.map +1 -0
  14. data/node_modules/govuk-frontend/dist/govuk/common/govuk-frontend-version.mjs +1 -1
  15. data/node_modules/govuk-frontend/dist/govuk/common/govuk-frontend-version.mjs.map +1 -1
  16. data/node_modules/govuk-frontend/dist/govuk/common/index.mjs.map +1 -1
  17. data/node_modules/govuk-frontend/dist/govuk/component.mjs +2 -1
  18. data/node_modules/govuk-frontend/dist/govuk/component.mjs.map +1 -1
  19. data/node_modules/govuk-frontend/dist/govuk/components/_index.import.scss +2 -0
  20. data/node_modules/govuk-frontend/dist/govuk/components/_index.scss +2 -0
  21. data/node_modules/govuk-frontend/dist/govuk/components/accordion/accordion.bundle.js +87 -62
  22. data/node_modules/govuk-frontend/dist/govuk/components/accordion/accordion.bundle.js.map +1 -1
  23. data/node_modules/govuk-frontend/dist/govuk/components/accordion/accordion.bundle.mjs +87 -62
  24. data/node_modules/govuk-frontend/dist/govuk/components/accordion/accordion.bundle.mjs.map +1 -1
  25. data/node_modules/govuk-frontend/dist/govuk/components/accordion/accordion.mjs +60 -56
  26. data/node_modules/govuk-frontend/dist/govuk/components/accordion/accordion.mjs.map +1 -1
  27. data/node_modules/govuk-frontend/dist/govuk/components/button/button.bundle.js +17 -6
  28. data/node_modules/govuk-frontend/dist/govuk/components/button/button.bundle.js.map +1 -1
  29. data/node_modules/govuk-frontend/dist/govuk/components/button/button.bundle.mjs +17 -6
  30. data/node_modules/govuk-frontend/dist/govuk/components/button/button.bundle.mjs.map +1 -1
  31. data/node_modules/govuk-frontend/dist/govuk/components/button/button.mjs.map +1 -1
  32. data/node_modules/govuk-frontend/dist/govuk/components/character-count/character-count.bundle.js +90 -32
  33. data/node_modules/govuk-frontend/dist/govuk/components/character-count/character-count.bundle.js.map +1 -1
  34. data/node_modules/govuk-frontend/dist/govuk/components/character-count/character-count.bundle.mjs +90 -32
  35. data/node_modules/govuk-frontend/dist/govuk/components/character-count/character-count.bundle.mjs.map +1 -1
  36. data/node_modules/govuk-frontend/dist/govuk/components/character-count/character-count.mjs +64 -27
  37. data/node_modules/govuk-frontend/dist/govuk/components/character-count/character-count.mjs.map +1 -1
  38. data/node_modules/govuk-frontend/dist/govuk/components/character-count/fixtures.json +173 -6
  39. data/node_modules/govuk-frontend/dist/govuk/components/character-count/macro-options.json +13 -6
  40. data/node_modules/govuk-frontend/dist/govuk/components/character-count/template-with-count-type-characters-and-error-message.html +12 -0
  41. data/node_modules/govuk-frontend/dist/govuk/components/character-count/template-with-count-type-characters-and-threshold.html +9 -0
  42. data/node_modules/govuk-frontend/dist/govuk/components/character-count/template-with-count-type-characters-and-value.html +9 -0
  43. data/node_modules/govuk-frontend/dist/govuk/components/character-count/template-with-count-type-characters.html +9 -0
  44. data/node_modules/govuk-frontend/dist/govuk/components/character-count/template-with-count-type-length.html +9 -0
  45. data/node_modules/govuk-frontend/dist/govuk/components/character-count/template-with-count-type-words-and-error-message.html +12 -0
  46. data/node_modules/govuk-frontend/dist/govuk/components/character-count/template-with-count-type-words-and-threshold.html +9 -0
  47. data/node_modules/govuk-frontend/dist/govuk/components/character-count/template-with-count-type-words-and-value.html +9 -0
  48. data/node_modules/govuk-frontend/dist/govuk/components/character-count/template-with-count-type-words.html +9 -0
  49. data/node_modules/govuk-frontend/dist/govuk/components/character-count/template-with-maxwords.html +9 -0
  50. data/node_modules/govuk-frontend/dist/govuk/components/character-count/template.njk +10 -3
  51. data/node_modules/govuk-frontend/dist/govuk/components/checkboxes/checkboxes.bundle.js +12 -5
  52. data/node_modules/govuk-frontend/dist/govuk/components/checkboxes/checkboxes.bundle.js.map +1 -1
  53. data/node_modules/govuk-frontend/dist/govuk/components/checkboxes/checkboxes.bundle.mjs +12 -5
  54. data/node_modules/govuk-frontend/dist/govuk/components/checkboxes/checkboxes.bundle.mjs.map +1 -1
  55. data/node_modules/govuk-frontend/dist/govuk/components/checkboxes/checkboxes.mjs.map +1 -1
  56. data/node_modules/govuk-frontend/dist/govuk/components/cookie-banner/_mixin.scss +6 -0
  57. data/node_modules/govuk-frontend/dist/govuk/components/error-summary/error-summary.bundle.js +17 -6
  58. data/node_modules/govuk-frontend/dist/govuk/components/error-summary/error-summary.bundle.js.map +1 -1
  59. data/node_modules/govuk-frontend/dist/govuk/components/error-summary/error-summary.bundle.mjs +17 -6
  60. data/node_modules/govuk-frontend/dist/govuk/components/error-summary/error-summary.bundle.mjs.map +1 -1
  61. data/node_modules/govuk-frontend/dist/govuk/components/error-summary/error-summary.mjs.map +1 -1
  62. data/node_modules/govuk-frontend/dist/govuk/components/exit-this-page/exit-this-page.bundle.js +43 -18
  63. data/node_modules/govuk-frontend/dist/govuk/components/exit-this-page/exit-this-page.bundle.js.map +1 -1
  64. data/node_modules/govuk-frontend/dist/govuk/components/exit-this-page/exit-this-page.bundle.mjs +43 -18
  65. data/node_modules/govuk-frontend/dist/govuk/components/exit-this-page/exit-this-page.bundle.mjs.map +1 -1
  66. data/node_modules/govuk-frontend/dist/govuk/components/exit-this-page/exit-this-page.mjs +16 -12
  67. data/node_modules/govuk-frontend/dist/govuk/components/exit-this-page/exit-this-page.mjs.map +1 -1
  68. data/node_modules/govuk-frontend/dist/govuk/components/feedback/README.md +15 -0
  69. data/node_modules/govuk-frontend/dist/govuk/components/feedback/_feedback.import.scss +6 -0
  70. data/node_modules/govuk-frontend/dist/govuk/components/feedback/_index.import.scss +8 -0
  71. data/node_modules/govuk-frontend/dist/govuk/components/feedback/_index.scss +5 -0
  72. data/node_modules/govuk-frontend/dist/govuk/components/feedback/_mixin.scss +48 -0
  73. data/node_modules/govuk-frontend/dist/govuk/components/feedback/fixtures.json +95 -0
  74. data/node_modules/govuk-frontend/dist/govuk/components/feedback/macro-options.json +50 -0
  75. data/node_modules/govuk-frontend/dist/govuk/components/feedback/macro.njk +3 -0
  76. data/node_modules/govuk-frontend/dist/govuk/components/feedback/template-default.html +12 -0
  77. data/node_modules/govuk-frontend/dist/govuk/components/feedback/template-silly-example.html +19 -0
  78. data/node_modules/govuk-frontend/dist/govuk/components/feedback/template.njk +24 -0
  79. data/node_modules/govuk-frontend/dist/govuk/components/file-upload/file-upload.bundle.js +54 -30
  80. data/node_modules/govuk-frontend/dist/govuk/components/file-upload/file-upload.bundle.js.map +1 -1
  81. data/node_modules/govuk-frontend/dist/govuk/components/file-upload/file-upload.bundle.mjs +54 -30
  82. data/node_modules/govuk-frontend/dist/govuk/components/file-upload/file-upload.bundle.mjs.map +1 -1
  83. data/node_modules/govuk-frontend/dist/govuk/components/file-upload/file-upload.mjs +27 -24
  84. data/node_modules/govuk-frontend/dist/govuk/components/file-upload/file-upload.mjs.map +1 -1
  85. data/node_modules/govuk-frontend/dist/govuk/components/footer/_mixin.scss +6 -0
  86. data/node_modules/govuk-frontend/dist/govuk/components/language-navigation/README.md +15 -0
  87. data/node_modules/govuk-frontend/dist/govuk/components/language-navigation/_index.import.scss +8 -0
  88. data/node_modules/govuk-frontend/dist/govuk/components/language-navigation/_index.scss +6 -0
  89. data/node_modules/govuk-frontend/dist/govuk/components/language-navigation/_language-navigation.import.scss +6 -0
  90. data/node_modules/govuk-frontend/dist/govuk/components/language-navigation/_mixin.scss +68 -0
  91. data/node_modules/govuk-frontend/dist/govuk/components/language-navigation/fixtures.json +482 -0
  92. data/node_modules/govuk-frontend/dist/govuk/components/language-navigation/macro-options.json +88 -0
  93. data/node_modules/govuk-frontend/dist/govuk/components/language-navigation/macro.njk +3 -0
  94. data/node_modules/govuk-frontend/dist/govuk/components/language-navigation/template-default.html +12 -0
  95. data/node_modules/govuk-frontend/dist/govuk/components/language-navigation/template-inverse.html +12 -0
  96. data/node_modules/govuk-frontend/dist/govuk/components/language-navigation/template-with-language-description.html +12 -0
  97. data/node_modules/govuk-frontend/dist/govuk/components/language-navigation/template-with-large-amount-of-multiple-languages.html +99 -0
  98. data/node_modules/govuk-frontend/dist/govuk/components/language-navigation/template-with-mixed-text-directions.html +12 -0
  99. data/node_modules/govuk-frontend/dist/govuk/components/language-navigation/template-with-multiple-languages.html +24 -0
  100. data/node_modules/govuk-frontend/dist/govuk/components/language-navigation/template-with-translated-navigation-label.html +12 -0
  101. data/node_modules/govuk-frontend/dist/govuk/components/language-navigation/template.njk +33 -0
  102. data/node_modules/govuk-frontend/dist/govuk/components/notification-banner/notification-banner.bundle.js +17 -6
  103. data/node_modules/govuk-frontend/dist/govuk/components/notification-banner/notification-banner.bundle.js.map +1 -1
  104. data/node_modules/govuk-frontend/dist/govuk/components/notification-banner/notification-banner.bundle.mjs +17 -6
  105. data/node_modules/govuk-frontend/dist/govuk/components/notification-banner/notification-banner.bundle.mjs.map +1 -1
  106. data/node_modules/govuk-frontend/dist/govuk/components/notification-banner/notification-banner.mjs.map +1 -1
  107. data/node_modules/govuk-frontend/dist/govuk/components/panel/fixtures.json +13 -11
  108. data/node_modules/govuk-frontend/dist/govuk/components/panel/template-interruption-with-headings-content-and-lists.html +6 -1
  109. data/node_modules/govuk-frontend/dist/govuk/components/password-input/password-input.bundle.js +32 -9
  110. data/node_modules/govuk-frontend/dist/govuk/components/password-input/password-input.bundle.js.map +1 -1
  111. data/node_modules/govuk-frontend/dist/govuk/components/password-input/password-input.bundle.mjs +32 -9
  112. data/node_modules/govuk-frontend/dist/govuk/components/password-input/password-input.bundle.mjs.map +1 -1
  113. data/node_modules/govuk-frontend/dist/govuk/components/password-input/password-input.mjs +5 -3
  114. data/node_modules/govuk-frontend/dist/govuk/components/password-input/password-input.mjs.map +1 -1
  115. data/node_modules/govuk-frontend/dist/govuk/components/radios/radios.bundle.js +12 -5
  116. data/node_modules/govuk-frontend/dist/govuk/components/radios/radios.bundle.js.map +1 -1
  117. data/node_modules/govuk-frontend/dist/govuk/components/radios/radios.bundle.mjs +12 -5
  118. data/node_modules/govuk-frontend/dist/govuk/components/radios/radios.bundle.mjs.map +1 -1
  119. data/node_modules/govuk-frontend/dist/govuk/components/radios/radios.mjs.map +1 -1
  120. data/node_modules/govuk-frontend/dist/govuk/components/service-navigation/_mixin.scss +48 -3
  121. data/node_modules/govuk-frontend/dist/govuk/components/service-navigation/fixtures.json +121 -0
  122. data/node_modules/govuk-frontend/dist/govuk/components/service-navigation/macro-options.json +20 -0
  123. data/node_modules/govuk-frontend/dist/govuk/components/service-navigation/service-navigation.bundle.js +12 -5
  124. data/node_modules/govuk-frontend/dist/govuk/components/service-navigation/service-navigation.bundle.js.map +1 -1
  125. data/node_modules/govuk-frontend/dist/govuk/components/service-navigation/service-navigation.bundle.mjs +12 -5
  126. data/node_modules/govuk-frontend/dist/govuk/components/service-navigation/service-navigation.bundle.mjs.map +1 -1
  127. data/node_modules/govuk-frontend/dist/govuk/components/service-navigation/service-navigation.mjs.map +1 -1
  128. data/node_modules/govuk-frontend/dist/govuk/components/service-navigation/template-inverse-with-language-navigation.html +72 -0
  129. data/node_modules/govuk-frontend/dist/govuk/components/service-navigation/template-with-inline-end-slot.html +33 -0
  130. data/node_modules/govuk-frontend/dist/govuk/components/service-navigation/template-with-language-navigation.html +62 -0
  131. data/node_modules/govuk-frontend/dist/govuk/components/service-navigation/template-with-right-aligned-language-navigation.html +62 -0
  132. data/node_modules/govuk-frontend/dist/govuk/components/service-navigation/template.njk +8 -3
  133. data/node_modules/govuk-frontend/dist/govuk/components/skip-link/skip-link.bundle.js +14 -6
  134. data/node_modules/govuk-frontend/dist/govuk/components/skip-link/skip-link.bundle.js.map +1 -1
  135. data/node_modules/govuk-frontend/dist/govuk/components/skip-link/skip-link.bundle.mjs +14 -6
  136. data/node_modules/govuk-frontend/dist/govuk/components/skip-link/skip-link.bundle.mjs.map +1 -1
  137. data/node_modules/govuk-frontend/dist/govuk/components/skip-link/skip-link.mjs +2 -1
  138. data/node_modules/govuk-frontend/dist/govuk/components/skip-link/skip-link.mjs.map +1 -1
  139. data/node_modules/govuk-frontend/dist/govuk/components/tabs/tabs.bundle.js +12 -5
  140. data/node_modules/govuk-frontend/dist/govuk/components/tabs/tabs.bundle.js.map +1 -1
  141. data/node_modules/govuk-frontend/dist/govuk/components/tabs/tabs.bundle.mjs +12 -5
  142. data/node_modules/govuk-frontend/dist/govuk/components/tabs/tabs.bundle.mjs.map +1 -1
  143. data/node_modules/govuk-frontend/dist/govuk/components/tabs/tabs.mjs.map +1 -1
  144. data/node_modules/govuk-frontend/dist/govuk/custom-properties/_frontend-version.mixin.scss +1 -1
  145. data/node_modules/govuk-frontend/dist/govuk/custom-properties/_functional-colours.mixin.scss +1 -0
  146. data/node_modules/govuk-frontend/dist/govuk/errors/index.mjs +8 -5
  147. data/node_modules/govuk-frontend/dist/govuk/errors/index.mjs.map +1 -1
  148. data/node_modules/govuk-frontend/dist/govuk/govuk-frontend.min.css +2 -2
  149. data/node_modules/govuk-frontend/dist/govuk/govuk-frontend.min.css.map +1 -1
  150. data/node_modules/govuk-frontend/dist/govuk/govuk-frontend.min.js +1 -1
  151. data/node_modules/govuk-frontend/dist/govuk/govuk-frontend.min.js.map +1 -1
  152. data/node_modules/govuk-frontend/dist/govuk/helpers/_colour.scss +1 -1
  153. data/node_modules/govuk-frontend/dist/govuk/i18n.mjs.map +1 -1
  154. data/node_modules/govuk-frontend/dist/govuk/init.mjs +8 -8
  155. data/node_modules/govuk-frontend/dist/govuk/init.mjs.map +1 -1
  156. data/node_modules/govuk-frontend/dist/govuk/settings/_colours-organisations.scss +16 -2
  157. data/node_modules/govuk-frontend/govuk-prototype-kit.config.json +9 -1
  158. data/node_modules/govuk-frontend/package.json +9 -7
  159. data/vendor/assets/javascripts/defra_ruby_template.js +202 -137
  160. data/vendor/assets/stylesheets/components/_index.import.scss +2 -0
  161. data/vendor/assets/stylesheets/components/_index.scss +2 -0
  162. data/vendor/assets/stylesheets/components/cookie-banner/_mixin.scss +6 -0
  163. data/vendor/assets/stylesheets/components/feedback/_feedback.import.scss +6 -0
  164. data/vendor/assets/stylesheets/components/feedback/_index.import.scss +8 -0
  165. data/vendor/assets/stylesheets/components/feedback/_index.scss +5 -0
  166. data/vendor/assets/stylesheets/components/feedback/_mixin.scss +48 -0
  167. data/vendor/assets/stylesheets/components/footer/_mixin.scss +6 -0
  168. data/vendor/assets/stylesheets/components/language-navigation/_index.import.scss +8 -0
  169. data/vendor/assets/stylesheets/components/language-navigation/_index.scss +6 -0
  170. data/vendor/assets/stylesheets/components/language-navigation/_language-navigation.import.scss +6 -0
  171. data/vendor/assets/stylesheets/components/language-navigation/_mixin.scss +68 -0
  172. data/vendor/assets/stylesheets/components/service-navigation/_mixin.scss +48 -3
  173. data/vendor/assets/stylesheets/custom-properties/_frontend-version.mixin.scss +1 -1
  174. data/vendor/assets/stylesheets/custom-properties/_functional-colours.mixin.scss +1 -0
  175. data/vendor/assets/stylesheets/defra_ruby_template.scss +8 -30
  176. data/vendor/assets/stylesheets/govuk-frontend.min.css +2 -2
  177. data/vendor/assets/stylesheets/helpers/_colour.scss +1 -1
  178. data/vendor/assets/stylesheets/settings/_colours-organisations.scss +16 -2
  179. metadata +53 -3
  180. data/node_modules/govuk-frontend/dist/govuk/components/character-count/template-with-word-count.html +0 -9
@@ -23,6 +23,9 @@ function isArray(option) {
23
23
  function isObject(option) {
24
24
  return !!option && typeof option === 'object' && !isArray(option);
25
25
  }
26
+ function isScope($scope) {
27
+ return !!$scope && ($scope instanceof Element || $scope instanceof Document);
28
+ }
26
29
  function formatErrorMessage(Component, message) {
27
30
  return `${Component.moduleName}: ${message}`;
28
31
  }
@@ -41,11 +44,14 @@ class SupportError extends GOVUKFrontendError {
41
44
  /**
42
45
  * Checks if GOV.UK Frontend is supported on this page
43
46
  *
44
- * @param {HTMLElement | null} [$scope] - HTML element `<body>` checked for browser support
47
+ * @param {Element | Document | null | string} [scopeOrMessage] - HTML element `<body>` checked for browser support or support error message
45
48
  */
46
- constructor($scope = document.body) {
47
- const supportMessage = 'noModule' in HTMLScriptElement.prototype ? 'GOV.UK Frontend initialised without `<body class="govuk-frontend-supported">` from template `<script>` snippet' : 'GOV.UK Frontend is not supported in this browser';
48
- super($scope ? supportMessage : 'GOV.UK Frontend initialised without `<script type="module">`');
49
+ constructor(scopeOrMessage = document.body) {
50
+ let supportMessage = 'noModule' in HTMLScriptElement.prototype ? 'GOV.UK Frontend initialised without `<body class="govuk-frontend-supported">` from template `<script>` snippet' : 'GOV.UK Frontend is not supported in this browser';
51
+ if (!isScope(scopeOrMessage)) {
52
+ supportMessage = 'GOV.UK Frontend initialised without `<script type="module">`';
53
+ }
54
+ super(typeof scopeOrMessage === 'string' ? scopeOrMessage : supportMessage);
49
55
  this.name = 'SupportError';
50
56
  }
51
57
  }
@@ -80,6 +86,7 @@ class InitError extends GOVUKFrontendError {
80
86
  * @import { ComponentWithModuleName } from '../common/index.mjs'
81
87
  */
82
88
 
89
+ const _self = typeof globalThis !== 'undefined' ? globalThis : self;
83
90
  class Component {
84
91
  /**
85
92
  * Returns the root element of the component
@@ -133,7 +140,7 @@ class Component {
133
140
  /**
134
141
  * @typedef {typeof Component & ChildClass} ChildClassConstructor
135
142
  */
136
- Component.elementType = HTMLElement;
143
+ Component.elementType = _self.HTMLElement;
137
144
 
138
145
  /**
139
146
  * Radios component
@@ -1 +1 @@
1
- {"version":3,"file":"radios.bundle.mjs","sources":["../../../../src/govuk/common/index.mjs","../../../../src/govuk/errors/index.mjs","../../../../src/govuk/component.mjs","../../../../src/govuk/components/radios/radios.mjs"],"sourcesContent":["/**\n * Common helpers which do not require polyfill.\n *\n * IMPORTANT: If a helper require a polyfill, please isolate it in its own module\n * so that the polyfill can be properly tree-shaken and does not burden\n * the components that do not need that helper\n */\n\n/**\n * Get GOV.UK Frontend breakpoint value from CSS custom property\n *\n * @private\n * @param {string} name - Breakpoint name\n * @returns {{ property: string, value?: string }} Breakpoint object\n */\nexport function getBreakpoint(name) {\n const property = `--govuk-breakpoint-${name}`\n\n // Get value from `<html>` with breakpoints on CSS :root\n const value = window\n .getComputedStyle(document.documentElement)\n .getPropertyValue(property)\n\n return {\n property,\n value: value || undefined\n }\n}\n\n/**\n * Move focus to element\n *\n * Sets tabindex to -1 to make the element programmatically focusable,\n * but removes it on blur as the element doesn't need to be focused again.\n *\n * @private\n * @template {HTMLElement} FocusElement\n * @param {FocusElement} $element - HTML element\n * @param {object} [options] - Handler options\n * @param {function(this: FocusElement): void} [options.onBeforeFocus] - Callback before focus\n * @param {function(this: FocusElement): void} [options.onBlur] - Callback on blur\n */\nexport function setFocus($element, options = {}) {\n const isFocusable = $element.getAttribute('tabindex')\n\n if (!isFocusable) {\n $element.setAttribute('tabindex', '-1')\n }\n\n /**\n * Handle element focus\n */\n function onFocus() {\n $element.addEventListener('blur', onBlur, { once: true })\n }\n\n /**\n * Handle element blur\n */\n function onBlur() {\n options.onBlur?.call($element)\n\n if (!isFocusable) {\n $element.removeAttribute('tabindex')\n }\n }\n\n // Add listener to reset element on blur, after focus\n $element.addEventListener('focus', onFocus, { once: true })\n\n // Focus element\n options.onBeforeFocus?.call($element)\n $element.focus()\n}\n\n/**\n * Checks if component is already initialised\n *\n * @internal\n * @param {Element} $root - HTML element to be checked\n * @param {string} moduleName - name of component module\n * @returns {boolean} Whether component is already initialised\n */\nexport function isInitialised($root, moduleName) {\n return (\n $root instanceof HTMLElement &&\n $root.hasAttribute(`data-${moduleName}-init`)\n )\n}\n\n/**\n * Checks if GOV.UK Frontend is supported on this page\n *\n * Some browsers will load and run our JavaScript but GOV.UK Frontend\n * won't be supported.\n *\n * @param {HTMLElement | null} [$scope] - (internal) `<body>` HTML element checked for browser support\n * @returns {boolean} Whether GOV.UK Frontend is supported on this page\n */\nexport function isSupported($scope = document.body) {\n if (!$scope) {\n return false\n }\n\n return $scope.classList.contains('govuk-frontend-supported')\n}\n\n/**\n * Check for an array\n *\n * @internal\n * @param {unknown} option - Option to check\n * @returns {boolean} Whether the option is an array\n */\nfunction isArray(option) {\n return Array.isArray(option)\n}\n\n/**\n * Check for an object\n *\n * @internal\n * @template {Partial<Record<keyof ObjectType, unknown>>} ObjectType\n * @param {unknown | ObjectType} option - Option to check\n * @returns {option is ObjectType} Whether the option is an object\n */\nexport function isObject(option) {\n return !!option && typeof option === 'object' && !isArray(option)\n}\n\n/**\n * Check for valid scope\n *\n * @internal\n * @template {Element | Document} ScopeType\n * @param {unknown | ScopeType} $scope - Scope of the document to search within\n * @returns {$scope is ScopeType} Whether the scope can be queried\n */\nexport function isScope($scope) {\n return !!$scope && ($scope instanceof Element || $scope instanceof Document)\n}\n\n/**\n * Format error message\n *\n * @internal\n * @param {ComponentWithModuleName} Component - Component that threw the error\n * @param {string} message - Error message\n * @returns {string} - Formatted error message\n */\nexport function formatErrorMessage(Component, message) {\n return `${Component.moduleName}: ${message}`\n}\n\n/* eslint-disable jsdoc/valid-types --\n * `{new(...args: any[] ): object}` is not recognised as valid\n * https://github.com/gajus/eslint-plugin-jsdoc/issues/145#issuecomment-1308722878\n * https://github.com/jsdoc-type-pratt-parser/jsdoc-type-pratt-parser/issues/131\n **/\n\n/**\n * @typedef ComponentWithModuleName\n * @property {string} moduleName - Name of the component\n */\n\n/* eslint-enable jsdoc/valid-types */\n","import { formatErrorMessage, isObject } from '../common/index.mjs'\n\n/**\n * GOV.UK Frontend error\n *\n * A base class for `Error`s thrown by GOV.UK Frontend.\n *\n * It is meant to be extended into specific types of errors\n * to be thrown by our code.\n *\n * @example\n * ```js\n * class MissingRootError extends GOVUKFrontendError {\n * // Setting an explicit name is important as extending the class will not\n * // set a new `name` on the subclass. The `name` property is important\n * // to ensure intelligible error names even if the class name gets\n * // mangled by a minifier\n * name = \"MissingRootError\"\n * }\n * ```\n * @virtual\n */\nexport class GOVUKFrontendError extends Error {\n name = 'GOVUKFrontendError'\n}\n\n/**\n * Indicates that GOV.UK Frontend is not supported\n */\nexport class SupportError extends GOVUKFrontendError {\n name = 'SupportError'\n\n /**\n * Checks if GOV.UK Frontend is supported on this page\n *\n * @param {HTMLElement | null} [$scope] - HTML element `<body>` checked for browser support\n */\n constructor($scope = document.body) {\n const supportMessage =\n 'noModule' in HTMLScriptElement.prototype\n ? 'GOV.UK Frontend initialised without `<body class=\"govuk-frontend-supported\">` from template `<script>` snippet'\n : 'GOV.UK Frontend is not supported in this browser'\n\n super(\n $scope\n ? supportMessage\n : 'GOV.UK Frontend initialised without `<script type=\"module\">`'\n )\n }\n}\n\n/**\n * Indicates that a component has received an illegal configuration\n */\nexport class ConfigError extends GOVUKFrontendError {\n name = 'ConfigError'\n}\n\n/**\n * Indicates an issue with an element (possibly `null` or `undefined`)\n */\nexport class ElementError extends GOVUKFrontendError {\n name = 'ElementError'\n\n /**\n * @internal\n * @overload\n * @param {string} message - Element error message\n */\n\n /**\n * @internal\n * @overload\n * @param {ElementErrorOptions} options - Element error options\n */\n\n /**\n * @internal\n * @param {string | ElementErrorOptions} messageOrOptions - Element error message or options\n */\n constructor(messageOrOptions) {\n let message = typeof messageOrOptions === 'string' ? messageOrOptions : ''\n\n // Build message from options\n if (isObject(messageOrOptions)) {\n const { component, identifier, element, expectedType } = messageOrOptions\n\n message = identifier\n\n // Append reason\n message += element\n ? ` is not of type ${expectedType ?? 'HTMLElement'}`\n : ' not found'\n\n // Prepend with module name (optional)\n if (component) {\n message = formatErrorMessage(component, message)\n }\n }\n\n super(message)\n }\n}\n\n/**\n * Indicates that a component is already initialised\n */\nexport class InitError extends GOVUKFrontendError {\n name = 'InitError'\n\n /**\n * @internal\n * @param {ComponentWithModuleName | string} componentOrMessage - name of the component module\n */\n constructor(componentOrMessage) {\n const message =\n typeof componentOrMessage === 'string'\n ? componentOrMessage\n : formatErrorMessage(\n componentOrMessage,\n `Root element (\\`$root\\`) already initialised`\n )\n\n super(message)\n }\n}\n\n/**\n * Element error options\n *\n * @internal\n * @typedef {object} ElementErrorOptions\n * @property {Element | Document | null} [element] - The element in error (optional)\n * @property {ComponentWithModuleName} [component] - Component throwing the error (optional)\n * @property {string} identifier - An identifier that'll let the user understand which element has an error. This is whatever makes the most sense\n * @property {string} [expectedType] - The type that was expected for the identifier (optional)\n */\n\n/**\n * @import { ComponentWithModuleName } from '../common/index.mjs'\n */\n","import { isInitialised, isSupported } from './common/index.mjs'\nimport { ElementError, InitError, SupportError } from './errors/index.mjs'\n\n/**\n * Base Component class\n *\n * Centralises the behaviours shared by our components\n *\n * @virtual\n * @template {Element} [RootElementType=HTMLElement]\n */\nexport class Component {\n /**\n * @type {typeof Element}\n */\n static elementType = HTMLElement\n\n // allows Typescript user to work around the lack of types\n // in GOVUKFrontend package, Typescript is not aware of $root\n // in components that extend GOVUKFrontendComponent\n /**\n * Returns the root element of the component\n *\n * @protected\n * @returns {RootElementType} - the root element of component\n */\n get $root() {\n return this._$root\n }\n\n /**\n * @protected\n * @type {RootElementType}\n */\n _$root\n\n /**\n * Constructs a new component, validating that GOV.UK Frontend is supported\n *\n * @internal\n * @param {Element | null} [$root] - HTML element to use for component\n */\n constructor($root) {\n const childConstructor = /** @type {ChildClassConstructor} */ (\n this.constructor\n )\n\n // TypeScript does not enforce that inheriting classes will define a `moduleName`\n // (even if we add a `@virtual` `static moduleName` property to this class).\n // While we trust users to do this correctly, we do a little check to provide them\n // a helpful error message.\n //\n // After this, we'll be sure that `childConstructor` has a `moduleName`\n // as expected of the `ChildClassConstructor` we've cast `this.constructor` to.\n if (typeof childConstructor.moduleName !== 'string') {\n throw new InitError(`\\`moduleName\\` not defined in component`)\n }\n\n if (!($root instanceof childConstructor.elementType)) {\n throw new ElementError({\n element: $root,\n component: childConstructor,\n identifier: 'Root element (`$root`)',\n expectedType: childConstructor.elementType.name\n })\n } else {\n this._$root = /** @type {RootElementType} */ ($root)\n }\n\n childConstructor.checkSupport()\n\n this.checkInitialised()\n\n const moduleName = childConstructor.moduleName\n\n this.$root.setAttribute(`data-${moduleName}-init`, '')\n }\n\n /**\n * Validates whether component is already initialised\n *\n * @private\n * @throws {InitError} when component is already initialised\n */\n checkInitialised() {\n const constructor = /** @type {ChildClassConstructor} */ (this.constructor)\n const moduleName = constructor.moduleName\n\n if (moduleName && isInitialised(this.$root, moduleName)) {\n throw new InitError(constructor)\n }\n }\n\n /**\n * Validates whether components are supported\n *\n * @throws {SupportError} when the components are not supported\n */\n static checkSupport() {\n if (!isSupported()) {\n throw new SupportError()\n }\n }\n}\n\n/**\n * @typedef ChildClass\n * @property {string} moduleName - The module name that'll be looked for in the DOM when initialising the component\n */\n\n/**\n * @typedef {typeof Component & ChildClass} ChildClassConstructor\n */\n","import { Component } from '../../component.mjs'\nimport { ElementError } from '../../errors/index.mjs'\n\n/**\n * Radios component\n *\n * @preserve\n */\nexport class Radios extends Component {\n /** @private */\n $inputs\n\n /**\n * Radios can be associated with a 'conditionally revealed' content block –\n * for example, a radio for 'Phone' could reveal an additional form field for\n * the user to enter their phone number.\n *\n * These associations are made using a `data-aria-controls` attribute, which\n * is promoted to an aria-controls attribute during initialisation.\n *\n * We also need to restore the state of any conditional reveals on the page\n * (for example if the user has navigated back), and set up event handlers to\n * keep the reveal in sync with the radio state.\n *\n * @param {Element | null} $root - HTML element to use for radios\n */\n constructor($root) {\n super($root)\n\n const $inputs = this.$root.querySelectorAll('input[type=\"radio\"]')\n if (!$inputs.length) {\n throw new ElementError({\n component: Radios,\n identifier: 'Form inputs (`<input type=\"radio\">`)'\n })\n }\n\n this.$inputs = $inputs\n\n this.$inputs.forEach(($input) => {\n const targetId = $input.getAttribute('data-aria-controls')\n\n // Skip radios without data-aria-controls attributes\n if (!targetId) {\n return\n }\n\n // Throw if target conditional element does not exist.\n if (!document.getElementById(targetId)) {\n throw new ElementError({\n component: Radios,\n identifier: `Conditional reveal (\\`id=\"${targetId}\"\\`)`\n })\n }\n\n // Promote the data-aria-controls attribute to a aria-controls attribute\n // so that the relationship is exposed in the AOM\n $input.setAttribute('aria-controls', targetId)\n $input.removeAttribute('data-aria-controls')\n })\n\n // When the page is restored after navigating 'back' in some browsers the\n // state of form controls is not restored until *after* the DOMContentLoaded\n // event is fired, so we need to sync after the pageshow event.\n window.addEventListener('pageshow', () => this.syncAllConditionalReveals())\n\n // Although we've set up handlers to sync state on the pageshow event, init\n // could be called after those events have fired, for example if they are\n // added to the page dynamically, so sync now too.\n this.syncAllConditionalReveals()\n\n // Handle events\n this.$root.addEventListener('click', (event) => this.handleClick(event))\n }\n\n /**\n * Sync the conditional reveal states for all radio buttons in this component.\n *\n * @private\n */\n syncAllConditionalReveals() {\n this.$inputs.forEach(($input) =>\n this.syncConditionalRevealWithInputState($input)\n )\n }\n\n /**\n * Sync conditional reveal with the input state\n *\n * Synchronise the visibility of the conditional reveal, and its accessible\n * state, with the input's checked state.\n *\n * @private\n * @param {HTMLInputElement} $input - Radio input\n */\n syncConditionalRevealWithInputState($input) {\n const targetId = $input.getAttribute('aria-controls')\n if (!targetId) {\n return\n }\n\n const $target = document.getElementById(targetId)\n if ($target?.classList.contains('govuk-radios__conditional')) {\n const inputIsChecked = $input.checked\n\n $input.setAttribute('aria-expanded', inputIsChecked.toString())\n $target.classList.toggle(\n 'govuk-radios__conditional--hidden',\n !inputIsChecked\n )\n }\n }\n\n /**\n * Click event handler\n *\n * Handle a click within the component root – if the click occurred on a radio, sync\n * the state of the conditional reveal for all radio buttons in the same form\n * with the same name (because checking one radio could have un-checked a\n * radio under the root of another Radio component)\n *\n * @private\n * @param {MouseEvent} event - Click event\n */\n handleClick(event) {\n const $clickedInput = event.target\n\n // Ignore clicks on things that aren't radio buttons\n if (\n !($clickedInput instanceof HTMLInputElement) ||\n $clickedInput.type !== 'radio'\n ) {\n return\n }\n\n // We only need to consider radios with conditional reveals, which will have\n // aria-controls attributes.\n const $allInputs = document.querySelectorAll(\n 'input[type=\"radio\"][aria-controls]'\n )\n\n const $clickedInputForm = $clickedInput.form\n const $clickedInputName = $clickedInput.name\n\n $allInputs.forEach(($input) => {\n const hasSameFormOwner = $input.form === $clickedInputForm\n const hasSameName = $input.name === $clickedInputName\n\n if (hasSameName && hasSameFormOwner) {\n this.syncConditionalRevealWithInputState($input)\n }\n })\n }\n\n /**\n * Name for the component used when initialising using data-module attributes.\n */\n static moduleName = 'govuk-radios'\n}\n"],"names":["isInitialised","$root","moduleName","HTMLElement","hasAttribute","isSupported","$scope","document","body","classList","contains","isArray","option","Array","isObject","formatErrorMessage","Component","message","GOVUKFrontendError","Error","constructor","args","name","SupportError","supportMessage","HTMLScriptElement","prototype","ElementError","messageOrOptions","component","identifier","element","expectedType","InitError","componentOrMessage","_$root","childConstructor","elementType","checkSupport","checkInitialised","setAttribute","Radios","$inputs","querySelectorAll","length","forEach","$input","targetId","getAttribute","getElementById","removeAttribute","window","addEventListener","syncAllConditionalReveals","event","handleClick","syncConditionalRevealWithInputState","$target","inputIsChecked","checked","toString","toggle","$clickedInput","target","HTMLInputElement","type","$allInputs","$clickedInputForm","form","$clickedInputName","hasSameFormOwner","hasSameName"],"mappings":"AAmFO,SAASA,aAAaA,CAACC,KAAK,EAAEC,UAAU,EAAE;EAC/C,OACED,KAAK,YAAYE,WAAW,IAC5BF,KAAK,CAACG,YAAY,CAAC,CAAA,KAAA,EAAQF,UAAU,CAAA,KAAA,CAAO,CAAC;AAEjD;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,SAASG,WAAWA,CAACC,MAAM,GAAGC,QAAQ,CAACC,IAAI,EAAE;EAClD,IAAI,CAACF,MAAM,EAAE;AACX,IAAA,OAAO,KAAK;AACd,EAAA;AAEA,EAAA,OAAOA,MAAM,CAACG,SAAS,CAACC,QAAQ,CAAC,0BAA0B,CAAC;AAC9D;AASA,SAASC,OAAOA,CAACC,MAAM,EAAE;AACvB,EAAA,OAAOC,KAAK,CAACF,OAAO,CAACC,MAAM,CAAC;AAC9B;AAUO,SAASE,QAAQA,CAACF,MAAM,EAAE;AAC/B,EAAA,OAAO,CAAC,CAACA,MAAM,IAAI,OAAOA,MAAM,KAAK,QAAQ,IAAI,CAACD,OAAO,CAACC,MAAM,CAAC;AACnE;AAsBO,SAASG,kBAAkBA,CAACC,SAAS,EAAEC,OAAO,EAAE;AACrD,EAAA,OAAO,GAAGD,SAAS,CAACd,UAAU,CAAA,EAAA,EAAKe,OAAO,CAAA,CAAE;AAC9C;AAQA;AACA;AACA;AACA;;AC7IO,MAAMC,kBAAkB,SAASC,KAAK,CAAC;AAAAC,EAAAA,WAAAA,CAAA,GAAAC,IAAA,EAAA;AAAA,IAAA,KAAA,CAAA,GAAAA,IAAA,CAAA;IAAA,IAAA,CAC5CC,IAAI,GAAG,oBAAoB;AAAA,EAAA;AAC7B;AAKO,MAAMC,YAAY,SAASL,kBAAkB,CAAC;AAGnD;AACF;AACA;AACA;AACA;AACEE,EAAAA,WAAWA,CAACd,MAAM,GAAGC,QAAQ,CAACC,IAAI,EAAE;IAClC,MAAMgB,cAAc,GAClB,UAAU,IAAIC,iBAAiB,CAACC,SAAS,GACrC,gHAAgH,GAChH,kDAAkD;AAExD,IAAA,KAAK,CACHpB,MAAM,GACFkB,cAAc,GACd,8DACN,CAAC;IAAA,IAAA,CAjBHF,IAAI,GAAG,cAAc;AAkBrB,EAAA;AACF;AAYO,MAAMK,YAAY,SAAST,kBAAkB,CAAC;EAmBnDE,WAAWA,CAACQ,gBAAgB,EAAE;IAC5B,IAAIX,OAAO,GAAG,OAAOW,gBAAgB,KAAK,QAAQ,GAAGA,gBAAgB,GAAG,EAAE;AAG1E,IAAA,IAAId,QAAQ,CAACc,gBAAgB,CAAC,EAAE;MAC9B,MAAM;QAAEC,SAAS;QAAEC,UAAU;QAAEC,OAAO;AAAEC,QAAAA;AAAa,OAAC,GAAGJ,gBAAgB;AAEzEX,MAAAA,OAAO,GAAGa,UAAU;MAGpBb,OAAO,IAAIc,OAAO,GACd,CAAA,gBAAA,EAAmBC,YAAY,IAAA,IAAA,GAAZA,YAAY,GAAI,aAAa,CAAA,CAAE,GAClD,YAAY;AAGhB,MAAA,IAAIH,SAAS,EAAE;AACbZ,QAAAA,OAAO,GAAGF,kBAAkB,CAACc,SAAS,EAAEZ,OAAO,CAAC;AAClD,MAAA;AACF,IAAA;IAEA,KAAK,CAACA,OAAO,CAAC;IAAA,IAAA,CAtChBK,IAAI,GAAG,cAAc;AAuCrB,EAAA;AACF;AAKO,MAAMW,SAAS,SAASf,kBAAkB,CAAC;EAOhDE,WAAWA,CAACc,kBAAkB,EAAE;AAC9B,IAAA,MAAMjB,OAAO,GACX,OAAOiB,kBAAkB,KAAK,QAAQ,GAClCA,kBAAkB,GAClBnB,kBAAkB,CAChBmB,kBAAkB,EAClB,8CACF,CAAC;IAEP,KAAK,CAACjB,OAAO,CAAC;IAAA,IAAA,CAfhBK,IAAI,GAAG,WAAW;AAgBlB,EAAA;AACF;AAaA;AACA;AACA;;ACjIO,MAAMN,SAAS,CAAC;AASrB;AACF;AACA;AACA;AACA;AACA;EACE,IAAIf,KAAKA,GAAG;IACV,OAAO,IAAI,CAACkC,MAAM;AACpB,EAAA;EAcAf,WAAWA,CAACnB,KAAK,EAAE;AAAA,IAAA,IAAA,CARnBkC,MAAM,GAAA,MAAA;AASJ,IAAA,MAAMC,gBAAgB,GACpB,IAAI,CAAChB,WACN;AASD,IAAA,IAAI,OAAOgB,gBAAgB,CAAClC,UAAU,KAAK,QAAQ,EAAE;AACnD,MAAA,MAAM,IAAI+B,SAAS,CAAC,CAAA,uCAAA,CAAyC,CAAC;AAChE,IAAA;AAEA,IAAA,IAAI,EAAEhC,KAAK,YAAYmC,gBAAgB,CAACC,WAAW,CAAC,EAAE;MACpD,MAAM,IAAIV,YAAY,CAAC;AACrBI,QAAAA,OAAO,EAAE9B,KAAK;AACd4B,QAAAA,SAAS,EAAEO,gBAAgB;AAC3BN,QAAAA,UAAU,EAAE,wBAAwB;AACpCE,QAAAA,YAAY,EAAEI,gBAAgB,CAACC,WAAW,CAACf;AAC7C,OAAC,CAAC;AACJ,IAAA,CAAC,MAAM;MACL,IAAI,CAACa,MAAM,GAAmClC,KAAM;AACtD,IAAA;IAEAmC,gBAAgB,CAACE,YAAY,EAAE;IAE/B,IAAI,CAACC,gBAAgB,EAAE;AAEvB,IAAA,MAAMrC,UAAU,GAAGkC,gBAAgB,CAAClC,UAAU;IAE9C,IAAI,CAACD,KAAK,CAACuC,YAAY,CAAC,QAAQtC,UAAU,CAAA,KAAA,CAAO,EAAE,EAAE,CAAC;AACxD,EAAA;AAQAqC,EAAAA,gBAAgBA,GAAG;AACjB,IAAA,MAAMnB,WAAW,GAAyC,IAAI,CAACA,WAAY;AAC3E,IAAA,MAAMlB,UAAU,GAAGkB,WAAW,CAAClB,UAAU;IAEzC,IAAIA,UAAU,IAAIF,aAAa,CAAC,IAAI,CAACC,KAAK,EAAEC,UAAU,CAAC,EAAE;AACvD,MAAA,MAAM,IAAI+B,SAAS,CAACb,WAAW,CAAC;AAClC,IAAA;AACF,EAAA;EAOA,OAAOkB,YAAYA,GAAG;AACpB,IAAA,IAAI,CAACjC,WAAW,EAAE,EAAE;MAClB,MAAM,IAAIkB,YAAY,EAAE;AAC1B,IAAA;AACF,EAAA;AACF;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AArGaP,SAAS,CAIbqB,WAAW,GAAGlC,WAAW;;ACZlC;AACA;AACA;AACA;AACA;AACO,MAAMsC,MAAM,SAASzB,SAAS,CAAC;AAIpC;AACF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;EACEI,WAAWA,CAACnB,KAAK,EAAE;IACjB,KAAK,CAACA,KAAK,CAAC;AAAA,IAAA,IAAA,CAjBdyC,OAAO,GAAA,MAAA;IAmBL,MAAMA,OAAO,GAAG,IAAI,CAACzC,KAAK,CAAC0C,gBAAgB,CAAC,qBAAqB,CAAC;AAClE,IAAA,IAAI,CAACD,OAAO,CAACE,MAAM,EAAE;MACnB,MAAM,IAAIjB,YAAY,CAAC;AACrBE,QAAAA,SAAS,EAAEY,MAAM;AACjBX,QAAAA,UAAU,EAAE;AACd,OAAC,CAAC;AACJ,IAAA;IAEA,IAAI,CAACY,OAAO,GAAGA,OAAO;AAEtB,IAAA,IAAI,CAACA,OAAO,CAACG,OAAO,CAAEC,MAAM,IAAK;AAC/B,MAAA,MAAMC,QAAQ,GAAGD,MAAM,CAACE,YAAY,CAAC,oBAAoB,CAAC;MAG1D,IAAI,CAACD,QAAQ,EAAE;AACb,QAAA;AACF,MAAA;AAGA,MAAA,IAAI,CAACxC,QAAQ,CAAC0C,cAAc,CAACF,QAAQ,CAAC,EAAE;QACtC,MAAM,IAAIpB,YAAY,CAAC;AACrBE,UAAAA,SAAS,EAAEY,MAAM;UACjBX,UAAU,EAAE,6BAA6BiB,QAAQ,CAAA,IAAA;AACnD,SAAC,CAAC;AACJ,MAAA;AAIAD,MAAAA,MAAM,CAACN,YAAY,CAAC,eAAe,EAAEO,QAAQ,CAAC;AAC9CD,MAAAA,MAAM,CAACI,eAAe,CAAC,oBAAoB,CAAC;AAC9C,IAAA,CAAC,CAAC;IAKFC,MAAM,CAACC,gBAAgB,CAAC,UAAU,EAAE,MAAM,IAAI,CAACC,yBAAyB,EAAE,CAAC;IAK3E,IAAI,CAACA,yBAAyB,EAAE;AAGhC,IAAA,IAAI,CAACpD,KAAK,CAACmD,gBAAgB,CAAC,OAAO,EAAGE,KAAK,IAAK,IAAI,CAACC,WAAW,CAACD,KAAK,CAAC,CAAC;AAC1E,EAAA;AAOAD,EAAAA,yBAAyBA,GAAG;AAC1B,IAAA,IAAI,CAACX,OAAO,CAACG,OAAO,CAAEC,MAAM,IAC1B,IAAI,CAACU,mCAAmC,CAACV,MAAM,CACjD,CAAC;AACH,EAAA;EAWAU,mCAAmCA,CAACV,MAAM,EAAE;AAC1C,IAAA,MAAMC,QAAQ,GAAGD,MAAM,CAACE,YAAY,CAAC,eAAe,CAAC;IACrD,IAAI,CAACD,QAAQ,EAAE;AACb,MAAA;AACF,IAAA;AAEA,IAAA,MAAMU,OAAO,GAAGlD,QAAQ,CAAC0C,cAAc,CAACF,QAAQ,CAAC;IACjD,IAAIU,OAAO,IAAA,IAAA,IAAPA,OAAO,CAAEhD,SAAS,CAACC,QAAQ,CAAC,2BAA2B,CAAC,EAAE;AAC5D,MAAA,MAAMgD,cAAc,GAAGZ,MAAM,CAACa,OAAO;MAErCb,MAAM,CAACN,YAAY,CAAC,eAAe,EAAEkB,cAAc,CAACE,QAAQ,EAAE,CAAC;MAC/DH,OAAO,CAAChD,SAAS,CAACoD,MAAM,CACtB,mCAAmC,EACnC,CAACH,cACH,CAAC;AACH,IAAA;AACF,EAAA;EAaAH,WAAWA,CAACD,KAAK,EAAE;AACjB,IAAA,MAAMQ,aAAa,GAAGR,KAAK,CAACS,MAAM;IAGlC,IACE,EAAED,aAAa,YAAYE,gBAAgB,CAAC,IAC5CF,aAAa,CAACG,IAAI,KAAK,OAAO,EAC9B;AACA,MAAA;AACF,IAAA;AAIA,IAAA,MAAMC,UAAU,GAAG3D,QAAQ,CAACoC,gBAAgB,CAC1C,oCACF,CAAC;AAED,IAAA,MAAMwB,iBAAiB,GAAGL,aAAa,CAACM,IAAI;AAC5C,IAAA,MAAMC,iBAAiB,GAAGP,aAAa,CAACxC,IAAI;AAE5C4C,IAAAA,UAAU,CAACrB,OAAO,CAAEC,MAAM,IAAK;AAC7B,MAAA,MAAMwB,gBAAgB,GAAGxB,MAAM,CAACsB,IAAI,KAAKD,iBAAiB;AAC1D,MAAA,MAAMI,WAAW,GAAGzB,MAAM,CAACxB,IAAI,KAAK+C,iBAAiB;MAErD,IAAIE,WAAW,IAAID,gBAAgB,EAAE;AACnC,QAAA,IAAI,CAACd,mCAAmC,CAACV,MAAM,CAAC;AAClD,MAAA;AACF,IAAA,CAAC,CAAC;AACJ,EAAA;AAMF;AAtJaL,MAAM,CAqJVvC,UAAU,GAAG,cAAc;;;;"}
1
+ {"version":3,"file":"radios.bundle.mjs","sources":["../../../../src/govuk/common/index.mjs","../../../../src/govuk/errors/index.mjs","../../../../src/govuk/component.mjs","../../../../src/govuk/components/radios/radios.mjs"],"sourcesContent":["/**\n * Common helpers which do not require polyfill.\n *\n * IMPORTANT: If a helper require a polyfill, please isolate it in its own module\n * so that the polyfill can be properly tree-shaken and does not burden\n * the components that do not need that helper\n */\n\n/**\n * Get GOV.UK Frontend breakpoint value from CSS custom property\n *\n * @private\n * @param {string} name - Breakpoint name\n * @returns {{ property: string, value?: string }} Breakpoint object\n */\nexport function getBreakpoint(name) {\n const property = `--govuk-breakpoint-${name}`\n\n // Get value from `<html>` with breakpoints on CSS :root\n const value = window\n .getComputedStyle(document.documentElement)\n .getPropertyValue(property)\n\n return {\n property,\n value: value || undefined\n }\n}\n\n/**\n * Move focus to element\n *\n * Sets tabindex to -1 to make the element programmatically focusable,\n * but removes it on blur as the element doesn't need to be focused again.\n *\n * @private\n * @template {HTMLElement} FocusElement\n * @param {FocusElement} $element - HTML element\n * @param {object} [options] - Handler options\n * @param {function(this: FocusElement): void} [options.onBeforeFocus] - Callback before focus\n * @param {function(this: FocusElement): void} [options.onBlur] - Callback on blur\n */\nexport function setFocus($element, options = {}) {\n const isFocusable = $element.getAttribute('tabindex')\n\n if (!isFocusable) {\n $element.setAttribute('tabindex', '-1')\n }\n\n /**\n * Handle element focus\n */\n function onFocus() {\n $element.addEventListener('blur', onBlur, { once: true })\n }\n\n /**\n * Handle element blur\n */\n function onBlur() {\n options.onBlur?.call($element)\n\n if (!isFocusable) {\n $element.removeAttribute('tabindex')\n }\n }\n\n // Add listener to reset element on blur, after focus\n $element.addEventListener('focus', onFocus, { once: true })\n\n // Focus element\n options.onBeforeFocus?.call($element)\n $element.focus()\n}\n\n/**\n * Checks if component is already initialised\n *\n * @internal\n * @param {Element} $root - HTML element to be checked\n * @param {string} moduleName - name of component module\n * @returns {boolean} Whether component is already initialised\n */\nexport function isInitialised($root, moduleName) {\n return (\n $root instanceof HTMLElement &&\n $root.hasAttribute(`data-${moduleName}-init`)\n )\n}\n\n/**\n * Checks if GOV.UK Frontend is supported on this page\n *\n * Some browsers will load and run our JavaScript but GOV.UK Frontend\n * won't be supported.\n *\n * @param {HTMLElement | null} [$scope] - (internal) `<body>` HTML element checked for browser support\n * @returns {boolean} Whether GOV.UK Frontend is supported on this page\n */\nexport function isSupported($scope = document.body) {\n if (!$scope) {\n return false\n }\n\n return $scope.classList.contains('govuk-frontend-supported')\n}\n\n/**\n * Check for an array\n *\n * @internal\n * @param {unknown} option - Option to check\n * @returns {boolean} Whether the option is an array\n */\nfunction isArray(option) {\n return Array.isArray(option)\n}\n\n/**\n * Check for an object\n *\n * @internal\n * @template {Partial<Record<keyof ObjectType, unknown>>} ObjectType\n * @param {unknown | ObjectType} option - Option to check\n * @returns {option is ObjectType} Whether the option is an object\n */\nexport function isObject(option) {\n return !!option && typeof option === 'object' && !isArray(option)\n}\n\n/**\n * Check for valid scope\n *\n * @internal\n * @template {Element | Document} ScopeType\n * @param {unknown | ScopeType} $scope - Scope of the document to search within\n * @returns {$scope is ScopeType} Whether the scope can be queried\n */\nexport function isScope($scope) {\n return !!$scope && ($scope instanceof Element || $scope instanceof Document)\n}\n\n/**\n * Format error message\n *\n * @internal\n * @param {ComponentWithModuleName} Component - Component that threw the error\n * @param {string} message - Error message\n * @returns {string} - Formatted error message\n */\nexport function formatErrorMessage(Component, message) {\n return `${Component.moduleName}: ${message}`\n}\n\n/* eslint-disable jsdoc/valid-types --\n * `{new(...args: any[] ): object}` is not recognised as valid\n * https://github.com/gajus/eslint-plugin-jsdoc/issues/145#issuecomment-1308722878\n * https://github.com/jsdoc-type-pratt-parser/jsdoc-type-pratt-parser/issues/131\n **/\n\n/**\n * @typedef ComponentWithModuleName\n * @property {string} moduleName - Name of the component\n */\n\n/* eslint-enable jsdoc/valid-types */\n","import { formatErrorMessage, isObject, isScope } from '../common/index.mjs'\n\n/**\n * GOV.UK Frontend error\n *\n * A base class for `Error`s thrown by GOV.UK Frontend.\n *\n * It is meant to be extended into specific types of errors\n * to be thrown by our code.\n *\n * @example\n * ```js\n * class MissingRootError extends GOVUKFrontendError {\n * // Setting an explicit name is important as extending the class will not\n * // set a new `name` on the subclass. The `name` property is important\n * // to ensure intelligible error names even if the class name gets\n * // mangled by a minifier\n * name = \"MissingRootError\"\n * }\n * ```\n * @virtual\n */\nexport class GOVUKFrontendError extends Error {\n name = 'GOVUKFrontendError'\n}\n\n/**\n * Indicates that GOV.UK Frontend is not supported\n */\nexport class SupportError extends GOVUKFrontendError {\n name = 'SupportError'\n\n /**\n * Checks if GOV.UK Frontend is supported on this page\n *\n * @param {Element | Document | null | string} [scopeOrMessage] - HTML element `<body>` checked for browser support or support error message\n */\n constructor(scopeOrMessage = document.body) {\n let supportMessage =\n 'noModule' in HTMLScriptElement.prototype\n ? 'GOV.UK Frontend initialised without `<body class=\"govuk-frontend-supported\">` from template `<script>` snippet'\n : 'GOV.UK Frontend is not supported in this browser'\n\n if (!isScope(scopeOrMessage)) {\n supportMessage =\n 'GOV.UK Frontend initialised without `<script type=\"module\">`'\n }\n\n super(typeof scopeOrMessage === 'string' ? scopeOrMessage : supportMessage)\n }\n}\n\n/**\n * Indicates that a component has received an illegal configuration\n */\nexport class ConfigError extends GOVUKFrontendError {\n name = 'ConfigError'\n}\n\n/**\n * Indicates an issue with an element (possibly `null` or `undefined`)\n */\nexport class ElementError extends GOVUKFrontendError {\n name = 'ElementError'\n\n /**\n * @internal\n * @overload\n * @param {string} message - Element error message\n */\n\n /**\n * @internal\n * @overload\n * @param {ElementErrorOptions} options - Element error options\n */\n\n /**\n * @internal\n * @param {string | ElementErrorOptions} messageOrOptions - Element error message or options\n */\n constructor(messageOrOptions) {\n let message = typeof messageOrOptions === 'string' ? messageOrOptions : ''\n\n // Build message from options\n if (isObject(messageOrOptions)) {\n const { component, identifier, element, expectedType } = messageOrOptions\n\n message = identifier\n\n // Append reason\n message += element\n ? ` is not of type ${expectedType ?? 'HTMLElement'}`\n : ' not found'\n\n // Prepend with module name (optional)\n if (component) {\n message = formatErrorMessage(component, message)\n }\n }\n\n super(message)\n }\n}\n\n/**\n * Indicates that a component is already initialised\n */\nexport class InitError extends GOVUKFrontendError {\n name = 'InitError'\n\n /**\n * @internal\n * @param {ComponentWithModuleName | string} componentOrMessage - name of the component module\n */\n constructor(componentOrMessage) {\n const message =\n typeof componentOrMessage === 'string'\n ? componentOrMessage\n : formatErrorMessage(\n componentOrMessage,\n `Root element (\\`$root\\`) already initialised`\n )\n\n super(message)\n }\n}\n\n/**\n * Element error options\n *\n * @internal\n * @typedef {object} ElementErrorOptions\n * @property {Element | Document | null} [element] - The element in error (optional)\n * @property {ComponentWithModuleName} [component] - Component throwing the error (optional)\n * @property {string} identifier - An identifier that'll let the user understand which element has an error. This is whatever makes the most sense\n * @property {string} [expectedType] - The type that was expected for the identifier (optional)\n */\n\n/**\n * @import { ComponentWithModuleName } from '../common/index.mjs'\n */\n","/* eslint-disable es-x/no-global-this */\n\nimport { isInitialised, isSupported } from './common/index.mjs'\nimport { ElementError, InitError, SupportError } from './errors/index.mjs'\n\nconst _self =\n typeof globalThis !== 'undefined'\n ? globalThis // Modern browsers, Node.js\n : self // Old browsers, web workers\n\n/**\n * Base Component class\n *\n * Centralises the behaviours shared by our components\n *\n * @virtual\n * @template {Element} [RootElementType=HTMLElement]\n */\nexport class Component {\n /**\n * @type {typeof Element}\n */\n static elementType = _self.HTMLElement\n\n // allows Typescript user to work around the lack of types\n // in GOVUKFrontend package, Typescript is not aware of $root\n // in components that extend GOVUKFrontendComponent\n /**\n * Returns the root element of the component\n *\n * @protected\n * @returns {RootElementType} - the root element of component\n */\n get $root() {\n return this._$root\n }\n\n /**\n * @protected\n * @type {RootElementType}\n */\n _$root\n\n /**\n * Constructs a new component, validating that GOV.UK Frontend is supported\n *\n * @internal\n * @param {Element | null} [$root] - HTML element to use for component\n */\n constructor($root) {\n const childConstructor = /** @type {ChildClassConstructor} */ (\n this.constructor\n )\n\n // TypeScript does not enforce that inheriting classes will define a `moduleName`\n // (even if we add a `@virtual` `static moduleName` property to this class).\n // While we trust users to do this correctly, we do a little check to provide them\n // a helpful error message.\n //\n // After this, we'll be sure that `childConstructor` has a `moduleName`\n // as expected of the `ChildClassConstructor` we've cast `this.constructor` to.\n if (typeof childConstructor.moduleName !== 'string') {\n throw new InitError(`\\`moduleName\\` not defined in component`)\n }\n\n if (!($root instanceof childConstructor.elementType)) {\n throw new ElementError({\n element: $root,\n component: childConstructor,\n identifier: 'Root element (`$root`)',\n expectedType: childConstructor.elementType.name\n })\n } else {\n this._$root = /** @type {RootElementType} */ ($root)\n }\n\n childConstructor.checkSupport()\n\n this.checkInitialised()\n\n const moduleName = childConstructor.moduleName\n\n this.$root.setAttribute(`data-${moduleName}-init`, '')\n }\n\n /**\n * Validates whether component is already initialised\n *\n * @private\n * @throws {InitError} when component is already initialised\n */\n checkInitialised() {\n const constructor = /** @type {ChildClassConstructor} */ (this.constructor)\n const moduleName = constructor.moduleName\n\n if (moduleName && isInitialised(this.$root, moduleName)) {\n throw new InitError(constructor)\n }\n }\n\n /**\n * Validates whether components are supported\n *\n * @throws {SupportError} when the components are not supported\n */\n static checkSupport() {\n if (!isSupported()) {\n throw new SupportError()\n }\n }\n}\n\n/**\n * @typedef ChildClass\n * @property {string} moduleName - The module name that'll be looked for in the DOM when initialising the component\n */\n\n/**\n * @typedef {typeof Component & ChildClass} ChildClassConstructor\n */\n","import { Component } from '../../component.mjs'\nimport { ElementError } from '../../errors/index.mjs'\n\n/**\n * Radios component\n *\n * @preserve\n */\nexport class Radios extends Component {\n /** @private */\n $inputs\n\n /**\n * Radios can be associated with a 'conditionally revealed' content block –\n * for example, a radio for 'Phone' could reveal an additional form field for\n * the user to enter their phone number.\n *\n * These associations are made using a `data-aria-controls` attribute, which\n * is promoted to an aria-controls attribute during initialisation.\n *\n * We also need to restore the state of any conditional reveals on the page\n * (for example if the user has navigated back), and set up event handlers to\n * keep the reveal in sync with the radio state.\n *\n * @param {Element | null} $root - HTML element to use for radios\n */\n constructor($root) {\n super($root)\n\n const $inputs = this.$root.querySelectorAll('input[type=\"radio\"]')\n if (!$inputs.length) {\n throw new ElementError({\n component: Radios,\n identifier: 'Form inputs (`<input type=\"radio\">`)'\n })\n }\n\n this.$inputs = $inputs\n\n this.$inputs.forEach(($input) => {\n const targetId = $input.getAttribute('data-aria-controls')\n\n // Skip radios without data-aria-controls attributes\n if (!targetId) {\n return\n }\n\n // Throw if target conditional element does not exist.\n if (!document.getElementById(targetId)) {\n throw new ElementError({\n component: Radios,\n identifier: `Conditional reveal (\\`id=\"${targetId}\"\\`)`\n })\n }\n\n // Promote the data-aria-controls attribute to a aria-controls attribute\n // so that the relationship is exposed in the AOM\n $input.setAttribute('aria-controls', targetId)\n $input.removeAttribute('data-aria-controls')\n })\n\n // When the page is restored after navigating 'back' in some browsers the\n // state of form controls is not restored until *after* the DOMContentLoaded\n // event is fired, so we need to sync after the pageshow event.\n window.addEventListener('pageshow', () => this.syncAllConditionalReveals())\n\n // Although we've set up handlers to sync state on the pageshow event, init\n // could be called after those events have fired, for example if they are\n // added to the page dynamically, so sync now too.\n this.syncAllConditionalReveals()\n\n // Handle events\n this.$root.addEventListener('click', (event) => this.handleClick(event))\n }\n\n /**\n * Sync the conditional reveal states for all radio buttons in this component.\n *\n * @private\n */\n syncAllConditionalReveals() {\n this.$inputs.forEach(($input) =>\n this.syncConditionalRevealWithInputState($input)\n )\n }\n\n /**\n * Sync conditional reveal with the input state\n *\n * Synchronise the visibility of the conditional reveal, and its accessible\n * state, with the input's checked state.\n *\n * @private\n * @param {HTMLInputElement} $input - Radio input\n */\n syncConditionalRevealWithInputState($input) {\n const targetId = $input.getAttribute('aria-controls')\n if (!targetId) {\n return\n }\n\n const $target = document.getElementById(targetId)\n if ($target?.classList.contains('govuk-radios__conditional')) {\n const inputIsChecked = $input.checked\n\n $input.setAttribute('aria-expanded', inputIsChecked.toString())\n $target.classList.toggle(\n 'govuk-radios__conditional--hidden',\n !inputIsChecked\n )\n }\n }\n\n /**\n * Click event handler\n *\n * Handle a click within the component root – if the click occurred on a radio, sync\n * the state of the conditional reveal for all radio buttons in the same form\n * with the same name (because checking one radio could have un-checked a\n * radio under the root of another Radio component)\n *\n * @private\n * @param {MouseEvent} event - Click event\n */\n handleClick(event) {\n const $clickedInput = event.target\n\n // Ignore clicks on things that aren't radio buttons\n if (\n !($clickedInput instanceof HTMLInputElement) ||\n $clickedInput.type !== 'radio'\n ) {\n return\n }\n\n // We only need to consider radios with conditional reveals, which will have\n // aria-controls attributes.\n const $allInputs = document.querySelectorAll(\n 'input[type=\"radio\"][aria-controls]'\n )\n\n const $clickedInputForm = $clickedInput.form\n const $clickedInputName = $clickedInput.name\n\n $allInputs.forEach(($input) => {\n const hasSameFormOwner = $input.form === $clickedInputForm\n const hasSameName = $input.name === $clickedInputName\n\n if (hasSameName && hasSameFormOwner) {\n this.syncConditionalRevealWithInputState($input)\n }\n })\n }\n\n /**\n * Name for the component used when initialising using data-module attributes.\n */\n static moduleName = 'govuk-radios'\n}\n"],"names":["isInitialised","$root","moduleName","HTMLElement","hasAttribute","isSupported","$scope","document","body","classList","contains","isArray","option","Array","isObject","isScope","Element","Document","formatErrorMessage","Component","message","GOVUKFrontendError","Error","constructor","args","name","SupportError","scopeOrMessage","supportMessage","HTMLScriptElement","prototype","ElementError","messageOrOptions","component","identifier","element","expectedType","InitError","componentOrMessage","_self","globalThis","self","_$root","childConstructor","elementType","checkSupport","checkInitialised","setAttribute","Radios","$inputs","querySelectorAll","length","forEach","$input","targetId","getAttribute","getElementById","removeAttribute","window","addEventListener","syncAllConditionalReveals","event","handleClick","syncConditionalRevealWithInputState","$target","inputIsChecked","checked","toString","toggle","$clickedInput","target","HTMLInputElement","type","$allInputs","$clickedInputForm","form","$clickedInputName","hasSameFormOwner","hasSameName"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"radios.mjs","sources":["../../../../src/govuk/components/radios/radios.mjs"],"sourcesContent":["import { Component } from '../../component.mjs'\nimport { ElementError } from '../../errors/index.mjs'\n\n/**\n * Radios component\n *\n * @preserve\n */\nexport class Radios extends Component {\n /** @private */\n $inputs\n\n /**\n * Radios can be associated with a 'conditionally revealed' content block –\n * for example, a radio for 'Phone' could reveal an additional form field for\n * the user to enter their phone number.\n *\n * These associations are made using a `data-aria-controls` attribute, which\n * is promoted to an aria-controls attribute during initialisation.\n *\n * We also need to restore the state of any conditional reveals on the page\n * (for example if the user has navigated back), and set up event handlers to\n * keep the reveal in sync with the radio state.\n *\n * @param {Element | null} $root - HTML element to use for radios\n */\n constructor($root) {\n super($root)\n\n const $inputs = this.$root.querySelectorAll('input[type=\"radio\"]')\n if (!$inputs.length) {\n throw new ElementError({\n component: Radios,\n identifier: 'Form inputs (`<input type=\"radio\">`)'\n })\n }\n\n this.$inputs = $inputs\n\n this.$inputs.forEach(($input) => {\n const targetId = $input.getAttribute('data-aria-controls')\n\n // Skip radios without data-aria-controls attributes\n if (!targetId) {\n return\n }\n\n // Throw if target conditional element does not exist.\n if (!document.getElementById(targetId)) {\n throw new ElementError({\n component: Radios,\n identifier: `Conditional reveal (\\`id=\"${targetId}\"\\`)`\n })\n }\n\n // Promote the data-aria-controls attribute to a aria-controls attribute\n // so that the relationship is exposed in the AOM\n $input.setAttribute('aria-controls', targetId)\n $input.removeAttribute('data-aria-controls')\n })\n\n // When the page is restored after navigating 'back' in some browsers the\n // state of form controls is not restored until *after* the DOMContentLoaded\n // event is fired, so we need to sync after the pageshow event.\n window.addEventListener('pageshow', () => this.syncAllConditionalReveals())\n\n // Although we've set up handlers to sync state on the pageshow event, init\n // could be called after those events have fired, for example if they are\n // added to the page dynamically, so sync now too.\n this.syncAllConditionalReveals()\n\n // Handle events\n this.$root.addEventListener('click', (event) => this.handleClick(event))\n }\n\n /**\n * Sync the conditional reveal states for all radio buttons in this component.\n *\n * @private\n */\n syncAllConditionalReveals() {\n this.$inputs.forEach(($input) =>\n this.syncConditionalRevealWithInputState($input)\n )\n }\n\n /**\n * Sync conditional reveal with the input state\n *\n * Synchronise the visibility of the conditional reveal, and its accessible\n * state, with the input's checked state.\n *\n * @private\n * @param {HTMLInputElement} $input - Radio input\n */\n syncConditionalRevealWithInputState($input) {\n const targetId = $input.getAttribute('aria-controls')\n if (!targetId) {\n return\n }\n\n const $target = document.getElementById(targetId)\n if ($target?.classList.contains('govuk-radios__conditional')) {\n const inputIsChecked = $input.checked\n\n $input.setAttribute('aria-expanded', inputIsChecked.toString())\n $target.classList.toggle(\n 'govuk-radios__conditional--hidden',\n !inputIsChecked\n )\n }\n }\n\n /**\n * Click event handler\n *\n * Handle a click within the component root – if the click occurred on a radio, sync\n * the state of the conditional reveal for all radio buttons in the same form\n * with the same name (because checking one radio could have un-checked a\n * radio under the root of another Radio component)\n *\n * @private\n * @param {MouseEvent} event - Click event\n */\n handleClick(event) {\n const $clickedInput = event.target\n\n // Ignore clicks on things that aren't radio buttons\n if (\n !($clickedInput instanceof HTMLInputElement) ||\n $clickedInput.type !== 'radio'\n ) {\n return\n }\n\n // We only need to consider radios with conditional reveals, which will have\n // aria-controls attributes.\n const $allInputs = document.querySelectorAll(\n 'input[type=\"radio\"][aria-controls]'\n )\n\n const $clickedInputForm = $clickedInput.form\n const $clickedInputName = $clickedInput.name\n\n $allInputs.forEach(($input) => {\n const hasSameFormOwner = $input.form === $clickedInputForm\n const hasSameName = $input.name === $clickedInputName\n\n if (hasSameName && hasSameFormOwner) {\n this.syncConditionalRevealWithInputState($input)\n }\n })\n }\n\n /**\n * Name for the component used when initialising using data-module attributes.\n */\n static moduleName = 'govuk-radios'\n}\n"],"names":["Radios","Component","constructor","$root","$inputs","querySelectorAll","length","ElementError","component","identifier","forEach","$input","targetId","getAttribute","document","getElementById","setAttribute","removeAttribute","window","addEventListener","syncAllConditionalReveals","event","handleClick","syncConditionalRevealWithInputState","$target","classList","contains","inputIsChecked","checked","toString","toggle","$clickedInput","target","HTMLInputElement","type","$allInputs","$clickedInputForm","form","$clickedInputName","name","hasSameFormOwner","hasSameName","moduleName"],"mappings":"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"}
1
+ {"version":3,"file":"radios.mjs","sources":["../../../../src/govuk/components/radios/radios.mjs"],"sourcesContent":["import { Component } from '../../component.mjs'\nimport { ElementError } from '../../errors/index.mjs'\n\n/**\n * Radios component\n *\n * @preserve\n */\nexport class Radios extends Component {\n /** @private */\n $inputs\n\n /**\n * Radios can be associated with a 'conditionally revealed' content block –\n * for example, a radio for 'Phone' could reveal an additional form field for\n * the user to enter their phone number.\n *\n * These associations are made using a `data-aria-controls` attribute, which\n * is promoted to an aria-controls attribute during initialisation.\n *\n * We also need to restore the state of any conditional reveals on the page\n * (for example if the user has navigated back), and set up event handlers to\n * keep the reveal in sync with the radio state.\n *\n * @param {Element | null} $root - HTML element to use for radios\n */\n constructor($root) {\n super($root)\n\n const $inputs = this.$root.querySelectorAll('input[type=\"radio\"]')\n if (!$inputs.length) {\n throw new ElementError({\n component: Radios,\n identifier: 'Form inputs (`<input type=\"radio\">`)'\n })\n }\n\n this.$inputs = $inputs\n\n this.$inputs.forEach(($input) => {\n const targetId = $input.getAttribute('data-aria-controls')\n\n // Skip radios without data-aria-controls attributes\n if (!targetId) {\n return\n }\n\n // Throw if target conditional element does not exist.\n if (!document.getElementById(targetId)) {\n throw new ElementError({\n component: Radios,\n identifier: `Conditional reveal (\\`id=\"${targetId}\"\\`)`\n })\n }\n\n // Promote the data-aria-controls attribute to a aria-controls attribute\n // so that the relationship is exposed in the AOM\n $input.setAttribute('aria-controls', targetId)\n $input.removeAttribute('data-aria-controls')\n })\n\n // When the page is restored after navigating 'back' in some browsers the\n // state of form controls is not restored until *after* the DOMContentLoaded\n // event is fired, so we need to sync after the pageshow event.\n window.addEventListener('pageshow', () => this.syncAllConditionalReveals())\n\n // Although we've set up handlers to sync state on the pageshow event, init\n // could be called after those events have fired, for example if they are\n // added to the page dynamically, so sync now too.\n this.syncAllConditionalReveals()\n\n // Handle events\n this.$root.addEventListener('click', (event) => this.handleClick(event))\n }\n\n /**\n * Sync the conditional reveal states for all radio buttons in this component.\n *\n * @private\n */\n syncAllConditionalReveals() {\n this.$inputs.forEach(($input) =>\n this.syncConditionalRevealWithInputState($input)\n )\n }\n\n /**\n * Sync conditional reveal with the input state\n *\n * Synchronise the visibility of the conditional reveal, and its accessible\n * state, with the input's checked state.\n *\n * @private\n * @param {HTMLInputElement} $input - Radio input\n */\n syncConditionalRevealWithInputState($input) {\n const targetId = $input.getAttribute('aria-controls')\n if (!targetId) {\n return\n }\n\n const $target = document.getElementById(targetId)\n if ($target?.classList.contains('govuk-radios__conditional')) {\n const inputIsChecked = $input.checked\n\n $input.setAttribute('aria-expanded', inputIsChecked.toString())\n $target.classList.toggle(\n 'govuk-radios__conditional--hidden',\n !inputIsChecked\n )\n }\n }\n\n /**\n * Click event handler\n *\n * Handle a click within the component root – if the click occurred on a radio, sync\n * the state of the conditional reveal for all radio buttons in the same form\n * with the same name (because checking one radio could have un-checked a\n * radio under the root of another Radio component)\n *\n * @private\n * @param {MouseEvent} event - Click event\n */\n handleClick(event) {\n const $clickedInput = event.target\n\n // Ignore clicks on things that aren't radio buttons\n if (\n !($clickedInput instanceof HTMLInputElement) ||\n $clickedInput.type !== 'radio'\n ) {\n return\n }\n\n // We only need to consider radios with conditional reveals, which will have\n // aria-controls attributes.\n const $allInputs = document.querySelectorAll(\n 'input[type=\"radio\"][aria-controls]'\n )\n\n const $clickedInputForm = $clickedInput.form\n const $clickedInputName = $clickedInput.name\n\n $allInputs.forEach(($input) => {\n const hasSameFormOwner = $input.form === $clickedInputForm\n const hasSameName = $input.name === $clickedInputName\n\n if (hasSameName && hasSameFormOwner) {\n this.syncConditionalRevealWithInputState($input)\n }\n })\n }\n\n /**\n * Name for the component used when initialising using data-module attributes.\n */\n static moduleName = 'govuk-radios'\n}\n"],"names":["Radios","Component","constructor","$root","$inputs","querySelectorAll","length","ElementError","component","identifier","forEach","$input","targetId","getAttribute","document","getElementById","setAttribute","removeAttribute","window","addEventListener","syncAllConditionalReveals","event","handleClick","syncConditionalRevealWithInputState","$target","classList","contains","inputIsChecked","checked","toString","toggle","$clickedInput","target","HTMLInputElement","type","$allInputs","$clickedInputForm","form","$clickedInputName","name","hasSameFormOwner","hasSameName","moduleName"],"mappings":"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"}
@@ -20,6 +20,28 @@
20
20
  --govuk-text-colour: #{$govuk-service-navigation-text-colour};
21
21
  color: base.govuk-functional-colour(text);
22
22
  background-color: $govuk-service-navigation-background;
23
+
24
+ @media print {
25
+ border-bottom-color: currentcolor;
26
+ background-color: transparent;
27
+ }
28
+ }
29
+
30
+ .govuk-service-navigation__inlining-container {
31
+ display: flex;
32
+ flex-wrap: wrap;
33
+ align-items: baseline;
34
+
35
+ .govuk-service-navigation__container {
36
+ // Expand the container to shift the `end` slot to the right
37
+ flex-grow: 1;
38
+
39
+ // Ensure some space between the `end` slot and the container
40
+ // when displayed inline
41
+ &:not(:last-child) {
42
+ margin-right: base.govuk-spacing(6);
43
+ }
44
+ }
23
45
  }
24
46
 
25
47
  .govuk-service-navigation__container {
@@ -27,9 +49,16 @@
27
49
  flex-direction: column;
28
50
  align-items: start;
29
51
 
52
+ // Avoid the end slot rendering on the right of the container
53
+ // in small viewports by ensuring the container is full width
54
+ @media #{base.govuk-until-breakpoint(tablet)} {
55
+ width: 100%;
56
+ }
57
+
30
58
  @media #{base.govuk-from-breakpoint(tablet)} {
31
59
  flex-direction: row;
32
60
  flex-wrap: wrap;
61
+ align-items: center;
33
62
  }
34
63
  }
35
64
 
@@ -65,6 +94,10 @@
65
94
  @include base.govuk-responsive-margin(6, $direction: right);
66
95
  }
67
96
  }
97
+
98
+ @media print {
99
+ border-color: currentcolor;
100
+ }
68
101
  }
69
102
 
70
103
  // Remove the top margin of the first nav item if there is a service name but
@@ -207,10 +240,19 @@
207
240
  --govuk-text-colour: #{base.govuk-functional-colour(inverse-text)};
208
241
  background-color: base.govuk-functional-colour(brand);
209
242
 
243
+ @media print {
244
+ --govuk-text-colour: #{base.govuk-functional-colour(print-text)};
245
+ background-color: transparent;
246
+ }
247
+
210
248
  .govuk-width-container {
211
249
  border-width: 1px 0;
212
250
  border-style: solid;
213
251
  border-color: $govuk-service-navigation-border-colour;
252
+
253
+ @media print {
254
+ border-color: currentcolor;
255
+ }
214
256
  }
215
257
 
216
258
  // Subtract 1px of space to account for the extra border-top
@@ -224,9 +266,12 @@
224
266
  border-color: currentcolor;
225
267
  }
226
268
 
227
- // Override link styles
228
- .govuk-service-navigation__link {
229
- @include base.govuk-link-style-text;
269
+ // Override link styles if on screens
270
+ // In print, we want the normal link styles to still apply
271
+ @media not print {
272
+ .govuk-service-navigation__link {
273
+ @include base.govuk-link-style-text;
274
+ }
230
275
  }
231
276
 
232
277
  // Override mobile menu toggle colour when not focused
@@ -635,6 +635,104 @@
635
635
  "screenshot": false,
636
636
  "html": "<div class=\"govuk-service-navigation\"\ndata-module=\"govuk-service-navigation\"\n>\n <div class=\"govuk-width-container\">\n\n <div class=\"govuk-service-navigation__container\">\n \n\n \n <nav aria-label=\"Menu\" class=\"govuk-service-navigation__wrapper\">\n <button type=\"button\" class=\"govuk-service-navigation__toggle govuk-js-service-navigation-toggle\" aria-controls=\"navigation\" hidden aria-hidden=\"true\">\n Menu\n </button>\n\n <ul class=\"govuk-service-navigation__list\" id=\"navigation\" >\n\n \n \n <li class=\"govuk-service-navigation__item\">\n <a class=\"govuk-service-navigation__link\" href=\"#/1\">\n \nNavigation item 1\n </a>\n </li>\n\n \n <li class=\"govuk-service-navigation__item govuk-service-navigation__item--active\">\n <a class=\"govuk-service-navigation__link\" href=\"#/2\" aria-current=\"true\">\n \n <strong class=\"govuk-service-navigation__active-fallback\">Navigation item 2</strong>\n\n </a>\n </li>\n\n \n <li class=\"govuk-service-navigation__item\">\n <a class=\"govuk-service-navigation__link\" href=\"#/3\">\n \nNavigation item 3\n </a>\n </li>\n\n \n <li class=\"govuk-service-navigation__item\">\n <a class=\"govuk-service-navigation__link\" href=\"#/4\">\n \nNavigation item 4\n </a>\n </li>\n\n </ul>\n </nav>\n </div>\n\n </div>\n\n </div>"
637
637
  },
638
+ {
639
+ "name": "with language navigation",
640
+ "options": {
641
+ "serviceName": "Service name",
642
+ "navigation": [
643
+ {
644
+ "href": "#/1",
645
+ "text": "Navigation item 1",
646
+ "active": true
647
+ },
648
+ {
649
+ "href": "#/2",
650
+ "text": "Navigation item 2"
651
+ },
652
+ {
653
+ "href": "#/3",
654
+ "text": "Navigation item 3"
655
+ }
656
+ ],
657
+ "slots": {
658
+ "end": "<nav class=\"govuk-language-navigation\" aria-label=\"Language navigation\">\n <ul class=\"govuk-language-navigation__list\">\n <li class=\"govuk-language-navigation__list-item\">\n <span class=\"govuk-language-navigation__text\" lang=\"en\" aria-current=\"true\">English</span>\n </li>\n <li class=\"govuk-language-navigation__list-item\">\n <a class=\"govuk-language-navigation__link\" href=\"#/cy\" lang=\"cy\" hreflang=\"cy\" rel=\"alternate\">Cymraeg</a>\n </li>\n </ul>\n</nav>"
659
+ }
660
+ },
661
+ "hidden": false,
662
+ "description": "HTML rendered by the language navigation component can be injected into the `end` slot of the service header.",
663
+ "pageTemplateOptions": {},
664
+ "screenshot": false,
665
+ "html": "<section aria-label=\"Service information\" class=\"govuk-service-navigation\"\ndata-module=\"govuk-service-navigation\"\n>\n <div class=\"govuk-width-container\">\n\n <div class=\"govuk-service-navigation__container\">\n \n <span class=\"govuk-service-navigation__service-name\">\n <span class=\"govuk-service-navigation__text\">Service name</span>\n </span>\n\n \n <nav aria-label=\"Menu\" class=\"govuk-service-navigation__wrapper\">\n <button type=\"button\" class=\"govuk-service-navigation__toggle govuk-js-service-navigation-toggle\" aria-controls=\"navigation\" hidden aria-hidden=\"true\">\n Menu\n </button>\n\n <ul class=\"govuk-service-navigation__list\" id=\"navigation\" >\n\n \n \n <li class=\"govuk-service-navigation__item govuk-service-navigation__item--active\">\n <a class=\"govuk-service-navigation__link\" href=\"#/1\" aria-current=\"true\">\n \n <strong class=\"govuk-service-navigation__active-fallback\">Navigation item 1</strong>\n\n </a>\n </li>\n\n \n <li class=\"govuk-service-navigation__item\">\n <a class=\"govuk-service-navigation__link\" href=\"#/2\">\n \nNavigation item 2\n </a>\n </li>\n\n \n <li class=\"govuk-service-navigation__item\">\n <a class=\"govuk-service-navigation__link\" href=\"#/3\">\n \nNavigation item 3\n </a>\n </li>\n\n </ul>\n </nav>\n </div>\n\n <nav class=\"govuk-language-navigation\" aria-label=\"Language navigation\">\n <ul class=\"govuk-language-navigation__list\">\n <li class=\"govuk-language-navigation__list-item\">\n <span class=\"govuk-language-navigation__text\" lang=\"en\" aria-current=\"true\">English</span>\n </li>\n <li class=\"govuk-language-navigation__list-item\">\n <a class=\"govuk-language-navigation__link\" href=\"#/cy\" lang=\"cy\" hreflang=\"cy\" rel=\"alternate\">Cymraeg</a>\n </li>\n </ul>\n</nav></div>\n\n </section>"
666
+ },
667
+ {
668
+ "name": "with right-aligned language navigation",
669
+ "options": {
670
+ "serviceName": "Service name",
671
+ "navigation": [
672
+ {
673
+ "href": "#/1",
674
+ "text": "Navigation item 1",
675
+ "active": true
676
+ },
677
+ {
678
+ "href": "#/2",
679
+ "text": "Navigation item 2"
680
+ },
681
+ {
682
+ "href": "#/3",
683
+ "text": "Navigation item 3"
684
+ }
685
+ ],
686
+ "slots": {
687
+ "end": {
688
+ "align": "inline",
689
+ "html": "<nav class=\"govuk-language-navigation\" aria-label=\"Language navigation\">\n <ul class=\"govuk-language-navigation__list\">\n <li class=\"govuk-language-navigation__list-item\">\n <span class=\"govuk-language-navigation__text\" lang=\"en\" aria-current=\"true\">English</span>\n </li>\n <li class=\"govuk-language-navigation__list-item\">\n <a class=\"govuk-language-navigation__link\" href=\"#/cy\" lang=\"cy\" hreflang=\"cy\" rel=\"alternate\">Cymraeg</a>\n </li>\n </ul>\n</nav>"
690
+ }
691
+ }
692
+ },
693
+ "hidden": false,
694
+ "description": "HTML rendered by the language navigation component can be injected into the `end` slot of the service header.",
695
+ "pageTemplateOptions": {},
696
+ "screenshot": false,
697
+ "html": "<section aria-label=\"Service information\" class=\"govuk-service-navigation\"\ndata-module=\"govuk-service-navigation\"\n>\n <div class=\"govuk-width-container govuk-service-navigation__inlining-container\">\n\n <div class=\"govuk-service-navigation__container\">\n \n <span class=\"govuk-service-navigation__service-name\">\n <span class=\"govuk-service-navigation__text\">Service name</span>\n </span>\n\n \n <nav aria-label=\"Menu\" class=\"govuk-service-navigation__wrapper\">\n <button type=\"button\" class=\"govuk-service-navigation__toggle govuk-js-service-navigation-toggle\" aria-controls=\"navigation\" hidden aria-hidden=\"true\">\n Menu\n </button>\n\n <ul class=\"govuk-service-navigation__list\" id=\"navigation\" >\n\n \n \n <li class=\"govuk-service-navigation__item govuk-service-navigation__item--active\">\n <a class=\"govuk-service-navigation__link\" href=\"#/1\" aria-current=\"true\">\n \n <strong class=\"govuk-service-navigation__active-fallback\">Navigation item 1</strong>\n\n </a>\n </li>\n\n \n <li class=\"govuk-service-navigation__item\">\n <a class=\"govuk-service-navigation__link\" href=\"#/2\">\n \nNavigation item 2\n </a>\n </li>\n\n \n <li class=\"govuk-service-navigation__item\">\n <a class=\"govuk-service-navigation__link\" href=\"#/3\">\n \nNavigation item 3\n </a>\n </li>\n\n </ul>\n </nav>\n </div>\n\n <nav class=\"govuk-language-navigation\" aria-label=\"Language navigation\">\n <ul class=\"govuk-language-navigation__list\">\n <li class=\"govuk-language-navigation__list-item\">\n <span class=\"govuk-language-navigation__text\" lang=\"en\" aria-current=\"true\">English</span>\n </li>\n <li class=\"govuk-language-navigation__list-item\">\n <a class=\"govuk-language-navigation__link\" href=\"#/cy\" lang=\"cy\" hreflang=\"cy\" rel=\"alternate\">Cymraeg</a>\n </li>\n </ul>\n</nav></div>\n\n </section>"
698
+ },
699
+ {
700
+ "name": "inverse with language navigation",
701
+ "options": {
702
+ "classes": "govuk-service-navigation--inverse",
703
+ "serviceName": "Apply for a juggling license",
704
+ "serviceUrl": "#/",
705
+ "navigation": [
706
+ {
707
+ "href": "#/1",
708
+ "text": "Navigation item 1"
709
+ },
710
+ {
711
+ "href": "#/2",
712
+ "text": "Navigation item 2",
713
+ "active": true
714
+ },
715
+ {
716
+ "href": "#/3",
717
+ "text": "Navigation item 3"
718
+ },
719
+ {
720
+ "href": "#/4",
721
+ "text": "Navigation item 4"
722
+ }
723
+ ],
724
+ "slots": {
725
+ "end": "<nav class=\"govuk-language-navigation govuk-language-navigation--inverse\" aria-label=\"Language navigation\">\n <ul class=\"govuk-language-navigation__list\">\n <li class=\"govuk-language-navigation__list-item\">\n <span class=\"govuk-language-navigation__text\" lang=\"en\" aria-current=\"true\">English</span>\n </li>\n <li class=\"govuk-language-navigation__list-item\">\n <a class=\"govuk-language-navigation__link\" href=\"#/cy\" lang=\"cy\" hreflang=\"cy\" rel=\"alternate\">Cymraeg</a>\n </li>\n </ul>\n</nav>"
726
+ }
727
+ },
728
+ "hidden": false,
729
+ "description": "Service navigation that appears sandwiched between other areas of brand blue, such as the GOV.UK header and a custom page masthead.",
730
+ "pageTemplateOptions": {
731
+ "bodyClasses": "app-template__body--inverse"
732
+ },
733
+ "screenshot": false,
734
+ "html": "<section aria-label=\"Service information\" class=\"govuk-service-navigation govuk-service-navigation--inverse\"\ndata-module=\"govuk-service-navigation\"\n>\n <div class=\"govuk-width-container\">\n\n <div class=\"govuk-service-navigation__container\">\n \n <span class=\"govuk-service-navigation__service-name\">\n <a href=\"#/\" class=\"govuk-service-navigation__link\">\n Apply for a juggling license\n </a>\n </span>\n\n \n <nav aria-label=\"Menu\" class=\"govuk-service-navigation__wrapper\">\n <button type=\"button\" class=\"govuk-service-navigation__toggle govuk-js-service-navigation-toggle\" aria-controls=\"navigation\" hidden aria-hidden=\"true\">\n Menu\n </button>\n\n <ul class=\"govuk-service-navigation__list\" id=\"navigation\" >\n\n \n \n <li class=\"govuk-service-navigation__item\">\n <a class=\"govuk-service-navigation__link\" href=\"#/1\">\n \nNavigation item 1\n </a>\n </li>\n\n \n <li class=\"govuk-service-navigation__item govuk-service-navigation__item--active\">\n <a class=\"govuk-service-navigation__link\" href=\"#/2\" aria-current=\"true\">\n \n <strong class=\"govuk-service-navigation__active-fallback\">Navigation item 2</strong>\n\n </a>\n </li>\n\n \n <li class=\"govuk-service-navigation__item\">\n <a class=\"govuk-service-navigation__link\" href=\"#/3\">\n \nNavigation item 3\n </a>\n </li>\n\n \n <li class=\"govuk-service-navigation__item\">\n <a class=\"govuk-service-navigation__link\" href=\"#/4\">\n \nNavigation item 4\n </a>\n </li>\n\n </ul>\n </nav>\n </div>\n\n <nav class=\"govuk-language-navigation govuk-language-navigation--inverse\" aria-label=\"Language navigation\">\n <ul class=\"govuk-language-navigation__list\">\n <li class=\"govuk-language-navigation__list-item\">\n <span class=\"govuk-language-navigation__text\" lang=\"en\" aria-current=\"true\">English</span>\n </li>\n <li class=\"govuk-language-navigation__list-item\">\n <a class=\"govuk-language-navigation__link\" href=\"#/cy\" lang=\"cy\" hreflang=\"cy\" rel=\"alternate\">Cymraeg</a>\n </li>\n </ul>\n</nav></div>\n\n </section>"
735
+ },
638
736
  {
639
737
  "name": "with slotted content",
640
738
  "options": {
@@ -650,6 +748,29 @@
650
748
  "pageTemplateOptions": {},
651
749
  "screenshot": false,
652
750
  "html": "<section aria-label=\"Service information\" class=\"govuk-service-navigation\"\ndata-module=\"govuk-service-navigation\"\n>\n <div class=\"govuk-width-container\">\n\n <div>[start]</div><div class=\"govuk-service-navigation__container\">\n \n\n \n <nav aria-label=\"Menu\" class=\"govuk-service-navigation__wrapper\">\n\n <ul class=\"govuk-service-navigation__list\" id=\"navigation\" >\n\n <li>[navigation start]</li>\n <li>[navigation end]</li></ul>\n </nav>\n </div>\n\n <div>[end]</div></div>\n\n </section>"
751
+ },
752
+ {
753
+ "name": "with `inline` end slot",
754
+ "options": {
755
+ "serviceName": "Service name",
756
+ "navigation": [
757
+ {
758
+ "href": "#/1",
759
+ "text": "Navigation item 1"
760
+ }
761
+ ],
762
+ "slots": {
763
+ "end": {
764
+ "html": "<div>[end]</div>",
765
+ "align": "inline"
766
+ }
767
+ }
768
+ },
769
+ "hidden": false,
770
+ "description": "",
771
+ "pageTemplateOptions": {},
772
+ "screenshot": false,
773
+ "html": "<section aria-label=\"Service information\" class=\"govuk-service-navigation\"\ndata-module=\"govuk-service-navigation\"\n>\n <div class=\"govuk-width-container govuk-service-navigation__inlining-container\">\n\n <div class=\"govuk-service-navigation__container\">\n \n <span class=\"govuk-service-navigation__service-name\">\n <span class=\"govuk-service-navigation__text\">Service name</span>\n </span>\n\n \n <nav aria-label=\"Menu\" class=\"govuk-service-navigation__wrapper\">\n\n <ul class=\"govuk-service-navigation__list\" id=\"navigation\" >\n\n \n \n <li class=\"govuk-service-navigation__item\">\n <a class=\"govuk-service-navigation__link\" href=\"#/1\">\n \nNavigation item 1\n </a>\n </li>\n\n </ul>\n </nav>\n </div>\n\n <div>[end]</div></div>\n\n </section>"
653
774
  }
654
775
  ],
655
776
  "previewLayout": "full-width"
@@ -127,6 +127,26 @@
127
127
  "required": false,
128
128
  "description": "HTML injected at the end of the service header container."
129
129
  },
130
+ {
131
+ "name": "end",
132
+ "type": "object",
133
+ "required": false,
134
+ "description": "Options for injecting HTML at the end of the service header container.",
135
+ "params": [
136
+ {
137
+ "name": "html",
138
+ "type": "string",
139
+ "required": false,
140
+ "description": "HTML injected at the end of the service header container."
141
+ },
142
+ {
143
+ "name": "align",
144
+ "type": "string",
145
+ "required": false,
146
+ "description": "By default, the `end` slot renders below the navigation items. Use `inline` to render it on the same line as the navigation items when space is available."
147
+ }
148
+ ]
149
+ },
130
150
  {
131
151
  "name": "navigationStart",
132
152
  "type": "string",
@@ -37,6 +37,9 @@
37
37
  function isObject(option) {
38
38
  return !!option && typeof option === 'object' && !isArray(option);
39
39
  }
40
+ function isScope($scope) {
41
+ return !!$scope && ($scope instanceof Element || $scope instanceof Document);
42
+ }
40
43
  function formatErrorMessage(Component, message) {
41
44
  return `${Component.moduleName}: ${message}`;
42
45
  }
@@ -55,11 +58,14 @@
55
58
  /**
56
59
  * Checks if GOV.UK Frontend is supported on this page
57
60
  *
58
- * @param {HTMLElement | null} [$scope] - HTML element `<body>` checked for browser support
61
+ * @param {Element | Document | null | string} [scopeOrMessage] - HTML element `<body>` checked for browser support or support error message
59
62
  */
60
- constructor($scope = document.body) {
61
- const supportMessage = 'noModule' in HTMLScriptElement.prototype ? 'GOV.UK Frontend initialised without `<body class="govuk-frontend-supported">` from template `<script>` snippet' : 'GOV.UK Frontend is not supported in this browser';
62
- super($scope ? supportMessage : 'GOV.UK Frontend initialised without `<script type="module">`');
63
+ constructor(scopeOrMessage = document.body) {
64
+ let supportMessage = 'noModule' in HTMLScriptElement.prototype ? 'GOV.UK Frontend initialised without `<body class="govuk-frontend-supported">` from template `<script>` snippet' : 'GOV.UK Frontend is not supported in this browser';
65
+ if (!isScope(scopeOrMessage)) {
66
+ supportMessage = 'GOV.UK Frontend initialised without `<script type="module">`';
67
+ }
68
+ super(typeof scopeOrMessage === 'string' ? scopeOrMessage : supportMessage);
63
69
  this.name = 'SupportError';
64
70
  }
65
71
  }
@@ -94,6 +100,7 @@
94
100
  * @import { ComponentWithModuleName } from '../common/index.mjs'
95
101
  */
96
102
 
103
+ const _self = typeof globalThis !== 'undefined' ? globalThis : self;
97
104
  class Component {
98
105
  /**
99
106
  * Returns the root element of the component
@@ -147,7 +154,7 @@
147
154
  /**
148
155
  * @typedef {typeof Component & ChildClass} ChildClassConstructor
149
156
  */
150
- Component.elementType = HTMLElement;
157
+ Component.elementType = _self.HTMLElement;
151
158
 
152
159
  /**
153
160
  * Service Navigation component