-
Notifications
You must be signed in to change notification settings - Fork 328
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.4.0 #4987
Merged
Merged
Release v5.4.0 #4987
+21
−15
Conversation
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
JavaScript changes to GitHub releasediff --git a/dist/govuk-frontend-5.3.1.min.js b/dist/govuk-frontend-5.4.0.min.js
index a2d459b47..7c8495726 100644
--- a/dist/govuk-frontend-5.3.1.min.js
+++ b/dist/govuk-frontend-5.4.0.min.js
@@ -1,44 +1,44 @@
-const version = "5.3.1";
+const version = "5.4.0";
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) {
+ const n = e ? e.trim() : "";
+ let s, i = null == t ? void 0 : t.type;
+ switch (i || (["true", "false"].includes(n) && (i = "boolean"), n.length > 0 && isFinite(Number(n)) && (i = "number")), i) {
case "boolean":
- n = "true" === s;
+ s = "true" === n;
break;
case "number":
- n = Number(s);
+ s = Number(n);
break;
default:
- n = e
+ s = e
}
- return n
+ return 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
+ for (const n of e)
+ for (const e of Object.keys(n)) {
+ const s = t[e],
+ i = n[e];
+ isObject(s) && isObject(i) ? t[e] = mergeConfigs(s, i) : t[e] = i
}
return t
}
-function extractConfigByNamespace(e, t, s) {
- const n = e.schema.properties[s];
- if ("object" !== (null == n ? void 0 : n.type)) return;
+function extractConfigByNamespace(e, t, n) {
+ const s = e.schema.properties[n];
+ if ("object" !== (null == s ? void 0 : s.type)) return;
const i = {
- [s]: {}
+ [n]: {}
};
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)))
+ for (const [s, i] of t.entries()) "object" == typeof e && (s < t.length - 1 ? (isObject(e[i]) || (e[i] = {}), e = e[i]) : o !== n && (e[i] = normaliseString(r)))
}
- return i[s]
+ return i[n]
}
function getFragmentFromUrl(e) {
@@ -54,20 +54,20 @@ function getBreakpoint(e) {
}
function setFocus(e, t = {}) {
- var s;
- const n = e.getAttribute("tabindex");
+ var n;
+ const s = e.getAttribute("tabindex");
function onBlur() {
- var s;
- null == (s = t.onBlur) || s.call(e), n || e.removeAttribute("tabindex")
+ var n;
+ null == (n = t.onBlur) || n.call(e), s || e.removeAttribute("tabindex")
}
- n || e.setAttribute("tabindex", "-1"), e.addEventListener("focus", (function() {
+ s || e.setAttribute("tabindex", "-1"), e.addEventListener("focus", (function() {
e.addEventListener("blur", onBlur, {
once: !0
})
}), {
once: !0
- }), null == (s = t.onBeforeFocus) || s.call(e), e.focus()
+ }), null == (n = t.onBeforeFocus) || n.call(e), e.focus()
}
function isSupported(e = document.body) {
@@ -81,9 +81,9 @@ function isObject(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
+ const n = {};
+ for (const [s, i] of Object.entries(e.schema.properties)) s in t && (n[s] = normaliseString(t[s], i)), "object" === (null == i ? void 0 : i.type) && (n[s] = extractConfigByNamespace(e, t, s));
+ return n
}
class GOVUKFrontendError extends Error {
constructor(...e) {
@@ -106,12 +106,12 @@ class ElementError extends GOVUKFrontendError {
let t = "string" == typeof e ? e : "";
if ("object" == typeof e) {
const {
- componentName: s,
- identifier: n,
+ componentName: n,
+ identifier: s,
element: i,
expectedType: o
} = e;
- t = `${s}: ${n}`, t += i ? ` is not of type ${null!=o?o:"HTMLElement"}` : " not found"
+ t = `${n}: ${s}`, t += i ? ` is not of type ${null!=o?o:"HTMLElement"}` : " not found"
}
super(t), this.name = "ElementError"
}
@@ -126,31 +126,31 @@ class GOVUKFrontendComponent {
}
class I18n {
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"
+ var n;
+ this.translations = void 0, this.locale = void 0, this.translations = e, this.locale = null != (n = t.locale) ? n : 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)
+ let n = this.translations[e];
+ if ("number" == typeof(null == t ? void 0 : t.count) && "object" == typeof n) {
+ const s = n[this.getPluralSuffix(e, t.count)];
+ s && (n = s)
}
- if ("string" == typeof s) {
- if (s.match(/%{(.\S+)}/)) {
+ if ("string" == typeof n) {
+ if (n.match(/%{(.\S+)}/)) {
if (!t) throw new Error("i18n: cannot replace placeholders in string if no option data provided");
- return this.replacePlaceholders(s, t)
+ return this.replacePlaceholders(n, t)
}
- return s
+ return n
}
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
+ const n = Intl.NumberFormat.supportedLocalesOf(this.locale).length ? new Intl.NumberFormat(this.locale) : void 0;
+ return e.replace(/%{(.\S+)}/g, (function(e, s) {
+ if (Object.prototype.hasOwnProperty.call(t, s)) {
+ const e = t[s];
+ return !1 === e || "number" != typeof e && "string" != typeof e ? "" : "number" == typeof e ? n ? n.format(e) : `${e}` : e
}
throw new Error(`i18n: no data found to replace ${e} placeholder in string`)
}))
@@ -160,11 +160,11 @@ class I18n {
}
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"
+ const n = this.translations[e],
+ s = this.hasIntlPluralRulesSupport() ? new Intl.PluralRules(this.locale).select(t) : this.selectPluralFormUsingFallbackRules(t);
+ if ("object" == typeof n) {
+ if (s in n) return s;
+ if ("other" in n) return console.warn(`i18n: Missing plural form ".${s}" for "${this.locale}" locale. Falling back to ".other".`), "other"
}
throw new Error(`i18n: Plural form ".other" is required for "${this.locale}" locale`)
}
@@ -176,8 +176,8 @@ class I18n {
getPluralRulesForLocale() {
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
+ const n = I18n.pluralRulesMap[t];
+ if (n.includes(this.locale) || n.includes(e)) return t
}
}
}
@@ -199,27 +199,27 @@ I18n.pluralRulesMap = {
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"
+ n = t % 10;
+ return 1 === n && 11 !== t ? "one" : n >= 2 && n <= 4 && !(t >= 12 && t <= 14) ? "few" : 0 === n || n >= 5 && n <= 9 || t >= 11 && t <= 14 ? "many" : "other"
},
scottish: e => 1 === e || 11 === e ? "one" : 2 === e || 12 === e ? "two" : e >= 3 && e <= 10 || e >= 13 && e <= 19 ? "few" : "other",
spanish: e => 1 === e ? "one" : e % 1e6 == 0 && 0 !== e ? "many" : "other",
welsh: e => 0 === e ? "zero" : 1 === e ? "one" : 2 === e ? "two" : 3 === e ? "few" : 6 === e ? "many" : "other"
};
class Accordion extends GOVUKFrontendComponent {
- constructor(t, s = {}) {
+ constructor(t, 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, !(t instanceof HTMLElement)) throw new ElementError({
componentName: "Accordion",
element: t,
identifier: "Root element (`$module`)"
});
- 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({
+ this.$module = t, this.config = mergeConfigs(Accordion.defaults, n, normaliseDataset(Accordion, t.dataset)), this.i18n = new I18n(this.config.i18n);
+ const s = this.$module.querySelectorAll(`.${this.sectionClass}`);
+ if (!s.length) throw new ElementError({
componentName: "Accordion",
identifier: `Sections (\`<div class="${this.sectionClass}">\`)`
});
- this.$sections = n, this.browserSupportsSessionStorage = e.checkForSessionStorage(), this.initControls(), this.initSectionHeaders();
+ this.$sections = s, this.browserSupportsSessionStorage = e.checkForSessionStorage(), this.initControls(), this.initSectionHeaders();
const i = this.checkIfAllSectionsOpen();
this.updateShowAllButton(i)
}
@@ -230,33 +230,33 @@ class Accordion extends GOVUKFrontendComponent {
}
initSectionHeaders() {
this.$sections.forEach(((e, t) => {
- const s = e.querySelector(`.${this.sectionHeaderClass}`);
- if (!s) throw new ElementError({
+ const n = e.querySelector(`.${this.sectionHeaderClass}`);
+ if (!n) throw new ElementError({
componentName: "Accordion",
identifier: `Section headers (\`<div class="${this.sectionHeaderClass}">\`)`
});
- this.constructHeaderMarkup(s, t), this.setExpanded(this.isExpanded(e), e), s.addEventListener("click", (() => this.onSectionToggle(e))), this.setInitialState(e)
+ this.constructHeaderMarkup(n, t), this.setExpanded(this.isExpanded(e), e), n.addEventListener("click", (() => this.onSectionToggle(e))), this.setInitialState(e)
}))
}
constructHeaderMarkup(e, t) {
- const s = e.querySelector(`.${this.sectionButtonClass}`),
- n = e.querySelector(`.${this.sectionHeadingClass}`),
+ const n = e.querySelector(`.${this.sectionButtonClass}`),
+ s = e.querySelector(`.${this.sectionHeadingClass}`),
i = e.querySelector(`.${this.sectionSummaryClass}`);
- if (!n) throw new ElementError({
+ if (!s) throw new ElementError({
componentName: "Accordion",
identifier: `Section heading (\`.${this.sectionHeadingClass}\`)`
});
- if (!s) throw new ElementError({
+ if (!n) 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-${t+1}`);
- for (const d of Array.from(s.attributes)) "id" !== d.nodeName && o.setAttribute(d.nodeName, `${d.nodeValue}`);
+ for (const d of Array.from(n.attributes)) "id" !== d.nodeName && o.setAttribute(d.nodeName, `${d.nodeValue}`);
const r = document.createElement("span");
- r.classList.add(this.sectionHeadingTextClass), r.id = s.id;
+ r.classList.add(this.sectionHeadingTextClass), r.id = n.id;
const a = document.createElement("span");
- a.classList.add(this.sectionHeadingTextFocusClass), r.appendChild(a), a.innerHTML = s.innerHTML;
+ a.classList.add(this.sectionHeadingTextFocusClass), r.appendChild(a), a.innerHTML = n.innerHTML;
const l = document.createElement("span");
l.classList.add(this.sectionShowHideToggleClass), l.setAttribute("data-nosnippet", "");
const c = document.createElement("span");
@@ -267,16 +267,16 @@ class Accordion extends GOVUKFrontendComponent {
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}`);
+ for (const n of Array.from(i.attributes)) e.setAttribute(n.nodeName, `${n.nodeValue}`);
t.innerHTML = i.innerHTML, i.parentNode.replaceChild(e, i), o.appendChild(e), o.appendChild(this.getButtonPunctuationEl())
}
- o.appendChild(l), n.removeChild(s), n.appendChild(o)
+ o.appendChild(l), s.removeChild(n), s.appendChild(o)
}
onBeforeMatch(e) {
const t = e.target;
if (!(t instanceof Element)) return;
- const s = t.closest(`.${this.sectionClass}`);
- s && this.setExpanded(!0, s)
+ const n = t.closest(`.${this.sectionClass}`);
+ n && this.setExpanded(!0, n)
}
onSectionToggle(e) {
const t = this.isExpanded(e);
@@ -289,24 +289,24 @@ class Accordion extends GOVUKFrontendComponent {
})), this.updateShowAllButton(e)
}
setExpanded(e, t) {
- const s = t.querySelector(`.${this.upChevronIconClass}`),
- n = t.querySelector(`.${this.sectionShowHideTextClass}`),
+ const n = t.querySelector(`.${this.upChevronIconClass}`),
+ s = 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 (!s || !n || !i) return;
+ if (!n || !s || !i) return;
const r = e ? this.i18n.t("hideSection") : this.i18n.t("showSection");
- n.textContent = r, i.setAttribute("aria-expanded", `${e}`);
+ s.textContent = r, i.setAttribute("aria-expanded", `${e}`);
const a = [],
l = t.querySelector(`.${this.sectionHeadingTextClass}`);
l && a.push(`${l.textContent}`.trim());
const c = t.querySelector(`.${this.sectionSummaryClass}`);
c && a.push(`${c.textContent}`.trim());
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));
+ a.push(h), i.setAttribute("aria-label", a.join(" , ")), e ? (o.removeAttribute("hidden"), t.classList.add(this.sectionExpandedClass), n.classList.remove(this.downChevronIconClass)) : (o.setAttribute("hidden", "until-found"), t.classList.remove(this.sectionExpandedClass), n.classList.add(this.downChevronIconClass));
const u = this.checkIfAllSectionsOpen();
this.updateShowAllButton(u)
}
@@ -324,8 +324,8 @@ class Accordion extends GOVUKFrontendComponent {
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)
+ n = t.getAttribute("aria-expanded");
+ e && n && window.sessionStorage.setItem(e, n)
}
}
}
@@ -333,9 +333,9 @@ class Accordion extends GOVUKFrontendComponent {
if (this.browserSupportsSessionStorage && this.config.rememberExpanded) {
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)
+ const n = t.getAttribute("aria-controls"),
+ s = n ? window.sessionStorage.getItem(n) : null;
+ null !== s && this.setExpanded("true" === s, e)
}
}
}
@@ -370,7 +370,7 @@ const e = {
let t;
try {
return window.sessionStorage.setItem(e, e), t = window.sessionStorage.getItem(e) === e.toString(), window.sessionStorage.removeItem(e), t
- } catch (s) {
+ } catch (n) {
return !1
}
}
@@ -396,8 +396,8 @@ class Button extends GOVUKFrontendComponent {
}
function closestAttributeValue(e, t) {
- const s = e.closest(`[${t}]`);
- return s ? s.getAttribute(t) : null
+ const n = e.closest(`[${t}]`);
+ return n ? n.getAttribute(t) : null
}
Button.moduleName = "govuk-button", Button.defaults = Object.freeze({
preventDoubleClick: !1
@@ -410,7 +410,7 @@ Button.moduleName = "govuk-button", Button.defaults = Object.freeze({
});
class CharacterCount extends GOVUKFrontendComponent {
constructor(e, t = {}) {
- var s, n;
+ var n, s;
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: e,
@@ -430,24 +430,24 @@ class CharacterCount extends GOVUKFrontendComponent {
maxwords: void 0
}), this.config = mergeConfigs(CharacterCount.defaults, t, r, o);
const a = function(e, t) {
- const s = [];
- for (const [n, i] of Object.entries(e)) {
+ const n = [];
+ for (const [s, i] of Object.entries(e)) {
const e = [];
if (Array.isArray(i)) {
for (const {
- required: s,
- errorMessage: n
+ required: n,
+ errorMessage: s
}
- of i) s.every((e => !!t[e])) || e.push(n);
- "anyOf" !== n || i.length - e.length >= 1 || s.push(...e)
+ of i) n.every((e => !!t[e])) || e.push(s);
+ "anyOf" !== s || i.length - e.length >= 1 || n.push(...e)
}
}
- return s
+ return n
}(CharacterCount.schema, this.config);
if (a[0]) throw new ConfigError(`Character count: ${a[0]}`);
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;
+ }), this.maxLength = null != (n = null != (s = this.config.maxwords) ? s : this.config.maxlength) ? n : 1 / 0, this.$module = e, this.$textarea = i;
const l = `${this.$textarea.id}-info`,
c = document.getElementById(l);
if (!c) throw new ElementError({
@@ -504,8 +504,8 @@ class CharacterCount extends GOVUKFrontendComponent {
}
formatCountMessage(e, t) {
if (0 === e) return this.i18n.t(`${t}AtLimit`);
- const s = e < 0 ? "OverLimit" : "UnderLimit";
- return this.i18n.t(`${t}${s}`, {
+ const n = e < 0 ? "OverLimit" : "UnderLimit";
+ return this.i18n.t(`${t}${n}`, {
count: Math.abs(e)
})
}
@@ -592,10 +592,10 @@ class Checkboxes extends GOVUKFrontendComponent {
syncConditionalRevealWithInputState(e) {
const t = e.getAttribute("aria-controls");
if (!t) return;
- const s = document.getElementById(t);
- if (null != s && s.classList.contains("govuk-checkboxes__conditional")) {
+ const n = document.getElementById(t);
+ if (null != n && n.classList.contains("govuk-checkboxes__conditional")) {
const t = e.checked;
- e.setAttribute("aria-expanded", t.toString()), s.classList.toggle("govuk-checkboxes__conditional--hidden", !t)
+ e.setAttribute("aria-expanded", t.toString()), n.classList.toggle("govuk-checkboxes__conditional--hidden", !t)
}
}
unCheckAllInputsExcept(e) {
@@ -633,25 +633,25 @@ class ErrorSummary extends GOVUKFrontendComponent {
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({
+ const n = document.getElementById(t);
+ if (!n) return !1;
+ const s = this.getAssociatedLegendOrLabel(n);
+ return !!s && (s.scrollIntoView(), n.focus({
preventScroll: !0
}), !0)
}
getAssociatedLegendOrLabel(e) {
var t;
- const s = e.closest("fieldset");
- if (s) {
- const t = s.getElementsByTagName("legend");
+ const n = e.closest("fieldset");
+ if (n) {
+ const t = n.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,
+ const n = t[0];
+ if (e instanceof HTMLInputElement && ("checkbox" === e.type || "radio" === e.type)) return n;
+ const s = n.getBoundingClientRect().top,
i = e.getBoundingClientRect();
if (i.height && window.innerHeight) {
- if (i.top + i.height - n < window.innerHeight / 2) return s
+ if (i.top + i.height - s < window.innerHeight / 2) return n
}
}
}
@@ -674,16 +674,16 @@ class ExitThisPage extends GOVUKFrontendComponent {
element: e,
identifier: "Root element (`$module`)"
});
- const s = e.querySelector(".govuk-exit-this-page__button");
- if (!(s instanceof HTMLAnchorElement)) throw new ElementError({
+ const n = e.querySelector(".govuk-exit-this-page__button");
+ if (!(n instanceof HTMLAnchorElement)) throw new ElementError({
componentName: "Exit this page",
- element: s,
+ element: n,
expectedType: "HTMLAnchorElement",
identifier: "Button (`.govuk-exit-this-page__button`)"
});
- 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))
+ this.config = mergeConfigs(ExitThisPage.defaults, t, normaliseDataset(ExitThisPage, e.dataset)), this.i18n = new I18n(this.config.i18n), this.$module = e, this.$button = n;
+ const s = document.querySelector(".govuk-js-exit-this-page-skiplink");
+ s instanceof HTMLAnchorElement && (this.$skiplinkButton = s), 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)
@@ -754,18 +754,18 @@ class Header extends GOVUKFrontendComponent {
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({
+ const n = t.getAttribute("aria-controls");
+ if (!n) throw new ElementError({
componentName: "Header",
identifier: 'Navigation button (`<button class="govuk-js-header-toggle">`) attribute (`aria-controls`)'
});
- const n = document.getElementById(s);
- if (!n) throw new ElementError({
+ const s = document.getElementById(n);
+ if (!s) throw new ElementError({
componentName: "Header",
- element: n,
- identifier: `Navigation (\`<ul id="${s}">\`)`
+ element: s,
+ identifier: `Navigation (\`<ul id="${n}">\`)`
});
- this.$menu = n, this.$menuButton = t, this.setupResponsiveChecks(), this.$menuButton.addEventListener("click", (() => this.handleMenuButtonClick()))
+ this.$menu = s, this.$menuButton = t, this.setupResponsiveChecks(), this.$menuButton.addEventListener("click", (() => this.handleMenuButtonClick()))
}
setupResponsiveChecks() {
const e = getBreakpoint("desktop");
@@ -809,23 +809,23 @@ class PasswordInput extends GOVUKFrontendComponent {
element: e,
identifier: "Root element (`$module`)"
});
- const s = e.querySelector(".govuk-js-password-input-input");
- if (!(s instanceof HTMLInputElement)) throw new ElementError({
+ const n = e.querySelector(".govuk-js-password-input-input");
+ if (!(n instanceof HTMLInputElement)) throw new ElementError({
componentName: "Password input",
- element: s,
+ element: n,
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({
+ if ("password" !== n.type) throw new ElementError("Password input: Form field (`.govuk-js-password-input-input`) must be of type `password`.");
+ const s = e.querySelector(".govuk-js-password-input-toggle");
+ if (!(s instanceof HTMLButtonElement)) throw new ElementError({
componentName: "Password input",
- element: n,
+ element: s,
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, {
+ if ("button" !== s.type) throw new ElementError("Password input: Button (`.govuk-js-password-input-toggle`) must be of type `button`.");
+ this.$module = e, this.$input = n, this.$showHideButton = s, 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");
@@ -846,9 +846,9 @@ class PasswordInput extends GOVUKFrontendComponent {
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`)
+ n = t ? "show" : "hide",
+ s = t ? "passwordHidden" : "passwordShown";
+ this.$showHideButton.innerText = this.i18n.t(`${n}Password`), this.$showHideButton.setAttribute("aria-label", this.i18n.t(`${n}PasswordAriaLabel`)), this.$screenReaderStatusMessage.innerText = this.i18n.t(`${s}Announcement`)
}
}
PasswordInput.moduleName = "govuk-password-input", PasswordInput.defaults = Object.freeze({
@@ -896,20 +896,20 @@ class Radios extends GOVUKFrontendComponent {
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 n = document.getElementById(t);
+ if (null != n && n.classList.contains("govuk-radios__conditional")) {
const t = e.checked;
- e.setAttribute("aria-expanded", t.toString()), s.classList.toggle("govuk-radios__conditional--hidden", !t)
+ e.setAttribute("aria-expanded", t.toString()), n.classList.toggle("govuk-radios__conditional--hidden", !t)
}
}
handleClick(e) {
const t = e.target;
if (!(t instanceof HTMLInputElement) || "radio" !== t.type) return;
- const s = document.querySelectorAll('input[type="radio"][aria-controls]'),
- n = t.form,
+ const n = document.querySelectorAll('input[type="radio"][aria-controls]'),
+ s = t.form,
i = t.name;
- s.forEach((e => {
- const t = e.form === n;
+ n.forEach((e => {
+ const t = e.form === s;
e.name === i && t && this.syncConditionalRevealWithInputState(e)
}))
}
@@ -925,17 +925,17 @@ class SkipLink extends GOVUKFrontendComponent {
identifier: "Root element (`$module`)"
});
this.$module = e;
- const s = this.$module.hash,
- n = null != (t = this.$module.getAttribute("href")) ? t : "";
+ const n = this.$module.hash,
+ s = null != (t = this.$module.getAttribute("href")) ? t : "";
let i;
try {
i = new window.URL(this.$module.href)
} catch (a) {
- throw new ElementError(`Skip link: Target link (\`href="${n}"\`) is invalid`)
+ throw new ElementError(`Skip link: Target link (\`href="${s}"\`) is invalid`)
}
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 o = getFragmentFromUrl(n);
+ if (!o) throw new ElementError(`Skip link: Target link (\`href="${s}"\`) has no hash fragment`);
const r = document.getElementById(o);
if (!r) throw new ElementError({
componentName: "Skip link",
@@ -966,17 +966,17 @@ class Tabs extends GOVUKFrontendComponent {
identifier: 'Links (`<a class="govuk-tabs__tab">`)'
});
this.$module = e, this.$tabs = t, this.boundTabClick = this.onTabClick.bind(this), this.boundTabKeydown = this.onTabKeydown.bind(this), this.boundOnHashChange = this.onHashChange.bind(this);
- const s = this.$module.querySelector(".govuk-tabs__list"),
- n = this.$module.querySelectorAll("li.govuk-tabs__list-item");
- if (!s) throw new ElementError({
+ const n = this.$module.querySelector(".govuk-tabs__list"),
+ s = this.$module.querySelectorAll("li.govuk-tabs__list-item");
+ if (!n) throw new ElementError({
componentName: "Tabs",
identifier: 'List (`<ul class="govuk-tabs__list">`)'
});
- if (!n.length) throw new ElementError({
+ if (!s.length) throw new ElementError({
componentName: "Tabs",
identifier: 'List items (`<li class="govuk-tabs__list-item">`)'
});
- this.$tabList = s, this.$tabListItems = n, this.setupResponsiveChecks()
+ this.$tabList = n, this.$tabListItems = s, this.setupResponsiveChecks()
}
setupResponsiveChecks() {
const e = getBreakpoint("tablet");
@@ -1012,8 +1012,8 @@ class Tabs extends GOVUKFrontendComponent {
t = this.getTab(e);
if (!t) return;
if (this.changingHash) return void(this.changingHash = !1);
- const s = this.getCurrentTab();
- s && (this.hideTab(s), this.showTab(t), t.focus())
+ const n = this.getCurrentTab();
+ n && (this.hideTab(n), this.showTab(t), t.focus())
}
hideTab(e) {
this.unhighlightTab(e), this.hidePanel(e)
@@ -1028,8 +1028,8 @@ class Tabs extends GOVUKFrontendComponent {
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))
+ const n = this.getPanel(e);
+ n && (n.setAttribute("role", "tabpanel"), n.setAttribute("aria-labelledby", e.id), n.classList.add(this.jsHiddenClass))
}
unsetAttributes(e) {
e.removeAttribute("id"), e.removeAttribute("role"), e.removeAttribute("aria-controls"), e.removeAttribute("aria-selected"), e.removeAttribute("tabindex");
@@ -1038,14 +1038,14 @@ class Tabs extends GOVUKFrontendComponent {
}
onTabClick(e) {
const t = this.getCurrentTab(),
- s = e.currentTarget;
- t && s instanceof HTMLAnchorElement && (e.preventDefault(), this.hideTab(t), this.showTab(s), this.createHistoryEntry(s))
+ n = e.currentTarget;
+ t && n instanceof HTMLAnchorElement && (e.preventDefault(), this.hideTab(t), this.showTab(n), this.createHistoryEntry(n))
}
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
+ const n = t.id;
+ t.id = "", this.changingHash = !0, window.location.hash = n, t.id = n
}
onTabKeydown(e) {
switch (e.key) {
@@ -1067,16 +1067,16 @@ class Tabs extends GOVUKFrontendComponent {
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))
+ const n = t.querySelector("a.govuk-tabs__tab");
+ n && (this.hideTab(e), this.showTab(n), n.focus(), this.createHistoryEntry(n))
}
activatePreviousTab() {
const e = this.getCurrentTab();
if (null == e || !e.parentElement) return;
const t = e.parentElement.previousElementSibling;
if (!t) return;
- const s = t.querySelector("a.govuk-tabs__tab");
- s && (this.hideTab(e), this.showTab(s), s.focus(), this.createHistoryEntry(s))
+ const n = t.querySelector("a.govuk-tabs__tab");
+ n && (this.hideTab(e), this.showTab(n), n.focus(), this.createHistoryEntry(n))
}
getPanel(e) {
const t = getFragmentFromUrl(e.href);
@@ -1104,7 +1104,7 @@ class Tabs extends GOVUKFrontendComponent {
function initAll(e) {
var t;
if (e = void 0 !== e ? e : {}, !isSupported()) return void console.log(new SupportError);
- const s = [
+ const n = [
[Accordion, e.accordion],
[Button, e.button],
[CharacterCount, e.characterCount],
@@ -1118,17 +1118,22 @@ function initAll(e) {
[SkipLink],
[Tabs]
],
- n = null != (t = e.scope) ? t : document;
- s.forEach((([e, t]) => {
- n.querySelectorAll(`[data-module="${e.moduleName}"]`).forEach((s => {
- try {
- "defaults" in e ? new e(s, t) : new e(s)
- } catch (n) {
- console.log(n)
- }
- }))
+ s = null != (t = e.scope) ? t : document;
+ n.forEach((([e, t]) => {
+ createAll(e, t, s)
}))
}
+
+function createAll(e, t, n = document) {
+ const s = n.querySelectorAll(`[data-module="${e.moduleName}"]`);
+ return Array.from(s).map((n => {
+ try {
+ return "defaults" in e && void 0 !== t ? new e(n, t) : new e(n)
+ } catch (s) {
+ return console.log(s), null
+ }
+ })).filter(Boolean)
+}
Tabs.moduleName = "govuk-tabs";
export {
Accordion,
@@ -1143,6 +1148,7 @@ export {
Radios,
SkipLink,
Tabs,
+ createAll,
initAll,
version
-}; //# sourceMappingURL=govuk-frontend-5.3.1.min.js.map
\ No newline at end of file
+}; //# sourceMappingURL=govuk-frontend-5.4.0.min.js.map
\ No newline at end of file
Action run for cf861ab |
Stylesheets changes to GitHub releasediff --git a/dist/govuk-frontend-5.3.1.min.css b/dist/govuk-frontend-5.4.0.min.css
index e58c0850b..0ef389ae2 100644
--- a/dist/govuk-frontend-5.3.1.min.css
+++ b/dist/govuk-frontend-5.4.0.min.css
@@ -1,7 +1,7 @@
@charset "UTF-8";
:root {
- --govuk-frontend-version: "5.3.1";
+ --govuk-frontend-version: "5.4.0";
--govuk-frontend-breakpoint-mobile: 20rem;
--govuk-frontend-breakpoint-tablet: 40.0625rem;
--govuk-frontend-breakpoint-desktop: 48.0625rem
@@ -3171,18 +3171,21 @@ screen and (forced-colors:active) {
}
.govuk-error-summary__body p {
- margin-top: 0;
- margin-bottom: 15px
+ margin-bottom: 0
+}
+
+.govuk-error-summary__body>*+* {
+ margin-top: 15px
}
@media (min-width:40.0625em) {
- .govuk-error-summary__body p {
- margin-bottom: 20px
+ .govuk-error-summary__body>*+* {
+ margin-top: 20px
}
}
-.govuk-error-summary__list {
- margin-top: 0;
+.govuk-error-summary__list,
+.govuk-error-summary__list li:last-child {
margin-bottom: 0
}
@@ -7585,6 +7588,10 @@ screen and (-ms-high-contrast:active) {
font-weight: 700 !important
}
+.govuk-\!-font-tabular-numbers {
+ font-variant-numeric: tabular-nums !important
+}
+
.govuk-\!-width-full,
.govuk-\!-width-three-quarters {
width: 100% !important
@@ -7636,4 +7643,4 @@ screen and (-ms-high-contrast:active) {
}
}
-/*# sourceMappingURL=govuk-frontend-5.3.1.min.css.map */
\ No newline at end of file
+/*# sourceMappingURL=govuk-frontend-5.4.0.min.css.map */
\ No newline at end of file
Action run for cf861ab |
Other changes to GitHub releasediff --git a/dist/VERSION.txt b/dist/VERSION.txt
index c7cb1311a..8a30e8f94 100644
--- a/dist/VERSION.txt
+++ b/dist/VERSION.txt
@@ -1 +1 @@
-5.3.1
+5.4.0
Action run for cf861ab |
📋 StatsFile sizes
Modules
View stats and visualisations on the review app Action run for cf861ab |
patrickpatrickpatrick
force-pushed
the
release-5.4.0
branch
from
May 17, 2024 10:37
efc192e
to
cf861ab
Compare
romaricpascal
approved these changes
May 17, 2024
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
To install this version with npm, run
npm install [email protected]
. You can also find more information about how to stay up to date in our documentation.This release includes new features to help you include only the components your service uses. Doing this can help reduce the size of the JavaScript and CSS files sent to users, improving their experience.
New features
Create individual components with
createAll
We've added a new
createAll
function that lets you initialise specific components in the same way thatinitAll
does.The
createAll
function will:data-module
attributeYou can also pass a config object and a scope within which to search for elements.
You can find out more about how to use the
createAll
function in our documentation.This change was introduced in pull request #4975: Add
createAll
function to initialise individual components.Use tabular numbers easily with
govuk-!-font-tabular-numbers
We've added a new override class for tabular number styling:
govuk-!-font-tabular-numbers
.Using tabular numbers can make it easier for users to read numbers intended for comparison to one another, or for numbers that dynamically update.
It was previously only possible to use tabular numbers by using the
govuk-font-tabular-numbers
Sass mixin.This change was introduced in pull request #4973: Add override class for tabular numbers.
Deprecated features
Importing layers using
all
filesYou'll see a warning when compiling your Sass if you import any of our layers using the
all
file. Importing using theall
files is deprecated, and we’ll remove them in the next major release.Update your import statements to refer to the
index
file for each layer rather thanall
:You do not need
/index
at the end of each import path if you’re using Dart Sass, LibSass 3.6.0 or higher, or Ruby Sass 3.6.0 or higher.This change was introduced in pull request #4955: Rename
all
files toindex
for our Sass entry points.Fixes
We've made fixes to GOV.UK Frontend in the following pull requests:
errorMessage
argument for the password input component - thanks to Tim South for contributing this changegovuk-frontend
errorList
is provided