/*
Copyright (C) 2017 Cloudbase Solutions SRL
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see .
*/
// @flow
import * as React from 'react'
import styled, { css } from 'styled-components'
import Palette from '../../styleUtils/Palette'
import StyleProps from '../../styleUtils/StyleProps'
import closeImage from './images/close.svg'
import requiredImage from './images/required.svg'
const Wrapper = styled.div`
position: relative;
${props => props.disabledLoading ? StyleProps.animations.disabledLoading : ''}
`
const Required = styled.div`
position: absolute;
width: 8px;
height: 8px;
right: -16px;
top: 12px;
background: url('${requiredImage}') center no-repeat;
`
const getInputWidth = props => {
if (props.width) {
return typeof props.width === 'number' ? `${props.width}px` : props.width
}
if (props.large) {
return `${StyleProps.inputSizes.large.width}px`
}
return `${StyleProps.inputSizes.regular.width}px`
}
const borderColor = (props, defaultColor = Palette.grayscale[3]) => props.highlight ? Palette.alert : defaultColor
const Input = styled.input`
width: ${props => getInputWidth(props)};
height: ${props => props.height || `${StyleProps.inputSizes.regular.height}px`};
line-height: ${props => props.lineHeight || 'normal'};
border-radius: ${StyleProps.borderRadius};
background-color: #FFF;
border: ${props => props.embedded ? 0 : css`1px solid ${props => borderColor(props)}`};
border-top-left-radius: ${props => props.embedded ? 0 : StyleProps.borderRadius};
border-top-right-radius: ${StyleProps.borderRadius};
border-bottom-left-radius: ${props => props.embedded ? 0 : StyleProps.borderRadius};
border-bottom-right-radius: ${StyleProps.borderRadius};
color: ${Palette.black};
padding: 0 8px 0 ${props => props.embedded ? 0 : '16px'};
font-size: inherit;
transition: all ${StyleProps.animations.swift};
box-sizing: border-box;
&:hover {
border-color: ${props => borderColor(props, props.disablePrimary ? null : Palette.primary)};
}
&:focus {
border-color: ${props => borderColor(props, props.disablePrimary ? null : Palette.primary)};
outline: none;
}
&:disabled {
color: ${props => !props.embedded ? Palette.grayscale[3] : 'inherit'};
border-color: ${props => !props.embedded ? Palette.grayscale[0] : 'inherit'};
background-color: ${props => !props.embedded ? Palette.grayscale[0] : 'inherit'};
}
&::placeholder {
color: ${Palette.grayscale[3]};
}
`
export const Close = styled.div`
display: ${props => props.show ? 'block' : 'none'};
width: 16px;
height: 16px;
background: url('${closeImage}') center no-repeat;
position: absolute;
top: 8px;
right: 8px;
cursor: pointer;
`
type Props = {
_ref?: (ref: HTMLElement) => void,
disabled?: boolean,
highlight?: boolean,
large?: boolean,
onChange?: (e: SyntheticInputEvent) => void,
placeholder?: string,
type?: string,
value?: string,
showClose?: boolean,
onCloseClick?: () => void,
embedded?: boolean,
height?: string,
'data-test-id'?: string,
required?: boolean,
disabledLoading?: boolean,
}
const TextInput = (props: Props) => {
const { _ref, value, onChange, showClose, onCloseClick, disabled, disabledLoading } = props
let actualDisabled = disabled || disabledLoading
let input
return (
{ input = ref; if (_ref) _ref(ref) }}
type="text"
value={value}
onChange={onChange}
data-test-id="textInput-input"
{...props}
disabled={actualDisabled}
/>
{props.required ? : null}
{
input.focus()
// $FlowIgnore
if (onChange) onChange({ target: { value: '' } })
if (onCloseClick) onCloseClick()
}}
/>
)
}
export default TextInput