govuk_publishing_components 55.0.1 → 55.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.
- checksums.yaml +4 -4
- data/app/assets/javascripts/govuk_publishing_components/components/file-upload.js +5 -0
- data/app/assets/stylesheets/govuk_publishing_components/components/_layout-super-navigation-header.scss +1 -0
- data/app/assets/stylesheets/govuk_publishing_components/components/_organisation-logo.scss +5 -2
- data/app/views/govuk_publishing_components/components/_file_upload.html.erb +13 -1
- data/app/views/govuk_publishing_components/components/_layout_super_navigation_header.html.erb +0 -1
- data/app/views/govuk_publishing_components/components/docs/file_upload.yml +6 -0
- data/app/views/govuk_publishing_components/components/feedback/_survey_signup_form.html.erb +1 -1
- data/lib/govuk_publishing_components/version.rb +1 -1
- data/node_modules/govuk-frontend/dist/govuk/all.bundle.js +313 -47
- data/node_modules/govuk-frontend/dist/govuk/all.bundle.js.map +1 -1
- data/node_modules/govuk-frontend/dist/govuk/all.bundle.mjs +312 -47
- data/node_modules/govuk-frontend/dist/govuk/all.bundle.mjs.map +1 -1
- data/node_modules/govuk-frontend/dist/govuk/all.mjs +2 -1
- data/node_modules/govuk-frontend/dist/govuk/all.mjs.map +1 -1
- data/node_modules/govuk-frontend/dist/govuk/common/configuration.mjs +21 -16
- data/node_modules/govuk-frontend/dist/govuk/common/configuration.mjs.map +1 -1
- data/node_modules/govuk-frontend/dist/govuk/common/govuk-frontend-version.mjs +1 -1
- data/node_modules/govuk-frontend/dist/govuk/common/index.mjs +3 -0
- data/node_modules/govuk-frontend/dist/govuk/common/index.mjs.map +1 -1
- data/node_modules/govuk-frontend/dist/govuk/{govuk-frontend-component.mjs → component.mjs} +5 -5
- data/node_modules/govuk-frontend/dist/govuk/component.mjs.map +1 -0
- data/node_modules/govuk-frontend/dist/govuk/components/accordion/accordion.bundle.js +27 -19
- data/node_modules/govuk-frontend/dist/govuk/components/accordion/accordion.bundle.js.map +1 -1
- data/node_modules/govuk-frontend/dist/govuk/components/accordion/accordion.bundle.mjs +27 -19
- data/node_modules/govuk-frontend/dist/govuk/components/accordion/accordion.bundle.mjs.map +1 -1
- data/node_modules/govuk-frontend/dist/govuk/components/accordion/accordion.mjs +1 -1
- data/node_modules/govuk-frontend/dist/govuk/components/accordion/accordion.mjs.map +1 -1
- data/node_modules/govuk-frontend/dist/govuk/components/button/button.bundle.js +27 -19
- data/node_modules/govuk-frontend/dist/govuk/components/button/button.bundle.js.map +1 -1
- data/node_modules/govuk-frontend/dist/govuk/components/button/button.bundle.mjs +27 -19
- data/node_modules/govuk-frontend/dist/govuk/components/button/button.bundle.mjs.map +1 -1
- data/node_modules/govuk-frontend/dist/govuk/components/button/button.mjs +1 -1
- data/node_modules/govuk-frontend/dist/govuk/components/button/button.mjs.map +1 -1
- data/node_modules/govuk-frontend/dist/govuk/components/button/macro-options.json +2 -1
- data/node_modules/govuk-frontend/dist/govuk/components/character-count/_index.scss +8 -0
- data/node_modules/govuk-frontend/dist/govuk/components/character-count/_index.scss.map +1 -1
- data/node_modules/govuk-frontend/dist/govuk/components/character-count/character-count.bundle.js +28 -20
- data/node_modules/govuk-frontend/dist/govuk/components/character-count/character-count.bundle.js.map +1 -1
- data/node_modules/govuk-frontend/dist/govuk/components/character-count/character-count.bundle.mjs +28 -20
- data/node_modules/govuk-frontend/dist/govuk/components/character-count/character-count.bundle.mjs.map +1 -1
- data/node_modules/govuk-frontend/dist/govuk/components/character-count/character-count.mjs +2 -2
- data/node_modules/govuk-frontend/dist/govuk/components/character-count/character-count.mjs.map +1 -1
- data/node_modules/govuk-frontend/dist/govuk/components/character-count/fixtures.json +16 -1
- data/node_modules/govuk-frontend/dist/govuk/components/character-count/macro-options.json +2 -2
- data/node_modules/govuk-frontend/dist/govuk/components/character-count/template.njk +5 -4
- data/node_modules/govuk-frontend/dist/govuk/components/checkboxes/checkboxes.bundle.js +8 -5
- data/node_modules/govuk-frontend/dist/govuk/components/checkboxes/checkboxes.bundle.js.map +1 -1
- data/node_modules/govuk-frontend/dist/govuk/components/checkboxes/checkboxes.bundle.mjs +8 -5
- data/node_modules/govuk-frontend/dist/govuk/components/checkboxes/checkboxes.bundle.mjs.map +1 -1
- data/node_modules/govuk-frontend/dist/govuk/components/checkboxes/checkboxes.mjs +2 -2
- data/node_modules/govuk-frontend/dist/govuk/components/checkboxes/checkboxes.mjs.map +1 -1
- data/node_modules/govuk-frontend/dist/govuk/components/error-summary/error-summary.bundle.js +27 -19
- data/node_modules/govuk-frontend/dist/govuk/components/error-summary/error-summary.bundle.js.map +1 -1
- data/node_modules/govuk-frontend/dist/govuk/components/error-summary/error-summary.bundle.mjs +27 -19
- data/node_modules/govuk-frontend/dist/govuk/components/error-summary/error-summary.bundle.mjs.map +1 -1
- data/node_modules/govuk-frontend/dist/govuk/components/error-summary/error-summary.mjs +1 -1
- data/node_modules/govuk-frontend/dist/govuk/components/error-summary/error-summary.mjs.map +1 -1
- data/node_modules/govuk-frontend/dist/govuk/components/exit-this-page/exit-this-page.bundle.js +27 -19
- data/node_modules/govuk-frontend/dist/govuk/components/exit-this-page/exit-this-page.bundle.js.map +1 -1
- data/node_modules/govuk-frontend/dist/govuk/components/exit-this-page/exit-this-page.bundle.mjs +27 -19
- data/node_modules/govuk-frontend/dist/govuk/components/exit-this-page/exit-this-page.bundle.mjs.map +1 -1
- data/node_modules/govuk-frontend/dist/govuk/components/exit-this-page/exit-this-page.mjs +1 -1
- data/node_modules/govuk-frontend/dist/govuk/components/exit-this-page/exit-this-page.mjs.map +1 -1
- data/node_modules/govuk-frontend/dist/govuk/components/file-upload/_index.scss +167 -0
- data/node_modules/govuk-frontend/dist/govuk/components/file-upload/_index.scss.map +1 -1
- data/node_modules/govuk-frontend/dist/govuk/components/file-upload/file-upload.bundle.js +754 -0
- data/node_modules/govuk-frontend/dist/govuk/components/file-upload/file-upload.bundle.js.map +1 -0
- data/node_modules/govuk-frontend/dist/govuk/components/file-upload/file-upload.bundle.mjs +746 -0
- data/node_modules/govuk-frontend/dist/govuk/components/file-upload/file-upload.bundle.mjs.map +1 -0
- data/node_modules/govuk-frontend/dist/govuk/components/file-upload/file-upload.mjs +267 -0
- data/node_modules/govuk-frontend/dist/govuk/components/file-upload/file-upload.mjs.map +1 -0
- data/node_modules/govuk-frontend/dist/govuk/components/file-upload/fixtures.json +207 -16
- data/node_modules/govuk-frontend/dist/govuk/components/file-upload/macro-options.json +52 -3
- data/node_modules/govuk-frontend/dist/govuk/components/file-upload/template-allows-direct-media-capture.html +6 -0
- data/node_modules/govuk-frontend/dist/govuk/components/file-upload/template-allows-image-files-only.html +6 -0
- data/node_modules/govuk-frontend/dist/govuk/components/file-upload/template-allows-multiple-files.html +6 -0
- data/node_modules/govuk-frontend/dist/govuk/components/file-upload/template-disabled.html +6 -0
- data/node_modules/govuk-frontend/dist/govuk/components/file-upload/template-enhanced-disabled.html +13 -0
- data/node_modules/govuk-frontend/dist/govuk/components/file-upload/template-enhanced-with-error-message-and-hint.html +16 -0
- data/node_modules/govuk-frontend/dist/govuk/components/file-upload/template-enhanced.html +10 -0
- data/node_modules/govuk-frontend/dist/govuk/components/file-upload/template-translated.html +10 -0
- data/node_modules/govuk-frontend/dist/govuk/components/file-upload/template.njk +42 -5
- data/node_modules/govuk-frontend/dist/govuk/components/header/_index.scss +14 -10
- data/node_modules/govuk-frontend/dist/govuk/components/header/_index.scss.map +1 -1
- data/node_modules/govuk-frontend/dist/govuk/components/header/header.bundle.js +8 -5
- data/node_modules/govuk-frontend/dist/govuk/components/header/header.bundle.js.map +1 -1
- data/node_modules/govuk-frontend/dist/govuk/components/header/header.bundle.mjs +8 -5
- data/node_modules/govuk-frontend/dist/govuk/components/header/header.bundle.mjs.map +1 -1
- data/node_modules/govuk-frontend/dist/govuk/components/header/header.mjs +2 -2
- data/node_modules/govuk-frontend/dist/govuk/components/header/header.mjs.map +1 -1
- data/node_modules/govuk-frontend/dist/govuk/components/header/macro-options.json +25 -12
- data/node_modules/govuk-frontend/dist/govuk/components/input/fixtures.json +16 -2
- data/node_modules/govuk-frontend/dist/govuk/components/input/macro-options.json +2 -2
- data/node_modules/govuk-frontend/dist/govuk/components/input/template-default.html +2 -2
- data/node_modules/govuk-frontend/dist/govuk/components/input/template.njk +5 -4
- data/node_modules/govuk-frontend/dist/govuk/components/notification-banner/notification-banner.bundle.js +27 -19
- data/node_modules/govuk-frontend/dist/govuk/components/notification-banner/notification-banner.bundle.js.map +1 -1
- data/node_modules/govuk-frontend/dist/govuk/components/notification-banner/notification-banner.bundle.mjs +27 -19
- data/node_modules/govuk-frontend/dist/govuk/components/notification-banner/notification-banner.bundle.mjs.map +1 -1
- data/node_modules/govuk-frontend/dist/govuk/components/notification-banner/notification-banner.mjs +1 -1
- data/node_modules/govuk-frontend/dist/govuk/components/notification-banner/notification-banner.mjs.map +1 -1
- data/node_modules/govuk-frontend/dist/govuk/components/password-input/fixtures.json +16 -2
- data/node_modules/govuk-frontend/dist/govuk/components/password-input/macro-options.json +2 -2
- data/node_modules/govuk-frontend/dist/govuk/components/password-input/password-input.bundle.js +27 -20
- data/node_modules/govuk-frontend/dist/govuk/components/password-input/password-input.bundle.js.map +1 -1
- data/node_modules/govuk-frontend/dist/govuk/components/password-input/password-input.bundle.mjs +27 -20
- data/node_modules/govuk-frontend/dist/govuk/components/password-input/password-input.bundle.mjs.map +1 -1
- data/node_modules/govuk-frontend/dist/govuk/components/password-input/password-input.mjs +1 -2
- data/node_modules/govuk-frontend/dist/govuk/components/password-input/password-input.mjs.map +1 -1
- data/node_modules/govuk-frontend/dist/govuk/components/password-input/template-default.html +3 -3
- data/node_modules/govuk-frontend/dist/govuk/components/password-input/template.njk +4 -2
- data/node_modules/govuk-frontend/dist/govuk/components/radios/radios.bundle.js +8 -5
- data/node_modules/govuk-frontend/dist/govuk/components/radios/radios.bundle.js.map +1 -1
- data/node_modules/govuk-frontend/dist/govuk/components/radios/radios.bundle.mjs +8 -5
- data/node_modules/govuk-frontend/dist/govuk/components/radios/radios.bundle.mjs.map +1 -1
- data/node_modules/govuk-frontend/dist/govuk/components/radios/radios.mjs +2 -2
- data/node_modules/govuk-frontend/dist/govuk/components/radios/radios.mjs.map +1 -1
- data/node_modules/govuk-frontend/dist/govuk/components/select/fixtures.json +16 -1
- data/node_modules/govuk-frontend/dist/govuk/components/select/macro-options.json +2 -2
- data/node_modules/govuk-frontend/dist/govuk/components/select/template-id.html +7 -0
- data/node_modules/govuk-frontend/dist/govuk/components/select/template.njk +6 -4
- data/node_modules/govuk-frontend/dist/govuk/components/service-navigation/service-navigation.bundle.js +8 -5
- data/node_modules/govuk-frontend/dist/govuk/components/service-navigation/service-navigation.bundle.js.map +1 -1
- data/node_modules/govuk-frontend/dist/govuk/components/service-navigation/service-navigation.bundle.mjs +8 -5
- data/node_modules/govuk-frontend/dist/govuk/components/service-navigation/service-navigation.bundle.mjs.map +1 -1
- data/node_modules/govuk-frontend/dist/govuk/components/service-navigation/service-navigation.mjs +2 -2
- data/node_modules/govuk-frontend/dist/govuk/components/service-navigation/service-navigation.mjs.map +1 -1
- data/node_modules/govuk-frontend/dist/govuk/components/skip-link/skip-link.bundle.js +9 -6
- data/node_modules/govuk-frontend/dist/govuk/components/skip-link/skip-link.bundle.js.map +1 -1
- data/node_modules/govuk-frontend/dist/govuk/components/skip-link/skip-link.bundle.mjs +9 -6
- data/node_modules/govuk-frontend/dist/govuk/components/skip-link/skip-link.bundle.mjs.map +1 -1
- data/node_modules/govuk-frontend/dist/govuk/components/skip-link/skip-link.mjs +3 -3
- data/node_modules/govuk-frontend/dist/govuk/components/skip-link/skip-link.mjs.map +1 -1
- data/node_modules/govuk-frontend/dist/govuk/components/summary-list/_index.scss +12 -21
- data/node_modules/govuk-frontend/dist/govuk/components/summary-list/_index.scss.map +1 -1
- data/node_modules/govuk-frontend/dist/govuk/components/summary-list/fixtures.json +142 -0
- data/node_modules/govuk-frontend/dist/govuk/components/summary-list/template-as-a-summary-card-extreme.html +106 -0
- data/node_modules/govuk-frontend/dist/govuk/components/tabs/tabs.bundle.js +8 -5
- data/node_modules/govuk-frontend/dist/govuk/components/tabs/tabs.bundle.js.map +1 -1
- data/node_modules/govuk-frontend/dist/govuk/components/tabs/tabs.bundle.mjs +8 -5
- data/node_modules/govuk-frontend/dist/govuk/components/tabs/tabs.bundle.mjs.map +1 -1
- data/node_modules/govuk-frontend/dist/govuk/components/tabs/tabs.mjs +2 -2
- data/node_modules/govuk-frontend/dist/govuk/components/tabs/tabs.mjs.map +1 -1
- data/node_modules/govuk-frontend/dist/govuk/components/textarea/fixtures.json +15 -1
- data/node_modules/govuk-frontend/dist/govuk/components/textarea/macro-options.json +2 -2
- data/node_modules/govuk-frontend/dist/govuk/components/textarea/template.njk +6 -4
- data/node_modules/govuk-frontend/dist/govuk/core/_govuk-frontend-properties.scss +1 -1
- data/node_modules/govuk-frontend/dist/govuk/errors/index.mjs +1 -1
- data/node_modules/govuk-frontend/dist/govuk/errors/index.mjs.map +1 -1
- data/node_modules/govuk-frontend/dist/govuk/govuk-frontend.min.css +2 -2
- data/node_modules/govuk-frontend/dist/govuk/govuk-frontend.min.css.map +1 -1
- data/node_modules/govuk-frontend/dist/govuk/govuk-frontend.min.js +1 -1
- data/node_modules/govuk-frontend/dist/govuk/govuk-frontend.min.js.map +1 -1
- data/node_modules/govuk-frontend/dist/govuk/helpers/_colour.scss +2 -2
- data/node_modules/govuk-frontend/dist/govuk/helpers/_colour.scss.map +1 -1
- data/node_modules/govuk-frontend/dist/govuk/init.mjs +11 -11
- data/node_modules/govuk-frontend/dist/govuk/init.mjs.map +1 -1
- data/node_modules/govuk-frontend/dist/govuk/settings/_colours-organisations.scss +18 -5
- data/node_modules/govuk-frontend/dist/govuk/settings/_colours-organisations.scss.map +1 -1
- data/node_modules/govuk-frontend/dist/govuk-prototype-kit/init.scss +1 -1
- data/node_modules/govuk-frontend/dist/govuk-prototype-kit/init.scss.map +1 -1
- data/node_modules/govuk-frontend/govuk-prototype-kit.config.json +1 -1
- data/node_modules/govuk-frontend/package.json +7 -7
- metadata +21 -5
- data/node_modules/govuk-frontend/dist/govuk/components/file-upload/template-with-value.html +0 -6
- data/node_modules/govuk-frontend/dist/govuk/govuk-frontend-component.mjs.map +0 -1
@@ -1,6 +1,6 @@
|
|
1
1
|
<div class="govuk-form-group">
|
2
|
-
<label class="govuk-label" for="
|
2
|
+
<label class="govuk-label" for="test-name">
|
3
3
|
National Insurance number
|
4
4
|
</label>
|
5
|
-
<input class="govuk-input" id="
|
5
|
+
<input class="govuk-input" id="test-name" name="test-name" type="text">
|
6
6
|
</div>
|
@@ -17,6 +17,7 @@
|
|
17
17
|
{#- a record of other elements that we need to associate with the input using
|
18
18
|
aria-describedby – for example hints or error messages -#}
|
19
19
|
{% set describedBy = params.describedBy if params.describedBy else undefined -%}
|
20
|
+
{%- set id = params.id if params.id else params.name -%}
|
20
21
|
|
21
22
|
{%- set hasPrefix = true if params.prefix and (params.prefix.text or params.prefix.html) else false %}
|
22
23
|
{%- set hasSuffix = true if params.suffix and (params.suffix.text or params.suffix.html) else false %}
|
@@ -27,7 +28,7 @@
|
|
27
28
|
<input
|
28
29
|
{{- govukAttributes({
|
29
30
|
class: classNames,
|
30
|
-
id:
|
31
|
+
id: id,
|
31
32
|
name: params.name,
|
32
33
|
type: params.type | default("text", true),
|
33
34
|
spellcheck: {
|
@@ -83,10 +84,10 @@
|
|
83
84
|
classes: params.label.classes,
|
84
85
|
isPageHeading: params.label.isPageHeading,
|
85
86
|
attributes: params.label.attributes,
|
86
|
-
for:
|
87
|
+
for: id
|
87
88
|
}) | trim | indent(2) }}
|
88
89
|
{% if params.hint %}
|
89
|
-
{% set hintId =
|
90
|
+
{% set hintId = id + '-hint' %}
|
90
91
|
{% set describedBy = describedBy + ' ' + hintId if describedBy else hintId %}
|
91
92
|
{{ govukHint({
|
92
93
|
id: hintId,
|
@@ -97,7 +98,7 @@
|
|
97
98
|
}) | trim | indent(2) }}
|
98
99
|
{% endif %}
|
99
100
|
{% if params.errorMessage %}
|
100
|
-
{% set errorId =
|
101
|
+
{% set errorId = id + '-error' %}
|
101
102
|
{% set describedBy = describedBy + ' ' + errorId if describedBy else errorId %}
|
102
103
|
{{ govukErrorMessage({
|
103
104
|
id: errorId,
|
@@ -60,6 +60,9 @@
|
|
60
60
|
* @typedef ComponentWithModuleName
|
61
61
|
* @property {string} moduleName - Name of the component
|
62
62
|
*/
|
63
|
+
/**
|
64
|
+
* @import { ObjectNested } from './configuration.mjs'
|
65
|
+
*/
|
63
66
|
|
64
67
|
class GOVUKFrontendError extends Error {
|
65
68
|
constructor(...args) {
|
@@ -111,10 +114,10 @@
|
|
111
114
|
}
|
112
115
|
}
|
113
116
|
/**
|
114
|
-
* @
|
117
|
+
* @import { ComponentWithModuleName } from '../common/index.mjs'
|
115
118
|
*/
|
116
119
|
|
117
|
-
class
|
120
|
+
class Component {
|
118
121
|
/**
|
119
122
|
* Returns the root element of the component
|
120
123
|
*
|
@@ -165,12 +168,12 @@
|
|
165
168
|
*/
|
166
169
|
|
167
170
|
/**
|
168
|
-
* @typedef {typeof
|
171
|
+
* @typedef {typeof Component & ChildClass} ChildClassConstructor
|
169
172
|
*/
|
170
|
-
|
173
|
+
Component.elementType = HTMLElement;
|
171
174
|
|
172
175
|
const configOverride = Symbol.for('configOverride');
|
173
|
-
class ConfigurableComponent extends
|
176
|
+
class ConfigurableComponent extends Component {
|
174
177
|
[configOverride](param) {
|
175
178
|
return {};
|
176
179
|
}
|
@@ -188,7 +191,7 @@
|
|
188
191
|
super($root);
|
189
192
|
this._config = void 0;
|
190
193
|
const childConstructor = this.constructor;
|
191
|
-
if (
|
194
|
+
if (!isObject(childConstructor.defaults)) {
|
192
195
|
throw new ConfigError(formatErrorMessage(childConstructor, 'Config passed as parameter into constructor but no defaults defined'));
|
193
196
|
}
|
194
197
|
const datasetConfig = normaliseDataset(childConstructor, this._$root.dataset);
|
@@ -220,16 +223,19 @@
|
|
220
223
|
return output;
|
221
224
|
}
|
222
225
|
function normaliseDataset(Component, dataset) {
|
223
|
-
if (
|
226
|
+
if (!isObject(Component.schema)) {
|
224
227
|
throw new ConfigError(formatErrorMessage(Component, 'Config passed as parameter into constructor but no schema defined'));
|
225
228
|
}
|
226
229
|
const out = {};
|
227
|
-
|
230
|
+
const entries = Object.entries(Component.schema.properties);
|
231
|
+
for (const entry of entries) {
|
232
|
+
const [namespace, property] = entry;
|
233
|
+
const field = namespace.toString();
|
228
234
|
if (field in dataset) {
|
229
235
|
out[field] = normaliseString(dataset[field], property);
|
230
236
|
}
|
231
237
|
if ((property == null ? void 0 : property.type) === 'object') {
|
232
|
-
out[field] = extractConfigByNamespace(Component.schema, dataset,
|
238
|
+
out[field] = extractConfigByNamespace(Component.schema, dataset, namespace);
|
233
239
|
}
|
234
240
|
}
|
235
241
|
return out;
|
@@ -255,13 +261,13 @@
|
|
255
261
|
return;
|
256
262
|
}
|
257
263
|
const newObject = {
|
258
|
-
[namespace]:
|
264
|
+
[namespace]: {}
|
259
265
|
};
|
260
266
|
for (const [key, value] of Object.entries(dataset)) {
|
261
267
|
let current = newObject;
|
262
268
|
const keyParts = key.split('.');
|
263
269
|
for (const [index, name] of keyParts.entries()) {
|
264
|
-
if (
|
270
|
+
if (isObject(current)) {
|
265
271
|
if (index < keyParts.length - 1) {
|
266
272
|
if (!isObject(current[name])) {
|
267
273
|
current[name] = {};
|
@@ -278,9 +284,10 @@
|
|
278
284
|
/**
|
279
285
|
* Schema for component config
|
280
286
|
*
|
287
|
+
* @template {Partial<Record<keyof ConfigurationType, unknown>>} ConfigurationType
|
281
288
|
* @typedef {object} Schema
|
282
|
-
* @property {
|
283
|
-
* @property {SchemaCondition[]} [anyOf] - List of schema conditions
|
289
|
+
* @property {Record<keyof ConfigurationType, SchemaProperty | undefined>} properties - Schema properties
|
290
|
+
* @property {SchemaCondition<ConfigurationType>[]} [anyOf] - List of schema conditions
|
284
291
|
*/
|
285
292
|
/**
|
286
293
|
* Schema property for component config
|
@@ -291,20 +298,21 @@
|
|
291
298
|
/**
|
292
299
|
* Schema condition for component config
|
293
300
|
*
|
301
|
+
* @template {Partial<Record<keyof ConfigurationType, unknown>>} ConfigurationType
|
294
302
|
* @typedef {object} SchemaCondition
|
295
|
-
* @property {
|
303
|
+
* @property {(keyof ConfigurationType)[]} required - List of required config fields
|
296
304
|
* @property {string} errorMessage - Error message when required config fields not provided
|
297
305
|
*/
|
298
306
|
/**
|
299
|
-
* @template {
|
307
|
+
* @template {Partial<Record<keyof ConfigurationType, unknown>>} [ConfigurationType=ObjectNested]
|
300
308
|
* @typedef ChildClass
|
301
309
|
* @property {string} moduleName - The module name that'll be looked for in the DOM when initialising the component
|
302
|
-
* @property {Schema} [schema] - The schema of the component configuration
|
310
|
+
* @property {Schema<ConfigurationType>} [schema] - The schema of the component configuration
|
303
311
|
* @property {ConfigurationType} [defaults] - The default values of the configuration of the component
|
304
312
|
*/
|
305
313
|
/**
|
306
|
-
* @template {
|
307
|
-
* @typedef {typeof
|
314
|
+
* @template {Partial<Record<keyof ConfigurationType, unknown>>} [ConfigurationType=ObjectNested]
|
315
|
+
* @typedef {typeof Component & ChildClass<ConfigurationType>} ChildClassConstructor<ConfigurationType>
|
308
316
|
*/
|
309
317
|
|
310
318
|
/**
|
@@ -337,7 +345,7 @@
|
|
337
345
|
*/
|
338
346
|
|
339
347
|
/**
|
340
|
-
* @
|
348
|
+
* @import { Schema } from '../../common/configuration.mjs'
|
341
349
|
*/
|
342
350
|
NotificationBanner.moduleName = 'govuk-notification-banner';
|
343
351
|
NotificationBanner.defaults = Object.freeze({
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"notification-banner.bundle.js","sources":["../../../../src/govuk/common/index.mjs","../../../../src/govuk/errors/index.mjs","../../../../src/govuk/govuk-frontend-component.mjs","../../../../src/govuk/common/configuration.mjs","../../../../src/govuk/components/notification-banner/notification-banner.mjs"],"sourcesContent":["/**\n * Common helpers which do not require polyfill.\n *\n * IMPORTANT: If a helper require a polyfill, please isolate it in its own module\n * so that the polyfill can be properly tree-shaken and does not burden\n * the components that do not need that helper\n */\n\n/**\n * Get hash fragment from URL\n *\n * Extract the hash fragment (everything after the hash) from a URL,\n * but not including the hash symbol\n *\n * @private\n * @param {string} url - URL\n * @returns {string | undefined} Fragment from URL, without the hash\n */\nexport function getFragmentFromUrl(url) {\n if (!url.includes('#')) {\n return undefined\n }\n\n return url.split('#').pop()\n}\n\n/**\n * Get GOV.UK Frontend breakpoint value from CSS custom property\n *\n * @private\n * @param {string} name - Breakpoint name\n * @returns {{ property: string, value?: string }} Breakpoint object\n */\nexport function getBreakpoint(name) {\n const property = `--govuk-frontend-breakpoint-${name}`\n\n // Get value from `<html>` with breakpoints on CSS :root\n const value = window\n .getComputedStyle(document.documentElement)\n .getPropertyValue(property)\n\n return {\n property,\n value: value || undefined\n }\n}\n\n/**\n * Move focus to element\n *\n * Sets tabindex to -1 to make the element programmatically focusable,\n * but removes it on blur as the element doesn't need to be focused again.\n *\n * @private\n * @template {HTMLElement} FocusElement\n * @param {FocusElement} $element - HTML element\n * @param {object} [options] - Handler options\n * @param {function(this: FocusElement): void} [options.onBeforeFocus] - Callback before focus\n * @param {function(this: FocusElement): void} [options.onBlur] - Callback on blur\n */\nexport function setFocus($element, options = {}) {\n const isFocusable = $element.getAttribute('tabindex')\n\n if (!isFocusable) {\n $element.setAttribute('tabindex', '-1')\n }\n\n /**\n * Handle element focus\n */\n function onFocus() {\n $element.addEventListener('blur', onBlur, { once: true })\n }\n\n /**\n * Handle element blur\n */\n function onBlur() {\n options.onBlur?.call($element)\n\n if (!isFocusable) {\n $element.removeAttribute('tabindex')\n }\n }\n\n // Add listener to reset element on blur, after focus\n $element.addEventListener('focus', onFocus, { once: true })\n\n // Focus element\n options.onBeforeFocus?.call($element)\n $element.focus()\n}\n\n/**\n * Checks if component is already initialised\n *\n * @internal\n * @param {Element} $root - HTML element to be checked\n * @param {string} moduleName - name of component module\n * @returns {boolean} Whether component is already initialised\n */\nexport function isInitialised($root, moduleName) {\n return (\n $root instanceof HTMLElement &&\n $root.hasAttribute(`data-${moduleName}-init`)\n )\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 */\nexport function isSupported($scope = document.body) {\n if (!$scope) {\n return false\n }\n\n return $scope.classList.contains('govuk-frontend-supported')\n}\n\n/**\n * Check for an array\n *\n * @internal\n * @param {unknown} option - Option to check\n * @returns {boolean} Whether the option is an array\n */\nfunction isArray(option) {\n return Array.isArray(option)\n}\n\n/**\n * Check for an object\n *\n * @internal\n * @param {unknown} option - Option to check\n * @returns {boolean} Whether the option is an object\n */\nexport function isObject(option) {\n return !!option && typeof option === 'object' && !isArray(option)\n}\n\n/**\n * Format error message\n *\n * @internal\n * @param {ComponentWithModuleName} Component - Component that threw the error\n * @param {string} message - Error message\n * @returns {string} - Formatted error message\n */\nexport function formatErrorMessage(Component, message) {\n return `${Component.moduleName}: ${message}`\n}\n\n/* eslint-disable jsdoc/valid-types --\n * `{new(...args: any[] ): object}` is not recognised as valid\n * https://github.com/gajus/eslint-plugin-jsdoc/issues/145#issuecomment-1308722878\n * https://github.com/jsdoc-type-pratt-parser/jsdoc-type-pratt-parser/issues/131\n **/\n\n/**\n * @typedef ComponentWithModuleName\n * @property {string} moduleName - Name of the component\n */\n\n/* eslint-enable jsdoc/valid-types */\n","import { formatErrorMessage } from '../common/index.mjs'\n\n/**\n * GOV.UK Frontend error\n *\n * A base class for `Error`s thrown by GOV.UK Frontend.\n *\n * It is meant to be extended into specific types of errors\n * to be thrown by our code.\n *\n * @example\n * ```js\n * class MissingRootError extends GOVUKFrontendError {\n * // Setting an explicit name is important as extending the class will not\n * // set a new `name` on the subclass. The `name` property is important\n * // to ensure intelligible error names even if the class name gets\n * // mangled by a minifier\n * name = \"MissingRootError\"\n * }\n * ```\n * @virtual\n */\nexport class GOVUKFrontendError extends Error {\n name = 'GOVUKFrontendError'\n}\n\n/**\n * Indicates that GOV.UK Frontend is not supported\n */\nexport class SupportError extends GOVUKFrontendError {\n name = 'SupportError'\n\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 =\n 'noModule' in HTMLScriptElement.prototype\n ? 'GOV.UK Frontend initialised without `<body class=\"govuk-frontend-supported\">` from template `<script>` snippet'\n : 'GOV.UK Frontend is not supported in this browser'\n\n super(\n $scope\n ? supportMessage\n : 'GOV.UK Frontend initialised without `<script type=\"module\">`'\n )\n }\n}\n\n/**\n * Indicates that a component has received an illegal configuration\n */\nexport class ConfigError extends GOVUKFrontendError {\n name = 'ConfigError'\n}\n\n/**\n * Indicates an issue with an element (possibly `null` or `undefined`)\n */\nexport class ElementError extends GOVUKFrontendError {\n name = 'ElementError'\n\n /**\n * @internal\n * @overload\n * @param {string} message - Element error message\n */\n\n /**\n * @internal\n * @overload\n * @param {ElementErrorOptions} options - Element error options\n */\n\n /**\n * @internal\n * @param {string | ElementErrorOptions} messageOrOptions - Element error message or options\n */\n constructor(messageOrOptions) {\n let message = typeof messageOrOptions === 'string' ? messageOrOptions : ''\n\n // Build message from options\n if (typeof messageOrOptions === 'object') {\n const { component, identifier, element, expectedType } = messageOrOptions\n\n message = identifier\n\n // Append reason\n message += element\n ? ` is not of type ${expectedType ?? 'HTMLElement'}`\n : ' not found'\n\n message = formatErrorMessage(component, message)\n }\n\n super(message)\n }\n}\n\n/**\n * Indicates that a component is already initialised\n */\nexport class InitError extends GOVUKFrontendError {\n name = 'InitError'\n\n /**\n * @internal\n * @param {ComponentWithModuleName | string} componentOrMessage - name of the component module\n */\n constructor(componentOrMessage) {\n const message =\n typeof componentOrMessage === 'string'\n ? componentOrMessage\n : formatErrorMessage(\n componentOrMessage,\n `Root element (\\`$root\\`) already initialised`\n )\n\n super(message)\n }\n}\n\n/**\n * Element error options\n *\n * @internal\n * @typedef {object} ElementErrorOptions\n * @property {string} identifier - An identifier that'll let the user understand which element has an error. This is whatever makes the most sense\n * @property {Element | null} [element] - The element in error\n * @property {string} [expectedType] - The type that was expected for the identifier\n * @property {ComponentWithModuleName} component - Component throwing the error\n */\n\n/**\n * @typedef {import('../common/index.mjs').ComponentWithModuleName} ComponentWithModuleName\n */\n","import { isInitialised, isSupported } from './common/index.mjs'\nimport { ElementError, InitError, SupportError } from './errors/index.mjs'\n\n/**\n * Base Component class\n *\n * Centralises the behaviours shared by our components\n *\n * @virtual\n * @template {Element} [RootElementType=HTMLElement]\n */\nexport class GOVUKFrontendComponent {\n /**\n * @type {typeof Element}\n */\n static elementType = HTMLElement\n\n // allows Typescript user to work around the lack of types\n // in GOVUKFrontend package, Typescript is not aware of $root\n // in components that extend GOVUKFrontendComponent\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\n /**\n * @protected\n * @type {RootElementType}\n */\n _$root\n\n /**\n * Constructs a new component, validating that GOV.UK Frontend is supported\n *\n * @internal\n * @param {Element | null} [$root] - HTML element to use for component\n */\n constructor($root) {\n const childConstructor = /** @type {ChildClassConstructor} */ (\n this.constructor\n )\n\n // TypeScript does not enforce that inheriting classes will define a `moduleName`\n // (even if we add a `@virtual` `static moduleName` property to this class).\n // While we trust users to do this correctly, we do a little check to provide them\n // a helpful error message.\n //\n // After this, we'll be sure that `childConstructor` has a `moduleName`\n // as expected of the `ChildClassConstructor` we've cast `this.constructor` to.\n if (typeof childConstructor.moduleName !== 'string') {\n throw new InitError(`\\`moduleName\\` not defined in component`)\n }\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 = /** @type {RootElementType} */ ($root)\n }\n\n childConstructor.checkSupport()\n\n this.checkInitialised()\n\n const moduleName = childConstructor.moduleName\n\n this.$root.setAttribute(`data-${moduleName}-init`, '')\n }\n\n /**\n * Validates whether component is already initialised\n *\n * @private\n * @throws {InitError} when component is already initialised\n */\n checkInitialised() {\n const constructor = /** @type {ChildClassConstructor} */ (this.constructor)\n const moduleName = constructor.moduleName\n\n if (moduleName && isInitialised(this.$root, moduleName)) {\n throw new InitError(constructor)\n }\n }\n\n /**\n * Validates whether components are supported\n *\n * @throws {SupportError} when the components are not supported\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 GOVUKFrontendComponent & ChildClass} ChildClassConstructor\n */\n","import { ConfigError } from '../errors/index.mjs'\nimport { GOVUKFrontendComponent } from '../govuk-frontend-component.mjs'\n\nimport { isObject, formatErrorMessage } from './index.mjs'\n\nexport const configOverride = Symbol.for('configOverride')\n\n/**\n * Base Component class\n *\n * Centralises the behaviours shared by our components\n *\n * @virtual\n * @template {ObjectNested} [ConfigurationType={}]\n * @template {Element & { dataset: DOMStringMap }} [RootElementType=HTMLElement]\n * @augments GOVUKFrontendComponent<RootElementType>\n */\nexport class ConfigurableComponent extends GOVUKFrontendComponent {\n /**\n * configOverride\n *\n * Function which defines configuration overrides to prioritize\n * properties from the root element's dataset.\n *\n * It should take a subset of configuration as input and return\n * a new configuration object with properties that should be\n * overridden based on the root element's dataset. A Symbol\n * is used for indexing to prevent conflicts.\n *\n * @internal\n * @virtual\n * @param {ObjectNested} [param] - Configuration object\n * @returns {ObjectNested} return - Configuration object\n */\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n [configOverride](param) {\n return {}\n }\n\n /**\n * Returns the root element of the component\n *\n * @protected\n * @returns {ConfigurationType} - the root element of component\n */\n get config() {\n return this._config\n }\n\n /**\n *\n * @type {ConfigurationType}\n */\n _config\n\n /**\n * Constructs a new component, validating that GOV.UK Frontend is supported\n *\n * @internal\n * @param {Element | null} [$root] - HTML element to use for component\n * @param {ConfigurationType} [config] - HTML element to use for component\n */\n constructor($root, config) {\n super($root)\n\n const childConstructor =\n /** @type {ChildClassConstructor<ConfigurationType>} */ (this.constructor)\n\n if (typeof childConstructor.defaults === 'undefined') {\n throw new ConfigError(\n formatErrorMessage(\n childConstructor,\n 'Config passed as parameter into constructor but no defaults defined'\n )\n )\n }\n\n const datasetConfig = /** @type {ConfigurationType} */ (\n normaliseDataset(childConstructor, this._$root.dataset)\n )\n\n this._config = /** @type {ConfigurationType} */ (\n mergeConfigs(\n childConstructor.defaults,\n config ?? {},\n this[configOverride](datasetConfig),\n datasetConfig\n )\n )\n }\n}\n\n/**\n * Normalise string\n *\n * 'If it looks like a duck, and it quacks like a duck…' 🦆\n *\n * If the passed value looks like a boolean or a number, convert it to a boolean\n * or number.\n *\n * Designed to be used to convert config passed via data attributes (which are\n * always strings) into something sensible.\n *\n * @internal\n * @param {DOMStringMap[string]} value - The value to normalise\n * @param {SchemaProperty} [property] - Component schema property\n * @returns {string | boolean | number | undefined} Normalised data\n */\nexport function normaliseString(value, property) {\n const trimmedValue = value ? value.trim() : ''\n\n let output\n let outputType = property?.type\n\n // No schema type set? Determine automatically\n if (!outputType) {\n if (['true', 'false'].includes(trimmedValue)) {\n outputType = 'boolean'\n }\n\n // Empty / whitespace-only strings are considered finite so we need to check\n // the length of the trimmed string as well\n if (trimmedValue.length > 0 && isFinite(Number(trimmedValue))) {\n outputType = 'number'\n }\n }\n\n switch (outputType) {\n case 'boolean':\n output = trimmedValue === 'true'\n break\n\n case 'number':\n output = Number(trimmedValue)\n break\n\n default:\n output = value\n }\n\n return output\n}\n\n/**\n * Normalise dataset\n *\n * Loop over an object and normalise each value using {@link normaliseString},\n * optionally expanding nested `i18n.field`\n *\n * @internal\n * @param {{ schema?: Schema, moduleName: string }} Component - Component class\n * @param {DOMStringMap} dataset - HTML element dataset\n * @returns {ObjectNested} Normalised dataset\n */\nexport function normaliseDataset(Component, dataset) {\n if (typeof Component.schema === 'undefined') {\n throw new ConfigError(\n formatErrorMessage(\n Component,\n 'Config passed as parameter into constructor but no schema defined'\n )\n )\n }\n\n const out = /** @type {ReturnType<typeof normaliseDataset>} */ ({})\n\n // Normalise top-level dataset ('data-*') values using schema types\n for (const [field, property] of Object.entries(Component.schema.properties)) {\n if (field in dataset) {\n out[field] = normaliseString(dataset[field], property)\n }\n\n /**\n * Extract and normalise nested object values automatically using\n * {@link normaliseString} but only schema object types are allowed\n */\n if (property?.type === 'object') {\n out[field] = extractConfigByNamespace(Component.schema, dataset, field)\n }\n }\n\n return out\n}\n\n/**\n * Config merging function\n *\n * Takes any number of objects and combines them together, with\n * greatest priority on the LAST item passed in.\n *\n * @internal\n * @param {...{ [key: string]: unknown }} configObjects - Config objects to merge\n * @returns {{ [key: string]: unknown }} A merged config object\n */\nexport function mergeConfigs(...configObjects) {\n // Start with an empty object as our base\n /** @type {{ [key: string]: unknown }} */\n const formattedConfigObject = {}\n\n // Loop through each of the passed objects\n for (const configObject of configObjects) {\n for (const key of Object.keys(configObject)) {\n const option = formattedConfigObject[key]\n const override = configObject[key]\n\n // Push their keys one-by-one into formattedConfigObject. Any duplicate\n // keys with object values will be merged, otherwise the new value will\n // override the existing value.\n if (isObject(option) && isObject(override)) {\n // @ts-expect-error Index signature for type 'string' is missing\n formattedConfigObject[key] = mergeConfigs(option, override)\n } else {\n // Apply override\n formattedConfigObject[key] = override\n }\n }\n }\n\n return formattedConfigObject\n}\n\n/**\n * Validate component config by schema\n *\n * Follows limited examples in JSON schema for wider support in future\n *\n * {@link https://ajv.js.org/json-schema.html#compound-keywords}\n * {@link https://ajv.js.org/packages/ajv-errors.html#single-message}\n *\n * @internal\n * @param {Schema} schema - Config schema\n * @param {{ [key: string]: unknown }} config - Component config\n * @returns {string[]} List of validation errors\n */\nexport function validateConfig(schema, config) {\n const validationErrors = []\n\n // Check errors for each schema\n for (const [name, conditions] of Object.entries(schema)) {\n const errors = []\n\n // Check errors for each schema condition\n if (Array.isArray(conditions)) {\n for (const { required, errorMessage } of conditions) {\n if (!required.every((key) => !!config[key])) {\n errors.push(errorMessage) // Missing config key value\n }\n }\n\n // Check one condition passes or add errors\n if (name === 'anyOf' && !(conditions.length - errors.length >= 1)) {\n validationErrors.push(...errors)\n }\n }\n }\n\n return validationErrors\n}\n\n/**\n * Extracts keys starting with a particular namespace from dataset ('data-*')\n * object, removing the namespace in the process, normalising all values\n *\n * @internal\n * @param {Schema} schema - The schema of a component\n * @param {DOMStringMap} dataset - The object to extract key-value pairs from\n * @param {string} namespace - The namespace to filter keys with\n * @returns {ObjectNested | undefined} Nested object with dot-separated key namespace removed\n */\nexport function extractConfigByNamespace(schema, dataset, namespace) {\n const property = schema.properties[namespace]\n\n // Only extract configs for object schema properties\n if (property?.type !== 'object') {\n return\n }\n\n // Add default empty config\n const newObject = {\n [namespace]: /** @type {ObjectNested} */ ({})\n }\n\n for (const [key, value] of Object.entries(dataset)) {\n /** @type {ObjectNested | ObjectNested[NestedKey]} */\n let current = newObject\n\n // Split the key into parts, using . as our namespace separator\n const keyParts = key.split('.')\n\n /**\n * Create new level per part\n *\n * e.g. 'i18n.textareaDescription.other' becomes\n * `{ i18n: { textareaDescription: { other } } }`\n */\n for (const [index, name] of keyParts.entries()) {\n if (typeof current === 'object') {\n // Drop down to nested object until the last part\n if (index < keyParts.length - 1) {\n // New nested object (optionally) replaces existing value\n if (!isObject(current[name])) {\n current[name] = {}\n }\n\n // Drop down into new or existing nested object\n current = current[name]\n } else if (key !== namespace) {\n // Normalised value (optionally) replaces existing value\n current[name] = normaliseString(value)\n }\n }\n }\n }\n\n return newObject[namespace]\n}\n\n/**\n * @internal\n * @typedef {keyof ObjectNested} NestedKey\n * @typedef {{ [key: string]: string | boolean | number | ObjectNested | undefined }} ObjectNested\n */\n\n/**\n * Schema for component config\n *\n * @typedef {object} Schema\n * @property {{ [field: string]: SchemaProperty | undefined }} properties - Schema properties\n * @property {SchemaCondition[]} [anyOf] - List of schema conditions\n */\n\n/**\n * Schema property for component config\n *\n * @typedef {object} SchemaProperty\n * @property {'string' | 'boolean' | 'number' | 'object'} type - Property type\n */\n\n/**\n * Schema condition for component config\n *\n * @typedef {object} SchemaCondition\n * @property {string[]} required - List of required config fields\n * @property {string} errorMessage - Error message when required config fields not provided\n */\n\n/**\n * @template {ObjectNested} [ConfigurationType={}]\n * @typedef ChildClass\n * @property {string} moduleName - The module name that'll be looked for in the DOM when initialising the component\n * @property {Schema} [schema] - The schema of the component configuration\n * @property {ConfigurationType} [defaults] - The default values of the configuration of the component\n */\n\n/**\n * @template {ObjectNested} [ConfigurationType={}]\n * @typedef {typeof GOVUKFrontendComponent & ChildClass<ConfigurationType>} ChildClassConstructor<ConfigurationType>\n */\n","import { ConfigurableComponent } from '../../common/configuration.mjs'\nimport { setFocus } from '../../common/index.mjs'\n\n/**\n * Notification Banner component\n *\n * @preserve\n * @augments ConfigurableComponent<NotificationBannerConfig>\n */\nexport class NotificationBanner extends ConfigurableComponent {\n /**\n * @param {Element | null} $root - HTML element to use for notification banner\n * @param {NotificationBannerConfig} [config] - Notification banner config\n */\n constructor($root, config = {}) {\n super($root, config)\n\n /**\n * Focus the notification banner\n *\n * If `role=\"alert\"` is set, focus the element to help some assistive\n * technologies prioritise announcing it.\n *\n * You can turn off the auto-focus functionality by setting\n * `data-disable-auto-focus=\"true\"` in the component HTML. You might wish to\n * do this based on user research findings, or to avoid a clash with another\n * element which should be focused when the page loads.\n */\n if (\n this.$root.getAttribute('role') === 'alert' &&\n !this.config.disableAutoFocus\n ) {\n setFocus(this.$root)\n }\n }\n\n /**\n * Name for the component used when initialising using data-module attributes.\n */\n static moduleName = 'govuk-notification-banner'\n\n /**\n * Notification banner default config\n *\n * @see {@link NotificationBannerConfig}\n * @constant\n * @type {NotificationBannerConfig}\n */\n static defaults = Object.freeze({\n disableAutoFocus: false\n })\n\n /**\n * Notification banner config schema\n *\n * @constant\n * @satisfies {Schema}\n */\n static schema = Object.freeze({\n properties: {\n disableAutoFocus: { type: 'boolean' }\n }\n })\n}\n\n/**\n * Notification banner config\n *\n * @typedef {object} NotificationBannerConfig\n * @property {boolean} [disableAutoFocus=false] - If set to `true` the\n * notification banner will not be focussed when the page loads. This only\n * applies if the component has a `role` of `alert` – in other cases the\n * component will not be focused on page load, regardless of this option.\n */\n\n/**\n * @typedef {import('../../common/configuration.mjs').Schema} Schema\n */\n"],"names":["setFocus","$element","options","_options$onBeforeFocu","isFocusable","getAttribute","setAttribute","onFocus","addEventListener","onBlur","once","_options$onBlur","call","removeAttribute","onBeforeFocus","focus","isInitialised","$root","moduleName","HTMLElement","hasAttribute","isSupported","$scope","document","body","classList","contains","isArray","option","Array","isObject","formatErrorMessage","Component","message","GOVUKFrontendError","Error","constructor","args","name","SupportError","supportMessage","HTMLScriptElement","prototype","ConfigError","ElementError","messageOrOptions","component","identifier","element","expectedType","InitError","componentOrMessage","GOVUKFrontendComponent","_$root","childConstructor","elementType","checkSupport","checkInitialised","configOverride","Symbol","for","ConfigurableComponent","param","config","_config","defaults","datasetConfig","normaliseDataset","dataset","mergeConfigs","normaliseString","value","property","trimmedValue","trim","output","outputType","type","includes","length","isFinite","Number","schema","out","field","Object","entries","properties","extractConfigByNamespace","configObjects","formattedConfigObject","configObject","key","keys","override","namespace","newObject","current","keyParts","split","index","NotificationBanner","disableAutoFocus","freeze"],"mappings":";;;;;;EA4DO,SAASA,QAAQA,CAACC,QAAQ,EAAEC,OAAO,GAAG,EAAE,EAAE;EAAA,EAAA,IAAAC,qBAAA,CAAA;EAC/C,EAAA,MAAMC,WAAW,GAAGH,QAAQ,CAACI,YAAY,CAAC,UAAU,CAAC,CAAA;IAErD,IAAI,CAACD,WAAW,EAAE;EAChBH,IAAAA,QAAQ,CAACK,YAAY,CAAC,UAAU,EAAE,IAAI,CAAC,CAAA;EACzC,GAAA;IAKA,SAASC,OAAOA,GAAG;EACjBN,IAAAA,QAAQ,CAACO,gBAAgB,CAAC,MAAM,EAAEC,MAAM,EAAE;EAAEC,MAAAA,IAAI,EAAE,IAAA;EAAK,KAAC,CAAC,CAAA;EAC3D,GAAA;IAKA,SAASD,MAAMA,GAAG;EAAA,IAAA,IAAAE,eAAA,CAAA;MAChB,CAAAA,eAAA,GAAAT,OAAO,CAACO,MAAM,KAAdE,IAAAA,IAAAA,eAAA,CAAgBC,IAAI,CAACX,QAAQ,CAAC,CAAA;MAE9B,IAAI,CAACG,WAAW,EAAE;EAChBH,MAAAA,QAAQ,CAACY,eAAe,CAAC,UAAU,CAAC,CAAA;EACtC,KAAA;EACF,GAAA;EAGAZ,EAAAA,QAAQ,CAACO,gBAAgB,CAAC,OAAO,EAAED,OAAO,EAAE;EAAEG,IAAAA,IAAI,EAAE,IAAA;EAAK,GAAC,CAAC,CAAA;IAG3D,CAAAP,qBAAA,GAAAD,OAAO,CAACY,aAAa,KAArBX,IAAAA,IAAAA,qBAAA,CAAuBS,IAAI,CAACX,QAAQ,CAAC,CAAA;IACrCA,QAAQ,CAACc,KAAK,EAAE,CAAA;EAClB,CAAA;EAUO,SAASC,aAAaA,CAACC,KAAK,EAAEC,UAAU,EAAE;IAC/C,OACED,KAAK,YAAYE,WAAW,IAC5BF,KAAK,CAACG,YAAY,CAAC,CAAA,KAAA,EAAQF,UAAU,CAAA,KAAA,CAAO,CAAC,CAAA;EAEjD,CAAA;;EAEA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACO,SAASG,WAAWA,CAACC,MAAM,GAAGC,QAAQ,CAACC,IAAI,EAAE;IAClD,IAAI,CAACF,MAAM,EAAE;EACX,IAAA,OAAO,KAAK,CAAA;EACd,GAAA;EAEA,EAAA,OAAOA,MAAM,CAACG,SAAS,CAACC,QAAQ,CAAC,0BAA0B,CAAC,CAAA;EAC9D,CAAA;EASA,SAASC,OAAOA,CAACC,MAAM,EAAE;EACvB,EAAA,OAAOC,KAAK,CAACF,OAAO,CAACC,MAAM,CAAC,CAAA;EAC9B,CAAA;EASO,SAASE,QAAQA,CAACF,MAAM,EAAE;EAC/B,EAAA,OAAO,CAAC,CAACA,MAAM,IAAI,OAAOA,MAAM,KAAK,QAAQ,IAAI,CAACD,OAAO,CAACC,MAAM,CAAC,CAAA;EACnE,CAAA;EAUO,SAASG,kBAAkBA,CAACC,SAAS,EAAEC,OAAO,EAAE;EACrD,EAAA,OAAO,GAAGD,SAAS,CAACd,UAAU,CAAA,EAAA,EAAKe,OAAO,CAAE,CAAA,CAAA;EAC9C,CAAA;EAQA;EACA;EACA;EACA;;EClJO,MAAMC,kBAAkB,SAASC,KAAK,CAAC;EAAAC,EAAAA,WAAAA,CAAA,GAAAC,IAAA,EAAA;EAAA,IAAA,KAAA,CAAA,GAAAA,IAAA,CAAA,CAAA;MAAA,IAC5CC,CAAAA,IAAI,GAAG,oBAAoB,CAAA;EAAA,GAAA;EAC7B,CAAA;EAKO,MAAMC,YAAY,SAASL,kBAAkB,CAAC;EAGnD;EACF;EACA;EACA;EACA;EACEE,EAAAA,WAAWA,CAACd,MAAM,GAAGC,QAAQ,CAACC,IAAI,EAAE;MAClC,MAAMgB,cAAc,GAClB,UAAU,IAAIC,iBAAiB,CAACC,SAAS,GACrC,gHAAgH,GAChH,kDAAkD,CAAA;EAExD,IAAA,KAAK,CACHpB,MAAM,GACFkB,cAAc,GACd,8DACN,CAAC,CAAA;MAAA,IAjBHF,CAAAA,IAAI,GAAG,cAAc,CAAA;EAkBrB,GAAA;EACF,CAAA;EAKO,MAAMK,WAAW,SAAST,kBAAkB,CAAC;EAAAE,EAAAA,WAAAA,CAAA,GAAAC,IAAA,EAAA;EAAA,IAAA,KAAA,CAAA,GAAAA,IAAA,CAAA,CAAA;MAAA,IAClDC,CAAAA,IAAI,GAAG,aAAa,CAAA;EAAA,GAAA;EACtB,CAAA;EAKO,MAAMM,YAAY,SAASV,kBAAkB,CAAC;IAmBnDE,WAAWA,CAACS,gBAAgB,EAAE;MAC5B,IAAIZ,OAAO,GAAG,OAAOY,gBAAgB,KAAK,QAAQ,GAAGA,gBAAgB,GAAG,EAAE,CAAA;EAG1E,IAAA,IAAI,OAAOA,gBAAgB,KAAK,QAAQ,EAAE;QACxC,MAAM;UAAEC,SAAS;UAAEC,UAAU;UAAEC,OAAO;EAAEC,QAAAA,YAAAA;EAAa,OAAC,GAAGJ,gBAAgB,CAAA;EAEzEZ,MAAAA,OAAO,GAAGc,UAAU,CAAA;QAGpBd,OAAO,IAAIe,OAAO,GACd,CAAmBC,gBAAAA,EAAAA,YAAY,IAAZA,IAAAA,GAAAA,YAAY,GAAI,aAAa,CAAE,CAAA,GAClD,YAAY,CAAA;EAEhBhB,MAAAA,OAAO,GAAGF,kBAAkB,CAACe,SAAS,EAAEb,OAAO,CAAC,CAAA;EAClD,KAAA;MAEA,KAAK,CAACA,OAAO,CAAC,CAAA;MAAA,IAnChBK,CAAAA,IAAI,GAAG,cAAc,CAAA;EAoCrB,GAAA;EACF,CAAA;EAKO,MAAMY,SAAS,SAAShB,kBAAkB,CAAC;IAOhDE,WAAWA,CAACe,kBAAkB,EAAE;EAC9B,IAAA,MAAMlB,OAAO,GACX,OAAOkB,kBAAkB,KAAK,QAAQ,GAClCA,kBAAkB,GAClBpB,kBAAkB,CAChBoB,kBAAkB,EAClB,8CACF,CAAC,CAAA;MAEP,KAAK,CAAClB,OAAO,CAAC,CAAA;MAAA,IAfhBK,CAAAA,IAAI,GAAG,WAAW,CAAA;EAgBlB,GAAA;EACF,CAAA;EAaA;EACA;EACA;;EC9HO,MAAMc,sBAAsB,CAAC;EASlC;EACF;EACA;EACA;EACA;EACA;IACE,IAAInC,KAAKA,GAAG;MACV,OAAO,IAAI,CAACoC,MAAM,CAAA;EACpB,GAAA;IAcAjB,WAAWA,CAACnB,KAAK,EAAE;EAAA,IAAA,IAAA,CARnBoC,MAAM,GAAA,KAAA,CAAA,CAAA;EASJ,IAAA,MAAMC,gBAAgB,GACpB,IAAI,CAAClB,WACN,CAAA;EASD,IAAA,IAAI,OAAOkB,gBAAgB,CAACpC,UAAU,KAAK,QAAQ,EAAE;EACnD,MAAA,MAAM,IAAIgC,SAAS,CAAC,CAAA,uCAAA,CAAyC,CAAC,CAAA;EAChE,KAAA;EAEA,IAAA,IAAI,EAAEjC,KAAK,YAAYqC,gBAAgB,CAACC,WAAW,CAAC,EAAE;QACpD,MAAM,IAAIX,YAAY,CAAC;EACrBI,QAAAA,OAAO,EAAE/B,KAAK;EACd6B,QAAAA,SAAS,EAAEQ,gBAAgB;EAC3BP,QAAAA,UAAU,EAAE,wBAAwB;EACpCE,QAAAA,YAAY,EAAEK,gBAAgB,CAACC,WAAW,CAACjB,IAAAA;EAC7C,OAAC,CAAC,CAAA;EACJ,KAAC,MAAM;QACL,IAAI,CAACe,MAAM,GAAmCpC,KAAM,CAAA;EACtD,KAAA;MAEAqC,gBAAgB,CAACE,YAAY,EAAE,CAAA;MAE/B,IAAI,CAACC,gBAAgB,EAAE,CAAA;EAEvB,IAAA,MAAMvC,UAAU,GAAGoC,gBAAgB,CAACpC,UAAU,CAAA;MAE9C,IAAI,CAACD,KAAK,CAACX,YAAY,CAAC,QAAQY,UAAU,CAAA,KAAA,CAAO,EAAE,EAAE,CAAC,CAAA;EACxD,GAAA;EAQAuC,EAAAA,gBAAgBA,GAAG;EACjB,IAAA,MAAMrB,WAAW,GAAyC,IAAI,CAACA,WAAY,CAAA;EAC3E,IAAA,MAAMlB,UAAU,GAAGkB,WAAW,CAAClB,UAAU,CAAA;MAEzC,IAAIA,UAAU,IAAIF,aAAa,CAAC,IAAI,CAACC,KAAK,EAAEC,UAAU,CAAC,EAAE;EACvD,MAAA,MAAM,IAAIgC,SAAS,CAACd,WAAW,CAAC,CAAA;EAClC,KAAA;EACF,GAAA;IAOA,OAAOoB,YAAYA,GAAG;EACpB,IAAA,IAAI,CAACnC,WAAW,EAAE,EAAE;QAClB,MAAM,IAAIkB,YAAY,EAAE,CAAA;EAC1B,KAAA;EACF,GAAA;EACF,CAAA;;EAEA;EACA;EACA;EACA;;EAEA;EACA;EACA;EArGaa,sBAAsB,CAI1BG,WAAW,GAAGpC,WAAW;;ECV3B,MAAMuC,cAAc,GAAGC,MAAM,CAACC,GAAG,CAAC,gBAAgB,CAAC,CAAA;EAYnD,MAAMC,qBAAqB,SAAST,sBAAsB,CAAC;IAkBhE,CAACM,cAAc,CAAEI,CAAAA,KAAK,EAAE;EACtB,IAAA,OAAO,EAAE,CAAA;EACX,GAAA;;EAEA;EACF;EACA;EACA;EACA;EACA;IACE,IAAIC,MAAMA,GAAG;MACX,OAAO,IAAI,CAACC,OAAO,CAAA;EACrB,GAAA;EAeA5B,EAAAA,WAAWA,CAACnB,KAAK,EAAE8C,MAAM,EAAE;MACzB,KAAK,CAAC9C,KAAK,CAAC,CAAA;EAAA,IAAA,IAAA,CAVd+C,OAAO,GAAA,KAAA,CAAA,CAAA;EAYL,IAAA,MAAMV,gBAAgB,GACqC,IAAI,CAAClB,WAAY,CAAA;EAE5E,IAAA,IAAI,OAAOkB,gBAAgB,CAACW,QAAQ,KAAK,WAAW,EAAE;QACpD,MAAM,IAAItB,WAAW,CACnBZ,kBAAkB,CAChBuB,gBAAgB,EAChB,qEACF,CACF,CAAC,CAAA;EACH,KAAA;MAEA,MAAMY,aAAa,GACjBC,gBAAgB,CAACb,gBAAgB,EAAE,IAAI,CAACD,MAAM,CAACe,OAAO,CACvD,CAAA;MAED,IAAI,CAACJ,OAAO,GACVK,YAAY,CACVf,gBAAgB,CAACW,QAAQ,EACzBF,MAAM,IAANA,IAAAA,GAAAA,MAAM,GAAI,EAAE,EACZ,IAAI,CAACL,cAAc,CAAC,CAACQ,aAAa,CAAC,EACnCA,aACF,CACD,CAAA;EACH,GAAA;EACF,CAAA;EAkBO,SAASI,eAAeA,CAACC,KAAK,EAAEC,QAAQ,EAAE;IAC/C,MAAMC,YAAY,GAAGF,KAAK,GAAGA,KAAK,CAACG,IAAI,EAAE,GAAG,EAAE,CAAA;EAE9C,EAAA,IAAIC,MAAM,CAAA;EACV,EAAA,IAAIC,UAAU,GAAGJ,QAAQ,IAARA,IAAAA,GAAAA,KAAAA,CAAAA,GAAAA,QAAQ,CAAEK,IAAI,CAAA;IAG/B,IAAI,CAACD,UAAU,EAAE;MACf,IAAI,CAAC,MAAM,EAAE,OAAO,CAAC,CAACE,QAAQ,CAACL,YAAY,CAAC,EAAE;EAC5CG,MAAAA,UAAU,GAAG,SAAS,CAAA;EACxB,KAAA;EAIA,IAAA,IAAIH,YAAY,CAACM,MAAM,GAAG,CAAC,IAAIC,QAAQ,CAACC,MAAM,CAACR,YAAY,CAAC,CAAC,EAAE;EAC7DG,MAAAA,UAAU,GAAG,QAAQ,CAAA;EACvB,KAAA;EACF,GAAA;EAEA,EAAA,QAAQA,UAAU;EAChB,IAAA,KAAK,SAAS;QACZD,MAAM,GAAGF,YAAY,KAAK,MAAM,CAAA;EAChC,MAAA,MAAA;EAEF,IAAA,KAAK,QAAQ;EACXE,MAAAA,MAAM,GAAGM,MAAM,CAACR,YAAY,CAAC,CAAA;EAC7B,MAAA,MAAA;EAEF,IAAA;EACEE,MAAAA,MAAM,GAAGJ,KAAK,CAAA;EAClB,GAAA;EAEA,EAAA,OAAOI,MAAM,CAAA;EACf,CAAA;EAaO,SAASR,gBAAgBA,CAACnC,SAAS,EAAEoC,OAAO,EAAE;EACnD,EAAA,IAAI,OAAOpC,SAAS,CAACkD,MAAM,KAAK,WAAW,EAAE;MAC3C,MAAM,IAAIvC,WAAW,CACnBZ,kBAAkB,CAChBC,SAAS,EACT,mEACF,CACF,CAAC,CAAA;EACH,GAAA;IAEA,MAAMmD,GAAG,GAAuD,EAAG,CAAA;EAGnE,EAAA,KAAK,MAAM,CAACC,KAAK,EAAEZ,QAAQ,CAAC,IAAIa,MAAM,CAACC,OAAO,CAACtD,SAAS,CAACkD,MAAM,CAACK,UAAU,CAAC,EAAE;MAC3E,IAAIH,KAAK,IAAIhB,OAAO,EAAE;EACpBe,MAAAA,GAAG,CAACC,KAAK,CAAC,GAAGd,eAAe,CAACF,OAAO,CAACgB,KAAK,CAAC,EAAEZ,QAAQ,CAAC,CAAA;EACxD,KAAA;MAMA,IAAI,CAAAA,QAAQ,IAARA,IAAAA,GAAAA,KAAAA,CAAAA,GAAAA,QAAQ,CAAEK,IAAI,MAAK,QAAQ,EAAE;EAC/BM,MAAAA,GAAG,CAACC,KAAK,CAAC,GAAGI,wBAAwB,CAACxD,SAAS,CAACkD,MAAM,EAAEd,OAAO,EAAEgB,KAAK,CAAC,CAAA;EACzE,KAAA;EACF,GAAA;EAEA,EAAA,OAAOD,GAAG,CAAA;EACZ,CAAA;EAYO,SAASd,YAAYA,CAAC,GAAGoB,aAAa,EAAE;IAG7C,MAAMC,qBAAqB,GAAG,EAAE,CAAA;EAGhC,EAAA,KAAK,MAAMC,YAAY,IAAIF,aAAa,EAAE;MACxC,KAAK,MAAMG,GAAG,IAAIP,MAAM,CAACQ,IAAI,CAACF,YAAY,CAAC,EAAE;EAC3C,MAAA,MAAM/D,MAAM,GAAG8D,qBAAqB,CAACE,GAAG,CAAC,CAAA;EACzC,MAAA,MAAME,QAAQ,GAAGH,YAAY,CAACC,GAAG,CAAC,CAAA;QAKlC,IAAI9D,QAAQ,CAACF,MAAM,CAAC,IAAIE,QAAQ,CAACgE,QAAQ,CAAC,EAAE;UAE1CJ,qBAAqB,CAACE,GAAG,CAAC,GAAGvB,YAAY,CAACzC,MAAM,EAAEkE,QAAQ,CAAC,CAAA;EAC7D,OAAC,MAAM;EAELJ,QAAAA,qBAAqB,CAACE,GAAG,CAAC,GAAGE,QAAQ,CAAA;EACvC,OAAA;EACF,KAAA;EACF,GAAA;EAEA,EAAA,OAAOJ,qBAAqB,CAAA;EAC9B,CAAA;EAkDO,SAASF,wBAAwBA,CAACN,MAAM,EAAEd,OAAO,EAAE2B,SAAS,EAAE;EACnE,EAAA,MAAMvB,QAAQ,GAAGU,MAAM,CAACK,UAAU,CAACQ,SAAS,CAAC,CAAA;IAG7C,IAAI,CAAAvB,QAAQ,IAARA,IAAAA,GAAAA,KAAAA,CAAAA,GAAAA,QAAQ,CAAEK,IAAI,MAAK,QAAQ,EAAE;EAC/B,IAAA,OAAA;EACF,GAAA;EAGA,EAAA,MAAMmB,SAAS,GAAG;MAChB,CAACD,SAAS,IAAgC,EAAE,CAAA;KAC7C,CAAA;EAED,EAAA,KAAK,MAAM,CAACH,GAAG,EAAErB,KAAK,CAAC,IAAIc,MAAM,CAACC,OAAO,CAAClB,OAAO,CAAC,EAAE;MAElD,IAAI6B,OAAO,GAAGD,SAAS,CAAA;EAGvB,IAAA,MAAME,QAAQ,GAAGN,GAAG,CAACO,KAAK,CAAC,GAAG,CAAC,CAAA;EAQ/B,IAAA,KAAK,MAAM,CAACC,KAAK,EAAE9D,IAAI,CAAC,IAAI4D,QAAQ,CAACZ,OAAO,EAAE,EAAE;EAC9C,MAAA,IAAI,OAAOW,OAAO,KAAK,QAAQ,EAAE;EAE/B,QAAA,IAAIG,KAAK,GAAGF,QAAQ,CAACnB,MAAM,GAAG,CAAC,EAAE;YAE/B,IAAI,CAACjD,QAAQ,CAACmE,OAAO,CAAC3D,IAAI,CAAC,CAAC,EAAE;EAC5B2D,YAAAA,OAAO,CAAC3D,IAAI,CAAC,GAAG,EAAE,CAAA;EACpB,WAAA;EAGA2D,UAAAA,OAAO,GAAGA,OAAO,CAAC3D,IAAI,CAAC,CAAA;EACzB,SAAC,MAAM,IAAIsD,GAAG,KAAKG,SAAS,EAAE;EAE5BE,UAAAA,OAAO,CAAC3D,IAAI,CAAC,GAAGgC,eAAe,CAACC,KAAK,CAAC,CAAA;EACxC,SAAA;EACF,OAAA;EACF,KAAA;EACF,GAAA;IAEA,OAAOyB,SAAS,CAACD,SAAS,CAAC,CAAA;EAC7B,CAAA;EAQA;EACA;EACA;EACA;EACA;EACA;EACA;EAEA;EACA;EACA;EACA;EACA;EACA;EAEA;EACA;EACA;EACA;EACA;EACA;EACA;EAEA;EACA;EACA;EACA;EACA;EACA;EACA;EAEA;EACA;EACA;EACA;;EClWA;EACA;EACA;EACA;EACA;EACA;EACO,MAAMM,kBAAkB,SAASxC,qBAAqB,CAAC;EAC5D;EACF;EACA;EACA;EACEzB,EAAAA,WAAWA,CAACnB,KAAK,EAAE8C,MAAM,GAAG,EAAE,EAAE;EAC9B,IAAA,KAAK,CAAC9C,KAAK,EAAE8C,MAAM,CAAC,CAAA;EAapB,IAAA,IACE,IAAI,CAAC9C,KAAK,CAACZ,YAAY,CAAC,MAAM,CAAC,KAAK,OAAO,IAC3C,CAAC,IAAI,CAAC0D,MAAM,CAACuC,gBAAgB,EAC7B;EACAtG,MAAAA,QAAQ,CAAC,IAAI,CAACiB,KAAK,CAAC,CAAA;EACtB,KAAA;EACF,GAAA;EA6BF,CAAA;;EAEA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;EAEA;EACA;EACA;EApEaoF,kBAAkB,CA8BtBnF,UAAU,GAAG,2BAA2B,CAAA;EA9BpCmF,kBAAkB,CAuCtBpC,QAAQ,GAAGoB,MAAM,CAACkB,MAAM,CAAC;EAC9BD,EAAAA,gBAAgB,EAAE,KAAA;EACpB,CAAC,CAAC,CAAA;EAzCSD,kBAAkB,CAiDtBnB,MAAM,GAAGG,MAAM,CAACkB,MAAM,CAAC;EAC5BhB,EAAAA,UAAU,EAAE;EACVe,IAAAA,gBAAgB,EAAE;EAAEzB,MAAAA,IAAI,EAAE,SAAA;EAAU,KAAA;EACtC,GAAA;EACF,CAAC,CAAC;;;;;;;;"}
|
1
|
+
{"version":3,"file":"notification-banner.bundle.js","sources":["../../../../src/govuk/common/index.mjs","../../../../src/govuk/errors/index.mjs","../../../../src/govuk/component.mjs","../../../../src/govuk/common/configuration.mjs","../../../../src/govuk/components/notification-banner/notification-banner.mjs"],"sourcesContent":["/**\n * Common helpers which do not require polyfill.\n *\n * IMPORTANT: If a helper require a polyfill, please isolate it in its own module\n * so that the polyfill can be properly tree-shaken and does not burden\n * the components that do not need that helper\n */\n\n/**\n * Get hash fragment from URL\n *\n * Extract the hash fragment (everything after the hash) from a URL,\n * but not including the hash symbol\n *\n * @private\n * @param {string} url - URL\n * @returns {string | undefined} Fragment from URL, without the hash\n */\nexport function getFragmentFromUrl(url) {\n if (!url.includes('#')) {\n return undefined\n }\n\n return url.split('#').pop()\n}\n\n/**\n * Get GOV.UK Frontend breakpoint value from CSS custom property\n *\n * @private\n * @param {string} name - Breakpoint name\n * @returns {{ property: string, value?: string }} Breakpoint object\n */\nexport function getBreakpoint(name) {\n const property = `--govuk-frontend-breakpoint-${name}`\n\n // Get value from `<html>` with breakpoints on CSS :root\n const value = window\n .getComputedStyle(document.documentElement)\n .getPropertyValue(property)\n\n return {\n property,\n value: value || undefined\n }\n}\n\n/**\n * Move focus to element\n *\n * Sets tabindex to -1 to make the element programmatically focusable,\n * but removes it on blur as the element doesn't need to be focused again.\n *\n * @private\n * @template {HTMLElement} FocusElement\n * @param {FocusElement} $element - HTML element\n * @param {object} [options] - Handler options\n * @param {function(this: FocusElement): void} [options.onBeforeFocus] - Callback before focus\n * @param {function(this: FocusElement): void} [options.onBlur] - Callback on blur\n */\nexport function setFocus($element, options = {}) {\n const isFocusable = $element.getAttribute('tabindex')\n\n if (!isFocusable) {\n $element.setAttribute('tabindex', '-1')\n }\n\n /**\n * Handle element focus\n */\n function onFocus() {\n $element.addEventListener('blur', onBlur, { once: true })\n }\n\n /**\n * Handle element blur\n */\n function onBlur() {\n options.onBlur?.call($element)\n\n if (!isFocusable) {\n $element.removeAttribute('tabindex')\n }\n }\n\n // Add listener to reset element on blur, after focus\n $element.addEventListener('focus', onFocus, { once: true })\n\n // Focus element\n options.onBeforeFocus?.call($element)\n $element.focus()\n}\n\n/**\n * Checks if component is already initialised\n *\n * @internal\n * @param {Element} $root - HTML element to be checked\n * @param {string} moduleName - name of component module\n * @returns {boolean} Whether component is already initialised\n */\nexport function isInitialised($root, moduleName) {\n return (\n $root instanceof HTMLElement &&\n $root.hasAttribute(`data-${moduleName}-init`)\n )\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 */\nexport function isSupported($scope = document.body) {\n if (!$scope) {\n return false\n }\n\n return $scope.classList.contains('govuk-frontend-supported')\n}\n\n/**\n * Check for an array\n *\n * @internal\n * @param {unknown} option - Option to check\n * @returns {boolean} Whether the option is an array\n */\nfunction isArray(option) {\n return Array.isArray(option)\n}\n\n/**\n * Check for an object\n *\n * @internal\n * @template {Partial<Record<keyof ObjectType, unknown>>} [ObjectType=ObjectNested]\n * @param {unknown | ObjectType} option - Option to check\n * @returns {option is ObjectType} Whether the option is an object\n */\nexport function isObject(option) {\n return !!option && typeof option === 'object' && !isArray(option)\n}\n\n/**\n * Format error message\n *\n * @internal\n * @param {ComponentWithModuleName} Component - Component that threw the error\n * @param {string} message - Error message\n * @returns {string} - Formatted error message\n */\nexport function formatErrorMessage(Component, message) {\n return `${Component.moduleName}: ${message}`\n}\n\n/* eslint-disable jsdoc/valid-types --\n * `{new(...args: any[] ): object}` is not recognised as valid\n * https://github.com/gajus/eslint-plugin-jsdoc/issues/145#issuecomment-1308722878\n * https://github.com/jsdoc-type-pratt-parser/jsdoc-type-pratt-parser/issues/131\n **/\n\n/**\n * @typedef ComponentWithModuleName\n * @property {string} moduleName - Name of the component\n */\n\n/* eslint-enable jsdoc/valid-types */\n\n/**\n * @import { ObjectNested } from './configuration.mjs'\n */\n","import { formatErrorMessage } from '../common/index.mjs'\n\n/**\n * GOV.UK Frontend error\n *\n * A base class for `Error`s thrown by GOV.UK Frontend.\n *\n * It is meant to be extended into specific types of errors\n * to be thrown by our code.\n *\n * @example\n * ```js\n * class MissingRootError extends GOVUKFrontendError {\n * // Setting an explicit name is important as extending the class will not\n * // set a new `name` on the subclass. The `name` property is important\n * // to ensure intelligible error names even if the class name gets\n * // mangled by a minifier\n * name = \"MissingRootError\"\n * }\n * ```\n * @virtual\n */\nexport class GOVUKFrontendError extends Error {\n name = 'GOVUKFrontendError'\n}\n\n/**\n * Indicates that GOV.UK Frontend is not supported\n */\nexport class SupportError extends GOVUKFrontendError {\n name = 'SupportError'\n\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 =\n 'noModule' in HTMLScriptElement.prototype\n ? 'GOV.UK Frontend initialised without `<body class=\"govuk-frontend-supported\">` from template `<script>` snippet'\n : 'GOV.UK Frontend is not supported in this browser'\n\n super(\n $scope\n ? supportMessage\n : 'GOV.UK Frontend initialised without `<script type=\"module\">`'\n )\n }\n}\n\n/**\n * Indicates that a component has received an illegal configuration\n */\nexport class ConfigError extends GOVUKFrontendError {\n name = 'ConfigError'\n}\n\n/**\n * Indicates an issue with an element (possibly `null` or `undefined`)\n */\nexport class ElementError extends GOVUKFrontendError {\n name = 'ElementError'\n\n /**\n * @internal\n * @overload\n * @param {string} message - Element error message\n */\n\n /**\n * @internal\n * @overload\n * @param {ElementErrorOptions} options - Element error options\n */\n\n /**\n * @internal\n * @param {string | ElementErrorOptions} messageOrOptions - Element error message or options\n */\n constructor(messageOrOptions) {\n let message = typeof messageOrOptions === 'string' ? messageOrOptions : ''\n\n // Build message from options\n if (typeof messageOrOptions === 'object') {\n const { component, identifier, element, expectedType } = messageOrOptions\n\n message = identifier\n\n // Append reason\n message += element\n ? ` is not of type ${expectedType ?? 'HTMLElement'}`\n : ' not found'\n\n message = formatErrorMessage(component, message)\n }\n\n super(message)\n }\n}\n\n/**\n * Indicates that a component is already initialised\n */\nexport class InitError extends GOVUKFrontendError {\n name = 'InitError'\n\n /**\n * @internal\n * @param {ComponentWithModuleName | string} componentOrMessage - name of the component module\n */\n constructor(componentOrMessage) {\n const message =\n typeof componentOrMessage === 'string'\n ? componentOrMessage\n : formatErrorMessage(\n componentOrMessage,\n `Root element (\\`$root\\`) already initialised`\n )\n\n super(message)\n }\n}\n\n/**\n * Element error options\n *\n * @internal\n * @typedef {object} ElementErrorOptions\n * @property {string} identifier - An identifier that'll let the user understand which element has an error. This is whatever makes the most sense\n * @property {Element | null} [element] - The element in error\n * @property {string} [expectedType] - The type that was expected for the identifier\n * @property {ComponentWithModuleName} component - Component throwing the error\n */\n\n/**\n * @import { ComponentWithModuleName } from '../common/index.mjs'\n */\n","import { isInitialised, isSupported } from './common/index.mjs'\nimport { ElementError, InitError, SupportError } from './errors/index.mjs'\n\n/**\n * Base Component class\n *\n * Centralises the behaviours shared by our components\n *\n * @virtual\n * @template {Element} [RootElementType=HTMLElement]\n */\nexport class Component {\n /**\n * @type {typeof Element}\n */\n static elementType = HTMLElement\n\n // allows Typescript user to work around the lack of types\n // in GOVUKFrontend package, Typescript is not aware of $root\n // in components that extend GOVUKFrontendComponent\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\n /**\n * @protected\n * @type {RootElementType}\n */\n _$root\n\n /**\n * Constructs a new component, validating that GOV.UK Frontend is supported\n *\n * @internal\n * @param {Element | null} [$root] - HTML element to use for component\n */\n constructor($root) {\n const childConstructor = /** @type {ChildClassConstructor} */ (\n this.constructor\n )\n\n // TypeScript does not enforce that inheriting classes will define a `moduleName`\n // (even if we add a `@virtual` `static moduleName` property to this class).\n // While we trust users to do this correctly, we do a little check to provide them\n // a helpful error message.\n //\n // After this, we'll be sure that `childConstructor` has a `moduleName`\n // as expected of the `ChildClassConstructor` we've cast `this.constructor` to.\n if (typeof childConstructor.moduleName !== 'string') {\n throw new InitError(`\\`moduleName\\` not defined in component`)\n }\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 = /** @type {RootElementType} */ ($root)\n }\n\n childConstructor.checkSupport()\n\n this.checkInitialised()\n\n const moduleName = childConstructor.moduleName\n\n this.$root.setAttribute(`data-${moduleName}-init`, '')\n }\n\n /**\n * Validates whether component is already initialised\n *\n * @private\n * @throws {InitError} when component is already initialised\n */\n checkInitialised() {\n const constructor = /** @type {ChildClassConstructor} */ (this.constructor)\n const moduleName = constructor.moduleName\n\n if (moduleName && isInitialised(this.$root, moduleName)) {\n throw new InitError(constructor)\n }\n }\n\n /**\n * Validates whether components are supported\n *\n * @throws {SupportError} when the components are not supported\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 */\n","import { Component } from '../component.mjs'\nimport { ConfigError } from '../errors/index.mjs'\n\nimport { isObject, formatErrorMessage } from './index.mjs'\n\nexport const configOverride = Symbol.for('configOverride')\n\n/**\n * Base Component class\n *\n * Centralises the behaviours shared by our components\n *\n * @virtual\n * @template {Partial<Record<keyof ConfigurationType, unknown>>} [ConfigurationType=ObjectNested]\n * @template {Element & { dataset: DOMStringMap }} [RootElementType=HTMLElement]\n * @augments Component<RootElementType>\n */\nexport class ConfigurableComponent extends Component {\n /**\n * configOverride\n *\n * Function which defines configuration overrides to prioritize\n * properties from the root element's dataset.\n *\n * It should take a subset of configuration as input and return\n * a new configuration object with properties that should be\n * overridden based on the root element's dataset. A Symbol\n * is used for indexing to prevent conflicts.\n *\n * @internal\n * @virtual\n * @param {Partial<ConfigurationType>} [param] - Configuration object\n * @returns {Partial<ConfigurationType>} return - Configuration object\n */\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n [configOverride](param) {\n return {}\n }\n\n /**\n * Returns the root element of the component\n *\n * @protected\n * @returns {ConfigurationType} - the root element of component\n */\n get config() {\n return this._config\n }\n\n /**\n *\n * @type {ConfigurationType}\n */\n _config\n\n /**\n * Constructs a new component, validating that GOV.UK Frontend is supported\n *\n * @internal\n * @param {Element | null} [$root] - HTML element to use for component\n * @param {ConfigurationType} [config] - HTML element to use for component\n */\n constructor($root, config) {\n super($root)\n\n const childConstructor =\n /** @type {ChildClassConstructor<ConfigurationType>} */ (this.constructor)\n\n if (!isObject(childConstructor.defaults)) {\n throw new ConfigError(\n formatErrorMessage(\n childConstructor,\n 'Config passed as parameter into constructor but no defaults defined'\n )\n )\n }\n\n const datasetConfig = /** @type {ConfigurationType} */ (\n normaliseDataset(childConstructor, this._$root.dataset)\n )\n\n this._config = /** @type {ConfigurationType} */ (\n mergeConfigs(\n childConstructor.defaults,\n config ?? {},\n this[configOverride](datasetConfig),\n datasetConfig\n )\n )\n }\n}\n\n/**\n * Normalise string\n *\n * 'If it looks like a duck, and it quacks like a duck…' 🦆\n *\n * If the passed value looks like a boolean or a number, convert it to a boolean\n * or number.\n *\n * Designed to be used to convert config passed via data attributes (which are\n * always strings) into something sensible.\n *\n * @internal\n * @param {DOMStringMap[string]} value - The value to normalise\n * @param {SchemaProperty} [property] - Component schema property\n * @returns {string | boolean | number | undefined} Normalised data\n */\nexport function normaliseString(value, property) {\n const trimmedValue = value ? value.trim() : ''\n\n let output\n let outputType = property?.type\n\n // No schema type set? Determine automatically\n if (!outputType) {\n if (['true', 'false'].includes(trimmedValue)) {\n outputType = 'boolean'\n }\n\n // Empty / whitespace-only strings are considered finite so we need to check\n // the length of the trimmed string as well\n if (trimmedValue.length > 0 && isFinite(Number(trimmedValue))) {\n outputType = 'number'\n }\n }\n\n switch (outputType) {\n case 'boolean':\n output = trimmedValue === 'true'\n break\n\n case 'number':\n output = Number(trimmedValue)\n break\n\n default:\n output = value\n }\n\n return output\n}\n\n/**\n * Normalise dataset\n *\n * Loop over an object and normalise each value using {@link normaliseString},\n * optionally expanding nested `i18n.field`\n *\n * @internal\n * @template {Partial<Record<keyof ConfigurationType, unknown>>} ConfigurationType\n * @template {[keyof ConfigurationType, SchemaProperty | undefined][]} SchemaEntryType\n * @param {{ schema?: Schema<ConfigurationType>, moduleName: string }} Component - Component class\n * @param {DOMStringMap} dataset - HTML element dataset\n * @returns {ObjectNested} Normalised dataset\n */\nexport function normaliseDataset(Component, dataset) {\n if (!isObject(Component.schema)) {\n throw new ConfigError(\n formatErrorMessage(\n Component,\n 'Config passed as parameter into constructor but no schema defined'\n )\n )\n }\n\n const out = /** @type {ObjectNested} */ ({})\n const entries = /** @type {SchemaEntryType} */ (\n Object.entries(Component.schema.properties)\n )\n\n // Normalise top-level dataset ('data-*') values using schema types\n for (const entry of entries) {\n const [namespace, property] = entry\n\n // Cast the `namespace` to string so it can be used to access the dataset\n const field = namespace.toString()\n\n if (field in dataset) {\n out[field] = normaliseString(dataset[field], property)\n }\n\n /**\n * Extract and normalise nested object values automatically using\n * {@link normaliseString} but only schema object types are allowed\n */\n if (property?.type === 'object') {\n out[field] = extractConfigByNamespace(\n Component.schema,\n dataset,\n namespace\n )\n }\n }\n\n return out\n}\n\n/**\n * Config merging function\n *\n * Takes any number of objects and combines them together, with\n * greatest priority on the LAST item passed in.\n *\n * @internal\n * @param {...{ [key: string]: unknown }} configObjects - Config objects to merge\n * @returns {{ [key: string]: unknown }} A merged config object\n */\nexport function mergeConfigs(...configObjects) {\n // Start with an empty object as our base\n /** @type {{ [key: string]: unknown }} */\n const formattedConfigObject = {}\n\n // Loop through each of the passed objects\n for (const configObject of configObjects) {\n for (const key of Object.keys(configObject)) {\n const option = formattedConfigObject[key]\n const override = configObject[key]\n\n // Push their keys one-by-one into formattedConfigObject. Any duplicate\n // keys with object values will be merged, otherwise the new value will\n // override the existing value.\n if (isObject(option) && isObject(override)) {\n formattedConfigObject[key] = mergeConfigs(option, override)\n } else {\n // Apply override\n formattedConfigObject[key] = override\n }\n }\n }\n\n return formattedConfigObject\n}\n\n/**\n * Validate component config by schema\n *\n * Follows limited examples in JSON schema for wider support in future\n *\n * {@link https://ajv.js.org/json-schema.html#compound-keywords}\n * {@link https://ajv.js.org/packages/ajv-errors.html#single-message}\n *\n * @internal\n * @template {Partial<Record<keyof ConfigurationType, unknown>>} ConfigurationType\n * @param {Schema<ConfigurationType>} schema - The schema of a component\n * @param {ConfigurationType} config - Component config\n * @returns {string[]} List of validation errors\n */\nexport function validateConfig(schema, config) {\n const validationErrors = []\n\n // Check errors for each schema\n for (const [name, conditions] of Object.entries(schema)) {\n const errors = []\n\n // Check errors for each schema condition\n if (Array.isArray(conditions)) {\n for (const { required, errorMessage } of conditions) {\n if (!required.every((key) => !!config[key])) {\n errors.push(errorMessage) // Missing config key value\n }\n }\n\n // Check one condition passes or add errors\n if (name === 'anyOf' && !(conditions.length - errors.length >= 1)) {\n validationErrors.push(...errors)\n }\n }\n }\n\n return validationErrors\n}\n\n/**\n * Extracts keys starting with a particular namespace from dataset ('data-*')\n * object, removing the namespace in the process, normalising all values\n *\n * @internal\n * @template {Partial<Record<keyof ConfigurationType, unknown>>} ConfigurationType\n * @param {Schema<ConfigurationType>} schema - The schema of a component\n * @param {DOMStringMap} dataset - The object to extract key-value pairs from\n * @param {keyof ConfigurationType} namespace - The namespace to filter keys with\n * @returns {ObjectNested | undefined} Nested object with dot-separated key namespace removed\n */\nexport function extractConfigByNamespace(schema, dataset, namespace) {\n const property = schema.properties[namespace]\n\n // Only extract configs for object schema properties\n if (property?.type !== 'object') {\n return\n }\n\n // Add default empty config\n const newObject = /** @type {Record<typeof namespace, ObjectNested>} */ ({\n [namespace]: {}\n })\n\n for (const [key, value] of Object.entries(dataset)) {\n /** @type {ObjectNested | ObjectNested[NestedKey]} */\n let current = newObject\n\n // Split the key into parts, using . as our namespace separator\n const keyParts = key.split('.')\n\n /**\n * Create new level per part\n *\n * e.g. 'i18n.textareaDescription.other' becomes\n * `{ i18n: { textareaDescription: { other } } }`\n */\n for (const [index, name] of keyParts.entries()) {\n if (isObject(current)) {\n // Drop down to nested object until the last part\n if (index < keyParts.length - 1) {\n // New nested object (optionally) replaces existing value\n if (!isObject(current[name])) {\n current[name] = {}\n }\n\n // Drop down into new or existing nested object\n current = current[name]\n } else if (key !== namespace) {\n // Normalised value (optionally) replaces existing value\n current[name] = normaliseString(value)\n }\n }\n }\n }\n\n return newObject[namespace]\n}\n\n/**\n * @internal\n * @typedef {keyof ObjectNested} NestedKey\n * @typedef {{ [key: string]: string | boolean | number | ObjectNested | undefined }} ObjectNested\n */\n\n/**\n * Schema for component config\n *\n * @template {Partial<Record<keyof ConfigurationType, unknown>>} ConfigurationType\n * @typedef {object} Schema\n * @property {Record<keyof ConfigurationType, SchemaProperty | undefined>} properties - Schema properties\n * @property {SchemaCondition<ConfigurationType>[]} [anyOf] - List of schema conditions\n */\n\n/**\n * Schema property for component config\n *\n * @typedef {object} SchemaProperty\n * @property {'string' | 'boolean' | 'number' | 'object'} type - Property type\n */\n\n/**\n * Schema condition for component config\n *\n * @template {Partial<Record<keyof ConfigurationType, unknown>>} ConfigurationType\n * @typedef {object} SchemaCondition\n * @property {(keyof ConfigurationType)[]} required - List of required config fields\n * @property {string} errorMessage - Error message when required config fields not provided\n */\n\n/**\n * @template {Partial<Record<keyof ConfigurationType, unknown>>} [ConfigurationType=ObjectNested]\n * @typedef ChildClass\n * @property {string} moduleName - The module name that'll be looked for in the DOM when initialising the component\n * @property {Schema<ConfigurationType>} [schema] - The schema of the component configuration\n * @property {ConfigurationType} [defaults] - The default values of the configuration of the component\n */\n\n/**\n * @template {Partial<Record<keyof ConfigurationType, unknown>>} [ConfigurationType=ObjectNested]\n * @typedef {typeof Component & ChildClass<ConfigurationType>} ChildClassConstructor<ConfigurationType>\n */\n","import { ConfigurableComponent } from '../../common/configuration.mjs'\nimport { setFocus } from '../../common/index.mjs'\n\n/**\n * Notification Banner component\n *\n * @preserve\n * @augments ConfigurableComponent<NotificationBannerConfig>\n */\nexport class NotificationBanner extends ConfigurableComponent {\n /**\n * @param {Element | null} $root - HTML element to use for notification banner\n * @param {NotificationBannerConfig} [config] - Notification banner config\n */\n constructor($root, config = {}) {\n super($root, config)\n\n /**\n * Focus the notification banner\n *\n * If `role=\"alert\"` is set, focus the element to help some assistive\n * technologies prioritise announcing it.\n *\n * You can turn off the auto-focus functionality by setting\n * `data-disable-auto-focus=\"true\"` in the component HTML. You might wish to\n * do this based on user research findings, or to avoid a clash with another\n * element which should be focused when the page loads.\n */\n if (\n this.$root.getAttribute('role') === 'alert' &&\n !this.config.disableAutoFocus\n ) {\n setFocus(this.$root)\n }\n }\n\n /**\n * Name for the component used when initialising using data-module attributes.\n */\n static moduleName = 'govuk-notification-banner'\n\n /**\n * Notification banner default config\n *\n * @see {@link NotificationBannerConfig}\n * @constant\n * @type {NotificationBannerConfig}\n */\n static defaults = Object.freeze({\n disableAutoFocus: false\n })\n\n /**\n * Notification banner config schema\n *\n * @constant\n * @satisfies {Schema<NotificationBannerConfig>}\n */\n static schema = Object.freeze({\n properties: {\n disableAutoFocus: { type: 'boolean' }\n }\n })\n}\n\n/**\n * Notification banner config\n *\n * @typedef {object} NotificationBannerConfig\n * @property {boolean} [disableAutoFocus=false] - If set to `true` the\n * notification banner will not be focussed when the page loads. This only\n * applies if the component has a `role` of `alert` – in other cases the\n * component will not be focused on page load, regardless of this option.\n */\n\n/**\n * @import { Schema } from '../../common/configuration.mjs'\n */\n"],"names":["setFocus","$element","options","_options$onBeforeFocu","isFocusable","getAttribute","setAttribute","onFocus","addEventListener","onBlur","once","_options$onBlur","call","removeAttribute","onBeforeFocus","focus","isInitialised","$root","moduleName","HTMLElement","hasAttribute","isSupported","$scope","document","body","classList","contains","isArray","option","Array","isObject","formatErrorMessage","Component","message","GOVUKFrontendError","Error","constructor","args","name","SupportError","supportMessage","HTMLScriptElement","prototype","ConfigError","ElementError","messageOrOptions","component","identifier","element","expectedType","InitError","componentOrMessage","_$root","childConstructor","elementType","checkSupport","checkInitialised","configOverride","Symbol","for","ConfigurableComponent","param","config","_config","defaults","datasetConfig","normaliseDataset","dataset","mergeConfigs","normaliseString","value","property","trimmedValue","trim","output","outputType","type","includes","length","isFinite","Number","schema","out","entries","Object","properties","entry","namespace","field","toString","extractConfigByNamespace","configObjects","formattedConfigObject","configObject","key","keys","override","newObject","current","keyParts","split","index","NotificationBanner","disableAutoFocus","freeze"],"mappings":"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"}
|
@@ -54,6 +54,9 @@ function formatErrorMessage(Component, message) {
|
|
54
54
|
* @typedef ComponentWithModuleName
|
55
55
|
* @property {string} moduleName - Name of the component
|
56
56
|
*/
|
57
|
+
/**
|
58
|
+
* @import { ObjectNested } from './configuration.mjs'
|
59
|
+
*/
|
57
60
|
|
58
61
|
class GOVUKFrontendError extends Error {
|
59
62
|
constructor(...args) {
|
@@ -105,10 +108,10 @@ class InitError extends GOVUKFrontendError {
|
|
105
108
|
}
|
106
109
|
}
|
107
110
|
/**
|
108
|
-
* @
|
111
|
+
* @import { ComponentWithModuleName } from '../common/index.mjs'
|
109
112
|
*/
|
110
113
|
|
111
|
-
class
|
114
|
+
class Component {
|
112
115
|
/**
|
113
116
|
* Returns the root element of the component
|
114
117
|
*
|
@@ -159,12 +162,12 @@ class GOVUKFrontendComponent {
|
|
159
162
|
*/
|
160
163
|
|
161
164
|
/**
|
162
|
-
* @typedef {typeof
|
165
|
+
* @typedef {typeof Component & ChildClass} ChildClassConstructor
|
163
166
|
*/
|
164
|
-
|
167
|
+
Component.elementType = HTMLElement;
|
165
168
|
|
166
169
|
const configOverride = Symbol.for('configOverride');
|
167
|
-
class ConfigurableComponent extends
|
170
|
+
class ConfigurableComponent extends Component {
|
168
171
|
[configOverride](param) {
|
169
172
|
return {};
|
170
173
|
}
|
@@ -182,7 +185,7 @@ class ConfigurableComponent extends GOVUKFrontendComponent {
|
|
182
185
|
super($root);
|
183
186
|
this._config = void 0;
|
184
187
|
const childConstructor = this.constructor;
|
185
|
-
if (
|
188
|
+
if (!isObject(childConstructor.defaults)) {
|
186
189
|
throw new ConfigError(formatErrorMessage(childConstructor, 'Config passed as parameter into constructor but no defaults defined'));
|
187
190
|
}
|
188
191
|
const datasetConfig = normaliseDataset(childConstructor, this._$root.dataset);
|
@@ -214,16 +217,19 @@ function normaliseString(value, property) {
|
|
214
217
|
return output;
|
215
218
|
}
|
216
219
|
function normaliseDataset(Component, dataset) {
|
217
|
-
if (
|
220
|
+
if (!isObject(Component.schema)) {
|
218
221
|
throw new ConfigError(formatErrorMessage(Component, 'Config passed as parameter into constructor but no schema defined'));
|
219
222
|
}
|
220
223
|
const out = {};
|
221
|
-
|
224
|
+
const entries = Object.entries(Component.schema.properties);
|
225
|
+
for (const entry of entries) {
|
226
|
+
const [namespace, property] = entry;
|
227
|
+
const field = namespace.toString();
|
222
228
|
if (field in dataset) {
|
223
229
|
out[field] = normaliseString(dataset[field], property);
|
224
230
|
}
|
225
231
|
if ((property == null ? void 0 : property.type) === 'object') {
|
226
|
-
out[field] = extractConfigByNamespace(Component.schema, dataset,
|
232
|
+
out[field] = extractConfigByNamespace(Component.schema, dataset, namespace);
|
227
233
|
}
|
228
234
|
}
|
229
235
|
return out;
|
@@ -249,13 +255,13 @@ function extractConfigByNamespace(schema, dataset, namespace) {
|
|
249
255
|
return;
|
250
256
|
}
|
251
257
|
const newObject = {
|
252
|
-
[namespace]:
|
258
|
+
[namespace]: {}
|
253
259
|
};
|
254
260
|
for (const [key, value] of Object.entries(dataset)) {
|
255
261
|
let current = newObject;
|
256
262
|
const keyParts = key.split('.');
|
257
263
|
for (const [index, name] of keyParts.entries()) {
|
258
|
-
if (
|
264
|
+
if (isObject(current)) {
|
259
265
|
if (index < keyParts.length - 1) {
|
260
266
|
if (!isObject(current[name])) {
|
261
267
|
current[name] = {};
|
@@ -272,9 +278,10 @@ function extractConfigByNamespace(schema, dataset, namespace) {
|
|
272
278
|
/**
|
273
279
|
* Schema for component config
|
274
280
|
*
|
281
|
+
* @template {Partial<Record<keyof ConfigurationType, unknown>>} ConfigurationType
|
275
282
|
* @typedef {object} Schema
|
276
|
-
* @property {
|
277
|
-
* @property {SchemaCondition[]} [anyOf] - List of schema conditions
|
283
|
+
* @property {Record<keyof ConfigurationType, SchemaProperty | undefined>} properties - Schema properties
|
284
|
+
* @property {SchemaCondition<ConfigurationType>[]} [anyOf] - List of schema conditions
|
278
285
|
*/
|
279
286
|
/**
|
280
287
|
* Schema property for component config
|
@@ -285,20 +292,21 @@ function extractConfigByNamespace(schema, dataset, namespace) {
|
|
285
292
|
/**
|
286
293
|
* Schema condition for component config
|
287
294
|
*
|
295
|
+
* @template {Partial<Record<keyof ConfigurationType, unknown>>} ConfigurationType
|
288
296
|
* @typedef {object} SchemaCondition
|
289
|
-
* @property {
|
297
|
+
* @property {(keyof ConfigurationType)[]} required - List of required config fields
|
290
298
|
* @property {string} errorMessage - Error message when required config fields not provided
|
291
299
|
*/
|
292
300
|
/**
|
293
|
-
* @template {
|
301
|
+
* @template {Partial<Record<keyof ConfigurationType, unknown>>} [ConfigurationType=ObjectNested]
|
294
302
|
* @typedef ChildClass
|
295
303
|
* @property {string} moduleName - The module name that'll be looked for in the DOM when initialising the component
|
296
|
-
* @property {Schema} [schema] - The schema of the component configuration
|
304
|
+
* @property {Schema<ConfigurationType>} [schema] - The schema of the component configuration
|
297
305
|
* @property {ConfigurationType} [defaults] - The default values of the configuration of the component
|
298
306
|
*/
|
299
307
|
/**
|
300
|
-
* @template {
|
301
|
-
* @typedef {typeof
|
308
|
+
* @template {Partial<Record<keyof ConfigurationType, unknown>>} [ConfigurationType=ObjectNested]
|
309
|
+
* @typedef {typeof Component & ChildClass<ConfigurationType>} ChildClassConstructor<ConfigurationType>
|
302
310
|
*/
|
303
311
|
|
304
312
|
/**
|
@@ -331,7 +339,7 @@ class NotificationBanner extends ConfigurableComponent {
|
|
331
339
|
*/
|
332
340
|
|
333
341
|
/**
|
334
|
-
* @
|
342
|
+
* @import { Schema } from '../../common/configuration.mjs'
|
335
343
|
*/
|
336
344
|
NotificationBanner.moduleName = 'govuk-notification-banner';
|
337
345
|
NotificationBanner.defaults = Object.freeze({
|