@ministryofjustice/frontend 4.0.0 → 5.0.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 (245) 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 +2523 -0
  5. package/moj/all.bundle.js.map +1 -0
  6. package/moj/all.bundle.mjs +2502 -0
  7. package/moj/all.bundle.mjs.map +1 -0
  8. package/moj/all.mjs +59 -69
  9. package/moj/all.mjs.map +1 -1
  10. package/moj/all.scss +2 -0
  11. package/moj/all.scss.map +1 -0
  12. package/moj/components/_all.scss +2 -0
  13. package/moj/components/_all.scss.map +1 -0
  14. package/moj/components/action-bar/_action-bar.scss +2 -0
  15. package/moj/components/action-bar/_action-bar.scss.map +1 -0
  16. package/moj/components/add-another/_add-another.scss +2 -0
  17. package/moj/components/add-another/_add-another.scss.map +1 -0
  18. package/moj/components/add-another/add-another.bundle.js +128 -0
  19. package/moj/components/add-another/add-another.bundle.js.map +1 -0
  20. package/moj/components/add-another/add-another.bundle.mjs +120 -0
  21. package/moj/components/add-another/add-another.bundle.mjs.map +1 -0
  22. package/moj/components/add-another/add-another.mjs +112 -99
  23. package/moj/components/add-another/add-another.mjs.map +1 -1
  24. package/moj/components/alert/_alert.scss +4 -0
  25. package/moj/components/alert/_alert.scss.map +1 -0
  26. package/moj/components/alert/alert.bundle.js +330 -0
  27. package/moj/components/alert/alert.bundle.js.map +1 -0
  28. package/moj/components/alert/alert.bundle.mjs +322 -0
  29. package/moj/components/alert/alert.bundle.mjs.map +1 -0
  30. package/moj/components/alert/alert.mjs +181 -217
  31. package/moj/components/alert/alert.mjs.map +1 -1
  32. package/moj/components/alert/{alert.spec.helper.js → alert.spec.helper.bundle.js} +1 -1
  33. package/moj/components/alert/alert.spec.helper.bundle.js.map +1 -0
  34. package/moj/components/alert/alert.spec.helper.bundle.mjs +67 -0
  35. package/moj/components/alert/alert.spec.helper.bundle.mjs.map +1 -0
  36. package/moj/components/alert/alert.spec.helper.mjs.map +1 -1
  37. package/moj/components/badge/_badge.scss +2 -0
  38. package/moj/components/badge/_badge.scss.map +1 -0
  39. package/moj/components/banner/_banner.scss +2 -0
  40. package/moj/components/banner/_banner.scss.map +1 -0
  41. package/moj/components/button-menu/README.md +10 -6
  42. package/moj/components/button-menu/_button-menu.scss +10 -3
  43. package/moj/components/button-menu/_button-menu.scss.map +1 -0
  44. package/moj/components/button-menu/button-menu.bundle.js +299 -0
  45. package/moj/components/button-menu/button-menu.bundle.js.map +1 -0
  46. package/moj/components/button-menu/{button-menu.js → button-menu.bundle.mjs} +74 -121
  47. package/moj/components/button-menu/button-menu.bundle.mjs.map +1 -0
  48. package/moj/components/button-menu/button-menu.mjs +246 -285
  49. package/moj/components/button-menu/button-menu.mjs.map +1 -1
  50. package/moj/components/cookie-banner/_cookie-banner.scss +2 -0
  51. package/moj/components/cookie-banner/_cookie-banner.scss.map +1 -0
  52. package/moj/components/currency-input/_currency-input.scss +2 -0
  53. package/moj/components/currency-input/_currency-input.scss.map +1 -0
  54. package/moj/components/date-picker/_date-picker.scss +2 -0
  55. package/moj/components/date-picker/_date-picker.scss.map +1 -0
  56. package/moj/components/date-picker/date-picker.bundle.js +784 -0
  57. package/moj/components/date-picker/date-picker.bundle.js.map +1 -0
  58. package/moj/components/date-picker/{date-picker.js → date-picker.bundle.mjs} +245 -439
  59. package/moj/components/date-picker/date-picker.bundle.mjs.map +1 -0
  60. package/moj/components/date-picker/date-picker.mjs +654 -840
  61. package/moj/components/date-picker/date-picker.mjs.map +1 -1
  62. package/moj/components/filter/_filter.scss +2 -0
  63. package/moj/components/filter/_filter.scss.map +1 -0
  64. package/moj/components/filter-toggle-button/filter-toggle-button.bundle.js +96 -0
  65. package/moj/components/filter-toggle-button/filter-toggle-button.bundle.js.map +1 -0
  66. package/moj/components/filter-toggle-button/filter-toggle-button.bundle.mjs +88 -0
  67. package/moj/components/filter-toggle-button/filter-toggle-button.bundle.mjs.map +1 -0
  68. package/moj/components/filter-toggle-button/filter-toggle-button.mjs +78 -84
  69. package/moj/components/filter-toggle-button/filter-toggle-button.mjs.map +1 -1
  70. package/moj/components/form-validator/form-validator.bundle.js +198 -0
  71. package/moj/components/form-validator/form-validator.bundle.js.map +1 -0
  72. package/moj/components/form-validator/form-validator.bundle.mjs +190 -0
  73. package/moj/components/form-validator/form-validator.bundle.mjs.map +1 -0
  74. package/moj/components/form-validator/form-validator.mjs +149 -152
  75. package/moj/components/form-validator/form-validator.mjs.map +1 -1
  76. package/moj/components/header/_header.scss +2 -0
  77. package/moj/components/header/_header.scss.map +1 -0
  78. package/moj/components/identity-bar/_identity-bar.scss +2 -0
  79. package/moj/components/identity-bar/_identity-bar.scss.map +1 -0
  80. package/moj/components/interruption-card/_interruption-card.scss +2 -0
  81. package/moj/components/interruption-card/_interruption-card.scss.map +1 -0
  82. package/moj/components/messages/_messages.scss +2 -0
  83. package/moj/components/messages/_messages.scss.map +1 -0
  84. package/moj/components/multi-file-upload/_multi-file-upload.scss +2 -0
  85. package/moj/components/multi-file-upload/_multi-file-upload.scss.map +1 -0
  86. package/moj/components/multi-file-upload/multi-file-upload.bundle.js +223 -0
  87. package/moj/components/multi-file-upload/multi-file-upload.bundle.js.map +1 -0
  88. package/moj/components/multi-file-upload/multi-file-upload.bundle.mjs +215 -0
  89. package/moj/components/multi-file-upload/multi-file-upload.bundle.mjs.map +1 -0
  90. package/moj/components/multi-file-upload/multi-file-upload.mjs +193 -209
  91. package/moj/components/multi-file-upload/multi-file-upload.mjs.map +1 -1
  92. package/moj/components/multi-select/_multi-select.scss +2 -0
  93. package/moj/components/multi-select/_multi-select.scss.map +1 -0
  94. package/moj/components/multi-select/multi-select.bundle.js +78 -0
  95. package/moj/components/multi-select/multi-select.bundle.js.map +1 -0
  96. package/moj/components/multi-select/multi-select.bundle.mjs +70 -0
  97. package/moj/components/multi-select/multi-select.bundle.mjs.map +1 -0
  98. package/moj/components/multi-select/multi-select.mjs +59 -67
  99. package/moj/components/multi-select/multi-select.mjs.map +1 -1
  100. package/moj/components/notification-badge/_notification-badge.scss +2 -0
  101. package/moj/components/notification-badge/_notification-badge.scss.map +1 -0
  102. package/moj/components/organisation-switcher/_organisation-switcher.scss +2 -0
  103. package/moj/components/organisation-switcher/_organisation-switcher.scss.map +1 -0
  104. package/moj/components/page-header-actions/_page-header-actions.scss +2 -0
  105. package/moj/components/page-header-actions/_page-header-actions.scss.map +1 -0
  106. package/moj/components/page-header-actions/template.njk +1 -1
  107. package/moj/components/pagination/_pagination.scss +2 -2
  108. package/moj/components/pagination/_pagination.scss.map +1 -0
  109. package/moj/components/password-reveal/_password-reveal.scss +2 -0
  110. package/moj/components/password-reveal/_password-reveal.scss.map +1 -0
  111. package/moj/components/password-reveal/password-reveal.bundle.js +49 -0
  112. package/moj/components/password-reveal/password-reveal.bundle.js.map +1 -0
  113. package/moj/components/password-reveal/password-reveal.bundle.mjs +41 -0
  114. package/moj/components/password-reveal/password-reveal.bundle.mjs.map +1 -0
  115. package/moj/components/password-reveal/password-reveal.mjs +36 -31
  116. package/moj/components/password-reveal/password-reveal.mjs.map +1 -1
  117. package/moj/components/primary-navigation/_primary-navigation.scss +2 -0
  118. package/moj/components/primary-navigation/_primary-navigation.scss.map +1 -0
  119. package/moj/components/progress-bar/_progress-bar.scss +2 -0
  120. package/moj/components/progress-bar/_progress-bar.scss.map +1 -0
  121. package/moj/components/rich-text-editor/README.md +15 -9
  122. package/moj/components/rich-text-editor/_rich-text-editor.scss +2 -0
  123. package/moj/components/rich-text-editor/_rich-text-editor.scss.map +1 -0
  124. package/moj/components/rich-text-editor/rich-text-editor.bundle.js +145 -0
  125. package/moj/components/rich-text-editor/rich-text-editor.bundle.js.map +1 -0
  126. package/moj/components/rich-text-editor/rich-text-editor.bundle.mjs +137 -0
  127. package/moj/components/rich-text-editor/rich-text-editor.bundle.mjs.map +1 -0
  128. package/moj/components/rich-text-editor/rich-text-editor.mjs +124 -145
  129. package/moj/components/rich-text-editor/rich-text-editor.mjs.map +1 -1
  130. package/moj/components/search/_search.scss +2 -0
  131. package/moj/components/search/_search.scss.map +1 -0
  132. package/moj/components/search-toggle/{search-toggle.scss → _search-toggle.scss} +2 -0
  133. package/moj/components/search-toggle/_search-toggle.scss.map +1 -0
  134. package/moj/components/search-toggle/search-toggle.bundle.js +54 -0
  135. package/moj/components/search-toggle/search-toggle.bundle.js.map +1 -0
  136. package/moj/components/search-toggle/search-toggle.bundle.mjs +46 -0
  137. package/moj/components/search-toggle/search-toggle.bundle.mjs.map +1 -0
  138. package/moj/components/search-toggle/search-toggle.mjs +40 -49
  139. package/moj/components/search-toggle/search-toggle.mjs.map +1 -1
  140. package/moj/components/side-navigation/_side-navigation.scss +2 -0
  141. package/moj/components/side-navigation/_side-navigation.scss.map +1 -0
  142. package/moj/components/sortable-table/_sortable-table.scss +2 -2
  143. package/moj/components/sortable-table/_sortable-table.scss.map +1 -0
  144. package/moj/components/sortable-table/sortable-table.bundle.js +134 -0
  145. package/moj/components/sortable-table/sortable-table.bundle.js.map +1 -0
  146. package/moj/components/sortable-table/sortable-table.bundle.mjs +126 -0
  147. package/moj/components/sortable-table/sortable-table.bundle.mjs.map +1 -0
  148. package/moj/components/sortable-table/sortable-table.mjs +117 -130
  149. package/moj/components/sortable-table/sortable-table.mjs.map +1 -1
  150. package/moj/components/sub-navigation/_sub-navigation.scss +2 -0
  151. package/moj/components/sub-navigation/_sub-navigation.scss.map +1 -0
  152. package/moj/components/tag/_tag.scss +2 -0
  153. package/moj/components/tag/_tag.scss.map +1 -0
  154. package/moj/components/task-list/_task-list.scss +2 -0
  155. package/moj/components/task-list/_task-list.scss.map +1 -0
  156. package/moj/components/ticket-panel/_ticket-panel.scss +2 -0
  157. package/moj/components/ticket-panel/_ticket-panel.scss.map +1 -0
  158. package/moj/components/timeline/_timeline.scss +2 -0
  159. package/moj/components/timeline/_timeline.scss.map +1 -0
  160. package/moj/filters/all.js +44 -22
  161. package/moj/helpers/_all.scss +2 -0
  162. package/moj/helpers/_all.scss.map +1 -0
  163. package/moj/helpers/_hidden.scss +2 -0
  164. package/moj/helpers/_hidden.scss.map +1 -0
  165. package/moj/helpers/_links.scss +2 -0
  166. package/moj/helpers/_links.scss.map +1 -0
  167. package/moj/{helpers.js → helpers.bundle.js} +37 -42
  168. package/moj/helpers.bundle.js.map +1 -0
  169. package/moj/helpers.bundle.mjs +179 -0
  170. package/moj/helpers.bundle.mjs.map +1 -0
  171. package/moj/helpers.mjs +52 -28
  172. package/moj/helpers.mjs.map +1 -1
  173. package/moj/init.js +11 -2
  174. package/moj/moj-frontend.min.css +1 -1
  175. package/moj/moj-frontend.min.css.map +1 -1
  176. package/moj/moj-frontend.min.js +1 -1
  177. package/moj/moj-frontend.min.js.map +1 -1
  178. package/moj/objects/_all.scss +2 -0
  179. package/moj/objects/_all.scss.map +1 -0
  180. package/moj/objects/_button-group.scss +17 -1
  181. package/moj/objects/_button-group.scss.map +1 -0
  182. package/moj/objects/_filter-layout.scss +2 -0
  183. package/moj/objects/_filter-layout.scss.map +1 -0
  184. package/moj/objects/_scrollable-pane.scss +2 -0
  185. package/moj/objects/_scrollable-pane.scss.map +1 -0
  186. package/moj/objects/_width-container.scss +2 -0
  187. package/moj/objects/_width-container.scss.map +1 -0
  188. package/moj/settings/_all.scss +2 -0
  189. package/moj/settings/_all.scss.map +1 -0
  190. package/moj/settings/_assets.scss +2 -0
  191. package/moj/settings/_assets.scss.map +1 -0
  192. package/moj/settings/_colours.scss +2 -0
  193. package/moj/settings/_colours.scss.map +1 -0
  194. package/moj/settings/_measurements.scss +2 -0
  195. package/moj/settings/_measurements.scss.map +1 -0
  196. package/moj/settings/_typography.scss +2 -0
  197. package/moj/settings/_typography.scss.map +1 -0
  198. package/moj/template.njk +13 -0
  199. package/moj/utilities/_all.scss +2 -0
  200. package/moj/utilities/_all.scss.map +1 -0
  201. package/moj/utilities/_hidden.scss +2 -0
  202. package/moj/utilities/_hidden.scss.map +1 -0
  203. package/moj/utilities/_width-container.scss +2 -0
  204. package/moj/utilities/_width-container.scss.map +1 -0
  205. package/moj/vendor/govuk-frontend/_base.scss +2 -0
  206. package/moj/vendor/govuk-frontend/_base.scss.map +1 -0
  207. package/moj/vendor/govuk-frontend/_index.scss +2 -0
  208. package/moj/vendor/govuk-frontend/_index.scss.map +1 -0
  209. package/moj/{version.js → version.bundle.js} +1 -1
  210. package/moj/version.bundle.js.map +1 -0
  211. package/moj/version.bundle.mjs +4 -0
  212. package/moj/version.bundle.mjs.map +1 -0
  213. package/moj/version.mjs.map +1 -1
  214. package/package.json +5 -6
  215. package/moj/all.jquery.min.js +0 -1
  216. package/moj/all.jquery.min.js.map +0 -1
  217. package/moj/all.js +0 -2662
  218. package/moj/all.js.map +0 -1
  219. package/moj/components/add-another/add-another.js +0 -115
  220. package/moj/components/add-another/add-another.js.map +0 -1
  221. package/moj/components/alert/alert.js +0 -356
  222. package/moj/components/alert/alert.js.map +0 -1
  223. package/moj/components/alert/alert.spec.helper.js.map +0 -1
  224. package/moj/components/button-menu/button-menu.js.map +0 -1
  225. package/moj/components/date-picker/date-picker.js.map +0 -1
  226. package/moj/components/filter-toggle-button/filter-toggle-button.js +0 -102
  227. package/moj/components/filter-toggle-button/filter-toggle-button.js.map +0 -1
  228. package/moj/components/form-validator/form-validator.js +0 -205
  229. package/moj/components/form-validator/form-validator.js.map +0 -1
  230. package/moj/components/multi-file-upload/multi-file-upload.js +0 -241
  231. package/moj/components/multi-file-upload/multi-file-upload.js.map +0 -1
  232. package/moj/components/multi-select/multi-select.js +0 -86
  233. package/moj/components/multi-select/multi-select.js.map +0 -1
  234. package/moj/components/password-reveal/password-reveal.js +0 -44
  235. package/moj/components/password-reveal/password-reveal.js.map +0 -1
  236. package/moj/components/rich-text-editor/rich-text-editor.js +0 -166
  237. package/moj/components/rich-text-editor/rich-text-editor.js.map +0 -1
  238. package/moj/components/search-toggle/search-toggle.js +0 -63
  239. package/moj/components/search-toggle/search-toggle.js.map +0 -1
  240. package/moj/components/sortable-table/sortable-table.js +0 -147
  241. package/moj/components/sortable-table/sortable-table.js.map +0 -1
  242. package/moj/helpers.js.map +0 -1
  243. package/moj/vendor/html5shiv.js +0 -326
  244. package/moj/vendor/jquery.js +0 -9300
  245. package/moj/version.js.map +0 -1
@@ -13,15 +13,11 @@
13
13
  re = new RegExp(`(^|\\s)${value}(\\s|$)`);
14
14
  m = el.getAttribute(attr).match(re);
15
15
  if (m && m.length === 3) {
16
- el.setAttribute(
17
- attr,
18
- el.getAttribute(attr).replace(re, m[1] && m[2] ? ' ' : '')
19
- );
16
+ el.setAttribute(attr, el.getAttribute(attr).replace(re, m[1] && m[2] ? ' ' : ''));
20
17
  }
21
18
  }
22
19
  }
23
20
  }
24
-
25
21
  function addAttributeValue(el, attr, value) {
26
22
  let re;
27
23
  if (!el.getAttribute(attr)) {
@@ -33,29 +29,17 @@
33
29
  }
34
30
  }
35
31
  }
36
-
37
32
  function dragAndDropSupported() {
38
33
  const div = document.createElement('div');
39
- return typeof div.ondrop !== 'undefined'
34
+ return typeof div.ondrop !== 'undefined';
40
35
  }
41
-
42
36
  function formDataSupported() {
43
- return typeof FormData === 'function'
37
+ return typeof FormData === 'function';
44
38
  }
45
-
46
39
  function fileApiSupported() {
47
40
  const input = document.createElement('input');
48
41
  input.type = 'file';
49
- return typeof input.files !== 'undefined'
50
- }
51
-
52
- function nodeListForEach(nodes, callback) {
53
- if (window.NodeList.prototype.forEach) {
54
- return nodes.forEach(callback)
55
- }
56
- for (let i = 0; i < nodes.length; i++) {
57
- callback.call(window, nodes[i], i, nodes);
58
- }
42
+ return typeof input.files !== 'undefined';
59
43
  }
60
44
 
61
45
  /**
@@ -64,21 +48,24 @@
64
48
  * Utility function to find an elements next sibling matching the provided
65
49
  * selector.
66
50
  *
67
- * @param {HTMLElement} $element - Element to find siblings for
68
- * @param {string} selector - selector for required sibling
51
+ * @param {Element | null} $element - Element to find siblings for
52
+ * @param {string} [selector] - selector for required sibling
69
53
  */
70
54
  function getNextSibling($element, selector) {
71
- if (!$element) return
55
+ if (!$element || !($element instanceof HTMLElement)) {
56
+ return;
57
+ }
58
+
72
59
  // Get the next sibling element
73
60
  let $sibling = $element.nextElementSibling;
74
61
 
75
62
  // If there's no selector, return the first sibling
76
- if (!selector) return $sibling
63
+ if (!selector) return $sibling;
77
64
 
78
65
  // If the sibling matches our selector, use it
79
66
  // If not, jump to the next sibling and continue the loop
80
67
  while ($sibling) {
81
- if ($sibling.matches(selector)) return $sibling
68
+ if ($sibling.matches(selector)) return $sibling;
82
69
  $sibling = $sibling.nextElementSibling;
83
70
  }
84
71
  }
@@ -89,37 +76,44 @@
89
76
  * Utility function to find an elements previous sibling matching the provided
90
77
  * selector.
91
78
  *
92
- * @param {HTMLElement} $element - Element to find siblings for
93
- * @param {string} selector - selector for required sibling
79
+ * @param {Element | null} $element - Element to find siblings for
80
+ * @param {string} [selector] - selector for required sibling
94
81
  */
95
82
  function getPreviousSibling($element, selector) {
96
- if (!$element) return
83
+ if (!$element || !($element instanceof HTMLElement)) {
84
+ return;
85
+ }
86
+
97
87
  // Get the previous sibling element
98
88
  let $sibling = $element.previousElementSibling;
99
89
 
100
90
  // If there's no selector, return the first sibling
101
- if (!selector) return $sibling
91
+ if (!selector) return $sibling;
102
92
 
103
93
  // If the sibling matches our selector, use it
104
94
  // If not, jump to the next sibling and continue the loop
105
95
  while ($sibling) {
106
- if ($sibling.matches(selector)) return $sibling
96
+ if ($sibling.matches(selector)) return $sibling;
107
97
  $sibling = $sibling.previousElementSibling;
108
98
  }
109
99
  }
110
100
 
101
+ /**
102
+ * @param {Element | null} $element
103
+ * @param {string} [selector]
104
+ */
111
105
  function findNearestMatchingElement($element, selector) {
112
- // If no element or selector is provided, return null
113
- if (!$element) return
114
- if (!selector) return
106
+ // If no element or selector is provided, return
107
+ if (!$element || !($element instanceof HTMLElement) || !selector) {
108
+ return;
109
+ }
115
110
 
116
111
  // Start with the current element
117
112
  let $currentElement = $element;
118
-
119
113
  while ($currentElement) {
120
114
  // First check the current element
121
115
  if ($currentElement.matches(selector)) {
122
- return $currentElement
116
+ return $currentElement;
123
117
  }
124
118
 
125
119
  // Check all previous siblings
@@ -127,7 +121,7 @@
127
121
  while ($sibling) {
128
122
  // Check if the sibling itself is a heading
129
123
  if ($sibling.matches(selector)) {
130
- return $sibling
124
+ return $sibling;
131
125
  }
132
126
  $sibling = $sibling.previousElementSibling;
133
127
  }
@@ -150,7 +144,6 @@
150
144
  */
151
145
  function setFocus($element, options = {}) {
152
146
  const isFocusable = $element.getAttribute('tabindex');
153
-
154
147
  if (!isFocusable) {
155
148
  $element.setAttribute('tabindex', '-1');
156
149
  }
@@ -159,7 +152,9 @@
159
152
  * Handle element focus
160
153
  */
161
154
  function onFocus() {
162
- $element.addEventListener('blur', onBlur, { once: true });
155
+ $element.addEventListener('blur', onBlur, {
156
+ once: true
157
+ });
163
158
  }
164
159
 
165
160
  /**
@@ -169,14 +164,15 @@
169
164
  if (options.onBlur) {
170
165
  options.onBlur.call($element);
171
166
  }
172
-
173
167
  if (!isFocusable) {
174
168
  $element.removeAttribute('tabindex');
175
169
  }
176
170
  }
177
171
 
178
172
  // Add listener to reset element on blur, after focus
179
- $element.addEventListener('focus', onFocus, { once: true });
173
+ $element.addEventListener('focus', onFocus, {
174
+ once: true
175
+ });
180
176
 
181
177
  // Focus element
182
178
  if (options.onBeforeFocus) {
@@ -192,9 +188,8 @@
192
188
  exports.formDataSupported = formDataSupported;
193
189
  exports.getNextSibling = getNextSibling;
194
190
  exports.getPreviousSibling = getPreviousSibling;
195
- exports.nodeListForEach = nodeListForEach;
196
191
  exports.removeAttributeValue = removeAttributeValue;
197
192
  exports.setFocus = setFocus;
198
193
 
199
194
  }));
200
- //# sourceMappingURL=helpers.js.map
195
+ //# sourceMappingURL=helpers.bundle.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"helpers.bundle.js","sources":["../../src/moj/helpers.mjs"],"sourcesContent":["export function removeAttributeValue(el, attr, value) {\n let re, m\n if (el.getAttribute(attr)) {\n if (el.getAttribute(attr) === value) {\n el.removeAttribute(attr)\n } else {\n re = new RegExp(`(^|\\\\s)${value}(\\\\s|$)`)\n m = el.getAttribute(attr).match(re)\n if (m && m.length === 3) {\n el.setAttribute(\n attr,\n el.getAttribute(attr).replace(re, m[1] && m[2] ? ' ' : '')\n )\n }\n }\n }\n}\n\nexport function addAttributeValue(el, attr, value) {\n let re\n if (!el.getAttribute(attr)) {\n el.setAttribute(attr, value)\n } else {\n re = new RegExp(`(^|\\\\s)${value}(\\\\s|$)`)\n if (!re.test(el.getAttribute(attr))) {\n el.setAttribute(attr, `${el.getAttribute(attr)} ${value}`)\n }\n }\n}\n\nexport function dragAndDropSupported() {\n const div = document.createElement('div')\n return typeof div.ondrop !== 'undefined'\n}\n\nexport function formDataSupported() {\n return typeof FormData === 'function'\n}\n\nexport function fileApiSupported() {\n const input = document.createElement('input')\n input.type = 'file'\n return typeof input.files !== 'undefined'\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\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 * @param {HTMLElement} $element - HTML element\n * @param {object} [options] - Handler options\n * @param {function(this: HTMLElement): void} [options.onBeforeFocus] - Callback before focus\n * @param {function(this: HTMLElement): 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 if (options.onBlur) {\n options.onBlur.call($element)\n }\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 if (options.onBeforeFocus) {\n options.onBeforeFocus.call($element)\n }\n $element.focus()\n}\n"],"names":["removeAttributeValue","el","attr","value","re","m","getAttribute","removeAttribute","RegExp","match","length","setAttribute","replace","addAttributeValue","test","dragAndDropSupported","div","document","createElement","ondrop","formDataSupported","FormData","fileApiSupported","input","type","files","getNextSibling","$element","selector","HTMLElement","$sibling","nextElementSibling","matches","getPreviousSibling","previousElementSibling","findNearestMatchingElement","$currentElement","parentElement","setFocus","options","isFocusable","onFocus","addEventListener","onBlur","once","call","onBeforeFocus","focus"],"mappings":"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"}
@@ -0,0 +1,179 @@
1
+ function removeAttributeValue(el, attr, value) {
2
+ let re, m;
3
+ if (el.getAttribute(attr)) {
4
+ if (el.getAttribute(attr) === value) {
5
+ el.removeAttribute(attr);
6
+ } else {
7
+ re = new RegExp(`(^|\\s)${value}(\\s|$)`);
8
+ m = el.getAttribute(attr).match(re);
9
+ if (m && m.length === 3) {
10
+ el.setAttribute(attr, el.getAttribute(attr).replace(re, m[1] && m[2] ? ' ' : ''));
11
+ }
12
+ }
13
+ }
14
+ }
15
+ function addAttributeValue(el, attr, value) {
16
+ let re;
17
+ if (!el.getAttribute(attr)) {
18
+ el.setAttribute(attr, value);
19
+ } else {
20
+ re = new RegExp(`(^|\\s)${value}(\\s|$)`);
21
+ if (!re.test(el.getAttribute(attr))) {
22
+ el.setAttribute(attr, `${el.getAttribute(attr)} ${value}`);
23
+ }
24
+ }
25
+ }
26
+ function dragAndDropSupported() {
27
+ const div = document.createElement('div');
28
+ return typeof div.ondrop !== 'undefined';
29
+ }
30
+ function formDataSupported() {
31
+ return typeof FormData === 'function';
32
+ }
33
+ function fileApiSupported() {
34
+ const input = document.createElement('input');
35
+ input.type = 'file';
36
+ return typeof input.files !== 'undefined';
37
+ }
38
+
39
+ /**
40
+ * Find an elements next sibling
41
+ *
42
+ * Utility function to find an elements next sibling matching the provided
43
+ * selector.
44
+ *
45
+ * @param {Element | null} $element - Element to find siblings for
46
+ * @param {string} [selector] - selector for required sibling
47
+ */
48
+ function getNextSibling($element, selector) {
49
+ if (!$element || !($element instanceof HTMLElement)) {
50
+ return;
51
+ }
52
+
53
+ // Get the next sibling element
54
+ let $sibling = $element.nextElementSibling;
55
+
56
+ // If there's no selector, return the first sibling
57
+ if (!selector) return $sibling;
58
+
59
+ // If the sibling matches our selector, use it
60
+ // If not, jump to the next sibling and continue the loop
61
+ while ($sibling) {
62
+ if ($sibling.matches(selector)) return $sibling;
63
+ $sibling = $sibling.nextElementSibling;
64
+ }
65
+ }
66
+
67
+ /**
68
+ * Find an elements preceding sibling
69
+ *
70
+ * Utility function to find an elements previous sibling matching the provided
71
+ * selector.
72
+ *
73
+ * @param {Element | null} $element - Element to find siblings for
74
+ * @param {string} [selector] - selector for required sibling
75
+ */
76
+ function getPreviousSibling($element, selector) {
77
+ if (!$element || !($element instanceof HTMLElement)) {
78
+ return;
79
+ }
80
+
81
+ // Get the previous sibling element
82
+ let $sibling = $element.previousElementSibling;
83
+
84
+ // If there's no selector, return the first sibling
85
+ if (!selector) return $sibling;
86
+
87
+ // If the sibling matches our selector, use it
88
+ // If not, jump to the next sibling and continue the loop
89
+ while ($sibling) {
90
+ if ($sibling.matches(selector)) return $sibling;
91
+ $sibling = $sibling.previousElementSibling;
92
+ }
93
+ }
94
+
95
+ /**
96
+ * @param {Element | null} $element
97
+ * @param {string} [selector]
98
+ */
99
+ function findNearestMatchingElement($element, selector) {
100
+ // If no element or selector is provided, return
101
+ if (!$element || !($element instanceof HTMLElement) || !selector) {
102
+ return;
103
+ }
104
+
105
+ // Start with the current element
106
+ let $currentElement = $element;
107
+ while ($currentElement) {
108
+ // First check the current element
109
+ if ($currentElement.matches(selector)) {
110
+ return $currentElement;
111
+ }
112
+
113
+ // Check all previous siblings
114
+ let $sibling = $currentElement.previousElementSibling;
115
+ while ($sibling) {
116
+ // Check if the sibling itself is a heading
117
+ if ($sibling.matches(selector)) {
118
+ return $sibling;
119
+ }
120
+ $sibling = $sibling.previousElementSibling;
121
+ }
122
+
123
+ // If no match found in siblings, move up to parent
124
+ $currentElement = $currentElement.parentElement;
125
+ }
126
+ }
127
+
128
+ /**
129
+ * Move focus to element
130
+ *
131
+ * Sets tabindex to -1 to make the element programmatically focusable,
132
+ * but removes it on blur as the element doesn't need to be focused again.
133
+ *
134
+ * @param {HTMLElement} $element - HTML element
135
+ * @param {object} [options] - Handler options
136
+ * @param {function(this: HTMLElement): void} [options.onBeforeFocus] - Callback before focus
137
+ * @param {function(this: HTMLElement): void} [options.onBlur] - Callback on blur
138
+ */
139
+ function setFocus($element, options = {}) {
140
+ const isFocusable = $element.getAttribute('tabindex');
141
+ if (!isFocusable) {
142
+ $element.setAttribute('tabindex', '-1');
143
+ }
144
+
145
+ /**
146
+ * Handle element focus
147
+ */
148
+ function onFocus() {
149
+ $element.addEventListener('blur', onBlur, {
150
+ once: true
151
+ });
152
+ }
153
+
154
+ /**
155
+ * Handle element blur
156
+ */
157
+ function onBlur() {
158
+ if (options.onBlur) {
159
+ options.onBlur.call($element);
160
+ }
161
+ if (!isFocusable) {
162
+ $element.removeAttribute('tabindex');
163
+ }
164
+ }
165
+
166
+ // Add listener to reset element on blur, after focus
167
+ $element.addEventListener('focus', onFocus, {
168
+ once: true
169
+ });
170
+
171
+ // Focus element
172
+ if (options.onBeforeFocus) {
173
+ options.onBeforeFocus.call($element);
174
+ }
175
+ $element.focus();
176
+ }
177
+
178
+ export { addAttributeValue, dragAndDropSupported, fileApiSupported, findNearestMatchingElement, formDataSupported, getNextSibling, getPreviousSibling, removeAttributeValue, setFocus };
179
+ //# sourceMappingURL=helpers.bundle.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"helpers.bundle.mjs","sources":["../../src/moj/helpers.mjs"],"sourcesContent":["export function removeAttributeValue(el, attr, value) {\n let re, m\n if (el.getAttribute(attr)) {\n if (el.getAttribute(attr) === value) {\n el.removeAttribute(attr)\n } else {\n re = new RegExp(`(^|\\\\s)${value}(\\\\s|$)`)\n m = el.getAttribute(attr).match(re)\n if (m && m.length === 3) {\n el.setAttribute(\n attr,\n el.getAttribute(attr).replace(re, m[1] && m[2] ? ' ' : '')\n )\n }\n }\n }\n}\n\nexport function addAttributeValue(el, attr, value) {\n let re\n if (!el.getAttribute(attr)) {\n el.setAttribute(attr, value)\n } else {\n re = new RegExp(`(^|\\\\s)${value}(\\\\s|$)`)\n if (!re.test(el.getAttribute(attr))) {\n el.setAttribute(attr, `${el.getAttribute(attr)} ${value}`)\n }\n }\n}\n\nexport function dragAndDropSupported() {\n const div = document.createElement('div')\n return typeof div.ondrop !== 'undefined'\n}\n\nexport function formDataSupported() {\n return typeof FormData === 'function'\n}\n\nexport function fileApiSupported() {\n const input = document.createElement('input')\n input.type = 'file'\n return typeof input.files !== 'undefined'\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\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 * @param {HTMLElement} $element - HTML element\n * @param {object} [options] - Handler options\n * @param {function(this: HTMLElement): void} [options.onBeforeFocus] - Callback before focus\n * @param {function(this: HTMLElement): 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 if (options.onBlur) {\n options.onBlur.call($element)\n }\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 if (options.onBeforeFocus) {\n options.onBeforeFocus.call($element)\n }\n $element.focus()\n}\n"],"names":["removeAttributeValue","el","attr","value","re","m","getAttribute","removeAttribute","RegExp","match","length","setAttribute","replace","addAttributeValue","test","dragAndDropSupported","div","document","createElement","ondrop","formDataSupported","FormData","fileApiSupported","input","type","files","getNextSibling","$element","selector","HTMLElement","$sibling","nextElementSibling","matches","getPreviousSibling","previousElementSibling","findNearestMatchingElement","$currentElement","parentElement","setFocus","options","isFocusable","onFocus","addEventListener","onBlur","once","call","onBeforeFocus","focus"],"mappings":"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"}
package/moj/helpers.mjs CHANGED
@@ -1,25 +1,39 @@
1
+ function removeAttributeValue(el, attr, value) {
2
+ let re, m;
3
+ if (el.getAttribute(attr)) {
4
+ if (el.getAttribute(attr) === value) {
5
+ el.removeAttribute(attr);
6
+ } else {
7
+ re = new RegExp(`(^|\\s)${value}(\\s|$)`);
8
+ m = el.getAttribute(attr).match(re);
9
+ if (m && m.length === 3) {
10
+ el.setAttribute(attr, el.getAttribute(attr).replace(re, m[1] && m[2] ? ' ' : ''));
11
+ }
12
+ }
13
+ }
14
+ }
15
+ function addAttributeValue(el, attr, value) {
16
+ let re;
17
+ if (!el.getAttribute(attr)) {
18
+ el.setAttribute(attr, value);
19
+ } else {
20
+ re = new RegExp(`(^|\\s)${value}(\\s|$)`);
21
+ if (!re.test(el.getAttribute(attr))) {
22
+ el.setAttribute(attr, `${el.getAttribute(attr)} ${value}`);
23
+ }
24
+ }
25
+ }
1
26
  function dragAndDropSupported() {
2
27
  const div = document.createElement('div');
3
- return typeof div.ondrop !== 'undefined'
28
+ return typeof div.ondrop !== 'undefined';
4
29
  }
5
-
6
30
  function formDataSupported() {
7
- return typeof FormData === 'function'
31
+ return typeof FormData === 'function';
8
32
  }
9
-
10
33
  function fileApiSupported() {
11
34
  const input = document.createElement('input');
12
35
  input.type = 'file';
13
- return typeof input.files !== 'undefined'
14
- }
15
-
16
- function nodeListForEach(nodes, callback) {
17
- if (window.NodeList.prototype.forEach) {
18
- return nodes.forEach(callback)
19
- }
20
- for (let i = 0; i < nodes.length; i++) {
21
- callback.call(window, nodes[i], i, nodes);
22
- }
36
+ return typeof input.files !== 'undefined';
23
37
  }
24
38
 
25
39
  /**
@@ -28,33 +42,41 @@ function nodeListForEach(nodes, callback) {
28
42
  * Utility function to find an elements previous sibling matching the provided
29
43
  * selector.
30
44
  *
31
- * @param {HTMLElement} $element - Element to find siblings for
32
- * @param {string} selector - selector for required sibling
45
+ * @param {Element | null} $element - Element to find siblings for
46
+ * @param {string} [selector] - selector for required sibling
33
47
  */
34
48
  function getPreviousSibling($element, selector) {
35
- if (!$element) return
49
+ if (!$element || !($element instanceof HTMLElement)) {
50
+ return;
51
+ }
52
+
36
53
  // Get the previous sibling element
37
54
  let $sibling = $element.previousElementSibling;
38
55
 
39
56
  // If the sibling matches our selector, use it
40
57
  // If not, jump to the next sibling and continue the loop
41
58
  while ($sibling) {
42
- if ($sibling.matches(selector)) return $sibling
59
+ if ($sibling.matches(selector)) return $sibling;
43
60
  $sibling = $sibling.previousElementSibling;
44
61
  }
45
62
  }
46
63
 
64
+ /**
65
+ * @param {Element | null} $element
66
+ * @param {string} [selector]
67
+ */
47
68
  function findNearestMatchingElement($element, selector) {
48
- // If no element or selector is provided, return null
49
- if (!$element) return
69
+ // If no element or selector is provided, return
70
+ if (!$element || !($element instanceof HTMLElement) || false) {
71
+ return;
72
+ }
50
73
 
51
74
  // Start with the current element
52
75
  let $currentElement = $element;
53
-
54
76
  while ($currentElement) {
55
77
  // First check the current element
56
78
  if ($currentElement.matches(selector)) {
57
- return $currentElement
79
+ return $currentElement;
58
80
  }
59
81
 
60
82
  // Check all previous siblings
@@ -62,7 +84,7 @@ function findNearestMatchingElement($element, selector) {
62
84
  while ($sibling) {
63
85
  // Check if the sibling itself is a heading
64
86
  if ($sibling.matches(selector)) {
65
- return $sibling
87
+ return $sibling;
66
88
  }
67
89
  $sibling = $sibling.previousElementSibling;
68
90
  }
@@ -85,7 +107,6 @@ function findNearestMatchingElement($element, selector) {
85
107
  */
86
108
  function setFocus($element, options = {}) {
87
109
  const isFocusable = $element.getAttribute('tabindex');
88
-
89
110
  if (!isFocusable) {
90
111
  $element.setAttribute('tabindex', '-1');
91
112
  }
@@ -94,7 +115,9 @@ function setFocus($element, options = {}) {
94
115
  * Handle element focus
95
116
  */
96
117
  function onFocus() {
97
- $element.addEventListener('blur', onBlur, { once: true });
118
+ $element.addEventListener('blur', onBlur, {
119
+ once: true
120
+ });
98
121
  }
99
122
 
100
123
  /**
@@ -104,14 +127,15 @@ function setFocus($element, options = {}) {
104
127
  if (options.onBlur) {
105
128
  options.onBlur.call($element);
106
129
  }
107
-
108
130
  if (!isFocusable) {
109
131
  $element.removeAttribute('tabindex');
110
132
  }
111
133
  }
112
134
 
113
135
  // Add listener to reset element on blur, after focus
114
- $element.addEventListener('focus', onFocus, { once: true });
136
+ $element.addEventListener('focus', onFocus, {
137
+ once: true
138
+ });
115
139
 
116
140
  // Focus element
117
141
  if (options.onBeforeFocus) {
@@ -120,5 +144,5 @@ function setFocus($element, options = {}) {
120
144
  $element.focus();
121
145
  }
122
146
 
123
- export { dragAndDropSupported, fileApiSupported, findNearestMatchingElement, formDataSupported, getPreviousSibling, nodeListForEach, setFocus };
147
+ export { addAttributeValue, dragAndDropSupported, fileApiSupported, findNearestMatchingElement, formDataSupported, getPreviousSibling, removeAttributeValue, setFocus };
124
148
  //# sourceMappingURL=helpers.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"helpers.mjs","sources":["../../src/moj/helpers.mjs"],"sourcesContent":["export function removeAttributeValue(el, attr, value) {\n let re, m\n if (el.getAttribute(attr)) {\n if (el.getAttribute(attr) === value) {\n el.removeAttribute(attr)\n } else {\n re = new RegExp(`(^|\\\\s)${value}(\\\\s|$)`)\n m = el.getAttribute(attr).match(re)\n if (m && m.length === 3) {\n el.setAttribute(\n attr,\n el.getAttribute(attr).replace(re, m[1] && m[2] ? ' ' : '')\n )\n }\n }\n }\n}\n\nexport function addAttributeValue(el, attr, value) {\n let re\n if (!el.getAttribute(attr)) {\n el.setAttribute(attr, value)\n } else {\n re = new RegExp(`(^|\\\\s)${value}(\\\\s|$)`)\n if (!re.test(el.getAttribute(attr))) {\n el.setAttribute(attr, `${el.getAttribute(attr)} ${value}`)\n }\n }\n}\n\nexport function dragAndDropSupported() {\n const div = document.createElement('div')\n return typeof div.ondrop !== 'undefined'\n}\n\nexport function formDataSupported() {\n return typeof FormData === 'function'\n}\n\nexport function fileApiSupported() {\n const input = document.createElement('input')\n input.type = 'file'\n return typeof input.files !== 'undefined'\n}\n\nexport function nodeListForEach(nodes, callback) {\n if (window.NodeList.prototype.forEach) {\n return nodes.forEach(callback)\n }\n for (let i = 0; i < nodes.length; i++) {\n callback.call(window, nodes[i], i, nodes)\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 {HTMLElement} $element - Element to find siblings for\n * @param {string} selector - selector for required sibling\n */\nexport function getNextSibling($element, selector) {\n if (!$element) return\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 {HTMLElement} $element - Element to find siblings for\n * @param {string} selector - selector for required sibling\n */\nexport function getPreviousSibling($element, selector) {\n if (!$element) return\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\nexport function findNearestMatchingElement($element, selector) {\n // If no element or selector is provided, return null\n if (!$element) return\n if (!selector) return\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\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 * @param {HTMLElement} $element - HTML element\n * @param {object} [options] - Handler options\n * @param {function(this: HTMLElement): void} [options.onBeforeFocus] - Callback before focus\n * @param {function(this: HTMLElement): 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 if (options.onBlur) {\n options.onBlur.call($element)\n }\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 if (options.onBeforeFocus) {\n options.onBeforeFocus.call($element)\n }\n $element.focus()\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"helpers.mjs","sources":["../../src/moj/helpers.mjs"],"sourcesContent":["export function removeAttributeValue(el, attr, value) {\n let re, m\n if (el.getAttribute(attr)) {\n if (el.getAttribute(attr) === value) {\n el.removeAttribute(attr)\n } else {\n re = new RegExp(`(^|\\\\s)${value}(\\\\s|$)`)\n m = el.getAttribute(attr).match(re)\n if (m && m.length === 3) {\n el.setAttribute(\n attr,\n el.getAttribute(attr).replace(re, m[1] && m[2] ? ' ' : '')\n )\n }\n }\n }\n}\n\nexport function addAttributeValue(el, attr, value) {\n let re\n if (!el.getAttribute(attr)) {\n el.setAttribute(attr, value)\n } else {\n re = new RegExp(`(^|\\\\s)${value}(\\\\s|$)`)\n if (!re.test(el.getAttribute(attr))) {\n el.setAttribute(attr, `${el.getAttribute(attr)} ${value}`)\n }\n }\n}\n\nexport function dragAndDropSupported() {\n const div = document.createElement('div')\n return typeof div.ondrop !== 'undefined'\n}\n\nexport function formDataSupported() {\n return typeof FormData === 'function'\n}\n\nexport function fileApiSupported() {\n const input = document.createElement('input')\n input.type = 'file'\n return typeof input.files !== 'undefined'\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\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 * @param {HTMLElement} $element - HTML element\n * @param {object} [options] - Handler options\n * @param {function(this: HTMLElement): void} [options.onBeforeFocus] - Callback before focus\n * @param {function(this: HTMLElement): 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 if (options.onBlur) {\n options.onBlur.call($element)\n }\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 if (options.onBeforeFocus) {\n options.onBeforeFocus.call($element)\n }\n $element.focus()\n}\n"],"names":["removeAttributeValue","el","attr","value","re","m","getAttribute","removeAttribute","RegExp","match","length","setAttribute","replace","addAttributeValue","test","dragAndDropSupported","div","document","createElement","ondrop","formDataSupported","FormData","fileApiSupported","input","type","files","getPreviousSibling","$element","selector","HTMLElement","$sibling","previousElementSibling","matches","findNearestMatchingElement","$currentElement","parentElement","setFocus","options","isFocusable","onFocus","addEventListener","onBlur","once","call","onBeforeFocus","focus"],"mappings":"AAAO,SAASA,oBAAoBA,CAACC,EAAE,EAAEC,IAAI,EAAEC,KAAK,EAAE;EACpD,IAAIC,EAAE,EAAEC,CAAC;AACT,EAAA,IAAIJ,EAAE,CAACK,YAAY,CAACJ,IAAI,CAAC,EAAE;IACzB,IAAID,EAAE,CAACK,YAAY,CAACJ,IAAI,CAAC,KAAKC,KAAK,EAAE;AACnCF,MAAAA,EAAE,CAACM,eAAe,CAACL,IAAI,CAAC;AAC1B,KAAC,MAAM;AACLE,MAAAA,EAAE,GAAG,IAAII,MAAM,CAAC,CAAUL,OAAAA,EAAAA,KAAK,SAAS,CAAC;MACzCE,CAAC,GAAGJ,EAAE,CAACK,YAAY,CAACJ,IAAI,CAAC,CAACO,KAAK,CAACL,EAAE,CAAC;AACnC,MAAA,IAAIC,CAAC,IAAIA,CAAC,CAACK,MAAM,KAAK,CAAC,EAAE;AACvBT,QAAAA,EAAE,CAACU,YAAY,CACbT,IAAI,EACJD,EAAE,CAACK,YAAY,CAACJ,IAAI,CAAC,CAACU,OAAO,CAACR,EAAE,EAAEC,CAAC,CAAC,CAAC,CAAC,IAAIA,CAAC,CAAC,CAAC,CAAC,GAAG,GAAG,GAAG,EAAE,CAC3D,CAAC;AACH;AACF;AACF;AACF;AAEO,SAASQ,iBAAiBA,CAACZ,EAAE,EAAEC,IAAI,EAAEC,KAAK,EAAE;AACjD,EAAA,IAAIC,EAAE;AACN,EAAA,IAAI,CAACH,EAAE,CAACK,YAAY,CAACJ,IAAI,CAAC,EAAE;AAC1BD,IAAAA,EAAE,CAACU,YAAY,CAACT,IAAI,EAAEC,KAAK,CAAC;AAC9B,GAAC,MAAM;AACLC,IAAAA,EAAE,GAAG,IAAII,MAAM,CAAC,CAAUL,OAAAA,EAAAA,KAAK,SAAS,CAAC;AACzC,IAAA,IAAI,CAACC,EAAE,CAACU,IAAI,CAACb,EAAE,CAACK,YAAY,CAACJ,IAAI,CAAC,CAAC,EAAE;AACnCD,MAAAA,EAAE,CAACU,YAAY,CAACT,IAAI,EAAE,CAAGD,EAAAA,EAAE,CAACK,YAAY,CAACJ,IAAI,CAAC,CAAIC,CAAAA,EAAAA,KAAK,EAAE,CAAC;AAC5D;AACF;AACF;AAEO,SAASY,oBAAoBA,GAAG;AACrC,EAAA,MAAMC,GAAG,GAAGC,QAAQ,CAACC,aAAa,CAAC,KAAK,CAAC;AACzC,EAAA,OAAO,OAAOF,GAAG,CAACG,MAAM,KAAK,WAAW;AAC1C;AAEO,SAASC,iBAAiBA,GAAG;EAClC,OAAO,OAAOC,QAAQ,KAAK,UAAU;AACvC;AAEO,SAASC,gBAAgBA,GAAG;AACjC,EAAA,MAAMC,KAAK,GAAGN,QAAQ,CAACC,aAAa,CAAC,OAAO,CAAC;EAC7CK,KAAK,CAACC,IAAI,GAAG,MAAM;AACnB,EAAA,OAAO,OAAOD,KAAK,CAACE,KAAK,KAAK,WAAW;AAC3C;;AA8BA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,SAASC,kBAAkBA,CAACC,QAAQ,EAAEC,QAAQ,EAAE;EACrD,IAAI,CAACD,QAAQ,IAAI,EAAEA,QAAQ,YAAYE,WAAW,CAAC,EAAE;AACnD,IAAA;AACF;;AAEA;AACA,EAAA,IAAIC,QAAQ,GAAGH,QAAQ,CAACI,sBAAsB;;AAK9C;AACA;AACA,EAAA,OAAOD,QAAQ,EAAE;IACf,IAAIA,QAAQ,CAACE,OAAO,CAACJ,QAAQ,CAAC,EAAE,OAAOE,QAAQ;IAC/CA,QAAQ,GAAGA,QAAQ,CAACC,sBAAsB;AAC5C;AACF;;AAEA;AACA;AACA;AACA;AACO,SAASE,0BAA0BA,CAACN,QAAQ,EAAEC,QAAQ,EAAE;AAC7D;EACA,IAAI,CAACD,QAAQ,IAAI,EAAEA,QAAQ,YAAYE,WAAW,CAAC,IAAI,KAAS,EAAE;AAChE,IAAA;AACF;;AAEA;EACA,IAAIK,eAAe,GAAGP,QAAQ;AAE9B,EAAA,OAAOO,eAAe,EAAE;AACtB;AACA,IAAA,IAAIA,eAAe,CAACF,OAAO,CAACJ,QAAQ,CAAC,EAAE;AACrC,MAAA,OAAOM,eAAe;AACxB;;AAEA;AACA,IAAA,IAAIJ,QAAQ,GAAGI,eAAe,CAACH,sBAAsB;AACrD,IAAA,OAAOD,QAAQ,EAAE;AACf;AACA,MAAA,IAAIA,QAAQ,CAACE,OAAO,CAACJ,QAAQ,CAAC,EAAE;AAC9B,QAAA,OAAOE,QAAQ;AACjB;MACAA,QAAQ,GAAGA,QAAQ,CAACC,sBAAsB;AAC5C;;AAEA;IACAG,eAAe,GAAGA,eAAe,CAACC,aAAa;AACjD;AACF;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,SAASC,QAAQA,CAACT,QAAQ,EAAEU,OAAO,GAAG,EAAE,EAAE;AAC/C,EAAA,MAAMC,WAAW,GAAGX,QAAQ,CAACrB,YAAY,CAAC,UAAU,CAAC;EAErD,IAAI,CAACgC,WAAW,EAAE;AAChBX,IAAAA,QAAQ,CAAChB,YAAY,CAAC,UAAU,EAAE,IAAI,CAAC;AACzC;;AAEA;AACF;AACA;EACE,SAAS4B,OAAOA,GAAG;AACjBZ,IAAAA,QAAQ,CAACa,gBAAgB,CAAC,MAAM,EAAEC,MAAM,EAAE;AAAEC,MAAAA,IAAI,EAAE;AAAK,KAAC,CAAC;AAC3D;;AAEA;AACF;AACA;EACE,SAASD,MAAMA,GAAG;IAChB,IAAIJ,OAAO,CAACI,MAAM,EAAE;AAClBJ,MAAAA,OAAO,CAACI,MAAM,CAACE,IAAI,CAAChB,QAAQ,CAAC;AAC/B;IAEA,IAAI,CAACW,WAAW,EAAE;AAChBX,MAAAA,QAAQ,CAACpB,eAAe,CAAC,UAAU,CAAC;AACtC;AACF;;AAEA;AACAoB,EAAAA,QAAQ,CAACa,gBAAgB,CAAC,OAAO,EAAED,OAAO,EAAE;AAAEG,IAAAA,IAAI,EAAE;AAAK,GAAC,CAAC;;AAE3D;EACA,IAAIL,OAAO,CAACO,aAAa,EAAE;AACzBP,IAAAA,OAAO,CAACO,aAAa,CAACD,IAAI,CAAChB,QAAQ,CAAC;AACtC;EACAA,QAAQ,CAACkB,KAAK,EAAE;AAClB;;;;"}
package/moj/init.js CHANGED
@@ -1,5 +1,14 @@
1
- if (window.GOVUKPrototypeKit && window.GOVUKPrototypeKit.documentReady) {
2
- window.GOVUKPrototypeKit.documentReady(function () {
1
+ import * as MOJFrontend from '../moj/moj-frontend.min.js'
2
+
3
+ // Maintain window global for compatibility
4
+ window.MOJFrontend = MOJFrontend
5
+
6
+ if (
7
+ window.GOVUKPrototypeKit &&
8
+ window.GOVUKPrototypeKit.documentReady &&
9
+ window.GOVUKPrototypeKit.majorVersion >= 13
10
+ ) {
11
+ window.GOVUKPrototypeKit.documentReady(() => {
3
12
  window.MOJFrontend.initAll()
4
13
  })
5
14
  }