Textarea
A multi-line text field. Vertically resizable, with the same border/focus/disabled treatment as Input and an optional invalid state.
bash
jlds add textareaUsage
html
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/jarooda/jlds@main/registry/css/index.css">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/jarooda/jlds@main/registry/css/textarea.css">
<textarea class="jl-textarea" placeholder="Write a message…"></textarea>vue
<script setup lang="ts">
import { ref } from "vue"
import { Textarea } from "@/components/ui/textarea"
const message = ref("")
</script>
<template>
<Textarea v-model="message" placeholder="Write a message…" />
</template>tsx
import { Textarea } from "@/components/ui/textarea"
<Textarea placeholder="Write a message…" />Invalid & disabled
Add invalid for error styling, or the native disabled attribute.
html
<textarea class="jl-textarea" aria-invalid="true">Too short</textarea>
<textarea class="jl-textarea" disabled>Disabled</textarea>vue
<template>
<Textarea invalid model-value="Too short" />
<Textarea disabled model-value="Disabled" />
</template>tsx
<Textarea invalid defaultValue="Too short" />
<Textarea disabled defaultValue="Disabled" />Auto-resize & counter
autoResize grows the field to fit its content; showCount (with maxLength) renders a character counter that turns red past the limit.
html
<!-- needs the behavior layer (js/all.js) -->
<span class="jl-textarea-wrap">
<textarea class="jl-textarea jl-textarea--auto" data-auto-resize maxlength="140">Deploys in ~40s.</textarea>
<span class="jl-textarea__count">15/140</span>
</span>vue
<template>
<Textarea v-model="msg" auto-resize show-count :max-length="140" />
</template>tsx
<Textarea autoResize showCount maxLength={140} value={msg} onChange={(e) => setMsg(e.target.value)} />Props
React
Textarea extends React.TextareaHTMLAttributes<HTMLTextAreaElement>, so rows, placeholder, value, onChange, disabled, etc. all pass through.
| Prop | Type | Default | Description |
|---|---|---|---|
invalid | boolean | false | Show error styling |
autoResize | boolean | false | Grow to fit content |
showCount | boolean | false | Character counter (with maxLength) |
Vue
Textarea supports v-model; other attributes (rows, placeholder, disabled, …) fall through to the inner <textarea>.
| Prop | Type | Default | Description |
|---|---|---|---|
invalid | boolean | false | Show error styling |
autoResize | boolean | false | Grow to fit content |
showCount | boolean | false | Character counter (with maxLength) |
maxLength | number | — | Max characters (drives the counter) |
modelValue | string | — | Bound value (v-model) |
CSS classes (HTML)
| Class | Purpose |
|---|---|
.jl-textarea | The textarea — always required (vertically resizable by default) |
[aria-invalid="true"] | Error styling |