// @flow import type { ElementRef, Node } from 'react'; import React from 'react'; import ReactDOMServer from 'react-dom/server'; import SimpleMDE from 'react-simplemde-editor'; import MarkdownPreview from 'component/common/markdown-preview'; import { openEditorMenu, stopContextMenu } from 'util/context-menu'; import { MAX_CHARACTERS_IN_COMMENT as defaultTextAreaLimit } from 'constants/comments'; import 'easymde/dist/easymde.min.css'; type Props = { name: string, label?: string | Node, render?: () => React$Node, prefix?: string, postfix?: string, error?: string | boolean, helper?: string | React$Node, type?: string, onChange?: any => any, defaultValue?: string | number, placeholder?: string | number, children?: React$Node, stretch?: boolean, affixClass?: string, // class applied to prefix/postfix label autoFocus?: boolean, labelOnLeft: boolean, inputProps?: { disabled?: boolean, }, inputButton?: React$Node, blockWrap: boolean, charCount?: number, textAreaMaxLength?: number, range?: number, min?: number, max?: number, }; 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 { render, label, prefix, postfix, error, helper, name, type, children, stretch, affixClass, autoFocus, inputButton, labelOnLeft, blockWrap, charCount, textAreaMaxLength = defaultTextAreaLimit, ...inputProps } = this.props; const errorMessage = typeof error === 'object' ? error.message : error; const Wrapper = blockWrap ? ({ children: innerChildren }) => {innerChildren} : ({ children: innerChildren }) => {innerChildren}; let input; if (type) { if (type === 'radio') { input = ( ); } else if (type === 'checkbox') { input = (
); } else if (type === 'range') { input = (
); } else if (type === 'select') { input = ( {(label || errorMessage) && ( )} ); } else if (type === 'markdown') { const handleEvents = { contextmenu: openEditorMenu, }; input = (
; return ReactDOMServer.renderToString(preview); }, }} />
); } else if (type === 'textarea') { const hasCharCount = charCount !== undefined && charCount >= 0; const countInfo = hasCharCount && ( {`${charCount || '0'}/${textAreaMaxLength}`} ); input = (