OTTODesign System

Code

Text Area

Storybook group: Components · Sidebar path: Components/Text Area · Extracted 28.09.2026

Version Tag Status API
v1 <oc-text-area-v1> Stable, allowed for generation TextAreaV1

Overview (v1)

Source: ./src/components/text-area/v1/Overview.mdx

Text area

The text area component provides users with a multi-line input field for text input. It has attributes for form identification, initial value setting, additional information display such as hint and placeholder, styling variants, and form validation.

Default variation

Story Default:

<oc-text-area-v1 name="myName" placeholder="this is a placeholder">Label</oc-text-area-v1>

Configuration

The text area component offers a variety of styling variants such as default, error, success, and warning. This component is configurable, allowing you to tailor its features and appearance to your specific needs. To explore all the available options and adjust the component, use the component configurator and see the changes affect the component in real-time.

Usage guidelines

Before integrating the text area component into your project, make sure you have correctly installed the OTTO components package. Look through the variations page for examples of possible component variations. Here, you can discover both common and specific variations that address different use cases.

Info

See the Text area UX documentation for detailed user experience guidelines.

Layout considerations

This component has visual overflow. It extends beyond its bounding box and is clipped by parent containers with overflow: hidden. Ensure the parent container has sufficient padding to accommodate the component's full visual area.

Accessibility

The text area component comes with a set of built-in accessibility features to ensure a seamless experience for all users.

Use oc-aria-label

To make the text area recognizable for screen readers, use the default slot to provide a clear and descriptive label. Use the aria-label attribute on the label to provide additional context if the visible label is not sufficient. See the general accessibility documentation for guidance on using oc-aria-label, including how it works with link and masked link behavior.

Further reading

Configuration (v1)

Source: ./src/components/text-area/v1/Configuration.mdx

Text area configuration

Configure the text area component with the controls below and see the changes live in the preview canvas. Click the Show code button within the preview canvas to see the source code for the current component configuration.

Story Default:

<oc-text-area-v1 name="myName" placeholder="this is a placeholder">Label</oc-text-area-v1>

Interactive configurator (Storybook controls); every option is listed in the API section of this file.

API v1

Source: ./src/components/text-area/v1/TextAreaV1.API.g.mdx

Text Area v1 API

API: <oc-text-area-v1> (TextAreaV1)

The Text Area component provides users with a multi-line input field for text input. It has attributes for form identification, initial value setting, additional information display, styling variants, and form validation.

Attributes / properties
Attribute Type Default Required Description
variant "default" | "error" | "success" | "warning" "default" no Sets the main styling and behavior of the text area.
value string "" no Sets the initial and reset value of the text area to the provided value for form processing.
placeholder string undefined no Provides additional information related to the desired input value of the text area. Displayed as a faint text inside the text area when it's empty.
hint string undefined no Provides additional information related to the text area below the input element.
validation-message string undefined no Provides a validation message related to the text area below the input element.

Implicitly sets the text area to the error state.
disabled boolean false no Disables the text area, preventing user interaction and input.
required boolean false no Marks the input as required for screen readers. Doesn't prevent form submission on its own.
hide-counter boolean false no Hides the counter. Maximum number of characters allowed in the text field is still enforced.
resizable boolean false no Enables the vertical resizing of the text area.
maxlength number undefined no Specifies the maximum number of characters allowed in the textarea.
name string undefined no Sets the name tag to identify the text area when submitting a form.
oc-aria-label string undefined no Sets the ARIA label of the textarea.
without-optional-label boolean false no Excludes the automatic "(optional)" label suffix even if the feature toggle is active.
Slots
Slot Required Description
default yes Sets the label for the text area to provide a brief description of the input field.
Events
Event Detail type Description
oc-property-change OcTextAreaV1Events["oc-property-change"] Whenever a property value changes, this event triggers. Use this event to track all property changes within the component.

Refer to the Events documentation for more information.
oc-mount { component: string; } Fired when the component is mounted to the DOM. The event is fired when the onMount hook of the component is called by the runtime.
oc-unmount { component: string; } Fired when the component is unmounted from the DOM. The event is fired when the function returned by the onMount hook of the component is called by the runtime.
CSS custom properties
Custom property Default Description
--min-height Sets the min-height of the textarea element.

Variations (v1)

Source: ./src/components/text-area/v1/Variations.mdx

Variations

Listed below are the most common variations of the text area component as well as specific component variations for different use cases.

You can explore all available options using the component configurator, adjust the component to your needs, and see the changes live in a preview canvas.

Default

Story: components-text-area-variations--default · tags: components

The default configuration uses the default variant and the placeholder attribute to show a placeholder text in the Text Area when clicked.

<oc-text-area-v1 name="myName" placeholder="this is a placeholder">Label</oc-text-area-v1>

Error

Story: components-text-area-variations--error · tags: components

The error variant uses a red color to indicate an error state.

Args: validation-message=Invalid input

<oc-text-area-v1 name="myName" placeholder="this is a placeholder" validation-message="Invalid input">
  Label
</oc-text-area-v1>

Success

Story: components-text-area-variations--success · tags: components

The success variant uses a green color to indicate a success state.

Args: variant=success

<oc-text-area-v1 name="myName" placeholder="this is a placeholder" variant="success">Label</oc-text-area-v1>

Warning

Story: components-text-area-variations--warning · tags: components

The warning variant uses a yellow color to indicate a warning state.

Args: variant=warning

<oc-text-area-v1 name="myName" placeholder="this is a placeholder" variant="warning">Label</oc-text-area-v1>

Disabled

Story: components-text-area-variations--disabled · tags: components

The disabled attribute set to true disables the Text Area, preventing users from interacting with it.

Args: disabled=true

<oc-text-area-v1 name="myName" placeholder="this is a placeholder" disabled>Label</oc-text-area-v1>

With hint

Story: components-text-area-variations--with-hint · tags: components

The hint attribute displays a hint below the Text Field.

Args: hint=Hint

<oc-text-area-v1 name="myName" placeholder="this is a placeholder" hint="Hint">Label</oc-text-area-v1>

With maxlength and counter and hint

Story: components-text-area-variations--with-maxlength-and-counter-and-hint · tags: components

A Text Area using the maxlength attribute limits the number of characters that can be entered in the Text Area and displays a counter below the Text Area to show the remaining characters. The hint attribute displays a hint below the Text Area.

Args: maxlength=50, hint=Hint

<oc-text-area-v1 name="myName" placeholder="this is a placeholder" maxlength="50" hint="Hint">Label</oc-text-area-v1>

With maxlength without counter

Story: components-text-area-variations--with-maxlength-without-counter · tags: components

Variation using the maxlength attribute limits the number of characters that can be entered in the Text Field and displays a counter below the Text Field to show the remaining characters. The hide-counter attribute hides the counter of the Text Field. Maximum number of characters allowed in the text field is still enforced.

Args: maxlength=50, hide-counter=true

<oc-text-area-v1 name="myName" placeholder="this is a placeholder" hide-counter maxlength="50">Label</oc-text-area-v1>

Resizable

Story: components-text-area-variations--resizable · tags: components

The resizable attribute allows users to resize the Text Area vertically.

Args: resizable=true

<oc-text-area-v1 name="myName" placeholder="this is a placeholder" resizable>Label</oc-text-area-v1>

Demo form

Story: components-text-area-variations--demo-form · tags: components

A demo form that showcases the Text Area component using the attributes hint, placeholder, and maxlength.

<h1 style="margin-bottom: 32px">Demo Form</h1>

<form id="form1">
  <oc-text-area-v1
    name="rating"
    placeholder="please be kind :)"
    maxlength="4000"
    hint="Rate the product"
    required
    >Rating</oc-text-area-v1
  >

  <div class="buttons">
    <oc-button-v1 type="reset" variant="secondary">Reset</oc-button-v1>
    <oc-button-v1 type="submit">Submit</oc-button-v1>
  </div>
</form>

<script>
  (() => {
    const form = document.getElementById("form1");

    form.addEventListener("submit", (ev) => {
      let formData = new FormData(form);
      let data = "";
      formData.forEach((value, key) => (data += key + "=" + value + "\\n"));
      console.log(data);
      alert("sending:\\n" + data);
      ev.preventDefault();
    });
  })();
</script>

<style>
  form {
    display: flex;
    flex-direction: column;
    gap: 24px;
  }

  .buttons {
    display: flex;
    gap: 16px;
  }
</style>
Story source (TypeScript, verbatim from Storybook)
{
  name: "Demo form",
  parameters: {
    controls: {
      disabled: true
    }
  },
  argTypes: hideControlsBadge(Metadata),
  render() {
    return html`
      <h1 style="margin-bottom: 32px">Demo Form</h1>

      <form id="form1">
        <oc-text-area-v1
          name="rating"
          placeholder="please be kind :)"
          maxlength="4000"
          hint="Rate the product"
          required
          >Rating</oc-text-area-v1
        >

        <div class="buttons">
          <oc-button-v1 type="reset" variant="secondary">Reset</oc-button-v1>
          <oc-button-v1 type="submit">Submit</oc-button-v1>
        </div>
      </form>

      <script>
        (() => {
          const form = document.getElementById("form1");

          form.addEventListener("submit", (ev) => {
            let formData = new FormData(form);
            let data = "";
            formData.forEach((value, key) => (data += key + "=" + value + "\\n"));
            console.log(data);
            alert("sending:\\n" + data);
            ev.preventDefault();
          });
        })();
      </script>

      <style>
        form {
          display: flex;
          flex-direction: column;
          gap: 24px;
        }

        .buttons {
          display: flex;
          gap: 16px;
        }
      </style>
    `;
  }
}

Interaction tests (TextAreaV1.interactions.stories.ts)

Interaction test stories (automated tests, not usage patterns).

Should Have Correct Form Data

Story: components-text-area-interaction-tests--should-have-correct-form-data · tags: play-fn

<form>
  <oc-text-area-v1 name="key1">label 1</oc-text-area-v1>
  <oc-text-area-v1 name="key2">label 2</oc-text-area-v1>
  <oc-text-area-v1 name="key3">label 3</oc-text-area-v1>
  <oc-text-area-v1 name="key4" value="I am disabled" disabled>label 4</oc-text-area-v1>
  <oc-button-v1 type="submit">Submit</oc-button-v1>
</form>
Story source (TypeScript, verbatim from Storybook)
{
  render() {
    return html` <form>
      <oc-text-area-v1 name="key1">label 1</oc-text-area-v1>
      <oc-text-area-v1 name="key2">label 2</oc-text-area-v1>
      <oc-text-area-v1 name="key3">label 3</oc-text-area-v1>
      <oc-text-area-v1 name="key4" value="I am disabled" disabled>label 4</oc-text-area-v1>
      <oc-button-v1 type="submit">Submit</oc-button-v1>
    </form>`;
  },
  async play({
    canvasElement
  }) {
    await macrotasks();
    const [input1, input2, input3] = deepQuerySelectorAll(canvasElement, ".text-area__input");
    await userEvent.type(input1, "foo");
    await userEvent.type(input2, "bar");
    await userEvent.type(input3, "foo bar");
    const form = canvasElement.querySelector("form") as HTMLFormElement;
    let formData = undefined;
    form.addEventListener("submit", ev => {
      ev.preventDefault();
      // eslint-disable-next-line @typescript-eslint/ban-ts-comment
      // @ts-ignore
      formData = Object.fromEntries(new FormData(form).entries());
    });
    const [button] = deepQuerySelectorAll(canvasElement, "button");
    await userEvent.click(button);
    await macrotasks();
    await expect(formData).toStrictEqual({
      key1: "foo",
      key2: "bar",
      key3: "foo bar"
    });
  }
}