Skip to content

Commit

Permalink
feat(inputs): some refactor. add events & props
Browse files Browse the repository at this point in the history
  • Loading branch information
reme3d2y committed Mar 18, 2020
1 parent dd1de2f commit 27f5bba
Show file tree
Hide file tree
Showing 3 changed files with 136 additions and 84 deletions.
166 changes: 124 additions & 42 deletions packages/input/src/Component.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,46 +16,66 @@ import styles from './Component.module.css';
*/

export type InputProps = {
/** Размер компонента */
size?: 's' | 'm' | 'l';
/** Атрибут type */
type?: 'number' | 'card' | 'email' | 'file' | 'hidden' | 'money' | 'password' | 'tel' | 'text';
/** Класс аддонов */
addonsClassName?: string;
/** Слот для отображения контента снизу */
children?: React.ReactNode;
/** Класс компонента */
className?: string;
/** Размер компонента */
size?: 's' | 'm' | 'l';
/** Id компонента для тестов */
dataTestId?: string;
/** Значение по умолчанию */
defaultValue?: string;
/** Атрибут disabled */
disabled?: boolean;
/** Текст ошибки */
error?: string;
/** Текст подсказки */
hint?: string;
/** Класс компонента */
innerClassName?: string;
/** Класс компонента */
inputClassName?: string;
/** Класс аддонов */
addonsClassName?: string;
/** Значение поля */
value?: string;
/** Плейсхолдер */
placeholder?: string;
/** Атрибут disabled */
disabled?: boolean;
/** Атрибут required */
required?: boolean;
/** Лейбл компонента */
label?: React.ReactNode;
/** Текст подсказки */
hint?: string;
/** Текст ошибки */
error?: string;
/** Слот слева от инпута */
leftAddons?: React.ReactNode;
/** Слот справа от инпута */
rightAddons?: React.ReactNode;
/** Слот для отображения контента снизу */
children?: React.ReactNode;
/** Обработчик фокуса инпута */
onFocus?: (event: React.FocusEvent<HTMLInputElement>) => void;
/** Максимальное число символов */
maxLength?: number;
/** Обработчик блюра инпута */
onBlur?: (event: React.FocusEvent<HTMLInputElement>) => void;
/** Обработчик ввода */
onChange?: (event: React.ChangeEvent<HTMLInputElement>) => void;
/** Id компонента для тестов */
dataTestId?: string;
/** Обработчик фокуса инпута */
onFocus?: (event: React.FocusEvent<HTMLInputElement>) => void;
/** Обработчик события нажатия на клавишу клавиатуры в момент, когда фокус находится на компоненте */
onKeyDown?: (event: React.KeyboardEvent<HTMLInputElement>) => void;
/** Обработчик события отжатия на клавишу клавиатуры в момент, когда фокус находится на компоненте */
onKeyUp?: (event: React.KeyboardEvent<HTMLInputElement>) => void;
/** Обработчик события вставки текста в поле */
onPaste?: (event: React.ClipboardEvent<HTMLInputElement>) => void;
/** Обработчик события прерывания касания по полю */
onTouchCancel?: (event: React.TouchEvent<HTMLInputElement>) => void;
/** Обработчик события прекращения касания по полю */
onTouchEnd?: (event: React.TouchEvent<HTMLInputElement>) => void;
/** Обработчик события перемещения при касании по полю */
onTouchMove?: (event: React.TouchEvent<HTMLInputElement>) => void;
/** Обработчик события касания по полю */
onTouchStart?: (event: React.TouchEvent<HTMLInputElement>) => void;
/** Плейсхолдер */
placeholder?: string;
/** Атрибут required */
required?: boolean;
/** Слот справа от инпута */
rightAddons?: React.ReactNode;
/** Атрибут type */
type?: 'number' | 'card' | 'email' | 'file' | 'hidden' | 'money' | 'password' | 'tel' | 'text';
/** Последовательность перехода между контролами при нажатии на Tab */
tabIndex?: number;
/** Значение поля */
value?: string;
};

/**
Expand All @@ -72,24 +92,34 @@ const errorIcon = (
export const Input = React.forwardRef<HTMLInputElement, InputProps>(({
size='s',
type='text',
addonsClassName,
children,
className,
dataTestId,
defaultValue,
disabled,
error,
hint,
className,
innerClassName,
inputClassName,
addonsClassName,
value,
disabled,
required,
placeholder,
label,
leftAddons,
rightAddons,
children,
maxLength,
onChange,
onFocus,
onKeyDown,
onKeyUp,
onPaste,
onTouchCancel,
onTouchEnd,
onTouchMove,
onTouchStart,
onBlur,
onChange,
dataTestId
placeholder,
required,
rightAddons,
tabIndex,
value
}, ref) => {
const [focused, setFocused] = useState(false);

Expand All @@ -115,6 +145,48 @@ export const Input = React.forwardRef<HTMLInputElement, InputProps>(({
}
};

const handleInputKeyDown = (e: React.KeyboardEvent<HTMLInputElement>) => {
if (onKeyDown) {
onKeyDown(e);
}
};

const handleInputKeyUp = (e: React.KeyboardEvent<HTMLInputElement>) => {
if (onKeyUp) {
onKeyUp(e);
}
};

const handleInputPaste = (e: React.ClipboardEvent<HTMLInputElement>) => {
if (onPaste) {
onPaste(e);
}
};

const handleInputTouchCancel = (e: React.TouchEvent<HTMLInputElement>) => {
if (onTouchCancel) {
onTouchCancel(e);
}
};

const handleInputTouchEnd = (e: React.TouchEvent<HTMLInputElement>) => {
if (onTouchEnd) {
onTouchEnd(e);
}
};

const handleInputTouchMove = (e: React.TouchEvent<HTMLInputElement>) => {
if (onTouchMove) {
onTouchMove(e);
}
};

const handleInputTouchStart = (e: React.TouchEvent<HTMLInputElement>) => {
if (onTouchStart) {
onTouchStart(e);
}
};

const rightAddonsRenderer = () => (
<div className={ cn(styles.addons, addonsClassName) }>
{ error && errorIcon }
Expand Down Expand Up @@ -154,15 +226,25 @@ export const Input = React.forwardRef<HTMLInputElement, InputProps>(({

<input
className={ cn(styles.input, styles[size], inputClassName) }
ref={ ref }
type={ type }
value={ value }
placeholder={ placeholder }
defaultValue={ defaultValue }
disabled={ disabled }
required={ required }
maxLength={ maxLength }
onBlur={ handleInputBlur }
onChange={ handleInputChange }
onFocus={ handleInputFocus }
onBlur={ handleInputBlur }
onKeyDown={ handleInputKeyDown }
onKeyUp={ handleInputKeyUp }
onPaste={ handleInputPaste }
onTouchCancel={ handleInputTouchCancel }
onTouchEnd={ handleInputTouchEnd }
onTouchMove={ handleInputTouchMove }
onTouchStart={ handleInputTouchStart }
placeholder={ placeholder }
ref={ ref }
required={ required }
tabIndex={ tabIndex }
type={ type }
value={ value }
data-test-id={ dataTestId }
/>
</div>
Expand Down
6 changes: 3 additions & 3 deletions packages/pure-input/src/Component.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -47,16 +47,16 @@
color: var(--input-placeholder-color);
}

.component:not(.disabled):hover {
.component:not(:disabled):hover {
background-color: var(--input-hover-bg-color);
}

.component.disabled:focus {
.component:disabled:focus {
border-bottom-color: var(--input-focus-border-color);
box-shadow: inset 0 -1px var(--input-focus-border-color);
}

.disabled {
.component:disabled {
color: var(--input-disabled-color);
border-bottom: 1px dashed var(--input-disabled-border-color);
background-color: var(--input-disabled-bg-color);
Expand Down
48 changes: 9 additions & 39 deletions packages/pure-input/src/Component.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
* Vendor
*/

import React from 'react';
import React, { InputHTMLAttributes } from 'react';
import cn from 'classnames';

/**
Expand All @@ -15,27 +15,9 @@ import styles from './Component.module.css';
* Types
*/

export type PureInputProps = {
export type PureInputProps = InputHTMLAttributes<HTMLInputElement> & {
/** Размер компонента */
size?: 's' | 'm' | 'l';
/** Атрибут type */
type?: 'number' | 'card' | 'email' | 'file' | 'hidden' | 'money' | 'password' | 'tel' | 'text';
/** Класс компонента */
className?: string;
/** Значение поля */
value?: string;
/** Плейсхолдер */
placeholder?: string;
/** Атрибут disabled */
disabled?: boolean;
/** Атрибут required */
required?: boolean;
/** Обработчик фокуса инпута */
onFocus?: (event: React.FocusEvent<HTMLInputElement>) => void;
/** Обработчик блюра инпута */
onBlur?: (event: React.FocusEvent<HTMLInputElement>) => void;
/** Обработчик ввода */
onChange?: (event: React.ChangeEvent<HTMLInputElement>) => void;
/** Id компонента для тестов */
dataTestId?: string;
};
Expand All @@ -48,33 +30,21 @@ export const PureInput = React.forwardRef<HTMLInputElement, PureInputProps>(({
size='s',
type='text',
className,
value,
disabled,
required,
placeholder,
onFocus,
onBlur,
onChange,
dataTestId
dataTestId,
...rest
}, ref) => (
<input
// Уберем eslint-disable, как только обновим линтер
// https://github.com/alfa-laboratory/arui-presets-lint/blob/feat/new-rules/eslint/index.js#L87
// eslint-disable-next-line react/jsx-props-no-spreading
{ ...rest }
className={ cn(
className,
styles.component,
styles[size],
{
[styles.disabled]: disabled
}
styles[size]
) }
ref={ ref }
type={ type }
value={ value }
placeholder={ placeholder }
disabled={ disabled }
required={ required }
onChange={ onChange }
onFocus={ onFocus }
onBlur={ onBlur }
data-test-id={ dataTestId }
/>
));

0 comments on commit 27f5bba

Please sign in to comment.