UNPKG

@freshworks/crayons

Version:
389 lines (388 loc) 15.7 kB
/* eslint-disable @typescript-eslint/explicit-module-boundary-types */ /* eslint-disable @typescript-eslint/no-explicit-any */ import { Component, Prop, h, Element, State, Method } from '@stencil/core'; import { hasSlot } from '../../utils'; import { TranslationController } from '../../global/Translation'; const NATIVE_CONTROLS = ['input', 'select', 'textarea']; export class FormControl { constructor() { this.type = 'TEXT'; this.required = false; this.hint = ''; this.placeholder = ''; this.choices = []; /** * Additional props can be passed here for crayons components. Useful when rendering crayons components implicitly via form-control. */ this.fieldProps = {}; this.touched = false; this.error = ''; this.hasSlot = false; } renderControl() { var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v; if (this.hasSlot) return null; if (!this.name) return null; let cmp; switch (this.type) { case 'TEXT': case 'NUMBER': case 'DECIMAL': case 'EMAIL': case 'TEL': case 'URL': { const type = this.type === 'DECIMAL' ? 'number' : (_a = this.type) === null || _a === void 0 ? void 0 : _a.toLowerCase(); const componentProps = Object.assign(Object.assign(Object.assign(Object.assign({}, this.fieldProps), { name: this.name, placeholder: this.placeholder, label: this.label, required: this.required, type: type }), (_b = this.controlProps) === null || _b === void 0 ? void 0 : _b.inputProps(this.name, type)), { state: (this.touched && this.error && 'error') || 'normal', ['hint-text']: this.hint, ['error-text']: TranslationController.t(this.error, { field: this.label || this.name, }) }); cmp = (h("fw-input", Object.assign({}, componentProps, { ref: (el) => (this.crayonsControlRef = el) }))); break; } case 'PARAGRAPH': { const componentProps = Object.assign(Object.assign(Object.assign(Object.assign({}, this.fieldProps), { name: this.name, placeholder: this.placeholder, label: this.label, required: this.required }), (_c = this.controlProps) === null || _c === void 0 ? void 0 : _c.inputProps(this.name, (_d = this.type) === null || _d === void 0 ? void 0 : _d.toLowerCase())), { state: (this.touched && this.error && 'error') || 'normal', ['hint-text']: this.hint, ['error-text']: TranslationController.t(this.error, { field: this.label || this.name, }) }); cmp = (h("fw-textarea", Object.assign({}, componentProps, { ref: (el) => (this.crayonsControlRef = el) }))); } break; case 'DATE': { const componentProps = Object.assign(Object.assign(Object.assign(Object.assign({}, this.fieldProps), { name: this.name, placeholder: this.placeholder, label: this.label, required: this.required }), (_e = this.controlProps) === null || _e === void 0 ? void 0 : _e.inputProps(this.name, (_f = this.type) === null || _f === void 0 ? void 0 : _f.toLowerCase())), { state: (this.touched && this.error && 'error') || 'normal', ['hint-text']: this.hint, ['error-text']: TranslationController.t(this.error, { field: this.label || this.name, }) }); cmp = (h("fw-datepicker", Object.assign({}, componentProps, { ref: (el) => (this.crayonsControlRef = el) }))); } break; case 'CHECKBOX': { const componentProps = Object.assign(Object.assign(Object.assign(Object.assign({}, this.fieldProps), { name: this.name, placeholder: this.placeholder, label: '', required: this.required }), (_g = this.controlProps) === null || _g === void 0 ? void 0 : _g.checkboxProps(this.name, (_h = this.type) === null || _h === void 0 ? void 0 : _h.toLowerCase())), { state: (this.touched && this.error && 'error') || 'normal', ['hint-text']: this.hint, ['error-text']: TranslationController.t(this.error, { field: this.label || this.name, }) }); cmp = (h("fw-checkbox", Object.assign({}, componentProps, { ref: (el) => (this.crayonsControlRef = el) }), this.label)); } break; case 'RADIO': { const controlProps = (_j = this.controlProps) === null || _j === void 0 ? void 0 : _j.radioProps(this.name, (_k = this.type) === null || _k === void 0 ? void 0 : _k.toLowerCase()); const componentProps = Object.assign(Object.assign(Object.assign({}, this.fieldProps), { 'name': this.name, 'placeholder': this.placeholder, 'label': this.label, 'required': this.required, 'allow-empty': true, 'state': (this.touched && this.error && 'error') || 'normal', ['hint-text']: this.hint, ['error-text']: TranslationController.t(this.error, { field: this.label || this.name, }) }), controlProps); cmp = (h("fw-radio-group", Object.assign({}, componentProps, { ref: (el) => (this.crayonsControlRef = el) }), (_l = this.choices) === null || _l === void 0 ? void 0 : _l.map((ch) => { const val = ch[componentProps.optionValuePath] || ch.value; const label = ch[componentProps.optionLabelPath] || ch.value; return (h("fw-radio", { name: this.name, value: val, state: this.touched && this.error ? 'error' : 'normal' }, label)); }))); } break; case 'DROPDOWN': case 'MULTI_SELECT': { const controlProps = (_m = this.controlProps) === null || _m === void 0 ? void 0 : _m.selectProps(this.name, (_o = this.type) === null || _o === void 0 ? void 0 : _o.toLowerCase()); let componentProps = Object.assign(Object.assign({}, this.fieldProps), { name: this.name, placeholder: this.placeholder, label: this.label, required: this.required, multiple: this.type === 'MULTI_SELECT', state: (this.touched && this.error && 'error') || 'normal', ['hint-text']: this.hint, ['error-text']: TranslationController.t(this.error, { field: this.label || this.name, }) }); componentProps = Object.assign(Object.assign(Object.assign({}, componentProps), controlProps), { options: this.choices }); cmp = (h("fw-select", Object.assign({}, componentProps, { ref: (el) => (this.crayonsControlRef = el) }))); } break; case 'RELATIONSHIP': { const controlProps = (_p = this.controlProps) === null || _p === void 0 ? void 0 : _p.selectProps(this.name, (_q = this.type) === null || _q === void 0 ? void 0 : _q.toLowerCase()); const componentProps = Object.assign(Object.assign({}, this.fieldProps), { name: this.name, placeholder: this.placeholder, label: this.label, required: this.required, state: (this.touched && this.error && 'error') || 'normal', ['hint-text']: this.hint, ['error-text']: TranslationController.t(this.error, { field: this.label || this.name, }) }); if (Array.isArray(controlProps.value) && typeof controlProps.value[0] === 'object' // handle multi_select, select [{}] initialValues ) { componentProps.selectedOptions = controlProps.value; } if (((_r = componentProps.selectedOptions) === null || _r === void 0 ? void 0 : _r.length) > 0) { (_s = this.crayonsControlRef) === null || _s === void 0 ? void 0 : _s.setSelectedOptions(componentProps.selectedOptions); } else if (!controlProps.value) { (_t = this.crayonsControlRef) === null || _t === void 0 ? void 0 : _t.setSelectedOptions([]); } componentProps.noDataText = TranslationController.t('search.startTyping'); cmp = (h("fw-select", Object.assign({}, componentProps, { ref: (el) => (this.crayonsControlRef = el) }))); } break; case 'TIME': { const componentProps = Object.assign(Object.assign(Object.assign(Object.assign({}, this.fieldProps), { name: this.name, placeholder: this.placeholder, label: this.label, required: this.required }), (_u = this.controlProps) === null || _u === void 0 ? void 0 : _u.inputProps(this.name, (_v = this.type) === null || _v === void 0 ? void 0 : _v.toLowerCase())), { state: (this.touched && this.error && 'error') || 'normal', ['hint-text']: this.hint, ['error-text']: TranslationController.t(this.error, { field: this.label || this.name, }) }); cmp = (h("fw-timepicker", Object.assign({}, componentProps, { ref: (el) => (this.crayonsControlRef = el) }))); } break; } return cmp; } componentWillLoad() { this.handleSlotChange(); } /** * Set Focus on the child */ async setFocus() { var _a, _b, _c, _d; if (!this.hasSlot) { await ((_b = (_a = this.crayonsControlRef) === null || _a === void 0 ? void 0 : _a.setFocus) === null || _b === void 0 ? void 0 : _b.call(_a)); } else { (_d = (_c = this.slotElement) === null || _c === void 0 ? void 0 : _c.focus) === null || _d === void 0 ? void 0 : _d.call(_c); } } handleSlotChange() { var _a; this.hasSlot = hasSlot(this.el); this.slotElement = (_a = [...this.el.querySelectorAll('*')].filter((el) => { var _a; return NATIVE_CONTROLS.includes((_a = el === null || el === void 0 ? void 0 : el.tagName) === null || _a === void 0 ? void 0 : _a.toLowerCase()); })) === null || _a === void 0 ? void 0 : _a[0]; } render() { return (h("div", { class: 'form-control-container' }, this.renderControl(), this.hasSlot && (h("label", { htmlFor: this.name, class: { label: true, required: this.required, } }, this.label)), h("slot", { onSlotchange: () => this.handleSlotChange() }), this.hasSlot && !(this.touched && this.error) && (h("div", { class: 'hint', id: `hint-${this.name}` }, this.hint)), this.hasSlot && this.touched && this.error && (h("div", { class: 'error', id: `error-${this.name}` }, TranslationController.t(this.error, { field: this.label || this.name, }))))); } static get is() { return "fw-form-control"; } static get encapsulation() { return "shadow"; } static get originalStyleUrls() { return { "$": ["form-control.scss"] }; } static get styleUrls() { return { "$": ["form-control.css"] }; } static get properties() { return { "type": { "type": "string", "mutable": false, "complexType": { "original": "| 'TEXT'\n | 'NUMBER'\n | 'DECIMAL'\n | 'DROPDOWN'\n | 'MULTI_SELECT'\n | 'RADIO'\n | 'CHECKBOX'\n | 'DATE'\n | 'PARAGRAPH'\n | 'EMAIL'\n | 'URL'\n | 'TEL'\n | 'TIME'\n | 'RELATIONSHIP'", "resolved": "\"CHECKBOX\" | \"DATE\" | \"DECIMAL\" | \"DROPDOWN\" | \"EMAIL\" | \"MULTI_SELECT\" | \"NUMBER\" | \"PARAGRAPH\" | \"RADIO\" | \"RELATIONSHIP\" | \"TEL\" | \"TEXT\" | \"TIME\" | \"URL\"", "references": {} }, "required": false, "optional": false, "docs": { "tags": [], "text": "" }, "attribute": "type", "reflect": false, "defaultValue": "'TEXT'" }, "name": { "type": "any", "mutable": false, "complexType": { "original": "any", "resolved": "any", "references": {} }, "required": false, "optional": false, "docs": { "tags": [], "text": "" }, "attribute": "name", "reflect": true }, "label": { "type": "any", "mutable": false, "complexType": { "original": "any", "resolved": "any", "references": {} }, "required": false, "optional": false, "docs": { "tags": [], "text": "" }, "attribute": "label", "reflect": false }, "required": { "type": "boolean", "mutable": false, "complexType": { "original": "boolean", "resolved": "boolean", "references": {} }, "required": false, "optional": false, "docs": { "tags": [], "text": "" }, "attribute": "required", "reflect": false, "defaultValue": "false" }, "hint": { "type": "string", "mutable": false, "complexType": { "original": "string", "resolved": "string", "references": {} }, "required": false, "optional": false, "docs": { "tags": [], "text": "" }, "attribute": "hint", "reflect": false, "defaultValue": "''" }, "placeholder": { "type": "string", "mutable": false, "complexType": { "original": "string", "resolved": "string", "references": {} }, "required": false, "optional": false, "docs": { "tags": [], "text": "" }, "attribute": "placeholder", "reflect": false, "defaultValue": "''" }, "choices": { "type": "any", "mutable": false, "complexType": { "original": "any", "resolved": "any", "references": {} }, "required": false, "optional": false, "docs": { "tags": [], "text": "" }, "attribute": "choices", "reflect": false, "defaultValue": "[]" }, "fieldProps": { "type": "any", "mutable": true, "complexType": { "original": "any", "resolved": "any", "references": {} }, "required": false, "optional": true, "docs": { "tags": [], "text": "Additional props can be passed here for crayons components. Useful when rendering crayons components implicitly via form-control." }, "attribute": "field-props", "reflect": false, "defaultValue": "{}" }, "controlProps": { "type": "any", "mutable": false, "complexType": { "original": "any", "resolved": "any", "references": {} }, "required": false, "optional": true, "docs": { "tags": [], "text": "Contains values for crayons components. Useful when rendering crayons components implicitly via form-control.\nNot required when using controls via slots." }, "attribute": "control-props", "reflect": false }, "touched": { "type": "boolean", "mutable": false, "complexType": { "original": "boolean", "resolved": "boolean", "references": {} }, "required": false, "optional": false, "docs": { "tags": [], "text": "" }, "attribute": "touched", "reflect": false, "defaultValue": "false" }, "error": { "type": "string", "mutable": false, "complexType": { "original": "string", "resolved": "string", "references": {} }, "required": false, "optional": false, "docs": { "tags": [], "text": "" }, "attribute": "error", "reflect": false, "defaultValue": "''" } }; } static get states() { return { "hasSlot": {} }; } static get methods() { return { "setFocus": { "complexType": { "signature": "() => Promise<void>", "parameters": [], "references": { "Promise": { "location": "global" } }, "return": "Promise<void>" }, "docs": { "text": "Set Focus on the child", "tags": [] } } }; } static get elementRef() { return "el"; } }