# @eisgs/input

> Ссылка на компонент `ref` пробрасывается в HTML Input.

Latest version **3.1.0** (published 2024-05-17) · MIT license · 0 weekly downloads

## Install

```sh
npm install @eisgs/input
pnpm add @eisgs/input
yarn add @eisgs/input
bun add @eisgs/input
```

## Health

**Score 15/100 (F)** — status: abandoned.

Positive: no vulnerabilities.

Warnings: low downloads; no types; no esm support.

Negative: abandoned; low maintenance score.

## Facts

| | |
|---|---|
| Version | 3.1.0 |
| Published | 2024-05-17 |
| First published | 2021-04-30 |
| Weekly downloads | 0 |
| License | MIT |
| TypeScript types | none |
| Module format | CommonJS |
| Dependencies | 5 |
| Unpacked size | 129.8 KB |
| Known vulnerabilities | 0 |
| Install scripts | no |
| Maintainers | traidersu, krll_mdntsv, lzdyd |

## Links

- npm: https://www.npmjs.com/package/@eisgs/input
- npm.io page: https://npm.io/package/@eisgs/input

## Dependencies (5)

- [@eisgs/hint](https://npm.io/package/@eisgs/hint.md) ^3.0.0
- [react-input-mask](https://npm.io/package/react-input-mask.md) 2.0.4
- [@eisgs/typography](https://npm.io/package/@eisgs/typography.md) ^1.3.1
- [react-number-format](https://npm.io/package/react-number-format.md) 4.5.0
- [@eisgs/theme-provider](https://npm.io/package/@eisgs/theme-provider.md) ^0.0.8

## Recent versions

- 3.1.0 (latest) — 2024-05-17
- 3.0.0 — 2023-03-02
- 2.0.0 — 2022-12-21
- 1.4.0 — 2022-11-07
- 1.3.0 — 2022-10-27
- 1.2.0 — 2022-07-19
- 1.1.6 — 2022-06-02
- 1.1.4 — 2022-05-06
- 1.1.3 — 2022-02-24
- 1.1.2 — 2022-01-26
- 1.1.0 — 2021-12-29
- 1.0.9 — 2021-09-17
- 1.0.8 — 2021-08-16
- 1.0.7 — 2021-07-16
- 1.0.6 — 2021-06-11
- … 5 more at https://npm.io/package/@eisgs/input/versions

## README

### Базовый Input

Ссылка на компонент `ref` пробрасывается в HTML Input. 

`onChange` и `value` позволяют управлять содержимым инпута.

`label` и `placeholder` позволяют указать дополнительную информацию для пользователя.

```jsx
import { Button } from '@eisgs/button';

const [value, setValue] = React.useState('');
const inputRef = React.useRef();

const handleInputFocus = () => inputRef.current.focus();

<div style={{ display: 'inline-flex', alignItems: 'flex-start' }}>
  <Input
    ref={inputRef}
    placeholder="Укажите значение"
    value={value}
    onChange={setValue}
    onBlur={console.log}
  />
  <Button onClick={handleInputFocus}>
    Фокус
  </Button>
</div>
```

### Floating label

Для применения плавающего заголовка необходимо передать флаг `floatingLabel`.

```jsx
const [value, setValue] = React.useState('');

<div className="w300">
  <Input
    floatingLabel
    label="Описание"
    value={value}
    onChange={setValue}
  />
</div>
```

### Валидация

`maxLength` позволяет ограничить количество символов при вводе.

`validate` позволяет проверить значение в поле ввода.

`error` - строка с текстом ошибки.

```jsx
const [valueInputOne, setValueInputOne] = React.useState('');
const [errorInputOne, setErrorInputOne] = React.useState('');

const validateFunction = (val) => {
  if (val.length && val !== 'яблоко') {
    setErrorInputOne('значение должно быть яблоко');
    return false;
  } else {
    setErrorInputOne('');
    return true;
  }
};

<div className="w300">
  <Input
    label="Инпут с функцией валидации"
    maxLength={6}
    validate={validateFunction}
    value={valueInputOne}
    onChange={setValueInputOne}
    error={errorInputOne}
  />

  <Input 
    label="Значение инпута невалидно" 
    error="Произошла ошибка" 
  />

  <Input 
    label="Значение инпута невалидно" 
    warning="Произошла ошибка" 
  />
</div>
```

### Маска

`mask` позволяет задать маску ввода.

`maskChar` позволяет закрывать незаполненные значения маски определенным символом.

`formatChars` позволяет определять символы форматирования маски.

`unmask` позволяет вернуть значение инпута без маски.

```jsx

const [firstInputValue, setFirstInputValue] = React.useState('');
const [secondInputValue, setSecondInputValue] = React.useState('1');
const [thirdInputValue, setThirdInputValue] = React.useState('');
const [fourthInputValue, setFourthInputValue] = React.useState('');
const firstMask = 'a/999/aa';
const secondMask = '+7(999)999-99-99';
const thirdMask = '||:||';
const forthMask = 'ХХ-ХХ-99'

const formatChars = { '|': '[0-9]' };

<div className="w300">
  <Input
    mask={firstMask}
    value={firstInputValue}
    onChange={setFirstInputValue}
    placeholder='A/777/AA'
    label='Обычная маска'
  />
  <Input
    mask={secondMask}
    maskChar='*'
    value={secondInputValue}
    onChange={setSecondInputValue}
    placeholder='+7(999)999-99-99'
    label='Маска с использованием maskChar'
  />
  <Input
    mask={thirdMask}
    value={thirdInputValue}
    onChange={setThirdInputValue}
    placeholder='12:12'
    label='Маска с использованием formatChars'
    formatChars={formatChars}
  />
  <Input
    mask={forthMask}
    value={fourthInputValue}
    onChange={setFourthInputValue}
    placeholder='XX-XX-00'
    label='Маска с использованием unmask'
    unmask
  />  
</div>
```

### Ограничения

`disabled` блокирует ввод значений.

Для того чтобы скрыть `placeholder` при `disabled` и отсутствии `value`, 
необходимо передать флаг `hidePlaceholderWhenDisabled`.

```jsx
const rowProps = {
  className:"w600",
  style: { display: 'flex', alignItems: 'flex-end', gap: 40 }
};

<>
  <div {...rowProps}>
    <Input
      disabled
      label="Disabled Empty"
      placeholder="Подсказка"
      value=""
    />
    <Input
      disabled
      floatingLabel
      label="Disabled Empty"
      placeholder="Подсказка"
      value=""
    />
  </div>

  <div {...rowProps}>
    <Input
      disabled
      hidePlaceholderWhenDisabled
      label="Disabled Empty (hidden placeholder)"
      placeholder="Подсказка"
      value=""
    />
    <Input
      disabled
      floatingLabel
      hidePlaceholderWhenDisabled
      label="Disabled Empty (hidden placeholder)"
      placeholder="Подсказка"
      value=""
    />
    </div>
    
    <div {...rowProps}>
      <Input
        disabled
        label="Disabled Filled"
        placeholder="Подсказка"
        value="Текст"
      />
      <Input
        disabled
        floatingLabel
        label="Disabled Filled"
        placeholder="Подсказка"
        value="Текст"
      />
  </div>
</>
```

### Цифровой инпут

Компонент принимает все пропсы от `react-number-format` (см. https://github.com/s-yadav/react-number-format/tree/v4.5.0#props).

Для ввода доступны только цифры.

```jsx
import { NumericInput } from '@eisgs/input';

const [firstInputValue, setFirstInputValue] = React.useState('');
const [secondInputValue, setSecondInputValue] = React.useState('');

<div className="w300">
  <NumericInput 
    label="Цифровой инпут"
    placeholder="Цифровой инпут"
    onChange={setFirstInputValue} 
    value={firstInputValue}
  />

  <NumericInput
    floatingLabel
    label="Цифровой инпут"
    onChange={setSecondInputValue}
    value={secondInputValue}
  />
</div>
```

### Валидация

Можно передать в validate функцию, объект RegExp или регулярное выражение в виде строки.

```jsx
import { NumericInput } from '@eisgs/input';

const [value, setValue] = React.useState();
const [valueInputOne, setValueInputOne] = React.useState('');
const [errorInputOne, setErrorInputOne] = React.useState('');

const validateFunction = (val) => {
  if (val && val < 100) {
    setErrorInputOne('значение должно быть меньше 100');
    return false;
  } else {
    setErrorInputOne('');
    return true;
  }
};

<>
  <div className="w300">
    <NumericInput
      placeholder="Цифровой инпут"
      label="Инпут с функцией валидации"
      validate={validateFunction}
      onChange={setValue}
      value={value}
      error={errorInputOne}
    />
  </div>
  <div className="w300">
    <NumericInput
      placeholder="Цифровой инпут"
      label="Значение инпута невалидно" 
      error="Произошла ошибка" 
    />
  </div>
  <div className="w300">
    <NumericInput
      placeholder="Цифровой инпут"
      label="Значение инпута невалидно" 
      warning="Произошла ошибка" 
    />
  </div>
</>
```

### Количество знаков после запятой

В параметре `decimalScale` можно ограничить количество знаков после запятой.

```jsx
import { NumericInput } from '@eisgs/input';

const [value, setValue] = React.useState();

<div className="w300">
  <NumericInput
    placeholder="Количество знаков после запятой - 2"
    onChange={setValue} 
    value={value} 
    decimalScale="2"
  />
</div>
```

### Разделитель групп разрядов

Разделитель групп разрядов задается в параметре `thousandSeparator`.

```jsx
import { NumericInput } from '@eisgs/input';

const [value, setValue] = React.useState();

<div className="w300">
  <NumericInput 
    onChange={setValue} 
    value={value} 
    thousandSeparator=" " 
  />
</div>
```

Кастомный разделитель для дробной части числа задается в параметре `decimalSeparator` (по умолчанию точка).

```jsx
import { NumericInput } from '@eisgs/input';

const [value, setValue] = React.useState();

<div className="w300">
  <NumericInput 
    onChange={setValue} 
    value={value} 
    decimalSeparator="," 
  />
</div>
```

### Инпут для поиска

```jsx
import { SearchInput } from '@eisgs/input';

const [reqData, setReqData] = React.useState({
  value: '',
  loading: false,
});

const search = () => {
  setReqData((data) => ({ ...data, loading: true }));
  setTimeout(() => setReqData((data) => ({ ...data, loading: false })), 3000);
};

const handleSearch = (value) => setReqData({ value });

const handleKeyDown = (event) => {
  //Отправка запроса по нажатию на Enter
  if (event.keyCode === 13) {
    search();
  }
};

<div className="w300">
  <SearchInput
    withClear
    loading={reqData.loading}
    value={reqData.value}
    onChange={handleSearch}
    placeholder="Найти"
    onKeyDown={handleKeyDown}
  />

  <SearchInput
    withClear
    floatingLabel
    loading={reqData.loading}
    value={reqData.value}
    onChange={handleSearch}
    label="Найти"
    onKeyDown={handleKeyDown}
  />
</div>
```

### Подсказка

При передаче `hint` отобразится подсказка

```jsx
<Input label="Описание" hint="Подсказка"/>
```

### Состояния (ИЖС)

```jsx

import { Typography } from "@eisgs/typography";

const viewList = ['desktop', 'mobile'];
const stateList = [
  {placeholder: 'Подсказка'},
  {label: 'Подсказка', placeholder: 'Подсказка'},
  {label: 'Подсказка', placeholder: 'Подсказка', floatingLabel: true}
];
const extraList = [
  {},
  {value: 'Текст'},
  {value: 'Текст', error: 'Текст ошибки'},
  {disabled: true},
  {disabled: true, value: 'Текст'}
];

<>
  {viewList.map(item =>
    <div key={item} style={{marginBottom: 40}}>
      <Typography type="p1" styles={`margin-bottom: 40px`}>{item}</Typography>
      {stateList.map((props, index) => (
        <div style={{display: 'flex', gap: 40}} key={index}>
          {extraList.map((extraProps, extraIndex) => (
            <Input
              {...props}
              {...extraProps}
              view={item}
              key={`${index}-${extraIndex}`}
              styles={`max-width: 168px`}
            />
          ))}
        </div>
      ))}
    </div>
  )}
</>
```

### Suffix

Параметр `suffix` позволяет добавить дополнительный контент справа

```jsx
import { NumericInput } from '@eisgs/input';
import { createSvgIcon } from "@eisgs/icon";

const RoubleIcon = createSvgIcon(
  <path d="M5.66412 13.0001V4.43213H7.92012C8.96812 4.43213 9.74412 4.64413 10.2481 5.06813C10.7601 5.49213 11.0161 6.10813 11.0161 6.91613C11.0161 7.46013 10.8921 7.92813 10.6441 8.32013C10.3961 8.70413 10.0281 9.00013 9.54012 9.20813C9.06012 9.41613 8.46412 9.52013 7.75212 9.52013H6.74412V13.0001H5.66412ZM4.62012 11.3681V10.5881H8.72412V11.3681H4.62012ZM4.62012 9.52013V8.60813H7.36812V9.52013H4.62012ZM7.59612 8.60813C8.08412 8.60813 8.49612 8.55613 8.83212 8.45213C9.17612 8.34813 9.44012 8.17613 9.62412 7.93613C9.80812 7.69613 9.90012 7.36813 9.90012 6.95213C9.90012 6.40813 9.73212 6.00413 9.39612 5.74013C9.06012 5.47613 8.53612 5.34413 7.82412 5.34413H6.74412V8.60813H7.59612Z" fill="#9BA9AD"/>, 
  'RoubleIcon'
);

const metriсSuffix = (value) => <span>м{value && <sup>{value}</sup>}</span>;

<div className="w300">
  <NumericInput placeholder="Укажите сумму" suffix={<RoubleIcon/>}/>
  <NumericInput placeholder="Укажите сумму" suffix="млн. руб."/>
  <NumericInput placeholder="Укажите длину" suffix={metriсSuffix()}/>
  <NumericInput placeholder="Укажите площадь" suffix={metriсSuffix(2)}/>
  <NumericInput placeholder="Укажите объем" suffix={metriсSuffix(3)}/>
</div>
```

---
_Source: https://npm.io/package/@eisgs/input · Machine-readable twin of the npm.io package page. Health data is recomputed on every publish._
