# Textarea

- Entry point: `@koobiq/components/textarea`
- NgModule: `KbqTextareaModule`
- Page: https://koobiq.io/en/components/textarea/overview

## Overview

`KbqTextarea` — component for multi-line text input.

**Example: Textarea overview** (`textarea-overview`)

```ts textarea-overview-example.ts
import { ChangeDetectionStrategy, Component } from '@angular/core';
import { KbqTextareaModule } from '@koobiq/components/textarea';

@Component({
    selector: 'textarea-overview-example',
    imports: [KbqTextareaModule],
    template: `
        <kbq-form-field>
            <kbq-label>Label</kbq-label>
            <textarea kbqTextarea placeholder="Placeholder" canGrow="false"></textarea>
        </kbq-form-field>
    `,
    changeDetection: ChangeDetectionStrategy.OnPush,
    host: {
        class: 'layout-margin-xl layout-row'
    }
})
export class TextareaOverviewExample {}
```

### Auto-resize

When the `canGrow` attribute is enabled, the text field will automatically adjust its height based on the content.

**Example: Textarea with canGrow attribute** (`textarea-can-grow`)

```ts textarea-can-grow-example.ts
import { ChangeDetectionStrategy, Component, model } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { KbqTextareaModule } from '@koobiq/components/textarea';
import { KbqToggleModule } from '@koobiq/components/toggle';

@Component({
    selector: 'textarea-can-grow-example',
    imports: [KbqTextareaModule, KbqToggleModule, FormsModule],
    template: `
        <kbq-toggle class="layout-margin-bottom-m" [(ngModel)]="canGrow">canGrow</kbq-toggle>

        <kbq-form-field>
            <kbq-label>Label</kbq-label>
            <textarea kbqTextarea placeholder="Placeholder" [canGrow]="canGrow()" [(ngModel)]="value"></textarea>
        </kbq-form-field>
    `,
    changeDetection: ChangeDetectionStrategy.OnPush,
    host: {
        class: 'layout-margin-xl layout-column'
    }
})
export class TextareaCanGrowExample {
    protected readonly canGrow = model(true);
    protected readonly value = model(
        'In computing, a denial-of-service attack (DoS attack) is a cyber-attack in which the perpetrator seeks to make a machine or network resource unavailable to its intended users by temporarily or indefinitely disrupting services of a host connected to a network. Denial of service is typically accomplished by flooding the targeted machine or resource with superfluous requests in an attempt to overload systems and prevent some or all legitimate requests from being fulfilled. The range of attacks varies widely, spanning from inundating a server with millions of requests to slow its performance, overwhelming a server with a substantial amount of invalid data, to submitting requests with an illegitimate IP address.'
    );
}
```

### Maximum number of rows

The `maxRows` attribute limits the maximum number of rows in the text field; when the limit is reached, scrolling appears.

**Example: Textarea with maxRows attribute** (`textarea-max-rows`)

```ts textarea-max-rows-example.ts
import { ChangeDetectionStrategy, Component, model } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { KbqInputModule } from '@koobiq/components/input';
import { KbqTextareaModule } from '@koobiq/components/textarea';

@Component({
    selector: 'textarea-max-rows-example',
    imports: [KbqTextareaModule, FormsModule, KbqInputModule],
    template: `
        <kbq-form-field>
            <kbq-label>Label</kbq-label>
            <textarea kbqTextarea placeholder="Placeholder" [maxRows]="5" [(ngModel)]="value"></textarea>
        </kbq-form-field>
    `,
    changeDetection: ChangeDetectionStrategy.OnPush,
    host: {
        class: 'layout-margin-xl layout-row'
    }
})
export class TextareaMaxRowsExample {
    protected readonly value = model(
        'In computing, a denial-of-service attack (DoS attack) is a cyber-attack in which the perpetrator seeks to make a machine or network resource unavailable to its intended users by temporarily or indefinitely disrupting services of a host connected to a network. Denial of service is typically accomplished by flooding the targeted machine or resource with superfluous requests in an attempt to overload systems and prevent some or all legitimate requests from being fulfilled. The range of attacks varies widely, spanning from inundating a server with millions of requests to slow its performance, overwhelming a server with a substantial amount of invalid data, to submitting requests with an illegitimate IP address.'
    );
}
```

### Disabled state

The field is not available for editing and interaction. Configured using the `disabled` attribute.

**Example: Textarea disabled** (`textarea-disabled`)

```ts textarea-disabled-example.ts
import { ChangeDetectionStrategy, Component, model } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { KbqTextareaModule } from '@koobiq/components/textarea';
import { KbqToggleModule } from '@koobiq/components/toggle';

@Component({
    selector: 'textarea-disabled-example',
    imports: [KbqTextareaModule, KbqToggleModule, FormsModule],
    template: `
        <kbq-toggle class="layout-margin-bottom-m" [(ngModel)]="disabled">Disabled</kbq-toggle>

        <kbq-form-field>
            <kbq-label>Label</kbq-label>
            <textarea kbqTextarea placeholder="Placeholder" [disabled]="disabled()"></textarea>
        </kbq-form-field>
    `,
    changeDetection: ChangeDetectionStrategy.OnPush,
    host: {
        class: 'layout-margin-xl layout-column'
    }
})
export class TextareaDisabledExample {
    protected readonly disabled = model(true);
}
```

### Error state

Display of the field in an error state for visual indication of invalid data.

**Example: Textarea error state** (`textarea-error-state`)

```ts textarea-error-state-example.ts
import { afterNextRender, ChangeDetectionStrategy, Component } from '@angular/core';
import { FormControl, ReactiveFormsModule, Validators } from '@angular/forms';
import { KbqTextareaModule } from '@koobiq/components/textarea';

@Component({
    selector: 'textarea-error-state-example',
    imports: [KbqTextareaModule, ReactiveFormsModule],
    template: `
        <kbq-form-field>
            <kbq-label>Label</kbq-label>
            <textarea kbqTextarea placeholder="Placeholder" [formControl]="control"></textarea>
            <kbq-hint>Please enter at least 10 characters</kbq-hint>
            <kbq-error>Minimum 10 characters</kbq-error>
        </kbq-form-field>
    `,
    changeDetection: ChangeDetectionStrategy.OnPush,
    host: {
        class: 'layout-margin-xl layout-row'
    }
})
export class TextareaErrorStateExample {
    protected readonly control = new FormControl('', [Validators.minLength(10), Validators.required]);

    constructor() {
        afterNextRender(() => {
            this.control.markAsTouched();
            this.control.updateValueAndValidity();
        });
    }
}
```

## API

### Directives

#### KbqTextarea (directive)

```ts
@Directive({ selector: 'textarea[kbqTextarea]', exportAs: 'kbqTextarea' })
class KbqTextarea implements KbqFormFieldControl<any>, CanUpdateErrorState {
    readonly canGrow = input<boolean>(true);
    readonly maxRows = input<number | undefined>();
    readonly errorStateMatcher = input<ErrorStateMatcher>();
    readonly freeRowsHeight = input<number | undefined>();
    readonly ngControl: NgControl | null;
    readonly parentForm: NgForm | null;
    readonly parentFormGroup: FormGroupDirective | null;
    readonly defaultErrorStateMatcher: ErrorStateMatcher;
    readonly errorState: Signal<boolean>;
    readonly maxRowLimitReached: Signal<boolean>;
    updateErrorState(): void;
    focus(): void;
}
```

- `[canGrow]`: `boolean` — Parameter enables or disables the ability to automatically increase the height.
  If set to false, the textarea becomes vertically resizable.
- `[maxRows]`: `number | undefined` — Maximum number of lines to which the textarea will grow. Unlimited when unset.
- `[errorStateMatcher]`: `ErrorStateMatcher` — An object used to control when error messages are shown.
- `[freeRowsHeight]`: `number | undefined` — Distance from the last line to the bottom border. Defaults to a single line height.
- `errorState`: `Signal<boolean>` — Whether the component is in an error state.
- `maxRowLimitReached`: `Signal<boolean>` — Flag that will be set to true when the maximum number of lines is reached.
  Maximum number of rows can be set using the maxRows input.
- `focus()`: `void` — Focuses the textarea.

### Constants

#### KBQ_TEXTAREA_VALUE_ACCESSOR (const)

```ts
const KBQ_TEXTAREA_VALUE_ACCESSOR: InjectionToken<{ value: any }>;
```
