Textarea
Forms & choicesBrick 0.1.2

Textarea

Textarea is Brick's finished native multi-line plain-text control. It composes released Atom value, form, Field, validation, auto-resize, and character-count behavior with Brick's visual recipes and customization hooks.

Live example

Built from the published package

Interactive

Keep it concise and specific.

Choose with confidence

Know when Textarea is the right part

Use it when

Use Textarea for comments, descriptions, notes, addresses, messages, and other values expected to span multiple lines. Compose it with Field whenever a visible label, description, required indicator, or error is needed.

Choose another path when

Use Input for a single line. Use a purpose-built editor for rich text, Markdown, code, mentions, tags, or formatting. Textarea does not own labels, submission, product-specific word limits, adornments, clear actions, or application persistence.

Installation and imports

tsx
import { Textarea } from "@flowstack-ui/brick";
// or
import { Textarea } from "@flowstack-ui/brick/textarea";
import "@flowstack-ui/brick/styles.css";

The complete stylesheet above is the recommended default. For a measured route-aware build, replace it with the shared foundation and this component's stylesheet:

tsx
import "@flowstack-ui/brick/styles/core.css"; // once at the application root
import "@flowstack-ui/brick/styles/textarea.css";

Add the modular stylesheet for every other Brick component the route renders. Do not combine modular styles with styles.css or tokens.css.

Quick start

tsx
import { Field, Textarea } from "@flowstack-ui/brick";

<Field.Root id="project-summary">
  <Field.Label>Project summary</Field.Label>
  <Textarea.Root name="summary" />
  <Field.Description>Explain the intended result.</Field.Description>
</Field.Root>

Visual recipes and states

  • outline uses a complete border and raised/base control surface.
  • soft uses a subtle filled surface and restrained border.
  • underline uses a transparent surface and bottom indicator.
  • Sizes change padding and typography while keeping the same native row count.
  • Shapes change only outline/soft corner geometry.
  • Invalid changes the border; compose Field.Error for non-color meaning.
  • Disabled and read-only remain visually and semantically distinct.
  • Count aligns to the logical end and uses danger text for Atom over-limit state.
  • Forced colors and reduced motion receive explicit treatment.

Examples

Character count

tsx
<Textarea.Root aria-label="Release notes" maxLength={280}>
  <Textarea.Count />
</Textarea.Root>

Bounded auto-resize

tsx
<Textarea.Root
  aria-label="Description"
  autoResize
  minRows={3}
  maxRows={8}
/>

Manual resize

tsx
<Textarea.Root aria-label="Notes" resize="both" />
Public contract

API

Start with the public parts and root options below. Components with multiple parts separate each area into its own named subsection.

Root

PropTypeDefault
variant"outline" | "soft" | "underline""outline"
size"sm" | "md" | "lg""md"
shape"sharp" | "rounded""rounded"
fullWidthbooleantrue
minRowsnumber3
autoResizebooleanfalse
maxRowsnumberonly with autoResize
resize"none" | "vertical" | "horizontal" | "both""vertical" when not auto-resizing
className, stylewrapper customization
textareaClassName, textareaStylenative control customization

Auto-resize and manual resize are intentionally exclusive. Underline has fixed sharp geometry and rejects shape. Root otherwise accepts released Atom Textarea props and supported native textarea props, including controlled and uncontrolled values, name, form, rows, cols, wrap, placeholder, minLength, maxLength, validation, events, ARIA, and data attributes.

Closed values are:

  • variants: outline, soft, underline;
  • sizes: sm, md, lg;
  • shapes: sharp, rounded;
  • manual resize: none, vertical, horizontal, both.

Count

Count accepts released Atom Textarea Count props, including render, asChild, native span props, and aria-live. Its default content is the current length or current/maxLength.

Public exports are Textarea, TextareaRoot, TextareaCount, TextareaRootProps, TextareaCountProps, TextareaVariant, TextareaSize, TextareaShape, and TextareaResize.

Shared responsibility

Accessibility

The native textarea supplies multi-line editing, selection, value, keyboard, mobile, and form semantics. Provide an accessible name, normally Field.Label; placeholder is not a label. Atom supplies Field relationships, required, read-only, disabled, invalid, reset, and validation behavior. Count is a polite live region by default, so include it only when its updates help the task.

Disabled controls are unavailable and omitted from submission. Read-only controls remain focusable and submitted. Brick adds no wrapper role or custom keyboard behavior.

Responsive behavior

Root defaults to full width, keeps min-inline-size: 0, and cannot exceed its container. Editable text remains at least 16 CSS pixels. Logical alignment supports RTL. Applications own surrounding responsive layout and may opt out of full width. Horizontal/both manual resize remains constrained by the container.

Stable visual contract

Styling and tokens

Customization

Prefer visual props, then semantic tokens, then component variables. Use Root className/style for the wrapper and textareaClassName/textareaStyle for the native editing surface.

tsx
<Textarea.Root
  aria-label="Notes"
  style={{
    "--brick-textarea-border": "#18794e",
    "--brick-textarea-focus-ring": "#18794e",
    "--brick-textarea-radius": "0.75rem",
  } as React.CSSProperties}
  textareaStyle={{ letterSpacing: "0.04em" }}
/>

Tokens and CSS hooks

Stable classes and the data-slot defaults:

  • .brick-textarea / data-slot="textarea"
  • .brick-textarea-control / data-slot="textarea-control"
  • .brick-textarea-count / data-slot="textarea-count"

Root exposes data-variant, data-size, data-shape, data-resize, data-full-width, and data-autoresize. Atom state remains on the native control and Count.

Public component variables:

css
--brick-textarea-padding-inline
--brick-textarea-padding-block
--brick-textarea-gap
--brick-textarea-radius
--brick-textarea-font-family
--brick-textarea-font-size
--brick-textarea-font-weight
--brick-textarea-line-height
--brick-textarea-letter-spacing
--brick-textarea-background
--brick-textarea-foreground
--brick-textarea-placeholder-foreground
--brick-textarea-border
--brick-textarea-hover-background
--brick-textarea-hover-border
--brick-textarea-focus-ring
--brick-textarea-invalid-border
--brick-textarea-disabled-background
--brick-textarea-disabled-foreground
--brick-textarea-disabled-border
--brick-textarea-readonly-background
--brick-textarea-count-foreground
--brick-textarea-count-over-limit-foreground

Advanced reference

Open these details only when you need to inspect DOM ownership, native forwarding, or lower-level composition.

Maintainer resources

Tests, playground evidence, source notes, and release history remain available without crowding the plug-and-play guide.