HextaUI

Input

Üç boyutlu, geçersiz ve salt okunur durumları, yerel doğrulama stilleri ve telefonların asla yakınlaştırmaması için 16px dokunmatik yazı tipi olan bir metin girişi.

import { Input } from "@/components/ui/input"
import { Label } from "@/components/ui/label"

export function InputDemo() {
  return (
    <div className="flex w-full max-w-sm flex-col gap-2">
      <Label htmlFor="input-demo-email">Email</Label>
      <Input
        id="input-demo-email"
        type="email"
        autoComplete="email"
        placeholder="[email protected]"
      />
    </div>
  )
}
pnpm dlx shadcn@latest add https://hextaui.com/r/input.json

Bileşeni, HextaUI tema token'larını ve bileşenin bağımlı olduğu tüm HextaUI bileşenlerini ekler.

import { Input } from "@/components/ui/input"
<label htmlFor="email">Email</label>
<Input id="email" type="email" placeholder="[email protected]" />

Boyutlar

sm, default ve lg düğme yükseklikleriyle eşleşir; böylece aynı boyuttaki bir girdi ve bir düğme bir satırda hizalanır.

import { Input } from "@/components/ui/input"

export function InputSizes() {
  return (
    <div className="flex w-full max-w-sm flex-col gap-3">
      <Input size="sm" aria-label="Small" placeholder="Small" />
      <Input aria-label="Default" placeholder="Default" />
      <Input size="lg" aria-label="Large" placeholder="Large" />
    </div>
  )
}

Açıklamayla

Ekran okuyucuların etiketten sonra okuması için aria-describedby'ı yardımcı metne yöneltin.

import { Input } from "@/components/ui/input"
import { Label } from "@/components/ui/label"

export function InputDescription() {
  return (
    <div className="flex w-full max-w-sm flex-col gap-2">
      <Label htmlFor="input-username">Username</Label>
      <Input
        id="input-username"
        autoComplete="username"
        placeholder="preet"
        aria-describedby="input-username-description"
      />
      <p
        id="input-username-description"
        className="text-sm text-muted-foreground"
      >
        Shown on your profile and in mentions.
      </p>
    </div>
  )
}

Geçersiz

aria-invalid kenarı ve odak halkasını kırmızıya çevirir. Mesajın yalnızca renklendirilmesi değil duyurulması için onu aria-describedby ile bağlayın.

import { Input } from "@/components/ui/input"
import { Label } from "@/components/ui/label"

export function InputInvalid() {
  return (
    <div className="flex w-full max-w-sm flex-col gap-2">
      <Label htmlFor="input-invalid">Email</Label>
      <Input
        id="input-invalid"
        type="email"
        defaultValue="preet@"
        aria-invalid
        aria-describedby="input-invalid-error"
      />
      <p id="input-invalid-error" className="text-sm text-destructive">
        Enter a full email address, like [email protected].
      </p>
    </div>
  )
}

Yerel doğrulama

required, type="email" veya pattern olan alanlar yalnızca birisi içlerine yazdıktan veya göndermeyi denedikten sonra kırmızıya döner; ilk render'da asla. Bir alanı geçersiz bulan bir gönderim onu bir kez sarsar; böylece göz düzeltilmesi gerekene gider. Siz yazarken veya Tab ile gezinirken asla sarsılmaz. Görmek için boş formu gönderin.

import { Button } from "@/components/ui/button"
import { Input } from "@/components/ui/input"
import { Label } from "@/components/ui/label"

export function InputNativeValidation() {
  return (
    <form className="flex w-full max-w-sm flex-col gap-3">
      <div className="flex flex-col gap-2">
        <Label htmlFor="input-native-email">Email</Label>
        <Input
          id="input-native-email"
          name="email"
          type="email"
          required
          placeholder="[email protected]"
        />
      </div>
      <div className="flex flex-col gap-2">
        <Label htmlFor="input-native-code">Invite code</Label>
        <Input
          id="input-native-code"
          name="code"
          required
          pattern="[A-Z]{4}-[0-9]{4}"
          placeholder="ABCD-1234"
        />
      </div>
      <Button type="submit" className="self-start">
        Join
      </Button>
    </form>
  )
}

Devre dışı

Devre dışı bir girdiye odaklanılamaz, düzenlenemez veya formla birlikte gönderilemez.

import { Input } from "@/components/ui/input"
import { Label } from "@/components/ui/label"

export function InputDisabled() {
  return (
    <div className="flex w-full max-w-sm flex-col gap-2">
      <Label htmlFor="input-disabled">Workspace</Label>
      <Input id="input-disabled" defaultValue="Acme Inc." disabled />
    </div>
  )
}

Salt okunur

readOnly değeri odaklanabilir, seçilebilir ve gönderilir tutar; düzenlenebilir görünmemesi için soluk bir yüzeye sahiptir. Kişilerin kopyalaması gereken değerler için disabled yerine bunu tercih edin.

import { Input } from "@/components/ui/input"
import { Label } from "@/components/ui/label"

export function InputReadOnly() {
  return (
    <div className="flex w-full max-w-sm flex-col gap-2">
      <Label htmlFor="input-read-only">API key</Label>
      <Input id="input-read-only" readOnly defaultValue="sk_live_51H8a…f2Qz" />
    </div>
  )
}

Dosya

type="file" aynı çerçeveyi alır; tarayıcının düğmesi düz metin olarak yeniden stillenir.

import { Input } from "@/components/ui/input"
import { Label } from "@/components/ui/label"

export function InputFile() {
  return (
    <div className="flex w-full max-w-sm flex-col gap-2">
      <Label htmlFor="input-file">Avatar</Label>
      <Input id="input-file" type="file" accept="image/*" />
    </div>
  )
}

Input türleri

Parola, sayı, arama, tarih ve saat tek bir yüksekliği ve çerçeveyi paylaşır. Koyu modda tarayıcının seçicileri ve spinner'ları da koyuya geçer.

import { Input } from "@/components/ui/input"

export function InputTypes() {
  return (
    <div className="grid w-full max-w-sm gap-3">
      <Input type="password" aria-label="Password" defaultValue="hunter2" />
      <Input type="number" aria-label="Seats" defaultValue={12} min={1} />
      <Input type="search" aria-label="Search" placeholder="Search…" />
      <Input type="date" aria-label="Start date" defaultValue="2026-10-03" />
      <Input type="time" aria-label="Start time" defaultValue="09:30" />
    </div>
  )
}

Kontrollü

onValueChange dizeyi doğrudan verir; böylece açılacak bir event.target.value yoktur. onChange de çalışmaya devam eder.

"use client"

import * as React from "react"

import { Input } from "@/components/ui/input"
import { Label } from "@/components/ui/label"

const limit = 32

export function InputControlled() {
  const [value, setValue] = React.useState("Quarterly planning")

  return (
    <div className="flex w-full max-w-sm flex-col gap-2">
      <Label htmlFor="input-controlled">Project name</Label>
      <Input
        id="input-controlled"
        value={value}
        maxLength={limit}
        onValueChange={setValue}
        aria-describedby="input-controlled-count"
      />
      <p
        id="input-controlled-count"
        className="text-end text-sm text-muted-foreground tabular-nums"
      >
        {value.length}/{limit}
      </p>
    </div>
  )
}

Düğmeyle

Boşlukla yan yana veya bir <ButtonGroup /> içinde tek bir kontrol olacak şekilde birleşik; girdi kalan genişliği alır.

import { Button } from "@/components/ui/button"
import { ButtonGroup } from "@/components/ui/button-group"
import { Input } from "@/components/ui/input"

export function InputWithButton() {
  return (
    <form className="flex w-full max-w-sm flex-col gap-4">
      <div className="flex gap-2">
        <Input type="email" aria-label="Email" placeholder="[email protected]" />
        <Button type="submit">Subscribe</Button>
      </div>
      <ButtonGroup className="w-full">
        <Input type="search" aria-label="Search" placeholder="Search…" />
        <Button variant="outline">Search</Button>
      </ButtonGroup>
    </form>
  )
}

Grid

Girdiler kapsayıcılarını doldurur; bu yüzden onları bir grid içine yerleştirin. Uzun değerlerin bir sütunu genişletememesi için grid hücrelerine min-w-0 verin.

import { Input } from "@/components/ui/input"
import { Label } from "@/components/ui/label"

export function InputGrid() {
  return (
    <div className="grid w-full max-w-sm grid-cols-2 gap-3">
      <div className="flex min-w-0 flex-col gap-2">
        <Label htmlFor="input-first-name">First name</Label>
        <Input id="input-first-name" autoComplete="given-name" />
      </div>
      <div className="flex min-w-0 flex-col gap-2">
        <Label htmlFor="input-last-name">Last name</Label>
        <Input id="input-last-name" autoComplete="family-name" />
      </div>
    </div>
  )
}

Uzun içerik

Uzun değerler alanın içinde kayar ve uzun placeholder'lar düzeni genişletmeden kesilir.

import { Input } from "@/components/ui/input"

export function InputLongContent() {
  return (
    <div className="flex w-full max-w-56 flex-col gap-3">
      <Input
        aria-label="URL"
        defaultValue="https://example.com/a/really/long/url/without/any/spaces/at/all"
      />
      <Input
        aria-label="Note"
        placeholder="A placeholder that is far too long to fit in this field"
      />
    </div>
  )
}

Sağdan sola

Metin, imleç ve dolgu yönü izler. Arapça bir formdaki e-posta adresi gibi soldan sağa değerler tutan alanlarda dir="auto" kullanın.

import { Input } from "@/components/ui/input"
import { Label } from "@/components/ui/label"

export function InputRtl() {
  return (
    <div dir="rtl" className="flex w-full max-w-sm flex-col gap-2">
      <Label htmlFor="input-rtl">البريد الإلكتروني</Label>
      <Input id="input-rtl" placeholder="[email protected]" dir="auto" />
      <Input aria-label="الاسم" placeholder="اكتب اسمك" />
    </div>
  )
}
  • Her girdinin bir adı olmalıdır. htmlFor ile bir <label> kullanın veya görünür etiket yoksa aria-label kullanın. Placeholder bir etiket değildir.
  • Yardımcı metni ve hata metnini aria-describedby ile bağlayın ve aria-invalid'i yalnızca gösterilecek bir hata olduğunda ayarlayın.
  • Dokunmatik ekranlarda metin en az 16px'tir; böylece girdi odaklandığında iOS Safari sayfayı yakınlaştırmaz.
  • Bir Base UI Field içinde etiket, açıklama, hata ve geçerlilik sizin için bağlanır.

Base UI input üzerine kuruludur. Her yerel input niteliğini kabul eder.

PropTürVarsayılan
sizeDüğmelerle eşleşen yükseklik ve dolgu.
"sm" | "default" | "lg""default"
htmlSizeYerel size niteliği; size variant olduğu için yeniden adlandırılmıştır.
number–
value
string | number | string[]–
defaultValue
string | number | string[]–
onValueChangeHer değişimde yeni değerle çağrılır.
(value: string, details) => void–
type
string"text"
disabled
booleanfalse
readOnly
booleanfalse
aria-invalidGeçersiz kenarı ve odak halkasını gösterir.
boolean–
className
string | (state) => string–
shakeBir form gönderimi bu girdiyi geçersiz bulduğunda bir kez sarsılır. Yerel doğrulama, Base UI Field ve aria-invalid ayarlayan kütüphanelerle çalışır. Azaltılmış harekette atlanır.
booleantrue
render
ReactElement | (props, state) => ReactElement<input>
ÖznitelikAçıklama
data-slot="input"CSS'te girdiyi hedefleyin.
data-sizeGeçerli boyut.
data-shakeBaşarısız bir gönderimden sonra girdi sarsılırken bulunur.
data-disabledGirdi devre dışı olduğunda bulunur.
data-invalidÇevreleyen Field geçersiz olduğunda bulunur. aria-invalid gibi stillenir.
data-validÇevreleyen Field geçerli olduğunda bulunur.
data-touchedBir Field içinde, girdi bir kez odağı kaybettikten sonra bulunur.
data-dirtyBir Field içinde, değer değiştikten sonra bulunur.
data-filledBir Field içinde, girdinin bir değeri olduğunda bulunur.
data-focusedBir Field içinde, odaktayken bulunur.

Girdinin arkasındaki sınıf adları; yerel bir <select> veya <textarea> gibi başka bir öğeyi eşleşecek şekilde stillemek için. { size } ile çağırın.

<InputGroupCount /> ve <FieldCounter /> arkasındaki karakter sayacı. Alanı sizin için okuyan bu parçaları kullanın. Bunu yalnızca uzunluğu kendiniz izlediğinizde kullanın.

PropTürVarsayılan
lengthZorunlu.
number–
maxLength
number | null–
threshold
number10% of maxLength, at most 20
announcement
(remaining: number) => string–
ÖznitelikAçıklama
data-slot="input-count"CSS'te sayacı hedefleyin.
data-state="near" | "limit"Eşik içinde ve sınırda bulunur.

Kullanıldığı bloklar

Input üzerine kurulan bloklar.