import { __decorate } from "tslib";
import { attr, DOM, observable } from '@ni/fast-element';
import { DesignSystem, TextArea as FoundationTextArea } from '@ni/fast-foundation';
import { mixinErrorPattern } from '../patterns/error/types';
import { styles } from './styles';
import { template } from './template';
import { TextAreaAppearance } from './types';
import { mixinRequiredVisiblePattern } from '../patterns/required-visible/types';
/**
 * A nimble-styed HTML text area
 */
export class TextArea extends mixinErrorPattern(mixinRequiredVisiblePattern(FoundationTextArea)) {
    constructor() {
        super(...arguments);
        /**
         * The appearance the text area should have.
         *
         * @public
         * @remarks
         * HTML Attribute: appearance
         */
        this.appearance = TextAreaAppearance.outline;
        this.appearanceReadOnly = false;
        /**
         * The width of the vertical scrollbar, if displayed.
         * @internal
         */
        this.scrollbarWidth = -1;
        this.updateScrollbarWidthQueued = false;
    }
    /**
     * @internal
     */
    connectedCallback() {
        super.connectedCallback();
        this.resizeObserver = new ResizeObserver(() => this.onResize());
        this.resizeObserver.observe(this);
    }
    /**
     * @internal
     */
    disconnectedCallback() {
        super.disconnectedCallback();
        this.resizeObserver?.disconnect();
    }
    /**
     * @internal
     */
    onTextAreaInput() {
        this.handleTextInput();
        this.queueUpdateScrollbarWidth();
    }
    // If a property can affect whether a scrollbar is visible, we need to
    // call queueUpdateScrollbarWidth() when it changes. The exceptions are
    // properties that affect size (e.g. height, width, cols, rows), because
    // we already have a ResizeObserver handling those changes. Also,
    // a change to errorVisible cannot cause scrollbar visibility to change,
    // because we always reserve space for the error icon.
    /**
     * @internal
     */
    placeholderChanged() {
        this.queueUpdateScrollbarWidth();
    }
    /**
     * @internal
     */
    valueChanged(previous, next) {
        super.valueChanged(previous, next);
        this.queueUpdateScrollbarWidth();
    }
    onResize() {
        // Do this directly instead of calling updateScrollbarWidth, b/c we don't want to
        // interfere with queue.
        this.scrollbarWidth = this.control.offsetWidth - this.control.clientWidth;
    }
    queueUpdateScrollbarWidth() {
        if (!this.$fastController.isConnected) {
            return;
        }
        if (!this.updateScrollbarWidthQueued) {
            this.updateScrollbarWidthQueued = true;
            DOM.queueUpdate(() => this.updateScrollbarWidth());
        }
    }
    updateScrollbarWidth() {
        this.updateScrollbarWidthQueued = false;
        this.scrollbarWidth = this.control.offsetWidth - this.control.clientWidth;
    }
}
__decorate([
    attr
], TextArea.prototype, "appearance", void 0);
__decorate([
    attr({ attribute: 'appearance-readonly', mode: 'boolean' })
], TextArea.prototype, "appearanceReadOnly", void 0);
__decorate([
    observable
], TextArea.prototype, "scrollbarWidth", void 0);
const nimbleTextArea = TextArea.compose({
    baseName: 'text-area',
    baseClass: FoundationTextArea,
    template,
    styles,
    shadowOptions: {
        delegatesFocus: true
    }
});
DesignSystem.getOrCreate().withPrefix('nimble').register(nimbleTextArea());
export const textAreaTag = 'nimble-text-area';
//# sourceMappingURL=index.js.map