3.0.0 • Published 1 year ago

@eisgs/input v3.0.0

Weekly downloads
-
License
MIT
Repository
-
Last release
1 year ago

Базовый Input

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

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

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

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.

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

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

Валидация

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

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

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

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>

Ограничения

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

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

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).

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

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 или регулярное выражение в виде строки.

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 можно ограничить количество знаков после запятой.

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

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

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

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

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

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

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

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

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

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

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

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

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

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 отобразится подсказка

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

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

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 позволяет добавить дополнительный контент справа

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>
3.0.0

1 year ago

2.0.0

1 year ago

1.4.0

2 years ago

1.3.0

2 years ago

1.2.0

2 years ago

1.1.6

2 years ago

1.1.4

2 years ago

1.1.0

2 years ago

1.1.3

2 years ago

1.1.2

2 years ago

1.0.9

3 years ago

1.0.8

3 years ago

1.0.7

3 years ago

1.0.2

3 years ago

1.0.6

3 years ago

1.0.5

3 years ago

1.0.4

3 years ago

1.0.3

3 years ago

1.0.1

3 years ago