@travelopia/web-components 0.7.6 → 0.8.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.
@@ -151,7 +151,7 @@ export class TPFormFieldElement extends HTMLElement {
151
151
  *
152
152
  * @return {boolean} Whether this field passed validation.
153
153
  */
154
- validate(): boolean;
154
+ validate(): Promise<boolean>;
155
155
  /**
156
156
  * Set the error message.
157
157
  *
@@ -162,6 +162,16 @@ export class TPFormFieldElement extends HTMLElement {
162
162
  * Remove the error message.
163
163
  */
164
164
  removeErrorMessage(): void;
165
+ /**
166
+ * Set the suspense message.
167
+ *
168
+ * @param {string} message Suspense message.
169
+ */
170
+ setSuspenseMessage(message?: string): void;
171
+ /**
172
+ * Remove the suspense message.
173
+ */
174
+ removeSuspenseMessage(): void;
165
175
  }
166
176
 
167
177
  /**
@@ -188,6 +198,16 @@ export class TPFormSubmitElement extends HTMLElement {
188
198
  update(): void;
189
199
  }
190
200
 
201
+ /**
202
+ * TP Form Suspense.
203
+ */
204
+ export class TPFormSuspenseElement extends HTMLElement {
205
+ }
206
+
207
+ /**
208
+ * Internal dependencies.
209
+ */
210
+ import { TPFormFieldElement } from './tp-form-field';
191
211
  /**
192
212
  * TP Form.
193
213
  */
@@ -205,13 +225,19 @@ export class TPFormElement extends HTMLElement {
205
225
  *
206
226
  * @param {Event} e Submit event.
207
227
  */
208
- protected handleFormSubmit(e: SubmitEvent): void;
228
+ protected handleFormSubmit(e: SubmitEvent): Promise<void>;
209
229
  /**
210
230
  * Validate the form.
211
231
  *
212
232
  * @return {boolean} Whether the form is valid or not.
213
233
  */
214
- validate(): boolean;
234
+ validate(): Promise<boolean>;
235
+ /**
236
+ * Validate one field.
237
+ *
238
+ * @param {HTMLElement} field Field node.
239
+ */
240
+ validateField(field: TPFormFieldElement): Promise<boolean>;
215
241
  /**
216
242
  * Reset form validation.
217
243
  */
@@ -1,2 +1,2 @@
1
- (()=>{"use strict";var t={d:(e,r)=>{for(var i in r)t.o(r,i)&&!t.o(e,i)&&Object.defineProperty(e,i,{enumerable:!0,get:r[i]})},o:(t,e)=>Object.prototype.hasOwnProperty.call(t,e),r:t=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})}},e={};t.r(e),t.d(e,{errorMessage:()=>l,name:()=>a,validator:()=>d});var r={};t.r(r),t.d(r,{errorMessage:()=>v,name:()=>u,validator:()=>m});var i={};t.r(i),t.d(i,{errorMessage:()=>b,name:()=>h,validator:()=>c});var s={};t.r(s),t.d(s,{errorMessage:()=>p,name:()=>g,validator:()=>f});var n={};t.r(n),t.d(n,{errorMessage:()=>y,name:()=>E,validator:()=>A});const o=(t="")=>{const{tpFormErrors:e}=window;return e&&""!==t&&t in e&&"string"==typeof e[t]?e[t]:""},a="required",l="This field is required",d={validate:t=>{var e,r;return null!==(r=""!==(null===(e=t.getField())||void 0===e?void 0:e.value))&&void 0!==r?r:""},getErrorMessage:()=>o(a)},u="email",v="Please enter a valid email address",m={validate:t=>{var e,r;return/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(null!==(r=null===(e=t.getField())||void 0===e?void 0:e.value)&&void 0!==r?r:"")},getErrorMessage:()=>o(u)},h="min-length",b="Must be at least %1 characters",c={validate:t=>{var e,r,i;const s=parseInt(null!==(e=t.getAttribute("min-length"))&&void 0!==e?e:"0"),n=null!==(i=null===(r=t.getField())||void 0===r?void 0:r.value)&&void 0!==i?i:"";return""===n||n.length>=s},getErrorMessage:t=>{var e;const r=o(h),i=null!==(e=t.getAttribute("min-length"))&&void 0!==e?e:"";return r.replace("%1",i)}},g="max-length",p="Must be less than %1 characters",f={validate:t=>{var e,r,i;const s=parseInt(null!==(e=t.getAttribute("max-length"))&&void 0!==e?e:"0"),n=null!==(i=null===(r=t.getField())||void 0===r?void 0:r.value)&&void 0!==i?i:"";return""===n||n.length<=s},getErrorMessage:t=>{var e;const r=o(g),i=null!==(e=t.getAttribute("max-length"))&&void 0!==e?e:"";return r.replace("%1",i)}},E="no-empty-spaces",y="This field should not contain only white-spaces",A={validate:t=>{const e=t.getField();return!!e&&(""===e.value||""!==e.value.trim())},getErrorMessage:()=>o(E)};class M extends HTMLElement{constructor(){var t;super(),this.form=this.querySelector("form"),null===(t=this.form)||void 0===t||t.addEventListener("submit",this.handleFormSubmit.bind(this))}handleFormSubmit(t){const e=this.validate();e&&"yes"!==this.getAttribute("prevent-submit")||(t.preventDefault(),t.stopImmediatePropagation());const r=this.querySelector("tp-form-submit");r&&(e?r.setAttribute("submitting","yes"):r.removeAttribute("submitting")),e&&this.dispatchEvent(new CustomEvent("submit-validation-success",{bubbles:!0}))}validate(){this.dispatchEvent(new CustomEvent("validate",{bubbles:!0}));const t=this.querySelectorAll("tp-form-field");if(!t)return this.dispatchEvent(new CustomEvent("validation-success",{bubbles:!0})),!0;let e=!0;return t.forEach((t=>{t.validate()||(e=!1)})),e?this.dispatchEvent(new CustomEvent("validation-success",{bubbles:!0})):this.dispatchEvent(new CustomEvent("validation-error",{bubbles:!0})),e}resetValidation(){const t=this.querySelectorAll("tp-form-field");if(!t)return;t.forEach((t=>{t.removeAttribute("valid"),t.removeAttribute("error")}));const e=this.querySelector("tp-form-submit");null==e||e.removeAttribute("submitting")}}class w extends HTMLElement{constructor(){super();const t=this.getField();null==t||t.addEventListener("keyup",this.handleFieldChanged.bind(this)),null==t||t.addEventListener("change",this.handleFieldChanged.bind(this))}handleFieldChanged(){(this.getAttribute("valid")||this.getAttribute("error"))&&this.validate()}static get observedAttributes(){return["valid","error"]}attributeChangedCallback(t="",e="",r=""){"valid"!==t&&"error"!==t||e===r||this.dispatchEvent(new CustomEvent("validate",{bubbles:!0})),this.update()}update(){var t;const{tpFormValidators:e}=window;if(!e)return;const r=null!==(t=this.getAttribute("error"))&&void 0!==t?t:"";""!==r&&r in e&&"function"==typeof e[r].getErrorMessage?this.setErrorMessage(e[r].getErrorMessage(this)):this.removeErrorMessage()}getField(){return this.querySelector("input,select,textarea")}validate(){const{tpFormValidators:t}=window;if(!t)return!0;if(this.offsetWidth<=0||this.offsetHeight<=0)return!0;let e=!0,r="";return this.getAttributeNames().every((i=>!(i in t)||"function"!=typeof t[i].validate||!1!==t[i].validate(this)||(e=!1,r=i,!1))),e?(this.setAttribute("valid","yes"),this.removeAttribute("error")):(this.removeAttribute("valid"),this.setAttribute("error",r)),e}setErrorMessage(t=""){const e=this.querySelector("tp-form-error");if(e)e.innerHTML=t;else{const e=document.createElement("tp-form-error");e.innerHTML=t,this.appendChild(e)}this.dispatchEvent(new CustomEvent("validation-error"))}removeErrorMessage(){var t;null===(t=this.querySelector("tp-form-error"))||void 0===t||t.remove(),this.dispatchEvent(new CustomEvent("validation-success"))}}class F extends HTMLElement{}class C extends HTMLElement{static get observedAttributes(){return["submitting-text","original-text","submitting"]}attributeChangedCallback(t="",e="",r=""){e!==r&&this.update()}update(){var t,e;const r=this.querySelector('button[type="submit"]');if(!r)return;const i=null!==(t=this.getAttribute("submitting-text"))&&void 0!==t?t:"",s=null!==(e=this.getAttribute("original-text"))&&void 0!==e?e:r.innerHTML;"yes"===this.getAttribute("submitting")?(r.setAttribute("disabled","disabled"),this.setAttribute("original-text",s),r.innerHTML=i):(r.removeAttribute("disabled"),this.removeAttribute("submitting"),this.removeAttribute("original-text"),r.innerHTML=s)}}const S=[e,r,i,s,n];window.tpFormValidators={},window.tpFormErrors={},S.forEach((({name:t,validator:e,errorMessage:r})=>{window.tpFormValidators[t]=e,window.tpFormErrors[t]=r})),customElements.define("tp-form",M),customElements.define("tp-form-field",w),customElements.define("tp-form-error",F),customElements.define("tp-form-submit",C)})();
1
+ (()=>{"use strict";var e={d:(t,s)=>{for(var r in s)e.o(s,r)&&!e.o(t,r)&&Object.defineProperty(t,r,{enumerable:!0,get:s[r]})},o:(e,t)=>Object.prototype.hasOwnProperty.call(e,t),r:e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})}},t={};e.r(t),e.d(t,{errorMessage:()=>u,name:()=>a,validator:()=>l});var s={};e.r(s),e.d(s,{errorMessage:()=>v,name:()=>d,validator:()=>h});var r={};e.r(r),e.d(r,{errorMessage:()=>m,name:()=>c,validator:()=>b});var i={};e.r(i),e.d(i,{errorMessage:()=>g,name:()=>p,validator:()=>f});var n={};e.r(n),e.d(n,{errorMessage:()=>y,name:()=>E,validator:()=>A});const o=(e="")=>{const{tpFormErrors:t}=window;return t&&""!==e&&e in t&&"string"==typeof t[e]?t[e]:""},a="required",u="This field is required",l={validate:e=>{var t,s;return null!==(s=""!==(null===(t=e.getField())||void 0===t?void 0:t.value))&&void 0!==s?s:""},getErrorMessage:()=>o(a)},d="email",v="Please enter a valid email address",h={validate:e=>{var t,s;return/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(null!==(s=null===(t=e.getField())||void 0===t?void 0:t.value)&&void 0!==s?s:"")},getErrorMessage:()=>o(d)},c="min-length",m="Must be at least %1 characters",b={validate:e=>{var t,s,r;const i=parseInt(null!==(t=e.getAttribute("min-length"))&&void 0!==t?t:"0"),n=null!==(r=null===(s=e.getField())||void 0===s?void 0:s.value)&&void 0!==r?r:"";return""===n||n.length>=i},getErrorMessage:e=>{var t;const s=o(c),r=null!==(t=e.getAttribute("min-length"))&&void 0!==t?t:"";return s.replace("%1",r)}},p="max-length",g="Must be less than %1 characters",f={validate:e=>{var t,s,r;const i=parseInt(null!==(t=e.getAttribute("max-length"))&&void 0!==t?t:"0"),n=null!==(r=null===(s=e.getField())||void 0===s?void 0:s.value)&&void 0!==r?r:"";return""===n||n.length<=i},getErrorMessage:e=>{var t;const s=o(p),r=null!==(t=e.getAttribute("max-length"))&&void 0!==t?t:"";return s.replace("%1",r)}},E="no-empty-spaces",y="This field should not contain only white-spaces",A={validate:e=>{const t=e.getField();return!!t&&(""===t.value||""!==t.value.trim())},getErrorMessage:()=>o(E)};var M=function(e,t,s,r){return new(s||(s=Promise))((function(i,n){function o(e){try{u(r.next(e))}catch(e){n(e)}}function a(e){try{u(r.throw(e))}catch(e){n(e)}}function u(e){var t;e.done?i(e.value):(t=e.value,t instanceof s?t:new s((function(e){e(t)}))).then(o,a)}u((r=r.apply(e,t||[])).next())}))};class w extends HTMLElement{constructor(){var e;super(),this.form=this.querySelector("form"),null===(e=this.form)||void 0===e||e.addEventListener("submit",this.handleFormSubmit.bind(this))}handleFormSubmit(e){var t;return M(this,void 0,void 0,(function*(){e.preventDefault(),e.stopImmediatePropagation();const s=this.querySelector("tp-form-submit");null==s||s.setAttribute("submitting","yes"),"yes"!==this.getAttribute("suspense")&&((yield this.validate())?(this.dispatchEvent(new CustomEvent("submit-validation-success",{bubbles:!0})),"yes"!==this.getAttribute("prevent-submit")&&(null===(t=this.form)||void 0===t||t.submit())):null==s||s.removeAttribute("submitting"))}))}validate(){return M(this,void 0,void 0,(function*(){this.dispatchEvent(new CustomEvent("validate",{bubbles:!0}));const e=this.querySelectorAll("tp-form-field");if(!e)return this.dispatchEvent(new CustomEvent("validation-success",{bubbles:!0})),!0;this.setAttribute("suspense","yes");let t=!0;const s=Array.from(e).map((e=>M(this,void 0,void 0,(function*(){return yield e.validate()}))));return yield Promise.all(s).then((e=>{t=e.every((e=>e))})).catch((()=>{t=!1})).finally((()=>this.removeAttribute("suspense"))),t?this.dispatchEvent(new CustomEvent("validation-success",{bubbles:!0})):this.dispatchEvent(new CustomEvent("validation-error",{bubbles:!0})),t}))}validateField(e){return M(this,void 0,void 0,(function*(){this.setAttribute("suspense","yes");const t=yield e.validate();return this.removeAttribute("suspense"),t}))}resetValidation(){const e=this.querySelectorAll("tp-form-field");if(!e)return;e.forEach((e=>{e.removeAttribute("valid"),e.removeAttribute("error"),e.removeAttribute("suspense")})),this.removeAttribute("suspense");const t=this.querySelector("tp-form-submit");null==t||t.removeAttribute("submitting")}}class S extends HTMLElement{constructor(){super();const e=this.getField();null==e||e.addEventListener("keyup",this.handleFieldChanged.bind(this)),null==e||e.addEventListener("change",this.handleFieldChanged.bind(this))}handleFieldChanged(){if("no"!==this.getAttribute("revalidate-on-change")&&(this.getAttribute("valid")||this.getAttribute("error"))){const e=this.closest("tp-form");null==e||e.validateField(this)}}static get observedAttributes(){return["valid","error","suspense"]}attributeChangedCallback(e="",t="",s=""){"valid"!==e&&"error"!==e&&"suspense"!==e||t===s||this.dispatchEvent(new CustomEvent("validate",{bubbles:!0})),this.update()}update(){var e,t,s;const{tpFormValidators:r}=window;if(!r)return;const i=null!==(e=this.getAttribute("error"))&&void 0!==e?e:"";""!==i&&i in r&&"function"==typeof r[i].getErrorMessage?this.setErrorMessage(r[i].getErrorMessage(this)):this.removeErrorMessage();const n=null!==(t=this.getAttribute("suspense"))&&void 0!==t?t:"";""!==n&&n in r&&"function"==typeof r[n].getSuspenseMessage?this.setSuspenseMessage(null===(s=r[n])||void 0===s?void 0:s.getSuspenseMessage(this)):this.removeSuspenseMessage()}getField(){return this.querySelector("input,select,textarea")}validate(){return e=this,t=void 0,r=function*(){const{tpFormValidators:e}=window;if(!e)return!0;if(this.offsetWidth<=0||this.offsetHeight<=0)return!0;let t=!0,s=null,r="";return this.getAttributeNames().every((i=>{if(i in e&&"function"==typeof e[i].validate){const n=e[i].validate(this);if(r=i,n instanceof Promise)return t=!1,this.dispatchEvent(new CustomEvent("validation-suspense-start")),s=new Promise(((e,t)=>{n.then((t=>{!0===t?(this.setAttribute("valid","yes"),this.removeAttribute("error"),e(!0)):(this.removeAttribute("valid"),this.setAttribute("error",r),e(!1)),this.dispatchEvent(new CustomEvent("validation-suspense-success"))})).catch((()=>{this.removeAttribute("valid"),this.setAttribute("error",r),this.dispatchEvent(new CustomEvent("validation-suspense-error")),t(!1)})).finally((()=>{this.removeAttribute("suspense")}))})),!1;if(!1===n)return t=!1,!1}return!0})),t?(this.setAttribute("valid","yes"),this.removeAttribute("error"),this.removeAttribute("suspense")):(this.removeAttribute("valid"),s?(this.setAttribute("suspense",r),this.removeAttribute("error")):(this.removeAttribute("suspense"),this.setAttribute("error",r))),s||t},new((s=void 0)||(s=Promise))((function(i,n){function o(e){try{u(r.next(e))}catch(e){n(e)}}function a(e){try{u(r.throw(e))}catch(e){n(e)}}function u(e){var t;e.done?i(e.value):(t=e.value,t instanceof s?t:new s((function(e){e(t)}))).then(o,a)}u((r=r.apply(e,t||[])).next())}));var e,t,s,r}setErrorMessage(e=""){const t=this.querySelector("tp-form-error");if(t)t.innerHTML=e;else{const t=document.createElement("tp-form-error");t.innerHTML=e,this.appendChild(t)}this.dispatchEvent(new CustomEvent("validation-error"))}removeErrorMessage(){var e;null===(e=this.querySelector("tp-form-error"))||void 0===e||e.remove(),this.dispatchEvent(new CustomEvent("validation-success"))}setSuspenseMessage(e=""){const t=this.querySelector("tp-form-suspense");if(t)t.innerHTML=e;else{const t=document.createElement("tp-form-suspense");t.innerHTML=e,this.appendChild(t)}}removeSuspenseMessage(){var e;null===(e=this.querySelector("tp-form-suspense"))||void 0===e||e.remove()}}class F extends HTMLElement{}class C extends HTMLElement{}class x extends HTMLElement{static get observedAttributes(){return["submitting-text","original-text","submitting"]}attributeChangedCallback(e="",t="",s=""){t!==s&&this.update()}update(){var e,t;const s=this.querySelector('button[type="submit"]');if(!s)return;const r=null!==(e=this.getAttribute("submitting-text"))&&void 0!==e?e:"",i=null!==(t=this.getAttribute("original-text"))&&void 0!==t?t:s.innerHTML;"yes"===this.getAttribute("submitting")?(s.setAttribute("disabled","disabled"),this.setAttribute("original-text",i),s.innerHTML=r):(s.removeAttribute("disabled"),this.removeAttribute("submitting"),this.removeAttribute("original-text"),s.innerHTML=i)}}const T=[t,s,r,i,n];window.tpFormValidators={},window.tpFormErrors={},window.tpFormSuspenseMessages={},T.forEach((({name:e,validator:t,errorMessage:s})=>{window.tpFormValidators[e]=t,window.tpFormErrors[e]=s})),customElements.define("tp-form",w),customElements.define("tp-form-field",S),customElements.define("tp-form-error",F),customElements.define("tp-form-suspense",C),customElements.define("tp-form-submit",x)})();
2
2
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"dist/form/index.js","mappings":"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","sources":["webpack://@travelopia/web-components/webpack/bootstrap","webpack://@travelopia/web-components/webpack/runtime/define property getters","webpack://@travelopia/web-components/webpack/runtime/hasOwnProperty shorthand","webpack://@travelopia/web-components/webpack/runtime/make namespace object","webpack://@travelopia/web-components/./src/form/utility.ts","webpack://@travelopia/web-components/./src/form/validators/required.ts","webpack://@travelopia/web-components/./src/form/validators/email.ts","webpack://@travelopia/web-components/./src/form/validators/min-length.ts","webpack://@travelopia/web-components/./src/form/validators/max-length.ts","webpack://@travelopia/web-components/./src/form/validators/no-empty-spaces.ts","webpack://@travelopia/web-components/./src/form/tp-form.ts","webpack://@travelopia/web-components/./src/form/tp-form-field.ts","webpack://@travelopia/web-components/./src/form/tp-form-error.ts","webpack://@travelopia/web-components/./src/form/tp-form-submit.ts","webpack://@travelopia/web-components/./src/form/index.ts"],"sourcesContent":["// The require scope\nvar __webpack_require__ = {};\n\n","// define getter functions for harmony exports\n__webpack_require__.d = (exports, definition) => {\n\tfor(var key in definition) {\n\t\tif(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n\t\t\tObject.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n\t\t}\n\t}\n};","__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))","// define __esModule on exports\n__webpack_require__.r = (exports) => {\n\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n\t}\n\tObject.defineProperty(exports, '__esModule', { value: true });\n};","/**\n * Get the error message based on its code.\n *\n * @param {string} error Error code.\n *\n * @return {string} The error message.\n */\nexport const getErrorMessage = ( error: string = '' ): string => {\n\t// Check if tpFormErrors exist in the window object.\n\tconst { tpFormErrors } = window;\n\n\t// If tpFormErrors does not exist.\n\tif ( ! tpFormErrors ) {\n\t\t// Return an empty string.\n\t\treturn '';\n\t}\n\n\t// Check if the error exists and has a corresponding error message.\n\tif ( '' !== error && error in tpFormErrors && 'string' === typeof tpFormErrors[ error ] ) {\n\t\t// Return the error message.\n\t\treturn tpFormErrors[ error ];\n\t}\n\n\t// Return an empty string.\n\treturn '';\n};\n","/**\n * Internal dependencies.\n */\nimport { TPFormFieldElement } from '../tp-form-field';\nimport { TPFormValidator } from '../definitions';\nimport { getErrorMessage } from '../utility';\n\n/**\n * Name.\n */\nexport const name: string = 'required';\n\n/**\n * Error message.\n */\nexport const errorMessage: string = 'This field is required';\n\n/**\n * Validator.\n */\nexport const validator: TPFormValidator = {\n\t// Validate.\n\tvalidate: ( field: TPFormFieldElement ): boolean => {\n\t\t// Check if the field is empty.\n\t\treturn '' !== field.getField()?.value ?? '';\n\t},\n\n\t// Get error message.\n\tgetErrorMessage: (): string => getErrorMessage( name ),\n};\n","/**\n * Internal dependencies.\n */\nimport { TPFormFieldElement } from '../tp-form-field';\nimport { TPFormValidator } from '../definitions';\nimport { getErrorMessage } from '../utility';\n\n/**\n * Name.\n */\nexport const name: string = 'email';\n\n/**\n * Error message.\n */\nexport const errorMessage: string = 'Please enter a valid email address';\n\n/**\n * Validator.\n */\nexport const validator: TPFormValidator = {\n\tvalidate: ( field: TPFormFieldElement ): boolean => {\n\t\t// Boolean value to determine if the field is valid or not.\n\t\treturn /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/.test( field.getField()?.value ?? '' );\n\t},\n\tgetErrorMessage: (): string => getErrorMessage( name ),\n};\n","/**\n * Internal dependencies.\n */\nimport { TPFormFieldElement } from '../tp-form-field';\nimport { TPFormValidator } from '../definitions';\nimport { getErrorMessage } from '../utility';\n\n/**\n * Name.\n */\nexport const name: string = 'min-length';\n\n/**\n * Error message.\n */\nexport const errorMessage: string = 'Must be at least %1 characters';\n\n/**\n * Validator.\n */\nexport const validator: TPFormValidator = {\n\tvalidate: ( field: TPFormFieldElement ): boolean => {\n\t\t// Get min length and value.\n\t\tconst minLength: number = parseInt( field.getAttribute( 'min-length' ) ?? '0' );\n\t\tconst value: string = field.getField()?.value ?? '';\n\n\t\t// Validate.\n\t\treturn '' === value || value.length >= minLength;\n\t},\n\tgetErrorMessage: ( field: TPFormFieldElement ): string => {\n\t\t// Get error message.\n\t\tconst error: string = getErrorMessage( name );\n\t\tconst minLength: string = field.getAttribute( 'min-length' ) ?? '';\n\n\t\t// Return error message.\n\t\treturn error.replace( '%1', minLength );\n\t},\n};\n","/**\n * Internal dependencies.\n */\nimport { TPFormFieldElement } from '../tp-form-field';\nimport { TPFormValidator } from '../definitions';\nimport { getErrorMessage } from '../utility';\n\n/**\n * Name.\n */\nexport const name: string = 'max-length';\n\n/**\n * Error message.\n */\nexport const errorMessage: string = 'Must be less than %1 characters';\n\n/**\n * Validator.\n */\nexport const validator: TPFormValidator = {\n\tvalidate: ( field: TPFormFieldElement ): boolean => {\n\t\t// Get max length and value.\n\t\tconst minLength: number = parseInt( field.getAttribute( 'max-length' ) ?? '0' );\n\t\tconst value: string = field.getField()?.value ?? '';\n\n\t\t// Validate.\n\t\treturn '' === value || value.length <= minLength;\n\t},\n\tgetErrorMessage: ( field: TPFormFieldElement ): string => {\n\t\t// Get error message.\n\t\tconst error: string = getErrorMessage( name );\n\t\tconst maxLength: string = field.getAttribute( 'max-length' ) ?? '';\n\n\t\t// Return error message.\n\t\treturn error.replace( '%1', maxLength );\n\t},\n};\n","/**\n * Internal dependencies.\n */\nimport { TPFormFieldElement } from '../tp-form-field';\nimport { TPFormValidator } from '../definitions';\nimport { getErrorMessage } from '../utility';\n\n/**\n * Name.\n */\nexport const name: string = 'no-empty-spaces';\n\n/**\n * Error message.\n */\nexport const errorMessage: string = 'This field should not contain only white-spaces';\n\n/**\n * Validator.\n */\nexport const validator: TPFormValidator = {\n\tvalidate: ( field: TPFormFieldElement ): boolean => {\n\t\t// Check if the field is empty.\n\t\tconst inputField = field.getField();\n\n\t\t// If no field is found return false.\n\t\tif ( ! inputField ) {\n\t\t\t// Return false.\n\t\t\treturn false;\n\t\t}\n\n\t\t// This case is not our concern. This is handled by `required` validator.\n\t\tif ( '' === inputField.value ) {\n\t\t\t// Return true.\n\t\t\treturn true;\n\t\t}\n\n\t\t// Return true if field is not empty.\n\t\treturn '' !== inputField.value.trim();\n\t},\n\tgetErrorMessage: (): string => getErrorMessage( name ),\n};\n","/**\n * Internal dependencies.\n */\nimport { TPFormFieldElement } from './tp-form-field';\nimport { TPFormSubmitElement } from './tp-form-submit';\n\n/**\n * TP Form.\n */\nexport class TPFormElement extends HTMLElement {\n\t/**\n\t * Properties.\n\t */\n\tprotected readonly form: HTMLFormElement | null;\n\n\t/**\n\t * Constructor.\n\t */\n\tconstructor() {\n\t\t// Initialize parent.\n\t\tsuper();\n\n\t\t// Get form.\n\t\tthis.form = this.querySelector( 'form' );\n\n\t\t// Add event listeners.\n\t\tthis.form?.addEventListener( 'submit', this.handleFormSubmit.bind( this ) );\n\t}\n\n\t/**\n\t * Handle form submission.\n\t *\n\t * @param {Event} e Submit event.\n\t */\n\tprotected handleFormSubmit( e: SubmitEvent ): void {\n\t\t// Validate the form.\n\t\tconst formValid: boolean = this.validate();\n\n\t\t// Prevent form submission if it's invalid.\n\t\tif ( ! formValid || 'yes' === this.getAttribute( 'prevent-submit' ) ) {\n\t\t\te.preventDefault();\n\t\t\te.stopImmediatePropagation();\n\t\t}\n\n\t\t// Get submit button.\n\t\tconst submit: TPFormSubmitElement | null = this.querySelector( 'tp-form-submit' );\n\n\t\t// If present.\n\t\tif ( submit ) {\n\t\t\t// Check if form is valid.\n\t\t\tif ( formValid ) {\n\t\t\t\tsubmit.setAttribute( 'submitting', 'yes' );\n\t\t\t} else {\n\t\t\t\tsubmit.removeAttribute( 'submitting' );\n\t\t\t}\n\t\t}\n\n\t\t// If form is valid then dispatch a custom 'submit-validation-success' event.\n\t\tif ( formValid ) {\n\t\t\tthis.dispatchEvent( new CustomEvent( 'submit-validation-success', { bubbles: true } ) );\n\t\t}\n\t}\n\n\t/**\n\t * Validate the form.\n\t *\n\t * @return {boolean} Whether the form is valid or not.\n\t */\n\tvalidate(): boolean {\n\t\t// Dispatch a custom 'validate' event.\n\t\tthis.dispatchEvent( new CustomEvent( 'validate', { bubbles: true } ) );\n\n\t\t// Get the form fields.\n\t\tconst fields: NodeListOf<TPFormFieldElement> | null = this.querySelectorAll( 'tp-form-field' );\n\n\t\t// If no fields are found, return true indicating validation passed.\n\t\tif ( ! fields ) {\n\t\t\tthis.dispatchEvent( new CustomEvent( 'validation-success', { bubbles: true } ) );\n\n\t\t\t// Return true indicating validation passed.\n\t\t\treturn true;\n\t\t}\n\n\t\t// Check if all fields are valid.\n\t\tlet formValid: boolean = true;\n\t\tfields.forEach( ( field: TPFormFieldElement ): void => {\n\t\t\t// Validate the field.\n\t\t\tif ( ! field.validate() ) {\n\t\t\t\tformValid = false;\n\t\t\t}\n\t\t} );\n\n\t\t// If form is valid then dispatch a custom 'validation-success' event else send a custom 'validation-error' event.\n\t\tif ( formValid ) {\n\t\t\tthis.dispatchEvent( new CustomEvent( 'validation-success', { bubbles: true } ) );\n\t\t} else {\n\t\t\tthis.dispatchEvent( new CustomEvent( 'validation-error', { bubbles: true } ) );\n\t\t}\n\n\t\t// Return whether the form is valid or not.\n\t\treturn formValid;\n\t}\n\n\t/**\n\t * Reset form validation.\n\t */\n\tresetValidation(): void {\n\t\t// Get the form fields.\n\t\tconst fields: NodeListOf<TPFormFieldElement> | null = this.querySelectorAll( 'tp-form-field' );\n\n\t\t// If no fields are found.\n\t\tif ( ! fields ) {\n\t\t\t// Exit the function.\n\t\t\treturn;\n\t\t}\n\n\t\t// Remove 'valid' and 'error' attributes from all fields.\n\t\tfields.forEach( ( field: TPFormFieldElement ): void => {\n\t\t\t// Remove 'valid' and 'error' attribute.\n\t\t\tfield.removeAttribute( 'valid' );\n\t\t\tfield.removeAttribute( 'error' );\n\t\t} );\n\n\t\t// Get submit button.\n\t\tconst submit: TPFormSubmitElement | null = this.querySelector( 'tp-form-submit' );\n\n\t\t// Remove 'submitting' attribute from submit button.\n\t\tsubmit?.removeAttribute( 'submitting' );\n\t}\n}\n","/**\n * Internal dependencies.\n */\nimport { TPFormErrorElement } from './tp-form-error';\n\n/**\n * TP Form Field.\n */\nexport class TPFormFieldElement extends HTMLElement {\n\t/**\n\t * Constructor.\n\t */\n\tconstructor() {\n\t\t// Initialize parent.\n\t\tsuper();\n\n\t\t// Get field.\n\t\tconst field = this.getField();\n\n\t\t// Add event listeners.\n\t\tfield?.addEventListener( 'keyup', this.handleFieldChanged.bind( this ) );\n\t\tfield?.addEventListener( 'change', this.handleFieldChanged.bind( this ) );\n\t}\n\n\t/**\n\t * Update validation when the field has changed.\n\t */\n\thandleFieldChanged(): void {\n\t\t// Validate the field again if 'valid' or 'error' attribute is present.\n\t\tif ( this.getAttribute( 'valid' ) || this.getAttribute( 'error' ) ) {\n\t\t\tthis.validate();\n\t\t}\n\t}\n\n\t/**\n\t * Get observed attributes.\n\t *\n\t * @return {Array} List of observed attributes.\n\t */\n\tstatic get observedAttributes(): string[] {\n\t\t// Attributes observed in the TPFormFieldElement web-component.\n\t\treturn [ 'valid', 'error' ];\n\t}\n\n\t/**\n\t * Attribute changed callback.\n\t *\n\t * @param {string} name Attribute name.\n\t * @param {string} oldValue Old value.\n\t * @param {string} newValue New value.\n\t */\n\tattributeChangedCallback( name: string = '', oldValue: string = '', newValue: string = '' ): void {\n\t\t// Check if the observed attributes 'valid' or 'error' have changed.\n\n\t\t// Dispatch a custom 'validate' event.\n\t\tif ( ( 'valid' === name || 'error' === name ) && oldValue !== newValue ) {\n\t\t\tthis.dispatchEvent( new CustomEvent( 'validate', { bubbles: true } ) );\n\t\t}\n\n\t\t// Update the component after the attribute change.\n\t\tthis.update();\n\t}\n\n\t/**\n\t * Update component.\n\t */\n\tupdate(): void {\n\t\t// Check if tpFormValidators exist in the window object.\n\t\tconst { tpFormValidators } = window;\n\n\t\t// Exit the function if validators are not available.\n\t\tif ( ! tpFormValidators ) {\n\t\t\t//Early return\n\t\t\treturn;\n\t\t}\n\n\t\t// Get the 'error' attribute value.\n\t\tconst error: string = this.getAttribute( 'error' ) ?? '';\n\n\t\t// Check if the error exists and has a corresponding error message function.\n\t\tif ( '' !== error && error in tpFormValidators && 'function' === typeof tpFormValidators[ error ].getErrorMessage ) {\n\t\t\tthis.setErrorMessage( tpFormValidators[ error ].getErrorMessage( this ) );\n\t\t} else {\n\t\t\tthis.removeErrorMessage();\n\t\t}\n\t}\n\n\t/**\n\t * Get the associated field.\n\t *\n\t * @return {HTMLElement} The associated field for this component.\n\t */\n\tgetField(): HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement | null {\n\t\t// Return the associated field by querying input, select, or textarea elements.\n\t\treturn this.querySelector( 'input,select,textarea' );\n\t}\n\n\t/**\n\t * Validate this field.\n\t *\n\t * @return {boolean} Whether this field passed validation.\n\t */\n\tvalidate(): boolean {\n\t\t// Retrieve tpFormValidators from the window object.\n\t\tconst { tpFormValidators } = window;\n\n\t\t// Exit the function if validators are not available.\n\t\tif ( ! tpFormValidators ) {\n\t\t\t// If no validators are found, return true indicating validation passed.\n\t\t\treturn true;\n\t\t}\n\n\t\t// Check if the field is visible.\n\t\tif ( this.offsetWidth <= 0 || this.offsetHeight <= 0 ) {\n\t\t\t// If the field is not visible, return true indicating validation passed.\n\t\t\treturn true;\n\t\t}\n\n\t\t// Prepare error and valid status.\n\t\tlet valid: boolean = true;\n\t\tlet error: string = '';\n\t\tconst allAttributes: string[] = this.getAttributeNames();\n\n\t\t// Traverse all attributes to see if we find a matching validator.\n\t\tallAttributes.every( ( attributeName: string ): boolean => {\n\t\t\t// Check if the attribute is a validator.\n\t\t\tif ( attributeName in tpFormValidators && 'function' === typeof tpFormValidators[ attributeName ].validate ) {\n\t\t\t\t// We found one, lets validate the field.\n\t\t\t\tconst isValid: boolean = tpFormValidators[ attributeName ].validate( this );\n\n\t\t\t\t// Looks like we found an error!\n\t\t\t\tif ( false === isValid ) {\n\t\t\t\t\tvalid = false;\n\t\t\t\t\terror = attributeName;\n\n\t\t\t\t\t// return false;\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// No error found, all good.\n\t\t\treturn true;\n\t\t} );\n\n\t\t// Check if the field is valid or not.\n\t\tif ( valid ) {\n\t\t\tthis.setAttribute( 'valid', 'yes' );\n\t\t\tthis.removeAttribute( 'error' );\n\t\t} else {\n\t\t\tthis.removeAttribute( 'valid' );\n\t\t\tthis.setAttribute( 'error', error );\n\t\t}\n\n\t\t// Return validity.\n\t\treturn valid;\n\t}\n\n\t/**\n\t * Set the error message.\n\t *\n\t * @param {string} message Error message.\n\t */\n\tsetErrorMessage( message: string = '' ): void {\n\t\t// Look for an existing tp-form-error element.\n\t\tconst error: TPFormErrorElement | null = this.querySelector( 'tp-form-error' );\n\n\t\t// If found, update its innerHTML with the error message. Otherwise, create a new tp-form-error element and append it to the component.\n\t\tif ( error ) {\n\t\t\terror.innerHTML = message;\n\t\t} else {\n\t\t\tconst errorElement: TPFormErrorElement = document.createElement( 'tp-form-error' );\n\t\t\terrorElement.innerHTML = message;\n\t\t\tthis.appendChild( errorElement );\n\t\t}\n\n\t\t// Dispatch a custom 'validation-error' event.\n\t\tthis.dispatchEvent( new CustomEvent( 'validation-error' ) );\n\t}\n\n\t/**\n\t * Remove the error message.\n\t */\n\tremoveErrorMessage(): void {\n\t\t// Find and remove the tp-form-error element.\n\t\tthis.querySelector( 'tp-form-error' )?.remove();\n\n\t\t// Dispatch a custom 'validation-success' event.\n\t\tthis.dispatchEvent( new CustomEvent( 'validation-success' ) );\n\t}\n}\n","/**\n * TP Form Error.\n */\nexport class TPFormErrorElement extends HTMLElement {\n}\n","/**\n * TP Form Submit.\n */\nexport class TPFormSubmitElement extends HTMLElement {\n\t/**\n\t * Get observed attributes.\n\t *\n\t * @return {Array} List of observed attributes.\n\t */\n\tstatic get observedAttributes(): string[] {\n\t\t// Attributes observed in the TPFormSubmitElement web-component.\n\t\treturn [ 'submitting-text', 'original-text', 'submitting' ];\n\t}\n\n\t/**\n\t * Attribute changed callback.\n\t *\n\t * @param {string} _name Attribute name.\n\t * @param {string} oldValue Old value.\n\t * @param {string} newValue New value.\n\t */\n\tattributeChangedCallback( _name: string = '', oldValue: string = '', newValue: string = '' ): void {\n\t\t// Update component if attribute has changed.\n\t\tif ( oldValue !== newValue ) {\n\t\t\tthis.update();\n\t\t}\n\t}\n\n\t/**\n\t * Update this component.\n\t */\n\tupdate(): void {\n\t\t// Get submit button.\n\t\tconst submitButton: HTMLButtonElement | null = this.querySelector( 'button[type=\"submit\"]' );\n\n\t\t// Check if we have a submit button.\n\t\tif ( ! submitButton ) {\n\t\t\t// No, we don't. Exit.\n\t\t\treturn;\n\t\t}\n\n\t\t// Prepare submit button text.\n\t\tconst submittingText: string = this.getAttribute( 'submitting-text' ) ?? '';\n\t\tconst originalText: string = this.getAttribute( 'original-text' ) ?? submitButton.innerHTML;\n\n\t\t// Check if we are submitting.\n\t\tif ( 'yes' === this.getAttribute( 'submitting' ) ) {\n\t\t\tsubmitButton.setAttribute( 'disabled', 'disabled' );\n\t\t\tthis.setAttribute( 'original-text', originalText );\n\t\t\tsubmitButton.innerHTML = submittingText;\n\t\t} else {\n\t\t\tsubmitButton.removeAttribute( 'disabled' );\n\t\t\tthis.removeAttribute( 'submitting' );\n\t\t\tthis.removeAttribute( 'original-text' );\n\t\t\tsubmitButton.innerHTML = originalText;\n\t\t}\n\t}\n}\n","/**\n * Styles.\n */\nimport './style.scss';\n\n/**\n * Validators.\n */\n\n// Import validators.\nimport { TPFormValidator } from './definitions';\nimport * as required from './validators/required';\nimport * as email from './validators/email';\nimport * as minLength from './validators/min-length';\nimport * as maxLength from './validators/max-length';\nimport * as noEmptySpaces from './validators/no-empty-spaces';\n\n// Prepare validators.\nconst validators = [\n\trequired,\n\temail,\n\tminLength,\n\tmaxLength,\n\tnoEmptySpaces,\n];\n\n/**\n * Register Validators and Errors.\n */\nwindow.tpFormValidators = {};\nwindow.tpFormErrors = {};\n\n// Register validators.\nvalidators.forEach( (\n\t{ name, validator, errorMessage }: { name: string, validator: TPFormValidator, errorMessage: string }\n): void => {\n\t// Assigning validators and error messages to various fields.\n\twindow.tpFormValidators[ name ] = validator;\n\twindow.tpFormErrors[ name ] = errorMessage;\n} );\n\n/**\n * Components.\n */\nimport { TPFormElement } from './tp-form';\nimport { TPFormFieldElement } from './tp-form-field';\nimport { TPFormErrorElement } from './tp-form-error';\nimport { TPFormSubmitElement } from './tp-form-submit';\n\n/**\n * Register Components.\n */\ncustomElements.define( 'tp-form', TPFormElement );\ncustomElements.define( 'tp-form-field', TPFormFieldElement );\ncustomElements.define( 'tp-form-error', TPFormErrorElement );\ncustomElements.define( 'tp-form-submit', TPFormSubmitElement );\n"],"names":["__webpack_require__","exports","definition","key","o","Object","defineProperty","enumerable","get","obj","prop","prototype","hasOwnProperty","call","Symbol","toStringTag","value","getErrorMessage","error","tpFormErrors","window","errorMessage","validator","validate","field","getField","test","minLength","parseInt","getAttribute","length","replace","maxLength","inputField","trim","TPFormElement","HTMLElement","constructor","super","this","form","querySelector","addEventListener","handleFormSubmit","bind","e","formValid","preventDefault","stopImmediatePropagation","submit","setAttribute","removeAttribute","dispatchEvent","CustomEvent","bubbles","fields","querySelectorAll","forEach","resetValidation","TPFormFieldElement","handleFieldChanged","observedAttributes","attributeChangedCallback","name","oldValue","newValue","update","tpFormValidators","setErrorMessage","removeErrorMessage","offsetWidth","offsetHeight","valid","getAttributeNames","every","attributeName","message","innerHTML","errorElement","document","createElement","appendChild","remove","TPFormErrorElement","TPFormSubmitElement","_name","submitButton","submittingText","originalText","validators","customElements","define"],"sourceRoot":""}
1
+ {"version":3,"file":"dist/form/index.js","mappings":"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","sources":["webpack://@travelopia/web-components/webpack/bootstrap","webpack://@travelopia/web-components/webpack/runtime/define property getters","webpack://@travelopia/web-components/webpack/runtime/hasOwnProperty shorthand","webpack://@travelopia/web-components/webpack/runtime/make namespace object","webpack://@travelopia/web-components/./src/form/utility.ts","webpack://@travelopia/web-components/./src/form/validators/required.ts","webpack://@travelopia/web-components/./src/form/validators/email.ts","webpack://@travelopia/web-components/./src/form/validators/min-length.ts","webpack://@travelopia/web-components/./src/form/validators/max-length.ts","webpack://@travelopia/web-components/./src/form/validators/no-empty-spaces.ts","webpack://@travelopia/web-components/./src/form/tp-form.ts","webpack://@travelopia/web-components/./src/form/tp-form-field.ts","webpack://@travelopia/web-components/./src/form/tp-form-error.ts","webpack://@travelopia/web-components/./src/form/tp-form-suspense.ts","webpack://@travelopia/web-components/./src/form/tp-form-submit.ts","webpack://@travelopia/web-components/./src/form/index.ts"],"sourcesContent":["// The require scope\nvar __webpack_require__ = {};\n\n","// define getter functions for harmony exports\n__webpack_require__.d = (exports, definition) => {\n\tfor(var key in definition) {\n\t\tif(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n\t\t\tObject.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n\t\t}\n\t}\n};","__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))","// define __esModule on exports\n__webpack_require__.r = (exports) => {\n\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n\t}\n\tObject.defineProperty(exports, '__esModule', { value: true });\n};","/**\n * Get the error message based on its code.\n *\n * @param {string} error Error code.\n *\n * @return {string} The error message.\n */\nexport const getErrorMessage = ( error: string = '' ): string => {\n\t// Check if tpFormErrors exist in the window object.\n\tconst { tpFormErrors } = window;\n\n\t// If tpFormErrors does not exist.\n\tif ( ! tpFormErrors ) {\n\t\t// Return an empty string.\n\t\treturn '';\n\t}\n\n\t// Check if the error exists and has a corresponding error message.\n\tif ( '' !== error && error in tpFormErrors && 'string' === typeof tpFormErrors[ error ] ) {\n\t\t// Return the error message.\n\t\treturn tpFormErrors[ error ];\n\t}\n\n\t// Return an empty string.\n\treturn '';\n};\n","/**\n * Internal dependencies.\n */\nimport { TPFormFieldElement } from '../tp-form-field';\nimport { TPFormValidator } from '../definitions';\nimport { getErrorMessage } from '../utility';\n\n/**\n * Name.\n */\nexport const name: string = 'required';\n\n/**\n * Error message.\n */\nexport const errorMessage: string = 'This field is required';\n\n/**\n * Validator.\n */\nexport const validator: TPFormValidator = {\n\t// Validate.\n\tvalidate: ( field: TPFormFieldElement ): boolean => {\n\t\t// Check if the field is empty.\n\t\treturn '' !== field.getField()?.value ?? '';\n\t},\n\n\t// Get error message.\n\tgetErrorMessage: (): string => getErrorMessage( name ),\n};\n","/**\n * Internal dependencies.\n */\nimport { TPFormFieldElement } from '../tp-form-field';\nimport { TPFormValidator } from '../definitions';\nimport { getErrorMessage } from '../utility';\n\n/**\n * Name.\n */\nexport const name: string = 'email';\n\n/**\n * Error message.\n */\nexport const errorMessage: string = 'Please enter a valid email address';\n\n/**\n * Validator.\n */\nexport const validator: TPFormValidator = {\n\tvalidate: ( field: TPFormFieldElement ): boolean => {\n\t\t// Boolean value to determine if the field is valid or not.\n\t\treturn /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/.test( field.getField()?.value ?? '' );\n\t},\n\tgetErrorMessage: (): string => getErrorMessage( name ),\n};\n","/**\n * Internal dependencies.\n */\nimport { TPFormFieldElement } from '../tp-form-field';\nimport { TPFormValidator } from '../definitions';\nimport { getErrorMessage } from '../utility';\n\n/**\n * Name.\n */\nexport const name: string = 'min-length';\n\n/**\n * Error message.\n */\nexport const errorMessage: string = 'Must be at least %1 characters';\n\n/**\n * Validator.\n */\nexport const validator: TPFormValidator = {\n\tvalidate: ( field: TPFormFieldElement ): boolean => {\n\t\t// Get min length and value.\n\t\tconst minLength: number = parseInt( field.getAttribute( 'min-length' ) ?? '0' );\n\t\tconst value: string = field.getField()?.value ?? '';\n\n\t\t// Validate.\n\t\treturn '' === value || value.length >= minLength;\n\t},\n\tgetErrorMessage: ( field: TPFormFieldElement ): string => {\n\t\t// Get error message.\n\t\tconst error: string = getErrorMessage( name );\n\t\tconst minLength: string = field.getAttribute( 'min-length' ) ?? '';\n\n\t\t// Return error message.\n\t\treturn error.replace( '%1', minLength );\n\t},\n};\n","/**\n * Internal dependencies.\n */\nimport { TPFormFieldElement } from '../tp-form-field';\nimport { TPFormValidator } from '../definitions';\nimport { getErrorMessage } from '../utility';\n\n/**\n * Name.\n */\nexport const name: string = 'max-length';\n\n/**\n * Error message.\n */\nexport const errorMessage: string = 'Must be less than %1 characters';\n\n/**\n * Validator.\n */\nexport const validator: TPFormValidator = {\n\tvalidate: ( field: TPFormFieldElement ): boolean => {\n\t\t// Get max length and value.\n\t\tconst minLength: number = parseInt( field.getAttribute( 'max-length' ) ?? '0' );\n\t\tconst value: string = field.getField()?.value ?? '';\n\n\t\t// Validate.\n\t\treturn '' === value || value.length <= minLength;\n\t},\n\tgetErrorMessage: ( field: TPFormFieldElement ): string => {\n\t\t// Get error message.\n\t\tconst error: string = getErrorMessage( name );\n\t\tconst maxLength: string = field.getAttribute( 'max-length' ) ?? '';\n\n\t\t// Return error message.\n\t\treturn error.replace( '%1', maxLength );\n\t},\n};\n","/**\n * Internal dependencies.\n */\nimport { TPFormFieldElement } from '../tp-form-field';\nimport { TPFormValidator } from '../definitions';\nimport { getErrorMessage } from '../utility';\n\n/**\n * Name.\n */\nexport const name: string = 'no-empty-spaces';\n\n/**\n * Error message.\n */\nexport const errorMessage: string = 'This field should not contain only white-spaces';\n\n/**\n * Validator.\n */\nexport const validator: TPFormValidator = {\n\tvalidate: ( field: TPFormFieldElement ): boolean => {\n\t\t// Check if the field is empty.\n\t\tconst inputField = field.getField();\n\n\t\t// If no field is found return false.\n\t\tif ( ! inputField ) {\n\t\t\t// Return false.\n\t\t\treturn false;\n\t\t}\n\n\t\t// This case is not our concern. This is handled by `required` validator.\n\t\tif ( '' === inputField.value ) {\n\t\t\t// Return true.\n\t\t\treturn true;\n\t\t}\n\n\t\t// Return true if field is not empty.\n\t\treturn '' !== inputField.value.trim();\n\t},\n\tgetErrorMessage: (): string => getErrorMessage( name ),\n};\n","/**\n * Internal dependencies.\n */\nimport { TPFormFieldElement } from './tp-form-field';\nimport { TPFormSubmitElement } from './tp-form-submit';\n\n/**\n * TP Form.\n */\nexport class TPFormElement extends HTMLElement {\n\t/**\n\t * Properties.\n\t */\n\tprotected readonly form: HTMLFormElement | null;\n\n\t/**\n\t * Constructor.\n\t */\n\tconstructor() {\n\t\t// Initialize parent.\n\t\tsuper();\n\n\t\t// Get form.\n\t\tthis.form = this.querySelector( 'form' );\n\n\t\t// Add event listeners.\n\t\tthis.form?.addEventListener( 'submit', this.handleFormSubmit.bind( this ) );\n\t}\n\n\t/**\n\t * Handle form submission.\n\t *\n\t * @param {Event} e Submit event.\n\t */\n\tprotected async handleFormSubmit( e: SubmitEvent ): Promise<void> {\n\t\t// Stop normal form submission.\n\t\te.preventDefault();\n\t\te.stopImmediatePropagation();\n\n\t\t// Get submit button.\n\t\tconst submit: TPFormSubmitElement | null = this.querySelector( 'tp-form-submit' );\n\t\tsubmit?.setAttribute( 'submitting', 'yes' );\n\n\t\t// Ignore a form that currently has suspense.\n\t\tif ( 'yes' === this.getAttribute( 'suspense' ) ) {\n\t\t\t// Bail early.\n\t\t\treturn;\n\t\t}\n\n\t\t// Validate the form.\n\t\tconst formValid: boolean = await this.validate();\n\n\t\t// If form is valid then dispatch a custom 'submit-validation-success' event.\n\t\tif ( formValid ) {\n\t\t\t// Trigger event.\n\t\t\tthis.dispatchEvent( new CustomEvent( 'submit-validation-success', { bubbles: true } ) );\n\n\t\t\t// Submit form.\n\t\t\tif ( 'yes' !== this.getAttribute( 'prevent-submit' ) ) {\n\t\t\t\tthis.form?.submit();\n\t\t\t}\n\t\t} else {\n\t\t\t// Form is not valid, remove submitting attribute.\n\t\t\tsubmit?.removeAttribute( 'submitting' );\n\t\t}\n\t}\n\n\t/**\n\t * Validate the form.\n\t *\n\t * @return {boolean} Whether the form is valid or not.\n\t */\n\tasync validate(): Promise<boolean> {\n\t\t// Dispatch a custom 'validate' event.\n\t\tthis.dispatchEvent( new CustomEvent( 'validate', { bubbles: true } ) );\n\n\t\t// Get the form fields.\n\t\tconst fields: NodeListOf<TPFormFieldElement> | null = this.querySelectorAll( 'tp-form-field' );\n\n\t\t// If no fields are found, return true indicating validation passed.\n\t\tif ( ! fields ) {\n\t\t\tthis.dispatchEvent( new CustomEvent( 'validation-success', { bubbles: true } ) );\n\n\t\t\t// Return true indicating validation passed.\n\t\t\treturn true;\n\t\t}\n\n\t\t// Start by setting the form as suspense.\n\t\tthis.setAttribute( 'suspense', 'yes' );\n\n\t\t// Check if all fields are valid.\n\t\tlet formValid: boolean = true;\n\t\tconst validationPromises: Promise<boolean>[] = Array\n\t\t\t.from( fields )\n\t\t\t.map( async ( field: TPFormFieldElement ): Promise<boolean> => await field.validate() );\n\n\t\t// Wait for promises to resolve.\n\t\tawait Promise.all( validationPromises )\n\t\t\t.then( ( results: boolean[] ): void => {\n\t\t\t\t// Check if all fields are valid.\n\t\t\t\tformValid = results.every( ( isValid: boolean ) => isValid );\n\t\t\t} )\n\t\t\t.catch( () => {\n\t\t\t\t// There was an error with one or more fields.\n\t\t\t\tformValid = false;\n\t\t\t} )\n\t\t\t.finally( () => this.removeAttribute( 'suspense' ) );\n\n\t\t// If form is valid then dispatch a custom 'validation-success' event else send a custom 'validation-error' event.\n\t\tif ( formValid ) {\n\t\t\tthis.dispatchEvent( new CustomEvent( 'validation-success', { bubbles: true } ) );\n\t\t} else {\n\t\t\tthis.dispatchEvent( new CustomEvent( 'validation-error', { bubbles: true } ) );\n\t\t}\n\n\t\t// Return whether the form is valid or not.\n\t\treturn formValid;\n\t}\n\n\t/**\n\t * Validate one field.\n\t *\n\t * @param {HTMLElement} field Field node.\n\t */\n\tasync validateField( field: TPFormFieldElement ): Promise<boolean> {\n\t\t// Set form as suspense, validate and undo suspense.\n\t\tthis.setAttribute( 'suspense', 'yes' );\n\t\tconst fieldValid: boolean = await field.validate();\n\t\tthis.removeAttribute( 'suspense' );\n\n\t\t// Return result.\n\t\treturn fieldValid;\n\t}\n\n\t/**\n\t * Reset form validation.\n\t */\n\tresetValidation(): void {\n\t\t// Get the form fields.\n\t\tconst fields: NodeListOf<TPFormFieldElement> | null = this.querySelectorAll( 'tp-form-field' );\n\n\t\t// If no fields are found.\n\t\tif ( ! fields ) {\n\t\t\t// Exit the function.\n\t\t\treturn;\n\t\t}\n\n\t\t// Remove 'valid' and 'error' attributes from all fields.\n\t\tfields.forEach( ( field: TPFormFieldElement ): void => {\n\t\t\t// Remove 'valid' and 'error' and 'suspense' attributes.\n\t\t\tfield.removeAttribute( 'valid' );\n\t\t\tfield.removeAttribute( 'error' );\n\t\t\tfield.removeAttribute( 'suspense' );\n\t\t} );\n\n\t\t// Remove 'suspense' attribute from form.\n\t\tthis.removeAttribute( 'suspense' );\n\n\t\t// Remove 'submitting' attribute from submit button.\n\t\tconst submit: TPFormSubmitElement | null = this.querySelector( 'tp-form-submit' );\n\t\tsubmit?.removeAttribute( 'submitting' );\n\t}\n}\n","/**\n * Internal dependencies.\n */\nimport { TPFormElement } from './tp-form';\nimport { TPFormErrorElement } from './tp-form-error';\nimport { TPFormSuspenseElement } from './tp-form-suspense';\n\n/**\n * TP Form Field.\n */\nexport class TPFormFieldElement extends HTMLElement {\n\t/**\n\t * Constructor.\n\t */\n\tconstructor() {\n\t\t// Initialize parent.\n\t\tsuper();\n\n\t\t// Get field.\n\t\tconst field = this.getField();\n\n\t\t// Add event listeners.\n\t\tfield?.addEventListener( 'keyup', this.handleFieldChanged.bind( this ) );\n\t\tfield?.addEventListener( 'change', this.handleFieldChanged.bind( this ) );\n\t}\n\n\t/**\n\t * Update validation when the field has changed.\n\t */\n\thandleFieldChanged(): void {\n\t\t// Check if we want to ignore field revalidations.\n\t\tif ( 'no' === this.getAttribute( 'revalidate-on-change' ) ) {\n\t\t\t// Yes we do, bail!\n\t\t\treturn;\n\t\t}\n\n\t\t// Validate the field again if 'valid' or 'error' attribute is present.\n\t\tif ( this.getAttribute( 'valid' ) || this.getAttribute( 'error' ) ) {\n\t\t\tconst form: TPFormElement | null = this.closest( 'tp-form' );\n\t\t\tform?.validateField( this );\n\t\t}\n\t}\n\n\t/**\n\t * Get observed attributes.\n\t *\n\t * @return {Array} List of observed attributes.\n\t */\n\tstatic get observedAttributes(): string[] {\n\t\t// Attributes observed in the TPFormFieldElement web-component.\n\t\treturn [ 'valid', 'error', 'suspense' ];\n\t}\n\n\t/**\n\t * Attribute changed callback.\n\t *\n\t * @param {string} name Attribute name.\n\t * @param {string} oldValue Old value.\n\t * @param {string} newValue New value.\n\t */\n\tattributeChangedCallback( name: string = '', oldValue: string = '', newValue: string = '' ): void {\n\t\t// Check if the observed attributes 'valid' or 'error' have changed.\n\n\t\t// Dispatch a custom 'validate' event.\n\t\tif ( ( 'valid' === name || 'error' === name || 'suspense' === name ) && oldValue !== newValue ) {\n\t\t\tthis.dispatchEvent( new CustomEvent( 'validate', { bubbles: true } ) );\n\t\t}\n\n\t\t// Update the component after the attribute change.\n\t\tthis.update();\n\t}\n\n\t/**\n\t * Update component.\n\t */\n\tupdate(): void {\n\t\t// Check if tpFormValidators exist in the window object.\n\t\tconst { tpFormValidators } = window;\n\n\t\t// Exit the function if validators are not available.\n\t\tif ( ! tpFormValidators ) {\n\t\t\t// Early return.\n\t\t\treturn;\n\t\t}\n\n\t\t// Get the 'error' attribute value.\n\t\tconst error: string = this.getAttribute( 'error' ) ?? '';\n\n\t\t// Check if the error exists and has a corresponding error message function.\n\t\tif ( '' !== error && error in tpFormValidators && 'function' === typeof tpFormValidators[ error ].getErrorMessage ) {\n\t\t\tthis.setErrorMessage( tpFormValidators[ error ].getErrorMessage( this ) );\n\t\t} else {\n\t\t\tthis.removeErrorMessage();\n\t\t}\n\n\t\t// Get the 'suspense' attribute value.\n\t\tconst suspense: string = this.getAttribute( 'suspense' ) ?? '';\n\n\t\t// Check if the suspense exists and has a corresponding suspense message function.\n\t\tif ( '' !== suspense && suspense in tpFormValidators && 'function' === typeof tpFormValidators[ suspense ].getSuspenseMessage ) {\n\t\t\t// @ts-ignore\n\t\t\tthis.setSuspenseMessage( tpFormValidators[ suspense ]?.getSuspenseMessage( this ) );\n\t\t} else {\n\t\t\tthis.removeSuspenseMessage();\n\t\t}\n\t}\n\n\t/**\n\t * Get the associated field.\n\t *\n\t * @return {HTMLElement} The associated field for this component.\n\t */\n\tgetField(): HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement | null {\n\t\t// Return the associated field by querying input, select, or textarea elements.\n\t\treturn this.querySelector( 'input,select,textarea' );\n\t}\n\n\t/**\n\t * Validate this field.\n\t *\n\t * @return {boolean} Whether this field passed validation.\n\t */\n\tasync validate(): Promise<boolean> {\n\t\t// Retrieve tpFormValidators from the window object.\n\t\tconst { tpFormValidators } = window;\n\n\t\t// Exit the function if validators are not available.\n\t\tif ( ! tpFormValidators ) {\n\t\t\t// If no validators are found, return true indicating validation passed.\n\t\t\treturn true;\n\t\t}\n\n\t\t// Check if the field is visible.\n\t\tif ( this.offsetWidth <= 0 || this.offsetHeight <= 0 ) {\n\t\t\t// If the field is not visible, return true indicating validation passed.\n\t\t\treturn true;\n\t\t}\n\n\t\t// Prepare error and valid status.\n\t\tlet valid: boolean = true;\n\t\tlet suspense: Promise<boolean> | null = null;\n\t\tlet error: string = '';\n\t\tconst allAttributes: string[] = this.getAttributeNames();\n\n\t\t// Traverse all attributes to see if we find a matching validator.\n\t\tallAttributes.every( ( attributeName: string ): boolean => {\n\t\t\t// Check if the attribute is a validator.\n\t\t\tif ( attributeName in tpFormValidators && 'function' === typeof tpFormValidators[ attributeName ].validate ) {\n\t\t\t\t// We found one, lets validate the field.\n\t\t\t\tconst isValid: boolean | Promise<boolean> = tpFormValidators[ attributeName ].validate( this );\n\t\t\t\terror = attributeName;\n\n\t\t\t\t// First check for a Promise.\n\t\t\t\tif ( isValid instanceof Promise ) {\n\t\t\t\t\t// Yes it is an async validation.\n\t\t\t\t\tvalid = false;\n\n\t\t\t\t\t// Dispatch a custom 'validation-suspense-start' event.\n\t\t\t\t\tthis.dispatchEvent( new CustomEvent( 'validation-suspense-start' ) );\n\n\t\t\t\t\t// Create the promise.\n\t\t\t\t\tsuspense = new Promise( ( resolve, reject ): void => {\n\t\t\t\t\t\t// Validate it.\n\t\t\t\t\t\tisValid\n\t\t\t\t\t\t\t.then( ( suspenseIsValid: boolean ) => {\n\t\t\t\t\t\t\t\t// Validation is complete.\n\t\t\t\t\t\t\t\tif ( true === suspenseIsValid ) {\n\t\t\t\t\t\t\t\t\tthis.setAttribute( 'valid', 'yes' );\n\t\t\t\t\t\t\t\t\tthis.removeAttribute( 'error' );\n\n\t\t\t\t\t\t\t\t\t// Resolve the promise.\n\t\t\t\t\t\t\t\t\tresolve( true );\n\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\tthis.removeAttribute( 'valid' );\n\t\t\t\t\t\t\t\t\tthis.setAttribute( 'error', error );\n\n\t\t\t\t\t\t\t\t\t// Resolve the promise.\n\t\t\t\t\t\t\t\t\tresolve( false );\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t// Dispatch a custom 'validation-suspense-success' event.\n\t\t\t\t\t\t\t\tthis.dispatchEvent( new CustomEvent( 'validation-suspense-success' ) );\n\t\t\t\t\t\t\t} )\n\t\t\t\t\t\t\t.catch( (): void => {\n\t\t\t\t\t\t\t\t// There was an error.\n\t\t\t\t\t\t\t\tthis.removeAttribute( 'valid' );\n\t\t\t\t\t\t\t\tthis.setAttribute( 'error', error );\n\n\t\t\t\t\t\t\t\t// Dispatch a custom 'validation-suspense-error' event.\n\t\t\t\t\t\t\t\tthis.dispatchEvent( new CustomEvent( 'validation-suspense-error' ) );\n\n\t\t\t\t\t\t\t\t// Reject the promise.\n\t\t\t\t\t\t\t\treject( false );\n\t\t\t\t\t\t\t} )\n\t\t\t\t\t\t\t.finally( (): void => {\n\t\t\t\t\t\t\t\t// Clean up.\n\t\t\t\t\t\t\t\tthis.removeAttribute( 'suspense' );\n\t\t\t\t\t\t\t} );\n\t\t\t\t\t} );\n\n\t\t\t\t\t// Return.\n\t\t\t\t\treturn false;\n\t\t\t\t} else if ( false === isValid ) {\n\t\t\t\t\t// Not a Promise, but looks like we found an error!\n\t\t\t\t\tvalid = false;\n\n\t\t\t\t\t// Return.\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// No error found, all good.\n\t\t\treturn true;\n\t\t} );\n\n\t\t// Check if the field is valid or not.\n\t\tif ( valid ) {\n\t\t\tthis.setAttribute( 'valid', 'yes' );\n\t\t\tthis.removeAttribute( 'error' );\n\t\t\tthis.removeAttribute( 'suspense' );\n\t\t} else {\n\t\t\tthis.removeAttribute( 'valid' );\n\n\t\t\t// Check for suspense.\n\t\t\tif ( suspense ) {\n\t\t\t\tthis.setAttribute( 'suspense', error );\n\t\t\t\tthis.removeAttribute( 'error' );\n\t\t\t} else {\n\t\t\t\tthis.removeAttribute( 'suspense' );\n\t\t\t\tthis.setAttribute( 'error', error );\n\t\t\t}\n\t\t}\n\n\t\t// Do we have a suspense?\n\t\tif ( suspense ) {\n\t\t\t// Yes we do, return the promise.\n\t\t\treturn suspense;\n\t\t}\n\n\t\t// No we don't, return a resolved promise.\n\t\treturn valid;\n\t}\n\n\t/**\n\t * Set the error message.\n\t *\n\t * @param {string} message Error message.\n\t */\n\tsetErrorMessage( message: string = '' ): void {\n\t\t// Look for an existing tp-form-error element.\n\t\tconst error: TPFormErrorElement | null = this.querySelector( 'tp-form-error' );\n\n\t\t// If found, update its innerHTML with the error message. Otherwise, create a new tp-form-error element and append it to the component.\n\t\tif ( error ) {\n\t\t\terror.innerHTML = message;\n\t\t} else {\n\t\t\tconst errorElement: TPFormErrorElement = document.createElement( 'tp-form-error' );\n\t\t\terrorElement.innerHTML = message;\n\t\t\tthis.appendChild( errorElement );\n\t\t}\n\n\t\t// Dispatch a custom 'validation-error' event.\n\t\tthis.dispatchEvent( new CustomEvent( 'validation-error' ) );\n\t}\n\n\t/**\n\t * Remove the error message.\n\t */\n\tremoveErrorMessage(): void {\n\t\t// Find and remove the tp-form-error element.\n\t\tthis.querySelector( 'tp-form-error' )?.remove();\n\n\t\t// Dispatch a custom 'validation-success' event.\n\t\tthis.dispatchEvent( new CustomEvent( 'validation-success' ) );\n\t}\n\n\t/**\n\t * Set the suspense message.\n\t *\n\t * @param {string} message Suspense message.\n\t */\n\tsetSuspenseMessage( message: string = '' ): void {\n\t\t// Look for an existing tp-form-error element.\n\t\tconst suspense: TPFormSuspenseElement | null = this.querySelector( 'tp-form-suspense' );\n\n\t\t// If found, update its innerHTML with the suspense message. Otherwise, create a new tp-form-suspense element and append it to the component.\n\t\tif ( suspense ) {\n\t\t\tsuspense.innerHTML = message;\n\t\t} else {\n\t\t\tconst suspenseElement: TPFormSuspenseElement = document.createElement( 'tp-form-suspense' );\n\t\t\tsuspenseElement.innerHTML = message;\n\t\t\tthis.appendChild( suspenseElement );\n\t\t}\n\t}\n\n\t/**\n\t * Remove the suspense message.\n\t */\n\tremoveSuspenseMessage(): void {\n\t\t// Find and remove the tp-form-suspense element.\n\t\tthis.querySelector( 'tp-form-suspense' )?.remove();\n\t}\n}\n","/**\n * TP Form Error.\n */\nexport class TPFormErrorElement extends HTMLElement {\n}\n","/**\n * TP Form Suspense.\n */\nexport class TPFormSuspenseElement extends HTMLElement {\n}\n","/**\n * TP Form Submit.\n */\nexport class TPFormSubmitElement extends HTMLElement {\n\t/**\n\t * Get observed attributes.\n\t *\n\t * @return {Array} List of observed attributes.\n\t */\n\tstatic get observedAttributes(): string[] {\n\t\t// Attributes observed in the TPFormSubmitElement web-component.\n\t\treturn [ 'submitting-text', 'original-text', 'submitting' ];\n\t}\n\n\t/**\n\t * Attribute changed callback.\n\t *\n\t * @param {string} _name Attribute name.\n\t * @param {string} oldValue Old value.\n\t * @param {string} newValue New value.\n\t */\n\tattributeChangedCallback( _name: string = '', oldValue: string = '', newValue: string = '' ): void {\n\t\t// Update component if attribute has changed.\n\t\tif ( oldValue !== newValue ) {\n\t\t\tthis.update();\n\t\t}\n\t}\n\n\t/**\n\t * Update this component.\n\t */\n\tupdate(): void {\n\t\t// Get submit button.\n\t\tconst submitButton: HTMLButtonElement | null = this.querySelector( 'button[type=\"submit\"]' );\n\n\t\t// Check if we have a submit button.\n\t\tif ( ! submitButton ) {\n\t\t\t// No, we don't. Exit.\n\t\t\treturn;\n\t\t}\n\n\t\t// Prepare submit button text.\n\t\tconst submittingText: string = this.getAttribute( 'submitting-text' ) ?? '';\n\t\tconst originalText: string = this.getAttribute( 'original-text' ) ?? submitButton.innerHTML;\n\n\t\t// Check if we are submitting.\n\t\tif ( 'yes' === this.getAttribute( 'submitting' ) ) {\n\t\t\tsubmitButton.setAttribute( 'disabled', 'disabled' );\n\t\t\tthis.setAttribute( 'original-text', originalText );\n\t\t\tsubmitButton.innerHTML = submittingText;\n\t\t} else {\n\t\t\tsubmitButton.removeAttribute( 'disabled' );\n\t\t\tthis.removeAttribute( 'submitting' );\n\t\t\tthis.removeAttribute( 'original-text' );\n\t\t\tsubmitButton.innerHTML = originalText;\n\t\t}\n\t}\n}\n","/**\n * Styles.\n */\nimport './style.scss';\n\n/**\n * Validators.\n */\n\n// Import validators.\nimport { TPFormValidator } from './definitions';\nimport * as required from './validators/required';\nimport * as email from './validators/email';\nimport * as minLength from './validators/min-length';\nimport * as maxLength from './validators/max-length';\nimport * as noEmptySpaces from './validators/no-empty-spaces';\n\n// Prepare validators.\nconst validators = [\n\trequired,\n\temail,\n\tminLength,\n\tmaxLength,\n\tnoEmptySpaces,\n];\n\n/**\n * Register Validators and Errors.\n */\nwindow.tpFormValidators = {};\nwindow.tpFormErrors = {};\nwindow.tpFormSuspenseMessages = {};\n\n// Register validators.\nvalidators.forEach( (\n\t{ name, validator, errorMessage }: { name: string, validator: TPFormValidator, errorMessage: string }\n): void => {\n\t// Assigning validators and error messages to various fields.\n\twindow.tpFormValidators[ name ] = validator;\n\twindow.tpFormErrors[ name ] = errorMessage;\n} );\n\n/**\n * Components.\n */\nimport { TPFormElement } from './tp-form';\nimport { TPFormFieldElement } from './tp-form-field';\nimport { TPFormErrorElement } from './tp-form-error';\nimport { TPFormSuspenseElement } from './tp-form-suspense';\nimport { TPFormSubmitElement } from './tp-form-submit';\n\n/**\n * Register Components.\n */\ncustomElements.define( 'tp-form', TPFormElement );\ncustomElements.define( 'tp-form-field', TPFormFieldElement );\ncustomElements.define( 'tp-form-error', TPFormErrorElement );\ncustomElements.define( 'tp-form-suspense', TPFormSuspenseElement );\ncustomElements.define( 'tp-form-submit', TPFormSubmitElement );\n"],"names":["__webpack_require__","exports","definition","key","o","Object","defineProperty","enumerable","get","obj","prop","prototype","hasOwnProperty","call","Symbol","toStringTag","value","getErrorMessage","error","tpFormErrors","window","errorMessage","validator","validate","field","getField","test","minLength","parseInt","getAttribute","length","replace","maxLength","inputField","trim","TPFormElement","HTMLElement","constructor","super","this","form","querySelector","addEventListener","handleFormSubmit","bind","e","preventDefault","stopImmediatePropagation","submit","setAttribute","dispatchEvent","CustomEvent","bubbles","removeAttribute","fields","querySelectorAll","formValid","validationPromises","Array","from","map","Promise","all","then","results","every","isValid","catch","finally","validateField","fieldValid","resetValidation","forEach","TPFormFieldElement","handleFieldChanged","closest","observedAttributes","attributeChangedCallback","name","oldValue","newValue","update","tpFormValidators","setErrorMessage","removeErrorMessage","suspense","getSuspenseMessage","setSuspenseMessage","removeSuspenseMessage","offsetWidth","offsetHeight","valid","getAttributeNames","attributeName","resolve","reject","suspenseIsValid","message","innerHTML","errorElement","document","createElement","appendChild","remove","suspenseElement","TPFormErrorElement","TPFormSuspenseElement","TPFormSubmitElement","_name","submitButton","submittingText","originalText","validators","tpFormSuspenseMessages","customElements","define"],"sourceRoot":""}
@@ -1,2 +1,2 @@
1
- (()=>{"use strict";class t extends HTMLElement{constructor(){super(),this.uniqueId=crypto.randomUUID(),this.target=this.querySelector(":scope > tp-tooltip-popover"),this.appendTriggerButton(),this.setPopoverTarget()}appendTriggerButton(){const t=this.querySelector("tp-tooltip-trigger");if(!t)return void console.error("tp-tooltip-trigger not found");const o=document.createElement("button");(null==t?void 0:t.firstElementChild)&&(null==o||o.appendChild(t.firstElementChild)),o.setAttribute("popovertarget",this.uniqueId),o.addEventListener("mouseover",(()=>{var t;null===(t=this.target)||void 0===t||t.showTooltip()})),o.addEventListener("mouseleave",(()=>{var t;null===(t=this.target)||void 0===t||t.hideTooltip()})),null==t||t.appendChild(o)}setPopoverTarget(){this.target?(this.target.setAttribute("popover","auto"),this.target.setAttribute("id",this.uniqueId)):console.error("tp-tooltip-popover not found")}}class o extends HTMLElement{}class e extends HTMLElement{constructor(){super(),this.trigger=this.closest("tp-tooltip"),this.tooltipWidth=parseInt(this.style.width)||0,this.tooltipArrowHeight=parseInt(this.getAttribute("arrow-height")||"8"),this.tooltipGap=parseInt(this.getAttribute("gap")||"10")}showTooltip(){this.showPopover(),this.positionTooltip()}hideTooltip(){this.hidePopover(),this.style.setProperty("--arrow-top-positioning",null),this.style.setProperty("--arrow-left-positioning",null)}positionTooltip(){if(!this.trigger)return;const t=this.getElementPosition(this);console.log(t);const o=this.getElementPosition(this.trigger),e=this.getElementPosition(this.trigger.parentNode);if(t&&o&&e){const i=o.bottom-o.height,r=Math.max(document.documentElement.clientWidth||0,window.innerWidth||0),s=o.width/2,n=this.tooltipWidth/2,h=0;let l,p,g;t.height+h>i?(l=o.bottom+this.tooltipGap+this.tooltipArrowHeight,this.style.setProperty("--border-bottom-color","#121212"),p=o.bottom-this.tooltipArrowHeight+this.tooltipGap):(l=o.bottom-t.height-o.height-this.tooltipGap-this.tooltipArrowHeight,this.style.setProperty("--border-top-color","#121212"),p=o.bottom-o.height-this.tooltipGap-this.tooltipArrowHeight),console.log(o.bottom,l,p),this.style.marginTop=`calc(${l}px )`,this.style.setProperty("--arrow-top-positioning",`${p}px`);const d=o.right-s;g=r-o.right+s<n+h?e.right-this.tooltipWidth:o.right-s<n+h?e.right-e.width:o.right-n-s,this.style.marginLeft=g+"px",this.style.setProperty("--arrow-left-positioning",`${d}px`)}}getElementPosition(t){return null==t?void 0:t.getBoundingClientRect()}}customElements.define("tp-tooltip",t),customElements.define("tp-tooltip-trigger",o),customElements.define("tp-tooltip-popover",e)})();
1
+ (()=>{"use strict";class t extends HTMLElement{constructor(){super(),this.trigger=null,this.makePopover()}makePopover(){this.getAttribute("popover")||this.setAttribute("popover","popover")}setTrigger(t){this.trigger=t}setContent(){var t,e,i;const o=null!==(e=null===(t=this.trigger)||void 0===t?void 0:t.getContent())&&void 0!==e?e:null;o&&(null===(i=this.querySelector("slot"))||void 0===i||i.replaceChildren(o))}setPosition(){if(!this.trigger)return;const{height:t,width:e}=this.getBoundingClientRect(),{x:i,y:o,width:s,height:r}=this.trigger.getBoundingClientRect();let n=0;const l=this.querySelector("tp-tooltop-arrow");l&&({height:n}=l.getBoundingClientRect()),o>t+this.trigger.offset+n?(this.style.top=o-t-this.trigger.offset-n/2+"px",null==l||l.setAttribute("position","bottom")):(this.style.top=`${o+r+this.trigger.offset+n/2}px`,null==l||l.setAttribute("position","top")),i+s/2>e/2&&(this.style.left=i+s/2-e/2+"px")}show(){this.setContent(),this.setPosition(),this.setAttribute("show","yes")}hide(){this.removeAttribute("show")}}class e extends HTMLElement{constructor(){super(),this.addEventListener("mouseenter",this.showTooltip.bind(this)),this.addEventListener("mouseleave",this.hideTooltip.bind(this))}get offset(){var t;return parseInt(null!==(t=this.getAttribute("offset"))&&void 0!==t?t:"0")}set offset(t){t?this.setAttribute("offset",t.toString()):this.removeAttribute("offset")}showTooltip(){var t;const e=null!==(t=this.getAttribute("tooltip"))&&void 0!==t?t:"";if(""===e)return;const i=document.querySelector(`#${e}`);null==i||i.setTrigger(this),null==i||i.show()}hideTooltip(){var t;const e=null!==(t=this.getAttribute("tooltip"))&&void 0!==t?t:"";if(""===e)return;const i=document.querySelector(`#${e}`);null==i||i.hide()}getContent(){const t=this.querySelector("template");return t?t.content.cloneNode(!0):null}}class i extends HTMLElement{}customElements.define("tp-tooltip",t),customElements.define("tp-tooltip-trigger",e),customElements.define("tp-tooltip-arrow",i)})();
2
2
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"dist/tooltip/index.js","mappings":"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","sources":["webpack://@travelopia/web-components/./src/tooltip/tp-tooltip.ts","webpack://@travelopia/web-components/./src/tooltip/tp-tooltip-trigger.ts","webpack://@travelopia/web-components/./src/tooltip/tp-tooltip-popover.ts","webpack://@travelopia/web-components/./src/tooltip/index.ts"],"sourcesContent":["import { TPTooltipPopoverElement } from \"./tp-tooltip-popover\";\nimport { TPTooltipTriggerElement } from \"./tp-tooltip-trigger\";\n\n/**\n * TP Tooltip Popover.\n */\nexport class TPTooltipElement extends HTMLElement {\n\t/**\n\t * Properties.\n\t */\n\tprotected uniqueId: string = crypto.randomUUID();\n\tprotected target: TPTooltipPopoverElement | null;\n\t/**\n\t * Constructor.\n\t */\n\tconstructor() {\n\t\t// Initialize parent.\n\t\tsuper();\n\t\tthis.target = this.querySelector( ':scope > tp-tooltip-popover' );\n\n\t\tthis.appendTriggerButton();\n\t\tthis.setPopoverTarget();\n\t}\n\n\t/**\n\t * Append a button to the trigger element. This button will be the actual target of mouse events.\n\t * Because popover API only work with Button element as a trigger point.\n\t * We move the slotted content into the button and add listeners to show/hide the tooltip.\n\t * If no trigger element is found, log an error and do nothing.\n\t */\n\n\tappendTriggerButton() {\n\t\tconst trigger: TPTooltipTriggerElement | null = this.querySelector( 'tp-tooltip-trigger' );\n\n\t\tif ( ! trigger ) {\n\t\t\tconsole.error( 'tp-tooltip-trigger not found' );\n\t\t\treturn;\n\t\t}\n\t\t// Move slotted content into the button\n\t\tconst button = document.createElement( 'button' );\n\t\tif ( trigger?.firstElementChild ) {\n\t\t\tbutton?.appendChild(trigger.firstElementChild);\n\t\t}\n\n\t\tbutton.setAttribute( 'popovertarget', this.uniqueId );\n\n\t\tbutton.addEventListener( 'mouseover', () => {\n\t\t\tthis.target?.showTooltip();\n\t\t});\n\t\tbutton.addEventListener( 'mouseleave', () => {\n\t\t\tthis.target?.hideTooltip();\n\t\t});\n\n\t\ttrigger?.appendChild( button );\n\t}\n\n\t/**\n\t * Set the popover target and unique id of the tp-tooltip-popover element.\n\t * The popover target is set to \"auto\" and the id is set to the uniqueId property.\n\t * If no target element is found, log an error and do nothing.\n\t */\n\tsetPopoverTarget() {\n\t\tif( ! this.target ) {\n\t\t\tconsole.error( 'tp-tooltip-popover not found' );\n\t\t\treturn;\n\t\t}\n\t\tthis.target.setAttribute( 'popover', \"auto\" );\n\t\tthis.target.setAttribute( 'id', this.uniqueId );\n\t}\n}\n","/**\n * TP Tooltip Trigger.\n */\nexport class TPTooltipTriggerElement extends HTMLElement {\n}","import { TPTooltipElement } from \"./tp-tooltip\";\n\n/**\n * TP Tooltip Popover.\n */\nexport class TPTooltipPopoverElement extends HTMLElement {\n\t/**\n\t * Properties.\n\t */\n\tprotected trigger: TPTooltipElement | null;\n\tprotected tooltipWidth: number;\n\tprotected tooltipArrowHeight: number;\n\tprotected tooltipGap: number;\n\n\tconstructor() {\n\n\t\t// Initialize parent.\n\t\tsuper();\n\n\t\tthis.trigger = this.closest( 'tp-tooltip' );\n\t\tthis.tooltipWidth = parseInt(this.style.width) || 0;\n\t\tthis.tooltipArrowHeight = parseInt(this.getAttribute( 'arrow-height' ) || '8');\n\t\tthis.tooltipGap = parseInt(this.getAttribute( 'gap' ) || '10');\n\t}\n\n\tshowTooltip() {\n\t\tthis.showPopover();\n\t\tthis.positionTooltip();\n\t}\n\n\thideTooltip() {\n\t\tthis.hidePopover();\n\t\tthis.style.setProperty( '--arrow-top-positioning', null );\n\t\tthis.style.setProperty( '--arrow-left-positioning', null );\n\t}\n\n\t/**\n\t * Position tooltip according to the position of the trigger element.\n\t * Position is calculated based on the following rules:\n\t * 1. If there is enough space above the trigger element, tooltip will be placed below the trigger element else it will be above.\n\t * 2. If there is enough space to the right of the trigger element tooltip will be aligned with the parent container of tp-tooltip element\n\t * the tooltip will be placed to the left of the trigger element.\n\t * 3. Similarly if there is not enough space on right of the trigger element.\n\t */\n\tpositionTooltip() {\n\t\t// Early return if button not found.\n\t\tif( !this.trigger ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Getting positions of elements of interest.\n\t\t// Getting position for tooltip popover.\n\t\tconst tooltipPopoverPosition = this.getElementPosition( this );\n\t\tconsole.log(tooltipPopoverPosition);\n\n\t\t// Getting position for tooltip trigger button.\n\t\tconst tooltipTriggerPosition = this.getElementPosition( this.trigger );\n\n\t\t// Getting position for tooltip parent element.\n\t\t// It will be used to position tooltip when there is not enough space to the right and left.\n\t\tconst parentPosition = this.getElementPosition( this.trigger.parentNode as Element );\n\n\t\tif( tooltipPopoverPosition && tooltipTriggerPosition && parentPosition) {\n\t\t\tconst distanceFromTopWall = (tooltipTriggerPosition.bottom - tooltipTriggerPosition.height);\n\n\t\t\t// Getting viewport width.\n\t\t\tconst viewportWidth = Math.max( document.documentElement.clientWidth || 0, window.innerWidth || 0 );\n\n\t\t\tconst tooltipTriggerHalfWidth = tooltipTriggerPosition.width / 2;\n\t\t\tconst tooltipPopupHalfWidth = this.tooltipWidth / 2;\n\t\t\tconst marginFromWalls = 0;\n\n\t\t\t// Setting tooltip text and arrow position in Y direction\n\t\t\tlet textMarginTop;\n\t\t\tlet arrowTopPosition;\n\n\t\t\tif( tooltipPopoverPosition.height + marginFromWalls > distanceFromTopWall ) {\n\t\t\t\ttextMarginTop = tooltipTriggerPosition.bottom + this.tooltipGap + this.tooltipArrowHeight;\n\t\t\t\tthis.style.setProperty( '--border-bottom-color', \"#121212\" );\n\t\t\t\tarrowTopPosition = tooltipTriggerPosition.bottom - this.tooltipArrowHeight + this.tooltipGap;\n\t\t\t} else {\n\t\t\t\ttextMarginTop = tooltipTriggerPosition.bottom - tooltipPopoverPosition.height - tooltipTriggerPosition.height - this.tooltipGap - this.tooltipArrowHeight;\n\t\t\t\tthis.style.setProperty( '--border-top-color', \"#121212\" );\n\t\t\t\tarrowTopPosition = tooltipTriggerPosition.bottom - tooltipTriggerPosition.height - this.tooltipGap - this.tooltipArrowHeight;\n\t\t\t}\n\t\t\tconsole.log(tooltipTriggerPosition.bottom, textMarginTop, arrowTopPosition);\n\n\t\t\tthis.style.marginTop = `calc(${ textMarginTop }px )`;\n\t\t\tthis.style.setProperty( '--arrow-top-positioning', `${ arrowTopPosition }px` );\n\n\n\t\t\t// Position tooltip in X direction.\n\t\t\tlet textMarginLeft;\n\t\t\tconst arrowLeftPosition = tooltipTriggerPosition.right - tooltipTriggerHalfWidth;\n\n\t\t\tif ( viewportWidth - tooltipTriggerPosition.right + tooltipTriggerHalfWidth < tooltipPopupHalfWidth + marginFromWalls ) {\n\t\t\t\t// Position of tooltip if there is not enough space to the right.\n\t\t\t\ttextMarginLeft = parentPosition.right - this.tooltipWidth;\n\t\t\t} else if ( tooltipTriggerPosition.right - tooltipTriggerHalfWidth < tooltipPopupHalfWidth + marginFromWalls ) {\n\t\t\t\t// Position of tooltip if there is not enough space to the left.\n\t\t\t\ttextMarginLeft = parentPosition.right - parentPosition.width;\n\t\t\t} else {\n\t\t\t\ttextMarginLeft = tooltipTriggerPosition.right - tooltipPopupHalfWidth - tooltipTriggerHalfWidth;\n\t\t\t}\n\n\t\t\t// Setting location of the tooltip text.\n\t\t\tthis.style.marginLeft = textMarginLeft + 'px';\n\t\t\tthis.style.setProperty( '--arrow-left-positioning', `${ arrowLeftPosition }px` );\n\t\t}\n\t}\n\n\t/**\n\t * Gets the position of a given element in the viewport.\n\t */\n\tgetElementPosition( element : Element | null ) {\n\t\tconst elementRect = element?.getBoundingClientRect();\n\t\treturn elementRect;\n\t}\n}\n","/**\n * Styles.\n */\nimport './style.scss';\n\n/**\n * Components.\n */\nimport { TPTooltipElement } from './tp-tooltip';\nimport { TPTooltipTriggerElement } from './tp-tooltip-trigger';\nimport { TPTooltipPopoverElement } from './tp-tooltip-popover';\n\n\n/**\n * Register Components.\n */\n\ncustomElements.define( 'tp-tooltip', TPTooltipElement );\ncustomElements.define( 'tp-tooltip-trigger', TPTooltipTriggerElement );\ncustomElements.define( 'tp-tooltip-popover', TPTooltipPopoverElement );"],"names":["TPTooltipElement","HTMLElement","constructor","super","uniqueId","crypto","randomUUID","this","target","querySelector","appendTriggerButton","setPopoverTarget","trigger","console","error","button","document","createElement","firstElementChild","appendChild","setAttribute","addEventListener","showTooltip","hideTooltip","TPTooltipTriggerElement","TPTooltipPopoverElement","closest","tooltipWidth","parseInt","style","width","tooltipArrowHeight","getAttribute","tooltipGap","showPopover","positionTooltip","hidePopover","setProperty","tooltipPopoverPosition","getElementPosition","log","tooltipTriggerPosition","parentPosition","parentNode","distanceFromTopWall","bottom","height","viewportWidth","Math","max","documentElement","clientWidth","window","innerWidth","tooltipTriggerHalfWidth","tooltipPopupHalfWidth","marginFromWalls","textMarginTop","arrowTopPosition","textMarginLeft","marginTop","arrowLeftPosition","right","marginLeft","element","getBoundingClientRect","customElements","define"],"sourceRoot":""}
1
+ {"version":3,"file":"dist/tooltip/index.js","mappings":"mBASO,MAAMA,UAAkBC,YAS9B,WAAAC,GAECC,QAPS,KAAAC,QAAmC,KAU5CC,KAAKC,aACN,CAKA,WAAAA,GAEQD,KAAKE,aAAc,YACzBF,KAAKG,aAAc,UAAW,UAEhC,CAOA,UAAAC,CAAYL,GAEXC,KAAKD,QAAUA,CAChB,CAKA,UAAAM,G,UAEC,MAAMC,EAAiD,QAA1B,EAAY,QAAZ,EAAAN,KAAKD,eAAO,eAAEQ,oBAAY,QAAI,KAGtDD,IAEwB,QAA5B,EAAAN,KAAKQ,cAAe,eAAQ,SAAEC,gBAAiBH,GAEjD,CAKA,WAAAI,GAEC,IAAOV,KAAKD,QAEX,OAID,MAAQY,OAAQC,EAAeC,MAAOC,GAAiBd,KAAKe,yBAGpDC,EAAGC,EAAqBC,EAAGC,EAAoBN,MAAOO,EAAcT,OAAQU,GAAkBrB,KAAKD,QAAQgB,wBAGnH,IAAIO,EAAsB,EAC1B,MAAMC,EAA+BvB,KAAKQ,cAAe,oBAGpDe,KACAZ,OAAQW,GAAgBC,EAAMR,yBAI9BI,EAAqBP,EAAgBZ,KAAKD,QAAQyB,OAASF,GAE/DtB,KAAKyB,MAAMC,IAAUP,EAAqBP,EAAgBZ,KAAKD,QAAQyB,OAAWF,EAAc,EAA/E,KAGjBC,SAAAA,EAAOpB,aAAc,WAAY,YAGjCH,KAAKyB,MAAMC,IAAM,GAAIP,EAAqBE,EAAgBrB,KAAKD,QAAQyB,OAAWF,EAAc,MAGhGC,SAAAA,EAAOpB,aAAc,WAAY,QAI7Bc,EAAwBG,EAAe,EAAQN,EAAe,IAClEd,KAAKyB,MAAME,KAAWV,EAAwBG,EAAe,EAAQN,EAAe,EAAlE,KAEpB,CAKA,IAAAc,GAEC5B,KAAKK,aACLL,KAAKU,cACLV,KAAKG,aAAc,OAAQ,MAC5B,CAKA,IAAA0B,GAEC7B,KAAK8B,gBAAiB,OACvB,EClHM,MAAMC,UAAyBnC,YAIrC,WAAAC,GAECC,QAGAE,KAAKgC,iBAAkB,aAAchC,KAAKiC,YAAYC,KAAMlC,OAC5DA,KAAKgC,iBAAkB,aAAchC,KAAKmC,YAAYD,KAAMlC,MAC7D,CAKA,UAAIwB,G,MAEH,OAAOY,SAAuC,QAA7B,EAAApC,KAAKE,aAAc,iBAAU,QAAI,IACnD,CAKA,UAAIsB,CAAQA,GAEJA,EAGNxB,KAAKG,aAAc,SAAUqB,EAAOa,YAFpCrC,KAAK8B,gBAAiB,SAIxB,CAKA,WAAAG,G,MAEC,MAAMK,EAAkD,QAA9B,EAAAtC,KAAKE,aAAc,kBAAW,QAAI,GAG5D,GAAK,KAAOoC,EAEX,OAID,MAAMC,EAA4BC,SAAShC,cAAe,IAAK8B,KAC/DC,SAAAA,EAASnC,WAAYJ,MACrBuC,SAAAA,EAASX,MACV,CAKA,WAAAO,G,MAEC,MAAMG,EAAkD,QAA9B,EAAAtC,KAAKE,aAAc,kBAAW,QAAI,GAG5D,GAAK,KAAOoC,EAEX,OAID,MAAMC,EAA4BC,SAAShC,cAAe,IAAK8B,KAC/DC,SAAAA,EAASV,MACV,CAOA,UAAAtB,GAEC,MAAMkC,EAAuCzC,KAAKQ,cAAe,YAGjE,OAAKiC,EAEGA,EAASnC,QAAQoC,WAAW,GAI7B,IACR,EC5FM,MAAMC,UAAuB/C,aCYpCgD,eAAeC,OAAQ,aAAclD,GACrCiD,eAAeC,OAAQ,qBAAsBd,GAC7Ca,eAAeC,OAAQ,mBAAoBF,E","sources":["webpack://@travelopia/web-components/./src/tooltip/tp-tooltip.ts","webpack://@travelopia/web-components/./src/tooltip/tp-tooltip-trigger.ts","webpack://@travelopia/web-components/./src/tooltip/tp-tooltip-arrow.ts","webpack://@travelopia/web-components/./src/tooltip/index.ts"],"sourcesContent":["/**\n * Internal dependencies.\n */\nimport { TPTooltipTrigger } from './tp-tooltip-trigger';\nimport { TPTooltipArrow } from './tp-tooltip-arrow';\n\n/**\n * TP Tooltip.\n */\nexport class TPTooltip extends HTMLElement {\n\t/**\n\t * Properties.\n\t */\n\tprotected trigger: TPTooltipTrigger | null = null;\n\n\t/**\n\t * Constructor.\n\t */\n\tconstructor() {\n\t\t// Call parent's constructor.\n\t\tsuper();\n\n\t\t// Make the tooltip a popover.\n\t\tthis.makePopover();\n\t}\n\n\t/**\n\t * Make this tooltip a popover, if it isn't already.\n\t */\n\tmakePopover(): void {\n\t\t// Check if this isn't already a popover.\n\t\tif ( ! this.getAttribute( 'popover' ) ) {\n\t\t\tthis.setAttribute( 'popover', 'popover' );\n\t\t}\n\t}\n\n\t/**\n\t * Set the trigger.\n\t *\n\t * @param {HTMLElement} trigger The trigger node.\n\t */\n\tsetTrigger( trigger: TPTooltipTrigger ): void {\n\t\t// Set the trigger.\n\t\tthis.trigger = trigger;\n\t}\n\n\t/**\n\t * Set the content for our tooltip.\n\t */\n\tsetContent(): void {\n\t\t// Get content.\n\t\tconst content: Node | null = this.trigger?.getContent() ?? null;\n\n\t\t// Check if we have content.\n\t\tif ( content ) {\n\t\t\t// Yes, replace slot's children with new content.\n\t\t\tthis.querySelector( 'slot' )?.replaceChildren( content );\n\t\t}\n\t}\n\n\t/**\n\t * Set the position of the tooltip.\n\t */\n\tsetPosition(): void {\n\t\t// Do we have a trigger?\n\t\tif ( ! this.trigger ) {\n\t\t\t// We don't, bail!\n\t\t\treturn;\n\t\t}\n\n\t\t// Get width and height of this tooltip.\n\t\tconst { height: tooltipHeight, width: tooltipWidth } = this.getBoundingClientRect();\n\n\t\t// Get position and coordinates of the trigger.\n\t\tconst { x: triggerLeftPosition, y: triggerTopPosition, width: triggerWidth, height: triggerHeight } = this.trigger.getBoundingClientRect();\n\n\t\t// Get arrow dimensions.\n\t\tlet arrowHeight: number = 0;\n\t\tconst arrow: TPTooltipArrow | null = this.querySelector( 'tp-tooltop-arrow' );\n\n\t\t// Check if we have an arrow.\n\t\tif ( arrow ) {\n\t\t\t( { height: arrowHeight } = arrow.getBoundingClientRect() );\n\t\t}\n\n\t\t// Determine the vertical position of this tooltip.\n\t\tif ( triggerTopPosition > tooltipHeight + this.trigger.offset + arrowHeight ) {\n\t\t\t// There is enough space on top of trigger element, so place popover above the trigger element.\n\t\t\tthis.style.top = `${ triggerTopPosition - tooltipHeight - this.trigger.offset - ( arrowHeight / 2 ) }px`;\n\n\t\t\t// Set arrow placement on bottom of popover\n\t\t\tarrow?.setAttribute( 'position', 'bottom' );\n\t\t} else {\n\t\t\t// There is not enough space on top of trigger element, so place popover below the trigger element.\n\t\t\tthis.style.top = `${ triggerTopPosition + triggerHeight + this.trigger.offset + ( arrowHeight / 2 ) }px`;\n\n\t\t\t// Set arrow placement on top of popover\n\t\t\tarrow?.setAttribute( 'position', 'top' );\n\t\t}\n\n\t\t// Determine the horizontal position of this tooltip.\n\t\tif ( triggerLeftPosition + ( triggerWidth / 2 ) > ( tooltipWidth / 2 ) ) {\n\t\t\tthis.style.left = `${ triggerLeftPosition + ( triggerWidth / 2 ) - ( tooltipWidth / 2 ) }px`;\n\t\t}\n\t}\n\n\t/**\n\t * Show the tooltip.\n\t */\n\tshow(): void {\n\t\t// Position tooltip and show it.\n\t\tthis.setContent();\n\t\tthis.setPosition();\n\t\tthis.setAttribute( 'show', 'yes' );\n\t}\n\n\t/**\n\t * Hide the tooltip.\n\t */\n\thide(): void {\n\t\t// Hide the attribute.\n\t\tthis.removeAttribute( 'show' );\n\t}\n}\n","/**\n * Internal dependencies.\n */\nimport { TPTooltip } from './tp-tooltip';\n\n/**\n * TP Tooltip Trigger.\n */\nexport class TPTooltipTrigger extends HTMLElement {\n\t/**\n\t * Constructor.\n\t */\n\tconstructor() {\n\t\t// Call parent's constructor.\n\t\tsuper();\n\n\t\t// Events.\n\t\tthis.addEventListener( 'mouseenter', this.showTooltip.bind( this ) );\n\t\tthis.addEventListener( 'mouseleave', this.hideTooltip.bind( this ) );\n\t}\n\n\t/**\n\t * Get offset.\n\t */\n\tget offset(): number {\n\t\t// Get the offset.\n\t\treturn parseInt( this.getAttribute( 'offset' ) ?? '0' );\n\t}\n\n\t/**\n\t * Set offset.\n\t */\n\tset offset( offset: number ) {\n\t\t// Set or remove offset.\n\t\tif ( ! offset ) {\n\t\t\tthis.removeAttribute( 'offset' );\n\t\t} else {\n\t\t\tthis.setAttribute( 'offset', offset.toString() );\n\t\t}\n\t}\n\n\t/**\n\t * Show the tooltip.\n\t */\n\tshowTooltip(): void {\n\t\t// Get the tooltip.\n\t\tconst tooltipId: string = this.getAttribute( 'tooltip' ) ?? '';\n\n\t\t// Check if we have a tooltip.\n\t\tif ( '' === tooltipId ) {\n\t\t\t// We don't, bail.\n\t\t\treturn;\n\t\t}\n\n\t\t// Find and show the tooltip with its content.\n\t\tconst tooltip: TPTooltip | null = document.querySelector( `#${ tooltipId }` );\n\t\ttooltip?.setTrigger( this );\n\t\ttooltip?.show();\n\t}\n\n\t/**\n\t * Hide the tooltip.\n\t */\n\thideTooltip(): void {\n\t\t// Get the tooltip.\n\t\tconst tooltipId: string = this.getAttribute( 'tooltip' ) ?? '';\n\n\t\t// Check if we have a tooltip.\n\t\tif ( '' === tooltipId ) {\n\t\t\t// We don't, bail.\n\t\t\treturn;\n\t\t}\n\n\t\t// Find and hide the tooltip.\n\t\tconst tooltip: TPTooltip | null = document.querySelector( `#${ tooltipId }` );\n\t\ttooltip?.hide();\n\t}\n\n\t/**\n\t * Get the content of the tooltip.\n\t *\n\t * @return {Node|null} The content of the tooltip.\n\t */\n\tgetContent(): Node | null {\n\t\t// Find template for content.\n\t\tconst template: HTMLTemplateElement | null = this.querySelector( 'template' );\n\n\t\t// Check if we found a template.\n\t\tif ( template ) {\n\t\t\t// We did, return its content.\n\t\t\treturn template.content.cloneNode( true );\n\t\t}\n\n\t\t// No template found, return null.\n\t\treturn null;\n\t}\n}\n","/**\n * TP Tooltip Arrow.\n */\nexport class TPTooltipArrow extends HTMLElement {\n}\n","/**\n * Styles.\n */\nimport './style.scss';\n\n/**\n * Components.\n */\nimport { TPTooltip } from './tp-tooltip';\nimport { TPTooltipTrigger } from './tp-tooltip-trigger';\nimport { TPTooltipArrow } from './tp-tooltip-arrow';\n\n/**\n * Register Components.\n */\ncustomElements.define( 'tp-tooltip', TPTooltip );\ncustomElements.define( 'tp-tooltip-trigger', TPTooltipTrigger );\ncustomElements.define( 'tp-tooltip-arrow', TPTooltipArrow );\n"],"names":["TPTooltip","HTMLElement","constructor","super","trigger","this","makePopover","getAttribute","setAttribute","setTrigger","setContent","content","getContent","querySelector","replaceChildren","setPosition","height","tooltipHeight","width","tooltipWidth","getBoundingClientRect","x","triggerLeftPosition","y","triggerTopPosition","triggerWidth","triggerHeight","arrowHeight","arrow","offset","style","top","left","show","hide","removeAttribute","TPTooltipTrigger","addEventListener","showTooltip","bind","hideTooltip","parseInt","toString","tooltipId","tooltip","document","template","cloneNode","TPTooltipArrow","customElements","define"],"sourceRoot":""}
@@ -1 +1 @@
1
- tp-tooltip-trigger>button{background-color:rgba(0,0,0,0);border:none;outline:none;cursor:pointer;padding:0}tp-tooltip-popover{--arrow-top-positioning: 0;--arrow-left-positioning: 0;--border-top-color: transparent;--border-bottom-color: transparent;background-color:#fff}tp-tooltip-popover::backdrop{width:0;height:0;border-width:8px;border-style:solid;border-top-color:var(--border-top-color);border-bottom-color:var(--border-bottom-color);border-left-color:rgba(0,0,0,0);border-right-color:rgba(0,0,0,0);top:var(--arrow-top-positioning);left:var(--arrow-left-positioning);transform:translateX(-50%)}
1
+ tp-tooltip{display:none}tp-tooltip[popover]{margin:0}tp-tooltip[show]{display:block}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@travelopia/web-components",
3
- "version": "0.7.6",
3
+ "version": "0.8.0",
4
4
  "description": "Accessible web components for the modern web",
5
5
  "files": [
6
6
  "dist"