@ministryofjustice/frontend 5.0.0 → 5.1.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 (112) hide show
  1. package/moj/all.bundle.js +1549 -1062
  2. package/moj/all.bundle.js.map +1 -1
  3. package/moj/all.bundle.mjs +1845 -1054
  4. package/moj/all.bundle.mjs.map +1 -1
  5. package/moj/all.mjs +7 -90
  6. package/moj/all.mjs.map +1 -1
  7. package/moj/all.scss +1 -0
  8. package/moj/all.scss.map +1 -1
  9. package/moj/common/index.mjs +57 -0
  10. package/moj/common/index.mjs.map +1 -0
  11. package/moj/common/moj-frontend-version.mjs +14 -0
  12. package/moj/common/moj-frontend-version.mjs.map +1 -0
  13. package/moj/components/add-another/add-another.bundle.js +105 -76
  14. package/moj/components/add-another/add-another.bundle.js.map +1 -1
  15. package/moj/components/add-another/add-another.bundle.mjs +222 -71
  16. package/moj/components/add-another/add-another.bundle.mjs.map +1 -1
  17. package/moj/components/add-another/add-another.mjs +103 -72
  18. package/moj/components/add-another/add-another.mjs.map +1 -1
  19. package/moj/components/alert/alert.bundle.js +115 -191
  20. package/moj/components/alert/alert.bundle.js.map +1 -1
  21. package/moj/components/alert/alert.bundle.mjs +354 -186
  22. package/moj/components/alert/alert.bundle.mjs.map +1 -1
  23. package/moj/components/alert/alert.mjs +55 -140
  24. package/moj/components/alert/alert.mjs.map +1 -1
  25. package/moj/components/button-menu/README.md +3 -1
  26. package/moj/components/button-menu/button-menu.bundle.js +91 -120
  27. package/moj/components/button-menu/button-menu.bundle.js.map +1 -1
  28. package/moj/components/button-menu/button-menu.bundle.mjs +329 -114
  29. package/moj/components/button-menu/button-menu.bundle.mjs.map +1 -1
  30. package/moj/components/button-menu/button-menu.mjs +89 -116
  31. package/moj/components/button-menu/button-menu.mjs.map +1 -1
  32. package/moj/components/date-picker/date-picker.bundle.js +174 -154
  33. package/moj/components/date-picker/date-picker.bundle.js.map +1 -1
  34. package/moj/components/date-picker/date-picker.bundle.mjs +411 -147
  35. package/moj/components/date-picker/date-picker.bundle.mjs.map +1 -1
  36. package/moj/components/date-picker/date-picker.mjs +172 -150
  37. package/moj/components/date-picker/date-picker.mjs.map +1 -1
  38. package/moj/components/filter/template.njk +1 -1
  39. package/moj/components/filter-toggle-button/filter-toggle-button.bundle.js +133 -44
  40. package/moj/components/filter-toggle-button/filter-toggle-button.bundle.js.map +1 -1
  41. package/moj/components/filter-toggle-button/filter-toggle-button.bundle.mjs +374 -41
  42. package/moj/components/filter-toggle-button/filter-toggle-button.bundle.mjs.map +1 -1
  43. package/moj/components/filter-toggle-button/filter-toggle-button.mjs +131 -40
  44. package/moj/components/filter-toggle-button/filter-toggle-button.mjs.map +1 -1
  45. package/moj/components/form-validator/form-validator.bundle.js +159 -69
  46. package/moj/components/form-validator/form-validator.bundle.js.map +1 -1
  47. package/moj/components/form-validator/form-validator.bundle.mjs +399 -65
  48. package/moj/components/form-validator/form-validator.bundle.mjs.map +1 -1
  49. package/moj/components/form-validator/form-validator.mjs +134 -54
  50. package/moj/components/form-validator/form-validator.mjs.map +1 -1
  51. package/moj/components/multi-file-upload/multi-file-upload.bundle.js +291 -117
  52. package/moj/components/multi-file-upload/multi-file-upload.bundle.js.map +1 -1
  53. package/moj/components/multi-file-upload/multi-file-upload.bundle.mjs +527 -109
  54. package/moj/components/multi-file-upload/multi-file-upload.bundle.mjs.map +1 -1
  55. package/moj/components/multi-file-upload/multi-file-upload.mjs +288 -101
  56. package/moj/components/multi-file-upload/multi-file-upload.mjs.map +1 -1
  57. package/moj/components/multi-file-upload/template.njk +1 -1
  58. package/moj/components/multi-select/multi-select.bundle.js +106 -41
  59. package/moj/components/multi-select/multi-select.bundle.js.map +1 -1
  60. package/moj/components/multi-select/multi-select.bundle.mjs +346 -37
  61. package/moj/components/multi-select/multi-select.bundle.mjs.map +1 -1
  62. package/moj/components/multi-select/multi-select.mjs +104 -37
  63. package/moj/components/multi-select/multi-select.mjs.map +1 -1
  64. package/moj/components/password-reveal/_password-reveal.scss +3 -1
  65. package/moj/components/password-reveal/_password-reveal.scss.map +1 -1
  66. package/moj/components/password-reveal/password-reveal.bundle.js +32 -29
  67. package/moj/components/password-reveal/password-reveal.bundle.js.map +1 -1
  68. package/moj/components/password-reveal/password-reveal.bundle.mjs +149 -24
  69. package/moj/components/password-reveal/password-reveal.bundle.mjs.map +1 -1
  70. package/moj/components/password-reveal/password-reveal.mjs +30 -25
  71. package/moj/components/password-reveal/password-reveal.mjs.map +1 -1
  72. package/moj/components/rich-text-editor/README.md +4 -3
  73. package/moj/components/rich-text-editor/rich-text-editor.bundle.js +127 -62
  74. package/moj/components/rich-text-editor/rich-text-editor.bundle.js.map +1 -1
  75. package/moj/components/rich-text-editor/rich-text-editor.bundle.mjs +367 -58
  76. package/moj/components/rich-text-editor/rich-text-editor.bundle.mjs.map +1 -1
  77. package/moj/components/rich-text-editor/rich-text-editor.mjs +125 -58
  78. package/moj/components/rich-text-editor/rich-text-editor.mjs.map +1 -1
  79. package/moj/components/search-toggle/search-toggle.bundle.js +94 -26
  80. package/moj/components/search-toggle/search-toggle.bundle.js.map +1 -1
  81. package/moj/components/search-toggle/search-toggle.bundle.mjs +334 -22
  82. package/moj/components/search-toggle/search-toggle.bundle.mjs.map +1 -1
  83. package/moj/components/search-toggle/search-toggle.mjs +92 -22
  84. package/moj/components/search-toggle/search-toggle.mjs.map +1 -1
  85. package/moj/components/sortable-table/sortable-table.bundle.js +151 -83
  86. package/moj/components/sortable-table/sortable-table.bundle.js.map +1 -1
  87. package/moj/components/sortable-table/sortable-table.bundle.mjs +390 -78
  88. package/moj/components/sortable-table/sortable-table.bundle.mjs.map +1 -1
  89. package/moj/components/sortable-table/sortable-table.mjs +149 -79
  90. package/moj/components/sortable-table/sortable-table.mjs.map +1 -1
  91. package/moj/core/_all.scss +3 -0
  92. package/moj/core/_all.scss.map +1 -0
  93. package/moj/core/_moj-frontend-properties.scss +7 -0
  94. package/moj/core/_moj-frontend-properties.scss.map +1 -0
  95. package/moj/filters/prototype-kit-13-filters.js +4 -3
  96. package/moj/helpers.bundle.js +22 -77
  97. package/moj/helpers.bundle.js.map +1 -1
  98. package/moj/helpers.bundle.mjs +23 -74
  99. package/moj/helpers.bundle.mjs.map +1 -1
  100. package/moj/helpers.mjs +23 -74
  101. package/moj/helpers.mjs.map +1 -1
  102. package/moj/moj-frontend.min.css +1 -1
  103. package/moj/moj-frontend.min.css.map +1 -1
  104. package/moj/moj-frontend.min.js +1 -1
  105. package/moj/moj-frontend.min.js.map +1 -1
  106. package/package.json +1 -1
  107. package/moj/version.bundle.js +0 -12
  108. package/moj/version.bundle.js.map +0 -1
  109. package/moj/version.bundle.mjs +0 -4
  110. package/moj/version.bundle.mjs.map +0 -1
  111. package/moj/version.mjs +0 -4
  112. package/moj/version.mjs.map +0 -1
@@ -1,120 +1,271 @@
1
- class AddAnother {
2
- constructor(container) {
3
- this.container = container;
4
- if (this.container.hasAttribute('data-moj-add-another-init')) {
5
- return this;
1
+ function isInitialised($root, moduleName) {
2
+ return $root instanceof HTMLElement && $root.hasAttribute(`data-${moduleName}-init`);
3
+ }
4
+
5
+ /**
6
+ * Checks if GOV.UK Frontend is supported on this page
7
+ *
8
+ * Some browsers will load and run our JavaScript but GOV.UK Frontend
9
+ * won't be supported.
10
+ *
11
+ * @param {HTMLElement | null} [$scope] - (internal) `<body>` HTML element checked for browser support
12
+ * @returns {boolean} Whether GOV.UK Frontend is supported on this page
13
+ */
14
+ function isSupported($scope = document.body) {
15
+ if (!$scope) {
16
+ return false;
17
+ }
18
+ return $scope.classList.contains('govuk-frontend-supported');
19
+ }
20
+ function formatErrorMessage(Component, message) {
21
+ return `${Component.moduleName}: ${message}`;
22
+ }
23
+
24
+ class GOVUKFrontendError extends Error {
25
+ constructor(...args) {
26
+ super(...args);
27
+ this.name = 'GOVUKFrontendError';
28
+ }
29
+ }
30
+ class SupportError extends GOVUKFrontendError {
31
+ /**
32
+ * Checks if GOV.UK Frontend is supported on this page
33
+ *
34
+ * @param {HTMLElement | null} [$scope] - HTML element `<body>` checked for browser support
35
+ */
36
+ constructor($scope = document.body) {
37
+ const supportMessage = 'noModule' in HTMLScriptElement.prototype ? 'GOV.UK Frontend initialised without `<body class="govuk-frontend-supported">` from template `<script>` snippet' : 'GOV.UK Frontend is not supported in this browser';
38
+ super($scope ? supportMessage : 'GOV.UK Frontend initialised without `<script type="module">`');
39
+ this.name = 'SupportError';
40
+ }
41
+ }
42
+ class ElementError extends GOVUKFrontendError {
43
+ constructor(messageOrOptions) {
44
+ let message = typeof messageOrOptions === 'string' ? messageOrOptions : '';
45
+ if (typeof messageOrOptions === 'object') {
46
+ const {
47
+ component,
48
+ identifier,
49
+ element,
50
+ expectedType
51
+ } = messageOrOptions;
52
+ message = identifier;
53
+ message += element ? ` is not of type ${expectedType != null ? expectedType : 'HTMLElement'}` : ' not found';
54
+ message = formatErrorMessage(component, message);
55
+ }
56
+ super(message);
57
+ this.name = 'ElementError';
58
+ }
59
+ }
60
+ class InitError extends GOVUKFrontendError {
61
+ constructor(componentOrMessage) {
62
+ const message = typeof componentOrMessage === 'string' ? componentOrMessage : formatErrorMessage(componentOrMessage, `Root element (\`$root\`) already initialised`);
63
+ super(message);
64
+ this.name = 'InitError';
65
+ }
66
+ }
67
+
68
+ class Component {
69
+ /**
70
+ * Returns the root element of the component
71
+ *
72
+ * @protected
73
+ * @returns {RootElementType} - the root element of component
74
+ */
75
+ get $root() {
76
+ return this._$root;
77
+ }
78
+ constructor($root) {
79
+ this._$root = void 0;
80
+ const childConstructor = this.constructor;
81
+ if (typeof childConstructor.moduleName !== 'string') {
82
+ throw new InitError(`\`moduleName\` not defined in component`);
6
83
  }
7
- this.container.setAttribute('data-moj-add-another-init', '');
8
- this.container.addEventListener('click', this.onRemoveButtonClick.bind(this));
9
- this.container.addEventListener('click', this.onAddButtonClick.bind(this));
10
- const buttons = this.container.querySelectorAll('.moj-add-another__add-button, moj-add-another__remove-button');
11
- buttons.forEach(button => {
12
- if (!(button instanceof HTMLButtonElement)) {
84
+ if (!($root instanceof childConstructor.elementType)) {
85
+ throw new ElementError({
86
+ element: $root,
87
+ component: childConstructor,
88
+ identifier: 'Root element (`$root`)',
89
+ expectedType: childConstructor.elementType.name
90
+ });
91
+ } else {
92
+ this._$root = $root;
93
+ }
94
+ childConstructor.checkSupport();
95
+ this.checkInitialised();
96
+ const moduleName = childConstructor.moduleName;
97
+ this.$root.setAttribute(`data-${moduleName}-init`, '');
98
+ }
99
+ checkInitialised() {
100
+ const constructor = this.constructor;
101
+ const moduleName = constructor.moduleName;
102
+ if (moduleName && isInitialised(this.$root, moduleName)) {
103
+ throw new InitError(constructor);
104
+ }
105
+ }
106
+ static checkSupport() {
107
+ if (!isSupported()) {
108
+ throw new SupportError();
109
+ }
110
+ }
111
+ }
112
+
113
+ /**
114
+ * @typedef ChildClass
115
+ * @property {string} moduleName - The module name that'll be looked for in the DOM when initialising the component
116
+ */
117
+
118
+ /**
119
+ * @typedef {typeof Component & ChildClass} ChildClassConstructor
120
+ */
121
+ Component.elementType = HTMLElement;
122
+
123
+ class AddAnother extends Component {
124
+ /**
125
+ * @param {Element | null} $root - HTML element to use for add another
126
+ */
127
+ constructor($root) {
128
+ super($root);
129
+ this.$root.addEventListener('click', this.onRemoveButtonClick.bind(this));
130
+ this.$root.addEventListener('click', this.onAddButtonClick.bind(this));
131
+ const $buttons = this.$root.querySelectorAll('.moj-add-another__add-button, moj-add-another__remove-button');
132
+ $buttons.forEach($button => {
133
+ if (!($button instanceof HTMLButtonElement)) {
13
134
  return;
14
135
  }
15
- button.type = 'button';
136
+ $button.type = 'button';
16
137
  });
17
138
  }
139
+
140
+ /**
141
+ * @param {MouseEvent} event - Click event
142
+ */
18
143
  onAddButtonClick(event) {
19
- const button = event.target;
20
- if (!button || !(button instanceof HTMLButtonElement) || !button.classList.contains('moj-add-another__add-button')) {
144
+ const $button = event.target;
145
+ if (!$button || !($button instanceof HTMLButtonElement) || !$button.classList.contains('moj-add-another__add-button')) {
21
146
  return;
22
147
  }
23
- const items = this.getItems();
24
- const item = this.getNewItem();
25
- if (!item || !(item instanceof HTMLElement)) {
148
+ const $items = this.getItems();
149
+ const $item = this.getNewItem();
150
+ if (!$item || !($item instanceof HTMLElement)) {
26
151
  return;
27
152
  }
28
- this.updateAttributes(item, items.length);
29
- this.resetItem(item);
30
- const firstItem = items[0];
31
- if (!this.hasRemoveButton(firstItem)) {
32
- this.createRemoveButton(firstItem);
153
+ this.updateAttributes($item, $items.length);
154
+ this.resetItem($item);
155
+ const $firstItem = $items[0];
156
+ if (!this.hasRemoveButton($firstItem)) {
157
+ this.createRemoveButton($firstItem);
33
158
  }
34
- items[items.length - 1].after(item);
35
- const input = item.querySelector('input, textarea, select');
36
- if (input && input instanceof HTMLInputElement) {
37
- input.focus();
159
+ $items[$items.length - 1].after($item);
160
+ const $input = $item.querySelector('input, textarea, select');
161
+ if ($input && $input instanceof HTMLInputElement) {
162
+ $input.focus();
38
163
  }
39
164
  }
40
- hasRemoveButton(item) {
41
- return item.querySelectorAll('.moj-add-another__remove-button').length;
165
+
166
+ /**
167
+ * @param {HTMLElement} $item - Add another item
168
+ */
169
+ hasRemoveButton($item) {
170
+ return $item.querySelectorAll('.moj-add-another__remove-button').length;
42
171
  }
43
172
  getItems() {
44
- if (!this.container) {
173
+ if (!this.$root) {
45
174
  return [];
46
175
  }
47
- const items = Array.from(this.container.querySelectorAll('.moj-add-another__item'));
48
- return items.filter(item => item instanceof HTMLElement);
176
+ const $items = Array.from(this.$root.querySelectorAll('.moj-add-another__item'));
177
+ return $items.filter(item => item instanceof HTMLElement);
49
178
  }
50
179
  getNewItem() {
51
- const items = this.getItems();
52
- const item = items[0].cloneNode(true);
53
- if (!item || !(item instanceof HTMLElement)) {
180
+ const $items = this.getItems();
181
+ const $item = $items[0].cloneNode(true);
182
+ if (!$item || !($item instanceof HTMLElement)) {
54
183
  return;
55
184
  }
56
- if (!this.hasRemoveButton(item)) {
57
- this.createRemoveButton(item);
185
+ if (!this.hasRemoveButton($item)) {
186
+ this.createRemoveButton($item);
58
187
  }
59
- return item;
188
+ return $item;
60
189
  }
61
- updateAttributes(item, index) {
62
- item.querySelectorAll('[data-name]').forEach(el => {
63
- if (!(el instanceof HTMLInputElement)) {
190
+
191
+ /**
192
+ * @param {HTMLElement} $item - Add another item
193
+ * @param {number} index - Add another item index
194
+ */
195
+ updateAttributes($item, index) {
196
+ $item.querySelectorAll('[data-name]').forEach($input => {
197
+ if (!($input instanceof HTMLInputElement)) {
64
198
  return;
65
199
  }
66
- const name = el.getAttribute('data-name') || '';
67
- const id = el.getAttribute('data-id') || '';
68
- const originalId = el.id;
69
- el.name = name.replace(/%index%/, `${index}`);
70
- el.id = id.replace(/%index%/, `${index}`);
71
- const label = el.parentElement.querySelector('label') || el.closest('label') || item.querySelector(`[for="${originalId}"]`);
72
- if (label && label instanceof HTMLLabelElement) {
73
- label.htmlFor = el.id;
200
+ const name = $input.getAttribute('data-name') || '';
201
+ const id = $input.getAttribute('data-id') || '';
202
+ const originalId = $input.id;
203
+ $input.name = name.replace(/%index%/, `${index}`);
204
+ $input.id = id.replace(/%index%/, `${index}`);
205
+ const $label = $input.parentElement.querySelector('label') || $input.closest('label') || $item.querySelector(`[for="${originalId}"]`);
206
+ if ($label && $label instanceof HTMLLabelElement) {
207
+ $label.htmlFor = $input.id;
74
208
  }
75
209
  });
76
210
  }
77
- createRemoveButton(item) {
78
- const button = document.createElement('button');
79
- button.type = 'button';
80
- button.classList.add('govuk-button', 'govuk-button--secondary', 'moj-add-another__remove-button');
81
- button.textContent = 'Remove';
82
- item.append(button);
211
+
212
+ /**
213
+ * @param {HTMLElement} $item - Add another item
214
+ */
215
+ createRemoveButton($item) {
216
+ const $button = document.createElement('button');
217
+ $button.type = 'button';
218
+ $button.classList.add('govuk-button', 'govuk-button--secondary', 'moj-add-another__remove-button');
219
+ $button.textContent = 'Remove';
220
+ $item.append($button);
83
221
  }
84
- resetItem(item) {
85
- item.querySelectorAll('[data-name], [data-id]').forEach(el => {
86
- if (!(el instanceof HTMLInputElement)) {
222
+
223
+ /**
224
+ * @param {HTMLElement} $item - Add another item
225
+ */
226
+ resetItem($item) {
227
+ $item.querySelectorAll('[data-name], [data-id]').forEach($input => {
228
+ if (!($input instanceof HTMLInputElement)) {
87
229
  return;
88
230
  }
89
- if (el.type === 'checkbox' || el.type === 'radio') {
90
- el.checked = false;
231
+ if ($input.type === 'checkbox' || $input.type === 'radio') {
232
+ $input.checked = false;
91
233
  } else {
92
- el.value = '';
234
+ $input.value = '';
93
235
  }
94
236
  });
95
237
  }
238
+
239
+ /**
240
+ * @param {MouseEvent} event - Click event
241
+ */
96
242
  onRemoveButtonClick(event) {
97
- const button = event.target;
98
- if (!button || !(button instanceof HTMLButtonElement) || !button.classList.contains('moj-add-another__remove-button')) {
243
+ const $button = event.target;
244
+ if (!$button || !($button instanceof HTMLButtonElement) || !$button.classList.contains('moj-add-another__remove-button')) {
99
245
  return;
100
246
  }
101
- button.closest('.moj-add-another__item').remove();
102
- const items = this.getItems();
103
- if (items.length === 1) {
104
- items[0].querySelector('.moj-add-another__remove-button').remove();
247
+ $button.closest('.moj-add-another__item').remove();
248
+ const $items = this.getItems();
249
+ if ($items.length === 1) {
250
+ $items[0].querySelector('.moj-add-another__remove-button').remove();
105
251
  }
106
- items.forEach((el, index) => {
107
- this.updateAttributes(el, index);
252
+ $items.forEach(($item, index) => {
253
+ this.updateAttributes($item, index);
108
254
  });
109
255
  this.focusHeading();
110
256
  }
111
257
  focusHeading() {
112
- const heading = this.container.querySelector('.moj-add-another__heading');
113
- if (heading && heading instanceof HTMLElement) {
114
- heading.focus();
258
+ const $heading = this.$root.querySelector('.moj-add-another__heading');
259
+ if ($heading && $heading instanceof HTMLElement) {
260
+ $heading.focus();
115
261
  }
116
262
  }
263
+
264
+ /**
265
+ * Name for the component used when initialising using data-module attributes.
266
+ */
117
267
  }
268
+ AddAnother.moduleName = 'moj-add-another';
118
269
 
119
270
  export { AddAnother };
120
271
  //# sourceMappingURL=add-another.bundle.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"add-another.bundle.mjs","sources":["../../../../src/moj/components/add-another/add-another.mjs"],"sourcesContent":["export class AddAnother {\n constructor(container) {\n this.container = container\n\n if (this.container.hasAttribute('data-moj-add-another-init')) {\n return this\n }\n\n this.container.setAttribute('data-moj-add-another-init', '')\n\n this.container.addEventListener(\n 'click',\n this.onRemoveButtonClick.bind(this)\n )\n this.container.addEventListener('click', this.onAddButtonClick.bind(this))\n\n const buttons = this.container.querySelectorAll(\n '.moj-add-another__add-button, moj-add-another__remove-button'\n )\n\n buttons.forEach((button) => {\n if (!(button instanceof HTMLButtonElement)) {\n return\n }\n\n button.type = 'button'\n })\n }\n\n onAddButtonClick(event) {\n const button = event.target\n\n if (\n !button ||\n !(button instanceof HTMLButtonElement) ||\n !button.classList.contains('moj-add-another__add-button')\n ) {\n return\n }\n\n const items = this.getItems()\n const item = this.getNewItem()\n\n if (!item || !(item instanceof HTMLElement)) {\n return\n }\n\n this.updateAttributes(item, items.length)\n this.resetItem(item)\n\n const firstItem = items[0]\n if (!this.hasRemoveButton(firstItem)) {\n this.createRemoveButton(firstItem)\n }\n\n items[items.length - 1].after(item)\n\n const input = item.querySelector('input, textarea, select')\n if (input && input instanceof HTMLInputElement) {\n input.focus()\n }\n }\n\n hasRemoveButton(item) {\n return item.querySelectorAll('.moj-add-another__remove-button').length\n }\n\n getItems() {\n if (!this.container) {\n return []\n }\n\n const items = Array.from(\n this.container.querySelectorAll('.moj-add-another__item')\n )\n\n return items.filter((item) => item instanceof HTMLElement)\n }\n\n getNewItem() {\n const items = this.getItems()\n const item = items[0].cloneNode(true)\n\n if (!item || !(item instanceof HTMLElement)) {\n return\n }\n\n if (!this.hasRemoveButton(item)) {\n this.createRemoveButton(item)\n }\n\n return item\n }\n\n updateAttributes(item, index) {\n item.querySelectorAll('[data-name]').forEach((el) => {\n if (!(el instanceof HTMLInputElement)) {\n return\n }\n\n const name = el.getAttribute('data-name') || ''\n const id = el.getAttribute('data-id') || ''\n const originalId = el.id\n\n el.name = name.replace(/%index%/, `${index}`)\n el.id = id.replace(/%index%/, `${index}`)\n\n const label =\n el.parentElement.querySelector('label') ||\n el.closest('label') ||\n item.querySelector(`[for=\"${originalId}\"]`)\n\n if (label && label instanceof HTMLLabelElement) {\n label.htmlFor = el.id\n }\n })\n }\n\n createRemoveButton(item) {\n const button = document.createElement('button')\n button.type = 'button'\n\n button.classList.add(\n 'govuk-button',\n 'govuk-button--secondary',\n 'moj-add-another__remove-button'\n )\n\n button.textContent = 'Remove'\n\n item.append(button)\n }\n\n resetItem(item) {\n item.querySelectorAll('[data-name], [data-id]').forEach((el) => {\n if (!(el instanceof HTMLInputElement)) {\n return\n }\n\n if (el.type === 'checkbox' || el.type === 'radio') {\n el.checked = false\n } else {\n el.value = ''\n }\n })\n }\n\n onRemoveButtonClick(event) {\n const button = event.target\n\n if (\n !button ||\n !(button instanceof HTMLButtonElement) ||\n !button.classList.contains('moj-add-another__remove-button')\n ) {\n return\n }\n\n button.closest('.moj-add-another__item').remove()\n\n const items = this.getItems()\n\n if (items.length === 1) {\n items[0].querySelector('.moj-add-another__remove-button').remove()\n }\n\n items.forEach((el, index) => {\n this.updateAttributes(el, index)\n })\n\n this.focusHeading()\n }\n\n focusHeading() {\n const heading = this.container.querySelector('.moj-add-another__heading')\n\n if (heading && heading instanceof HTMLElement) {\n heading.focus()\n }\n }\n}\n"],"names":["AddAnother","constructor","container","hasAttribute","setAttribute","addEventListener","onRemoveButtonClick","bind","onAddButtonClick","buttons","querySelectorAll","forEach","button","HTMLButtonElement","type","event","target","classList","contains","items","getItems","item","getNewItem","HTMLElement","updateAttributes","length","resetItem","firstItem","hasRemoveButton","createRemoveButton","after","input","querySelector","HTMLInputElement","focus","Array","from","filter","cloneNode","index","el","name","getAttribute","id","originalId","replace","label","parentElement","closest","HTMLLabelElement","htmlFor","document","createElement","add","textContent","append","checked","value","remove","focusHeading","heading"],"mappings":"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"}
1
+ {"version":3,"file":"add-another.bundle.mjs","sources":["../../../../node_modules/govuk-frontend/dist/govuk/common/index.mjs","../../../../node_modules/govuk-frontend/dist/govuk/errors/index.mjs","../../../../node_modules/govuk-frontend/dist/govuk/component.mjs","../../../../src/moj/components/add-another/add-another.mjs"],"sourcesContent":["function getFragmentFromUrl(url) {\n if (!url.includes('#')) {\n return undefined;\n }\n return url.split('#').pop();\n}\nfunction getBreakpoint(name) {\n const property = `--govuk-frontend-breakpoint-${name}`;\n const value = window.getComputedStyle(document.documentElement).getPropertyValue(property);\n return {\n property,\n value: value || undefined\n };\n}\nfunction setFocus($element, options = {}) {\n var _options$onBeforeFocu;\n const isFocusable = $element.getAttribute('tabindex');\n if (!isFocusable) {\n $element.setAttribute('tabindex', '-1');\n }\n function onFocus() {\n $element.addEventListener('blur', onBlur, {\n once: true\n });\n }\n function onBlur() {\n var _options$onBlur;\n (_options$onBlur = options.onBlur) == null || _options$onBlur.call($element);\n if (!isFocusable) {\n $element.removeAttribute('tabindex');\n }\n }\n $element.addEventListener('focus', onFocus, {\n once: true\n });\n (_options$onBeforeFocu = options.onBeforeFocus) == null || _options$onBeforeFocu.call($element);\n $element.focus();\n}\nfunction isInitialised($root, moduleName) {\n return $root instanceof HTMLElement && $root.hasAttribute(`data-${moduleName}-init`);\n}\n\n/**\n * Checks if GOV.UK Frontend is supported on this page\n *\n * Some browsers will load and run our JavaScript but GOV.UK Frontend\n * won't be supported.\n *\n * @param {HTMLElement | null} [$scope] - (internal) `<body>` HTML element checked for browser support\n * @returns {boolean} Whether GOV.UK Frontend is supported on this page\n */\nfunction isSupported($scope = document.body) {\n if (!$scope) {\n return false;\n }\n return $scope.classList.contains('govuk-frontend-supported');\n}\nfunction isArray(option) {\n return Array.isArray(option);\n}\nfunction isObject(option) {\n return !!option && typeof option === 'object' && !isArray(option);\n}\nfunction formatErrorMessage(Component, message) {\n return `${Component.moduleName}: ${message}`;\n}\n/**\n * @typedef ComponentWithModuleName\n * @property {string} moduleName - Name of the component\n */\n/**\n * @import { ObjectNested } from './configuration.mjs'\n */\n\nexport { formatErrorMessage, getBreakpoint, getFragmentFromUrl, isInitialised, isObject, isSupported, setFocus };\n//# sourceMappingURL=index.mjs.map\n","import { formatErrorMessage } from '../common/index.mjs';\n\nclass GOVUKFrontendError extends Error {\n constructor(...args) {\n super(...args);\n this.name = 'GOVUKFrontendError';\n }\n}\nclass SupportError extends GOVUKFrontendError {\n /**\n * Checks if GOV.UK Frontend is supported on this page\n *\n * @param {HTMLElement | null} [$scope] - HTML element `<body>` checked for browser support\n */\n constructor($scope = document.body) {\n const supportMessage = 'noModule' in HTMLScriptElement.prototype ? 'GOV.UK Frontend initialised without `<body class=\"govuk-frontend-supported\">` from template `<script>` snippet' : 'GOV.UK Frontend is not supported in this browser';\n super($scope ? supportMessage : 'GOV.UK Frontend initialised without `<script type=\"module\">`');\n this.name = 'SupportError';\n }\n}\nclass ConfigError extends GOVUKFrontendError {\n constructor(...args) {\n super(...args);\n this.name = 'ConfigError';\n }\n}\nclass ElementError extends GOVUKFrontendError {\n constructor(messageOrOptions) {\n let message = typeof messageOrOptions === 'string' ? messageOrOptions : '';\n if (typeof messageOrOptions === 'object') {\n const {\n component,\n identifier,\n element,\n expectedType\n } = messageOrOptions;\n message = identifier;\n message += element ? ` is not of type ${expectedType != null ? expectedType : 'HTMLElement'}` : ' not found';\n message = formatErrorMessage(component, message);\n }\n super(message);\n this.name = 'ElementError';\n }\n}\nclass InitError extends GOVUKFrontendError {\n constructor(componentOrMessage) {\n const message = typeof componentOrMessage === 'string' ? componentOrMessage : formatErrorMessage(componentOrMessage, `Root element (\\`$root\\`) already initialised`);\n super(message);\n this.name = 'InitError';\n }\n}\n/**\n * @import { ComponentWithModuleName } from '../common/index.mjs'\n */\n\nexport { ConfigError, ElementError, GOVUKFrontendError, InitError, SupportError };\n//# sourceMappingURL=index.mjs.map\n","import { isInitialised, isSupported } from './common/index.mjs';\nimport { InitError, ElementError, SupportError } from './errors/index.mjs';\n\nclass Component {\n /**\n * Returns the root element of the component\n *\n * @protected\n * @returns {RootElementType} - the root element of component\n */\n get $root() {\n return this._$root;\n }\n constructor($root) {\n this._$root = void 0;\n const childConstructor = this.constructor;\n if (typeof childConstructor.moduleName !== 'string') {\n throw new InitError(`\\`moduleName\\` not defined in component`);\n }\n if (!($root instanceof childConstructor.elementType)) {\n throw new ElementError({\n element: $root,\n component: childConstructor,\n identifier: 'Root element (`$root`)',\n expectedType: childConstructor.elementType.name\n });\n } else {\n this._$root = $root;\n }\n childConstructor.checkSupport();\n this.checkInitialised();\n const moduleName = childConstructor.moduleName;\n this.$root.setAttribute(`data-${moduleName}-init`, '');\n }\n checkInitialised() {\n const constructor = this.constructor;\n const moduleName = constructor.moduleName;\n if (moduleName && isInitialised(this.$root, moduleName)) {\n throw new InitError(constructor);\n }\n }\n static checkSupport() {\n if (!isSupported()) {\n throw new SupportError();\n }\n }\n}\n\n/**\n * @typedef ChildClass\n * @property {string} moduleName - The module name that'll be looked for in the DOM when initialising the component\n */\n\n/**\n * @typedef {typeof Component & ChildClass} ChildClassConstructor\n */\nComponent.elementType = HTMLElement;\n\nexport { Component };\n//# sourceMappingURL=component.mjs.map\n","import { Component } from 'govuk-frontend'\n\nexport class AddAnother extends Component {\n /**\n * @param {Element | null} $root - HTML element to use for add another\n */\n constructor($root) {\n super($root)\n\n this.$root.addEventListener('click', this.onRemoveButtonClick.bind(this))\n this.$root.addEventListener('click', this.onAddButtonClick.bind(this))\n\n const $buttons = this.$root.querySelectorAll(\n '.moj-add-another__add-button, moj-add-another__remove-button'\n )\n\n $buttons.forEach(($button) => {\n if (!($button instanceof HTMLButtonElement)) {\n return\n }\n\n $button.type = 'button'\n })\n }\n\n /**\n * @param {MouseEvent} event - Click event\n */\n onAddButtonClick(event) {\n const $button = event.target\n\n if (\n !$button ||\n !($button instanceof HTMLButtonElement) ||\n !$button.classList.contains('moj-add-another__add-button')\n ) {\n return\n }\n\n const $items = this.getItems()\n const $item = this.getNewItem()\n\n if (!$item || !($item instanceof HTMLElement)) {\n return\n }\n\n this.updateAttributes($item, $items.length)\n this.resetItem($item)\n\n const $firstItem = $items[0]\n if (!this.hasRemoveButton($firstItem)) {\n this.createRemoveButton($firstItem)\n }\n\n $items[$items.length - 1].after($item)\n\n const $input = $item.querySelector('input, textarea, select')\n if ($input && $input instanceof HTMLInputElement) {\n $input.focus()\n }\n }\n\n /**\n * @param {HTMLElement} $item - Add another item\n */\n hasRemoveButton($item) {\n return $item.querySelectorAll('.moj-add-another__remove-button').length\n }\n\n getItems() {\n if (!this.$root) {\n return []\n }\n\n const $items = Array.from(\n this.$root.querySelectorAll('.moj-add-another__item')\n )\n\n return $items.filter((item) => item instanceof HTMLElement)\n }\n\n getNewItem() {\n const $items = this.getItems()\n const $item = $items[0].cloneNode(true)\n\n if (!$item || !($item instanceof HTMLElement)) {\n return\n }\n\n if (!this.hasRemoveButton($item)) {\n this.createRemoveButton($item)\n }\n\n return $item\n }\n\n /**\n * @param {HTMLElement} $item - Add another item\n * @param {number} index - Add another item index\n */\n updateAttributes($item, index) {\n $item.querySelectorAll('[data-name]').forEach(($input) => {\n if (!($input instanceof HTMLInputElement)) {\n return\n }\n\n const name = $input.getAttribute('data-name') || ''\n const id = $input.getAttribute('data-id') || ''\n const originalId = $input.id\n\n $input.name = name.replace(/%index%/, `${index}`)\n $input.id = id.replace(/%index%/, `${index}`)\n\n const $label =\n $input.parentElement.querySelector('label') ||\n $input.closest('label') ||\n $item.querySelector(`[for=\"${originalId}\"]`)\n\n if ($label && $label instanceof HTMLLabelElement) {\n $label.htmlFor = $input.id\n }\n })\n }\n\n /**\n * @param {HTMLElement} $item - Add another item\n */\n createRemoveButton($item) {\n const $button = document.createElement('button')\n $button.type = 'button'\n\n $button.classList.add(\n 'govuk-button',\n 'govuk-button--secondary',\n 'moj-add-another__remove-button'\n )\n\n $button.textContent = 'Remove'\n\n $item.append($button)\n }\n\n /**\n * @param {HTMLElement} $item - Add another item\n */\n resetItem($item) {\n $item.querySelectorAll('[data-name], [data-id]').forEach(($input) => {\n if (!($input instanceof HTMLInputElement)) {\n return\n }\n\n if ($input.type === 'checkbox' || $input.type === 'radio') {\n $input.checked = false\n } else {\n $input.value = ''\n }\n })\n }\n\n /**\n * @param {MouseEvent} event - Click event\n */\n onRemoveButtonClick(event) {\n const $button = event.target\n\n if (\n !$button ||\n !($button instanceof HTMLButtonElement) ||\n !$button.classList.contains('moj-add-another__remove-button')\n ) {\n return\n }\n\n $button.closest('.moj-add-another__item').remove()\n\n const $items = this.getItems()\n\n if ($items.length === 1) {\n $items[0].querySelector('.moj-add-another__remove-button').remove()\n }\n\n $items.forEach(($item, index) => {\n this.updateAttributes($item, index)\n })\n\n this.focusHeading()\n }\n\n focusHeading() {\n const $heading = this.$root.querySelector('.moj-add-another__heading')\n\n if ($heading && $heading instanceof HTMLElement) {\n $heading.focus()\n }\n }\n\n /**\n * Name for the component used when initialising using data-module attributes.\n */\n static moduleName = 'moj-add-another'\n}\n"],"names":["isInitialised","$root","moduleName","HTMLElement","hasAttribute","isSupported","$scope","document","body","classList","contains","formatErrorMessage","Component","message","GOVUKFrontendError","Error","constructor","args","name","SupportError","supportMessage","HTMLScriptElement","prototype","ElementError","messageOrOptions","component","identifier","element","expectedType","InitError","componentOrMessage","_$root","childConstructor","elementType","checkSupport","checkInitialised","setAttribute","AddAnother","addEventListener","onRemoveButtonClick","bind","onAddButtonClick","$buttons","querySelectorAll","forEach","$button","HTMLButtonElement","type","event","target","$items","getItems","$item","getNewItem","updateAttributes","length","resetItem","$firstItem","hasRemoveButton","createRemoveButton","after","$input","querySelector","HTMLInputElement","focus","Array","from","filter","item","cloneNode","index","getAttribute","id","originalId","replace","$label","parentElement","closest","HTMLLabelElement","htmlFor","createElement","add","textContent","append","checked","value","remove","focusHeading","$heading"],"mappings":"AAqGO,SAASA,aAAaA,CAACC,KAAK,EAAEC,UAAU,EAAE;EAC/C,OACED,KAAK,YAAYE,WAAW,IAC5BF,KAAK,CAACG,YAAY,CAAC,CAAA,KAAA,EAAQF,UAAU,CAAA,KAAA,CAAO,CAAC;AAEjD;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,SAASG,WAAWA,CAACC,MAAM,GAAGC,QAAQ,CAACC,IAAI,EAAE;EAClD,IAAI,CAACF,MAAM,EAAE;AACX,IAAA,OAAO,KAAK;AACd;AAEA,EAAA,OAAOA,MAAM,CAACG,SAAS,CAACC,QAAQ,CAAC,0BAA0B,CAAC;AAC9D;AAiCO,SAASC,kBAAkBA,CAACC,SAAS,EAAEC,OAAO,EAAE;AACrD,EAAA,OAAO,GAAGD,SAAS,CAACV,UAAU,CAAA,EAAA,EAAKW,OAAO,CAAE,CAAA;AAC9C;;ACxIO,MAAMC,kBAAkB,SAASC,KAAK,CAAC;AAAAC,EAAAA,WAAAA,CAAA,GAAAC,IAAA,EAAA;AAAA,IAAA,KAAA,CAAA,GAAAA,IAAA,CAAA;IAAA,IAC5C,CAAAC,IAAI,GAAG,oBAAoB;AAAA;AAC7B;AAKO,MAAMC,YAAY,SAASL,kBAAkB,CAAC;AAGnD;AACF;AACA;AACA;AACA;AACEE,EAAAA,WAAWA,CAACV,MAAM,GAAGC,QAAQ,CAACC,IAAI,EAAE;IAClC,MAAMY,cAAc,GAClB,UAAU,IAAIC,iBAAiB,CAACC,SAAS,GACrC,gHAAgH,GAChH,kDAAkD;AAExD,IAAA,KAAK,CACHhB,MAAM,GACFc,cAAc,GACd,8DACN,CAAC;IAAA,IAjBH,CAAAF,IAAI,GAAG,cAAc;AAkBrB;AACF;AAYO,MAAMK,YAAY,SAAST,kBAAkB,CAAC;EAmBnDE,WAAWA,CAACQ,gBAAgB,EAAE;IAC5B,IAAIX,OAAO,GAAG,OAAOW,gBAAgB,KAAK,QAAQ,GAAGA,gBAAgB,GAAG,EAAE;AAG1E,IAAA,IAAI,OAAOA,gBAAgB,KAAK,QAAQ,EAAE;MACxC,MAAM;QAAEC,SAAS;QAAEC,UAAU;QAAEC,OAAO;AAAEC,QAAAA;AAAa,OAAC,GAAGJ,gBAAgB;AAEzEX,MAAAA,OAAO,GAAGa,UAAU;AAGpBb,MAAAA,OAAO,IAAIc,OAAO,GACd,CAAA,gBAAA,EAAmBC,YAAY,IAAZ,IAAAA,GAAAA,YAAY,GAAI,aAAa,CAAE,CAAA,GAClD,YAAY;AAEhBf,MAAAA,OAAO,GAAGF,kBAAkB,CAACc,SAAS,EAAEZ,OAAO,CAAC;AAClD;IAEA,KAAK,CAACA,OAAO,CAAC;IAAA,IAnChB,CAAAK,IAAI,GAAG,cAAc;AAoCrB;AACF;AAKO,MAAMW,SAAS,SAASf,kBAAkB,CAAC;EAOhDE,WAAWA,CAACc,kBAAkB,EAAE;AAC9B,IAAA,MAAMjB,OAAO,GACX,OAAOiB,kBAAkB,KAAK,QAAQ,GAClCA,kBAAkB,GAClBnB,kBAAkB,CAChBmB,kBAAkB,EAClB,8CACF,CAAC;IAEP,KAAK,CAACjB,OAAO,CAAC;IAAA,IAfhB,CAAAK,IAAI,GAAG,WAAW;AAgBlB;AACF;;AC/GO,MAAMN,SAAS,CAAC;AASrB;AACF;AACA;AACA;AACA;AACA;EACE,IAAIX,KAAKA,GAAG;IACV,OAAO,IAAI,CAAC8B,MAAM;AACpB;EAcAf,WAAWA,CAACf,KAAK,EAAE;AAAA,IAAA,IAAA,CARnB8B,MAAM,GAAA,MAAA;AASJ,IAAA,MAAMC,gBAAgB,GACpB,IAAI,CAAChB,WACN;AASD,IAAA,IAAI,OAAOgB,gBAAgB,CAAC9B,UAAU,KAAK,QAAQ,EAAE;AACnD,MAAA,MAAM,IAAI2B,SAAS,CAAC,CAAA,uCAAA,CAAyC,CAAC;AAChE;AAEA,IAAA,IAAI,EAAE5B,KAAK,YAAY+B,gBAAgB,CAACC,WAAW,CAAC,EAAE;MACpD,MAAM,IAAIV,YAAY,CAAC;AACrBI,QAAAA,OAAO,EAAE1B,KAAK;AACdwB,QAAAA,SAAS,EAAEO,gBAAgB;AAC3BN,QAAAA,UAAU,EAAE,wBAAwB;AACpCE,QAAAA,YAAY,EAAEI,gBAAgB,CAACC,WAAW,CAACf;AAC7C,OAAC,CAAC;AACJ,KAAC,MAAM;MACL,IAAI,CAACa,MAAM,GAAmC9B,KAAM;AACtD;IAEA+B,gBAAgB,CAACE,YAAY,EAAE;IAE/B,IAAI,CAACC,gBAAgB,EAAE;AAEvB,IAAA,MAAMjC,UAAU,GAAG8B,gBAAgB,CAAC9B,UAAU;IAE9C,IAAI,CAACD,KAAK,CAACmC,YAAY,CAAC,QAAQlC,UAAU,CAAA,KAAA,CAAO,EAAE,EAAE,CAAC;AACxD;AAQAiC,EAAAA,gBAAgBA,GAAG;AACjB,IAAA,MAAMnB,WAAW,GAAyC,IAAI,CAACA,WAAY;AAC3E,IAAA,MAAMd,UAAU,GAAGc,WAAW,CAACd,UAAU;IAEzC,IAAIA,UAAU,IAAIF,aAAa,CAAC,IAAI,CAACC,KAAK,EAAEC,UAAU,CAAC,EAAE;AACvD,MAAA,MAAM,IAAI2B,SAAS,CAACb,WAAW,CAAC;AAClC;AACF;EAOA,OAAOkB,YAAYA,GAAG;IACpB,IAAI,CAAC7B,WAAW,EAAE,EAAE;MAClB,MAAM,IAAIc,YAAY,EAAE;AAC1B;AACF;AACF;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AArGaP,SAAS,CAIbqB,WAAW,GAAG9B,WAAW;;ACb3B,MAAMkC,UAAU,SAASzB,SAAS,CAAC;AACxC;AACF;AACA;EACEI,WAAWA,CAACf,KAAK,EAAE;IACjB,KAAK,CAACA,KAAK,CAAC;AAEZ,IAAA,IAAI,CAACA,KAAK,CAACqC,gBAAgB,CAAC,OAAO,EAAE,IAAI,CAACC,mBAAmB,CAACC,IAAI,CAAC,IAAI,CAAC,CAAC;AACzE,IAAA,IAAI,CAACvC,KAAK,CAACqC,gBAAgB,CAAC,OAAO,EAAE,IAAI,CAACG,gBAAgB,CAACD,IAAI,CAAC,IAAI,CAAC,CAAC;IAEtE,MAAME,QAAQ,GAAG,IAAI,CAACzC,KAAK,CAAC0C,gBAAgB,CAC1C,8DACF,CAAC;AAEDD,IAAAA,QAAQ,CAACE,OAAO,CAAEC,OAAO,IAAK;AAC5B,MAAA,IAAI,EAAEA,OAAO,YAAYC,iBAAiB,CAAC,EAAE;AAC3C,QAAA;AACF;MAEAD,OAAO,CAACE,IAAI,GAAG,QAAQ;AACzB,KAAC,CAAC;AACJ;;AAEA;AACF;AACA;EACEN,gBAAgBA,CAACO,KAAK,EAAE;AACtB,IAAA,MAAMH,OAAO,GAAGG,KAAK,CAACC,MAAM;AAE5B,IAAA,IACE,CAACJ,OAAO,IACR,EAAEA,OAAO,YAAYC,iBAAiB,CAAC,IACvC,CAACD,OAAO,CAACpC,SAAS,CAACC,QAAQ,CAAC,6BAA6B,CAAC,EAC1D;AACA,MAAA;AACF;AAEA,IAAA,MAAMwC,MAAM,GAAG,IAAI,CAACC,QAAQ,EAAE;AAC9B,IAAA,MAAMC,KAAK,GAAG,IAAI,CAACC,UAAU,EAAE;IAE/B,IAAI,CAACD,KAAK,IAAI,EAAEA,KAAK,YAAYjD,WAAW,CAAC,EAAE;AAC7C,MAAA;AACF;IAEA,IAAI,CAACmD,gBAAgB,CAACF,KAAK,EAAEF,MAAM,CAACK,MAAM,CAAC;AAC3C,IAAA,IAAI,CAACC,SAAS,CAACJ,KAAK,CAAC;AAErB,IAAA,MAAMK,UAAU,GAAGP,MAAM,CAAC,CAAC,CAAC;AAC5B,IAAA,IAAI,CAAC,IAAI,CAACQ,eAAe,CAACD,UAAU,CAAC,EAAE;AACrC,MAAA,IAAI,CAACE,kBAAkB,CAACF,UAAU,CAAC;AACrC;IAEAP,MAAM,CAACA,MAAM,CAACK,MAAM,GAAG,CAAC,CAAC,CAACK,KAAK,CAACR,KAAK,CAAC;AAEtC,IAAA,MAAMS,MAAM,GAAGT,KAAK,CAACU,aAAa,CAAC,yBAAyB,CAAC;AAC7D,IAAA,IAAID,MAAM,IAAIA,MAAM,YAAYE,gBAAgB,EAAE;MAChDF,MAAM,CAACG,KAAK,EAAE;AAChB;AACF;;AAEA;AACF;AACA;EACEN,eAAeA,CAACN,KAAK,EAAE;AACrB,IAAA,OAAOA,KAAK,CAACT,gBAAgB,CAAC,iCAAiC,CAAC,CAACY,MAAM;AACzE;AAEAJ,EAAAA,QAAQA,GAAG;AACT,IAAA,IAAI,CAAC,IAAI,CAAClD,KAAK,EAAE;AACf,MAAA,OAAO,EAAE;AACX;AAEA,IAAA,MAAMiD,MAAM,GAAGe,KAAK,CAACC,IAAI,CACvB,IAAI,CAACjE,KAAK,CAAC0C,gBAAgB,CAAC,wBAAwB,CACtD,CAAC;IAED,OAAOO,MAAM,CAACiB,MAAM,CAAEC,IAAI,IAAKA,IAAI,YAAYjE,WAAW,CAAC;AAC7D;AAEAkD,EAAAA,UAAUA,GAAG;AACX,IAAA,MAAMH,MAAM,GAAG,IAAI,CAACC,QAAQ,EAAE;IAC9B,MAAMC,KAAK,GAAGF,MAAM,CAAC,CAAC,CAAC,CAACmB,SAAS,CAAC,IAAI,CAAC;IAEvC,IAAI,CAACjB,KAAK,IAAI,EAAEA,KAAK,YAAYjD,WAAW,CAAC,EAAE;AAC7C,MAAA;AACF;AAEA,IAAA,IAAI,CAAC,IAAI,CAACuD,eAAe,CAACN,KAAK,CAAC,EAAE;AAChC,MAAA,IAAI,CAACO,kBAAkB,CAACP,KAAK,CAAC;AAChC;AAEA,IAAA,OAAOA,KAAK;AACd;;AAEA;AACF;AACA;AACA;AACEE,EAAAA,gBAAgBA,CAACF,KAAK,EAAEkB,KAAK,EAAE;IAC7BlB,KAAK,CAACT,gBAAgB,CAAC,aAAa,CAAC,CAACC,OAAO,CAAEiB,MAAM,IAAK;AACxD,MAAA,IAAI,EAAEA,MAAM,YAAYE,gBAAgB,CAAC,EAAE;AACzC,QAAA;AACF;MAEA,MAAM7C,IAAI,GAAG2C,MAAM,CAACU,YAAY,CAAC,WAAW,CAAC,IAAI,EAAE;MACnD,MAAMC,EAAE,GAAGX,MAAM,CAACU,YAAY,CAAC,SAAS,CAAC,IAAI,EAAE;AAC/C,MAAA,MAAME,UAAU,GAAGZ,MAAM,CAACW,EAAE;AAE5BX,MAAAA,MAAM,CAAC3C,IAAI,GAAGA,IAAI,CAACwD,OAAO,CAAC,SAAS,EAAE,CAAA,EAAGJ,KAAK,CAAA,CAAE,CAAC;AACjDT,MAAAA,MAAM,CAACW,EAAE,GAAGA,EAAE,CAACE,OAAO,CAAC,SAAS,EAAE,CAAA,EAAGJ,KAAK,CAAA,CAAE,CAAC;MAE7C,MAAMK,MAAM,GACVd,MAAM,CAACe,aAAa,CAACd,aAAa,CAAC,OAAO,CAAC,IAC3CD,MAAM,CAACgB,OAAO,CAAC,OAAO,CAAC,IACvBzB,KAAK,CAACU,aAAa,CAAC,CAAA,MAAA,EAASW,UAAU,CAAA,EAAA,CAAI,CAAC;AAE9C,MAAA,IAAIE,MAAM,IAAIA,MAAM,YAAYG,gBAAgB,EAAE;AAChDH,QAAAA,MAAM,CAACI,OAAO,GAAGlB,MAAM,CAACW,EAAE;AAC5B;AACF,KAAC,CAAC;AACJ;;AAEA;AACF;AACA;EACEb,kBAAkBA,CAACP,KAAK,EAAE;AACxB,IAAA,MAAMP,OAAO,GAAGtC,QAAQ,CAACyE,aAAa,CAAC,QAAQ,CAAC;IAChDnC,OAAO,CAACE,IAAI,GAAG,QAAQ;IAEvBF,OAAO,CAACpC,SAAS,CAACwE,GAAG,CACnB,cAAc,EACd,yBAAyB,EACzB,gCACF,CAAC;IAEDpC,OAAO,CAACqC,WAAW,GAAG,QAAQ;AAE9B9B,IAAAA,KAAK,CAAC+B,MAAM,CAACtC,OAAO,CAAC;AACvB;;AAEA;AACF;AACA;EACEW,SAASA,CAACJ,KAAK,EAAE;IACfA,KAAK,CAACT,gBAAgB,CAAC,wBAAwB,CAAC,CAACC,OAAO,CAAEiB,MAAM,IAAK;AACnE,MAAA,IAAI,EAAEA,MAAM,YAAYE,gBAAgB,CAAC,EAAE;AACzC,QAAA;AACF;MAEA,IAAIF,MAAM,CAACd,IAAI,KAAK,UAAU,IAAIc,MAAM,CAACd,IAAI,KAAK,OAAO,EAAE;QACzDc,MAAM,CAACuB,OAAO,GAAG,KAAK;AACxB,OAAC,MAAM;QACLvB,MAAM,CAACwB,KAAK,GAAG,EAAE;AACnB;AACF,KAAC,CAAC;AACJ;;AAEA;AACF;AACA;EACE9C,mBAAmBA,CAACS,KAAK,EAAE;AACzB,IAAA,MAAMH,OAAO,GAAGG,KAAK,CAACC,MAAM;AAE5B,IAAA,IACE,CAACJ,OAAO,IACR,EAAEA,OAAO,YAAYC,iBAAiB,CAAC,IACvC,CAACD,OAAO,CAACpC,SAAS,CAACC,QAAQ,CAAC,gCAAgC,CAAC,EAC7D;AACA,MAAA;AACF;IAEAmC,OAAO,CAACgC,OAAO,CAAC,wBAAwB,CAAC,CAACS,MAAM,EAAE;AAElD,IAAA,MAAMpC,MAAM,GAAG,IAAI,CAACC,QAAQ,EAAE;AAE9B,IAAA,IAAID,MAAM,CAACK,MAAM,KAAK,CAAC,EAAE;MACvBL,MAAM,CAAC,CAAC,CAAC,CAACY,aAAa,CAAC,iCAAiC,CAAC,CAACwB,MAAM,EAAE;AACrE;AAEApC,IAAAA,MAAM,CAACN,OAAO,CAAC,CAACQ,KAAK,EAAEkB,KAAK,KAAK;AAC/B,MAAA,IAAI,CAAChB,gBAAgB,CAACF,KAAK,EAAEkB,KAAK,CAAC;AACrC,KAAC,CAAC;IAEF,IAAI,CAACiB,YAAY,EAAE;AACrB;AAEAA,EAAAA,YAAYA,GAAG;IACb,MAAMC,QAAQ,GAAG,IAAI,CAACvF,KAAK,CAAC6D,aAAa,CAAC,2BAA2B,CAAC;AAEtE,IAAA,IAAI0B,QAAQ,IAAIA,QAAQ,YAAYrF,WAAW,EAAE;MAC/CqF,QAAQ,CAACxB,KAAK,EAAE;AAClB;AACF;;AAEA;AACF;AACA;AAEA;AAtMa3B,UAAU,CAqMdnC,UAAU,GAAG,iBAAiB;;;;","x_google_ignoreList":[0,1,2]}
@@ -1,120 +1,151 @@
1
- class AddAnother {
2
- constructor(container) {
3
- this.container = container;
4
- if (this.container.hasAttribute('data-moj-add-another-init')) {
5
- return this;
6
- }
7
- this.container.setAttribute('data-moj-add-another-init', '');
8
- this.container.addEventListener('click', this.onRemoveButtonClick.bind(this));
9
- this.container.addEventListener('click', this.onAddButtonClick.bind(this));
10
- const buttons = this.container.querySelectorAll('.moj-add-another__add-button, moj-add-another__remove-button');
11
- buttons.forEach(button => {
12
- if (!(button instanceof HTMLButtonElement)) {
1
+ import { Component } from 'govuk-frontend';
2
+
3
+ class AddAnother extends Component {
4
+ /**
5
+ * @param {Element | null} $root - HTML element to use for add another
6
+ */
7
+ constructor($root) {
8
+ super($root);
9
+ this.$root.addEventListener('click', this.onRemoveButtonClick.bind(this));
10
+ this.$root.addEventListener('click', this.onAddButtonClick.bind(this));
11
+ const $buttons = this.$root.querySelectorAll('.moj-add-another__add-button, moj-add-another__remove-button');
12
+ $buttons.forEach($button => {
13
+ if (!($button instanceof HTMLButtonElement)) {
13
14
  return;
14
15
  }
15
- button.type = 'button';
16
+ $button.type = 'button';
16
17
  });
17
18
  }
19
+
20
+ /**
21
+ * @param {MouseEvent} event - Click event
22
+ */
18
23
  onAddButtonClick(event) {
19
- const button = event.target;
20
- if (!button || !(button instanceof HTMLButtonElement) || !button.classList.contains('moj-add-another__add-button')) {
24
+ const $button = event.target;
25
+ if (!$button || !($button instanceof HTMLButtonElement) || !$button.classList.contains('moj-add-another__add-button')) {
21
26
  return;
22
27
  }
23
- const items = this.getItems();
24
- const item = this.getNewItem();
25
- if (!item || !(item instanceof HTMLElement)) {
28
+ const $items = this.getItems();
29
+ const $item = this.getNewItem();
30
+ if (!$item || !($item instanceof HTMLElement)) {
26
31
  return;
27
32
  }
28
- this.updateAttributes(item, items.length);
29
- this.resetItem(item);
30
- const firstItem = items[0];
31
- if (!this.hasRemoveButton(firstItem)) {
32
- this.createRemoveButton(firstItem);
33
+ this.updateAttributes($item, $items.length);
34
+ this.resetItem($item);
35
+ const $firstItem = $items[0];
36
+ if (!this.hasRemoveButton($firstItem)) {
37
+ this.createRemoveButton($firstItem);
33
38
  }
34
- items[items.length - 1].after(item);
35
- const input = item.querySelector('input, textarea, select');
36
- if (input && input instanceof HTMLInputElement) {
37
- input.focus();
39
+ $items[$items.length - 1].after($item);
40
+ const $input = $item.querySelector('input, textarea, select');
41
+ if ($input && $input instanceof HTMLInputElement) {
42
+ $input.focus();
38
43
  }
39
44
  }
40
- hasRemoveButton(item) {
41
- return item.querySelectorAll('.moj-add-another__remove-button').length;
45
+
46
+ /**
47
+ * @param {HTMLElement} $item - Add another item
48
+ */
49
+ hasRemoveButton($item) {
50
+ return $item.querySelectorAll('.moj-add-another__remove-button').length;
42
51
  }
43
52
  getItems() {
44
- if (!this.container) {
53
+ if (!this.$root) {
45
54
  return [];
46
55
  }
47
- const items = Array.from(this.container.querySelectorAll('.moj-add-another__item'));
48
- return items.filter(item => item instanceof HTMLElement);
56
+ const $items = Array.from(this.$root.querySelectorAll('.moj-add-another__item'));
57
+ return $items.filter(item => item instanceof HTMLElement);
49
58
  }
50
59
  getNewItem() {
51
- const items = this.getItems();
52
- const item = items[0].cloneNode(true);
53
- if (!item || !(item instanceof HTMLElement)) {
60
+ const $items = this.getItems();
61
+ const $item = $items[0].cloneNode(true);
62
+ if (!$item || !($item instanceof HTMLElement)) {
54
63
  return;
55
64
  }
56
- if (!this.hasRemoveButton(item)) {
57
- this.createRemoveButton(item);
65
+ if (!this.hasRemoveButton($item)) {
66
+ this.createRemoveButton($item);
58
67
  }
59
- return item;
68
+ return $item;
60
69
  }
61
- updateAttributes(item, index) {
62
- item.querySelectorAll('[data-name]').forEach(el => {
63
- if (!(el instanceof HTMLInputElement)) {
70
+
71
+ /**
72
+ * @param {HTMLElement} $item - Add another item
73
+ * @param {number} index - Add another item index
74
+ */
75
+ updateAttributes($item, index) {
76
+ $item.querySelectorAll('[data-name]').forEach($input => {
77
+ if (!($input instanceof HTMLInputElement)) {
64
78
  return;
65
79
  }
66
- const name = el.getAttribute('data-name') || '';
67
- const id = el.getAttribute('data-id') || '';
68
- const originalId = el.id;
69
- el.name = name.replace(/%index%/, `${index}`);
70
- el.id = id.replace(/%index%/, `${index}`);
71
- const label = el.parentElement.querySelector('label') || el.closest('label') || item.querySelector(`[for="${originalId}"]`);
72
- if (label && label instanceof HTMLLabelElement) {
73
- label.htmlFor = el.id;
80
+ const name = $input.getAttribute('data-name') || '';
81
+ const id = $input.getAttribute('data-id') || '';
82
+ const originalId = $input.id;
83
+ $input.name = name.replace(/%index%/, `${index}`);
84
+ $input.id = id.replace(/%index%/, `${index}`);
85
+ const $label = $input.parentElement.querySelector('label') || $input.closest('label') || $item.querySelector(`[for="${originalId}"]`);
86
+ if ($label && $label instanceof HTMLLabelElement) {
87
+ $label.htmlFor = $input.id;
74
88
  }
75
89
  });
76
90
  }
77
- createRemoveButton(item) {
78
- const button = document.createElement('button');
79
- button.type = 'button';
80
- button.classList.add('govuk-button', 'govuk-button--secondary', 'moj-add-another__remove-button');
81
- button.textContent = 'Remove';
82
- item.append(button);
91
+
92
+ /**
93
+ * @param {HTMLElement} $item - Add another item
94
+ */
95
+ createRemoveButton($item) {
96
+ const $button = document.createElement('button');
97
+ $button.type = 'button';
98
+ $button.classList.add('govuk-button', 'govuk-button--secondary', 'moj-add-another__remove-button');
99
+ $button.textContent = 'Remove';
100
+ $item.append($button);
83
101
  }
84
- resetItem(item) {
85
- item.querySelectorAll('[data-name], [data-id]').forEach(el => {
86
- if (!(el instanceof HTMLInputElement)) {
102
+
103
+ /**
104
+ * @param {HTMLElement} $item - Add another item
105
+ */
106
+ resetItem($item) {
107
+ $item.querySelectorAll('[data-name], [data-id]').forEach($input => {
108
+ if (!($input instanceof HTMLInputElement)) {
87
109
  return;
88
110
  }
89
- if (el.type === 'checkbox' || el.type === 'radio') {
90
- el.checked = false;
111
+ if ($input.type === 'checkbox' || $input.type === 'radio') {
112
+ $input.checked = false;
91
113
  } else {
92
- el.value = '';
114
+ $input.value = '';
93
115
  }
94
116
  });
95
117
  }
118
+
119
+ /**
120
+ * @param {MouseEvent} event - Click event
121
+ */
96
122
  onRemoveButtonClick(event) {
97
- const button = event.target;
98
- if (!button || !(button instanceof HTMLButtonElement) || !button.classList.contains('moj-add-another__remove-button')) {
123
+ const $button = event.target;
124
+ if (!$button || !($button instanceof HTMLButtonElement) || !$button.classList.contains('moj-add-another__remove-button')) {
99
125
  return;
100
126
  }
101
- button.closest('.moj-add-another__item').remove();
102
- const items = this.getItems();
103
- if (items.length === 1) {
104
- items[0].querySelector('.moj-add-another__remove-button').remove();
127
+ $button.closest('.moj-add-another__item').remove();
128
+ const $items = this.getItems();
129
+ if ($items.length === 1) {
130
+ $items[0].querySelector('.moj-add-another__remove-button').remove();
105
131
  }
106
- items.forEach((el, index) => {
107
- this.updateAttributes(el, index);
132
+ $items.forEach(($item, index) => {
133
+ this.updateAttributes($item, index);
108
134
  });
109
135
  this.focusHeading();
110
136
  }
111
137
  focusHeading() {
112
- const heading = this.container.querySelector('.moj-add-another__heading');
113
- if (heading && heading instanceof HTMLElement) {
114
- heading.focus();
138
+ const $heading = this.$root.querySelector('.moj-add-another__heading');
139
+ if ($heading && $heading instanceof HTMLElement) {
140
+ $heading.focus();
115
141
  }
116
142
  }
143
+
144
+ /**
145
+ * Name for the component used when initialising using data-module attributes.
146
+ */
117
147
  }
148
+ AddAnother.moduleName = 'moj-add-another';
118
149
 
119
150
  export { AddAnother };
120
151
  //# sourceMappingURL=add-another.mjs.map