2018-12-06 07:42:30 -08:00
|
|
|
// @flow
|
2019-02-06 19:06:48 -08:00
|
|
|
/* eslint-disable max-len */
|
2019-01-24 06:56:49 -08:00
|
|
|
import React, { type Element } from 'react';
|
2018-12-06 07:42:30 -08:00
|
|
|
import styled from 'styled-components';
|
|
|
|
|
2019-02-10 09:52:34 -08:00
|
|
|
import { appTheme } from '../theme';
|
2019-01-24 06:56:49 -08:00
|
|
|
|
2019-02-06 19:06:48 -08:00
|
|
|
type Props = {
|
|
|
|
inputType?: 'input' | 'textarea',
|
|
|
|
value: string,
|
|
|
|
onChange?: string => void,
|
|
|
|
onFocus?: (SyntheticFocusEvent<HTMLInputElement>) => void,
|
|
|
|
rows?: number,
|
|
|
|
disabled?: boolean,
|
|
|
|
type?: string,
|
|
|
|
step?: number,
|
|
|
|
name?: string,
|
|
|
|
renderRight?: () => Element<*> | null,
|
|
|
|
bgColor?: string,
|
|
|
|
};
|
|
|
|
|
|
|
|
type DefaultStylesProps = PropsWithTheme<{
|
|
|
|
bgColor: ?string,
|
|
|
|
withRightElement: boolean,
|
|
|
|
}>;
|
|
|
|
|
|
|
|
// $FlowFixMe
|
|
|
|
const getDefaultStyles: ($PropertyType<Props, 'inputType'>) => Element<*> = t => styled[t]`
|
|
|
|
border-radius: ${(props: DefaultStylesProps) => props.theme.boxBorderRadius};
|
2018-12-19 13:41:16 -08:00
|
|
|
border: none;
|
2019-02-15 18:59:05 -08:00
|
|
|
background-color: ${(props: DefaultStylesProps) => props.bgColor || props.theme.colors.inputBg};
|
2019-02-06 19:06:48 -08:00
|
|
|
color: ${(props: DefaultStylesProps) => props.theme.colors.text};
|
2018-12-19 13:41:16 -08:00
|
|
|
padding: 15px;
|
2019-02-06 19:06:48 -08:00
|
|
|
padding-right: ${(props: DefaultStylesProps) => (props.withRightElement ? '85px' : '15px')};
|
2018-12-06 07:42:30 -08:00
|
|
|
width: 100%;
|
2018-12-06 12:50:01 -08:00
|
|
|
outline: none;
|
2019-02-06 19:06:48 -08:00
|
|
|
font-family: ${(props: DefaultStylesProps) => props.theme.fontFamily};
|
2019-02-16 19:34:12 -08:00
|
|
|
border: 1px solid ${(props: DefaultStylesProps) => props.theme.colors.inputBorder};
|
2018-12-06 07:42:30 -08:00
|
|
|
|
2018-12-19 13:41:16 -08:00
|
|
|
::placeholder {
|
|
|
|
opacity: 0.5;
|
|
|
|
}
|
2019-02-18 10:04:41 -08:00
|
|
|
|
|
|
|
&:focus,
|
|
|
|
&:active {
|
|
|
|
border-color: ${(props: DefaultStylesProps) => props.theme.colors.inputBorderActive};
|
|
|
|
}
|
2018-12-06 07:42:30 -08:00
|
|
|
`;
|
|
|
|
|
2019-01-24 06:56:49 -08:00
|
|
|
const Wrapper = styled.div`
|
|
|
|
position: relative;
|
|
|
|
`;
|
|
|
|
|
|
|
|
const RightElement = styled.div`
|
|
|
|
position: absolute;
|
|
|
|
top: 15px;
|
|
|
|
right: 15px;
|
|
|
|
`;
|
|
|
|
|
2018-12-19 13:41:16 -08:00
|
|
|
const Input = getDefaultStyles('input');
|
|
|
|
const Textarea = getDefaultStyles('textarea');
|
2018-12-06 07:42:30 -08:00
|
|
|
|
2019-01-12 09:55:53 -08:00
|
|
|
export const InputComponent = ({
|
|
|
|
inputType,
|
2019-01-24 06:56:49 -08:00
|
|
|
bgColor,
|
2019-01-12 09:55:53 -08:00
|
|
|
onChange = () => {},
|
2019-01-24 06:56:49 -08:00
|
|
|
renderRight = () => null,
|
2019-01-12 09:55:53 -08:00
|
|
|
...props
|
|
|
|
}: Props) => {
|
2019-01-24 06:56:49 -08:00
|
|
|
const rightElement = renderRight();
|
2018-12-06 12:50:01 -08:00
|
|
|
const inputTypes = {
|
2018-12-15 07:10:39 -08:00
|
|
|
input: () => (
|
2019-01-24 06:56:49 -08:00
|
|
|
<Input
|
|
|
|
onChange={evt => onChange(evt.target.value)}
|
|
|
|
withRightElement={Boolean(rightElement)}
|
|
|
|
bgColor={bgColor}
|
2019-01-31 08:38:42 -08:00
|
|
|
data-testid='Input'
|
2019-01-24 06:56:49 -08:00
|
|
|
{...props}
|
|
|
|
/>
|
2018-12-15 07:10:39 -08:00
|
|
|
),
|
|
|
|
textarea: () => (
|
2019-02-06 19:06:48 -08:00
|
|
|
<Textarea
|
|
|
|
onChange={evt => onChange(evt.target.value)}
|
|
|
|
bgColor={bgColor}
|
|
|
|
data-testid='Textarea'
|
|
|
|
{...props}
|
|
|
|
/>
|
2018-12-15 07:10:39 -08:00
|
|
|
),
|
2018-12-06 12:50:01 -08:00
|
|
|
};
|
|
|
|
|
|
|
|
if (!Object.keys(inputTypes).find(key => key === inputType)) {
|
2018-12-07 05:45:20 -08:00
|
|
|
throw new Error(`Invalid input type: ${String(inputType)}`);
|
2018-12-06 07:42:30 -08:00
|
|
|
}
|
|
|
|
|
2019-01-24 06:56:49 -08:00
|
|
|
return (
|
|
|
|
<Wrapper>
|
|
|
|
{inputTypes[inputType || 'input']()}
|
|
|
|
{rightElement && <RightElement>{rightElement}</RightElement>}
|
|
|
|
</Wrapper>
|
|
|
|
);
|
2018-12-06 07:42:30 -08:00
|
|
|
};
|
|
|
|
|
|
|
|
InputComponent.defaultProps = {
|
|
|
|
inputType: 'input',
|
|
|
|
rows: 4,
|
|
|
|
disabled: false,
|
|
|
|
type: 'text',
|
2019-01-23 09:04:57 -08:00
|
|
|
name: '',
|
2019-01-24 06:56:49 -08:00
|
|
|
renderRight: () => null,
|
|
|
|
onChange: () => {},
|
|
|
|
onFocus: () => {},
|
|
|
|
step: 1,
|
2019-02-15 18:59:05 -08:00
|
|
|
bgColor: appTheme.colors.inputBg,
|
2018-12-06 07:42:30 -08:00
|
|
|
};
|