lbry-desktop/src/renderer/component/common/form-components/form-field.jsx

121 lines
3.3 KiB
React
Raw Normal View History

2018-03-26 23:32:43 +02:00
// @flow
import * as React from 'react';
import ReactDOMServer from 'react-dom/server';
2018-03-26 23:32:43 +02:00
import classnames from 'classnames';
import MarkdownPreview from 'component/common/markdown-preview';
2018-03-26 23:32:43 +02:00
import SimpleMDE from 'react-simplemde-editor';
2018-06-13 07:20:53 +02:00
import 'simplemde/dist/simplemde.min.css';
2018-06-15 22:11:02 +02:00
import Toggle from 'react-toggle';
2018-03-26 23:32:43 +02:00
type Props = {
name: string,
label?: string,
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,
2018-06-14 22:10:50 +02:00
affixClass?: string, // class applied to prefix/postfix label
2018-06-15 22:11:02 +02:00
useToggle?: boolean,
2018-03-26 23:32:43 +02:00
};
export class FormField extends React.PureComponent<Props> {
render() {
const {
render,
label,
prefix,
postfix,
error,
helper,
name,
type,
children,
stretch,
2018-06-14 22:10:50 +02:00
affixClass,
2018-06-15 22:11:02 +02:00
useToggle,
2018-03-26 23:32:43 +02:00
...inputProps
} = this.props;
const errorMessage = typeof error === 'object' ? error.message : error;
2018-03-26 23:32:43 +02:00
let input;
if (type) {
if (type === 'select') {
input = (
2018-05-25 06:36:43 +02:00
<select className="form-field__select" id={name} {...inputProps}>
2018-03-26 23:32:43 +02:00
{children}
</select>
);
} else if (type === 'markdown') {
input = (
<div className="form-field--SimpleMDE">
<SimpleMDE
{...inputProps}
type="textarea"
options={{
2018-06-13 07:20:53 +02:00
hideIcons: ['heading', 'image', 'fullscreen', 'side-by-side'],
previewRender(plainText) {
const preview = <MarkdownPreview content={plainText} />;
return ReactDOMServer.renderToString(preview);
},
}}
2018-03-26 23:32:43 +02:00
/>
</div>
);
2018-04-06 07:15:29 +02:00
} else if (type === 'textarea') {
input = <textarea type={type} id={name} {...inputProps} />;
2018-06-15 22:11:02 +02:00
} else if (type === 'checkbox' && useToggle) {
input = <Toggle id={name} {...inputProps} />;
2018-03-26 23:32:43 +02:00
} else {
input = <input type={type} id={name} {...inputProps} />;
}
}
return (
<div
className={classnames('form-field', {
'form-field--stretch': stretch || type === 'markdown',
2018-06-21 04:22:13 +02:00
'form-field--disabled': inputProps.disabled,
2018-03-26 23:32:43 +02:00
})}
>
{(label || errorMessage) && (
2018-03-26 23:32:43 +02:00
<label
className={classnames('form-field__label', { 'form-field__error': errorMessage })}
2018-03-26 23:32:43 +02:00
htmlFor={name}
>
{!errorMessage && label}
{errorMessage}
2018-03-26 23:32:43 +02:00
</label>
)}
<div
className={classnames('form-field__input', {
'form-field--auto-height': type === 'markdown',
})}
>
2018-03-26 23:32:43 +02:00
{prefix && (
2018-06-14 22:10:50 +02:00
<label htmlFor={name} className={classnames('form-field__prefix', affixClass)}>
2018-03-26 23:32:43 +02:00
{prefix}
</label>
)}
{input}
{postfix && (
2018-06-14 22:10:50 +02:00
<label htmlFor={name} className={classnames('form-field__postfix', affixClass)}>
2018-03-26 23:32:43 +02:00
{postfix}
</label>
)}
</div>
2018-06-13 07:20:53 +02:00
{helper && <div className="form-field__help">{helper}</div>}
2018-03-26 23:32:43 +02:00
</div>
);
}
}
export default FormField;