@ministryofjustice/frontend 3.5.0 → 3.6.1

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 (37) hide show
  1. package/moj/all.jquery.min.js +1 -81
  2. package/moj/all.js +2577 -2853
  3. package/moj/all.mjs +126 -0
  4. package/moj/all.scss +1 -1
  5. package/moj/components/add-another/add-another.js +111 -132
  6. package/moj/components/add-another/add-another.mjs +106 -0
  7. package/moj/components/alert/alert.js +352 -479
  8. package/moj/components/alert/alert.mjs +251 -0
  9. package/moj/components/alert/alert.spec.helper.js +6 -24
  10. package/moj/components/alert/alert.spec.helper.mjs +66 -0
  11. package/moj/components/button-menu/button-menu.js +326 -343
  12. package/moj/components/button-menu/button-menu.mjs +329 -0
  13. package/moj/components/cookie-banner/_cookie-banner.scss +1 -1
  14. package/moj/components/date-picker/date-picker.js +905 -922
  15. package/moj/components/date-picker/date-picker.mjs +961 -0
  16. package/moj/components/filter-toggle-button/filter-toggle-button.js +98 -119
  17. package/moj/components/filter-toggle-button/filter-toggle-button.mjs +93 -0
  18. package/moj/components/form-validator/form-validator.js +201 -396
  19. package/moj/components/form-validator/form-validator.mjs +168 -0
  20. package/moj/components/multi-file-upload/multi-file-upload.js +227 -441
  21. package/moj/components/multi-file-upload/multi-file-upload.mjs +219 -0
  22. package/moj/components/multi-select/multi-select.js +82 -103
  23. package/moj/components/multi-select/multi-select.mjs +77 -0
  24. package/moj/components/password-reveal/password-reveal.js +40 -61
  25. package/moj/components/password-reveal/password-reveal.mjs +35 -0
  26. package/moj/components/rich-text-editor/rich-text-editor.js +162 -183
  27. package/moj/components/rich-text-editor/rich-text-editor.mjs +157 -0
  28. package/moj/components/search-toggle/search-toggle.js +52 -73
  29. package/moj/components/search-toggle/search-toggle.mjs +54 -0
  30. package/moj/components/sortable-table/sortable-table.js +143 -164
  31. package/moj/components/sortable-table/sortable-table.mjs +138 -0
  32. package/moj/helpers.js +196 -215
  33. package/moj/helpers.mjs +123 -0
  34. package/moj/moj-frontend.min.js +1 -81
  35. package/moj/version.js +6 -23
  36. package/moj/version.mjs +3 -0
  37. package/package.json +24 -6
package/moj/all.mjs ADDED
@@ -0,0 +1,126 @@
1
+ import { AddAnother } from './components/add-another/add-another.mjs';
2
+ import { Alert } from './components/alert/alert.mjs';
3
+ import { ButtonMenu } from './components/button-menu/button-menu.mjs';
4
+ import { DatePicker } from './components/date-picker/date-picker.mjs';
5
+ export { FilterToggleButton } from './components/filter-toggle-button/filter-toggle-button.mjs';
6
+ export { MultiFileUpload } from './components/multi-file-upload/multi-file-upload.mjs';
7
+ import { MultiSelect } from './components/multi-select/multi-select.mjs';
8
+ import { PasswordReveal } from './components/password-reveal/password-reveal.mjs';
9
+ import { RichTextEditor } from './components/rich-text-editor/rich-text-editor.mjs';
10
+ import { SearchToggle } from './components/search-toggle/search-toggle.mjs';
11
+ import { SortableTable } from './components/sortable-table/sortable-table.mjs';
12
+ import { nodeListForEach } from './helpers.mjs';
13
+ export { version } from './version.mjs';
14
+
15
+ /* eslint-disable no-new */
16
+
17
+
18
+ function initAll(options) {
19
+ // Set the options to an empty object by default if no options are passed.
20
+ options = typeof options !== 'undefined' ? options : {};
21
+
22
+ // Allow the user to initialise MOJ Frontend in only certain sections of the page
23
+ // Defaults to the entire document if nothing is set.
24
+ const scope = typeof options.scope !== 'undefined' ? options.scope : document;
25
+
26
+ const $addAnothers = scope.querySelectorAll('[data-module="moj-add-another"]');
27
+
28
+ nodeListForEach($addAnothers, function ($addAnother) {
29
+ new AddAnother($addAnother);
30
+ });
31
+
32
+ const $multiSelects = scope.querySelectorAll(
33
+ '[data-module="moj-multi-select"]'
34
+ );
35
+
36
+ nodeListForEach($multiSelects, function ($multiSelect) {
37
+ new MultiSelect({
38
+ container: $multiSelect.querySelector(
39
+ $multiSelect.getAttribute('data-multi-select-checkbox')
40
+ ),
41
+ checkboxes: $multiSelect.querySelectorAll(
42
+ 'tbody .govuk-checkboxes__input'
43
+ ),
44
+ id_prefix: $multiSelect.getAttribute('data-multi-select-idprefix')
45
+ });
46
+ });
47
+
48
+ const $passwordReveals = scope.querySelectorAll(
49
+ '[data-module="moj-password-reveal"]'
50
+ );
51
+
52
+ nodeListForEach($passwordReveals, function ($passwordReveal) {
53
+ new PasswordReveal($passwordReveal);
54
+ });
55
+
56
+ const $richTextEditors = scope.querySelectorAll(
57
+ '[data-module="moj-rich-text-editor"]'
58
+ );
59
+
60
+ nodeListForEach($richTextEditors, function ($richTextEditor) {
61
+ const options = {
62
+ textarea: window.jQuery($richTextEditor)
63
+ };
64
+
65
+ const toolbarAttr = $richTextEditor.getAttribute(
66
+ 'data-moj-rich-text-editor-toolbar'
67
+ );
68
+
69
+ if (toolbarAttr) {
70
+ const toolbar = toolbarAttr.split(',');
71
+
72
+ options.toolbar = {};
73
+
74
+ for (const item in toolbar) {
75
+ options.toolbar[toolbar[item]] = true;
76
+ }
77
+ }
78
+
79
+ new RichTextEditor(options);
80
+ });
81
+
82
+ const $searchToggles = scope.querySelectorAll(
83
+ '[data-module="moj-search-toggle"]'
84
+ );
85
+
86
+ nodeListForEach($searchToggles, function ($searchToggle) {
87
+ new SearchToggle({
88
+ toggleButton: {
89
+ container: window.jQuery($searchToggle.querySelector('.moj-search-toggle__toggle')),
90
+ text: $searchToggle.getAttribute('data-moj-search-toggle-text')
91
+ },
92
+ search: {
93
+ container: window.jQuery($searchToggle.querySelector('.moj-search'))
94
+ }
95
+ });
96
+ });
97
+
98
+ const $sortableTables = scope.querySelectorAll(
99
+ '[data-module="moj-sortable-table"]'
100
+ );
101
+
102
+ nodeListForEach($sortableTables, function ($table) {
103
+ new SortableTable({
104
+ table: $table
105
+ });
106
+ });
107
+
108
+ const $datepickers = scope.querySelectorAll('[data-module="moj-date-picker"]');
109
+
110
+ nodeListForEach($datepickers, function ($datepicker) {
111
+ new DatePicker($datepicker, {}).init();
112
+ });
113
+
114
+ const $buttonMenus = scope.querySelectorAll('[data-module="moj-button-menu"]');
115
+
116
+ nodeListForEach($buttonMenus, function ($buttonmenu) {
117
+ new ButtonMenu($buttonmenu, {}).init();
118
+ });
119
+
120
+ const $alerts = scope.querySelectorAll('[data-module="moj-alert"]');
121
+ nodeListForEach($alerts, function ($alert) {
122
+ new Alert($alert, {}).init();
123
+ });
124
+ }
125
+
126
+ export { AddAnother, Alert, ButtonMenu, DatePicker, MultiSelect, PasswordReveal, RichTextEditor, SearchToggle, SortableTable, initAll };
package/moj/all.scss CHANGED
@@ -1,6 +1,6 @@
1
1
  $govuk-suppressed-warnings: ("govuk-typography-scale-14");
2
2
 
3
- @import "node_modules/govuk-frontend/dist/govuk/base";
3
+ @import "govuk-frontend/dist/govuk/base";
4
4
 
5
5
  @import "settings/all";
6
6
  @import "helpers/all";
@@ -1,135 +1,114 @@
1
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 addAnother$1;
14
- var hasRequiredAddAnother;
15
-
16
- function requireAddAnother () {
17
- if (hasRequiredAddAnother) return addAnother$1;
18
- hasRequiredAddAnother = 1;
19
- const $ = _global_window_jQuery;
20
-
21
- function AddAnother(container) {
22
- this.container = $(container);
23
-
24
- if (this.container.data('moj-add-another-initialised')) {
25
- return
26
- }
27
-
28
- this.container.data('moj-add-another-initialised', true);
29
-
30
- this.container.on(
31
- 'click',
32
- '.moj-add-another__remove-button',
33
- $.proxy(this, 'onRemoveButtonClick')
34
- );
35
- this.container.on(
36
- 'click',
37
- '.moj-add-another__add-button',
38
- $.proxy(this, 'onAddButtonClick')
39
- );
40
- this.container
41
- .find('.moj-add-another__add-button, moj-add-another__remove-button')
42
- .prop('type', 'button');
43
- }
44
-
45
- AddAnother.prototype.onAddButtonClick = function (e) {
46
- const item = this.getNewItem();
47
- this.updateAttributes(this.getItems().length, item);
48
- this.resetItem(item);
49
- const firstItem = this.getItems().first();
50
- if (!this.hasRemoveButton(firstItem)) {
51
- this.createRemoveButton(firstItem);
52
- }
53
- this.getItems().last().after(item);
54
- item.find('input, textarea, select').first().focus();
55
- };
56
-
57
- AddAnother.prototype.hasRemoveButton = function (item) {
58
- return item.find('.moj-add-another__remove-button').length
59
- };
60
-
61
- AddAnother.prototype.getItems = function () {
62
- return this.container.find('.moj-add-another__item')
63
- };
64
-
65
- AddAnother.prototype.getNewItem = function () {
66
- const item = this.getItems().first().clone();
67
- if (!this.hasRemoveButton(item)) {
68
- this.createRemoveButton(item);
69
- }
70
- return item
71
- };
72
-
73
- AddAnother.prototype.updateAttributes = function (index, item) {
74
- item.find('[data-name]').each(function (i, el) {
75
- const originalId = el.id;
76
-
77
- el.name = $(el)
78
- .attr('data-name')
79
- .replace(/%index%/, index);
80
- el.id = $(el)
81
- .attr('data-id')
82
- .replace(/%index%/, index);
83
-
84
- const label =
85
- $(el).siblings('label')[0] ||
86
- $(el).parents('label')[0] ||
87
- item.find(`[for="${originalId}"]`)[0];
88
- label.htmlFor = el.id;
89
- });
90
- };
91
-
92
- AddAnother.prototype.createRemoveButton = function (item) {
93
- item.append(
94
- '<button type="button" class="govuk-button govuk-button--secondary moj-add-another__remove-button">Remove</button>'
95
- );
96
- };
97
-
98
- AddAnother.prototype.resetItem = function (item) {
99
- item.find('[data-name], [data-id]').each(function (index, el) {
100
- if (el.type === 'checkbox' || el.type === 'radio') {
101
- el.checked = false;
102
- } else {
103
- el.value = '';
104
- }
105
- });
106
- };
107
-
108
- AddAnother.prototype.onRemoveButtonClick = function (e) {
109
- $(e.currentTarget).parents('.moj-add-another__item').remove();
110
- const items = this.getItems();
111
- if (items.length === 1) {
112
- items.find('.moj-add-another__remove-button').remove();
113
- }
114
- items.each(
115
- $.proxy(function (index, el) {
116
- this.updateAttributes(index, $(el));
117
- }, this)
118
- );
119
- this.focusHeading();
120
- };
121
-
122
- AddAnother.prototype.focusHeading = function () {
123
- this.container.find('.moj-add-another__heading').get(0).focus();
124
- };
125
-
126
- addAnother$1 = { AddAnother };
127
- return addAnother$1;
128
- }
129
-
130
- var addAnotherExports = requireAddAnother();
131
- var addAnother = /*@__PURE__*/getDefaultExportFromCjs(addAnotherExports);
132
-
133
- return addAnother;
2
+ typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
3
+ typeof define === 'function' && define.amd ? define(['exports'], factory) :
4
+ (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.MOJFrontend = global.MOJFrontend || {}));
5
+ })(this, (function (exports) { 'use strict';
6
+
7
+ function AddAnother(container) {
8
+ this.container = window.jQuery(container);
9
+
10
+ if (this.container.data('moj-add-another-initialised')) {
11
+ return
12
+ }
13
+
14
+ this.container.data('moj-add-another-initialised', true);
15
+
16
+ this.container.on(
17
+ 'click',
18
+ '.moj-add-another__remove-button',
19
+ window.jQuery.proxy(this, 'onRemoveButtonClick')
20
+ );
21
+ this.container.on(
22
+ 'click',
23
+ '.moj-add-another__add-button',
24
+ window.jQuery.proxy(this, 'onAddButtonClick')
25
+ );
26
+ this.container
27
+ .find('.moj-add-another__add-button, moj-add-another__remove-button')
28
+ .prop('type', 'button');
29
+ }
30
+
31
+ AddAnother.prototype.onAddButtonClick = function (e) {
32
+ const item = this.getNewItem();
33
+ this.updateAttributes(this.getItems().length, item);
34
+ this.resetItem(item);
35
+ const firstItem = this.getItems().first();
36
+ if (!this.hasRemoveButton(firstItem)) {
37
+ this.createRemoveButton(firstItem);
38
+ }
39
+ this.getItems().last().after(item);
40
+ item.find('input, textarea, select').first().focus();
41
+ };
42
+
43
+ AddAnother.prototype.hasRemoveButton = function (item) {
44
+ return item.find('.moj-add-another__remove-button').length
45
+ };
46
+
47
+ AddAnother.prototype.getItems = function () {
48
+ return this.container.find('.moj-add-another__item')
49
+ };
50
+
51
+ AddAnother.prototype.getNewItem = function () {
52
+ const item = this.getItems().first().clone();
53
+ if (!this.hasRemoveButton(item)) {
54
+ this.createRemoveButton(item);
55
+ }
56
+ return item
57
+ };
58
+
59
+ AddAnother.prototype.updateAttributes = function (index, item) {
60
+ item.find('[data-name]').each(function (i, el) {
61
+ const originalId = el.id;
62
+
63
+ el.name = window.jQuery(el)
64
+ .attr('data-name')
65
+ .replace(/%index%/, index);
66
+ el.id = window.jQuery(el)
67
+ .attr('data-id')
68
+ .replace(/%index%/, index);
69
+
70
+ const label =
71
+ window.jQuery(el).siblings('label')[0] ||
72
+ window.jQuery(el).parents('label')[0] ||
73
+ item.find(`[for="${originalId}"]`)[0];
74
+ label.htmlFor = el.id;
75
+ });
76
+ };
77
+
78
+ AddAnother.prototype.createRemoveButton = function (item) {
79
+ item.append(
80
+ '<button type="button" class="govuk-button govuk-button--secondary moj-add-another__remove-button">Remove</button>'
81
+ );
82
+ };
83
+
84
+ AddAnother.prototype.resetItem = function (item) {
85
+ item.find('[data-name], [data-id]').each(function (index, el) {
86
+ if (el.type === 'checkbox' || el.type === 'radio') {
87
+ el.checked = false;
88
+ } else {
89
+ el.value = '';
90
+ }
91
+ });
92
+ };
93
+
94
+ AddAnother.prototype.onRemoveButtonClick = function (e) {
95
+ window.jQuery(e.currentTarget).parents('.moj-add-another__item').remove();
96
+ const items = this.getItems();
97
+ if (items.length === 1) {
98
+ items.find('.moj-add-another__remove-button').remove();
99
+ }
100
+ items.each(
101
+ window.jQuery.proxy(function (index, el) {
102
+ this.updateAttributes(index, window.jQuery(el));
103
+ }, this)
104
+ );
105
+ this.focusHeading();
106
+ };
107
+
108
+ AddAnother.prototype.focusHeading = function () {
109
+ this.container.find('.moj-add-another__heading').get(0).focus();
110
+ };
111
+
112
+ exports.AddAnother = AddAnother;
134
113
 
135
114
  }));
@@ -0,0 +1,106 @@
1
+ function AddAnother(container) {
2
+ this.container = window.jQuery(container);
3
+
4
+ if (this.container.data('moj-add-another-initialised')) {
5
+ return
6
+ }
7
+
8
+ this.container.data('moj-add-another-initialised', true);
9
+
10
+ this.container.on(
11
+ 'click',
12
+ '.moj-add-another__remove-button',
13
+ window.jQuery.proxy(this, 'onRemoveButtonClick')
14
+ );
15
+ this.container.on(
16
+ 'click',
17
+ '.moj-add-another__add-button',
18
+ window.jQuery.proxy(this, 'onAddButtonClick')
19
+ );
20
+ this.container
21
+ .find('.moj-add-another__add-button, moj-add-another__remove-button')
22
+ .prop('type', 'button');
23
+ }
24
+
25
+ AddAnother.prototype.onAddButtonClick = function (e) {
26
+ const item = this.getNewItem();
27
+ this.updateAttributes(this.getItems().length, item);
28
+ this.resetItem(item);
29
+ const firstItem = this.getItems().first();
30
+ if (!this.hasRemoveButton(firstItem)) {
31
+ this.createRemoveButton(firstItem);
32
+ }
33
+ this.getItems().last().after(item);
34
+ item.find('input, textarea, select').first().focus();
35
+ };
36
+
37
+ AddAnother.prototype.hasRemoveButton = function (item) {
38
+ return item.find('.moj-add-another__remove-button').length
39
+ };
40
+
41
+ AddAnother.prototype.getItems = function () {
42
+ return this.container.find('.moj-add-another__item')
43
+ };
44
+
45
+ AddAnother.prototype.getNewItem = function () {
46
+ const item = this.getItems().first().clone();
47
+ if (!this.hasRemoveButton(item)) {
48
+ this.createRemoveButton(item);
49
+ }
50
+ return item
51
+ };
52
+
53
+ AddAnother.prototype.updateAttributes = function (index, item) {
54
+ item.find('[data-name]').each(function (i, el) {
55
+ const originalId = el.id;
56
+
57
+ el.name = window.jQuery(el)
58
+ .attr('data-name')
59
+ .replace(/%index%/, index);
60
+ el.id = window.jQuery(el)
61
+ .attr('data-id')
62
+ .replace(/%index%/, index);
63
+
64
+ const label =
65
+ window.jQuery(el).siblings('label')[0] ||
66
+ window.jQuery(el).parents('label')[0] ||
67
+ item.find(`[for="${originalId}"]`)[0];
68
+ label.htmlFor = el.id;
69
+ });
70
+ };
71
+
72
+ AddAnother.prototype.createRemoveButton = function (item) {
73
+ item.append(
74
+ '<button type="button" class="govuk-button govuk-button--secondary moj-add-another__remove-button">Remove</button>'
75
+ );
76
+ };
77
+
78
+ AddAnother.prototype.resetItem = function (item) {
79
+ item.find('[data-name], [data-id]').each(function (index, el) {
80
+ if (el.type === 'checkbox' || el.type === 'radio') {
81
+ el.checked = false;
82
+ } else {
83
+ el.value = '';
84
+ }
85
+ });
86
+ };
87
+
88
+ AddAnother.prototype.onRemoveButtonClick = function (e) {
89
+ window.jQuery(e.currentTarget).parents('.moj-add-another__item').remove();
90
+ const items = this.getItems();
91
+ if (items.length === 1) {
92
+ items.find('.moj-add-another__remove-button').remove();
93
+ }
94
+ items.each(
95
+ window.jQuery.proxy(function (index, el) {
96
+ this.updateAttributes(index, window.jQuery(el));
97
+ }, this)
98
+ );
99
+ this.focusHeading();
100
+ };
101
+
102
+ AddAnother.prototype.focusHeading = function () {
103
+ this.container.find('.moj-add-another__heading').get(0).focus();
104
+ };
105
+
106
+ export { AddAnother };