UNPKG

gov-gui

Version:

Gov UI Component Library Typscript Build

501 lines (500 loc) 19.8 kB
import { h } from "@stencil/core"; import { getGlobalPropsClasses } from "../../global/global-styles-helper"; import { getAnimationClasses } from "../../global/animation-helpers"; import "../../global/styles.css"; export class GovForm { constructor() { this.submitBtnText = "Submit"; this.cancelBtnText = "Cancel"; this.resetOnSubmit = false; this.errorMessage = ''; this.successMessage = ''; this.animationDelay = '2s'; this.allClasses = ''; // Validate that only allowed child components exist. this.validateChildren = () => { const allowedTags = [ 'GOV-INPUT', 'GOV-RADIOBUTTON', 'GOV-CHECKBOX', 'GOV-DATE-TIME-PICKER', 'GOV-CALENDER', 'GOV-UPLOAD' ]; const slot = this.el.shadowRoot.querySelector('slot'); if (slot) { slot.assignedElements().forEach(node => { if (!allowedTags.includes(node.tagName)) { console.error('Invalid child component:', node); node.remove(); throw new Error('gov-form only accepts <gov-input>, <gov-radiobutton>, <gov-checkbox>, <gov-date-time-picker>, <gov-calender>, and <gov-upload> as children.'); } }); } }; } //watching for any change in animations to trigger them watchAnimations() { this.provideClass(); } watchAnimationsDelay() { this.provideClass(); } watchAnimationsSpeed() { this.provideClass(); } /** * Validates required fields. For each component with the "required" attribute: * - If the component implements a public validate() method, it is called. * - Otherwise, a simple value check is performed. */ async validateRequiredFields() { let allValid = true; const components = this.el.querySelectorAll('gov-input, gov-radiobutton, gov-checkbox, gov-date-time-picker, gov-upload, gov-calender'); for (const component of Array.from(components)) { if (component.hasAttribute('required')) { // If the component has its own validate() method, use that. if (typeof component.validate === 'function') { const valid = await component.validate(); if (!valid) { allValid = false; } } else { const tagName = component.tagName.toLowerCase(); const value = this.getValueFromComponent(component); if ((tagName === 'gov-input' && (value === '' || (typeof value === 'string' && value.trim() === ''))) || (tagName === 'gov-checkbox' && !value) || (tagName === 'gov-date-time-picker' && !value) || (tagName === 'gov-calender' && !value) || (tagName === 'gov-radiobutton' && !value)) { allValid = false; } } } } if (!allValid) { this.errorMessage = 'Please fill out all required fields.'; } return allValid; } async handleSubmit(event) { event.preventDefault(); this.errorMessage = ''; this.successMessage = ''; // Await the asynchronous validation const valid = await this.validateRequiredFields(); if (!valid) { return; } try { const formData = this.createFormData(); const formattedData = JSON.stringify(formData, null, 2); this.formSubmitted.emit(formData); console.log('Form Data:', formattedData); if (this.url) { await fetch(this.url, { method: this.method || 'POST', headers: { 'Content-Type': 'application/json' }, body: formattedData, }); } this.successMessage = `Form submitted successfully!`; if (this.resetOnSubmit) this.resetForm(); } catch (error) { this.errorMessage = error.message; } } createFormData() { const data = {}; const components = this.el.querySelectorAll('gov-input, gov-radiobutton, gov-checkbox, gov-date-time-picker, gov-upload, gov-calender'); components.forEach(component => { const name = component.getAttribute('name'); if (!name) return; const value = this.getValueFromComponent(component); const tagName = component.tagName.toLowerCase(); if (value !== null && value !== undefined) { if (tagName === 'gov-checkbox') { data[name] = String(value); } else { // Always assign the value even if it is an empty string. data[name] = String(value); } } }); return data; } /** * Retrieves the value from a child component. */ getValueFromComponent(component) { var _a, _b, _c, _d; const comp = component; const tag = component.tagName.toLowerCase(); if (tag === 'gov-input') { return (_a = comp.value) !== null && _a !== void 0 ? _a : ''; } else if (tag === 'gov-radiobutton') { return (_b = comp.value) !== null && _b !== void 0 ? _b : ''; } else if (tag === 'gov-checkbox') { return (_c = comp.checked) !== null && _c !== void 0 ? _c : false; } else if (tag === 'gov-upload') { return (_d = comp.fileNameValue) !== null && _d !== void 0 ? _d : ''; } else if (tag === 'gov-date-time-picker') { return `${comp.date} : ${comp.time}`; } else if (tag === 'gov-calender') { const dateMap = comp.date; if (dateMap.size === 3) { const year = dateMap.get('Year'); const month = dateMap.get('Month'); const day = dateMap.get('Day'); const dateString = `${month} ${day}, ${year}`; return dateString; } } return null; } resetForm() { const components = this.el.querySelectorAll('gov-input, gov-radiobutton, gov-checkbox, gov-date-time-picker, gov-upload, gov-calender'); components.forEach(component => { if (typeof component.reset === 'function') { component.reset(); } }); } // inject the animations and styles on component load componentWillLoad() { this.validateChildren(); const animationClasses = getAnimationClasses({ animation: this.animation, animationDelay: this.animationDelay, animationSpeed: this.animationSpeed }); this.allClasses = getGlobalPropsClasses({ classes: ' ' + animationClasses, }); } //Called on change of any animation related property to trigger change provideClass() { const animationClasses = getAnimationClasses({ animation: this.animation, animationDelay: this.animationDelay, animationSpeed: this.animationSpeed }); this.allClasses = getGlobalPropsClasses({ classes: ' ' + animationClasses, }); } render() { return (h("div", { key: '740b0a09ef052af0701e7425e9fc7b5c3e7ea701', class: `form ${this.allClasses}` }, this.header && h("div", { key: '9660be1de7fd5b882e4b95c24409a7e952263b4c', class: "header" }, this.header), h("form", { key: '49aee2468c4231a6d4f836d4149a42598cca4f6a', encType: this.encType, method: this.method, onSubmit: (e) => this.handleSubmit(e) }, h("div", { key: 'b0edf8b6158584cf006e987545be16fb6e9e70fb', class: "form-content" }, h("slot", { key: 'f0d27a8190078868f46a250cca28a744e522274a', onSlotchange: this.validateChildren })), h("div", { key: 'e38bf3befd7500e1ad6db6834a10f5c9bc74cca8', class: "footer" }, !this.hideCancelBtn && (h("gov-button", { key: 'cfb8fdae5b9a60016398bacf229abbb0c9f2e165', variant: "white", type: "button", label: this.cancelBtnText })), !this.hideSubmitBtn && (h("gov-button", { key: 'ab6d791c8e784dfd490ea6f9740686ef7181ed91', variant: this.variant || 'primary', type: "submit", label: this.submitBtnText })))), h("div", { key: '16e932b28d06b55a7bb72193fff830a37f4cd11a', class: "submit-status" }, this.errorMessage && h("div", { key: '8ae1cb60ffd61ebdd99334c0258e85b8772df2be', class: "error" }, this.errorMessage), this.successMessage && h("div", { key: 'b79af8ca7bd4b1376153009d0eeb7541430e7956', class: "success" }, this.successMessage)))); } static get is() { return "gov-form"; } static get encapsulation() { return "shadow"; } static get styles() { return "@import '../../global/styles.css';\n\n * {\n font-family: Arial, sans-serif;\n }\n\n .form {\n width: 100%;\n border-radius: 12px;\n background-color: var(--white-color);\n border: 1px solid var(--border-color);\n box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1);\n }\n\n .form-content {\n padding: 20px;\n }\n\n .header {\n font-size: 1.3rem;\n font-weight: 600;\n color: #212121;\n padding: 20px 20px 0 20px;\n }\n\n .footer {\n display: flex;\n justify-content: end;\n gap: 12px;\n padding: 0 20px 20px 20px;\n }\n\n .error {\n padding: 0.75rem;\n border-radius: 4px;\n background-color: var(--danger-color);\n color: var(--white-color);\n text-align: center;\n }\n \n .success {\n padding: 0.75rem;\n border-radius: 4px;\n background-color: var(--success-color);\n color: var(--white-color);\n text-align: center;\n }\n\n .submit-status {\n margin-bottom: 1rem;\n padding: 0.75rem;\n border-radius: 4px;\n }"; } static get properties() { return { "header": { "type": "string", "mutable": false, "complexType": { "original": "string", "resolved": "string", "references": {} }, "required": false, "optional": false, "docs": { "tags": [], "text": "" }, "getter": false, "setter": false, "attribute": "header", "reflect": false }, "url": { "type": "string", "mutable": false, "complexType": { "original": "string", "resolved": "string", "references": {} }, "required": false, "optional": true, "docs": { "tags": [], "text": "" }, "getter": false, "setter": false, "attribute": "url", "reflect": false }, "method": { "type": "string", "mutable": false, "complexType": { "original": "string", "resolved": "string", "references": {} }, "required": false, "optional": true, "docs": { "tags": [], "text": "" }, "getter": false, "setter": false, "attribute": "method", "reflect": false }, "encType": { "type": "string", "mutable": false, "complexType": { "original": "string", "resolved": "string", "references": {} }, "required": false, "optional": true, "docs": { "tags": [], "text": "" }, "getter": false, "setter": false, "attribute": "enc-type", "reflect": false }, "submitBtnText": { "type": "string", "mutable": false, "complexType": { "original": "string", "resolved": "string", "references": {} }, "required": false, "optional": true, "docs": { "tags": [], "text": "" }, "getter": false, "setter": false, "attribute": "submit-btn-text", "reflect": false, "defaultValue": "\"Submit\"" }, "cancelBtnText": { "type": "string", "mutable": false, "complexType": { "original": "string", "resolved": "string", "references": {} }, "required": false, "optional": true, "docs": { "tags": [], "text": "" }, "getter": false, "setter": false, "attribute": "cancel-btn-text", "reflect": false, "defaultValue": "\"Cancel\"" }, "hideCancelBtn": { "type": "boolean", "mutable": false, "complexType": { "original": "boolean", "resolved": "boolean", "references": {} }, "required": false, "optional": true, "docs": { "tags": [], "text": "" }, "getter": false, "setter": false, "attribute": "hide-cancel-btn", "reflect": false }, "hideSubmitBtn": { "type": "boolean", "mutable": false, "complexType": { "original": "boolean", "resolved": "boolean", "references": {} }, "required": false, "optional": true, "docs": { "tags": [], "text": "" }, "getter": false, "setter": false, "attribute": "hide-submit-btn", "reflect": false }, "variant": { "type": "string", "mutable": false, "complexType": { "original": "string", "resolved": "string", "references": {} }, "required": false, "optional": true, "docs": { "tags": [], "text": "" }, "getter": false, "setter": false, "attribute": "variant", "reflect": false }, "resetOnSubmit": { "type": "boolean", "mutable": false, "complexType": { "original": "boolean", "resolved": "boolean", "references": {} }, "required": false, "optional": false, "docs": { "tags": [], "text": "" }, "getter": false, "setter": false, "attribute": "reset-on-submit", "reflect": false, "defaultValue": "false" }, "animation": { "type": "string", "mutable": false, "complexType": { "original": "string", "resolved": "string", "references": {} }, "required": false, "optional": true, "docs": { "tags": [], "text": "" }, "getter": false, "setter": false, "attribute": "animation", "reflect": false }, "animationDelay": { "type": "string", "mutable": false, "complexType": { "original": "'2s' | '3s' | '4s' | '5s'", "resolved": "\"2s\" | \"3s\" | \"4s\" | \"5s\"", "references": {} }, "required": false, "optional": true, "docs": { "tags": [], "text": "" }, "getter": false, "setter": false, "attribute": "animation-delay", "reflect": false, "defaultValue": "'2s'" }, "animationSpeed": { "type": "string", "mutable": false, "complexType": { "original": "'slow' | 'slower' | 'fast' | 'faster'", "resolved": "\"fast\" | \"faster\" | \"slow\" | \"slower\"", "references": {} }, "required": false, "optional": true, "docs": { "tags": [], "text": "" }, "getter": false, "setter": false, "attribute": "animation-speed", "reflect": false } }; } static get states() { return { "errorMessage": {}, "successMessage": {} }; } static get events() { return [{ "method": "formSubmitted", "name": "formSubmitted", "bubbles": true, "cancelable": true, "composed": true, "docs": { "tags": [], "text": "" }, "complexType": { "original": "Record<string, string>", "resolved": "{ [x: string]: string; }", "references": { "Record": { "location": "global", "id": "global::Record" } } } }]; } static get elementRef() { return "el"; } static get watchers() { return [{ "propName": "animation", "methodName": "watchAnimations" }, { "propName": "animationDelay", "methodName": "watchAnimationsDelay" }, { "propName": "animationSpeed", "methodName": "watchAnimationsSpeed" }]; } } //# sourceMappingURL=gov-form.js.map