Gecko UIGecko UI

RHFTextarea

Multi-line text input component integrated with React Hook Form

RHFTextarea

A multi-line textarea component integrated with React Hook Form that automatically displays error states with a red border when validation fails. Supports auto-resizing functionality.

Installation

import { RHFTextarea } from '@geckoui/geckoui';

Basic Usage

import { useForm, FormProvider } from 'react-hook-form';
import { RHFTextarea } from '@geckoui/geckoui';

function Example() {
  const methods = useForm({
    defaultValues: {
      description: ''
    }
  });

  return (
    <FormProvider {...methods}>
      <RHFTextarea name="description" placeholder="Enter description" />
    </FormProvider>
  );
}

Props API

Extends all props from Textarea component plus:

PropTypeDefaultDescription
namestring-Field name (required)
controlControlAuto-injectedOptional: Pass explicitly for nested forms or custom form context
rulesRegisterOptions-Inline validation rules
autoResizebooleanfalseEnable automatic height adjustment
rowsnumber2Minimum number of rows
maxRowsnumber-Maximum number of rows (only with autoResize)
onChange(value: string) => void-Change callback (receives value, not event)
onBlur(value: string) => void-Blur callback
...restTextareaProps-All Textarea component props

Examples

With Validation (Zod)

import { useForm, FormProvider } from 'react-hook-form';
import { zodResolver } from '@hookform/resolvers/zod';
import { z } from 'zod';
import { RHFTextarea, RHFInputGroup } from '@geckoui/geckoui';

const schema = z.object({
  bio: z.string().min(10, 'Bio must be at least 10 characters').max(500, 'Bio must not exceed 500 characters')
});

function Example() {
  const methods = useForm({
    resolver: zodResolver(schema),
    mode: 'onBlur',
    defaultValues: { bio: '' }
  });

  return (
    <FormProvider {...methods}>
      <RHFInputGroup label="Bio" required>
        <RHFTextarea name="bio" placeholder="Tell us about yourself (min 10 chars)" />
      </RHFInputGroup>
    </FormProvider>
  );
}

Auto-Resizing Textarea

<RHFTextarea
  name="comments"
  autoResize
  rows={3}
  maxRows={10}
  placeholder="This textarea grows as you type (max 10 rows)"
/>

With Row Constraints

<RHFTextarea
  name="notes"
  rows={5}
  placeholder="Fixed at 5 rows"
/>

Disabled State

<RHFTextarea name="readonly" disabled />

Complete Form Example

import { useForm, FormProvider } from 'react-hook-form';
import { zodResolver } from '@hookform/resolvers/zod';
import { z } from 'zod';
import { RHFTextarea, RHFInputGroup, Button } from '@geckoui/geckoui';

const schema = z.object({
  title: z.string().min(1, 'Title is required'),
  description: z.string().min(20, 'Description must be at least 20 characters'),
  notes: z.string().optional()
});

function FormExample() {
  const methods = useForm({
    resolver: zodResolver(schema),
    mode: 'onBlur',
    defaultValues: {
      title: '',
      description: '',
      notes: ''
    }
  });

  return (
    <FormProvider {...methods}>
      <form onSubmit={methods.handleSubmit(console.log)}>
        <RHFInputGroup label="Title" required>
          <RHFTextarea name="title" rows={1} placeholder="Enter title" />
        </RHFInputGroup>

        <RHFInputGroup label="Description" required>
          <RHFTextarea
            name="description"
            autoResize
            rows={3}
            maxRows={8}
            placeholder="Enter description (min 20 chars)"
          />
        </RHFInputGroup>

        <RHFInputGroup label="Additional Notes">
          <RHFTextarea name="notes" rows={2} placeholder="Optional notes" />
        </RHFInputGroup>

        <Button type="submit">Submit</Button>
      </form>
    </FormProvider>
  );
}

Inline Rules Validation

For simple validation, use the rules prop:

<RHFTextarea
  name="description"
  rules={{
    required: 'Description is required',
    minLength: { value: 10, message: 'Must be at least 10 characters' }
  }}
/>

For complex forms, we recommend using a schema resolver (Zod, Yup) instead.

Error States

RHFTextarea automatically displays error states with:

  • Red border via GeckoUIRHFTextarea--error CSS class when fieldState.error exists

Use RHFInputGroup component for label + textarea + error layout:

<RHFInputGroup label="Description" required>
  <RHFTextarea name="description" />
</RHFInputGroup>

Or combine with RHFError component manually:

<RHFTextarea name="description" />
<RHFError name="description" />

Tip: Use mode: 'onBlur' in useForm to validate on blur for better UX:

const methods = useForm({
  resolver: zodResolver(schema),
  mode: 'onBlur'
});

Auto-Resize Behavior

When autoResize is enabled:

  • Textarea grows automatically as content increases
  • Minimum height is determined by the rows prop
  • Maximum height is determined by the maxRows prop
  • Shrinks back down when content is removed

When autoResize is disabled:

  • Textarea has a fixed height based on rows
  • Users can resize manually (if CSS allows)
  • The maxRows prop is ignored

Accessibility

  • Inherits all accessibility features from Textarea component
  • Proper ARIA attributes for error states
  • Keyboard navigable
  • Screen reader compatible