---
title: Input
description: A field that accepts single-line or multiline text.
category: Form
status: beta
since: 0.3.4
tags: [input, field, search]
syncStatus: reviewed
verified: true
---

## Usage

### Basic
:::TuffDemoWrapper{demo="InputBasicInputDemo" code-lang="vue"}
---
code: |
  <template>
    <TuffInput v-model="value" placeholder="Type here..." />
  </template>
---
:::

### Search Row
:::TuffDemoWrapper{demo="InputSearchRowDemo" code-lang="vue"}
---
code: |
  <template>
    <TuffInput placeholder="Search..." />
    <TxButton size="sm">Go</TxButton>
  </template>
---
:::

### Input Types
`type` takes `text`, `password`, `textarea`, `date`, `email`, or `number`; `rows` sets the textarea height.
:::TuffDemoWrapper{demo="InputInputTypesDemo" code-lang="vue"}
---
code: |
  <template>
    <TuffInput v-model="text" placeholder="Text input" />
    <TuffInput v-model="password" type="password" placeholder="Password input" />
    <TuffInput v-model="content" type="textarea" placeholder="Multiline text" :rows="4" />
  </template>
---
:::

### Readonly and Disabled
:::TuffDemoWrapper{demo="InputReadonlyDisabledDemo" code-lang="vue"}
---
code: |
  <template>
    <TuffInput v-model="readonlyValue" readonly placeholder="Readonly" />
    <TuffInput v-model="disabledValue" disabled placeholder="Disabled" />
  </template>
---
:::

### Clearable
`clearable` shows a focusable clear button while there is a value; it hides when disabled or readonly.
:::TuffDemoWrapper{demo="InputClearableDemo" code-lang="vue"}
---
code: |
  <template>
    <TuffInput v-model="clearableValue" clearable placeholder="Clearable" />
  </template>
---
:::

### Prefix and Suffix
The `prefix` / `suffix` slots take precedence over `prefixIcon` / `suffixIcon`.
:::TuffDemoWrapper{demo="InputPrefixSuffixDemo" code-lang="vue"}
---
code: |
  <template>
    <TuffInput v-model="keyword" placeholder="Search">
      <template #prefix>
        <TxIcon icon="i-carbon-search" />
      </template>
    </TuffInput>
    <TuffInput v-model="user" placeholder="User">
      <template #suffix>
        <TxIcon icon="i-carbon-user" />
      </template>
    </TuffInput>
  </template>
---
:::

### Best Practices

- Show focus only through the subtle border and shadow shift; don't add a second focus ring around the wrapper unless the surrounding form requires one.
- Keep search states light for toolbars and list filters; use `TxSearchInput` when Enter search or debounced remote search is part of the contract.
- With `type="number"` the value is a number or `''`; normalize it in your schema before persisting.
- Give each field's icons one path: the slot or the icon prop.

## API Reference

### Props

:::TuffPropsTable
---
rows:
  - name: modelValue / v-model
    description: 'The input value.'
    type: 'string | number'
    default: "''"
  - name: placeholder
    description: 'Placeholder text.'
    type: 'string'
    default: "''"
  - name: type
    description: 'Input type; `textarea` renders a multiline field.'
    type: "'text' | 'password' | 'textarea' | 'date' | 'email' | 'number'"
    default: "'text'"
  - name: disabled
    description: 'Disables input.'
    type: 'boolean'
    default: 'false'
  - name: readonly
    description: 'Makes the field read-only.'
    type: 'boolean'
    default: 'false'
  - name: clearable
    description: 'Shows a clear button while there is a value.'
    type: 'boolean'
    default: 'false'
  - name: rows
    description: 'Textarea rows; `textarea` only.'
    type: 'number'
    default: '3'
  - name: prefixIcon
    description: 'Prefix icon class; the `prefix` slot wins.'
    type: 'string'
    default: "''"
  - name: suffixIcon
    description: 'Suffix icon class; the `suffix` slot wins.'
    type: 'string'
    default: "''"
  - name: capsLockText
    description: 'Text of the CapsLock warning on password fields, announced via `role="status"`.'
    type: 'string'
    default: "'CapsLock is on'"
---
:::

### Events

:::TuffPropsTable
---
rows:
  - name: update:modelValue
    description: 'Fires when the value changes.'
    type: '(value: string | number) => void'
    default: '-'
  - name: input
    description: 'Fires on input, with the same value as `update:modelValue`.'
    type: '(value: string | number) => void'
    default: '-'
  - name: focus
    description: 'Fires when the native control gains focus.'
    type: '(event: FocusEvent) => void'
    default: '-'
  - name: blur
    description: 'Fires when the native control loses focus.'
    type: '(event: FocusEvent) => void'
    default: '-'
  - name: clear
    description: 'Fires after a clear.'
    type: '() => void'
    default: '-'
---
:::

### Slots

:::TuffPropsTable
---
rows:
  - name: prefix
    description: 'Prefix content, replacing `prefixIcon`.'
    type: '-'
    default: '-'
  - name: suffix
    description: 'Suffix content, replacing `suffixIcon`.'
    type: '-'
    default: '-'
---
:::

### Exposed Methods

:::TuffPropsTable
---
rows:
  - name: focus
    description: 'Focuses the native control.'
    type: '() => void'
    default: '-'
  - name: blur
    description: 'Blurs the native control.'
    type: '() => void'
    default: '-'
  - name: clear
    description: 'Clears the value; no-op when disabled or readonly.'
    type: '() => void'
    default: '-'
  - name: setValue
    description: 'Sets the value and emits `update:modelValue` and `input`.'
    type: '(value: string) => void'
    default: '-'
  - name: getValue
    description: 'Returns the current value.'
    type: '() => string | number'
    default: '-'
  - name: inputEl
    description: 'Ref to the native input or textarea.'
    type: 'HTMLInputElement | HTMLTextAreaElement | null'
    default: '-'
---
:::

## Migration from FlatInput

`FlatInput` / `TxFlatInput` is retired; `TxInput` covers it:

| FlatInput | TxInput |
|-----------|---------|
| `area` | `type="textarea"` |
| `password` | `type="password"` |
| `icon="i-…"` | `prefix-icon="i-…"` |
| default slot (prefix content) | `#prefix` slot |
| `disabled` / `readonly` | `disabled` / `readonly` |
| `nonWin` | dropped; the Windows-underline visual is gone |

`update:modelValue` keeps its contract; `focus` / `blur` now come from the native input element.

## Overview

- `type="number"` emits `Number(value)` for non-empty input and `''` when cleared.
- Clearing emits `update:modelValue`, `input`, then `clear`; it is a no-op when disabled or readonly.
- `class` / `style` stay on the wrapper; all other attrs go to the native `input` / `textarea`.

## Technologies

- `index.ts` exports both `TuffInput` and `TxInput`.
- Source: `packages/tuffex/packages/components/src/input/`.

<TuffDocSourceLink />
