/* 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 . */ import * as React from "react"; import styled, { css } from "styled-components"; import { ThemePalette, ThemeProps } from "@src/components/Theme"; import closeImage from "./images/close.svg"; import requiredImage from "./images/required.svg"; const Wrapper = styled.div` position: relative; ${props => props.disabledLoading ? ThemeProps.animations.disabledLoading : ""} `; const Required = styled.div` position: absolute; width: 8px; height: 8px; right: ${props => props.right}px; top: 12px; background: url("${requiredImage}") center no-repeat; `; const getInputWidth = (props: any) => { if (props.width) { return typeof props.width === "number" ? `${props.width}px` : props.width; } if (props.large) { return `${ThemeProps.inputSizes.large.width}px`; } return `${ThemeProps.inputSizes.regular.width}px`; }; const borderColor = ( props: any, defaultColor: string | undefined | null = ThemePalette.grayscale[3] ) => (props.highlight ? ThemePalette.alert : defaultColor); const Input = styled.input` width: ${props => getInputWidth(props)}; height: ${props => props.height || `${ThemeProps.inputSizes.regular.height}px`}; line-height: ${props => props.lineHeight || "normal"}; border-radius: ${ThemeProps.borderRadius}; background-color: #fff; border: ${props => props.embedded ? 0 : css`1px solid ${borderColor(props)}`}; border-top-left-radius: ${props => props.embedded ? 0 : ThemeProps.borderRadius}; border-top-right-radius: ${ThemeProps.borderRadius}; border-bottom-left-radius: ${props => props.embedded ? 0 : ThemeProps.borderRadius}; border-bottom-right-radius: ${ThemeProps.borderRadius}; color: ${ThemePalette.black}; padding: 0 8px 0 ${props => (props.embedded ? 0 : "16px")}; font-size: inherit; transition: all ${ThemeProps.animations.swift}; box-sizing: border-box; &:hover { border-color: ${props => borderColor(props, props.disablePrimary ? null : ThemePalette.primary)}; } &:focus { border-color: ${props => borderColor(props, props.disablePrimary ? null : ThemePalette.primary)}; outline: none; } &:disabled { color: ${props => !props.embedded ? ThemePalette.grayscale[3] : "inherit"}; border-color: ${props => !props.embedded ? ThemePalette.grayscale[0] : "inherit"}; background-color: ${props => !props.embedded ? ThemePalette.grayscale[0] : "inherit"}; } &::placeholder { color: ${ThemePalette.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: React.ChangeEvent | { target: { value: string } } ) => void; placeholder?: string; type?: string; value?: string; showClose?: boolean; onCloseClick?: () => void; embedded?: boolean; width?: string | number; height?: string; style?: React.CSSProperties; lineHeight?: string; required?: boolean; disabledLoading?: boolean; onInputKeyDown?: (e: React.KeyboardEvent) => void; onFocus?: () => void; onBlur?: () => void; autoComplete?: string; }; const TextInput = (props: Props) => { const { // eslint-disable-next-line @typescript-eslint/naming-convention _ref, value, onChange, showClose, onCloseClick, disabled, disabledLoading, onInputKeyDown, ...otherProps } = props; const actualDisabled = disabled || disabledLoading; let input: { focus: () => void }; return ( { input = ref; if (_ref) _ref(ref); }} type="text" value={value} onChange={onChange} // eslint-disable-next-line react/jsx-props-no-spreading {...otherProps} onKeyDown={onInputKeyDown} disabled={actualDisabled} /> {props.required ? : null} { input.focus(); if (onChange) onChange({ target: { value: "" } }); if (onCloseClick) onCloseClick(); }} /> ); }; export default TextInput;