katalyst-govuk-formbuilder 1.8.0 → 1.9.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/builds/katalyst/govuk/formbuilder.css +1 -1
- data/app/assets/builds/katalyst/govuk/formbuilder.js +341 -92
- data/app/assets/builds/katalyst/govuk/formbuilder.min.js +18 -12
- data/vendor/assets/stylesheets/govuk-frontend/dist/govuk/components/_all.scss +1 -0
- data/vendor/assets/stylesheets/govuk-frontend/dist/govuk/components/header/_index.scss +1 -1
- data/vendor/assets/stylesheets/govuk-frontend/dist/govuk/components/password-input/_index.scss +55 -0
- data/vendor/assets/stylesheets/govuk-frontend/dist/govuk/components/password-input/_password-input.scss +4 -0
- data/vendor/assets/stylesheets/govuk-frontend/dist/govuk/core/_govuk-frontend-properties.scss +1 -1
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1410f1442239fc641fda6da3021a483bca381b9057d18bfe10b6ec35684944fd
|
4
|
+
data.tar.gz: 9c0b30c979e992dc9438ef0e3abbf033569059843545245970cd05b80a66425d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a8cbc04a855e37fe7f1e4f8d665dc8337eaa1e69d614b913c0c64b1f0c0454535ebb43e5ecc6d4bb140daca4486a4bb4d96bf51cedf05af103c16bc8a15f5811
|
7
|
+
data.tar.gz: 4ba3bc8e477227905bac144c46ec69cac954cacf882834046990eb40fc626ba23f99cc8fcbbe0158450b30639c82ce905ce019e6d754c87cd3ffc5cdda90fed1
|
@@ -1,41 +1,68 @@
|
|
1
|
+
function normaliseString(value, property) {
|
2
|
+
const trimmedValue = value ? value.trim() : '';
|
3
|
+
let output;
|
4
|
+
let outputType = property == null ? void 0 : property.type;
|
5
|
+
if (!outputType) {
|
6
|
+
if (['true', 'false'].includes(trimmedValue)) {
|
7
|
+
outputType = 'boolean';
|
8
|
+
}
|
9
|
+
if (trimmedValue.length > 0 && isFinite(Number(trimmedValue))) {
|
10
|
+
outputType = 'number';
|
11
|
+
}
|
12
|
+
}
|
13
|
+
switch (outputType) {
|
14
|
+
case 'boolean':
|
15
|
+
output = trimmedValue === 'true';
|
16
|
+
break;
|
17
|
+
case 'number':
|
18
|
+
output = Number(trimmedValue);
|
19
|
+
break;
|
20
|
+
default:
|
21
|
+
output = value;
|
22
|
+
}
|
23
|
+
return output;
|
24
|
+
}
|
25
|
+
|
1
26
|
function mergeConfigs(...configObjects) {
|
2
|
-
function flattenObject(configObject) {
|
3
|
-
const flattenedObject = {};
|
4
|
-
function flattenLoop(obj, prefix) {
|
5
|
-
for (const [key, value] of Object.entries(obj)) {
|
6
|
-
const prefixedKey = prefix ? `${prefix}.${key}` : key;
|
7
|
-
if (value && typeof value === 'object') {
|
8
|
-
flattenLoop(value, prefixedKey);
|
9
|
-
} else {
|
10
|
-
flattenedObject[prefixedKey] = value;
|
11
|
-
}
|
12
|
-
}
|
13
|
-
}
|
14
|
-
flattenLoop(configObject);
|
15
|
-
return flattenedObject;
|
16
|
-
}
|
17
27
|
const formattedConfigObject = {};
|
18
28
|
for (const configObject of configObjects) {
|
19
|
-
const
|
20
|
-
|
21
|
-
|
29
|
+
for (const key of Object.keys(configObject)) {
|
30
|
+
const option = formattedConfigObject[key];
|
31
|
+
const override = configObject[key];
|
32
|
+
if (isObject(option) && isObject(override)) {
|
33
|
+
formattedConfigObject[key] = mergeConfigs(option, override);
|
34
|
+
} else {
|
35
|
+
formattedConfigObject[key] = override;
|
36
|
+
}
|
22
37
|
}
|
23
38
|
}
|
24
39
|
return formattedConfigObject;
|
25
40
|
}
|
26
|
-
function extractConfigByNamespace(
|
27
|
-
const
|
28
|
-
|
41
|
+
function extractConfigByNamespace(Component, dataset, namespace) {
|
42
|
+
const property = Component.schema.properties[namespace];
|
43
|
+
if ((property == null ? void 0 : property.type) !== 'object') {
|
44
|
+
return;
|
45
|
+
}
|
46
|
+
const newObject = {
|
47
|
+
[namespace]: ({})
|
48
|
+
};
|
49
|
+
for (const [key, value] of Object.entries(dataset)) {
|
50
|
+
let current = newObject;
|
29
51
|
const keyParts = key.split('.');
|
30
|
-
|
31
|
-
if (
|
32
|
-
keyParts.
|
52
|
+
for (const [index, name] of keyParts.entries()) {
|
53
|
+
if (typeof current === 'object') {
|
54
|
+
if (index < keyParts.length - 1) {
|
55
|
+
if (!isObject(current[name])) {
|
56
|
+
current[name] = {};
|
57
|
+
}
|
58
|
+
current = current[name];
|
59
|
+
} else if (key !== namespace) {
|
60
|
+
current[name] = normaliseString(value);
|
61
|
+
}
|
33
62
|
}
|
34
|
-
const newKey = keyParts.join('.');
|
35
|
-
newObject[newKey] = value;
|
36
63
|
}
|
37
64
|
}
|
38
|
-
return newObject;
|
65
|
+
return newObject[namespace];
|
39
66
|
}
|
40
67
|
function getFragmentFromUrl(url) {
|
41
68
|
if (!url.includes('#')) {
|
@@ -85,41 +112,38 @@ function validateConfig(schema, config) {
|
|
85
112
|
const validationErrors = [];
|
86
113
|
for (const [name, conditions] of Object.entries(schema)) {
|
87
114
|
const errors = [];
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
115
|
+
if (Array.isArray(conditions)) {
|
116
|
+
for (const {
|
117
|
+
required,
|
118
|
+
errorMessage
|
119
|
+
} of conditions) {
|
120
|
+
if (!required.every(key => !!config[key])) {
|
121
|
+
errors.push(errorMessage);
|
122
|
+
}
|
123
|
+
}
|
124
|
+
if (name === 'anyOf' && !(conditions.length - errors.length >= 1)) {
|
125
|
+
validationErrors.push(...errors);
|
94
126
|
}
|
95
|
-
}
|
96
|
-
if (name === 'anyOf' && !(conditions.length - errors.length >= 1)) {
|
97
|
-
validationErrors.push(...errors);
|
98
127
|
}
|
99
128
|
}
|
100
129
|
return validationErrors;
|
101
130
|
}
|
102
|
-
|
103
|
-
|
104
|
-
if (typeof value !== 'string') {
|
105
|
-
return value;
|
106
|
-
}
|
107
|
-
const trimmedValue = value.trim();
|
108
|
-
if (trimmedValue === 'true') {
|
109
|
-
return true;
|
110
|
-
}
|
111
|
-
if (trimmedValue === 'false') {
|
112
|
-
return false;
|
113
|
-
}
|
114
|
-
if (trimmedValue.length > 0 && isFinite(Number(trimmedValue))) {
|
115
|
-
return Number(trimmedValue);
|
116
|
-
}
|
117
|
-
return value;
|
131
|
+
function isArray(option) {
|
132
|
+
return Array.isArray(option);
|
118
133
|
}
|
119
|
-
function
|
134
|
+
function isObject(option) {
|
135
|
+
return !!option && typeof option === 'object' && !isArray(option);
|
136
|
+
}
|
137
|
+
|
138
|
+
function normaliseDataset(Component, dataset) {
|
120
139
|
const out = {};
|
121
|
-
for (const [
|
122
|
-
|
140
|
+
for (const [field, property] of Object.entries(Component.schema.properties)) {
|
141
|
+
if (field in dataset) {
|
142
|
+
out[field] = normaliseString(dataset[field], property);
|
143
|
+
}
|
144
|
+
if ((property == null ? void 0 : property.type) === 'object') {
|
145
|
+
out[field] = extractConfigByNamespace(Component, dataset, field);
|
146
|
+
}
|
123
147
|
}
|
124
148
|
return out;
|
125
149
|
}
|
@@ -189,18 +213,21 @@ class I18n {
|
|
189
213
|
if (!lookupKey) {
|
190
214
|
throw new Error('i18n: lookup key missing');
|
191
215
|
}
|
192
|
-
|
193
|
-
|
216
|
+
let translation = this.translations[lookupKey];
|
217
|
+
if (typeof (options == null ? void 0 : options.count) === 'number' && typeof translation === 'object') {
|
218
|
+
const translationPluralForm = translation[this.getPluralSuffix(lookupKey, options.count)];
|
219
|
+
if (translationPluralForm) {
|
220
|
+
translation = translationPluralForm;
|
221
|
+
}
|
194
222
|
}
|
195
|
-
|
196
|
-
|
197
|
-
if (translationString.match(/%{(.\S+)}/)) {
|
223
|
+
if (typeof translation === 'string') {
|
224
|
+
if (translation.match(/%{(.\S+)}/)) {
|
198
225
|
if (!options) {
|
199
226
|
throw new Error('i18n: cannot replace placeholders in string if no option data provided');
|
200
227
|
}
|
201
|
-
return this.replacePlaceholders(
|
228
|
+
return this.replacePlaceholders(translation, options);
|
202
229
|
}
|
203
|
-
return
|
230
|
+
return translation;
|
204
231
|
}
|
205
232
|
return lookupKey;
|
206
233
|
}
|
@@ -228,12 +255,15 @@ class I18n {
|
|
228
255
|
if (!isFinite(count)) {
|
229
256
|
return 'other';
|
230
257
|
}
|
258
|
+
const translation = this.translations[lookupKey];
|
231
259
|
const preferredForm = this.hasIntlPluralRulesSupport() ? new Intl.PluralRules(this.locale).select(count) : this.selectPluralFormUsingFallbackRules(count);
|
232
|
-
if (
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
260
|
+
if (typeof translation === 'object') {
|
261
|
+
if (preferredForm in translation) {
|
262
|
+
return preferredForm;
|
263
|
+
} else if ('other' in translation) {
|
264
|
+
console.warn(`i18n: Missing plural form ".${preferredForm}" for "${this.locale}" locale. Falling back to ".other".`);
|
265
|
+
return 'other';
|
266
|
+
}
|
237
267
|
}
|
238
268
|
throw new Error(`i18n: Plural form ".other" is required for "${this.locale}" locale`);
|
239
269
|
}
|
@@ -420,8 +450,8 @@ class Accordion extends GOVUKFrontendComponent {
|
|
420
450
|
});
|
421
451
|
}
|
422
452
|
this.$module = $module;
|
423
|
-
this.config = mergeConfigs(Accordion.defaults, config, normaliseDataset($module.dataset));
|
424
|
-
this.i18n = new I18n(
|
453
|
+
this.config = mergeConfigs(Accordion.defaults, config, normaliseDataset(Accordion, $module.dataset));
|
454
|
+
this.i18n = new I18n(this.config.i18n);
|
425
455
|
const $sections = this.$module.querySelectorAll(`.${this.sectionClass}`);
|
426
456
|
if (!$sections.length) {
|
427
457
|
throw new ElementError({
|
@@ -657,6 +687,16 @@ Accordion.defaults = Object.freeze({
|
|
657
687
|
},
|
658
688
|
rememberExpanded: true
|
659
689
|
});
|
690
|
+
Accordion.schema = Object.freeze({
|
691
|
+
properties: {
|
692
|
+
i18n: {
|
693
|
+
type: 'object'
|
694
|
+
},
|
695
|
+
rememberExpanded: {
|
696
|
+
type: 'boolean'
|
697
|
+
}
|
698
|
+
}
|
699
|
+
});
|
660
700
|
const helper = {
|
661
701
|
/**
|
662
702
|
* Check for `window.sessionStorage`, and that it actually works.
|
@@ -677,7 +717,6 @@ const helper = {
|
|
677
717
|
}
|
678
718
|
};
|
679
719
|
|
680
|
-
const KEY_SPACE = 32;
|
681
720
|
const DEBOUNCE_TIMEOUT_IN_SECONDS = 1;
|
682
721
|
|
683
722
|
/**
|
@@ -703,13 +742,13 @@ class Button extends GOVUKFrontendComponent {
|
|
703
742
|
});
|
704
743
|
}
|
705
744
|
this.$module = $module;
|
706
|
-
this.config = mergeConfigs(Button.defaults, config, normaliseDataset($module.dataset));
|
745
|
+
this.config = mergeConfigs(Button.defaults, config, normaliseDataset(Button, $module.dataset));
|
707
746
|
this.$module.addEventListener('keydown', event => this.handleKeyDown(event));
|
708
747
|
this.$module.addEventListener('click', event => this.debounce(event));
|
709
748
|
}
|
710
749
|
handleKeyDown(event) {
|
711
750
|
const $target = event.target;
|
712
|
-
if (event.
|
751
|
+
if (event.key !== ' ') {
|
713
752
|
return;
|
714
753
|
}
|
715
754
|
if ($target instanceof HTMLElement && $target.getAttribute('role') === 'button') {
|
@@ -738,10 +777,21 @@ class Button extends GOVUKFrontendComponent {
|
|
738
777
|
* @property {boolean} [preventDoubleClick=false] - Prevent accidental double
|
739
778
|
* clicks on submit buttons from submitting forms multiple times.
|
740
779
|
*/
|
780
|
+
|
781
|
+
/**
|
782
|
+
* @typedef {import('../../common/index.mjs').Schema} Schema
|
783
|
+
*/
|
741
784
|
Button.moduleName = 'govuk-button';
|
742
785
|
Button.defaults = Object.freeze({
|
743
786
|
preventDoubleClick: false
|
744
787
|
});
|
788
|
+
Button.schema = Object.freeze({
|
789
|
+
properties: {
|
790
|
+
preventDoubleClick: {
|
791
|
+
type: 'boolean'
|
792
|
+
}
|
793
|
+
}
|
794
|
+
});
|
745
795
|
|
746
796
|
function closestAttributeValue($element, attributeName) {
|
747
797
|
const $closestElementWithAttribute = $element.closest(`[${attributeName}]`);
|
@@ -794,7 +844,7 @@ class CharacterCount extends GOVUKFrontendComponent {
|
|
794
844
|
identifier: 'Form field (`.govuk-js-character-count`)'
|
795
845
|
});
|
796
846
|
}
|
797
|
-
const datasetConfig = normaliseDataset($module.dataset);
|
847
|
+
const datasetConfig = normaliseDataset(CharacterCount, $module.dataset);
|
798
848
|
let configOverrides = {};
|
799
849
|
if ('maxwords' in datasetConfig || 'maxlength' in datasetConfig) {
|
800
850
|
configOverrides = {
|
@@ -807,7 +857,7 @@ class CharacterCount extends GOVUKFrontendComponent {
|
|
807
857
|
if (errors[0]) {
|
808
858
|
throw new ConfigError(`Character count: ${errors[0]}`);
|
809
859
|
}
|
810
|
-
this.i18n = new I18n(
|
860
|
+
this.i18n = new I18n(this.config.i18n, {
|
811
861
|
locale: closestAttributeValue($module, 'lang')
|
812
862
|
});
|
813
863
|
this.maxLength = (_ref = (_this$config$maxwords = this.config.maxwords) != null ? _this$config$maxwords : this.config.maxlength) != null ? _ref : Infinity;
|
@@ -1020,6 +1070,20 @@ CharacterCount.defaults = Object.freeze({
|
|
1020
1070
|
}
|
1021
1071
|
});
|
1022
1072
|
CharacterCount.schema = Object.freeze({
|
1073
|
+
properties: {
|
1074
|
+
i18n: {
|
1075
|
+
type: 'object'
|
1076
|
+
},
|
1077
|
+
maxwords: {
|
1078
|
+
type: 'number'
|
1079
|
+
},
|
1080
|
+
maxlength: {
|
1081
|
+
type: 'number'
|
1082
|
+
},
|
1083
|
+
threshold: {
|
1084
|
+
type: 'number'
|
1085
|
+
}
|
1086
|
+
},
|
1023
1087
|
anyOf: [{
|
1024
1088
|
required: ['maxwords'],
|
1025
1089
|
errorMessage: 'Either "maxlength" or "maxwords" must be provided'
|
@@ -1169,7 +1233,7 @@ class ErrorSummary extends GOVUKFrontendComponent {
|
|
1169
1233
|
});
|
1170
1234
|
}
|
1171
1235
|
this.$module = $module;
|
1172
|
-
this.config = mergeConfigs(ErrorSummary.defaults, config, normaliseDataset($module.dataset));
|
1236
|
+
this.config = mergeConfigs(ErrorSummary.defaults, config, normaliseDataset(ErrorSummary, $module.dataset));
|
1173
1237
|
if (!this.config.disableAutoFocus) {
|
1174
1238
|
setFocus(this.$module);
|
1175
1239
|
}
|
@@ -1234,10 +1298,21 @@ class ErrorSummary extends GOVUKFrontendComponent {
|
|
1234
1298
|
* @property {boolean} [disableAutoFocus=false] - If set to `true` the error
|
1235
1299
|
* summary will not be focussed when the page loads.
|
1236
1300
|
*/
|
1301
|
+
|
1302
|
+
/**
|
1303
|
+
* @typedef {import('../../common/index.mjs').Schema} Schema
|
1304
|
+
*/
|
1237
1305
|
ErrorSummary.moduleName = 'govuk-error-summary';
|
1238
1306
|
ErrorSummary.defaults = Object.freeze({
|
1239
1307
|
disableAutoFocus: false
|
1240
1308
|
});
|
1309
|
+
ErrorSummary.schema = Object.freeze({
|
1310
|
+
properties: {
|
1311
|
+
disableAutoFocus: {
|
1312
|
+
type: 'boolean'
|
1313
|
+
}
|
1314
|
+
}
|
1315
|
+
});
|
1241
1316
|
|
1242
1317
|
/**
|
1243
1318
|
* Exit this page component
|
@@ -1280,8 +1355,8 @@ class ExitThisPage extends GOVUKFrontendComponent {
|
|
1280
1355
|
identifier: 'Button (`.govuk-exit-this-page__button`)'
|
1281
1356
|
});
|
1282
1357
|
}
|
1283
|
-
this.config = mergeConfigs(ExitThisPage.defaults, config, normaliseDataset($module.dataset));
|
1284
|
-
this.i18n = new I18n(
|
1358
|
+
this.config = mergeConfigs(ExitThisPage.defaults, config, normaliseDataset(ExitThisPage, $module.dataset));
|
1359
|
+
this.i18n = new I18n(this.config.i18n);
|
1285
1360
|
this.$module = $module;
|
1286
1361
|
this.$button = $button;
|
1287
1362
|
const $skiplinkButton = document.querySelector('.govuk-js-exit-this-page-skiplink');
|
@@ -1351,7 +1426,7 @@ class ExitThisPage extends GOVUKFrontendComponent {
|
|
1351
1426
|
if (!this.$updateSpan) {
|
1352
1427
|
return;
|
1353
1428
|
}
|
1354
|
-
if (
|
1429
|
+
if (event.key === 'Shift' && !this.lastKeyWasModified) {
|
1355
1430
|
this.keypressCounter += 1;
|
1356
1431
|
this.updateIndicator();
|
1357
1432
|
if (this.timeoutMessageId) {
|
@@ -1445,6 +1520,10 @@ class ExitThisPage extends GOVUKFrontendComponent {
|
|
1445
1520
|
* @property {string} [pressOneMoreTime] - Screen reader announcement informing
|
1446
1521
|
* the user they must press the activation key one more time.
|
1447
1522
|
*/
|
1523
|
+
|
1524
|
+
/**
|
1525
|
+
* @typedef {import('../../common/index.mjs').Schema} Schema
|
1526
|
+
*/
|
1448
1527
|
ExitThisPage.moduleName = 'govuk-exit-this-page';
|
1449
1528
|
ExitThisPage.defaults = Object.freeze({
|
1450
1529
|
i18n: {
|
@@ -1454,6 +1533,13 @@ ExitThisPage.defaults = Object.freeze({
|
|
1454
1533
|
pressOneMoreTime: 'Shift, press 1 more time to exit.'
|
1455
1534
|
}
|
1456
1535
|
});
|
1536
|
+
ExitThisPage.schema = Object.freeze({
|
1537
|
+
properties: {
|
1538
|
+
i18n: {
|
1539
|
+
type: 'object'
|
1540
|
+
}
|
1541
|
+
}
|
1542
|
+
});
|
1457
1543
|
|
1458
1544
|
/**
|
1459
1545
|
* Header component
|
@@ -1568,7 +1654,7 @@ class NotificationBanner extends GOVUKFrontendComponent {
|
|
1568
1654
|
});
|
1569
1655
|
}
|
1570
1656
|
this.$module = $module;
|
1571
|
-
this.config = mergeConfigs(NotificationBanner.defaults, config, normaliseDataset($module.dataset));
|
1657
|
+
this.config = mergeConfigs(NotificationBanner.defaults, config, normaliseDataset(NotificationBanner, $module.dataset));
|
1572
1658
|
if (this.$module.getAttribute('role') === 'alert' && !this.config.disableAutoFocus) {
|
1573
1659
|
setFocus(this.$module);
|
1574
1660
|
}
|
@@ -1584,10 +1670,175 @@ class NotificationBanner extends GOVUKFrontendComponent {
|
|
1584
1670
|
* applies if the component has a `role` of `alert` – in other cases the
|
1585
1671
|
* component will not be focused on page load, regardless of this option.
|
1586
1672
|
*/
|
1673
|
+
|
1674
|
+
/**
|
1675
|
+
* @typedef {import('../../common/index.mjs').Schema} Schema
|
1676
|
+
*/
|
1587
1677
|
NotificationBanner.moduleName = 'govuk-notification-banner';
|
1588
1678
|
NotificationBanner.defaults = Object.freeze({
|
1589
1679
|
disableAutoFocus: false
|
1590
1680
|
});
|
1681
|
+
NotificationBanner.schema = Object.freeze({
|
1682
|
+
properties: {
|
1683
|
+
disableAutoFocus: {
|
1684
|
+
type: 'boolean'
|
1685
|
+
}
|
1686
|
+
}
|
1687
|
+
});
|
1688
|
+
|
1689
|
+
/**
|
1690
|
+
* Password input component
|
1691
|
+
*
|
1692
|
+
* @preserve
|
1693
|
+
*/
|
1694
|
+
class PasswordInput extends GOVUKFrontendComponent {
|
1695
|
+
/**
|
1696
|
+
* @param {Element | null} $module - HTML element to use for password input
|
1697
|
+
* @param {PasswordInputConfig} [config] - Password input config
|
1698
|
+
*/
|
1699
|
+
constructor($module, config = {}) {
|
1700
|
+
super();
|
1701
|
+
this.$module = void 0;
|
1702
|
+
this.config = void 0;
|
1703
|
+
this.i18n = void 0;
|
1704
|
+
this.$input = void 0;
|
1705
|
+
this.$showHideButton = void 0;
|
1706
|
+
this.$screenReaderStatusMessage = void 0;
|
1707
|
+
if (!($module instanceof HTMLElement)) {
|
1708
|
+
throw new ElementError({
|
1709
|
+
componentName: 'Password input',
|
1710
|
+
element: $module,
|
1711
|
+
identifier: 'Root element (`$module`)'
|
1712
|
+
});
|
1713
|
+
}
|
1714
|
+
const $input = $module.querySelector('.govuk-js-password-input-input');
|
1715
|
+
if (!($input instanceof HTMLInputElement)) {
|
1716
|
+
throw new ElementError({
|
1717
|
+
componentName: 'Password input',
|
1718
|
+
element: $input,
|
1719
|
+
expectedType: 'HTMLInputElement',
|
1720
|
+
identifier: 'Form field (`.govuk-js-password-input-input`)'
|
1721
|
+
});
|
1722
|
+
}
|
1723
|
+
if ($input.type !== 'password') {
|
1724
|
+
throw new ElementError('Password input: Form field (`.govuk-js-password-input-input`) must be of type `password`.');
|
1725
|
+
}
|
1726
|
+
const $showHideButton = $module.querySelector('.govuk-js-password-input-toggle');
|
1727
|
+
if (!($showHideButton instanceof HTMLButtonElement)) {
|
1728
|
+
throw new ElementError({
|
1729
|
+
componentName: 'Password input',
|
1730
|
+
element: $showHideButton,
|
1731
|
+
expectedType: 'HTMLButtonElement',
|
1732
|
+
identifier: 'Button (`.govuk-js-password-input-toggle`)'
|
1733
|
+
});
|
1734
|
+
}
|
1735
|
+
if ($showHideButton.type !== 'button') {
|
1736
|
+
throw new ElementError('Password input: Button (`.govuk-js-password-input-toggle`) must be of type `button`.');
|
1737
|
+
}
|
1738
|
+
this.$module = $module;
|
1739
|
+
this.$input = $input;
|
1740
|
+
this.$showHideButton = $showHideButton;
|
1741
|
+
this.config = mergeConfigs(PasswordInput.defaults, config, normaliseDataset(PasswordInput, $module.dataset));
|
1742
|
+
this.i18n = new I18n(this.config.i18n, {
|
1743
|
+
locale: closestAttributeValue($module, 'lang')
|
1744
|
+
});
|
1745
|
+
this.$showHideButton.removeAttribute('hidden');
|
1746
|
+
const $screenReaderStatusMessage = document.createElement('div');
|
1747
|
+
$screenReaderStatusMessage.className = 'govuk-password-input__sr-status govuk-visually-hidden';
|
1748
|
+
$screenReaderStatusMessage.setAttribute('aria-live', 'polite');
|
1749
|
+
this.$screenReaderStatusMessage = $screenReaderStatusMessage;
|
1750
|
+
this.$input.insertAdjacentElement('afterend', $screenReaderStatusMessage);
|
1751
|
+
this.$showHideButton.addEventListener('click', this.toggle.bind(this));
|
1752
|
+
if (this.$input.form) {
|
1753
|
+
this.$input.form.addEventListener('submit', () => this.hide());
|
1754
|
+
}
|
1755
|
+
window.addEventListener('pageshow', event => {
|
1756
|
+
if (event.persisted && this.$input.type !== 'password') {
|
1757
|
+
this.hide();
|
1758
|
+
}
|
1759
|
+
});
|
1760
|
+
this.hide();
|
1761
|
+
}
|
1762
|
+
toggle(event) {
|
1763
|
+
event.preventDefault();
|
1764
|
+
if (this.$input.type === 'password') {
|
1765
|
+
this.show();
|
1766
|
+
return;
|
1767
|
+
}
|
1768
|
+
this.hide();
|
1769
|
+
}
|
1770
|
+
show() {
|
1771
|
+
this.setType('text');
|
1772
|
+
}
|
1773
|
+
hide() {
|
1774
|
+
this.setType('password');
|
1775
|
+
}
|
1776
|
+
setType(type) {
|
1777
|
+
if (type === this.$input.type) {
|
1778
|
+
return;
|
1779
|
+
}
|
1780
|
+
this.$input.setAttribute('type', type);
|
1781
|
+
const isHidden = type === 'password';
|
1782
|
+
const prefixButton = isHidden ? 'show' : 'hide';
|
1783
|
+
const prefixStatus = isHidden ? 'passwordHidden' : 'passwordShown';
|
1784
|
+
this.$showHideButton.innerText = this.i18n.t(`${prefixButton}Password`);
|
1785
|
+
this.$showHideButton.setAttribute('aria-label', this.i18n.t(`${prefixButton}PasswordAriaLabel`));
|
1786
|
+
this.$screenReaderStatusMessage.innerText = this.i18n.t(`${prefixStatus}Announcement`);
|
1787
|
+
}
|
1788
|
+
}
|
1789
|
+
|
1790
|
+
/**
|
1791
|
+
* Password input config
|
1792
|
+
*
|
1793
|
+
* @typedef {object} PasswordInputConfig
|
1794
|
+
* @property {PasswordInputTranslations} [i18n=PasswordInput.defaults.i18n] - Password input translations
|
1795
|
+
*/
|
1796
|
+
|
1797
|
+
/**
|
1798
|
+
* Password input translations
|
1799
|
+
*
|
1800
|
+
* @see {@link PasswordInput.defaults.i18n}
|
1801
|
+
* @typedef {object} PasswordInputTranslations
|
1802
|
+
*
|
1803
|
+
* Messages displayed to the user indicating the state of the show/hide toggle.
|
1804
|
+
* @property {string} [showPassword] - Visible text of the button when the
|
1805
|
+
* password is currently hidden. Plain text only.
|
1806
|
+
* @property {string} [hidePassword] - Visible text of the button when the
|
1807
|
+
* password is currently visible. Plain text only.
|
1808
|
+
* @property {string} [showPasswordAriaLabel] - aria-label of the button when
|
1809
|
+
* the password is currently hidden. Plain text only.
|
1810
|
+
* @property {string} [hidePasswordAriaLabel] - aria-label of the button when
|
1811
|
+
* the password is currently visible. Plain text only.
|
1812
|
+
* @property {string} [passwordShownAnnouncement] - Screen reader
|
1813
|
+
* announcement to make when the password has just become visible.
|
1814
|
+
* Plain text only.
|
1815
|
+
* @property {string} [passwordHiddenAnnouncement] - Screen reader
|
1816
|
+
* announcement to make when the password has just been hidden.
|
1817
|
+
* Plain text only.
|
1818
|
+
*/
|
1819
|
+
|
1820
|
+
/**
|
1821
|
+
* @typedef {import('../../common/index.mjs').Schema} Schema
|
1822
|
+
* @typedef {import('../../i18n.mjs').TranslationPluralForms} TranslationPluralForms
|
1823
|
+
*/
|
1824
|
+
PasswordInput.moduleName = 'govuk-password-input';
|
1825
|
+
PasswordInput.defaults = Object.freeze({
|
1826
|
+
i18n: {
|
1827
|
+
showPassword: 'Show',
|
1828
|
+
hidePassword: 'Hide',
|
1829
|
+
showPasswordAriaLabel: 'Show password',
|
1830
|
+
hidePasswordAriaLabel: 'Hide password',
|
1831
|
+
passwordShownAnnouncement: 'Your password is visible',
|
1832
|
+
passwordHiddenAnnouncement: 'Your password is hidden'
|
1833
|
+
}
|
1834
|
+
});
|
1835
|
+
PasswordInput.schema = Object.freeze({
|
1836
|
+
properties: {
|
1837
|
+
i18n: {
|
1838
|
+
type: 'object'
|
1839
|
+
}
|
1840
|
+
}
|
1841
|
+
});
|
1591
1842
|
|
1592
1843
|
/**
|
1593
1844
|
* Radios component
|
@@ -1756,12 +2007,6 @@ class Tabs extends GOVUKFrontendComponent {
|
|
1756
2007
|
this.$tabs = void 0;
|
1757
2008
|
this.$tabList = void 0;
|
1758
2009
|
this.$tabListItems = void 0;
|
1759
|
-
this.keys = {
|
1760
|
-
left: 37,
|
1761
|
-
right: 39,
|
1762
|
-
up: 38,
|
1763
|
-
down: 40
|
1764
|
-
};
|
1765
2010
|
this.jsHiddenClass = 'govuk-tabs__panel--hidden';
|
1766
2011
|
this.changingHash = false;
|
1767
2012
|
this.boundTabClick = void 0;
|
@@ -1941,14 +2186,18 @@ class Tabs extends GOVUKFrontendComponent {
|
|
1941
2186
|
$panel.id = panelId;
|
1942
2187
|
}
|
1943
2188
|
onTabKeydown(event) {
|
1944
|
-
switch (event.
|
1945
|
-
case
|
1946
|
-
case
|
2189
|
+
switch (event.key) {
|
2190
|
+
case 'ArrowLeft':
|
2191
|
+
case 'ArrowUp':
|
2192
|
+
case 'Left':
|
2193
|
+
case 'Up':
|
1947
2194
|
this.activatePreviousTab();
|
1948
2195
|
event.preventDefault();
|
1949
2196
|
break;
|
1950
|
-
case
|
1951
|
-
case
|
2197
|
+
case 'ArrowRight':
|
2198
|
+
case 'ArrowDown':
|
2199
|
+
case 'Right':
|
2200
|
+
case 'Down':
|
1952
2201
|
this.activateNextTab();
|
1953
2202
|
event.preventDefault();
|
1954
2203
|
break;
|
@@ -2040,7 +2289,7 @@ function initAll(config) {
|
|
2040
2289
|
console.log(new SupportError());
|
2041
2290
|
return;
|
2042
2291
|
}
|
2043
|
-
const components = [[Button, config.button], [CharacterCount, config.characterCount], [Checkboxes], [ErrorSummary, config.errorSummary], [Radios]];
|
2292
|
+
const components = [[Button, config.button], [CharacterCount, config.characterCount], [Checkboxes], [ErrorSummary, config.errorSummary], [Radios], [PasswordInput, config.passwordInput]];
|
2044
2293
|
const $scope = (_config$scope = config.scope) != null ? _config$scope : document;
|
2045
2294
|
components.forEach(([Component, config]) => {
|
2046
2295
|
const $elements = $scope.querySelectorAll(`[data-module="${Component.moduleName}"]`);
|
@@ -2054,4 +2303,4 @@ function initAll(config) {
|
|
2054
2303
|
});
|
2055
2304
|
}
|
2056
2305
|
|
2057
|
-
export { Button, CharacterCount, Checkboxes, ErrorSummary, Radios, initAll };
|
2306
|
+
export { Button, CharacterCount, Checkboxes, ErrorSummary, PasswordInput, Radios, initAll };
|
@@ -1,4 +1,4 @@
|
|
1
|
-
function
|
1
|
+
function e(e,t){const s=e?e.trim():"";let i,n=null==t?void 0:t.type;switch(n||(["true","false"].includes(s)&&(n="boolean"),s.length>0&&isFinite(Number(s))&&(n="number")),n){case"boolean":i="true"===s;break;case"number":i=Number(s);break;default:i=e}return i}function t(...e){const s={};for(const i of e)for(const e of Object.keys(i)){const n=s[e],o=i[e];r(n)&&r(o)?s[e]=t(n,o):s[e]=o}return s}function s(t,s,i){const n=t.schema.properties[i];if("object"!==(null==n?void 0:n.type))return;const o={[i]:{}};for(const[t,n]of Object.entries(s)){let s=o;const a=t.split(".");for(const[o,l]of a.entries())"object"==typeof s&&(o<a.length-1?(r(s[l])||(s[l]={}),s=s[l]):t!==i&&(s[l]=e(n)))}return o[i]}function i(e){if(e.includes("#"))return e.split("#").pop()}function n(e){const t=`--govuk-frontend-breakpoint-${e}`;return{property:t,value:window.getComputedStyle(document.documentElement).getPropertyValue(t)||void 0}}function o(e,t={}){var s;const i=e.getAttribute("tabindex");function n(){var s;null==(s=t.onBlur)||s.call(e),i||e.removeAttribute("tabindex")}i||e.setAttribute("tabindex","-1"),e.addEventListener("focus",(function(){e.addEventListener("blur",n,{once:!0})}),{once:!0}),null==(s=t.onBeforeFocus)||s.call(e),e.focus()}function a(e=document.body){return!!e&&e.classList.contains("govuk-frontend-supported")}function r(e){return!!e&&"object"==typeof e&&!function(e){return Array.isArray(e)}(e)}function l(t,i){const n={};for(const[o,a]of Object.entries(t.schema.properties))o in i&&(n[o]=e(i[o],a)),"object"===(null==a?void 0:a.type)&&(n[o]=s(t,i,o));return n}class c extends Error{constructor(...e){super(...e),this.name="GOVUKFrontendError"}}class h extends c{constructor(e=document.body){const t="noModule"in HTMLScriptElement.prototype?'GOV.UK Frontend initialised without `<body class="govuk-frontend-supported">` from template `<script>` snippet':"GOV.UK Frontend is not supported in this browser";super(e?t:'GOV.UK Frontend initialised without `<script type="module">`'),this.name="SupportError"}}class u extends c{constructor(...e){super(...e),this.name="ConfigError"}}class d extends c{constructor(e){let t="string"==typeof e?e:"";if("object"==typeof e){const{componentName:s,identifier:i,element:n,expectedType:o}=e;t=`${s}: ${i}`,t+=n?` is not of type ${null!=o?o:"HTMLElement"}`:" not found"}super(t),this.name="ElementError"}}class m{constructor(){this.checkSupport()}checkSupport(){if(!a())throw new h}}class p{constructor(e={},t={}){var s;this.translations=void 0,this.locale=void 0,this.translations=e,this.locale=null!=(s=t.locale)?s:document.documentElement.lang||"en"}t(e,t){if(!e)throw new Error("i18n: lookup key missing");let s=this.translations[e];if("number"==typeof(null==t?void 0:t.count)&&"object"==typeof s){const i=s[this.getPluralSuffix(e,t.count)];i&&(s=i)}if("string"==typeof s){if(s.match(/%{(.\S+)}/)){if(!t)throw new Error("i18n: cannot replace placeholders in string if no option data provided");return this.replacePlaceholders(s,t)}return s}return e}replacePlaceholders(e,t){const s=Intl.NumberFormat.supportedLocalesOf(this.locale).length?new Intl.NumberFormat(this.locale):void 0;return e.replace(/%{(.\S+)}/g,(function(e,i){if(Object.prototype.hasOwnProperty.call(t,i)){const e=t[i];return!1===e||"number"!=typeof e&&"string"!=typeof e?"":"number"==typeof e?s?s.format(e):`${e}`:e}throw new Error(`i18n: no data found to replace ${e} placeholder in string`)}))}hasIntlPluralRulesSupport(){return Boolean("PluralRules"in window.Intl&&Intl.PluralRules.supportedLocalesOf(this.locale).length)}getPluralSuffix(e,t){if(t=Number(t),!isFinite(t))return"other";const s=this.translations[e],i=this.hasIntlPluralRulesSupport()?new Intl.PluralRules(this.locale).select(t):this.selectPluralFormUsingFallbackRules(t);if("object"==typeof s){if(i in s)return i;if("other"in s)return console.warn(`i18n: Missing plural form ".${i}" for "${this.locale}" locale. Falling back to ".other".`),"other"}throw new Error(`i18n: Plural form ".other" is required for "${this.locale}" locale`)}selectPluralFormUsingFallbackRules(e){e=Math.abs(Math.floor(e));const t=this.getPluralRulesForLocale();return t?p.pluralRules[t](e):"other"}getPluralRulesForLocale(){const e=this.locale.split("-")[0];for(const t in p.pluralRulesMap){const s=p.pluralRulesMap[t];if(s.includes(this.locale)||s.includes(e))return t}}}p.pluralRulesMap={arabic:["ar"],chinese:["my","zh","id","ja","jv","ko","ms","th","vi"],french:["hy","bn","fr","gu","hi","fa","pa","zu"],german:["af","sq","az","eu","bg","ca","da","nl","en","et","fi","ka","de","el","hu","lb","no","so","sw","sv","ta","te","tr","ur"],irish:["ga"],russian:["ru","uk"],scottish:["gd"],spanish:["pt-PT","it","es"],welsh:["cy"]},p.pluralRules={arabic:e=>0===e?"zero":1===e?"one":2===e?"two":e%100>=3&&e%100<=10?"few":e%100>=11&&e%100<=99?"many":"other",chinese:()=>"other",french:e=>0===e||1===e?"one":"other",german:e=>1===e?"one":"other",irish:e=>1===e?"one":2===e?"two":e>=3&&e<=6?"few":e>=7&&e<=10?"many":"other",russian(e){const t=e%100,s=t%10;return 1===s&&11!==t?"one":s>=2&&s<=4&&!(t>=12&&t<=14)?"few":0===s||s>=5&&s<=9||t>=11&&t<=14?"many":"other"},scottish:e=>1===e||11===e?"one":2===e||12===e?"two":e>=3&&e<=10||e>=13&&e<=19?"few":"other",spanish:e=>1===e?"one":e%1e6==0&&0!==e?"many":"other",welsh:e=>0===e?"zero":1===e?"one":2===e?"two":3===e?"few":6===e?"many":"other"};
|
2
2
|
/**
|
3
3
|
* Accordion component
|
4
4
|
*
|
@@ -13,13 +13,13 @@ function t(...t){function e(t){const e={};return function t(s,i){for(const[n,o]o
|
|
13
13
|
*
|
14
14
|
* @preserve
|
15
15
|
*/
|
16
|
-
class
|
16
|
+
class g extends m{constructor(e,s={}){if(super(),this.$module=void 0,this.config=void 0,this.i18n=void 0,this.controlsClass="govuk-accordion__controls",this.showAllClass="govuk-accordion__show-all",this.showAllTextClass="govuk-accordion__show-all-text",this.sectionClass="govuk-accordion__section",this.sectionExpandedClass="govuk-accordion__section--expanded",this.sectionButtonClass="govuk-accordion__section-button",this.sectionHeaderClass="govuk-accordion__section-header",this.sectionHeadingClass="govuk-accordion__section-heading",this.sectionHeadingDividerClass="govuk-accordion__section-heading-divider",this.sectionHeadingTextClass="govuk-accordion__section-heading-text",this.sectionHeadingTextFocusClass="govuk-accordion__section-heading-text-focus",this.sectionShowHideToggleClass="govuk-accordion__section-toggle",this.sectionShowHideToggleFocusClass="govuk-accordion__section-toggle-focus",this.sectionShowHideTextClass="govuk-accordion__section-toggle-text",this.upChevronIconClass="govuk-accordion-nav__chevron",this.downChevronIconClass="govuk-accordion-nav__chevron--down",this.sectionSummaryClass="govuk-accordion__section-summary",this.sectionSummaryFocusClass="govuk-accordion__section-summary-focus",this.sectionContentClass="govuk-accordion__section-content",this.$sections=void 0,this.browserSupportsSessionStorage=!1,this.$showAllButton=null,this.$showAllIcon=null,this.$showAllText=null,!(e instanceof HTMLElement))throw new d({componentName:"Accordion",element:e,identifier:"Root element (`$module`)"});this.$module=e,this.config=t(g.defaults,s,l(g,e.dataset)),this.i18n=new p(this.config.i18n);const i=this.$module.querySelectorAll(`.${this.sectionClass}`);if(!i.length)throw new d({componentName:"Accordion",identifier:`Sections (\`<div class="${this.sectionClass}">\`)`});this.$sections=i,this.browserSupportsSessionStorage=f.checkForSessionStorage(),this.initControls(),this.initSectionHeaders();const n=this.checkIfAllSectionsOpen();this.updateShowAllButton(n)}initControls(){this.$showAllButton=document.createElement("button"),this.$showAllButton.setAttribute("type","button"),this.$showAllButton.setAttribute("class",this.showAllClass),this.$showAllButton.setAttribute("aria-expanded","false"),this.$showAllIcon=document.createElement("span"),this.$showAllIcon.classList.add(this.upChevronIconClass),this.$showAllButton.appendChild(this.$showAllIcon);const e=document.createElement("div");e.setAttribute("class",this.controlsClass),e.appendChild(this.$showAllButton),this.$module.insertBefore(e,this.$module.firstChild),this.$showAllText=document.createElement("span"),this.$showAllText.classList.add(this.showAllTextClass),this.$showAllButton.appendChild(this.$showAllText),this.$showAllButton.addEventListener("click",(()=>this.onShowOrHideAllToggle())),"onbeforematch"in document&&document.addEventListener("beforematch",(e=>this.onBeforeMatch(e)))}initSectionHeaders(){this.$sections.forEach(((e,t)=>{const s=e.querySelector(`.${this.sectionHeaderClass}`);if(!s)throw new d({componentName:"Accordion",identifier:`Section headers (\`<div class="${this.sectionHeaderClass}">\`)`});this.constructHeaderMarkup(s,t),this.setExpanded(this.isExpanded(e),e),s.addEventListener("click",(()=>this.onSectionToggle(e))),this.setInitialState(e)}))}constructHeaderMarkup(e,t){const s=e.querySelector(`.${this.sectionButtonClass}`),i=e.querySelector(`.${this.sectionHeadingClass}`),n=e.querySelector(`.${this.sectionSummaryClass}`);if(!i)throw new d({componentName:"Accordion",identifier:`Section heading (\`.${this.sectionHeadingClass}\`)`});if(!s)throw new d({componentName:"Accordion",identifier:`Section button placeholder (\`<span class="${this.sectionButtonClass}">\`)`});const o=document.createElement("button");o.setAttribute("type","button"),o.setAttribute("aria-controls",`${this.$module.id}-content-${t+1}`);for(const e of Array.from(s.attributes))"id"!==e.nodeName&&o.setAttribute(e.nodeName,`${e.nodeValue}`);const a=document.createElement("span");a.classList.add(this.sectionHeadingTextClass),a.id=s.id;const r=document.createElement("span");r.classList.add(this.sectionHeadingTextFocusClass),a.appendChild(r),r.innerHTML=s.innerHTML;const l=document.createElement("span");l.classList.add(this.sectionShowHideToggleClass),l.setAttribute("data-nosnippet","");const c=document.createElement("span");c.classList.add(this.sectionShowHideToggleFocusClass),l.appendChild(c);const h=document.createElement("span"),u=document.createElement("span");if(u.classList.add(this.upChevronIconClass),c.appendChild(u),h.classList.add(this.sectionShowHideTextClass),c.appendChild(h),o.appendChild(a),o.appendChild(this.getButtonPunctuationEl()),null!=n&&n.parentNode){const e=document.createElement("span"),t=document.createElement("span");t.classList.add(this.sectionSummaryFocusClass),e.appendChild(t);for(const t of Array.from(n.attributes))e.setAttribute(t.nodeName,`${t.nodeValue}`);t.innerHTML=n.innerHTML,n.parentNode.replaceChild(e,n),o.appendChild(e),o.appendChild(this.getButtonPunctuationEl())}o.appendChild(l),i.removeChild(s),i.appendChild(o)}onBeforeMatch(e){const t=e.target;if(!(t instanceof Element))return;const s=t.closest(`.${this.sectionClass}`);s&&this.setExpanded(!0,s)}onSectionToggle(e){const t=this.isExpanded(e);this.setExpanded(!t,e),this.storeState(e)}onShowOrHideAllToggle(){const e=!this.checkIfAllSectionsOpen();this.$sections.forEach((t=>{this.setExpanded(e,t),this.storeState(t)})),this.updateShowAllButton(e)}setExpanded(e,t){const s=t.querySelector(`.${this.upChevronIconClass}`),i=t.querySelector(`.${this.sectionShowHideTextClass}`),n=t.querySelector(`.${this.sectionButtonClass}`),o=t.querySelector(`.${this.sectionContentClass}`);if(!o)throw new d({componentName:"Accordion",identifier:`Section content (\`<div class="${this.sectionContentClass}">\`)`});if(!s||!i||!n)return;const a=e?this.i18n.t("hideSection"):this.i18n.t("showSection");i.textContent=a,n.setAttribute("aria-expanded",`${e}`);const r=[],l=t.querySelector(`.${this.sectionHeadingTextClass}`);l&&r.push(`${l.textContent}`.trim());const c=t.querySelector(`.${this.sectionSummaryClass}`);c&&r.push(`${c.textContent}`.trim());const h=e?this.i18n.t("hideSectionAriaLabel"):this.i18n.t("showSectionAriaLabel");r.push(h),n.setAttribute("aria-label",r.join(" , ")),e?(o.removeAttribute("hidden"),t.classList.add(this.sectionExpandedClass),s.classList.remove(this.downChevronIconClass)):(o.setAttribute("hidden","until-found"),t.classList.remove(this.sectionExpandedClass),s.classList.add(this.downChevronIconClass));const u=this.checkIfAllSectionsOpen();this.updateShowAllButton(u)}isExpanded(e){return e.classList.contains(this.sectionExpandedClass)}checkIfAllSectionsOpen(){return this.$sections.length===this.$module.querySelectorAll(`.${this.sectionExpandedClass}`).length}updateShowAllButton(e){this.$showAllButton&&this.$showAllText&&this.$showAllIcon&&(this.$showAllButton.setAttribute("aria-expanded",e.toString()),this.$showAllText.textContent=e?this.i18n.t("hideAllSections"):this.i18n.t("showAllSections"),this.$showAllIcon.classList.toggle(this.downChevronIconClass,!e))}storeState(e){if(this.browserSupportsSessionStorage&&this.config.rememberExpanded){const t=e.querySelector(`.${this.sectionButtonClass}`);if(t){const e=t.getAttribute("aria-controls"),s=t.getAttribute("aria-expanded");e&&s&&window.sessionStorage.setItem(e,s)}}}setInitialState(e){if(this.browserSupportsSessionStorage&&this.config.rememberExpanded){const t=e.querySelector(`.${this.sectionButtonClass}`);if(t){const s=t.getAttribute("aria-controls"),i=s?window.sessionStorage.getItem(s):null;null!==i&&this.setExpanded("true"===i,e)}}}getButtonPunctuationEl(){const e=document.createElement("span");return e.classList.add("govuk-visually-hidden",this.sectionHeadingDividerClass),e.innerHTML=", ",e}}g.moduleName="govuk-accordion",g.defaults=Object.freeze({i18n:{hideAllSections:"Hide all sections",hideSection:"Hide",hideSectionAriaLabel:"Hide this section",showAllSections:"Show all sections",showSection:"Show",showSectionAriaLabel:"Show this section"},rememberExpanded:!0}),g.schema=Object.freeze({properties:{i18n:{type:"object"},rememberExpanded:{type:"boolean"}}});const f={checkForSessionStorage:function(){const e="this is the test string";let t;try{return window.sessionStorage.setItem(e,e),t=window.sessionStorage.getItem(e)===e.toString(),window.sessionStorage.removeItem(e),t}catch(e){return!1}}};
|
17
17
|
/**
|
18
18
|
* JavaScript enhancements for the Button component
|
19
19
|
*
|
20
20
|
* @preserve
|
21
21
|
*/
|
22
|
-
class
|
22
|
+
class b extends m{constructor(e,s={}){if(super(),this.$module=void 0,this.config=void 0,this.debounceFormSubmitTimer=null,!(e instanceof HTMLElement))throw new d({componentName:"Button",element:e,identifier:"Root element (`$module`)"});this.$module=e,this.config=t(b.defaults,s,l(b,e.dataset)),this.$module.addEventListener("keydown",(e=>this.handleKeyDown(e))),this.$module.addEventListener("click",(e=>this.debounce(e)))}handleKeyDown(e){const t=e.target;" "===e.key&&t instanceof HTMLElement&&"button"===t.getAttribute("role")&&(e.preventDefault(),t.click())}debounce(e){if(this.config.preventDoubleClick)return this.debounceFormSubmitTimer?(e.preventDefault(),!1):void(this.debounceFormSubmitTimer=window.setTimeout((()=>{this.debounceFormSubmitTimer=null}),1e3))}}function v(e,t){const s=e.closest(`[${t}]`);return s?s.getAttribute(t):null}
|
23
23
|
/**
|
24
24
|
* Character count component
|
25
25
|
*
|
@@ -31,13 +31,13 @@ class f extends d{constructor(e,s={}){if(super(),this.$module=void 0,this.config
|
|
31
31
|
* of the available characters/words has been entered.
|
32
32
|
*
|
33
33
|
* @preserve
|
34
|
-
*/
|
34
|
+
*/b.moduleName="govuk-button",b.defaults=Object.freeze({preventDoubleClick:!1}),b.schema=Object.freeze({properties:{preventDoubleClick:{type:"boolean"}}});class w extends m{constructor(e,s={}){var i,n;if(super(),this.$module=void 0,this.$textarea=void 0,this.$visibleCountMessage=void 0,this.$screenReaderCountMessage=void 0,this.lastInputTimestamp=null,this.lastInputValue="",this.valueChecker=null,this.config=void 0,this.i18n=void 0,this.maxLength=void 0,!(e instanceof HTMLElement))throw new d({componentName:"Character count",element:e,identifier:"Root element (`$module`)"});const o=e.querySelector(".govuk-js-character-count");if(!(o instanceof HTMLTextAreaElement||o instanceof HTMLInputElement))throw new d({componentName:"Character count",element:o,expectedType:"HTMLTextareaElement or HTMLInputElement",identifier:"Form field (`.govuk-js-character-count`)"});const a=l(w,e.dataset);let r={};("maxwords"in a||"maxlength"in a)&&(r={maxlength:void 0,maxwords:void 0}),this.config=t(w.defaults,s,r,a);const c=function(e,t){const s=[];for(const[i,n]of Object.entries(e)){const e=[];if(Array.isArray(n)){for(const{required:s,errorMessage:i}of n)s.every((e=>!!t[e]))||e.push(i);"anyOf"!==i||n.length-e.length>=1||s.push(...e)}}return s}(w.schema,this.config);if(c[0])throw new u(`Character count: ${c[0]}`);this.i18n=new p(this.config.i18n,{locale:v(e,"lang")}),this.maxLength=null!=(i=null!=(n=this.config.maxwords)?n:this.config.maxlength)?i:1/0,this.$module=e,this.$textarea=o;const h=`${this.$textarea.id}-info`,m=document.getElementById(h);if(!m)throw new d({componentName:"Character count",element:m,identifier:`Count message (\`id="${h}"\`)`});`${m.textContent}`.match(/^\s*$/)&&(m.textContent=this.i18n.t("textareaDescription",{count:this.maxLength})),this.$textarea.insertAdjacentElement("afterend",m);const g=document.createElement("div");g.className="govuk-character-count__sr-status govuk-visually-hidden",g.setAttribute("aria-live","polite"),this.$screenReaderCountMessage=g,m.insertAdjacentElement("afterend",g);const f=document.createElement("div");f.className=m.className,f.classList.add("govuk-character-count__status"),f.setAttribute("aria-hidden","true"),this.$visibleCountMessage=f,m.insertAdjacentElement("afterend",f),m.classList.add("govuk-visually-hidden"),this.$textarea.removeAttribute("maxlength"),this.bindChangeEvents(),window.addEventListener("pageshow",(()=>this.updateCountMessage())),this.updateCountMessage()}bindChangeEvents(){this.$textarea.addEventListener("keyup",(()=>this.handleKeyUp())),this.$textarea.addEventListener("focus",(()=>this.handleFocus())),this.$textarea.addEventListener("blur",(()=>this.handleBlur()))}handleKeyUp(){this.updateVisibleCountMessage(),this.lastInputTimestamp=Date.now()}handleFocus(){this.valueChecker=window.setInterval((()=>{(!this.lastInputTimestamp||Date.now()-500>=this.lastInputTimestamp)&&this.updateIfValueChanged()}),1e3)}handleBlur(){this.valueChecker&&window.clearInterval(this.valueChecker)}updateIfValueChanged(){this.$textarea.value!==this.lastInputValue&&(this.lastInputValue=this.$textarea.value,this.updateCountMessage())}updateCountMessage(){this.updateVisibleCountMessage(),this.updateScreenReaderCountMessage()}updateVisibleCountMessage(){const e=this.maxLength-this.count(this.$textarea.value)<0;this.$visibleCountMessage.classList.toggle("govuk-character-count__message--disabled",!this.isOverThreshold()),this.$textarea.classList.toggle("govuk-textarea--error",e),this.$visibleCountMessage.classList.toggle("govuk-error-message",e),this.$visibleCountMessage.classList.toggle("govuk-hint",!e),this.$visibleCountMessage.textContent=this.getCountMessage()}updateScreenReaderCountMessage(){this.isOverThreshold()?this.$screenReaderCountMessage.removeAttribute("aria-hidden"):this.$screenReaderCountMessage.setAttribute("aria-hidden","true"),this.$screenReaderCountMessage.textContent=this.getCountMessage()}count(e){if(this.config.maxwords){var t;return(null!=(t=e.match(/\S+/g))?t:[]).length}return e.length}getCountMessage(){const e=this.maxLength-this.count(this.$textarea.value),t=this.config.maxwords?"words":"characters";return this.formatCountMessage(e,t)}formatCountMessage(e,t){if(0===e)return this.i18n.t(`${t}AtLimit`);const s=e<0?"OverLimit":"UnderLimit";return this.i18n.t(`${t}${s}`,{count:Math.abs(e)})}isOverThreshold(){if(!this.config.threshold)return!0;const e=this.count(this.$textarea.value);return this.maxLength*this.config.threshold/100<=e}}w.moduleName="govuk-character-count",w.defaults=Object.freeze({threshold:0,i18n:{charactersUnderLimit:{one:"You have %{count} character remaining",other:"You have %{count} characters remaining"},charactersAtLimit:"You have 0 characters remaining",charactersOverLimit:{one:"You have %{count} character too many",other:"You have %{count} characters too many"},wordsUnderLimit:{one:"You have %{count} word remaining",other:"You have %{count} words remaining"},wordsAtLimit:"You have 0 words remaining",wordsOverLimit:{one:"You have %{count} word too many",other:"You have %{count} words too many"},textareaDescription:{other:""}}}),w.schema=Object.freeze({properties:{i18n:{type:"object"},maxwords:{type:"number"},maxlength:{type:"number"},threshold:{type:"number"}},anyOf:[{required:["maxwords"],errorMessage:'Either "maxlength" or "maxwords" must be provided'},{required:["maxlength"],errorMessage:'Either "maxlength" or "maxwords" must be provided'}]});
|
35
35
|
/**
|
36
36
|
* Checkboxes component
|
37
37
|
*
|
38
38
|
* @preserve
|
39
39
|
*/
|
40
|
-
class
|
40
|
+
class $ extends m{constructor(e){if(super(),this.$module=void 0,this.$inputs=void 0,!(e instanceof HTMLElement))throw new d({componentName:"Checkboxes",element:e,identifier:"Root element (`$module`)"});const t=e.querySelectorAll('input[type="checkbox"]');if(!t.length)throw new d({componentName:"Checkboxes",identifier:'Form inputs (`<input type="checkbox">`)'});this.$module=e,this.$inputs=t,this.$inputs.forEach((e=>{const t=e.getAttribute("data-aria-controls");if(t){if(!document.getElementById(t))throw new d({componentName:"Checkboxes",identifier:`Conditional reveal (\`id="${t}"\`)`});e.setAttribute("aria-controls",t),e.removeAttribute("data-aria-controls")}})),window.addEventListener("pageshow",(()=>this.syncAllConditionalReveals())),this.syncAllConditionalReveals(),this.$module.addEventListener("click",(e=>this.handleClick(e)))}syncAllConditionalReveals(){this.$inputs.forEach((e=>this.syncConditionalRevealWithInputState(e)))}syncConditionalRevealWithInputState(e){const t=e.getAttribute("aria-controls");if(!t)return;const s=document.getElementById(t);if(s&&s.classList.contains("govuk-checkboxes__conditional")){const t=e.checked;e.setAttribute("aria-expanded",t.toString()),s.classList.toggle("govuk-checkboxes__conditional--hidden",!t)}}unCheckAllInputsExcept(e){document.querySelectorAll(`input[type="checkbox"][name="${e.name}"]`).forEach((t=>{e.form===t.form&&t!==e&&(t.checked=!1,this.syncConditionalRevealWithInputState(t))}))}unCheckExclusiveInputs(e){document.querySelectorAll(`input[data-behaviour="exclusive"][type="checkbox"][name="${e.name}"]`).forEach((t=>{e.form===t.form&&(t.checked=!1,this.syncConditionalRevealWithInputState(t))}))}handleClick(e){const t=e.target;if(!(t instanceof HTMLInputElement)||"checkbox"!==t.type)return;if(t.getAttribute("aria-controls")&&this.syncConditionalRevealWithInputState(t),!t.checked)return;"exclusive"===t.getAttribute("data-behaviour")?this.unCheckAllInputsExcept(t):this.unCheckExclusiveInputs(t)}}$.moduleName="govuk-checkboxes";
|
41
41
|
/**
|
42
42
|
* Error summary component
|
43
43
|
*
|
@@ -46,40 +46,46 @@ class w extends d{constructor(t){if(super(),this.$module=void 0,this.$inputs=voi
|
|
46
46
|
*
|
47
47
|
* @preserve
|
48
48
|
*/
|
49
|
-
class
|
49
|
+
class y extends m{constructor(e,s={}){if(super(),this.$module=void 0,this.config=void 0,!(e instanceof HTMLElement))throw new d({componentName:"Error summary",element:e,identifier:"Root element (`$module`)"});this.$module=e,this.config=t(y.defaults,s,l(y,e.dataset)),this.config.disableAutoFocus||o(this.$module),this.$module.addEventListener("click",(e=>this.handleClick(e)))}handleClick(e){const t=e.target;t&&this.focusTarget(t)&&e.preventDefault()}focusTarget(e){if(!(e instanceof HTMLAnchorElement))return!1;const t=i(e.href);if(!t)return!1;const s=document.getElementById(t);if(!s)return!1;const n=this.getAssociatedLegendOrLabel(s);return!!n&&(n.scrollIntoView(),s.focus({preventScroll:!0}),!0)}getAssociatedLegendOrLabel(e){var t;const s=e.closest("fieldset");if(s){const t=s.getElementsByTagName("legend");if(t.length){const s=t[0];if(e instanceof HTMLInputElement&&("checkbox"===e.type||"radio"===e.type))return s;const i=s.getBoundingClientRect().top,n=e.getBoundingClientRect();if(n.height&&window.innerHeight){if(n.top+n.height-i<window.innerHeight/2)return s}}}return null!=(t=document.querySelector(`label[for='${e.getAttribute("id")}']`))?t:e.closest("label")}}y.moduleName="govuk-error-summary",y.defaults=Object.freeze({disableAutoFocus:!1}),y.schema=Object.freeze({properties:{disableAutoFocus:{type:"boolean"}}});
|
50
50
|
/**
|
51
51
|
* Exit this page component
|
52
52
|
*
|
53
53
|
* @preserve
|
54
54
|
*/
|
55
|
-
class k extends
|
55
|
+
class k extends m{constructor(e,s={}){if(super(),this.$module=void 0,this.config=void 0,this.i18n=void 0,this.$button=void 0,this.$skiplinkButton=null,this.$updateSpan=null,this.$indicatorContainer=null,this.$overlay=null,this.keypressCounter=0,this.lastKeyWasModified=!1,this.timeoutTime=5e3,this.keypressTimeoutId=null,this.timeoutMessageId=null,!(e instanceof HTMLElement))throw new d({componentName:"Exit this page",element:e,identifier:"Root element (`$module`)"});const i=e.querySelector(".govuk-exit-this-page__button");if(!(i instanceof HTMLAnchorElement))throw new d({componentName:"Exit this page",element:i,expectedType:"HTMLAnchorElement",identifier:"Button (`.govuk-exit-this-page__button`)"});this.config=t(k.defaults,s,l(k,e.dataset)),this.i18n=new p(this.config.i18n),this.$module=e,this.$button=i;const n=document.querySelector(".govuk-js-exit-this-page-skiplink");n instanceof HTMLAnchorElement&&(this.$skiplinkButton=n),this.buildIndicator(),this.initUpdateSpan(),this.initButtonClickHandler(),"govukFrontendExitThisPageKeypress"in document.body.dataset||(document.addEventListener("keyup",this.handleKeypress.bind(this),!0),document.body.dataset.govukFrontendExitThisPageKeypress="true"),window.addEventListener("pageshow",this.resetPage.bind(this))}initUpdateSpan(){this.$updateSpan=document.createElement("span"),this.$updateSpan.setAttribute("role","status"),this.$updateSpan.className="govuk-visually-hidden",this.$module.appendChild(this.$updateSpan)}initButtonClickHandler(){this.$button.addEventListener("click",this.handleClick.bind(this)),this.$skiplinkButton&&this.$skiplinkButton.addEventListener("click",this.handleClick.bind(this))}buildIndicator(){this.$indicatorContainer=document.createElement("div"),this.$indicatorContainer.className="govuk-exit-this-page__indicator",this.$indicatorContainer.setAttribute("aria-hidden","true");for(let e=0;e<3;e++){const e=document.createElement("div");e.className="govuk-exit-this-page__indicator-light",this.$indicatorContainer.appendChild(e)}this.$button.appendChild(this.$indicatorContainer)}updateIndicator(){if(!this.$indicatorContainer)return;this.$indicatorContainer.classList.toggle("govuk-exit-this-page__indicator--visible",this.keypressCounter>0);this.$indicatorContainer.querySelectorAll(".govuk-exit-this-page__indicator-light").forEach(((e,t)=>{e.classList.toggle("govuk-exit-this-page__indicator-light--on",t<this.keypressCounter)}))}exitPage(){this.$updateSpan&&(this.$updateSpan.textContent="",document.body.classList.add("govuk-exit-this-page-hide-content"),this.$overlay=document.createElement("div"),this.$overlay.className="govuk-exit-this-page-overlay",this.$overlay.setAttribute("role","alert"),document.body.appendChild(this.$overlay),this.$overlay.textContent=this.i18n.t("activated"),window.location.href=this.$button.href)}handleClick(e){e.preventDefault(),this.exitPage()}handleKeypress(e){this.$updateSpan&&("Shift"!==e.key||this.lastKeyWasModified?this.keypressTimeoutId&&this.resetKeypressTimer():(this.keypressCounter+=1,this.updateIndicator(),this.timeoutMessageId&&(window.clearTimeout(this.timeoutMessageId),this.timeoutMessageId=null),this.keypressCounter>=3?(this.keypressCounter=0,this.keypressTimeoutId&&(window.clearTimeout(this.keypressTimeoutId),this.keypressTimeoutId=null),this.exitPage()):1===this.keypressCounter?this.$updateSpan.textContent=this.i18n.t("pressTwoMoreTimes"):this.$updateSpan.textContent=this.i18n.t("pressOneMoreTime"),this.setKeypressTimer()),this.lastKeyWasModified=e.shiftKey)}setKeypressTimer(){this.keypressTimeoutId&&window.clearTimeout(this.keypressTimeoutId),this.keypressTimeoutId=window.setTimeout(this.resetKeypressTimer.bind(this),this.timeoutTime)}resetKeypressTimer(){if(!this.$updateSpan)return;this.keypressTimeoutId&&(window.clearTimeout(this.keypressTimeoutId),this.keypressTimeoutId=null);const e=this.$updateSpan;this.keypressCounter=0,e.textContent=this.i18n.t("timedOut"),this.timeoutMessageId=window.setTimeout((()=>{e.textContent=""}),this.timeoutTime),this.updateIndicator()}resetPage(){document.body.classList.remove("govuk-exit-this-page-hide-content"),this.$overlay&&(this.$overlay.remove(),this.$overlay=null),this.$updateSpan&&(this.$updateSpan.setAttribute("role","status"),this.$updateSpan.textContent=""),this.updateIndicator(),this.keypressTimeoutId&&window.clearTimeout(this.keypressTimeoutId),this.timeoutMessageId&&window.clearTimeout(this.timeoutMessageId)}}k.moduleName="govuk-exit-this-page",k.defaults=Object.freeze({i18n:{activated:"Loading.",timedOut:"Exit this page expired.",pressTwoMoreTimes:"Shift, press 2 more times to exit.",pressOneMoreTime:"Shift, press 1 more time to exit."}}),k.schema=Object.freeze({properties:{i18n:{type:"object"}}});(
|
56
56
|
/**
|
57
57
|
* Header component
|
58
58
|
*
|
59
59
|
* @preserve
|
60
60
|
*/
|
61
|
-
class extends
|
61
|
+
class extends m{constructor(e){if(super(),this.$module=void 0,this.$menuButton=void 0,this.$menu=void 0,this.menuIsOpen=!1,this.mql=null,!e)throw new d({componentName:"Header",element:e,identifier:"Root element (`$module`)"});this.$module=e;const t=e.querySelector(".govuk-js-header-toggle");if(!t)return this;const s=t.getAttribute("aria-controls");if(!s)throw new d({componentName:"Header",identifier:'Navigation button (`<button class="govuk-js-header-toggle">`) attribute (`aria-controls`)'});const i=document.getElementById(s);if(!i)throw new d({componentName:"Header",element:i,identifier:`Navigation (\`<ul id="${s}">\`)`});this.$menu=i,this.$menuButton=t,this.setupResponsiveChecks(),this.$menuButton.addEventListener("click",(()=>this.handleMenuButtonClick()))}setupResponsiveChecks(){const e=n("desktop");if(!e.value)throw new d({componentName:"Header",identifier:`CSS custom property (\`${e.property}\`) on pseudo-class \`:root\``});this.mql=window.matchMedia(`(min-width: ${e.value})`),"addEventListener"in this.mql?this.mql.addEventListener("change",(()=>this.checkMode())):this.mql.addListener((()=>this.checkMode())),this.checkMode()}checkMode(){this.mql&&this.$menu&&this.$menuButton&&(this.mql.matches?(this.$menu.removeAttribute("hidden"),this.$menuButton.setAttribute("hidden","")):(this.$menuButton.removeAttribute("hidden"),this.$menuButton.setAttribute("aria-expanded",this.menuIsOpen.toString()),this.menuIsOpen?this.$menu.removeAttribute("hidden"):this.$menu.setAttribute("hidden","")))}handleMenuButtonClick(){this.menuIsOpen=!this.menuIsOpen,this.checkMode()}}).moduleName="govuk-header";
|
62
62
|
/**
|
63
63
|
* Notification Banner component
|
64
64
|
*
|
65
65
|
* @preserve
|
66
66
|
*/
|
67
|
-
class C extends
|
67
|
+
class C extends m{constructor(e,s={}){if(super(),this.$module=void 0,this.config=void 0,!(e instanceof HTMLElement))throw new d({componentName:"Notification banner",element:e,identifier:"Root element (`$module`)"});this.$module=e,this.config=t(C.defaults,s,l(C,e.dataset)),"alert"!==this.$module.getAttribute("role")||this.config.disableAutoFocus||o(this.$module)}}C.moduleName="govuk-notification-banner",C.defaults=Object.freeze({disableAutoFocus:!1}),C.schema=Object.freeze({properties:{disableAutoFocus:{type:"boolean"}}});
|
68
|
+
/**
|
69
|
+
* Password input component
|
70
|
+
*
|
71
|
+
* @preserve
|
72
|
+
*/
|
73
|
+
class A extends m{constructor(e,s={}){if(super(),this.$module=void 0,this.config=void 0,this.i18n=void 0,this.$input=void 0,this.$showHideButton=void 0,this.$screenReaderStatusMessage=void 0,!(e instanceof HTMLElement))throw new d({componentName:"Password input",element:e,identifier:"Root element (`$module`)"});const i=e.querySelector(".govuk-js-password-input-input");if(!(i instanceof HTMLInputElement))throw new d({componentName:"Password input",element:i,expectedType:"HTMLInputElement",identifier:"Form field (`.govuk-js-password-input-input`)"});if("password"!==i.type)throw new d("Password input: Form field (`.govuk-js-password-input-input`) must be of type `password`.");const n=e.querySelector(".govuk-js-password-input-toggle");if(!(n instanceof HTMLButtonElement))throw new d({componentName:"Password input",element:n,expectedType:"HTMLButtonElement",identifier:"Button (`.govuk-js-password-input-toggle`)"});if("button"!==n.type)throw new d("Password input: Button (`.govuk-js-password-input-toggle`) must be of type `button`.");this.$module=e,this.$input=i,this.$showHideButton=n,this.config=t(A.defaults,s,l(A,e.dataset)),this.i18n=new p(this.config.i18n,{locale:v(e,"lang")}),this.$showHideButton.removeAttribute("hidden");const o=document.createElement("div");o.className="govuk-password-input__sr-status govuk-visually-hidden",o.setAttribute("aria-live","polite"),this.$screenReaderStatusMessage=o,this.$input.insertAdjacentElement("afterend",o),this.$showHideButton.addEventListener("click",this.toggle.bind(this)),this.$input.form&&this.$input.form.addEventListener("submit",(()=>this.hide())),window.addEventListener("pageshow",(e=>{e.persisted&&"password"!==this.$input.type&&this.hide()})),this.hide()}toggle(e){e.preventDefault(),"password"!==this.$input.type?this.hide():this.show()}show(){this.setType("text")}hide(){this.setType("password")}setType(e){if(e===this.$input.type)return;this.$input.setAttribute("type",e);const t="password"===e,s=t?"show":"hide",i=t?"passwordHidden":"passwordShown";this.$showHideButton.innerText=this.i18n.t(`${s}Password`),this.$showHideButton.setAttribute("aria-label",this.i18n.t(`${s}PasswordAriaLabel`)),this.$screenReaderStatusMessage.innerText=this.i18n.t(`${i}Announcement`)}}A.moduleName="govuk-password-input",A.defaults=Object.freeze({i18n:{showPassword:"Show",hidePassword:"Hide",showPasswordAriaLabel:"Show password",hidePasswordAriaLabel:"Hide password",passwordShownAnnouncement:"Your password is visible",passwordHiddenAnnouncement:"Your password is hidden"}}),A.schema=Object.freeze({properties:{i18n:{type:"object"}}});
|
68
74
|
/**
|
69
75
|
* Radios component
|
70
76
|
*
|
71
77
|
* @preserve
|
72
78
|
*/
|
73
|
-
class
|
79
|
+
class x extends m{constructor(e){if(super(),this.$module=void 0,this.$inputs=void 0,!(e instanceof HTMLElement))throw new d({componentName:"Radios",element:e,identifier:"Root element (`$module`)"});const t=e.querySelectorAll('input[type="radio"]');if(!t.length)throw new d({componentName:"Radios",identifier:'Form inputs (`<input type="radio">`)'});this.$module=e,this.$inputs=t,this.$inputs.forEach((e=>{const t=e.getAttribute("data-aria-controls");if(t){if(!document.getElementById(t))throw new d({componentName:"Radios",identifier:`Conditional reveal (\`id="${t}"\`)`});e.setAttribute("aria-controls",t),e.removeAttribute("data-aria-controls")}})),window.addEventListener("pageshow",(()=>this.syncAllConditionalReveals())),this.syncAllConditionalReveals(),this.$module.addEventListener("click",(e=>this.handleClick(e)))}syncAllConditionalReveals(){this.$inputs.forEach((e=>this.syncConditionalRevealWithInputState(e)))}syncConditionalRevealWithInputState(e){const t=e.getAttribute("aria-controls");if(!t)return;const s=document.getElementById(t);if(null!=s&&s.classList.contains("govuk-radios__conditional")){const t=e.checked;e.setAttribute("aria-expanded",t.toString()),s.classList.toggle("govuk-radios__conditional--hidden",!t)}}handleClick(e){const t=e.target;if(!(t instanceof HTMLInputElement)||"radio"!==t.type)return;const s=document.querySelectorAll('input[type="radio"][aria-controls]'),i=t.form,n=t.name;s.forEach((e=>{const t=e.form===i;e.name===n&&t&&this.syncConditionalRevealWithInputState(e)}))}}x.moduleName="govuk-radios";(
|
74
80
|
/**
|
75
81
|
* Skip link component
|
76
82
|
*
|
77
83
|
* @preserve
|
78
84
|
*/
|
79
|
-
class extends
|
85
|
+
class extends m{constructor(e){var t;if(super(),this.$module=void 0,!(e instanceof HTMLAnchorElement))throw new d({componentName:"Skip link",element:e,expectedType:"HTMLAnchorElement",identifier:"Root element (`$module`)"});this.$module=e;const s=this.$module.hash,n=null!=(t=this.$module.getAttribute("href"))?t:"";let a;try{a=new window.URL(this.$module.href)}catch(e){throw new d(`Skip link: Target link (\`href="${n}"\`) is invalid`)}if(a.origin!==window.location.origin||a.pathname!==window.location.pathname)return;const r=i(s);if(!r)throw new d(`Skip link: Target link (\`href="${n}"\`) has no hash fragment`);const l=document.getElementById(r);if(!l)throw new d({componentName:"Skip link",element:l,identifier:`Target content (\`id="${r}"\`)`});this.$module.addEventListener("click",(()=>o(l,{onBeforeFocus(){l.classList.add("govuk-skip-link-focused-element")},onBlur(){l.classList.remove("govuk-skip-link-focused-element")}})))}}).moduleName="govuk-skip-link";function S(e){let t;if(e=void 0!==e?e:{},!a())return void console.log(new h);const s=[[b,e.button],[w,e.characterCount],[$],[y,e.errorSummary],[x],[A,e.passwordInput]],i=null!=(t=e.scope)?t:document;s.forEach((([e,t])=>{i.querySelectorAll(`[data-module="${e.moduleName}"]`).forEach((s=>{try{"defaults"in e?new e(s,t):new e(s)}catch(e){console.log(e)}}))}))}(
|
80
86
|
/**
|
81
87
|
* Tabs component
|
82
88
|
*
|
83
89
|
* @preserve
|
84
90
|
*/
|
85
|
-
class extends
|
91
|
+
class extends m{constructor(e){if(super(),this.$module=void 0,this.$tabs=void 0,this.$tabList=void 0,this.$tabListItems=void 0,this.jsHiddenClass="govuk-tabs__panel--hidden",this.changingHash=!1,this.boundTabClick=void 0,this.boundTabKeydown=void 0,this.boundOnHashChange=void 0,this.mql=null,!e)throw new d({componentName:"Tabs",element:e,identifier:"Root element (`$module`)"});const t=e.querySelectorAll("a.govuk-tabs__tab");if(!t.length)throw new d({componentName:"Tabs",identifier:'Links (`<a class="govuk-tabs__tab">`)'});this.$module=e,this.$tabs=t,this.boundTabClick=this.onTabClick.bind(this),this.boundTabKeydown=this.onTabKeydown.bind(this),this.boundOnHashChange=this.onHashChange.bind(this);const s=this.$module.querySelector(".govuk-tabs__list"),i=this.$module.querySelectorAll("li.govuk-tabs__list-item");if(!s)throw new d({componentName:"Tabs",identifier:'List (`<ul class="govuk-tabs__list">`)'});if(!i.length)throw new d({componentName:"Tabs",identifier:'List items (`<li class="govuk-tabs__list-item">`)'});this.$tabList=s,this.$tabListItems=i,this.setupResponsiveChecks()}setupResponsiveChecks(){const e=n("tablet");if(!e.value)throw new d({componentName:"Tabs",identifier:`CSS custom property (\`${e.property}\`) on pseudo-class \`:root\``});this.mql=window.matchMedia(`(min-width: ${e.value})`),"addEventListener"in this.mql?this.mql.addEventListener("change",(()=>this.checkMode())):this.mql.addListener((()=>this.checkMode())),this.checkMode()}checkMode(){var e;null!=(e=this.mql)&&e.matches?this.setup():this.teardown()}setup(){var e;this.$tabList.setAttribute("role","tablist"),this.$tabListItems.forEach((e=>{e.setAttribute("role","presentation")})),this.$tabs.forEach((e=>{this.setAttributes(e),e.addEventListener("click",this.boundTabClick,!0),e.addEventListener("keydown",this.boundTabKeydown,!0),this.hideTab(e)}));const t=null!=(e=this.getTab(window.location.hash))?e:this.$tabs[0];this.showTab(t),window.addEventListener("hashchange",this.boundOnHashChange,!0)}teardown(){this.$tabList.removeAttribute("role"),this.$tabListItems.forEach((e=>{e.removeAttribute("role")})),this.$tabs.forEach((e=>{e.removeEventListener("click",this.boundTabClick,!0),e.removeEventListener("keydown",this.boundTabKeydown,!0),this.unsetAttributes(e)})),window.removeEventListener("hashchange",this.boundOnHashChange,!0)}onHashChange(){const e=window.location.hash,t=this.getTab(e);if(!t)return;if(this.changingHash)return void(this.changingHash=!1);const s=this.getCurrentTab();s&&(this.hideTab(s),this.showTab(t),t.focus())}hideTab(e){this.unhighlightTab(e),this.hidePanel(e)}showTab(e){this.highlightTab(e),this.showPanel(e)}getTab(e){return this.$module.querySelector(`a.govuk-tabs__tab[href="${e}"]`)}setAttributes(e){const t=i(e.href);if(!t)return;e.setAttribute("id",`tab_${t}`),e.setAttribute("role","tab"),e.setAttribute("aria-controls",t),e.setAttribute("aria-selected","false"),e.setAttribute("tabindex","-1");const s=this.getPanel(e);s&&(s.setAttribute("role","tabpanel"),s.setAttribute("aria-labelledby",e.id),s.classList.add(this.jsHiddenClass))}unsetAttributes(e){e.removeAttribute("id"),e.removeAttribute("role"),e.removeAttribute("aria-controls"),e.removeAttribute("aria-selected"),e.removeAttribute("tabindex");const t=this.getPanel(e);t&&(t.removeAttribute("role"),t.removeAttribute("aria-labelledby"),t.classList.remove(this.jsHiddenClass))}onTabClick(e){const t=this.getCurrentTab(),s=e.currentTarget;t&&s instanceof HTMLAnchorElement&&(e.preventDefault(),this.hideTab(t),this.showTab(s),this.createHistoryEntry(s))}createHistoryEntry(e){const t=this.getPanel(e);if(!t)return;const s=t.id;t.id="",this.changingHash=!0,window.location.hash=s,t.id=s}onTabKeydown(e){switch(e.key){case"ArrowLeft":case"ArrowUp":case"Left":case"Up":this.activatePreviousTab(),e.preventDefault();break;case"ArrowRight":case"ArrowDown":case"Right":case"Down":this.activateNextTab(),e.preventDefault()}}activateNextTab(){const e=this.getCurrentTab();if(null==e||!e.parentElement)return;const t=e.parentElement.nextElementSibling;if(!t)return;const s=t.querySelector("a.govuk-tabs__tab");s&&(this.hideTab(e),this.showTab(s),s.focus(),this.createHistoryEntry(s))}activatePreviousTab(){const e=this.getCurrentTab();if(null==e||!e.parentElement)return;const t=e.parentElement.previousElementSibling;if(!t)return;const s=t.querySelector("a.govuk-tabs__tab");s&&(this.hideTab(e),this.showTab(s),s.focus(),this.createHistoryEntry(s))}getPanel(e){const t=i(e.href);return t?this.$module.querySelector(`#${t}`):null}showPanel(e){const t=this.getPanel(e);t&&t.classList.remove(this.jsHiddenClass)}hidePanel(e){const t=this.getPanel(e);t&&t.classList.add(this.jsHiddenClass)}unhighlightTab(e){e.parentElement&&(e.setAttribute("aria-selected","false"),e.parentElement.classList.remove("govuk-tabs__list-item--selected"),e.setAttribute("tabindex","-1"))}highlightTab(e){e.parentElement&&(e.setAttribute("aria-selected","true"),e.parentElement.classList.add("govuk-tabs__list-item--selected"),e.setAttribute("tabindex","0"))}getCurrentTab(){return this.$module.querySelector(".govuk-tabs__list-item--selected a.govuk-tabs__tab")}}).moduleName="govuk-tabs";export{b as Button,w as CharacterCount,$ as Checkboxes,y as ErrorSummary,A as PasswordInput,x as Radios,S as initAll};
|
data/vendor/assets/stylesheets/govuk-frontend/dist/govuk/components/password-input/_index.scss
ADDED
@@ -0,0 +1,55 @@
|
|
1
|
+
@import "../button/index";
|
2
|
+
@import "../input/index";
|
3
|
+
|
4
|
+
@include govuk-exports("govuk/component/password-input") {
|
5
|
+
.govuk-password-input__wrapper {
|
6
|
+
// This element inherits styles from .govuk-input__wrapper, including:
|
7
|
+
// - being display: block with contents in a stacked column below the mobile breakpoint
|
8
|
+
// - being display: flex above the mobile breakpoint
|
9
|
+
|
10
|
+
@include govuk-media-query($from: mobile) {
|
11
|
+
flex-direction: row;
|
12
|
+
|
13
|
+
// The default of `stretch` makes the toggle button appear taller than the input, due to using
|
14
|
+
// box-shadow, which we don't particularly want in this situation
|
15
|
+
align-items: flex-start;
|
16
|
+
}
|
17
|
+
}
|
18
|
+
|
19
|
+
.govuk-password-input__input {
|
20
|
+
// IE 11 and Microsoft Edge comes with its own password reveal function. We want to hide it,
|
21
|
+
// so that there aren't two controls presented to the user that do the same thing but aren't in
|
22
|
+
// sync with one another. This doesn't affect the function that allows Edge users to toggle
|
23
|
+
// password visibility by pressing Alt+F8, which cannot be programatically disabled.
|
24
|
+
&::-ms-reveal {
|
25
|
+
display: none;
|
26
|
+
}
|
27
|
+
}
|
28
|
+
|
29
|
+
.govuk-password-input__toggle {
|
30
|
+
// Add margin to the top so that the button doesn't obscure the input's focus style
|
31
|
+
margin-top: govuk-spacing(1);
|
32
|
+
|
33
|
+
// Remove default margin-bottom from button
|
34
|
+
margin-bottom: 0;
|
35
|
+
|
36
|
+
// Hide the button by default, JS removes this attribute
|
37
|
+
&[hidden] {
|
38
|
+
display: none;
|
39
|
+
}
|
40
|
+
|
41
|
+
@include govuk-media-query($from: mobile) {
|
42
|
+
// Buttons are normally 100% width on this breakpoint, but we don't want that in this case
|
43
|
+
width: auto;
|
44
|
+
flex-grow: 1;
|
45
|
+
flex-shrink: 0;
|
46
|
+
flex-basis: 5em;
|
47
|
+
|
48
|
+
// Move the spacing from top to the left
|
49
|
+
margin-top: 0;
|
50
|
+
margin-left: govuk-spacing(1);
|
51
|
+
}
|
52
|
+
}
|
53
|
+
}
|
54
|
+
|
55
|
+
/*# sourceMappingURL=_index.scss.map */
|
data/vendor/assets/stylesheets/govuk-frontend/dist/govuk/core/_govuk-frontend-properties.scss
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
:root {
|
2
2
|
// This variable is automatically overwritten during builds and releases.
|
3
3
|
// It doesn't need to be updated manually.
|
4
|
-
--govuk-frontend-version: "5.
|
4
|
+
--govuk-frontend-version: "5.3.0";
|
5
5
|
|
6
6
|
// CSS custom property for each breakpoint
|
7
7
|
@each $name, $value in $govuk-breakpoints {
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: katalyst-govuk-formbuilder
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.9.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Katalyst Interactive
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-
|
11
|
+
date: 2024-04-04 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: govuk_design_system_formbuilder
|
@@ -96,6 +96,8 @@ files:
|
|
96
96
|
- vendor/assets/stylesheets/govuk-frontend/dist/govuk/components/pagination/_pagination.scss
|
97
97
|
- vendor/assets/stylesheets/govuk-frontend/dist/govuk/components/panel/_index.scss
|
98
98
|
- vendor/assets/stylesheets/govuk-frontend/dist/govuk/components/panel/_panel.scss
|
99
|
+
- vendor/assets/stylesheets/govuk-frontend/dist/govuk/components/password-input/_index.scss
|
100
|
+
- vendor/assets/stylesheets/govuk-frontend/dist/govuk/components/password-input/_password-input.scss
|
99
101
|
- vendor/assets/stylesheets/govuk-frontend/dist/govuk/components/phase-banner/_index.scss
|
100
102
|
- vendor/assets/stylesheets/govuk-frontend/dist/govuk/components/phase-banner/_phase-banner.scss
|
101
103
|
- vendor/assets/stylesheets/govuk-frontend/dist/govuk/components/radios/_index.scss
|