UNPKG

@freshworks/crayons

Version:
243 lines (239 loc) 14.7 kB
import { attachShadow, createEvent, h, proxyCustomElement } from '@stencil/core/internal/client'; import { h as handleKeyDown, a as hasSlot, r as renderHiddenField } from './index2.js'; import { F as FieldControl } from './field-control.js'; import { d as defineCustomElement$1, a as defineCustomElement$3 } from './icon.js'; import { d as defineCustomElement$2 } from './spinner.js'; const inputCss = ":host{font-family:var(--fw-font-family, -apple-system, blinkmacsystemfont, \"Segoe UI\", roboto, oxygen, ubuntu, cantarell, \"Open Sans\", \"Helvetica Neue\", sans-serif);-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;-webkit-box-sizing:border-box;box-sizing:border-box}.field-control{position:relative}.field-control-label{display:block;font-size:12px;color:var(--fw-label-color, #475867);font-weight:600;margin-bottom:4px;padding-left:2px;line-height:20px}.field-control-label.required::after{content:\"*\";position:relative;display:inline-block;top:2px;font-size:14px;color:#d72d30;padding-left:2px;font-weight:700}.field-control-hint-text{font-family:-apple-system, blinkmacsystemfont, \"Segoe UI\", \"Roboto\", \"Helvetica Neue\", arial, sans-serif;font-size:12px;line-height:20px;margin-top:4px;margin-bottom:0;color:var(--fw-hint-color, #acb6be);position:inherit;display:block;padding-left:2px;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.field-control-error-text{font-family:-apple-system, blinkmacsystemfont, \"Segoe UI\", \"Roboto\", \"Helvetica Neue\", arial, sans-serif;font-size:12px;line-height:20px;margin-top:4px;margin-bottom:0;color:var(--fw-error-color, #d72d30);position:inherit;display:block;padding-left:2px;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.field-control-warning-text{font-family:-apple-system, blinkmacsystemfont, \"Segoe UI\", \"Roboto\", \"Helvetica Neue\", arial, sans-serif;font-size:12px;line-height:20px;margin-top:4px;margin-bottom:0;color:var(--fw-warning-color, #f8ab59);position:inherit;display:block;padding-left:2px;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}*,::after,::before{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}:host{display:block}.input-container{width:inherit;height:inherit}.input-container-inner{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;width:100%;border:1px solid #cfd7df;background-color:#fff;position:relative;border-radius:4px;-webkit-box-shadow:inset 0px 1px 2px rgba(24, 50, 71, 0.05);box-shadow:inset 0px 1px 2px rgba(24, 50, 71, 0.05)}.input-container-inner.error{border-color:#d72d30}.input-container-inner.error.has-focus{-webkit-box-shadow:none;box-shadow:none;border-color:#d72d30}.input-container-inner.error:hover,.input-container-inner.error:focus{border-color:#d72d30}.input-container-inner.error+.help-block{color:#d72d30}.input-container-inner.warning{border-color:#f8ab59}.input-container-inner.warning.has-focus{-webkit-box-shadow:none;box-shadow:none;border-color:#f8ab59}.input-container-inner.warning:hover,.input-container-inner.warning:focus{border-color:#f8ab59}.input-container-inner.warning+.help-block{color:#f8ab59}.input-container-inner .inner__content{display:-ms-flexbox;display:flex;-ms-flex:1 1 auto;flex:1 1 auto;-ms-flex-wrap:wrap;flex-wrap:wrap}.input-container-inner .inner__content .input__label{-ms-flex:1 1 40%;flex:1 1 40%;display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;margin-left:8px}.input-container-inner .inner__content .input__label input{width:100%;padding:5px 0px;resize:none;border:none;outline:none;-webkit-box-shadow:none;box-shadow:none;min-height:24px;font-size:14px;font-weight:500;letter-spacing:0;line-height:20px;color:#183247;-webkit-box-sizing:border-box;box-sizing:border-box;cursor:text;display:inline-block;font-family:inherit}.input-container-inner .inner__content .input__label input[disabled]{font-weight:400;color:#92a2b1;background-color:#f7f9fa;pointer-events:none}.input-container-inner .inner__content .input__prefix{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;-ms-flex:0 1 auto;flex:0 1 auto;margin-left:4px}.input-container-inner .inner__content .input__prefix.hasContent{margin-left:8px}.input-container-inner .inner__suffix{-ms-flex:0 1 auto;flex:0 1 auto;display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;margin-right:8px}@media (prefers-reduced-motion){.input-container-inner{}.input-container-inner:hover{-webkit-transition:none;transition:none}}.input-container-inner:hover{border:1px #475867 solid}.input-container-inner.has-focus{outline:none;background:#fff;background-color:#fff;border:1px solid #2c5cc5;-webkit-box-shadow:0 0 0 1px #2c5cc5;box-shadow:0 0 0 1px #2c5cc5}.input-container-inner.disabled{font-weight:400;color:#92a2b1;border:1px solid #ebeff3;background-color:#f7f9fa;border-style:solid;pointer-events:none}.input-container-inner .clear-button{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;-ms-flex-pack:center;justify-content:center;height:16px;width:16px}.input-container-inner .clear-button:hover,.input-container-inner .clear-button:focus{cursor:pointer;pointer-events:initial}.input-container-inner .clear-button .clear-img{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;-ms-flex-pack:center;justify-content:center;width:12px;height:12px}.input-container-inner+.help-block{font-family:-apple-system, blinkmacsystemfont, \"Segoe UI\", \"Roboto\", \"Helvetica Neue\", arial, sans-serif;font-size:12px;line-height:20px;margin-top:4px;margin-bottom:0;color:var(--fw-hint-color, #acb6be);position:inherit;display:block;padding-left:2px;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}::-webkit-input-placeholder{color:#acb6be}::-moz-placeholder{color:#acb6be}:-ms-input-placeholder{color:#acb6be}:-moz-placeholder{color:#acb6be}"; let Input = class extends HTMLElement { constructor() { super(); this.__registerHost(); attachShadow(this); this.fwFocus = createEvent(this, "fwFocus", 7); this.fwBlur = createEvent(this, "fwBlur", 7); this.fwInput = createEvent(this, "fwInput", 7); this.fwInputClear = createEvent(this, "fwInputClear", 7); this.hasFocus = false; this.hasPrefix = false; this.hasHintTextSlot = false; this.hasWarningTextSlot = false; this.hasErrorTextSlot = false; /** * Label displayed on the interface, for the component. */ this.label = ''; /** * Default value displayed in the input box. */ this.value = ''; /** * Type of value accepted as the input value. If a user enters a value other than the specified type, the input box is not populated. */ this.type = 'text'; /** * Specifies whether the browser can display suggestions to autocomplete the text value. */ this.autocomplete = 'off'; /** * Displays a right-justified clear icon in the text box. Clicking the icon clears the input text. If the attribute’s value is undefined, the value is set to false. For a read-only input box, the clear icon is not displayed unless a default value is specified for the input box. */ this.clearInput = false; /** * The step attribute is used when the type is `number`. It specifies the interval between legal numbers in a number/decimal input element. * Works with the min and max attributes to limit the increments at which a value can be set. * Possible values are `any` or a positive floating point number. * Default value is `any` */ this.step = 'any'; /** * Name of the component, saved as part of form data. */ this.name = ''; /** * Theme based on which the text box is styled. */ this.state = 'normal'; /** * If true, the user cannot enter a value in the input box. If the attribute’s value is undefined, the value is set to false. */ this.readonly = false; /** * Specifies the input box as a mandatory field and displays an asterisk next to the label. If the attribute’s value is undefined, the value is set to false. */ this.required = false; /** * Disables the component on the interface. If the attribute’s value is undefined, the value is set to false. */ this.disabled = false; /** * Identifier of the icon that is displayed in the left side of the text box. The attribute’s value must be a valid svg file in the repo of icons (assets/icons). */ this.iconLeft = undefined; /** * Identifier of the icon that is displayed in the right side of the text box. The attribute’s value must be a valid svg file in the repo of icons (assets/icons). */ this.iconRight = undefined; /** * Hint text displayed below the text box. */ this.hintText = ''; /** * Warning text displayed below the text box. */ this.warningText = ''; /** * Error text displayed below the text box. */ this.errorText = ''; this.onInput = (ev) => { const input = ev.target; this.value = input.value || ''; this.fwInput.emit({ event: ev, name: this.name, value: this.getValue(), }); }; this.onFocus = () => { this.hasFocus = true; this.fwFocus.emit(); }; this.onBlur = (ev) => { this.hasFocus = false; this.fwBlur.emit({ event: ev, name: this.name, }); }; this.clearTextInput = (ev) => { if (!this.disabled) { this.value = ''; if (this.nativeInput) { this.nativeInput.value = ''; } this.fwInputClear.emit({ event: ev, name: this.name, value: this.value, }); } }; } showClearButton() { var _a; return this.clearInput && !this.disabled && ((_a = this.value) === null || _a === void 0 ? void 0 : _a.length) > 0; } getValue() { return this.value || ''; } hasValue() { return this.getValue().length > 0; } /** * Sets focus on a specific `fw-input`. Use this method instead of the global `input.focus()`. */ async setFocus() { if (this.nativeInput) { this.nativeInput.focus(); } } renderClearButton() { return (h("div", { class: 'clear-button', role: 'button', tabindex: '0', onClick: (e) => this.clearTextInput(e), onKeyDown: handleKeyDown(this.clearTextInput) }, h("fw-icon", { class: 'clear-img', name: 'cross', size: 8, library: 'system' }))); } renderIcon(iconName) { return h("fw-icon", { name: iconName }); } componentWillLoad() { this.hasPrefix = !!this.host.querySelector('[slot="input-prefix"]') || !!this.iconLeft; this.checkSlotContent(); } getAriaDescribedBy() { if (this.state === 'normal') return `hint-${this.name}`; else if (this.state === 'error') return `error-${this.name}`; else if (this.state === 'warning') return `warning-${this.name}`; return null; } checkSlotContent() { this.hasHintTextSlot = hasSlot(this.host, 'hint-text'); this.hasWarningTextSlot = hasSlot(this.host, 'warning-text'); this.hasErrorTextSlot = hasSlot(this.host, 'error-text'); } render() { const { host, name, value } = this; renderHiddenField(host, name, value); return (h(FieldControl, { inputId: this.name, label: this.label, labelId: `${this.label}-${this.name}`, state: this.state, hintTextId: `hint-${this.name}`, hintText: this.hintText, hasHintTextSlot: this.hasHintTextSlot, errorTextId: `error-${this.name}`, errorText: this.errorText, hasErrorTextSlot: this.hasErrorTextSlot, warningTextId: `warning-${this.name}`, warningText: this.warningText, hasWarningTextSlot: this.hasWarningTextSlot, required: this.required }, h("div", { "aria-disabled": this.disabled, class: { 'has-value': this.hasValue(), 'has-focus': this.hasFocus, } }, h("div", { class: { 'input-container': true, } }, h("div", { class: { 'input-container-inner': true, 'has-focus': this.hasFocus, 'disabled': this.disabled, [this.state]: true, } }, h("div", { class: 'inner__content' }, h("div", { class: { input__prefix: true, hasContent: this.hasPrefix } }, this.iconLeft && this.renderIcon(this.iconLeft), h("slot", { name: 'input-prefix' })), h("div", { class: 'input__label' }, h("input", { ref: (input) => { this.nativeInput = input; }, id: this.name, autoComplete: this.autocomplete, disabled: this.disabled, name: this.name, placeholder: this.placeholder || '', minLength: this.minlength, maxLength: this.maxlength, min: this.min, max: this.max, readOnly: this.readonly, required: this.required, step: this.step, type: this.type, value: this.value, onInput: this.onInput, onBlur: this.onBlur, onFocus: this.onFocus, "aria-invalid": this.state === 'error', "aria-describedby": this.getAriaDescribedBy() }), this.showClearButton() && this.renderClearButton())), h("div", { class: 'inner__suffix' }, this.iconRight && this.renderIcon(this.iconRight), h("slot", { name: 'input-suffix' }))))))); } get host() { return this; } static get style() { return inputCss; } }; Input = /*@__PURE__*/ proxyCustomElement(Input, [1, "fw-input", { "label": [1], "value": [1025], "type": [1], "autocomplete": [1], "clearInput": [4, "clear-input"], "maxlength": [2], "minlength": [2], "max": [2], "min": [2], "step": [1], "name": [1], "placeholder": [1], "state": [1], "readonly": [4], "required": [4], "disabled": [4], "iconLeft": [1, "icon-left"], "iconRight": [1, "icon-right"], "hintText": [1, "hint-text"], "warningText": [1, "warning-text"], "errorText": [1, "error-text"], "hasFocus": [32], "hasPrefix": [32], "hasHintTextSlot": [32], "hasWarningTextSlot": [32], "hasErrorTextSlot": [32], "setFocus": [64] }]); function defineCustomElement() { const components = ["fw-input", "fw-icon", "fw-spinner", "fw-toast-message"]; components.forEach(tagName => { switch (tagName) { case "fw-input": if (!customElements.get(tagName)) { customElements.define(tagName, Input); } break; case "fw-icon": if (!customElements.get(tagName)) { defineCustomElement$3(); } break; case "fw-spinner": if (!customElements.get(tagName)) { defineCustomElement$2(); } break; case "fw-toast-message": if (!customElements.get(tagName)) { defineCustomElement$1(); } break; } }); } export { Input as I, defineCustomElement as d };