@ministryofjustice/frontend 4.0.1 → 5.1.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 (256) hide show
  1. package/govuk-prototype-kit.config.json +19 -4
  2. package/moj/_base.scss +2 -0
  3. package/moj/_base.scss.map +1 -0
  4. package/moj/all.bundle.js +3010 -0
  5. package/moj/all.bundle.js.map +1 -0
  6. package/moj/all.bundle.mjs +3293 -0
  7. package/moj/all.bundle.mjs.map +1 -0
  8. package/moj/all.mjs +17 -110
  9. package/moj/all.mjs.map +1 -1
  10. package/moj/all.scss +3 -0
  11. package/moj/all.scss.map +1 -0
  12. package/moj/common/index.mjs +57 -0
  13. package/moj/common/index.mjs.map +1 -0
  14. package/moj/common/moj-frontend-version.mjs +14 -0
  15. package/moj/common/moj-frontend-version.mjs.map +1 -0
  16. package/moj/components/_all.scss +2 -0
  17. package/moj/components/_all.scss.map +1 -0
  18. package/moj/components/action-bar/_action-bar.scss +2 -0
  19. package/moj/components/action-bar/_action-bar.scss.map +1 -0
  20. package/moj/components/add-another/_add-another.scss +2 -0
  21. package/moj/components/add-another/_add-another.scss.map +1 -0
  22. package/moj/components/add-another/add-another.bundle.js +157 -0
  23. package/moj/components/add-another/add-another.bundle.js.map +1 -0
  24. package/moj/components/add-another/add-another.bundle.mjs +271 -0
  25. package/moj/components/add-another/add-another.bundle.mjs.map +1 -0
  26. package/moj/components/add-another/add-another.mjs +135 -91
  27. package/moj/components/add-another/add-another.mjs.map +1 -1
  28. package/moj/components/alert/_alert.scss +4 -0
  29. package/moj/components/alert/_alert.scss.map +1 -0
  30. package/moj/components/alert/alert.bundle.js +254 -0
  31. package/moj/components/alert/alert.bundle.js.map +1 -0
  32. package/moj/components/alert/alert.bundle.mjs +490 -0
  33. package/moj/components/alert/alert.bundle.mjs.map +1 -0
  34. package/moj/components/alert/alert.mjs +97 -218
  35. package/moj/components/alert/alert.mjs.map +1 -1
  36. package/moj/components/alert/{alert.spec.helper.js → alert.spec.helper.bundle.js} +1 -1
  37. package/moj/components/alert/alert.spec.helper.bundle.js.map +1 -0
  38. package/moj/components/alert/alert.spec.helper.bundle.mjs +67 -0
  39. package/moj/components/alert/alert.spec.helper.bundle.mjs.map +1 -0
  40. package/moj/components/alert/alert.spec.helper.mjs.map +1 -1
  41. package/moj/components/badge/_badge.scss +2 -0
  42. package/moj/components/badge/_badge.scss.map +1 -0
  43. package/moj/components/banner/_banner.scss +2 -0
  44. package/moj/components/banner/_banner.scss.map +1 -0
  45. package/moj/components/button-menu/README.md +12 -6
  46. package/moj/components/button-menu/_button-menu.scss +4 -1
  47. package/moj/components/button-menu/_button-menu.scss.map +1 -0
  48. package/moj/components/button-menu/button-menu.bundle.js +270 -0
  49. package/moj/components/button-menu/button-menu.bundle.js.map +1 -0
  50. package/moj/components/button-menu/button-menu.bundle.mjs +506 -0
  51. package/moj/components/button-menu/button-menu.bundle.mjs.map +1 -0
  52. package/moj/components/button-menu/button-menu.mjs +214 -280
  53. package/moj/components/button-menu/button-menu.mjs.map +1 -1
  54. package/moj/components/cookie-banner/_cookie-banner.scss +2 -0
  55. package/moj/components/cookie-banner/_cookie-banner.scss.map +1 -0
  56. package/moj/components/currency-input/_currency-input.scss +2 -0
  57. package/moj/components/currency-input/_currency-input.scss.map +1 -0
  58. package/moj/components/date-picker/_date-picker.scss +2 -0
  59. package/moj/components/date-picker/_date-picker.scss.map +1 -0
  60. package/moj/components/date-picker/date-picker.bundle.js +804 -0
  61. package/moj/components/date-picker/date-picker.bundle.js.map +1 -0
  62. package/moj/components/date-picker/date-picker.bundle.mjs +1040 -0
  63. package/moj/components/date-picker/date-picker.bundle.mjs.map +1 -0
  64. package/moj/components/date-picker/date-picker.mjs +663 -827
  65. package/moj/components/date-picker/date-picker.mjs.map +1 -1
  66. package/moj/components/filter/_filter.scss +2 -0
  67. package/moj/components/filter/_filter.scss.map +1 -0
  68. package/moj/components/filter/template.njk +1 -1
  69. package/moj/components/filter-toggle-button/filter-toggle-button.bundle.js +185 -0
  70. package/moj/components/filter-toggle-button/filter-toggle-button.bundle.js.map +1 -0
  71. package/moj/components/filter-toggle-button/filter-toggle-button.bundle.mjs +421 -0
  72. package/moj/components/filter-toggle-button/filter-toggle-button.bundle.mjs.map +1 -0
  73. package/moj/components/filter-toggle-button/filter-toggle-button.mjs +166 -81
  74. package/moj/components/filter-toggle-button/filter-toggle-button.mjs.map +1 -1
  75. package/moj/components/form-validator/form-validator.bundle.js +288 -0
  76. package/moj/components/form-validator/form-validator.bundle.js.map +1 -0
  77. package/moj/components/form-validator/form-validator.bundle.mjs +524 -0
  78. package/moj/components/form-validator/form-validator.bundle.mjs.map +1 -0
  79. package/moj/components/form-validator/form-validator.mjs +226 -149
  80. package/moj/components/form-validator/form-validator.mjs.map +1 -1
  81. package/moj/components/header/_header.scss +2 -0
  82. package/moj/components/header/_header.scss.map +1 -0
  83. package/moj/components/identity-bar/_identity-bar.scss +2 -0
  84. package/moj/components/identity-bar/_identity-bar.scss.map +1 -0
  85. package/moj/components/interruption-card/_interruption-card.scss +2 -0
  86. package/moj/components/interruption-card/_interruption-card.scss.map +1 -0
  87. package/moj/components/messages/_messages.scss +2 -0
  88. package/moj/components/messages/_messages.scss.map +1 -0
  89. package/moj/components/multi-file-upload/_multi-file-upload.scss +2 -0
  90. package/moj/components/multi-file-upload/_multi-file-upload.scss.map +1 -0
  91. package/moj/components/multi-file-upload/multi-file-upload.bundle.js +397 -0
  92. package/moj/components/multi-file-upload/multi-file-upload.bundle.js.map +1 -0
  93. package/moj/components/multi-file-upload/multi-file-upload.bundle.mjs +633 -0
  94. package/moj/components/multi-file-upload/multi-file-upload.bundle.mjs.map +1 -0
  95. package/moj/components/multi-file-upload/multi-file-upload.mjs +384 -213
  96. package/moj/components/multi-file-upload/multi-file-upload.mjs.map +1 -1
  97. package/moj/components/multi-file-upload/template.njk +1 -1
  98. package/moj/components/multi-select/_multi-select.scss +2 -0
  99. package/moj/components/multi-select/_multi-select.scss.map +1 -0
  100. package/moj/components/multi-select/multi-select.bundle.js +143 -0
  101. package/moj/components/multi-select/multi-select.bundle.js.map +1 -0
  102. package/moj/components/multi-select/multi-select.bundle.mjs +379 -0
  103. package/moj/components/multi-select/multi-select.bundle.mjs.map +1 -0
  104. package/moj/components/multi-select/multi-select.mjs +123 -64
  105. package/moj/components/multi-select/multi-select.mjs.map +1 -1
  106. package/moj/components/notification-badge/_notification-badge.scss +2 -0
  107. package/moj/components/notification-badge/_notification-badge.scss.map +1 -0
  108. package/moj/components/organisation-switcher/_organisation-switcher.scss +2 -0
  109. package/moj/components/organisation-switcher/_organisation-switcher.scss.map +1 -0
  110. package/moj/components/page-header-actions/_page-header-actions.scss +2 -0
  111. package/moj/components/page-header-actions/_page-header-actions.scss.map +1 -0
  112. package/moj/components/pagination/_pagination.scss +2 -2
  113. package/moj/components/pagination/_pagination.scss.map +1 -0
  114. package/moj/components/password-reveal/_password-reveal.scss +5 -1
  115. package/moj/components/password-reveal/_password-reveal.scss.map +1 -0
  116. package/moj/components/password-reveal/password-reveal.bundle.js +52 -0
  117. package/moj/components/password-reveal/password-reveal.bundle.js.map +1 -0
  118. package/moj/components/password-reveal/password-reveal.bundle.mjs +166 -0
  119. package/moj/components/password-reveal/password-reveal.bundle.mjs.map +1 -0
  120. package/moj/components/password-reveal/password-reveal.mjs +39 -29
  121. package/moj/components/password-reveal/password-reveal.mjs.map +1 -1
  122. package/moj/components/primary-navigation/_primary-navigation.scss +2 -0
  123. package/moj/components/primary-navigation/_primary-navigation.scss.map +1 -0
  124. package/moj/components/progress-bar/_progress-bar.scss +2 -0
  125. package/moj/components/progress-bar/_progress-bar.scss.map +1 -0
  126. package/moj/components/rich-text-editor/README.md +16 -9
  127. package/moj/components/rich-text-editor/_rich-text-editor.scss +2 -0
  128. package/moj/components/rich-text-editor/_rich-text-editor.scss.map +1 -0
  129. package/moj/components/rich-text-editor/rich-text-editor.bundle.js +210 -0
  130. package/moj/components/rich-text-editor/rich-text-editor.bundle.js.map +1 -0
  131. package/moj/components/rich-text-editor/rich-text-editor.bundle.mjs +446 -0
  132. package/moj/components/rich-text-editor/rich-text-editor.bundle.mjs.map +1 -0
  133. package/moj/components/rich-text-editor/rich-text-editor.mjs +186 -140
  134. package/moj/components/rich-text-editor/rich-text-editor.mjs.map +1 -1
  135. package/moj/components/search/_search.scss +2 -0
  136. package/moj/components/search/_search.scss.map +1 -0
  137. package/moj/components/search-toggle/{search-toggle.scss → _search-toggle.scss} +2 -0
  138. package/moj/components/search-toggle/_search-toggle.scss.map +1 -0
  139. package/moj/components/search-toggle/search-toggle.bundle.js +122 -0
  140. package/moj/components/search-toggle/search-toggle.bundle.js.map +1 -0
  141. package/moj/components/search-toggle/search-toggle.bundle.mjs +358 -0
  142. package/moj/components/search-toggle/search-toggle.bundle.mjs.map +1 -0
  143. package/moj/components/search-toggle/search-toggle.mjs +104 -43
  144. package/moj/components/search-toggle/search-toggle.mjs.map +1 -1
  145. package/moj/components/side-navigation/_side-navigation.scss +2 -0
  146. package/moj/components/side-navigation/_side-navigation.scss.map +1 -0
  147. package/moj/components/sortable-table/_sortable-table.scss +2 -2
  148. package/moj/components/sortable-table/_sortable-table.scss.map +1 -0
  149. package/moj/components/sortable-table/sortable-table.bundle.js +202 -0
  150. package/moj/components/sortable-table/sortable-table.bundle.js.map +1 -0
  151. package/moj/components/sortable-table/sortable-table.bundle.mjs +438 -0
  152. package/moj/components/sortable-table/sortable-table.bundle.mjs.map +1 -0
  153. package/moj/components/sortable-table/sortable-table.mjs +179 -122
  154. package/moj/components/sortable-table/sortable-table.mjs.map +1 -1
  155. package/moj/components/sub-navigation/_sub-navigation.scss +2 -0
  156. package/moj/components/sub-navigation/_sub-navigation.scss.map +1 -0
  157. package/moj/components/tag/_tag.scss +2 -0
  158. package/moj/components/tag/_tag.scss.map +1 -0
  159. package/moj/components/task-list/_task-list.scss +2 -0
  160. package/moj/components/task-list/_task-list.scss.map +1 -0
  161. package/moj/components/ticket-panel/_ticket-panel.scss +2 -0
  162. package/moj/components/ticket-panel/_ticket-panel.scss.map +1 -0
  163. package/moj/components/timeline/_timeline.scss +2 -0
  164. package/moj/components/timeline/_timeline.scss.map +1 -0
  165. package/moj/core/_all.scss +3 -0
  166. package/moj/core/_all.scss.map +1 -0
  167. package/moj/core/_moj-frontend-properties.scss +7 -0
  168. package/moj/core/_moj-frontend-properties.scss.map +1 -0
  169. package/moj/filters/all.js +44 -22
  170. package/moj/filters/prototype-kit-13-filters.js +4 -3
  171. package/moj/helpers/_all.scss +2 -0
  172. package/moj/helpers/_all.scss.map +1 -0
  173. package/moj/helpers/_hidden.scss +2 -0
  174. package/moj/helpers/_hidden.scss.map +1 -0
  175. package/moj/helpers/_links.scss +2 -0
  176. package/moj/helpers/_links.scss.map +1 -0
  177. package/moj/helpers.bundle.js +140 -0
  178. package/moj/helpers.bundle.js.map +1 -0
  179. package/moj/helpers.bundle.mjs +128 -0
  180. package/moj/helpers.bundle.mjs.map +1 -0
  181. package/moj/helpers.mjs +50 -77
  182. package/moj/helpers.mjs.map +1 -1
  183. package/moj/init.js +11 -2
  184. package/moj/moj-frontend.min.css +1 -1
  185. package/moj/moj-frontend.min.css.map +1 -1
  186. package/moj/moj-frontend.min.js +1 -1
  187. package/moj/moj-frontend.min.js.map +1 -1
  188. package/moj/objects/_all.scss +2 -0
  189. package/moj/objects/_all.scss.map +1 -0
  190. package/moj/objects/_button-group.scss +2 -0
  191. package/moj/objects/_button-group.scss.map +1 -0
  192. package/moj/objects/_filter-layout.scss +2 -0
  193. package/moj/objects/_filter-layout.scss.map +1 -0
  194. package/moj/objects/_scrollable-pane.scss +2 -0
  195. package/moj/objects/_scrollable-pane.scss.map +1 -0
  196. package/moj/objects/_width-container.scss +2 -0
  197. package/moj/objects/_width-container.scss.map +1 -0
  198. package/moj/settings/_all.scss +2 -0
  199. package/moj/settings/_all.scss.map +1 -0
  200. package/moj/settings/_assets.scss +2 -0
  201. package/moj/settings/_assets.scss.map +1 -0
  202. package/moj/settings/_colours.scss +2 -0
  203. package/moj/settings/_colours.scss.map +1 -0
  204. package/moj/settings/_measurements.scss +2 -0
  205. package/moj/settings/_measurements.scss.map +1 -0
  206. package/moj/settings/_typography.scss +2 -0
  207. package/moj/settings/_typography.scss.map +1 -0
  208. package/moj/template.njk +13 -0
  209. package/moj/utilities/_all.scss +2 -0
  210. package/moj/utilities/_all.scss.map +1 -0
  211. package/moj/utilities/_hidden.scss +2 -0
  212. package/moj/utilities/_hidden.scss.map +1 -0
  213. package/moj/utilities/_width-container.scss +2 -0
  214. package/moj/utilities/_width-container.scss.map +1 -0
  215. package/moj/vendor/govuk-frontend/_base.scss +2 -0
  216. package/moj/vendor/govuk-frontend/_base.scss.map +1 -0
  217. package/moj/vendor/govuk-frontend/_index.scss +2 -0
  218. package/moj/vendor/govuk-frontend/_index.scss.map +1 -0
  219. package/package.json +5 -6
  220. package/moj/all.jquery.min.js +0 -1
  221. package/moj/all.jquery.min.js.map +0 -1
  222. package/moj/all.js +0 -2662
  223. package/moj/all.js.map +0 -1
  224. package/moj/components/add-another/add-another.js +0 -115
  225. package/moj/components/add-another/add-another.js.map +0 -1
  226. package/moj/components/alert/alert.js +0 -356
  227. package/moj/components/alert/alert.js.map +0 -1
  228. package/moj/components/alert/alert.spec.helper.js.map +0 -1
  229. package/moj/components/button-menu/button-menu.js +0 -338
  230. package/moj/components/button-menu/button-menu.js.map +0 -1
  231. package/moj/components/date-picker/date-picker.js +0 -970
  232. package/moj/components/date-picker/date-picker.js.map +0 -1
  233. package/moj/components/filter-toggle-button/filter-toggle-button.js +0 -102
  234. package/moj/components/filter-toggle-button/filter-toggle-button.js.map +0 -1
  235. package/moj/components/form-validator/form-validator.js +0 -205
  236. package/moj/components/form-validator/form-validator.js.map +0 -1
  237. package/moj/components/multi-file-upload/multi-file-upload.js +0 -241
  238. package/moj/components/multi-file-upload/multi-file-upload.js.map +0 -1
  239. package/moj/components/multi-select/multi-select.js +0 -86
  240. package/moj/components/multi-select/multi-select.js.map +0 -1
  241. package/moj/components/password-reveal/password-reveal.js +0 -44
  242. package/moj/components/password-reveal/password-reveal.js.map +0 -1
  243. package/moj/components/rich-text-editor/rich-text-editor.js +0 -166
  244. package/moj/components/rich-text-editor/rich-text-editor.js.map +0 -1
  245. package/moj/components/search-toggle/search-toggle.js +0 -63
  246. package/moj/components/search-toggle/search-toggle.js.map +0 -1
  247. package/moj/components/sortable-table/sortable-table.js +0 -147
  248. package/moj/components/sortable-table/sortable-table.js.map +0 -1
  249. package/moj/helpers.js +0 -200
  250. package/moj/helpers.js.map +0 -1
  251. package/moj/vendor/html5shiv.js +0 -326
  252. package/moj/vendor/jquery.js +0 -9300
  253. package/moj/version.js +0 -12
  254. package/moj/version.js.map +0 -1
  255. package/moj/version.mjs +0 -4
  256. package/moj/version.mjs.map +0 -1
@@ -0,0 +1,254 @@
1
+ (function (global, factory) {
2
+ typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('govuk-frontend')) :
3
+ typeof define === 'function' && define.amd ? define(['exports', 'govuk-frontend'], factory) :
4
+ (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.MOJFrontend = global.MOJFrontend || {}, global.GOVUKFrontend));
5
+ })(this, (function (exports, govukFrontend) { 'use strict';
6
+
7
+ /**
8
+ * GOV.UK Frontend helpers
9
+ *
10
+ * @todo Import from GOV.UK Frontend
11
+ */
12
+
13
+ /**
14
+ * Move focus to element
15
+ *
16
+ * Sets tabindex to -1 to make the element programmatically focusable,
17
+ * but removes it on blur as the element doesn't need to be focused again.
18
+ *
19
+ * @template {HTMLElement} FocusElement
20
+ * @param {FocusElement} $element - HTML element
21
+ * @param {object} [options] - Handler options
22
+ * @param {function(this: FocusElement): void} [options.onBeforeFocus] - Callback before focus
23
+ * @param {function(this: FocusElement): void} [options.onBlur] - Callback on blur
24
+ */
25
+ function setFocus($element, options = {}) {
26
+ var _options$onBeforeFocu;
27
+ const isFocusable = $element.getAttribute('tabindex');
28
+ if (!isFocusable) {
29
+ $element.setAttribute('tabindex', '-1');
30
+ }
31
+
32
+ /**
33
+ * Handle element focus
34
+ */
35
+ function onFocus() {
36
+ $element.addEventListener('blur', onBlur, {
37
+ once: true
38
+ });
39
+ }
40
+
41
+ /**
42
+ * Handle element blur
43
+ */
44
+ function onBlur() {
45
+ var _options$onBlur;
46
+ (_options$onBlur = options.onBlur) == null || _options$onBlur.call($element);
47
+ if (!isFocusable) {
48
+ $element.removeAttribute('tabindex');
49
+ }
50
+ }
51
+
52
+ // Add listener to reset element on blur, after focus
53
+ $element.addEventListener('focus', onFocus, {
54
+ once: true
55
+ });
56
+
57
+ // Focus element
58
+ (_options$onBeforeFocu = options.onBeforeFocus) == null || _options$onBeforeFocu.call($element);
59
+ $element.focus();
60
+ }
61
+
62
+ /**
63
+ * @param {Element} $element - Element to remove attribute value from
64
+ * @param {string} attr - Attribute name
65
+ * @param {string} value - Attribute value
66
+ */
67
+
68
+ /**
69
+ * Find an elements preceding sibling
70
+ *
71
+ * Utility function to find an elements previous sibling matching the provided
72
+ * selector.
73
+ *
74
+ * @param {Element | null} $element - Element to find siblings for
75
+ * @param {string} [selector] - selector for required sibling
76
+ */
77
+ function getPreviousSibling($element, selector) {
78
+ if (!$element || !($element instanceof HTMLElement)) {
79
+ return;
80
+ }
81
+
82
+ // Get the previous sibling element
83
+ let $sibling = $element.previousElementSibling;
84
+
85
+ // If the sibling matches our selector, use it
86
+ // If not, jump to the next sibling and continue the loop
87
+ while ($sibling) {
88
+ if ($sibling.matches(selector)) return $sibling;
89
+ $sibling = $sibling.previousElementSibling;
90
+ }
91
+ }
92
+
93
+ /**
94
+ * @param {Element | null} $element
95
+ * @param {string} [selector]
96
+ */
97
+ function findNearestMatchingElement($element, selector) {
98
+ // If no element or selector is provided, return
99
+ if (!$element || !($element instanceof HTMLElement) || false) {
100
+ return;
101
+ }
102
+
103
+ // Start with the current element
104
+ let $currentElement = $element;
105
+ while ($currentElement) {
106
+ // First check the current element
107
+ if ($currentElement.matches(selector)) {
108
+ return $currentElement;
109
+ }
110
+
111
+ // Check all previous siblings
112
+ let $sibling = $currentElement.previousElementSibling;
113
+ while ($sibling) {
114
+ // Check if the sibling itself is a heading
115
+ if ($sibling.matches(selector)) {
116
+ return $sibling;
117
+ }
118
+ $sibling = $sibling.previousElementSibling;
119
+ }
120
+
121
+ // If no match found in siblings, move up to parent
122
+ $currentElement = $currentElement.parentElement;
123
+ }
124
+ }
125
+
126
+ /**
127
+ * @augments {ConfigurableComponent<AlertConfig>}
128
+ */
129
+ class Alert extends govukFrontend.ConfigurableComponent {
130
+ /**
131
+ * @param {Element | null} $root - HTML element to use for alert
132
+ * @param {AlertConfig} [config] - Alert config
133
+ */
134
+ constructor($root, config = {}) {
135
+ super($root, config);
136
+
137
+ /**
138
+ * Focus the alert
139
+ *
140
+ * If `role="alert"` is set, focus the element to help some assistive
141
+ * technologies prioritise announcing it.
142
+ *
143
+ * You can turn off the auto-focus functionality by setting
144
+ * `data-disable-auto-focus="true"` in the component HTML. You might wish to
145
+ * do this based on user research findings, or to avoid a clash with another
146
+ * element which should be focused when the page loads.
147
+ */
148
+ if (this.$root.getAttribute('role') === 'alert' && !this.config.disableAutoFocus) {
149
+ setFocus(this.$root);
150
+ }
151
+ this.$dismissButton = this.$root.querySelector('.moj-alert__dismiss');
152
+ if (this.config.dismissible && this.$dismissButton) {
153
+ this.$dismissButton.innerHTML = this.config.dismissText;
154
+ this.$dismissButton.removeAttribute('hidden');
155
+ this.$root.addEventListener('click', event => {
156
+ if (event.target instanceof Node && this.$dismissButton.contains(event.target)) {
157
+ this.dimiss();
158
+ }
159
+ });
160
+ }
161
+ }
162
+
163
+ /**
164
+ * Handle dismissing the alert
165
+ */
166
+ dimiss() {
167
+ let $elementToRecieveFocus;
168
+
169
+ // If a selector has been provided, attempt to find that element
170
+ if (this.config.focusOnDismissSelector) {
171
+ $elementToRecieveFocus = document.querySelector(this.config.focusOnDismissSelector);
172
+ }
173
+
174
+ // Is the next sibling another alert
175
+ if (!$elementToRecieveFocus) {
176
+ const $nextSibling = this.$root.nextElementSibling;
177
+ if ($nextSibling && $nextSibling.matches('.moj-alert')) {
178
+ $elementToRecieveFocus = $nextSibling;
179
+ }
180
+ }
181
+
182
+ // Else try to find any preceding sibling alert or heading
183
+ if (!$elementToRecieveFocus) {
184
+ $elementToRecieveFocus = getPreviousSibling(this.$root, '.moj-alert, h1, h2, h3, h4, h5, h6');
185
+ }
186
+
187
+ // Else find the closest ancestor heading, or fallback to main, or last resort
188
+ // use the body element
189
+ if (!$elementToRecieveFocus) {
190
+ $elementToRecieveFocus = findNearestMatchingElement(this.$root, 'h1, h2, h3, h4, h5, h6, main, body');
191
+ }
192
+
193
+ // If we have an element, place focus on it
194
+ if ($elementToRecieveFocus instanceof HTMLElement) {
195
+ setFocus($elementToRecieveFocus);
196
+ }
197
+
198
+ // Remove the alert
199
+ this.$root.remove();
200
+ }
201
+
202
+ /**
203
+ * Name for the component used when initialising using data-module attributes.
204
+ */
205
+ }
206
+
207
+ /**
208
+ * @typedef {object} AlertConfig
209
+ * @property {boolean} [dismissible=false] - Can the alert be dismissed by the user
210
+ * @property {string} [dismissText=Dismiss] - the label text for the dismiss button
211
+ * @property {boolean} [disableAutoFocus=false] - whether the alert will be autofocused
212
+ * @property {string} [focusOnDismissSelector] - CSS Selector for element to be focused on dismiss
213
+ */
214
+
215
+ /**
216
+ * @import { Schema } from 'govuk-frontend/dist/govuk/common/configuration.mjs'
217
+ */
218
+ Alert.moduleName = 'moj-alert';
219
+ /**
220
+ * Alert default config
221
+ *
222
+ * @type {AlertConfig}
223
+ */
224
+ Alert.defaults = Object.freeze({
225
+ dismissible: false,
226
+ dismissText: 'Dismiss',
227
+ disableAutoFocus: false
228
+ });
229
+ /**
230
+ * Alert config schema
231
+ *
232
+ * @satisfies {Schema<AlertConfig>}
233
+ */
234
+ Alert.schema = Object.freeze(/** @type {const} */{
235
+ properties: {
236
+ dismissible: {
237
+ type: 'boolean'
238
+ },
239
+ dismissText: {
240
+ type: 'string'
241
+ },
242
+ disableAutoFocus: {
243
+ type: 'boolean'
244
+ },
245
+ focusOnDismissSelector: {
246
+ type: 'string'
247
+ }
248
+ }
249
+ });
250
+
251
+ exports.Alert = Alert;
252
+
253
+ }));
254
+ //# sourceMappingURL=alert.bundle.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"alert.bundle.js","sources":["../../../../src/moj/common/index.mjs","../../../../src/moj/helpers.mjs","../../../../src/moj/components/alert/alert.mjs"],"sourcesContent":["/**\n * GOV.UK Frontend helpers\n *\n * @todo Import from GOV.UK Frontend\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 * @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 * @param {Element} $element - Element to remove attribute value from\n * @param {string} attr - Attribute name\n * @param {string} value - Attribute value\n */\nexport function removeAttributeValue($element, attr, value) {\n let re, m\n if ($element.getAttribute(attr)) {\n if ($element.getAttribute(attr) === value) {\n $element.removeAttribute(attr)\n } else {\n re = new RegExp(`(^|\\\\s)${value}(\\\\s|$)`)\n m = $element.getAttribute(attr).match(re)\n if (m && m.length === 3) {\n $element.setAttribute(\n attr,\n $element.getAttribute(attr).replace(re, m[1] && m[2] ? ' ' : '')\n )\n }\n }\n }\n}\n\n/**\n * @param {Element} $element - Element to add attribute value to\n * @param {string} attr - Attribute name\n * @param {string} value - Attribute value\n */\nexport function addAttributeValue($element, attr, value) {\n let re\n if (!$element.getAttribute(attr)) {\n $element.setAttribute(attr, value)\n } else {\n re = new RegExp(`(^|\\\\s)${value}(\\\\s|$)`)\n if (!re.test($element.getAttribute(attr))) {\n $element.setAttribute(attr, `${$element.getAttribute(attr)} ${value}`)\n }\n }\n}\n\n/**\n * Find an elements next sibling\n *\n * Utility function to find an elements next sibling matching the provided\n * selector.\n *\n * @param {Element | null} $element - Element to find siblings for\n * @param {string} [selector] - selector for required sibling\n */\nexport function getNextSibling($element, selector) {\n if (!$element || !($element instanceof HTMLElement)) {\n return\n }\n\n // Get the next sibling element\n let $sibling = $element.nextElementSibling\n\n // If there's no selector, return the first sibling\n if (!selector) return $sibling\n\n // If the sibling matches our selector, use it\n // If not, jump to the next sibling and continue the loop\n while ($sibling) {\n if ($sibling.matches(selector)) return $sibling\n $sibling = $sibling.nextElementSibling\n }\n}\n\n/**\n * Find an elements preceding sibling\n *\n * Utility function to find an elements previous sibling matching the provided\n * selector.\n *\n * @param {Element | null} $element - Element to find siblings for\n * @param {string} [selector] - selector for required sibling\n */\nexport function getPreviousSibling($element, selector) {\n if (!$element || !($element instanceof HTMLElement)) {\n return\n }\n\n // Get the previous sibling element\n let $sibling = $element.previousElementSibling\n\n // If there's no selector, return the first sibling\n if (!selector) return $sibling\n\n // If the sibling matches our selector, use it\n // If not, jump to the next sibling and continue the loop\n while ($sibling) {\n if ($sibling.matches(selector)) return $sibling\n $sibling = $sibling.previousElementSibling\n }\n}\n\n/**\n * @param {Element | null} $element\n * @param {string} [selector]\n */\nexport function findNearestMatchingElement($element, selector) {\n // If no element or selector is provided, return\n if (!$element || !($element instanceof HTMLElement) || !selector) {\n return\n }\n\n // Start with the current element\n let $currentElement = $element\n\n while ($currentElement) {\n // First check the current element\n if ($currentElement.matches(selector)) {\n return $currentElement\n }\n\n // Check all previous siblings\n let $sibling = $currentElement.previousElementSibling\n while ($sibling) {\n // Check if the sibling itself is a heading\n if ($sibling.matches(selector)) {\n return $sibling\n }\n $sibling = $sibling.previousElementSibling\n }\n\n // If no match found in siblings, move up to parent\n $currentElement = $currentElement.parentElement\n }\n}\n","import { ConfigurableComponent } from 'govuk-frontend'\n\nimport { setFocus } from '../../common/index.mjs'\nimport {\n findNearestMatchingElement,\n getPreviousSibling\n} from '../../helpers.mjs'\n\n/**\n * @augments {ConfigurableComponent<AlertConfig>}\n */\nexport class Alert extends ConfigurableComponent {\n /**\n * @param {Element | null} $root - HTML element to use for alert\n * @param {AlertConfig} [config] - Alert config\n */\n constructor($root, config = {}) {\n super($root, config)\n\n /**\n * Focus the alert\n *\n * If `role=\"alert\"` is set, focus the element to help some assistive\n * technologies prioritise announcing it.\n *\n * You can turn off the auto-focus functionality by setting\n * `data-disable-auto-focus=\"true\"` in the component HTML. You might wish to\n * do this based on user research findings, or to avoid a clash with another\n * element which should be focused when the page loads.\n */\n if (\n this.$root.getAttribute('role') === 'alert' &&\n !this.config.disableAutoFocus\n ) {\n setFocus(this.$root)\n }\n\n this.$dismissButton = this.$root.querySelector('.moj-alert__dismiss')\n\n if (this.config.dismissible && this.$dismissButton) {\n this.$dismissButton.innerHTML = this.config.dismissText\n this.$dismissButton.removeAttribute('hidden')\n\n this.$root.addEventListener('click', (event) => {\n if (\n event.target instanceof Node &&\n this.$dismissButton.contains(event.target)\n ) {\n this.dimiss()\n }\n })\n }\n }\n\n /**\n * Handle dismissing the alert\n */\n dimiss() {\n let $elementToRecieveFocus\n\n // If a selector has been provided, attempt to find that element\n if (this.config.focusOnDismissSelector) {\n $elementToRecieveFocus = document.querySelector(\n this.config.focusOnDismissSelector\n )\n }\n\n // Is the next sibling another alert\n if (!$elementToRecieveFocus) {\n const $nextSibling = this.$root.nextElementSibling\n if ($nextSibling && $nextSibling.matches('.moj-alert')) {\n $elementToRecieveFocus = $nextSibling\n }\n }\n\n // Else try to find any preceding sibling alert or heading\n if (!$elementToRecieveFocus) {\n $elementToRecieveFocus = getPreviousSibling(\n this.$root,\n '.moj-alert, h1, h2, h3, h4, h5, h6'\n )\n }\n\n // Else find the closest ancestor heading, or fallback to main, or last resort\n // use the body element\n if (!$elementToRecieveFocus) {\n $elementToRecieveFocus = findNearestMatchingElement(\n this.$root,\n 'h1, h2, h3, h4, h5, h6, main, body'\n )\n }\n\n // If we have an element, place focus on it\n if ($elementToRecieveFocus instanceof HTMLElement) {\n setFocus($elementToRecieveFocus)\n }\n\n // Remove the alert\n this.$root.remove()\n }\n\n /**\n * Name for the component used when initialising using data-module attributes.\n */\n static moduleName = 'moj-alert'\n\n /**\n * Alert default config\n *\n * @type {AlertConfig}\n */\n static defaults = Object.freeze({\n dismissible: false,\n dismissText: 'Dismiss',\n disableAutoFocus: false\n })\n\n /**\n * Alert config schema\n *\n * @satisfies {Schema<AlertConfig>}\n */\n static schema = Object.freeze(\n /** @type {const} */ ({\n properties: {\n dismissible: { type: 'boolean' },\n dismissText: { type: 'string' },\n disableAutoFocus: { type: 'boolean' },\n focusOnDismissSelector: { type: 'string' }\n }\n })\n )\n}\n\n/**\n * @typedef {object} AlertConfig\n * @property {boolean} [dismissible=false] - Can the alert be dismissed by the user\n * @property {string} [dismissText=Dismiss] - the label text for the dismiss button\n * @property {boolean} [disableAutoFocus=false] - whether the alert will be autofocused\n * @property {string} [focusOnDismissSelector] - CSS Selector for element to be focused on dismiss\n */\n\n/**\n * @import { Schema } from 'govuk-frontend/dist/govuk/common/configuration.mjs'\n */\n"],"names":["setFocus","$element","options","_options$onBeforeFocu","isFocusable","getAttribute","setAttribute","onFocus","addEventListener","onBlur","once","_options$onBlur","call","removeAttribute","onBeforeFocus","focus","getPreviousSibling","selector","HTMLElement","$sibling","previousElementSibling","matches","findNearestMatchingElement","$currentElement","parentElement","Alert","ConfigurableComponent","constructor","$root","config","disableAutoFocus","$dismissButton","querySelector","dismissible","innerHTML","dismissText","event","target","Node","contains","dimiss","$elementToRecieveFocus","focusOnDismissSelector","document","$nextSibling","nextElementSibling","remove","moduleName","defaults","Object","freeze","schema","properties","type"],"mappings":"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"}