2017-05-18 21:21:33 +03:00
|
|
|
import React from 'react';
|
2017-10-09 21:01:34 +03:00
|
|
|
import { Subscriber } from 'joy-react-broadcast';
|
2017-05-18 21:21:33 +03:00
|
|
|
import styled, { css } from 'styled-components';
|
|
|
|
import remcalc from 'remcalc';
|
2017-09-20 12:30:53 +03:00
|
|
|
import is, { isNot } from 'styled-is';
|
2017-10-09 21:01:34 +03:00
|
|
|
import PropTypes from 'prop-types';
|
|
|
|
|
|
|
|
import typography from '../../typography';
|
|
|
|
import { borderRadius, border } from '../../boxes';
|
2017-05-18 21:21:33 +03:00
|
|
|
|
|
|
|
const colorWithDisabled = props =>
|
|
|
|
props.disabled ? props.theme.disabled : props.theme.text;
|
|
|
|
|
|
|
|
const colorWithDefaultValue = props =>
|
|
|
|
props.value === props.defaultValue
|
|
|
|
? props.theme.disabled
|
|
|
|
: colorWithDisabled(props);
|
|
|
|
|
|
|
|
const color = props =>
|
|
|
|
props.defaultValue ? colorWithDefaultValue(props) : colorWithDisabled(props);
|
|
|
|
|
2017-11-09 13:27:32 +02:00
|
|
|
const height = props =>
|
|
|
|
props.multiple ? 'auto' : props.textarea ? remcalc(96) : remcalc(48);
|
2017-05-18 21:21:33 +03:00
|
|
|
|
|
|
|
const paddingTop = props => (props.multiple ? remcalc(20) : remcalc(13));
|
|
|
|
|
|
|
|
const style = css`
|
|
|
|
box-sizing: border-box;
|
2017-11-16 12:47:32 +02:00
|
|
|
${typography.loadedFontFamily};
|
2017-05-18 21:21:33 +03:00
|
|
|
width: 100%;
|
|
|
|
height: ${height};
|
2017-11-09 13:27:32 +02:00
|
|
|
min-height: ${height};
|
2017-05-18 21:21:33 +03:00
|
|
|
|
|
|
|
margin-bottom: ${remcalc(8)};
|
|
|
|
margin-top: ${remcalc(8)};
|
|
|
|
padding: ${paddingTop} ${remcalc(18)};
|
|
|
|
|
|
|
|
border-radius: ${borderRadius};
|
|
|
|
background-color: ${props => props.theme.white};
|
|
|
|
border: ${border.unchecked};
|
2017-11-09 13:27:32 +02:00
|
|
|
color: ${color};
|
2017-05-18 21:21:33 +03:00
|
|
|
|
2017-11-16 12:47:32 +02:00
|
|
|
&::-webkit-input-placeholder {
|
|
|
|
color: rgba(73, 73, 73, 0.5);
|
|
|
|
}
|
|
|
|
&::-moz-placeholder {
|
|
|
|
color: rgba(73, 73, 73, 0.5);
|
|
|
|
}
|
|
|
|
&:-ms-input-placeholder {
|
|
|
|
color: rgba(73, 73, 73, 0.5);
|
|
|
|
}
|
|
|
|
|
2017-11-22 14:13:33 +02:00
|
|
|
&:invalid {
|
|
|
|
box-shadow: none;
|
|
|
|
}
|
|
|
|
|
2017-10-11 17:56:24 +03:00
|
|
|
${is('disabled')`
|
2017-11-09 13:27:32 +02:00
|
|
|
background-color: ${props => props.theme.disabled};
|
|
|
|
color: ${props => props.theme.textDisabled};
|
|
|
|
|
2017-10-11 17:56:24 +03:00
|
|
|
::-webkit-input-placeholder { /* WebKit, Blink, Edge */
|
2017-11-09 13:27:32 +02:00
|
|
|
color: ${props => props.theme.placeholder};
|
2017-10-11 17:56:24 +03:00
|
|
|
}
|
2017-11-09 13:27:32 +02:00
|
|
|
|
2017-10-11 17:56:24 +03:00
|
|
|
::-moz-placeholder { /* Mozilla Firefox 19+ */
|
2017-10-17 13:01:57 +03:00
|
|
|
color: ${props => props.theme.placeholder};
|
2017-10-11 17:56:24 +03:00
|
|
|
}
|
2017-11-09 13:27:32 +02:00
|
|
|
|
2017-10-11 17:56:24 +03:00
|
|
|
:-ms-input-placeholder { /* Internet Explorer 10-11 */
|
2017-10-17 13:01:57 +03:00
|
|
|
color: ${props => props.theme.placeholder};
|
2017-10-11 17:56:24 +03:00
|
|
|
}
|
|
|
|
`};
|
|
|
|
|
2017-11-09 13:27:32 +02:00
|
|
|
&:disabled {
|
|
|
|
background-color: ${props => props.theme.disabled};
|
|
|
|
color: ${props => props.theme.textDisabled};
|
|
|
|
|
|
|
|
::-webkit-input-placeholder {
|
|
|
|
/* WebKit, Blink, Edge */
|
|
|
|
color: ${props => props.theme.placeholder};
|
|
|
|
}
|
|
|
|
|
|
|
|
::-moz-placeholder {
|
|
|
|
/* Mozilla Firefox 19+ */
|
|
|
|
color: ${props => props.theme.placeholder};
|
|
|
|
}
|
|
|
|
|
|
|
|
:-ms-input-placeholder {
|
|
|
|
/* Internet Explorer 10-11 */
|
|
|
|
color: ${props => props.theme.placeholder};
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-11-16 12:47:32 +02:00
|
|
|
${is('small')`
|
|
|
|
width: ${remcalc(120)}
|
|
|
|
`};
|
|
|
|
|
|
|
|
${is('xSmall')`
|
|
|
|
width: ${remcalc(80)}
|
|
|
|
`};
|
|
|
|
|
2017-05-18 21:21:33 +03:00
|
|
|
${is('error')`
|
2017-07-11 17:11:52 +03:00
|
|
|
border-color: ${props => props.theme.redDark}
|
2017-05-18 21:21:33 +03:00
|
|
|
`};
|
2017-11-22 14:13:33 +02:00
|
|
|
|
|
|
|
${is('embedded')`
|
|
|
|
border: none;
|
|
|
|
border-bottom: ${remcalc(1)} solid ${props => props.theme.text};
|
|
|
|
border-radius: 0;
|
|
|
|
background: transparent;
|
|
|
|
padding: 0;
|
|
|
|
padding-right: ${remcalc(12)};
|
|
|
|
display: inline;
|
|
|
|
height: ${remcalc(24)};
|
|
|
|
appearance: none;
|
|
|
|
min-height: 0;
|
|
|
|
`};
|
2017-05-18 21:21:33 +03:00
|
|
|
|
|
|
|
${is('warning')`
|
2017-07-11 17:11:52 +03:00
|
|
|
border-color: ${props => props.theme.orangeDark}
|
2017-05-18 21:21:33 +03:00
|
|
|
`};
|
|
|
|
|
2017-11-16 12:47:32 +02:00
|
|
|
${is('wrapped')`
|
|
|
|
margin: 0;
|
|
|
|
border: none;
|
|
|
|
width: ${remcalc(120)};
|
|
|
|
`};
|
|
|
|
|
2017-05-18 21:21:33 +03:00
|
|
|
${is('success')`
|
2017-07-11 17:11:52 +03:00
|
|
|
border-color: ${props => props.theme.greenDark}
|
2017-05-18 21:21:33 +03:00
|
|
|
`};
|
|
|
|
|
2017-09-20 12:30:53 +03:00
|
|
|
${isNot('fluid')`
|
|
|
|
max-width: ${remcalc(300)};
|
|
|
|
`};
|
|
|
|
|
|
|
|
${is('mono')`
|
|
|
|
font-family: monospace;
|
|
|
|
`};
|
|
|
|
|
|
|
|
${is('marginless')`
|
|
|
|
margin: 0;
|
|
|
|
`};
|
|
|
|
|
2017-10-13 22:57:35 +03:00
|
|
|
${isNot('value')`
|
|
|
|
text-overflow: ellipsis;
|
|
|
|
`};
|
|
|
|
|
2017-11-09 13:27:32 +02:00
|
|
|
${is('resize')`
|
|
|
|
resize: ${props => props.resize};
|
|
|
|
`};
|
|
|
|
|
2017-05-18 21:21:33 +03:00
|
|
|
font-size: ${remcalc(15)};
|
|
|
|
line-height: normal !important;
|
|
|
|
|
|
|
|
${typography.normal};
|
|
|
|
font-style: normal;
|
|
|
|
font-stretch: normal;
|
|
|
|
|
|
|
|
appearance: none;
|
|
|
|
outline: 0;
|
|
|
|
|
|
|
|
&:focus {
|
|
|
|
border-color: ${props => props.theme.primary};
|
|
|
|
outline: 0;
|
|
|
|
}
|
|
|
|
`;
|
|
|
|
|
2017-11-09 13:27:32 +02:00
|
|
|
const BaseInput = Component => ({ resize, type, ...props }) => {
|
2017-05-18 21:21:33 +03:00
|
|
|
const render = value => {
|
|
|
|
const _value = value || {};
|
|
|
|
const { input = {}, meta = {}, id = '' } = _value;
|
|
|
|
|
|
|
|
const hasError = Boolean(props.error || _value.error || meta.error);
|
|
|
|
const hasWarning = Boolean(props.warning || _value.warning || meta.warning);
|
|
|
|
const hasSuccess = Boolean(props.success || _value.success || meta.success);
|
|
|
|
|
2017-11-09 13:27:32 +02:00
|
|
|
const textarea = type === 'textarea';
|
2017-09-20 12:30:53 +03:00
|
|
|
const marginless = Boolean(props.marginless);
|
|
|
|
const fluid = Boolean(props.fluid);
|
|
|
|
const mono = Boolean(props.mono);
|
|
|
|
|
2017-05-18 21:21:33 +03:00
|
|
|
return (
|
|
|
|
<Component
|
|
|
|
{...props}
|
|
|
|
{...input}
|
|
|
|
id={id}
|
|
|
|
error={hasError}
|
|
|
|
warning={hasWarning}
|
|
|
|
success={hasSuccess}
|
2017-09-20 12:30:53 +03:00
|
|
|
fluid={fluid}
|
|
|
|
marginless={marginless}
|
|
|
|
mono={mono}
|
2017-11-09 13:27:32 +02:00
|
|
|
resize={textarea ? resize : null}
|
|
|
|
textarea={textarea}
|
2017-05-18 21:21:33 +03:00
|
|
|
/>
|
|
|
|
);
|
|
|
|
};
|
|
|
|
|
2017-08-28 22:21:08 +03:00
|
|
|
return <Subscriber channel="input-group">{render}</Subscriber>;
|
2017-05-18 21:21:33 +03:00
|
|
|
};
|
|
|
|
|
|
|
|
BaseInput.propTypes = {
|
|
|
|
error: PropTypes.bool,
|
|
|
|
warning: PropTypes.bool
|
|
|
|
};
|
|
|
|
|
|
|
|
export default BaseInput;
|
|
|
|
|
|
|
|
export const Stylable = Component => {
|
2017-07-26 15:50:49 +03:00
|
|
|
const stylable =
|
|
|
|
typeof Component === 'string' ? styled[Component] : styled(Component);
|
2017-05-18 21:21:33 +03:00
|
|
|
|
|
|
|
return stylable`
|
|
|
|
${style}
|
|
|
|
`;
|
|
|
|
};
|