@abgov/ui-components-common 1.6.0 → 1.7.0-alpha.1

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.
package/index.cjs CHANGED
@@ -1 +1 @@
1
- "use strict";var M=Object.defineProperty;var y=r=>{throw TypeError(r)};var S=(r,t,e)=>t in r?M(r,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):r[t]=e;var d=(r,t,e)=>S(r,typeof t!="symbol"?t+"":t,e),N=(r,t,e)=>t.has(r)||y("Cannot "+e);var g=(r,t,e)=>t.has(r)?y("Cannot add the same private member more than once"):t instanceof WeakSet?t.add(r):t.set(r,e);var V=(r,t,e)=>(N(r,t,"access private method"),e);Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});class w{constructor(t){d(this,"validators");this.validators=t||{}}add(t,...e){this.validators[t]=e}validate(t){const e={};return Object.entries(this.validators).forEach(([a,i])=>{const n=i.map(s=>s(t[a])).find(s=>!!s);n&&(e[a]=n)}),e}}function D(){return[c("Day is required"),m({min:1,max:31,minMsg:"Day must be between 1 and 31",maxMsg:"Day must be between 1 and 31"})]}function E(){return[c("Month is required"),m({min:0,max:11,minMsg:"Month must be between Jan and Dec",maxMsg:"Month must be between Jan and Dec"})]}function _(){const r=new Date().getFullYear();return[c("Year is required"),m({min:1900,max:r,minMsg:"Year must be greater than 1900",maxMsg:`Year must be less than ${r}`})]}function c(r){return t=>(r=r||"Required",typeof t=="number"&&!isNaN(t)||t?"":r)}function R(r){const t=new RegExp(/^\+?[\d-() ]{10,18}$/);return h(t,r||"Invalid phone number")}function I(r){const t=new RegExp(/^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/);return h(t,r||"Invalid email address")}function $(){return r=>{if(!r)return"";const t="121212121".split("").map(i=>parseInt(i)),e=r.replace(/\D/g,"");return e.length!==9?"SIN must contain 9 numbers":e.split("").map(i=>parseInt(i)).map((i,n)=>{const s=i*t[n];return s<10?s:`${s}`.split("").map(u=>parseInt(u)).reduce((u,l)=>u+l,0)}).reduce((i,n)=>i+n,0)%10===0?"":"Invalid SIN"}}function x(){return h(/^[ABCEGHJ-NPRSTVXY]\d[ABCEGHJ-NPRSTV-Z][ -]?\d[ABCEGHJ-NPRSTV-Z]\d$/i,"Invalid postal code")}function h(r,t){return e=>!e||e.match(r)?"":t}function C({invalidMsg:r,minMsg:t,maxMsg:e,min:a,max:i}={}){return n=>{let s=new Date(-1);return`${n||""}`.length===0?"":(typeof n=="string"&&(s=new Date(n)),typeof n=="number"&&(s=new Date(n)),n.toDateString&&(s=n),s.getDate()===-1?r||"Invalid date":a&&s<a?t||`Must be after ${a}`:i&&s>i?e||`Must be before ${i}`:"")}}function m({invalidTypeMsg:r,minMsg:t,maxMsg:e,min:a=-Number.MAX_VALUE,max:i=Number.MAX_VALUE}={}){return n=>{let s=Number.MAX_VALUE;return`${n??""}`.length===0?"":(typeof n=="string"&&(s=parseFloat(n)),typeof n=="number"&&(s=n),isNaN(s)?r||"Must be a numeric value":s>i?e||`Must be less than or equal to ${i}`:s<a?t||`Must be greater than or equal to ${a}`:"")}}function T({invalidTypeMsg:r,minMsg:t,maxMsg:e,min:a=-Number.MAX_VALUE,max:i=Number.MAX_VALUE}){return n=>`${n||""}`.length===0?"":typeof n!="string"?r||"Invalid type":n.length>i?e||`Must be less than ${i} characters`:n.length<a?t||`Must be greater than ${a} characters`:""}function L(r,t,e,a){if(!r){console.error("dispatch element is null");return}r.dispatchEvent(new CustomEvent(t,{composed:!0,bubbles:a==null?void 0:a.bubbles,detail:e}))}function o(r,t,e,a){if(!r){console.error("dispatch element is null");return}r.dispatchEvent(new CustomEvent("msg",{composed:!0,bubbles:a==null?void 0:a.bubbles,detail:{action:t,data:e}}))}var f,q,A;class U{constructor(t){g(this,f);d(this,"state");d(this,"_formData");d(this,"_formRef");this.type=t}init(t){if(this._formRef){console.warn("init: form element has already been set");return}this._formRef=t.detail.el,this.state={uuid:crypto.randomUUID(),form:{},history:[],editting:"",status:"not-started"}}initList(t){this._formRef=t.detail.el,this.state=[]}initState(t,e){o(this._formRef,"external::init:state",t),typeof t=="string"?this.state=JSON.parse(t):Array.isArray(t)||(this.state=t),e&&setTimeout(e,200)}updateListState(t){const e=t.detail;Array.isArray(e.data)&&(this.state=e.data)}updateObjectState(t){var a,i;if(Array.isArray(this.state))return;const e=t.detail;e.type==="list"?this.state={...this.state,form:{...((a=this.state)==null?void 0:a.form)||{},[e.id]:e.data}}:this.state={...this.state,...e.data,form:{...((i=this.state)==null?void 0:i.form)||{},...e.data.form},history:e.data.history}}getStateList(){return this.state?Array.isArray(this.state)?this.state.length===0?[]:this.state.map(t=>Object.values(t.form).filter(e=>{var a;return((a=e==null?void 0:e.data)==null?void 0:a.type)==="details"}).map(e=>{var a;return e.data.type==="details"&&((a=e.data)==null?void 0:a.fieldsets)||{}}).reduce((e,a)=>{for(const[i,n]of Object.entries(a))e[i]=n.value;return e},{})):(console.warn("Utils:getStateList: unable to update the state of a non-multi form type",this.state),[]):[]}getStateValue(t,e){if(Array.isArray(this.state))return console.error("getStateValue: unable to update the state of a multi form type"),"";if(!this.state)return console.error("getStateValue: state has not yet been set"),"";const a=this.state.form[t].data;return a.type!=="details"?"":a.fieldsets[e].value}continueTo(t){if(!t){console.error("continueTo [name] is undefined");return}o(this._formRef,"external::continue",{next:t})}validate(t,e,a,i){var b;const{el:n,state:s,cancelled:u}=t.detail,l=(b=s==null?void 0:s[e])==null?void 0:b.value;if(window.scrollTo({top:0,behavior:"smooth"}),u)return[!0,l];for(const v of a){const p=v(l);if(V(this,f,A).call(this,n,e,p,i),p)return[!1,""]}return[!0,l]}validateGroup(t,e,a){let i=0;const n={};for(const s of e){const[u]=this.validate(t,s,a,{grouped:!0});u&&(n[s]=!0,i++)}return[i,n]}edit(t){o(this._formRef,"external::alter:state",{index:t,operation:"edit"})}remove(t){o(this._formRef,"external::alter:state",{index:t,operation:"remove"})}clean(t){return t.history.reduce((e,a)=>(e[a]=t.form[a],e),{})}}f=new WeakSet,q=function(t){var e;Array.isArray(t.data)&&(Array.isArray(this.state)||(this.state={...this.state,form:{...((e=this.state)==null?void 0:e.form)||{},[t.id]:t.data}}))},A=function(t,e,a,i){t.dispatchEvent(new CustomEvent("msg",{composed:!0,detail:{action:"external::set:error",data:{name:e,msg:a,grouped:i==null?void 0:i.grouped}}}))};const Y=["basic","success","failure"];function O(r,t){const e=crypto.randomUUID();return t={uuid:e,type:"basic",...t||{}},!t.duration&&t.type&&Y.includes(t.type)&&(t.duration="short"),o(document.body,"goa:temp-notification",{message:r,...t},{bubbles:!0}),e}function P(r){o(document.body,"goa:temp-notification:dismiss",r,{bubbles:!0})}function j(r,t){o(document.body,"goa:temp-notification:progress",{uuid:r,progress:t},{bubbles:!0})}const F={show:O,dismiss:P,setProgress:j};exports.FormValidator=w;exports.PublicFormController=U;exports.SINValidator=$;exports.TemporaryNotification=F;exports.birthDayValidator=D;exports.birthMonthValidator=E;exports.birthYearValidator=_;exports.dateValidator=C;exports.dispatch=L;exports.emailValidator=I;exports.lengthValidator=T;exports.numericValidator=m;exports.phoneNumberValidator=R;exports.postalCodeValidator=x;exports.regexValidator=h;exports.relay=o;exports.requiredValidator=c;
1
+ "use strict";var S=Object.defineProperty;var y=r=>{throw TypeError(r)};var M=(r,t,e)=>t in r?S(r,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):r[t]=e;var l=(r,t,e)=>M(r,typeof t!="symbol"?t+"":t,e),C=(r,t,e)=>t.has(r)||y("Cannot "+e);var V=(r,t,e)=>t.has(r)?y("Cannot add the same private member more than once"):t instanceof WeakSet?t.add(r):t.set(r,e);var _=(r,t,e)=>(C(r,t,"access private method"),e);Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});class N{constructor(t){l(this,"validators");this.validators=t||{}}add(t,...e){this.validators[t]=e}validate(t){const e={};return Object.entries(this.validators).forEach(([i,a])=>{const n=a.map(s=>s(t[i])).find(s=>!!s);n&&(e[i]=n)}),e}}function w(){return[c("Day is required"),h({min:1,max:31,minMsg:"Day must be between 1 and 31",maxMsg:"Day must be between 1 and 31"})]}function E(){return[c("Month is required"),h({min:0,max:11,minMsg:"Month must be between Jan and Dec",maxMsg:"Month must be between Jan and Dec"})]}function R(){const r=new Date().getFullYear();return[c("Year is required"),h({min:1900,max:r,minMsg:"Year must be greater than 1900",maxMsg:`Year must be less than ${r}`})]}function c(r){return t=>(r=r||"Required",typeof t=="number"&&!isNaN(t)||t?"":r)}function D(r){const t=new RegExp(/^\+?[\d-() ]{10,18}$/);return m(t,r||"Invalid phone number")}function I(r){const t=new RegExp(/^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/);return m(t,r||"Invalid email address")}function $(){return r=>{if(!r)return"";const t="121212121".split("").map(a=>parseInt(a)),e=r.replace(/\D/g,"");return e.length!==9?"SIN must contain 9 numbers":e.split("").map(a=>parseInt(a)).map((a,n)=>{const s=a*t[n];return s<10?s:`${s}`.split("").map(u=>parseInt(u)).reduce((u,f)=>u+f,0)}).reduce((a,n)=>a+n,0)%10===0?"":"Invalid SIN"}}function x(){return m(/^[ABCEGHJ-NPRSTVXY]\d[ABCEGHJ-NPRSTV-Z][ -]?\d[ABCEGHJ-NPRSTV-Z]\d$/i,"Invalid postal code")}function m(r,t){return e=>!e||e.match(r)?"":t}function L({invalidMsg:r,minMsg:t,maxMsg:e,min:i,max:a}={}){return n=>{let s=new Date(-1);return`${n||""}`.length===0?"":(typeof n=="string"&&(s=new Date(n)),typeof n=="number"&&(s=new Date(n)),n.toDateString&&(s=n),s.getDate()===-1?r||"Invalid date":i&&s<i?t||`Must be after ${i}`:a&&s>a?e||`Must be before ${a}`:"")}}function h({invalidTypeMsg:r,minMsg:t,maxMsg:e,min:i=-Number.MAX_VALUE,max:a=Number.MAX_VALUE}={}){return n=>{let s=Number.MAX_VALUE;return`${n??""}`.length===0?"":(typeof n=="string"&&(s=parseFloat(n)),typeof n=="number"&&(s=n),isNaN(s)?r||"Must be a numeric value":s>a?e||`Must be less than or equal to ${a}`:s<i?t||`Must be greater than or equal to ${i}`:"")}}function T({invalidTypeMsg:r,minMsg:t,maxMsg:e,min:i=-Number.MAX_VALUE,max:a=Number.MAX_VALUE}){return n=>`${n||""}`.length===0?"":typeof n!="string"?r||"Invalid type":n.length>a?e||`Must be less than ${a} characters`:n.length<i?t||`Must be greater than ${i} characters`:""}function b(r,t,e,i){if(!r){console.error("dispatch element is null");return}r.dispatchEvent(new CustomEvent(t,{composed:!0,bubbles:i==null?void 0:i.bubbles,detail:e}))}function o(r,t,e,i){if(!r){console.error("dispatch element is null");return}r.dispatchEvent(new CustomEvent("msg",{composed:!0,bubbles:i==null?void 0:i.bubbles,detail:{action:t,data:e}}))}var d,q,v;class U{constructor(t){V(this,d);l(this,"state");l(this,"_formData");l(this,"_formRef");l(this,"_isCompleting",!1);this.type=t}init(t){if(this._formRef){console.warn("init: form element has already been set");return}this._formRef=t.detail.el,this.state={uuid:crypto.randomUUID(),form:{},history:[],editting:"",status:"not-started"}}initList(t){this._formRef=t.detail.el,this.state=[]}initState(t,e){o(this._formRef,"external::init:state",t),typeof t=="string"?this.state=JSON.parse(t):Array.isArray(t)||(this.state=t),e&&setTimeout(e,200)}updateListState(t){const e=t.detail;Array.isArray(e.data)&&(this.state=e.data)}updateObjectState(t){var i,a;if(Array.isArray(this.state))return;const e=t.detail;e.type==="list"?this.state={...this.state,form:{...((i=this.state)==null?void 0:i.form)||{},[e.id]:e.data}}:this.state={...this.state,...e.data,form:{...((a=this.state)==null?void 0:a.form)||{},...e.data.form},history:e.data.history}}getStateList(){return this.state?Array.isArray(this.state)?this.state.length===0?[]:this.state.map(t=>Object.values(t.form).filter(e=>{var i;return((i=e==null?void 0:e.data)==null?void 0:i.type)==="details"}).map(e=>{var i;return e.data.type==="details"&&((i=e.data)==null?void 0:i.fieldsets)||{}}).reduce((e,i)=>{for(const[a,n]of Object.entries(i))e[a]=n.value;return e},{})):(console.warn("Utils:getStateList: unable to update the state of a non-multi form type",this.state),[]):[]}getStateValue(t,e){if(Array.isArray(this.state))return console.error("getStateValue: unable to update the state of a multi form type"),"";if(!this.state)return console.error("getStateValue: state has not yet been set"),"";const i=this.state.form[t].data;return i.type!=="details"?"":i.fieldsets[e].value}continueTo(t){if(!t){console.error("continueTo [name] is undefined");return}o(this._formRef,"external::continue",{next:t})}validate(t,e,i,a){var p;const{el:n,state:s,cancelled:u}=t.detail,f=(p=s==null?void 0:s[e])==null?void 0:p.value;if(window.scrollTo({top:0,behavior:"smooth"}),u)return[!0,f];for(const A of i){const g=A(f);if(_(this,d,v).call(this,n,e,g,a),g)return[!1,""]}return[!0,f]}validateGroup(t,e,i){let a=0;const n={};for(const s of e){const[u]=this.validate(t,s,i,{grouped:!0});u&&(n[s]=!0,a++)}return[a,n]}edit(t){o(this._formRef,"external::alter:state",{index:t,operation:"edit"})}remove(t){o(this._formRef,"external::alter:state",{index:t,operation:"remove"})}complete(){if(!this._formRef){console.error("complete: form ref is not set");return}if(this._isCompleting){console.warn("complete: completion already in progress");return}this._isCompleting=!0,o(this._formRef,"fieldset::submit",null,{bubbles:!0}),this._isCompleting=!1}completeSubform(){if(!this._formRef){console.error("completeSubform: form ref is not set");return}if(this._isCompleting){console.warn("completeSubform: completion already in progress");return}const t=this._formRef;this._isCompleting=!0;const e=i=>{t.removeEventListener("_stateChange",e),b(t,"_complete",{},{bubbles:!0}),this._isCompleting=!1};t.addEventListener("_stateChange",e),b(t,"_continue",null,{bubbles:!0})}clean(t){return t.history.reduce((e,i)=>(e[i]=t.form[i],e),{})}}d=new WeakSet,q=function(t){var e;Array.isArray(t.data)&&(Array.isArray(this.state)||(this.state={...this.state,form:{...((e=this.state)==null?void 0:e.form)||{},[t.id]:t.data}}))},v=function(t,e,i,a){t.dispatchEvent(new CustomEvent("msg",{composed:!0,detail:{action:"external::set:error",data:{name:e,msg:i,grouped:a==null?void 0:a.grouped}}}))};const Y=["basic","success","failure"];function O(r,t){const e=crypto.randomUUID();return t={uuid:e,type:"basic",...t||{}},!t.duration&&t.type&&Y.includes(t.type)&&(t.duration="short"),o(document.body,"goa:temp-notification",{message:r,...t},{bubbles:!0}),e}function P(r){o(document.body,"goa:temp-notification:dismiss",r,{bubbles:!0})}function j(r,t){o(document.body,"goa:temp-notification:progress",{uuid:r,progress:t},{bubbles:!0})}const F={show:O,dismiss:P,setProgress:j};exports.FormValidator=N;exports.PublicFormController=U;exports.SINValidator=$;exports.TemporaryNotification=F;exports.birthDayValidator=w;exports.birthMonthValidator=E;exports.birthYearValidator=R;exports.dateValidator=L;exports.dispatch=b;exports.emailValidator=I;exports.lengthValidator=T;exports.numericValidator=h;exports.phoneNumberValidator=D;exports.postalCodeValidator=x;exports.regexValidator=m;exports.relay=o;exports.requiredValidator=c;
package/index.js CHANGED
@@ -1,11 +1,11 @@
1
- var M = Object.defineProperty;
2
- var y = (r) => {
1
+ var S = Object.defineProperty;
2
+ var g = (r) => {
3
3
  throw TypeError(r);
4
4
  };
5
- var S = (r, t, e) => t in r ? M(r, t, { enumerable: !0, configurable: !0, writable: !0, value: e }) : r[t] = e;
6
- var l = (r, t, e) => S(r, typeof t != "symbol" ? t + "" : t, e), w = (r, t, e) => t.has(r) || y("Cannot " + e);
7
- var g = (r, t, e) => t.has(r) ? y("Cannot add the same private member more than once") : t instanceof WeakSet ? t.add(r) : t.set(r, e);
8
- var A = (r, t, e) => (w(r, t, "access private method"), e);
5
+ var M = (r, t, e) => t in r ? S(r, t, { enumerable: !0, configurable: !0, writable: !0, value: e }) : r[t] = e;
6
+ var l = (r, t, e) => M(r, typeof t != "symbol" ? t + "" : t, e), w = (r, t, e) => t.has(r) || g("Cannot " + e);
7
+ var y = (r, t, e) => t.has(r) ? g("Cannot add the same private member more than once") : t instanceof WeakSet ? t.add(r) : t.set(r, e);
8
+ var _ = (r, t, e) => (w(r, t, "access private method"), e);
9
9
  class x {
10
10
  constructor(t) {
11
11
  l(this, "validators");
@@ -16,16 +16,16 @@ class x {
16
16
  }
17
17
  validate(t) {
18
18
  const e = {};
19
- return Object.entries(this.validators).forEach(([a, n]) => {
20
- const i = n.map((s) => s(t[a])).find((s) => !!s);
21
- i && (e[a] = i);
19
+ return Object.entries(this.validators).forEach(([n, i]) => {
20
+ const a = i.map((s) => s(t[n])).find((s) => !!s);
21
+ a && (e[n] = a);
22
22
  }), e;
23
23
  }
24
24
  }
25
25
  function I() {
26
26
  return [
27
27
  c("Day is required"),
28
- m({
28
+ h({
29
29
  min: 1,
30
30
  max: 31,
31
31
  minMsg: "Day must be between 1 and 31",
@@ -36,7 +36,7 @@ function I() {
36
36
  function L() {
37
37
  return [
38
38
  c("Month is required"),
39
- m({
39
+ h({
40
40
  min: 0,
41
41
  max: 11,
42
42
  minMsg: "Month must be between Jan and Dec",
@@ -48,7 +48,7 @@ function U() {
48
48
  const r = (/* @__PURE__ */ new Date()).getFullYear();
49
49
  return [
50
50
  c("Year is required"),
51
- m({
51
+ h({
52
52
  min: 1900,
53
53
  max: r,
54
54
  minMsg: "Year must be greater than 1900",
@@ -59,69 +59,69 @@ function U() {
59
59
  function c(r) {
60
60
  return (t) => (r = r || "Required", typeof t == "number" && !isNaN(t) || t ? "" : r);
61
61
  }
62
- function C(r) {
62
+ function T(r) {
63
63
  const t = new RegExp(/^\+?[\d-() ]{10,18}$/);
64
- return h(t, r || "Invalid phone number");
64
+ return m(t, r || "Invalid phone number");
65
65
  }
66
- function T(r) {
66
+ function q(r) {
67
67
  const t = new RegExp(
68
68
  /^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/
69
69
  );
70
- return h(t, r || "Invalid email address");
70
+ return m(t, r || "Invalid email address");
71
71
  }
72
- function q() {
72
+ function Y() {
73
73
  return (r) => {
74
74
  if (!r) return "";
75
- const t = "121212121".split("").map((n) => parseInt(n)), e = r.replace(/\D/g, "");
76
- return e.length !== 9 ? "SIN must contain 9 numbers" : e.split("").map((n) => parseInt(n)).map((n, i) => {
77
- const s = n * t[i];
78
- return s < 10 ? s : `${s}`.split("").map((o) => parseInt(o)).reduce((o, f) => o + f, 0);
79
- }).reduce((n, i) => n + i, 0) % 10 === 0 ? "" : "Invalid SIN";
75
+ const t = "121212121".split("").map((i) => parseInt(i)), e = r.replace(/\D/g, "");
76
+ return e.length !== 9 ? "SIN must contain 9 numbers" : e.split("").map((i) => parseInt(i)).map((i, a) => {
77
+ const s = i * t[a];
78
+ return s < 10 ? s : `${s}`.split("").map((u) => parseInt(u)).reduce((u, f) => u + f, 0);
79
+ }).reduce((i, a) => i + a, 0) % 10 === 0 ? "" : "Invalid SIN";
80
80
  };
81
81
  }
82
- function Y() {
83
- return h(
82
+ function J() {
83
+ return m(
84
84
  /^[ABCEGHJ-NPRSTVXY]\d[ABCEGHJ-NPRSTV-Z][ -]?\d[ABCEGHJ-NPRSTV-Z]\d$/i,
85
85
  "Invalid postal code"
86
86
  );
87
87
  }
88
- function h(r, t) {
88
+ function m(r, t) {
89
89
  return (e) => !e || e.match(r) ? "" : t;
90
90
  }
91
- function J({
91
+ function O({
92
92
  invalidMsg: r,
93
93
  minMsg: t,
94
94
  maxMsg: e,
95
- min: a,
96
- max: n
95
+ min: n,
96
+ max: i
97
97
  } = {}) {
98
- return (i) => {
98
+ return (a) => {
99
99
  let s = /* @__PURE__ */ new Date(-1);
100
- return `${i || ""}`.length === 0 ? "" : (typeof i == "string" && (s = new Date(i)), typeof i == "number" && (s = new Date(i)), i.toDateString && (s = i), s.getDate() === -1 ? r || "Invalid date" : a && s < a ? t || `Must be after ${a}` : n && s > n ? e || `Must be before ${n}` : "");
100
+ return `${a || ""}`.length === 0 ? "" : (typeof a == "string" && (s = new Date(a)), typeof a == "number" && (s = new Date(a)), a.toDateString && (s = a), s.getDate() === -1 ? r || "Invalid date" : n && s < n ? t || `Must be after ${n}` : i && s > i ? e || `Must be before ${i}` : "");
101
101
  };
102
102
  }
103
- function m({
103
+ function h({
104
104
  invalidTypeMsg: r,
105
105
  minMsg: t,
106
106
  maxMsg: e,
107
- min: a = -Number.MAX_VALUE,
108
- max: n = Number.MAX_VALUE
107
+ min: n = -Number.MAX_VALUE,
108
+ max: i = Number.MAX_VALUE
109
109
  } = {}) {
110
- return (i) => {
110
+ return (a) => {
111
111
  let s = Number.MAX_VALUE;
112
- return `${i ?? ""}`.length === 0 ? "" : (typeof i == "string" && (s = parseFloat(i)), typeof i == "number" && (s = i), isNaN(s) ? r || "Must be a numeric value" : s > n ? e || `Must be less than or equal to ${n}` : s < a ? t || `Must be greater than or equal to ${a}` : "");
112
+ return `${a ?? ""}`.length === 0 ? "" : (typeof a == "string" && (s = parseFloat(a)), typeof a == "number" && (s = a), isNaN(s) ? r || "Must be a numeric value" : s > i ? e || `Must be less than or equal to ${i}` : s < n ? t || `Must be greater than or equal to ${n}` : "");
113
113
  };
114
114
  }
115
- function O({
115
+ function X({
116
116
  invalidTypeMsg: r,
117
117
  minMsg: t,
118
118
  maxMsg: e,
119
- min: a = -Number.MAX_VALUE,
120
- max: n = Number.MAX_VALUE
119
+ min: n = -Number.MAX_VALUE,
120
+ max: i = Number.MAX_VALUE
121
121
  }) {
122
- return (i) => `${i || ""}`.length === 0 ? "" : typeof i != "string" ? r || "Invalid type" : i.length > n ? e || `Must be less than ${n} characters` : i.length < a ? t || `Must be greater than ${a} characters` : "";
122
+ return (a) => `${a || ""}`.length === 0 ? "" : typeof a != "string" ? r || "Invalid type" : a.length > i ? e || `Must be less than ${i} characters` : a.length < n ? t || `Must be greater than ${n} characters` : "";
123
123
  }
124
- function X(r, t, e, a) {
124
+ function v(r, t, e, n) {
125
125
  if (!r) {
126
126
  console.error("dispatch element is null");
127
127
  return;
@@ -129,12 +129,12 @@ function X(r, t, e, a) {
129
129
  r.dispatchEvent(
130
130
  new CustomEvent(t, {
131
131
  composed: !0,
132
- bubbles: a == null ? void 0 : a.bubbles,
132
+ bubbles: n == null ? void 0 : n.bubbles,
133
133
  detail: e
134
134
  })
135
135
  );
136
136
  }
137
- function u(r, t, e, a) {
137
+ function o(r, t, e, n) {
138
138
  if (!r) {
139
139
  console.error("dispatch element is null");
140
140
  return;
@@ -142,7 +142,7 @@ function u(r, t, e, a) {
142
142
  r.dispatchEvent(
143
143
  new CustomEvent("msg", {
144
144
  composed: !0,
145
- bubbles: a == null ? void 0 : a.bubbles,
145
+ bubbles: n == null ? void 0 : n.bubbles,
146
146
  detail: {
147
147
  action: t,
148
148
  data: e
@@ -150,13 +150,14 @@ function u(r, t, e, a) {
150
150
  })
151
151
  );
152
152
  }
153
- var d, E, v;
153
+ var d, E, A;
154
154
  class j {
155
155
  constructor(t) {
156
- g(this, d);
156
+ y(this, d);
157
157
  l(this, "state");
158
158
  l(this, "_formData");
159
159
  l(this, "_formRef");
160
+ l(this, "_isCompleting", !1);
160
161
  this.type = t;
161
162
  }
162
163
  // Obtain reference to the form element
@@ -178,38 +179,38 @@ class j {
178
179
  }
179
180
  // Public method to allow for the initialization of the state
180
181
  initState(t, e) {
181
- u(this._formRef, "external::init:state", t), typeof t == "string" ? this.state = JSON.parse(t) : Array.isArray(t) || (this.state = t), e && setTimeout(e, 200);
182
+ o(this._formRef, "external::init:state", t), typeof t == "string" ? this.state = JSON.parse(t) : Array.isArray(t) || (this.state = t), e && setTimeout(e, 200);
182
183
  }
183
184
  updateListState(t) {
184
185
  const e = t.detail;
185
186
  Array.isArray(e.data) && (this.state = e.data);
186
187
  }
187
188
  updateObjectState(t) {
188
- var a, n;
189
+ var n, i;
189
190
  if (Array.isArray(this.state))
190
191
  return;
191
192
  const e = t.detail;
192
193
  e.type === "list" ? this.state = {
193
194
  ...this.state,
194
- form: { ...((a = this.state) == null ? void 0 : a.form) || {}, [e.id]: e.data }
195
+ form: { ...((n = this.state) == null ? void 0 : n.form) || {}, [e.id]: e.data }
195
196
  } : this.state = {
196
197
  ...this.state,
197
198
  ...e.data,
198
- form: { ...((n = this.state) == null ? void 0 : n.form) || {}, ...e.data.form },
199
+ form: { ...((i = this.state) == null ? void 0 : i.form) || {}, ...e.data.form },
199
200
  history: e.data.history
200
201
  };
201
202
  }
202
203
  getStateList() {
203
204
  return this.state ? Array.isArray(this.state) ? this.state.length === 0 ? [] : this.state.map((t) => Object.values(t.form).filter((e) => {
204
- var a;
205
- return ((a = e == null ? void 0 : e.data) == null ? void 0 : a.type) === "details";
205
+ var n;
206
+ return ((n = e == null ? void 0 : e.data) == null ? void 0 : n.type) === "details";
206
207
  }).map((e) => {
207
- var a;
208
- return e.data.type === "details" && ((a = e.data) == null ? void 0 : a.fieldsets) || {};
208
+ var n;
209
+ return e.data.type === "details" && ((n = e.data) == null ? void 0 : n.fieldsets) || {};
209
210
  }).reduce(
210
- (e, a) => {
211
- for (const [n, i] of Object.entries(a))
212
- e[n] = i.value;
211
+ (e, n) => {
212
+ for (const [i, a] of Object.entries(n))
213
+ e[i] = a.value;
213
214
  return e;
214
215
  },
215
216
  {}
@@ -243,8 +244,8 @@ class j {
243
244
  return console.error("getStateValue: unable to update the state of a multi form type"), "";
244
245
  if (!this.state)
245
246
  return console.error("getStateValue: state has not yet been set"), "";
246
- const a = this.state.form[t].data;
247
- return a.type !== "details" ? "" : a.fieldsets[e].value;
247
+ const n = this.state.form[t].data;
248
+ return n.type !== "details" ? "" : n.fieldsets[e].value;
248
249
  }
249
250
  // Public method to allow for the continuing to the next page
250
251
  continueTo(t) {
@@ -252,17 +253,17 @@ class j {
252
253
  console.error("continueTo [name] is undefined");
253
254
  return;
254
255
  }
255
- u(this._formRef, "external::continue", { next: t });
256
+ o(this._formRef, "external::continue", { next: t });
256
257
  }
257
258
  // Public method to perform validation and send the appropriate messages to the form elements
258
- validate(t, e, a, n) {
259
+ validate(t, e, n, i) {
259
260
  var b;
260
- const { el: i, state: s, cancelled: o } = t.detail, f = (b = s == null ? void 0 : s[e]) == null ? void 0 : b.value;
261
- if (window.scrollTo({ top: 0, behavior: "smooth" }), o)
261
+ const { el: a, state: s, cancelled: u } = t.detail, f = (b = s == null ? void 0 : s[e]) == null ? void 0 : b.value;
262
+ if (window.scrollTo({ top: 0, behavior: "smooth" }), u)
262
263
  return [!0, f];
263
- for (const V of a) {
264
+ for (const V of n) {
264
265
  const p = V(f);
265
- if (A(this, d, v).call(this, i, e, p, n), p)
266
+ if (_(this, d, A).call(this, a, e, p, i), p)
266
267
  return [!1, ""];
267
268
  }
268
269
  return [!0, f];
@@ -276,27 +277,86 @@ class j {
276
277
  * @param {FieldValidator[]} validators - An array of validator functions to apply to the fields.
277
278
  * @return {[number, Record<string, boolean>]} - Returns back the number of fields that passed and a record of the fields and their pass status.
278
279
  */
279
- validateGroup(t, e, a) {
280
- let n = 0;
281
- const i = {};
280
+ validateGroup(t, e, n) {
281
+ let i = 0;
282
+ const a = {};
282
283
  for (const s of e) {
283
- const [o] = this.validate(t, s, a, { grouped: !0 });
284
- o && (i[s] = !0, n++);
284
+ const [u] = this.validate(t, s, n, { grouped: !0 });
285
+ u && (a[s] = !0, i++);
285
286
  }
286
- return [n, i];
287
+ return [i, a];
287
288
  }
288
289
  edit(t) {
289
- u(this._formRef, "external::alter:state", { index: t, operation: "edit" });
290
+ o(this._formRef, "external::alter:state", { index: t, operation: "edit" });
290
291
  }
291
292
  remove(t) {
292
- u(this._formRef, "external::alter:state", {
293
+ o(this._formRef, "external::alter:state", {
293
294
  index: t,
294
295
  operation: "remove"
295
296
  });
296
297
  }
298
+ /**
299
+ * Completes the form and triggers the onComplete callback.
300
+ * This method should be used when you want to complete a form without navigating to a summary page.
301
+ *
302
+ * @important Developers must validate the form before calling this method.
303
+ *
304
+ * @example
305
+ * // Validate first, then complete
306
+ * const [isValid] = this.validate(e, "firstName", [
307
+ * requiredValidator("First name is required.")
308
+ * ]);
309
+ * if (isValid) {
310
+ * this.complete();
311
+ * }
312
+ * @returns void
313
+ */
314
+ complete() {
315
+ if (!this._formRef) {
316
+ console.error("complete: form ref is not set");
317
+ return;
318
+ }
319
+ if (this._isCompleting) {
320
+ console.warn("complete: completion already in progress");
321
+ return;
322
+ }
323
+ this._isCompleting = !0, o(this._formRef, "fieldset::submit", null, { bubbles: !0 }), this._isCompleting = !1;
324
+ }
325
+ /**
326
+ * Completes a subform and returns control to the parent form.
327
+ * This method should be used when working with subforms that need to complete without a summary page.
328
+ *
329
+ * @important Developers must validate the subform before calling this method.
330
+ *
331
+ * @example
332
+ * // Validate first, then complete the subform
333
+ * const [isValid] = this._childFormController.validate(e, "fullName", [
334
+ * requiredValidator("Please enter the dependent's full name.")
335
+ * ]);
336
+ * if (isValid) {
337
+ * this._childFormController.completeSubform();
338
+ * }
339
+ * @returns void
340
+ */
341
+ completeSubform() {
342
+ if (!this._formRef) {
343
+ console.error("completeSubform: form ref is not set");
344
+ return;
345
+ }
346
+ if (this._isCompleting) {
347
+ console.warn("completeSubform: completion already in progress");
348
+ return;
349
+ }
350
+ const t = this._formRef;
351
+ this._isCompleting = !0;
352
+ const e = (n) => {
353
+ t.removeEventListener("_stateChange", e), v(t, "_complete", {}, { bubbles: !0 }), this._isCompleting = !1;
354
+ };
355
+ t.addEventListener("_stateChange", e), v(t, "_continue", null, { bubbles: !0 });
356
+ }
297
357
  // removes any data collected that doesn't correspond with the final history path
298
358
  clean(t) {
299
- return t.history.reduce((e, a) => (e[a] = t.form[a], e), {});
359
+ return t.history.reduce((e, n) => (e[n] = t.form[n], e), {});
300
360
  }
301
361
  }
302
362
  d = new WeakSet(), E = function(t) {
@@ -309,7 +369,7 @@ d = new WeakSet(), E = function(t) {
309
369
  }
310
370
  }));
311
371
  }, // Private method to dispatch the error message to the form element
312
- v = function(t, e, a, n) {
372
+ A = function(t, e, n, i) {
313
373
  t.dispatchEvent(
314
374
  new CustomEvent("msg", {
315
375
  composed: !0,
@@ -317,33 +377,33 @@ v = function(t, e, a, n) {
317
377
  action: "external::set:error",
318
378
  data: {
319
379
  name: e,
320
- msg: a,
321
- grouped: n == null ? void 0 : n.grouped
380
+ msg: n,
381
+ grouped: i == null ? void 0 : i.grouped
322
382
  }
323
383
  }
324
384
  })
325
385
  );
326
386
  };
327
- const N = ["basic", "success", "failure"];
328
- function D(r, t) {
387
+ const R = ["basic", "success", "failure"];
388
+ function C(r, t) {
329
389
  const e = crypto.randomUUID();
330
- return t = { uuid: e, type: "basic", ...t || {} }, !t.duration && t.type && N.includes(t.type) && (t.duration = "short"), u(
390
+ return t = { uuid: e, type: "basic", ...t || {} }, !t.duration && t.type && R.includes(t.type) && (t.duration = "short"), o(
331
391
  document.body,
332
392
  "goa:temp-notification",
333
393
  { message: r, ...t },
334
394
  { bubbles: !0 }
335
395
  ), e;
336
396
  }
337
- function _(r) {
338
- u(
397
+ function N(r) {
398
+ o(
339
399
  document.body,
340
400
  "goa:temp-notification:dismiss",
341
401
  r,
342
402
  { bubbles: !0 }
343
403
  );
344
404
  }
345
- function R(r, t) {
346
- u(
405
+ function D(r, t) {
406
+ o(
347
407
  document.body,
348
408
  "goa:temp-notification:progress",
349
409
  { uuid: r, progress: t },
@@ -351,26 +411,26 @@ function R(r, t) {
351
411
  );
352
412
  }
353
413
  const G = {
354
- show: D,
355
- dismiss: _,
356
- setProgress: R
414
+ show: C,
415
+ dismiss: N,
416
+ setProgress: D
357
417
  };
358
418
  export {
359
419
  x as FormValidator,
360
420
  j as PublicFormController,
361
- q as SINValidator,
421
+ Y as SINValidator,
362
422
  G as TemporaryNotification,
363
423
  I as birthDayValidator,
364
424
  L as birthMonthValidator,
365
425
  U as birthYearValidator,
366
- J as dateValidator,
367
- X as dispatch,
368
- T as emailValidator,
369
- O as lengthValidator,
370
- m as numericValidator,
371
- C as phoneNumberValidator,
372
- Y as postalCodeValidator,
373
- h as regexValidator,
374
- u as relay,
426
+ O as dateValidator,
427
+ v as dispatch,
428
+ q as emailValidator,
429
+ X as lengthValidator,
430
+ h as numericValidator,
431
+ T as phoneNumberValidator,
432
+ J as postalCodeValidator,
433
+ m as regexValidator,
434
+ o as relay,
375
435
  c as requiredValidator
376
436
  };
@@ -29,6 +29,7 @@ export declare class PublicFormController<T> {
29
29
  state?: AppState<T> | AppState<T>[];
30
30
  _formData?: Record<string, string>;
31
31
  _formRef?: HTMLElement;
32
+ private _isCompleting;
32
33
  constructor(type: "details" | "list");
33
34
  init(e: Event): void;
34
35
  initList(e: Event): void;
@@ -53,5 +54,39 @@ export declare class PublicFormController<T> {
53
54
  validateGroup(e: Event, fields: string[], validators: FieldValidator[]): [number, Record<string, boolean>];
54
55
  edit(index: number): void;
55
56
  remove(index: number): void;
57
+ /**
58
+ * Completes the form and triggers the onComplete callback.
59
+ * This method should be used when you want to complete a form without navigating to a summary page.
60
+ *
61
+ * @important Developers must validate the form before calling this method.
62
+ *
63
+ * @example
64
+ * // Validate first, then complete
65
+ * const [isValid] = this.validate(e, "firstName", [
66
+ * requiredValidator("First name is required.")
67
+ * ]);
68
+ * if (isValid) {
69
+ * this.complete();
70
+ * }
71
+ * @returns void
72
+ */
73
+ complete(): void;
74
+ /**
75
+ * Completes a subform and returns control to the parent form.
76
+ * This method should be used when working with subforms that need to complete without a summary page.
77
+ *
78
+ * @important Developers must validate the subform before calling this method.
79
+ *
80
+ * @example
81
+ * // Validate first, then complete the subform
82
+ * const [isValid] = this._childFormController.validate(e, "fullName", [
83
+ * requiredValidator("Please enter the dependent's full name.")
84
+ * ]);
85
+ * if (isValid) {
86
+ * this._childFormController.completeSubform();
87
+ * }
88
+ * @returns void
89
+ */
90
+ completeSubform(): void;
56
91
  clean(data: AppState<T>): Record<string, unknown>;
57
92
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@abgov/ui-components-common",
3
- "version": "1.6.0",
3
+ "version": "1.7.0-alpha.1",
4
4
  "bugs": {
5
5
  "url": "https://github.com/GovAlta/ui-components/issues"
6
6
  },