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
@@ -1 +1 @@
1
- {"version":3,"file":"file-upload.mjs","sources":["../../../../src/govuk/components/file-upload/file-upload.mjs"],"sourcesContent":["import { closestAttributeValue } from '../../common/closest-attribute-value.mjs'\nimport { ConfigurableComponent } from '../../common/configuration.mjs'\nimport { ElementError } from '../../errors/index.mjs'\nimport { I18n } from '../../i18n.mjs'\n\n/**\n * File upload component\n *\n * @preserve\n * @augments ConfigurableComponent<FileUploadConfig>\n */\nexport class FileUpload extends ConfigurableComponent {\n /**\n * @private\n * @type {HTMLFileInputElement}\n */\n $input\n\n /**\n * @private\n * @type {HTMLButtonElement}\n */\n $button\n\n /**\n * @private\n * @type {HTMLSpanElement}\n */\n $status\n\n /**\n * @private\n * @type {HTMLLabelElement}\n */\n $label\n\n /** @private */\n i18n\n\n /** @private */\n id\n\n /** @private */\n $announcements\n\n /**\n * @private\n * @type {boolean | undefined}\n */\n enteredAnotherElement\n\n /**\n * @param {Element | null} $root - File input element\n * @param {FileUploadConfig} [config] - File Upload config\n */\n constructor($root, config = {}) {\n super($root, config)\n\n const $input = this.$root.querySelector('input[type=\"file\"]')\n\n if ($input === null) {\n throw new ElementError({\n component: FileUpload,\n identifier: 'File inputs (`<input type=\"file\">`)'\n })\n }\n\n this.$input = /** @type {HTMLFileInputElement} */ ($input)\n\n if (!this.$input.id) {\n throw new ElementError({\n component: FileUpload,\n identifier: 'File input (`<input type=\"file\">`) attribute (`id`)'\n })\n }\n\n this.id = this.$input.id\n\n this.i18n = new I18n(this.config.i18n, {\n // Read the fallback if necessary rather than have it set in the defaults\n locale: closestAttributeValue(this.$root, 'lang')\n })\n\n const $label = this.findLabel()\n // Add an ID to the label if it doesn't have one already\n // so it can be referenced by `aria-labelledby`\n if (!$label.id) {\n $label.id = `${this.id}-label`\n }\n this.$label = $label\n\n // we need to copy the 'id' of the root element\n // to the new button replacement element\n // so that focus will work in the error summary\n this.$input.id = `${this.id}-input`\n\n // Hide the native input\n this.$input.setAttribute('hidden', 'hidden')\n\n // Inject status and button HTML\n // $status has to come first as it's used within `createButton()`\n this.$status = this.createStatus()\n this.$button = this.createButton()\n\n // Inject button into component\n this.$root.insertAdjacentElement('afterbegin', this.$button)\n\n // Bind change event to the underlying input\n this.$input.addEventListener('change', this.onChange.bind(this))\n\n // Synchronise the `disabled` state between the button and underlying input\n this.updateDisabledState()\n this.observeDisabledState()\n\n // Handle drop zone visibility\n // A live region to announce when users enter or leave the drop zone\n this.$announcements = document.createElement('span')\n this.$announcements.classList.add('govuk-file-upload-announcements')\n this.$announcements.classList.add('govuk-visually-hidden')\n this.$announcements.setAttribute('aria-live', 'assertive')\n this.$root.insertAdjacentElement('afterend', this.$announcements)\n\n // Bind all of the events relating to drag and drop functionality\n this.bindDraggingEvents()\n }\n\n /**\n * Create status element that shows what/how many files are selected\n *\n * @private\n * @returns {HTMLSpanElement} - the status element\n */\n createStatus() {\n const $status = document.createElement('span')\n $status.className = 'govuk-body govuk-file-upload-button__status'\n $status.setAttribute('aria-live', 'polite')\n $status.innerText = this.i18n.t('noFileChosen')\n\n return $status\n }\n\n /**\n * Assembles the button HTML element.\n *\n * @private\n * @returns {HTMLButtonElement} - the button element\n */\n createButton() {\n // Create the file selection button\n const $button = document.createElement('button')\n $button.classList.add('govuk-file-upload-button')\n $button.type = 'button'\n $button.id = this.id\n $button.classList.add('govuk-file-upload-button--empty')\n\n // Copy `aria-describedby` if present so hints and errors\n // are associated to the `<button>`\n const ariaDescribedBy = this.$input.getAttribute('aria-describedby')\n if (ariaDescribedBy) {\n $button.setAttribute('aria-describedby', ariaDescribedBy)\n }\n\n // Inject status element\n $button.appendChild(this.$status)\n\n const commaSpan = document.createElement('span')\n commaSpan.className = 'govuk-visually-hidden'\n commaSpan.innerText = ', '\n commaSpan.id = `${this.id}-comma`\n\n $button.appendChild(commaSpan)\n\n const containerSpan = document.createElement('span')\n containerSpan.className =\n 'govuk-file-upload-button__pseudo-button-container'\n\n const buttonSpan = document.createElement('span')\n buttonSpan.className =\n 'govuk-button govuk-button--secondary govuk-file-upload-button__pseudo-button'\n buttonSpan.innerText = this.i18n.t('chooseFilesButton')\n\n containerSpan.appendChild(buttonSpan)\n\n // Add a space so the button and instruction read correctly\n // when CSS is disabled\n containerSpan.insertAdjacentText('beforeend', ' ')\n\n const instructionSpan = document.createElement('span')\n instructionSpan.className =\n 'govuk-body govuk-file-upload-button__instruction'\n instructionSpan.innerText = this.i18n.t('dropInstruction')\n\n containerSpan.appendChild(instructionSpan)\n\n $button.appendChild(containerSpan)\n $button.setAttribute(\n 'aria-labelledby',\n `${this.$label.id} ${commaSpan.id} ${$button.id}`\n )\n $button.addEventListener('click', this.onClick.bind(this))\n $button.addEventListener('dragover', (event) => {\n // prevent default to allow drop\n event.preventDefault()\n })\n\n return $button\n }\n\n /**\n * Bind dragging events.\n *\n * @private\n */\n bindDraggingEvents() {\n // if there is no CSS and input is hidden\n // button will need to handle drop event\n this.$button.addEventListener('drop', this.onDrop.bind(this))\n\n // While user is dragging, it gets a little more complex because of Safari.\n // Safari doesn't fill `relatedTarget` on `dragleave` (nor `dragenter`).\n // This means we can't use `relatedTarget` to:\n // - check if the user is still within the wrapper\n // (`relatedTarget` being a descendant of the wrapper)\n // - check if the user is still over the viewport\n // (`relatedTarget` being null if outside)\n //\n // Thanks to `dragenter` bubbling, we can listen on the `document` with a\n // single function and update the visibility based on whether we entered a\n // node inside or outside the wrapper.\n document.addEventListener(\n 'dragenter',\n this.updateDropzoneVisibility.bind(this)\n )\n\n // To detect if we're outside the document, we can track if there was a\n // `dragenter` event preceding a `dragleave`. If there wasn't, this means\n // we're outside the document.\n //\n // The order of events is guaranteed by the HTML specs:\n // https://html.spec.whatwg.org/multipage/dnd.html#drag-and-drop-processing-model\n document.addEventListener('dragenter', () => {\n this.enteredAnotherElement = true\n })\n\n document.addEventListener('dragleave', () => {\n if (!this.enteredAnotherElement && !this.$button.disabled) {\n this.hideDraggingState()\n this.$announcements.innerText = this.i18n.t('leftDropZone')\n }\n\n this.enteredAnotherElement = false\n })\n }\n\n /**\n * Updates the visibility of the dropzone as users enters the various elements on the page\n *\n * @private\n * @param {DragEvent} event - The `dragenter` event\n */\n updateDropzoneVisibility(event) {\n if (this.$button.disabled) return\n\n // DOM interfaces only type `event.target` as `EventTarget`\n // so we first need to make sure it's a `Node`\n if (event.target instanceof Node) {\n if (this.$root.contains(event.target)) {\n if (event.dataTransfer && this.canDrop(event.dataTransfer)) {\n // Only update the class and make the announcement if not already visible\n // to avoid repeated announcements on NVDA (2024.4) + Firefox (133)\n if (\n !this.$button.classList.contains(\n 'govuk-file-upload-button--dragging'\n )\n ) {\n this.showDraggingState()\n this.$announcements.innerText = this.i18n.t('enteredDropZone')\n }\n }\n } else {\n // Only hide the dropzone if it is visible to prevent announcing user\n // left the drop zone when they enter the page but haven't reached yet\n // the file upload component\n if (\n this.$button.classList.contains('govuk-file-upload-button--dragging')\n ) {\n this.hideDraggingState()\n this.$announcements.innerText = this.i18n.t('leftDropZone')\n }\n }\n }\n }\n\n /**\n * Show the drop zone visually\n *\n * @private\n */\n showDraggingState() {\n this.$button.classList.add('govuk-file-upload-button--dragging')\n }\n\n /**\n * Hides the drop zone visually\n *\n * @private\n */\n hideDraggingState() {\n this.$button.classList.remove('govuk-file-upload-button--dragging')\n }\n\n /**\n * Handles user dropping on the component\n *\n * @private\n * @param {DragEvent} event - The `dragenter` event\n */\n onDrop(event) {\n event.preventDefault()\n\n if (event.dataTransfer && this.canFillInput(event.dataTransfer)) {\n this.$input.files = event.dataTransfer.files\n\n // Dispatch a `change` event so external code that would rely on the `<input>`\n // dispatching an event when files are dropped still work.\n // Use a `CustomEvent` so our events are distinguishable from browser's native events\n this.$input.dispatchEvent(new CustomEvent('change'))\n\n this.hideDraggingState()\n }\n }\n\n /**\n * Confirms if enhanced `<input>` can be filled with files from the given `DataTransfer`\n *\n * @param {DataTransfer} dataTransfer - The `DataTransfer` being dropped\n * @returns {boolean} - true if the `DataTransfer` contains files, in number matching the `multiple` attribute of the original `<input>`\n * @private\n */\n canFillInput(dataTransfer) {\n return this.matchesInputCapacity(dataTransfer.files.length)\n }\n\n /**\n * Confirms if the content of a `DataTransfer` dragged over component can be dropped\n *\n * Unfortunately, there's a certain level of uncertainty in Safari which does not\n * even provide a list of `items` while dragging (and seems to even miss the `types` sometimes)\n *\n * @param {DataTransfer} dataTransfer - The `DataTransfer` being dragged\n * @returns {boolean} - true if the `DataTransfer` looks OK for filling the input, false otherwise\n * @private\n */\n canDrop(dataTransfer) {\n // If the browser is kind enough to give a list of items, we'll use that as source of truth\n if (dataTransfer.items.length) {\n return this.matchesInputCapacity(countFileItems(dataTransfer.items))\n }\n\n // If we have some type information, we'll use that\n if (dataTransfer.types.length) {\n return dataTransfer.types.includes('Files')\n }\n\n // If we have nothing to go by, we'll assume things are OK\n // until we have a more accurate picture inside the `drop` event\n return true\n }\n\n /**\n * Confirms the given number of files matches that allowed by the enhanced `<input>`\n *\n * @param {number} numberOfFiles - The number of files\n * @returns {boolean} - `true` if the enhanced `<input>` can accept that number of files\n * @private\n */\n matchesInputCapacity(numberOfFiles) {\n if (this.$input.multiple) {\n return numberOfFiles > 0\n }\n\n return numberOfFiles === 1\n }\n\n /**\n * Check if the value of the underlying input has changed\n *\n * @private\n */\n onChange() {\n const fileCount = this.$input.files.length\n\n if (fileCount === 0) {\n // If there are no files, show the default selection text\n this.$status.innerText = this.i18n.t('noFileChosen')\n this.$button.classList.add('govuk-file-upload-button--empty')\n } else {\n if (\n // If there is 1 file, just show the file name\n fileCount === 1\n ) {\n this.$status.innerText = this.$input.files[0].name\n } else {\n // Otherwise, tell the user how many files are selected\n this.$status.innerText = this.i18n.t('multipleFilesChosen', {\n count: fileCount\n })\n }\n\n this.$button.classList.remove('govuk-file-upload-button--empty')\n }\n }\n\n /**\n * Looks up the `<label>` element associated to the field\n *\n * @private\n * @returns {HTMLLabelElement} The `<label>` element associated to the field\n * @throws {ElementError} If the `<label>` cannot be found\n */\n findLabel() {\n // Use `label` in the selector so TypeScript knows the type fo `HTMLElement`\n const $label = document.querySelector(`label[for=\"${this.$input.id}\"]`)\n\n if (!$label) {\n throw new ElementError({\n component: FileUpload,\n identifier: `Field label (\\`<label for=${this.$input.id}>\\`)`\n })\n }\n\n return $label\n }\n\n /**\n * When the button is clicked, emulate clicking the actual, hidden file input\n *\n * @private\n */\n onClick() {\n this.$input.click()\n }\n\n /**\n * Create a mutation observer to check if the input's attributes altered.\n *\n * @private\n */\n observeDisabledState() {\n const observer = new MutationObserver((mutationList) => {\n for (const mutation of mutationList) {\n if (\n mutation.type === 'attributes' &&\n mutation.attributeName === 'disabled'\n ) {\n this.updateDisabledState()\n }\n }\n })\n\n observer.observe(this.$input, {\n attributes: true\n })\n }\n\n /**\n * Synchronise the `disabled` state between the input and replacement button.\n *\n * @private\n */\n updateDisabledState() {\n this.$button.disabled = this.$input.disabled\n\n this.$root.classList.toggle(\n 'govuk-file-upload-wrapper--disabled',\n this.$button.disabled\n )\n }\n\n /**\n * Name for the component used when initialising using data-module attributes.\n */\n static moduleName = 'govuk-file-upload'\n\n /**\n * File upload default config\n *\n * @see {@link FileUploadConfig}\n * @constant\n * @type {FileUploadConfig}\n */\n static defaults = Object.freeze({\n i18n: {\n chooseFilesButton: 'Choose file',\n dropInstruction: 'or drop file',\n noFileChosen: 'No file chosen',\n multipleFilesChosen: {\n // the 'one' string isn't used as the component displays the filename\n // instead, however it's here for coverage's sake\n one: '%{count} file chosen',\n other: '%{count} files chosen'\n },\n enteredDropZone: 'Entered drop zone',\n leftDropZone: 'Left drop zone'\n }\n })\n\n /**\n * File upload config schema\n *\n * @constant\n * @satisfies {Schema<FileUploadConfig>}\n */\n static schema = Object.freeze({\n properties: {\n i18n: { type: 'object' }\n }\n })\n}\n\n/**\n * Counts the number of `DataTransferItem` whose kind is `file`\n *\n * @param {DataTransferItemList} list - The list\n * @returns {number} - The number of items whose kind is `file` in the list\n */\nfunction countFileItems(list) {\n let result = 0\n\n // `DataTransferItemList` is not iterable\n // eslint-disable-next-line @typescript-eslint/prefer-for-of\n for (let i = 0; i < list.length; i++) {\n if (list[i].kind === 'file') {\n result++\n }\n }\n return result\n}\n\n/**\n * @typedef {HTMLInputElement & {files: FileList}} HTMLFileInputElement\n */\n\n/**\n * File upload config\n *\n * @see {@link FileUpload.defaults}\n * @typedef {object} FileUploadConfig\n * @property {FileUploadTranslations} [i18n=FileUpload.defaults.i18n] - File upload translations\n */\n\n/**\n * File upload translations\n *\n * @see {@link FileUpload.defaults.i18n}\n * @typedef {object} FileUploadTranslations\n *\n * Messages used by the component\n * @property {string} [chooseFile] - The text of the button that opens the file picker\n * @property {string} [dropInstruction] - The text informing users they can drop files\n * @property {TranslationPluralForms} [multipleFilesChosen] - The text displayed when multiple files\n * have been chosen by the user\n * @property {string} [noFileChosen] - The text to displayed when no file has been chosen by the user\n * @property {string} [enteredDropZone] - The text announced by assistive technology\n * when user drags files and enters the drop zone\n * @property {string} [leftDropZone] - The text announced by assistive technology\n * when user drags files and leaves the drop zone without dropping\n */\n\n/**\n * @import { Schema } from '../../common/configuration.mjs'\n * @import { TranslationPluralForms } from '../../i18n.mjs'\n */\n"],"names":["FileUpload","ConfigurableComponent","constructor","$root","config","$input","$button","$status","$label","i18n","id","$announcements","enteredAnotherElement","querySelector","ElementError","component","identifier","I18n","locale","closestAttributeValue","findLabel","setAttribute","createStatus","createButton","insertAdjacentElement","addEventListener","onChange","bind","updateDisabledState","observeDisabledState","document","createElement","classList","add","bindDraggingEvents","className","innerText","t","type","ariaDescribedBy","getAttribute","appendChild","commaSpan","containerSpan","buttonSpan","insertAdjacentText","instructionSpan","onClick","event","preventDefault","onDrop","updateDropzoneVisibility","disabled","hideDraggingState","target","Node","contains","dataTransfer","canDrop","showDraggingState","remove","canFillInput","files","dispatchEvent","CustomEvent","matchesInputCapacity","length","items","countFileItems","types","includes","numberOfFiles","multiple","fileCount","name","count","click","observer","MutationObserver","mutationList","mutation","attributeName","observe","attributes","toggle","moduleName","defaults","Object","freeze","chooseFilesButton","dropInstruction","noFileChosen","multipleFilesChosen","one","other","enteredDropZone","leftDropZone","schema","properties","list","result","i","kind"],"mappings":"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"}
1
+ {"version":3,"file":"file-upload.mjs","sources":["../../../../src/govuk/components/file-upload/file-upload.mjs"],"sourcesContent":["import { closestAttributeValue } from '../../common/closest-attribute-value.mjs'\nimport { ConfigurableComponent } from '../../common/configuration.mjs'\nimport { createElement } from '../../common/create-element.mjs'\nimport { ElementError } from '../../errors/index.mjs'\nimport { I18n } from '../../i18n.mjs'\n\n/**\n * File upload component\n *\n * @preserve\n * @augments ConfigurableComponent<FileUploadConfig>\n */\nexport class FileUpload extends ConfigurableComponent {\n /**\n * @private\n * @type {HTMLFileInputElement}\n */\n $input\n\n /**\n * @private\n * @type {HTMLButtonElement}\n */\n $button\n\n /**\n * @private\n * @type {HTMLSpanElement}\n */\n $status\n\n /**\n * @private\n * @type {HTMLLabelElement}\n */\n $label\n\n /** @private */\n i18n\n\n /** @private */\n id\n\n /** @private */\n $announcements\n\n /**\n * @private\n * @type {boolean | undefined}\n */\n enteredAnotherElement\n\n /**\n * @param {Element | null} $root - File input element\n * @param {FileUploadConfig} [config] - File Upload config\n */\n constructor($root, config = {}) {\n super($root, config)\n\n const $input = this.$root.querySelector('input[type=\"file\"]')\n\n if ($input === null) {\n throw new ElementError({\n component: FileUpload,\n identifier: 'File inputs (`<input type=\"file\">`)'\n })\n }\n\n this.$input = /** @type {HTMLFileInputElement} */ ($input)\n\n if (!this.$input.id) {\n throw new ElementError({\n component: FileUpload,\n identifier: 'File input (`<input type=\"file\">`) attribute (`id`)'\n })\n }\n\n this.id = this.$input.id\n\n this.i18n = new I18n(this.config.i18n, {\n // Read the fallback if necessary rather than have it set in the defaults\n locale: closestAttributeValue(this.$root, 'lang')\n })\n\n const $label = this.findLabel()\n // Add an ID to the label if it doesn't have one already\n // so it can be referenced by `aria-labelledby`\n if (!$label.id) {\n $label.id = `${this.id}-label`\n }\n this.$label = $label\n\n // we need to copy the 'id' of the root element\n // to the new button replacement element\n // so that focus will work in the error summary\n this.$input.id = `${this.id}-input`\n\n // Hide the native input\n this.$input.setAttribute('hidden', 'hidden')\n\n // Inject status and button HTML\n // $status has to come first as it's used within `createButton()`\n this.$status = this.createStatus()\n this.$button = this.createButton()\n\n // Inject button into component\n this.$root.insertAdjacentElement('afterbegin', this.$button)\n\n // Bind change event to the underlying input\n this.$input.addEventListener('change', this.onChange.bind(this))\n\n // Synchronise the `disabled` state between the button and underlying input\n this.updateDisabledState()\n this.observeDisabledState()\n\n // Handle drop zone visibility\n // A live region to announce when users enter or leave the drop zone\n this.$announcements = createElement('span', {\n class: 'govuk-file-upload-announcements govuk-visually-hidden',\n 'aria-live': 'assertive'\n })\n\n this.$root.insertAdjacentElement('afterend', this.$announcements)\n\n // Bind all of the events relating to drag and drop functionality\n this.bindDraggingEvents()\n }\n\n /**\n * Create status element that shows what/how many files are selected\n *\n * @private\n * @returns {HTMLSpanElement} - the status element\n */\n createStatus() {\n const $status = createElement('span', {\n class: 'govuk-body govuk-file-upload-button__status',\n 'aria-live': 'polite'\n })\n $status.innerText = this.i18n.t('noFileChosen')\n\n return $status\n }\n\n /**\n * Assembles the button HTML element.\n *\n * @private\n * @returns {HTMLButtonElement} - the button element\n */\n createButton() {\n // Create the file selection button\n const $button = createElement('button', {\n class: 'govuk-file-upload-button govuk-file-upload-button--empty',\n type: 'button',\n id: this.id\n })\n\n // Copy `aria-describedby` if present so hints and errors\n // are associated to the `<button>`\n const ariaDescribedBy = this.$input.getAttribute('aria-describedby')\n if (ariaDescribedBy) {\n $button.setAttribute('aria-describedby', ariaDescribedBy)\n }\n\n // Inject status element\n $button.appendChild(this.$status)\n\n const commaSpan = createElement(\n 'span',\n {\n class: 'govuk-visually-hidden',\n id: `${this.id}-comma`\n },\n [', ']\n )\n\n $button.appendChild(commaSpan)\n\n const containerSpan = createElement('span', {\n class: 'govuk-file-upload-button__pseudo-button-container'\n })\n\n const buttonSpan = createElement(\n 'span',\n {\n class:\n 'govuk-button govuk-button--secondary govuk-file-upload-button__pseudo-button'\n },\n [this.i18n.t('chooseFilesButton')]\n )\n\n containerSpan.appendChild(buttonSpan)\n\n // Add a space so the button and instruction read correctly\n // when CSS is disabled\n containerSpan.insertAdjacentText('beforeend', ' ')\n\n const instructionSpan = createElement(\n 'span',\n {\n class: 'govuk-body govuk-file-upload-button__instruction'\n },\n [this.i18n.t('dropInstruction')]\n )\n\n containerSpan.appendChild(instructionSpan)\n\n $button.appendChild(containerSpan)\n $button.setAttribute(\n 'aria-labelledby',\n `${this.$label.id} ${commaSpan.id} ${$button.id}`\n )\n $button.addEventListener('click', this.onClick.bind(this))\n $button.addEventListener('dragover', (event) => {\n // prevent default to allow drop\n event.preventDefault()\n })\n\n return $button\n }\n\n /**\n * Bind dragging events.\n *\n * @private\n */\n bindDraggingEvents() {\n // if there is no CSS and input is hidden\n // button will need to handle drop event\n this.$button.addEventListener('drop', this.onDrop.bind(this))\n\n // While user is dragging, it gets a little more complex because of Safari.\n // Safari doesn't fill `relatedTarget` on `dragleave` (nor `dragenter`).\n // This means we can't use `relatedTarget` to:\n // - check if the user is still within the wrapper\n // (`relatedTarget` being a descendant of the wrapper)\n // - check if the user is still over the viewport\n // (`relatedTarget` being null if outside)\n //\n // Thanks to `dragenter` bubbling, we can listen on the `document` with a\n // single function and update the visibility based on whether we entered a\n // node inside or outside the wrapper.\n document.addEventListener(\n 'dragenter',\n this.updateDropzoneVisibility.bind(this)\n )\n\n // To detect if we're outside the document, we can track if there was a\n // `dragenter` event preceding a `dragleave`. If there wasn't, this means\n // we're outside the document.\n //\n // The order of events is guaranteed by the HTML specs:\n // https://html.spec.whatwg.org/multipage/dnd.html#drag-and-drop-processing-model\n document.addEventListener('dragenter', () => {\n this.enteredAnotherElement = true\n })\n\n document.addEventListener('dragleave', () => {\n if (!this.enteredAnotherElement && !this.$button.disabled) {\n this.hideDraggingState()\n this.$announcements.innerText = this.i18n.t('leftDropZone')\n }\n\n this.enteredAnotherElement = false\n })\n }\n\n /**\n * Updates the visibility of the dropzone as users enters the various elements on the page\n *\n * @private\n * @param {DragEvent} event - The `dragenter` event\n */\n updateDropzoneVisibility(event) {\n if (this.$button.disabled) return\n\n // DOM interfaces only type `event.target` as `EventTarget`\n // so we first need to make sure it's a `Node`\n if (event.target instanceof Node) {\n if (this.$root.contains(event.target)) {\n if (event.dataTransfer && this.canDrop(event.dataTransfer)) {\n // Only update the class and make the announcement if not already visible\n // to avoid repeated announcements on NVDA (2024.4) + Firefox (133)\n if (\n !this.$button.classList.contains(\n 'govuk-file-upload-button--dragging'\n )\n ) {\n this.showDraggingState()\n this.$announcements.innerText = this.i18n.t('enteredDropZone')\n }\n }\n } else {\n // Only hide the dropzone if it is visible to prevent announcing user\n // left the drop zone when they enter the page but haven't reached yet\n // the file upload component\n if (\n this.$button.classList.contains('govuk-file-upload-button--dragging')\n ) {\n this.hideDraggingState()\n this.$announcements.innerText = this.i18n.t('leftDropZone')\n }\n }\n }\n }\n\n /**\n * Show the drop zone visually\n *\n * @private\n */\n showDraggingState() {\n this.$button.classList.add('govuk-file-upload-button--dragging')\n }\n\n /**\n * Hides the drop zone visually\n *\n * @private\n */\n hideDraggingState() {\n this.$button.classList.remove('govuk-file-upload-button--dragging')\n }\n\n /**\n * Handles user dropping on the component\n *\n * @private\n * @param {DragEvent} event - The `dragenter` event\n */\n onDrop(event) {\n event.preventDefault()\n\n if (event.dataTransfer && this.canFillInput(event.dataTransfer)) {\n this.$input.files = event.dataTransfer.files\n\n // Dispatch a `change` event so external code that would rely on the `<input>`\n // dispatching an event when files are dropped still work.\n // Use a `CustomEvent` so our events are distinguishable from browser's native events\n this.$input.dispatchEvent(new CustomEvent('change'))\n\n this.hideDraggingState()\n }\n }\n\n /**\n * Confirms if enhanced `<input>` can be filled with files from the given `DataTransfer`\n *\n * @param {DataTransfer} dataTransfer - The `DataTransfer` being dropped\n * @returns {boolean} - true if the `DataTransfer` contains files, in number matching the `multiple` attribute of the original `<input>`\n * @private\n */\n canFillInput(dataTransfer) {\n return this.matchesInputCapacity(dataTransfer.files.length)\n }\n\n /**\n * Confirms if the content of a `DataTransfer` dragged over component can be dropped\n *\n * Unfortunately, there's a certain level of uncertainty in Safari which does not\n * even provide a list of `items` while dragging (and seems to even miss the `types` sometimes)\n *\n * @param {DataTransfer} dataTransfer - The `DataTransfer` being dragged\n * @returns {boolean} - true if the `DataTransfer` looks OK for filling the input, false otherwise\n * @private\n */\n canDrop(dataTransfer) {\n // If the browser is kind enough to give a list of items, we'll use that as source of truth\n if (dataTransfer.items.length) {\n return this.matchesInputCapacity(countFileItems(dataTransfer.items))\n }\n\n // If we have some type information, we'll use that\n if (dataTransfer.types.length) {\n return dataTransfer.types.includes('Files')\n }\n\n // If we have nothing to go by, we'll assume things are OK\n // until we have a more accurate picture inside the `drop` event\n return true\n }\n\n /**\n * Confirms the given number of files matches that allowed by the enhanced `<input>`\n *\n * @param {number} numberOfFiles - The number of files\n * @returns {boolean} - `true` if the enhanced `<input>` can accept that number of files\n * @private\n */\n matchesInputCapacity(numberOfFiles) {\n if (this.$input.multiple) {\n return numberOfFiles > 0\n }\n\n return numberOfFiles === 1\n }\n\n /**\n * Check if the value of the underlying input has changed\n *\n * @private\n */\n onChange() {\n const fileCount = this.$input.files.length\n\n if (fileCount === 0) {\n // If there are no files, show the default selection text\n this.$status.innerText = this.i18n.t('noFileChosen')\n this.$button.classList.add('govuk-file-upload-button--empty')\n } else {\n if (\n // If there is 1 file, just show the file name\n fileCount === 1\n ) {\n this.$status.innerText = this.$input.files[0].name\n } else {\n // Otherwise, tell the user how many files are selected\n this.$status.innerText = this.i18n.t('multipleFilesChosen', {\n count: fileCount\n })\n }\n\n this.$button.classList.remove('govuk-file-upload-button--empty')\n }\n }\n\n /**\n * Looks up the `<label>` element associated to the field\n *\n * @private\n * @returns {HTMLLabelElement} The `<label>` element associated to the field\n * @throws {ElementError} If the `<label>` cannot be found\n */\n findLabel() {\n // Use `label` in the selector so TypeScript knows the type fo `HTMLElement`\n const $label = document.querySelector(`label[for=\"${this.$input.id}\"]`)\n\n if (!$label) {\n throw new ElementError({\n component: FileUpload,\n identifier: `Field label (\\`<label for=${this.$input.id}>\\`)`\n })\n }\n\n return $label\n }\n\n /**\n * When the button is clicked, emulate clicking the actual, hidden file input\n *\n * @private\n */\n onClick() {\n this.$input.click()\n }\n\n /**\n * Create a mutation observer to check if the input's attributes altered.\n *\n * @private\n */\n observeDisabledState() {\n const observer = new MutationObserver((mutationList) => {\n for (const mutation of mutationList) {\n if (\n mutation.type === 'attributes' &&\n mutation.attributeName === 'disabled'\n ) {\n this.updateDisabledState()\n }\n }\n })\n\n observer.observe(this.$input, {\n attributes: true\n })\n }\n\n /**\n * Synchronise the `disabled` state between the input and replacement button.\n *\n * @private\n */\n updateDisabledState() {\n this.$button.disabled = this.$input.disabled\n\n this.$root.classList.toggle(\n 'govuk-file-upload-wrapper--disabled',\n this.$button.disabled\n )\n }\n\n /**\n * Name for the component used when initialising using data-module attributes.\n */\n static moduleName = 'govuk-file-upload'\n\n /**\n * File upload default config\n *\n * @see {@link FileUploadConfig}\n * @constant\n * @type {FileUploadConfig}\n */\n static defaults = Object.freeze({\n i18n: {\n chooseFilesButton: 'Choose file',\n dropInstruction: 'or drop file',\n noFileChosen: 'No file chosen',\n multipleFilesChosen: {\n // the 'one' string isn't used as the component displays the filename\n // instead, however it's here for coverage's sake\n one: '%{count} file chosen',\n other: '%{count} files chosen'\n },\n enteredDropZone: 'Entered drop zone',\n leftDropZone: 'Left drop zone'\n }\n })\n\n /**\n * File upload config schema\n *\n * @constant\n * @satisfies {Schema<FileUploadConfig>}\n */\n static schema = Object.freeze({\n properties: {\n i18n: { type: 'object' }\n }\n })\n}\n\n/**\n * Counts the number of `DataTransferItem` whose kind is `file`\n *\n * @param {DataTransferItemList} list - The list\n * @returns {number} - The number of items whose kind is `file` in the list\n */\nfunction countFileItems(list) {\n let result = 0\n\n // `DataTransferItemList` is not iterable\n // eslint-disable-next-line @typescript-eslint/prefer-for-of\n for (let i = 0; i < list.length; i++) {\n if (list[i].kind === 'file') {\n result++\n }\n }\n return result\n}\n\n/**\n * @typedef {HTMLInputElement & {files: FileList}} HTMLFileInputElement\n */\n\n/**\n * File upload config\n *\n * @see {@link FileUpload.defaults}\n * @typedef {object} FileUploadConfig\n * @property {FileUploadTranslations} [i18n=FileUpload.defaults.i18n] - File upload translations\n */\n\n/**\n * File upload translations\n *\n * @see {@link FileUpload.defaults.i18n}\n * @typedef {object} FileUploadTranslations\n *\n * Messages used by the component\n * @property {string} [chooseFile] - The text of the button that opens the file picker\n * @property {string} [dropInstruction] - The text informing users they can drop files\n * @property {TranslationPluralForms} [multipleFilesChosen] - The text displayed when multiple files\n * have been chosen by the user\n * @property {string} [noFileChosen] - The text to displayed when no file has been chosen by the user\n * @property {string} [enteredDropZone] - The text announced by assistive technology\n * when user drags files and enters the drop zone\n * @property {string} [leftDropZone] - The text announced by assistive technology\n * when user drags files and leaves the drop zone without dropping\n */\n\n/**\n * @import { Schema } from '../../common/configuration.mjs'\n * @import { TranslationPluralForms } from '../../i18n.mjs'\n */\n"],"names":["FileUpload","ConfigurableComponent","constructor","$root","config","$input","$button","$status","$label","i18n","id","$announcements","enteredAnotherElement","querySelector","ElementError","component","identifier","I18n","locale","closestAttributeValue","findLabel","setAttribute","createStatus","createButton","insertAdjacentElement","addEventListener","onChange","bind","updateDisabledState","observeDisabledState","createElement","class","bindDraggingEvents","innerText","t","type","ariaDescribedBy","getAttribute","appendChild","commaSpan","containerSpan","buttonSpan","insertAdjacentText","instructionSpan","onClick","event","preventDefault","onDrop","document","updateDropzoneVisibility","disabled","hideDraggingState","target","Node","contains","dataTransfer","canDrop","classList","showDraggingState","add","remove","canFillInput","files","dispatchEvent","CustomEvent","matchesInputCapacity","length","items","countFileItems","types","includes","numberOfFiles","multiple","fileCount","name","count","click","observer","MutationObserver","mutationList","mutation","attributeName","observe","attributes","toggle","moduleName","defaults","Object","freeze","chooseFilesButton","dropInstruction","noFileChosen","multipleFilesChosen","one","other","enteredDropZone","leftDropZone","schema","properties","list","result","i","kind"],"mappings":";;;;;;AAMA;AACA;AACA;AACA;AACA;AACA;AACO,MAAMA,UAAU,SAASC,qBAAqB,CAAC;AAwCpD;AACF;AACA;AACA;AACEC,EAAAA,WAAWA,CAACC,KAAK,EAAEC,MAAM,GAAG,EAAE,EAAE;AAC9B,IAAA,KAAK,CAACD,KAAK,EAAEC,MAAM,CAAC;AAAA,IAAA,IAAA,CAxCtBC,MAAM,GAAA,MAAA;AAAA,IAAA,IAAA,CAMNC,OAAO,GAAA,MAAA;AAAA,IAAA,IAAA,CAMPC,OAAO,GAAA,MAAA;AAAA,IAAA,IAAA,CAMPC,MAAM,GAAA,MAAA;AAAA,IAAA,IAAA,CAGNC,IAAI,GAAA,MAAA;AAAA,IAAA,IAAA,CAGJC,EAAE,GAAA,MAAA;AAAA,IAAA,IAAA,CAGFC,cAAc,GAAA,MAAA;AAAA,IAAA,IAAA,CAMdC,qBAAqB,GAAA,MAAA;IASnB,MAAMP,MAAM,GAAG,IAAI,CAACF,KAAK,CAACU,aAAa,CAAC,oBAAoB,CAAC;IAE7D,IAAIR,MAAM,KAAK,IAAI,EAAE;MACnB,MAAM,IAAIS,YAAY,CAAC;AACrBC,QAAAA,SAAS,EAAEf,UAAU;AACrBgB,QAAAA,UAAU,EAAE;AACd,OAAC,CAAC;AACJ,IAAA;IAEA,IAAI,CAACX,MAAM,GAAwCA,MAAO;AAE1D,IAAA,IAAI,CAAC,IAAI,CAACA,MAAM,CAACK,EAAE,EAAE;MACnB,MAAM,IAAII,YAAY,CAAC;AACrBC,QAAAA,SAAS,EAAEf,UAAU;AACrBgB,QAAAA,UAAU,EAAE;AACd,OAAC,CAAC;AACJ,IAAA;AAEA,IAAA,IAAI,CAACN,EAAE,GAAG,IAAI,CAACL,MAAM,CAACK,EAAE;IAExB,IAAI,CAACD,IAAI,GAAG,IAAIQ,IAAI,CAAC,IAAI,CAACb,MAAM,CAACK,IAAI,EAAE;AAErCS,MAAAA,MAAM,EAAEC,qBAAqB,CAAC,IAAI,CAAChB,KAAK,EAAE,MAAM;AAClD,KAAC,CAAC;AAEF,IAAA,MAAMK,MAAM,GAAG,IAAI,CAACY,SAAS,EAAE;AAG/B,IAAA,IAAI,CAACZ,MAAM,CAACE,EAAE,EAAE;AACdF,MAAAA,MAAM,CAACE,EAAE,GAAG,GAAG,IAAI,CAACA,EAAE,CAAA,MAAA,CAAQ;AAChC,IAAA;IACA,IAAI,CAACF,MAAM,GAAGA,MAAM;IAKpB,IAAI,CAACH,MAAM,CAACK,EAAE,GAAG,CAAA,EAAG,IAAI,CAACA,EAAE,CAAA,MAAA,CAAQ;IAGnC,IAAI,CAACL,MAAM,CAACgB,YAAY,CAAC,QAAQ,EAAE,QAAQ,CAAC;AAI5C,IAAA,IAAI,CAACd,OAAO,GAAG,IAAI,CAACe,YAAY,EAAE;AAClC,IAAA,IAAI,CAAChB,OAAO,GAAG,IAAI,CAACiB,YAAY,EAAE;IAGlC,IAAI,CAACpB,KAAK,CAACqB,qBAAqB,CAAC,YAAY,EAAE,IAAI,CAAClB,OAAO,CAAC;AAG5D,IAAA,IAAI,CAACD,MAAM,CAACoB,gBAAgB,CAAC,QAAQ,EAAE,IAAI,CAACC,QAAQ,CAACC,IAAI,CAAC,IAAI,CAAC,CAAC;IAGhE,IAAI,CAACC,mBAAmB,EAAE;IAC1B,IAAI,CAACC,oBAAoB,EAAE;AAI3B,IAAA,IAAI,CAAClB,cAAc,GAAGmB,aAAa,CAAC,MAAM,EAAE;AAC1CC,MAAAA,KAAK,EAAE,uDAAuD;AAC9D,MAAA,WAAW,EAAE;AACf,KAAC,CAAC;IAEF,IAAI,CAAC5B,KAAK,CAACqB,qBAAqB,CAAC,UAAU,EAAE,IAAI,CAACb,cAAc,CAAC;IAGjE,IAAI,CAACqB,kBAAkB,EAAE;AAC3B,EAAA;AAQAV,EAAAA,YAAYA,GAAG;AACb,IAAA,MAAMf,OAAO,GAAGuB,aAAa,CAAC,MAAM,EAAE;AACpCC,MAAAA,KAAK,EAAE,6CAA6C;AACpD,MAAA,WAAW,EAAE;AACf,KAAC,CAAC;IACFxB,OAAO,CAAC0B,SAAS,GAAG,IAAI,CAACxB,IAAI,CAACyB,CAAC,CAAC,cAAc,CAAC;AAE/C,IAAA,OAAO3B,OAAO;AAChB,EAAA;AAQAgB,EAAAA,YAAYA,GAAG;AAEb,IAAA,MAAMjB,OAAO,GAAGwB,aAAa,CAAC,QAAQ,EAAE;AACtCC,MAAAA,KAAK,EAAE,0DAA0D;AACjEI,MAAAA,IAAI,EAAE,QAAQ;MACdzB,EAAE,EAAE,IAAI,CAACA;AACX,KAAC,CAAC;IAIF,MAAM0B,eAAe,GAAG,IAAI,CAAC/B,MAAM,CAACgC,YAAY,CAAC,kBAAkB,CAAC;AACpE,IAAA,IAAID,eAAe,EAAE;AACnB9B,MAAAA,OAAO,CAACe,YAAY,CAAC,kBAAkB,EAAEe,eAAe,CAAC;AAC3D,IAAA;AAGA9B,IAAAA,OAAO,CAACgC,WAAW,CAAC,IAAI,CAAC/B,OAAO,CAAC;AAEjC,IAAA,MAAMgC,SAAS,GAAGT,aAAa,CAC7B,MAAM,EACN;AACEC,MAAAA,KAAK,EAAE,uBAAuB;AAC9BrB,MAAAA,EAAE,EAAE,CAAA,EAAG,IAAI,CAACA,EAAE,CAAA,MAAA;AAChB,KAAC,EACD,CAAC,IAAI,CACP,CAAC;AAEDJ,IAAAA,OAAO,CAACgC,WAAW,CAACC,SAAS,CAAC;AAE9B,IAAA,MAAMC,aAAa,GAAGV,aAAa,CAAC,MAAM,EAAE;AAC1CC,MAAAA,KAAK,EAAE;AACT,KAAC,CAAC;AAEF,IAAA,MAAMU,UAAU,GAAGX,aAAa,CAC9B,MAAM,EACN;AACEC,MAAAA,KAAK,EACH;KACH,EACD,CAAC,IAAI,CAACtB,IAAI,CAACyB,CAAC,CAAC,mBAAmB,CAAC,CACnC,CAAC;AAEDM,IAAAA,aAAa,CAACF,WAAW,CAACG,UAAU,CAAC;AAIrCD,IAAAA,aAAa,CAACE,kBAAkB,CAAC,WAAW,EAAE,GAAG,CAAC;AAElD,IAAA,MAAMC,eAAe,GAAGb,aAAa,CACnC,MAAM,EACN;AACEC,MAAAA,KAAK,EAAE;KACR,EACD,CAAC,IAAI,CAACtB,IAAI,CAACyB,CAAC,CAAC,iBAAiB,CAAC,CACjC,CAAC;AAEDM,IAAAA,aAAa,CAACF,WAAW,CAACK,eAAe,CAAC;AAE1CrC,IAAAA,OAAO,CAACgC,WAAW,CAACE,aAAa,CAAC;IAClClC,OAAO,CAACe,YAAY,CAClB,iBAAiB,EACjB,CAAA,EAAG,IAAI,CAACb,MAAM,CAACE,EAAE,CAAA,CAAA,EAAI6B,SAAS,CAAC7B,EAAE,CAAA,CAAA,EAAIJ,OAAO,CAACI,EAAE,EACjD,CAAC;AACDJ,IAAAA,OAAO,CAACmB,gBAAgB,CAAC,OAAO,EAAE,IAAI,CAACmB,OAAO,CAACjB,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1DrB,IAAAA,OAAO,CAACmB,gBAAgB,CAAC,UAAU,EAAGoB,KAAK,IAAK;MAE9CA,KAAK,CAACC,cAAc,EAAE;AACxB,IAAA,CAAC,CAAC;AAEF,IAAA,OAAOxC,OAAO;AAChB,EAAA;AAOA0B,EAAAA,kBAAkBA,GAAG;AAGnB,IAAA,IAAI,CAAC1B,OAAO,CAACmB,gBAAgB,CAAC,MAAM,EAAE,IAAI,CAACsB,MAAM,CAACpB,IAAI,CAAC,IAAI,CAAC,CAAC;AAa7DqB,IAAAA,QAAQ,CAACvB,gBAAgB,CACvB,WAAW,EACX,IAAI,CAACwB,wBAAwB,CAACtB,IAAI,CAAC,IAAI,CACzC,CAAC;AAQDqB,IAAAA,QAAQ,CAACvB,gBAAgB,CAAC,WAAW,EAAE,MAAM;MAC3C,IAAI,CAACb,qBAAqB,GAAG,IAAI;AACnC,IAAA,CAAC,CAAC;AAEFoC,IAAAA,QAAQ,CAACvB,gBAAgB,CAAC,WAAW,EAAE,MAAM;MAC3C,IAAI,CAAC,IAAI,CAACb,qBAAqB,IAAI,CAAC,IAAI,CAACN,OAAO,CAAC4C,QAAQ,EAAE;QACzD,IAAI,CAACC,iBAAiB,EAAE;AACxB,QAAA,IAAI,CAACxC,cAAc,CAACsB,SAAS,GAAG,IAAI,CAACxB,IAAI,CAACyB,CAAC,CAAC,cAAc,CAAC;AAC7D,MAAA;MAEA,IAAI,CAACtB,qBAAqB,GAAG,KAAK;AACpC,IAAA,CAAC,CAAC;AACJ,EAAA;EAQAqC,wBAAwBA,CAACJ,KAAK,EAAE;AAC9B,IAAA,IAAI,IAAI,CAACvC,OAAO,CAAC4C,QAAQ,EAAE;AAI3B,IAAA,IAAIL,KAAK,CAACO,MAAM,YAAYC,IAAI,EAAE;MAChC,IAAI,IAAI,CAAClD,KAAK,CAACmD,QAAQ,CAACT,KAAK,CAACO,MAAM,CAAC,EAAE;AACrC,QAAA,IAAIP,KAAK,CAACU,YAAY,IAAI,IAAI,CAACC,OAAO,CAACX,KAAK,CAACU,YAAY,CAAC,EAAE;UAG1D,IACE,CAAC,IAAI,CAACjD,OAAO,CAACmD,SAAS,CAACH,QAAQ,CAC9B,oCACF,CAAC,EACD;YACA,IAAI,CAACI,iBAAiB,EAAE;AACxB,YAAA,IAAI,CAAC/C,cAAc,CAACsB,SAAS,GAAG,IAAI,CAACxB,IAAI,CAACyB,CAAC,CAAC,iBAAiB,CAAC;AAChE,UAAA;AACF,QAAA;AACF,MAAA,CAAC,MAAM;QAIL,IACE,IAAI,CAAC5B,OAAO,CAACmD,SAAS,CAACH,QAAQ,CAAC,oCAAoC,CAAC,EACrE;UACA,IAAI,CAACH,iBAAiB,EAAE;AACxB,UAAA,IAAI,CAACxC,cAAc,CAACsB,SAAS,GAAG,IAAI,CAACxB,IAAI,CAACyB,CAAC,CAAC,cAAc,CAAC;AAC7D,QAAA;AACF,MAAA;AACF,IAAA;AACF,EAAA;AAOAwB,EAAAA,iBAAiBA,GAAG;IAClB,IAAI,CAACpD,OAAO,CAACmD,SAAS,CAACE,GAAG,CAAC,oCAAoC,CAAC;AAClE,EAAA;AAOAR,EAAAA,iBAAiBA,GAAG;IAClB,IAAI,CAAC7C,OAAO,CAACmD,SAAS,CAACG,MAAM,CAAC,oCAAoC,CAAC;AACrE,EAAA;EAQAb,MAAMA,CAACF,KAAK,EAAE;IACZA,KAAK,CAACC,cAAc,EAAE;AAEtB,IAAA,IAAID,KAAK,CAACU,YAAY,IAAI,IAAI,CAACM,YAAY,CAAChB,KAAK,CAACU,YAAY,CAAC,EAAE;MAC/D,IAAI,CAAClD,MAAM,CAACyD,KAAK,GAAGjB,KAAK,CAACU,YAAY,CAACO,KAAK;MAK5C,IAAI,CAACzD,MAAM,CAAC0D,aAAa,CAAC,IAAIC,WAAW,CAAC,QAAQ,CAAC,CAAC;MAEpD,IAAI,CAACb,iBAAiB,EAAE;AAC1B,IAAA;AACF,EAAA;EASAU,YAAYA,CAACN,YAAY,EAAE;IACzB,OAAO,IAAI,CAACU,oBAAoB,CAACV,YAAY,CAACO,KAAK,CAACI,MAAM,CAAC;AAC7D,EAAA;EAYAV,OAAOA,CAACD,YAAY,EAAE;AAEpB,IAAA,IAAIA,YAAY,CAACY,KAAK,CAACD,MAAM,EAAE;MAC7B,OAAO,IAAI,CAACD,oBAAoB,CAACG,cAAc,CAACb,YAAY,CAACY,KAAK,CAAC,CAAC;AACtE,IAAA;AAGA,IAAA,IAAIZ,YAAY,CAACc,KAAK,CAACH,MAAM,EAAE;AAC7B,MAAA,OAAOX,YAAY,CAACc,KAAK,CAACC,QAAQ,CAAC,OAAO,CAAC;AAC7C,IAAA;AAIA,IAAA,OAAO,IAAI;AACb,EAAA;EASAL,oBAAoBA,CAACM,aAAa,EAAE;AAClC,IAAA,IAAI,IAAI,CAAClE,MAAM,CAACmE,QAAQ,EAAE;MACxB,OAAOD,aAAa,GAAG,CAAC;AAC1B,IAAA;IAEA,OAAOA,aAAa,KAAK,CAAC;AAC5B,EAAA;AAOA7C,EAAAA,QAAQA,GAAG;IACT,MAAM+C,SAAS,GAAG,IAAI,CAACpE,MAAM,CAACyD,KAAK,CAACI,MAAM;IAE1C,IAAIO,SAAS,KAAK,CAAC,EAAE;AAEnB,MAAA,IAAI,CAAClE,OAAO,CAAC0B,SAAS,GAAG,IAAI,CAACxB,IAAI,CAACyB,CAAC,CAAC,cAAc,CAAC;MACpD,IAAI,CAAC5B,OAAO,CAACmD,SAAS,CAACE,GAAG,CAAC,iCAAiC,CAAC;AAC/D,IAAA,CAAC,MAAM;MACL,IAEEc,SAAS,KAAK,CAAC,EACf;AACA,QAAA,IAAI,CAAClE,OAAO,CAAC0B,SAAS,GAAG,IAAI,CAAC5B,MAAM,CAACyD,KAAK,CAAC,CAAC,CAAC,CAACY,IAAI;AACpD,MAAA,CAAC,MAAM;AAEL,QAAA,IAAI,CAACnE,OAAO,CAAC0B,SAAS,GAAG,IAAI,CAACxB,IAAI,CAACyB,CAAC,CAAC,qBAAqB,EAAE;AAC1DyC,UAAAA,KAAK,EAAEF;AACT,SAAC,CAAC;AACJ,MAAA;MAEA,IAAI,CAACnE,OAAO,CAACmD,SAAS,CAACG,MAAM,CAAC,iCAAiC,CAAC;AAClE,IAAA;AACF,EAAA;AASAxC,EAAAA,SAASA,GAAG;AAEV,IAAA,MAAMZ,MAAM,GAAGwC,QAAQ,CAACnC,aAAa,CAAC,CAAA,WAAA,EAAc,IAAI,CAACR,MAAM,CAACK,EAAE,IAAI,CAAC;IAEvE,IAAI,CAACF,MAAM,EAAE;MACX,MAAM,IAAIM,YAAY,CAAC;AACrBC,QAAAA,SAAS,EAAEf,UAAU;AACrBgB,QAAAA,UAAU,EAAE,CAAA,0BAAA,EAA6B,IAAI,CAACX,MAAM,CAACK,EAAE,CAAA,IAAA;AACzD,OAAC,CAAC;AACJ,IAAA;AAEA,IAAA,OAAOF,MAAM;AACf,EAAA;AAOAoC,EAAAA,OAAOA,GAAG;AACR,IAAA,IAAI,CAACvC,MAAM,CAACuE,KAAK,EAAE;AACrB,EAAA;AAOA/C,EAAAA,oBAAoBA,GAAG;AACrB,IAAA,MAAMgD,QAAQ,GAAG,IAAIC,gBAAgB,CAAEC,YAAY,IAAK;AACtD,MAAA,KAAK,MAAMC,QAAQ,IAAID,YAAY,EAAE;QACnC,IACEC,QAAQ,CAAC7C,IAAI,KAAK,YAAY,IAC9B6C,QAAQ,CAACC,aAAa,KAAK,UAAU,EACrC;UACA,IAAI,CAACrD,mBAAmB,EAAE;AAC5B,QAAA;AACF,MAAA;AACF,IAAA,CAAC,CAAC;AAEFiD,IAAAA,QAAQ,CAACK,OAAO,CAAC,IAAI,CAAC7E,MAAM,EAAE;AAC5B8E,MAAAA,UAAU,EAAE;AACd,KAAC,CAAC;AACJ,EAAA;AAOAvD,EAAAA,mBAAmBA,GAAG;IACpB,IAAI,CAACtB,OAAO,CAAC4C,QAAQ,GAAG,IAAI,CAAC7C,MAAM,CAAC6C,QAAQ;AAE5C,IAAA,IAAI,CAAC/C,KAAK,CAACsD,SAAS,CAAC2B,MAAM,CACzB,qCAAqC,EACrC,IAAI,CAAC9E,OAAO,CAAC4C,QACf,CAAC;AACH,EAAA;AAyCF;;AAEA;AACA;AACA;AACA;AACA;AACA;AA/gBalD,UAAU,CAoedqF,UAAU,GAAG,mBAAmB;AApe5BrF,UAAU,CA6edsF,QAAQ,GAAGC,MAAM,CAACC,MAAM,CAAC;AAC9B/E,EAAAA,IAAI,EAAE;AACJgF,IAAAA,iBAAiB,EAAE,aAAa;AAChCC,IAAAA,eAAe,EAAE,cAAc;AAC/BC,IAAAA,YAAY,EAAE,gBAAgB;AAC9BC,IAAAA,mBAAmB,EAAE;AAGnBC,MAAAA,GAAG,EAAE,sBAAsB;AAC3BC,MAAAA,KAAK,EAAE;KACR;AACDC,IAAAA,eAAe,EAAE,mBAAmB;AACpCC,IAAAA,YAAY,EAAE;AAChB;AACF,CAAC,CAAC;AA3fShG,UAAU,CAmgBdiG,MAAM,GAAGV,MAAM,CAACC,MAAM,CAAC;AAC5BU,EAAAA,UAAU,EAAE;AACVzF,IAAAA,IAAI,EAAE;AAAE0B,MAAAA,IAAI,EAAE;AAAS;AACzB;AACF,CAAC,CAAC;AASJ,SAASiC,cAAcA,CAAC+B,IAAI,EAAE;EAC5B,IAAIC,MAAM,GAAG,CAAC;AAId,EAAA,KAAK,IAAIC,CAAC,GAAG,CAAC,EAAEA,CAAC,GAAGF,IAAI,CAACjC,MAAM,EAAEmC,CAAC,EAAE,EAAE;IACpC,IAAIF,IAAI,CAACE,CAAC,CAAC,CAACC,IAAI,KAAK,MAAM,EAAE;AAC3BF,MAAAA,MAAM,EAAE;AACV,IAAA;AACF,EAAA;AACA,EAAA,OAAOA,MAAM;AACf;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;"}
@@ -19,6 +19,12 @@
19
19
  border-top-color: base.govuk-functional-colour(brand);
20
20
  color: $govuk-footer-text;
21
21
  background: base.govuk-functional-colour(template-background);
22
+
23
+ @media print {
24
+ border-top-color: currentcolor;
25
+ color: base.govuk-functional-colour(text);
26
+ background-color: transparent;
27
+ }
22
28
  }
23
29
 
24
30
  .govuk-footer__crown {
@@ -0,0 +1,15 @@
1
+ # Language navigation
2
+
3
+ ## Installation
4
+
5
+ See the [main README quick start guide](https://github.com/alphagov/govuk-frontend#quick-start) for how to install this component.
6
+
7
+ ## Guidance and Examples
8
+
9
+ Find out when to use the language navigation component in your service in the [GOV.UK Design System](https://design-system.service.gov.uk/components/language-navigation).
10
+
11
+ ## Component options
12
+
13
+ Use options to customise the appearance, content and behaviour of a component when using a macro, for example, changing the text.
14
+
15
+ See [options table](https://design-system.service.gov.uk/components/language-navigation/#options-language-navigation-example) for details.
@@ -0,0 +1,8 @@
1
+ @use "mixin";
2
+
3
+ @import "../../base";
4
+
5
+ @include govuk-exports("govuk/component/language-navigation") {
6
+ @include mixin.styles;
7
+ }
8
+
@@ -0,0 +1,6 @@
1
+ @use "../../custom-properties";
2
+
3
+ @use "mixin";
4
+
5
+ @include mixin.styles;
6
+
@@ -0,0 +1,6 @@
1
+ @use "../../settings/warnings--internal";
2
+
3
+ @include warnings--internal.component-scss-file-warning("language-navigation");
4
+
5
+ @import "index";
6
+
@@ -0,0 +1,68 @@
1
+ @use "../../base";
2
+
3
+ /// @access private
4
+ @mixin styles {
5
+ .govuk-language-navigation {
6
+ @include base.govuk-font($size: 19);
7
+
8
+ @include base.govuk-responsive-margin(6, "bottom");
9
+ color: base.govuk-functional-colour(text);
10
+ }
11
+
12
+ .govuk-language-navigation__list {
13
+ display: inline-flex;
14
+ flex-wrap: wrap;
15
+ row-gap: base.govuk-spacing(2);
16
+ margin: 0;
17
+ padding: 0;
18
+ list-style-type: none;
19
+ }
20
+
21
+ .govuk-language-navigation__list-item {
22
+ display: flex;
23
+ align-items: center;
24
+
25
+ &:not(:last-child) {
26
+ &::after {
27
+ content: "";
28
+ display: block;
29
+ height: 1em;
30
+ margin-right: base.govuk-spacing(2);
31
+ margin-left: base.govuk-spacing(2);
32
+ border-right: 1px solid;
33
+ border-right-color: base.govuk-functional-colour(border);
34
+ }
35
+ }
36
+ }
37
+
38
+ .govuk-language-navigation__link {
39
+ @include base.govuk-link-common;
40
+ @include base.govuk-link-style-default;
41
+ }
42
+
43
+ .govuk-language-navigation--inverse {
44
+ color: base.govuk-functional-colour(inverse-text);
45
+
46
+ .govuk-language-navigation__link {
47
+ @include base.govuk-link-style-inverse;
48
+ }
49
+
50
+ .govuk-language-navigation__list-item::after {
51
+ border-right-color: currentcolor;
52
+ }
53
+ }
54
+
55
+ // Ensure the Language navigation has enough
56
+ // spacing with the rest of the Service Navigation
57
+ .govuk-service-navigation .govuk-language-navigation {
58
+ // Slightly smaller margin because the Service Navigation's menu toggle
59
+ // has a little margin underneath it already.
60
+ margin-top: base.govuk-spacing(1);
61
+ margin-bottom: base.govuk-spacing(3);
62
+
63
+ @media #{base.govuk-from-breakpoint(tablet)} {
64
+ margin-top: base.govuk-spacing(3);
65
+ }
66
+ }
67
+ }
68
+