@ministryofjustice/frontend 5.2.1 → 7.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.
- package/moj/all.bundle.js +30 -12
- package/moj/all.bundle.js.map +1 -1
- package/moj/all.bundle.mjs +85 -38
- package/moj/all.bundle.mjs.map +1 -1
- package/moj/all.mjs +13 -5
- package/moj/all.mjs.map +1 -1
- package/moj/common/index.mjs.map +1 -1
- package/moj/common/moj-frontend-version.mjs +2 -2
- package/moj/common/moj-frontend-version.mjs.map +1 -1
- package/moj/components/add-another/add-another.bundle.js.map +1 -1
- package/moj/components/add-another/add-another.bundle.mjs +10 -2
- package/moj/components/add-another/add-another.bundle.mjs.map +1 -1
- package/moj/components/add-another/add-another.mjs.map +1 -1
- package/moj/components/alert/alert.bundle.js +1 -1
- package/moj/components/alert/alert.bundle.js.map +1 -1
- package/moj/components/alert/alert.bundle.mjs +5 -3
- package/moj/components/alert/alert.bundle.mjs.map +1 -1
- package/moj/components/alert/alert.mjs.map +1 -1
- package/moj/components/button-menu/button-menu.bundle.js.map +1 -1
- package/moj/components/button-menu/button-menu.bundle.mjs +4 -2
- package/moj/components/button-menu/button-menu.bundle.mjs.map +1 -1
- package/moj/components/button-menu/button-menu.mjs.map +1 -1
- package/moj/components/date-picker/date-picker.bundle.js +11 -1
- package/moj/components/date-picker/date-picker.bundle.js.map +1 -1
- package/moj/components/date-picker/date-picker.bundle.mjs +15 -3
- package/moj/components/date-picker/date-picker.bundle.mjs.map +1 -1
- package/moj/components/date-picker/date-picker.mjs +11 -1
- package/moj/components/date-picker/date-picker.mjs.map +1 -1
- package/moj/components/domain-specific/probation/header/header.bundle.js.map +1 -1
- package/moj/components/domain-specific/probation/header/header.bundle.mjs +10 -2
- package/moj/components/domain-specific/probation/header/header.bundle.mjs.map +1 -1
- package/moj/components/domain-specific/probation/header/header.mjs.map +1 -1
- package/moj/components/filter-toggle-button/filter-toggle-button.bundle.js.map +1 -1
- package/moj/components/filter-toggle-button/filter-toggle-button.bundle.mjs +4 -2
- package/moj/components/filter-toggle-button/filter-toggle-button.bundle.mjs.map +1 -1
- package/moj/components/filter-toggle-button/filter-toggle-button.mjs.map +1 -1
- package/moj/components/form-validator/form-validator.bundle.js.map +1 -1
- package/moj/components/form-validator/form-validator.bundle.mjs +4 -2
- package/moj/components/form-validator/form-validator.bundle.mjs.map +1 -1
- package/moj/components/form-validator/form-validator.mjs.map +1 -1
- package/moj/components/messages/README.md +1 -1
- package/moj/components/multi-file-upload/multi-file-upload.bundle.js +3 -3
- package/moj/components/multi-file-upload/multi-file-upload.bundle.js.map +1 -1
- package/moj/components/multi-file-upload/multi-file-upload.bundle.mjs +7 -5
- package/moj/components/multi-file-upload/multi-file-upload.bundle.mjs.map +1 -1
- package/moj/components/multi-file-upload/multi-file-upload.mjs +3 -3
- package/moj/components/multi-file-upload/multi-file-upload.mjs.map +1 -1
- package/moj/components/multi-select/multi-select.bundle.js.map +1 -1
- package/moj/components/multi-select/multi-select.bundle.mjs +4 -2
- package/moj/components/multi-select/multi-select.bundle.mjs.map +1 -1
- package/moj/components/multi-select/multi-select.mjs.map +1 -1
- package/moj/components/notification-badge/_notification-badge.scss +10 -6
- package/moj/components/notification-badge/_notification-badge.scss.map +1 -1
- package/moj/components/notification-badge/template.njk +11 -5
- package/moj/components/pagination/template.njk +2 -2
- package/moj/components/password-reveal/password-reveal.bundle.js.map +1 -1
- package/moj/components/password-reveal/password-reveal.bundle.mjs +10 -2
- package/moj/components/password-reveal/password-reveal.bundle.mjs.map +1 -1
- package/moj/components/password-reveal/password-reveal.mjs.map +1 -1
- package/moj/components/rich-text-editor/rich-text-editor.bundle.js.map +1 -1
- package/moj/components/rich-text-editor/rich-text-editor.bundle.mjs +4 -2
- package/moj/components/rich-text-editor/rich-text-editor.bundle.mjs.map +1 -1
- package/moj/components/rich-text-editor/rich-text-editor.mjs.map +1 -1
- package/moj/components/search-toggle/search-toggle.bundle.js.map +1 -1
- package/moj/components/search-toggle/search-toggle.bundle.mjs +4 -2
- package/moj/components/search-toggle/search-toggle.bundle.mjs.map +1 -1
- package/moj/components/search-toggle/search-toggle.mjs.map +1 -1
- package/moj/components/sortable-table/sortable-table.bundle.js.map +1 -1
- package/moj/components/sortable-table/sortable-table.bundle.mjs +4 -2
- package/moj/components/sortable-table/sortable-table.bundle.mjs.map +1 -1
- package/moj/components/sortable-table/sortable-table.mjs.map +1 -1
- package/moj/components/timeline/README.md +1 -1
- package/moj/core/_moj-frontend-properties.scss +1 -1
- package/moj/helpers.bundle.js.map +1 -1
- package/moj/helpers.bundle.mjs.map +1 -1
- package/moj/helpers.mjs +1 -1
- package/moj/helpers.mjs.map +1 -1
- package/moj/moj-frontend.min.css +1 -1
- package/moj/moj-frontend.min.css.map +1 -1
- package/moj/moj-frontend.min.js +1 -1
- package/moj/moj-frontend.min.js.map +1 -1
- package/moj/objects/_scrollable-pane.scss +2 -2
- package/moj/objects/_scrollable-pane.scss.map +1 -1
- package/package.json +2 -2
package/moj/all.bundle.mjs
CHANGED
|
@@ -23,6 +23,9 @@ function isArray(option) {
|
|
|
23
23
|
function isObject(option) {
|
|
24
24
|
return !!option && typeof option === 'object' && !isArray(option);
|
|
25
25
|
}
|
|
26
|
+
function isScope($scope) {
|
|
27
|
+
return !!$scope && ($scope instanceof Element || $scope instanceof Document);
|
|
28
|
+
}
|
|
26
29
|
function formatErrorMessage(Component, message) {
|
|
27
30
|
return `${Component.moduleName}: ${message}`;
|
|
28
31
|
}
|
|
@@ -54,7 +57,7 @@ class ConfigError extends GOVUKFrontendError {
|
|
|
54
57
|
class ElementError extends GOVUKFrontendError {
|
|
55
58
|
constructor(messageOrOptions) {
|
|
56
59
|
let message = typeof messageOrOptions === 'string' ? messageOrOptions : '';
|
|
57
|
-
if (
|
|
60
|
+
if (isObject(messageOrOptions)) {
|
|
58
61
|
const {
|
|
59
62
|
component,
|
|
60
63
|
identifier,
|
|
@@ -63,7 +66,9 @@ class ElementError extends GOVUKFrontendError {
|
|
|
63
66
|
} = messageOrOptions;
|
|
64
67
|
message = identifier;
|
|
65
68
|
message += element ? ` is not of type ${expectedType != null ? expectedType : 'HTMLElement'}` : ' not found';
|
|
66
|
-
|
|
69
|
+
if (component) {
|
|
70
|
+
message = formatErrorMessage(component, message);
|
|
71
|
+
}
|
|
67
72
|
}
|
|
68
73
|
super(message);
|
|
69
74
|
this.name = 'ElementError';
|
|
@@ -200,6 +205,30 @@ function normaliseDataset(Component, dataset) {
|
|
|
200
205
|
}
|
|
201
206
|
return out;
|
|
202
207
|
}
|
|
208
|
+
function normaliseOptions(scopeOrOptions) {
|
|
209
|
+
let $scope = document;
|
|
210
|
+
let onError;
|
|
211
|
+
if (isObject(scopeOrOptions)) {
|
|
212
|
+
const options = scopeOrOptions;
|
|
213
|
+
if (isScope(options.scope) || options.scope === null) {
|
|
214
|
+
$scope = options.scope;
|
|
215
|
+
}
|
|
216
|
+
if (typeof options.onError === 'function') {
|
|
217
|
+
onError = options.onError;
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
if (isScope(scopeOrOptions)) {
|
|
221
|
+
$scope = scopeOrOptions;
|
|
222
|
+
} else if (scopeOrOptions === null) {
|
|
223
|
+
$scope = null;
|
|
224
|
+
} else if (typeof scopeOrOptions === 'function') {
|
|
225
|
+
onError = scopeOrOptions;
|
|
226
|
+
}
|
|
227
|
+
return {
|
|
228
|
+
scope: $scope,
|
|
229
|
+
onError
|
|
230
|
+
};
|
|
231
|
+
}
|
|
203
232
|
function mergeConfigs(...configObjects) {
|
|
204
233
|
const formattedConfigObject = {};
|
|
205
234
|
for (const configObject of configObjects) {
|
|
@@ -254,42 +283,42 @@ function extractConfigByNamespace(schema, dataset, namespace) {
|
|
|
254
283
|
* @template {CompatibleClass} ComponentClass
|
|
255
284
|
* @param {ComponentClass} Component - class of the component to create
|
|
256
285
|
* @param {ComponentConfig<ComponentClass>} [config] - Config supplied to component
|
|
257
|
-
* @param {OnErrorCallback<ComponentClass> | Element | Document | CreateAllOptions<ComponentClass>
|
|
286
|
+
* @param {OnErrorCallback<ComponentClass> | Element | Document | null | CreateAllOptions<ComponentClass>} [scopeOrOptions] - options for createAll including scope of the document to search within and callback function if error throw by component on init
|
|
258
287
|
* @returns {Array<InstanceType<ComponentClass>>} - array of instantiated components
|
|
259
288
|
*/
|
|
260
|
-
function createAll(Component, config,
|
|
261
|
-
let $
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
var
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
if (onError) {
|
|
278
|
-
onError(
|
|
289
|
+
function createAll(Component, config, scopeOrOptions) {
|
|
290
|
+
let $elements;
|
|
291
|
+
const options = normaliseOptions(scopeOrOptions);
|
|
292
|
+
try {
|
|
293
|
+
var _options$scope;
|
|
294
|
+
if (!isSupported()) {
|
|
295
|
+
throw new SupportError();
|
|
296
|
+
}
|
|
297
|
+
if (options.scope === null) {
|
|
298
|
+
throw new ElementError({
|
|
299
|
+
element: options.scope,
|
|
300
|
+
component: Component,
|
|
301
|
+
identifier: 'Scope element (`$scope`)'
|
|
302
|
+
});
|
|
303
|
+
}
|
|
304
|
+
$elements = (_options$scope = options.scope) == null ? void 0 : _options$scope.querySelectorAll(`[data-module="${Component.moduleName}"]`);
|
|
305
|
+
} catch (error) {
|
|
306
|
+
if (options.onError) {
|
|
307
|
+
options.onError(error, {
|
|
279
308
|
component: Component,
|
|
280
309
|
config
|
|
281
310
|
});
|
|
282
311
|
} else {
|
|
283
|
-
console.log(
|
|
312
|
+
console.log(error);
|
|
284
313
|
}
|
|
285
314
|
return [];
|
|
286
315
|
}
|
|
287
|
-
return Array.from($elements).map($element => {
|
|
316
|
+
return Array.from($elements != null ? $elements : []).map($element => {
|
|
288
317
|
try {
|
|
289
318
|
return typeof config !== 'undefined' ? new Component($element, config) : new Component($element);
|
|
290
319
|
} catch (error) {
|
|
291
|
-
if (onError) {
|
|
292
|
-
onError(error, {
|
|
320
|
+
if (options.onError) {
|
|
321
|
+
options.onError(error, {
|
|
293
322
|
element: $element,
|
|
294
323
|
component: Component,
|
|
295
324
|
config
|
|
@@ -308,11 +337,11 @@ function createAll(Component, config, createAllOptions) {
|
|
|
308
337
|
*/
|
|
309
338
|
|
|
310
339
|
/**
|
|
311
|
-
*
|
|
340
|
+
* MOJ Frontend release version
|
|
312
341
|
*
|
|
313
342
|
* {@link https://github.com/ministryofjustice/moj-frontend/releases}
|
|
314
343
|
*/
|
|
315
|
-
const version = '
|
|
344
|
+
const version = '7.0.0';
|
|
316
345
|
|
|
317
346
|
class AddAnother extends Component {
|
|
318
347
|
/**
|
|
@@ -601,7 +630,7 @@ function getPreviousSibling($element, selector) {
|
|
|
601
630
|
*/
|
|
602
631
|
function findNearestMatchingElement($element, selector) {
|
|
603
632
|
// If no element or selector is provided, return
|
|
604
|
-
if (!$element || !($element instanceof HTMLElement) ||
|
|
633
|
+
if (!$element || !($element instanceof HTMLElement) || !selector) {
|
|
605
634
|
return;
|
|
606
635
|
}
|
|
607
636
|
|
|
@@ -1346,7 +1375,7 @@ class DatePicker extends ConfigurableComponent {
|
|
|
1346
1375
|
const day = match[1];
|
|
1347
1376
|
const month = match[3];
|
|
1348
1377
|
const year = match[4];
|
|
1349
|
-
formattedDate = new Date(
|
|
1378
|
+
formattedDate = new Date(Number(year), Number(month) - 1, Number(day));
|
|
1350
1379
|
if (formattedDate instanceof Date && Number.isFinite(formattedDate.getTime())) {
|
|
1351
1380
|
return formattedDate;
|
|
1352
1381
|
}
|
|
@@ -1522,6 +1551,16 @@ class DatePicker extends ConfigurableComponent {
|
|
|
1522
1551
|
|
|
1523
1552
|
// get the date from the input element
|
|
1524
1553
|
this.inputDate = this.formattedDateFromString(this.$input.value);
|
|
1554
|
+
// move current date to the closest selectable date if it is out of range
|
|
1555
|
+
if (this.minDate && this.minDate > this.inputDate) {
|
|
1556
|
+
this.inputDate = new Date(this.minDate.getTime());
|
|
1557
|
+
}
|
|
1558
|
+
if (this.maxDate && this.maxDate < this.inputDate) {
|
|
1559
|
+
this.inputDate = new Date(this.maxDate.getTime());
|
|
1560
|
+
}
|
|
1561
|
+
if (this.minDate && this.maxDate && this.minDate > this.maxDate) {
|
|
1562
|
+
console.error('min date is after max date. No dates will be selectable');
|
|
1563
|
+
}
|
|
1525
1564
|
this.currentDate = this.inputDate;
|
|
1526
1565
|
this.currentDate.setHours(0, 0, 0, 0);
|
|
1527
1566
|
this.updateCalendar();
|
|
@@ -2469,13 +2508,13 @@ class MultiFileUpload extends ConfigurableComponent {
|
|
|
2469
2508
|
$message.innerHTML = this.getSuccessHtml(xhr.response.success);
|
|
2470
2509
|
this.$status.textContent = xhr.response.success.messageText;
|
|
2471
2510
|
$actions.append(this.getDeleteButton(xhr.response.file));
|
|
2472
|
-
this.config.hooks.exitHook(this, file, xhr, xhr.
|
|
2511
|
+
this.config.hooks.exitHook(this, file, xhr, xhr.statusText);
|
|
2473
2512
|
};
|
|
2474
2513
|
const onError = () => {
|
|
2475
2514
|
const error = new Error(xhr.response && 'error' in xhr.response ? xhr.response.error.message : xhr.statusText || 'Upload failed');
|
|
2476
2515
|
$message.innerHTML = this.getErrorHtml(error);
|
|
2477
2516
|
this.$status.textContent = error.message;
|
|
2478
|
-
this.config.hooks.errorHook(this, file, xhr, xhr.
|
|
2517
|
+
this.config.hooks.errorHook(this, file, xhr, xhr.statusText, error);
|
|
2479
2518
|
};
|
|
2480
2519
|
xhr.addEventListener('load', onLoad);
|
|
2481
2520
|
xhr.addEventListener('error', onError);
|
|
@@ -2512,7 +2551,7 @@ class MultiFileUpload extends ConfigurableComponent {
|
|
|
2512
2551
|
}
|
|
2513
2552
|
const $rowDelete = $rows.find($row => $row.contains($button));
|
|
2514
2553
|
if ($rowDelete) $rowDelete.remove();
|
|
2515
|
-
this.config.hooks.deleteHook(this, undefined, xhr, xhr.
|
|
2554
|
+
this.config.hooks.deleteHook(this, undefined, xhr, xhr.statusText);
|
|
2516
2555
|
});
|
|
2517
2556
|
xhr.open('POST', this.config.deleteUrl);
|
|
2518
2557
|
xhr.setRequestHeader('Content-Type', 'application/json');
|
|
@@ -3407,16 +3446,24 @@ SortableTable.schema = Object.freeze(/** @type {const} */{
|
|
|
3407
3446
|
});
|
|
3408
3447
|
|
|
3409
3448
|
/**
|
|
3410
|
-
*
|
|
3449
|
+
* Initialise all components
|
|
3450
|
+
*
|
|
3451
|
+
* Use the `data-module` attributes to find, instantiate and init all of the
|
|
3452
|
+
* components provided as part of MOJ Frontend.
|
|
3453
|
+
*
|
|
3454
|
+
* @param {Config | Element | Document | null} [scopeOrConfig]
|
|
3411
3455
|
*/
|
|
3412
|
-
function initAll(
|
|
3413
|
-
for (const Component of [AddAnother, Alert, ButtonMenu, DatePicker, MultiSelect, PasswordReveal, RichTextEditor, SearchToggle, SortableTable
|
|
3414
|
-
createAll(Component, undefined,
|
|
3456
|
+
function initAll(scopeOrConfig) {
|
|
3457
|
+
for (const Component of [AddAnother, Alert, ButtonMenu, DatePicker, MultiSelect, PasswordReveal, PdsHeader, RichTextEditor, SearchToggle, SortableTable]) {
|
|
3458
|
+
createAll(Component, undefined, scopeOrConfig);
|
|
3415
3459
|
}
|
|
3416
3460
|
}
|
|
3417
3461
|
|
|
3418
3462
|
/**
|
|
3419
|
-
*
|
|
3463
|
+
* Config for all components via `initAll()`
|
|
3464
|
+
*
|
|
3465
|
+
* @typedef {object} Config
|
|
3466
|
+
* @property {Element | Document | null } scope - the scope to search for components in
|
|
3420
3467
|
*/
|
|
3421
3468
|
|
|
3422
3469
|
/**
|