Input

Primitive single-line text input component that accepts standard HTML attributes

Usage

<script setup lang="ts">
import { Input } from '@hareui/vue'
</script>
<script setup lang="ts">import { Input } from '@hareui/vue'</script><template>  <Input aria-label="Name" class="w-64" placeholder="Enter your name" /></template>

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

Anatomy

ui keydata-slotElement
baseinput<input>

Attributes not declared as props (aria-label, min, max, autocomplete, listeners…) fall through to the <input>.

Examples

Variants

The Input 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 on surface backgrounds
<script setup lang="ts">import { Input } from '@hareui/vue'</script><template>  <div class="flex w-[240px] flex-col gap-2">    <Input full-width placeholder="Primary input" variant="primary" />    <Input full-width placeholder="Secondary input" variant="secondary" />  </div></template>

In Surface

When used on a surface background (HeroUI's Surface, here a bg-surface container), use variant="secondary" to apply the lower emphasis variant suitable for surface backgrounds.

<script setup lang="ts">import { Input, Surface } from '@hareui/vue'</script><template>  <Surface class="flex h-[180px] w-[280px] items-center justify-center rounded-3xl bg-surface p-4">    <Input class="w-full" placeholder="Your name" variant="secondary" />  </Surface></template>

Full Width

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

Input Types

<script setup lang="ts">import { Input, Label } from '@hareui/vue'</script><template>  <div class="flex w-80 flex-col gap-4">    <div class="flex flex-col gap-1">      <Label for="input-type-email">Email</Label>      <Input id="input-type-email" placeholder="[email protected]" type="email" />    </div>    <div class="flex flex-col gap-1">      <Label for="input-type-number">Age</Label>      <Input id="input-type-number" :min="0" placeholder="30" type="number" />    </div>    <div class="flex flex-col gap-1">      <Label for="input-type-password">Password</Label>      <Input id="input-type-password" placeholder="••••••••" type="password" />    </div>  </div></template>

Controlled

Bind the value with v-model.

https://heroui.com
<script setup lang="ts">import { Input } from '@hareui/vue'import { ref } from 'vue'const value = ref('heroui.com')</script><template>  <div class="flex w-80 flex-col gap-2">    <Input v-model="value" aria-label="Domain" placeholder="domain" />    <span class="px-1 text-sm text-muted">https://{{ value || 'your-domain' }}</span>  </div></template>

Customization

Tailwind CSS

<script setup lang="ts">import { Input } from '@hareui/vue'</script><template>  <Input    aria-label="Search projects"    class="w-64 rounded-xl border border-border/80 bg-default text-foreground placeholder:text-muted"    placeholder="Search projects..."  /></template>

Global Configuration

app.use(createHareUI({
  ui: {
    input: {
      slots: { base: 'rounded-lg px-4' },
      defaultVariants: { variant: 'secondary' },
    },
  },
}))

CSS Variables

The input reads the field tokens --field-border, --field-border-hover, --field-border-focus, --field-focus and --border-width-field; the secondary variant adds --input-bg, --input-bg-hover and --input-bg-focus.

Styling Reference

Slots

  • base → [data-slot="input"] – native input element styling

Interactive States

  • Hover: :hover (when not focused)
  • Focus Visible: :focus (focus styles apply on any focus, as in HeroUI's input.css)
  • Invalid: [data-invalid="true"] (set with aria-invalid by the invalid prop)
  • Disabled: :disabled, [data-disabled="true"] or [aria-disabled="true"]
  • Read Only: [readonly] (set by the readonly prop)

API Reference

Props

PropTypeDefaultDescription
typestringundefinedThe native input type.
idstring-The id of the input. Defaults to the id provided by a surrounding TextField.
namestring-The name of the input, used when submitting a form.
placeholderstring-Temporary text shown when the input is empty.
defaultValuestring | number-The initial value when uncontrolled (no v-model).
variant"primary" | "secondary"'primary'Visual variant of the input. Defaults to the surrounding TextField variant.
fullWidthbooleanundefinedWhether the input takes the full width of its container.
disabledbooleanundefinedWhether the input is disabled.
invalidbooleanundefinedWhether the input is invalid.
requiredbooleanundefinedWhether the input is required.
readonlybooleanundefinedWhether the input 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 input value.

Emits

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

For labels, descriptions and error messages, use TextField; an Input placed in its default slot inherits the field's id, aria-describedby, invalid, disabled, required, variant and fullWidth.

On this page

No Headings