govuk_publishing_components 44.1.0 → 44.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/govuk_publishing_components/version.rb +1 -1
- data/node_modules/govuk-frontend/dist/govuk/all.bundle.js +336 -225
- data/node_modules/govuk-frontend/dist/govuk/all.bundle.js.map +1 -1
- data/node_modules/govuk-frontend/dist/govuk/all.bundle.mjs +334 -226
- data/node_modules/govuk-frontend/dist/govuk/all.bundle.mjs.map +1 -1
- data/node_modules/govuk-frontend/dist/govuk/all.mjs +3 -0
- data/node_modules/govuk-frontend/dist/govuk/all.mjs.map +1 -1
- data/node_modules/govuk-frontend/dist/govuk/assets/images/govuk-crest.svg +1 -0
- data/node_modules/govuk-frontend/dist/govuk/common/govuk-frontend-version.mjs +1 -1
- data/node_modules/govuk-frontend/dist/govuk/common/index.mjs +21 -1
- data/node_modules/govuk-frontend/dist/govuk/common/index.mjs.map +1 -1
- data/node_modules/govuk-frontend/dist/govuk/components/_index.scss +1 -0
- data/node_modules/govuk-frontend/dist/govuk/components/_index.scss.map +1 -1
- data/node_modules/govuk-frontend/dist/govuk/components/accordion/accordion.bundle.js +92 -26
- 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 +92 -26
- 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 +12 -21
- 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 +86 -20
- 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 +86 -20
- 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 +6 -16
- data/node_modules/govuk-frontend/dist/govuk/components/button/button.mjs.map +1 -1
- data/node_modules/govuk-frontend/dist/govuk/components/character-count/character-count.bundle.js +89 -23
- 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 +89 -23
- 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 +10 -19
- data/node_modules/govuk-frontend/dist/govuk/components/character-count/character-count.mjs.map +1 -1
- data/node_modules/govuk-frontend/dist/govuk/components/checkboxes/checkboxes.bundle.js +113 -47
- 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 +113 -47
- 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 +7 -16
- data/node_modules/govuk-frontend/dist/govuk/components/checkboxes/checkboxes.mjs.map +1 -1
- data/node_modules/govuk-frontend/dist/govuk/components/details/_index.scss +7 -2
- data/node_modules/govuk-frontend/dist/govuk/components/details/_index.scss.map +1 -1
- data/node_modules/govuk-frontend/dist/govuk/components/error-summary/error-summary.bundle.js +86 -20
- 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 +86 -20
- 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 +6 -16
- 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 +87 -21
- 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 +87 -21
- 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 +7 -16
- 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/footer/_index.scss +8 -10
- data/node_modules/govuk-frontend/dist/govuk/components/footer/_index.scss.map +1 -1
- data/node_modules/govuk-frontend/dist/govuk/components/header/_index.scss +8 -0
- data/node_modules/govuk-frontend/dist/govuk/components/header/_index.scss.map +1 -1
- data/node_modules/govuk-frontend/dist/govuk/components/header/fixtures.json +12 -0
- data/node_modules/govuk-frontend/dist/govuk/components/header/header.bundle.js +87 -21
- 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 +87 -21
- 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 +7 -16
- data/node_modules/govuk-frontend/dist/govuk/components/header/header.mjs.map +1 -1
- data/node_modules/govuk-frontend/dist/govuk/components/header/template-with-full-width-border.html +24 -0
- data/node_modules/govuk-frontend/dist/govuk/components/notification-banner/notification-banner.bundle.js +86 -20
- 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 +86 -20
- 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 +6 -16
- 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/password-input.bundle.js +89 -23
- 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 +89 -23
- 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 +9 -18
- data/node_modules/govuk-frontend/dist/govuk/components/password-input/password-input.mjs.map +1 -1
- data/node_modules/govuk-frontend/dist/govuk/components/radios/radios.bundle.js +113 -47
- 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 +113 -47
- 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 +7 -16
- data/node_modules/govuk-frontend/dist/govuk/components/radios/radios.mjs.map +1 -1
- data/node_modules/govuk-frontend/dist/govuk/components/service-navigation/README.md +15 -0
- data/node_modules/govuk-frontend/dist/govuk/components/service-navigation/_index.scss +168 -0
- data/node_modules/govuk-frontend/dist/govuk/components/service-navigation/_index.scss.map +1 -0
- data/node_modules/govuk-frontend/dist/govuk/components/service-navigation/_service-navigation.scss +4 -0
- data/node_modules/govuk-frontend/dist/govuk/components/service-navigation/_service-navigation.scss.map +1 -0
- data/node_modules/govuk-frontend/dist/govuk/components/service-navigation/fixtures.json +464 -0
- data/node_modules/govuk-frontend/dist/govuk/components/service-navigation/macro-options.json +138 -0
- data/node_modules/govuk-frontend/dist/govuk/components/service-navigation/macro.njk +3 -0
- data/node_modules/govuk-frontend/dist/govuk/components/service-navigation/service-navigation.bundle.js +249 -0
- data/node_modules/govuk-frontend/dist/govuk/components/service-navigation/service-navigation.bundle.js.map +1 -0
- data/node_modules/govuk-frontend/dist/govuk/components/service-navigation/service-navigation.bundle.mjs +241 -0
- data/node_modules/govuk-frontend/dist/govuk/components/service-navigation/service-navigation.bundle.mjs.map +1 -0
- data/node_modules/govuk-frontend/dist/govuk/components/service-navigation/service-navigation.mjs +85 -0
- data/node_modules/govuk-frontend/dist/govuk/components/service-navigation/service-navigation.mjs.map +1 -0
- data/node_modules/govuk-frontend/dist/govuk/components/service-navigation/template-default.html +57 -0
- data/node_modules/govuk-frontend/dist/govuk/components/service-navigation/template-with-html-navigation-items.html +49 -0
- data/node_modules/govuk-frontend/dist/govuk/components/service-navigation/template-with-large-navigation.html +153 -0
- data/node_modules/govuk-frontend/dist/govuk/components/service-navigation/template-with-long-service-name.html +20 -0
- data/node_modules/govuk-frontend/dist/govuk/components/service-navigation/template-with-navigation-with-a-current-item.html +58 -0
- data/node_modules/govuk-frontend/dist/govuk/components/service-navigation/template-with-navigation-with-an-active-item.html +58 -0
- data/node_modules/govuk-frontend/dist/govuk/components/service-navigation/template-with-non-link-navigation-items.html +49 -0
- data/node_modules/govuk-frontend/dist/govuk/components/service-navigation/template-with-service-link.html +20 -0
- data/node_modules/govuk-frontend/dist/govuk/components/service-navigation/template-with-service-name-and-navigation.html +63 -0
- data/node_modules/govuk-frontend/dist/govuk/components/service-navigation/template-with-service-name.html +18 -0
- data/node_modules/govuk-frontend/dist/govuk/components/service-navigation/template.njk +102 -0
- data/node_modules/govuk-frontend/dist/govuk/components/skip-link/skip-link.bundle.js +93 -26
- 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 +93 -26
- 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 +13 -21
- data/node_modules/govuk-frontend/dist/govuk/components/skip-link/skip-link.mjs.map +1 -1
- data/node_modules/govuk-frontend/dist/govuk/components/tabs/tabs.bundle.js +93 -27
- 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 +93 -27
- 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 +13 -22
- data/node_modules/govuk-frontend/dist/govuk/components/tabs/tabs.mjs.map +1 -1
- data/node_modules/govuk-frontend/dist/govuk/components/warning-text/_index.scss +4 -3
- data/node_modules/govuk-frontend/dist/govuk/components/warning-text/_index.scss.map +1 -1
- data/node_modules/govuk-frontend/dist/govuk/core/_govuk-frontend-properties.scss +1 -1
- data/node_modules/govuk-frontend/dist/govuk/errors/index.mjs +16 -3
- data/node_modules/govuk-frontend/dist/govuk/errors/index.mjs.map +1 -1
- data/node_modules/govuk-frontend/dist/govuk/govuk-frontend-component.mjs +49 -5
- data/node_modules/govuk-frontend/dist/govuk/govuk-frontend-component.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/init.mjs +72 -10
- data/node_modules/govuk-frontend/dist/govuk/init.mjs.map +1 -1
- data/node_modules/govuk-frontend/dist/govuk/settings/_colours-organisations.scss +3 -0
- data/node_modules/govuk-frontend/dist/govuk/settings/_colours-organisations.scss.map +1 -1
- data/node_modules/govuk-frontend/govuk-prototype-kit.config.json +5 -1
- data/node_modules/govuk-frontend/package.json +8 -8
- metadata +29 -4
- data/node_modules/govuk-frontend/dist/govuk/assets/images/govuk-crest-2x.png +0 -0
- data/node_modules/govuk-frontend/dist/govuk/assets/images/govuk-crest.png +0 -0
@@ -1,4 +1,4 @@
|
|
1
|
-
const version = '5.
|
1
|
+
const version = '5.7.0';
|
2
2
|
|
3
3
|
function normaliseString(value, property) {
|
4
4
|
const trimmedValue = value ? value.trim() : '';
|
@@ -108,6 +108,19 @@ function setFocus($element, options = {}) {
|
|
108
108
|
(_options$onBeforeFocu = options.onBeforeFocus) == null || _options$onBeforeFocu.call($element);
|
109
109
|
$element.focus();
|
110
110
|
}
|
111
|
+
function isInitialised($root, moduleName) {
|
112
|
+
return $root instanceof HTMLElement && $root.hasAttribute(`data-${moduleName}-init`);
|
113
|
+
}
|
114
|
+
|
115
|
+
/**
|
116
|
+
* Checks if GOV.UK Frontend is supported on this page
|
117
|
+
*
|
118
|
+
* Some browsers will load and run our JavaScript but GOV.UK Frontend
|
119
|
+
* won't be supported.
|
120
|
+
*
|
121
|
+
* @param {HTMLElement | null} [$scope] - (internal) `<body>` HTML element checked for browser support
|
122
|
+
* @returns {boolean} Whether GOV.UK Frontend is supported on this page
|
123
|
+
*/
|
111
124
|
function isSupported($scope = document.body) {
|
112
125
|
if (!$scope) {
|
113
126
|
return false;
|
@@ -140,6 +153,9 @@ function isArray(option) {
|
|
140
153
|
function isObject(option) {
|
141
154
|
return !!option && typeof option === 'object' && !isArray(option);
|
142
155
|
}
|
156
|
+
function formatErrorMessage(Component, message) {
|
157
|
+
return `${Component.moduleName}: ${message}`;
|
158
|
+
}
|
143
159
|
|
144
160
|
/**
|
145
161
|
* Schema for component config
|
@@ -163,6 +179,10 @@ function isObject(option) {
|
|
163
179
|
* @property {string[]} required - List of required config fields
|
164
180
|
* @property {string} errorMessage - Error message when required config fields not provided
|
165
181
|
*/
|
182
|
+
/**
|
183
|
+
* @typedef ComponentWithModuleName
|
184
|
+
* @property {string} moduleName - Name of the component
|
185
|
+
*/
|
166
186
|
|
167
187
|
function normaliseDataset(Component, dataset) {
|
168
188
|
const out = {};
|
@@ -206,30 +226,85 @@ class ElementError extends GOVUKFrontendError {
|
|
206
226
|
let message = typeof messageOrOptions === 'string' ? messageOrOptions : '';
|
207
227
|
if (typeof messageOrOptions === 'object') {
|
208
228
|
const {
|
209
|
-
|
229
|
+
component,
|
210
230
|
identifier,
|
211
231
|
element,
|
212
232
|
expectedType
|
213
233
|
} = messageOrOptions;
|
214
|
-
message =
|
234
|
+
message = identifier;
|
215
235
|
message += element ? ` is not of type ${expectedType != null ? expectedType : 'HTMLElement'}` : ' not found';
|
236
|
+
message = formatErrorMessage(component, message);
|
216
237
|
}
|
217
238
|
super(message);
|
218
239
|
this.name = 'ElementError';
|
219
240
|
}
|
220
241
|
}
|
242
|
+
class InitError extends GOVUKFrontendError {
|
243
|
+
constructor(componentOrMessage) {
|
244
|
+
const message = typeof componentOrMessage === 'string' ? componentOrMessage : formatErrorMessage(componentOrMessage, `Root element (\`$root\`) already initialised`);
|
245
|
+
super(message);
|
246
|
+
this.name = 'InitError';
|
247
|
+
}
|
248
|
+
}
|
249
|
+
/**
|
250
|
+
* @typedef {import('../common/index.mjs').ComponentWithModuleName} ComponentWithModuleName
|
251
|
+
*/
|
221
252
|
|
222
253
|
class GOVUKFrontendComponent {
|
223
|
-
|
224
|
-
|
254
|
+
/**
|
255
|
+
* Returns the root element of the component
|
256
|
+
*
|
257
|
+
* @protected
|
258
|
+
* @returns {RootElementType} - the root element of component
|
259
|
+
*/
|
260
|
+
get $root() {
|
261
|
+
return this._$root;
|
262
|
+
}
|
263
|
+
constructor($root) {
|
264
|
+
this._$root = void 0;
|
265
|
+
const childConstructor = this.constructor;
|
266
|
+
if (typeof childConstructor.moduleName !== 'string') {
|
267
|
+
throw new InitError(`\`moduleName\` not defined in component`);
|
268
|
+
}
|
269
|
+
if (!($root instanceof childConstructor.elementType)) {
|
270
|
+
throw new ElementError({
|
271
|
+
element: $root,
|
272
|
+
component: childConstructor,
|
273
|
+
identifier: 'Root element (`$root`)',
|
274
|
+
expectedType: childConstructor.elementType.name
|
275
|
+
});
|
276
|
+
} else {
|
277
|
+
this._$root = $root;
|
278
|
+
}
|
279
|
+
childConstructor.checkSupport();
|
280
|
+
this.checkInitialised();
|
281
|
+
const moduleName = childConstructor.moduleName;
|
282
|
+
this.$root.setAttribute(`data-${moduleName}-init`, '');
|
283
|
+
}
|
284
|
+
checkInitialised() {
|
285
|
+
const constructor = this.constructor;
|
286
|
+
const moduleName = constructor.moduleName;
|
287
|
+
if (moduleName && isInitialised(this.$root, moduleName)) {
|
288
|
+
throw new InitError(constructor);
|
289
|
+
}
|
225
290
|
}
|
226
|
-
checkSupport() {
|
291
|
+
static checkSupport() {
|
227
292
|
if (!isSupported()) {
|
228
293
|
throw new SupportError();
|
229
294
|
}
|
230
295
|
}
|
231
296
|
}
|
232
297
|
|
298
|
+
/**
|
299
|
+
* @typedef ChildClass
|
300
|
+
* @property {string} moduleName - The module name that'll be looked for in the DOM when initialising the component
|
301
|
+
*/
|
302
|
+
|
303
|
+
/**
|
304
|
+
* @typedef {typeof GOVUKFrontendComponent & ChildClass} ChildClassConstructor
|
305
|
+
*/
|
306
|
+
GOVUKFrontendComponent.elementType = HTMLElement;
|
307
|
+
|
233
308
|
class I18n {
|
234
309
|
constructor(translations = {}, config = {}) {
|
235
310
|
var _config$locale;
|
@@ -439,12 +514,11 @@ I18n.pluralRules = {
|
|
439
514
|
*/
|
440
515
|
class Accordion extends GOVUKFrontendComponent {
|
441
516
|
/**
|
442
|
-
* @param {Element | null} $
|
517
|
+
* @param {Element | null} $root - HTML element to use for accordion
|
443
518
|
* @param {AccordionConfig} [config] - Accordion config
|
444
519
|
*/
|
445
|
-
constructor($
|
446
|
-
super();
|
447
|
-
this.$module = void 0;
|
520
|
+
constructor($root, config = {}) {
|
521
|
+
super($root);
|
448
522
|
this.config = void 0;
|
449
523
|
this.i18n = void 0;
|
450
524
|
this.controlsClass = 'govuk-accordion__controls';
|
@@ -470,20 +544,12 @@ class Accordion extends GOVUKFrontendComponent {
|
|
470
544
|
this.$showAllButton = null;
|
471
545
|
this.$showAllIcon = null;
|
472
546
|
this.$showAllText = null;
|
473
|
-
|
474
|
-
throw new ElementError({
|
475
|
-
componentName: 'Accordion',
|
476
|
-
element: $module,
|
477
|
-
identifier: 'Root element (`$module`)'
|
478
|
-
});
|
479
|
-
}
|
480
|
-
this.$module = $module;
|
481
|
-
this.config = mergeConfigs(Accordion.defaults, config, normaliseDataset(Accordion, $module.dataset));
|
547
|
+
this.config = mergeConfigs(Accordion.defaults, config, normaliseDataset(Accordion, this.$root.dataset));
|
482
548
|
this.i18n = new I18n(this.config.i18n);
|
483
|
-
const $sections = this.$
|
549
|
+
const $sections = this.$root.querySelectorAll(`.${this.sectionClass}`);
|
484
550
|
if (!$sections.length) {
|
485
551
|
throw new ElementError({
|
486
|
-
|
552
|
+
component: Accordion,
|
487
553
|
identifier: `Sections (\`<div class="${this.sectionClass}">\`)`
|
488
554
|
});
|
489
555
|
}
|
@@ -503,7 +569,7 @@ class Accordion extends GOVUKFrontendComponent {
|
|
503
569
|
const $accordionControls = document.createElement('div');
|
504
570
|
$accordionControls.setAttribute('class', this.controlsClass);
|
505
571
|
$accordionControls.appendChild(this.$showAllButton);
|
506
|
-
this.$
|
572
|
+
this.$root.insertBefore($accordionControls, this.$root.firstChild);
|
507
573
|
this.$showAllText = document.createElement('span');
|
508
574
|
this.$showAllText.classList.add(this.showAllTextClass);
|
509
575
|
this.$showAllButton.appendChild(this.$showAllText);
|
@@ -517,7 +583,7 @@ class Accordion extends GOVUKFrontendComponent {
|
|
517
583
|
const $header = $section.querySelector(`.${this.sectionHeaderClass}`);
|
518
584
|
if (!$header) {
|
519
585
|
throw new ElementError({
|
520
|
-
|
586
|
+
component: Accordion,
|
521
587
|
identifier: `Section headers (\`<div class="${this.sectionHeaderClass}">\`)`
|
522
588
|
});
|
523
589
|
}
|
@@ -533,19 +599,19 @@ class Accordion extends GOVUKFrontendComponent {
|
|
533
599
|
const $summary = $header.querySelector(`.${this.sectionSummaryClass}`);
|
534
600
|
if (!$heading) {
|
535
601
|
throw new ElementError({
|
536
|
-
|
602
|
+
component: Accordion,
|
537
603
|
identifier: `Section heading (\`.${this.sectionHeadingClass}\`)`
|
538
604
|
});
|
539
605
|
}
|
540
606
|
if (!$span) {
|
541
607
|
throw new ElementError({
|
542
|
-
|
608
|
+
component: Accordion,
|
543
609
|
identifier: `Section button placeholder (\`<span class="${this.sectionButtonClass}">\`)`
|
544
610
|
});
|
545
611
|
}
|
546
612
|
const $button = document.createElement('button');
|
547
613
|
$button.setAttribute('type', 'button');
|
548
|
-
$button.setAttribute('aria-controls', `${this.$
|
614
|
+
$button.setAttribute('aria-controls', `${this.$root.id}-content-${index + 1}`);
|
549
615
|
for (const attr of Array.from($span.attributes)) {
|
550
616
|
if (attr.name !== 'id') {
|
551
617
|
$button.setAttribute(attr.name, attr.value);
|
@@ -619,7 +685,7 @@ class Accordion extends GOVUKFrontendComponent {
|
|
619
685
|
const $content = $section.querySelector(`.${this.sectionContentClass}`);
|
620
686
|
if (!$content) {
|
621
687
|
throw new ElementError({
|
622
|
-
|
688
|
+
component: Accordion,
|
623
689
|
identifier: `Section content (\`<div class="${this.sectionContentClass}">\`)`
|
624
690
|
});
|
625
691
|
}
|
@@ -782,25 +848,16 @@ const DEBOUNCE_TIMEOUT_IN_SECONDS = 1;
|
|
782
848
|
*/
|
783
849
|
class Button extends GOVUKFrontendComponent {
|
784
850
|
/**
|
785
|
-
* @param {Element | null} $
|
851
|
+
* @param {Element | null} $root - HTML element to use for button
|
786
852
|
* @param {ButtonConfig} [config] - Button config
|
787
853
|
*/
|
788
|
-
constructor($
|
789
|
-
super();
|
790
|
-
this.$module = void 0;
|
854
|
+
constructor($root, config = {}) {
|
855
|
+
super($root);
|
791
856
|
this.config = void 0;
|
792
857
|
this.debounceFormSubmitTimer = null;
|
793
|
-
|
794
|
-
|
795
|
-
|
796
|
-
element: $module,
|
797
|
-
identifier: 'Root element (`$module`)'
|
798
|
-
});
|
799
|
-
}
|
800
|
-
this.$module = $module;
|
801
|
-
this.config = mergeConfigs(Button.defaults, config, normaliseDataset(Button, $module.dataset));
|
802
|
-
this.$module.addEventListener('keydown', event => this.handleKeyDown(event));
|
803
|
-
this.$module.addEventListener('click', event => this.debounce(event));
|
858
|
+
this.config = mergeConfigs(Button.defaults, config, normaliseDataset(Button, this.$root.dataset));
|
859
|
+
this.$root.addEventListener('keydown', event => this.handleKeyDown(event));
|
860
|
+
this.$root.addEventListener('click', event => this.debounce(event));
|
804
861
|
}
|
805
862
|
handleKeyDown(event) {
|
806
863
|
const $target = event.target;
|
@@ -868,13 +925,12 @@ function closestAttributeValue($element, attributeName) {
|
|
868
925
|
*/
|
869
926
|
class CharacterCount extends GOVUKFrontendComponent {
|
870
927
|
/**
|
871
|
-
* @param {Element | null} $
|
928
|
+
* @param {Element | null} $root - HTML element to use for character count
|
872
929
|
* @param {CharacterCountConfig} [config] - Character count config
|
873
930
|
*/
|
874
|
-
constructor($
|
931
|
+
constructor($root, config = {}) {
|
875
932
|
var _ref, _this$config$maxwords;
|
876
|
-
super();
|
877
|
-
this.$module = void 0;
|
933
|
+
super($root);
|
878
934
|
this.$textarea = void 0;
|
879
935
|
this.$visibleCountMessage = void 0;
|
880
936
|
this.$screenReaderCountMessage = void 0;
|
@@ -884,23 +940,16 @@ class CharacterCount extends GOVUKFrontendComponent {
|
|
884
940
|
this.config = void 0;
|
885
941
|
this.i18n = void 0;
|
886
942
|
this.maxLength = void 0;
|
887
|
-
|
888
|
-
throw new ElementError({
|
889
|
-
componentName: 'Character count',
|
890
|
-
element: $module,
|
891
|
-
identifier: 'Root element (`$module`)'
|
892
|
-
});
|
893
|
-
}
|
894
|
-
const $textarea = $module.querySelector('.govuk-js-character-count');
|
943
|
+
const $textarea = this.$root.querySelector('.govuk-js-character-count');
|
895
944
|
if (!($textarea instanceof HTMLTextAreaElement || $textarea instanceof HTMLInputElement)) {
|
896
945
|
throw new ElementError({
|
897
|
-
|
946
|
+
component: CharacterCount,
|
898
947
|
element: $textarea,
|
899
948
|
expectedType: 'HTMLTextareaElement or HTMLInputElement',
|
900
949
|
identifier: 'Form field (`.govuk-js-character-count`)'
|
901
950
|
});
|
902
951
|
}
|
903
|
-
const datasetConfig = normaliseDataset(CharacterCount,
|
952
|
+
const datasetConfig = normaliseDataset(CharacterCount, this.$root.dataset);
|
904
953
|
let configOverrides = {};
|
905
954
|
if ('maxwords' in datasetConfig || 'maxlength' in datasetConfig) {
|
906
955
|
configOverrides = {
|
@@ -911,19 +960,18 @@ class CharacterCount extends GOVUKFrontendComponent {
|
|
911
960
|
this.config = mergeConfigs(CharacterCount.defaults, config, configOverrides, datasetConfig);
|
912
961
|
const errors = validateConfig(CharacterCount.schema, this.config);
|
913
962
|
if (errors[0]) {
|
914
|
-
throw new ConfigError(
|
963
|
+
throw new ConfigError(formatErrorMessage(CharacterCount, errors[0]));
|
915
964
|
}
|
916
965
|
this.i18n = new I18n(this.config.i18n, {
|
917
|
-
locale: closestAttributeValue(
|
966
|
+
locale: closestAttributeValue(this.$root, 'lang')
|
918
967
|
});
|
919
968
|
this.maxLength = (_ref = (_this$config$maxwords = this.config.maxwords) != null ? _this$config$maxwords : this.config.maxlength) != null ? _ref : Infinity;
|
920
|
-
this.$module = $module;
|
921
969
|
this.$textarea = $textarea;
|
922
970
|
const textareaDescriptionId = `${this.$textarea.id}-info`;
|
923
971
|
const $textareaDescription = document.getElementById(textareaDescriptionId);
|
924
972
|
if (!$textareaDescription) {
|
925
973
|
throw new ElementError({
|
926
|
-
|
974
|
+
component: CharacterCount,
|
927
975
|
element: $textareaDescription,
|
928
976
|
identifier: `Count message (\`id="${textareaDescriptionId}"\`)`
|
929
977
|
});
|
@@ -1167,27 +1215,18 @@ class Checkboxes extends GOVUKFrontendComponent {
|
|
1167
1215
|
* (for example if the user has navigated back), and set up event handlers to
|
1168
1216
|
* keep the reveal in sync with the checkbox state.
|
1169
1217
|
*
|
1170
|
-
* @param {Element | null} $
|
1218
|
+
* @param {Element | null} $root - HTML element to use for checkboxes
|
1171
1219
|
*/
|
1172
|
-
constructor($
|
1173
|
-
super();
|
1174
|
-
this.$module = void 0;
|
1220
|
+
constructor($root) {
|
1221
|
+
super($root);
|
1175
1222
|
this.$inputs = void 0;
|
1176
|
-
|
1177
|
-
throw new ElementError({
|
1178
|
-
componentName: 'Checkboxes',
|
1179
|
-
element: $module,
|
1180
|
-
identifier: 'Root element (`$module`)'
|
1181
|
-
});
|
1182
|
-
}
|
1183
|
-
const $inputs = $module.querySelectorAll('input[type="checkbox"]');
|
1223
|
+
const $inputs = this.$root.querySelectorAll('input[type="checkbox"]');
|
1184
1224
|
if (!$inputs.length) {
|
1185
1225
|
throw new ElementError({
|
1186
|
-
|
1226
|
+
component: Checkboxes,
|
1187
1227
|
identifier: 'Form inputs (`<input type="checkbox">`)'
|
1188
1228
|
});
|
1189
1229
|
}
|
1190
|
-
this.$module = $module;
|
1191
1230
|
this.$inputs = $inputs;
|
1192
1231
|
this.$inputs.forEach($input => {
|
1193
1232
|
const targetId = $input.getAttribute('data-aria-controls');
|
@@ -1196,7 +1235,7 @@ class Checkboxes extends GOVUKFrontendComponent {
|
|
1196
1235
|
}
|
1197
1236
|
if (!document.getElementById(targetId)) {
|
1198
1237
|
throw new ElementError({
|
1199
|
-
|
1238
|
+
component: Checkboxes,
|
1200
1239
|
identifier: `Conditional reveal (\`id="${targetId}"\`)`
|
1201
1240
|
});
|
1202
1241
|
}
|
@@ -1205,7 +1244,7 @@ class Checkboxes extends GOVUKFrontendComponent {
|
|
1205
1244
|
});
|
1206
1245
|
window.addEventListener('pageshow', () => this.syncAllConditionalReveals());
|
1207
1246
|
this.syncAllConditionalReveals();
|
1208
|
-
this.$
|
1247
|
+
this.$root.addEventListener('click', event => this.handleClick(event));
|
1209
1248
|
}
|
1210
1249
|
syncAllConditionalReveals() {
|
1211
1250
|
this.$inputs.forEach($input => this.syncConditionalRevealWithInputState($input));
|
@@ -1274,26 +1313,17 @@ Checkboxes.moduleName = 'govuk-checkboxes';
|
|
1274
1313
|
*/
|
1275
1314
|
class ErrorSummary extends GOVUKFrontendComponent {
|
1276
1315
|
/**
|
1277
|
-
* @param {Element | null} $
|
1316
|
+
* @param {Element | null} $root - HTML element to use for error summary
|
1278
1317
|
* @param {ErrorSummaryConfig} [config] - Error summary config
|
1279
1318
|
*/
|
1280
|
-
constructor($
|
1281
|
-
super();
|
1282
|
-
this.$module = void 0;
|
1319
|
+
constructor($root, config = {}) {
|
1320
|
+
super($root);
|
1283
1321
|
this.config = void 0;
|
1284
|
-
|
1285
|
-
throw new ElementError({
|
1286
|
-
componentName: 'Error summary',
|
1287
|
-
element: $module,
|
1288
|
-
identifier: 'Root element (`$module`)'
|
1289
|
-
});
|
1290
|
-
}
|
1291
|
-
this.$module = $module;
|
1292
|
-
this.config = mergeConfigs(ErrorSummary.defaults, config, normaliseDataset(ErrorSummary, $module.dataset));
|
1322
|
+
this.config = mergeConfigs(ErrorSummary.defaults, config, normaliseDataset(ErrorSummary, this.$root.dataset));
|
1293
1323
|
if (!this.config.disableAutoFocus) {
|
1294
|
-
setFocus(this.$
|
1324
|
+
setFocus(this.$root);
|
1295
1325
|
}
|
1296
|
-
this.$
|
1326
|
+
this.$root.addEventListener('click', event => this.handleClick(event));
|
1297
1327
|
}
|
1298
1328
|
handleClick(event) {
|
1299
1329
|
const $target = event.target;
|
@@ -1377,12 +1407,11 @@ ErrorSummary.schema = Object.freeze({
|
|
1377
1407
|
*/
|
1378
1408
|
class ExitThisPage extends GOVUKFrontendComponent {
|
1379
1409
|
/**
|
1380
|
-
* @param {Element | null} $
|
1410
|
+
* @param {Element | null} $root - HTML element that wraps the Exit This Page button
|
1381
1411
|
* @param {ExitThisPageConfig} [config] - Exit This Page config
|
1382
1412
|
*/
|
1383
|
-
constructor($
|
1384
|
-
super();
|
1385
|
-
this.$module = void 0;
|
1413
|
+
constructor($root, config = {}) {
|
1414
|
+
super($root);
|
1386
1415
|
this.config = void 0;
|
1387
1416
|
this.i18n = void 0;
|
1388
1417
|
this.$button = void 0;
|
@@ -1395,25 +1424,17 @@ class ExitThisPage extends GOVUKFrontendComponent {
|
|
1395
1424
|
this.timeoutTime = 5000;
|
1396
1425
|
this.keypressTimeoutId = null;
|
1397
1426
|
this.timeoutMessageId = null;
|
1398
|
-
|
1399
|
-
throw new ElementError({
|
1400
|
-
componentName: 'Exit this page',
|
1401
|
-
element: $module,
|
1402
|
-
identifier: 'Root element (`$module`)'
|
1403
|
-
});
|
1404
|
-
}
|
1405
|
-
const $button = $module.querySelector('.govuk-exit-this-page__button');
|
1427
|
+
const $button = this.$root.querySelector('.govuk-exit-this-page__button');
|
1406
1428
|
if (!($button instanceof HTMLAnchorElement)) {
|
1407
1429
|
throw new ElementError({
|
1408
|
-
|
1430
|
+
component: ExitThisPage,
|
1409
1431
|
element: $button,
|
1410
1432
|
expectedType: 'HTMLAnchorElement',
|
1411
1433
|
identifier: 'Button (`.govuk-exit-this-page__button`)'
|
1412
1434
|
});
|
1413
1435
|
}
|
1414
|
-
this.config = mergeConfigs(ExitThisPage.defaults, config, normaliseDataset(ExitThisPage,
|
1436
|
+
this.config = mergeConfigs(ExitThisPage.defaults, config, normaliseDataset(ExitThisPage, this.$root.dataset));
|
1415
1437
|
this.i18n = new I18n(this.config.i18n);
|
1416
|
-
this.$module = $module;
|
1417
1438
|
this.$button = $button;
|
1418
1439
|
const $skiplinkButton = document.querySelector('.govuk-js-exit-this-page-skiplink');
|
1419
1440
|
if ($skiplinkButton instanceof HTMLAnchorElement) {
|
@@ -1432,7 +1453,7 @@ class ExitThisPage extends GOVUKFrontendComponent {
|
|
1432
1453
|
this.$updateSpan = document.createElement('span');
|
1433
1454
|
this.$updateSpan.setAttribute('role', 'status');
|
1434
1455
|
this.$updateSpan.className = 'govuk-visually-hidden';
|
1435
|
-
this.$
|
1456
|
+
this.$root.appendChild(this.$updateSpan);
|
1436
1457
|
}
|
1437
1458
|
initButtonClickHandler() {
|
1438
1459
|
this.$button.addEventListener('click', this.handleClick.bind(this));
|
@@ -1607,38 +1628,29 @@ class Header extends GOVUKFrontendComponent {
|
|
1607
1628
|
* Apply a matchMedia for desktop which will trigger a state sync if the
|
1608
1629
|
* browser viewport moves between states.
|
1609
1630
|
*
|
1610
|
-
* @param {Element | null} $
|
1631
|
+
* @param {Element | null} $root - HTML element to use for header
|
1611
1632
|
*/
|
1612
|
-
constructor($
|
1613
|
-
super();
|
1614
|
-
this.$module = void 0;
|
1633
|
+
constructor($root) {
|
1634
|
+
super($root);
|
1615
1635
|
this.$menuButton = void 0;
|
1616
1636
|
this.$menu = void 0;
|
1617
1637
|
this.menuIsOpen = false;
|
1618
1638
|
this.mql = null;
|
1619
|
-
|
1620
|
-
throw new ElementError({
|
1621
|
-
componentName: 'Header',
|
1622
|
-
element: $module,
|
1623
|
-
identifier: 'Root element (`$module`)'
|
1624
|
-
});
|
1625
|
-
}
|
1626
|
-
this.$module = $module;
|
1627
|
-
const $menuButton = $module.querySelector('.govuk-js-header-toggle');
|
1639
|
+
const $menuButton = this.$root.querySelector('.govuk-js-header-toggle');
|
1628
1640
|
if (!$menuButton) {
|
1629
1641
|
return this;
|
1630
1642
|
}
|
1631
1643
|
const menuId = $menuButton.getAttribute('aria-controls');
|
1632
1644
|
if (!menuId) {
|
1633
1645
|
throw new ElementError({
|
1634
|
-
|
1646
|
+
component: Header,
|
1635
1647
|
identifier: 'Navigation button (`<button class="govuk-js-header-toggle">`) attribute (`aria-controls`)'
|
1636
1648
|
});
|
1637
1649
|
}
|
1638
1650
|
const $menu = document.getElementById(menuId);
|
1639
1651
|
if (!$menu) {
|
1640
1652
|
throw new ElementError({
|
1641
|
-
|
1653
|
+
component: Header,
|
1642
1654
|
element: $menu,
|
1643
1655
|
identifier: `Navigation (\`<ul id="${menuId}">\`)`
|
1644
1656
|
});
|
@@ -1652,7 +1664,7 @@ class Header extends GOVUKFrontendComponent {
|
|
1652
1664
|
const breakpoint = getBreakpoint('desktop');
|
1653
1665
|
if (!breakpoint.value) {
|
1654
1666
|
throw new ElementError({
|
1655
|
-
|
1667
|
+
component: Header,
|
1656
1668
|
identifier: `CSS custom property (\`${breakpoint.property}\`) on pseudo-class \`:root\``
|
1657
1669
|
});
|
1658
1670
|
}
|
@@ -1695,24 +1707,15 @@ Header.moduleName = 'govuk-header';
|
|
1695
1707
|
*/
|
1696
1708
|
class NotificationBanner extends GOVUKFrontendComponent {
|
1697
1709
|
/**
|
1698
|
-
* @param {Element | null} $
|
1710
|
+
* @param {Element | null} $root - HTML element to use for notification banner
|
1699
1711
|
* @param {NotificationBannerConfig} [config] - Notification banner config
|
1700
1712
|
*/
|
1701
|
-
constructor($
|
1702
|
-
super();
|
1703
|
-
this.$module = void 0;
|
1713
|
+
constructor($root, config = {}) {
|
1714
|
+
super($root);
|
1704
1715
|
this.config = void 0;
|
1705
|
-
|
1706
|
-
|
1707
|
-
|
1708
|
-
element: $module,
|
1709
|
-
identifier: 'Root element (`$module`)'
|
1710
|
-
});
|
1711
|
-
}
|
1712
|
-
this.$module = $module;
|
1713
|
-
this.config = mergeConfigs(NotificationBanner.defaults, config, normaliseDataset(NotificationBanner, $module.dataset));
|
1714
|
-
if (this.$module.getAttribute('role') === 'alert' && !this.config.disableAutoFocus) {
|
1715
|
-
setFocus(this.$module);
|
1716
|
+
this.config = mergeConfigs(NotificationBanner.defaults, config, normaliseDataset(NotificationBanner, this.$root.dataset));
|
1717
|
+
if (this.$root.getAttribute('role') === 'alert' && !this.config.disableAutoFocus) {
|
1718
|
+
setFocus(this.$root);
|
1716
1719
|
}
|
1717
1720
|
}
|
1718
1721
|
}
|
@@ -1749,28 +1752,20 @@ NotificationBanner.schema = Object.freeze({
|
|
1749
1752
|
*/
|
1750
1753
|
class PasswordInput extends GOVUKFrontendComponent {
|
1751
1754
|
/**
|
1752
|
-
* @param {Element | null} $
|
1755
|
+
* @param {Element | null} $root - HTML element to use for password input
|
1753
1756
|
* @param {PasswordInputConfig} [config] - Password input config
|
1754
1757
|
*/
|
1755
|
-
constructor($
|
1756
|
-
super();
|
1757
|
-
this.$module = void 0;
|
1758
|
+
constructor($root, config = {}) {
|
1759
|
+
super($root);
|
1758
1760
|
this.config = void 0;
|
1759
1761
|
this.i18n = void 0;
|
1760
1762
|
this.$input = void 0;
|
1761
1763
|
this.$showHideButton = void 0;
|
1762
1764
|
this.$screenReaderStatusMessage = void 0;
|
1763
|
-
|
1764
|
-
throw new ElementError({
|
1765
|
-
componentName: 'Password input',
|
1766
|
-
element: $module,
|
1767
|
-
identifier: 'Root element (`$module`)'
|
1768
|
-
});
|
1769
|
-
}
|
1770
|
-
const $input = $module.querySelector('.govuk-js-password-input-input');
|
1765
|
+
const $input = this.$root.querySelector('.govuk-js-password-input-input');
|
1771
1766
|
if (!($input instanceof HTMLInputElement)) {
|
1772
1767
|
throw new ElementError({
|
1773
|
-
|
1768
|
+
component: PasswordInput,
|
1774
1769
|
element: $input,
|
1775
1770
|
expectedType: 'HTMLInputElement',
|
1776
1771
|
identifier: 'Form field (`.govuk-js-password-input-input`)'
|
@@ -1779,10 +1774,10 @@ class PasswordInput extends GOVUKFrontendComponent {
|
|
1779
1774
|
if ($input.type !== 'password') {
|
1780
1775
|
throw new ElementError('Password input: Form field (`.govuk-js-password-input-input`) must be of type `password`.');
|
1781
1776
|
}
|
1782
|
-
const $showHideButton =
|
1777
|
+
const $showHideButton = this.$root.querySelector('.govuk-js-password-input-toggle');
|
1783
1778
|
if (!($showHideButton instanceof HTMLButtonElement)) {
|
1784
1779
|
throw new ElementError({
|
1785
|
-
|
1780
|
+
component: PasswordInput,
|
1786
1781
|
element: $showHideButton,
|
1787
1782
|
expectedType: 'HTMLButtonElement',
|
1788
1783
|
identifier: 'Button (`.govuk-js-password-input-toggle`)'
|
@@ -1791,12 +1786,11 @@ class PasswordInput extends GOVUKFrontendComponent {
|
|
1791
1786
|
if ($showHideButton.type !== 'button') {
|
1792
1787
|
throw new ElementError('Password input: Button (`.govuk-js-password-input-toggle`) must be of type `button`.');
|
1793
1788
|
}
|
1794
|
-
this.$module = $module;
|
1795
1789
|
this.$input = $input;
|
1796
1790
|
this.$showHideButton = $showHideButton;
|
1797
|
-
this.config = mergeConfigs(PasswordInput.defaults, config, normaliseDataset(PasswordInput,
|
1791
|
+
this.config = mergeConfigs(PasswordInput.defaults, config, normaliseDataset(PasswordInput, this.$root.dataset));
|
1798
1792
|
this.i18n = new I18n(this.config.i18n, {
|
1799
|
-
locale: closestAttributeValue(
|
1793
|
+
locale: closestAttributeValue(this.$root, 'lang')
|
1800
1794
|
});
|
1801
1795
|
this.$showHideButton.removeAttribute('hidden');
|
1802
1796
|
const $screenReaderStatusMessage = document.createElement('div');
|
@@ -1914,27 +1908,18 @@ class Radios extends GOVUKFrontendComponent {
|
|
1914
1908
|
* (for example if the user has navigated back), and set up event handlers to
|
1915
1909
|
* keep the reveal in sync with the radio state.
|
1916
1910
|
*
|
1917
|
-
* @param {Element | null} $
|
1911
|
+
* @param {Element | null} $root - HTML element to use for radios
|
1918
1912
|
*/
|
1919
|
-
constructor($
|
1920
|
-
super();
|
1921
|
-
this.$module = void 0;
|
1913
|
+
constructor($root) {
|
1914
|
+
super($root);
|
1922
1915
|
this.$inputs = void 0;
|
1923
|
-
|
1924
|
-
throw new ElementError({
|
1925
|
-
componentName: 'Radios',
|
1926
|
-
element: $module,
|
1927
|
-
identifier: 'Root element (`$module`)'
|
1928
|
-
});
|
1929
|
-
}
|
1930
|
-
const $inputs = $module.querySelectorAll('input[type="radio"]');
|
1916
|
+
const $inputs = this.$root.querySelectorAll('input[type="radio"]');
|
1931
1917
|
if (!$inputs.length) {
|
1932
1918
|
throw new ElementError({
|
1933
|
-
|
1919
|
+
component: Radios,
|
1934
1920
|
identifier: 'Form inputs (`<input type="radio">`)'
|
1935
1921
|
});
|
1936
1922
|
}
|
1937
|
-
this.$module = $module;
|
1938
1923
|
this.$inputs = $inputs;
|
1939
1924
|
this.$inputs.forEach($input => {
|
1940
1925
|
const targetId = $input.getAttribute('data-aria-controls');
|
@@ -1943,7 +1928,7 @@ class Radios extends GOVUKFrontendComponent {
|
|
1943
1928
|
}
|
1944
1929
|
if (!document.getElementById(targetId)) {
|
1945
1930
|
throw new ElementError({
|
1946
|
-
|
1931
|
+
component: Radios,
|
1947
1932
|
identifier: `Conditional reveal (\`id="${targetId}"\`)`
|
1948
1933
|
});
|
1949
1934
|
}
|
@@ -1952,7 +1937,7 @@ class Radios extends GOVUKFrontendComponent {
|
|
1952
1937
|
});
|
1953
1938
|
window.addEventListener('pageshow', () => this.syncAllConditionalReveals());
|
1954
1939
|
this.syncAllConditionalReveals();
|
1955
|
-
this.$
|
1940
|
+
this.$root.addEventListener('click', event => this.handleClick(event));
|
1956
1941
|
}
|
1957
1942
|
syncAllConditionalReveals() {
|
1958
1943
|
this.$inputs.forEach($input => this.syncConditionalRevealWithInputState($input));
|
@@ -1989,35 +1974,105 @@ class Radios extends GOVUKFrontendComponent {
|
|
1989
1974
|
Radios.moduleName = 'govuk-radios';
|
1990
1975
|
|
1991
1976
|
/**
|
1992
|
-
*
|
1977
|
+
* Service Navigation component
|
1993
1978
|
*
|
1994
1979
|
* @preserve
|
1995
1980
|
*/
|
1996
|
-
class
|
1981
|
+
class ServiceNavigation extends GOVUKFrontendComponent {
|
1997
1982
|
/**
|
1998
|
-
* @param {Element | null} $
|
1999
|
-
* @throws {ElementError} when $module is not set or the wrong type
|
2000
|
-
* @throws {ElementError} when $module.hash does not contain a hash
|
2001
|
-
* @throws {ElementError} when the linked element is missing or the wrong type
|
1983
|
+
* @param {Element | null} $root - HTML element to use for header
|
2002
1984
|
*/
|
2003
|
-
constructor($
|
2004
|
-
|
2005
|
-
|
2006
|
-
this.$
|
2007
|
-
|
1985
|
+
constructor($root) {
|
1986
|
+
super($root);
|
1987
|
+
this.$menuButton = void 0;
|
1988
|
+
this.$menu = void 0;
|
1989
|
+
this.menuIsOpen = false;
|
1990
|
+
this.mql = null;
|
1991
|
+
const $menuButton = this.$root.querySelector('.govuk-js-service-navigation-toggle');
|
1992
|
+
if (!$menuButton) {
|
1993
|
+
return this;
|
1994
|
+
}
|
1995
|
+
const menuId = $menuButton.getAttribute('aria-controls');
|
1996
|
+
if (!menuId) {
|
2008
1997
|
throw new ElementError({
|
2009
|
-
|
2010
|
-
|
2011
|
-
|
2012
|
-
|
1998
|
+
component: ServiceNavigation,
|
1999
|
+
identifier: 'Navigation button (`<button class="govuk-js-service-navigation-toggle">`) attribute (`aria-controls`)'
|
2000
|
+
});
|
2001
|
+
}
|
2002
|
+
const $menu = document.getElementById(menuId);
|
2003
|
+
if (!$menu) {
|
2004
|
+
throw new ElementError({
|
2005
|
+
component: ServiceNavigation,
|
2006
|
+
element: $menu,
|
2007
|
+
identifier: `Navigation (\`<ul id="${menuId}">\`)`
|
2008
|
+
});
|
2009
|
+
}
|
2010
|
+
this.$menu = $menu;
|
2011
|
+
this.$menuButton = $menuButton;
|
2012
|
+
this.setupResponsiveChecks();
|
2013
|
+
this.$menuButton.addEventListener('click', () => this.handleMenuButtonClick());
|
2014
|
+
}
|
2015
|
+
setupResponsiveChecks() {
|
2016
|
+
const breakpoint = getBreakpoint('tablet');
|
2017
|
+
if (!breakpoint.value) {
|
2018
|
+
throw new ElementError({
|
2019
|
+
component: ServiceNavigation,
|
2020
|
+
identifier: `CSS custom property (\`${breakpoint.property}\`) on pseudo-class \`:root\``
|
2013
2021
|
});
|
2014
2022
|
}
|
2015
|
-
this
|
2016
|
-
|
2017
|
-
|
2023
|
+
this.mql = window.matchMedia(`(min-width: ${breakpoint.value})`);
|
2024
|
+
if ('addEventListener' in this.mql) {
|
2025
|
+
this.mql.addEventListener('change', () => this.checkMode());
|
2026
|
+
} else {
|
2027
|
+
this.mql.addListener(() => this.checkMode());
|
2028
|
+
}
|
2029
|
+
this.checkMode();
|
2030
|
+
}
|
2031
|
+
checkMode() {
|
2032
|
+
if (!this.mql || !this.$menu || !this.$menuButton) {
|
2033
|
+
return;
|
2034
|
+
}
|
2035
|
+
if (this.mql.matches) {
|
2036
|
+
this.$menu.removeAttribute('hidden');
|
2037
|
+
this.$menuButton.setAttribute('hidden', '');
|
2038
|
+
} else {
|
2039
|
+
this.$menuButton.removeAttribute('hidden');
|
2040
|
+
this.$menuButton.setAttribute('aria-expanded', this.menuIsOpen.toString());
|
2041
|
+
if (this.menuIsOpen) {
|
2042
|
+
this.$menu.removeAttribute('hidden');
|
2043
|
+
} else {
|
2044
|
+
this.$menu.setAttribute('hidden', '');
|
2045
|
+
}
|
2046
|
+
}
|
2047
|
+
}
|
2048
|
+
handleMenuButtonClick() {
|
2049
|
+
this.menuIsOpen = !this.menuIsOpen;
|
2050
|
+
this.checkMode();
|
2051
|
+
}
|
2052
|
+
}
|
2053
|
+
ServiceNavigation.moduleName = 'govuk-service-navigation';
|
2054
|
+
|
2055
|
+
/**
|
2056
|
+
* Skip link component
|
2057
|
+
*
|
2058
|
+
* @preserve
|
2059
|
+
* @augments GOVUKFrontendComponent<HTMLAnchorElement>
|
2060
|
+
*/
|
2061
|
+
class SkipLink extends GOVUKFrontendComponent {
|
2062
|
+
/**
|
2063
|
+
* @param {Element | null} $root - HTML element to use for skip link
|
2064
|
+
* @throws {ElementError} when $root is not set or the wrong type
|
2065
|
+
* @throws {ElementError} when $root.hash does not contain a hash
|
2066
|
+
* @throws {ElementError} when the linked element is missing or the wrong type
|
2067
|
+
*/
|
2068
|
+
constructor($root) {
|
2069
|
+
var _this$$root$getAttrib;
|
2070
|
+
super($root);
|
2071
|
+
const hash = this.$root.hash;
|
2072
|
+
const href = (_this$$root$getAttrib = this.$root.getAttribute('href')) != null ? _this$$root$getAttrib : '';
|
2018
2073
|
let url;
|
2019
2074
|
try {
|
2020
|
-
url = new window.URL(this.$
|
2075
|
+
url = new window.URL(this.$root.href);
|
2021
2076
|
} catch (error) {
|
2022
2077
|
throw new ElementError(`Skip link: Target link (\`href="${href}"\`) is invalid`);
|
2023
2078
|
}
|
@@ -2031,12 +2086,12 @@ class SkipLink extends GOVUKFrontendComponent {
|
|
2031
2086
|
const $linkedElement = document.getElementById(linkedElementId);
|
2032
2087
|
if (!$linkedElement) {
|
2033
2088
|
throw new ElementError({
|
2034
|
-
|
2089
|
+
component: SkipLink,
|
2035
2090
|
element: $linkedElement,
|
2036
2091
|
identifier: `Target content (\`id="${linkedElementId}"\`)`
|
2037
2092
|
});
|
2038
2093
|
}
|
2039
|
-
this.$
|
2094
|
+
this.$root.addEventListener('click', () => setFocus($linkedElement, {
|
2040
2095
|
onBeforeFocus() {
|
2041
2096
|
$linkedElement.classList.add('govuk-skip-link-focused-element');
|
2042
2097
|
},
|
@@ -2046,6 +2101,7 @@ class SkipLink extends GOVUKFrontendComponent {
|
|
2046
2101
|
}));
|
2047
2102
|
}
|
2048
2103
|
}
|
2104
|
+
SkipLink.elementType = HTMLAnchorElement;
|
2049
2105
|
SkipLink.moduleName = 'govuk-skip-link';
|
2050
2106
|
|
2051
2107
|
/**
|
@@ -2055,11 +2111,10 @@ SkipLink.moduleName = 'govuk-skip-link';
|
|
2055
2111
|
*/
|
2056
2112
|
class Tabs extends GOVUKFrontendComponent {
|
2057
2113
|
/**
|
2058
|
-
* @param {Element | null} $
|
2114
|
+
* @param {Element | null} $root - HTML element to use for tabs
|
2059
2115
|
*/
|
2060
|
-
constructor($
|
2061
|
-
super();
|
2062
|
-
this.$module = void 0;
|
2116
|
+
constructor($root) {
|
2117
|
+
super($root);
|
2063
2118
|
this.$tabs = void 0;
|
2064
2119
|
this.$tabList = void 0;
|
2065
2120
|
this.$tabListItems = void 0;
|
@@ -2069,36 +2124,28 @@ class Tabs extends GOVUKFrontendComponent {
|
|
2069
2124
|
this.boundTabKeydown = void 0;
|
2070
2125
|
this.boundOnHashChange = void 0;
|
2071
2126
|
this.mql = null;
|
2072
|
-
|
2073
|
-
throw new ElementError({
|
2074
|
-
componentName: 'Tabs',
|
2075
|
-
element: $module,
|
2076
|
-
identifier: 'Root element (`$module`)'
|
2077
|
-
});
|
2078
|
-
}
|
2079
|
-
const $tabs = $module.querySelectorAll('a.govuk-tabs__tab');
|
2127
|
+
const $tabs = this.$root.querySelectorAll('a.govuk-tabs__tab');
|
2080
2128
|
if (!$tabs.length) {
|
2081
2129
|
throw new ElementError({
|
2082
|
-
|
2130
|
+
component: Tabs,
|
2083
2131
|
identifier: 'Links (`<a class="govuk-tabs__tab">`)'
|
2084
2132
|
});
|
2085
2133
|
}
|
2086
|
-
this.$module = $module;
|
2087
2134
|
this.$tabs = $tabs;
|
2088
2135
|
this.boundTabClick = this.onTabClick.bind(this);
|
2089
2136
|
this.boundTabKeydown = this.onTabKeydown.bind(this);
|
2090
2137
|
this.boundOnHashChange = this.onHashChange.bind(this);
|
2091
|
-
const $tabList = this.$
|
2092
|
-
const $tabListItems = this.$
|
2138
|
+
const $tabList = this.$root.querySelector('.govuk-tabs__list');
|
2139
|
+
const $tabListItems = this.$root.querySelectorAll('li.govuk-tabs__list-item');
|
2093
2140
|
if (!$tabList) {
|
2094
2141
|
throw new ElementError({
|
2095
|
-
|
2142
|
+
component: Tabs,
|
2096
2143
|
identifier: 'List (`<ul class="govuk-tabs__list">`)'
|
2097
2144
|
});
|
2098
2145
|
}
|
2099
2146
|
if (!$tabListItems.length) {
|
2100
2147
|
throw new ElementError({
|
2101
|
-
|
2148
|
+
component: Tabs,
|
2102
2149
|
identifier: 'List items (`<li class="govuk-tabs__list-item">`)'
|
2103
2150
|
});
|
2104
2151
|
}
|
@@ -2110,7 +2157,7 @@ class Tabs extends GOVUKFrontendComponent {
|
|
2110
2157
|
const breakpoint = getBreakpoint('tablet');
|
2111
2158
|
if (!breakpoint.value) {
|
2112
2159
|
throw new ElementError({
|
2113
|
-
|
2160
|
+
component: Tabs,
|
2114
2161
|
identifier: `CSS custom property (\`${breakpoint.property}\`) on pseudo-class \`:root\``
|
2115
2162
|
});
|
2116
2163
|
}
|
@@ -2185,7 +2232,7 @@ class Tabs extends GOVUKFrontendComponent {
|
|
2185
2232
|
this.showPanel($tab);
|
2186
2233
|
}
|
2187
2234
|
getTab(hash) {
|
2188
|
-
return this.$
|
2235
|
+
return this.$root.querySelector(`a.govuk-tabs__tab[href="${hash}"]`);
|
2189
2236
|
}
|
2190
2237
|
setAttributes($tab) {
|
2191
2238
|
const panelId = getFragmentFromUrl($tab.href);
|
@@ -2296,7 +2343,7 @@ class Tabs extends GOVUKFrontendComponent {
|
|
2296
2343
|
if (!panelId) {
|
2297
2344
|
return null;
|
2298
2345
|
}
|
2299
|
-
return this.$
|
2346
|
+
return this.$root.querySelector(`#${panelId}`);
|
2300
2347
|
}
|
2301
2348
|
showPanel($tab) {
|
2302
2349
|
const $panel = this.getPanel($tab);
|
@@ -2329,7 +2376,7 @@ class Tabs extends GOVUKFrontendComponent {
|
|
2329
2376
|
$tab.setAttribute('tabindex', '0');
|
2330
2377
|
}
|
2331
2378
|
getCurrentTab() {
|
2332
|
-
return this.$
|
2379
|
+
return this.$root.querySelector('.govuk-tabs__list-item--selected a.govuk-tabs__tab');
|
2333
2380
|
}
|
2334
2381
|
}
|
2335
2382
|
Tabs.moduleName = 'govuk-tabs';
|
@@ -2340,19 +2387,28 @@ Tabs.moduleName = 'govuk-tabs';
|
|
2340
2387
|
* Use the `data-module` attributes to find, instantiate and init all of the
|
2341
2388
|
* components provided as part of GOV.UK Frontend.
|
2342
2389
|
*
|
2343
|
-
* @param {Config & { scope?: Element }} [config] - Config for all components (with optional scope)
|
2390
|
+
* @param {Config & { scope?: Element, onError?: OnErrorCallback<CompatibleClass> }} [config] - Config for all components (with optional scope)
|
2344
2391
|
*/
|
2345
2392
|
function initAll(config) {
|
2346
2393
|
var _config$scope;
|
2347
2394
|
config = typeof config !== 'undefined' ? config : {};
|
2348
2395
|
if (!isSupported()) {
|
2349
|
-
|
2396
|
+
if (config.onError) {
|
2397
|
+
config.onError(new SupportError(), {
|
2398
|
+
config
|
2399
|
+
});
|
2400
|
+
} else {
|
2401
|
+
console.log(new SupportError());
|
2402
|
+
}
|
2350
2403
|
return;
|
2351
2404
|
}
|
2352
|
-
const components = [[Accordion, config.accordion], [Button, config.button], [CharacterCount, config.characterCount], [Checkboxes], [ErrorSummary, config.errorSummary], [ExitThisPage, config.exitThisPage], [Header], [NotificationBanner, config.notificationBanner], [PasswordInput, config.passwordInput], [Radios], [SkipLink], [Tabs]];
|
2353
|
-
const
|
2405
|
+
const components = [[Accordion, config.accordion], [Button, config.button], [CharacterCount, config.characterCount], [Checkboxes], [ErrorSummary, config.errorSummary], [ExitThisPage, config.exitThisPage], [Header], [NotificationBanner, config.notificationBanner], [PasswordInput, config.passwordInput], [Radios], [ServiceNavigation], [SkipLink], [Tabs]];
|
2406
|
+
const options = {
|
2407
|
+
scope: (_config$scope = config.scope) != null ? _config$scope : document,
|
2408
|
+
onError: config.onError
|
2409
|
+
};
|
2354
2410
|
components.forEach(([Component, config]) => {
|
2355
|
-
createAll(Component, config,
|
2411
|
+
createAll(Component, config, options);
|
2356
2412
|
});
|
2357
2413
|
}
|
2358
2414
|
|
@@ -2367,17 +2423,50 @@ function initAll(config) {
|
|
2367
2423
|
*
|
2368
2424
|
* @template {CompatibleClass} T
|
2369
2425
|
* @param {T} Component - class of the component to create
|
2370
|
-
* @param {T["defaults"]} [config] -
|
2371
|
-
* @param {Element|Document} [
|
2426
|
+
* @param {T["defaults"]} [config] - Config supplied to component
|
2427
|
+
* @param {OnErrorCallback<T> | Element | Document | CreateAllOptions<T> } [createAllOptions] - options for createAll including scope of the document to search within and callback function if error throw by component on init
|
2372
2428
|
* @returns {Array<InstanceType<T>>} - array of instantiated components
|
2373
2429
|
*/
|
2374
|
-
function createAll(Component, config,
|
2430
|
+
function createAll(Component, config, createAllOptions) {
|
2431
|
+
let $scope = document;
|
2432
|
+
let onError;
|
2433
|
+
if (typeof createAllOptions === 'object') {
|
2434
|
+
var _createAllOptions$sco;
|
2435
|
+
createAllOptions = createAllOptions;
|
2436
|
+
$scope = (_createAllOptions$sco = createAllOptions.scope) != null ? _createAllOptions$sco : $scope;
|
2437
|
+
onError = createAllOptions.onError;
|
2438
|
+
}
|
2439
|
+
if (typeof createAllOptions === 'function') {
|
2440
|
+
onError = createAllOptions;
|
2441
|
+
}
|
2442
|
+
if (createAllOptions instanceof HTMLElement) {
|
2443
|
+
$scope = createAllOptions;
|
2444
|
+
}
|
2375
2445
|
const $elements = $scope.querySelectorAll(`[data-module="${Component.moduleName}"]`);
|
2446
|
+
if (!isSupported()) {
|
2447
|
+
if (onError) {
|
2448
|
+
onError(new SupportError(), {
|
2449
|
+
component: Component,
|
2450
|
+
config
|
2451
|
+
});
|
2452
|
+
} else {
|
2453
|
+
console.log(new SupportError());
|
2454
|
+
}
|
2455
|
+
return [];
|
2456
|
+
}
|
2376
2457
|
return Array.from($elements).map($element => {
|
2377
2458
|
try {
|
2378
|
-
return
|
2459
|
+
return typeof config !== 'undefined' ? new Component($element, config) : new Component($element);
|
2379
2460
|
} catch (error) {
|
2380
|
-
|
2461
|
+
if (onError) {
|
2462
|
+
onError(error, {
|
2463
|
+
element: $element,
|
2464
|
+
component: Component,
|
2465
|
+
config
|
2466
|
+
});
|
2467
|
+
} else {
|
2468
|
+
console.log(error);
|
2469
|
+
}
|
2381
2470
|
return null;
|
2382
2471
|
}
|
2383
2472
|
}).filter(Boolean);
|
@@ -2416,6 +2505,25 @@ function createAll(Component, config, $scope = document) {
|
|
2416
2505
|
*
|
2417
2506
|
* @typedef {keyof Config} ConfigKey
|
2418
2507
|
*/
|
2508
|
+
/**
|
2509
|
+
* @template {CompatibleClass} T
|
2510
|
+
* @typedef {object} ErrorContext
|
2511
|
+
* @property {Element} [element] - Element used for component module initialisation
|
2512
|
+
* @property {T} [component] - Class of component
|
2513
|
+
* @property {T["defaults"]} config - Config supplied to component
|
2514
|
+
*/
|
2515
|
+
/**
|
2516
|
+
* @template {CompatibleClass} T
|
2517
|
+
* @callback OnErrorCallback
|
2518
|
+
* @param {unknown} error - Thrown error
|
2519
|
+
* @param {ErrorContext<T>} context - Object containing the element, component class and configuration
|
2520
|
+
*/
|
2521
|
+
/**
|
2522
|
+
* @template {CompatibleClass} T
|
2523
|
+
* @typedef {object} CreateAllOptions
|
2524
|
+
* @property {Element | Document} [scope] - scope of the document to search within
|
2525
|
+
* @property {OnErrorCallback<T>} [onError] - callback function if error throw by component on init
|
2526
|
+
*/
|
2419
2527
|
|
2420
|
-
export { Accordion, Button, CharacterCount, Checkboxes, ErrorSummary, ExitThisPage, Header, NotificationBanner, PasswordInput, Radios, SkipLink, Tabs, createAll, initAll, version };
|
2528
|
+
export { Accordion, Button, CharacterCount, Checkboxes, GOVUKFrontendComponent as Component, ErrorSummary, ExitThisPage, Header, NotificationBanner, PasswordInput, Radios, ServiceNavigation, SkipLink, Tabs, createAll, initAll, isSupported, version };
|
2421
2529
|
//# sourceMappingURL=all.bundle.mjs.map
|