New Research: Supply Chain Attack on Axios Pulls Malicious Dependency from npm.Details →
Socket
Book a DemoSign in
Socket

finform

Package Overview
Dependencies
Maintainers
1
Versions
389
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

finform

Пакет для управления инпутами с поддержкой валидации и отображения ошибок в попапе.

latest
Source
npmnpm
Version
1.6.44
Version published
Weekly downloads
139
-40.85%
Maintainers
1
Weekly downloads
 
Created
Source

Документация по компонентам формы

Пакет для управления инпутами с поддержкой валидации и отображения ошибок в попапе.

Содержание

Установка и импорт

Импорт компонентов

import { 
  InputContainer,
  Input,
  TextArea,
  NumberInput,
  MaskedInput,
  Select,
  MultiSelect,
  Search,
  MultipleSearch,
  GroupSelect,
  GroupSearch,
  GroupSelectWithSearch,
  DateInput,
  DateTimeInput,
  FileInput,
  Checkbox,
  RoundCheckbox
} from 'finform';

Важно: Компоненты Checkbox и RoundCheckbox не требуют обертки в InputContainer.

Типы данных

Option

Интерфейс для опций в выпадающих списках и поиске:

interface Option {
  id: string | number;  // Уникальный идентификатор опции
  name: string;          // Отображаемое название опции
}

GroupOption

Интерфейс для группированных опций:

interface GroupOption {
  id: string | number;   // Уникальный идентификатор группы
  name: string;          // Название группы
  items: Option[];       // Массив опций в группе
}

Основные концепции

Все компоненты формы должны быть обернуты в InputContainer, который обеспечивает:

  • Отображение placeholder'а
  • Визуальное оформление состояния фокуса
  • Отображение ошибок в попапе при наведении на иконку ошибки
  • Иконки и дополнительные элементы управления

Структура использования

import { InputContainer, Input } from 'finform';

<InputContainer error={errorMessage}>
  <Input
    id="field-id"
    placeholder="Введите значение"
    value={value}
    onChange={setValue}
  />
</InputContainer>

InputContainer

Основной контейнер для всех инпутов. Обеспечивает единообразное оформление и обработку ошибок.

Props

ПропТипПо умолчаниюОписание
childrenReact.ReactNode-Единственный дочерний компонент (Input, Select, TextArea и т.д.)
classNamestring''Дополнительные CSS классы
styleReact.CSSProperties{}Инлайн стили
errorstring | nullnullТекст ошибки для отображения в попапе

Важно: error должен быть строкой (не массивом) для корректного отображения в попапе. При наведении на иконку ошибки появляется попап с текстом ошибки.

Компоненты

Текстовые инпуты

Input — базовый текстовый инпут

Input

import { InputContainer, Input } from 'finform';

const [value, setValue] = useState('');
const [error, setError] = useState<string | null>(null);

<InputContainer error={error}>
  <Input
    id="username"
    placeholder="Имя пользователя"
    value={value}
    onChange={setValue}
  />
</InputContainer>

Props

ПропТипПо умолчаниюОписание
idstring-Уникальный идентификатор поля
namestring-Имя поля для формы
valuestring | number | null-Значение инпута
onChange(value: string) => void-Обработчик изменения значения
placeholderstring-Текст placeholder'а
disabledbooleanfalseОтключение поля
classNamestring''Дополнительные CSS классы
styleReact.CSSProperties{}Инлайн стили
typestring'text'Тип HTML инпута (text, email, password и т.д.)
autoCompletestring'off'Автозаполнение браузера
iconbooleantrueПоказывать ли иконку в InputContainer
onKeyDown(e: KeyboardEvent) => void-Обработчик нажатия клавиш
onBlur(e: FocusEvent) => void-Обработчик потери фокуса
onClick(e: MouseEvent) => void-Обработчик клика
requiredbooleanfalseОбязательное поле

Примечание: Пропсы focused, setFocused, error передаются автоматически через InputContainer и не должны указываться вручную.

TextArea — многострочный текстовый инпут

TextArea

import { InputContainer, TextArea } from 'finform';

const [value, setValue] = useState('');
const [error, setError] = useState<string | null>(null);

<InputContainer error={error}>
  <TextArea
    id="description"
    placeholder="Описание"
    value={value}
    onChange={setValue}
    rows={5}
    autoResize={true}
  />
</InputContainer>

Props

Все пропсы из Input, плюс:

ПропТипПо умолчаниюОписание
rowsnumber3Количество строк
autoResizebooleantrueАвтоматическое изменение высоты при вводе
disableResizebooleanfalseОтключить возможность ручного изменения размера

Особенности:

  • При autoResize={true} высота автоматически подстраивается под содержимое
  • При disableResize={true} отключается возможность ручного изменения размера через UI
NumberInput — инпут для числовых значений

NumberInput

import { InputContainer, NumberInput } from 'finform';

const [value, setValue] = useState<number | null>(null);
const [error, setError] = useState<string | null>(null);

<InputContainer error={error}>
  <NumberInput
    id="amount"
    placeholder="Сумма"
    value={value}
    onChange={setValue}
    min={0}
    max={1000000}
    decimals={2}
  />
</InputContainer>

Props

Все пропсы из Input, плюс:

ПропТипПо умолчаниюОписание
minnumber | falsefalseМинимальное значение
maxnumber | falsefalseМаксимальное значение
decimalsnumber | falsefalseКоличество знаков после запятой
innerErrorobject | null-Внутренняя ошибка валидации (используется компонентом)
setInnerError(error: object | null) => void-Установка внутренней ошибки (используется компонентом)

Особенности:

  • Автоматическое форматирование чисел с пробелами для разделения тысяч (например: 1 000 000)
  • Поддержка отрицательных чисел
  • Автоматическая валидация при вводе с отображением ошибок через innerError
  • При превышении max или min автоматически показывается ошибка
  • Поддержка как точки, так и запятой в качестве разделителя дробной части
MaskedInput — инпут с маской ввода

MaskedInput

import { InputContainer, MaskedInput } from 'finform';

const [value, setValue] = useState('');
const [error, setError] = useState<string | null>(null);

<InputContainer error={error}>
  <MaskedInput
    id="phone"
    placeholder="Телефон"
    value={value}
    onChange={setValue}
    mask="+7 (999) 999-99-99"
  />
</InputContainer>

Props

Все пропсы из Input, плюс:

ПропТипПо умолчаниюОписание
maskstring-Маска ввода (символ 9 означает цифру)

Примеры масок:

  • "+7 (999) 999-99-99" — телефон
  • "99.99.9999" — дата
  • "9999 9999 9999 9999" — номер карты

Выпадающие списки

Select — одиночный выбор

Select

import { InputContainer, Select } from 'finform';

interface Option {
  id: string | number;
  name: string;
}

const options: Option[] = [
  { id: 1, name: 'Опция 1' },
  { id: 2, name: 'Опция 2' },
];

const [value, setValue] = useState<number | null>(null);
const [error, setError] = useState<string | null>(null);

<InputContainer error={error}>
  <Select
    id="category"
    placeholder="Выберите категорию"
    value={value}
    onChange={(option) => setValue(option?.id || null)}
    options={options}
  />
</InputContainer>

Важно: onChange получает объект Option целиком, а не только значение.

Props

ПропТипПо умолчаниюОписание
idstring-Уникальный идентификатор поля
namestring-Имя поля для формы
valuestring | number | null-ID выбранной опции
onChange(option: Option | null) => void-Обработчик выбора опции (получает весь объект Option)
optionsOption[][]Массив опций для выбора
placeholderstring-Текст placeholder'а
disabledbooleanfalseОтключение поля
classNamestring''Дополнительные CSS классы
styleReact.CSSProperties{}Инлайн стили
iconbooleantrueПоказывать ли иконку в InputContainer
addButtonanyfalseКнопка добавления новой опции (отображается в списке)
MultiSelect — множественный выбор

MultiSelect

import { InputContainer, MultiSelect } from 'finform';

const options: Option[] = [
  { id: 1, name: 'Опция 1' },
  { id: 2, name: 'Опция 2' },
];

const [values, setValues] = useState<number[]>([]);
const [error, setError] = useState<string | null>(null);

<InputContainer error={error}>
  <MultiSelect
    id="tags"
    placeholder="Выберите теги"
    values={values}
    onChange={(option) => {
      setValues(prev => 
        prev.includes(option.id) 
          ? prev.filter(id => id !== option.id)
          : [...prev, option.id]
      );
    }}
    onChangeAll={(selectAll) => {
      setValues(selectAll ? options.map(o => o.id) : []);
    }}
    options={options}
  />
</InputContainer>

Props

ПропТипПо умолчаниюОписание
idstring-Уникальный идентификатор поля
namestring-Имя поля для формы
values(string | number)[][]Массив ID выбранных опций
onChange(option: Option) => void-Обработчик выбора/снятия опции
onChangeAll(selectAll: boolean) => void-Обработчик выбора всех/снятия всех опций
optionsOption[][]Массив опций для выбора
placeholderstring-Текст placeholder'а
disabledbooleanfalseОтключение поля
classNamestring''Дополнительные CSS классы
styleReact.CSSProperties{}Инлайн стили
iconbooleantrueПоказывать ли иконку в InputContainer

Особенности:

  • onChange вызывается при клике на опцию — нужно самостоятельно управлять массивом values
  • onChangeAll вызывается при клике на "Выбрать все" — передается true для выбора всех, false для снятия всех

Поиск

Search — поиск с одиночным выбором
import { InputContainer, Search } from 'finform';

const [search, setSearch] = useState('');
const [value, setValue] = useState<number | null>(null);
const [error, setError] = useState<string | null>(null);

<InputContainer error={error}>
  <Search
    id="user-search"
    placeholder="Поиск пользователя"
    value={value}
    search={search}
    onChange={(option) => {
      setValue(option?.id || null);
      setSearch(option?.name || '');
    }}
    onSearch={setSearch}
    options={filteredOptions}
    loading={isLoading}
    clearOnClickOutside={true}
  />
</InputContainer>

Props

Все пропсы из Select, плюс:

ПропТипПо умолчаниюОписание
searchstring-Текущее значение строки поиска
onSearch(text: string) => void-Обработчик изменения текста поиска
loadingbooleanfalseИндикатор загрузки данных
clearOnClickOutsidebooleantrueОчищать поле поиска при клике вне компонента, если опция не выбрана

Особенности:

  • При вводе текста в поле поиска вызывается onSearch — используйте это для фильтрации опций
  • Если введенный текст совпадает с названием опции при клике вне компонента, опция автоматически выбирается
  • При loading={true} отображается индикатор загрузки вместо иконки
MultipleSearch — поиск с множественным выбором

MultipleSearch

import { InputContainer, MultipleSearch } from 'finform';

const [search, setSearch] = useState('');
const [values, setValues] = useState<number[]>([]);
const [error, setError] = useState<string | null>(null);

<InputContainer error={error}>
  <MultipleSearch
    id="users-search"
    placeholder="Поиск пользователей"
    values={values}
    search={search}
    onChange={(option) => {
      setValues(prev => 
        prev.includes(option.id) 
          ? prev.filter(id => id !== option.id)
          : [...prev, option.id]
      );
    }}
    onSearch={setSearch}
    options={filteredOptions}
    loading={isLoading}
  />
</InputContainer>

Props

Все пропсы из Search, но onChange работает как в MultiSelect:

ПропТипПо умолчаниюОписание
values(string | number)[][]Массив ID выбранных опций
onChange(option: Option) => void-Обработчик выбора/снятия опции

Особенности:

  • Выбранные опции отображаются как теги внутри поля
  • Работает аналогично MultiSelect, но с возможностью поиска

Группированные списки

GroupSelect — выпадающий список с группировкой

GroupSelect

import { InputContainer, GroupSelect } from 'finform';

interface GroupOption {
  id: string | number;
  name: string;
  items: Option[];
}

const groupOptions: GroupOption[] = [
  {
    id: 'group1',
    name: 'Группа 1',
    items: [
      { id: 1, name: 'Опция 1.1' },
      { id: 2, name: 'Опция 1.2' },
    ]
  },
];

const [value, setValue] = useState<number | null>(null);
const [error, setError] = useState<string | null>(null);

<InputContainer error={error}>
  <GroupSelect
    id="grouped-select"
    placeholder="Выберите из группы"
    value={value}
    onChange={(option) => setValue(option?.id || null)}
    options={groupOptions}
  />
</InputContainer>

Props

Все пропсы из Select, но options имеет тип GroupOption[]:

ПропТипПо умолчаниюОписание
optionsGroupOption[][]Массив группированных опций

Особенности:

  • Опции отображаются сгруппированными по группам
  • Названия групп отображаются как заголовки
GroupSearch — поиск с группировкой

GroupSearch

import { InputContainer, GroupSearch } from 'finform';

const [search, setSearch] = useState('');
const [value, setValue] = useState<number | null>(null);
const [error, setError] = useState<string | null>(null);

<InputContainer error={error}>
  <GroupSearch
    id="grouped-search"
    placeholder="Поиск в группах"
    value={value}
    search={search}
    onChange={(option) => {
      setValue(option?.id || null);
      setSearch(option?.name || '');
    }}
    onSearch={setSearch}
    options={groupOptions}
    loading={isLoading}
  />
</InputContainer>

Props

Все пропсы из GroupSelect, плюс:

ПропТипПо умолчаниюОписание
searchstring-Текущее значение строки поиска
onSearch(text: string) => void-Обработчик изменения текста поиска
loadingbooleanfalseИндикатор загрузки данных

Особенности:

  • Поиск работает по опциям внутри всех групп
  • Группы остаются видимыми при поиске
GroupSelectWithSearch — список с группировкой и поиском

GroupSelectWithSearch

import { InputContainer, GroupSelectWithSearch } from 'finform';

const [search, setSearch] = useState('');
const [value, setValue] = useState<number | null>(null);
const [error, setError] = useState<string | null>(null);

<InputContainer error={error}>
  <GroupSelectWithSearch
    id="grouped-select-search"
    placeholder="Выберите с поиском"
    value={value}
    search={search}
    onChange={(option) => {
      setValue(option?.id || null);
      setSearch(option?.name || '');
    }}
    onSearch={setSearch}
    options={groupOptions}
    loading={isLoading}
  />
</InputContainer>

Props

Все пропсы из GroupSearch и GroupSelect.

Особенности:

  • Комбинирует возможности группировки и поиска
  • Поиск работает по всем опциям во всех группах

Дата и время

DateInput — выбор даты

DateInput

import { InputContainer, DateInput } from 'finform';

const [value, setValue] = useState<Date | null>(null);
const [error, setError] = useState<string | null>(null);

<InputContainer error={error}>
  <DateInput
    id="birthdate"
    placeholder="Дата рождения"
    value={value}
    onChange={setValue}
    defaultDate="2024-01-01"
  />
</InputContainer>

Props

ПропТипПо умолчаниюОписание
idstring-Уникальный идентификатор поля
namestring-Имя поля для формы
valueDate | null-Выбранная дата
onChange(date: Date | null) => void-Обработчик изменения даты
placeholderstring-Текст placeholder'а
disabledbooleanfalseОтключение поля
classNamestring''Дополнительные CSS классы
styleReact.CSSProperties{}Инлайн стили
defaultDatestring-Дата по умолчанию в формате YYYY-MM-DD
iconbooleantrueПоказывать ли иконку в InputContainer
innerErrorobject | null-Внутренняя ошибка валидации (используется компонентом)
setInnerError(error: object | null) => void-Установка внутренней ошибки (используется компонентом)

Особенности:

  • Использует библиотеку Flatpickr для выбора даты
  • Поддерживает различные форматы даты
  • При неверном формате ввода автоматически показывается ошибка через innerError
DateTimeInput — выбор даты и времени

DateTimeInput

import { InputContainer, DateTimeInput } from 'finform';

const [value, setValue] = useState<Date | null>(null);
const [error, setError] = useState<string | null>(null);

<InputContainer error={error}>
  <DateTimeInput
    id="datetime"
    placeholder="Дата и время"
    value={value}
    onChange={setValue}
  />
</InputContainer>

Props

Все пропсы из DateInput.

Особенности:

  • Позволяет выбрать как дату, так и время
  • Формат отображения включает время

Файлы

FileInput — загрузка файлов

FileInput

import { InputContainer, FileInput } from 'finform';

const [file, setFile] = useState<File | null>(null);
const [error, setError] = useState<string | null>(null);

<InputContainer error={error}>
  <FileInput
    id="document"
    placeholder="Выберите файл"
    value={file}
    onChange={(fileData) => {
      // fileData содержит: { size, name, content }
      // content - это base64 строка
      setFile(fileData);
    }}
    valueText={file?.name || ''}
    accept=".pdf,.doc,.docx"
  />
</InputContainer>

Props

ПропТипПо умолчаниюОписание
idstring-Уникальный идентификатор поля
namestring-Имя поля для формы
valueobject | null-Объект с данными файла (не используется напрямую)
onChange(fileData: { size: number, name: string, content: string }) => void-Обработчик выбора файла
valueTextstring''Текст для отображения имени файла
placeholderstring-Текст placeholder'а
disabledbooleanfalseОтключение поля
classNamestring''Дополнительные CSS классы
styleReact.CSSProperties{}Инлайн стили
acceptstring-Разрешенные типы файлов (например: ".pdf,.doc,.docx" или "image/*")

Особенности:

  • Файл автоматически конвертируется в base64 строку
  • onChange получает объект с полями:
    • size — размер файла в байтах
    • name — имя файла
    • content — содержимое файла в формате base64 (data URL)
  • Используйте valueText для отображения имени выбранного файла
  • Placeholder всегда активен для FileInput

Чекбоксы

Checkbox — чекбокс

Checkbox

import { Checkbox } from 'finform';

const [checked, setChecked] = useState(false);

<Checkbox
  id="agree"
  checked={checked}
  toggleCallback={(checked) => setChecked(checked)}
  text="Я согласен с условиями"
/>

Props

ПропТипПо умолчаниюОписание
idstring-Уникальный идентификатор чекбокса
namestring-Имя для группировки чекбоксов
valuestring | number-Значение чекбокса (для форм)
checkedbooleanfalseСостояние чекбокса
toggleCallback(checked: boolean, event: Event) => void-Обработчик изменения состояния
textstring-Текст рядом с чекбоксом
textStyleReact.CSSProperties{}Стили для текста
checkboxStyleReact.CSSProperties{}Стили для самого чекбокса
styleReact.CSSProperties{}Общий стиль контейнера

Особенности:

  • Не требует обертки в InputContainer
  • Используйте toggleCallback вместо onChange для обработки изменений
  • Для группировки чекбоксов используйте одинаковый name и разные value
RoundCheckbox — круглый чекбокс

RoundCheckbox

import { RoundCheckbox } from 'finform';

const [checked, setChecked] = useState(false);

<RoundCheckbox
  id="option"
  checked={checked}
  toggleCallback={(checked) => setChecked(checked)}
/>

Props

Все пропсы из Checkbox, но без text, textStyle (круглый чекбокс обычно используется без текста).

Особенности:

  • Визуально отличается от обычного Checkbox — имеет круглую форму
  • Обычно используется для выбора опций без текста рядом

Обработка ошибок

Важно: Для корректного отображения ошибки в попапе необходимо передать строку в проп error компонента InputContainer. При наведении на иконку ошибки появляется попап с текстом ошибки.

Пример 1: Простая валидация

import { InputContainer, Input } from 'finform';
import { useState } from 'react';

function MyForm() {
  const [value, setValue] = useState('');
  const [error, setError] = useState<string | null>(null);

  const handleSubmit = () => {
    if (!value.trim()) {
      setError('Поле обязательно для заполнения');
      return;
    }
    
    if (value.length < 3) {
      setError('Минимальная длина 3 символа');
      return;
    }
    
    setError(null);
    // Отправка формы
  };

  return (
    <InputContainer error={error}>
      <Input
        id="field"
        placeholder="Введите значение"
        value={value}
        onChange={(newValue) => {
          setValue(newValue);
          // Очищаем ошибку при изменении значения
          if (error) setError(null);
        }}
      />
    </InputContainer>
  );
}

Пример 2: Работа с массивом ошибок

Если валидация возвращает массив ошибок, используйте первую ошибку или объедините их:

import { InputContainer, Input } from 'finform';
import { useState } from 'react';

function MyForm() {
  const [value, setValue] = useState('');
  const [validationErrors, setValidationErrors] = useState<string[]>([]);

  // Использовать первую ошибку
  const errorMessage = validationErrors.length > 0 
    ? validationErrors[0] 
    : null;

  return (
    <InputContainer error={errorMessage}>
      <Input
        id="field"
        placeholder="Введите значение"
        value={value}
        onChange={setValue}
      />
    </InputContainer>
  );
}

Примеры полных форм

Пример 1: Форма регистрации

import { useState } from 'react';
import { 
  InputContainer, 
  Input, 
  Select, 
  DateInput, 
  Checkbox 
} from 'finform';

interface Option {
  id: number;
  name: string;
}

function RegistrationForm() {
  const [username, setUsername] = useState('');
  const [usernameError, setUsernameError] = useState<string | null>(null);
  
  const [email, setEmail] = useState('');
  const [emailError, setEmailError] = useState<string | null>(null);
  
  const [country, setCountry] = useState<number | null>(null);
  const [countryError, setCountryError] = useState<string | null>(null);
  
  const [birthdate, setBirthdate] = useState<Date | null>(null);
  const [birthdateError, setBirthdateError] = useState<string | null>(null);
  
  const [agreed, setAgreed] = useState(false);

  const countries: Option[] = [
    { id: 1, name: 'Россия' },
    { id: 2, name: 'Беларусь' },
    { id: 3, name: 'Казахстан' },
  ];

  const handleSubmit = () => {
    // Валидация
    if (!username.trim()) {
      setUsernameError('Имя пользователя обязательно');
      return;
    }
    
    if (!email.includes('@')) {
      setEmailError('Некорректный email');
      return;
    }
    
    if (!country) {
      setCountryError('Выберите страну');
      return;
    }
    
    if (!birthdate) {
      setBirthdateError('Укажите дату рождения');
      return;
    }
    
    if (!agreed) {
      alert('Необходимо согласие с условиями');
      return;
    }

    // Отправка формы
    console.log({ username, email, country, birthdate });
  };

  return (
    <form onSubmit={(e) => { e.preventDefault(); handleSubmit(); }}>
      <InputContainer error={usernameError}>
        <Input
          id="username"
          placeholder="Имя пользователя"
          value={username}
          onChange={(value) => {
            setUsername(value);
            if (usernameError) setUsernameError(null);
          }}
        />
      </InputContainer>

      <InputContainer error={emailError}>
        <Input
          id="email"
          type="email"
          placeholder="Email"
          value={email}
          onChange={(value) => {
            setEmail(value);
            if (emailError) setEmailError(null);
          }}
        />
      </InputContainer>

      <InputContainer error={countryError}>
        <Select
          id="country"
          placeholder="Выберите страну"
          value={country}
          onChange={(option) => {
            setCountry(option?.id || null);
            if (countryError) setCountryError(null);
          }}
          options={countries}
        />
      </InputContainer>

      <InputContainer error={birthdateError}>
        <DateInput
          id="birthdate"
          placeholder="Дата рождения"
          value={birthdate}
          onChange={(date) => {
            setBirthdate(date);
            if (birthdateError) setBirthdateError(null);
          }}
        />
      </InputContainer>

      <Checkbox
        id="agree"
        checked={agreed}
        toggleCallback={setAgreed}
        text="Я согласен с условиями использования"
      />

      <button type="submit">Зарегистрироваться</button>
    </form>
  );
}

Пример 2: Форма с поиском и множественным выбором

import { useState, useMemo } from 'react';
import { InputContainer, Search, MultiSelect } from 'finform';

interface User {
  id: number;
  name: string;
}

function UserSelectionForm() {
  const [searchQuery, setSearchQuery] = useState('');
  const [selectedUser, setSelectedUser] = useState<number | null>(null);
  const [selectedTags, setSelectedTags] = useState<number[]>([]);
  const [isLoading, setIsLoading] = useState(false);

  const allUsers: User[] = [
    { id: 1, name: 'Иван Иванов' },
    { id: 2, name: 'Петр Петров' },
    { id: 3, name: 'Мария Сидорова' },
  ];

  const tags = [
    { id: 1, name: 'Важное' },
    { id: 2, name: 'Срочное' },
    { id: 3, name: 'Проект А' },
    { id: 4, name: 'Проект Б' },
  ];

  // Фильтрация пользователей по поисковому запросу
  const filteredUsers = useMemo(() => {
    if (!searchQuery.trim()) return [];
    return allUsers.filter(user => 
      user.name.toLowerCase().includes(searchQuery.toLowerCase())
    );
  }, [searchQuery]);

  return (
    <div>
      <InputContainer>
        <Search
          id="user-search"
          placeholder="Поиск пользователя"
          value={selectedUser}
          search={searchQuery}
          onChange={(option) => {
            setSelectedUser(option?.id || null);
            setSearchQuery(option?.name || '');
          }}
          onSearch={setSearchQuery}
          options={filteredUsers}
          loading={isLoading}
        />
      </InputContainer>

      <InputContainer>
        <MultiSelect
          id="tags"
          placeholder="Выберите теги"
          values={selectedTags}
          onChange={(option) => {
            setSelectedTags(prev => 
              prev.includes(option.id) 
                ? prev.filter(id => id !== option.id)
                : [...prev, option.id]
            );
          }}
          onChangeAll={(selectAll) => {
            setSelectedTags(selectAll ? tags.map(t => t.id) : []);
          }}
          options={tags}
        />
      </InputContainer>
    </div>
  );
}

Особенности работы компонентов

InputContainer

  • Обязательная обертка: Все компоненты (кроме Checkbox и RoundCheckbox) должны быть обернуты в InputContainer
  • Единственный дочерний элемент: InputContainer принимает только один дочерний компонент
  • Автоматическая передача пропсов: InputContainer автоматически передает дочернему компоненту пропсы focused, setFocused, error, innerError, setInnerError
  • Управление placeholder: Placeholder автоматически перемещается вверх при наличии значения или фокуса
  • Иконки: Иконки отображаются автоматически, можно отключить через проп icon={false}

NumberInput

  • Форматирование: Автоматически форматирует числа с пробелами для разделения тысяч
  • Валидация: Автоматически проверяет значения на соответствие min и max
  • Дробные числа: Поддерживает дробные числа с ограничением количества знаков через decimals
  • Разделители: Принимает как точку, так и запятую в качестве разделителя дробной части

FileInput

  • Base64 конвертация: Автоматически конвертирует файл в base64 строку
  • Возвращаемые данные: onChange получает объект { size, name, content }, где content — это data URL (base64)
  • Отображение имени: Используйте valueText для отображения имени выбранного файла

Search и MultipleSearch

  • Фильтрация: Компоненты не фильтруют опции автоматически — нужно реализовать фильтрацию в onSearch
  • Автовыбор: Если введенный текст точно совпадает с названием опции, она автоматически выбирается при клике вне компонента
  • Очистка: При clearOnClickOutside={true} поле поиска очищается, если опция не была выбрана

DateInput и DateTimeInput

  • Библиотека: Используют Flatpickr для выбора даты
  • Валидация: Автоматически валидируют формат ввода через innerError
  • Формат: Принимают и возвращают объекты Date

Checkbox и RoundCheckbox

  • Без InputContainer: Эти компоненты не требуют обертки в InputContainer
  • Группировка: Для группировки используйте одинаковый name и разные value
  • Обработчик: Используйте toggleCallback вместо onChange

Примечания

  • Все инпуты должны быть обернуты в InputContainer для корректной работы (кроме Checkbox и RoundCheckbox)
  • InputContainer принимает только один дочерний элемент
  • Для отображения ошибки в попапе передавайте строку в проп error компонента InputContainer
  • Ошибка автоматически скрывается при передаче null или пустой строки
  • Компоненты автоматически управляют состоянием фокуса — не передавайте focused и setFocused вручную
  • Для работы компонентов требуется настроенная тема styled-components (проверьте наличие ThemeProvider)

FAQs

Package last updated on 04 Mar 2026

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts