UNPKG

vicowa-web-components

Version:
180 lines (157 loc) 6.17 kB
import { VicowaInputBaseClass, validate } from '../vicowa-input-base/vicowa-input-base.js'; import '../vicowa-string/vicowa-string.js'; import translator from '../utilities/translate.js'; /** * Class that represents the vicowa-input custom element * @extends VicowaInputBaseClass * @property {string} validatorName Name of the validator function to use with this instance or empty for no validation * @property {string} value The string representation of the value for this instance * @property {string} label The label for this input element or empty if it has no label * @property {boolean} topLabel Boolean that indicates if the label should e on top of the input control, default is to the left * @property {boolean} hideLabel Boolean to indicate that the label should be hidden * @property {boolean} static Boolean to indicate if the input should be drawn as if it is a static field, this will disable all input on it * @property {string} placeholder Placeholder text to show in the control * @property {number} index Tab index * @property {string} tooltip Tooltip string for the control * @property {boolean} disabled Indicates if the control is disabled or not * @property {function} onChange Assign a function to this member that will get called when the value changes * @property {function} validator Assign a custom validator function to this to use instead of one of the pre defined ones */ class VicowaInput extends VicowaInputBaseClass { #activeTranslator; constructor() { super(); } static get properties() { return Object.assign({}, super.properties, { placeholder: { type: String, value: '', reflectToAttribute: true, observer: (control) => control.#placeholderChanged(), }, }); } updateTranslation() { super.updateTranslation(); this.$.input.placeholder = (this.#activeTranslator && this.placeholder) ? this.#activeTranslator.translate(this.placeholder).fetch() : this.placeholder; } attached() { super.attached(); const validateAndSet = () => { validate(this, this.value, true); this.value = this.$.input.value; }; const validateAndSetNoErrorMessage = () => { this.value = this.$.input.value; validate(this, this.value, false); }; this.addAutoEventListener(this.$.input, 'blur', validateAndSet); // loosing focus this.addAutoEventListener(this.$.input, 'change', validateAndSet); // applying the value this.addAutoEventListener(this.$.input, 'input', validateAndSetNoErrorMessage); // inputting text this.$.input.placeholder = this.placeholder; translator.addTranslationUpdatedObserver((translatorInstance) => { this.#activeTranslator = translatorInstance; this.updateTranslation(); }, this); } #placeholderChanged() { this.$.input.placeholder = this.placeholder; this.updateTranslation(); } static get template() { return ` <style> #label { position: relative; display: inline-block; margin-right: 10px; font-family: var(--vicowa-input-label-font-family, inherit); font-size: var(--vicowa-input-label-font-size, inherit); font-style: var(--vicowa-input-label-font-style, inherit); font-weight: var(--vicowa-input-label-font-weight, inherit); color: var(--vicowa-input-label-color, inherit); opacity: var(--vicowa-input-label-opacity, inherit); width: var(--vicowa-input-label-width, auto); overflow: hidden; text-overflow: ellipsis; flex: var(--vicowa-input-label-flex, 1 1 auto); } :host { position: relative; display: block; box-sizing: border-box; } :host([hide-label]) #label { display: none; } :host([disabled]) { opacity: 0.5; pointer-events: none; } #control-container { display: flex; flex-direction: row; } :host([top-label]) #control-container { flex-direction: column; } #input { box-sizing: border-box; border: var(--vicowa-input-border, 1px solid gray); font-family: var(--vicowa-input-control-font-family, inherit); font-size: var(--vicowa-input-control-font-size, inherit); font-style: var(--vicowa-input-control-font-style, inherit); font-weight: var(--vicowa-input-control-font-weight, inherit); color: var(--vicowa-input-control-color, inherit); background: var(--vicowa-input-control-background, transparent); height: var(--vicowa-input-control-height, auto); width: var(--vicowa-input-control-width, 100px); } :host([top-label]) #input { width: var(--vicowa-input-control-width, 100%); } :host(.invalid) #input { background: var(--vicowa-input-control-error-background, red); color: var(--vicowa-input-control-error-color, white); } #error { font-family: var(--vicowa-input-error-font-family, inherit); font-size: var(--vicowa-input-error-font-size, 0.6em); font-style: var(--vicowa-input-error-font-style, italic); font-weight: var(--vicowa-input-error-font-weight, inherit); color: var(--vicowa-input-error-color, red); opacity: var(--vicowa-input-error-opacity, 1); } #input::placeholder { font-family: var(--vicowa-input-placeholder-font-family, inherit); font-size: var(--vicowa-input-placeholder-font-size, 1em); font-style: var(--vicowa-input-placeholder-font-style, italic); font-weight: var(--vicowa-input-placeholder-font-weight, inherit); color: var(--vicowa-input-placeholder-color, black); opacity: var(--vicowa-input-placeholder-opacity, 0.3); } :host([static]) #input { background: transparent; border-color: transparent; outline: none; overflow: hidden; text-overflow: ellipsis; } :host([static]) #input::placeholder { color: transparent; } #error[string=''], :host([static]) #error { display: none; } </style> <div id="control-container"> <label for="input"><vicowa-string id="label"></vicowa-string></label> <input name="input" id="input" title=""> </div> <vicowa-string id="error"></vicowa-string> `; } } window.customElements.define('vicowa-input', VicowaInput);