katalyst-govuk-formbuilder 1.19.0 → 1.20.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.
@@ -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,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"};
1
+ import{Controller as e}from"@hotwired/stimulus";function t(e=document.body){return!!e&&e.classList.contains("govuk-frontend-supported")}function n(e){return!!e&&"object"==typeof e&&!function(e){return Array.isArray(e)}(e)}function s(e,t){return`${e.moduleName}: ${t}`}class i extends Error{constructor(...e){super(...e),this.name="GOVUKFrontendError"}}class o extends i{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 r extends i{constructor(...e){super(...e),this.name="ConfigError"}}class a extends i{constructor(e){let t="string"==typeof e?e:"";if("object"==typeof e){const{component:n,identifier:i,element:o,expectedType:r}=e;t=i,t+=o?` is not of type ${null!=r?r:"HTMLElement"}`:" not found",t=s(n,t)}super(t),this.name="ElementError"}}class l extends i{constructor(e){super("string"==typeof e?e:s(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 l("`moduleName` not defined in component");if(!(e instanceof t.elementType))throw new a({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 l(e)}static checkSupport(){if(!t())throw new o}}u.elementType=HTMLElement;const c=Symbol.for("configOverride");class h extends u{[c](e){return{}}get config(){return this._config}constructor(e,t){super(e),this._config=void 0;const i=this.constructor;if(!n(i.defaults))throw new r(s(i,"Config passed as parameter into constructor but no defaults defined"));const o=function(e,t){if(!n(e.schema))throw new r(s(e,"Config passed as parameter into constructor but no schema defined"));const i={},o=Object.entries(e.schema.properties);for(const n of o){const[s,o]=n,r=s.toString();r in t&&(i[r]=d(t[r],o)),"object"===(null==o?void 0:o.type)&&(i[r]=m(e.schema,t,s))}return i}(i,this._$root.dataset);this._config=p(i.defaults,null!=t?t:{},this[c](o),o)}}function d(e,t){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":s="true"===n;break;case"number":s=Number(n);break;default:s=e}return s}function p(...e){const t={};for(const s of e)for(const e of Object.keys(s)){const i=t[e],o=s[e];n(i)&&n(o)?t[e]=p(i,o):t[e]=o}return t}function m(e,t,s){const i=e.properties[s];if("object"!==(null==i?void 0:i.type))return;const o={[s]:{}};for(const[e,i]of Object.entries(t)){let t=o;const r=e.split(".");for(const[o,a]of r.entries())n(t)&&(o<r.length-1?(n(t[a])||(t[a]={}),t=t[a]):e!==s&&(t[a]=d(i)))}return o[s]}class f{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 s=n[this.getPluralSuffix(e,t.count)];s&&(n=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(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,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`)})}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],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`)}selectPluralFormUsingFallbackRules(e){e=Math.abs(Math.floor(e));const t=this.getPluralRulesForLocale();return t?f.pluralRules[t](e):"other"}getPluralRulesForLocale(){const e=this.locale.split("-")[0];for(const t in f.pluralRulesMap){const n=f.pluralRulesMap[t];if(n.includes(this.locale)||n.includes(e))return t}}}f.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"]},f.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",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}
8
+ class g extends h{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 v(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(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'}]});
21
+ */g.moduleName="govuk-button",g.defaults=Object.freeze({preventDoubleClick:!1}),g.schema=Object.freeze({properties:{preventDoubleClick:{type:"boolean"}}});class w extends h{[c](e){let t={};return("maxwords"in e||"maxlength"in e)&&(t={maxlength:void 0,maxwords:void 0}),t}constructor(e,t={}){var n,i;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 o=this.$root.querySelector(".govuk-js-character-count");if(!(o instanceof HTMLTextAreaElement||o instanceof HTMLInputElement))throw new a({component:w,element:o,expectedType:"HTMLTextareaElement or HTMLInputElement",identifier:"Form field (`.govuk-js-character-count`)"});const l=function(e,t){const n=[];for(const[s,i]of Object.entries(e)){const e=[];if(Array.isArray(i)){for(const{required:n,errorMessage:s}of i)n.every(e=>!!t[e])||e.push(s);"anyOf"!==s||i.length-e.length>=1||n.push(...e)}}return n}(w.schema,this.config);if(l[0])throw new r(s(w,l[0]));this.i18n=new f(this.config.i18n,{locale:v(this.$root,"lang")}),this.maxLength=null!=(n=null!=(i=this.config.maxwords)?i:this.config.maxlength)?n:1/0,this.$textarea=o;const u=`${this.$textarea.id}-info`,c=document.getElementById(u);if(!c)throw new a({component:w,element:c,identifier:`Count message (\`id="${u}"\`)`});this.$errorMessage=this.$root.querySelector(".govuk-error-message"),`${c.textContent}`.match(/^\s*$/)&&(c.textContent=this.i18n.t("textareaDescription",{count:this.maxLength})),this.$textarea.insertAdjacentElement("afterend",c);const h=document.createElement("div");h.className="govuk-character-count__sr-status govuk-visually-hidden",h.setAttribute("aria-live","polite"),this.$screenReaderCountMessage=h,c.insertAdjacentElement("afterend",h);const d=document.createElement("div");d.className=c.className,d.classList.add("govuk-character-count__status"),d.setAttribute("aria-hidden","true"),this.$visibleCountMessage=d,c.insertAdjacentElement("afterend",d),c.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}}w.moduleName="govuk-character-count",w.defaults=Object.freeze({threshold:0,i18n:{charactersUnderLimit:{one:"You have %{count} character remaining",other:"You have %{count} characters remaining"},charactersAtLimit:"You have 0 characters remaining",charactersOverLimit:{one:"You have %{count} character too many",other:"You have %{count} characters too many"},wordsUnderLimit:{one:"You have %{count} word remaining",other:"You have %{count} words remaining"},wordsAtLimit:"You have 0 words remaining",wordsOverLimit:{one:"You have %{count} word too many",other:"You have %{count} words too many"},textareaDescription:{other:""}}}),w.schema=Object.freeze({properties:{i18n:{type:"object"},maxwords:{type:"number"},maxlength:{type:"number"},threshold:{type:"number"}},anyOf:[{required:["maxwords"],errorMessage:'Either "maxlength" or "maxwords" must be provided'},{required:["maxlength"],errorMessage:'Either "maxlength" or "maxwords" must be provided'}]});
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(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";
27
+ class b extends u{constructor(e){super(e),this.$inputs=void 0;const t=this.$root.querySelectorAll('input[type="checkbox"]');if(!t.length)throw new a({component:b,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 a({component:b,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)}}b.moduleName="govuk-checkboxes";
28
28
  /**
29
29
  * Error summary component
30
30
  *
@@ -34,17 +34,18 @@ 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",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"}}});
37
+ class y extends h{constructor(e,t={}){super(e,t),this.config.disableAutoFocus||function(e,t={}){var n;const s=e.getAttribute("tabindex");function i(){var n;null==(n=t.onBlur)||n.call(e),s||e.removeAttribute("tabindex")}s||e.setAttribute("tabindex","-1"),e.addEventListener("focus",function(){e.addEventListener("blur",i,{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 s=this.getAssociatedLegendOrLabel(n);return!!s&&(s.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 s=n.getBoundingClientRect().top,i=e.getBoundingClientRect();if(i.height&&window.innerHeight){if(i.top+i.height-s<window.innerHeight/2)return n}}}return null!=(t=document.querySelector(`label[for='${e.getAttribute("id")}']`))?t:e.closest("label")}}y.moduleName="govuk-error-summary",y.defaults=Object.freeze({disableAutoFocus:!1}),y.schema=Object.freeze({properties:{disableAutoFocus:{type:"boolean"}}});
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",()=>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"}}});
44
+ class $ extends h{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 a({component:$,element:n,expectedType:"HTMLInputElement",identifier:"Form field (`.govuk-js-password-input-input`)"});if("password"!==n.type)throw new a("Password input: Form field (`.govuk-js-password-input-input`) must be of type `password`.");const s=this.$root.querySelector(".govuk-js-password-input-toggle");if(!(s instanceof HTMLButtonElement))throw new a({component:$,element:s,expectedType:"HTMLButtonElement",identifier:"Button (`.govuk-js-password-input-toggle`)"});if("button"!==s.type)throw new a("Password input: Button (`.govuk-js-password-input-toggle`) must be of type `button`.");this.$input=n,this.$showHideButton=s,this.i18n=new f(this.config.i18n,{locale:v(this.$root,"lang")}),this.$showHideButton.removeAttribute("hidden");const i=document.createElement("div");i.className="govuk-password-input__sr-status govuk-visually-hidden",i.setAttribute("aria-live","polite"),this.$screenReaderStatusMessage=i,this.$input.insertAdjacentElement("afterend",i),this.$showHideButton.addEventListener("click",this.toggle.bind(this)),this.$input.form&&this.$input.form.addEventListener("submit",()=>this.hide()),window.addEventListener("pageshow",e=>{e.persisted&&"password"!==this.$input.type&&this.hide()}),this.hide()}toggle(e){e.preventDefault(),"password"!==this.$input.type?this.hide():this.show()}show(){this.setType("text")}hide(){this.setType("password")}setType(e){if(e===this.$input.type)return;this.$input.setAttribute("type",e);const t="password"===e,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`)}}$.moduleName="govuk-password-input",$.defaults=Object.freeze({i18n:{showPassword:"Show",hidePassword:"Hide",showPasswordAriaLabel:"Show password",hidePasswordAriaLabel:"Hide password",passwordShownAnnouncement:"Your password is visible",passwordHiddenAnnouncement:"Your password is hidden"}}),$.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(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};
50
+ class x extends u{constructor(e){super(e),this.$inputs=void 0;const t=this.$root.querySelectorAll('input[type="radio"]');if(!t.length)throw new a({component:x,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 a({component:x,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]'),s=t.form,i=t.name;n.forEach(e=>{const t=e.form===s;e.name===i&&t&&this.syncConditionalRevealWithInputState(e)})}}x.moduleName="govuk-radios";class k extends e{static targets=["preview","destroy"];static values={mimeTypes:Array};connect(){this.counter=0,this.initialPreviewContent=null,this.onUploadFlag=!1}onUpload(e){this.onUploadFlag=!0,this.hasDestroyTarget&&(this.destroyTarget.value=!1),this.previewTarget.removeAttribute("hidden"),this.hasPreviewTarget&&(e.currentTarget.files.length>0?this.showPreview(e.currentTarget.files[0]):this.setPreviewContent(this.initialPreviewContent))}setDestroy(e){e.preventDefault(),this.initialPreviewContent&&this.onUploadFlag?(this.onUploadFlag=!1,this.setPreviewContent(this.initialPreviewContent)):(this.hasDestroyTarget&&(this.destroyTarget.value=!0),this.hasPreviewTarget&&(this.previewTarget.setAttribute("hidden",""),this.setPreviewContent("")),this.previousInput&&this.previousInput.toggleAttribute("disabled",!0)),this.fileInput.value=""}setPreviewContent(e){this.filenameTag&&(this.filenameTag.innerText=text)}drop(e){e.preventDefault();const t=this.fileForEvent(e,this.mimeTypesValue);if(t){const e=new DataTransfer;e.items.add(t),this.fileInput.files=e.files,this.fileInput.dispatchEvent(new Event("change"))}this.counter=0,this.element.classList.remove("droppable")}dragover(e){e.preventDefault()}dragenter(e){e.preventDefault(),0===this.counter&&this.element.classList.add("droppable"),this.counter++}dragleave(e){e.preventDefault(),this.counter--,0===this.counter&&this.element.classList.remove("droppable")}get fileInput(){return this.element.querySelector("input[type='file']")}get previousInput(){return this.element.querySelector(`input[type='hidden'][name='${this.fileInput.name}']`)}get filenameTag(){return this.hasPreviewTarget?this.previewTarget.querySelector("p.preview-filename"):null}showPreview(e){const t=new FileReader;t.onload=t=>{this.filenameTag&&(this.filenameTag.innerText=e.name)},t.readAsDataURL(e)}fileForEvent(e,t){const n=e=>t.indexOf(e.type)>-1;let s;if(e.dataTransfer.items){const t=[...e.dataTransfer.items].find(n);t&&(s=t.getAsFile())}else s=[...e.dataTransfer.files].find(n);return s}}const C=[{identifier:"govuk-document-field",controllerConstructor:class extends k{connect(){super.connect(),this.initialPreviewContent=this.filenameTag.text}setPreviewContent(e){this.filenameTag.innerText=e}showPreview(e){const t=new FileReader;t.onload=t=>{this.filenameTag&&(this.filenameTag.innerText=e.name)},t.readAsDataURL(e)}get filenameTag(){return this.previewTarget.querySelector("p.preview-filename")}}},{identifier:"govuk-image-field",controllerConstructor:class extends k{connect(){super.connect(),this.initialPreviewContent=this.imageTag.getAttribute("src")}setPreviewContent(e){this.imageTag.src=e}showPreview(e){const t=new FileReader;t.onload=e=>{this.imageTag.src=e.target.result},t.readAsDataURL(e)}get imageTag(){return this.previewTarget.querySelector("img")}}}];function T(e){let n;if(e=void 0!==e?e:{},!t())return void console.log(new o);const s=[[g,e.button],[w,e.characterCount],[b],[y,e.errorSummary],[x],[$,e.passwordInput]],i=null!=(n=e.scope)?n:document;s.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)}})})}export{g as Button,w as CharacterCount,b as Checkboxes,y as ErrorSummary,$ as PasswordInput,x as Radios,C as default,T as initAll};
51
+ //# sourceMappingURL=formbuilder.min.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"formbuilder.min.js","sources":["../../../../../node_modules/govuk-frontend/dist/govuk/common/index.mjs","../../../../../node_modules/govuk-frontend/dist/govuk/errors/index.mjs","../../../../../node_modules/govuk-frontend/dist/govuk/component.mjs","../../../../../node_modules/govuk-frontend/dist/govuk/common/configuration.mjs","../../../../../node_modules/govuk-frontend/dist/govuk/i18n.mjs","../../../../../node_modules/govuk-frontend/dist/govuk/components/button/button.mjs","../../../../../node_modules/govuk-frontend/dist/govuk/common/closest-attribute-value.mjs","../../../../../node_modules/govuk-frontend/dist/govuk/components/character-count/character-count.mjs","../../../../../node_modules/govuk-frontend/dist/govuk/components/checkboxes/checkboxes.mjs","../../../../../node_modules/govuk-frontend/dist/govuk/components/error-summary/error-summary.mjs","../../../../../node_modules/govuk-frontend/dist/govuk/components/password-input/password-input.mjs","../../../../../node_modules/govuk-frontend/dist/govuk/components/radios/radios.mjs","../../../../javascript/katalyst/govuk/controllers/file_field_controller.js","../../../../javascript/katalyst/govuk/controllers/index.js","../../../../javascript/katalyst/govuk/controllers/document_field_controller.js","../../../../javascript/katalyst/govuk/controllers/image_field_controller.js","../../../../javascript/katalyst/govuk/formbuilder.js"],"sourcesContent":["function getFragmentFromUrl(url) {\n if (!url.includes('#')) {\n return undefined;\n }\n return url.split('#').pop();\n}\nfunction getBreakpoint(name) {\n const property = `--govuk-frontend-breakpoint-${name}`;\n const value = window.getComputedStyle(document.documentElement).getPropertyValue(property);\n return {\n property,\n value: value || undefined\n };\n}\nfunction setFocus($element, options = {}) {\n var _options$onBeforeFocu;\n const isFocusable = $element.getAttribute('tabindex');\n if (!isFocusable) {\n $element.setAttribute('tabindex', '-1');\n }\n function onFocus() {\n $element.addEventListener('blur', onBlur, {\n once: true\n });\n }\n function onBlur() {\n var _options$onBlur;\n (_options$onBlur = options.onBlur) == null || _options$onBlur.call($element);\n if (!isFocusable) {\n $element.removeAttribute('tabindex');\n }\n }\n $element.addEventListener('focus', onFocus, {\n once: true\n });\n (_options$onBeforeFocu = options.onBeforeFocus) == null || _options$onBeforeFocu.call($element);\n $element.focus();\n}\nfunction isInitialised($root, moduleName) {\n return $root instanceof HTMLElement && $root.hasAttribute(`data-${moduleName}-init`);\n}\n\n/**\n * Checks if GOV.UK Frontend is supported on this page\n *\n * Some browsers will load and run our JavaScript but GOV.UK Frontend\n * won't be supported.\n *\n * @param {HTMLElement | null} [$scope] - (internal) `<body>` HTML element checked for browser support\n * @returns {boolean} Whether GOV.UK Frontend is supported on this page\n */\nfunction isSupported($scope = document.body) {\n if (!$scope) {\n return false;\n }\n return $scope.classList.contains('govuk-frontend-supported');\n}\nfunction isArray(option) {\n return Array.isArray(option);\n}\nfunction isObject(option) {\n return !!option && typeof option === 'object' && !isArray(option);\n}\nfunction formatErrorMessage(Component, message) {\n return `${Component.moduleName}: ${message}`;\n}\n/**\n * @typedef ComponentWithModuleName\n * @property {string} moduleName - Name of the component\n */\n/**\n * @import { ObjectNested } from './configuration.mjs'\n */\n\nexport { formatErrorMessage, getBreakpoint, getFragmentFromUrl, isInitialised, isObject, isSupported, setFocus };\n//# sourceMappingURL=index.mjs.map\n","import { formatErrorMessage } from '../common/index.mjs';\n\nclass GOVUKFrontendError extends Error {\n constructor(...args) {\n super(...args);\n this.name = 'GOVUKFrontendError';\n }\n}\nclass SupportError extends GOVUKFrontendError {\n /**\n * Checks if GOV.UK Frontend is supported on this page\n *\n * @param {HTMLElement | null} [$scope] - HTML element `<body>` checked for browser support\n */\n constructor($scope = document.body) {\n const supportMessage = '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';\n super($scope ? supportMessage : 'GOV.UK Frontend initialised without `<script type=\"module\">`');\n this.name = 'SupportError';\n }\n}\nclass ConfigError extends GOVUKFrontendError {\n constructor(...args) {\n super(...args);\n this.name = 'ConfigError';\n }\n}\nclass ElementError extends GOVUKFrontendError {\n constructor(messageOrOptions) {\n let message = typeof messageOrOptions === 'string' ? messageOrOptions : '';\n if (typeof messageOrOptions === 'object') {\n const {\n component,\n identifier,\n element,\n expectedType\n } = messageOrOptions;\n message = identifier;\n message += element ? ` is not of type ${expectedType != null ? expectedType : 'HTMLElement'}` : ' not found';\n message = formatErrorMessage(component, message);\n }\n super(message);\n this.name = 'ElementError';\n }\n}\nclass InitError extends GOVUKFrontendError {\n constructor(componentOrMessage) {\n const message = typeof componentOrMessage === 'string' ? componentOrMessage : formatErrorMessage(componentOrMessage, `Root element (\\`$root\\`) already initialised`);\n super(message);\n this.name = 'InitError';\n }\n}\n/**\n * @import { ComponentWithModuleName } from '../common/index.mjs'\n */\n\nexport { ConfigError, ElementError, GOVUKFrontendError, InitError, SupportError };\n//# sourceMappingURL=index.mjs.map\n","import { isInitialised, isSupported } from './common/index.mjs';\nimport { InitError, ElementError, SupportError } from './errors/index.mjs';\n\nclass Component {\n /**\n * Returns the root element of the component\n *\n * @protected\n * @returns {RootElementType} - the root element of component\n */\n get $root() {\n return this._$root;\n }\n constructor($root) {\n this._$root = void 0;\n const childConstructor = this.constructor;\n if (typeof childConstructor.moduleName !== 'string') {\n throw new InitError(`\\`moduleName\\` not defined in component`);\n }\n if (!($root instanceof childConstructor.elementType)) {\n throw new ElementError({\n element: $root,\n component: childConstructor,\n identifier: 'Root element (`$root`)',\n expectedType: childConstructor.elementType.name\n });\n } else {\n this._$root = $root;\n }\n childConstructor.checkSupport();\n this.checkInitialised();\n const moduleName = childConstructor.moduleName;\n this.$root.setAttribute(`data-${moduleName}-init`, '');\n }\n checkInitialised() {\n const constructor = this.constructor;\n const moduleName = constructor.moduleName;\n if (moduleName && isInitialised(this.$root, moduleName)) {\n throw new InitError(constructor);\n }\n }\n static checkSupport() {\n if (!isSupported()) {\n throw new SupportError();\n }\n }\n}\n\n/**\n * @typedef ChildClass\n * @property {string} moduleName - The module name that'll be looked for in the DOM when initialising the component\n */\n\n/**\n * @typedef {typeof Component & ChildClass} ChildClassConstructor\n */\nComponent.elementType = HTMLElement;\n\nexport { Component };\n//# sourceMappingURL=component.mjs.map\n","import { Component } from '../component.mjs';\nimport { ConfigError } from '../errors/index.mjs';\nimport { isObject, formatErrorMessage } from './index.mjs';\n\nconst configOverride = Symbol.for('configOverride');\nclass ConfigurableComponent extends Component {\n [configOverride](param) {\n return {};\n }\n\n /**\n * Returns the root element of the component\n *\n * @protected\n * @returns {ConfigurationType} - the root element of component\n */\n get config() {\n return this._config;\n }\n constructor($root, config) {\n super($root);\n this._config = void 0;\n const childConstructor = this.constructor;\n if (!isObject(childConstructor.defaults)) {\n throw new ConfigError(formatErrorMessage(childConstructor, 'Config passed as parameter into constructor but no defaults defined'));\n }\n const datasetConfig = normaliseDataset(childConstructor, this._$root.dataset);\n this._config = mergeConfigs(childConstructor.defaults, config != null ? config : {}, this[configOverride](datasetConfig), datasetConfig);\n }\n}\nfunction normaliseString(value, property) {\n const trimmedValue = value ? value.trim() : '';\n let output;\n let outputType = property == null ? void 0 : property.type;\n if (!outputType) {\n if (['true', 'false'].includes(trimmedValue)) {\n outputType = 'boolean';\n }\n if (trimmedValue.length > 0 && isFinite(Number(trimmedValue))) {\n outputType = 'number';\n }\n }\n switch (outputType) {\n case 'boolean':\n output = trimmedValue === 'true';\n break;\n case 'number':\n output = Number(trimmedValue);\n break;\n default:\n output = value;\n }\n return output;\n}\nfunction normaliseDataset(Component, dataset) {\n if (!isObject(Component.schema)) {\n throw new ConfigError(formatErrorMessage(Component, 'Config passed as parameter into constructor but no schema defined'));\n }\n const out = {};\n const entries = Object.entries(Component.schema.properties);\n for (const entry of entries) {\n const [namespace, property] = entry;\n const field = namespace.toString();\n if (field in dataset) {\n out[field] = normaliseString(dataset[field], property);\n }\n if ((property == null ? void 0 : property.type) === 'object') {\n out[field] = extractConfigByNamespace(Component.schema, dataset, namespace);\n }\n }\n return out;\n}\nfunction mergeConfigs(...configObjects) {\n const formattedConfigObject = {};\n for (const configObject of configObjects) {\n for (const key of Object.keys(configObject)) {\n const option = formattedConfigObject[key];\n const override = configObject[key];\n if (isObject(option) && isObject(override)) {\n formattedConfigObject[key] = mergeConfigs(option, override);\n } else {\n formattedConfigObject[key] = override;\n }\n }\n }\n return formattedConfigObject;\n}\nfunction validateConfig(schema, config) {\n const validationErrors = [];\n for (const [name, conditions] of Object.entries(schema)) {\n const errors = [];\n if (Array.isArray(conditions)) {\n for (const {\n required,\n errorMessage\n } of conditions) {\n if (!required.every(key => !!config[key])) {\n errors.push(errorMessage);\n }\n }\n if (name === 'anyOf' && !(conditions.length - errors.length >= 1)) {\n validationErrors.push(...errors);\n }\n }\n }\n return validationErrors;\n}\nfunction extractConfigByNamespace(schema, dataset, namespace) {\n const property = schema.properties[namespace];\n if ((property == null ? void 0 : property.type) !== 'object') {\n return;\n }\n const newObject = {\n [namespace]: {}\n };\n for (const [key, value] of Object.entries(dataset)) {\n let current = newObject;\n const keyParts = key.split('.');\n for (const [index, name] of keyParts.entries()) {\n if (isObject(current)) {\n if (index < keyParts.length - 1) {\n if (!isObject(current[name])) {\n current[name] = {};\n }\n current = current[name];\n } else if (key !== namespace) {\n current[name] = normaliseString(value);\n }\n }\n }\n }\n return newObject[namespace];\n}\n/**\n * Schema for component config\n *\n * @template {Partial<Record<keyof ConfigurationType, unknown>>} ConfigurationType\n * @typedef {object} Schema\n * @property {Record<keyof ConfigurationType, SchemaProperty | undefined>} properties - Schema properties\n * @property {SchemaCondition<ConfigurationType>[]} [anyOf] - List of schema conditions\n */\n/**\n * Schema property for component config\n *\n * @typedef {object} SchemaProperty\n * @property {'string' | 'boolean' | 'number' | 'object'} type - Property type\n */\n/**\n * Schema condition for component config\n *\n * @template {Partial<Record<keyof ConfigurationType, unknown>>} ConfigurationType\n * @typedef {object} SchemaCondition\n * @property {(keyof ConfigurationType)[]} required - List of required config fields\n * @property {string} errorMessage - Error message when required config fields not provided\n */\n/**\n * @template {Partial<Record<keyof ConfigurationType, unknown>>} [ConfigurationType=ObjectNested]\n * @typedef ChildClass\n * @property {string} moduleName - The module name that'll be looked for in the DOM when initialising the component\n * @property {Schema<ConfigurationType>} [schema] - The schema of the component configuration\n * @property {ConfigurationType} [defaults] - The default values of the configuration of the component\n */\n/**\n * @template {Partial<Record<keyof ConfigurationType, unknown>>} [ConfigurationType=ObjectNested]\n * @typedef {typeof Component & ChildClass<ConfigurationType>} ChildClassConstructor<ConfigurationType>\n */\n\nexport { ConfigurableComponent, configOverride, extractConfigByNamespace, mergeConfigs, normaliseDataset, normaliseString, validateConfig };\n//# sourceMappingURL=configuration.mjs.map\n","class I18n {\n constructor(translations = {}, config = {}) {\n var _config$locale;\n this.translations = void 0;\n this.locale = void 0;\n this.translations = translations;\n this.locale = (_config$locale = config.locale) != null ? _config$locale : document.documentElement.lang || 'en';\n }\n t(lookupKey, options) {\n if (!lookupKey) {\n throw new Error('i18n: lookup key missing');\n }\n let translation = this.translations[lookupKey];\n if (typeof (options == null ? void 0 : options.count) === 'number' && typeof translation === 'object') {\n const translationPluralForm = translation[this.getPluralSuffix(lookupKey, options.count)];\n if (translationPluralForm) {\n translation = translationPluralForm;\n }\n }\n if (typeof translation === 'string') {\n if (translation.match(/%{(.\\S+)}/)) {\n if (!options) {\n throw new Error('i18n: cannot replace placeholders in string if no option data provided');\n }\n return this.replacePlaceholders(translation, options);\n }\n return translation;\n }\n return lookupKey;\n }\n replacePlaceholders(translationString, options) {\n const formatter = Intl.NumberFormat.supportedLocalesOf(this.locale).length ? new Intl.NumberFormat(this.locale) : undefined;\n return translationString.replace(/%{(.\\S+)}/g, function (placeholderWithBraces, placeholderKey) {\n if (Object.prototype.hasOwnProperty.call(options, placeholderKey)) {\n const placeholderValue = options[placeholderKey];\n if (placeholderValue === false || typeof placeholderValue !== 'number' && typeof placeholderValue !== 'string') {\n return '';\n }\n if (typeof placeholderValue === 'number') {\n return formatter ? formatter.format(placeholderValue) : `${placeholderValue}`;\n }\n return placeholderValue;\n }\n throw new Error(`i18n: no data found to replace ${placeholderWithBraces} placeholder in string`);\n });\n }\n hasIntlPluralRulesSupport() {\n return Boolean('PluralRules' in window.Intl && Intl.PluralRules.supportedLocalesOf(this.locale).length);\n }\n getPluralSuffix(lookupKey, count) {\n count = Number(count);\n if (!isFinite(count)) {\n return 'other';\n }\n const translation = this.translations[lookupKey];\n const preferredForm = this.hasIntlPluralRulesSupport() ? new Intl.PluralRules(this.locale).select(count) : this.selectPluralFormUsingFallbackRules(count);\n if (typeof translation === 'object') {\n if (preferredForm in translation) {\n return preferredForm;\n } else if ('other' in translation) {\n console.warn(`i18n: Missing plural form \".${preferredForm}\" for \"${this.locale}\" locale. Falling back to \".other\".`);\n return 'other';\n }\n }\n throw new Error(`i18n: Plural form \".other\" is required for \"${this.locale}\" locale`);\n }\n selectPluralFormUsingFallbackRules(count) {\n count = Math.abs(Math.floor(count));\n const ruleset = this.getPluralRulesForLocale();\n if (ruleset) {\n return I18n.pluralRules[ruleset](count);\n }\n return 'other';\n }\n getPluralRulesForLocale() {\n const localeShort = this.locale.split('-')[0];\n for (const pluralRule in I18n.pluralRulesMap) {\n const languages = I18n.pluralRulesMap[pluralRule];\n if (languages.includes(this.locale) || languages.includes(localeShort)) {\n return pluralRule;\n }\n }\n }\n}\nI18n.pluralRulesMap = {\n arabic: ['ar'],\n chinese: ['my', 'zh', 'id', 'ja', 'jv', 'ko', 'ms', 'th', 'vi'],\n french: ['hy', 'bn', 'fr', 'gu', 'hi', 'fa', 'pa', 'zu'],\n 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'],\n irish: ['ga'],\n russian: ['ru', 'uk'],\n scottish: ['gd'],\n spanish: ['pt-PT', 'it', 'es'],\n welsh: ['cy']\n};\nI18n.pluralRules = {\n arabic(n) {\n if (n === 0) {\n return 'zero';\n }\n if (n === 1) {\n return 'one';\n }\n if (n === 2) {\n return 'two';\n }\n if (n % 100 >= 3 && n % 100 <= 10) {\n return 'few';\n }\n if (n % 100 >= 11 && n % 100 <= 99) {\n return 'many';\n }\n return 'other';\n },\n chinese() {\n return 'other';\n },\n french(n) {\n return n === 0 || n === 1 ? 'one' : 'other';\n },\n german(n) {\n return n === 1 ? 'one' : 'other';\n },\n irish(n) {\n if (n === 1) {\n return 'one';\n }\n if (n === 2) {\n return 'two';\n }\n if (n >= 3 && n <= 6) {\n return 'few';\n }\n if (n >= 7 && n <= 10) {\n return 'many';\n }\n return 'other';\n },\n russian(n) {\n const lastTwo = n % 100;\n const last = lastTwo % 10;\n if (last === 1 && lastTwo !== 11) {\n return 'one';\n }\n if (last >= 2 && last <= 4 && !(lastTwo >= 12 && lastTwo <= 14)) {\n return 'few';\n }\n if (last === 0 || last >= 5 && last <= 9 || lastTwo >= 11 && lastTwo <= 14) {\n return 'many';\n }\n return 'other';\n },\n scottish(n) {\n if (n === 1 || n === 11) {\n return 'one';\n }\n if (n === 2 || n === 12) {\n return 'two';\n }\n if (n >= 3 && n <= 10 || n >= 13 && n <= 19) {\n return 'few';\n }\n return 'other';\n },\n spanish(n) {\n if (n === 1) {\n return 'one';\n }\n if (n % 1000000 === 0 && n !== 0) {\n return 'many';\n }\n return 'other';\n },\n welsh(n) {\n if (n === 0) {\n return 'zero';\n }\n if (n === 1) {\n return 'one';\n }\n if (n === 2) {\n return 'two';\n }\n if (n === 3) {\n return 'few';\n }\n if (n === 6) {\n return 'many';\n }\n return 'other';\n }\n};\n\nexport { I18n };\n//# sourceMappingURL=i18n.mjs.map\n","import { ConfigurableComponent } from '../../common/configuration.mjs';\n\nconst DEBOUNCE_TIMEOUT_IN_SECONDS = 1;\n\n/**\n * JavaScript enhancements for the Button component\n *\n * @preserve\n * @augments ConfigurableComponent<ButtonConfig>\n */\nclass Button extends ConfigurableComponent {\n /**\n * @param {Element | null} $root - HTML element to use for button\n * @param {ButtonConfig} [config] - Button config\n */\n constructor($root, config = {}) {\n super($root, config);\n this.debounceFormSubmitTimer = null;\n this.$root.addEventListener('keydown', event => this.handleKeyDown(event));\n this.$root.addEventListener('click', event => this.debounce(event));\n }\n handleKeyDown(event) {\n const $target = event.target;\n if (event.key !== ' ') {\n return;\n }\n if ($target instanceof HTMLElement && $target.getAttribute('role') === 'button') {\n event.preventDefault();\n $target.click();\n }\n }\n debounce(event) {\n if (!this.config.preventDoubleClick) {\n return;\n }\n if (this.debounceFormSubmitTimer) {\n event.preventDefault();\n return false;\n }\n this.debounceFormSubmitTimer = window.setTimeout(() => {\n this.debounceFormSubmitTimer = null;\n }, DEBOUNCE_TIMEOUT_IN_SECONDS * 1000);\n }\n}\n\n/**\n * Button config\n *\n * @typedef {object} ButtonConfig\n * @property {boolean} [preventDoubleClick=false] - Prevent accidental double\n * clicks on submit buttons from submitting forms multiple times.\n */\n\n/**\n * @import { Schema } from '../../common/configuration.mjs'\n */\nButton.moduleName = 'govuk-button';\nButton.defaults = Object.freeze({\n preventDoubleClick: false\n});\nButton.schema = Object.freeze({\n properties: {\n preventDoubleClick: {\n type: 'boolean'\n }\n }\n});\n\nexport { Button };\n//# sourceMappingURL=button.mjs.map\n","function closestAttributeValue($element, attributeName) {\n const $closestElementWithAttribute = $element.closest(`[${attributeName}]`);\n return $closestElementWithAttribute ? $closestElementWithAttribute.getAttribute(attributeName) : null;\n}\n\nexport { closestAttributeValue };\n//# sourceMappingURL=closest-attribute-value.mjs.map\n","import { closestAttributeValue } from '../../common/closest-attribute-value.mjs';\nimport { ConfigurableComponent, configOverride, validateConfig } from '../../common/configuration.mjs';\nimport { formatErrorMessage } from '../../common/index.mjs';\nimport { ElementError, ConfigError } from '../../errors/index.mjs';\nimport { I18n } from '../../i18n.mjs';\n\n/**\n * Character count component\n *\n * Tracks the number of characters or words in the `.govuk-js-character-count`\n * `<textarea>` inside the element. Displays a message with the remaining number\n * of characters/words available, or the number of characters/words in excess.\n *\n * You can configure the message to only appear after a certain percentage\n * of the available characters/words has been entered.\n *\n * @preserve\n * @augments ConfigurableComponent<CharacterCountConfig>\n */\nclass CharacterCount extends ConfigurableComponent {\n [configOverride](datasetConfig) {\n let configOverrides = {};\n if ('maxwords' in datasetConfig || 'maxlength' in datasetConfig) {\n configOverrides = {\n maxlength: undefined,\n maxwords: undefined\n };\n }\n return configOverrides;\n }\n\n /**\n * @param {Element | null} $root - HTML element to use for character count\n * @param {CharacterCountConfig} [config] - Character count config\n */\n constructor($root, config = {}) {\n var _ref, _this$config$maxwords;\n super($root, config);\n this.$textarea = void 0;\n this.$visibleCountMessage = void 0;\n this.$screenReaderCountMessage = void 0;\n this.lastInputTimestamp = null;\n this.lastInputValue = '';\n this.valueChecker = null;\n this.i18n = void 0;\n this.maxLength = void 0;\n const $textarea = this.$root.querySelector('.govuk-js-character-count');\n if (!($textarea instanceof HTMLTextAreaElement || $textarea instanceof HTMLInputElement)) {\n throw new ElementError({\n component: CharacterCount,\n element: $textarea,\n expectedType: 'HTMLTextareaElement or HTMLInputElement',\n identifier: 'Form field (`.govuk-js-character-count`)'\n });\n }\n const errors = validateConfig(CharacterCount.schema, this.config);\n if (errors[0]) {\n throw new ConfigError(formatErrorMessage(CharacterCount, errors[0]));\n }\n this.i18n = new I18n(this.config.i18n, {\n locale: closestAttributeValue(this.$root, 'lang')\n });\n this.maxLength = (_ref = (_this$config$maxwords = this.config.maxwords) != null ? _this$config$maxwords : this.config.maxlength) != null ? _ref : Infinity;\n this.$textarea = $textarea;\n const textareaDescriptionId = `${this.$textarea.id}-info`;\n const $textareaDescription = document.getElementById(textareaDescriptionId);\n if (!$textareaDescription) {\n throw new ElementError({\n component: CharacterCount,\n element: $textareaDescription,\n identifier: `Count message (\\`id=\"${textareaDescriptionId}\"\\`)`\n });\n }\n this.$errorMessage = this.$root.querySelector('.govuk-error-message');\n if (`${$textareaDescription.textContent}`.match(/^\\s*$/)) {\n $textareaDescription.textContent = this.i18n.t('textareaDescription', {\n count: this.maxLength\n });\n }\n this.$textarea.insertAdjacentElement('afterend', $textareaDescription);\n const $screenReaderCountMessage = document.createElement('div');\n $screenReaderCountMessage.className = 'govuk-character-count__sr-status govuk-visually-hidden';\n $screenReaderCountMessage.setAttribute('aria-live', 'polite');\n this.$screenReaderCountMessage = $screenReaderCountMessage;\n $textareaDescription.insertAdjacentElement('afterend', $screenReaderCountMessage);\n const $visibleCountMessage = document.createElement('div');\n $visibleCountMessage.className = $textareaDescription.className;\n $visibleCountMessage.classList.add('govuk-character-count__status');\n $visibleCountMessage.setAttribute('aria-hidden', 'true');\n this.$visibleCountMessage = $visibleCountMessage;\n $textareaDescription.insertAdjacentElement('afterend', $visibleCountMessage);\n $textareaDescription.classList.add('govuk-visually-hidden');\n this.$textarea.removeAttribute('maxlength');\n this.bindChangeEvents();\n window.addEventListener('pageshow', () => this.updateCountMessage());\n this.updateCountMessage();\n }\n bindChangeEvents() {\n this.$textarea.addEventListener('keyup', () => this.handleKeyUp());\n this.$textarea.addEventListener('focus', () => this.handleFocus());\n this.$textarea.addEventListener('blur', () => this.handleBlur());\n }\n handleKeyUp() {\n this.updateVisibleCountMessage();\n this.lastInputTimestamp = Date.now();\n }\n handleFocus() {\n this.valueChecker = window.setInterval(() => {\n if (!this.lastInputTimestamp || Date.now() - 500 >= this.lastInputTimestamp) {\n this.updateIfValueChanged();\n }\n }, 1000);\n }\n handleBlur() {\n if (this.valueChecker) {\n window.clearInterval(this.valueChecker);\n }\n }\n updateIfValueChanged() {\n if (this.$textarea.value !== this.lastInputValue) {\n this.lastInputValue = this.$textarea.value;\n this.updateCountMessage();\n }\n }\n updateCountMessage() {\n this.updateVisibleCountMessage();\n this.updateScreenReaderCountMessage();\n }\n updateVisibleCountMessage() {\n const remainingNumber = this.maxLength - this.count(this.$textarea.value);\n const isError = remainingNumber < 0;\n this.$visibleCountMessage.classList.toggle('govuk-character-count__message--disabled', !this.isOverThreshold());\n if (!this.$errorMessage) {\n this.$textarea.classList.toggle('govuk-textarea--error', isError);\n }\n this.$visibleCountMessage.classList.toggle('govuk-error-message', isError);\n this.$visibleCountMessage.classList.toggle('govuk-hint', !isError);\n this.$visibleCountMessage.textContent = this.getCountMessage();\n }\n updateScreenReaderCountMessage() {\n if (this.isOverThreshold()) {\n this.$screenReaderCountMessage.removeAttribute('aria-hidden');\n } else {\n this.$screenReaderCountMessage.setAttribute('aria-hidden', 'true');\n }\n this.$screenReaderCountMessage.textContent = this.getCountMessage();\n }\n count(text) {\n if (this.config.maxwords) {\n var _text$match;\n const tokens = (_text$match = text.match(/\\S+/g)) != null ? _text$match : [];\n return tokens.length;\n }\n return text.length;\n }\n getCountMessage() {\n const remainingNumber = this.maxLength - this.count(this.$textarea.value);\n const countType = this.config.maxwords ? 'words' : 'characters';\n return this.formatCountMessage(remainingNumber, countType);\n }\n formatCountMessage(remainingNumber, countType) {\n if (remainingNumber === 0) {\n return this.i18n.t(`${countType}AtLimit`);\n }\n const translationKeySuffix = remainingNumber < 0 ? 'OverLimit' : 'UnderLimit';\n return this.i18n.t(`${countType}${translationKeySuffix}`, {\n count: Math.abs(remainingNumber)\n });\n }\n isOverThreshold() {\n if (!this.config.threshold) {\n return true;\n }\n const currentLength = this.count(this.$textarea.value);\n const maxLength = this.maxLength;\n const thresholdValue = maxLength * this.config.threshold / 100;\n return thresholdValue <= currentLength;\n }\n}\n\n/**\n * Character count config\n *\n * @see {@link CharacterCount.defaults}\n * @typedef {object} CharacterCountConfig\n * @property {number} [maxlength] - The maximum number of characters.\n * If maxwords is provided, the maxlength option will be ignored.\n * @property {number} [maxwords] - The maximum number of words. If maxwords is\n * provided, the maxlength option will be ignored.\n * @property {number} [threshold=0] - The percentage value of the limit at\n * which point the count message is displayed. If this attribute is set, the\n * count message will be hidden by default.\n * @property {CharacterCountTranslations} [i18n=CharacterCount.defaults.i18n] - Character count translations\n */\n\n/**\n * Character count translations\n *\n * @see {@link CharacterCount.defaults.i18n}\n * @typedef {object} CharacterCountTranslations\n *\n * Messages shown to users as they type. It provides feedback on how many words\n * or characters they have remaining or if they are over the limit. This also\n * includes a message used as an accessible description for the textarea.\n * @property {TranslationPluralForms} [charactersUnderLimit] - Message displayed\n * when the number of characters is under the configured maximum, `maxlength`.\n * This message is displayed visually and through assistive technologies. The\n * component will replace the `%{count}` placeholder with the number of\n * remaining characters. This is a [pluralised list of\n * messages](https://frontend.design-system.service.gov.uk/localise-govuk-frontend).\n * @property {string} [charactersAtLimit] - Message displayed when the number of\n * characters reaches the configured maximum, `maxlength`. This message is\n * displayed visually and through assistive technologies.\n * @property {TranslationPluralForms} [charactersOverLimit] - Message displayed\n * when the number of characters is over the configured maximum, `maxlength`.\n * This message is displayed visually and through assistive technologies. The\n * component will replace the `%{count}` placeholder with the number of\n * remaining characters. This is a [pluralised list of\n * messages](https://frontend.design-system.service.gov.uk/localise-govuk-frontend).\n * @property {TranslationPluralForms} [wordsUnderLimit] - Message displayed when\n * the number of words is under the configured maximum, `maxlength`. This\n * message is displayed visually and through assistive technologies. The\n * component will replace the `%{count}` placeholder with the number of\n * remaining words. This is a [pluralised list of\n * messages](https://frontend.design-system.service.gov.uk/localise-govuk-frontend).\n * @property {string} [wordsAtLimit] - Message displayed when the number of\n * words reaches the configured maximum, `maxlength`. This message is\n * displayed visually and through assistive technologies.\n * @property {TranslationPluralForms} [wordsOverLimit] - Message displayed when\n * the number of words is over the configured maximum, `maxlength`. This\n * message is displayed visually and through assistive technologies. The\n * component will replace the `%{count}` placeholder with the number of\n * remaining words. This is a [pluralised list of\n * messages](https://frontend.design-system.service.gov.uk/localise-govuk-frontend).\n * @property {TranslationPluralForms} [textareaDescription] - Message made\n * available to assistive technologies, if none is already present in the\n * HTML, to describe that the component accepts only a limited amount of\n * content. It is visible on the page when JavaScript is unavailable. The\n * component will replace the `%{count}` placeholder with the value of the\n * `maxlength` or `maxwords` parameter.\n */\n\n/**\n * @import { Schema } from '../../common/configuration.mjs'\n * @import { TranslationPluralForms } from '../../i18n.mjs'\n */\nCharacterCount.moduleName = 'govuk-character-count';\nCharacterCount.defaults = Object.freeze({\n threshold: 0,\n i18n: {\n charactersUnderLimit: {\n one: 'You have %{count} character remaining',\n other: 'You have %{count} characters remaining'\n },\n charactersAtLimit: 'You have 0 characters remaining',\n charactersOverLimit: {\n one: 'You have %{count} character too many',\n other: 'You have %{count} characters too many'\n },\n wordsUnderLimit: {\n one: 'You have %{count} word remaining',\n other: 'You have %{count} words remaining'\n },\n wordsAtLimit: 'You have 0 words remaining',\n wordsOverLimit: {\n one: 'You have %{count} word too many',\n other: 'You have %{count} words too many'\n },\n textareaDescription: {\n other: ''\n }\n }\n});\nCharacterCount.schema = Object.freeze({\n properties: {\n i18n: {\n type: 'object'\n },\n maxwords: {\n type: 'number'\n },\n maxlength: {\n type: 'number'\n },\n threshold: {\n type: 'number'\n }\n },\n anyOf: [{\n required: ['maxwords'],\n errorMessage: 'Either \"maxlength\" or \"maxwords\" must be provided'\n }, {\n required: ['maxlength'],\n errorMessage: 'Either \"maxlength\" or \"maxwords\" must be provided'\n }]\n});\n\nexport { CharacterCount };\n//# sourceMappingURL=character-count.mjs.map\n","import { Component } from '../../component.mjs';\nimport { ElementError } from '../../errors/index.mjs';\n\n/**\n * Checkboxes component\n *\n * @preserve\n */\nclass Checkboxes extends Component {\n /**\n * Checkboxes can be associated with a 'conditionally revealed' content block\n * – for example, a checkbox for 'Phone' could reveal an additional form field\n * for the user to enter their phone number.\n *\n * These associations are made using a `data-aria-controls` attribute, which\n * is promoted to an aria-controls attribute during initialisation.\n *\n * We also need to restore the state of any conditional reveals on the page\n * (for example if the user has navigated back), and set up event handlers to\n * keep the reveal in sync with the checkbox state.\n *\n * @param {Element | null} $root - HTML element to use for checkboxes\n */\n constructor($root) {\n super($root);\n this.$inputs = void 0;\n const $inputs = this.$root.querySelectorAll('input[type=\"checkbox\"]');\n if (!$inputs.length) {\n throw new ElementError({\n component: Checkboxes,\n identifier: 'Form inputs (`<input type=\"checkbox\">`)'\n });\n }\n this.$inputs = $inputs;\n this.$inputs.forEach($input => {\n const targetId = $input.getAttribute('data-aria-controls');\n if (!targetId) {\n return;\n }\n if (!document.getElementById(targetId)) {\n throw new ElementError({\n component: Checkboxes,\n identifier: `Conditional reveal (\\`id=\"${targetId}\"\\`)`\n });\n }\n $input.setAttribute('aria-controls', targetId);\n $input.removeAttribute('data-aria-controls');\n });\n window.addEventListener('pageshow', () => this.syncAllConditionalReveals());\n this.syncAllConditionalReveals();\n this.$root.addEventListener('click', event => this.handleClick(event));\n }\n syncAllConditionalReveals() {\n this.$inputs.forEach($input => this.syncConditionalRevealWithInputState($input));\n }\n syncConditionalRevealWithInputState($input) {\n const targetId = $input.getAttribute('aria-controls');\n if (!targetId) {\n return;\n }\n const $target = document.getElementById(targetId);\n if ($target != null && $target.classList.contains('govuk-checkboxes__conditional')) {\n const inputIsChecked = $input.checked;\n $input.setAttribute('aria-expanded', inputIsChecked.toString());\n $target.classList.toggle('govuk-checkboxes__conditional--hidden', !inputIsChecked);\n }\n }\n unCheckAllInputsExcept($input) {\n const allInputsWithSameName = document.querySelectorAll(`input[type=\"checkbox\"][name=\"${$input.name}\"]`);\n allInputsWithSameName.forEach($inputWithSameName => {\n const hasSameFormOwner = $input.form === $inputWithSameName.form;\n if (hasSameFormOwner && $inputWithSameName !== $input) {\n $inputWithSameName.checked = false;\n this.syncConditionalRevealWithInputState($inputWithSameName);\n }\n });\n }\n unCheckExclusiveInputs($input) {\n const allInputsWithSameNameAndExclusiveBehaviour = document.querySelectorAll(`input[data-behaviour=\"exclusive\"][type=\"checkbox\"][name=\"${$input.name}\"]`);\n allInputsWithSameNameAndExclusiveBehaviour.forEach($exclusiveInput => {\n const hasSameFormOwner = $input.form === $exclusiveInput.form;\n if (hasSameFormOwner) {\n $exclusiveInput.checked = false;\n this.syncConditionalRevealWithInputState($exclusiveInput);\n }\n });\n }\n handleClick(event) {\n const $clickedInput = event.target;\n if (!($clickedInput instanceof HTMLInputElement) || $clickedInput.type !== 'checkbox') {\n return;\n }\n const hasAriaControls = $clickedInput.getAttribute('aria-controls');\n if (hasAriaControls) {\n this.syncConditionalRevealWithInputState($clickedInput);\n }\n if (!$clickedInput.checked) {\n return;\n }\n const hasBehaviourExclusive = $clickedInput.getAttribute('data-behaviour') === 'exclusive';\n if (hasBehaviourExclusive) {\n this.unCheckAllInputsExcept($clickedInput);\n } else {\n this.unCheckExclusiveInputs($clickedInput);\n }\n }\n}\nCheckboxes.moduleName = 'govuk-checkboxes';\n\nexport { Checkboxes };\n//# sourceMappingURL=checkboxes.mjs.map\n","import { ConfigurableComponent } from '../../common/configuration.mjs';\nimport { setFocus, getFragmentFromUrl } from '../../common/index.mjs';\n\n/**\n * Error summary component\n *\n * Takes focus on initialisation for accessible announcement, unless disabled in\n * configuration.\n *\n * @preserve\n * @augments ConfigurableComponent<ErrorSummaryConfig>\n */\nclass ErrorSummary extends ConfigurableComponent {\n /**\n * @param {Element | null} $root - HTML element to use for error summary\n * @param {ErrorSummaryConfig} [config] - Error summary config\n */\n constructor($root, config = {}) {\n super($root, config);\n if (!this.config.disableAutoFocus) {\n setFocus(this.$root);\n }\n this.$root.addEventListener('click', event => this.handleClick(event));\n }\n handleClick(event) {\n const $target = event.target;\n if ($target && this.focusTarget($target)) {\n event.preventDefault();\n }\n }\n focusTarget($target) {\n if (!($target instanceof HTMLAnchorElement)) {\n return false;\n }\n const inputId = getFragmentFromUrl($target.href);\n if (!inputId) {\n return false;\n }\n const $input = document.getElementById(inputId);\n if (!$input) {\n return false;\n }\n const $legendOrLabel = this.getAssociatedLegendOrLabel($input);\n if (!$legendOrLabel) {\n return false;\n }\n $legendOrLabel.scrollIntoView();\n $input.focus({\n preventScroll: true\n });\n return true;\n }\n getAssociatedLegendOrLabel($input) {\n var _document$querySelect;\n const $fieldset = $input.closest('fieldset');\n if ($fieldset) {\n const $legends = $fieldset.getElementsByTagName('legend');\n if ($legends.length) {\n const $candidateLegend = $legends[0];\n if ($input instanceof HTMLInputElement && ($input.type === 'checkbox' || $input.type === 'radio')) {\n return $candidateLegend;\n }\n const legendTop = $candidateLegend.getBoundingClientRect().top;\n const inputRect = $input.getBoundingClientRect();\n if (inputRect.height && window.innerHeight) {\n const inputBottom = inputRect.top + inputRect.height;\n if (inputBottom - legendTop < window.innerHeight / 2) {\n return $candidateLegend;\n }\n }\n }\n }\n return (_document$querySelect = document.querySelector(`label[for='${$input.getAttribute('id')}']`)) != null ? _document$querySelect : $input.closest('label');\n }\n}\n\n/**\n * Error summary config\n *\n * @typedef {object} ErrorSummaryConfig\n * @property {boolean} [disableAutoFocus=false] - If set to `true` the error\n * summary will not be focussed when the page loads.\n */\n\n/**\n * @import { Schema } from '../../common/configuration.mjs'\n */\nErrorSummary.moduleName = 'govuk-error-summary';\nErrorSummary.defaults = Object.freeze({\n disableAutoFocus: false\n});\nErrorSummary.schema = Object.freeze({\n properties: {\n disableAutoFocus: {\n type: 'boolean'\n }\n }\n});\n\nexport { ErrorSummary };\n//# sourceMappingURL=error-summary.mjs.map\n","import { closestAttributeValue } from '../../common/closest-attribute-value.mjs';\nimport { ConfigurableComponent } from '../../common/configuration.mjs';\nimport { ElementError } from '../../errors/index.mjs';\nimport { I18n } from '../../i18n.mjs';\n\n/**\n * Password input component\n *\n * @preserve\n * @augments ConfigurableComponent<PasswordInputConfig>\n */\nclass PasswordInput extends ConfigurableComponent {\n /**\n * @param {Element | null} $root - HTML element to use for password input\n * @param {PasswordInputConfig} [config] - Password input config\n */\n constructor($root, config = {}) {\n super($root, config);\n this.i18n = void 0;\n this.$input = void 0;\n this.$showHideButton = void 0;\n this.$screenReaderStatusMessage = void 0;\n const $input = this.$root.querySelector('.govuk-js-password-input-input');\n if (!($input instanceof HTMLInputElement)) {\n throw new ElementError({\n component: PasswordInput,\n element: $input,\n expectedType: 'HTMLInputElement',\n identifier: 'Form field (`.govuk-js-password-input-input`)'\n });\n }\n if ($input.type !== 'password') {\n throw new ElementError('Password input: Form field (`.govuk-js-password-input-input`) must be of type `password`.');\n }\n const $showHideButton = this.$root.querySelector('.govuk-js-password-input-toggle');\n if (!($showHideButton instanceof HTMLButtonElement)) {\n throw new ElementError({\n component: PasswordInput,\n element: $showHideButton,\n expectedType: 'HTMLButtonElement',\n identifier: 'Button (`.govuk-js-password-input-toggle`)'\n });\n }\n if ($showHideButton.type !== 'button') {\n throw new ElementError('Password input: Button (`.govuk-js-password-input-toggle`) must be of type `button`.');\n }\n this.$input = $input;\n this.$showHideButton = $showHideButton;\n this.i18n = new I18n(this.config.i18n, {\n locale: closestAttributeValue(this.$root, 'lang')\n });\n this.$showHideButton.removeAttribute('hidden');\n const $screenReaderStatusMessage = document.createElement('div');\n $screenReaderStatusMessage.className = 'govuk-password-input__sr-status govuk-visually-hidden';\n $screenReaderStatusMessage.setAttribute('aria-live', 'polite');\n this.$screenReaderStatusMessage = $screenReaderStatusMessage;\n this.$input.insertAdjacentElement('afterend', $screenReaderStatusMessage);\n this.$showHideButton.addEventListener('click', this.toggle.bind(this));\n if (this.$input.form) {\n this.$input.form.addEventListener('submit', () => this.hide());\n }\n window.addEventListener('pageshow', event => {\n if (event.persisted && this.$input.type !== 'password') {\n this.hide();\n }\n });\n this.hide();\n }\n toggle(event) {\n event.preventDefault();\n if (this.$input.type === 'password') {\n this.show();\n return;\n }\n this.hide();\n }\n show() {\n this.setType('text');\n }\n hide() {\n this.setType('password');\n }\n setType(type) {\n if (type === this.$input.type) {\n return;\n }\n this.$input.setAttribute('type', type);\n const isHidden = type === 'password';\n const prefixButton = isHidden ? 'show' : 'hide';\n const prefixStatus = isHidden ? 'passwordHidden' : 'passwordShown';\n this.$showHideButton.innerText = this.i18n.t(`${prefixButton}Password`);\n this.$showHideButton.setAttribute('aria-label', this.i18n.t(`${prefixButton}PasswordAriaLabel`));\n this.$screenReaderStatusMessage.innerText = this.i18n.t(`${prefixStatus}Announcement`);\n }\n}\n\n/**\n * Password input config\n *\n * @typedef {object} PasswordInputConfig\n * @property {PasswordInputTranslations} [i18n=PasswordInput.defaults.i18n] - Password input translations\n */\n\n/**\n * Password input translations\n *\n * @see {@link PasswordInput.defaults.i18n}\n * @typedef {object} PasswordInputTranslations\n *\n * Messages displayed to the user indicating the state of the show/hide toggle.\n * @property {string} [showPassword] - Visible text of the button when the\n * password is currently hidden. Plain text only.\n * @property {string} [hidePassword] - Visible text of the button when the\n * password is currently visible. Plain text only.\n * @property {string} [showPasswordAriaLabel] - aria-label of the button when\n * the password is currently hidden. Plain text only.\n * @property {string} [hidePasswordAriaLabel] - aria-label of the button when\n * the password is currently visible. Plain text only.\n * @property {string} [passwordShownAnnouncement] - Screen reader\n * announcement to make when the password has just become visible.\n * Plain text only.\n * @property {string} [passwordHiddenAnnouncement] - Screen reader\n * announcement to make when the password has just been hidden.\n * Plain text only.\n */\n\n/**\n * @import { Schema } from '../../common/configuration.mjs'\n */\nPasswordInput.moduleName = 'govuk-password-input';\nPasswordInput.defaults = Object.freeze({\n i18n: {\n showPassword: 'Show',\n hidePassword: 'Hide',\n showPasswordAriaLabel: 'Show password',\n hidePasswordAriaLabel: 'Hide password',\n passwordShownAnnouncement: 'Your password is visible',\n passwordHiddenAnnouncement: 'Your password is hidden'\n }\n});\nPasswordInput.schema = Object.freeze({\n properties: {\n i18n: {\n type: 'object'\n }\n }\n});\n\nexport { PasswordInput };\n//# sourceMappingURL=password-input.mjs.map\n","import { Component } from '../../component.mjs';\nimport { ElementError } from '../../errors/index.mjs';\n\n/**\n * Radios component\n *\n * @preserve\n */\nclass Radios extends Component {\n /**\n * Radios can be associated with a 'conditionally revealed' content block –\n * for example, a radio for 'Phone' could reveal an additional form field for\n * the user to enter their phone number.\n *\n * These associations are made using a `data-aria-controls` attribute, which\n * is promoted to an aria-controls attribute during initialisation.\n *\n * We also need to restore the state of any conditional reveals on the page\n * (for example if the user has navigated back), and set up event handlers to\n * keep the reveal in sync with the radio state.\n *\n * @param {Element | null} $root - HTML element to use for radios\n */\n constructor($root) {\n super($root);\n this.$inputs = void 0;\n const $inputs = this.$root.querySelectorAll('input[type=\"radio\"]');\n if (!$inputs.length) {\n throw new ElementError({\n component: Radios,\n identifier: 'Form inputs (`<input type=\"radio\">`)'\n });\n }\n this.$inputs = $inputs;\n this.$inputs.forEach($input => {\n const targetId = $input.getAttribute('data-aria-controls');\n if (!targetId) {\n return;\n }\n if (!document.getElementById(targetId)) {\n throw new ElementError({\n component: Radios,\n identifier: `Conditional reveal (\\`id=\"${targetId}\"\\`)`\n });\n }\n $input.setAttribute('aria-controls', targetId);\n $input.removeAttribute('data-aria-controls');\n });\n window.addEventListener('pageshow', () => this.syncAllConditionalReveals());\n this.syncAllConditionalReveals();\n this.$root.addEventListener('click', event => this.handleClick(event));\n }\n syncAllConditionalReveals() {\n this.$inputs.forEach($input => this.syncConditionalRevealWithInputState($input));\n }\n syncConditionalRevealWithInputState($input) {\n const targetId = $input.getAttribute('aria-controls');\n if (!targetId) {\n return;\n }\n const $target = document.getElementById(targetId);\n if ($target != null && $target.classList.contains('govuk-radios__conditional')) {\n const inputIsChecked = $input.checked;\n $input.setAttribute('aria-expanded', inputIsChecked.toString());\n $target.classList.toggle('govuk-radios__conditional--hidden', !inputIsChecked);\n }\n }\n handleClick(event) {\n const $clickedInput = event.target;\n if (!($clickedInput instanceof HTMLInputElement) || $clickedInput.type !== 'radio') {\n return;\n }\n const $allInputs = document.querySelectorAll('input[type=\"radio\"][aria-controls]');\n const $clickedInputForm = $clickedInput.form;\n const $clickedInputName = $clickedInput.name;\n $allInputs.forEach($input => {\n const hasSameFormOwner = $input.form === $clickedInputForm;\n const hasSameName = $input.name === $clickedInputName;\n if (hasSameName && hasSameFormOwner) {\n this.syncConditionalRevealWithInputState($input);\n }\n });\n }\n}\nRadios.moduleName = 'govuk-radios';\n\nexport { Radios };\n//# sourceMappingURL=radios.mjs.map\n","import { Controller } from \"@hotwired/stimulus\";\n\nexport default class FileFieldController extends Controller {\n static targets = [\"preview\", \"destroy\"];\n static values = {\n mimeTypes: Array,\n };\n\n connect() {\n this.counter = 0;\n this.initialPreviewContent = null;\n this.onUploadFlag = false;\n }\n\n onUpload(event) {\n this.onUploadFlag = true;\n\n // Set the file to be destroyed only if it is already persisted\n if (this.hasDestroyTarget) {\n this.destroyTarget.value = false;\n }\n this.previewTarget.removeAttribute(\"hidden\");\n\n // Show preview only if a file has been selected in the file picker popup. If cancelled, show previous file or do\n // not show preview at all\n if (this.hasPreviewTarget) {\n if (event.currentTarget.files.length > 0) {\n this.showPreview(event.currentTarget.files[0]);\n } else {\n this.setPreviewContent(this.initialPreviewContent);\n }\n }\n }\n\n setDestroy(event) {\n event.preventDefault();\n\n // If the data is already persisted and another image has been picked from the file picker popup, but the new image\n // is removed, show the original image\n if (this.initialPreviewContent && this.onUploadFlag) {\n this.onUploadFlag = false;\n this.setPreviewContent(this.initialPreviewContent);\n } else {\n // Set image to be destroyed, hide preview and remove image url\n if (this.hasDestroyTarget) {\n this.destroyTarget.value = true;\n }\n if (this.hasPreviewTarget) {\n this.previewTarget.setAttribute(\"hidden\", \"\");\n this.setPreviewContent(\"\");\n }\n if (this.previousInput) {\n this.previousInput.toggleAttribute(\"disabled\", true);\n }\n }\n\n this.fileInput.value = \"\";\n }\n\n setPreviewContent(content) {\n if (this.filenameTag) {\n this.filenameTag.innerText = text;\n }\n }\n\n drop(event) {\n event.preventDefault();\n\n const file = this.fileForEvent(event, this.mimeTypesValue);\n if (file) {\n const dT = new DataTransfer();\n dT.items.add(file);\n this.fileInput.files = dT.files;\n this.fileInput.dispatchEvent(new Event(\"change\"));\n }\n\n this.counter = 0;\n this.element.classList.remove(\"droppable\");\n }\n\n dragover(event) {\n event.preventDefault();\n }\n\n dragenter(event) {\n event.preventDefault();\n\n if (this.counter === 0) {\n this.element.classList.add(\"droppable\");\n }\n this.counter++;\n }\n\n dragleave(event) {\n event.preventDefault();\n\n this.counter--;\n if (this.counter === 0) {\n this.element.classList.remove(\"droppable\");\n }\n }\n\n get fileInput() {\n return this.element.querySelector(\"input[type='file']\");\n }\n\n get previousInput() {\n return this.element.querySelector(\n `input[type='hidden'][name='${this.fileInput.name}']`,\n );\n }\n\n get filenameTag() {\n if (!this.hasPreviewTarget) return null;\n\n return this.previewTarget.querySelector(\"p.preview-filename\");\n }\n\n showPreview(file) {\n const reader = new FileReader();\n\n reader.onload = (e) => {\n if (this.filenameTag) {\n this.filenameTag.innerText = file.name;\n }\n };\n reader.readAsDataURL(file);\n }\n\n /**\n * Given a drop event, find the first acceptable file.\n * @param event {DropEvent}\n * @param mimeTypes {String[]}\n * @returns {File}\n */\n fileForEvent(event, mimeTypes) {\n const accept = (file) => mimeTypes.indexOf(file.type) > -1;\n\n let file;\n\n if (event.dataTransfer.items) {\n const item = [...event.dataTransfer.items].find(accept);\n if (item) {\n file = item.getAsFile();\n }\n } else {\n file = [...event.dataTransfer.files].find(accept);\n }\n\n return file;\n }\n}\n","import DocumentFieldController from \"./document_field_controller\";\nimport ImageFieldController from \"./image_field_controller\";\n\nconst Definitions = [\n {\n identifier: \"govuk-document-field\",\n controllerConstructor: DocumentFieldController,\n },\n {\n identifier: \"govuk-image-field\",\n controllerConstructor: ImageFieldController,\n },\n];\n\nexport { Definitions as default };\n","import FileFieldController from \"./file_field_controller\";\n\nexport default class DocumentFieldController extends FileFieldController {\n connect() {\n super.connect();\n\n this.initialPreviewContent = this.filenameTag.text;\n }\n\n setPreviewContent(content) {\n this.filenameTag.innerText = content;\n }\n\n showPreview(file) {\n const reader = new FileReader();\n\n reader.onload = (e) => {\n if (this.filenameTag) {\n this.filenameTag.innerText = file.name;\n }\n };\n reader.readAsDataURL(file);\n }\n\n get filenameTag() {\n return this.previewTarget.querySelector(\"p.preview-filename\");\n }\n}\n","import FileFieldController from \"./file_field_controller\";\n\nexport default class ImageFieldController extends FileFieldController {\n connect() {\n super.connect();\n\n this.initialPreviewContent = this.imageTag.getAttribute(\"src\");\n }\n\n setPreviewContent(content) {\n this.imageTag.src = content;\n }\n\n showPreview(file) {\n const reader = new FileReader();\n\n reader.onload = (e) => {\n this.imageTag.src = e.target.result;\n };\n reader.readAsDataURL(file);\n }\n\n get imageTag() {\n return this.previewTarget.querySelector(\"img\");\n }\n}\n","import {\n Button,\n CharacterCount,\n Checkboxes,\n ErrorSummary,\n PasswordInput,\n Radios,\n} from \"govuk-frontend/dist/govuk/all.mjs\";\nimport { SupportError } from \"govuk-frontend/dist/govuk/errors/index.mjs\";\nimport { isSupported } from \"govuk-frontend/dist/govuk/common/index.mjs\";\n\nfunction initAll(config) {\n let _config$scope;\n config = typeof config !== \"undefined\" ? config : {};\n if (!isSupported()) {\n console.log(new SupportError());\n return;\n }\n const components = [\n [Button, config.button],\n [CharacterCount, config.characterCount],\n [Checkboxes],\n [ErrorSummary, config.errorSummary],\n [Radios],\n [PasswordInput, config.passwordInput],\n ];\n const $scope =\n (_config$scope = config.scope) != null ? _config$scope : document;\n components.forEach(([Component, config]) => {\n const $elements = $scope.querySelectorAll(\n `[data-module=\"${Component.moduleName}\"]`,\n );\n $elements.forEach(($element) => {\n try {\n \"defaults\" in Component\n ? new Component($element, config)\n : new Component($element);\n } catch (error) {\n console.log(error);\n }\n });\n });\n}\n\n// stimulus controllers\nimport controllers from \"./controllers\";\n\nexport {\n controllers as default,\n initAll,\n Button,\n CharacterCount,\n Checkboxes,\n ErrorSummary,\n PasswordInput,\n Radios,\n};\n"],"names":["isSupported","$scope","document","body","classList","contains","isObject","option","Array","isArray","formatErrorMessage","Component","message","moduleName","GOVUKFrontendError","Error","constructor","args","super","this","name","SupportError","supportMessage","HTMLScriptElement","prototype","ConfigError","ElementError","messageOrOptions","component","identifier","element","expectedType","InitError","componentOrMessage","$root","_$root","childConstructor","elementType","checkSupport","checkInitialised","setAttribute","HTMLElement","hasAttribute","isInitialised","configOverride","Symbol","for","ConfigurableComponent","param","config","_config","defaults","datasetConfig","dataset","schema","out","entries","Object","properties","entry","namespace","property","field","toString","normaliseString","type","extractConfigByNamespace","normaliseDataset","mergeConfigs","value","trimmedValue","trim","output","outputType","includes","length","isFinite","Number","configObjects","formattedConfigObject","configObject","key","keys","override","newObject","current","keyParts","split","index","I18n","translations","_config$locale","locale","documentElement","lang","t","lookupKey","options","translation","count","translationPluralForm","getPluralSuffix","match","replacePlaceholders","translationString","formatter","Intl","NumberFormat","supportedLocalesOf","undefined","replace","placeholderWithBraces","placeholderKey","hasOwnProperty","call","placeholderValue","format","hasIntlPluralRulesSupport","Boolean","window","PluralRules","preferredForm","select","selectPluralFormUsingFallbackRules","console","warn","Math","abs","floor","ruleset","getPluralRulesForLocale","pluralRules","localeShort","pluralRule","pluralRulesMap","languages","arabic","chinese","french","german","irish","russian","scottish","spanish","welsh","n","lastTwo","last","Button","debounceFormSubmitTimer","addEventListener","event","handleKeyDown","debounce","$target","target","getAttribute","preventDefault","click","preventDoubleClick","setTimeout","DEBOUNCE_TIMEOUT_IN_SECONDS","closestAttributeValue","$element","attributeName","$closestElementWithAttribute","closest","freeze","CharacterCount","configOverrides","maxlength","maxwords","_ref","_this$config$maxwords","$textarea","$visibleCountMessage","$screenReaderCountMessage","lastInputTimestamp","lastInputValue","valueChecker","i18n","maxLength","querySelector","HTMLTextAreaElement","HTMLInputElement","errors","validationErrors","conditions","required","errorMessage","every","push","validateConfig","Infinity","textareaDescriptionId","id","$textareaDescription","getElementById","$errorMessage","textContent","insertAdjacentElement","createElement","className","add","removeAttribute","bindChangeEvents","updateCountMessage","handleKeyUp","handleFocus","handleBlur","updateVisibleCountMessage","Date","now","setInterval","updateIfValueChanged","clearInterval","updateScreenReaderCountMessage","isError","toggle","isOverThreshold","getCountMessage","text","_text$match","remainingNumber","countType","formatCountMessage","translationKeySuffix","threshold","currentLength","charactersUnderLimit","one","other","charactersAtLimit","charactersOverLimit","wordsUnderLimit","wordsAtLimit","wordsOverLimit","textareaDescription","anyOf","Checkboxes","$inputs","querySelectorAll","forEach","$input","targetId","syncAllConditionalReveals","handleClick","syncConditionalRevealWithInputState","inputIsChecked","checked","unCheckAllInputsExcept","$inputWithSameName","form","unCheckExclusiveInputs","$exclusiveInput","$clickedInput","ErrorSummary","disableAutoFocus","_options$onBeforeFocu","isFocusable","onBlur","_options$onBlur","once","onBeforeFocus","focus","setFocus","focusTarget","HTMLAnchorElement","inputId","url","pop","getFragmentFromUrl","href","$legendOrLabel","getAssociatedLegendOrLabel","scrollIntoView","preventScroll","_document$querySelect","$fieldset","$legends","getElementsByTagName","$candidateLegend","legendTop","getBoundingClientRect","top","inputRect","height","innerHeight","PasswordInput","$showHideButton","$screenReaderStatusMessage","HTMLButtonElement","bind","hide","persisted","show","setType","isHidden","prefixButton","prefixStatus","innerText","showPassword","hidePassword","showPasswordAriaLabel","hidePasswordAriaLabel","passwordShownAnnouncement","passwordHiddenAnnouncement","Radios","$allInputs","$clickedInputForm","$clickedInputName","hasSameFormOwner","FileFieldController","Controller","static","mimeTypes","connect","counter","initialPreviewContent","onUploadFlag","onUpload","hasDestroyTarget","destroyTarget","previewTarget","hasPreviewTarget","currentTarget","files","showPreview","setPreviewContent","setDestroy","previousInput","toggleAttribute","fileInput","content","filenameTag","drop","file","fileForEvent","mimeTypesValue","dT","DataTransfer","items","dispatchEvent","Event","remove","dragover","dragenter","dragleave","reader","FileReader","onload","e","readAsDataURL","accept","indexOf","dataTransfer","item","find","getAsFile","Definitions","controllerConstructor","imageTag","src","result","initAll","_config$scope","log","components","button","characterCount","errorSummary","passwordInput","scope","error"],"mappings":"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","x_google_ignoreList":[0,1,2,3,4,5,6,7,8,9,10,11]}
data/config/importmap.rb CHANGED
@@ -1,8 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- pin "@hotwired/stimulus", to: "stimulus.min.js", preload: true
4
3
  pin "@katalyst/govuk-formbuilder", to: "katalyst/govuk/formbuilder.js"
5
4
 
6
- pin_all_from Katalyst::GOVUK::Formbuilder::Engine.root.join("app/assets/javascripts"),
5
+ pin_all_from Katalyst::GOVUK::FormBuilder::Engine.root.join("app/assets/javascripts"),
7
6
  # preload in tests so that we don't start clicking before controllers load
8
7
  preload: Rails.env.test?
@@ -2,7 +2,7 @@
2
2
 
3
3
  module Katalyst
4
4
  module GOVUK
5
- module Formbuilder
5
+ module FormBuilder
6
6
  module Builder
7
7
  extend ActiveSupport::Concern
8
8
 
@@ -249,6 +249,72 @@ module Katalyst
249
249
  options:, label:, hint:, form_group:, caption:, **, &).html
250
250
  end
251
251
 
252
+ # Generates a file input element for uploading documents.
253
+ #
254
+ # @example A upload field with label as a proc
255
+ # = f.govuk_document_field :data, label: -> { tag.h3('Upload your document') }
256
+ #
257
+ def govuk_document_field(attribute_name,
258
+ label: {},
259
+ caption: {},
260
+ hint: {},
261
+ form_group: {},
262
+ mime_types: config.document_mime_types,
263
+ **,
264
+ &)
265
+ Elements::Document.new(
266
+ self, object_name, attribute_name, label:, caption:, hint:, form_group:, mime_types:, **, &
267
+ ).html
268
+ end
269
+
270
+ # Generates a file input element with a preview for uploading images.
271
+ #
272
+ # @param attribute_name [Symbol] The name of the attribute
273
+ # @param hint [Hash,Proc] The content of the hint. No hint will be added if 'text' is left +nil+.
274
+ # When a +Proc+ is supplied the hint will be wrapped in a +div+ instead of a +span+
275
+ # @option hint text [String] the hint text
276
+ # @option hint kwargs [Hash] additional arguments are applied as attributes to the hint
277
+ # @param label [Hash,Proc] configures or sets the associated label content
278
+ # @option label text [String] the label text
279
+ # @option label size [String] the size of the label font, can be +xl+, +l+, +m+, +s+ or nil
280
+ # @option label tag [Symbol,String] the label's wrapper tag, intended to allow labels to act as page headings
281
+ # @option label hidden [Boolean] control the visibility of the label. Hidden labels will still be read by screen
282
+ # readers
283
+ # @option label kwargs [Hash] additional arguments are applied as attributes on the +label+ element
284
+ # @param caption [Hash] configures or sets the caption content which is inserted above the label
285
+ # @option caption text [String] the caption text
286
+ # @option caption size [String] the size of the caption, can be +xl+, +l+ or +m+. Defaults to +m+
287
+ # @option caption kwargs [Hash] additional arguments are applied as attributes on the caption +span+ element
288
+ # @option kwargs [Hash] kwargs additional arguments are applied as attributes to the +input+ element.
289
+ # @param form_group [Hash] configures the form group
290
+ # @option form_group classes [Array,String] sets the form group's classes
291
+ # @option form_group kwargs [Hash] additional attributes added to the form group
292
+ # @param & [Block] arbitrary HTML that will be rendered between the hint and the input
293
+ # @return [ActiveSupport::SafeBuffer] HTML output
294
+ #
295
+ # @example An image field with injected content
296
+ # = f.govuk_image_field :incident_image,
297
+ # label: { text: 'Attach a picture of the incident' } do
298
+ #
299
+ # p.govuk-inset-text
300
+ # | If you don't know exactly leave this section blank
301
+ #
302
+ # @example A image upload field with label as a proc
303
+ # = f.govuk_image_field :image, label: -> { tag.h3('Upload your image') }
304
+ #
305
+ def govuk_image_field(attribute_name,
306
+ label: {},
307
+ caption: {},
308
+ hint: {},
309
+ form_group: {},
310
+ mime_types: config.image_mime_types,
311
+ **,
312
+ &)
313
+ Elements::Image.new(
314
+ self, object_name, attribute_name, label:, caption:, hint:, form_group:, mime_types:, **, &
315
+ ).html
316
+ end
317
+
252
318
  # Keep track of whether we are inside a fieldset
253
319
  # This allows labels to default to bold ("s") normally but use the default otherwise
254
320
  def fieldset_context
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "active_support/configurable"
4
+
5
+ module Katalyst
6
+ module GOVUK
7
+ module FormBuilder
8
+ module Config
9
+ extend ActiveSupport::Concern
10
+
11
+ included do
12
+ config_accessor(:document_mime_types) do
13
+ %w[image/png image/gif image/jpeg image/webp application/pdf audio/*].freeze
14
+ end
15
+
16
+ config_accessor(:image_mime_types) do
17
+ %w[image/png image/gif image/jpeg image/webp].freeze
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
@@ -2,7 +2,7 @@
2
2
 
3
3
  module Katalyst
4
4
  module GOVUK
5
- module Formbuilder
5
+ module FormBuilder
6
6
  module Containers
7
7
  module FieldsetContext
8
8
  def initialize(builder, object_name = nil, attribute_name = nil, &)
@@ -4,7 +4,7 @@ require "govuk_design_system_formbuilder"
4
4
 
5
5
  module Katalyst
6
6
  module GOVUK
7
- module Formbuilder
7
+ module FormBuilder
8
8
  module Elements
9
9
  class Combobox < GOVUKDesignSystemFormBuilder::Base
10
10
  include GOVUKDesignSystemFormBuilder::Traits::Error
@@ -0,0 +1,68 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "govuk_design_system_formbuilder"
4
+
5
+ module Katalyst
6
+ module GOVUK
7
+ module FormBuilder
8
+ module Elements
9
+ class Document < GOVUKDesignSystemFormBuilder::Base
10
+ include ActionDispatch::Routing::RouteSet::MountedHelpers
11
+
12
+ include GOVUKDesignSystemFormBuilder::Traits::Error
13
+ include GOVUKDesignSystemFormBuilder::Traits::Hint
14
+ include GOVUKDesignSystemFormBuilder::Traits::Label
15
+ include GOVUKDesignSystemFormBuilder::Traits::Supplemental
16
+ include GOVUKDesignSystemFormBuilder::Traits::HTMLAttributes
17
+ include GOVUKDesignSystemFormBuilder::Traits::HTMLClasses
18
+
19
+ include FormBuilder::Traits::File
20
+
21
+ def initialize(builder, object_name, attribute_name, hint:, label:, caption:, form_group:, mime_types:,
22
+ **kwargs, &)
23
+ super(builder, object_name, attribute_name, &)
24
+
25
+ @mime_types = mime_types
26
+ @label = label
27
+ @caption = caption
28
+ @hint = hint
29
+ @html_attributes = kwargs.merge(file_input_options)
30
+ @form_group = form_group
31
+ end
32
+
33
+ def html
34
+ GOVUKDesignSystemFormBuilder::Containers::FormGroup.new(
35
+ *bound,
36
+ **default_form_group_options(**@form_group),
37
+ ).html do
38
+ safe_join([label_element, preview, hint_element, error_element, file, destroy_element,
39
+ supplemental_content])
40
+ end
41
+ end
42
+
43
+ def preview
44
+ options = {}
45
+ add_option(options, :data, "#{stimulus_controller}_target", "preview")
46
+ add_option(options, :class, "preview-file")
47
+ options[:hidden] = "" unless preview?
48
+
49
+ tag.div(**options) do
50
+ filename = @builder.object.send(@attribute_name).filename.to_s
51
+ tag.p(filename, class: "preview-filename") + destroy_element_trigger
52
+ end
53
+ end
54
+
55
+ private
56
+
57
+ def stimulus_controller
58
+ "govuk-document-field"
59
+ end
60
+
61
+ def form_group_class
62
+ "govuk-document-field"
63
+ end
64
+ end
65
+ end
66
+ end
67
+ end
68
+ end