import React, { useState } from 'react'; import ImmutablePureComponent from 'react-immutable-pure-component'; import PropTypes from 'prop-types'; import classNames from 'classnames'; import { v4 as uuidv4 } from 'uuid'; import { SketchPicker } from 'react-color'; import Overlay from 'react-overlays/lib/Overlay'; import { isMobile } from '../../is_mobile'; import detectPassiveEvents from 'detect-passive-events'; const FormPropTypes = { label: PropTypes.oneOfType([ PropTypes.string, PropTypes.object, PropTypes.node, ]), }; const listenerOptions = detectPassiveEvents.hasSupport ? { passive: true } : false; export const InputContainer = (props) => { const containerClass = classNames('input', { 'with_label': props.label, 'required': props.required, 'boolean': props.type === 'checkbox', }, props.extraClass); return (
{props.children} {props.hint && {props.hint}}
); }; InputContainer.propTypes = { label: FormPropTypes.label, hint: PropTypes.node, required: PropTypes.bool, type: PropTypes.string, children: PropTypes.node, extraClass: PropTypes.string, }; export const LabelInputContainer = ({ label, children, ...props }) => { const [id] = useState(uuidv4()); const childrenWithProps = React.Children.map(children, child => ( React.cloneElement(child, { id: id, key: id }) )); return (
{childrenWithProps}
); }; LabelInputContainer.propTypes = { label: FormPropTypes.label.isRequired, children: PropTypes.node, }; export const LabelInput = ({ label, dispatch, ...props }) => ( ); LabelInput.propTypes = { label: FormPropTypes.label.isRequired, dispatch: PropTypes.func, }; export class SimpleInput extends ImmutablePureComponent { static propTypes = { label: FormPropTypes.label, hint: PropTypes.node, } render() { const { hint, ...props } = this.props; const Input = this.props.label ? LabelInput : 'input'; return ( ); } } export class SimpleForm extends ImmutablePureComponent { static propTypes = { children: PropTypes.node, }; static defaultProps = { acceptCharset: 'UTF-8', onSubmit: e => {}, }; onSubmit = e => { this.props.onSubmit(e); e.preventDefault(); } render() { const { children, onSubmit, ...props } = this.props; return (
{children}
); } } export const FieldsGroup = ({ children }) => (
{children}
); FieldsGroup.propTypes = { children: PropTypes.node, }; export const Checkbox = props => ( ); export class RadioGroup extends ImmutablePureComponent { static propTypes = { label: FormPropTypes.label, children: PropTypes.node, } render() { const { label, children, onChange } = this.props; const childrenWithProps = React.Children.map(children, child => React.cloneElement(child, { onChange }) ); return (
    {childrenWithProps}
); } } export class ColorPicker extends React.PureComponent { static propTypes = { style: PropTypes.object, value: PropTypes.string.isRequired, onChange: PropTypes.func.isRequired, onClose: PropTypes.func, } handleDocumentClick = e => { if (this.node && !this.node.contains(e.target)) { this.props.onClose(); } } componentDidMount() { document.addEventListener('click', this.handleDocumentClick, false); document.addEventListener('touchend', this.handleDocumentClick, listenerOptions); } componentWillUnmount() { document.removeEventListener('click', this.handleDocumentClick, false); document.removeEventListener('touchend', this.handleDocumentClick, listenerOptions); } setRef = c => { this.node = c; } render() { const { style, value, onChange } = this.props; let margin_left_picker = isMobile(window.innerWidth) ? '20px' : '12px'; return (
); } } export class ColorWithPicker extends ImmutablePureComponent { static propTypes = { buttonId: PropTypes.string.isRequired, label: FormPropTypes.label, value: PropTypes.string.isRequired, onChange: PropTypes.func.isRequired, } onToggle = (e) => { if (!e.key || e.key === 'Enter') { if (this.state.active) { this.onHidePicker(); } else { this.onShowPicker(e); } } } state = { active: false, placement: null, } onHidePicker = () => { this.setState({ active: false }); } onShowPicker = ({ target }) => { this.setState({ active: true }); this.setState({ placement: isMobile(window.innerWidth) ? 'bottom' : 'right' }); } render() { const { buttonId, label, value, onChange } = this.props; const { active, placement } = this.state; return (
); } } export class RadioItem extends ImmutablePureComponent { static propTypes = { label: FormPropTypes.label, hint: PropTypes.node, value: PropTypes.string.isRequired, checked: PropTypes.bool.isRequired, onChange: PropTypes.func, dispatch: PropTypes.func, } static defaultProps = { checked: false, } state = { id: uuidv4(), } render() { const { label, hint, dispatch, ...props } = this.props; const { id } = this.state; return (
  • ); } } export class SelectDropdown extends ImmutablePureComponent { static propTypes = { label: FormPropTypes.label, items: PropTypes.object.isRequired, } render() { const { label, items, ...props } = this.props; const optionElems = Object.keys(items).map(item => ( )); const selectElem = ; return label ? ( {selectElem} ) : selectElem; } } export const TextInput = props => ( ); export const FileChooser = props => ( ); FileChooser.defaultProps = { accept: ['image/jpeg', 'image/png', 'image/gif', 'image/webp'], }; export const FileChooserLogo = props => ( ); FileChooserLogo.defaultProps = { accept: ['image/svg', 'image/png'], };