// @flow import 'easymde/dist/easymde.min.css'; import { FF_MAX_CHARS_DEFAULT } from 'constants/form-field'; import React from 'react'; import type { ElementRef, Node } from 'react'; type Props = { affixClass?: string, // class applied to prefix/postfix label autoFocus?: boolean, blockWrap: boolean, charCount?: number, children?: React$Node, defaultValue?: string | number, disabled?: boolean, error?: string | boolean, helper?: string | React$Node, inputButton?: React$Node, label?: string | Node, labelOnLeft: boolean, max?: number, min?: number, name: string, placeholder?: string | number, postfix?: string, prefix?: string, range?: number, readOnly?: boolean, stretch?: boolean, textAreaMaxLength?: number, type?: string, value?: string | number, onChange?: (any) => any, render?: () => React$Node, }; export class FormField extends React.PureComponent { static defaultProps = { labelOnLeft: false, blockWrap: true }; input: { current: ElementRef }; constructor(props: Props) { super(props); this.input = React.createRef(); } componentDidMount() { const { autoFocus } = this.props; const input = this.input.current; if (input && autoFocus) input.focus(); } render() { const { affixClass, autoFocus, blockWrap, charCount, children, error, helper, inputButton, label, labelOnLeft, name, postfix, prefix, stretch, textAreaMaxLength, type, render, ...inputProps } = this.props; const errorMessage = typeof error === 'object' ? error.message : error; // Ideally, the character count should (and can) be appended to the // SimpleMDE's "options::status" bar. However, I couldn't figure out how // to pass the current value to it's callback, nor query the current // text length from the callback. So, we'll use our own widget. const hasCharCount = charCount !== undefined && charCount >= 0; const countInfo = hasCharCount && textAreaMaxLength !== undefined && ( {`${charCount || '0'}/${textAreaMaxLength}`} ); const Wrapper = blockWrap ? ({ children: innerChildren }) => {innerChildren} : ({ children: innerChildren }) => {innerChildren}; const inputSimple = (type: string) => ( <> ); const inputSelect = (selectClass: string) => ( {(label || errorMessage) && ( )} ); const input = () => { switch (type) { case 'radio': return {inputSimple('radio')}; case 'checkbox': return
{inputSimple('checkbox')}
; case 'range': return
{inputSimple('range')}
; case 'select': return inputSelect(''); case 'select-tiny': return inputSelect('select--slim'); case 'textarea': return ( {label && (
)}