UNPKG

@synergy-design-system/components

Version:

This package provides the base of the Synergy Design System as native web components. It uses [lit](https://www.lit.dev) and parts of [shoelace](https://shoelace.style/). Synergy officially supports the latest two versions of all major browsers (as define

387 lines (382 loc) 12.2 kB
import { textarea_custom_styles_default } from "./chunk.SHIPVO7H.js"; import { textarea_styles_default } from "./chunk.FQWBH6B3.js"; import { defaultValue } from "./chunk.3NXKLKWH.js"; import { form_control_custom_styles_default, form_control_styles_default } from "./chunk.G4URZQCL.js"; import { FormControlController } from "./chunk.HP2LEQRU.js"; import { HasSlotController } from "./chunk.WVVQK5TE.js"; import { enableDefaultSettings } from "./chunk.HYFCK7MM.js"; import { watch } from "./chunk.BVZQ6QSY.js"; import { component_styles_default } from "./chunk.NLYVOJGK.js"; import { SynergyElement } from "./chunk.3THJTCRO.js"; import { __decorateClass } from "./chunk.Z4XV3SMG.js"; // src/components/textarea/textarea.component.ts import { classMap } from "lit/directives/class-map.js"; import { html } from "lit"; import { ifDefined } from "lit/directives/if-defined.js"; import { live } from "lit/directives/live.js"; import { property, query, state } from "lit/decorators.js"; var SynTextarea = class extends SynergyElement { constructor() { super(...arguments); this.formControlController = new FormControlController(this, { assumeInteractionOn: ["syn-blur", "syn-input"] }); this.hasSlotController = new HasSlotController(this, "help-text", "label"); this.hasFocus = false; this.title = ""; this.name = ""; this.value = ""; this.size = "medium"; this.label = ""; this.helpText = ""; this.placeholder = ""; this.rows = 4; this.resize = "vertical"; this.disabled = false; this.readonly = false; this.form = ""; this.required = false; this.spellcheck = true; this.defaultValue = ""; } /** Gets the validity state object */ get validity() { return this.input.validity; } /** Gets the validation message */ get validationMessage() { return this.input.validationMessage; } connectedCallback() { super.connectedCallback(); this.resizeObserver = new ResizeObserver(() => this.setTextareaHeight()); this.updateComplete.then(() => { this.setTextareaHeight(); this.resizeObserver.observe(this.input); }); } firstUpdated() { this.formControlController.updateValidity(); } disconnectedCallback() { var _a; super.disconnectedCallback(); if (this.input) { (_a = this.resizeObserver) == null ? void 0 : _a.unobserve(this.input); } } handleBlur() { this.hasFocus = false; this.emit("syn-blur"); } handleChange() { this.value = this.input.value; this.setTextareaHeight(); this.emit("syn-change"); } handleFocus() { this.hasFocus = true; this.emit("syn-focus"); } handleInput() { this.value = this.input.value; this.emit("syn-input"); } handleInvalid(event) { this.formControlController.setValidity(false); this.formControlController.emitInvalidEvent(event); } setTextareaHeight() { if (this.resize === "auto") { this.sizeAdjuster.style.height = `${this.input.clientHeight}px`; this.input.style.height = "auto"; this.input.style.height = `${this.input.scrollHeight}px`; } else { this.input.style.height = ""; } } handleDisabledChange() { this.formControlController.setValidity(this.disabled); } handleRowsChange() { this.setTextareaHeight(); } async handleValueChange() { await this.updateComplete; this.formControlController.updateValidity(); this.setTextareaHeight(); } /** Sets focus on the textarea. */ focus(options) { this.input.focus(options); } /** Removes focus from the textarea. */ blur() { this.input.blur(); } /** Selects all the text in the textarea. */ select() { this.input.select(); } /** Gets or sets the textarea's scroll position. */ scrollPosition(position) { if (position) { if (typeof position.top === "number") this.input.scrollTop = position.top; if (typeof position.left === "number") this.input.scrollLeft = position.left; return void 0; } return { top: this.input.scrollTop, left: this.input.scrollTop }; } /** Sets the start and end positions of the text selection (0-based). */ setSelectionRange(selectionStart, selectionEnd, selectionDirection = "none") { this.input.setSelectionRange(selectionStart, selectionEnd, selectionDirection); } /** Replaces a range of text with a new string. */ setRangeText(replacement, start, end, selectMode = "preserve") { const selectionStart = start != null ? start : this.input.selectionStart; const selectionEnd = end != null ? end : this.input.selectionEnd; this.input.setRangeText(replacement, selectionStart, selectionEnd, selectMode); if (this.value !== this.input.value) { this.value = this.input.value; this.setTextareaHeight(); } } /** Checks for validity but does not show a validation message. Returns `true` when valid and `false` when invalid. */ checkValidity() { return this.input.checkValidity(); } /** Gets the associated form, if one exists. */ getForm() { return this.formControlController.getForm(); } /** Checks for validity and shows the browser's validation message if the control is invalid. */ reportValidity() { return this.input.reportValidity(); } /** Sets a custom validation message. Pass an empty string to restore validity. */ setCustomValidity(message) { this.input.setCustomValidity(message); this.formControlController.updateValidity(); } render() { const hasLabelSlot = this.hasSlotController.test("label"); const hasHelpTextSlot = this.hasSlotController.test("help-text"); const hasLabel = this.label ? true : !!hasLabelSlot; const hasHelpText = this.helpText ? true : !!hasHelpTextSlot; return html` <div part="form-control" class=${classMap({ "form-control": true, "form-control--small": this.size === "small", "form-control--medium": this.size === "medium", "form-control--large": this.size === "large", "form-control--has-label": hasLabel, "form-control--has-help-text": hasHelpText })} > <label part="form-control-label" class="form-control__label" for="input" aria-hidden=${hasLabel ? "false" : "true"} > <slot name="label">${this.label}</slot> </label> <div part="form-control-input" class="form-control-input"> <div part="base" class=${classMap({ textarea: true, "textarea--small": this.size === "small", "textarea--medium": this.size === "medium", "textarea--large": this.size === "large", "textarea--standard": !this.readonly, "textarea--readonly": this.readonly, "textarea--disabled": this.disabled, "textarea--focused": this.hasFocus, "textarea--empty": !this.value, "textarea--resize-none": this.resize === "none", "textarea--resize-vertical": this.resize === "vertical", "textarea--resize-auto": this.resize === "auto" })} > <textarea part="textarea" id="input" class="textarea__control" title=${this.title} name=${ifDefined(this.name)} .value=${live(this.value)} ?disabled=${this.disabled} ?readonly=${this.readonly} ?required=${this.required} placeholder=${ifDefined(this.placeholder)} rows=${ifDefined(this.rows)} minlength=${ifDefined(this.minlength)} maxlength=${ifDefined(this.maxlength)} autocapitalize=${ifDefined(this.autocapitalize)} autocorrect=${ifDefined(this.autocorrect ? void 0 : "off")} ?autofocus=${this.autofocus} spellcheck=${ifDefined(this.spellcheck)} enterkeyhint=${ifDefined(this.enterkeyhint)} inputmode=${ifDefined(this.inputmode)} aria-describedby="help-text" @change=${this.handleChange} @input=${this.handleInput} @invalid=${this.handleInvalid} @focus=${this.handleFocus} @blur=${this.handleBlur} ></textarea> <!-- This "adjuster" exists to prevent layout shifting. https://github.com/shoelace-style/shoelace/issues/2180 --> <div part="textarea-adjuster" class="textarea__size-adjuster" ?hidden=${this.resize !== "auto"}></div> </div> </div> <div part="form-control-help-text" id="help-text" class="form-control__help-text" aria-hidden=${hasHelpText ? "false" : "true"} > <slot name="help-text">${this.helpText}</slot> </div> </div> `; } }; SynTextarea.styles = [component_styles_default, form_control_styles_default, textarea_styles_default, form_control_custom_styles_default, textarea_custom_styles_default]; __decorateClass([ query(".textarea__control") ], SynTextarea.prototype, "input", 2); __decorateClass([ query(".textarea__size-adjuster") ], SynTextarea.prototype, "sizeAdjuster", 2); __decorateClass([ state() ], SynTextarea.prototype, "hasFocus", 2); __decorateClass([ property({ reflect: true }) ], SynTextarea.prototype, "title", 2); __decorateClass([ property() ], SynTextarea.prototype, "name", 2); __decorateClass([ property() ], SynTextarea.prototype, "value", 2); __decorateClass([ property({ reflect: true }) ], SynTextarea.prototype, "size", 2); __decorateClass([ property() ], SynTextarea.prototype, "label", 2); __decorateClass([ property({ attribute: "help-text" }) ], SynTextarea.prototype, "helpText", 2); __decorateClass([ property() ], SynTextarea.prototype, "placeholder", 2); __decorateClass([ property({ type: Number }) ], SynTextarea.prototype, "rows", 2); __decorateClass([ property() ], SynTextarea.prototype, "resize", 2); __decorateClass([ property({ type: Boolean, reflect: true }) ], SynTextarea.prototype, "disabled", 2); __decorateClass([ property({ type: Boolean, reflect: true }) ], SynTextarea.prototype, "readonly", 2); __decorateClass([ property({ reflect: true }) ], SynTextarea.prototype, "form", 2); __decorateClass([ property({ type: Boolean, reflect: true }) ], SynTextarea.prototype, "required", 2); __decorateClass([ property({ type: Number }) ], SynTextarea.prototype, "minlength", 2); __decorateClass([ property({ type: Number }) ], SynTextarea.prototype, "maxlength", 2); __decorateClass([ property() ], SynTextarea.prototype, "autocapitalize", 2); __decorateClass([ property({ attribute: "autocorrect", reflect: true, converter: { fromAttribute: (value) => value === "" || value === "on", toAttribute: (value) => value ? "on" : "off" }, type: Boolean }) ], SynTextarea.prototype, "autocorrect", 2); __decorateClass([ property() ], SynTextarea.prototype, "autocomplete", 2); __decorateClass([ property({ type: Boolean }) ], SynTextarea.prototype, "autofocus", 2); __decorateClass([ property() ], SynTextarea.prototype, "enterkeyhint", 2); __decorateClass([ property({ type: Boolean, converter: { // Allow "true|false" attribute values but keep the property boolean fromAttribute: (value) => !value || value === "false" ? false : true, toAttribute: (value) => value ? "true" : "false" } }) ], SynTextarea.prototype, "spellcheck", 2); __decorateClass([ property() ], SynTextarea.prototype, "inputmode", 2); __decorateClass([ defaultValue() ], SynTextarea.prototype, "defaultValue", 2); __decorateClass([ watch("disabled", { waitUntilFirstUpdate: true }) ], SynTextarea.prototype, "handleDisabledChange", 1); __decorateClass([ watch("rows", { waitUntilFirstUpdate: true }) ], SynTextarea.prototype, "handleRowsChange", 1); __decorateClass([ watch("value", { waitUntilFirstUpdate: true }) ], SynTextarea.prototype, "handleValueChange", 1); SynTextarea = __decorateClass([ enableDefaultSettings("SynTextarea") ], SynTextarea); export { SynTextarea }; //# sourceMappingURL=chunk.KGSP7LN2.js.map