Skip to content

Commit

Permalink
feat(inputs): improve components, update styles & props
Browse files Browse the repository at this point in the history
  • Loading branch information
reme3d2y committed Mar 4, 2020
1 parent b60d64c commit 98ff5dd
Show file tree
Hide file tree
Showing 6 changed files with 80 additions and 50 deletions.
12 changes: 11 additions & 1 deletion packages/base-input/src/Component.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -66,9 +66,13 @@
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
}

.input::placeholder {
.input::placeholder,
.input[placeholder] {
text-overflow: ellipsis;
transition: opacity .2s ease-in-out, color .2s ease-in-out;
}

.input::placeholder {
color: var(--base-input-placeholder-color);
}

Expand All @@ -91,6 +95,12 @@
transition-timing-function: cubic-bezier(.25, .1, .25, 1);
}

.addons {
display: flex;
flex-shrink: 0;
align-items: center;
}

.s {
padding: 14px var(--base-input-side-paddings) 13px var(--base-input-side-paddings);
}
Expand Down
1 change: 1 addition & 0 deletions packages/base-input/src/Component.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ export const BaseInputStory = () => {

return (
<BaseInput
type={ select('type', ['text', 'number', 'card', 'email', 'file', 'hidden', 'money', 'password', 'tel', 'text'], 'text') }
size={ select('size', ['s', 'm', 'l'], 's') }
disabled={ boolean('Disabled', false) }
placeholder={ text('placeholder', '') }
Expand Down
26 changes: 13 additions & 13 deletions packages/base-input/src/Component.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
* Vendor
*/

import React, { useRef, useState } from 'react';
import React, { useState } from 'react';
import cn from 'classnames';

/**
Expand All @@ -20,6 +20,8 @@ import styles from './Component.module.css';
export type BaseInputProps = {
/** Размер компонента */
size?: 's' | 'm' | 'l';
/** Атрибут type */
type?: 'number' | 'card' | 'email' | 'file' | 'hidden' | 'money' | 'password' | 'tel' | 'text';
/** Класс компонента */
className?: string;
/** Класс компонента */
Expand All @@ -46,7 +48,7 @@ export type BaseInputProps = {
onFocus?: (event?: React.FocusEvent<HTMLInputElement>) => void;
/** Обработчик блюра инпута */
onBlur?: (event?: React.FocusEvent<HTMLInputElement>) => void;
/** */
/** Обработчик ввода */
onChange?: (event?: React.ChangeEvent<HTMLInputElement>) => void;
/** Id компонента для тестов */
dataTestId?: string;
Expand All @@ -56,8 +58,9 @@ export type BaseInputProps = {
* Expo
*/

export const BaseInput: React.FC<BaseInputProps> = ({
export const BaseInput = React.forwardRef<HTMLInputElement, BaseInputProps>(({
size='s',
type='text',
className,
innerClassName,
inputClassName,
Expand All @@ -72,10 +75,8 @@ export const BaseInput: React.FC<BaseInputProps> = ({
onFocus,
onBlur,
onChange,
dataTestId,
...restProps
}) => {
const inputRef = useRef(null);
dataTestId
}, ref) => {
const [focused, setFocused] = useState(false);
const [filled, setFilled] = useState(!!value);

Expand Down Expand Up @@ -126,14 +127,15 @@ export const BaseInput: React.FC<BaseInputProps> = ({
) }

{ leftAddons && (
<div className={ cn(styles.leftAddons) }>
<div className={ cn(styles.addons, styles.leftAddons) }>
{ leftAddons }
</div>
) }

<input
className={ cn(styles.input, styles[size], inputClassName) }
ref={ inputRef }
ref={ ref }
type={ type }
value={ value }
placeholder={ placeholder }
disabled={ disabled }
Expand All @@ -142,12 +144,10 @@ export const BaseInput: React.FC<BaseInputProps> = ({
onFocus={ handleInputFocus }
onBlur={ handleInputBlur }
data-test-id={ dataTestId }
// REVIEW: Думаю в данном кейсе это нормальное решение
{ ...restProps }
/>

{ rightAddons && (
<div className={ cn(styles.rightAddons) }>
<div className={ cn(styles.addons, styles.rightAddons) }>
{ rightAddons }
</div>
) }
Expand All @@ -156,4 +156,4 @@ export const BaseInput: React.FC<BaseInputProps> = ({
{ children }
</div>
);
};
});
11 changes: 8 additions & 3 deletions packages/input/src/Component.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,15 @@
box-sizing: border-box;
}

.inner {}

.input {}

.error-icon {
margin-left: var(--gap-s);
margin-right: var(--gap-s);
}

.sub {
display: block;
font-size: 14px;
Expand All @@ -30,6 +37,4 @@
.has-error .inner {
box-shadow: inset 0 -1px var(--input-error-color);
border-bottom-color: var(--input-error-color);
}

.left-addons {}
}
1 change: 1 addition & 0 deletions packages/input/src/Component.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ export const InputStory = () => {
return (
<Input
size={ select('size', ['s', 'm', 'l'], 's') }
type={ select('type', ['text', 'number', 'card', 'email', 'file', 'hidden', 'money', 'password', 'tel', 'text'], 'text') }
disabled={ boolean('Disabled', false) }
placeholder={ text('placeholder', '') }
label={ text('label', '') }
Expand Down
79 changes: 46 additions & 33 deletions packages/input/src/Component.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,58 +27,71 @@ type InputProps = BaseInputProps & {
* Expo
*/

// TODO:
const errorIcon = (
<svg width='18' height='18' viewBox='0 0 18 18' fill='none' xmlns='http://www.w3.org/2000/svg'>
<path d='M16.8709 14.432L9.80088 2.61199C9.71724 2.47327 9.59918 2.35852 9.45813 2.27886C9.31709 2.19921 9.15786 2.15735 8.99588 2.15735C8.8339 2.15735 8.67467 2.19921 8.53362 2.27886C8.39258 2.35852 8.27452 2.47327 8.19088 2.61199L1.13088 14.432C1.04895 14.5739 1.00552 14.7347 1.00489 14.8985C1.00426 15.0623 1.04647 15.2235 1.12731 15.366C1.20816 15.5085 1.32484 15.6273 1.46579 15.7108C1.60674 15.7943 1.76707 15.8395 1.93088 15.842H16.0609C16.2259 15.8426 16.3881 15.7993 16.5309 15.7165C16.6736 15.6337 16.7918 15.5145 16.8732 15.3709C16.9546 15.2274 16.9964 15.0648 16.9942 14.8998C16.9921 14.7348 16.9461 14.5733 16.8609 14.432H16.8709ZM9.87088 13.242C9.87088 13.4489 9.7887 13.6473 9.64242 13.7935C9.49614 13.9398 9.29775 14.022 9.09088 14.022H8.86088C8.75845 14.022 8.65702 14.0018 8.56239 13.9626C8.46775 13.9234 8.38177 13.866 8.30934 13.7935C8.23691 13.7211 8.17945 13.6351 8.14025 13.5405C8.10105 13.4458 8.08088 13.3444 8.08088 13.242V13.002C8.08088 12.572 8.43088 12.222 8.86088 12.222H9.13088C9.56188 12.222 9.91088 12.572 9.91088 13.002L9.87088 13.242ZM9.64088 11.242H8.31088L8.09088 5.80199H9.91088L9.64088 11.242Z' fill='#EF3124'/>
</svg>
);

export const Input: React.FC<InputProps> = ({
size,
children,
size='s',
type='text',
className,
innerClassName,
inputClassName,
value,
label,
placeholder,
hint,
error,
disabled,
onChange,
required,
placeholder,
label,
leftAddons,
rightAddons,
children,
onFocus,
onBlur,
dataTestId
onChange,
dataTestId,
hint,
error
}) => {
const hasHint = !!hint;
const hasError = !!error;
const hasSub = hasHint || hasError;

return (
<div
<BaseInput
className={ cn(
styles.component,
{
[styles.hasError]: hasError
},
className
) }
data-test-id={ dataTestId }
innerClassName={ cn(styles.inner) }
inputClassName={ cn(styles.input) }
type={ type }
required={ required }
rightAddons={
hasError ? <div className={ cn(styles.errorIcon) }>{ errorIcon }</div> : rightAddons
}
leftAddons={ leftAddons }
size={ size }
value={ value }
label={ label }
placeholder={ placeholder }
disabled={ disabled }
onChange={ onChange }
onFocus={ onFocus }
onBlur={ onBlur }
dataTestId={ dataTestId }
>
<BaseInput
className={ cn(styles.baseInput) }
innerClassName={ cn(styles.inner, innerClassName) }
inputClassName={ cn(styles.input, inputClassName) }
size={ size }
value={ value }
label={ label }
placeholder={ placeholder }
disabled={ disabled }
onChange={ onChange }
onFocus={ onFocus }
onBlur={ onBlur }
>
{ hasSub && (
<span className={ cn(styles.sub) }>
{ (hasHint && !hasError) && hint }
{ hasError && error }
</span>
) }
</BaseInput>
</div>
{ hasSub && (
<span className={ cn(styles.sub) }>
{ (hasHint && !hasError) && hint }
{ hasError && error }
</span>
) }

{ children }
</BaseInput>
);
};

0 comments on commit 98ff5dd

Please sign in to comment.