| 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"
});
}
}