Перейти к содержимому

Поле ввода

Однострочное текстовое поле для ввода логина, строки поиска и форм оформления заказа — с толстой рамкой и резкой тенью в стиле «необрутализм».

import {
  Field,
  FieldDescription,

Input захватывает одну строку текста — имена, email, поисковые запросы. Построен на компоненте Base UI Input, тонкой обёртке над нативным <input>, и оформлен по рецепту необрутализма: толстая рамка, жёсткая тень и жирный шрифт с высококонтрастным focus outline.

Когда это пригодится:

  • Auth и регистрация — email, username и password в паре с Field и FieldLabel.
  • Поисковые строки — рядом с Button или с иконками через InputGroup.
  • Checkout и настройки — адреса, номера карт и поля профиля в FieldGroup.

Установка

pnpm dlx shadcn@latest add https://neobrutalism.com/r/base/input.json
npx shadcn@latest add https://neobrutalism.com/r/base/input.json
yarn dlx shadcn@latest add https://neobrutalism.com/r/base/input.json
bunx --bun shadcn@latest add https://neobrutalism.com/r/base/input.json

Скопируйте и вставьте следующий код в свой проект.

components/ui/input.tsx
import * as React from "react"

import { cn } from "@/lib/utils"

function Input({ className, type, ...props }: React.ComponentProps<"input">) {
  return (
    <input
      type={type}
      data-slot="input"
      className={cn(
        "h-8 w-full min-w-0 rounded border-2 bg-input px-3 py-2 text-sm shadow-sm transition-colors outline-none file:inline-flex file:h-6 file:border-0 file:bg-transparent file:text-sm file:font-medium file:text-foreground placeholder:text-muted-foreground focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-primary disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50 aria-invalid:border-destructive",
        className
      )}
      {...props}
    />
  )
}

export { Input }

Обновите пути импорта в соответствии с настройками вашего проекта.

Использование

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

Примеры

Базовый

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

export function InputBasic() {

Field

Используйте Field, FieldLabel и FieldDescription, чтобы создать поле с меткой и описанием.

import {
  Field,
  FieldDescription,

Field Group

Используйте FieldGroup, чтобы показать несколько блоков Field и создавать формы.

import { Button } from "@/components/ui/button"
import {
  Field,

Отключённое

Используйте проп disabled, чтобы отключить поле. Чтобы стилизовать отключённое состояние, добавьте атрибут data-disabled к компоненту Field.

import {
  Field,
  FieldDescription,

Невалидное

Используйте проп aria-invalid, чтобы пометить поле как невалидное. Чтобы стилизовать невалидное состояние, добавьте атрибут data-invalid к компоненту Field.

import {
  Field,
  FieldDescription,

Файл

Используйте проп type="file", чтобы создать поле выбора файла.

import {
  Field,
  FieldDescription,

Встроенное

Используйте Field с пропом orientation="horizontal", чтобы создать встроенное поле. Сочетайте с Button, чтобы создать поле поиска с кнопкой.

import { Button } from "@/components/ui/button"
import { Field } from "@/components/ui/field"
import { Input } from "@/components/ui/input"

Сетка

Используйте сеточную раскладку, чтобы разместить несколько полей рядом.

import { Field, FieldGroup, FieldLabel } from "@/components/ui/field"
import { Input } from "@/components/ui/input"

Обязательное

Используйте атрибут required, чтобы обозначить обязательные поля.

import {
  Field,
  FieldDescription,

Badge

Используйте Badge в метке, чтобы выделить рекомендованное поле.

import { Badge } from "@/components/ui/badge"
import { Field, FieldLabel } from "@/components/ui/field"
import { Input } from "@/components/ui/input"

Input Group

Чтобы добавить иконки, текст или кнопки внутрь поля, используйте компонент InputGroup. Больше примеров — в компоненте Input Group.

import { InfoIcon } from "lucide-react"

import { Field, FieldLabel } from "@/components/ui/field"

Button Group

Чтобы добавить кнопки к полю, используйте компонент ButtonGroup. Больше примеров — в компоненте Button Group.

import { Button } from "@/components/ui/button"
import { ButtonGroup } from "@/components/ui/button-group"
import { Field, FieldLabel } from "@/components/ui/field"

Форма

Полный пример формы с несколькими полями, select и кнопкой.

import { Button } from "@/components/ui/button"
import {
  Field,

RTL

Чтобы включить поддержку RTL в Neobrutalism, см. руководство по настройке RTL.

"use client"

import * as React from "react"

Доступность

Input рендерит нативный <input>, поэтому редактирование с клавиатуры, фокус и отправка формы не требуют ARIA. На вас остаётся следующее:

  • Labelите каждый input. Свяжите с FieldLabel (или <label htmlFor>) — placeholder не label: он исчезает при вводе и объявляется ненадёжно.
  • Свяжите текст ошибки. Ставьте aria-invalid на input и указывайте aria-describedby на id вашего FieldError или FieldDescription, чтобы программы чтения с экрана читали сообщение вместе с полем.
  • Выбирайте правильные type и autocomplete. type="email" плюс autocomplete="email" даёт нужную мобильную клавиатуру и автозаполнение.