Textarea
Textarea is a styled native control with one durable behavior: its presentation is derived from the value it currently renders and its responsive width. Restored and controlled values therefore receive the right height without a second persistence layer.
Installation
Run one command from a Boring Stack application. Klean detects the framework and conventional destination, then adds the framework-native source and its direct dependencies.
npx klean-ui add textarea- No initializer or configuration file
- No framework, alias, or theme questions
- No Klean runtime dependency
Native form recipe
<script setup>
import Textarea from '@/components/ui/textarea/Textarea.vue'
</script>
<template>
<div class="grid gap-2">
<label for="note">Internal note</label>
<Textarea
id="note"
v-model="form.note"
name="note"
rows="3"
:aria-invalid="Boolean(form.errors.note)"
aria-describedby="note-help note-error"
/>
<p id="note-help">Plain text, up to 2,000 characters.</p>
<p id="note-error" class="empty:hidden text-sm text-red-700">
{{ form.errors.note }}
</p>
</div>
</template>
The surrounding label, help, error, IDs, validation, and value source remain ordinary application markup. Keep help and error nodes stable, bind aria-invalid to the boolean error state, and hide an empty error with empty:hidden. There is no Field context, accessibility helper, or autoGrow switch.
Durable resizing
Textarea measures after mount and after its current value changes. It also observes width changes because responsive wrapping changes content height. This covers server data, URL state, and application-owned restored drafts without writing localStorage itself.
Content-derived height is the default contract, not a feature flag. Caller Tailwind can still replace it:
<Textarea class="h-40 resize-y overflow-y-auto" />Because caller classes merge last, this removes the derived height, hidden overflow, and fixed-resize defaults cleanly.
API
Textarea accepts native textarea attributes, framework-native value binding, and caller classes. It exposes its native element for explicit focus recovery. It has no variant, size, autoGrow, label, description, error, or validation props.
Accessibility contract
- Use a real associated label and connect help or error text explicitly.
- Keep description IDs stable instead of rebuilding them when an error changes.
- Keep the native
name,required,disabled, and form behavior. - Apply
aria-invalidwith useful visible error text. - Do not use placeholder text as the label.
- Caller-owned fixed sizing must preserve usable content access and keyboard operation.
- Focus remains visible and decorative transitions respect reduced motion.