@ministryofjustice/frontend 3.3.1 → 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.
- package/README.md +4 -10
- package/govuk-prototype-kit.config.json +5 -16
- package/moj/all.jquery.min.js +15 -4
- package/moj/all.js +2856 -2280
- package/moj/all.scss +2 -0
- package/moj/components/_all.scss +1 -0
- package/moj/components/action-bar/_action-bar.scss +4 -6
- package/moj/components/add-another/_add-another.scss +9 -7
- package/moj/components/add-another/add-another.js +128 -76
- package/moj/components/alert/README.md +0 -0
- package/moj/components/alert/_alert.scss +142 -0
- package/moj/components/alert/alert.js +482 -0
- package/moj/components/alert/alert.spec.helper.js +92 -0
- package/moj/components/alert/macro.njk +3 -0
- package/moj/components/alert/template.njk +83 -0
- package/moj/components/badge/_badge.scss +3 -4
- package/moj/components/banner/_banner.scss +5 -10
- package/moj/components/button-menu/_button-menu.scss +10 -9
- package/moj/components/button-menu/button-menu.js +348 -318
- package/moj/components/cookie-banner/_cookie-banner.scss +6 -5
- package/moj/components/currency-input/_currency-input.scss +4 -4
- package/moj/components/date-picker/README.md +14 -17
- package/moj/components/date-picker/_date-picker.scss +122 -106
- package/moj/components/date-picker/date-picker.js +927 -900
- package/moj/components/filter/README.md +1 -1
- package/moj/components/filter/_filter.scss +53 -75
- package/moj/components/filter-toggle-button/filter-toggle-button.js +122 -87
- package/moj/components/form-validator/form-validator.js +399 -156
- package/moj/components/header/_header.scss +17 -19
- package/moj/components/identity-bar/_identity-bar.scss +5 -5
- package/moj/components/interruption-card/_interruption-card.scss +2 -2
- package/moj/components/messages/_messages.scss +12 -19
- package/moj/components/multi-file-upload/README.md +1 -1
- package/moj/components/multi-file-upload/_multi-file-upload.scss +34 -30
- package/moj/components/multi-file-upload/multi-file-upload.js +454 -183
- package/moj/components/multi-select/_multi-select.scss +4 -3
- package/moj/components/multi-select/multi-select.js +106 -70
- package/moj/components/notification-badge/_notification-badge.scss +12 -12
- package/moj/components/organisation-switcher/_organisation-switcher.scss +1 -1
- package/moj/components/page-header-actions/_page-header-actions.scss +3 -2
- package/moj/components/pagination/_pagination.scss +26 -31
- package/moj/components/password-reveal/_password-reveal.scss +1 -2
- package/moj/components/password-reveal/password-reveal.js +63 -31
- package/moj/components/primary-navigation/_primary-navigation.scss +26 -29
- package/moj/components/progress-bar/_progress-bar.scss +21 -26
- package/moj/components/rich-text-editor/_rich-text-editor.scss +17 -16
- package/moj/components/rich-text-editor/rich-text-editor.js +186 -139
- package/moj/components/search/_search.scss +6 -4
- package/moj/components/search-toggle/search-toggle.js +83 -53
- package/moj/components/search-toggle/search-toggle.scss +21 -15
- package/moj/components/side-navigation/_side-navigation.scss +12 -21
- package/moj/components/sortable-table/_sortable-table.scss +25 -23
- package/moj/components/sortable-table/sortable-table.js +162 -119
- package/moj/components/sub-navigation/_sub-navigation.scss +24 -28
- package/moj/components/tag/_tag.scss +8 -9
- package/moj/components/task-list/_task-list.scss +8 -7
- package/moj/components/ticket-panel/_ticket-panel.scss +14 -6
- package/moj/components/timeline/_timeline.scss +18 -20
- package/moj/filters/all.js +28 -30
- package/moj/filters/prototype-kit-13-filters.js +2 -1
- package/moj/helpers/_all.scss +1 -0
- package/moj/helpers/_hidden.scss +1 -1
- package/moj/helpers/_links.scss +20 -0
- package/moj/helpers.js +218 -51
- package/moj/init.js +2 -2
- package/moj/moj-frontend.min.css +2 -2
- package/moj/moj-frontend.min.js +15 -4
- package/moj/objects/_filter-layout.scss +11 -10
- package/moj/objects/_scrollable-pane.scss +11 -14
- package/moj/settings/_colours.scss +5 -0
- package/moj/settings/_measurements.scss +0 -2
- package/moj/utilities/_hidden.scss +3 -3
- package/moj/utilities/_width-container.scss +1 -1
- package/moj/version.js +28 -1
- package/package.json +1 -1
- package/moj/all.spec.js +0 -22
- package/moj/components/button-menu/button-menu.spec.js +0 -361
- package/moj/components/date-picker/date-picker.spec.js +0 -1130
- package/moj/components/filter-toggle-button/filter-toggle-button.spec.js +0 -304
- package/moj/components/multi-select/multi-select.spec.js +0 -135
- package/moj/components/password-reveal/password-reveal.spec.js +0 -55
- package/moj/components/search-toggle/search-toggle.spec.js +0 -134
- package/moj/namespace.js +0 -1
|
@@ -1,183 +1,454 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
}
|
|
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 _global_window_jQuery = window.jQuery;
|
|
12
|
+
|
|
13
|
+
var helpers;
|
|
14
|
+
var hasRequiredHelpers;
|
|
15
|
+
|
|
16
|
+
function requireHelpers () {
|
|
17
|
+
if (hasRequiredHelpers) return helpers;
|
|
18
|
+
hasRequiredHelpers = 1;
|
|
19
|
+
function removeAttributeValue(el, attr, value) {
|
|
20
|
+
let re, m;
|
|
21
|
+
if (el.getAttribute(attr)) {
|
|
22
|
+
if (el.getAttribute(attr) === value) {
|
|
23
|
+
el.removeAttribute(attr);
|
|
24
|
+
} else {
|
|
25
|
+
re = new RegExp(`(^|\\s)${value}(\\s|$)`);
|
|
26
|
+
m = el.getAttribute(attr).match(re);
|
|
27
|
+
if (m && m.length === 3) {
|
|
28
|
+
el.setAttribute(
|
|
29
|
+
attr,
|
|
30
|
+
el.getAttribute(attr).replace(re, m[1] && m[2] ? ' ' : '')
|
|
31
|
+
);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
function addAttributeValue(el, attr, value) {
|
|
38
|
+
let re;
|
|
39
|
+
if (!el.getAttribute(attr)) {
|
|
40
|
+
el.setAttribute(attr, value);
|
|
41
|
+
} else {
|
|
42
|
+
re = new RegExp(`(^|\\s)${value}(\\s|$)`);
|
|
43
|
+
if (!re.test(el.getAttribute(attr))) {
|
|
44
|
+
el.setAttribute(attr, `${el.getAttribute(attr)} ${value}`);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
function dragAndDropSupported() {
|
|
50
|
+
const div = document.createElement('div');
|
|
51
|
+
return typeof div.ondrop !== 'undefined'
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
function formDataSupported() {
|
|
55
|
+
return typeof FormData === 'function'
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
function fileApiSupported() {
|
|
59
|
+
const input = document.createElement('input');
|
|
60
|
+
input.type = 'file';
|
|
61
|
+
return typeof input.files !== 'undefined'
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
function nodeListForEach(nodes, callback) {
|
|
65
|
+
if (window.NodeList.prototype.forEach) {
|
|
66
|
+
return nodes.forEach(callback)
|
|
67
|
+
}
|
|
68
|
+
for (let i = 0; i < nodes.length; i++) {
|
|
69
|
+
callback.call(window, nodes[i], i, nodes);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Find an elements next sibling
|
|
75
|
+
*
|
|
76
|
+
* Utility function to find an elements next sibling matching the provided
|
|
77
|
+
* selector.
|
|
78
|
+
*
|
|
79
|
+
* @param {HTMLElement} $element - Element to find siblings for
|
|
80
|
+
* @param {string} selector - selector for required sibling
|
|
81
|
+
*/
|
|
82
|
+
function getNextSibling($element, selector) {
|
|
83
|
+
if (!$element) return
|
|
84
|
+
// Get the next sibling element
|
|
85
|
+
let $sibling = $element.nextElementSibling;
|
|
86
|
+
|
|
87
|
+
// If there's no selector, return the first sibling
|
|
88
|
+
if (!selector) return $sibling
|
|
89
|
+
|
|
90
|
+
// If the sibling matches our selector, use it
|
|
91
|
+
// If not, jump to the next sibling and continue the loop
|
|
92
|
+
while ($sibling) {
|
|
93
|
+
if ($sibling.matches(selector)) return $sibling
|
|
94
|
+
$sibling = $sibling.nextElementSibling;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* Find an elements preceding sibling
|
|
100
|
+
*
|
|
101
|
+
* Utility function to find an elements previous sibling matching the provided
|
|
102
|
+
* selector.
|
|
103
|
+
*
|
|
104
|
+
* @param {HTMLElement} $element - Element to find siblings for
|
|
105
|
+
* @param {string} selector - selector for required sibling
|
|
106
|
+
*/
|
|
107
|
+
function getPreviousSibling($element, selector) {
|
|
108
|
+
if (!$element) return
|
|
109
|
+
// Get the previous sibling element
|
|
110
|
+
let $sibling = $element.previousElementSibling;
|
|
111
|
+
|
|
112
|
+
// If there's no selector, return the first sibling
|
|
113
|
+
if (!selector) return $sibling
|
|
114
|
+
|
|
115
|
+
// If the sibling matches our selector, use it
|
|
116
|
+
// If not, jump to the next sibling and continue the loop
|
|
117
|
+
while ($sibling) {
|
|
118
|
+
if ($sibling.matches(selector)) return $sibling
|
|
119
|
+
$sibling = $sibling.previousElementSibling;
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
function findNearestMatchingElement($element, selector) {
|
|
124
|
+
// If no element or selector is provided, return null
|
|
125
|
+
if (!$element) return
|
|
126
|
+
if (!selector) return
|
|
127
|
+
|
|
128
|
+
// Start with the current element
|
|
129
|
+
let $currentElement = $element;
|
|
130
|
+
|
|
131
|
+
while ($currentElement) {
|
|
132
|
+
// First check the current element
|
|
133
|
+
if ($currentElement.matches(selector)) {
|
|
134
|
+
return $currentElement
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
// Check all previous siblings
|
|
138
|
+
let $sibling = $currentElement.previousElementSibling;
|
|
139
|
+
while ($sibling) {
|
|
140
|
+
// Check if the sibling itself is a heading
|
|
141
|
+
if ($sibling.matches(selector)) {
|
|
142
|
+
return $sibling
|
|
143
|
+
}
|
|
144
|
+
$sibling = $sibling.previousElementSibling;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
// If no match found in siblings, move up to parent
|
|
148
|
+
$currentElement = $currentElement.parentElement;
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
/**
|
|
153
|
+
* Move focus to element
|
|
154
|
+
*
|
|
155
|
+
* Sets tabindex to -1 to make the element programmatically focusable,
|
|
156
|
+
* but removes it on blur as the element doesn't need to be focused again.
|
|
157
|
+
*
|
|
158
|
+
* @param {HTMLElement} $element - HTML element
|
|
159
|
+
* @param {object} [options] - Handler options
|
|
160
|
+
* @param {function(this: HTMLElement): void} [options.onBeforeFocus] - Callback before focus
|
|
161
|
+
* @param {function(this: HTMLElement): void} [options.onBlur] - Callback on blur
|
|
162
|
+
*/
|
|
163
|
+
function setFocus($element, options = {}) {
|
|
164
|
+
const isFocusable = $element.getAttribute('tabindex');
|
|
165
|
+
|
|
166
|
+
if (!isFocusable) {
|
|
167
|
+
$element.setAttribute('tabindex', '-1');
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
/**
|
|
171
|
+
* Handle element focus
|
|
172
|
+
*/
|
|
173
|
+
function onFocus() {
|
|
174
|
+
$element.addEventListener('blur', onBlur, { once: true });
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
/**
|
|
178
|
+
* Handle element blur
|
|
179
|
+
*/
|
|
180
|
+
function onBlur() {
|
|
181
|
+
if (options.onBlur) {
|
|
182
|
+
options.onBlur.call($element);
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
if (!isFocusable) {
|
|
186
|
+
$element.removeAttribute('tabindex');
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
// Add listener to reset element on blur, after focus
|
|
191
|
+
$element.addEventListener('focus', onFocus, { once: true });
|
|
192
|
+
|
|
193
|
+
// Focus element
|
|
194
|
+
if (options.onBeforeFocus) {
|
|
195
|
+
options.onBeforeFocus.call($element);
|
|
196
|
+
}
|
|
197
|
+
$element.focus();
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
helpers = {
|
|
201
|
+
removeAttributeValue,
|
|
202
|
+
addAttributeValue,
|
|
203
|
+
dragAndDropSupported,
|
|
204
|
+
formDataSupported,
|
|
205
|
+
fileApiSupported,
|
|
206
|
+
nodeListForEach,
|
|
207
|
+
getNextSibling,
|
|
208
|
+
getPreviousSibling,
|
|
209
|
+
findNearestMatchingElement,
|
|
210
|
+
setFocus
|
|
211
|
+
};
|
|
212
|
+
return helpers;
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
var multiFileUpload$1;
|
|
216
|
+
var hasRequiredMultiFileUpload;
|
|
217
|
+
|
|
218
|
+
function requireMultiFileUpload () {
|
|
219
|
+
if (hasRequiredMultiFileUpload) return multiFileUpload$1;
|
|
220
|
+
hasRequiredMultiFileUpload = 1;
|
|
221
|
+
const $ = _global_window_jQuery;
|
|
222
|
+
|
|
223
|
+
const {
|
|
224
|
+
dragAndDropSupported,
|
|
225
|
+
fileApiSupported,
|
|
226
|
+
formDataSupported
|
|
227
|
+
} = requireHelpers();
|
|
228
|
+
|
|
229
|
+
function MultiFileUpload(params) {
|
|
230
|
+
if (!(dragAndDropSupported() && formDataSupported() && fileApiSupported())) {
|
|
231
|
+
return
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
this.defaultParams = {
|
|
235
|
+
uploadFileEntryHook: $.noop,
|
|
236
|
+
uploadFileExitHook: $.noop,
|
|
237
|
+
uploadFileErrorHook: $.noop,
|
|
238
|
+
fileDeleteHook: $.noop,
|
|
239
|
+
uploadStatusText: 'Uploading files, please wait',
|
|
240
|
+
dropzoneHintText: 'Drag and drop files here or',
|
|
241
|
+
dropzoneButtonText: 'Choose files'
|
|
242
|
+
};
|
|
243
|
+
|
|
244
|
+
this.params = $.extend({}, this.defaultParams, params);
|
|
245
|
+
this.container = $(this.params.container);
|
|
246
|
+
|
|
247
|
+
this.container.addClass('moj-multi-file-upload--enhanced');
|
|
248
|
+
|
|
249
|
+
this.feedbackContainer = this.container.find(
|
|
250
|
+
'.moj-multi-file__uploaded-files'
|
|
251
|
+
);
|
|
252
|
+
this.setupFileInput();
|
|
253
|
+
this.setupDropzone();
|
|
254
|
+
this.setupLabel();
|
|
255
|
+
this.setupStatusBox();
|
|
256
|
+
this.container.on(
|
|
257
|
+
'click',
|
|
258
|
+
'.moj-multi-file-upload__delete',
|
|
259
|
+
$.proxy(this, 'onFileDeleteClick')
|
|
260
|
+
);
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
MultiFileUpload.prototype.setupDropzone = function () {
|
|
264
|
+
this.fileInput.wrap('<div class="moj-multi-file-upload__dropzone" />');
|
|
265
|
+
this.dropzone = this.container.find('.moj-multi-file-upload__dropzone');
|
|
266
|
+
this.dropzone.on('dragover', $.proxy(this, 'onDragOver'));
|
|
267
|
+
this.dropzone.on('dragleave', $.proxy(this, 'onDragLeave'));
|
|
268
|
+
this.dropzone.on('drop', $.proxy(this, 'onDrop'));
|
|
269
|
+
};
|
|
270
|
+
|
|
271
|
+
MultiFileUpload.prototype.setupLabel = function () {
|
|
272
|
+
this.label = $(
|
|
273
|
+
`<label for="${this.fileInput[0].id}" class="govuk-button govuk-button--secondary">${this.params.dropzoneButtonText}</label>`
|
|
274
|
+
);
|
|
275
|
+
this.dropzone.append(
|
|
276
|
+
`<p class="govuk-body">${this.params.dropzoneHintText}</p>`
|
|
277
|
+
);
|
|
278
|
+
this.dropzone.append(this.label);
|
|
279
|
+
};
|
|
280
|
+
|
|
281
|
+
MultiFileUpload.prototype.setupFileInput = function () {
|
|
282
|
+
this.fileInput = this.container.find('.moj-multi-file-upload__input');
|
|
283
|
+
this.fileInput.on('change', $.proxy(this, 'onFileChange'));
|
|
284
|
+
this.fileInput.on('focus', $.proxy(this, 'onFileFocus'));
|
|
285
|
+
this.fileInput.on('blur', $.proxy(this, 'onFileBlur'));
|
|
286
|
+
};
|
|
287
|
+
|
|
288
|
+
MultiFileUpload.prototype.setupStatusBox = function () {
|
|
289
|
+
this.status = $(
|
|
290
|
+
'<div aria-live="polite" role="status" class="govuk-visually-hidden" />'
|
|
291
|
+
);
|
|
292
|
+
this.dropzone.append(this.status);
|
|
293
|
+
};
|
|
294
|
+
|
|
295
|
+
MultiFileUpload.prototype.onDragOver = function (e) {
|
|
296
|
+
e.preventDefault();
|
|
297
|
+
this.dropzone.addClass('moj-multi-file-upload--dragover');
|
|
298
|
+
};
|
|
299
|
+
|
|
300
|
+
MultiFileUpload.prototype.onDragLeave = function () {
|
|
301
|
+
this.dropzone.removeClass('moj-multi-file-upload--dragover');
|
|
302
|
+
};
|
|
303
|
+
|
|
304
|
+
MultiFileUpload.prototype.onDrop = function (e) {
|
|
305
|
+
e.preventDefault();
|
|
306
|
+
this.dropzone.removeClass('moj-multi-file-upload--dragover');
|
|
307
|
+
this.feedbackContainer.removeClass('moj-hidden');
|
|
308
|
+
this.status.html(this.params.uploadStatusText);
|
|
309
|
+
this.uploadFiles(e.originalEvent.dataTransfer.files);
|
|
310
|
+
};
|
|
311
|
+
|
|
312
|
+
MultiFileUpload.prototype.uploadFiles = function (files) {
|
|
313
|
+
for (let i = 0; i < files.length; i++) {
|
|
314
|
+
this.uploadFile(files[i]);
|
|
315
|
+
}
|
|
316
|
+
};
|
|
317
|
+
|
|
318
|
+
MultiFileUpload.prototype.onFileChange = function (e) {
|
|
319
|
+
this.feedbackContainer.removeClass('moj-hidden');
|
|
320
|
+
this.status.html(this.params.uploadStatusText);
|
|
321
|
+
this.uploadFiles(e.currentTarget.files);
|
|
322
|
+
this.fileInput.replaceWith($(e.currentTarget).val('').clone(true));
|
|
323
|
+
this.setupFileInput();
|
|
324
|
+
this.fileInput.get(0).focus();
|
|
325
|
+
};
|
|
326
|
+
|
|
327
|
+
MultiFileUpload.prototype.onFileFocus = function (e) {
|
|
328
|
+
this.label.addClass('moj-multi-file-upload--focused');
|
|
329
|
+
};
|
|
330
|
+
|
|
331
|
+
MultiFileUpload.prototype.onFileBlur = function (e) {
|
|
332
|
+
this.label.removeClass('moj-multi-file-upload--focused');
|
|
333
|
+
};
|
|
334
|
+
|
|
335
|
+
MultiFileUpload.prototype.getSuccessHtml = function (success) {
|
|
336
|
+
return `<span class="moj-multi-file-upload__success"> <svg class="moj-banner__icon" fill="currentColor" role="presentation" focusable="false" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 25 25" height="25" width="25"><path d="M25,6.2L8.7,23.2L0,14.1l4-4.2l4.7,4.9L21,2L25,6.2z"/></svg>${success.messageHtml}</span>`
|
|
337
|
+
};
|
|
338
|
+
|
|
339
|
+
MultiFileUpload.prototype.getErrorHtml = function (error) {
|
|
340
|
+
return `<span class="moj-multi-file-upload__error"> <svg class="moj-banner__icon" fill="currentColor" role="presentation" focusable="false" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 25 25" height="25" width="25"><path d="M13.6,15.4h-2.3v-4.5h2.3V15.4z M13.6,19.8h-2.3v-2.2h2.3V19.8z M0,23.2h25L12.5,2L0,23.2z"/></svg>${error.message}</span>`
|
|
341
|
+
};
|
|
342
|
+
|
|
343
|
+
MultiFileUpload.prototype.getFileRowHtml = function (file) {
|
|
344
|
+
const html = `
|
|
345
|
+
<div class="govuk-summary-list__row moj-multi-file-upload__row">;
|
|
346
|
+
<div class="govuk-summary-list__value moj-multi-file-upload__message">;
|
|
347
|
+
<span class="moj-multi-file-upload__filename">${file.name}</span>;
|
|
348
|
+
<span class="moj-multi-file-upload__progress">0%</span>;
|
|
349
|
+
</div>';
|
|
350
|
+
<div class="govuk-summary-list__actions moj-multi-file-upload__actions"></div>;
|
|
351
|
+
</div>`;
|
|
352
|
+
return html
|
|
353
|
+
};
|
|
354
|
+
|
|
355
|
+
MultiFileUpload.prototype.getDeleteButtonHtml = function (file) {
|
|
356
|
+
return `<button class="moj-multi-file-upload__delete govuk-button govuk-button--secondary govuk-!-margin-bottom-0" type="button" name="delete" value="${file.filename}">
|
|
357
|
+
Delete <span class="govuk-visually-hidden">${file.originalname}</span>
|
|
358
|
+
</button>`
|
|
359
|
+
};
|
|
360
|
+
|
|
361
|
+
MultiFileUpload.prototype.uploadFile = function (file) {
|
|
362
|
+
this.params.uploadFileEntryHook(this, file);
|
|
363
|
+
const item = $(this.getFileRowHtml(file));
|
|
364
|
+
const formData = new FormData();
|
|
365
|
+
formData.append('documents', file);
|
|
366
|
+
this.feedbackContainer.find('.moj-multi-file-upload__list').append(item);
|
|
367
|
+
|
|
368
|
+
$.ajax({
|
|
369
|
+
url: this.params.uploadUrl,
|
|
370
|
+
type: 'post',
|
|
371
|
+
data: formData,
|
|
372
|
+
processData: false,
|
|
373
|
+
contentType: false,
|
|
374
|
+
success: $.proxy(function (response) {
|
|
375
|
+
if (response.error) {
|
|
376
|
+
item
|
|
377
|
+
.find('.moj-multi-file-upload__message')
|
|
378
|
+
.html(this.getErrorHtml(response.error));
|
|
379
|
+
this.status.html(response.error.message);
|
|
380
|
+
} else {
|
|
381
|
+
item
|
|
382
|
+
.find('.moj-multi-file-upload__message')
|
|
383
|
+
.html(this.getSuccessHtml(response.success));
|
|
384
|
+
this.status.html(response.success.messageText);
|
|
385
|
+
}
|
|
386
|
+
item
|
|
387
|
+
.find('.moj-multi-file-upload__actions')
|
|
388
|
+
.append(this.getDeleteButtonHtml(response.file));
|
|
389
|
+
this.params.uploadFileExitHook(this, file, response);
|
|
390
|
+
}, this),
|
|
391
|
+
error: $.proxy(function (jqXHR, textStatus, errorThrown) {
|
|
392
|
+
this.params.uploadFileErrorHook(
|
|
393
|
+
this,
|
|
394
|
+
file,
|
|
395
|
+
jqXHR,
|
|
396
|
+
textStatus,
|
|
397
|
+
errorThrown
|
|
398
|
+
);
|
|
399
|
+
}, this),
|
|
400
|
+
xhr: function () {
|
|
401
|
+
const xhr = new XMLHttpRequest();
|
|
402
|
+
xhr.upload.addEventListener(
|
|
403
|
+
'progress',
|
|
404
|
+
function (e) {
|
|
405
|
+
if (e.lengthComputable) {
|
|
406
|
+
let percentComplete = e.loaded / e.total;
|
|
407
|
+
percentComplete = parseInt(percentComplete * 100, 10);
|
|
408
|
+
item
|
|
409
|
+
.find('.moj-multi-file-upload__progress')
|
|
410
|
+
.text(` ${percentComplete}%`);
|
|
411
|
+
}
|
|
412
|
+
},
|
|
413
|
+
false
|
|
414
|
+
);
|
|
415
|
+
return xhr
|
|
416
|
+
}
|
|
417
|
+
});
|
|
418
|
+
};
|
|
419
|
+
|
|
420
|
+
MultiFileUpload.prototype.onFileDeleteClick = function (e) {
|
|
421
|
+
e.preventDefault(); // if user refreshes page and then deletes
|
|
422
|
+
const button = $(e.currentTarget);
|
|
423
|
+
const data = {};
|
|
424
|
+
data[button[0].name] = button[0].value;
|
|
425
|
+
$.ajax({
|
|
426
|
+
url: this.params.deleteUrl,
|
|
427
|
+
type: 'post',
|
|
428
|
+
dataType: 'json',
|
|
429
|
+
data,
|
|
430
|
+
success: $.proxy(function (response) {
|
|
431
|
+
if (response.error) ; else {
|
|
432
|
+
button.parents('.moj-multi-file-upload__row').remove();
|
|
433
|
+
if (
|
|
434
|
+
this.feedbackContainer.find('.moj-multi-file-upload__row').length ===
|
|
435
|
+
0
|
|
436
|
+
) {
|
|
437
|
+
this.feedbackContainer.addClass('moj-hidden');
|
|
438
|
+
}
|
|
439
|
+
}
|
|
440
|
+
this.params.fileDeleteHook(this, response);
|
|
441
|
+
}, this)
|
|
442
|
+
});
|
|
443
|
+
};
|
|
444
|
+
|
|
445
|
+
multiFileUpload$1 = { MultiFileUpload };
|
|
446
|
+
return multiFileUpload$1;
|
|
447
|
+
}
|
|
448
|
+
|
|
449
|
+
var multiFileUploadExports = requireMultiFileUpload();
|
|
450
|
+
var multiFileUpload = /*@__PURE__*/getDefaultExportFromCjs(multiFileUploadExports);
|
|
451
|
+
|
|
452
|
+
return multiFileUpload;
|
|
453
|
+
|
|
454
|
+
}));
|
|
@@ -2,13 +2,14 @@
|
|
|
2
2
|
# MULTI-SELECT
|
|
3
3
|
========================================================================== */
|
|
4
4
|
|
|
5
|
-
|
|
6
5
|
.moj-multi-select__checkbox {
|
|
7
6
|
display: inline-block;
|
|
8
7
|
padding-left: 0;
|
|
9
8
|
}
|
|
10
9
|
|
|
11
10
|
.moj-multi-select__toggle-label {
|
|
12
|
-
|
|
11
|
+
// stylelint-disable-next-line declaration-no-important
|
|
13
12
|
margin: 0 !important;
|
|
14
|
-
|
|
13
|
+
// stylelint-disable-next-line declaration-no-important
|
|
14
|
+
padding: 0 !important;
|
|
15
|
+
}
|