Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Release v5.3.0 #4896

Merged
merged 1 commit into from
Mar 26, 2024
Merged

Release v5.3.0 #4896

merged 1 commit into from
Mar 26, 2024

Conversation

36degrees
Copy link
Contributor

@36degrees 36degrees commented Mar 26, 2024

GOV.UK Frontend v5.3.0 (Feature release)

To install this version with npm, run npm install govuk-frontend@5.3.0. You can also find more information about how to stay up to date in our documentation.

New features

Use the Password input component to help users accessibly enter passwords

The Password input component allows users to choose:

  • whether their passwords are visible or not
  • to enter their passwords in plain text

This helps users use longer and more complex passwords without needing to remember what they've already typed.

This change was introduced in pull request #4442: Create password input component. Thanks to @andysellick for the original contribution.

Recommended changes

Update the HTML for the Character count component

We've updated the HTML for the Character count component. The component wrapper data-module="govuk-character-count" and its form group class="govuk-form-group" are now combined as the same <div>. The hint text used as the count message now appears directly after the <textarea>.

If you're not using Nunjucks macros, then you should:

  • move all classes and attributes from the form group <div> to the component wrapper <div>
  • remove the opening <div> and closing </div> tags used by the form group
  • check the count message is now directly after the <textarea>

The following example shows some HTML and the difference once it’s updated.

HTML before:

<div class="govuk-character-count" data-module="govuk-character-count" data-maxlength="100">
  <div class="govuk-form-group">
    <!-- // Label, hint, error and textarea -->
  </div>
  <!-- // Count message -->
</div>

HTML after:

<div class="govuk-form-group govuk-character-count" data-module="govuk-character-count" data-maxlength="100">
  <!-- // Label, hint, error, textarea and count message -->
</div>

Check your changes against the Character count example in the Design System to make sure you’ve correctly implemented them.

This change was introduced in pull request #4566: Use Character count formGroup as module wrapper.

Remove redundant role attributes from elements

We've made minor changes to the HTML of the page template, as well as the header, footer and pagination components.

You can update your HTML to remove the role attribute from some elements. These include the:

  • main role on the main element in the template
  • banner role on the header element in the Header component
  • contentinfo role on the footer element in the Footer component
  • navigation role on the nav element in the Pagination component

These roles were present to support legacy browsers, such as older versions of Internet Explorer. GOV.UK Frontend no longer supports these browsers, so you can now remove these roles.

You do not need to change anything if you're using the Nunjucks versions of the page template or these components,

This change was introduced in pull request #4854: Remove redundant role attributes.

Fixes

We've fixed an upstream issue in the cssnano npm package that caused elements with transparency to render incorrectly in Internet Explorer 11. This affected the pre-compiled CSS files in the GOV.UK Frontend npm package and GitHub releases for versions 5.0, 5.1 and 5.2. This was fixed in:

We've made fixes to GOV.UK Frontend in the following pull requests:

@govuk-design-system-ci govuk-design-system-ci temporarily deployed to govuk-frontend-pr-4896 March 26, 2024 10:30 Inactive
Copy link

JavaScript changes to GitHub release

diff --git a/dist/govuk-frontend-5.2.0.min.js b/dist/govuk-frontend-5.3.0.min.js
index a6cf3ebc2..9d0e3f01b 100644
--- a/dist/govuk-frontend-5.2.0.min.js
+++ b/dist/govuk-frontend-5.3.0.min.js
@@ -1,108 +1,119 @@
-const version = "5.2.0";
+const version = "5.3.0";
 
-function mergeConfigs(...t) {
-    function flattenObject(t) {
-        const e = {};
-        return function flattenLoop(t, n) {
-            for (const [i, s] of Object.entries(t)) {
-                const t = n ? `${n}.${i}` : i;
-                s && "object" == typeof s ? flattenLoop(s, t) : e[t] = s
-            }
-        }(t), e
-    }
-    const e = {};
-    for (const n of t) {
-        const t = flattenObject(n);
-        for (const [n, i] of Object.entries(t)) e[n] = i
+function normaliseString(e, t) {
+    const s = e ? e.trim() : "";
+    let n, i = null == t ? void 0 : t.type;
+    switch (i || (["true", "false"].includes(s) && (i = "boolean"), s.length > 0 && isFinite(Number(s)) && (i = "number")), i) {
+        case "boolean":
+            n = "true" === s;
+            break;
+        case "number":
+            n = Number(s);
+            break;
+        default:
+            n = e
     }
-    return e
+    return n
 }
 
-function extractConfigByNamespace(t, e) {
-    const n = {};
-    for (const [i, s] of Object.entries(t)) {
-        const t = i.split(".");
-        if (t[0] === e) {
-            t.length > 1 && t.shift();
-            n[t.join(".")] = s
+function mergeConfigs(...e) {
+    const t = {};
+    for (const s of e)
+        for (const e of Object.keys(s)) {
+            const n = t[e],
+                i = s[e];
+            isObject(n) && isObject(i) ? t[e] = mergeConfigs(n, i) : t[e] = i
         }
-    }
-    return n
+    return t
 }
 
-function getFragmentFromUrl(t) {
-    if (t.includes("#")) return t.split("#").pop()
+function extractConfigByNamespace(e, t, s) {
+    const n = e.schema.properties[s];
+    if ("object" !== (null == n ? void 0 : n.type)) return;
+    const i = {
+        [s]: {}
+    };
+    for (const [o, r] of Object.entries(t)) {
+        let e = i;
+        const t = o.split(".");
+        for (const [n, i] of t.entries()) "object" == typeof e && (n < t.length - 1 ? (isObject(e[i]) || (e[i] = {}), e = e[i]) : o !== s && (e[i] = normaliseString(r)))
+    }
+    return i[s]
 }
 
-function getBreakpoint(t) {
-    const e = `--govuk-frontend-breakpoint-${t}`;
+function getFragmentFromUrl(e) {
+    if (e.includes("#")) return e.split("#").pop()
+}
+
+function getBreakpoint(e) {
+    const t = `--govuk-frontend-breakpoint-${e}`;
     return {
-        property: e,
-        value: window.getComputedStyle(document.documentElement).getPropertyValue(e) || void 0
+        property: t,
+        value: window.getComputedStyle(document.documentElement).getPropertyValue(t) || void 0
     }
 }
 
-function setFocus(t, e = {}) {
-    var n;
-    const i = t.getAttribute("tabindex");
+function setFocus(e, t = {}) {
+    var s;
+    const n = e.getAttribute("tabindex");
 
     function onBlur() {
-        var n;
-        null == (n = e.onBlur) || n.call(t), i || t.removeAttribute("tabindex")
+        var s;
+        null == (s = t.onBlur) || s.call(e), n || e.removeAttribute("tabindex")
     }
-    i || t.setAttribute("tabindex", "-1"), t.addEventListener("focus", (function() {
-        t.addEventListener("blur", onBlur, {
+    n || e.setAttribute("tabindex", "-1"), e.addEventListener("focus", (function() {
+        e.addEventListener("blur", onBlur, {
             once: !0
         })
     }), {
         once: !0
-    }), null == (n = e.onBeforeFocus) || n.call(t), t.focus()
+    }), null == (s = t.onBeforeFocus) || s.call(e), e.focus()
 }
 
-function isSupported(t = document.body) {
-    return !!t && t.classList.contains("govuk-frontend-supported")
+function isSupported(e = document.body) {
+    return !!e && e.classList.contains("govuk-frontend-supported")
 }
 
-function normaliseString(t) {
-    if ("string" != typeof t) return t;
-    const e = t.trim();
-    return "true" === e || "false" !== e && (e.length > 0 && isFinite(Number(e)) ? Number(e) : t)
+function isObject(e) {
+    return !!e && "object" == typeof e && ! function(e) {
+        return Array.isArray(e)
+    }(e)
 }
 
-function normaliseDataset(t) {
-    const e = {};
-    for (const [n, i] of Object.entries(t)) e[n] = normaliseString(i);
-    return e
+function normaliseDataset(e, t) {
+    const s = {};
+    for (const [n, i] of Object.entries(e.schema.properties)) n in t && (s[n] = normaliseString(t[n], i)), "object" === (null == i ? void 0 : i.type) && (s[n] = extractConfigByNamespace(e, t, n));
+    return s
 }
 class GOVUKFrontendError extends Error {
-    constructor(...t) {
-        super(...t), this.name = "GOVUKFrontendError"
+    constructor(...e) {
+        super(...e), this.name = "GOVUKFrontendError"
     }
 }
 class SupportError extends GOVUKFrontendError {
-    constructor(t = document.body) {
-        const e = "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(t ? e : 'GOV.UK Frontend initialised without `<script type="module">`'), this.name = "SupportError"
+    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 ConfigError extends GOVUKFrontendError {
-    constructor(...t) {
-        super(...t), this.name = "ConfigError"
+    constructor(...e) {
+        super(...e), this.name = "ConfigError"
     }
 }
 class ElementError extends GOVUKFrontendError {
-    constructor(t) {
-        let e = "string" == typeof t ? t : "";
-        if ("object" == typeof t) {
+    constructor(e) {
+        let t = "string" == typeof e ? e : "";
+        if ("object" == typeof e) {
             const {
-                componentName: n,
-                identifier: i,
-                element: s,
+                componentName: s,
+                identifier: n,
+                element: i,
                 expectedType: o
-            } = t;
-            e = `${n}: ${i}`, e += s ? ` is not of type ${null!=o?o:"HTMLElement"}` : " not found"
+            } = e;
+            t = `${s}: ${n}`, t += i ? ` is not of type ${null!=o?o:"HTMLElement"}` : " not found"
         }
-        super(e), this.name = "ElementError"
+        super(t), this.name = "ElementError"
     }
 }
 class GOVUKFrontendComponent {
@@ -114,53 +125,59 @@ class GOVUKFrontendComponent {
     }
 }
 class I18n {
-    constructor(t = {}, e = {}) {
-        var n;
-        this.translations = void 0, this.locale = void 0, this.translations = t, this.locale = null != (n = e.locale) ? n : document.documentElement.lang || "en"
-    }
-    t(t, e) {
-        if (!t) throw new Error("i18n: lookup key missing");
-        "number" == typeof(null == e ? void 0 : e.count) && (t = `${t}.${this.getPluralSuffix(t,e.count)}`);
-        const n = this.translations[t];
-        if ("string" == typeof n) {
-            if (n.match(/%{(.\S+)}/)) {
-                if (!e) throw new Error("i18n: cannot replace placeholders in string if no option data provided");
-                return this.replacePlaceholders(n, e)
+    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 n = s[this.getPluralSuffix(e, t.count)];
+            n && (s = n)
+        }
+        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 n
+            return s
         }
-        return t
-    }
-    replacePlaceholders(t, e) {
-        const n = Intl.NumberFormat.supportedLocalesOf(this.locale).length ? new Intl.NumberFormat(this.locale) : void 0;
-        return t.replace(/%{(.\S+)}/g, (function(t, i) {
-            if (Object.prototype.hasOwnProperty.call(e, i)) {
-                const t = e[i];
-                return !1 === t || "number" != typeof t && "string" != typeof t ? "" : "number" == typeof t ? n ? n.format(t) : `${t}` : t
+        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, n) {
+            if (Object.prototype.hasOwnProperty.call(t, n)) {
+                const e = t[n];
+                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 ${t} placeholder in string`)
+            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(t, e) {
-        if (e = Number(e), !isFinite(e)) return "other";
-        const n = this.hasIntlPluralRulesSupport() ? new Intl.PluralRules(this.locale).select(e) : this.selectPluralFormUsingFallbackRules(e);
-        if (`${t}.${n}` in this.translations) return n;
-        if (`${t}.other` in this.translations) return console.warn(`i18n: Missing plural form ".${n}" for "${this.locale}" locale. Falling back to ".other".`), "other";
+    getPluralSuffix(e, t) {
+        if (t = Number(t), !isFinite(t)) return "other";
+        const s = this.translations[e],
+            n = this.hasIntlPluralRulesSupport() ? new Intl.PluralRules(this.locale).select(t) : this.selectPluralFormUsingFallbackRules(t);
+        if ("object" == typeof s) {
+            if (n in s) return n;
+            if ("other" in s) return console.warn(`i18n: Missing plural form ".${n}" for "${this.locale}" locale. Falling back to ".other".`), "other"
+        }
         throw new Error(`i18n: Plural form ".other" is required for "${this.locale}" locale`)
     }
-    selectPluralFormUsingFallbackRules(t) {
-        t = Math.abs(Math.floor(t));
-        const e = this.getPluralRulesForLocale();
-        return e ? I18n.pluralRules[e](t) : "other"
+    selectPluralFormUsingFallbackRules(e) {
+        e = Math.abs(Math.floor(e));
+        const t = this.getPluralRulesForLocale();
+        return t ? I18n.pluralRules[t](e) : "other"
     }
     getPluralRulesForLocale() {
-        const t = this.locale.split("-")[0];
-        for (const e in I18n.pluralRulesMap) {
-            const n = I18n.pluralRulesMap[e];
-            if (n.includes(this.locale) || n.includes(t)) return e
+        const e = this.locale.split("-")[0];
+        for (const t in I18n.pluralRulesMap) {
+            const s = I18n.pluralRulesMap[t];
+            if (s.includes(this.locale) || s.includes(e)) return t
         }
     }
 }
@@ -175,156 +192,156 @@ I18n.pluralRulesMap = {
     spanish: ["pt-PT", "it", "es"],
     welsh: ["cy"]
 }, I18n.pluralRules = {
-    arabic: t => 0 === t ? "zero" : 1 === t ? "one" : 2 === t ? "two" : t % 100 >= 3 && t % 100 <= 10 ? "few" : t % 100 >= 11 && t % 100 <= 99 ? "many" : "other",
+    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: t => 0 === t || 1 === t ? "one" : "other",
-    german: t => 1 === t ? "one" : "other",
-    irish: t => 1 === t ? "one" : 2 === t ? "two" : t >= 3 && t <= 6 ? "few" : t >= 7 && t <= 10 ? "many" : "other",
-    russian(t) {
-        const e = t % 100,
-            n = e % 10;
-        return 1 === n && 11 !== e ? "one" : n >= 2 && n <= 4 && !(e >= 12 && e <= 14) ? "few" : 0 === n || n >= 5 && n <= 9 || e >= 11 && e <= 14 ? "many" : "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: t => 1 === t || 11 === t ? "one" : 2 === t || 12 === t ? "two" : t >= 3 && t <= 10 || t >= 13 && t <= 19 ? "few" : "other",
-    spanish: t => 1 === t ? "one" : t % 1e6 == 0 && 0 !== t ? "many" : "other",
-    welsh: t => 0 === t ? "zero" : 1 === t ? "one" : 2 === t ? "two" : 3 === t ? "few" : 6 === t ? "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"
 };
 class Accordion extends GOVUKFrontendComponent {
-    constructor(e, n = {}) {
-        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 ElementError({
+    constructor(t, 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, !(t instanceof HTMLElement)) throw new ElementError({
             componentName: "Accordion",
-            element: e,
+            element: t,
             identifier: "Root element (`$module`)"
         });
-        this.$module = e, this.config = mergeConfigs(Accordion.defaults, n, normaliseDataset(e.dataset)), this.i18n = new I18n(extractConfigByNamespace(this.config, "i18n"));
-        const i = this.$module.querySelectorAll(`.${this.sectionClass}`);
-        if (!i.length) throw new ElementError({
+        this.$module = t, this.config = mergeConfigs(Accordion.defaults, s, normaliseDataset(Accordion, t.dataset)), this.i18n = new I18n(this.config.i18n);
+        const n = this.$module.querySelectorAll(`.${this.sectionClass}`);
+        if (!n.length) throw new ElementError({
             componentName: "Accordion",
             identifier: `Sections (\`<div class="${this.sectionClass}">\`)`
         });
-        this.$sections = i, this.browserSupportsSessionStorage = t.checkForSessionStorage(), this.initControls(), this.initSectionHeaders();
-        const s = this.checkIfAllSectionsOpen();
-        this.updateShowAllButton(s)
+        this.$sections = n, this.browserSupportsSessionStorage = e.checkForSessionStorage(), this.initControls(), this.initSectionHeaders();
+        const i = this.checkIfAllSectionsOpen();
+        this.updateShowAllButton(i)
     }
     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 t = document.createElement("div");
-        t.setAttribute("class", this.controlsClass), t.appendChild(this.$showAllButton), this.$module.insertBefore(t, 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", (t => this.onBeforeMatch(t)))
+        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(((t, e) => {
-            const n = t.querySelector(`.${this.sectionHeaderClass}`);
-            if (!n) throw new ElementError({
+        this.$sections.forEach(((e, t) => {
+            const s = e.querySelector(`.${this.sectionHeaderClass}`);
+            if (!s) throw new ElementError({
                 componentName: "Accordion",
                 identifier: `Section headers (\`<div class="${this.sectionHeaderClass}">\`)`
             });
-            this.constructHeaderMarkup(n, e), this.setExpanded(this.isExpanded(t), t), n.addEventListener("click", (() => this.onSectionToggle(t))), this.setInitialState(t)
+            this.constructHeaderMarkup(s, t), this.setExpanded(this.isExpanded(e), e), s.addEventListener("click", (() => this.onSectionToggle(e))), this.setInitialState(e)
         }))
     }
-    constructHeaderMarkup(t, e) {
-        const n = t.querySelector(`.${this.sectionButtonClass}`),
-            i = t.querySelector(`.${this.sectionHeadingClass}`),
-            s = t.querySelector(`.${this.sectionSummaryClass}`);
-        if (!i) throw new ElementError({
+    constructHeaderMarkup(e, t) {
+        const s = e.querySelector(`.${this.sectionButtonClass}`),
+            n = e.querySelector(`.${this.sectionHeadingClass}`),
+            i = e.querySelector(`.${this.sectionSummaryClass}`);
+        if (!n) throw new ElementError({
             componentName: "Accordion",
             identifier: `Section heading (\`.${this.sectionHeadingClass}\`)`
         });
-        if (!n) throw new ElementError({
+        if (!s) throw new ElementError({
             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-${e+1}`);
-        for (const d of Array.from(n.attributes)) "id" !== d.nodeName && o.setAttribute(d.nodeName, `${d.nodeValue}`);
+        o.setAttribute("type", "button"), o.setAttribute("aria-controls", `${this.$module.id}-content-${t+1}`);
+        for (const d of Array.from(s.attributes)) "id" !== d.nodeName && o.setAttribute(d.nodeName, `${d.nodeValue}`);
         const r = document.createElement("span");
-        r.classList.add(this.sectionHeadingTextClass), r.id = n.id;
+        r.classList.add(this.sectionHeadingTextClass), r.id = s.id;
         const a = document.createElement("span");
-        a.classList.add(this.sectionHeadingTextFocusClass), r.appendChild(a), a.innerHTML = n.innerHTML;
+        a.classList.add(this.sectionHeadingTextFocusClass), r.appendChild(a), a.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(r), o.appendChild(this.getButtonPunctuationEl()), null != s && s.parentNode) {
-            const t = document.createElement("span"),
-                e = document.createElement("span");
-            e.classList.add(this.sectionSummaryFocusClass), t.appendChild(e);
-            for (const n of Array.from(s.attributes)) t.setAttribute(n.nodeName, `${n.nodeValue}`);
-            e.innerHTML = s.innerHTML, s.parentNode.replaceChild(t, s), o.appendChild(t), o.appendChild(this.getButtonPunctuationEl())
+        if (u.classList.add(this.upChevronIconClass), c.appendChild(u), h.classList.add(this.sectionShowHideTextClass), c.appendChild(h), o.appendChild(r), o.appendChild(this.getButtonPunctuationEl()), null != i && i.parentNode) {
+            const e = document.createElement("span"),
+                t = document.createElement("span");
+            t.classList.add(this.sectionSummaryFocusClass), e.appendChild(t);
+            for (const s of Array.from(i.attributes)) e.setAttribute(s.nodeName, `${s.nodeValue}`);
+            t.innerHTML = i.innerHTML, i.parentNode.replaceChild(e, i), o.appendChild(e), o.appendChild(this.getButtonPunctuationEl())
         }
-        o.appendChild(l), i.removeChild(n), i.appendChild(o)
+        o.appendChild(l), n.removeChild(s), n.appendChild(o)
     }
-    onBeforeMatch(t) {
-        const e = t.target;
-        if (!(e instanceof Element)) return;
-        const n = e.closest(`.${this.sectionClass}`);
-        n && this.setExpanded(!0, n)
+    onBeforeMatch(e) {
+        const t = e.target;
+        if (!(t instanceof Element)) return;
+        const s = t.closest(`.${this.sectionClass}`);
+        s && this.setExpanded(!0, s)
     }
-    onSectionToggle(t) {
-        const e = this.isExpanded(t);
-        this.setExpanded(!e, t), this.storeState(t)
+    onSectionToggle(e) {
+        const t = this.isExpanded(e);
+        this.setExpanded(!t, e), this.storeState(e)
     }
     onShowOrHideAllToggle() {
-        const t = !this.checkIfAllSectionsOpen();
-        this.$sections.forEach((e => {
-            this.setExpanded(t, e), this.storeState(e)
-        })), this.updateShowAllButton(t)
-    }
-    setExpanded(t, e) {
-        const n = e.querySelector(`.${this.upChevronIconClass}`),
-            i = e.querySelector(`.${this.sectionShowHideTextClass}`),
-            s = e.querySelector(`.${this.sectionButtonClass}`),
-            o = e.querySelector(`.${this.sectionContentClass}`);
+        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}`),
+            n = t.querySelector(`.${this.sectionShowHideTextClass}`),
+            i = t.querySelector(`.${this.sectionButtonClass}`),
+            o = t.querySelector(`.${this.sectionContentClass}`);
         if (!o) throw new ElementError({
             componentName: "Accordion",
             identifier: `Section content (\`<div class="${this.sectionContentClass}">\`)`
         });
-        if (!n || !i || !s) return;
-        const r = t ? this.i18n.t("hideSection") : this.i18n.t("showSection");
-        i.textContent = r, s.setAttribute("aria-expanded", `${t}`);
+        if (!s || !n || !i) return;
+        const r = e ? this.i18n.t("hideSection") : this.i18n.t("showSection");
+        n.textContent = r, i.setAttribute("aria-expanded", `${e}`);
         const a = [],
-            l = e.querySelector(`.${this.sectionHeadingTextClass}`);
+            l = t.querySelector(`.${this.sectionHeadingTextClass}`);
         l && a.push(`${l.textContent}`.trim());
-        const c = e.querySelector(`.${this.sectionSummaryClass}`);
+        const c = t.querySelector(`.${this.sectionSummaryClass}`);
         c && a.push(`${c.textContent}`.trim());
-        const h = t ? this.i18n.t("hideSectionAriaLabel") : this.i18n.t("showSectionAriaLabel");
-        a.push(h), s.setAttribute("aria-label", a.join(" , ")), t ? (o.removeAttribute("hidden"), e.classList.add(this.sectionExpandedClass), n.classList.remove(this.downChevronIconClass)) : (o.setAttribute("hidden", "until-found"), e.classList.remove(this.sectionExpandedClass), n.classList.add(this.downChevronIconClass));
+        const h = e ? this.i18n.t("hideSectionAriaLabel") : this.i18n.t("showSectionAriaLabel");
+        a.push(h), i.setAttribute("aria-label", a.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(t) {
-        return t.classList.contains(this.sectionExpandedClass)
+    isExpanded(e) {
+        return e.classList.contains(this.sectionExpandedClass)
     }
     checkIfAllSectionsOpen() {
         return this.$sections.length === this.$module.querySelectorAll(`.${this.sectionExpandedClass}`).length
     }
-    updateShowAllButton(t) {
-        this.$showAllButton && this.$showAllText && this.$showAllIcon && (this.$showAllButton.setAttribute("aria-expanded", t.toString()), this.$showAllText.textContent = t ? this.i18n.t("hideAllSections") : this.i18n.t("showAllSections"), this.$showAllIcon.classList.toggle(this.downChevronIconClass, !t))
+    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(t) {
+    storeState(e) {
         if (this.browserSupportsSessionStorage && this.config.rememberExpanded) {
-            const e = t.querySelector(`.${this.sectionButtonClass}`);
-            if (e) {
-                const t = e.getAttribute("aria-controls"),
-                    n = e.getAttribute("aria-expanded");
-                t && n && window.sessionStorage.setItem(t, n)
+            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(t) {
+    setInitialState(e) {
         if (this.browserSupportsSessionStorage && this.config.rememberExpanded) {
-            const e = t.querySelector(`.${this.sectionButtonClass}`);
-            if (e) {
-                const n = e.getAttribute("aria-controls"),
-                    i = n ? window.sessionStorage.getItem(n) : null;
-                null !== i && this.setExpanded("true" === i, t)
+            const t = e.querySelector(`.${this.sectionButtonClass}`);
+            if (t) {
+                const s = t.getAttribute("aria-controls"),
+                    n = s ? window.sessionStorage.getItem(s) : null;
+                null !== n && this.setExpanded("true" === n, e)
             }
         }
     }
     getButtonPunctuationEl() {
-        const t = document.createElement("span");
-        return t.classList.add("govuk-visually-hidden", this.sectionHeadingDividerClass), t.innerHTML = ", ", t
+        const e = document.createElement("span");
+        return e.classList.add("govuk-visually-hidden", this.sectionHeadingDividerClass), e.innerHTML = ", ", e
     }
 }
 Accordion.moduleName = "govuk-accordion", Accordion.defaults = Object.freeze({
@@ -337,83 +354,100 @@ Accordion.moduleName = "govuk-accordion", Accordion.defaults = Object.freeze({
         showSectionAriaLabel: "Show this section"
     },
     rememberExpanded: !0
+}), Accordion.schema = Object.freeze({
+    properties: {
+        i18n: {
+            type: "object"
+        },
+        rememberExpanded: {
+            type: "boolean"
+        }
+    }
 });
-const t = {
+const e = {
     checkForSessionStorage: function() {
-        const t = "this is the test string";
-        let e;
+        const e = "this is the test string";
+        let t;
         try {
-            return window.sessionStorage.setItem(t, t), e = window.sessionStorage.getItem(t) === t.toString(), window.sessionStorage.removeItem(t), e
-        } catch (n) {
+            return window.sessionStorage.setItem(e, e), t = window.sessionStorage.getItem(e) === e.toString(), window.sessionStorage.removeItem(e), t
+        } catch (s) {
             return !1
         }
     }
 };
 class Button extends GOVUKFrontendComponent {
-    constructor(t, e = {}) {
-        if (super(), this.$module = void 0, this.config = void 0, this.debounceFormSubmitTimer = null, !(t instanceof HTMLElement)) throw new ElementError({
+    constructor(e, t = {}) {
+        if (super(), this.$module = void 0, this.config = void 0, this.debounceFormSubmitTimer = null, !(e instanceof HTMLElement)) throw new ElementError({
             componentName: "Button",
-            element: t,
+            element: e,
             identifier: "Root element (`$module`)"
         });
-        this.$module = t, this.config = mergeConfigs(Button.defaults, e, normaliseDataset(t.dataset)), this.$module.addEventListener("keydown", (t => this.handleKeyDown(t))), this.$module.addEventListener("click", (t => this.debounce(t)))
+        this.$module = e, this.config = mergeConfigs(Button.defaults, t, normaliseDataset(Button, e.dataset)), this.$module.addEventListener("keydown", (e => this.handleKeyDown(e))), this.$module.addEventListener("click", (e => this.debounce(e)))
     }
-    handleKeyDown(t) {
-        const e = t.target;
-        32 === t.keyCode && e instanceof HTMLElement && "button" === e.getAttribute("role") && (t.preventDefault(), e.click())
+    handleKeyDown(e) {
+        const t = e.target;
+        " " === e.key && t instanceof HTMLElement && "button" === t.getAttribute("role") && (e.preventDefault(), t.click())
     }
-    debounce(t) {
-        if (this.config.preventDoubleClick) return this.debounceFormSubmitTimer ? (t.preventDefault(), !1) : void(this.debounceFormSubmitTimer = window.setTimeout((() => {
+    debounce(e) {
+        if (this.config.preventDoubleClick) return this.debounceFormSubmitTimer ? (e.preventDefault(), !1) : void(this.debounceFormSubmitTimer = window.setTimeout((() => {
             this.debounceFormSubmitTimer = null
         }), 1e3))
     }
 }
 
-function closestAttributeValue(t, e) {
-    const n = t.closest(`[${e}]`);
-    return n ? n.getAttribute(e) : null
+function closestAttributeValue(e, t) {
+    const s = e.closest(`[${t}]`);
+    return s ? s.getAttribute(t) : null
 }
 Button.moduleName = "govuk-button", Button.defaults = Object.freeze({
     preventDoubleClick: !1
+}), Button.schema = Object.freeze({
+    properties: {
+        preventDoubleClick: {
+            type: "boolean"
+        }
+    }
 });
 class CharacterCount extends GOVUKFrontendComponent {
-    constructor(t, e = {}) {
-        var n, i;
-        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, !(t instanceof HTMLElement)) throw new ElementError({
+    constructor(e, t = {}) {
+        var s, 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 ElementError({
             componentName: "Character count",
-            element: t,
+            element: e,
             identifier: "Root element (`$module`)"
         });
-        const s = t.querySelector(".govuk-js-character-count");
-        if (!(s instanceof HTMLTextAreaElement || s instanceof HTMLInputElement)) throw new ElementError({
+        const i = e.querySelector(".govuk-js-character-count");
+        if (!(i instanceof HTMLTextAreaElement || i instanceof HTMLInputElement)) throw new ElementError({
             componentName: "Character count",
-            element: s,
+            element: i,
             expectedType: "HTMLTextareaElement or HTMLInputElement",
             identifier: "Form field (`.govuk-js-character-count`)"
         });
-        const o = normaliseDataset(t.dataset);
+        const o = normaliseDataset(CharacterCount, e.dataset);
         let r = {};
         ("maxwords" in o || "maxlength" in o) && (r = {
             maxlength: void 0,
             maxwords: void 0
-        }), this.config = mergeConfigs(CharacterCount.defaults, e, r, o);
-        const a = function(t, e) {
-            const n = [];
-            for (const [i, s] of Object.entries(t)) {
-                const t = [];
-                for (const {
-                        required: n,
-                        errorMessage: i
-                    }
-                    of s) n.every((t => !!e[t])) || t.push(i);
-                "anyOf" !== i || s.length - t.length >= 1 || n.push(...t)
+        }), this.config = mergeConfigs(CharacterCount.defaults, t, r, o);
+        const a = function(e, t) {
+            const s = [];
+            for (const [n, i] of Object.entries(e)) {
+                const e = [];
+                if (Array.isArray(i)) {
+                    for (const {
+                            required: s,
+                            errorMessage: n
+                        }
+                        of i) s.every((e => !!t[e])) || e.push(n);
+                    "anyOf" !== n || i.length - e.length >= 1 || s.push(...e)
+                }
             }
-            return n
+            return s
         }(CharacterCount.schema, this.config);
         if (a[0]) throw new ConfigError(`Character count: ${a[0]}`);
-        this.i18n = new I18n(extractConfigByNamespace(this.config, "i18n"), {
-            locale: closestAttributeValue(t, "lang")
-        }), this.maxLength = null != (n = null != (i = this.config.maxwords) ? i : this.config.maxlength) ? n : 1 / 0, this.$module = t, this.$textarea = s;
+        this.i18n = new I18n(this.config.i18n, {
+            locale: closestAttributeValue(e, "lang")
+        }), this.maxLength = null != (s = null != (n = this.config.maxwords) ? n : this.config.maxlength) ? s : 1 / 0, this.$module = e, this.$textarea = i;
         const l = `${this.$textarea.id}-info`,
             c = document.getElementById(l);
         if (!c) throw new ElementError({
@@ -450,35 +484,35 @@ class CharacterCount extends GOVUKFrontendComponent {
         this.updateVisibleCountMessage(), this.updateScreenReaderCountMessage()
     }
     updateVisibleCountMessage() {
-        const t = 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", t), this.$visibleCountMessage.classList.toggle("govuk-error-message", t), this.$visibleCountMessage.classList.toggle("govuk-hint", !t), this.$visibleCountMessage.textContent = this.getCountMessage()
+        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(t) {
+    count(e) {
         if (this.config.maxwords) {
-            var e;
-            return (null != (e = t.match(/\S+/g)) ? e : []).length
+            var t;
+            return (null != (t = e.match(/\S+/g)) ? t : []).length
         }
-        return t.length
+        return e.length
     }
     getCountMessage() {
-        const t = this.maxLength - this.count(this.$textarea.value),
-            e = this.config.maxwords ? "words" : "characters";
-        return this.formatCountMessage(t, e)
-    }
-    formatCountMessage(t, e) {
-        if (0 === t) return this.i18n.t(`${e}AtLimit`);
-        const n = t < 0 ? "OverLimit" : "UnderLimit";
-        return this.i18n.t(`${e}${n}`, {
-            count: Math.abs(t)
+        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 t = this.count(this.$textarea.value);
-        return this.maxLength * this.config.threshold / 100 <= t
+        const e = this.count(this.$textarea.value);
+        return this.maxLength * this.config.threshold / 100 <= e
     }
 }
 CharacterCount.moduleName = "govuk-character-count", CharacterCount.defaults = Object.freeze({
@@ -507,6 +541,20 @@ CharacterCount.moduleName = "govuk-character-count", CharacterCount.defaults = O
         }
     }
 }), CharacterCount.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'
@@ -516,120 +564,126 @@ CharacterCount.moduleName = "govuk-character-count", CharacterCount.defaults = O
     }]
 });
 class Checkboxes extends GOVUKFrontendComponent {
-    constructor(t) {
-        if (super(), this.$module = void 0, this.$inputs = void 0, !(t instanceof HTMLElement)) throw new ElementError({
+    constructor(e) {
+        if (super(), this.$module = void 0, this.$inputs = void 0, !(e instanceof HTMLElement)) throw new ElementError({
             componentName: "Checkboxes",
-            element: t,
+            element: e,
             identifier: "Root element (`$module`)"
         });
-        const e = t.querySelectorAll('input[type="checkbox"]');
-        if (!e.length) throw new ElementError({
+        const t = e.querySelectorAll('input[type="checkbox"]');
+        if (!t.length) throw new ElementError({
             componentName: "Checkboxes",
             identifier: 'Form inputs (`<input type="checkbox">`)'
         });
-        this.$module = t, this.$inputs = e, this.$inputs.forEach((t => {
-            const e = t.getAttribute("data-aria-controls");
-            if (e) {
-                if (!document.getElementById(e)) throw new ElementError({
+        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 ElementError({
                     componentName: "Checkboxes",
-                    identifier: `Conditional reveal (\`id="${e}"\`)`
+                    identifier: `Conditional reveal (\`id="${t}"\`)`
                 });
-                t.setAttribute("aria-controls", e), t.removeAttribute("data-aria-controls")
+                e.setAttribute("aria-controls", t), e.removeAttribute("data-aria-controls")
             }
-        })), window.addEventListener("pageshow", (() => this.syncAllConditionalReveals())), this.syncAllConditionalReveals(), this.$module.addEventListener("click", (t => this.handleClick(t)))
+        })), window.addEventListener("pageshow", (() => this.syncAllConditionalReveals())), this.syncAllConditionalReveals(), this.$module.addEventListener("click", (e => this.handleClick(e)))
     }
     syncAllConditionalReveals() {
-        this.$inputs.forEach((t => this.syncConditionalRevealWithInputState(t)))
-    }
-    syncConditionalRevealWithInputState(t) {
-        const e = t.getAttribute("aria-controls");
-        if (!e) return;
-        const n = document.getElementById(e);
-        if (n && n.classList.contains("govuk-checkboxes__conditional")) {
-            const e = t.checked;
-            t.setAttribute("aria-expanded", e.toString()), n.classList.toggle("govuk-checkboxes__conditional--hidden", !e)
+        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(t) {
-        document.querySelectorAll(`input[type="checkbox"][name="${t.name}"]`).forEach((e => {
-            t.form === e.form && e !== t && (e.checked = !1, this.syncConditionalRevealWithInputState(e))
+    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(t) {
-        document.querySelectorAll(`input[data-behaviour="exclusive"][type="checkbox"][name="${t.name}"]`).forEach((e => {
-            t.form === e.form && (e.checked = !1, this.syncConditionalRevealWithInputState(e))
+    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(t) {
-        const e = t.target;
-        if (!(e instanceof HTMLInputElement) || "checkbox" !== e.type) return;
-        if (e.getAttribute("aria-controls") && this.syncConditionalRevealWithInputState(e), !e.checked) return;
-        "exclusive" === e.getAttribute("data-behaviour") ? this.unCheckAllInputsExcept(e) : this.unCheckExclusiveInputs(e)
+    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)
     }
 }
 Checkboxes.moduleName = "govuk-checkboxes";
 class ErrorSummary extends GOVUKFrontendComponent {
-    constructor(t, e = {}) {
-        if (super(), this.$module = void 0, this.config = void 0, !(t instanceof HTMLElement)) throw new ElementError({
+    constructor(e, t = {}) {
+        if (super(), this.$module = void 0, this.config = void 0, !(e instanceof HTMLElement)) throw new ElementError({
             componentName: "Error summary",
-            element: t,
+            element: e,
             identifier: "Root element (`$module`)"
         });
-        this.$module = t, this.config = mergeConfigs(ErrorSummary.defaults, e, normaliseDataset(t.dataset)), this.config.disableAutoFocus || setFocus(this.$module), this.$module.addEventListener("click", (t => this.handleClick(t)))
-    }
-    handleClick(t) {
-        const e = t.target;
-        e && this.focusTarget(e) && t.preventDefault()
-    }
-    focusTarget(t) {
-        if (!(t instanceof HTMLAnchorElement)) return !1;
-        const e = getFragmentFromUrl(t.href);
-        if (!e) return !1;
-        const n = document.getElementById(e);
-        if (!n) return !1;
-        const i = this.getAssociatedLegendOrLabel(n);
-        return !!i && (i.scrollIntoView(), n.focus({
+        this.$module = e, this.config = mergeConfigs(ErrorSummary.defaults, t, normaliseDataset(ErrorSummary, e.dataset)), this.config.disableAutoFocus || setFocus(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 = getFragmentFromUrl(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(t) {
-        var e;
-        const n = t.closest("fieldset");
-        if (n) {
-            const e = n.getElementsByTagName("legend");
-            if (e.length) {
-                const n = e[0];
-                if (t instanceof HTMLInputElement && ("checkbox" === t.type || "radio" === t.type)) return n;
-                const i = n.getBoundingClientRect().top,
-                    s = t.getBoundingClientRect();
-                if (s.height && window.innerHeight) {
-                    if (s.top + s.height - i < window.innerHeight / 2) return n
+    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 n = s.getBoundingClientRect().top,
+                    i = e.getBoundingClientRect();
+                if (i.height && window.innerHeight) {
+                    if (i.top + i.height - n < window.innerHeight / 2) return s
                 }
             }
         }
-        return null != (e = document.querySelector(`label[for='${t.getAttribute("id")}']`)) ? e : t.closest("label")
+        return null != (t = document.querySelector(`label[for='${e.getAttribute("id")}']`)) ? t : e.closest("label")
     }
 }
 ErrorSummary.moduleName = "govuk-error-summary", ErrorSummary.defaults = Object.freeze({
     disableAutoFocus: !1
+}), ErrorSummary.schema = Object.freeze({
+    properties: {
+        disableAutoFocus: {
+            type: "boolean"
+        }
+    }
 });
 class ExitThisPage extends GOVUKFrontendComponent {
-    constructor(t, e = {}) {
-        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, !(t instanceof HTMLElement)) throw new ElementError({
+    constructor(e, t = {}) {
+        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 ElementError({
             componentName: "Exit this page",
-            element: t,
+            element: e,
             identifier: "Root element (`$module`)"
         });
-        const n = t.querySelector(".govuk-exit-this-page__button");
-        if (!(n instanceof HTMLAnchorElement)) throw new ElementError({
+        const s = e.querySelector(".govuk-exit-this-page__button");
+        if (!(s instanceof HTMLAnchorElement)) throw new ElementError({
             componentName: "Exit this page",
-            element: n,
+            element: s,
             expectedType: "HTMLAnchorElement",
             identifier: "Button (`.govuk-exit-this-page__button`)"
         });
-        this.config = mergeConfigs(ExitThisPage.defaults, e, normaliseDataset(t.dataset)), this.i18n = new I18n(extractConfigByNamespace(this.config, "i18n")), this.$module = t, this.$button = n;
-        const i = document.querySelector(".govuk-js-exit-this-page-skiplink");
-        i instanceof HTMLAnchorElement && (this.$skiplinkButton = i), 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))
+        this.config = mergeConfigs(ExitThisPage.defaults, t, normaliseDataset(ExitThisPage, e.dataset)), this.i18n = new I18n(this.config.i18n), this.$module = e, this.$button = s;
+        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)
@@ -639,27 +693,27 @@ class ExitThisPage extends GOVUKFrontendComponent {
     }
     buildIndicator() {
         this.$indicatorContainer = document.createElement("div"), this.$indicatorContainer.className = "govuk-exit-this-page__indicator", this.$indicatorContainer.setAttribute("aria-hidden", "true");
-        for (let t = 0; t < 3; t++) {
-            const t = document.createElement("div");
-            t.className = "govuk-exit-this-page__indicator-light", this.$indicatorContainer.appendChild(t)
+        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(((t, e) => {
-            t.classList.toggle("govuk-exit-this-page__indicator-light--on", e < this.keypressCounter)
+        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(t) {
-        t.preventDefault(), this.exitPage()
+    handleClick(e) {
+        e.preventDefault(), this.exitPage()
     }
-    handleKeypress(t) {
-        this.$updateSpan && ("Shift" !== t.key && 16 !== t.keyCode && 16 !== t.which || 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 = t.shiftKey)
+    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)
@@ -667,9 +721,9 @@ class ExitThisPage extends GOVUKFrontendComponent {
     resetKeypressTimer() {
         if (!this.$updateSpan) return;
         this.keypressTimeoutId && (window.clearTimeout(this.keypressTimeoutId), this.keypressTimeoutId = null);
-        const t = this.$updateSpan;
-        this.keypressCounter = 0, t.textContent = this.i18n.t("timedOut"), this.timeoutMessageId = window.setTimeout((() => {
-            t.textContent = ""
+        const e = this.$updateSpan;
+        this.keypressCounter = 0, e.textContent = this.i18n.t("timedOut"), this.timeoutMessageId = window.setTimeout((() => {
+            e.textContent = ""
         }), this.timeoutTime), this.updateIndicator()
     }
     resetPage() {
@@ -683,37 +737,43 @@ ExitThisPage.moduleName = "govuk-exit-this-page", ExitThisPage.defaults = Object
         pressTwoMoreTimes: "Shift, press 2 more times to exit.",
         pressOneMoreTime: "Shift, press 1 more time to exit."
     }
+}), ExitThisPage.schema = Object.freeze({
+    properties: {
+        i18n: {
+            type: "object"
+        }
+    }
 });
 class Header extends GOVUKFrontendComponent {
-    constructor(t) {
-        if (super(), this.$module = void 0, this.$menuButton = void 0, this.$menu = void 0, this.menuIsOpen = !1, this.mql = null, !t) throw new ElementError({
+    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 ElementError({
             componentName: "Header",
-            element: t,
+            element: e,
             identifier: "Root element (`$module`)"
         });
-        this.$module = t;
-        const e = t.querySelector(".govuk-js-header-toggle");
-        if (!e) return this;
-        const n = e.getAttribute("aria-controls");
-        if (!n) throw new ElementError({
+        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 ElementError({
             componentName: "Header",
             identifier: 'Navigation button (`<button class="govuk-js-header-toggle">`) attribute (`aria-controls`)'
         });
-        const i = document.getElementById(n);
-        if (!i) throw new ElementError({
+        const n = document.getElementById(s);
+        if (!n) throw new ElementError({
             componentName: "Header",
-            element: i,
-            identifier: `Navigation (\`<ul id="${n}">\`)`
+            element: n,
+            identifier: `Navigation (\`<ul id="${s}">\`)`
         });
-        this.$menu = i, this.$menuButton = e, this.setupResponsiveChecks(), this.$menuButton.addEventListener("click", (() => this.handleMenuButtonClick()))
+        this.$menu = n, this.$menuButton = t, this.setupResponsiveChecks(), this.$menuButton.addEventListener("click", (() => this.handleMenuButtonClick()))
     }
     setupResponsiveChecks() {
-        const t = getBreakpoint("desktop");
-        if (!t.value) throw new ElementError({
+        const e = getBreakpoint("desktop");
+        if (!e.value) throw new ElementError({
             componentName: "Header",
-            identifier: `CSS custom property (\`${t.property}\`) on pseudo-class \`:root\``
+            identifier: `CSS custom property (\`${e.property}\`) on pseudo-class \`:root\``
         });
-        this.mql = window.matchMedia(`(min-width: ${t.value})`), "addEventListener" in this.mql ? this.mql.addEventListener("change", (() => this.checkMode())) : this.mql.addListener((() => this.checkMode())), this.checkMode()
+        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", "")))
@@ -724,87 +784,158 @@ class Header extends GOVUKFrontendComponent {
 }
 Header.moduleName = "govuk-header";
 class NotificationBanner extends GOVUKFrontendComponent {
-    constructor(t, e = {}) {
-        if (super(), this.$module = void 0, this.config = void 0, !(t instanceof HTMLElement)) throw new ElementError({
+    constructor(e, t = {}) {
+        if (super(), this.$module = void 0, this.config = void 0, !(e instanceof HTMLElement)) throw new ElementError({
             componentName: "Notification banner",
-            element: t,
+            element: e,
             identifier: "Root element (`$module`)"
         });
-        this.$module = t, this.config = mergeConfigs(NotificationBanner.defaults, e, normaliseDataset(t.dataset)), "alert" !== this.$module.getAttribute("role") || this.config.disableAutoFocus || setFocus(this.$module)
+        this.$module = e, this.config = mergeConfigs(NotificationBanner.defaults, t, normaliseDataset(NotificationBanner, e.dataset)), "alert" !== this.$module.getAttribute("role") || this.config.disableAutoFocus || setFocus(this.$module)
     }
 }
 NotificationBanner.moduleName = "govuk-notification-banner", NotificationBanner.defaults = Object.freeze({
     disableAutoFocus: !1
+}), NotificationBanner.schema = Object.freeze({
+    properties: {
+        disableAutoFocus: {
+            type: "boolean"
+        }
+    }
+});
+class PasswordInput extends GOVUKFrontendComponent {
+    constructor(e, t = {}) {
+        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 ElementError({
+            componentName: "Password input",
+            element: e,
+            identifier: "Root element (`$module`)"
+        });
+        const s = e.querySelector(".govuk-js-password-input-input");
+        if (!(s instanceof HTMLInputElement)) throw new ElementError({
+            componentName: "Password input",
+            element: s,
+            expectedType: "HTMLInputElement",
+            identifier: "Form field (`.govuk-js-password-input-input`)"
+        });
+        if ("password" !== s.type) throw new ElementError("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 ElementError({
+            componentName: "Password input",
+            element: n,
+            expectedType: "HTMLButtonElement",
+            identifier: "Button (`.govuk-js-password-input-toggle`)"
+        });
+        if ("button" !== n.type) throw new ElementError("Password input: Button (`.govuk-js-password-input-toggle`) must be of type `button`.");
+        this.$module = e, this.$input = s, this.$showHideButton = n, this.config = mergeConfigs(PasswordInput.defaults, t, normaliseDataset(PasswordInput, e.dataset)), this.i18n = new I18n(this.config.i18n, {
+            locale: closestAttributeValue(e, "lang")
+        }), this.$showHideButton.removeAttribute("hidden");
+        const i = document.createElement("div");
+        i.className = "govuk-password-input__sr-status govuk-visually-hidden", i.setAttribute("aria-live", "polite"), this.$screenReaderStatusMessage = i, this.$input.insertAdjacentElement("afterend", i), 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",
+            n = 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(`${n}Announcement`)
+    }
+}
+PasswordInput.moduleName = "govuk-password-input", PasswordInput.defaults = Object.freeze({
+    i18n: {
+        showPassword: "Show",
+        hidePassword: "Hide",
+        showPasswordAriaLabel: "Show password",
+        hidePasswordAriaLabel: "Hide password",
+        passwordShownAnnouncement: "Your password is visible",
+        passwordHiddenAnnouncement: "Your password is hidden"
+    }
+}), PasswordInput.schema = Object.freeze({
+    properties: {
+        i18n: {
+            type: "object"
+        }
+    }
 });
 class Radios extends GOVUKFrontendComponent {
-    constructor(t) {
-        if (super(), this.$module = void 0, this.$inputs = void 0, !(t instanceof HTMLElement)) throw new ElementError({
+    constructor(e) {
+        if (super(), this.$module = void 0, this.$inputs = void 0, !(e instanceof HTMLElement)) throw new ElementError({
             componentName: "Radios",
-            element: t,
+            element: e,
             identifier: "Root element (`$module`)"
         });
-        const e = t.querySelectorAll('input[type="radio"]');
-        if (!e.length) throw new ElementError({
+        const t = e.querySelectorAll('input[type="radio"]');
+        if (!t.length) throw new ElementError({
             componentName: "Radios",
             identifier: 'Form inputs (`<input type="radio">`)'
         });
-        this.$module = t, this.$inputs = e, this.$inputs.forEach((t => {
-            const e = t.getAttribute("data-aria-controls");
-            if (e) {
-                if (!document.getElementById(e)) throw new ElementError({
+        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 ElementError({
                     componentName: "Radios",
-                    identifier: `Conditional reveal (\`id="${e}"\`)`
+                    identifier: `Conditional reveal (\`id="${t}"\`)`
                 });
-                t.setAttribute("aria-controls", e), t.removeAttribute("data-aria-controls")
+                e.setAttribute("aria-controls", t), e.removeAttribute("data-aria-controls")
             }
-        })), window.addEventListener("pageshow", (() => this.syncAllConditionalReveals())), this.syncAllConditionalReveals(), this.$module.addEventListener("click", (t => this.handleClick(t)))
+        })), window.addEventListener("pageshow", (() => this.syncAllConditionalReveals())), this.syncAllConditionalReveals(), this.$module.addEventListener("click", (e => this.handleClick(e)))
     }
     syncAllConditionalReveals() {
-        this.$inputs.forEach((t => this.syncConditionalRevealWithInputState(t)))
-    }
-    syncConditionalRevealWithInputState(t) {
-        const e = t.getAttribute("aria-controls");
-        if (!e) return;
-        const n = document.getElementById(e);
-        if (null != n && n.classList.contains("govuk-radios__conditional")) {
-            const e = t.checked;
-            t.setAttribute("aria-expanded", e.toString()), n.classList.toggle("govuk-radios__conditional--hidden", !e)
+        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(t) {
-        const e = t.target;
-        if (!(e instanceof HTMLInputElement) || "radio" !== e.type) return;
-        const n = document.querySelectorAll('input[type="radio"][aria-controls]'),
-            i = e.form,
-            s = e.name;
-        n.forEach((t => {
-            const e = t.form === i;
-            t.name === s && e && this.syncConditionalRevealWithInputState(t)
+    handleClick(e) {
+        const t = e.target;
+        if (!(t instanceof HTMLInputElement) || "radio" !== t.type) return;
+        const s = document.querySelectorAll('input[type="radio"][aria-controls]'),
+            n = t.form,
+            i = t.name;
+        s.forEach((e => {
+            const t = e.form === n;
+            e.name === i && t && this.syncConditionalRevealWithInputState(e)
         }))
     }
 }
 Radios.moduleName = "govuk-radios";
 class SkipLink extends GOVUKFrontendComponent {
-    constructor(t) {
-        var e;
-        if (super(), this.$module = void 0, !(t instanceof HTMLAnchorElement)) throw new ElementError({
+    constructor(e) {
+        var t;
+        if (super(), this.$module = void 0, !(e instanceof HTMLAnchorElement)) throw new ElementError({
             componentName: "Skip link",
-            element: t,
+            element: e,
             expectedType: "HTMLAnchorElement",
             identifier: "Root element (`$module`)"
         });
-        this.$module = t;
-        const n = this.$module.hash,
-            i = null != (e = this.$module.getAttribute("href")) ? e : "";
-        let s;
+        this.$module = e;
+        const s = this.$module.hash,
+            n = null != (t = this.$module.getAttribute("href")) ? t : "";
+        let i;
         try {
-            s = new window.URL(this.$module.href)
+            i = new window.URL(this.$module.href)
         } catch (a) {
-            throw new ElementError(`Skip link: Target link (\`href="${i}"\`) is invalid`)
+            throw new ElementError(`Skip link: Target link (\`href="${n}"\`) is invalid`)
         }
-        if (s.origin !== window.location.origin || s.pathname !== window.location.pathname) return;
-        const o = getFragmentFromUrl(n);
-        if (!o) throw new ElementError(`Skip link: Target link (\`href="${i}"\`) has no hash fragment`);
+        if (i.origin !== window.location.origin || i.pathname !== window.location.pathname) return;
+        const o = getFragmentFromUrl(s);
+        if (!o) throw new ElementError(`Skip link: Target link (\`href="${n}"\`) has no hash fragment`);
         const r = document.getElementById(o);
         if (!r) throw new ElementError({
             componentName: "Skip link",
@@ -823,177 +954,177 @@ class SkipLink extends GOVUKFrontendComponent {
 }
 SkipLink.moduleName = "govuk-skip-link";
 class Tabs extends GOVUKFrontendComponent {
-    constructor(t) {
-        if (super(), this.$module = void 0, this.$tabs = void 0, this.$tabList = void 0, this.$tabListItems = void 0, this.keys = {
-                left: 37,
-                right: 39,
-                up: 38,
-                down: 40
-            }, this.jsHiddenClass = "govuk-tabs__panel--hidden", this.changingHash = !1, this.boundTabClick = void 0, this.boundTabKeydown = void 0, this.boundOnHashChange = void 0, this.mql = null, !t) throw new ElementError({
+    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 ElementError({
             componentName: "Tabs",
-            element: t,
+            element: e,
             identifier: "Root element (`$module`)"
         });
-        const e = t.querySelectorAll("a.govuk-tabs__tab");
-        if (!e.length) throw new ElementError({
+        const t = e.querySelectorAll("a.govuk-tabs__tab");
+        if (!t.length) throw new ElementError({
             componentName: "Tabs",
             identifier: 'Links (`<a class="govuk-tabs__tab">`)'
         });
-        this.$module = t, this.$tabs = e, this.boundTabClick = this.onTabClick.bind(this), this.boundTabKeydown = this.onTabKeydown.bind(this), this.boundOnHashChange = this.onHashChange.bind(this);
-        const n = this.$module.querySelector(".govuk-tabs__list"),
-            i = this.$module.querySelectorAll("li.govuk-tabs__list-item");
-        if (!n) throw new ElementError({
+        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"),
+            n = this.$module.querySelectorAll("li.govuk-tabs__list-item");
+        if (!s) throw new ElementError({
             componentName: "Tabs",
             identifier: 'List (`<ul class="govuk-tabs__list">`)'
         });
-        if (!i.length) throw new ElementError({
+        if (!n.length) throw new ElementError({
             componentName: "Tabs",
             identifier: 'List items (`<li class="govuk-tabs__list-item">`)'
         });
-        this.$tabList = n, this.$tabListItems = i, this.setupResponsiveChecks()
+        this.$tabList = s, this.$tabListItems = n, this.setupResponsiveChecks()
     }
     setupResponsiveChecks() {
-        const t = getBreakpoint("tablet");
-        if (!t.value) throw new ElementError({
+        const e = getBreakpoint("tablet");
+        if (!e.value) throw new ElementError({
             componentName: "Tabs",
-            identifier: `CSS custom property (\`${t.property}\`) on pseudo-class \`:root\``
+            identifier: `CSS custom property (\`${e.property}\`) on pseudo-class \`:root\``
         });
-        this.mql = window.matchMedia(`(min-width: ${t.value})`), "addEventListener" in this.mql ? this.mql.addEventListener("change", (() => this.checkMode())) : this.mql.addListener((() => this.checkMode())), this.checkMode()
+        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 t;
-        null != (t = this.mql) && t.matches ? this.setup() : this.teardown()
+        var e;
+        null != (e = this.mql) && e.matches ? this.setup() : this.teardown()
     }
     setup() {
-        var t;
-        this.$tabList.setAttribute("role", "tablist"), this.$tabListItems.forEach((t => {
-            t.setAttribute("role", "presentation")
-        })), this.$tabs.forEach((t => {
-            this.setAttributes(t), t.addEventListener("click", this.boundTabClick, !0), t.addEventListener("keydown", this.boundTabKeydown, !0), this.hideTab(t)
+        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 e = null != (t = this.getTab(window.location.hash)) ? t : this.$tabs[0];
-        this.showTab(e), window.addEventListener("hashchange", this.boundOnHashChange, !0)
+        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((t => {
-            t.removeAttribute("role")
-        })), this.$tabs.forEach((t => {
-            t.removeEventListener("click", this.boundTabClick, !0), t.removeEventListener("keydown", this.boundTabKeydown, !0), this.unsetAttributes(t)
+        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 t = window.location.hash,
-            e = this.getTab(t);
-        if (!e) return;
+        const e = window.location.hash,
+            t = this.getTab(e);
+        if (!t) return;
         if (this.changingHash) return void(this.changingHash = !1);
-        const n = this.getCurrentTab();
-        n && (this.hideTab(n), this.showTab(e), e.focus())
-    }
-    hideTab(t) {
-        this.unhighlightTab(t), this.hidePanel(t)
-    }
-    showTab(t) {
-        this.highlightTab(t), this.showPanel(t)
-    }
-    getTab(t) {
-        return this.$module.querySelector(`a.govuk-tabs__tab[href="${t}"]`)
-    }
-    setAttributes(t) {
-        const e = getFragmentFromUrl(t.href);
-        if (!e) return;
-        t.setAttribute("id", `tab_${e}`), t.setAttribute("role", "tab"), t.setAttribute("aria-controls", e), t.setAttribute("aria-selected", "false"), t.setAttribute("tabindex", "-1");
-        const n = this.getPanel(t);
-        n && (n.setAttribute("role", "tabpanel"), n.setAttribute("aria-labelledby", t.id), n.classList.add(this.jsHiddenClass))
-    }
-    unsetAttributes(t) {
-        t.removeAttribute("id"), t.removeAttribute("role"), t.removeAttribute("aria-controls"), t.removeAttribute("aria-selected"), t.removeAttribute("tabindex");
-        const e = this.getPanel(t);
-        e && (e.removeAttribute("role"), e.removeAttribute("aria-labelledby"), e.classList.remove(this.jsHiddenClass))
-    }
-    onTabClick(t) {
-        const e = this.getCurrentTab(),
-            n = t.currentTarget;
-        e && n instanceof HTMLAnchorElement && (t.preventDefault(), this.hideTab(e), this.showTab(n), this.createHistoryEntry(n))
-    }
-    createHistoryEntry(t) {
-        const e = this.getPanel(t);
-        if (!e) return;
-        const n = e.id;
-        e.id = "", this.changingHash = !0, window.location.hash = n, e.id = n
-    }
-    onTabKeydown(t) {
-        switch (t.keyCode) {
-            case this.keys.left:
-            case this.keys.up:
-                this.activatePreviousTab(), t.preventDefault();
+        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 = getFragmentFromUrl(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 this.keys.right:
-            case this.keys.down:
-                this.activateNextTab(), t.preventDefault()
+            case "ArrowRight":
+            case "ArrowDown":
+            case "Right":
+            case "Down":
+                this.activateNextTab(), e.preventDefault()
         }
     }
     activateNextTab() {
-        const t = this.getCurrentTab();
-        if (null == t || !t.parentElement) return;
-        const e = t.parentElement.nextElementSibling;
-        if (!e) return;
-        const n = e.querySelector("a.govuk-tabs__tab");
-        n && (this.hideTab(t), this.showTab(n), n.focus(), this.createHistoryEntry(n))
+        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 t = this.getCurrentTab();
-        if (null == t || !t.parentElement) return;
-        const e = t.parentElement.previousElementSibling;
-        if (!e) return;
-        const n = e.querySelector("a.govuk-tabs__tab");
-        n && (this.hideTab(t), this.showTab(n), n.focus(), this.createHistoryEntry(n))
+        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(t) {
-        const e = getFragmentFromUrl(t.href);
-        return e ? this.$module.querySelector(`#${e}`) : null
+    getPanel(e) {
+        const t = getFragmentFromUrl(e.href);
+        return t ? this.$module.querySelector(`#${t}`) : null
     }
-    showPanel(t) {
-        const e = this.getPanel(t);
-        e && e.classList.remove(this.jsHiddenClass)
+    showPanel(e) {
+        const t = this.getPanel(e);
+        t && t.classList.remove(this.jsHiddenClass)
     }
-    hidePanel(t) {
-        const e = this.getPanel(t);
-        e && e.classList.add(this.jsHiddenClass)
+    hidePanel(e) {
+        const t = this.getPanel(e);
+        t && t.classList.add(this.jsHiddenClass)
     }
-    unhighlightTab(t) {
-        t.parentElement && (t.setAttribute("aria-selected", "false"), t.parentElement.classList.remove("govuk-tabs__list-item--selected"), t.setAttribute("tabindex", "-1"))
+    unhighlightTab(e) {
+        e.parentElement && (e.setAttribute("aria-selected", "false"), e.parentElement.classList.remove("govuk-tabs__list-item--selected"), e.setAttribute("tabindex", "-1"))
     }
-    highlightTab(t) {
-        t.parentElement && (t.setAttribute("aria-selected", "true"), t.parentElement.classList.add("govuk-tabs__list-item--selected"), t.setAttribute("tabindex", "0"))
+    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")
     }
 }
 
-function initAll(t) {
-    var e;
-    if (t = void 0 !== t ? t : {}, !isSupported()) return void console.log(new SupportError);
-    const n = [
-            [Accordion, t.accordion],
-            [Button, t.button],
-            [CharacterCount, t.characterCount],
+function initAll(e) {
+    var t;
+    if (e = void 0 !== e ? e : {}, !isSupported()) return void console.log(new SupportError);
+    const s = [
+            [Accordion, e.accordion],
+            [Button, e.button],
+            [CharacterCount, e.characterCount],
             [Checkboxes],
-            [ErrorSummary, t.errorSummary],
-            [ExitThisPage, t.exitThisPage],
+            [ErrorSummary, e.errorSummary],
+            [ExitThisPage, e.exitThisPage],
             [Header],
-            [NotificationBanner, t.notificationBanner],
+            [NotificationBanner, e.notificationBanner],
+            [PasswordInput, e.passwordInput],
             [Radios],
             [SkipLink],
             [Tabs]
         ],
-        i = null != (e = t.scope) ? e : document;
-    n.forEach((([t, e]) => {
-        i.querySelectorAll(`[data-module="${t.moduleName}"]`).forEach((n => {
+        n = null != (t = e.scope) ? t : document;
+    s.forEach((([e, t]) => {
+        n.querySelectorAll(`[data-module="${e.moduleName}"]`).forEach((s => {
             try {
-                "defaults" in t ? new t(n, e) : new t(n)
-            } catch (i) {
-                console.log(i)
+                "defaults" in e ? new e(s, t) : new e(s)
+            } catch (n) {
+                console.log(n)
             }
         }))
     }))
@@ -1008,9 +1139,10 @@ export {
     ExitThisPage,
     Header,
     NotificationBanner,
+    PasswordInput,
     Radios,
     SkipLink,
     Tabs,
     initAll,
     version
-}; //# sourceMappingURL=govuk-frontend-5.2.0.min.js.map
\ No newline at end of file
+}; //# sourceMappingURL=govuk-frontend-5.3.0.min.js.map
\ No newline at end of file

Action run for 05bea72

Copy link

Stylesheets changes to GitHub release

diff --git a/dist/govuk-frontend-5.2.0.min.css b/dist/govuk-frontend-5.3.0.min.css
index 8cc48decc..fe9f09663 100644
--- a/dist/govuk-frontend-5.2.0.min.css
+++ b/dist/govuk-frontend-5.3.0.min.css
@@ -1,7 +1,7 @@
 @charset "UTF-8";
 
 :root {
-    --govuk-frontend-version: "5.2.0";
+    --govuk-frontend-version: "5.3.0";
     --govuk-frontend-breakpoint-mobile: 20rem;
     --govuk-frontend-breakpoint-tablet: 40.0625rem;
     --govuk-frontend-breakpoint-desktop: 48.0625rem
@@ -48,7 +48,7 @@
 }
 
 .govuk-link:focus {
-    outline: 3px solid #0000;
+    outline: 3px solid transparent;
     background-color: #fd0;
     box-shadow: 0 -2px #fd0, 0 4px #0b0c0c;
     text-decoration: none;
@@ -106,7 +106,7 @@
 }
 
 .govuk-link--text-colour:hover {
-    color: #0b0c0cfc
+    color: rgba(11, 12, 12, .99)
 }
 
 .govuk-link--text-colour:active,
@@ -129,7 +129,7 @@
 
 .govuk-link--inverse:active,
 .govuk-link--inverse:hover {
-    color: #fffffffc
+    color: hsla(0, 0%, 100%, .99)
 }
 
 .govuk-link--inverse:focus {
@@ -161,7 +161,7 @@
 }
 
 .govuk-link-image:focus {
-    outline: 3px solid #0000;
+    outline: 3px solid transparent;
     box-shadow: 0 0 0 4px #fd0, 0 0 0 8px #0b0c0c
 }
 
@@ -1301,7 +1301,7 @@
 }
 
 .govuk-frontend-supported .govuk-accordion__show-all:focus {
-    outline: 3px solid #0000;
+    outline: 3px solid transparent;
     color: #0b0c0c;
     background-color: #fd0;
     box-shadow: 0 -2px #fd0, 0 4px #0b0c0c;
@@ -1356,7 +1356,7 @@
     padding: 10px 0 0;
     border: 0;
     border-top: 1px solid #b1b4b6;
-    border-bottom: 10px solid #0000;
+    border-bottom: 10px solid transparent;
     color: #0b0c0c;
     background: none;
     text-align: left;
@@ -1400,7 +1400,7 @@
 .govuk-frontend-supported .govuk-accordion__section-button:focus .govuk-accordion__section-heading-text-focus,
 .govuk-frontend-supported .govuk-accordion__section-button:focus .govuk-accordion__section-summary-focus,
 .govuk-frontend-supported .govuk-accordion__section-button:focus .govuk-accordion__section-toggle-focus {
-    outline: 3px solid #0000;
+    outline: 3px solid transparent;
     color: #0b0c0c;
     background-color: #fd0;
     box-shadow: 0 -2px #fd0, 0 4px #0b0c0c;
@@ -1494,7 +1494,7 @@
 
     .govuk-frontend-supported .govuk-accordion__section-button:hover .govuk-accordion-nav__chevron,
     .govuk-frontend-supported .govuk-accordion__show-all:hover .govuk-accordion-nav__chevron {
-        background-color: initial
+        background-color: transparent
     }
 
     .govuk-frontend-supported .govuk-accordion__section-button:focus .govuk-accordion-nav__chevron,
@@ -1505,8 +1505,8 @@
     .govuk-frontend-supported .govuk-accordion__show-all:focus .govuk-accordion__section-heading-text-focus,
     .govuk-frontend-supported .govuk-accordion__show-all:focus .govuk-accordion__section-summary-focus,
     .govuk-frontend-supported .govuk-accordion__show-all:focus .govuk-accordion__section-toggle-focus {
-        background: #0000;
-        background-color: initial
+        background: transparent;
+        background-color: transparent
     }
 }
 
@@ -1561,7 +1561,7 @@
 }
 
 .govuk-back-link:focus {
-    outline: 3px solid #0000;
+    outline: 3px solid transparent;
     color: #0b0c0c;
     background-color: #fd0;
     box-shadow: 0 -2px #fd0, 0 4px #0b0c0c;
@@ -1584,7 +1584,7 @@
 }
 
 .govuk-back-link:hover {
-    color: #0b0c0cfc
+    color: rgba(11, 12, 12, .99)
 }
 
 .govuk-back-link:active,
@@ -1643,7 +1643,7 @@
 
 .govuk-back-link--inverse:active,
 .govuk-back-link--inverse:hover {
-    color: #fffffffc
+    color: hsla(0, 0%, 100%, .99)
 }
 
 .govuk-back-link--inverse:focus {
@@ -1765,7 +1765,7 @@
 }
 
 .govuk-breadcrumbs__link:focus {
-    outline: 3px solid #0000;
+    outline: 3px solid transparent;
     color: #0b0c0c;
     background-color: #fd0;
     box-shadow: 0 -2px #fd0, 0 4px #0b0c0c;
@@ -1788,7 +1788,7 @@
 }
 
 .govuk-breadcrumbs__link:hover {
-    color: #0b0c0cfc
+    color: rgba(11, 12, 12, .99)
 }
 
 .govuk-breadcrumbs__link:active,
@@ -1832,7 +1832,7 @@
 
 .govuk-breadcrumbs--inverse .govuk-breadcrumbs__link:active,
 .govuk-breadcrumbs--inverse .govuk-breadcrumbs__link:hover {
-    color: #fffffffc
+    color: hsla(0, 0%, 100%, .99)
 }
 
 .govuk-breadcrumbs--inverse .govuk-breadcrumbs__link:focus {
@@ -1856,7 +1856,7 @@
     width: 100%;
     margin: 0 0 22px;
     padding: 8px 10px 7px;
-    border: 2px solid #0000;
+    border: 2px solid transparent;
     border-radius: 0;
     color: #fff;
     background-color: #00703c;
@@ -1917,7 +1917,7 @@
 
 .govuk-button:focus {
     border-color: #fd0;
-    outline: 3px solid #0000;
+    outline: 3px solid transparent;
     box-shadow: inset 0 0 0 1px #fd0
 }
 
@@ -1936,7 +1936,7 @@
     right: -2px;
     bottom: -4px;
     left: -2px;
-    background: #0000
+    background: transparent
 }
 
 .govuk-button:active:before {
@@ -2290,7 +2290,7 @@
 .govuk-textarea:disabled {
     opacity: .5;
     color: inherit;
-    background-color: initial;
+    background-color: transparent;
     cursor: not-allowed
 }
 
@@ -2506,7 +2506,7 @@
     content: "";
     box-sizing: border-box;
     position: absolute;
-    background: #0000
+    background: transparent
 }
 
 .govuk-checkboxes__label:after {
@@ -2517,7 +2517,7 @@
     transform: rotate(-45deg);
     border: solid;
     border-width: 0 0 5px 5px;
-    border-top-color: #0000;
+    border-top-color: transparent;
     opacity: 0
 }
 
@@ -2535,7 +2535,7 @@
 
 .govuk-checkboxes__input:focus+.govuk-checkboxes__label:before {
     border-width: 4px;
-    outline: 3px solid #0000;
+    outline: 3px solid transparent;
     outline-offset: 1px;
     box-shadow: 0 0 0 3px #fd0
 }
@@ -2650,7 +2650,7 @@ screen and (forced-colors:active) {
 }
 
 .govuk-checkboxes--small .govuk-checkboxes__item:hover .govuk-checkboxes__input:not(:disabled)+.govuk-checkboxes__label:before {
-    outline: 3px dashed #0000;
+    outline: 3px dashed transparent;
     outline-offset: 1px;
     box-shadow: 0 0 0 10px #b1b4b6
 }
@@ -2679,7 +2679,7 @@ screen and (forced-colors:active) {
 
 .govuk-cookie-banner {
     padding-top: 20px;
-    border-bottom: 10px solid #0000;
+    border-bottom: 10px solid transparent;
     background-color: #f3f2f1
 }
 
@@ -2746,7 +2746,7 @@ screen and (forced-colors:active) {
 .govuk-input:disabled {
     opacity: .5;
     color: inherit;
-    background-color: initial;
+    background-color: transparent;
     cursor: not-allowed
 }
 
@@ -3031,7 +3031,7 @@ screen and (forced-colors:active) {
     }
 
     .govuk-details__summary:focus {
-        outline: 3px solid #0000;
+        outline: 3px solid transparent;
         color: #0b0c0c;
         background-color: #fd0;
         box-shadow: 0 -2px #fd0, 0 4px #0b0c0c;
@@ -3074,7 +3074,7 @@ screen and (forced-colors:active) {
         height: 0;
         -webkit-clip-path: polygon(0 0, 100% 50%, 0 100%);
         clip-path: polygon(0 0, 100% 50%, 0 100%);
-        border-color: #0000;
+        border-color: transparent;
         border-style: solid;
         border-width: 7px 0 7px 12.124px;
         border-left-color: inherit
@@ -3086,7 +3086,7 @@ screen and (forced-colors:active) {
         height: 0;
         -webkit-clip-path: polygon(0 0, 50% 100%, 100% 0);
         clip-path: polygon(0 0, 50% 100%, 100% 0);
-        border-color: #0000;
+        border-color: transparent;
         border-style: solid;
         border-width: 12.124px 7px 0;
         border-top-color: inherit
@@ -3211,7 +3211,7 @@ screen and (forced-colors:active) {
 }
 
 .govuk-error-summary__list a:focus {
-    outline: 3px solid #0000;
+    outline: 3px solid transparent;
     background-color: #fd0;
     box-shadow: 0 -2px #fd0, 0 4px #0b0c0c;
     text-decoration: none;
@@ -3352,7 +3352,11 @@ screen and (forced-colors:active) {
     font: inherit
 }
 
-.govuk-file-upload:focus,
+.govuk-file-upload:focus {
+    outline: 3px solid #fd0;
+    box-shadow: inset 0 0 0 4px #0b0c0c
+}
+
 .govuk-file-upload:focus-within {
     outline: 3px solid #fd0;
     box-shadow: inset 0 0 0 4px #0b0c0c
@@ -3428,7 +3432,7 @@ screen and (forced-colors:active) {
 }
 
 .govuk-footer__link:focus {
-    outline: 3px solid #0000;
+    outline: 3px solid transparent;
     color: #0b0c0c;
     background-color: #fd0;
     box-shadow: 0 -2px #fd0, 0 4px #0b0c0c;
@@ -3451,7 +3455,7 @@ screen and (forced-colors:active) {
 }
 
 .govuk-footer__link:hover {
-    color: #0b0c0cfc
+    color: rgba(11, 12, 12, .99)
 }
 
 .govuk-footer__link:active,
@@ -3743,7 +3747,7 @@ only screen and (min-resolution:2dppx) {
 
 .govuk-header__link:active,
 .govuk-header__link:hover {
-    color: #fffffffc
+    color: hsla(0, 0%, 100%, .99)
 }
 
 .govuk-header__link:hover {
@@ -3753,7 +3757,7 @@ only screen and (min-resolution:2dppx) {
 }
 
 .govuk-header__link:focus {
-    outline: 3px solid #0000;
+    outline: 3px solid transparent;
     color: #0b0c0c;
     background-color: #fd0;
     box-shadow: 0 -2px #fd0, 0 4px #0b0c0c;
@@ -3895,7 +3899,7 @@ only screen and (min-resolution:2dppx) {
 }
 
 .govuk-header__menu-button:focus {
-    outline: 3px solid #0000;
+    outline: 3px solid transparent;
     color: #0b0c0c;
     background-color: #fd0;
     box-shadow: 0 -2px #fd0, 0 4px #0b0c0c;
@@ -3910,7 +3914,7 @@ only screen and (min-resolution:2dppx) {
     height: 0;
     -webkit-clip-path: polygon(0 0, 50% 100%, 100% 0);
     clip-path: polygon(0 0, 50% 100%, 100% 0);
-    border-color: #0000;
+    border-color: transparent;
     border-style: solid;
     border-width: 8.66px 5px 0;
     border-top-color: inherit;
@@ -3924,7 +3928,7 @@ only screen and (min-resolution:2dppx) {
     height: 0;
     -webkit-clip-path: polygon(50% 0, 0 100%, 100% 100%);
     clip-path: polygon(50% 0, 0 100%, 100% 100%);
-    border-color: #0000;
+    border-color: transparent;
     border-style: solid;
     border-width: 0 5px 8.66px;
     border-bottom-color: inherit
@@ -4029,7 +4033,7 @@ only screen and (min-resolution:2dppx) {
     .govuk-header {
         border-bottom-width: 0;
         color: #0b0c0c;
-        background: #0000
+        background: transparent
     }
 
     .govuk-header__link:link,
@@ -4138,7 +4142,7 @@ only screen and (min-resolution:2dppx) {
 
 .govuk-notification-banner__header {
     padding: 2px 15px 5px;
-    border-bottom: 1px solid #0000
+    border-bottom: 1px solid transparent
 }
 
 @media (min-width:40.0625em) {
@@ -4243,7 +4247,7 @@ only screen and (min-resolution:2dppx) {
 }
 
 .govuk-notification-banner__link:focus {
-    outline: 3px solid #0000;
+    outline: 3px solid transparent;
     background-color: #fd0;
     box-shadow: 0 -2px #fd0, 0 4px #0b0c0c;
     text-decoration: none;
@@ -4400,7 +4404,7 @@ only screen and (min-resolution:2dppx) {
 
 .govuk-pagination__item--current {
     font-weight: 700;
-    outline: 1px solid #0000;
+    outline: 1px solid transparent;
     background-color: #1d70b8
 }
 
@@ -4415,7 +4419,7 @@ only screen and (min-resolution:2dppx) {
 
 .govuk-pagination__item--current .govuk-pagination__link:active,
 .govuk-pagination__item--current .govuk-pagination__link:hover {
-    color: #fffffffc
+    color: hsla(0, 0%, 100%, .99)
 }
 
 .govuk-pagination__item--current .govuk-pagination__link:focus {
@@ -4428,7 +4432,7 @@ only screen and (min-resolution:2dppx) {
 }
 
 .govuk-pagination__item--ellipses:hover {
-    background-color: initial
+    background-color: transparent
 }
 
 .govuk-pagination__link {
@@ -4541,7 +4545,7 @@ only screen and (min-resolution:2dppx) {
 }
 
 .govuk-pagination--block .govuk-pagination__link:focus .govuk-pagination__link-label {
-    outline: 3px solid #0000;
+    outline: 3px solid transparent;
     color: #0b0c0c;
     background-color: #fd0;
     box-shadow: 0 -2px #fd0, 0 4px #0b0c0c;
@@ -4568,7 +4572,7 @@ only screen and (min-resolution:2dppx) {
     box-sizing: border-box;
     margin-bottom: 15px;
     padding: 35px;
-    border: 5px solid #0000;
+    border: 5px solid transparent;
     text-align: center
 }
 
@@ -4639,6 +4643,37 @@ only screen and (min-resolution:2dppx) {
     margin-bottom: 0
 }
 
+@media (min-width:20em) {
+    .govuk-password-input__wrapper {
+        flex-direction: row;
+        align-items: flex-start
+    }
+}
+
+.govuk-password-input__input::-ms-reveal {
+    display: none
+}
+
+.govuk-password-input__toggle {
+    margin-top: 5px;
+    margin-bottom: 0
+}
+
+.govuk-password-input__toggle[hidden] {
+    display: none
+}
+
+@media (min-width:20em) {
+    .govuk-password-input__toggle {
+        width: auto;
+        flex-grow: 1;
+        flex-shrink: 0;
+        flex-basis: 5em;
+        margin-top: 0;
+        margin-left: 5px
+    }
+}
+
 .govuk-tag {
     font-family: GDS Transport, arial, sans-serif;
     -webkit-font-smoothing: antialiased;
@@ -4843,7 +4878,7 @@ only screen and (min-resolution:2dppx) {
     height: 40px;
     border: 2px solid;
     border-radius: 50%;
-    background: #0000
+    background: transparent
 }
 
 .govuk-radios__label:after {
@@ -4873,7 +4908,7 @@ only screen and (min-resolution:2dppx) {
 
 .govuk-radios__input:focus+.govuk-radios__label:before {
     border-width: 4px;
-    outline: 3px solid #0000;
+    outline: 3px solid transparent;
     outline-offset: 1px;
     box-shadow: 0 0 0 4px #fd0
 }
@@ -5003,7 +5038,7 @@ screen and (forced-colors:active) {
 }
 
 .govuk-radios--small .govuk-radios__item:hover .govuk-radios__input:not(:disabled)+.govuk-radios__label:before {
-    outline: 4px dashed #0000;
+    outline: 4px dashed transparent;
     outline-offset: 1px;
     box-shadow: 0 0 0 10px #b1b4b6
 }
@@ -5155,7 +5190,7 @@ screen and (forced-colors:active) {
 }
 
 .govuk-skip-link:hover {
-    color: #0b0c0cfc
+    color: rgba(11, 12, 12, .99)
 }
 
 .govuk-skip-link:active,
@@ -5416,7 +5451,7 @@ screen and (forced-colors:active) {
 
 .govuk-summary-card__title-wrapper {
     padding: 15px;
-    border-bottom: 1px solid #0000;
+    border-bottom: 1px solid transparent;
     background-color: #f3f2f1
 }
 
@@ -5809,7 +5844,7 @@ screen and (-ms-high-contrast:active) {
 }
 
 .govuk-tabs__tab:focus {
-    outline: 3px solid #0000;
+    outline: 3px solid transparent;
     background-color: #fd0;
     box-shadow: 0 -2px #fd0, 0 4px #0b0c0c;
     text-decoration: none;
@@ -5907,7 +5942,7 @@ screen and (-ms-high-contrast:active) {
 
 @media (min-width:40.0625em) {
     .govuk-frontend-supported .govuk-tabs__tab:hover {
-        color: #0b0c0cfc
+        color: rgba(11, 12, 12, .99)
     }
 
     .govuk-frontend-supported .govuk-tabs__tab:active,
@@ -6122,7 +6157,7 @@ screen and (-ms-high-contrast:active) {
     .govuk-warning-text__icon {
         border-color: windowText;
         color: windowText;
-        background: #0000
+        background: transparent
     }
 }
 
@@ -7602,4 +7637,4 @@ screen and (-ms-high-contrast:active) {
     }
 }
 
-/*# sourceMappingURL=govuk-frontend-5.2.0.min.css.map */
\ No newline at end of file
+/*# sourceMappingURL=govuk-frontend-5.3.0.min.css.map */
\ No newline at end of file

Action run for 05bea72

Copy link

Other changes to GitHub release

diff --git a/dist/VERSION.txt b/dist/VERSION.txt
index 91ff57278..03f488b07 100644
--- a/dist/VERSION.txt
+++ b/dist/VERSION.txt
@@ -1 +1 @@
-5.2.0
+5.3.0

Action run for 05bea72

Copy link

📋 Stats

File sizes

File Size
dist/govuk-frontend-development.min.css 113.25 KiB
dist/govuk-frontend-development.min.js 42.21 KiB
packages/govuk-frontend/dist/govuk/all.bundle.js 87.2 KiB
packages/govuk-frontend/dist/govuk/all.bundle.mjs 81.94 KiB
packages/govuk-frontend/dist/govuk/all.mjs 4.17 KiB
packages/govuk-frontend/dist/govuk/govuk-frontend-component.mjs 359 B
packages/govuk-frontend/dist/govuk/govuk-frontend.min.css 113.24 KiB
packages/govuk-frontend/dist/govuk/govuk-frontend.min.js 42.2 KiB
packages/govuk-frontend/dist/govuk/i18n.mjs 5.55 KiB

Modules

File Size (bundled) Size (minified)
all.mjs 77.67 KiB 40.18 KiB
accordion.mjs 22.71 KiB 12.85 KiB
button.mjs 5.98 KiB 2.69 KiB
character-count.mjs 22.4 KiB 9.92 KiB
checkboxes.mjs 5.83 KiB 2.83 KiB
error-summary.mjs 7.89 KiB 3.46 KiB
exit-this-page.mjs 17.1 KiB 9.26 KiB
header.mjs 4.46 KiB 2.6 KiB
notification-banner.mjs 6.26 KiB 2.62 KiB
password-input.mjs 15.15 KiB 7.25 KiB
radios.mjs 4.83 KiB 2.38 KiB
skip-link.mjs 4.39 KiB 2.18 KiB
tabs.mjs 10.13 KiB 6.11 KiB

View stats and visualisations on the review app


Action run for 05bea72

@36degrees 36degrees merged commit 0801b62 into main Mar 26, 2024
48 checks passed
@36degrees 36degrees deleted the release-5.3.0 branch March 26, 2024 10:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants