@polarityio/pi-textarea
v1.1.1
Published
Multi-line text input component with auto-expand, resizable, and error state support
Readme
Polarity Integration Component Library
Textarea Component
A multi-line text input component supporting auto-expanding height, standard row-based sizing, native resize handles, and the same label/error-state conventions as pi-input.
Installation
npm install @polarityio/pi-textareaPeer Dependencies
- lit ^3.0.0
Usage
Registering the element is not a side effect of importing the package — call defineCustomElementOnce explicitly (this is the same pattern @polarityio/pi-components uses):
import { PiTextarea, CUSTOM_ELEMENT_NAME } from '@polarityio/pi-textarea';
import { defineCustomElementOnce } from '@polarityio/pi-shared';
defineCustomElementOnce(CUSTOM_ELEMENT_NAME, PiTextarea);<!-- Basic textarea -->
<pi-textarea label="Notes" placeholder="Enter notes..." rows="4"></pi-textarea>
<!-- Auto-expanding textarea -->
<pi-textarea label="Description" auto-expand></pi-textarea>
<!-- Auto-expand capped at 6 rows, then scrolls internally -->
<pi-textarea label="Description" auto-expand max-rows="6"></pi-textarea>
<!-- Manually resizable in both directions -->
<pi-textarea label="Notes" resize="both"></pi-textarea>
<!-- Textarea with error message -->
<pi-textarea label="Comments" error-message="This field is required"></pi-textarea>Handling Events
const textarea = document.querySelector('pi-textarea');
textarea.addEventListener('pi-input', (e) => {
console.log('Current value:', e.detail.value);
});
textarea.addEventListener('pi-change', (e) => {
console.log('Committed value:', e.detail.value);
});API Reference
Properties
| Property | Type | Default | Description |
| -------------- | ---------------------------------------------------- | ----------- | --------------------------------------------------------------------------------------------------- |
| value | string | '' | Current textarea value |
| placeholder | string | '' | Placeholder text displayed when the textarea is empty |
| label | string | '' | Label text displayed above the textarea |
| name | string | '' | Name used for form submission via FormData when inside a <form> |
| disabled | boolean | false | Disables the textarea |
| readonly | boolean | false | Makes the textarea read-only |
| error | boolean | false | Sets error state styling on the textarea |
| errorMessage | string | '' | Error message displayed below the textarea. Setting this also activates the error state. |
| noErrorSpace | boolean | false | When true, no space is reserved below the textarea when idle. Useful for compact layouts. |
| rows | number | 3 | Number of visible text rows (native rows attribute) |
| maxlength | number \| undefined | undefined | Maximum character length |
| minlength | number \| undefined | undefined | Minimum character length |
| autocomplete | string | 'off' | HTML autocomplete attribute |
| autoExpand | boolean | false | Grows the textarea's height to fit content as the user types, up to maxRows if set |
| maxRows | number \| undefined | undefined | Maximum rows to grow to while autoExpand is on; content beyond this scrolls internally |
| resize | 'none' \| 'horizontal' \| 'vertical' \| 'both' | 'none' | Native CSS resize behavior. The vertical component is suppressed while autoExpand is on |
Form participation
pi-textarea is a form-associated custom element: when placed inside a <form>, its name/value are included in the form's FormData on submit, just like a native <textarea>. Set aria-label or aria-labelledby on the host element to provide an accessible name for assistive technology when label is not set — it's forwarded to the native textarea.
Events
| Event Name | Detail | Description |
| ----------- | ------------------- | ------------------------------------------------------------ |
| pi-input | { value: string } | Fired on each keystroke in the textarea |
| pi-change | { value: string } | Fired when the value changes and the textarea loses focus |
CSS Custom Properties
| Property | Default | Description |
| -------------------------------- | ----------------------------------------------- | ---------------------------- |
| --pi-textarea-line-height | 1.4 | Line height of the text |
| --pi-textarea-padding | 4px 8px | Padding inside the textarea |
| --pi-textarea-border | 1px solid var(--pi-textarea-border-color) | Border definition |
| --pi-textarea-border-color | var(--pi-color-border-element) | Border color |
| --pi-textarea-border-radius | var(--pi-size-radius-base, 4px) | Border radius |
| --pi-textarea-background | var(--pi-color-background-container-base) | Background color |
| --pi-textarea-text-color | var(--pi-color-font-primary) | Text color |
| --pi-textarea-disabled-bg | var(--pi-color-background-container-disabled) | Background when disabled |
CSS Parts
| Part Name | Description |
| ---------------- | ------------------------------------------------ |
| wrapper | The container wrapping the native <textarea> |
| textarea | The native HTML <textarea> element |
| error-message | The error message container below the textarea |
Public Methods
| Method | Description |
| ------------------------------- | ------------------------------------------------------ |
| focus(options?: FocusOptions) | Programmatically focuses the native textarea element |
| select() | Selects all text in the textarea |
Theming
Customize the appearance using CSS custom properties. This component uses design tokens from @polarityio/pi-shared for consistent theming across the component library.
pi-textarea {
--pi-textarea-border-radius: 8px;
--pi-textarea-padding: 8px 12px;
}
pi-textarea::part(textarea) {
font-size: 1rem;
}License
MIT
