@akhatmirzo/ui

Input

A single-line text field with icons, prefix/suffix, a clear button and a password toggle.

Import

import { Input } from '@akhatmirzo/ui';

When to use

  • For short, single-line values — names, emails, search, amounts. For multi-line text, use Textarea.
  • Always inside a Field — the label, hint and error get wired up for you. For a field without a visible label (like search), pass aria-label.
  • For strict formats like phone numbers, card numbers and dates, MaskedInput is a better fit.
  • A placeholder is not a label — it disappears as soon as you type. Use it for an example value: "90 123 45 67".

Sizes

32, 40 (default) and 48px — the same as Button, so they line up in a row.

Icons, prefix and suffix

leftIcon / rightIcon are decorative icons (aria-hidden). prefix / suffix are fixed text inside the field, set off by a divider: a country code, a currency, a domain.

+998
so'm
https://.uz

Clearing (clearable)

With clearable, a ✕ button appears whenever the field has a value. Esc clears it too. Clearing fires a regular input event, so onChange runs in controlled mode, followed by onClear.

Qiymat: Samarqand

Password

With type="password", a show/hide button appears on the right automatically.

Kamida 8 ta belgi

States

Error (invalid), disabled (disabled) and read-only (readOnly). Inside a Field, passing error turns on invalid automatically.

With Field

Tasdiqlash kodi SMS orqali keladi

+998

Email manzil noto'g'ri

Props

Input accepts every other <input> attribute (type, name, placeholder, inputMode, autoComplete, onChange ...), and ref points to the inner <input>. className goes to the outer container; use inputClassName for the inner element.

PropTypeDefaultDescription
size'sm' | 'md' | 'lg''md'Height: 32 / 40 / 48px
invalidboolean—Error state (automatic inside a Field with an error)
leftIconReactNode—Icon on the left
rightIconReactNode—Icon on the right
prefixReactNode—Text on the left with a divider (e.g. "+998")
suffixReactNode—Text on the right with a divider (e.g. "so'm")
clearablebooleanfalseShows ✕ when there is a value; Esc clears too
onClear() => void—Called after clearing
labels{ clear?: string; showPassword?: string; hidePassword?: string }{ clear: 'Tozalash', showPassword: "Parolni ko'rsatish", hidePassword: 'Parolni yashirish' }aria-label text for the built-in buttons
inputClassNamestring—Class for the inner <input>
typestring'text''password' adds the show/hide button
readOnlybooleanfalseRead-only; muted background, no clear button

Data attributes

Set on the outer container (data-slot="input"):

AttributeValue
data-sizesm · md · lg
data-invalidPresent when invalid
data-disabledPresent when disabled
data-readonlyPresent when readOnly

Accessibility

  • Native <input> — browser autofill, validation and keyboard behavior all keep working.
  • With Field, id, aria-describedby, aria-invalid and aria-required are wired up automatically.
  • The focus ring lives on the container (:focus-within), so icons and prefixes stay inside the ring.
  • Esc clears the value (only with clearable and a non-empty field). On an empty field the event bubbles up — closing a Dialog, for example.
  • The clear button is not in the Tab order (tabIndex={-1}); Esc covers it from the keyboard. The password toggle is focusable and its aria-label follows its state.
  • Icons are aria-hidden — if one carries meaning, put it in the label or aria-label.

On this page