@ministryofjustice/frontend 3.4.0 → 3.5.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 (33) hide show
  1. package/moj/all.jquery.min.js +7 -70
  2. package/moj/all.js +2856 -2865
  3. package/moj/components/add-another/add-another.js +135 -104
  4. package/moj/components/alert/alert.js +482 -247
  5. package/moj/components/alert/alert.spec.helper.js +30 -5
  6. package/moj/components/button-menu/button-menu.js +346 -319
  7. package/moj/components/date-picker/date-picker.js +925 -900
  8. package/moj/components/filter-toggle-button/filter-toggle-button.js +122 -91
  9. package/moj/components/form-validator/form-validator.js +399 -164
  10. package/moj/components/multi-file-upload/multi-file-upload.js +445 -210
  11. package/moj/components/multi-select/multi-select.js +106 -75
  12. package/moj/components/password-reveal/password-reveal.js +64 -33
  13. package/moj/components/rich-text-editor/rich-text-editor.js +186 -153
  14. package/moj/components/search-toggle/search-toggle.js +77 -46
  15. package/moj/components/sortable-table/sortable-table.js +167 -146
  16. package/moj/helpers/_links.scss +1 -1
  17. package/moj/helpers.js +218 -180
  18. package/moj/moj-frontend.min.js +7 -70
  19. package/moj/version.js +28 -1
  20. package/package.json +1 -1
  21. package/moj/all.spec.js +0 -24
  22. package/moj/components/add-another/add-another.spec.js +0 -165
  23. package/moj/components/alert/alert.spec.js +0 -229
  24. package/moj/components/button-menu/button-menu.spec.js +0 -360
  25. package/moj/components/date-picker/date-picker.spec.js +0 -1178
  26. package/moj/components/filter-toggle-button/filter-toggle-button.spec.js +0 -302
  27. package/moj/components/multi-file-upload/multi-file-upload.spec.js +0 -510
  28. package/moj/components/multi-select/multi-select.spec.js +0 -128
  29. package/moj/components/password-reveal/password-reveal.spec.js +0 -57
  30. package/moj/components/search-toggle/search-toggle.spec.js +0 -129
  31. package/moj/components/sortable-table/sortable-table.spec.js +0 -362
  32. package/moj/helpers.spec.js +0 -235
  33. package/moj/namespace.js +0 -2
package/moj/helpers.js CHANGED
@@ -1,180 +1,218 @@
1
- MOJFrontend.removeAttributeValue = function (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(
11
- attr,
12
- el.getAttribute(attr).replace(re, m[1] && m[2] ? ' ' : '')
13
- )
14
- }
15
- }
16
- }
17
- }
18
-
19
- MOJFrontend.addAttributeValue = function (el, attr, value) {
20
- let re
21
- if (!el.getAttribute(attr)) {
22
- el.setAttribute(attr, value)
23
- } else {
24
- re = new RegExp(`(^|\\s)${value}(\\s|$)`)
25
- if (!re.test(el.getAttribute(attr))) {
26
- el.setAttribute(attr, `${el.getAttribute(attr)} ${value}`)
27
- }
28
- }
29
- }
30
-
31
- MOJFrontend.dragAndDropSupported = function () {
32
- const div = document.createElement('div')
33
- return typeof div.ondrop !== 'undefined'
34
- }
35
-
36
- MOJFrontend.formDataSupported = function () {
37
- return typeof FormData === 'function'
38
- }
39
-
40
- MOJFrontend.fileApiSupported = function () {
41
- const input = document.createElement('input')
42
- input.type = 'file'
43
- return typeof input.files !== 'undefined'
44
- }
45
-
46
- MOJFrontend.nodeListForEach = function (nodes, callback) {
47
- if (window.NodeList.prototype.forEach) {
48
- return nodes.forEach(callback)
49
- }
50
- for (let i = 0; i < nodes.length; i++) {
51
- callback.call(window, nodes[i], i, nodes)
52
- }
53
- }
54
-
55
- /**
56
- * Find an elements next sibling
57
- *
58
- * Utility function to find an elements next sibling matching the provided
59
- * selector.
60
- *
61
- * @param {HTMLElement} element - Element to find siblings for
62
- * @param {string} selector - selector for required sibling
63
- */
64
- MOJFrontend.getNextSibling = function ($element, selector) {
65
- if (!$element) return
66
- // Get the next sibling element
67
- let $sibling = $element.nextElementSibling
68
-
69
- // If there's no selector, return the first sibling
70
- if (!selector) return $sibling
71
-
72
- // If the sibling matches our selector, use it
73
- // If not, jump to the next sibling and continue the loop
74
- while ($sibling) {
75
- if ($sibling.matches(selector)) return $sibling
76
- $sibling = $sibling.nextElementSibling
77
- }
78
- }
79
-
80
- /**
81
- * Find an elements preceding sibling
82
- *
83
- * Utility function to find an elements previous sibling matching the provided
84
- * selector.
85
- *
86
- * @param {HTMLElement} element - Element to find siblings for
87
- * @param {string} selector - selector for required sibling
88
- */
89
- MOJFrontend.getPreviousSibling = function ($element, selector) {
90
- if (!$element) return
91
- // Get the previous sibling element
92
- let $sibling = $element.previousElementSibling
93
-
94
- // If there's no selector, return the first sibling
95
- if (!selector) return $sibling
96
-
97
- // If the sibling matches our selector, use it
98
- // If not, jump to the next sibling and continue the loop
99
- while ($sibling) {
100
- if ($sibling.matches(selector)) return $sibling
101
- $sibling = $sibling.previousElementSibling
102
- }
103
- }
104
-
105
- MOJFrontend.findNearestMatchingElement = function ($element, selector) {
106
- // If no element or selector is provided, return null
107
- if (!$element) return
108
- if (!selector) return
109
-
110
- // Start with the current element
111
- let $currentElement = $element
112
-
113
- while ($currentElement) {
114
- // First check the current element
115
- if ($currentElement.matches(selector)) {
116
- return $currentElement
117
- }
118
-
119
- // Check all previous siblings
120
- let $sibling = $currentElement.previousElementSibling
121
- while ($sibling) {
122
- // Check if the sibling itself is a heading
123
- if ($sibling.matches(selector)) {
124
- return $sibling
125
- }
126
- $sibling = $sibling.previousElementSibling
127
- }
128
-
129
- // If no match found in siblings, move up to parent
130
- $currentElement = $currentElement.parentElement
131
- }
132
- }
133
-
134
- /**
135
- * Move focus to element
136
- *
137
- * Sets tabindex to -1 to make the element programmatically focusable,
138
- * but removes it on blur as the element doesn't need to be focused again.
139
- *
140
- * @param {HTMLElement} $element - HTML element
141
- * @param {object} [options] - Handler options
142
- * @param {function(this: HTMLElement): void} [options.onBeforeFocus] - Callback before focus
143
- * @param {function(this: HTMLElement): void} [options.onBlur] - Callback on blur
144
- */
145
- MOJFrontend.setFocus = function ($element, options = {}) {
146
- const isFocusable = $element.getAttribute('tabindex')
147
-
148
- if (!isFocusable) {
149
- $element.setAttribute('tabindex', '-1')
150
- }
151
-
152
- /**
153
- * Handle element focus
154
- */
155
- function onFocus() {
156
- $element.addEventListener('blur', onBlur, { once: true })
157
- }
158
-
159
- /**
160
- * Handle element blur
161
- */
162
- function onBlur() {
163
- if (options.onBlur) {
164
- options.onBlur.call($element)
165
- }
166
-
167
- if (!isFocusable) {
168
- $element.removeAttribute('tabindex')
169
- }
170
- }
171
-
172
- // Add listener to reset element on blur, after focus
173
- $element.addEventListener('focus', onFocus, { once: true })
174
-
175
- // Focus element
176
- if (options.onBeforeFocus) {
177
- options.onBeforeFocus.call($element)
178
- }
179
- $element.focus()
180
- }
1
+ (function (global, factory) {
2
+ typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
3
+ typeof define === 'function' && define.amd ? define(factory) :
4
+ (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.MOJFrontend = factory());
5
+ })(this, (function () { 'use strict';
6
+
7
+ function getDefaultExportFromCjs (x) {
8
+ return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x;
9
+ }
10
+
11
+ var helpers$1;
12
+ var hasRequiredHelpers;
13
+
14
+ function requireHelpers () {
15
+ if (hasRequiredHelpers) return helpers$1;
16
+ hasRequiredHelpers = 1;
17
+ function removeAttributeValue(el, attr, value) {
18
+ let re, m;
19
+ if (el.getAttribute(attr)) {
20
+ if (el.getAttribute(attr) === value) {
21
+ el.removeAttribute(attr);
22
+ } else {
23
+ re = new RegExp(`(^|\\s)${value}(\\s|$)`);
24
+ m = el.getAttribute(attr).match(re);
25
+ if (m && m.length === 3) {
26
+ el.setAttribute(
27
+ attr,
28
+ el.getAttribute(attr).replace(re, m[1] && m[2] ? ' ' : '')
29
+ );
30
+ }
31
+ }
32
+ }
33
+ }
34
+
35
+ function addAttributeValue(el, attr, value) {
36
+ let re;
37
+ if (!el.getAttribute(attr)) {
38
+ el.setAttribute(attr, value);
39
+ } else {
40
+ re = new RegExp(`(^|\\s)${value}(\\s|$)`);
41
+ if (!re.test(el.getAttribute(attr))) {
42
+ el.setAttribute(attr, `${el.getAttribute(attr)} ${value}`);
43
+ }
44
+ }
45
+ }
46
+
47
+ function dragAndDropSupported() {
48
+ const div = document.createElement('div');
49
+ return typeof div.ondrop !== 'undefined'
50
+ }
51
+
52
+ function formDataSupported() {
53
+ return typeof FormData === 'function'
54
+ }
55
+
56
+ function fileApiSupported() {
57
+ const input = document.createElement('input');
58
+ input.type = 'file';
59
+ return typeof input.files !== 'undefined'
60
+ }
61
+
62
+ function nodeListForEach(nodes, callback) {
63
+ if (window.NodeList.prototype.forEach) {
64
+ return nodes.forEach(callback)
65
+ }
66
+ for (let i = 0; i < nodes.length; i++) {
67
+ callback.call(window, nodes[i], i, nodes);
68
+ }
69
+ }
70
+
71
+ /**
72
+ * Find an elements next sibling
73
+ *
74
+ * Utility function to find an elements next sibling matching the provided
75
+ * selector.
76
+ *
77
+ * @param {HTMLElement} $element - Element to find siblings for
78
+ * @param {string} selector - selector for required sibling
79
+ */
80
+ function getNextSibling($element, selector) {
81
+ if (!$element) return
82
+ // Get the next sibling element
83
+ let $sibling = $element.nextElementSibling;
84
+
85
+ // If there's no selector, return the first sibling
86
+ if (!selector) return $sibling
87
+
88
+ // If the sibling matches our selector, use it
89
+ // If not, jump to the next sibling and continue the loop
90
+ while ($sibling) {
91
+ if ($sibling.matches(selector)) return $sibling
92
+ $sibling = $sibling.nextElementSibling;
93
+ }
94
+ }
95
+
96
+ /**
97
+ * Find an elements preceding sibling
98
+ *
99
+ * Utility function to find an elements previous sibling matching the provided
100
+ * selector.
101
+ *
102
+ * @param {HTMLElement} $element - Element to find siblings for
103
+ * @param {string} selector - selector for required sibling
104
+ */
105
+ function getPreviousSibling($element, selector) {
106
+ if (!$element) return
107
+ // Get the previous sibling element
108
+ let $sibling = $element.previousElementSibling;
109
+
110
+ // If there's no selector, return the first sibling
111
+ if (!selector) return $sibling
112
+
113
+ // If the sibling matches our selector, use it
114
+ // If not, jump to the next sibling and continue the loop
115
+ while ($sibling) {
116
+ if ($sibling.matches(selector)) return $sibling
117
+ $sibling = $sibling.previousElementSibling;
118
+ }
119
+ }
120
+
121
+ function findNearestMatchingElement($element, selector) {
122
+ // If no element or selector is provided, return null
123
+ if (!$element) return
124
+ if (!selector) return
125
+
126
+ // Start with the current element
127
+ let $currentElement = $element;
128
+
129
+ while ($currentElement) {
130
+ // First check the current element
131
+ if ($currentElement.matches(selector)) {
132
+ return $currentElement
133
+ }
134
+
135
+ // Check all previous siblings
136
+ let $sibling = $currentElement.previousElementSibling;
137
+ while ($sibling) {
138
+ // Check if the sibling itself is a heading
139
+ if ($sibling.matches(selector)) {
140
+ return $sibling
141
+ }
142
+ $sibling = $sibling.previousElementSibling;
143
+ }
144
+
145
+ // If no match found in siblings, move up to parent
146
+ $currentElement = $currentElement.parentElement;
147
+ }
148
+ }
149
+
150
+ /**
151
+ * Move focus to element
152
+ *
153
+ * Sets tabindex to -1 to make the element programmatically focusable,
154
+ * but removes it on blur as the element doesn't need to be focused again.
155
+ *
156
+ * @param {HTMLElement} $element - HTML element
157
+ * @param {object} [options] - Handler options
158
+ * @param {function(this: HTMLElement): void} [options.onBeforeFocus] - Callback before focus
159
+ * @param {function(this: HTMLElement): void} [options.onBlur] - Callback on blur
160
+ */
161
+ function setFocus($element, options = {}) {
162
+ const isFocusable = $element.getAttribute('tabindex');
163
+
164
+ if (!isFocusable) {
165
+ $element.setAttribute('tabindex', '-1');
166
+ }
167
+
168
+ /**
169
+ * Handle element focus
170
+ */
171
+ function onFocus() {
172
+ $element.addEventListener('blur', onBlur, { once: true });
173
+ }
174
+
175
+ /**
176
+ * Handle element blur
177
+ */
178
+ function onBlur() {
179
+ if (options.onBlur) {
180
+ options.onBlur.call($element);
181
+ }
182
+
183
+ if (!isFocusable) {
184
+ $element.removeAttribute('tabindex');
185
+ }
186
+ }
187
+
188
+ // Add listener to reset element on blur, after focus
189
+ $element.addEventListener('focus', onFocus, { once: true });
190
+
191
+ // Focus element
192
+ if (options.onBeforeFocus) {
193
+ options.onBeforeFocus.call($element);
194
+ }
195
+ $element.focus();
196
+ }
197
+
198
+ helpers$1 = {
199
+ removeAttributeValue,
200
+ addAttributeValue,
201
+ dragAndDropSupported,
202
+ formDataSupported,
203
+ fileApiSupported,
204
+ nodeListForEach,
205
+ getNextSibling,
206
+ getPreviousSibling,
207
+ findNearestMatchingElement,
208
+ setFocus
209
+ };
210
+ return helpers$1;
211
+ }
212
+
213
+ var helpersExports = requireHelpers();
214
+ var helpers = /*@__PURE__*/getDefaultExportFromCjs(helpersExports);
215
+
216
+ return helpers;
217
+
218
+ }));