Skip to main content

Textarea

Textarea

Multi-line text input for longer content like messages and descriptions

Tags: component form text-input

View Demo

Textarea allows users to enter and edit multi-line text content.

Import​

<script>
  import { Textarea } from '@classic-homes/theme-svelte';
</script>

Basic Usage​

<Textarea placeholder="Enter your message..." />

Props​

Prop Type Default Description
value string '' Textarea value (bindable)
placeholder string - Placeholder text
disabled boolean false Disables the textarea
readonly boolean false Makes the textarea read-only
required boolean false Marks as required
name string - Textarea name for forms
id string - Textarea ID for label association
rows number 3 Number of visible text rows
class string - Additional CSS classes
onValueChange (value: string) => void - Callback when value changes

Rows​

Control the visible height with the rows prop:

<Textarea rows={2} placeholder="Short note" />
<Textarea rows={5} placeholder="Detailed description" />
<Textarea rows={10} placeholder="Long form content" />

Two-Way Binding​

Use Svelte's bind:value for two-way data binding:

<script>
  let message = $state('');
</script>

<Textarea bind:value={message} placeholder="Your message" /><p>Character count: {message.length}</p>

Value Change Callback​

Use onValueChange for controlled input handling:

<script>
  let value = $state('');

  function handleChange(newValue: string) {
    // Limit to 500 characters
    value = newValue.slice(0, 500);
  }
</script>

<Textarea {value} onValueChange={handleChange} /><p>{500 - value.length} characters remaining</p>

States​

Disabled​

<Textarea disabled value="Cannot edit this content" />

Read-only​

<Textarea readonly value="This content is read-only" />

Required​

<Textarea required placeholder="Required field" />

With Label​

Always associate textareas with labels for accessibility:

<script>
  import { Textarea, Label } from '@classic-homes/theme-svelte';
</script>

<div class="space-y-2">
  <Label for="message">Message</Label>
  <Textarea id="message" placeholder="Enter your message..." />
</div>

Resizing​

The textarea has resize-y applied by default, allowing vertical resizing. Override with CSS classes:

<!-- No resize -->
<Textarea class="resize-none" />

<!-- Both directions -->
<Textarea class="resize" />

Accessibility​

The Textarea component includes:

  • Full keyboard navigation
  • Visible focus ring with focus-visible
  • Disabled state with cursor-not-allowed
  • Works with <label> associations via id
  • Minimum height maintained for usability

Examples​

Character Counter​

<script>
  import { Textarea, Label } from '@classic-homes/theme-svelte';

  let bio = $state('');
  const maxLength = 280;
</script>

<div class="space-y-2">
  <Label for="bio">Bio</Label>
  <Textarea id="bio" bind:value={bio} rows={4} placeholder="Tell us about yourself..." />
  <p class="text-sm text-muted-foreground text-right">
    {bio.length}/{maxLength}
  </p>
</div>

With Help Text​

<div class="space-y-2">
  <Label for="description">Description</Label>
  <Textarea id="description" rows={4} placeholder="Describe your item..." />
  <p class="text-sm text-muted-foreground">
    Include key details to help buyers understand your item.
  </p>
</div>

Fixed Height​

<Textarea class="resize-none h-32" placeholder="Fixed height textarea" />

Full Width in Container​

<div class="max-w-md">
  <Textarea placeholder="Constrained to container width" />
</div>
  • Input - Single-line text input
  • Label - Label for form inputs
  • FormField - Complete field with label and validation
On this page