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 key | data-slot | Element |
|---|---|---|
base | input | <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 casessecondary- 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.
<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'sinput.css) - Invalid:
[data-invalid="true"](set witharia-invalidby theinvalidprop) - Disabled:
:disabled,[data-disabled="true"]or[aria-disabled="true"] - Read Only:
[readonly](set by thereadonlyprop)
API Reference
Props
| Prop | Type | Default | Description |
|---|---|---|---|
type | string | undefined | The native input type. |
id | string | - | The id of the input. Defaults to the id provided by a surrounding TextField. |
name | string | - | The name of the input, used when submitting a form. |
placeholder | string | - | Temporary text shown when the input is empty. |
defaultValue | string | number | - | The initial value when uncontrolled (no v-model). |
variant | "primary" | "secondary" | 'primary' | Visual variant of the input. Defaults to the surrounding TextField variant. |
fullWidth | boolean | undefined | Whether the input takes the full width of its container. |
disabled | boolean | undefined | Whether the input is disabled. |
invalid | boolean | undefined | Whether the input is invalid. |
required | boolean | undefined | Whether the input is required. |
readonly | boolean | undefined | Whether the input can be selected but not changed. Defaults to the surrounding TextField. |
validate | ValidateFn<string | number> | - | Validates the value when used without a TextField (inside one, set validate on the TextField). |
validationBehavior | ValidationBehavior | 'native' | Validation behavior when used without a TextField. Defaults to the surrounding Form. |
ui | ComponentSlots<{ 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. |
modelValue | string | number | - | The input value. |
Emits
| Event | Payload | Description |
|---|---|---|
update:modelValue | [value: string | number | undefined] | - |
For labels, descriptions and error messages, use TextField; an
Inputplaced in its default slot inherits the field's id,aria-describedby,invalid,disabled,required,variantandfullWidth.





