Skip to content

Conversation

govuk-design-system-ci
Copy link
Collaborator

Fixes

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

@govuk-design-system-ci govuk-design-system-ci requested a review from a team as a code owner August 22, 2025 13:43
@govuk-design-system-ci govuk-design-system-ci temporarily deployed to govuk-frontend-pr-6187 August 22, 2025 13:43 Inactive
Copy link

JavaScript changes to GitHub release

diff --git a/dist/govuk-frontend-5.11.1.min.js b/dist/govuk-frontend-5.11.2.min.js
index ced7a4879..f872ffb7b 100644
--- a/dist/govuk-frontend-5.11.1.min.js
+++ b/dist/govuk-frontend-5.11.2.min.js
@@ -1,8 +1,4 @@
-const version = "5.11.1";
-
-function getFragmentFromUrl(t) {
-    if (t.includes("#")) return t.split("#").pop()
-}
+const version = "5.11.2";
 
 function getBreakpoint(t) {
     const e = `--govuk-breakpoint-${t}`;
@@ -39,6 +35,10 @@ function isObject(t) {
     }(t)
 }
 
+function isScope(t) {
+    return !!t && (t instanceof Element || t instanceof Document)
+}
+
 function formatErrorMessage(Component, t) {
     return `${Component.moduleName}: ${t}`
 }
@@ -61,14 +61,14 @@ class ConfigError extends GOVUKFrontendError {
 class ElementError extends GOVUKFrontendError {
     constructor(t) {
         let e = "string" == typeof t ? t : "";
-        if ("object" == typeof t) {
+        if (isObject(t)) {
             const {
                 component: i,
                 identifier: n,
                 element: s,
                 expectedType: o
             } = t;
-            e = n, e += s ? ` is not of type ${null!=o?o:"HTMLElement"}` : " not found", e = formatErrorMessage(i, e)
+            e = n, e += s ? ` is not of type ${null!=o?o:"HTMLElement"}` : " not found", i && (e = formatErrorMessage(i, e))
         }
         super(e), this.name = "ElementError"
     }
@@ -150,6 +150,18 @@ function normaliseString(t, e) {
     return n
 }
 
+function normaliseOptions(t) {
+    let e, i = document;
+    if (isObject(t)) {
+        const n = t;
+        (isScope(n.scope) || null === n.scope) && (i = n.scope), "function" == typeof n.onError && (e = n.onError)
+    }
+    return isScope(t) ? i = t : null === t ? i = null : "function" == typeof t && (e = t), {
+        scope: i,
+        onError: e
+    }
+}
+
 function mergeConfigs(...t) {
     const e = {};
     for (const i of t)
@@ -182,7 +194,7 @@ class I18n {
     t(t, e) {
         if (!t) throw new Error("i18n: lookup key missing");
         let i = this.translations[t];
-        if ("number" == typeof(null == e ? void 0 : e.count) && "object" == typeof i) {
+        if ("number" == typeof(null == e ? void 0 : e.count) && isObject(i)) {
             const n = i[this.getPluralSuffix(t, e.count)];
             n && (i = n)
         }
@@ -212,7 +224,7 @@ class I18n {
         if (e = Number(e), !isFinite(e)) return "other";
         const i = this.translations[t],
             n = this.hasIntlPluralRulesSupport() ? new Intl.PluralRules(this.locale).select(e) : this.selectPluralFormUsingFallbackRules(e);
-        if ("object" == typeof i) {
+        if (isObject(i)) {
             if (n in i) return n;
             if ("other" in i) return console.warn(`i18n: Missing plural form ".${n}" for "${this.locale}" locale. Falling back to ".other".`), "other"
         }
@@ -345,9 +357,9 @@ class Accordion extends ConfigurableComponent {
         n.textContent = r, s.setAttribute("aria-expanded", `${t}`);
         const a = [],
             l = e.querySelector(`.${this.sectionHeadingTextClass}`);
-        l && a.push(`${l.textContent}`.trim());
+        l && a.push(l.textContent.trim());
         const c = e.querySelector(`.${this.sectionSummaryClass}`);
-        c && a.push(`${c.textContent}`.trim());
+        c && a.push(c.textContent.trim());
         const u = t ? this.i18n.t("hideSectionAriaLabel") : this.i18n.t("showSectionAriaLabel");
         a.push(u), s.setAttribute("aria-label", a.join(" , ")), t ? (o.removeAttribute("hidden"), e.classList.add(this.sectionExpandedClass), i.classList.remove(this.downChevronIconClass)) : (o.setAttribute("hidden", "until-found"), e.classList.remove(this.sectionExpandedClass), i.classList.add(this.downChevronIconClass)), this.updateShowAllButton(this.areAllSectionsOpen())
     }
@@ -476,7 +488,7 @@ class CharacterCount extends ConfigurableComponent {
             element: a,
             identifier: `Count message (\`id="${r}"\`)`
         });
-        this.$errorMessage = this.$root.querySelector(".govuk-error-message"), `${a.textContent}`.match(/^\s*$/) && (a.textContent = this.i18n.t("textareaDescription", {
+        this.$errorMessage = this.$root.querySelector(".govuk-error-message"), a.textContent.match(/^\s*$/) && (a.textContent = this.i18n.t("textareaDescription", {
             count: this.maxLength
         })), this.$textarea.insertAdjacentElement("afterend", a);
         const l = document.createElement("div");
@@ -643,7 +655,7 @@ class ErrorSummary extends ConfigurableComponent {
     }
     focusTarget(t) {
         if (!(t instanceof HTMLAnchorElement)) return !1;
-        const e = getFragmentFromUrl(t.href);
+        const e = t.hash.replace("#", "");
         if (!e) return !1;
         const i = document.getElementById(e);
         if (!i) return !1;
@@ -761,7 +773,7 @@ class FileUpload extends ConfigurableComponent {
             identifier: 'File inputs (`<input type="file">`)'
         });
         if ("file" !== i.type) throw new ElementError(formatErrorMessage(FileUpload, 'File input (`<input type="file">`) attribute (`type`) is not `file`'));
-        if (this.$input = i, this.$input.setAttribute("hidden", "true"), !this.$input.id) throw new ElementError({
+        if (this.$input = i, !this.$input.id) throw new ElementError({
             component: FileUpload,
             identifier: 'File input (`<input type="file">`) attribute (`id`)'
         });
@@ -769,7 +781,7 @@ class FileUpload extends ConfigurableComponent {
             locale: closestAttributeValue(this.$root, "lang")
         });
         const n = this.findLabel();
-        n.id || (n.id = `${this.id}-label`), this.$input.id = `${this.id}-input`;
+        n.id || (n.id = `${this.id}-label`), this.$input.id = `${this.id}-input`, this.$input.setAttribute("hidden", "true");
         const s = document.createElement("button");
         s.classList.add("govuk-file-upload-button"), s.type = "button", s.id = this.id, s.classList.add("govuk-file-upload-button--empty");
         const o = this.$input.getAttribute("aria-describedby");
@@ -1050,27 +1062,21 @@ class SkipLink extends Component {
         super(t);
         const i = this.$root.hash,
             n = null != (e = this.$root.getAttribute("href")) ? e : "";
-        let s;
-        try {
-            s = new window.URL(this.$root.href)
-        } catch (a) {
-            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(i);
-        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({
+        if (this.$root.origin !== window.location.origin || this.$root.pathname !== window.location.pathname) return;
+        const s = i.replace("#", "");
+        if (!s) throw new ElementError(`Skip link: Target link (\`href="${n}"\`) has no hash fragment`);
+        const o = document.getElementById(s);
+        if (!o) throw new ElementError({
             component: SkipLink,
-            element: r,
-            identifier: `Target content (\`id="${o}"\`)`
+            element: o,
+            identifier: `Target content (\`id="${s}"\`)`
         });
-        this.$root.addEventListener("click", (() => setFocus(r, {
+        this.$root.addEventListener("click", (() => setFocus(o, {
             onBeforeFocus() {
-                r.classList.add("govuk-skip-link-focused-element")
+                o.classList.add("govuk-skip-link-focused-element")
             },
             onBlur() {
-                r.classList.remove("govuk-skip-link-focused-element")
+                o.classList.remove("govuk-skip-link-focused-element")
             }
         })))
     }
@@ -1144,7 +1150,7 @@ class Tabs extends Component {
         return this.$root.querySelector(`a.govuk-tabs__tab[href="${t}"]`)
     }
     setAttributes(t) {
-        const e = getFragmentFromUrl(t.href);
+        const e = t.hash.replace("#", "");
         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 i = this.getPanel(t);
@@ -1194,7 +1200,7 @@ class Tabs extends Component {
         i && (this.hideTab(t), this.showTab(i), i.focus(), this.createHistoryEntry(i))
     }
     getPanel(t) {
-        const e = getFragmentFromUrl(t.href);
+        const e = t.hash.replace("#", "");
         return e ? this.$root.querySelector(`#${e}`) : null
     }
     showPanel(t) {
@@ -1216,56 +1222,68 @@ class Tabs extends Component {
     }
 }
 
-function initAll(t) {
-    var e;
-    if (t = void 0 !== t ? t : {}, !isSupported()) return void(t.onError ? t.onError(new SupportError, {
-        config: t
-    }) : console.log(new SupportError));
-    const i = [
-            [Accordion, t.accordion],
-            [Button, t.button],
-            [CharacterCount, t.characterCount],
-            [Checkboxes],
-            [ErrorSummary, t.errorSummary],
-            [ExitThisPage, t.exitThisPage],
-            [FileUpload, t.fileUpload],
-            [Header],
-            [NotificationBanner, t.notificationBanner],
-            [PasswordInput, t.passwordInput],
-            [Radios],
-            [ServiceNavigation],
-            [SkipLink],
-            [Tabs]
-        ],
-        n = {
-            scope: null != (e = t.scope) ? e : document,
-            onError: t.onError
-        };
-    i.forEach((([Component, t]) => {
-        createAll(Component, t, n)
+function initAll(t = {}) {
+    const e = isObject(t) ? t : {},
+        i = normaliseOptions(t);
+    try {
+        if (!isSupported()) throw new SupportError;
+        if (null === i.scope) throw new ElementError({
+            element: i.scope,
+            identifier: "GOV.UK Frontend scope element (`$scope`)"
+        })
+    } catch (n) {
+        return void(i.onError ? i.onError(n, {
+            config: e
+        }) : console.log(n))
+    } [
+        [Accordion, e.accordion],
+        [Button, e.button],
+        [CharacterCount, e.characterCount],
+        [Checkboxes],
+        [ErrorSummary, e.errorSummary],
+        [ExitThisPage, e.exitThisPage],
+        [FileUpload, e.fileUpload],
+        [Header],
+        [NotificationBanner, e.notificationBanner],
+        [PasswordInput, e.passwordInput],
+        [Radios],
+        [ServiceNavigation],
+        [SkipLink],
+        [Tabs]
+    ].forEach((([Component, t]) => {
+        createAll(Component, t, i)
     }))
 }
 
 function createAll(Component, t, e) {
-    let i, n = document;
-    var s;
-    "object" == typeof e && (n = null != (s = e.scope) ? s : n, i = e.onError);
-    "function" == typeof e && (i = e), e instanceof HTMLElement && (n = e);
-    const o = n.querySelectorAll(`[data-module="${Component.moduleName}"]`);
-    return isSupported() ? Array.from(o).map((e => {
+    let i;
+    const n = normaliseOptions(e);
+    try {
+        var s;
+        if (!isSupported()) throw new SupportError;
+        if (null === n.scope) throw new ElementError({
+            element: n.scope,
+            component: Component,
+            identifier: "Scope element (`$scope`)"
+        });
+        i = null == (s = n.scope) ? void 0 : s.querySelectorAll(`[data-module="${Component.moduleName}"]`)
+    } catch (o) {
+        return n.onError ? n.onError(o, {
+            component: Component,
+            config: t
+        }) : console.log(o), []
+    }
+    return Array.from(null != i ? i : []).map((e => {
         try {
             return void 0 !== t ? new Component(e, t) : new Component(e)
-        } catch (n) {
-            return i ? i(n, {
+        } catch (o) {
+            return n.onError ? n.onError(o, {
                 element: e,
                 component: Component,
                 config: t
-            }) : console.log(n), null
+            }) : console.log(o), null
         }
-    })).filter(Boolean) : (i ? i(new SupportError, {
-        component: Component,
-        config: t
-    }) : console.log(new SupportError), [])
+    })).filter(Boolean)
 }
 Tabs.moduleName = "govuk-tabs";
 export {
@@ -1289,4 +1307,4 @@ export {
     initAll,
     isSupported,
     version
-}; //# sourceMappingURL=govuk-frontend-5.11.1.min.js.map
\ No newline at end of file
+}; //# sourceMappingURL=govuk-frontend-5.11.2.min.js.map
\ No newline at end of file

Action run for 4e655b1

Copy link

Stylesheets changes to GitHub release

diff --git a/dist/govuk-frontend-5.11.1.min.css b/dist/govuk-frontend-5.11.2.min.css
index 7665f0c55..764109f55 100644
--- a/dist/govuk-frontend-5.11.1.min.css
+++ b/dist/govuk-frontend-5.11.2.min.css
@@ -1,7 +1,7 @@
 @charset "UTF-8";
 
 :root {
-    --govuk-frontend-version: "5.11.1";
+    --govuk-frontend-version: "5.11.2";
     --govuk-breakpoint-mobile: 20rem;
     --govuk-frontend-breakpoint-mobile: var(--govuk-breakpoint-mobile);
     --govuk-breakpoint-tablet: 40.0625rem;
@@ -4913,6 +4913,10 @@ screen and (forced-colors:active) {
     text-decoration: none
 }
 
+.govuk-pagination__link-title {
+    text-decoration-thickness: inherit
+}
+
 .govuk-pagination__link-label {
     font-weight: 400;
     text-decoration: underline;
@@ -5923,12 +5927,13 @@ screen and (forced-colors:active) {
 }
 
 .govuk-skip-link {
-    font-family: GDS Transport, arial, sans-serif;
-    -webkit-font-smoothing: antialiased;
-    -moz-osx-font-smoothing: grayscale;
     text-decoration: underline;
     text-decoration-thickness: max(1px, .0625rem);
     text-underline-offset: .1578em;
+    font-family: GDS Transport, arial, sans-serif;
+    -webkit-font-smoothing: antialiased;
+    -moz-osx-font-smoothing: grayscale;
+    font-weight: 400;
     font-size: .875rem;
     line-height: 1.1428571429;
     display: block;
@@ -5952,12 +5957,6 @@ screen and (forced-colors:active) {
     user-select: none
 }
 
-@media print {
-    .govuk-skip-link {
-        font-family: sans-serif
-    }
-}
-
 .govuk-skip-link:link,
 .govuk-skip-link:visited {
     color: #0b0c0c
@@ -5986,6 +5985,10 @@ screen and (forced-colors:active) {
     .govuk-skip-link:focus {
         color: #000
     }
+
+    .govuk-skip-link {
+        font-family: sans-serif
+    }
 }
 
 @media (min-width:40.0625em) {
@@ -8404,4 +8407,4 @@ screen and (-ms-high-contrast:active) {
     }
 }
 
-/*# sourceMappingURL=govuk-frontend-5.11.1.min.css.map */
\ No newline at end of file
+/*# sourceMappingURL=govuk-frontend-5.11.2.min.css.map */
\ No newline at end of file

Action run for 4e655b1

Copy link

Other changes to GitHub release

diff --git a/dist/VERSION.txt b/dist/VERSION.txt
index 32447ce31..a87467fbf 100644
--- a/dist/VERSION.txt
+++ b/dist/VERSION.txt
@@ -1 +1 @@
-5.11.1
+5.11.2

Action run for 4e655b1

Copy link

📋 Stats

No changes to any distributed file sizes!


Action run for 4e655b1

@owenatgov owenatgov merged commit a340be6 into main Aug 22, 2025
51 checks passed
@owenatgov owenatgov deleted the release-5.11.2 branch August 22, 2025 13:56
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.

3 participants