# Custom textarea

> **Info:** This is release candidate documentation for **Stream Chat Angular SDK v8**. For the latest stable version, see the [latest version (v7)](https://getstream.io/chat/docs/sdk/angular/).

## Introduction

This guide shows you how to replace the built in textarea component inside the [message input component](https://getstream.io/chat/docs/sdk/angular/v8/components/MessageInputComponent/). One example where it's useful, is if you want to implement a HTML based editor for your chat users.

The guide will provide step-by-step instructions to create the textarea on the right:

![Message input with built-in textarea](https://getstream.io/docs-assets/images/fff9efc3de41.png)

![Message input with custom textarea](https://getstream.io/docs-assets/images/2e556682a3de.png)

If you want to follow the tutorial, make sure to have a simple stream-chat-angular application set up. If you don't already have that, [follow our tutorial](https://getstream.io/chat/sdk/angular/tutorial/).

## Custom textarea component

Let's create a new component for our custom textarea:

```bash
ng g c textarea --inline-style --inline-template
```

The textarea will be displayed inside the `stream-message-input` component, and the two components need to communicate with each other. To ensure compatibility, your custom textarea component needs to implement the [`Textarea` interface](https://github.com/GetStream/stream-chat-angular/blob/master/projects/stream-chat-angular/src/lib/message-input/textarea.interface.ts).

The interface has some optional elements that you might decide to ignore based on your own requirements. Below you'll find the essential parts of the interface:

```typescript
@Input() value: string = '';
@Output() readonly valueChange = new EventEmitter<string>();
@Output() readonly send = new EventEmitter<void>();
@Output() readonly pasteFromClipboard = new EventEmitter<ClipboardEvent>();
```

| Name                 | Input/Output | Description                                                                                                                                                                                                                     |
| -------------------- | ------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `value`              | Input        | The value to display inside the textarea. For new messages it will be an empty string (or the saved draft text), but for editing messages this will be the original message content                                             |
| `valueChange`        | Output       | An output to notify the message input component about value changes. It is used to send `typing.start` and `typing.stop` events to other users and to update the message draft                                                  |
| `send`               | Output       | An output to notify the message input component to send the message. It is useful if you want to enable your users to trigger message send with hitting the `Enter`                                                             |
| `pasteFromClipboard` | Output       | An output to forward `paste` events to the message input component. The message input uses it to upload pasted files as attachments (or calls your `customPasteEventHandler` if you set one in the `MessageInputConfigService`) |

Now let's see a very simple custom textarea implementation:

```typescript
import { Component, EventEmitter, Input, Output } from "@angular/core";
import { TextareaInterface } from "stream-chat-angular";

@Component({
  selector: "app-textarea",
  template: `
    <button (click)="setToBold(input)">Bold</button>
    <textarea
      style="width: 100%"
      [value]="value || ''"
      #input
      placeholder="Type your message here"
      rows="1"
      (input)="inputChanged(input.value)"
      (keydown.enter)="enterHit($event)"
      (paste)="pasteFromClipboard.emit($event)"
    ></textarea>
  `,
  styles: [":host {width: 100%}"],
})
export class TextareaComponent implements TextareaInterface {
  @Input() value = "";
  @Output() readonly valueChange = new EventEmitter<string>();
  @Output() readonly send = new EventEmitter<void>();
  @Output() readonly pasteFromClipboard = new EventEmitter<ClipboardEvent>();

  constructor() {}

  inputChanged(value: string) {
    this.valueChange.emit(value);
  }

  setToBold(input: HTMLTextAreaElement) {
    const currentValue = input.value;
    const newValue = `<b>${currentValue}</b>`;
    input.value = newValue;
    this.inputChanged(newValue);
  }

  enterHit(event: Event) {
    event.preventDefault();
    this.send.next();
  }
}
```

## Registering the component

To use the custom textarea component we need to let the `stream-message-input` component know which component to create for the textarea slot. To do this you need to define a provider for the `textareaInjectionToken`.

Let's update your `app.module.ts` to the following:

```typescript {6,10,14,16-20}
import { NgModule } from "@angular/core";
import { BrowserModule } from "@angular/platform-browser";

import { AppComponent } from "./app.component";
import { StreamChatModule, textareaInjectionToken } from "stream-chat-angular";
import { TextareaComponent } from "./textarea/textarea.component";
import { provideTranslateService } from "@ngx-translate/core";

@NgModule({
  declarations: [AppComponent, TextareaComponent],
  imports: [
    BrowserModule,
    StreamChatModule,
    // Make sure you remove any import to StreamAutocompleteTextareaModule or StreamTextareaModule
  ],
  providers: [
    {
      provide: textareaInjectionToken,
      useValue: TextareaComponent,
    },
    provideTranslateService(),
  ],
  bootstrap: [AppComponent],
})
export class AppModule {}
```

With that the built-in textarea will be replaced with your custom textarea component.

## Displaying HTML content

By default the [`Message`](https://getstream.io/chat/docs/sdk/angular/v8/components/MessageComponent/) and [`ChannelPreview`](https://getstream.io/chat/docs/sdk/angular/v8/components/ChannelPreviewComponent/) components will format message content as text. So the message bubble will display something like this: `<b>Hi</b>` instead of this: <b>Hi</b>.

To fix this, you need to set text formatting to HTML using the [`MessageService`](https://getstream.io/chat/docs/sdk/angular/v8/services/MessageService/)

```typescript {8}
constructor(
    private chatService: ChatClientService,
    private channelService: ChannelService,
    private streamI18nService: StreamI18nService,
    messageService: MessageService
  ) {
    // Set message formatting before initializing the ChannelService
    messageService.displayAs = 'html';
    void this.chatService.init(
      environment.apiKey,
      environment.userId,
      environment.userToken
    );
    void this.channelService.init({
      type: 'messaging',
      members: { $in: [environment.userId] },
    });
    this.streamI18nService.setTranslation();
  }
```

If you want to use a different formatting, you have to provide your own message and channel preview components for that.

## Limitations

- The built-in [`TextareaComponent`](https://getstream.io/chat/docs/sdk/angular/v8/components/TextareaComponent/#feature-overview) and [`AutocompleteTextareaComponent`](https://getstream.io/chat/docs/sdk/angular/v8/components/AutocompleteTextareaComponent/#feature-overview) have additional features that you have to implement for yourself if you decide to create your own textarea component.
- The built-in `Message` and `ChannelPreview` components can only format message content as text or HTML. If you want to implement a different formatting (for example Markdown), you need to create a custom [message](https://getstream.io/chat/docs/sdk/angular/v8/components/MessageComponent/#customization) and [channel preview](https://getstream.io/chat/docs/sdk/angular/v8/components/ChannelPreviewComponent/#customization) components.

---

For the most recent version of this documentation, visit [https://getstream.io/chat/docs/sdk/angular/v8/code-examples/custom-textarea/](https://getstream.io/chat/docs/sdk/angular/v8/code-examples/custom-textarea/).