YaVendio Registry
Components

YA Textarea

A multiline text input component for longer content

The YaTextarea is a multiline text input field in the YaVendio Design System. It supports vertical/horizontal orientations, character counter, validation states, and integrates seamlessly with external buttons.

Quick Start

pnpm dlx shadcn@latest add @yavendio/ya-textarea
npx shadcn@latest add @yavendio/ya-textarea
yarn dlx shadcn@latest add @yavendio/ya-textarea
import { YaTextarea } from '@/components/ui/ya-textarea'

export default function Example() {
  return <YaTextarea label="Message" placeholder="Type your message here..." />
}

Orientations

YaTextarea supports two layout orientations for different use cases.

OrientationDescriptionFeatures
verticalLabel above textareaHelp text below, counter right of label
horizontalLabel beside textarea (85px width)No help text, compact layout

Vertical (Default)

Label appears above the textarea field.

Provide a detailed description

<YaTextarea
  orientation="vertical"
  label="Description"
  placeholder="Enter a description..."
  helpText="Provide a detailed description"
/>

Horizontal

Label appears to the left of the textarea field.

<YaTextarea
  orientation="horizontal"
  label="Bio"
  placeholder="Tell us about yourself..."
/>

Orientation Comparison

This is help text

<div className="flex flex-col gap-6">
  <YaTextarea
    orientation="vertical"
    label="Vertical Layout"
    placeholder="Label above"
    helpText="This is help text"
  />

  <YaTextarea
    orientation="horizontal"
    label="Horizontal"
    placeholder="Label on the left"
  />
</div>

With Counter

Display a character counter next to the label.

0/500

Brief description about yourself

import { useState } from 'react'
import { YaTextarea } from '@/components/ui/ya-textarea'

export default function CounterExample() {
  const [value, setValue] = useState('')
  const maxLength = 500

  return (
    <YaTextarea
      label="Bio"
      placeholder="Tell us about yourself..."
      value={value}
      onChange={(e) => setValue(e.target.value.slice(0, maxLength))}
      counter={{ current: value.length, max: maxLength }}
      helpText="Brief description about yourself"
    />
  )
}

With External Button

Integrate with YaButton for combined textarea-action patterns.

Your feedback helps us improve

import { YaTextarea } from '@/components/ui/ya-textarea'
import { YaButton } from '@/components/ui/ya-button'
import { Send } from 'lucide-react'

<YaTextarea
  label="Feedback"
  placeholder="Share your thoughts..."
  helpText="Your feedback helps us improve"
  button={
    <YaButton variant="primary" rightIcon={<Send />}>
      Send
    </YaButton>
  }
/>

States

All States

Please provide a valid message

Disabled

<YaTextarea label="Message" placeholder="This textarea is disabled" disabled />
  • Reduced opacity (50%)
  • pointer-events: none
  • Non-interactive

Destructive

Apply danger styling for validation errors.

Message is required

<YaTextarea
  label="Message"
  placeholder="Type your message here..."
  destructive
  errorText="Message is required"
/>

Features:

  • Red border
  • Red label text
  • Error message displayed below (vertical only)

Examples

Feedback Form

0/1000

We appreciate your honest feedback

import { useState } from 'react'
import { YaTextarea } from '@/components/ui/ya-textarea'
import { YaButton } from '@/components/ui/ya-button'
import { Send } from 'lucide-react'

export default function FeedbackForm() {
  const [feedback, setFeedback] = useState('')
  const maxLength = 1000

  return (
    <YaTextarea
      label="Your Feedback"
      placeholder="Share your experience with us..."
      value={feedback}
      onChange={(e) => setFeedback(e.target.value.slice(0, maxLength))}
      counter={{ current: feedback.length, max: maxLength }}
      helpText="We appreciate your honest feedback"
      button={
        <YaButton variant="primary" rightIcon={<Send />}>
          Submit
        </YaButton>
      }
    />
  )
}

Contact Form

Please describe your inquiry in detail

import { YaInput } from '@/components/ui/ya-input'
import { YaTextarea } from '@/components/ui/ya-textarea'
import { YaButton } from '@/components/ui/ya-button'

<form className="flex flex-col gap-4">
  <YaInput label="Name" placeholder="Your name" />
  <YaInput label="Email" placeholder="your@email.com" />
  <YaTextarea
    label="Message"
    placeholder="How can we help you?"
    helpText="Please describe your inquiry in detail"
  />
  <div className="flex gap-2 mt-4">
    <YaButton type="submit" variant="primary">
      Send Message
    </YaButton>
    <YaButton type="button" variant="secondary">
      Cancel
    </YaButton>
  </div>
</form>

With Validation

Minimum 10 characters required

import { useState } from 'react'
import { YaTextarea } from '@/components/ui/ya-textarea'

export default function ValidatedTextarea() {
  const [value, setValue] = useState('')
  const [error, setError] = useState('')
  const minLength = 10

  const handleChange = (e: React.ChangeEvent<HTMLTextAreaElement>) => {
    const newValue = e.target.value
    setValue(newValue)

    if (newValue.length > 0 && newValue.length < minLength) {
      setError(`Message must be at least ${minLength} characters`)
    } else {
      setError('')
    }
  }

  return (
    <YaTextarea
      label="Message"
      placeholder="Enter your message..."
      value={value}
      onChange={handleChange}
      destructive={!!error}
      errorText={error}
      helpText={`Minimum ${minLength} characters required`}
    />
  )
}

Props

YaTextarea

PropTypeDefaultDescription
orientation'vertical' | 'horizontal''vertical'Layout orientation
labelstring-Label text
helpTextstring-Help text (vertical only)
errorTextstring-Error message (vertical only, when destructive)
placeholderstring-Placeholder text
counter{ current: number; max: number }-Character counter
buttonReactNode-External button
destructivebooleanfalseApplies error styling
disabledbooleanfalseDisable the textarea
classNamestring-Additional classes

Additional Props

YaTextarea extends all standard HTML textarea attributes:

  • id, name, value
  • rows, cols, maxLength
  • onChange, onFocus, onBlur
  • aria-label, aria-describedby
  • And all other HTML textarea props

Accessibility

Best Practices

DoDon't
Use for multiline contentUse for single-line input
Always include a labelSkip labels for accessibility
Use help text to guide usersLeave users guessing
Display clear error messagesVague error feedback
Use destructive for validationRed styling without prop
Use character counter for limitsAllow unlimited input when there's a max

TypeScript

import { type VariantProps } from 'class-variance-authority'
import { yaTextareaWrapperVariants, yaTextareaFieldVariants } from '@/components/ui/ya-textarea'

type TextareaOrientation = VariantProps<typeof yaTextareaWrapperVariants>['orientation']

On this page