@travelopia/web-components 0.7.5 → 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.
- package/dist/declarations.d.ts +29 -3
- package/dist/form/index.js +1 -1
- package/dist/form/index.js.map +1 -1
- package/dist/multi-select/index.js +1 -1
- package/dist/multi-select/index.js.map +1 -1
- package/dist/tooltip/index.js +1 -1
- package/dist/tooltip/index.js.map +1 -1
- package/dist/tooltip/style.css +1 -1
- package/package.json +1 -1
package/dist/declarations.d.ts
CHANGED
|
@@ -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
|
*/
|
package/dist/form/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
(()=>{"use strict";var
|
|
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
|
package/dist/form/index.js.map
CHANGED
|
@@ -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.currentlyHighlightedOption=-1,this.keyboardEventListener=this.handleKeyboardInputs.bind(this),document.addEventListener("click",this.handleDocumentClick.bind(this)),this.addEventListener("change",this.update.bind(this));const t=this.querySelector("tp-multi-select-options");t&&new MutationObserver(this.initialize.bind(this)).observe(t,{childList:!0,subtree:!0}),this.initialize()}static get observedAttributes(){return["open"]}attributeChangedCallback(t="",e="",l=""){e!==l&&"open"===t&&("yes"===l?(document.addEventListener("keydown",this.keyboardEventListener),this.dispatchEvent(new CustomEvent("open",{bubbles:!0}))):(this.unHighlightAllOptions(),document.removeEventListener("keydown",this.keyboardEventListener),this.dispatchEvent(new CustomEvent("close",{bubbles:!0}))))}set value(t){if(!t||!Array.isArray(t))return;const e=this.querySelectorAll("tp-multi-select-option");null==e||e.forEach((e=>{var l;t.includes(null!==(l=e.getAttribute("value"))&&void 0!==l?l:"")?e.setAttribute("selected","yes"):e.removeAttribute("selected")})),this.dispatchEvent(new CustomEvent("change",{bubbles:!0}))}get value(){const t=[],e=this.querySelectorAll("select option[selected]");return null==e||e.forEach((e=>{const l=e.getAttribute("value");l&&t.push(l)})),t}updateFormFieldValue(){const t=this.querySelectorAll("tp-multi-select-option"),e=this.querySelector("select");if(!t||!e)return;const l=Array.from(e.options);t.forEach((t=>{var i,s;const n=null!==(i=t.getAttribute("value"))&&void 0!==i?i:"";if(n){const i=l.find((t=>t.value===n));if("yes"===t.getAttribute("selected"))if(i)i.setAttribute("selected","selected");else{const l=document.createElement("option");l.setAttribute("value",null!==(s=t.getAttribute("value"))&&void 0!==s?s:""),l.setAttribute("selected","selected"),null==e||e.append(l)}else null==i||i.remove()}})),e.dispatchEvent(new Event("change"))}update(){this.updateFormFieldValue();const t=this.value;0!==t.length?this.setAttribute("selected","yes"):this.removeAttribute("selected");const e=this.querySelector("tp-multi-select-status");e&&(t.length>0?e.setAttribute("total",t.length.toString()):e.removeAttribute("total"))}handleDocumentClick(t){this===t.target||this.contains(t.target)||this.removeAttribute("open")}initialize(){var t;let e=this.querySelector("select");if(e)e.innerHTML="";else{e=document.createElement("select"),e.setAttribute("name",null!==(t=this.getAttribute("name"))&&void 0!==t?t:"");const l=this.getAttribute("form");l&&e.setAttribute("form",l),"no"!==this.getAttribute("multiple")&&e.setAttribute("multiple","multiple"),this.append(e)}this.update()}select(t=""){if("no"===this.getAttribute("multiple")&&(this.unSelectAll(),""===t))return void("yes"===this.getAttribute("close-on-select")&&this.removeAttribute("open"));const e=this.querySelectorAll(`tp-multi-select-option[value="${t}"]`);null==e||e.forEach((t=>{"yes"!==t.getAttribute("disabled")&&t.setAttribute("selected","yes")}));const l=this.querySelector("tp-multi-select-search");null==l||l.clear(),null==l||l.focus(),"yes"===this.getAttribute("close-on-select")&&this.removeAttribute("open"),this.update()}selectAll(){const t=this.querySelectorAll("tp-multi-select-option");null==t||t.forEach((t=>{"yes"!==t.getAttribute("disabled")&&t.setAttribute("selected","yes")})),this.update()}unSelect(t=""){const e=this.querySelectorAll(`tp-multi-select-option[value="${t}"]`);null==e||e.forEach((t=>{t.removeAttribute("selected")})),this.update()}unSelectAll(){const t=this.querySelectorAll("tp-multi-select-option");null==t||t.forEach((t=>{t.removeAttribute("selected")})),this.update()}handleKeyboardInputs(t){switch(t.key){case"ArrowDown":t.preventDefault(),this.highlightNextOption();break;case"ArrowUp":t.preventDefault(),this.highlightPreviousOption();break;case"Enter":this.toggleHighlightedOption();break;case"Escape":this.unHighlightAllOptions(),this.removeAttribute("open")}}highlightNextOption(){const t=this.querySelectorAll('tp-multi-select-option:not([hidden="yes"])');if(!t)return void(this.currentlyHighlightedOption=-1);let e=this.currentlyHighlightedOption+1;for(;e<t.length&&"yes"===t[e].getAttribute("disabled");)e++;e!==t.length&&(-1!==this.currentlyHighlightedOption&&t[this.currentlyHighlightedOption].removeAttribute("highlighted"),t[e].setAttribute("highlighted","yes"),t[e].scrollIntoView({behavior:"smooth",block:"nearest"}),this.currentlyHighlightedOption=e)}highlightPreviousOption(){const t=this.querySelectorAll('tp-multi-select-option:not([hidden="yes"])');if(!t)return void(this.currentlyHighlightedOption=-1);let e=this.currentlyHighlightedOption-1;for(;e>=0&&"yes"===t[e].getAttribute("disabled");)e--;e<0||(0!==this.currentlyHighlightedOption&&t[this.currentlyHighlightedOption].removeAttribute("highlighted"),t[e].setAttribute("highlighted","yes"),t[e].scrollIntoView({behavior:"smooth",block:"nearest"}),this.currentlyHighlightedOption=e)}toggleHighlightedOption(){const t=this.querySelector('tp-multi-select-option[highlighted="yes"]');null==t||t.toggle(null)}unHighlightAllOptions(){this.currentlyHighlightedOption=-1;const t=this.querySelectorAll("tp-multi-select-option");t&&t.forEach((t=>{t.removeAttribute("highlighted")}))}}class e extends HTMLElement{constructor(){super(),this.addEventListener("click",this.toggleOpen.bind(this))}toggleOpen(){const t=this.closest("tp-multi-select");t&&("yes"===t.getAttribute("open")?t.removeAttribute("open"):t.setAttribute("open","yes"))}}class l extends HTMLElement{}class i extends HTMLElement{static get observedAttributes(){return["total","format"]}attributeChangedCallback(t="",e="",l=""){e!==l&&this.update()}update(){var t,e,l,i;const s=null!==(t=this.getAttribute("format"))&&void 0!==t?t:"$total Selected";let n=s.replace("$total",null!==(e=this.getAttribute("total"))&&void 0!==e?e:"");if(s.includes("$value")){const t=this.closest("tp-multi-select");if(t){const e=null!==(l=t.value)&&void 0!==l?l:[];let s="";if(e.length>0){const l=t.querySelector(`tp-multi-select-option[value="${e[0]}"]`);l&&(s=null!==(i=l.getAttribute("label"))&&void 0!==i?i:"")}n=n.replace("$value",s)}}this.innerHTML=n}}class s extends HTMLElement{}class n extends HTMLElement{constructor(){super(),this.addEventListener("click",this.toggle.bind(this))}toggle(t){var e;null==t||t.preventDefault(),null==t||t.stopPropagation();const l=this.closest("tp-multi-select"),i=null!==(e=this.getAttribute("value"))&&void 0!==e?e:"";"yes"!==this.getAttribute("selected")?(null==l||l.select(i),null==l||l.dispatchEvent(new CustomEvent("select",{bubbles:!0,detail:{value:i}}))):(null==l||l.unSelect(i),null==l||l.dispatchEvent(new CustomEvent("unselect",{bubbles:!0,detail:{value:i}}))),null==l||l.dispatchEvent(new CustomEvent("change",{bubbles:!0}))}}class u extends HTMLElement{constructor(){var t;super();const e=this.querySelector("input");e&&(e.addEventListener("keydown",this.handleKeyboardInputs.bind(this)),e.addEventListener("keyup",this.handleSearchChange.bind(this)),e.addEventListener("input",this.handleSearchChange.bind(this)),this.addEventListener("click",this.handleClick.bind(this)),null===(t=this.closest("tp-multi-select"))||void 0===t||t.addEventListener("open",this.focus.bind(this)))}handleKeyboardInputs(t){const e=this.closest("tp-multi-select"),l=this.querySelector("input");if(e&&l)switch(t.key){case"Enter":t.preventDefault();break;case"ArrowDown":e.setAttribute("open","yes");break;case"Backspace":if(0===l.value.length){const t=e.querySelector("tp-multi-select-pill:last-of-type");t&&t.removePill()}}}handleSearchChange(){var t;const e=this.closest("tp-multi-select"),l=this.querySelector("input"),i=null===(t=this.closest("tp-multi-select"))||void 0===t?void 0:t.querySelectorAll("tp-multi-select-option");if(!e||!l||!i)return;let s=0;i.forEach((t=>{var e;(null===(e=t.getAttribute("label"))||void 0===e?void 0:e.toLowerCase().match(new RegExp(`.*${l.value.toLowerCase().replace(/\s/g,".*")}.*`)))?(t.removeAttribute("hidden"),s++):t.setAttribute("hidden","yes")})),""===l.value?l.removeAttribute("style"):(l.style.width=`${l.value.length+2}ch`,e.setAttribute("open","yes")),e.setAttribute("visible-options",s.toString())}handleClick(t){var e;t.preventDefault(),t.stopPropagation(),this.dispatchEvent(new CustomEvent("multi-select-opened")),document.dispatchEvent(new Event("click")),null===(e=this.closest("tp-multi-select"))||void 0===e||e.setAttribute("open","yes")}clear(){const t=this.querySelector("input");t&&(t.value="",t.dispatchEvent(new Event("change")))}focus(){var t;this.handleSearchChange(),null===(t=this.querySelector("input"))||void 0===t||t.focus()}}class o extends HTMLElement{constructor(){var t;super(),null===(t=this.querySelector("button"))||void 0===t||t.addEventListener("click",this.handleButtonClick.bind(this))}handleButtonClick(t){null==t||t.preventDefault(),null==t||t.stopPropagation(),this.removePill()}removePill(){var t;const e=this.closest("tp-multi-select");e&&this.getAttribute("value")&&(e.unSelect(null!==(t=this.getAttribute("value"))&&void 0!==t?t:""),e.dispatchEvent(new CustomEvent("unselect",{bubbles:!0})),e.dispatchEvent(new CustomEvent("change",{bubbles:!0})))}}class r extends HTMLElement{constructor(){var t,e,l;super(),null===(t=this.closest("tp-multi-select"))||void 0===t||t.addEventListener("change",this.update.bind(this)),null===(l=null===(e=this.closest("tp-multi-select"))||void 0===e?void 0:e.querySelector("select"))||void 0===l||l.addEventListener("change",(()=>this.update())),this.update()}update(){var t;const e=this.closest("tp-multi-select");if(!e)return;const l=this.querySelectorAll("tp-multi-select-pill"),i=null!==(t=e.value)&&void 0!==t?t:[],s=[];l.forEach((t=>{var e;const l=null!==(e=t.getAttribute("value"))&&void 0!==e?e:"";""!==l&&(s.push(l),i.includes(l)||t.remove())})),i.filter((t=>!s.includes(t))).forEach((t=>{var l;if(""===t)return;const i=e.querySelector(`tp-multi-select-option[value="${t}"]`);i&&this.appendChild(this.createPill(t,null!==(l=i.getAttribute("label"))&&void 0!==l?l:""))}))}createPill(t,e){const l=document.createElement("tp-multi-select-pill");l.setAttribute("value",t);const i=document.createElement("span");i.textContent=e;const s=document.createElement("button");return s.setAttribute("type","button"),s.textContent="x",s.addEventListener("click",(()=>{l.removePill()})),l.appendChild(i),l.appendChild(s),l}}class c extends HTMLElement{constructor(){var t;super(),null===(t=this.closest("tp-multi-select"))||void 0===t||t.addEventListener("change",this.handleValueChanged.bind(this)),this.addEventListener("click",this.toggleSelectAll.bind(this))}handleValueChanged(){var t,e;const l=this.closest("tp-multi-select"),i=null==l?void 0:l.querySelectorAll("tp-multi-select-option");l&&i&&(Array.from(i).filter((t=>"yes"!==t.getAttribute("disabled"))).length===l.value.length?(this.setAttribute("selected","yes"),this.innerHTML=null!==(t=this.getAttribute("unselect-text"))&&void 0!==t?t:""):(this.removeAttribute("selected"),this.innerHTML=null!==(e=this.getAttribute("select-text"))&&void 0!==e?e:""))}toggleSelectAll(){const t=this.closest("tp-multi-select");t&&("yes"!==this.getAttribute("selected")?(t.selectAll(),t.dispatchEvent(new CustomEvent("select-all",{bubbles:!0}))):(t.unSelectAll(),t.dispatchEvent(new CustomEvent("unselect-all",{bubbles:!0}))),t.dispatchEvent(new CustomEvent("change",{bubbles:!0})))}}customElements.define("tp-multi-select",t),customElements.define("tp-multi-select-field",e),customElements.define("tp-multi-select-placeholder",l),customElements.define("tp-multi-select-status",i),customElements.define("tp-multi-select-options",s),customElements.define("tp-multi-select-option",n),customElements.define("tp-multi-select-search",u),customElements.define("tp-multi-select-pill",o),customElements.define("tp-multi-select-pills",r),customElements.define("tp-multi-select-select-all",c)})();
|
|
1
|
+
(()=>{"use strict";class t extends HTMLElement{constructor(){super(),this.currentlyHighlightedOption=-1,this.keyboardEventListener=this.handleKeyboardInputs.bind(this),document.addEventListener("click",this.handleDocumentClick.bind(this)),this.addEventListener("change",this.update.bind(this));const t=this.querySelector("tp-multi-select-options");t&&new MutationObserver(this.initialize.bind(this)).observe(t,{childList:!0,subtree:!0}),this.initialize()}static get observedAttributes(){return["open"]}attributeChangedCallback(t="",e="",l=""){e!==l&&"open"===t&&("yes"===l?(document.addEventListener("keydown",this.keyboardEventListener),this.dispatchEvent(new CustomEvent("open",{bubbles:!0}))):(this.unHighlightAllOptions(),document.removeEventListener("keydown",this.keyboardEventListener),this.dispatchEvent(new CustomEvent("close",{bubbles:!0}))))}set value(t){if(!t||!Array.isArray(t))return;const e=this.querySelectorAll("tp-multi-select-option");null==e||e.forEach((e=>{var l;t.includes(null!==(l=e.getAttribute("value"))&&void 0!==l?l:"")?e.setAttribute("selected","yes"):e.removeAttribute("selected")})),this.dispatchEvent(new CustomEvent("change",{bubbles:!0}))}get value(){const t=[],e=this.querySelectorAll("select option[selected]");return null==e||e.forEach((e=>{const l=e.getAttribute("value");l&&t.push(l)})),t}updateFormFieldValue(){const t=this.querySelectorAll("tp-multi-select-option"),e=this.querySelector("select");if(!t||!e)return;const l=Array.from(e.options);t.forEach((t=>{var i,s;const n=null!==(i=t.getAttribute("value"))&&void 0!==i?i:"";if(n){const i=l.find((t=>t.value===n));if("yes"===t.getAttribute("selected"))if(i)i.setAttribute("selected","selected");else{const l=document.createElement("option");l.setAttribute("value",null!==(s=t.getAttribute("value"))&&void 0!==s?s:""),l.setAttribute("selected","selected"),null==e||e.append(l)}else null==i||i.remove()}})),e.dispatchEvent(new Event("change"))}update(){this.updateFormFieldValue();const t=this.value;0!==t.length?this.setAttribute("selected","yes"):this.removeAttribute("selected");const e=this.querySelector("tp-multi-select-status");e&&(t.length>0?e.setAttribute("total",t.length.toString()):e.removeAttribute("total"))}handleDocumentClick(t){this===t.target||this.contains(t.target)||this.removeAttribute("open")}initialize(){var t;let e=this.querySelector("select");if(e)e.innerHTML="";else{e=document.createElement("select"),e.setAttribute("name",null!==(t=this.getAttribute("name"))&&void 0!==t?t:"");const l=this.getAttribute("form");l&&e.setAttribute("form",l),"no"!==this.getAttribute("multiple")&&e.setAttribute("multiple","multiple"),this.append(e)}this.update()}select(t=""){if("no"===this.getAttribute("multiple")&&(this.unSelectAll(),""===t))return void("yes"===this.getAttribute("close-on-select")&&this.removeAttribute("open"));const e=this.querySelectorAll(`tp-multi-select-option[value="${t}"]`);null==e||e.forEach((t=>{"yes"!==t.getAttribute("disabled")&&t.setAttribute("selected","yes")}));const l=this.querySelector("tp-multi-select-search");null==l||l.clear(),null==l||l.focus(),"yes"===this.getAttribute("close-on-select")&&this.removeAttribute("open"),this.update()}selectAll(){const t=this.querySelectorAll("tp-multi-select-option");null==t||t.forEach((t=>{"yes"!==t.getAttribute("disabled")&&t.setAttribute("selected","yes")})),this.update()}unSelect(t=""){const e=this.querySelectorAll(`tp-multi-select-option[value="${t}"]`);null==e||e.forEach((t=>{t.removeAttribute("selected")})),this.update()}unSelectAll(){const t=this.querySelectorAll("tp-multi-select-option");null==t||t.forEach((t=>{t.removeAttribute("selected")})),this.update()}handleKeyboardInputs(t){switch(t.key){case"ArrowDown":t.preventDefault(),this.highlightNextOption();break;case"ArrowUp":t.preventDefault(),this.highlightPreviousOption();break;case"Enter":this.toggleHighlightedOption();break;case"Escape":this.unHighlightAllOptions(),this.removeAttribute("open")}}highlightNextOption(){const t=this.querySelectorAll('tp-multi-select-option:not([hidden="yes"])');if(!t)return void(this.currentlyHighlightedOption=-1);let e=this.currentlyHighlightedOption+1;for(;e<t.length&&"yes"===t[e].getAttribute("disabled");)e++;e!==t.length&&(-1!==this.currentlyHighlightedOption&&t[this.currentlyHighlightedOption].removeAttribute("highlighted"),t[e].setAttribute("highlighted","yes"),t[e].scrollIntoView({behavior:"smooth",block:"nearest"}),this.currentlyHighlightedOption=e)}highlightPreviousOption(){const t=this.querySelectorAll('tp-multi-select-option:not([hidden="yes"])');if(!t)return void(this.currentlyHighlightedOption=-1);let e=this.currentlyHighlightedOption-1;for(;e>=0&&"yes"===t[e].getAttribute("disabled");)e--;e<0||(0!==this.currentlyHighlightedOption&&t[this.currentlyHighlightedOption].removeAttribute("highlighted"),t[e].setAttribute("highlighted","yes"),t[e].scrollIntoView({behavior:"smooth",block:"nearest"}),this.currentlyHighlightedOption=e)}toggleHighlightedOption(){const t=this.querySelector('tp-multi-select-option[highlighted="yes"]');null==t||t.toggle(null)}unHighlightAllOptions(){this.currentlyHighlightedOption=-1;const t=this.querySelectorAll("tp-multi-select-option");t&&t.forEach((t=>{t.removeAttribute("highlighted")}))}}class e extends HTMLElement{constructor(){super(),this.addEventListener("click",this.toggleOpen.bind(this))}toggleOpen(){const t=this.closest("tp-multi-select");t&&("yes"===t.getAttribute("open")?t.removeAttribute("open"):t.setAttribute("open","yes"))}}class l extends HTMLElement{}class i extends HTMLElement{static get observedAttributes(){return["total","format"]}attributeChangedCallback(t="",e="",l=""){e!==l&&this.update()}update(){var t,e,l,i;const s=null!==(t=this.getAttribute("format"))&&void 0!==t?t:"$total Selected";let n=s.replace("$total",null!==(e=this.getAttribute("total"))&&void 0!==e?e:"");if(s.includes("$value")){const t=this.closest("tp-multi-select");if(t){const e=null!==(l=t.value)&&void 0!==l?l:[];let s="";if(e.length>0){const l=t.querySelector(`tp-multi-select-option[value="${e[0]}"]`);l&&(s=null!==(i=l.getAttribute("label"))&&void 0!==i?i:"")}n=n.replace("$value",s)}}this.innerHTML=n}}class s extends HTMLElement{}class n extends HTMLElement{constructor(){super(),this.addEventListener("click",this.toggle.bind(this))}toggle(t){var e;null==t||t.preventDefault(),null==t||t.stopPropagation();const l=this.closest("tp-multi-select"),i=null!==(e=this.getAttribute("value"))&&void 0!==e?e:"";"yes"!==this.getAttribute("selected")?(null==l||l.select(i),null==l||l.dispatchEvent(new CustomEvent("select",{bubbles:!0,detail:{value:i}}))):(null==l||l.unSelect(i),null==l||l.dispatchEvent(new CustomEvent("unselect",{bubbles:!0,detail:{value:i}}))),null==l||l.dispatchEvent(new CustomEvent("change",{bubbles:!0}))}}class u extends HTMLElement{constructor(){var t;super();const e=this.querySelector("input");e&&(e.addEventListener("keydown",this.handleKeyboardInputs.bind(this)),e.addEventListener("keyup",this.handleSearchChange.bind(this)),e.addEventListener("input",this.handleSearchChange.bind(this)),this.addEventListener("click",this.handleClick.bind(this)),null===(t=this.closest("tp-multi-select"))||void 0===t||t.addEventListener("open",this.focus.bind(this)))}handleKeyboardInputs(t){const e=this.closest("tp-multi-select"),l=this.querySelector("input");if(e&&l)switch(t.key){case"Enter":t.preventDefault();break;case"ArrowDown":e.setAttribute("open","yes");break;case"Backspace":if(0===l.value.length){const t=e.querySelector("tp-multi-select-pill:last-of-type");t&&t.removePill()}}}handleSearchChange(){var t;const e=this.closest("tp-multi-select"),l=this.querySelector("input"),i=null===(t=this.closest("tp-multi-select"))||void 0===t?void 0:t.querySelectorAll("tp-multi-select-option");if(!e||!l||!i)return;let s=0;i.forEach((t=>{var e;(null===(e=t.getAttribute("label"))||void 0===e?void 0:e.toLowerCase().match(new RegExp(`.*${l.value.toLowerCase().replace(/\s/g,".*")}.*`)))?(t.removeAttribute("hidden"),s++):t.setAttribute("hidden","yes")})),""===l.value?l.removeAttribute("style"):(l.style.width=`${l.value.length+2}ch`,e.setAttribute("open","yes")),e.setAttribute("visible-options",s.toString())}handleClick(t){var e;t.preventDefault(),t.stopPropagation(),this.dispatchEvent(new CustomEvent("multi-select-opened")),document.dispatchEvent(new Event("click")),null===(e=this.closest("tp-multi-select"))||void 0===e||e.setAttribute("open","yes")}clear(){const t=this.querySelector("input");t&&(t.value="",t.dispatchEvent(new Event("change")))}focus(){var t;this.handleSearchChange(),null===(t=this.querySelector("input"))||void 0===t||t.focus()}}class o extends HTMLElement{constructor(){var t;super(),null===(t=this.querySelector("button"))||void 0===t||t.addEventListener("click",this.handleButtonClick.bind(this))}handleButtonClick(t){null==t||t.preventDefault(),null==t||t.stopPropagation(),this.removePill()}removePill(){var t;const e=this.closest("tp-multi-select");e&&this.getAttribute("value")&&(e.unSelect(null!==(t=this.getAttribute("value"))&&void 0!==t?t:""),e.dispatchEvent(new CustomEvent("unselect",{bubbles:!0})),e.dispatchEvent(new CustomEvent("change",{bubbles:!0})))}}class r extends HTMLElement{constructor(){var t,e,l;super(),null===(t=this.closest("tp-multi-select"))||void 0===t||t.addEventListener("change",this.update.bind(this)),null===(l=null===(e=this.closest("tp-multi-select"))||void 0===e?void 0:e.querySelector("select"))||void 0===l||l.addEventListener("change",(()=>this.update())),this.update()}update(){var t;const e=this.closest("tp-multi-select");if(!e)return;const l=this.querySelectorAll("tp-multi-select-pill"),i=null!==(t=[...new Set(e.value)])&&void 0!==t?t:[],s=[];l.forEach((t=>{var e;const l=null!==(e=t.getAttribute("value"))&&void 0!==e?e:"";""!==l&&(s.push(l),i.includes(l)||t.remove())})),i.filter((t=>!s.includes(t))).forEach((t=>{var l;if(""===t)return;const i=e.querySelector(`tp-multi-select-option[value="${t}"]`);i&&this.appendChild(this.createPill(t,null!==(l=i.getAttribute("label"))&&void 0!==l?l:""))}))}createPill(t,e){const l=document.createElement("tp-multi-select-pill");l.setAttribute("value",t);const i=document.createElement("span");i.textContent=e;const s=document.createElement("button");return s.setAttribute("type","button"),s.textContent="x",s.addEventListener("click",(()=>{l.removePill()})),l.appendChild(i),l.appendChild(s),l}}class c extends HTMLElement{constructor(){var t;super(),null===(t=this.closest("tp-multi-select"))||void 0===t||t.addEventListener("change",this.handleValueChanged.bind(this)),this.addEventListener("click",this.toggleSelectAll.bind(this))}handleValueChanged(){var t,e;const l=this.closest("tp-multi-select"),i=null==l?void 0:l.querySelectorAll("tp-multi-select-option");l&&i&&(Array.from(i).filter((t=>"yes"!==t.getAttribute("disabled"))).length===l.value.length?(this.setAttribute("selected","yes"),this.innerHTML=null!==(t=this.getAttribute("unselect-text"))&&void 0!==t?t:""):(this.removeAttribute("selected"),this.innerHTML=null!==(e=this.getAttribute("select-text"))&&void 0!==e?e:""))}toggleSelectAll(){const t=this.closest("tp-multi-select");t&&("yes"!==this.getAttribute("selected")?(t.selectAll(),t.dispatchEvent(new CustomEvent("select-all",{bubbles:!0}))):(t.unSelectAll(),t.dispatchEvent(new CustomEvent("unselect-all",{bubbles:!0}))),t.dispatchEvent(new CustomEvent("change",{bubbles:!0})))}}customElements.define("tp-multi-select",t),customElements.define("tp-multi-select-field",e),customElements.define("tp-multi-select-placeholder",l),customElements.define("tp-multi-select-status",i),customElements.define("tp-multi-select-options",s),customElements.define("tp-multi-select-option",n),customElements.define("tp-multi-select-search",u),customElements.define("tp-multi-select-pill",o),customElements.define("tp-multi-select-pills",r),customElements.define("tp-multi-select-select-all",c)})();
|
|
2
2
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dist/multi-select/index.js","mappings":"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","sources":["webpack://@travelopia/web-components/./src/multi-select/tp-multi-select.ts","webpack://@travelopia/web-components/./src/multi-select/tp-multi-select-field.ts","webpack://@travelopia/web-components/./src/multi-select/tp-multi-select-placeholder.ts","webpack://@travelopia/web-components/./src/multi-select/tp-multi-select-status.ts","webpack://@travelopia/web-components/./src/multi-select/tp-multi-select-options.ts","webpack://@travelopia/web-components/./src/multi-select/tp-multi-select-option.ts","webpack://@travelopia/web-components/./src/multi-select/tp-multi-select-search.ts","webpack://@travelopia/web-components/./src/multi-select/tp-multi-select-pill.ts","webpack://@travelopia/web-components/./src/multi-select/tp-multi-select-pills.ts","webpack://@travelopia/web-components/./src/multi-select/tp-multi-select-select-all.ts","webpack://@travelopia/web-components/./src/multi-select/index.ts"],"sourcesContent":["/**\n * Internal dependencies.\n */\nimport { TPMultiSelectOptionElement } from './tp-multi-select-option';\nimport { TPMultiSelectStatusElement } from './tp-multi-select-status';\nimport { TPMultiSelectOptionsElement } from './tp-multi-select-options';\nimport { TPMultiSelectSearchElement } from './tp-multi-select-search';\n\n/**\n * TP Multi Select.\n */\nexport class TPMultiSelectElement extends HTMLElement {\n\t/**\n\t * Properties.\n\t */\n\tcurrentlyHighlightedOption: number = -1;\n\tprotected keyboardEventListener: EventListener;\n\n\t/**\n\t * Constructor.\n\t */\n\tconstructor() {\n\t\t// Initialize parent.\n\t\tsuper();\n\n\t\t// Events.\n\t\tthis.keyboardEventListener = this.handleKeyboardInputs.bind( this ) as EventListener;\n\t\tdocument.addEventListener( 'click', this.handleDocumentClick.bind( this ) );\n\t\tthis.addEventListener( 'change', this.update.bind( this ) );\n\n\t\t// Get options.\n\t\tconst options: TPMultiSelectOptionsElement | null = this.querySelector( 'tp-multi-select-options' );\n\n\t\t// Listen for dynamic changes to the option values.\n\t\tif ( options ) {\n\t\t\tconst mutationObserver: MutationObserver = new MutationObserver( this.initialize.bind( this ) );\n\t\t\tmutationObserver.observe( options, { childList: true, subtree: true } );\n\t\t}\n\n\t\t// Initialize component.\n\t\tthis.initialize();\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 to observe.\n\t\treturn [ 'open' ];\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// If no changes.\n\t\tif ( oldValue === newValue ) {\n\t\t\t// Exit.\n\t\t\treturn;\n\t\t}\n\n\t\t// Changed attribute name is 'open'.\n\t\tif ( 'open' === name ) {\n\t\t\t// If new value is 'yes' then open the dropdown.\n\t\t\tif ( 'yes' === newValue ) {\n\t\t\t\tdocument.addEventListener( 'keydown', this.keyboardEventListener );\n\t\t\t\tthis.dispatchEvent( new CustomEvent( 'open', { bubbles: true } ) );\n\t\t\t} else {\n\t\t\t\tthis.unHighlightAllOptions();\n\t\t\t\tdocument.removeEventListener( 'keydown', this.keyboardEventListener );\n\t\t\t\tthis.dispatchEvent( new CustomEvent( 'close', { bubbles: true } ) );\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Set the value of this component.\n\t *\n\t * @param {Array} value Value.\n\t */\n\tset value( value: string[] ) {\n\t\t// Bail if value is not an array.\n\t\tif ( ! value || ! Array.isArray( value ) ) {\n\t\t\t// Bail early.\n\t\t\treturn;\n\t\t}\n\n\t\t// Set the value of the select field.\n\t\tconst styledOptions: NodeListOf<TPMultiSelectOptionElement> | null = this.querySelectorAll( 'tp-multi-select-option' );\n\t\tstyledOptions?.forEach( ( option: TPMultiSelectOptionElement ): void => {\n\t\t\t// Check if the value is in the array.\n\t\t\tif ( value.includes( option.getAttribute( 'value' ) ?? '' ) ) {\n\t\t\t\toption.setAttribute( 'selected', 'yes' );\n\t\t\t} else {\n\t\t\t\toption.removeAttribute( 'selected' );\n\t\t\t}\n\t\t} );\n\n\t\t// Dispatch change event.\n\t\tthis.dispatchEvent( new CustomEvent( 'change', { bubbles: true } ) );\n\t}\n\n\t/**\n\t * Get the value of this component.\n\t *\n\t * @return {Array} Value of this component.\n\t */\n\tget value(): string[] {\n\t\t// Get the value of the select field.\n\t\tconst value: string[] = [];\n\n\t\t// Get selected options.\n\t\tconst selectedOptions: NodeListOf<HTMLOptionElement> | null = this.querySelectorAll( 'select option[selected]' );\n\t\tselectedOptions?.forEach( ( option: HTMLOptionElement ) => {\n\t\t\t// Get option value.\n\t\t\tconst optionValue = option.getAttribute( 'value' );\n\n\t\t\t// Add value to array.\n\t\t\tif ( optionValue ) {\n\t\t\t\tvalue.push( optionValue );\n\t\t\t}\n\t\t} );\n\n\t\t// Return value.\n\t\treturn value;\n\t}\n\n\t/**\n\t * Update the value of the select field.\n\t */\n\tprotected updateFormFieldValue(): void {\n\t\t// Get options.\n\t\tconst styledSelectedOptions: NodeListOf<TPMultiSelectOptionElement> | null = this.querySelectorAll( `tp-multi-select-option` );\n\t\tconst selectField: HTMLSelectElement | null = this.querySelector( 'select' );\n\n\t\t// Bail if there's no styled selected options or select field.\n\t\tif ( ! styledSelectedOptions || ! selectField ) {\n\t\t\t// Bail.\n\t\t\treturn;\n\t\t}\n\n\t\t// Get selected options.\n\t\tconst selectOptions: HTMLOptionElement[] = Array.from( selectField.options );\n\n\t\t// Traverse options.\n\t\tstyledSelectedOptions.forEach( ( option: TPMultiSelectOptionElement ): void => {\n\t\t\t// Get option value.\n\t\t\tconst optionValue = option.getAttribute( 'value' ) ?? '';\n\n\t\t\t// If option value is present.\n\t\t\tif ( optionValue ) {\n\t\t\t\tconst matchingSelectOption: HTMLOptionElement | undefined = selectOptions.find( ( selectOption ) => selectOption.value === optionValue );\n\n\t\t\t\t// Update select field.\n\t\t\t\tif ( 'yes' === option.getAttribute( 'selected' ) ) {\n\t\t\t\t\t// Update select field.\n\t\t\t\t\tif ( matchingSelectOption ) {\n\t\t\t\t\t\tmatchingSelectOption.setAttribute( 'selected', 'selected' );\n\t\t\t\t\t} else {\n\t\t\t\t\t\tconst newOption: HTMLOptionElement = document.createElement( 'option' );\n\t\t\t\t\t\tnewOption.setAttribute( 'value', option.getAttribute( 'value' ) ?? '' );\n\t\t\t\t\t\tnewOption.setAttribute( 'selected', 'selected' );\n\t\t\t\t\t\tselectField?.append( newOption );\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tmatchingSelectOption?.remove();\n\t\t\t\t}\n\t\t\t}\n\t\t} );\n\n\t\t// Dispatch events.\n\t\tselectField.dispatchEvent( new Event( 'change' ) );\n\t}\n\n\t/**\n\t * Update component and sub-components.\n\t */\n\tupdate(): void {\n\t\t// First, update field value.\n\t\tthis.updateFormFieldValue();\n\n\t\t// Get value.\n\t\tconst value: string[] = this.value;\n\n\t\t// Toggle selected attribute.\n\t\tif ( 0 !== value.length ) {\n\t\t\tthis.setAttribute( 'selected', 'yes' );\n\t\t} else {\n\t\t\tthis.removeAttribute( 'selected' );\n\t\t}\n\n\t\t// Get status.\n\t\tconst status: TPMultiSelectStatusElement | null = this.querySelector( 'tp-multi-select-status' );\n\n\t\t// Update status.\n\t\tif ( status ) {\n\t\t\t// Update status.\n\t\t\tif ( value.length > 0 ) {\n\t\t\t\tstatus.setAttribute( 'total', value.length.toString() );\n\t\t\t} else {\n\t\t\t\tstatus.removeAttribute( 'total' );\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Handle clicking the document.\n\t *\n\t * @param {Event} e Event.\n\t */\n\tprotected handleDocumentClick( e: Event ): void {\n\t\t// Close on click outside.\n\t\tif ( this !== e.target && ! this.contains( e.target as Node ) ) {\n\t\t\tthis.removeAttribute( 'open' );\n\t\t}\n\t}\n\n\t/**\n\t * Initialize component.\n\t */\n\tinitialize(): void {\n\t\t// Get select element.\n\t\tlet selectElement: HTMLSelectElement | null = this.querySelector( 'select' );\n\n\t\t// Create select element (if it doesn't already exist).\n\t\tif ( ! selectElement ) {\n\t\t\tselectElement = document.createElement( 'select' );\n\t\t\tselectElement.setAttribute( 'name', this.getAttribute( 'name' ) ?? '' );\n\n\t\t\t// Get form reference.\n\t\t\tconst formReference = this.getAttribute( 'form' );\n\n\t\t\t// Add form reference.\n\t\t\tif ( formReference ) {\n\t\t\t\tselectElement.setAttribute( 'form', formReference );\n\t\t\t}\n\n\t\t\t// Set multiple.\n\t\t\tif ( 'no' !== this.getAttribute( 'multiple' ) ) {\n\t\t\t\tselectElement.setAttribute( 'multiple', 'multiple' );\n\t\t\t}\n\n\t\t\t// Append.\n\t\t\tthis.append( selectElement );\n\t\t} else {\n\t\t\tselectElement.innerHTML = '';\n\t\t}\n\n\t\t// Update components for selected options.\n\t\tthis.update();\n\t}\n\n\t/**\n\t * Select a value.\n\t *\n\t * @param {string} value Value to select.\n\t */\n\tselect( value: string = '' ): void {\n\t\t// Stuff for single-select.\n\t\tif ( 'no' === this.getAttribute( 'multiple' ) ) {\n\t\t\t// First, unselect everything.\n\t\t\tthis.unSelectAll();\n\n\t\t\t// If the value is blank, don't do anything else.\n\t\t\tif ( '' === value ) {\n\t\t\t\t// Close the field, if applicable.\n\t\t\t\tif ( 'yes' === this.getAttribute( 'close-on-select' ) ) {\n\t\t\t\t\tthis.removeAttribute( 'open' );\n\t\t\t\t}\n\n\t\t\t\t// Exit.\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\n\t\t// Select all options.\n\t\tconst styledSelectedOptions: NodeListOf<TPMultiSelectOptionElement> | null = this.querySelectorAll( `tp-multi-select-option[value=\"${ value }\"]` );\n\t\tstyledSelectedOptions?.forEach( ( option: TPMultiSelectOptionElement ): void => {\n\t\t\t// Update select field.\n\t\t\tif ( 'yes' !== option.getAttribute( 'disabled' ) ) {\n\t\t\t\toption.setAttribute( 'selected', 'yes' );\n\t\t\t}\n\t\t} );\n\n\t\t// Search stuff.\n\t\tconst search: TPMultiSelectSearchElement | null = this.querySelector( 'tp-multi-select-search' );\n\t\tsearch?.clear();\n\t\tsearch?.focus();\n\n\t\t// Close the field, if applicable.\n\t\tif ( 'yes' === this.getAttribute( 'close-on-select' ) ) {\n\t\t\tthis.removeAttribute( 'open' );\n\t\t}\n\n\t\t// Update component.\n\t\tthis.update();\n\t}\n\n\t/**\n\t * Select all values.\n\t */\n\tselectAll(): void {\n\t\t// Get all options.\n\t\tconst styledOptions: NodeListOf<TPMultiSelectOptionElement> | null = this.querySelectorAll( 'tp-multi-select-option' );\n\t\tstyledOptions?.forEach( ( option: TPMultiSelectOptionElement ): void => {\n\t\t\t// Update select field.\n\t\t\tif ( 'yes' !== option.getAttribute( 'disabled' ) ) {\n\t\t\t\toption.setAttribute( 'selected', 'yes' );\n\t\t\t}\n\t\t} );\n\n\t\t// Update component.\n\t\tthis.update();\n\t}\n\n\t/**\n\t * Un-select a value.\n\t *\n\t * @param {string} value Value to unselect.\n\t */\n\tunSelect( value: string = '' ): void {\n\t\t// Get all options with the specified value.\n\t\tconst styledSelectedOptions: NodeListOf<TPMultiSelectOptionElement> | null = this.querySelectorAll( `tp-multi-select-option[value=\"${ value }\"]` );\n\t\tstyledSelectedOptions?.forEach( ( option: TPMultiSelectOptionElement ): void => {\n\t\t\t// Remove selected attribute.\n\t\t\toption.removeAttribute( 'selected' );\n\t\t} );\n\n\t\t// update component.\n\t\tthis.update();\n\t}\n\n\t/**\n\t * Un-select all values.\n\t */\n\tunSelectAll(): void {\n\t\t// Get all options.\n\t\tconst styledSelectedOptions: NodeListOf<TPMultiSelectOptionElement> | null = this.querySelectorAll( 'tp-multi-select-option' );\n\t\tstyledSelectedOptions?.forEach( ( option: TPMultiSelectOptionElement ): void => {\n\t\t\t// Remove selected attribute.\n\t\t\toption.removeAttribute( 'selected' );\n\t\t} );\n\n\t\t// Update component.\n\t\tthis.update();\n\t}\n\n\t/**\n\t * Handle keyboard inputs.\n\t *\n\t * @param {Event} e Keyboard event.\n\t */\n\thandleKeyboardInputs( e: KeyboardEvent ): void {\n\t\t// Keyboard events.\n\t\tswitch ( e.key ) {\n\t\t\tcase 'ArrowDown':\n\t\t\t\te.preventDefault();\n\t\t\t\tthis.highlightNextOption();\n\t\t\t\tbreak;\n\t\t\tcase 'ArrowUp':\n\t\t\t\te.preventDefault();\n\t\t\t\tthis.highlightPreviousOption();\n\t\t\t\tbreak;\n\t\t\tcase 'Enter':\n\t\t\t\tthis.toggleHighlightedOption();\n\t\t\t\tbreak;\n\t\t\tcase 'Escape':\n\t\t\t\tthis.unHighlightAllOptions();\n\t\t\t\tthis.removeAttribute( 'open' );\n\t\t\t\tbreak;\n\t\t}\n\t}\n\n\t/**\n\t * Highlight the next option.\n\t */\n\thighlightNextOption(): void {\n\t\t// Get options.\n\t\tconst options: NodeListOf<TPMultiSelectOptionElement> | null = this.querySelectorAll( 'tp-multi-select-option:not([hidden=\"yes\"])' );\n\n\t\t// Bail early if there are no options. Set the currently highlighted option to -1 (no more options to highlight).\n\t\tif ( ! options ) {\n\t\t\tthis.currentlyHighlightedOption = -1;\n\n\t\t\t// Exit.\n\t\t\treturn;\n\t\t}\n\n\t\t// Find the next option to be highlighted. Assume next option is the favorable option.\n\t\tlet nextToBeHighlighted = this.currentlyHighlightedOption + 1;\n\n\t\t// Keep iterating to skip over disabled options until we find a suitable option.\n\t\twhile ( nextToBeHighlighted < options.length && options[ nextToBeHighlighted ].getAttribute( 'disabled' ) === 'yes' ) {\n\t\t\tnextToBeHighlighted++;\n\t\t}\n\n\t\t// If there are no more options to highlight, exit. Here, the last highlighted option keeps highlighted.\n\t\tif ( nextToBeHighlighted === options.length ) {\n\t\t\t// Exit.\n\t\t\treturn;\n\t\t}\n\n\t\t// Remove highlight from the current option, if any.\n\t\tif ( this.currentlyHighlightedOption !== -1 ) {\n\t\t\toptions[ this.currentlyHighlightedOption ].removeAttribute( 'highlighted' );\n\t\t}\n\n\t\t// Highlight the found option.\n\t\toptions[ nextToBeHighlighted ].setAttribute( 'highlighted', 'yes' );\n\n\t\t// Scroll the highlighted option into view with smooth behavior.\n\t\toptions[ nextToBeHighlighted ].scrollIntoView( { behavior: 'smooth', block: 'nearest' } );\n\n\t\t// Update the currentlyHighlightedOption for the next iteration.\n\t\tthis.currentlyHighlightedOption = nextToBeHighlighted;\n\t}\n\n\t/**\n\t * Highlight previous option.\n\t */\n\thighlightPreviousOption(): void {\n\t\t// Get options.\n\t\tconst options: NodeListOf<TPMultiSelectOptionElement> | null = this.querySelectorAll( 'tp-multi-select-option:not([hidden=\"yes\"])' );\n\n\t\t// Bail early if there are no options. Set the currently highlighted option to -1 (no more options to highlight).\n\t\tif ( ! options ) {\n\t\t\tthis.currentlyHighlightedOption = -1;\n\n\t\t\t// Exit.\n\t\t\treturn;\n\t\t}\n\n\t\t// Find the previous option to be highlighted. Assume previous option is the favorable option.\n\t\tlet previousToBeHighlighted = this.currentlyHighlightedOption - 1;\n\n\t\t// Keep iterating to skip over disabled options until we find a suitable option.\n\t\twhile ( previousToBeHighlighted >= 0 && options[ previousToBeHighlighted ].getAttribute( 'disabled' ) === 'yes' ) {\n\t\t\tpreviousToBeHighlighted--;\n\t\t}\n\n\t\t// If there are no more options to highlight, exit.\n\t\tif ( previousToBeHighlighted < 0 ) {\n\t\t\t// Exit.\n\t\t\treturn;\n\t\t}\n\n\t\t// Remove highlight from the current option, if any.\n\t\tif ( this.currentlyHighlightedOption !== 0 ) {\n\t\t\toptions[ this.currentlyHighlightedOption ].removeAttribute( 'highlighted' );\n\t\t}\n\n\t\t// Highlight the found option.\n\t\toptions[ previousToBeHighlighted ].setAttribute( 'highlighted', 'yes' );\n\n\t\t// Scroll the highlighted option into view with smooth behavior.\n\t\toptions[ previousToBeHighlighted ].scrollIntoView( { behavior: 'smooth', block: 'nearest' } );\n\n\t\t// Update the currentlyHighlightedOption for the next iteration.\n\t\tthis.currentlyHighlightedOption = previousToBeHighlighted;\n\t}\n\n\t/**\n\t * Toggle highlighted option.\n\t */\n\ttoggleHighlightedOption(): void {\n\t\t// Get option and if it exists set it to null.\n\t\tconst option: TPMultiSelectOptionElement | null = this.querySelector( `tp-multi-select-option[highlighted=\"yes\"]` );\n\t\toption?.toggle( null );\n\t}\n\n\t/**\n\t * Un-highlight all options.\n\t */\n\tunHighlightAllOptions(): void {\n\t\t// Reset the currentlyHighlightedOption.\n\t\tthis.currentlyHighlightedOption = -1;\n\n\t\t// Get options.\n\t\tconst options: NodeListOf<TPMultiSelectOptionElement> | null = this.querySelectorAll( 'tp-multi-select-option' );\n\n\t\t// If there are options, un-highlight them.\n\t\tif ( options ) {\n\t\t\toptions.forEach( ( option: TPMultiSelectOptionElement ): void => {\n\t\t\t\t// Remove highlighted attribute.\n\t\t\t\toption.removeAttribute( 'highlighted' );\n\t\t\t} );\n\t\t}\n\t}\n}\n","/**\n * Internal dependencies.\n */\nimport { TPMultiSelectElement } from './tp-multi-select';\n\n/**\n * TP Multi Select Field.\n */\nexport class TPMultiSelectFieldElement extends HTMLElement {\n\t/**\n\t * Constructor.\n\t */\n\tconstructor() {\n\t\t// Initialize parent.\n\t\tsuper();\n\n\t\t// Add event listener.\n\t\tthis.addEventListener( 'click', this.toggleOpen.bind( this ) );\n\t}\n\n\t/**\n\t * Toggle opening this component.\n\t */\n\ttoggleOpen(): void {\n\t\t// Get multi-select.\n\t\tconst multiSelect: TPMultiSelectElement | null = this.closest( 'tp-multi-select' );\n\n\t\t// Bail early if we don't have a multi-select.\n\t\tif ( ! multiSelect ) {\n\t\t\t// Bail early.\n\t\t\treturn;\n\t\t}\n\n\t\t// Toggle open.\n\t\tif ( 'yes' === multiSelect.getAttribute( 'open' ) ) {\n\t\t\tmultiSelect.removeAttribute( 'open' );\n\t\t} else {\n\t\t\tmultiSelect.setAttribute( 'open', 'yes' );\n\t\t}\n\t}\n}\n","/**\n * TP Multi Select Placeholder.\n */\nexport class TPMultiSelectPlaceholderElement extends HTMLElement {\n}\n","/**\n * Internal dependencies.\n */\nimport { TPMultiSelectElement } from './tp-multi-select';\nimport { TPMultiSelectOptionElement } from './tp-multi-select-option';\n\n/**\n * TP Multi Select Status.\n */\nexport class TPMultiSelectStatusElement 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 to observe.\n\t\treturn [ 'total', 'format' ];\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.\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 format attribute.\n\t\tconst format: string = this.getAttribute( 'format' ) ?? '$total Selected';\n\t\tlet html: string = format.replace( '$total', this.getAttribute( 'total' ) ?? '' );\n\n\t\t// Format string includes $value.\n\t\tif ( format.includes( '$value' ) ) {\n\t\t\t// Get multi-select.\n\t\t\tconst multiSelect: TPMultiSelectElement | null = this.closest( 'tp-multi-select' );\n\n\t\t\t// Check if multi-select exists.\n\t\t\tif ( multiSelect ) {\n\t\t\t\t// Get value if present or create an empty array.\n\t\t\t\tconst value: string[] = multiSelect.value ?? [];\n\t\t\t\tlet replace: string = '';\n\n\t\t\t\t// Check if value array is not empty.\n\t\t\t\tif ( value.length > 0 ) {\n\t\t\t\t\t// Get first value.\n\t\t\t\t\tconst option: TPMultiSelectOptionElement | null = multiSelect.querySelector( `tp-multi-select-option[value=\"${ value[ 0 ] }\"]` );\n\n\t\t\t\t\t// Check if option exists.\n\t\t\t\t\tif ( option ) {\n\t\t\t\t\t\treplace = option.getAttribute( 'label' ) ?? '';\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Replace $value.\n\t\t\t\thtml = html.replace( '$value', replace );\n\t\t\t}\n\t\t}\n\n\t\t// Set inner HTML.\n\t\tthis.innerHTML = html;\n\t}\n}\n","/**\n * TP Multi Select Options.\n */\nexport class TPMultiSelectOptionsElement extends HTMLElement {\n}\n","/**\n * Internal dependencies.\n */\nimport { TPMultiSelectElement } from './tp-multi-select';\n\n/**\n * TP Multi Select Option.\n */\nexport class TPMultiSelectOptionElement extends HTMLElement {\n\t/**\n\t * Constructor.\n\t */\n\tconstructor() {\n\t\t// Initialize parent.\n\t\tsuper();\n\n\t\t// Add event listener to toggle the selected state.\n\t\tthis.addEventListener( 'click', this.toggle.bind( this ) );\n\t}\n\n\t/**\n\t * Select / un-select this option.\n\t *\n\t * @param {Event} e Click event.\n\t */\n\ttoggle( e: Event | null ): void {\n\t\t// Prevent default behavior and stop propagation.\n\t\te?.preventDefault();\n\t\te?.stopPropagation();\n\n\t\t// Get multi-select element and value of option.\n\t\tconst multiSelect: TPMultiSelectElement | null = this.closest( 'tp-multi-select' );\n\t\tconst value: string = this.getAttribute( 'value' ) ?? '';\n\n\t\t// Toggle selected state. Dispatch custom events accordingly.\n\t\tif ( 'yes' !== this.getAttribute( 'selected' ) ) {\n\t\t\tmultiSelect?.select( value );\n\t\t\tmultiSelect?.dispatchEvent( new CustomEvent( 'select', {\n\t\t\t\tbubbles: true,\n\t\t\t\tdetail: { value },\n\t\t\t} ) );\n\t\t} else {\n\t\t\tmultiSelect?.unSelect( value );\n\t\t\tmultiSelect?.dispatchEvent( new CustomEvent( 'unselect', {\n\t\t\t\tbubbles: true,\n\t\t\t\tdetail: { value },\n\t\t\t} ) );\n\t\t}\n\n\t\t// Dispatch change event.\n\t\tmultiSelect?.dispatchEvent( new CustomEvent( 'change', { bubbles: true } ) );\n\t}\n}\n","/**\n * Internal dependencies.\n */\nimport { TPMultiSelectElement } from './tp-multi-select';\nimport { TPMultiSelectOptionElement } from './tp-multi-select-option';\nimport { TPMultiSelectPillElement } from './tp-multi-select-pill';\n\n/**\n * TP Multi Select Search.\n */\nexport class TPMultiSelectSearchElement extends HTMLElement {\n\t/**\n\t * Constructor.\n\t */\n\tconstructor() {\n\t\t// Initialize parent.\n\t\tsuper();\n\n\t\t// get input.\n\t\tconst input: HTMLInputElement | null = this.querySelector( 'input' );\n\n\t\t// Check if input exists.\n\t\tif ( ! input ) {\n\t\t\t// No, its not. Exit.\n\t\t\treturn;\n\t\t}\n\n\t\t// Add event listeners.\n\t\tinput.addEventListener( 'keydown', this.handleKeyboardInputs.bind( this ) );\n\t\tinput.addEventListener( 'keyup', this.handleSearchChange.bind( this ) );\n\t\tinput.addEventListener( 'input', this.handleSearchChange.bind( this ) );\n\t\tthis.addEventListener( 'click', this.handleClick.bind( this ) );\n\t\tthis.closest( 'tp-multi-select' )?.addEventListener( 'open', this.focus.bind( this ) );\n\t}\n\n\t/**\n\t * Handle keyboard inputs.\n\t *\n\t * @param {Event} e Keyboard event.\n\t */\n\thandleKeyboardInputs( e: KeyboardEvent ): void {\n\t\t// Get multi select and search field.\n\t\tconst multiSelect: TPMultiSelectElement | null = this.closest( 'tp-multi-select' );\n\t\tconst search: HTMLInputElement | null = this.querySelector( 'input' );\n\n\t\t// Check if multi select and search field exists.\n\t\tif ( ! multiSelect || ! search ) {\n\t\t\t// Bail early.\n\t\t\treturn;\n\t\t}\n\n\t\t// Handle keyboard inputs.\n\t\tswitch ( e.key ) {\n\t\t\tcase 'Enter':\n\t\t\t\te.preventDefault(); // Prevent inadvertent form submits.\n\t\t\t\tbreak;\n\t\t\tcase 'ArrowDown':\n\t\t\t\tmultiSelect.setAttribute( 'open', 'yes' );\n\t\t\t\tbreak;\n\t\t\tcase 'Backspace': // Remove last pill if search is empty.\n\t\t\t\tif ( 0 === search.value.length ) {\n\t\t\t\t\tconst pill: TPMultiSelectPillElement | null = multiSelect.querySelector( 'tp-multi-select-pill:last-of-type' );\n\n\t\t\t\t\t// Check if pill exists, remove it.\n\t\t\t\t\tif ( pill ) {\n\t\t\t\t\t\tpill.removePill();\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t}\n\t}\n\n\t/**\n\t * Handle search field value changed.\n\t */\n\tprotected handleSearchChange(): void {\n\t\t// Get search field and options.\n\t\tconst multiSelect: TPMultiSelectElement | null = this.closest( 'tp-multi-select' );\n\t\tconst search: HTMLInputElement | null = this.querySelector( 'input' );\n\t\tconst options: NodeListOf<TPMultiSelectOptionElement> | undefined = this.closest( 'tp-multi-select' )?.querySelectorAll( 'tp-multi-select-option' );\n\n\t\t// Check if multi select, search, and options field exists.\n\t\tif ( ! multiSelect || ! search || ! options ) {\n\t\t\t// Bail early.\n\t\t\treturn;\n\t\t}\n\n\t\t// Initialize matched option count.\n\t\tlet matchedOptionCount = 0;\n\t\toptions.forEach( ( option: TPMultiSelectOptionElement ): void => {\n\t\t\t// Hide and show options based on search.\n\t\t\tif ( option.getAttribute( 'label' )?.toLowerCase().match( new RegExp( `.*${ search.value.toLowerCase().replace( /\\s/g, '.*' ) }.*` ) ) ) {\n\t\t\t\toption.removeAttribute( 'hidden' );\n\t\t\t\tmatchedOptionCount++;\n\t\t\t} else {\n\t\t\t\toption.setAttribute( 'hidden', 'yes' );\n\t\t\t}\n\t\t} );\n\n\t\t// Resize input width.\n\t\tif ( '' === search.value ) {\n\t\t\tsearch.removeAttribute( 'style' );\n\t\t} else {\n\t\t\tsearch.style.width = `${ search.value.length + 2 }ch`;\n\t\t\tmultiSelect.setAttribute( 'open', 'yes' );\n\t\t}\n\n\t\t// Show matched option count.\n\t\tmultiSelect.setAttribute( 'visible-options', matchedOptionCount.toString() );\n\t}\n\n\t/**\n\t * Handle click.\n\t *\n\t * @param {Event} e Click event.\n\t */\n\tprotected handleClick( e: Event ): void {\n\t\t// First, prevent propagation to avoid document.click set on `tp-multi-select`.\n\t\te.preventDefault();\n\t\te.stopPropagation();\n\n\t\t// Now send the event so other stuff can work as per normal, and another event for good measure.\n\t\tthis.dispatchEvent( new CustomEvent( 'multi-select-opened' ) );\n\t\tdocument.dispatchEvent( new Event( 'click' ) );\n\n\t\t// Open multi select.\n\t\tthis.closest( 'tp-multi-select' )?.setAttribute( 'open', 'yes' );\n\t}\n\n\t/**\n\t * Clear the search field.\n\t */\n\tclear(): void {\n\t\t// Clear search field.\n\t\tconst search: HTMLInputElement | null = this.querySelector( 'input' );\n\n\t\t// Check if search field exists.\n\t\tif ( search ) {\n\t\t\t// Set value to empty string and dispatch change event.\n\t\t\tsearch.value = '';\n\t\t\tsearch.dispatchEvent( new Event( 'change' ) );\n\t\t}\n\t}\n\n\t/**\n\t * Set focus on the search field.\n\t */\n\tfocus(): void {\n\t\t// When it's focused, use search change to ensure the results are refreshed.\n\t\tthis.handleSearchChange();\n\n\t\t// Focus on input.\n\t\tthis.querySelector( 'input' )?.focus();\n\t}\n}\n","/**\n * Internal dependencies.\n */\nimport { TPMultiSelectElement } from './tp-multi-select';\n\n/**\n * TP Multi Select Pill.\n */\nexport class TPMultiSelectPillElement extends HTMLElement {\n\t/**\n\t * Constructor.\n\t */\n\tconstructor() {\n\t\t// Initialize parent.\n\t\tsuper();\n\n\t\t// Add event listener.\n\t\tthis.querySelector( 'button' )?.addEventListener( 'click', this.handleButtonClick.bind( this ) );\n\t}\n\n\t/**\n\t * Handle button click.\n\t *\n\t * @param {Event} e Click event.\n\t */\n\thandleButtonClick( e: Event | null ): void {\n\t\t// Prevent default behavior and stop propagation.\n\t\te?.preventDefault();\n\t\te?.stopPropagation();\n\n\t\t// Remove pill.\n\t\tthis.removePill();\n\t}\n\n\t/**\n\t * Remove this pill.\n\t */\n\tremovePill(): void {\n\t\t// Get multi-select.\n\t\tconst multiSelect: TPMultiSelectElement | null = this.closest( 'tp-multi-select' );\n\n\t\t// Unselect value.\n\t\tif ( multiSelect && this.getAttribute( 'value' ) ) {\n\t\t\tmultiSelect.unSelect( this.getAttribute( 'value' ) ?? '' );\n\t\t\tmultiSelect.dispatchEvent( new CustomEvent( 'unselect', { bubbles: true } ) );\n\t\t\tmultiSelect.dispatchEvent( new CustomEvent( 'change', { bubbles: true } ) );\n\t\t}\n\t}\n}\n","/**\n * Internal dependencies.\n */\nimport { TPMultiSelectElement } from './tp-multi-select';\nimport { TPMultiSelectPillElement } from './tp-multi-select-pill';\nimport { TPMultiSelectOptionElement } from './tp-multi-select-option';\n\n/**\n * TP Multi Select Pills.\n */\nexport class TPMultiSelectPillsElement extends HTMLElement {\n\t/**\n\t * Constructor.\n\t */\n\tconstructor() {\n\t\t// Initialize parent.\n\t\tsuper();\n\n\t\t// Events.\n\t\tthis.closest( 'tp-multi-select' )?.addEventListener( 'change', this.update.bind( this ) );\n\t\tthis.closest( 'tp-multi-select' )?.querySelector( 'select' )?.addEventListener( 'change', ( () => this.update() ) as EventListener );\n\n\t\t// Update.\n\t\tthis.update();\n\t}\n\n\t/**\n\t * Update this component.\n\t */\n\tupdate(): void {\n\t\t// Get multi-select.\n\t\tconst multiSelect: TPMultiSelectElement | null = this.closest( 'tp-multi-select' );\n\n\t\t// Bail if there's no multi-select.\n\t\tif ( ! multiSelect ) {\n\t\t\t// Bail early.\n\t\t\treturn;\n\t\t}\n\n\t\t// Determine pills.\n\t\tconst pills: NodeListOf<TPMultiSelectPillElement> | null = this.querySelectorAll( 'tp-multi-select-pill' );\n\t\tconst values: string[] = multiSelect.value ?? [];\n\t\tconst pillValues: string[] = [];\n\n\t\t// Remove pills that shouldn't exist.\n\t\tpills.forEach( ( pill: TPMultiSelectPillElement ): void => {\n\t\t\t// Get pill value.\n\t\t\tconst pillValue: string = pill.getAttribute( 'value' ) ?? '';\n\n\t\t\t// Early return if pill value is empty string.\n\t\t\tif ( '' === pillValue ) {\n\t\t\t\t// Early return.\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Add pill value to the array.\n\t\t\tpillValues.push( pillValue );\n\n\t\t\t// Remove pill if it doesn't exist in the values.\n\t\t\tif ( ! values.includes( pillValue ) ) {\n\t\t\t\tpill.remove();\n\t\t\t}\n\t\t} );\n\n\t\t// Create new pills.\n\t\tconst pillsToCreate: string[] = values.filter( ( value: string ) => ! pillValues.includes( value ) );\n\n\t\t// Create pills.\n\t\tpillsToCreate.forEach( ( pillValue: string ): void => {\n\t\t\t// Early return if pill value is empty string.\n\t\t\tif ( '' === pillValue ) {\n\t\t\t\t// Early return.\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Get multi-select option.\n\t\t\tconst multiSelectOption: TPMultiSelectOptionElement | null = multiSelect.querySelector( `tp-multi-select-option[value=\"${ pillValue }\"]` );\n\n\t\t\t// Bail early if there's no multi-select option.\n\t\t\tif ( ! multiSelectOption ) {\n\t\t\t\t// Early return.\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Add pill.\n\t\t\tthis.appendChild( this.createPill( pillValue, multiSelectOption.getAttribute( 'label' ) ?? '' ) );\n\t\t} );\n\t}\n\n\t/**\n\t * Create a new pill.\n\t *\n\t * @param {string} value Pill value.\n\t * @param {string} label Pill label.\n\t *\n\t * @return {TPMultiSelectPillElement} New pill.\n\t */\n\tcreatePill( value: string, label: string ): TPMultiSelectPillElement {\n\t\t// Create pill and set value attribute.\n\t\tconst newPill = document.createElement( 'tp-multi-select-pill' ) as TPMultiSelectPillElement;\n\t\tnewPill.setAttribute( 'value', value );\n\n\t\t// Create pill label.\n\t\tconst pillLabel: HTMLElement = document.createElement( 'span' );\n\t\tpillLabel.textContent = label;\n\n\t\t// Create pill close button.\n\t\tconst pillCloseButton: HTMLElement = document.createElement( 'button' );\n\t\tpillCloseButton.setAttribute( 'type', 'button' );\n\t\tpillCloseButton.textContent = 'x';\n\n\t\t// Add event listener.\n\t\tpillCloseButton.addEventListener( 'click', () => {\n\t\t\t// On click, run removePill method.\n\t\t\tnewPill.removePill();\n\t\t} );\n\n\t\t// Append label and close button to pill.\n\t\tnewPill.appendChild( pillLabel );\n\t\tnewPill.appendChild( pillCloseButton );\n\n\t\t// Return newPill element.\n\t\treturn newPill;\n\t}\n}\n","/**\n * Internal dependencies.\n */\nimport { TPMultiSelectElement } from './tp-multi-select';\nimport { TPMultiSelectOptionElement } from './tp-multi-select-option';\n\n/**\n * TP Multi Select Select All.\n */\nexport class TPMultiSelectSelectAllElement extends HTMLElement {\n\t/**\n\t * Constructor.\n\t */\n\tconstructor() {\n\t\t// Initialize parent.\n\t\tsuper();\n\n\t\t// Add event listeners.\n\t\tthis.closest( 'tp-multi-select' )?.addEventListener( 'change', this.handleValueChanged.bind( this ) );\n\t\tthis.addEventListener( 'click', this.toggleSelectAll.bind( this ) );\n\t}\n\n\t/**\n\t * Handle value changed.\n\t */\n\thandleValueChanged(): void {\n\t\t// Get multi select and options.\n\t\tconst multiSelect: TPMultiSelectElement | null = this.closest( 'tp-multi-select' );\n\t\tconst options: NodeListOf<TPMultiSelectOptionElement> | null | undefined = multiSelect?.querySelectorAll( 'tp-multi-select-option' );\n\n\t\t// Check if multi select and options exists.\n\t\tif ( ! multiSelect || ! options ) {\n\t\t\t// Bail early.\n\t\t\treturn;\n\t\t}\n\n\t\t// Check if all options are selected.\n\t\tif ( Array.from( options ).filter( ( optionNode ) => optionNode.getAttribute( 'disabled' ) !== 'yes' ).length === multiSelect.value.length ) {\n\t\t\tthis.setAttribute( 'selected', 'yes' );\n\t\t\tthis.innerHTML = this.getAttribute( 'unselect-text' ) ?? '';\n\t\t} else {\n\t\t\tthis.removeAttribute( 'selected' );\n\t\t\tthis.innerHTML = this.getAttribute( 'select-text' ) ?? '';\n\t\t}\n\t}\n\n\t/**\n\t * Toggle select all.\n\t */\n\ttoggleSelectAll(): void {\n\t\t// Get multi select.\n\t\tconst multiSelect: TPMultiSelectElement | null = this.closest( 'tp-multi-select' );\n\n\t\t// Check if multi select exists.\n\t\tif ( ! multiSelect ) {\n\t\t\t// Bail early.\n\t\t\treturn;\n\t\t}\n\n\t\t// Check if select all is yes. Apply selectAll and unselectAll methods accordingly.\n\t\tif ( 'yes' !== this.getAttribute( 'selected' ) ) {\n\t\t\tmultiSelect.selectAll();\n\t\t\tmultiSelect.dispatchEvent( new CustomEvent( 'select-all', { bubbles: true } ) );\n\t\t} else {\n\t\t\tmultiSelect.unSelectAll();\n\t\t\tmultiSelect.dispatchEvent( new CustomEvent( 'unselect-all', { bubbles: true } ) );\n\t\t}\n\n\t\t// Dispatch change event.\n\t\tmultiSelect.dispatchEvent( new CustomEvent( 'change', { bubbles: true } ) );\n\t}\n}\n","/**\n * Styles.\n */\nimport './style.scss';\n\n/**\n * Components.\n */\nimport { TPMultiSelectElement } from './tp-multi-select';\nimport { TPMultiSelectFieldElement } from './tp-multi-select-field';\nimport { TPMultiSelectPlaceholderElement } from './tp-multi-select-placeholder';\nimport { TPMultiSelectStatusElement } from './tp-multi-select-status';\nimport { TPMultiSelectOptionsElement } from './tp-multi-select-options';\nimport { TPMultiSelectOptionElement } from './tp-multi-select-option';\nimport { TPMultiSelectSearchElement } from './tp-multi-select-search';\nimport { TPMultiSelectPillElement } from './tp-multi-select-pill';\nimport { TPMultiSelectPillsElement } from './tp-multi-select-pills';\nimport { TPMultiSelectSelectAllElement } from './tp-multi-select-select-all';\n\n/**\n * Register Components.\n */\ncustomElements.define( 'tp-multi-select', TPMultiSelectElement );\ncustomElements.define( 'tp-multi-select-field', TPMultiSelectFieldElement );\ncustomElements.define( 'tp-multi-select-placeholder', TPMultiSelectPlaceholderElement );\ncustomElements.define( 'tp-multi-select-status', TPMultiSelectStatusElement );\ncustomElements.define( 'tp-multi-select-options', TPMultiSelectOptionsElement );\ncustomElements.define( 'tp-multi-select-option', TPMultiSelectOptionElement );\ncustomElements.define( 'tp-multi-select-search', TPMultiSelectSearchElement );\ncustomElements.define( 'tp-multi-select-pill', TPMultiSelectPillElement );\ncustomElements.define( 'tp-multi-select-pills', TPMultiSelectPillsElement );\ncustomElements.define( 'tp-multi-select-select-all', TPMultiSelectSelectAllElement );\n"],"names":["TPMultiSelectElement","HTMLElement","constructor","super","currentlyHighlightedOption","this","keyboardEventListener","handleKeyboardInputs","bind","document","addEventListener","handleDocumentClick","update","options","querySelector","MutationObserver","initialize","observe","childList","subtree","observedAttributes","attributeChangedCallback","name","oldValue","newValue","dispatchEvent","CustomEvent","bubbles","unHighlightAllOptions","removeEventListener","value","Array","isArray","styledOptions","querySelectorAll","forEach","option","includes","getAttribute","setAttribute","removeAttribute","selectedOptions","optionValue","push","updateFormFieldValue","styledSelectedOptions","selectField","selectOptions","from","matchingSelectOption","find","selectOption","newOption","createElement","append","remove","Event","length","status","toString","e","target","contains","selectElement","innerHTML","formReference","select","unSelectAll","search","clear","focus","selectAll","unSelect","key","preventDefault","highlightNextOption","highlightPreviousOption","toggleHighlightedOption","nextToBeHighlighted","scrollIntoView","behavior","block","previousToBeHighlighted","toggle","TPMultiSelectFieldElement","toggleOpen","multiSelect","closest","TPMultiSelectPlaceholderElement","TPMultiSelectStatusElement","_name","format","html","replace","TPMultiSelectOptionsElement","TPMultiSelectOptionElement","stopPropagation","detail","TPMultiSelectSearchElement","input","handleSearchChange","handleClick","pill","removePill","matchedOptionCount","toLowerCase","match","RegExp","style","width","TPMultiSelectPillElement","handleButtonClick","TPMultiSelectPillsElement","pills","values","pillValues","pillValue","filter","multiSelectOption","appendChild","createPill","label","newPill","pillLabel","textContent","pillCloseButton","TPMultiSelectSelectAllElement","handleValueChanged","toggleSelectAll","optionNode","customElements","define"],"sourceRoot":""}
|
|
1
|
+
{"version":3,"file":"dist/multi-select/index.js","mappings":"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","sources":["webpack://@travelopia/web-components/./src/multi-select/tp-multi-select.ts","webpack://@travelopia/web-components/./src/multi-select/tp-multi-select-field.ts","webpack://@travelopia/web-components/./src/multi-select/tp-multi-select-placeholder.ts","webpack://@travelopia/web-components/./src/multi-select/tp-multi-select-status.ts","webpack://@travelopia/web-components/./src/multi-select/tp-multi-select-options.ts","webpack://@travelopia/web-components/./src/multi-select/tp-multi-select-option.ts","webpack://@travelopia/web-components/./src/multi-select/tp-multi-select-search.ts","webpack://@travelopia/web-components/./src/multi-select/tp-multi-select-pill.ts","webpack://@travelopia/web-components/./src/multi-select/tp-multi-select-pills.ts","webpack://@travelopia/web-components/./src/multi-select/tp-multi-select-select-all.ts","webpack://@travelopia/web-components/./src/multi-select/index.ts"],"sourcesContent":["/**\n * Internal dependencies.\n */\nimport { TPMultiSelectOptionElement } from './tp-multi-select-option';\nimport { TPMultiSelectStatusElement } from './tp-multi-select-status';\nimport { TPMultiSelectOptionsElement } from './tp-multi-select-options';\nimport { TPMultiSelectSearchElement } from './tp-multi-select-search';\n\n/**\n * TP Multi Select.\n */\nexport class TPMultiSelectElement extends HTMLElement {\n\t/**\n\t * Properties.\n\t */\n\tcurrentlyHighlightedOption: number = -1;\n\tprotected keyboardEventListener: EventListener;\n\n\t/**\n\t * Constructor.\n\t */\n\tconstructor() {\n\t\t// Initialize parent.\n\t\tsuper();\n\n\t\t// Events.\n\t\tthis.keyboardEventListener = this.handleKeyboardInputs.bind( this ) as EventListener;\n\t\tdocument.addEventListener( 'click', this.handleDocumentClick.bind( this ) );\n\t\tthis.addEventListener( 'change', this.update.bind( this ) );\n\n\t\t// Get options.\n\t\tconst options: TPMultiSelectOptionsElement | null = this.querySelector( 'tp-multi-select-options' );\n\n\t\t// Listen for dynamic changes to the option values.\n\t\tif ( options ) {\n\t\t\tconst mutationObserver: MutationObserver = new MutationObserver( this.initialize.bind( this ) );\n\t\t\tmutationObserver.observe( options, { childList: true, subtree: true } );\n\t\t}\n\n\t\t// Initialize component.\n\t\tthis.initialize();\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 to observe.\n\t\treturn [ 'open' ];\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// If no changes.\n\t\tif ( oldValue === newValue ) {\n\t\t\t// Exit.\n\t\t\treturn;\n\t\t}\n\n\t\t// Changed attribute name is 'open'.\n\t\tif ( 'open' === name ) {\n\t\t\t// If new value is 'yes' then open the dropdown.\n\t\t\tif ( 'yes' === newValue ) {\n\t\t\t\tdocument.addEventListener( 'keydown', this.keyboardEventListener );\n\t\t\t\tthis.dispatchEvent( new CustomEvent( 'open', { bubbles: true } ) );\n\t\t\t} else {\n\t\t\t\tthis.unHighlightAllOptions();\n\t\t\t\tdocument.removeEventListener( 'keydown', this.keyboardEventListener );\n\t\t\t\tthis.dispatchEvent( new CustomEvent( 'close', { bubbles: true } ) );\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Set the value of this component.\n\t *\n\t * @param {Array} value Value.\n\t */\n\tset value( value: string[] ) {\n\t\t// Bail if value is not an array.\n\t\tif ( ! value || ! Array.isArray( value ) ) {\n\t\t\t// Bail early.\n\t\t\treturn;\n\t\t}\n\n\t\t// Set the value of the select field.\n\t\tconst styledOptions: NodeListOf<TPMultiSelectOptionElement> | null = this.querySelectorAll( 'tp-multi-select-option' );\n\t\tstyledOptions?.forEach( ( option: TPMultiSelectOptionElement ): void => {\n\t\t\t// Check if the value is in the array.\n\t\t\tif ( value.includes( option.getAttribute( 'value' ) ?? '' ) ) {\n\t\t\t\toption.setAttribute( 'selected', 'yes' );\n\t\t\t} else {\n\t\t\t\toption.removeAttribute( 'selected' );\n\t\t\t}\n\t\t} );\n\n\t\t// Dispatch change event.\n\t\tthis.dispatchEvent( new CustomEvent( 'change', { bubbles: true } ) );\n\t}\n\n\t/**\n\t * Get the value of this component.\n\t *\n\t * @return {Array} Value of this component.\n\t */\n\tget value(): string[] {\n\t\t// Get the value of the select field.\n\t\tconst value: string[] = [];\n\n\t\t// Get selected options.\n\t\tconst selectedOptions: NodeListOf<HTMLOptionElement> | null = this.querySelectorAll( 'select option[selected]' );\n\t\tselectedOptions?.forEach( ( option: HTMLOptionElement ) => {\n\t\t\t// Get option value.\n\t\t\tconst optionValue = option.getAttribute( 'value' );\n\n\t\t\t// Add value to array.\n\t\t\tif ( optionValue ) {\n\t\t\t\tvalue.push( optionValue );\n\t\t\t}\n\t\t} );\n\n\t\t// Return value.\n\t\treturn value;\n\t}\n\n\t/**\n\t * Update the value of the select field.\n\t */\n\tprotected updateFormFieldValue(): void {\n\t\t// Get options.\n\t\tconst styledSelectedOptions: NodeListOf<TPMultiSelectOptionElement> | null = this.querySelectorAll( `tp-multi-select-option` );\n\t\tconst selectField: HTMLSelectElement | null = this.querySelector( 'select' );\n\n\t\t// Bail if there's no styled selected options or select field.\n\t\tif ( ! styledSelectedOptions || ! selectField ) {\n\t\t\t// Bail.\n\t\t\treturn;\n\t\t}\n\n\t\t// Get selected options.\n\t\tconst selectOptions: HTMLOptionElement[] = Array.from( selectField.options );\n\n\t\t// Traverse options.\n\t\tstyledSelectedOptions.forEach( ( option: TPMultiSelectOptionElement ): void => {\n\t\t\t// Get option value.\n\t\t\tconst optionValue = option.getAttribute( 'value' ) ?? '';\n\n\t\t\t// If option value is present.\n\t\t\tif ( optionValue ) {\n\t\t\t\tconst matchingSelectOption: HTMLOptionElement | undefined = selectOptions.find( ( selectOption ) => selectOption.value === optionValue );\n\n\t\t\t\t// Update select field.\n\t\t\t\tif ( 'yes' === option.getAttribute( 'selected' ) ) {\n\t\t\t\t\t// Update select field.\n\t\t\t\t\tif ( matchingSelectOption ) {\n\t\t\t\t\t\tmatchingSelectOption.setAttribute( 'selected', 'selected' );\n\t\t\t\t\t} else {\n\t\t\t\t\t\tconst newOption: HTMLOptionElement = document.createElement( 'option' );\n\t\t\t\t\t\tnewOption.setAttribute( 'value', option.getAttribute( 'value' ) ?? '' );\n\t\t\t\t\t\tnewOption.setAttribute( 'selected', 'selected' );\n\t\t\t\t\t\tselectField?.append( newOption );\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tmatchingSelectOption?.remove();\n\t\t\t\t}\n\t\t\t}\n\t\t} );\n\n\t\t// Dispatch events.\n\t\tselectField.dispatchEvent( new Event( 'change' ) );\n\t}\n\n\t/**\n\t * Update component and sub-components.\n\t */\n\tupdate(): void {\n\t\t// First, update field value.\n\t\tthis.updateFormFieldValue();\n\n\t\t// Get value.\n\t\tconst value: string[] = this.value;\n\n\t\t// Toggle selected attribute.\n\t\tif ( 0 !== value.length ) {\n\t\t\tthis.setAttribute( 'selected', 'yes' );\n\t\t} else {\n\t\t\tthis.removeAttribute( 'selected' );\n\t\t}\n\n\t\t// Get status.\n\t\tconst status: TPMultiSelectStatusElement | null = this.querySelector( 'tp-multi-select-status' );\n\n\t\t// Update status.\n\t\tif ( status ) {\n\t\t\t// Update status.\n\t\t\tif ( value.length > 0 ) {\n\t\t\t\tstatus.setAttribute( 'total', value.length.toString() );\n\t\t\t} else {\n\t\t\t\tstatus.removeAttribute( 'total' );\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Handle clicking the document.\n\t *\n\t * @param {Event} e Event.\n\t */\n\tprotected handleDocumentClick( e: Event ): void {\n\t\t// Close on click outside.\n\t\tif ( this !== e.target && ! this.contains( e.target as Node ) ) {\n\t\t\tthis.removeAttribute( 'open' );\n\t\t}\n\t}\n\n\t/**\n\t * Initialize component.\n\t */\n\tinitialize(): void {\n\t\t// Get select element.\n\t\tlet selectElement: HTMLSelectElement | null = this.querySelector( 'select' );\n\n\t\t// Create select element (if it doesn't already exist).\n\t\tif ( ! selectElement ) {\n\t\t\tselectElement = document.createElement( 'select' );\n\t\t\tselectElement.setAttribute( 'name', this.getAttribute( 'name' ) ?? '' );\n\n\t\t\t// Get form reference.\n\t\t\tconst formReference = this.getAttribute( 'form' );\n\n\t\t\t// Add form reference.\n\t\t\tif ( formReference ) {\n\t\t\t\tselectElement.setAttribute( 'form', formReference );\n\t\t\t}\n\n\t\t\t// Set multiple.\n\t\t\tif ( 'no' !== this.getAttribute( 'multiple' ) ) {\n\t\t\t\tselectElement.setAttribute( 'multiple', 'multiple' );\n\t\t\t}\n\n\t\t\t// Append.\n\t\t\tthis.append( selectElement );\n\t\t} else {\n\t\t\tselectElement.innerHTML = '';\n\t\t}\n\n\t\t// Update components for selected options.\n\t\tthis.update();\n\t}\n\n\t/**\n\t * Select a value.\n\t *\n\t * @param {string} value Value to select.\n\t */\n\tselect( value: string = '' ): void {\n\t\t// Stuff for single-select.\n\t\tif ( 'no' === this.getAttribute( 'multiple' ) ) {\n\t\t\t// First, unselect everything.\n\t\t\tthis.unSelectAll();\n\n\t\t\t// If the value is blank, don't do anything else.\n\t\t\tif ( '' === value ) {\n\t\t\t\t// Close the field, if applicable.\n\t\t\t\tif ( 'yes' === this.getAttribute( 'close-on-select' ) ) {\n\t\t\t\t\tthis.removeAttribute( 'open' );\n\t\t\t\t}\n\n\t\t\t\t// Exit.\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\n\t\t// Select all options.\n\t\tconst styledSelectedOptions: NodeListOf<TPMultiSelectOptionElement> | null = this.querySelectorAll( `tp-multi-select-option[value=\"${ value }\"]` );\n\t\tstyledSelectedOptions?.forEach( ( option: TPMultiSelectOptionElement ): void => {\n\t\t\t// Update select field.\n\t\t\tif ( 'yes' !== option.getAttribute( 'disabled' ) ) {\n\t\t\t\toption.setAttribute( 'selected', 'yes' );\n\t\t\t}\n\t\t} );\n\n\t\t// Search stuff.\n\t\tconst search: TPMultiSelectSearchElement | null = this.querySelector( 'tp-multi-select-search' );\n\t\tsearch?.clear();\n\t\tsearch?.focus();\n\n\t\t// Close the field, if applicable.\n\t\tif ( 'yes' === this.getAttribute( 'close-on-select' ) ) {\n\t\t\tthis.removeAttribute( 'open' );\n\t\t}\n\n\t\t// Update component.\n\t\tthis.update();\n\t}\n\n\t/**\n\t * Select all values.\n\t */\n\tselectAll(): void {\n\t\t// Get all options.\n\t\tconst styledOptions: NodeListOf<TPMultiSelectOptionElement> | null = this.querySelectorAll( 'tp-multi-select-option' );\n\t\tstyledOptions?.forEach( ( option: TPMultiSelectOptionElement ): void => {\n\t\t\t// Update select field.\n\t\t\tif ( 'yes' !== option.getAttribute( 'disabled' ) ) {\n\t\t\t\toption.setAttribute( 'selected', 'yes' );\n\t\t\t}\n\t\t} );\n\n\t\t// Update component.\n\t\tthis.update();\n\t}\n\n\t/**\n\t * Un-select a value.\n\t *\n\t * @param {string} value Value to unselect.\n\t */\n\tunSelect( value: string = '' ): void {\n\t\t// Get all options with the specified value.\n\t\tconst styledSelectedOptions: NodeListOf<TPMultiSelectOptionElement> | null = this.querySelectorAll( `tp-multi-select-option[value=\"${ value }\"]` );\n\t\tstyledSelectedOptions?.forEach( ( option: TPMultiSelectOptionElement ): void => {\n\t\t\t// Remove selected attribute.\n\t\t\toption.removeAttribute( 'selected' );\n\t\t} );\n\n\t\t// update component.\n\t\tthis.update();\n\t}\n\n\t/**\n\t * Un-select all values.\n\t */\n\tunSelectAll(): void {\n\t\t// Get all options.\n\t\tconst styledSelectedOptions: NodeListOf<TPMultiSelectOptionElement> | null = this.querySelectorAll( 'tp-multi-select-option' );\n\t\tstyledSelectedOptions?.forEach( ( option: TPMultiSelectOptionElement ): void => {\n\t\t\t// Remove selected attribute.\n\t\t\toption.removeAttribute( 'selected' );\n\t\t} );\n\n\t\t// Update component.\n\t\tthis.update();\n\t}\n\n\t/**\n\t * Handle keyboard inputs.\n\t *\n\t * @param {Event} e Keyboard event.\n\t */\n\thandleKeyboardInputs( e: KeyboardEvent ): void {\n\t\t// Keyboard events.\n\t\tswitch ( e.key ) {\n\t\t\tcase 'ArrowDown':\n\t\t\t\te.preventDefault();\n\t\t\t\tthis.highlightNextOption();\n\t\t\t\tbreak;\n\t\t\tcase 'ArrowUp':\n\t\t\t\te.preventDefault();\n\t\t\t\tthis.highlightPreviousOption();\n\t\t\t\tbreak;\n\t\t\tcase 'Enter':\n\t\t\t\tthis.toggleHighlightedOption();\n\t\t\t\tbreak;\n\t\t\tcase 'Escape':\n\t\t\t\tthis.unHighlightAllOptions();\n\t\t\t\tthis.removeAttribute( 'open' );\n\t\t\t\tbreak;\n\t\t}\n\t}\n\n\t/**\n\t * Highlight the next option.\n\t */\n\thighlightNextOption(): void {\n\t\t// Get options.\n\t\tconst options: NodeListOf<TPMultiSelectOptionElement> | null = this.querySelectorAll( 'tp-multi-select-option:not([hidden=\"yes\"])' );\n\n\t\t// Bail early if there are no options. Set the currently highlighted option to -1 (no more options to highlight).\n\t\tif ( ! options ) {\n\t\t\tthis.currentlyHighlightedOption = -1;\n\n\t\t\t// Exit.\n\t\t\treturn;\n\t\t}\n\n\t\t// Find the next option to be highlighted. Assume next option is the favorable option.\n\t\tlet nextToBeHighlighted = this.currentlyHighlightedOption + 1;\n\n\t\t// Keep iterating to skip over disabled options until we find a suitable option.\n\t\twhile ( nextToBeHighlighted < options.length && options[ nextToBeHighlighted ].getAttribute( 'disabled' ) === 'yes' ) {\n\t\t\tnextToBeHighlighted++;\n\t\t}\n\n\t\t// If there are no more options to highlight, exit. Here, the last highlighted option keeps highlighted.\n\t\tif ( nextToBeHighlighted === options.length ) {\n\t\t\t// Exit.\n\t\t\treturn;\n\t\t}\n\n\t\t// Remove highlight from the current option, if any.\n\t\tif ( this.currentlyHighlightedOption !== -1 ) {\n\t\t\toptions[ this.currentlyHighlightedOption ].removeAttribute( 'highlighted' );\n\t\t}\n\n\t\t// Highlight the found option.\n\t\toptions[ nextToBeHighlighted ].setAttribute( 'highlighted', 'yes' );\n\n\t\t// Scroll the highlighted option into view with smooth behavior.\n\t\toptions[ nextToBeHighlighted ].scrollIntoView( { behavior: 'smooth', block: 'nearest' } );\n\n\t\t// Update the currentlyHighlightedOption for the next iteration.\n\t\tthis.currentlyHighlightedOption = nextToBeHighlighted;\n\t}\n\n\t/**\n\t * Highlight previous option.\n\t */\n\thighlightPreviousOption(): void {\n\t\t// Get options.\n\t\tconst options: NodeListOf<TPMultiSelectOptionElement> | null = this.querySelectorAll( 'tp-multi-select-option:not([hidden=\"yes\"])' );\n\n\t\t// Bail early if there are no options. Set the currently highlighted option to -1 (no more options to highlight).\n\t\tif ( ! options ) {\n\t\t\tthis.currentlyHighlightedOption = -1;\n\n\t\t\t// Exit.\n\t\t\treturn;\n\t\t}\n\n\t\t// Find the previous option to be highlighted. Assume previous option is the favorable option.\n\t\tlet previousToBeHighlighted = this.currentlyHighlightedOption - 1;\n\n\t\t// Keep iterating to skip over disabled options until we find a suitable option.\n\t\twhile ( previousToBeHighlighted >= 0 && options[ previousToBeHighlighted ].getAttribute( 'disabled' ) === 'yes' ) {\n\t\t\tpreviousToBeHighlighted--;\n\t\t}\n\n\t\t// If there are no more options to highlight, exit.\n\t\tif ( previousToBeHighlighted < 0 ) {\n\t\t\t// Exit.\n\t\t\treturn;\n\t\t}\n\n\t\t// Remove highlight from the current option, if any.\n\t\tif ( this.currentlyHighlightedOption !== 0 ) {\n\t\t\toptions[ this.currentlyHighlightedOption ].removeAttribute( 'highlighted' );\n\t\t}\n\n\t\t// Highlight the found option.\n\t\toptions[ previousToBeHighlighted ].setAttribute( 'highlighted', 'yes' );\n\n\t\t// Scroll the highlighted option into view with smooth behavior.\n\t\toptions[ previousToBeHighlighted ].scrollIntoView( { behavior: 'smooth', block: 'nearest' } );\n\n\t\t// Update the currentlyHighlightedOption for the next iteration.\n\t\tthis.currentlyHighlightedOption = previousToBeHighlighted;\n\t}\n\n\t/**\n\t * Toggle highlighted option.\n\t */\n\ttoggleHighlightedOption(): void {\n\t\t// Get option and if it exists set it to null.\n\t\tconst option: TPMultiSelectOptionElement | null = this.querySelector( `tp-multi-select-option[highlighted=\"yes\"]` );\n\t\toption?.toggle( null );\n\t}\n\n\t/**\n\t * Un-highlight all options.\n\t */\n\tunHighlightAllOptions(): void {\n\t\t// Reset the currentlyHighlightedOption.\n\t\tthis.currentlyHighlightedOption = -1;\n\n\t\t// Get options.\n\t\tconst options: NodeListOf<TPMultiSelectOptionElement> | null = this.querySelectorAll( 'tp-multi-select-option' );\n\n\t\t// If there are options, un-highlight them.\n\t\tif ( options ) {\n\t\t\toptions.forEach( ( option: TPMultiSelectOptionElement ): void => {\n\t\t\t\t// Remove highlighted attribute.\n\t\t\t\toption.removeAttribute( 'highlighted' );\n\t\t\t} );\n\t\t}\n\t}\n}\n","/**\n * Internal dependencies.\n */\nimport { TPMultiSelectElement } from './tp-multi-select';\n\n/**\n * TP Multi Select Field.\n */\nexport class TPMultiSelectFieldElement extends HTMLElement {\n\t/**\n\t * Constructor.\n\t */\n\tconstructor() {\n\t\t// Initialize parent.\n\t\tsuper();\n\n\t\t// Add event listener.\n\t\tthis.addEventListener( 'click', this.toggleOpen.bind( this ) );\n\t}\n\n\t/**\n\t * Toggle opening this component.\n\t */\n\ttoggleOpen(): void {\n\t\t// Get multi-select.\n\t\tconst multiSelect: TPMultiSelectElement | null = this.closest( 'tp-multi-select' );\n\n\t\t// Bail early if we don't have a multi-select.\n\t\tif ( ! multiSelect ) {\n\t\t\t// Bail early.\n\t\t\treturn;\n\t\t}\n\n\t\t// Toggle open.\n\t\tif ( 'yes' === multiSelect.getAttribute( 'open' ) ) {\n\t\t\tmultiSelect.removeAttribute( 'open' );\n\t\t} else {\n\t\t\tmultiSelect.setAttribute( 'open', 'yes' );\n\t\t}\n\t}\n}\n","/**\n * TP Multi Select Placeholder.\n */\nexport class TPMultiSelectPlaceholderElement extends HTMLElement {\n}\n","/**\n * Internal dependencies.\n */\nimport { TPMultiSelectElement } from './tp-multi-select';\nimport { TPMultiSelectOptionElement } from './tp-multi-select-option';\n\n/**\n * TP Multi Select Status.\n */\nexport class TPMultiSelectStatusElement 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 to observe.\n\t\treturn [ 'total', 'format' ];\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.\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 format attribute.\n\t\tconst format: string = this.getAttribute( 'format' ) ?? '$total Selected';\n\t\tlet html: string = format.replace( '$total', this.getAttribute( 'total' ) ?? '' );\n\n\t\t// Format string includes $value.\n\t\tif ( format.includes( '$value' ) ) {\n\t\t\t// Get multi-select.\n\t\t\tconst multiSelect: TPMultiSelectElement | null = this.closest( 'tp-multi-select' );\n\n\t\t\t// Check if multi-select exists.\n\t\t\tif ( multiSelect ) {\n\t\t\t\t// Get value if present or create an empty array.\n\t\t\t\tconst value: string[] = multiSelect.value ?? [];\n\t\t\t\tlet replace: string = '';\n\n\t\t\t\t// Check if value array is not empty.\n\t\t\t\tif ( value.length > 0 ) {\n\t\t\t\t\t// Get first value.\n\t\t\t\t\tconst option: TPMultiSelectOptionElement | null = multiSelect.querySelector( `tp-multi-select-option[value=\"${ value[ 0 ] }\"]` );\n\n\t\t\t\t\t// Check if option exists.\n\t\t\t\t\tif ( option ) {\n\t\t\t\t\t\treplace = option.getAttribute( 'label' ) ?? '';\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Replace $value.\n\t\t\t\thtml = html.replace( '$value', replace );\n\t\t\t}\n\t\t}\n\n\t\t// Set inner HTML.\n\t\tthis.innerHTML = html;\n\t}\n}\n","/**\n * TP Multi Select Options.\n */\nexport class TPMultiSelectOptionsElement extends HTMLElement {\n}\n","/**\n * Internal dependencies.\n */\nimport { TPMultiSelectElement } from './tp-multi-select';\n\n/**\n * TP Multi Select Option.\n */\nexport class TPMultiSelectOptionElement extends HTMLElement {\n\t/**\n\t * Constructor.\n\t */\n\tconstructor() {\n\t\t// Initialize parent.\n\t\tsuper();\n\n\t\t// Add event listener to toggle the selected state.\n\t\tthis.addEventListener( 'click', this.toggle.bind( this ) );\n\t}\n\n\t/**\n\t * Select / un-select this option.\n\t *\n\t * @param {Event} e Click event.\n\t */\n\ttoggle( e: Event | null ): void {\n\t\t// Prevent default behavior and stop propagation.\n\t\te?.preventDefault();\n\t\te?.stopPropagation();\n\n\t\t// Get multi-select element and value of option.\n\t\tconst multiSelect: TPMultiSelectElement | null = this.closest( 'tp-multi-select' );\n\t\tconst value: string = this.getAttribute( 'value' ) ?? '';\n\n\t\t// Toggle selected state. Dispatch custom events accordingly.\n\t\tif ( 'yes' !== this.getAttribute( 'selected' ) ) {\n\t\t\tmultiSelect?.select( value );\n\t\t\tmultiSelect?.dispatchEvent( new CustomEvent( 'select', {\n\t\t\t\tbubbles: true,\n\t\t\t\tdetail: { value },\n\t\t\t} ) );\n\t\t} else {\n\t\t\tmultiSelect?.unSelect( value );\n\t\t\tmultiSelect?.dispatchEvent( new CustomEvent( 'unselect', {\n\t\t\t\tbubbles: true,\n\t\t\t\tdetail: { value },\n\t\t\t} ) );\n\t\t}\n\n\t\t// Dispatch change event.\n\t\tmultiSelect?.dispatchEvent( new CustomEvent( 'change', { bubbles: true } ) );\n\t}\n}\n","/**\n * Internal dependencies.\n */\nimport { TPMultiSelectElement } from './tp-multi-select';\nimport { TPMultiSelectOptionElement } from './tp-multi-select-option';\nimport { TPMultiSelectPillElement } from './tp-multi-select-pill';\n\n/**\n * TP Multi Select Search.\n */\nexport class TPMultiSelectSearchElement extends HTMLElement {\n\t/**\n\t * Constructor.\n\t */\n\tconstructor() {\n\t\t// Initialize parent.\n\t\tsuper();\n\n\t\t// get input.\n\t\tconst input: HTMLInputElement | null = this.querySelector( 'input' );\n\n\t\t// Check if input exists.\n\t\tif ( ! input ) {\n\t\t\t// No, its not. Exit.\n\t\t\treturn;\n\t\t}\n\n\t\t// Add event listeners.\n\t\tinput.addEventListener( 'keydown', this.handleKeyboardInputs.bind( this ) );\n\t\tinput.addEventListener( 'keyup', this.handleSearchChange.bind( this ) );\n\t\tinput.addEventListener( 'input', this.handleSearchChange.bind( this ) );\n\t\tthis.addEventListener( 'click', this.handleClick.bind( this ) );\n\t\tthis.closest( 'tp-multi-select' )?.addEventListener( 'open', this.focus.bind( this ) );\n\t}\n\n\t/**\n\t * Handle keyboard inputs.\n\t *\n\t * @param {Event} e Keyboard event.\n\t */\n\thandleKeyboardInputs( e: KeyboardEvent ): void {\n\t\t// Get multi select and search field.\n\t\tconst multiSelect: TPMultiSelectElement | null = this.closest( 'tp-multi-select' );\n\t\tconst search: HTMLInputElement | null = this.querySelector( 'input' );\n\n\t\t// Check if multi select and search field exists.\n\t\tif ( ! multiSelect || ! search ) {\n\t\t\t// Bail early.\n\t\t\treturn;\n\t\t}\n\n\t\t// Handle keyboard inputs.\n\t\tswitch ( e.key ) {\n\t\t\tcase 'Enter':\n\t\t\t\te.preventDefault(); // Prevent inadvertent form submits.\n\t\t\t\tbreak;\n\t\t\tcase 'ArrowDown':\n\t\t\t\tmultiSelect.setAttribute( 'open', 'yes' );\n\t\t\t\tbreak;\n\t\t\tcase 'Backspace': // Remove last pill if search is empty.\n\t\t\t\tif ( 0 === search.value.length ) {\n\t\t\t\t\tconst pill: TPMultiSelectPillElement | null = multiSelect.querySelector( 'tp-multi-select-pill:last-of-type' );\n\n\t\t\t\t\t// Check if pill exists, remove it.\n\t\t\t\t\tif ( pill ) {\n\t\t\t\t\t\tpill.removePill();\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t}\n\t}\n\n\t/**\n\t * Handle search field value changed.\n\t */\n\tprotected handleSearchChange(): void {\n\t\t// Get search field and options.\n\t\tconst multiSelect: TPMultiSelectElement | null = this.closest( 'tp-multi-select' );\n\t\tconst search: HTMLInputElement | null = this.querySelector( 'input' );\n\t\tconst options: NodeListOf<TPMultiSelectOptionElement> | undefined = this.closest( 'tp-multi-select' )?.querySelectorAll( 'tp-multi-select-option' );\n\n\t\t// Check if multi select, search, and options field exists.\n\t\tif ( ! multiSelect || ! search || ! options ) {\n\t\t\t// Bail early.\n\t\t\treturn;\n\t\t}\n\n\t\t// Initialize matched option count.\n\t\tlet matchedOptionCount = 0;\n\t\toptions.forEach( ( option: TPMultiSelectOptionElement ): void => {\n\t\t\t// Hide and show options based on search.\n\t\t\tif ( option.getAttribute( 'label' )?.toLowerCase().match( new RegExp( `.*${ search.value.toLowerCase().replace( /\\s/g, '.*' ) }.*` ) ) ) {\n\t\t\t\toption.removeAttribute( 'hidden' );\n\t\t\t\tmatchedOptionCount++;\n\t\t\t} else {\n\t\t\t\toption.setAttribute( 'hidden', 'yes' );\n\t\t\t}\n\t\t} );\n\n\t\t// Resize input width.\n\t\tif ( '' === search.value ) {\n\t\t\tsearch.removeAttribute( 'style' );\n\t\t} else {\n\t\t\tsearch.style.width = `${ search.value.length + 2 }ch`;\n\t\t\tmultiSelect.setAttribute( 'open', 'yes' );\n\t\t}\n\n\t\t// Show matched option count.\n\t\tmultiSelect.setAttribute( 'visible-options', matchedOptionCount.toString() );\n\t}\n\n\t/**\n\t * Handle click.\n\t *\n\t * @param {Event} e Click event.\n\t */\n\tprotected handleClick( e: Event ): void {\n\t\t// First, prevent propagation to avoid document.click set on `tp-multi-select`.\n\t\te.preventDefault();\n\t\te.stopPropagation();\n\n\t\t// Now send the event so other stuff can work as per normal, and another event for good measure.\n\t\tthis.dispatchEvent( new CustomEvent( 'multi-select-opened' ) );\n\t\tdocument.dispatchEvent( new Event( 'click' ) );\n\n\t\t// Open multi select.\n\t\tthis.closest( 'tp-multi-select' )?.setAttribute( 'open', 'yes' );\n\t}\n\n\t/**\n\t * Clear the search field.\n\t */\n\tclear(): void {\n\t\t// Clear search field.\n\t\tconst search: HTMLInputElement | null = this.querySelector( 'input' );\n\n\t\t// Check if search field exists.\n\t\tif ( search ) {\n\t\t\t// Set value to empty string and dispatch change event.\n\t\t\tsearch.value = '';\n\t\t\tsearch.dispatchEvent( new Event( 'change' ) );\n\t\t}\n\t}\n\n\t/**\n\t * Set focus on the search field.\n\t */\n\tfocus(): void {\n\t\t// When it's focused, use search change to ensure the results are refreshed.\n\t\tthis.handleSearchChange();\n\n\t\t// Focus on input.\n\t\tthis.querySelector( 'input' )?.focus();\n\t}\n}\n","/**\n * Internal dependencies.\n */\nimport { TPMultiSelectElement } from './tp-multi-select';\n\n/**\n * TP Multi Select Pill.\n */\nexport class TPMultiSelectPillElement extends HTMLElement {\n\t/**\n\t * Constructor.\n\t */\n\tconstructor() {\n\t\t// Initialize parent.\n\t\tsuper();\n\n\t\t// Add event listener.\n\t\tthis.querySelector( 'button' )?.addEventListener( 'click', this.handleButtonClick.bind( this ) );\n\t}\n\n\t/**\n\t * Handle button click.\n\t *\n\t * @param {Event} e Click event.\n\t */\n\thandleButtonClick( e: Event | null ): void {\n\t\t// Prevent default behavior and stop propagation.\n\t\te?.preventDefault();\n\t\te?.stopPropagation();\n\n\t\t// Remove pill.\n\t\tthis.removePill();\n\t}\n\n\t/**\n\t * Remove this pill.\n\t */\n\tremovePill(): void {\n\t\t// Get multi-select.\n\t\tconst multiSelect: TPMultiSelectElement | null = this.closest( 'tp-multi-select' );\n\n\t\t// Unselect value.\n\t\tif ( multiSelect && this.getAttribute( 'value' ) ) {\n\t\t\tmultiSelect.unSelect( this.getAttribute( 'value' ) ?? '' );\n\t\t\tmultiSelect.dispatchEvent( new CustomEvent( 'unselect', { bubbles: true } ) );\n\t\t\tmultiSelect.dispatchEvent( new CustomEvent( 'change', { bubbles: true } ) );\n\t\t}\n\t}\n}\n","/**\n * Internal dependencies.\n */\nimport { TPMultiSelectElement } from './tp-multi-select';\nimport { TPMultiSelectPillElement } from './tp-multi-select-pill';\nimport { TPMultiSelectOptionElement } from './tp-multi-select-option';\n\n/**\n * TP Multi Select Pills.\n */\nexport class TPMultiSelectPillsElement extends HTMLElement {\n\t/**\n\t * Constructor.\n\t */\n\tconstructor() {\n\t\t// Initialize parent.\n\t\tsuper();\n\n\t\t// Events.\n\t\tthis.closest( 'tp-multi-select' )?.addEventListener( 'change', this.update.bind( this ) );\n\t\tthis.closest( 'tp-multi-select' )?.querySelector( 'select' )?.addEventListener( 'change', ( () => this.update() ) as EventListener );\n\n\t\t// Update.\n\t\tthis.update();\n\t}\n\n\t/**\n\t * Update this component.\n\t */\n\tupdate(): void {\n\t\t// Get multi-select.\n\t\tconst multiSelect: TPMultiSelectElement | null = this.closest( 'tp-multi-select' );\n\n\t\t// Bail if there's no multi-select.\n\t\tif ( ! multiSelect ) {\n\t\t\t// Bail early.\n\t\t\treturn;\n\t\t}\n\n\t\t// Determine pills.\n\t\tconst pills: NodeListOf<TPMultiSelectPillElement> | null = this.querySelectorAll( 'tp-multi-select-pill' );\n\t\tconst values: string[] = [ ...new Set( multiSelect.value ) ] ?? [];\n\t\tconst pillValues: string[] = [];\n\n\t\t// Remove pills that shouldn't exist.\n\t\tpills.forEach( ( pill: TPMultiSelectPillElement ): void => {\n\t\t\t// Get pill value.\n\t\t\tconst pillValue: string = pill.getAttribute( 'value' ) ?? '';\n\n\t\t\t// Early return if pill value is empty string.\n\t\t\tif ( '' === pillValue ) {\n\t\t\t\t// Early return.\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Add pill value to the array.\n\t\t\tpillValues.push( pillValue );\n\n\t\t\t// Remove pill if it doesn't exist in the values.\n\t\t\tif ( ! values.includes( pillValue ) ) {\n\t\t\t\tpill.remove();\n\t\t\t}\n\t\t} );\n\n\t\t// Create new pills.\n\t\tconst pillsToCreate: string[] = values.filter( ( value: string ) => ! pillValues.includes( value ) );\n\n\t\t// Create pills.\n\t\tpillsToCreate.forEach( ( pillValue: string ): void => {\n\t\t\t// Early return if pill value is empty string.\n\t\t\tif ( '' === pillValue ) {\n\t\t\t\t// Early return.\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Get multi-select option.\n\t\t\tconst multiSelectOption: TPMultiSelectOptionElement | null = multiSelect.querySelector( `tp-multi-select-option[value=\"${ pillValue }\"]` );\n\n\t\t\t// Bail early if there's no multi-select option.\n\t\t\tif ( ! multiSelectOption ) {\n\t\t\t\t// Early return.\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Add pill.\n\t\t\tthis.appendChild( this.createPill( pillValue, multiSelectOption.getAttribute( 'label' ) ?? '' ) );\n\t\t} );\n\t}\n\n\t/**\n\t * Create a new pill.\n\t *\n\t * @param {string} value Pill value.\n\t * @param {string} label Pill label.\n\t *\n\t * @return {TPMultiSelectPillElement} New pill.\n\t */\n\tcreatePill( value: string, label: string ): TPMultiSelectPillElement {\n\t\t// Create pill and set value attribute.\n\t\tconst newPill = document.createElement( 'tp-multi-select-pill' ) as TPMultiSelectPillElement;\n\t\tnewPill.setAttribute( 'value', value );\n\n\t\t// Create pill label.\n\t\tconst pillLabel: HTMLElement = document.createElement( 'span' );\n\t\tpillLabel.textContent = label;\n\n\t\t// Create pill close button.\n\t\tconst pillCloseButton: HTMLElement = document.createElement( 'button' );\n\t\tpillCloseButton.setAttribute( 'type', 'button' );\n\t\tpillCloseButton.textContent = 'x';\n\n\t\t// Add event listener.\n\t\tpillCloseButton.addEventListener( 'click', () => {\n\t\t\t// On click, run removePill method.\n\t\t\tnewPill.removePill();\n\t\t} );\n\n\t\t// Append label and close button to pill.\n\t\tnewPill.appendChild( pillLabel );\n\t\tnewPill.appendChild( pillCloseButton );\n\n\t\t// Return newPill element.\n\t\treturn newPill;\n\t}\n}\n","/**\n * Internal dependencies.\n */\nimport { TPMultiSelectElement } from './tp-multi-select';\nimport { TPMultiSelectOptionElement } from './tp-multi-select-option';\n\n/**\n * TP Multi Select Select All.\n */\nexport class TPMultiSelectSelectAllElement extends HTMLElement {\n\t/**\n\t * Constructor.\n\t */\n\tconstructor() {\n\t\t// Initialize parent.\n\t\tsuper();\n\n\t\t// Add event listeners.\n\t\tthis.closest( 'tp-multi-select' )?.addEventListener( 'change', this.handleValueChanged.bind( this ) );\n\t\tthis.addEventListener( 'click', this.toggleSelectAll.bind( this ) );\n\t}\n\n\t/**\n\t * Handle value changed.\n\t */\n\thandleValueChanged(): void {\n\t\t// Get multi select and options.\n\t\tconst multiSelect: TPMultiSelectElement | null = this.closest( 'tp-multi-select' );\n\t\tconst options: NodeListOf<TPMultiSelectOptionElement> | null | undefined = multiSelect?.querySelectorAll( 'tp-multi-select-option' );\n\n\t\t// Check if multi select and options exists.\n\t\tif ( ! multiSelect || ! options ) {\n\t\t\t// Bail early.\n\t\t\treturn;\n\t\t}\n\n\t\t// Check if all options are selected.\n\t\tif ( Array.from( options ).filter( ( optionNode ) => optionNode.getAttribute( 'disabled' ) !== 'yes' ).length === multiSelect.value.length ) {\n\t\t\tthis.setAttribute( 'selected', 'yes' );\n\t\t\tthis.innerHTML = this.getAttribute( 'unselect-text' ) ?? '';\n\t\t} else {\n\t\t\tthis.removeAttribute( 'selected' );\n\t\t\tthis.innerHTML = this.getAttribute( 'select-text' ) ?? '';\n\t\t}\n\t}\n\n\t/**\n\t * Toggle select all.\n\t */\n\ttoggleSelectAll(): void {\n\t\t// Get multi select.\n\t\tconst multiSelect: TPMultiSelectElement | null = this.closest( 'tp-multi-select' );\n\n\t\t// Check if multi select exists.\n\t\tif ( ! multiSelect ) {\n\t\t\t// Bail early.\n\t\t\treturn;\n\t\t}\n\n\t\t// Check if select all is yes. Apply selectAll and unselectAll methods accordingly.\n\t\tif ( 'yes' !== this.getAttribute( 'selected' ) ) {\n\t\t\tmultiSelect.selectAll();\n\t\t\tmultiSelect.dispatchEvent( new CustomEvent( 'select-all', { bubbles: true } ) );\n\t\t} else {\n\t\t\tmultiSelect.unSelectAll();\n\t\t\tmultiSelect.dispatchEvent( new CustomEvent( 'unselect-all', { bubbles: true } ) );\n\t\t}\n\n\t\t// Dispatch change event.\n\t\tmultiSelect.dispatchEvent( new CustomEvent( 'change', { bubbles: true } ) );\n\t}\n}\n","/**\n * Styles.\n */\nimport './style.scss';\n\n/**\n * Components.\n */\nimport { TPMultiSelectElement } from './tp-multi-select';\nimport { TPMultiSelectFieldElement } from './tp-multi-select-field';\nimport { TPMultiSelectPlaceholderElement } from './tp-multi-select-placeholder';\nimport { TPMultiSelectStatusElement } from './tp-multi-select-status';\nimport { TPMultiSelectOptionsElement } from './tp-multi-select-options';\nimport { TPMultiSelectOptionElement } from './tp-multi-select-option';\nimport { TPMultiSelectSearchElement } from './tp-multi-select-search';\nimport { TPMultiSelectPillElement } from './tp-multi-select-pill';\nimport { TPMultiSelectPillsElement } from './tp-multi-select-pills';\nimport { TPMultiSelectSelectAllElement } from './tp-multi-select-select-all';\n\n/**\n * Register Components.\n */\ncustomElements.define( 'tp-multi-select', TPMultiSelectElement );\ncustomElements.define( 'tp-multi-select-field', TPMultiSelectFieldElement );\ncustomElements.define( 'tp-multi-select-placeholder', TPMultiSelectPlaceholderElement );\ncustomElements.define( 'tp-multi-select-status', TPMultiSelectStatusElement );\ncustomElements.define( 'tp-multi-select-options', TPMultiSelectOptionsElement );\ncustomElements.define( 'tp-multi-select-option', TPMultiSelectOptionElement );\ncustomElements.define( 'tp-multi-select-search', TPMultiSelectSearchElement );\ncustomElements.define( 'tp-multi-select-pill', TPMultiSelectPillElement );\ncustomElements.define( 'tp-multi-select-pills', TPMultiSelectPillsElement );\ncustomElements.define( 'tp-multi-select-select-all', TPMultiSelectSelectAllElement );\n"],"names":["TPMultiSelectElement","HTMLElement","constructor","super","currentlyHighlightedOption","this","keyboardEventListener","handleKeyboardInputs","bind","document","addEventListener","handleDocumentClick","update","options","querySelector","MutationObserver","initialize","observe","childList","subtree","observedAttributes","attributeChangedCallback","name","oldValue","newValue","dispatchEvent","CustomEvent","bubbles","unHighlightAllOptions","removeEventListener","value","Array","isArray","styledOptions","querySelectorAll","forEach","option","includes","getAttribute","setAttribute","removeAttribute","selectedOptions","optionValue","push","updateFormFieldValue","styledSelectedOptions","selectField","selectOptions","from","matchingSelectOption","find","selectOption","newOption","createElement","append","remove","Event","length","status","toString","e","target","contains","selectElement","innerHTML","formReference","select","unSelectAll","search","clear","focus","selectAll","unSelect","key","preventDefault","highlightNextOption","highlightPreviousOption","toggleHighlightedOption","nextToBeHighlighted","scrollIntoView","behavior","block","previousToBeHighlighted","toggle","TPMultiSelectFieldElement","toggleOpen","multiSelect","closest","TPMultiSelectPlaceholderElement","TPMultiSelectStatusElement","_name","format","html","replace","TPMultiSelectOptionsElement","TPMultiSelectOptionElement","stopPropagation","detail","TPMultiSelectSearchElement","input","handleSearchChange","handleClick","pill","removePill","matchedOptionCount","toLowerCase","match","RegExp","style","width","TPMultiSelectPillElement","handleButtonClick","TPMultiSelectPillsElement","pills","values","Set","pillValues","pillValue","filter","multiSelectOption","appendChild","createPill","label","newPill","pillLabel","textContent","pillCloseButton","TPMultiSelectSelectAllElement","handleValueChanged","toggleSelectAll","optionNode","customElements","define"],"sourceRoot":""}
|
package/dist/tooltip/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
(()=>{"use strict";class t extends HTMLElement{constructor(){super(),this.
|
|
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":""}
|
package/dist/tooltip/style.css
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
tp-tooltip
|
|
1
|
+
tp-tooltip{display:none}tp-tooltip[popover]{margin:0}tp-tooltip[show]{display:block}
|