govuk_publishing_components 51.1.1 → 51.2.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 (113) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/javascripts/govuk_publishing_components/components/feedback.js +29 -34
  3. data/app/assets/javascripts/govuk_publishing_components/vendor/lux/lux-reporter.js +7 -2
  4. data/app/assets/stylesheets/component_guide/application.scss +1 -1
  5. data/app/assets/stylesheets/govuk_publishing_components/_all_components.scss +1 -0
  6. data/app/assets/stylesheets/govuk_publishing_components/components/helpers/_markdown-typography.scss +2 -2
  7. data/app/models/govuk_publishing_components/audit_comparer.rb +3 -3
  8. data/app/views/govuk_publishing_components/components/_title.html.erb +2 -3
  9. data/app/views/govuk_publishing_components/components/docs/add_another.yml +1 -1
  10. data/app/views/govuk_publishing_components/components/docs/feedback.yml +1 -1
  11. data/lib/govuk_publishing_components/presenters/checkboxes_helper.rb +1 -1
  12. data/lib/govuk_publishing_components/presenters/shared_helper.rb +0 -11
  13. data/lib/govuk_publishing_components/version.rb +1 -1
  14. data/node_modules/govuk-frontend/dist/govuk/all.bundle.js +217 -184
  15. data/node_modules/govuk-frontend/dist/govuk/all.bundle.js.map +1 -1
  16. data/node_modules/govuk-frontend/dist/govuk/all.bundle.mjs +216 -184
  17. data/node_modules/govuk-frontend/dist/govuk/all.bundle.mjs.map +1 -1
  18. data/node_modules/govuk-frontend/dist/govuk/all.mjs +1 -0
  19. data/node_modules/govuk-frontend/dist/govuk/all.mjs.map +1 -1
  20. data/node_modules/govuk-frontend/dist/govuk/all.scss +6 -0
  21. data/node_modules/govuk-frontend/dist/govuk/all.scss.map +1 -1
  22. data/node_modules/govuk-frontend/dist/govuk/common/configuration.mjs +164 -0
  23. data/node_modules/govuk-frontend/dist/govuk/common/configuration.mjs.map +1 -0
  24. data/node_modules/govuk-frontend/dist/govuk/common/govuk-frontend-version.mjs +1 -1
  25. data/node_modules/govuk-frontend/dist/govuk/common/index.mjs +1 -87
  26. data/node_modules/govuk-frontend/dist/govuk/common/index.mjs.map +1 -1
  27. data/node_modules/govuk-frontend/dist/govuk/components/accordion/accordion.bundle.js +149 -112
  28. data/node_modules/govuk-frontend/dist/govuk/components/accordion/accordion.bundle.js.map +1 -1
  29. data/node_modules/govuk-frontend/dist/govuk/components/accordion/accordion.bundle.mjs +148 -111
  30. data/node_modules/govuk-frontend/dist/govuk/components/accordion/accordion.bundle.mjs.map +1 -1
  31. data/node_modules/govuk-frontend/dist/govuk/components/accordion/accordion.mjs +5 -8
  32. data/node_modules/govuk-frontend/dist/govuk/components/accordion/accordion.mjs.map +1 -1
  33. data/node_modules/govuk-frontend/dist/govuk/components/button/button.bundle.js +149 -112
  34. data/node_modules/govuk-frontend/dist/govuk/components/button/button.bundle.js.map +1 -1
  35. data/node_modules/govuk-frontend/dist/govuk/components/button/button.bundle.mjs +148 -111
  36. data/node_modules/govuk-frontend/dist/govuk/components/button/button.bundle.mjs.map +1 -1
  37. data/node_modules/govuk-frontend/dist/govuk/components/button/button.mjs +5 -8
  38. data/node_modules/govuk-frontend/dist/govuk/components/button/button.mjs.map +1 -1
  39. data/node_modules/govuk-frontend/dist/govuk/components/character-count/character-count.bundle.js +174 -140
  40. data/node_modules/govuk-frontend/dist/govuk/components/character-count/character-count.bundle.js.map +1 -1
  41. data/node_modules/govuk-frontend/dist/govuk/components/character-count/character-count.bundle.mjs +173 -139
  42. data/node_modules/govuk-frontend/dist/govuk/components/character-count/character-count.bundle.mjs.map +1 -1
  43. data/node_modules/govuk-frontend/dist/govuk/components/character-count/character-count.mjs +17 -16
  44. data/node_modules/govuk-frontend/dist/govuk/components/character-count/character-count.mjs.map +1 -1
  45. data/node_modules/govuk-frontend/dist/govuk/components/character-count/macro-options.json +4 -4
  46. data/node_modules/govuk-frontend/dist/govuk/components/checkboxes/checkboxes.bundle.js +1 -24
  47. data/node_modules/govuk-frontend/dist/govuk/components/checkboxes/checkboxes.bundle.js.map +1 -1
  48. data/node_modules/govuk-frontend/dist/govuk/components/checkboxes/checkboxes.bundle.mjs +0 -23
  49. data/node_modules/govuk-frontend/dist/govuk/components/checkboxes/checkboxes.bundle.mjs.map +1 -1
  50. data/node_modules/govuk-frontend/dist/govuk/components/date-input/macro-options.json +2 -2
  51. data/node_modules/govuk-frontend/dist/govuk/components/error-summary/error-summary.bundle.js +149 -112
  52. data/node_modules/govuk-frontend/dist/govuk/components/error-summary/error-summary.bundle.js.map +1 -1
  53. data/node_modules/govuk-frontend/dist/govuk/components/error-summary/error-summary.bundle.mjs +148 -111
  54. data/node_modules/govuk-frontend/dist/govuk/components/error-summary/error-summary.bundle.mjs.map +1 -1
  55. data/node_modules/govuk-frontend/dist/govuk/components/error-summary/error-summary.mjs +6 -8
  56. data/node_modules/govuk-frontend/dist/govuk/components/error-summary/error-summary.mjs.map +1 -1
  57. data/node_modules/govuk-frontend/dist/govuk/components/exit-this-page/exit-this-page.bundle.js +149 -112
  58. data/node_modules/govuk-frontend/dist/govuk/components/exit-this-page/exit-this-page.bundle.js.map +1 -1
  59. data/node_modules/govuk-frontend/dist/govuk/components/exit-this-page/exit-this-page.bundle.mjs +148 -111
  60. data/node_modules/govuk-frontend/dist/govuk/components/exit-this-page/exit-this-page.bundle.mjs.map +1 -1
  61. data/node_modules/govuk-frontend/dist/govuk/components/exit-this-page/exit-this-page.mjs +5 -8
  62. data/node_modules/govuk-frontend/dist/govuk/components/exit-this-page/exit-this-page.mjs.map +1 -1
  63. data/node_modules/govuk-frontend/dist/govuk/components/header/header.bundle.js +1 -24
  64. data/node_modules/govuk-frontend/dist/govuk/components/header/header.bundle.js.map +1 -1
  65. data/node_modules/govuk-frontend/dist/govuk/components/header/header.bundle.mjs +0 -23
  66. data/node_modules/govuk-frontend/dist/govuk/components/header/header.bundle.mjs.map +1 -1
  67. data/node_modules/govuk-frontend/dist/govuk/components/input/macro-options.json +4 -4
  68. data/node_modules/govuk-frontend/dist/govuk/components/notification-banner/notification-banner.bundle.js +149 -112
  69. data/node_modules/govuk-frontend/dist/govuk/components/notification-banner/notification-banner.bundle.js.map +1 -1
  70. data/node_modules/govuk-frontend/dist/govuk/components/notification-banner/notification-banner.bundle.mjs +148 -111
  71. data/node_modules/govuk-frontend/dist/govuk/components/notification-banner/notification-banner.bundle.mjs.map +1 -1
  72. data/node_modules/govuk-frontend/dist/govuk/components/notification-banner/notification-banner.mjs +6 -8
  73. data/node_modules/govuk-frontend/dist/govuk/components/notification-banner/notification-banner.mjs.map +1 -1
  74. data/node_modules/govuk-frontend/dist/govuk/components/password-input/macro-options.json +1 -1
  75. data/node_modules/govuk-frontend/dist/govuk/components/password-input/password-input.bundle.js +149 -112
  76. data/node_modules/govuk-frontend/dist/govuk/components/password-input/password-input.bundle.js.map +1 -1
  77. data/node_modules/govuk-frontend/dist/govuk/components/password-input/password-input.bundle.mjs +148 -111
  78. data/node_modules/govuk-frontend/dist/govuk/components/password-input/password-input.bundle.mjs.map +1 -1
  79. data/node_modules/govuk-frontend/dist/govuk/components/password-input/password-input.mjs +5 -8
  80. data/node_modules/govuk-frontend/dist/govuk/components/password-input/password-input.mjs.map +1 -1
  81. data/node_modules/govuk-frontend/dist/govuk/components/radios/radios.bundle.js +1 -24
  82. data/node_modules/govuk-frontend/dist/govuk/components/radios/radios.bundle.js.map +1 -1
  83. data/node_modules/govuk-frontend/dist/govuk/components/radios/radios.bundle.mjs +0 -23
  84. data/node_modules/govuk-frontend/dist/govuk/components/radios/radios.bundle.mjs.map +1 -1
  85. data/node_modules/govuk-frontend/dist/govuk/components/service-navigation/service-navigation.bundle.js +1 -24
  86. data/node_modules/govuk-frontend/dist/govuk/components/service-navigation/service-navigation.bundle.js.map +1 -1
  87. data/node_modules/govuk-frontend/dist/govuk/components/service-navigation/service-navigation.bundle.mjs +0 -23
  88. data/node_modules/govuk-frontend/dist/govuk/components/service-navigation/service-navigation.bundle.mjs.map +1 -1
  89. data/node_modules/govuk-frontend/dist/govuk/components/skip-link/skip-link.bundle.js +1 -24
  90. data/node_modules/govuk-frontend/dist/govuk/components/skip-link/skip-link.bundle.js.map +1 -1
  91. data/node_modules/govuk-frontend/dist/govuk/components/skip-link/skip-link.bundle.mjs +0 -23
  92. data/node_modules/govuk-frontend/dist/govuk/components/skip-link/skip-link.bundle.mjs.map +1 -1
  93. data/node_modules/govuk-frontend/dist/govuk/components/tabs/tabs.bundle.js +1 -24
  94. data/node_modules/govuk-frontend/dist/govuk/components/tabs/tabs.bundle.js.map +1 -1
  95. data/node_modules/govuk-frontend/dist/govuk/components/tabs/tabs.bundle.mjs +0 -23
  96. data/node_modules/govuk-frontend/dist/govuk/components/tabs/tabs.bundle.mjs.map +1 -1
  97. data/node_modules/govuk-frontend/dist/govuk/components/textarea/macro-options.json +1 -1
  98. data/node_modules/govuk-frontend/dist/govuk/core/_govuk-frontend-properties.scss +1 -1
  99. data/node_modules/govuk-frontend/dist/govuk/govuk-frontend.min.css +1 -1
  100. data/node_modules/govuk-frontend/dist/govuk/govuk-frontend.min.css.map +1 -1
  101. data/node_modules/govuk-frontend/dist/govuk/govuk-frontend.min.js +1 -1
  102. data/node_modules/govuk-frontend/dist/govuk/govuk-frontend.min.js.map +1 -1
  103. data/node_modules/govuk-frontend/dist/govuk/init.mjs +17 -13
  104. data/node_modules/govuk-frontend/dist/govuk/init.mjs.map +1 -1
  105. data/node_modules/govuk-frontend/dist/govuk/settings/_typography-responsive.scss +5 -10
  106. data/node_modules/govuk-frontend/dist/govuk/settings/_typography-responsive.scss.map +1 -1
  107. data/node_modules/govuk-frontend/govuk-prototype-kit.config.json +1 -1
  108. data/node_modules/govuk-frontend/package.json +9 -9
  109. metadata +4 -6
  110. data/node_modules/govuk-frontend/dist/govuk/common/normalise-dataset.mjs +0 -18
  111. data/node_modules/govuk-frontend/dist/govuk/common/normalise-dataset.mjs.map +0 -1
  112. data/node_modules/govuk-frontend/dist/govuk/common/normalise-string.mjs +0 -31
  113. data/node_modules/govuk-frontend/dist/govuk/common/normalise-string.mjs.map +0 -1
@@ -1,75 +1,5 @@
1
- const version = '5.7.1';
1
+ const version = '5.8.0';
2
2
 
3
- function normaliseString(value, property) {
4
- const trimmedValue = value ? value.trim() : '';
5
- let output;
6
- let outputType = property == null ? void 0 : property.type;
7
- if (!outputType) {
8
- if (['true', 'false'].includes(trimmedValue)) {
9
- outputType = 'boolean';
10
- }
11
- if (trimmedValue.length > 0 && isFinite(Number(trimmedValue))) {
12
- outputType = 'number';
13
- }
14
- }
15
- switch (outputType) {
16
- case 'boolean':
17
- output = trimmedValue === 'true';
18
- break;
19
- case 'number':
20
- output = Number(trimmedValue);
21
- break;
22
- default:
23
- output = value;
24
- }
25
- return output;
26
- }
27
-
28
- /**
29
- * @typedef {import('./index.mjs').SchemaProperty} SchemaProperty
30
- */
31
-
32
- function mergeConfigs(...configObjects) {
33
- const formattedConfigObject = {};
34
- for (const configObject of configObjects) {
35
- for (const key of Object.keys(configObject)) {
36
- const option = formattedConfigObject[key];
37
- const override = configObject[key];
38
- if (isObject(option) && isObject(override)) {
39
- formattedConfigObject[key] = mergeConfigs(option, override);
40
- } else {
41
- formattedConfigObject[key] = override;
42
- }
43
- }
44
- }
45
- return formattedConfigObject;
46
- }
47
- function extractConfigByNamespace(Component, dataset, namespace) {
48
- const property = Component.schema.properties[namespace];
49
- if ((property == null ? void 0 : property.type) !== 'object') {
50
- return;
51
- }
52
- const newObject = {
53
- [namespace]: ({})
54
- };
55
- for (const [key, value] of Object.entries(dataset)) {
56
- let current = newObject;
57
- const keyParts = key.split('.');
58
- for (const [index, name] of keyParts.entries()) {
59
- if (typeof current === 'object') {
60
- if (index < keyParts.length - 1) {
61
- if (!isObject(current[name])) {
62
- current[name] = {};
63
- }
64
- current = current[name];
65
- } else if (key !== namespace) {
66
- current[name] = normaliseString(value);
67
- }
68
- }
69
- }
70
- }
71
- return newObject[namespace];
72
- }
73
3
  function getFragmentFromUrl(url) {
74
4
  if (!url.includes('#')) {
75
5
  return undefined;
@@ -127,26 +57,6 @@ function isSupported($scope = document.body) {
127
57
  }
128
58
  return $scope.classList.contains('govuk-frontend-supported');
129
59
  }
130
- function validateConfig(schema, config) {
131
- const validationErrors = [];
132
- for (const [name, conditions] of Object.entries(schema)) {
133
- const errors = [];
134
- if (Array.isArray(conditions)) {
135
- for (const {
136
- required,
137
- errorMessage
138
- } of conditions) {
139
- if (!required.every(key => !!config[key])) {
140
- errors.push(errorMessage);
141
- }
142
- }
143
- if (name === 'anyOf' && !(conditions.length - errors.length >= 1)) {
144
- validationErrors.push(...errors);
145
- }
146
- }
147
- }
148
- return validationErrors;
149
- }
150
60
  function isArray(option) {
151
61
  return Array.isArray(option);
152
62
  }
@@ -156,47 +66,11 @@ function isObject(option) {
156
66
  function formatErrorMessage(Component, message) {
157
67
  return `${Component.moduleName}: ${message}`;
158
68
  }
159
-
160
- /**
161
- * Schema for component config
162
- *
163
- * @typedef {object} Schema
164
- * @property {{ [field: string]: SchemaProperty | undefined }} properties - Schema properties
165
- * @property {SchemaCondition[]} [anyOf] - List of schema conditions
166
- */
167
-
168
- /**
169
- * Schema property for component config
170
- *
171
- * @typedef {object} SchemaProperty
172
- * @property {'string' | 'boolean' | 'number' | 'object'} type - Property type
173
- */
174
-
175
- /**
176
- * Schema condition for component config
177
- *
178
- * @typedef {object} SchemaCondition
179
- * @property {string[]} required - List of required config fields
180
- * @property {string} errorMessage - Error message when required config fields not provided
181
- */
182
69
  /**
183
70
  * @typedef ComponentWithModuleName
184
71
  * @property {string} moduleName - Name of the component
185
72
  */
186
73
 
187
- function normaliseDataset(Component, dataset) {
188
- const out = {};
189
- for (const [field, property] of Object.entries(Component.schema.properties)) {
190
- if (field in dataset) {
191
- out[field] = normaliseString(dataset[field], property);
192
- }
193
- if ((property == null ? void 0 : property.type) === 'object') {
194
- out[field] = extractConfigByNamespace(Component, dataset, field);
195
- }
196
- }
197
- return out;
198
- }
199
-
200
74
  class GOVUKFrontendError extends Error {
201
75
  constructor(...args) {
202
76
  super(...args);
@@ -305,6 +179,164 @@ class GOVUKFrontendComponent {
305
179
  */
306
180
  GOVUKFrontendComponent.elementType = HTMLElement;
307
181
 
182
+ const configOverride = Symbol.for('configOverride');
183
+ class ConfigurableComponent extends GOVUKFrontendComponent {
184
+ [configOverride](param) {
185
+ return {};
186
+ }
187
+
188
+ /**
189
+ * Returns the root element of the component
190
+ *
191
+ * @protected
192
+ * @returns {ConfigurationType} - the root element of component
193
+ */
194
+ get config() {
195
+ return this._config;
196
+ }
197
+ constructor($root, config) {
198
+ super($root);
199
+ this._config = void 0;
200
+ const childConstructor = this.constructor;
201
+ if (typeof childConstructor.defaults === 'undefined') {
202
+ throw new ConfigError(formatErrorMessage(childConstructor, 'Config passed as parameter into constructor but no defaults defined'));
203
+ }
204
+ const datasetConfig = normaliseDataset(childConstructor, this._$root.dataset);
205
+ this._config = mergeConfigs(childConstructor.defaults, config != null ? config : {}, this[configOverride](datasetConfig), datasetConfig);
206
+ }
207
+ }
208
+ function normaliseString(value, property) {
209
+ const trimmedValue = value ? value.trim() : '';
210
+ let output;
211
+ let outputType = property == null ? void 0 : property.type;
212
+ if (!outputType) {
213
+ if (['true', 'false'].includes(trimmedValue)) {
214
+ outputType = 'boolean';
215
+ }
216
+ if (trimmedValue.length > 0 && isFinite(Number(trimmedValue))) {
217
+ outputType = 'number';
218
+ }
219
+ }
220
+ switch (outputType) {
221
+ case 'boolean':
222
+ output = trimmedValue === 'true';
223
+ break;
224
+ case 'number':
225
+ output = Number(trimmedValue);
226
+ break;
227
+ default:
228
+ output = value;
229
+ }
230
+ return output;
231
+ }
232
+ function normaliseDataset(Component, dataset) {
233
+ if (typeof Component.schema === 'undefined') {
234
+ throw new ConfigError(formatErrorMessage(Component, 'Config passed as parameter into constructor but no schema defined'));
235
+ }
236
+ const out = {};
237
+ for (const [field, property] of Object.entries(Component.schema.properties)) {
238
+ if (field in dataset) {
239
+ out[field] = normaliseString(dataset[field], property);
240
+ }
241
+ if ((property == null ? void 0 : property.type) === 'object') {
242
+ out[field] = extractConfigByNamespace(Component.schema, dataset, field);
243
+ }
244
+ }
245
+ return out;
246
+ }
247
+ function mergeConfigs(...configObjects) {
248
+ const formattedConfigObject = {};
249
+ for (const configObject of configObjects) {
250
+ for (const key of Object.keys(configObject)) {
251
+ const option = formattedConfigObject[key];
252
+ const override = configObject[key];
253
+ if (isObject(option) && isObject(override)) {
254
+ formattedConfigObject[key] = mergeConfigs(option, override);
255
+ } else {
256
+ formattedConfigObject[key] = override;
257
+ }
258
+ }
259
+ }
260
+ return formattedConfigObject;
261
+ }
262
+ function validateConfig(schema, config) {
263
+ const validationErrors = [];
264
+ for (const [name, conditions] of Object.entries(schema)) {
265
+ const errors = [];
266
+ if (Array.isArray(conditions)) {
267
+ for (const {
268
+ required,
269
+ errorMessage
270
+ } of conditions) {
271
+ if (!required.every(key => !!config[key])) {
272
+ errors.push(errorMessage);
273
+ }
274
+ }
275
+ if (name === 'anyOf' && !(conditions.length - errors.length >= 1)) {
276
+ validationErrors.push(...errors);
277
+ }
278
+ }
279
+ }
280
+ return validationErrors;
281
+ }
282
+ function extractConfigByNamespace(schema, dataset, namespace) {
283
+ const property = schema.properties[namespace];
284
+ if ((property == null ? void 0 : property.type) !== 'object') {
285
+ return;
286
+ }
287
+ const newObject = {
288
+ [namespace]: ({})
289
+ };
290
+ for (const [key, value] of Object.entries(dataset)) {
291
+ let current = newObject;
292
+ const keyParts = key.split('.');
293
+ for (const [index, name] of keyParts.entries()) {
294
+ if (typeof current === 'object') {
295
+ if (index < keyParts.length - 1) {
296
+ if (!isObject(current[name])) {
297
+ current[name] = {};
298
+ }
299
+ current = current[name];
300
+ } else if (key !== namespace) {
301
+ current[name] = normaliseString(value);
302
+ }
303
+ }
304
+ }
305
+ }
306
+ return newObject[namespace];
307
+ }
308
+ /**
309
+ * Schema for component config
310
+ *
311
+ * @typedef {object} Schema
312
+ * @property {{ [field: string]: SchemaProperty | undefined }} properties - Schema properties
313
+ * @property {SchemaCondition[]} [anyOf] - List of schema conditions
314
+ */
315
+ /**
316
+ * Schema property for component config
317
+ *
318
+ * @typedef {object} SchemaProperty
319
+ * @property {'string' | 'boolean' | 'number' | 'object'} type - Property type
320
+ */
321
+ /**
322
+ * Schema condition for component config
323
+ *
324
+ * @typedef {object} SchemaCondition
325
+ * @property {string[]} required - List of required config fields
326
+ * @property {string} errorMessage - Error message when required config fields not provided
327
+ */
328
+ /**
329
+ * @template {ObjectNested} [ConfigurationType={}]
330
+ * @typedef ChildClass
331
+ * @property {string} moduleName - The module name that'll be looked for in the DOM when initialising the component
332
+ * @property {Schema} [schema] - The schema of the component configuration
333
+ * @property {ConfigurationType} [defaults] - The default values of the configuration of the component
334
+ */
335
+ /**
336
+ * @template {ObjectNested} [ConfigurationType={}]
337
+ * @typedef {typeof GOVUKFrontendComponent & ChildClass<ConfigurationType>} ChildClassConstructor<ConfigurationType>
338
+ */
339
+
308
340
  class I18n {
309
341
  constructor(translations = {}, config = {}) {
310
342
  var _config$locale;
@@ -511,15 +543,15 @@ I18n.pluralRules = {
511
543
  * attribute, which also provides accessibility.
512
544
  *
513
545
  * @preserve
546
+ * @augments ConfigurableComponent<AccordionConfig>
514
547
  */
515
- class Accordion extends GOVUKFrontendComponent {
548
+ class Accordion extends ConfigurableComponent {
516
549
  /**
517
550
  * @param {Element | null} $root - HTML element to use for accordion
518
551
  * @param {AccordionConfig} [config] - Accordion config
519
552
  */
520
553
  constructor($root, config = {}) {
521
- super($root);
522
- this.config = void 0;
554
+ super($root, config);
523
555
  this.i18n = void 0;
524
556
  this.controlsClass = 'govuk-accordion__controls';
525
557
  this.showAllClass = 'govuk-accordion__show-all';
@@ -544,7 +576,6 @@ class Accordion extends GOVUKFrontendComponent {
544
576
  this.$showAllButton = null;
545
577
  this.$showAllIcon = null;
546
578
  this.$showAllText = null;
547
- this.config = mergeConfigs(Accordion.defaults, config, normaliseDataset(Accordion, this.$root.dataset));
548
579
  this.i18n = new I18n(this.config.i18n);
549
580
  const $sections = this.$root.querySelectorAll(`.${this.sectionClass}`);
550
581
  if (!$sections.length) {
@@ -814,7 +845,7 @@ class Accordion extends GOVUKFrontendComponent {
814
845
  */
815
846
 
816
847
  /**
817
- * @typedef {import('../../common/index.mjs').Schema} Schema
848
+ * @typedef {import('../../common/configuration.mjs').Schema} Schema
818
849
  */
819
850
  Accordion.moduleName = 'govuk-accordion';
820
851
  Accordion.defaults = Object.freeze({
@@ -845,17 +876,16 @@ const DEBOUNCE_TIMEOUT_IN_SECONDS = 1;
845
876
  * JavaScript enhancements for the Button component
846
877
  *
847
878
  * @preserve
879
+ * @augments ConfigurableComponent<ButtonConfig>
848
880
  */
849
- class Button extends GOVUKFrontendComponent {
881
+ class Button extends ConfigurableComponent {
850
882
  /**
851
883
  * @param {Element | null} $root - HTML element to use for button
852
884
  * @param {ButtonConfig} [config] - Button config
853
885
  */
854
886
  constructor($root, config = {}) {
855
- super($root);
856
- this.config = void 0;
887
+ super($root, config);
857
888
  this.debounceFormSubmitTimer = null;
858
- this.config = mergeConfigs(Button.defaults, config, normaliseDataset(Button, this.$root.dataset));
859
889
  this.$root.addEventListener('keydown', event => this.handleKeyDown(event));
860
890
  this.$root.addEventListener('click', event => this.debounce(event));
861
891
  }
@@ -892,7 +922,7 @@ class Button extends GOVUKFrontendComponent {
892
922
  */
893
923
 
894
924
  /**
895
- * @typedef {import('../../common/index.mjs').Schema} Schema
925
+ * @typedef {import('../../common/configuration.mjs').Schema} Schema
896
926
  */
897
927
  Button.moduleName = 'govuk-button';
898
928
  Button.defaults = Object.freeze({
@@ -922,22 +952,33 @@ function closestAttributeValue($element, attributeName) {
922
952
  * of the available characters/words has been entered.
923
953
  *
924
954
  * @preserve
955
+ * @augments ConfigurableComponent<CharacterCountConfig>
925
956
  */
926
- class CharacterCount extends GOVUKFrontendComponent {
957
+ class CharacterCount extends ConfigurableComponent {
958
+ [configOverride](datasetConfig) {
959
+ let configOverrides = {};
960
+ if ('maxwords' in datasetConfig || 'maxlength' in datasetConfig) {
961
+ configOverrides = {
962
+ maxlength: undefined,
963
+ maxwords: undefined
964
+ };
965
+ }
966
+ return configOverrides;
967
+ }
968
+
927
969
  /**
928
970
  * @param {Element | null} $root - HTML element to use for character count
929
971
  * @param {CharacterCountConfig} [config] - Character count config
930
972
  */
931
973
  constructor($root, config = {}) {
932
974
  var _ref, _this$config$maxwords;
933
- super($root);
975
+ super($root, config);
934
976
  this.$textarea = void 0;
935
977
  this.$visibleCountMessage = void 0;
936
978
  this.$screenReaderCountMessage = void 0;
937
979
  this.lastInputTimestamp = null;
938
980
  this.lastInputValue = '';
939
981
  this.valueChecker = null;
940
- this.config = void 0;
941
982
  this.i18n = void 0;
942
983
  this.maxLength = void 0;
943
984
  const $textarea = this.$root.querySelector('.govuk-js-character-count');
@@ -949,15 +990,6 @@ class CharacterCount extends GOVUKFrontendComponent {
949
990
  identifier: 'Form field (`.govuk-js-character-count`)'
950
991
  });
951
992
  }
952
- const datasetConfig = normaliseDataset(CharacterCount, this.$root.dataset);
953
- let configOverrides = {};
954
- if ('maxwords' in datasetConfig || 'maxlength' in datasetConfig) {
955
- configOverrides = {
956
- maxlength: undefined,
957
- maxwords: undefined
958
- };
959
- }
960
- this.config = mergeConfigs(CharacterCount.defaults, config, configOverrides, datasetConfig);
961
993
  const errors = validateConfig(CharacterCount.schema, this.config);
962
994
  if (errors[0]) {
963
995
  throw new ConfigError(formatErrorMessage(CharacterCount, errors[0]));
@@ -1143,7 +1175,7 @@ class CharacterCount extends GOVUKFrontendComponent {
1143
1175
  */
1144
1176
 
1145
1177
  /**
1146
- * @typedef {import('../../common/index.mjs').Schema} Schema
1178
+ * @typedef {import('../../common/configuration.mjs').Schema} Schema
1147
1179
  * @typedef {import('../../i18n.mjs').TranslationPluralForms} TranslationPluralForms
1148
1180
  */
1149
1181
  CharacterCount.moduleName = 'govuk-character-count';
@@ -1310,16 +1342,15 @@ Checkboxes.moduleName = 'govuk-checkboxes';
1310
1342
  * configuration.
1311
1343
  *
1312
1344
  * @preserve
1345
+ * @augments ConfigurableComponent<ErrorSummaryConfig>
1313
1346
  */
1314
- class ErrorSummary extends GOVUKFrontendComponent {
1347
+ class ErrorSummary extends ConfigurableComponent {
1315
1348
  /**
1316
1349
  * @param {Element | null} $root - HTML element to use for error summary
1317
1350
  * @param {ErrorSummaryConfig} [config] - Error summary config
1318
1351
  */
1319
1352
  constructor($root, config = {}) {
1320
- super($root);
1321
- this.config = void 0;
1322
- this.config = mergeConfigs(ErrorSummary.defaults, config, normaliseDataset(ErrorSummary, this.$root.dataset));
1353
+ super($root, config);
1323
1354
  if (!this.config.disableAutoFocus) {
1324
1355
  setFocus(this.$root);
1325
1356
  }
@@ -1386,7 +1417,7 @@ class ErrorSummary extends GOVUKFrontendComponent {
1386
1417
  */
1387
1418
 
1388
1419
  /**
1389
- * @typedef {import('../../common/index.mjs').Schema} Schema
1420
+ * @typedef {import('../../common/configuration.mjs').Schema} Schema
1390
1421
  */
1391
1422
  ErrorSummary.moduleName = 'govuk-error-summary';
1392
1423
  ErrorSummary.defaults = Object.freeze({
@@ -1404,15 +1435,15 @@ ErrorSummary.schema = Object.freeze({
1404
1435
  * Exit this page component
1405
1436
  *
1406
1437
  * @preserve
1438
+ * @augments ConfigurableComponent<ExitThisPageConfig>
1407
1439
  */
1408
- class ExitThisPage extends GOVUKFrontendComponent {
1440
+ class ExitThisPage extends ConfigurableComponent {
1409
1441
  /**
1410
1442
  * @param {Element | null} $root - HTML element that wraps the Exit This Page button
1411
1443
  * @param {ExitThisPageConfig} [config] - Exit This Page config
1412
1444
  */
1413
1445
  constructor($root, config = {}) {
1414
- super($root);
1415
- this.config = void 0;
1446
+ super($root, config);
1416
1447
  this.i18n = void 0;
1417
1448
  this.$button = void 0;
1418
1449
  this.$skiplinkButton = null;
@@ -1433,7 +1464,6 @@ class ExitThisPage extends GOVUKFrontendComponent {
1433
1464
  identifier: 'Button (`.govuk-exit-this-page__button`)'
1434
1465
  });
1435
1466
  }
1436
- this.config = mergeConfigs(ExitThisPage.defaults, config, normaliseDataset(ExitThisPage, this.$root.dataset));
1437
1467
  this.i18n = new I18n(this.config.i18n);
1438
1468
  this.$button = $button;
1439
1469
  const $skiplinkButton = document.querySelector('.govuk-js-exit-this-page-skiplink');
@@ -1599,7 +1629,7 @@ class ExitThisPage extends GOVUKFrontendComponent {
1599
1629
  */
1600
1630
 
1601
1631
  /**
1602
- * @typedef {import('../../common/index.mjs').Schema} Schema
1632
+ * @typedef {import('../../common/configuration.mjs').Schema} Schema
1603
1633
  */
1604
1634
  ExitThisPage.moduleName = 'govuk-exit-this-page';
1605
1635
  ExitThisPage.defaults = Object.freeze({
@@ -1704,16 +1734,15 @@ Header.moduleName = 'govuk-header';
1704
1734
  * Notification Banner component
1705
1735
  *
1706
1736
  * @preserve
1737
+ * @augments ConfigurableComponent<NotificationBannerConfig>
1707
1738
  */
1708
- class NotificationBanner extends GOVUKFrontendComponent {
1739
+ class NotificationBanner extends ConfigurableComponent {
1709
1740
  /**
1710
1741
  * @param {Element | null} $root - HTML element to use for notification banner
1711
1742
  * @param {NotificationBannerConfig} [config] - Notification banner config
1712
1743
  */
1713
1744
  constructor($root, config = {}) {
1714
- super($root);
1715
- this.config = void 0;
1716
- this.config = mergeConfigs(NotificationBanner.defaults, config, normaliseDataset(NotificationBanner, this.$root.dataset));
1745
+ super($root, config);
1717
1746
  if (this.$root.getAttribute('role') === 'alert' && !this.config.disableAutoFocus) {
1718
1747
  setFocus(this.$root);
1719
1748
  }
@@ -1731,7 +1760,7 @@ class NotificationBanner extends GOVUKFrontendComponent {
1731
1760
  */
1732
1761
 
1733
1762
  /**
1734
- * @typedef {import('../../common/index.mjs').Schema} Schema
1763
+ * @typedef {import('../../common/configuration.mjs').Schema} Schema
1735
1764
  */
1736
1765
  NotificationBanner.moduleName = 'govuk-notification-banner';
1737
1766
  NotificationBanner.defaults = Object.freeze({
@@ -1749,15 +1778,15 @@ NotificationBanner.schema = Object.freeze({
1749
1778
  * Password input component
1750
1779
  *
1751
1780
  * @preserve
1781
+ * @augments ConfigurableComponent<PasswordInputConfig>
1752
1782
  */
1753
- class PasswordInput extends GOVUKFrontendComponent {
1783
+ class PasswordInput extends ConfigurableComponent {
1754
1784
  /**
1755
1785
  * @param {Element | null} $root - HTML element to use for password input
1756
1786
  * @param {PasswordInputConfig} [config] - Password input config
1757
1787
  */
1758
1788
  constructor($root, config = {}) {
1759
- super($root);
1760
- this.config = void 0;
1789
+ super($root, config);
1761
1790
  this.i18n = void 0;
1762
1791
  this.$input = void 0;
1763
1792
  this.$showHideButton = void 0;
@@ -1788,7 +1817,6 @@ class PasswordInput extends GOVUKFrontendComponent {
1788
1817
  }
1789
1818
  this.$input = $input;
1790
1819
  this.$showHideButton = $showHideButton;
1791
- this.config = mergeConfigs(PasswordInput.defaults, config, normaliseDataset(PasswordInput, this.$root.dataset));
1792
1820
  this.i18n = new I18n(this.config.i18n, {
1793
1821
  locale: closestAttributeValue(this.$root, 'lang')
1794
1822
  });
@@ -1868,7 +1896,7 @@ class PasswordInput extends GOVUKFrontendComponent {
1868
1896
  */
1869
1897
 
1870
1898
  /**
1871
- * @typedef {import('../../common/index.mjs').Schema} Schema
1899
+ * @typedef {import('../../common/configuration.mjs').Schema} Schema
1872
1900
  * @typedef {import('../../i18n.mjs').TranslationPluralForms} TranslationPluralForms
1873
1901
  */
1874
1902
  PasswordInput.moduleName = 'govuk-password-input';
@@ -2421,11 +2449,11 @@ function initAll(config) {
2421
2449
  *
2422
2450
  * Any component errors will be caught and logged to the console.
2423
2451
  *
2424
- * @template {CompatibleClass} T
2425
- * @param {T} Component - class of the component to create
2426
- * @param {T["defaults"]} [config] - Config supplied to component
2427
- * @param {OnErrorCallback<T> | Element | Document | CreateAllOptions<T> } [createAllOptions] - options for createAll including scope of the document to search within and callback function if error throw by component on init
2428
- * @returns {Array<InstanceType<T>>} - array of instantiated components
2452
+ * @template {CompatibleClass} ComponentClass
2453
+ * @param {ComponentClass} Component - class of the component to create
2454
+ * @param {ComponentConfig<ComponentClass>} [config] - Config supplied to component
2455
+ * @param {OnErrorCallback<ComponentClass> | Element | Document | CreateAllOptions<ComponentClass> } [createAllOptions] - options for createAll including scope of the document to search within and callback function if error throw by component on init
2456
+ * @returns {Array<InstanceType<ComponentClass>>} - array of instantiated components
2429
2457
  */
2430
2458
  function createAll(Component, config, createAllOptions) {
2431
2459
  let $scope = document;
@@ -2472,7 +2500,7 @@ function createAll(Component, config, createAllOptions) {
2472
2500
  }).filter(Boolean);
2473
2501
  }
2474
2502
  /**
2475
- * @typedef {{new (...args: any[]): any, defaults?: object, moduleName: string}} CompatibleClass
2503
+ * @typedef {{new (...args: any[]): any, moduleName: string}} CompatibleClass
2476
2504
  */
2477
2505
  /**
2478
2506
  * Config for all components via `initAll()`
@@ -2506,24 +2534,28 @@ function createAll(Component, config, createAllOptions) {
2506
2534
  * @typedef {keyof Config} ConfigKey
2507
2535
  */
2508
2536
  /**
2509
- * @template {CompatibleClass} T
2537
+ * @template {CompatibleClass} ComponentClass
2538
+ * @typedef {ConstructorParameters<ComponentClass>[1]} ComponentConfig
2539
+ */
2540
+ /**
2541
+ * @template {CompatibleClass} ComponentClass
2510
2542
  * @typedef {object} ErrorContext
2511
2543
  * @property {Element} [element] - Element used for component module initialisation
2512
- * @property {T} [component] - Class of component
2513
- * @property {T["defaults"]} config - Config supplied to component
2544
+ * @property {ComponentClass} [component] - Class of component
2545
+ * @property {ComponentConfig<ComponentClass>} config - Config supplied to component
2514
2546
  */
2515
2547
  /**
2516
- * @template {CompatibleClass} T
2548
+ * @template {CompatibleClass} ComponentClass
2517
2549
  * @callback OnErrorCallback
2518
2550
  * @param {unknown} error - Thrown error
2519
- * @param {ErrorContext<T>} context - Object containing the element, component class and configuration
2551
+ * @param {ErrorContext<ComponentClass>} context - Object containing the element, component class and configuration
2520
2552
  */
2521
2553
  /**
2522
- * @template {CompatibleClass} T
2554
+ * @template {CompatibleClass} ComponentClass
2523
2555
  * @typedef {object} CreateAllOptions
2524
2556
  * @property {Element | Document} [scope] - scope of the document to search within
2525
- * @property {OnErrorCallback<T>} [onError] - callback function if error throw by component on init
2557
+ * @property {OnErrorCallback<ComponentClass>} [onError] - callback function if error throw by component on init
2526
2558
  */
2527
2559
 
2528
- export { Accordion, Button, CharacterCount, Checkboxes, GOVUKFrontendComponent as Component, ErrorSummary, ExitThisPage, Header, NotificationBanner, PasswordInput, Radios, ServiceNavigation, SkipLink, Tabs, createAll, initAll, isSupported, version };
2560
+ export { Accordion, Button, CharacterCount, Checkboxes, GOVUKFrontendComponent as Component, ConfigurableComponent, ErrorSummary, ExitThisPage, Header, NotificationBanner, PasswordInput, Radios, ServiceNavigation, SkipLink, Tabs, createAll, initAll, isSupported, version };
2529
2561
  //# sourceMappingURL=all.bundle.mjs.map