UNPKG

monphind-ui

Version:

A reactive component library built on top of the Web Components API

157 lines (156 loc) 5.03 kB
import { useElement } from "./core/element"; const name = 'm-textarea'; const style = `:host { display: block; width: 250px; height: 200px; border-radius: 15px; background-color: var(--m-textarea-default-backgroundColor,${"white"}); position: relative; outline: 0px solid transparent; transition: outline 0.2s; } :host textarea { width: 100%; height: 100%; resize: none; outline: none; border: none; border-radius: 15px; padding: 13px; font-size: 14px; background-color: transparent; box-sizing: border-box; font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Open Sans", "Helvetica Neue", sans-serif; color: var(--m-textarea-textColor ,${"black"}); } :host p.label { position: absolute; left: 16px; top: 13px; margin: 0; font-weight: 300; font-size: 12px; color: var(--m-textarea-default-label-color,${"rgb(178,178,178)"}); width: -moz-fit-content; width: fit-content; height: -moz-fit-content; height: fit-content; pointer-events: none; transition: transform 0.3s; } :host([focused=true]) p.label { color: var(--m-textarea-focused-label-color,${"#2EA2F9"}); transform: translateY(-37px); } :host textarea[has_text=true] ~ p.label { transform: translateY(-37px); } :host([focused=true]) { outline: 2px solid var(--m-textarea-focused-outline-color,${"#2ea1f9d6"}); } :host([disabled=true]) { background-color: var(--m-textarea-disabled-backgroundColor,${"#EFEFEF"}); } :host([disabled=true]) p.label { color: var(--m-textarea-disabled-label-color,${"rgb(178,178,178)"}); } :host([error=true]) { outline: 2px solid var(--m-textarea-error-outline-color,${"rgba(255,0,0,0.507)"}); } :host([error=true]) p.label { color: var(--m-textarea-error-label-color,${"rgba(255,0,0,0.507)"}); } :host([readonly=true]) textarea { color: var(--m-textarea-readonly-color,${"rgb(178,178,178)"}); }`; const template = `<textarea></textarea> <p class="label"></p>`; const props = { disabled: false, label: "", value: "", count: 0, readonly: false, adaptive: false, error: false }; export class Textarea extends useElement({ name, props, style, template, syncProps: ["adaptive", "disabled", "label", "readonly", "value", "error"], setup() { return {}; }, dispatch: { connected() { const label = this.label; const labelEle = this.shadowRoot?.querySelector(".label"); labelEle.textContent = label; const textarea = this.shadowRoot?.querySelector("textarea"); textarea.addEventListener("input", () => { this.value = textarea.value; this.count = textarea.value.length; }); textarea.addEventListener("focus", () => { this.setAttribute("focused", "true"); }); textarea.addEventListener("blur", () => { this.setAttribute("focused", "false"); }); }, propChanged(key, value) { const labelEle = this.shadowRoot?.querySelector(".label"); const textarea = this.shadowRoot?.querySelector("textarea"); switch (key) { case "adaptive": { this.setAttribute("auto-height", String(String(value) === 'true')); if (value === 'true') { this.style.height = 'auto'; this.style.height = textarea.scrollHeight + 'px'; } break; } case "disabled": { if (value === 'true') { textarea.disabled = true; } else { textarea.disabled = false; textarea.removeAttribute("disabled"); } break; } case "label": { labelEle.textContent = String(value); break; } case "readonly": { if (value === "true") { textarea.readOnly = true; } else { textarea.readOnly = false; textarea.removeAttribute("readonly"); } break; } case "value": { textarea.value = String(value); textarea.setAttribute("has_text", String(value).length ? "true" : "false"); this.count = String(value).length; if (this.getAttribute("auto-height") === 'true') { this.style.height = `auto`; this.style.height = `${textarea.scrollHeight}px`; } break; } } } } }) { } Textarea.defineElement(); import 'vue';