Textarea

For the times when you really just have a lot to say.

<script>
	import { Field, Label } from '$lib/components/fieldset';
	import { Textarea } from '$lib/components/textarea';
</script>

<Field>
	<Label>Description</Label>
	<Textarea name="description" />
</Field>

Component API

PropDefaultDescription
Textarea extends the Headless UI <Textarea> component
disabledfalseWhether or not to disable the textarea.
invalidfalseWhether the textarea has a validation error.
resizabletrueWhether the textarea can be resized vertically.
name-The name to use when submitting an HTML form.
defaultValue-The initial value for the textarea.
value-The controlled value of the textarea.
onChange-Handler to call when the textarea value changes.
rows-The number of visible lines in the textarea.
Field extends the Headless UI <Field> component
disabledfalseWhether or not to disable the entire field.
Label extends the Headless UI <Label> component
This component does not expose any component-specific props.
Description extends the Headless UI <Description> component
This component does not expose any component-specific props.
ErrorMessage extends the Headless UI <Description> component
This component does not expose any component-specific props.

Examples

Basic example

Use the Textarea component on its own to render a standalone textarea without an associated Label component:

<script>
	import { Textarea } from '$lib/components/textarea';
</script>

<Textarea aria-label="Description" name="description" />

Make sure to provide an aria-label for assistive technology, or connect the Textarea to your own <label> element using an id.

With label

Wrap a Label and Textarea with the Field component to automatically associate them using a generated ID:

<script>
	import { Field, Label } from '$lib/components/fieldset';
	import { Textarea } from '$lib/components/textarea';
</script>

<Field>
	<Label>Description</Label>
	<Textarea name="description" />
</Field>

With description

Use the Description component to add a description above or below your Textarea:

This will be shown under the product title.

<script>
	import { Description, Field, Label } from '$lib/components/fieldset';
	import { Textarea } from '$lib/components/textarea';
</script>

<Field>
	<Label>Description</Label>
	<Description>This will be shown under the product title.</Description>
	<Textarea name="name" />
</Field>

Disabled state

Add the disabled prop to the Field component to disable an Textarea and the associated Label:

<script>
	import { Field, Label } from '$lib/components/fieldset';
	import { Textarea } from '$lib/components/textarea';
</script>

<Field disabled>
	<Label>Description</Label>
	<Textarea name="description" />
</Field>

You can also disable a textarea outside of a Field by adding the disabled prop directly to the Textarea itself.

Validation errors

Add the invalid prop to the Field component to indicate a validation error, and render the error using the ErrorMessage component:

This field is required.

<script>
	import { ErrorMessage, Field, Label } from '$lib/components/fieldset';
	import { Textarea } from '$lib/components/textarea';
</script>

<Field>
	<Label>Description</Label>
	<Textarea name="description" invalid={errors.has('description')} />
	{#if errors.has('description')}
		<ErrorMessage>{errors.get('description')}</ErrorMessage>
	{/if}
</Field>

With custom layout

Use the unstyled Field component from @headlessui/react directly instead of the styled Field component to implement a custom layout:

This will be shown under the product title.

<script>
	import { Description, Label } from '$lib/components/fieldset';
	import { Textarea } from '$lib/components/textarea';
	import * as Headless from '@headlessui/react';
</script>

<Headless.Field class="grid grid-cols-12 gap-6">
	<div class="col-span-5">
		<Label>Description</Label>
		<Description class="mt-1">This will be shown under the product title.</Description>
	</div>
	<div class="col-span-7">
		<Textarea name="description" rows="3" />
	</div>
</Headless.Field>

Using the unstyled Field component will ensure important accessibility features are still handled for you like generating IDs and associating elements using aria-* attributes.

Controlled component

Use the normal value and onChange props to use the Textarea component as a controlled component:

<script>
	import { Field, Label } from '$lib/components/fieldset';
	import { Textarea } from '$lib/components/textarea';

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

<Field>
	<Label>Description</Label>
	<Textarea name="description" value={name} onChange={(e) => (name = e.target.value)} />
</Field>