UNPKG

kitten-components

Version:
286 lines (252 loc) 6.62 kB
import React, { Component, Fragment } from 'react' import classNames from 'classnames' import Radium, { StyleRoot, Style } from 'radium' import PropTypes from 'prop-types' import { Marger as MargerBase } from 'kitten/components/layout/marger' import { CommentAvatar } from 'kitten/components/form/comment-avatar' import { ButtonImage } from 'kitten/components/buttons/button-image' import { Button as ButtonBase } from 'kitten/components/buttons/button' import { Text } from 'kitten/components/typography/text' import { ScreenConfig } from 'kitten/constants/screen-config' import COLORS from 'kitten/constants/colors-config' const Marger = Radium(MargerBase) const Button = Radium(ButtonBase) export class CommentForm extends Component { static propTypes = { avatarImgProps: PropTypes.object.isRequired, isDisabled: PropTypes.bool, placeholder: PropTypes.string.isRequired, commentButton: PropTypes.string, error: PropTypes.bool, errorMessage: PropTypes.string, onSubmit: PropTypes.func, defaultValue: PropTypes.string, } static defaultProps = { onSubmit: () => {}, error: false, errorMessage: '', isDisabled: false, commentButton: '', defaultValue: '', } constructor(props) { super(props) this.state = { isFocused: false, value: this.props.defaultValue, height: 'auto', } } handleFocus = () => { this.setState({ isFocused: true }) } handleBlur = () => { this.setState({ isFocused: false }) } handleChange = e => { const element = e.target this.setState( { value: element.value, height: 'auto', }, () => { this.setState({ height: element.scrollHeight, }) }, ) } handleSubmit = () => { this.props.onSubmit(this.state.value) } render() { const { avatarImgProps } = this.props return ( <StyleRoot> <div style={styles.grid}> <CommentAvatar avatarImgProps={avatarImgProps} /> {this.renderInput()} </div> </StyleRoot> ) } renderInput() { const { isDisabled, placeholder, defaultValue, error, errorMessage, } = this.props const styleInput = [ styles.input.textarea, error && styles.input.textarea.error, this.state.isFocused && styles.input.textarea.focus, isDisabled && styles.input.textarea.isDisabled, { height: this.state.height }, ] const styleArrow = [ styles.input.arrow, error && styles.input.arrow.error, this.state.isFocused && styles.input.arrow.focus, ] const textareaClassNames = classNames( 'k-CommentForm__input', 'k-u-weight-light', ) // We are forced to duplicate <Style />, to avoid having space between the class and the pseudo-element. // https://github.com/FormidableLabs/radium/issues/243 return ( <Fragment> <Style scopeSelector=".k-CommentForm__input::-webkit-input-placeholder" rules={{ color: COLORS.font2 }} /> <Style scopeSelector=".k-CommentForm__input:-moz-placeholder" rules={{ color: COLORS.font2 }} /> <Style scopeSelector=".k-CommentForm__input::-moz-placeholder" rules={{ color: COLORS.font2 }} /> <Style scopeSelector=".k-CommentForm__input:-ms-input-placeholder" rules={{ color: COLORS.font2 }} /> <div style={styles.grid.col}> <Marger bottom=".5" style={styles.input}> <textarea className={textareaClassNames} style={styleInput} defaultValue={defaultValue} key="comment-form" disabled={isDisabled} placeholder={placeholder} onFocus={this.handleFocus} onBlur={this.handleBlur} onChange={this.handleChange} rows="1" /> <span style={styleArrow}> <span style={styles.input.arrow.before} /> </span> </Marger> {this.renderError()} {this.renderButton()} </div> </Fragment> ) } renderButton() { if (!this.state.value) return const { commentButton } = this.props return ( <Marger top="2"> <Button type="button" modifier="helium" onClick={this.handleSubmit} style={styles.button.left} > {commentButton} </Button> </Marger> ) } renderError() { const { error, errorMessage } = this.props if (!error) return return ( <Marger top=".5"> <Text color="error" size="micro" weight="regular"> {errorMessage} </Text> </Marger> ) } } const styles = { grid: { display: 'flex', col: { flex: 1, marginLeft: 20, [`@media (min-width: ${ScreenConfig['S'].min}px)`]: { marginLeft: 35, }, }, }, input: { display: 'flex', position: 'relative', textarea: { width: '100%', overflowY: 'hidden', resize: 'none', boxSizing: 'border-box', borderWidth: 2, borderStyle: 'solid', borderColor: COLORS.line1, color: COLORS.font1, padding: 30, fontSize: 14, [`@media (min-width: ${ScreenConfig['S'].min}px)`]: { fontSize: 16, }, focus: { outline: 'none', borderColor: COLORS.line2, color: COLORS.font1, }, isDisabled: { borderColor: COLORS.line1, color: COLORS.font2, backgroundColor: COLORS.line1, }, error: { borderColor: COLORS.error3, color: COLORS.error3, }, }, arrow: { position: 'absolute', top: 20, display: 'block', width: 0, height: 0, borderWidth: 10, borderStyle: 'solid', borderColor: 'transparent', borderRightColor: COLORS.line1, left: -20, [`@media (min-width: ${ScreenConfig['S'].min}px)`]: { top: 35, }, focus: { borderRightColor: COLORS.line2, }, error: { borderRightColor: COLORS.error3, }, before: { position: 'absolute', width: 0, height: 0, marginTop: -10, borderWidth: 10, borderStyle: 'solid', borderColor: 'transparent', borderRightColor: 'white', left: -7, }, }, }, button: { left: { marginRight: 10, }, }, }