govuk_tech_docs 4.1.2 → 4.3.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 (74) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +18 -0
  3. data/govuk_tech_docs.gemspec +1 -1
  4. data/lib/assets/stylesheets/_govuk_tech_docs.scss +3 -0
  5. data/lib/govuk_tech_docs/meta_tags.rb +5 -1
  6. data/lib/govuk_tech_docs/version.rb +1 -1
  7. data/lib/source/layouts/core.erb +21 -5
  8. data/node_modules/govuk-frontend/dist/govuk/all.bundle.js +508 -209
  9. data/node_modules/govuk-frontend/dist/govuk/all.bundle.mjs +505 -208
  10. data/node_modules/govuk-frontend/dist/govuk/all.mjs +3 -1
  11. data/node_modules/govuk-frontend/dist/govuk/all.scss +6 -0
  12. data/node_modules/govuk-frontend/dist/govuk/common/configuration.mjs +169 -0
  13. data/node_modules/govuk-frontend/dist/govuk/common/govuk-frontend-version.mjs +1 -1
  14. data/node_modules/govuk-frontend/dist/govuk/common/index.mjs +4 -87
  15. data/node_modules/govuk-frontend/dist/govuk/{govuk-frontend-component.mjs → component.mjs} +5 -5
  16. data/node_modules/govuk-frontend/dist/govuk/components/accordion/accordion.bundle.js +161 -116
  17. data/node_modules/govuk-frontend/dist/govuk/components/accordion/accordion.bundle.mjs +160 -115
  18. data/node_modules/govuk-frontend/dist/govuk/components/accordion/accordion.mjs +5 -8
  19. data/node_modules/govuk-frontend/dist/govuk/components/button/button.bundle.js +161 -116
  20. data/node_modules/govuk-frontend/dist/govuk/components/button/button.bundle.mjs +160 -115
  21. data/node_modules/govuk-frontend/dist/govuk/components/button/button.mjs +5 -8
  22. data/node_modules/govuk-frontend/dist/govuk/components/character-count/_index.scss +8 -0
  23. data/node_modules/govuk-frontend/dist/govuk/components/character-count/character-count.bundle.js +187 -145
  24. data/node_modules/govuk-frontend/dist/govuk/components/character-count/character-count.bundle.mjs +186 -144
  25. data/node_modules/govuk-frontend/dist/govuk/components/character-count/character-count.mjs +18 -17
  26. data/node_modules/govuk-frontend/dist/govuk/components/checkboxes/checkboxes.bundle.js +9 -29
  27. data/node_modules/govuk-frontend/dist/govuk/components/checkboxes/checkboxes.bundle.mjs +8 -28
  28. data/node_modules/govuk-frontend/dist/govuk/components/checkboxes/checkboxes.mjs +2 -2
  29. data/node_modules/govuk-frontend/dist/govuk/components/error-summary/error-summary.bundle.js +161 -116
  30. data/node_modules/govuk-frontend/dist/govuk/components/error-summary/error-summary.bundle.mjs +160 -115
  31. data/node_modules/govuk-frontend/dist/govuk/components/error-summary/error-summary.mjs +6 -8
  32. data/node_modules/govuk-frontend/dist/govuk/components/exit-this-page/exit-this-page.bundle.js +161 -116
  33. data/node_modules/govuk-frontend/dist/govuk/components/exit-this-page/exit-this-page.bundle.mjs +160 -115
  34. data/node_modules/govuk-frontend/dist/govuk/components/exit-this-page/exit-this-page.mjs +5 -8
  35. data/node_modules/govuk-frontend/dist/govuk/components/file-upload/_index.scss +167 -0
  36. data/node_modules/govuk-frontend/dist/govuk/components/file-upload/file-upload.bundle.js +754 -0
  37. data/node_modules/govuk-frontend/dist/govuk/components/file-upload/file-upload.bundle.mjs +746 -0
  38. data/node_modules/govuk-frontend/dist/govuk/components/file-upload/file-upload.mjs +267 -0
  39. data/node_modules/govuk-frontend/dist/govuk/components/header/_index.scss +14 -10
  40. data/node_modules/govuk-frontend/dist/govuk/components/header/header.bundle.js +9 -29
  41. data/node_modules/govuk-frontend/dist/govuk/components/header/header.bundle.mjs +8 -28
  42. data/node_modules/govuk-frontend/dist/govuk/components/header/header.mjs +2 -2
  43. data/node_modules/govuk-frontend/dist/govuk/components/notification-banner/notification-banner.bundle.js +161 -116
  44. data/node_modules/govuk-frontend/dist/govuk/components/notification-banner/notification-banner.bundle.mjs +160 -115
  45. data/node_modules/govuk-frontend/dist/govuk/components/notification-banner/notification-banner.mjs +6 -8
  46. data/node_modules/govuk-frontend/dist/govuk/components/password-input/password-input.bundle.js +161 -117
  47. data/node_modules/govuk-frontend/dist/govuk/components/password-input/password-input.bundle.mjs +160 -116
  48. data/node_modules/govuk-frontend/dist/govuk/components/password-input/password-input.mjs +5 -9
  49. data/node_modules/govuk-frontend/dist/govuk/components/radios/radios.bundle.js +9 -29
  50. data/node_modules/govuk-frontend/dist/govuk/components/radios/radios.bundle.mjs +8 -28
  51. data/node_modules/govuk-frontend/dist/govuk/components/radios/radios.mjs +2 -2
  52. data/node_modules/govuk-frontend/dist/govuk/components/service-navigation/service-navigation.bundle.js +9 -29
  53. data/node_modules/govuk-frontend/dist/govuk/components/service-navigation/service-navigation.bundle.mjs +8 -28
  54. data/node_modules/govuk-frontend/dist/govuk/components/service-navigation/service-navigation.mjs +2 -2
  55. data/node_modules/govuk-frontend/dist/govuk/components/skip-link/skip-link.bundle.js +10 -30
  56. data/node_modules/govuk-frontend/dist/govuk/components/skip-link/skip-link.bundle.mjs +9 -29
  57. data/node_modules/govuk-frontend/dist/govuk/components/skip-link/skip-link.mjs +3 -3
  58. data/node_modules/govuk-frontend/dist/govuk/components/summary-list/_index.scss +12 -21
  59. data/node_modules/govuk-frontend/dist/govuk/components/tabs/tabs.bundle.js +9 -29
  60. data/node_modules/govuk-frontend/dist/govuk/components/tabs/tabs.bundle.mjs +8 -28
  61. data/node_modules/govuk-frontend/dist/govuk/components/tabs/tabs.mjs +2 -2
  62. data/node_modules/govuk-frontend/dist/govuk/core/_govuk-frontend-properties.scss +1 -1
  63. data/node_modules/govuk-frontend/dist/govuk/errors/index.mjs +1 -1
  64. data/node_modules/govuk-frontend/dist/govuk/govuk-frontend.min.js +1 -1
  65. data/node_modules/govuk-frontend/dist/govuk/helpers/_colour.scss +2 -2
  66. data/node_modules/govuk-frontend/dist/govuk/init.mjs +28 -24
  67. data/node_modules/govuk-frontend/dist/govuk/settings/_colours-organisations.scss +18 -5
  68. data/node_modules/govuk-frontend/dist/govuk/settings/_typography-responsive.scss +5 -10
  69. data/node_modules/govuk-frontend/dist/govuk-prototype-kit/init.scss +1 -1
  70. data/package-lock.json +8 -7
  71. data/package.json +1 -1
  72. metadata +12 -10
  73. data/node_modules/govuk-frontend/dist/govuk/common/normalise-dataset.mjs +0 -18
  74. data/node_modules/govuk-frontend/dist/govuk/common/normalise-string.mjs +0 -31
@@ -1,73 +1,3 @@
1
- function normaliseString(value, property) {
2
- const trimmedValue = value ? value.trim() : '';
3
- let output;
4
- let outputType = property == null ? void 0 : property.type;
5
- if (!outputType) {
6
- if (['true', 'false'].includes(trimmedValue)) {
7
- outputType = 'boolean';
8
- }
9
- if (trimmedValue.length > 0 && isFinite(Number(trimmedValue))) {
10
- outputType = 'number';
11
- }
12
- }
13
- switch (outputType) {
14
- case 'boolean':
15
- output = trimmedValue === 'true';
16
- break;
17
- case 'number':
18
- output = Number(trimmedValue);
19
- break;
20
- default:
21
- output = value;
22
- }
23
- return output;
24
- }
25
-
26
- /**
27
- * @typedef {import('./index.mjs').SchemaProperty} SchemaProperty
28
- */
29
-
30
- function mergeConfigs(...configObjects) {
31
- const formattedConfigObject = {};
32
- for (const configObject of configObjects) {
33
- for (const key of Object.keys(configObject)) {
34
- const option = formattedConfigObject[key];
35
- const override = configObject[key];
36
- if (isObject(option) && isObject(override)) {
37
- formattedConfigObject[key] = mergeConfigs(option, override);
38
- } else {
39
- formattedConfigObject[key] = override;
40
- }
41
- }
42
- }
43
- return formattedConfigObject;
44
- }
45
- function extractConfigByNamespace(Component, dataset, namespace) {
46
- const property = Component.schema.properties[namespace];
47
- if ((property == null ? void 0 : property.type) !== 'object') {
48
- return;
49
- }
50
- const newObject = {
51
- [namespace]: ({})
52
- };
53
- for (const [key, value] of Object.entries(dataset)) {
54
- let current = newObject;
55
- const keyParts = key.split('.');
56
- for (const [index, name] of keyParts.entries()) {
57
- if (typeof current === 'object') {
58
- if (index < keyParts.length - 1) {
59
- if (!isObject(current[name])) {
60
- current[name] = {};
61
- }
62
- current = current[name];
63
- } else if (key !== namespace) {
64
- current[name] = normaliseString(value);
65
- }
66
- }
67
- }
68
- }
69
- return newObject[namespace];
70
- }
71
1
  function isInitialised($root, moduleName) {
72
2
  return $root instanceof HTMLElement && $root.hasAttribute(`data-${moduleName}-init`);
73
3
  }
@@ -96,46 +26,13 @@ function isObject(option) {
96
26
  function formatErrorMessage(Component, message) {
97
27
  return `${Component.moduleName}: ${message}`;
98
28
  }
99
-
100
- /**
101
- * Schema for component config
102
- *
103
- * @typedef {object} Schema
104
- * @property {{ [field: string]: SchemaProperty | undefined }} properties - Schema properties
105
- * @property {SchemaCondition[]} [anyOf] - List of schema conditions
106
- */
107
-
108
- /**
109
- * Schema property for component config
110
- *
111
- * @typedef {object} SchemaProperty
112
- * @property {'string' | 'boolean' | 'number' | 'object'} type - Property type
113
- */
114
-
115
- /**
116
- * Schema condition for component config
117
- *
118
- * @typedef {object} SchemaCondition
119
- * @property {string[]} required - List of required config fields
120
- * @property {string} errorMessage - Error message when required config fields not provided
121
- */
122
29
  /**
123
30
  * @typedef ComponentWithModuleName
124
31
  * @property {string} moduleName - Name of the component
125
32
  */
126
-
127
- function normaliseDataset(Component, dataset) {
128
- const out = {};
129
- for (const [field, property] of Object.entries(Component.schema.properties)) {
130
- if (field in dataset) {
131
- out[field] = normaliseString(dataset[field], property);
132
- }
133
- if ((property == null ? void 0 : property.type) === 'object') {
134
- out[field] = extractConfigByNamespace(Component, dataset, field);
135
- }
136
- }
137
- return out;
138
- }
33
+ /**
34
+ * @import { ObjectNested } from './configuration.mjs'
35
+ */
139
36
 
140
37
  class GOVUKFrontendError extends Error {
141
38
  constructor(...args) {
@@ -155,6 +52,12 @@ class SupportError extends GOVUKFrontendError {
155
52
  this.name = 'SupportError';
156
53
  }
157
54
  }
55
+ class ConfigError extends GOVUKFrontendError {
56
+ constructor(...args) {
57
+ super(...args);
58
+ this.name = 'ConfigError';
59
+ }
60
+ }
158
61
  class ElementError extends GOVUKFrontendError {
159
62
  constructor(messageOrOptions) {
160
63
  let message = typeof messageOrOptions === 'string' ? messageOrOptions : '';
@@ -181,10 +84,10 @@ class InitError extends GOVUKFrontendError {
181
84
  }
182
85
  }
183
86
  /**
184
- * @typedef {import('../common/index.mjs').ComponentWithModuleName} ComponentWithModuleName
87
+ * @import { ComponentWithModuleName } from '../common/index.mjs'
185
88
  */
186
89
 
187
- class GOVUKFrontendComponent {
90
+ class Component {
188
91
  /**
189
92
  * Returns the root element of the component
190
93
  *
@@ -235,9 +138,152 @@ class GOVUKFrontendComponent {
235
138
  */
236
139
 
237
140
  /**
238
- * @typedef {typeof GOVUKFrontendComponent & ChildClass} ChildClassConstructor
141
+ * @typedef {typeof Component & ChildClass} ChildClassConstructor
142
+ */
143
+ Component.elementType = HTMLElement;
144
+
145
+ const configOverride = Symbol.for('configOverride');
146
+ class ConfigurableComponent extends Component {
147
+ [configOverride](param) {
148
+ return {};
149
+ }
150
+
151
+ /**
152
+ * Returns the root element of the component
153
+ *
154
+ * @protected
155
+ * @returns {ConfigurationType} - the root element of component
156
+ */
157
+ get config() {
158
+ return this._config;
159
+ }
160
+ constructor($root, config) {
161
+ super($root);
162
+ this._config = void 0;
163
+ const childConstructor = this.constructor;
164
+ if (!isObject(childConstructor.defaults)) {
165
+ throw new ConfigError(formatErrorMessage(childConstructor, 'Config passed as parameter into constructor but no defaults defined'));
166
+ }
167
+ const datasetConfig = normaliseDataset(childConstructor, this._$root.dataset);
168
+ this._config = mergeConfigs(childConstructor.defaults, config != null ? config : {}, this[configOverride](datasetConfig), datasetConfig);
169
+ }
170
+ }
171
+ function normaliseString(value, property) {
172
+ const trimmedValue = value ? value.trim() : '';
173
+ let output;
174
+ let outputType = property == null ? void 0 : property.type;
175
+ if (!outputType) {
176
+ if (['true', 'false'].includes(trimmedValue)) {
177
+ outputType = 'boolean';
178
+ }
179
+ if (trimmedValue.length > 0 && isFinite(Number(trimmedValue))) {
180
+ outputType = 'number';
181
+ }
182
+ }
183
+ switch (outputType) {
184
+ case 'boolean':
185
+ output = trimmedValue === 'true';
186
+ break;
187
+ case 'number':
188
+ output = Number(trimmedValue);
189
+ break;
190
+ default:
191
+ output = value;
192
+ }
193
+ return output;
194
+ }
195
+ function normaliseDataset(Component, dataset) {
196
+ if (!isObject(Component.schema)) {
197
+ throw new ConfigError(formatErrorMessage(Component, 'Config passed as parameter into constructor but no schema defined'));
198
+ }
199
+ const out = {};
200
+ const entries = Object.entries(Component.schema.properties);
201
+ for (const entry of entries) {
202
+ const [namespace, property] = entry;
203
+ const field = namespace.toString();
204
+ if (field in dataset) {
205
+ out[field] = normaliseString(dataset[field], property);
206
+ }
207
+ if ((property == null ? void 0 : property.type) === 'object') {
208
+ out[field] = extractConfigByNamespace(Component.schema, dataset, namespace);
209
+ }
210
+ }
211
+ return out;
212
+ }
213
+ function mergeConfigs(...configObjects) {
214
+ const formattedConfigObject = {};
215
+ for (const configObject of configObjects) {
216
+ for (const key of Object.keys(configObject)) {
217
+ const option = formattedConfigObject[key];
218
+ const override = configObject[key];
219
+ if (isObject(option) && isObject(override)) {
220
+ formattedConfigObject[key] = mergeConfigs(option, override);
221
+ } else {
222
+ formattedConfigObject[key] = override;
223
+ }
224
+ }
225
+ }
226
+ return formattedConfigObject;
227
+ }
228
+ function extractConfigByNamespace(schema, dataset, namespace) {
229
+ const property = schema.properties[namespace];
230
+ if ((property == null ? void 0 : property.type) !== 'object') {
231
+ return;
232
+ }
233
+ const newObject = {
234
+ [namespace]: {}
235
+ };
236
+ for (const [key, value] of Object.entries(dataset)) {
237
+ let current = newObject;
238
+ const keyParts = key.split('.');
239
+ for (const [index, name] of keyParts.entries()) {
240
+ if (isObject(current)) {
241
+ if (index < keyParts.length - 1) {
242
+ if (!isObject(current[name])) {
243
+ current[name] = {};
244
+ }
245
+ current = current[name];
246
+ } else if (key !== namespace) {
247
+ current[name] = normaliseString(value);
248
+ }
249
+ }
250
+ }
251
+ }
252
+ return newObject[namespace];
253
+ }
254
+ /**
255
+ * Schema for component config
256
+ *
257
+ * @template {Partial<Record<keyof ConfigurationType, unknown>>} ConfigurationType
258
+ * @typedef {object} Schema
259
+ * @property {Record<keyof ConfigurationType, SchemaProperty | undefined>} properties - Schema properties
260
+ * @property {SchemaCondition<ConfigurationType>[]} [anyOf] - List of schema conditions
261
+ */
262
+ /**
263
+ * Schema property for component config
264
+ *
265
+ * @typedef {object} SchemaProperty
266
+ * @property {'string' | 'boolean' | 'number' | 'object'} type - Property type
267
+ */
268
+ /**
269
+ * Schema condition for component config
270
+ *
271
+ * @template {Partial<Record<keyof ConfigurationType, unknown>>} ConfigurationType
272
+ * @typedef {object} SchemaCondition
273
+ * @property {(keyof ConfigurationType)[]} required - List of required config fields
274
+ * @property {string} errorMessage - Error message when required config fields not provided
275
+ */
276
+ /**
277
+ * @template {Partial<Record<keyof ConfigurationType, unknown>>} [ConfigurationType=ObjectNested]
278
+ * @typedef ChildClass
279
+ * @property {string} moduleName - The module name that'll be looked for in the DOM when initialising the component
280
+ * @property {Schema<ConfigurationType>} [schema] - The schema of the component configuration
281
+ * @property {ConfigurationType} [defaults] - The default values of the configuration of the component
282
+ */
283
+ /**
284
+ * @template {Partial<Record<keyof ConfigurationType, unknown>>} [ConfigurationType=ObjectNested]
285
+ * @typedef {typeof Component & ChildClass<ConfigurationType>} ChildClassConstructor<ConfigurationType>
239
286
  */
240
- GOVUKFrontendComponent.elementType = HTMLElement;
241
287
 
242
288
  class I18n {
243
289
  constructor(translations = {}, config = {}) {
@@ -445,15 +491,15 @@ I18n.pluralRules = {
445
491
  * attribute, which also provides accessibility.
446
492
  *
447
493
  * @preserve
494
+ * @augments ConfigurableComponent<AccordionConfig>
448
495
  */
449
- class Accordion extends GOVUKFrontendComponent {
496
+ class Accordion extends ConfigurableComponent {
450
497
  /**
451
498
  * @param {Element | null} $root - HTML element to use for accordion
452
499
  * @param {AccordionConfig} [config] - Accordion config
453
500
  */
454
501
  constructor($root, config = {}) {
455
- super($root);
456
- this.config = void 0;
502
+ super($root, config);
457
503
  this.i18n = void 0;
458
504
  this.controlsClass = 'govuk-accordion__controls';
459
505
  this.showAllClass = 'govuk-accordion__show-all';
@@ -478,7 +524,6 @@ class Accordion extends GOVUKFrontendComponent {
478
524
  this.$showAllButton = null;
479
525
  this.$showAllIcon = null;
480
526
  this.$showAllText = null;
481
- this.config = mergeConfigs(Accordion.defaults, config, normaliseDataset(Accordion, this.$root.dataset));
482
527
  this.i18n = new I18n(this.config.i18n);
483
528
  const $sections = this.$root.querySelectorAll(`.${this.sectionClass}`);
484
529
  if (!$sections.length) {
@@ -748,7 +793,7 @@ class Accordion extends GOVUKFrontendComponent {
748
793
  */
749
794
 
750
795
  /**
751
- * @typedef {import('../../common/index.mjs').Schema} Schema
796
+ * @import { Schema } from '../../common/configuration.mjs'
752
797
  */
753
798
  Accordion.moduleName = 'govuk-accordion';
754
799
  Accordion.defaults = Object.freeze({
@@ -1,7 +1,5 @@
1
- import { mergeConfigs } from '../../common/index.mjs';
2
- import { normaliseDataset } from '../../common/normalise-dataset.mjs';
1
+ import { ConfigurableComponent } from '../../common/configuration.mjs';
3
2
  import { ElementError } from '../../errors/index.mjs';
4
- import { GOVUKFrontendComponent } from '../../govuk-frontend-component.mjs';
5
3
  import { I18n } from '../../i18n.mjs';
6
4
 
7
5
  /**
@@ -17,15 +15,15 @@ import { I18n } from '../../i18n.mjs';
17
15
  * attribute, which also provides accessibility.
18
16
  *
19
17
  * @preserve
18
+ * @augments ConfigurableComponent<AccordionConfig>
20
19
  */
21
- class Accordion extends GOVUKFrontendComponent {
20
+ class Accordion extends ConfigurableComponent {
22
21
  /**
23
22
  * @param {Element | null} $root - HTML element to use for accordion
24
23
  * @param {AccordionConfig} [config] - Accordion config
25
24
  */
26
25
  constructor($root, config = {}) {
27
- super($root);
28
- this.config = void 0;
26
+ super($root, config);
29
27
  this.i18n = void 0;
30
28
  this.controlsClass = 'govuk-accordion__controls';
31
29
  this.showAllClass = 'govuk-accordion__show-all';
@@ -50,7 +48,6 @@ class Accordion extends GOVUKFrontendComponent {
50
48
  this.$showAllButton = null;
51
49
  this.$showAllIcon = null;
52
50
  this.$showAllText = null;
53
- this.config = mergeConfigs(Accordion.defaults, config, normaliseDataset(Accordion, this.$root.dataset));
54
51
  this.i18n = new I18n(this.config.i18n);
55
52
  const $sections = this.$root.querySelectorAll(`.${this.sectionClass}`);
56
53
  if (!$sections.length) {
@@ -320,7 +317,7 @@ class Accordion extends GOVUKFrontendComponent {
320
317
  */
321
318
 
322
319
  /**
323
- * @typedef {import('../../common/index.mjs').Schema} Schema
320
+ * @import { Schema } from '../../common/configuration.mjs'
324
321
  */
325
322
  Accordion.moduleName = 'govuk-accordion';
326
323
  Accordion.defaults = Object.freeze({