TextArea

Primitive multiline text input component that accepts standard HTML attributes

Usage

import { TextArea } from '@hareui/vue'
<script setup lang="ts">import { TextArea } from '@hareui/vue'</script><template>  <TextArea    aria-label="Quick project update"    class="h-32 w-96"    placeholder="Share a quick project update..."  /></template>

For validation, labels, and error messages, see TextField.

Examples

Variants

The TextArea component supports two visual variants:

  • primary (default) - Standard styling with shadow, suitable for most use cases
  • secondary - Lower emphasis variant without shadow, suitable for use in Surface components
<script setup lang="ts">import { TextArea } from '@hareui/vue'</script><template>  <div class="flex w-[280px] flex-col gap-2">    <TextArea full-width placeholder="Primary textarea" variant="primary" />    <TextArea full-width placeholder="Secondary textarea" variant="secondary" />  </div></template>

In Surface

When used inside a Surface component, use variant="secondary" to apply the lower emphasis variant suitable for surface backgrounds.

<script setup lang="ts">import { Surface, TextArea } from '@hareui/vue'</script><template>  <Surface class="w-full rounded-3xl p-6">    <TextArea      class="w-full min-w-[280px]"      placeholder="Describe your product"      variant="secondary"    />  </Surface></template>

Full Width

<script setup lang="ts">import { TextArea } from '@hareui/vue'</script><template>  <div class="w-[400px] space-y-3">    <TextArea full-width placeholder="Full width textarea" />  </div></template>

Controlled

Characters: 0 / 280
<script setup lang="ts">import { Description, TextArea } from '@hareui/vue'import { ref } from 'vue'const value = ref('')</script><template>  <div class="flex w-96 flex-col gap-2">    <TextArea      v-model="value"      aria-describedby="textarea-controlled-description"      aria-label="Announcement"      placeholder="Compose an announcement..."    />    <Description id="textarea-controlled-description">      Characters: {{ value.length }} / 280    </Description>  </div></template>

Rows and Resizing

<script setup lang="ts">import { Label, TextArea } from '@hareui/vue'</script><template>  <div class="flex w-96 flex-col gap-4">    <div class="flex flex-col gap-2">      <Label for="textarea-rows-3">        Short feedback      </Label>      <TextArea        id="textarea-rows-3"        aria-label="Short feedback"        placeholder="This week's highlights..."        :rows="3"      />    </div>    <div class="flex flex-col gap-2">      <Label for="textarea-rows-6">        Detailed notes      </Label>      <TextArea        id="textarea-rows-6"        aria-label="Detailed notes"        placeholder="Write out the full meeting notes..."        :rows="6"        :style="{ resize: 'vertical' }"      />    </div>  </div></template>

Customization

Tailwind CSS

<script setup lang="ts">import { TextArea } from '@hareui/vue'const fieldClass  = 'rounded-xl border border-border/80 bg-surface shadow-sm ring-1 ring-black/5 transition-[box-shadow,border-color] focus-visible:ring-2 focus-visible:ring-neutral-400/25 dark:ring-white/10 dark:focus-visible:ring-neutral-500/30'</script><template>  <TextArea    aria-label="Notes"    :class="`h-28 w-full max-w-xs text-sm text-neutral-800 placeholder:text-neutral-400 dark:text-neutral-100 dark:placeholder:text-neutral-500 ${fieldClass}`"    placeholder="Add a note..."  /></template>

Global Configuration

app.use(createHareUI({
  ui: {
    textArea: {
      slots: { base: 'rounded-xl px-4 py-3 leading-6' },
      defaultVariants: { variant: 'secondary' },
    },
  },
}))

Styling Reference

Slots

  • base → [data-slot="textarea"] – Underlying <textarea> element styling

Interactive States

  • Hover: :hover (when not focused)
  • Focus Visible: :focus
  • Invalid: [data-invalid="true"]
  • Disabled: :disabled, [data-disabled="true"] or [aria-disabled="true"]

API Reference

TextArea accepts all standard HTML <textarea> attributes (rows, cols, maxlength, minlength, wrap, autocomplete, …) plus the following:

Props

PropTypeDefaultDescription
idstring-The id of the textarea. Defaults to the id provided by a surrounding TextField.
namestring-The name of the textarea, used when submitting a form.
placeholderstring-Temporary text shown when the textarea is empty.
defaultValuestring | number-The initial value when uncontrolled (no v-model).
variant"primary" | "secondary"'primary'Visual variant of the textarea. Defaults to the surrounding TextField variant.
fullWidthbooleanundefinedWhether the textarea takes the full width of its container.
disabledbooleanundefinedWhether the textarea is disabled.
invalidbooleanundefinedWhether the textarea is invalid.
requiredbooleanundefinedWhether the textarea is required.
readonlybooleanundefinedWhether the textarea can be selected but not changed. Defaults to the surrounding TextField.
validateValidateFn<string | number>-Validates the value when used without a TextField (inside one, set validate on the TextField).
validationBehaviorValidationBehavior'native'Validation behavior when used without a TextField. Defaults to the surrounding Form.
uiComponentSlots<{ slots: { base: string[]; }; variants: { variant: { primary: { base: string; }; secondary: { base: string[]; }; }; fullWidth: { false: { base: string; }; true: { base: string; }; }; }; defaultVariants: { fullWidth: boolean; variant: string; }; }>-Per-slot class overrides.
modelValuestring | number-The textarea value.

Emits

EventPayloadDescription
update:modelValue[value: string | number | undefined]-

For validation props like invalid, required, and error handling, use TextField with TextArea in its default slot.

On this page

No Headings