katalyst-govuk-formbuilder 1.18.0 → 1.19.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/app/assets/builds/katalyst/govuk/formbuilder.css +13 -5
- data/app/assets/builds/katalyst/govuk/formbuilder.js +4 -1
- data/app/assets/builds/katalyst/govuk/formbuilder.min.js +7 -7
- data/lib/katalyst/govuk/formbuilder/builder.rb +59 -25
- data/node_modules/govuk-frontend/dist/govuk/components/header/_index.scss +16 -5
- data/node_modules/govuk-frontend/dist/govuk/core/_govuk-frontend-properties.scss +1 -1
- data/node_modules/govuk-frontend/dist/govuk/helpers/_colour.scss +11 -0
- data/node_modules/govuk-frontend/dist/govuk/helpers/_focused.scss +14 -4
- data/node_modules/govuk-frontend/dist/govuk/helpers/_typography.scss +1 -1
- data/node_modules/govuk-frontend/dist/govuk/settings/_colours-organisations.scss +0 -9
- data/node_modules/govuk-frontend/dist/govuk/tools/_rebrand.scss +3 -3
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 42d43b53184ef918be025f8391885c3602860a7e7bd1799570bc755af31ad0f5
|
4
|
+
data.tar.gz: d2acf23780969e42b7098415579b99860730b6d53ee28d0f4583f62895e5a3bd
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 214c9b0f9231bf465de56e53aaabfe3d57241c3fd6b8e28205651881fc489d1d68daeaa47ab27bb763c2920fa0232ba30565670e13066041347748c92e9cb351
|
7
|
+
data.tar.gz: 4677462887210510eaaa725c17ba4eaae7d785d95a5a549509bdbcd33b9861d8ad0170dd4c973ce79b5e99aac857e9c01ad626b952784a7e227873e831054048
|
@@ -47,7 +47,7 @@
|
|
47
47
|
|
48
48
|
|
49
49
|
:root {
|
50
|
-
--govuk-frontend-version: "5.10.
|
50
|
+
--govuk-frontend-version: "5.10.2";
|
51
51
|
--govuk-frontend-breakpoint-mobile: 20rem;
|
52
52
|
--govuk-frontend-breakpoint-tablet: 40.0625rem;
|
53
53
|
--govuk-frontend-breakpoint-desktop: 48.0625rem;
|
@@ -80,8 +80,12 @@
|
|
80
80
|
background-color: #ffdd00;
|
81
81
|
box-shadow: 0 -2px #ffdd00, 0 4px #0b0c0c;
|
82
82
|
text-decoration: none;
|
83
|
-
|
84
|
-
|
83
|
+
}
|
84
|
+
@supports not (text-wrap: balance) {
|
85
|
+
.govuk-link:focus {
|
86
|
+
-webkit-box-decoration-break: clone;
|
87
|
+
box-decoration-break: clone;
|
88
|
+
}
|
85
89
|
}
|
86
90
|
.govuk-link:link {
|
87
91
|
color: #1d70b8;
|
@@ -2225,8 +2229,12 @@
|
|
2225
2229
|
background-color: #ffdd00;
|
2226
2230
|
box-shadow: 0 -2px #ffdd00, 0 4px #0b0c0c;
|
2227
2231
|
text-decoration: none;
|
2228
|
-
|
2229
|
-
|
2232
|
+
}
|
2233
|
+
@supports not (text-wrap: balance) {
|
2234
|
+
.govuk-error-summary__list a:focus {
|
2235
|
+
-webkit-box-decoration-break: clone;
|
2236
|
+
box-decoration-break: clone;
|
2237
|
+
}
|
2230
2238
|
}
|
2231
2239
|
.govuk-error-summary__list a:link, .govuk-error-summary__list a:visited {
|
2232
2240
|
color: #d4351c;
|
@@ -623,6 +623,7 @@ class CharacterCount extends ConfigurableComponent {
|
|
623
623
|
identifier: `Count message (\`id="${textareaDescriptionId}"\`)`
|
624
624
|
});
|
625
625
|
}
|
626
|
+
this.$errorMessage = this.$root.querySelector('.govuk-error-message');
|
626
627
|
if (`${$textareaDescription.textContent}`.match(/^\s*$/)) {
|
627
628
|
$textareaDescription.textContent = this.i18n.t('textareaDescription', {
|
628
629
|
count: this.maxLength
|
@@ -681,7 +682,9 @@ class CharacterCount extends ConfigurableComponent {
|
|
681
682
|
const remainingNumber = this.maxLength - this.count(this.$textarea.value);
|
682
683
|
const isError = remainingNumber < 0;
|
683
684
|
this.$visibleCountMessage.classList.toggle('govuk-character-count__message--disabled', !this.isOverThreshold());
|
684
|
-
this.$
|
685
|
+
if (!this.$errorMessage) {
|
686
|
+
this.$textarea.classList.toggle('govuk-textarea--error', isError);
|
687
|
+
}
|
685
688
|
this.$visibleCountMessage.classList.toggle('govuk-error-message', isError);
|
686
689
|
this.$visibleCountMessage.classList.toggle('govuk-hint', !isError);
|
687
690
|
this.$visibleCountMessage.textContent = this.getCountMessage();
|
@@ -1,11 +1,11 @@
|
|
1
|
-
function e(e=document.body){return!!e&&e.classList.contains("govuk-frontend-supported")}function t(e){return!!e&&"object"==typeof e&&!function(e){return Array.isArray(e)}(e)}function n(e,t){return`${e.moduleName}: ${t}`}class o extends Error{constructor(...e){super(...e),this.name="GOVUKFrontendError"}}class s extends o{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 i extends o{constructor(...e){super(...e),this.name="ConfigError"}}class r extends o{constructor(e){let t="string"==typeof e?e:"";if("object"==typeof e){const{component:o,identifier:s,element:i,expectedType:r}=e;t=s,t+=i?` is not of type ${null!=r?r:"HTMLElement"}`:" not found",t=n(o,t)}super(t),this.name="ElementError"}}class a extends o{constructor(e){super("string"==typeof e?e:n(e,"Root element (`$root`) already initialised")),this.name="InitError"}}class u{get $root(){return this._$root}constructor(e){this._$root=void 0;const t=this.constructor;if("string"!=typeof t.moduleName)throw new a("`moduleName` not defined in component");if(!(e instanceof t.elementType))throw new r({element:e,component:t,identifier:"Root element (`$root`)",expectedType:t.elementType.name});this._$root=e,t.checkSupport(),this.checkInitialised();const n=t.moduleName;this.$root.setAttribute(`data-${n}-init`,"")}checkInitialised(){const e=this.constructor,t=e.moduleName;if(t&&function(e,t){return e instanceof HTMLElement&&e.hasAttribute(`data-${t}-init`)}(this.$root,t))throw new a(e)}static checkSupport(){if(!e())throw new s}}u.elementType=HTMLElement;const c=Symbol.for("configOverride");class l extends u{[c](e){return{}}get config(){return this._config}constructor(e,o){super(e),this._config=void 0;const s=this.constructor;if(!t(s.defaults))throw new i(n(s,"Config passed as parameter into constructor but no defaults defined"));const r=function(e,o){if(!t(e.schema))throw new i(n(e,"Config passed as parameter into constructor but no schema defined"));const s={},r=Object.entries(e.schema.properties);for(const t of r){const[n,i]=t,r=n.toString();r in o&&(s[r]=h(o[r],i)),"object"===(null==i?void 0:i.type)&&(s[r]=p(e.schema,o,n))}return s}(s,this._$root.dataset);this._config=d(s.defaults,null!=o?o:{},this[c](r),r)}}function h(e,t){const n=e?e.trim():"";let o,s=null==t?void 0:t.type;switch(s||(["true","false"].includes(n)&&(s="boolean"),n.length>0&&isFinite(Number(n))&&(s="number")),s){case"boolean":o="true"===n;break;case"number":o=Number(n);break;default:o=e}return o}function d(...e){const n={};for(const o of e)for(const e of Object.keys(o)){const s=n[e],i=o[e];t(s)&&t(i)?n[e]=d(s,i):n[e]=i}return n}function p(e,n,o){const s=e.properties[o];if("object"!==(null==s?void 0:s.type))return;const i={[o]:{}};for(const[e,s]of Object.entries(n)){let n=i;const r=e.split(".");for(const[i,a]of r.entries())t(n)&&(i<r.length-1?(t(n[a])||(n[a]={}),n=n[a]):e!==o&&(n[a]=h(s)))}return i[o]}class m{constructor(e={},t={}){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 n=this.translations[e];if("number"==typeof(null==t?void 0:t.count)&&"object"==typeof n){const o=n[this.getPluralSuffix(e,t.count)];o&&(n=o)}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(n,t)}return n}return e}replacePlaceholders(e,t){const n=Intl.NumberFormat.supportedLocalesOf(this.locale).length?new Intl.NumberFormat(this.locale):void 0;return e.replace(/%{(.\S+)}/g,
|
1
|
+
function e(e=document.body){return!!e&&e.classList.contains("govuk-frontend-supported")}function t(e){return!!e&&"object"==typeof e&&!function(e){return Array.isArray(e)}(e)}function n(e,t){return`${e.moduleName}: ${t}`}class o extends Error{constructor(...e){super(...e),this.name="GOVUKFrontendError"}}class s extends o{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 i extends o{constructor(...e){super(...e),this.name="ConfigError"}}class r extends o{constructor(e){let t="string"==typeof e?e:"";if("object"==typeof e){const{component:o,identifier:s,element:i,expectedType:r}=e;t=s,t+=i?` is not of type ${null!=r?r:"HTMLElement"}`:" not found",t=n(o,t)}super(t),this.name="ElementError"}}class a extends o{constructor(e){super("string"==typeof e?e:n(e,"Root element (`$root`) already initialised")),this.name="InitError"}}class u{get $root(){return this._$root}constructor(e){this._$root=void 0;const t=this.constructor;if("string"!=typeof t.moduleName)throw new a("`moduleName` not defined in component");if(!(e instanceof t.elementType))throw new r({element:e,component:t,identifier:"Root element (`$root`)",expectedType:t.elementType.name});this._$root=e,t.checkSupport(),this.checkInitialised();const n=t.moduleName;this.$root.setAttribute(`data-${n}-init`,"")}checkInitialised(){const e=this.constructor,t=e.moduleName;if(t&&function(e,t){return e instanceof HTMLElement&&e.hasAttribute(`data-${t}-init`)}(this.$root,t))throw new a(e)}static checkSupport(){if(!e())throw new s}}u.elementType=HTMLElement;const c=Symbol.for("configOverride");class l extends u{[c](e){return{}}get config(){return this._config}constructor(e,o){super(e),this._config=void 0;const s=this.constructor;if(!t(s.defaults))throw new i(n(s,"Config passed as parameter into constructor but no defaults defined"));const r=function(e,o){if(!t(e.schema))throw new i(n(e,"Config passed as parameter into constructor but no schema defined"));const s={},r=Object.entries(e.schema.properties);for(const t of r){const[n,i]=t,r=n.toString();r in o&&(s[r]=h(o[r],i)),"object"===(null==i?void 0:i.type)&&(s[r]=p(e.schema,o,n))}return s}(s,this._$root.dataset);this._config=d(s.defaults,null!=o?o:{},this[c](r),r)}}function h(e,t){const n=e?e.trim():"";let o,s=null==t?void 0:t.type;switch(s||(["true","false"].includes(n)&&(s="boolean"),n.length>0&&isFinite(Number(n))&&(s="number")),s){case"boolean":o="true"===n;break;case"number":o=Number(n);break;default:o=e}return o}function d(...e){const n={};for(const o of e)for(const e of Object.keys(o)){const s=n[e],i=o[e];t(s)&&t(i)?n[e]=d(s,i):n[e]=i}return n}function p(e,n,o){const s=e.properties[o];if("object"!==(null==s?void 0:s.type))return;const i={[o]:{}};for(const[e,s]of Object.entries(n)){let n=i;const r=e.split(".");for(const[i,a]of r.entries())t(n)&&(i<r.length-1?(t(n[a])||(n[a]={}),n=n[a]):e!==o&&(n[a]=h(s)))}return i[o]}class m{constructor(e={},t={}){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 n=this.translations[e];if("number"==typeof(null==t?void 0:t.count)&&"object"==typeof n){const o=n[this.getPluralSuffix(e,t.count)];o&&(n=o)}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(n,t)}return n}return e}replacePlaceholders(e,t){const n=Intl.NumberFormat.supportedLocalesOf(this.locale).length?new Intl.NumberFormat(this.locale):void 0;return e.replace(/%{(.\S+)}/g,function(e,o){if(Object.prototype.hasOwnProperty.call(t,o)){const e=t[o];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`)})}hasIntlPluralRulesSupport(){return Boolean("PluralRules"in window.Intl&&Intl.PluralRules.supportedLocalesOf(this.locale).length)}getPluralSuffix(e,t){if(t=Number(t),!isFinite(t))return"other";const n=this.translations[e],o=this.hasIntlPluralRulesSupport()?new Intl.PluralRules(this.locale).select(t):this.selectPluralFormUsingFallbackRules(t);if("object"==typeof n){if(o in n)return o;if("other"in n)return console.warn(`i18n: Missing plural form ".${o}" for "${this.locale}" locale. Falling back to ".other".`),"other"}throw new Error(`i18n: Plural form ".other" is required for "${this.locale}" locale`)}selectPluralFormUsingFallbackRules(e){e=Math.abs(Math.floor(e));const t=this.getPluralRulesForLocale();return t?m.pluralRules[t](e):"other"}getPluralRulesForLocale(){const e=this.locale.split("-")[0];for(const t in m.pluralRulesMap){const n=m.pluralRulesMap[t];if(n.includes(this.locale)||n.includes(e))return t}}}m.pluralRulesMap={arabic:["ar"],chinese:["my","zh","id","ja","jv","ko","ms","th","vi"],french:["hy","bn","fr","gu","hi","fa","pa","zu"],german:["af","sq","az","eu","bg","ca","da","nl","en","et","fi","ka","de","el","hu","lb","no","so","sw","sv","ta","te","tr","ur"],irish:["ga"],russian:["ru","uk"],scottish:["gd"],spanish:["pt-PT","it","es"],welsh:["cy"]},m.pluralRules={arabic:e=>0===e?"zero":1===e?"one":2===e?"two":e%100>=3&&e%100<=10?"few":e%100>=11&&e%100<=99?"many":"other",chinese:()=>"other",french:e=>0===e||1===e?"one":"other",german:e=>1===e?"one":"other",irish:e=>1===e?"one":2===e?"two":e>=3&&e<=6?"few":e>=7&&e<=10?"many":"other",russian(e){const t=e%100,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"};
|
2
2
|
/**
|
3
3
|
* JavaScript enhancements for the Button component
|
4
4
|
*
|
5
5
|
* @preserve
|
6
6
|
* @augments ConfigurableComponent<ButtonConfig>
|
7
7
|
*/
|
8
|
-
class f extends l{constructor(e,t={}){super(e,t),this.debounceFormSubmitTimer=null,this.$root.addEventListener("keydown",
|
8
|
+
class f extends l{constructor(e,t={}){super(e,t),this.debounceFormSubmitTimer=null,this.$root.addEventListener("keydown",e=>this.handleKeyDown(e)),this.$root.addEventListener("click",e=>this.debounce(e))}handleKeyDown(e){const t=e.target;" "===e.key&&t instanceof HTMLElement&&"button"===t.getAttribute("role")&&(e.preventDefault(),t.click())}debounce(e){if(this.config.preventDoubleClick)return this.debounceFormSubmitTimer?(e.preventDefault(),!1):void(this.debounceFormSubmitTimer=window.setTimeout(()=>{this.debounceFormSubmitTimer=null},1e3))}}function g(e,t){const n=e.closest(`[${t}]`);return n?n.getAttribute(t):null}
|
9
9
|
/**
|
10
10
|
* Character count component
|
11
11
|
*
|
@@ -18,13 +18,13 @@ class f extends l{constructor(e,t={}){super(e,t),this.debounceFormSubmitTimer=nu
|
|
18
18
|
*
|
19
19
|
* @preserve
|
20
20
|
* @augments ConfigurableComponent<CharacterCountConfig>
|
21
|
-
*/f.moduleName="govuk-button",f.defaults=Object.freeze({preventDoubleClick:!1}),f.schema=Object.freeze({properties:{preventDoubleClick:{type:"boolean"}}});class v extends l{[c](e){let t={};return("maxwords"in e||"maxlength"in e)&&(t={maxlength:void 0,maxwords:void 0}),t}constructor(e,t={}){var o,s;super(e,t),this.$textarea=void 0,this.$visibleCountMessage=void 0,this.$screenReaderCountMessage=void 0,this.lastInputTimestamp=null,this.lastInputValue="",this.valueChecker=null,this.i18n=void 0,this.maxLength=void 0;const a=this.$root.querySelector(".govuk-js-character-count");if(!(a instanceof HTMLTextAreaElement||a instanceof HTMLInputElement))throw new r({component:v,element:a,expectedType:"HTMLTextareaElement or HTMLInputElement",identifier:"Form field (`.govuk-js-character-count`)"});const u=function(e,t){const n=[];for(const[o,s]of Object.entries(e)){const e=[];if(Array.isArray(s)){for(const{required:n,errorMessage:o}of s)n.every(
|
21
|
+
*/f.moduleName="govuk-button",f.defaults=Object.freeze({preventDoubleClick:!1}),f.schema=Object.freeze({properties:{preventDoubleClick:{type:"boolean"}}});class v extends l{[c](e){let t={};return("maxwords"in e||"maxlength"in e)&&(t={maxlength:void 0,maxwords:void 0}),t}constructor(e,t={}){var o,s;super(e,t),this.$textarea=void 0,this.$visibleCountMessage=void 0,this.$screenReaderCountMessage=void 0,this.lastInputTimestamp=null,this.lastInputValue="",this.valueChecker=null,this.i18n=void 0,this.maxLength=void 0;const a=this.$root.querySelector(".govuk-js-character-count");if(!(a instanceof HTMLTextAreaElement||a instanceof HTMLInputElement))throw new r({component:v,element:a,expectedType:"HTMLTextareaElement or HTMLInputElement",identifier:"Form field (`.govuk-js-character-count`)"});const u=function(e,t){const n=[];for(const[o,s]of Object.entries(e)){const e=[];if(Array.isArray(s)){for(const{required:n,errorMessage:o}of s)n.every(e=>!!t[e])||e.push(o);"anyOf"!==o||s.length-e.length>=1||n.push(...e)}}return n}(v.schema,this.config);if(u[0])throw new i(n(v,u[0]));this.i18n=new m(this.config.i18n,{locale:g(this.$root,"lang")}),this.maxLength=null!=(o=null!=(s=this.config.maxwords)?s:this.config.maxlength)?o:1/0,this.$textarea=a;const c=`${this.$textarea.id}-info`,l=document.getElementById(c);if(!l)throw new r({component:v,element:l,identifier:`Count message (\`id="${c}"\`)`});this.$errorMessage=this.$root.querySelector(".govuk-error-message"),`${l.textContent}`.match(/^\s*$/)&&(l.textContent=this.i18n.t("textareaDescription",{count:this.maxLength})),this.$textarea.insertAdjacentElement("afterend",l);const h=document.createElement("div");h.className="govuk-character-count__sr-status govuk-visually-hidden",h.setAttribute("aria-live","polite"),this.$screenReaderCountMessage=h,l.insertAdjacentElement("afterend",h);const d=document.createElement("div");d.className=l.className,d.classList.add("govuk-character-count__status"),d.setAttribute("aria-hidden","true"),this.$visibleCountMessage=d,l.insertAdjacentElement("afterend",d),l.classList.add("govuk-visually-hidden"),this.$textarea.removeAttribute("maxlength"),this.bindChangeEvents(),window.addEventListener("pageshow",()=>this.updateCountMessage()),this.updateCountMessage()}bindChangeEvents(){this.$textarea.addEventListener("keyup",()=>this.handleKeyUp()),this.$textarea.addEventListener("focus",()=>this.handleFocus()),this.$textarea.addEventListener("blur",()=>this.handleBlur())}handleKeyUp(){this.updateVisibleCountMessage(),this.lastInputTimestamp=Date.now()}handleFocus(){this.valueChecker=window.setInterval(()=>{(!this.lastInputTimestamp||Date.now()-500>=this.lastInputTimestamp)&&this.updateIfValueChanged()},1e3)}handleBlur(){this.valueChecker&&window.clearInterval(this.valueChecker)}updateIfValueChanged(){this.$textarea.value!==this.lastInputValue&&(this.lastInputValue=this.$textarea.value,this.updateCountMessage())}updateCountMessage(){this.updateVisibleCountMessage(),this.updateScreenReaderCountMessage()}updateVisibleCountMessage(){const e=this.maxLength-this.count(this.$textarea.value)<0;this.$visibleCountMessage.classList.toggle("govuk-character-count__message--disabled",!this.isOverThreshold()),this.$errorMessage||this.$textarea.classList.toggle("govuk-textarea--error",e),this.$visibleCountMessage.classList.toggle("govuk-error-message",e),this.$visibleCountMessage.classList.toggle("govuk-hint",!e),this.$visibleCountMessage.textContent=this.getCountMessage()}updateScreenReaderCountMessage(){this.isOverThreshold()?this.$screenReaderCountMessage.removeAttribute("aria-hidden"):this.$screenReaderCountMessage.setAttribute("aria-hidden","true"),this.$screenReaderCountMessage.textContent=this.getCountMessage()}count(e){if(this.config.maxwords){var t;return(null!=(t=e.match(/\S+/g))?t:[]).length}return e.length}getCountMessage(){const e=this.maxLength-this.count(this.$textarea.value),t=this.config.maxwords?"words":"characters";return this.formatCountMessage(e,t)}formatCountMessage(e,t){if(0===e)return this.i18n.t(`${t}AtLimit`);const n=e<0?"OverLimit":"UnderLimit";return this.i18n.t(`${t}${n}`,{count:Math.abs(e)})}isOverThreshold(){if(!this.config.threshold)return!0;const e=this.count(this.$textarea.value);return this.maxLength*this.config.threshold/100<=e}}v.moduleName="govuk-character-count",v.defaults=Object.freeze({threshold:0,i18n:{charactersUnderLimit:{one:"You have %{count} character remaining",other:"You have %{count} characters remaining"},charactersAtLimit:"You have 0 characters remaining",charactersOverLimit:{one:"You have %{count} character too many",other:"You have %{count} characters too many"},wordsUnderLimit:{one:"You have %{count} word remaining",other:"You have %{count} words remaining"},wordsAtLimit:"You have 0 words remaining",wordsOverLimit:{one:"You have %{count} word too many",other:"You have %{count} words too many"},textareaDescription:{other:""}}}),v.schema=Object.freeze({properties:{i18n:{type:"object"},maxwords:{type:"number"},maxlength:{type:"number"},threshold:{type:"number"}},anyOf:[{required:["maxwords"],errorMessage:'Either "maxlength" or "maxwords" must be provided'},{required:["maxlength"],errorMessage:'Either "maxlength" or "maxwords" must be provided'}]});
|
22
22
|
/**
|
23
23
|
* Checkboxes component
|
24
24
|
*
|
25
25
|
* @preserve
|
26
26
|
*/
|
27
|
-
class w extends u{constructor(e){super(e),this.$inputs=void 0;const t=this.$root.querySelectorAll('input[type="checkbox"]');if(!t.length)throw new r({component:w,identifier:'Form inputs (`<input type="checkbox">`)'});this.$inputs=t,this.$inputs.forEach(
|
27
|
+
class w extends u{constructor(e){super(e),this.$inputs=void 0;const t=this.$root.querySelectorAll('input[type="checkbox"]');if(!t.length)throw new r({component:w,identifier:'Form inputs (`<input type="checkbox">`)'});this.$inputs=t,this.$inputs.forEach(e=>{const t=e.getAttribute("data-aria-controls");if(t){if(!document.getElementById(t))throw new r({component:w,identifier:`Conditional reveal (\`id="${t}"\`)`});e.setAttribute("aria-controls",t),e.removeAttribute("data-aria-controls")}}),window.addEventListener("pageshow",()=>this.syncAllConditionalReveals()),this.syncAllConditionalReveals(),this.$root.addEventListener("click",e=>this.handleClick(e))}syncAllConditionalReveals(){this.$inputs.forEach(e=>this.syncConditionalRevealWithInputState(e))}syncConditionalRevealWithInputState(e){const t=e.getAttribute("aria-controls");if(!t)return;const n=document.getElementById(t);if(null!=n&&n.classList.contains("govuk-checkboxes__conditional")){const t=e.checked;e.setAttribute("aria-expanded",t.toString()),n.classList.toggle("govuk-checkboxes__conditional--hidden",!t)}}unCheckAllInputsExcept(e){document.querySelectorAll(`input[type="checkbox"][name="${e.name}"]`).forEach(t=>{e.form===t.form&&t!==e&&(t.checked=!1,this.syncConditionalRevealWithInputState(t))})}unCheckExclusiveInputs(e){document.querySelectorAll(`input[data-behaviour="exclusive"][type="checkbox"][name="${e.name}"]`).forEach(t=>{e.form===t.form&&(t.checked=!1,this.syncConditionalRevealWithInputState(t))})}handleClick(e){const t=e.target;if(!(t instanceof HTMLInputElement)||"checkbox"!==t.type)return;if(t.getAttribute("aria-controls")&&this.syncConditionalRevealWithInputState(t),!t.checked)return;"exclusive"===t.getAttribute("data-behaviour")?this.unCheckAllInputsExcept(t):this.unCheckExclusiveInputs(t)}}w.moduleName="govuk-checkboxes";
|
28
28
|
/**
|
29
29
|
* Error summary component
|
30
30
|
*
|
@@ -34,17 +34,17 @@ class w extends u{constructor(e){super(e),this.$inputs=void 0;const t=this.$root
|
|
34
34
|
* @preserve
|
35
35
|
* @augments ConfigurableComponent<ErrorSummaryConfig>
|
36
36
|
*/
|
37
|
-
class b extends l{constructor(e,t={}){super(e,t),this.config.disableAutoFocus||function(e,t={}){var n;const o=e.getAttribute("tabindex");function s(){var n;null==(n=t.onBlur)||n.call(e),o||e.removeAttribute("tabindex")}o||e.setAttribute("tabindex","-1"),e.addEventListener("focus",
|
37
|
+
class b extends l{constructor(e,t={}){super(e,t),this.config.disableAutoFocus||function(e,t={}){var n;const o=e.getAttribute("tabindex");function s(){var n;null==(n=t.onBlur)||n.call(e),o||e.removeAttribute("tabindex")}o||e.setAttribute("tabindex","-1"),e.addEventListener("focus",function(){e.addEventListener("blur",s,{once:!0})},{once:!0}),null==(n=t.onBeforeFocus)||n.call(e),e.focus()}(this.$root),this.$root.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=function(e){if(e.includes("#"))return e.split("#").pop()}(e.href);if(!t)return!1;const n=document.getElementById(t);if(!n)return!1;const o=this.getAssociatedLegendOrLabel(n);return!!o&&(o.scrollIntoView(),n.focus({preventScroll:!0}),!0)}getAssociatedLegendOrLabel(e){var t;const n=e.closest("fieldset");if(n){const t=n.getElementsByTagName("legend");if(t.length){const n=t[0];if(e instanceof HTMLInputElement&&("checkbox"===e.type||"radio"===e.type))return n;const o=n.getBoundingClientRect().top,s=e.getBoundingClientRect();if(s.height&&window.innerHeight){if(s.top+s.height-o<window.innerHeight/2)return n}}}return null!=(t=document.querySelector(`label[for='${e.getAttribute("id")}']`))?t:e.closest("label")}}b.moduleName="govuk-error-summary",b.defaults=Object.freeze({disableAutoFocus:!1}),b.schema=Object.freeze({properties:{disableAutoFocus:{type:"boolean"}}});
|
38
38
|
/**
|
39
39
|
* Password input component
|
40
40
|
*
|
41
41
|
* @preserve
|
42
42
|
* @augments ConfigurableComponent<PasswordInputConfig>
|
43
43
|
*/
|
44
|
-
class y extends l{constructor(e,t={}){super(e,t),this.i18n=void 0,this.$input=void 0,this.$showHideButton=void 0,this.$screenReaderStatusMessage=void 0;const n=this.$root.querySelector(".govuk-js-password-input-input");if(!(n instanceof HTMLInputElement))throw new r({component:y,element:n,expectedType:"HTMLInputElement",identifier:"Form field (`.govuk-js-password-input-input`)"});if("password"!==n.type)throw new r("Password input: Form field (`.govuk-js-password-input-input`) must be of type `password`.");const o=this.$root.querySelector(".govuk-js-password-input-toggle");if(!(o instanceof HTMLButtonElement))throw new r({component:y,element:o,expectedType:"HTMLButtonElement",identifier:"Button (`.govuk-js-password-input-toggle`)"});if("button"!==o.type)throw new r("Password input: Button (`.govuk-js-password-input-toggle`) must be of type `button`.");this.$input=n,this.$showHideButton=o,this.i18n=new m(this.config.i18n,{locale:g(this.$root,"lang")}),this.$showHideButton.removeAttribute("hidden");const s=document.createElement("div");s.className="govuk-password-input__sr-status govuk-visually-hidden",s.setAttribute("aria-live","polite"),this.$screenReaderStatusMessage=s,this.$input.insertAdjacentElement("afterend",s),this.$showHideButton.addEventListener("click",this.toggle.bind(this)),this.$input.form&&this.$input.form.addEventListener("submit",(
|
44
|
+
class y extends l{constructor(e,t={}){super(e,t),this.i18n=void 0,this.$input=void 0,this.$showHideButton=void 0,this.$screenReaderStatusMessage=void 0;const n=this.$root.querySelector(".govuk-js-password-input-input");if(!(n instanceof HTMLInputElement))throw new r({component:y,element:n,expectedType:"HTMLInputElement",identifier:"Form field (`.govuk-js-password-input-input`)"});if("password"!==n.type)throw new r("Password input: Form field (`.govuk-js-password-input-input`) must be of type `password`.");const o=this.$root.querySelector(".govuk-js-password-input-toggle");if(!(o instanceof HTMLButtonElement))throw new r({component:y,element:o,expectedType:"HTMLButtonElement",identifier:"Button (`.govuk-js-password-input-toggle`)"});if("button"!==o.type)throw new r("Password input: Button (`.govuk-js-password-input-toggle`) must be of type `button`.");this.$input=n,this.$showHideButton=o,this.i18n=new m(this.config.i18n,{locale:g(this.$root,"lang")}),this.$showHideButton.removeAttribute("hidden");const s=document.createElement("div");s.className="govuk-password-input__sr-status govuk-visually-hidden",s.setAttribute("aria-live","polite"),this.$screenReaderStatusMessage=s,this.$input.insertAdjacentElement("afterend",s),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,n=t?"show":"hide",o=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(`${o}Announcement`)}}y.moduleName="govuk-password-input",y.defaults=Object.freeze({i18n:{showPassword:"Show",hidePassword:"Hide",showPasswordAriaLabel:"Show password",hidePasswordAriaLabel:"Hide password",passwordShownAnnouncement:"Your password is visible",passwordHiddenAnnouncement:"Your password is hidden"}}),y.schema=Object.freeze({properties:{i18n:{type:"object"}}});
|
45
45
|
/**
|
46
46
|
* Radios component
|
47
47
|
*
|
48
48
|
* @preserve
|
49
49
|
*/
|
50
|
-
class $ extends u{constructor(e){super(e),this.$inputs=void 0;const t=this.$root.querySelectorAll('input[type="radio"]');if(!t.length)throw new r({component:$,identifier:'Form inputs (`<input type="radio">`)'});this.$inputs=t,this.$inputs.forEach(
|
50
|
+
class $ extends u{constructor(e){super(e),this.$inputs=void 0;const t=this.$root.querySelectorAll('input[type="radio"]');if(!t.length)throw new r({component:$,identifier:'Form inputs (`<input type="radio">`)'});this.$inputs=t,this.$inputs.forEach(e=>{const t=e.getAttribute("data-aria-controls");if(t){if(!document.getElementById(t))throw new r({component:$,identifier:`Conditional reveal (\`id="${t}"\`)`});e.setAttribute("aria-controls",t),e.removeAttribute("data-aria-controls")}}),window.addEventListener("pageshow",()=>this.syncAllConditionalReveals()),this.syncAllConditionalReveals(),this.$root.addEventListener("click",e=>this.handleClick(e))}syncAllConditionalReveals(){this.$inputs.forEach(e=>this.syncConditionalRevealWithInputState(e))}syncConditionalRevealWithInputState(e){const t=e.getAttribute("aria-controls");if(!t)return;const n=document.getElementById(t);if(null!=n&&n.classList.contains("govuk-radios__conditional")){const t=e.checked;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 n=document.querySelectorAll('input[type="radio"][aria-controls]'),o=t.form,s=t.name;n.forEach(e=>{const t=e.form===o;e.name===s&&t&&this.syncConditionalRevealWithInputState(e)})}}function x(t){let n;if(t=void 0!==t?t:{},!e())return void console.log(new s);const o=[[f,t.button],[v,t.characterCount],[w],[b,t.errorSummary],[$],[y,t.passwordInput]],i=null!=(n=t.scope)?n:document;o.forEach(([e,t])=>{i.querySelectorAll(`[data-module="${e.moduleName}"]`).forEach(n=>{try{"defaults"in e?new e(n,t):new e(n)}catch(e){console.log(e)}})})}$.moduleName="govuk-radios";export{f as Button,v as CharacterCount,w as Checkboxes,b as ErrorSummary,y as PasswordInput,$ as Radios,x as initAll};
|
@@ -7,6 +7,34 @@ module Katalyst
|
|
7
7
|
extend ActiveSupport::Concern
|
8
8
|
|
9
9
|
included do
|
10
|
+
# Overwrite GOVUK default to set small to true
|
11
|
+
# @see GOVUKDesignSystemFormBuilder::Builder#govuk_collection_radio_buttons
|
12
|
+
def govuk_collection_radio_buttons(attribute_name, collection, value_method, text_method = nil,
|
13
|
+
hint_method = nil, hint: {}, legend: {}, caption: {}, inline: false,
|
14
|
+
small: true, bold_labels: nil,
|
15
|
+
include_hidden: config.default_collection_radio_buttons_include_hidden,
|
16
|
+
form_group: {}, **, &)
|
17
|
+
GOVUKDesignSystemFormBuilder::Elements::Radios::Collection.new(
|
18
|
+
self,
|
19
|
+
object_name,
|
20
|
+
attribute_name,
|
21
|
+
collection,
|
22
|
+
value_method:,
|
23
|
+
text_method:,
|
24
|
+
hint_method:,
|
25
|
+
hint:,
|
26
|
+
legend:,
|
27
|
+
caption:,
|
28
|
+
inline:,
|
29
|
+
small:,
|
30
|
+
bold_labels:,
|
31
|
+
form_group:,
|
32
|
+
include_hidden:,
|
33
|
+
**,
|
34
|
+
&
|
35
|
+
).html
|
36
|
+
end
|
37
|
+
|
10
38
|
# Overwrite GOVUK default to set small to true
|
11
39
|
# @see GOVUKDesignSystemFormBuilder::Builder#govuk_radio_buttons_fieldset
|
12
40
|
def govuk_radio_buttons_fieldset(attribute_name, hint: {}, legend: {}, caption: {}, inline: false,
|
@@ -105,32 +133,27 @@ module Katalyst
|
|
105
133
|
end
|
106
134
|
end
|
107
135
|
|
108
|
-
#
|
136
|
+
# Generates a select for an enum defined in the model.
|
137
|
+
# @see GOVUKDesignSystemFormBuilder::Builder#govuk_collection_select
|
138
|
+
def govuk_enum_select(attribute_name, **, &)
|
139
|
+
govuk_collection_select(attribute_name, enum_values(attribute_name),
|
140
|
+
:itself, enum_labels_for(attribute_name), **, &)
|
141
|
+
end
|
142
|
+
|
143
|
+
# Generates a checkbox fieldset for an enum defined in the model.
|
144
|
+
#
|
145
|
+
# @api internal
|
146
|
+
# @see GOVUKDesignSystemFormBuilder::Builder#govuk_collection_check_boxes
|
147
|
+
def govuk_enum_check_boxes(attribute_name, **, &)
|
148
|
+
govuk_collection_check_boxes(attribute_name, enum_values(attribute_name),
|
149
|
+
:itself, enum_labels_for(attribute_name), **, &)
|
150
|
+
end
|
151
|
+
|
152
|
+
# Generates a radio buttons fieldset for an enum defined in the model.
|
109
153
|
# @see GOVUKDesignSystemFormBuilder::Builder#govuk_collection_radio_buttons
|
110
|
-
def
|
111
|
-
|
112
|
-
|
113
|
-
include_hidden: config.default_collection_radio_buttons_include_hidden,
|
114
|
-
form_group: {}, **, &)
|
115
|
-
GOVUKDesignSystemFormBuilder::Elements::Radios::Collection.new(
|
116
|
-
self,
|
117
|
-
object_name,
|
118
|
-
attribute_name,
|
119
|
-
collection,
|
120
|
-
value_method:,
|
121
|
-
text_method:,
|
122
|
-
hint_method:,
|
123
|
-
hint:,
|
124
|
-
legend:,
|
125
|
-
caption:,
|
126
|
-
inline:,
|
127
|
-
small:,
|
128
|
-
bold_labels:,
|
129
|
-
form_group:,
|
130
|
-
include_hidden:,
|
131
|
-
**,
|
132
|
-
&
|
133
|
-
).html
|
154
|
+
def govuk_enum_radio_buttons(attribute_name, **, &)
|
155
|
+
govuk_collection_radio_buttons(attribute_name, enum_values(attribute_name),
|
156
|
+
:itself, enum_labels_for(attribute_name), **, &)
|
134
157
|
end
|
135
158
|
|
136
159
|
# Generates a pair of +trix-toolbar+ and +trix-editor+ elements with a label, optional hint.
|
@@ -231,6 +254,17 @@ module Katalyst
|
|
231
254
|
def fieldset_context
|
232
255
|
@fieldset_context ||= []
|
233
256
|
end
|
257
|
+
|
258
|
+
private
|
259
|
+
|
260
|
+
def enum_values(attribute_name)
|
261
|
+
object.class.defined_enums[attribute_name.to_s].keys
|
262
|
+
end
|
263
|
+
|
264
|
+
def enum_labels_for(attribute_name)
|
265
|
+
model = object.class
|
266
|
+
->(value) { model.human_attribute_name("#{attribute_name}.#{value}") }
|
267
|
+
end
|
234
268
|
end
|
235
269
|
end
|
236
270
|
end
|
@@ -30,6 +30,16 @@
|
|
30
30
|
color: $govuk-header-text;
|
31
31
|
}
|
32
32
|
|
33
|
+
.govuk-header--with-js-navigation {
|
34
|
+
@include govuk-media-query($until: desktop) {
|
35
|
+
.govuk-header__logo {
|
36
|
+
// Protect the absolute positioned menu button from overlapping with the
|
37
|
+
// logo with right padding using the button's width
|
38
|
+
padding-right: $govuk-header-menu-button-width;
|
39
|
+
}
|
40
|
+
}
|
41
|
+
}
|
42
|
+
|
33
43
|
.govuk-header__container--full-width {
|
34
44
|
padding: 0 govuk-spacing(3);
|
35
45
|
border-color: $govuk-header-border-color;
|
@@ -94,12 +104,17 @@
|
|
94
104
|
@include _govuk-rebrand {
|
95
105
|
margin-right: govuk-px-to-rem(7px); // 1 'dot'
|
96
106
|
margin-bottom: $govuk-header-rebrand-logo-bottom-margin;
|
107
|
+
|
108
|
+
// Remove right-margin if there's no product name
|
109
|
+
&:last-child {
|
110
|
+
margin-right: 0;
|
111
|
+
}
|
97
112
|
}
|
98
113
|
}
|
99
114
|
|
100
115
|
// Colour in the Dot
|
101
116
|
.govuk-logo-dot {
|
102
|
-
fill: #
|
117
|
+
fill: #00ffe0;
|
103
118
|
|
104
119
|
// Override Dot colour when printing
|
105
120
|
@include govuk-media-query($media-type: print) {
|
@@ -279,10 +294,6 @@
|
|
279
294
|
.govuk-header__logo {
|
280
295
|
@include govuk-responsive-margin($govuk-header-vertical-spacing-value, "bottom");
|
281
296
|
|
282
|
-
// Protect the absolute positioned menu button from overlapping with the
|
283
|
-
// logo with right padding using the button's width
|
284
|
-
padding-right: $govuk-header-menu-button-width;
|
285
|
-
|
286
297
|
@include govuk-media-query($from: desktop) {
|
287
298
|
width: 33.33%;
|
288
299
|
padding-right: $govuk-gutter-half;
|
@@ -1,7 +1,7 @@
|
|
1
1
|
:root {
|
2
2
|
// This variable is automatically overwritten during builds and releases.
|
3
3
|
// It doesn't need to be updated manually.
|
4
|
-
--govuk-frontend-version: "5.10.
|
4
|
+
--govuk-frontend-version: "5.10.2";
|
5
5
|
|
6
6
|
// CSS custom property for each breakpoint
|
7
7
|
@each $name, $value in $govuk-breakpoints {
|
@@ -66,6 +66,17 @@
|
|
66
66
|
@error "Unknown organisation `#{$organisation}`";
|
67
67
|
}
|
68
68
|
|
69
|
+
// Output a deprecation warning if the legacy colour palette is being used.
|
70
|
+
// Remove in next major version.
|
71
|
+
$is-legacy: $govuk-colours-organisations == $_govuk-legacy-organisation-colours;
|
72
|
+
@if $is-legacy and _should-warn("legacy-organisation-colours") {
|
73
|
+
@warn _warning-text("legacy-organisation-colours",
|
74
|
+
"We've updated the organisation colour palette. Opt in to the new " +
|
75
|
+
"colours using `$govuk-new-organisation-colours: true`. The old " +
|
76
|
+
"palette is deprecated and we'll remove it in the next major version."
|
77
|
+
);
|
78
|
+
}
|
79
|
+
|
69
80
|
// Output a warning if $websafe is set.
|
70
81
|
@if $websafe and _should-warn("organisation-colour-websafe-param") {
|
71
82
|
@warn _warning-text("organisation-colour-websafe-param",
|
@@ -24,10 +24,20 @@
|
|
24
24
|
// box shadow adds the "underline"
|
25
25
|
text-decoration: none;
|
26
26
|
|
27
|
-
//
|
28
|
-
//
|
29
|
-
|
30
|
-
|
27
|
+
// Fixes an issue in Chromium 108–111 where the box-shadow on the focus state
|
28
|
+
// is missing on links that wrap across multiple lines [1].
|
29
|
+
//
|
30
|
+
// However, text-wrap: balance doesn't play nicely with box-decoration-break:
|
31
|
+
// clone, causing links to re-flow when focused [2]. As text-wrap: balance
|
32
|
+
// wasn't introduced until Chromium 114 we can use it as a way to target
|
33
|
+
// this fix to just 108–111.
|
34
|
+
//
|
35
|
+
// [1]: http://crbug.com/40884971
|
36
|
+
// [2]: https://github.com/alphagov/govuk-frontend/issues/5878
|
37
|
+
@supports not (text-wrap: balance) {
|
38
|
+
-webkit-box-decoration-break: clone;
|
39
|
+
box-decoration-break: clone;
|
40
|
+
}
|
31
41
|
}
|
32
42
|
|
33
43
|
/// Focused box
|
@@ -190,7 +190,7 @@
|
|
190
190
|
// No match? Try with string type (e.g. $size: "16" not 16)
|
191
191
|
@if not $font-map {
|
192
192
|
@each $font-size in map-keys($govuk-typography-scale) {
|
193
|
-
@if not $font-map and #{$font-size} == #{$size} {
|
193
|
+
@if not $font-map and "#{$font-size}" == "#{$size}" {
|
194
194
|
$font-map: map-get($govuk-typography-scale, $font-size);
|
195
195
|
}
|
196
196
|
}
|
@@ -359,15 +359,6 @@ $govuk-colours-organisations: $_govuk-legacy-organisation-colours !default;
|
|
359
359
|
$govuk-colours-organisations: $_govuk-organisation-colours;
|
360
360
|
}
|
361
361
|
|
362
|
-
// Output a deprecation warning if the legacy colour palette is being used.
|
363
|
-
// Remove in next major version.
|
364
|
-
@if $govuk-colours-organisations == $_govuk-legacy-organisation-colours {
|
365
|
-
@include _warning(
|
366
|
-
"legacy-organisation-colours",
|
367
|
-
"The legacy organisation colour palette has been deprecated and will be removed in the next major version."
|
368
|
-
);
|
369
|
-
}
|
370
|
-
|
371
362
|
/// Organisation colour aliases
|
372
363
|
///
|
373
364
|
/// Some organisations have been renamed within our code over time. Here we
|
@@ -21,9 +21,9 @@
|
|
21
21
|
/// }
|
22
22
|
///
|
23
23
|
///
|
24
|
-
/// @param {String}
|
25
|
-
/// @param {String}
|
26
|
-
/// @param {String}
|
24
|
+
/// @param {String} $property - The name of the property being rebranded
|
25
|
+
/// @param {String} $from - The original value of the property
|
26
|
+
/// @param {String} $to - The rebranded value of the property
|
27
27
|
/// @throw if `$property` is set but `$from` or `$to` are missing
|
28
28
|
/// @access private
|
29
29
|
@mixin _govuk-rebrand($property: null, $from: null, $to: null) {
|