Przejdź do treści

Input

Stabilny

Jednowierszowe pole tekstowe na imiona, adresy e-mail, liczby i wyszukiwane frazy — zawsze w parze z widoczną etykietą.

Instalacja

$ pnpm dlx shadcn@latest add https://www.prfct.dev/r/input.json

Użycie

import { Field, FieldLabel } from "@/components/ui/field"
import { Input } from "@/components/ui/input"
<Field>
  <FieldLabel htmlFor="email">Email</FieldLabel>
  <Input id="email" type="email" placeholder="you@company.com" />
</Field>

Samo pole nie ma widocznej nazwy. W formularzach zawsze łącz je z komponentem Field, który spójnie rozmieszcza etykietę, opis i komunikat o błędzie.

Przykłady

Rozmiary

sm, defaultlg mają te same wysokości co ButtonSelect — 32, 36 i 40 px — więc pole i jego akcja zawsze wyrównują się w jednym wierszu.

Typy

prfct stylizuje każdy natywny typ pola. Dobierz właściwe typeinputMode, żeby klawiatura na telefonie pasowała do danych, i ustaw autoComplete, żeby przeglądarki i menedżery haseł mogły wypełnić pole.

Stan błędu

Ustaw aria-invalid na polu i data-invalid na jego Field, a problem wyjaśnij w FieldError powiązanym przez aria-describedby. Obramowanie robi się czerwone, a poświata fokusu razem z nim, ale znaczenie niosą komunikat i jego ikona — nigdy sam kolor.

Wyłączone i tylko do odczytu

Użyj disabled, gdy wartości nie da się w tej chwili zmienić: fokus klawiatury pomija takie pole, a jego wartość nie trafia do wysyłanego formularza. Użyj readOnly, gdy ktoś musi zobaczyć, zaznaczyć lub skopiować wartość, której nie może edytować — takie pole nadal przyjmuje fokus i jest wysyłane z formularzem.

Plik

Pola plików dostają stonowany, obramowany przycisk wyboru, który pasuje do pola. Przeciąganie i upuszczanie albo wiele plików z podglądem buduj na tej podstawie, zamiast zastępować natywne pole — obsługę klawiatury i technologii wspomagających dostajesz wtedy za darmo.

Z przyciskiem

Wysokości są wspólne, więc pole i przycisk stoją obok siebie bez żadnych poprawek. Jeśli nie ma widocznej etykiety, nadaj polu aria-label.

Tryb kontrolowany

Przekaż valueonChange, żeby budować interfejs na podstawie tego, co ktoś wpisuje — tutaj licznik znaków i podgląd adresu URL na żywo. Jeśli wartość jest potrzebna dopiero przy wysyłaniu, wybierz pole niekontrolowane z defaultValue.

Wytyczne

Kiedy używać

  • Krótki, dowolny tekst w jednej linii: imiona i nazwiska, adresy e-mail, adresy URL, kwoty, wyszukiwane frazy.
  • Wartości natywnego typu, który przeglądarka już rozumie: email, number, date, url, password.

Kiedy nie używać

  • Akapity i tekst wielowierszowy — użyj komponentu Textarea.
  • Wybór ze znanej listy — sięgnij po Select, a przy długich listach po Combobox.
  • Kody o stałej długości, np. do 2FA — do tego służy Input OTP.
  • Ikony, jednostki lub przyciski wewnątrz pola — wybierz Input Group.

Etykiety, nie placeholdery

Placeholder znika, gdy tylko ktoś zacznie pisać, więc nie może przechowywać nazwy pola ani instrukcji. Nazwę umieść w widocznej etykiecie, instrukcje w opisie, a placeholdera używaj — jeśli w ogóle — do pokazania przykładu oczekiwanego formatu.

Dobrze.Stała etykieta nazywa pole; placeholder pokazuje tylko przykład.
Źle.Placeholder jako jedyna etykieta znika, gdy tylko zaczniesz pisać.

Szerokość to wskazówka

Szerokość pola podpowiada, ile trzeba wpisać. Dopasuj pola do oczekiwanej treści — kod pocztowy powinien wyglądać na krótszy niż adres — zamiast rozciągać każde pole na całą szerokość kontenera.

Dobrze.Szerokości odpowiadają oczekiwanej długości każdej wartości.
Źle.Jednakowe pola na całą szerokość nie zdradzają, które odpowiedzi są krótkie.

Waliduj we właściwym momencie

Waliduj przy wysyłaniu formularza i wtedy, gdy pole traci fokus — nie przy każdym naciśnięciu klawisza, bo wtedy wytykasz ludziom błąd, zanim skończą pisać. Gdy pole jest już oznaczone jako błędne, sprawdzaj je ponownie w trakcie pisania, żeby komunikat zniknął, gdy tylko błąd zostanie poprawiony. Pełny wzorzec opisuje strona Field.

Dostępność

Input renderuje natywny <input> przez Base UI, więc zachowuje wszystko, co zapewnia przeglądarka — autouzupełnianie, sprawdzanie pisowni, kompozycję IME, wysyłanie formularza — i działa wewnątrz FieldForm z Base UI, gdy potrzebujesz wbudowanej walidacji.

  • Nazwij każde pole. Powiąż widoczną etykietę przez htmlFor/id, a polom bez widocznej etykiety nadaj aria-label.
  • Opisuj i wyjaśniaj. Powiąż opisy i błędy przez aria-describedby; ustawiaj aria-invalid, dopóki wartość jest błędna.
  • Określ cel pola. Ustaw autoComplete przy danych osobowych, takich jak name, emailtel (WCAG 1.3.5).
  • Kontrast. Obramowanie pola używa tokenu input, który spełnia wymóg kontrastu elementów nietekstowych — 3:1 względem strony (WCAG 1.4.11). Tekst placeholdera używa muted-foreground o kontraście co najmniej 4,5:1.
  • Bez powiększania przy fokusie. Poniżej breakpointu md tekst ma 16 px, żeby Safari na iOS nie powiększało strony, gdy pole dostaje fokus; na większych ekranach ma 14 px.
KlawiszDziałanie
Tab
Przenosi fokus do pola. Fokus widać jako obramowanie w kolorze marki z delikatną poświatą.
ShiftTab
Przenosi fokus do poprzedniego elementu, który może go przyjąć.
Enter
Wysyła formularz, w którym znajduje się pole.

Dokumentacja API

Input

Renderuje element <input>. Przyjmuje wszystkie natywne atrybuty pola input i propsy komponentu Input z Base UI. Wariant size z prfct zastępuje natywny atrybut size.

PropTypDomyślnie
size

Wysokość i poziomy odstęp wewnętrzny: 32, 36 lub 40 px, tak jak w Button i Select.

"sm" | "default" | "lg""default"
type

Dowolny natywny typ pola: email, password, number, date, url, file, search…

string"text"
value

Wartość kontrolowana. Łącz z onChange.

string | numberBrak wartości domyślnej
defaultValue

Wartość początkowa pola niekontrolowanego.

string | numberBrak wartości domyślnej
disabled

Blokuje interakcję, usuwa pole z kolejności tabulacji i z wysyłanych danych formularza.

booleanfalse
readOnly

Blokuje edycję, ale pole nadal przyjmuje fokus, jego wartość da się zaznaczyć i trafia do wysyłanego formularza.

booleanfalse
aria-invalid

Oznacza wartość jako błędną: czerwone obramowanie i czerwona poświata fokusu. Łącz z FieldError.

booleanBrak wartości domyślnej

inputVariants

Generator klas jest eksportowany dla elementów, które mają wyglądać jak pole — na przykład wartości tylko do odczytu renderowanej jako <div>.

import { inputVariants } from "@/components/ui/input"
import { cn } from "@/lib/utils"

<div className={cn(inputVariants({ size: "sm" }), "flex items-center font-mono")}>
  ws_8f3k29d1
</div>