/**
 * Copyright IBM Corp. 2026
 *
 * This source code is licensed under the Apache-2.0 license found in the
 * LICENSE file in the root directory of this source tree.
 */

import "../../globals/settings.js";
import { carbonElement } from "../../globals/decorators/carbon-element.js";
import { __decorate } from "../../_virtual/_@oxc-project_runtime@0.126.0/helpers/decorate.js";
import iconLoader from "../../globals/internal/icon-loader.js";
import if_non_empty_default from "../../globals/directives/if-non-empty.js";
import text_input_default from "../text-input/text-input.js";
import textarea_default$1 from "./textarea.scss.js";
import { LitElement, html } from "lit";
import { property, query } from "lit/decorators.js";
import { classMap } from "lit/directives/class-map.js";
import { ifDefined } from "lit/directives/if-defined.js";
import WarningFilled16 from "@carbon/icons/es/warning--filled/16.js";
import WarningAltFilled16 from "@carbon/icons/es/warning--alt--filled/16.js";
//#region src/components/textarea/textarea.ts
/**
* Copyright IBM Corp. 2019, 2025
*
* This source code is licensed under the Apache-2.0 license found in the
* LICENSE file in the root directory of this source tree.
*/
/**
* Text area.
*
* @element cds-textarea
* @slot helper-text - The helper text.
* @slot label-text - The label text.
* @slot validity-message - The validity message. If present and non-empty, this input shows the UI of its invalid state.
*/
let CDSTextarea = class CDSTextarea extends text_input_default {
	constructor(..._args) {
		super(..._args);
		this.isFluid = false;
		this.counterMode = "character";
		this.id = "";
		this.pattern = "";
		this.required = false;
		this.rows = 4;
		this._prevCounterMode = this.counterMode;
	}
	/**
	* Manually handles maxCount for counterMode = 'word'
	* @param event The keyboard event.
	*/
	_onKeyDown(evt) {
		if (!this.disabled && this.enableCounter && this.counterMode === "word") {
			const currentWordCount = this.value?.match(/\p{L}+/gu)?.length || 0;
			if (this.maxCount && currentWordCount >= this.maxCount && evt.key === " " || this.maxCount && currentWordCount >= this.maxCount && evt.key === "Enter") evt.preventDefault();
		}
	}
	/**
	* Handles `onPaste` event on the `<input>`.
	* Manually handles maxCount for counterMode = 'word' when
	* the user is pasting text
	*
	* @param event The clipboard event.
	*/
	_onPaste(evt) {
		if (this.counterMode === "word" && this.enableCounter && typeof this.maxCount !== "undefined") {
			const existingWords = this._textarea.value.match(/\p{L}+/gu) || [];
			const pastedWords = evt.clipboardData?.getData("Text").match(/\p{L}+/gu) || [];
			if (existingWords.length + pastedWords.length > this.maxCount) {
				evt.preventDefault();
				const allowedWords = existingWords.concat(pastedWords).slice(0, this.maxCount);
				this._textarea.value = allowedWords.join(" ");
				this._textarea.dispatchEvent(new InputEvent("input", {
					inputType: "insertFromPaste",
					data: allowedWords.join(" "),
					bubbles: true
				}));
			}
		}
	}
	/**
	* Handles `oninput` event on the `<input>`.
	*
	* @param event The event.
	* @param event.target The event target.
	*/
	_handleInput({ target }) {
		this.value = target.value;
	}
	render() {
		const { enableCounter, maxCount } = this;
		const textCount = this.value?.length ?? 0;
		const wordCount = this.value?.match(/\p{L}+/gu)?.length || 0;
		const invalidIcon = iconLoader(WarningFilled16, { class: `cds--text-area__invalid-icon` });
		const warnIcon = iconLoader(WarningAltFilled16, { class: `cds--text-area__invalid-icon cds--text-area__invalid-icon--warning` });
		const textareaClasses = classMap({
			[`cds--text-area`]: true,
			[`cds--text-area--warn`]: this.warn,
			[`cds--text-area--invalid`]: this.invalid,
			[`cds--text-area__wrapper--decorator`]: this._hasAILabel
		});
		const textareaWrapperClasses = classMap({
			[`cds--text-area__wrapper`]: true,
			[`cds--text-area__wrapper--cols`]: this.cols,
			[`cds--text-area__wrapper--warn`]: this.warn,
			[`cds--text-area__wrapper--readonly`]: this.readonly
		});
		const labelClasses = classMap({
			[`cds--label`]: true,
			[`cds--visually-hidden`]: this.hideLabel,
			[`cds--label--disabled`]: this.disabled
		});
		const counterClasses = classMap({
			[`cds--label`]: true,
			[`cds--label--disabled`]: this.disabled,
			[`cds--text-area__label-counter`]: true
		});
		const helperTextClasses = classMap({
			[`cds--form__helper-text`]: true,
			[`cds--form__helper-text--disabled`]: this.disabled
		});
		const counter = enableCounter && maxCount ? html` <label class="${counterClasses}">
            <slot name="label-text"
              >${this.counterMode === "word" ? wordCount : textCount}/${maxCount}</slot
            >
          </label>` : null;
		const icon = () => {
			if (this.invalid) return invalidIcon;
			else if (this.warn && !this.invalid) return warnIcon;
			return null;
		};
		const helper = html`
      <div class="${helperTextClasses}" id="helper-text">
        <slot name="helper-text">${this.helperText}</slot>
      </div>
    `;
		const normalizedProps = {
			invalid: this.invalid,
			warn: this.warn,
			"slot-name": this.invalid ? "invalid-text" : "warn-text",
			"slot-text": this.invalid ? this.invalidText : this.warnText
		};
		const validationMessage = html`
      <div
        class="${"cds"}--form-requirement"
        ?hidden="${!normalizedProps.invalid && !normalizedProps.warn}">
        <slot name="${normalizedProps["slot-name"]}">
          ${normalizedProps["slot-text"]} ${this.isFluid ? icon() : null}
        </slot>
      </div>
    `;
		return html`
      <div class="${"cds"}--text-area__label-wrapper">
        <label class="${labelClasses}" for="input">
          <slot name="label-text"> ${this.label} </slot>
        </label>
        ${counter}
      </div>
      <div class="${textareaWrapperClasses}" ?data-invalid="${this.invalid}">
        ${!this.isFluid ? icon() : null}
        <textarea
          autocomplete="${this.autocomplete}"
          ?autofocus="${this.autofocus}"
          class="${textareaClasses}"
          cols="${ifDefined(this.cols)}"
          ?data-invalid="${this.invalid}"
          ?disabled="${this.disabled}"
          id="input"
          name="${if_non_empty_default(this.name)}"
          pattern="${if_non_empty_default(this.pattern)}"
          placeholder="${if_non_empty_default(this.placeholder)}"
          ?readonly="${this.readonly}"
          ?required="${this.required}"
          rows="${ifDefined(this.rows)}"
          .value="${this.value}"
          maxlength="${this.counterMode === "character" ? if_non_empty_default(this.maxCount) : ""}"
          @keydown="${this._onKeyDown}"
          @paste="${this._onPaste}"
          @input="${this._handleInput}"></textarea>
        <slot name="ai-label" @slotchange="${this._handleSlotChange}"></slot>
        <slot name="slug" @slotchange="${this._handleSlotChange}"></slot>
        ${this.isFluid ? html`
              <hr class="${"cds"}--text-area__divider" />
              ${validationMessage}
            ` : null}
      </div>
      ${""}
      ${!this.isFluid ? html` ${helper} ${validationMessage} ` : null}
    `;
	}
	updated() {
		super.updated?.();
		if (this.counterMode !== this._prevCounterMode) {
			const textarea = this._textarea;
			if (textarea) if (this.counterMode === "character") textarea.setAttribute("maxlength", String(this.maxCount));
			else textarea.removeAttribute("maxlength");
			this._prevCounterMode = this.counterMode;
		}
		const wrapper = this.shadowRoot?.querySelector(`.cds--text-area__wrapper`);
		if (!wrapper) return;
		this._resizeObserver = new ResizeObserver(() => {
			this._measureWrapper();
		});
		this._resizeObserver.observe(wrapper);
	}
	/**
	* Measures the width of the wrapper and applies that to the max-width of the
	* helper-text and invalid/warn-text
	*/
	_measureWrapper() {
		const wrapperWidth = (this.shadowRoot?.querySelector(`.cds--text-area__wrapper`))?.scrollWidth;
		[this.shadowRoot?.querySelector(`.cds--form__helper-text`), this.shadowRoot?.querySelector(`.cds--form-requirement`)].forEach((el) => {
			if (el) {
				el.style.maxWidth = `${wrapperWidth}px`;
				el.style.overflowWrap = "break-word";
			}
		});
	}
	disconnectedCallback() {
		super.disconnectedCallback?.();
		this._resizeObserver?.disconnect();
	}
	static {
		this.shadowRootOptions = {
			...LitElement.shadowRootOptions,
			delegatesFocus: true
		};
	}
	static {
		this.styles = textarea_default$1;
	}
};
__decorate([property({ type: Number })], CDSTextarea.prototype, "cols", void 0);
__decorate([property({ type: Boolean })], CDSTextarea.prototype, "isFluid", void 0);
__decorate([property({
	type: String,
	reflect: true,
	hasChanged(newVal, oldVal) {
		if ((newVal === "character" || newVal === "word") && newVal !== oldVal) return true;
		return false;
	},
	attribute: "counter-mode"
})], CDSTextarea.prototype, "counterMode", void 0);
__decorate([property()], CDSTextarea.prototype, "id", void 0);
__decorate([property()], CDSTextarea.prototype, "pattern", void 0);
__decorate([property({
	type: Boolean,
	reflect: true
})], CDSTextarea.prototype, "required", void 0);
__decorate([property()], CDSTextarea.prototype, "rows", void 0);
__decorate([query("textarea")], CDSTextarea.prototype, "_textarea", void 0);
CDSTextarea = __decorate([carbonElement(`cds-textarea`)], CDSTextarea);
var textarea_default = CDSTextarea;
//#endregion
export { textarea_default as default };

//# sourceMappingURL=textarea.js.map