All files / app/components validation-input.js

100% Statements 17/17
83.33% Branches 5/6
100% Functions 5/5
100% Lines 17/17
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91                                                      2x                         4x 4x 4x               30x 30x     30x 42x 42x 4x 4x   42x   30x       30x 30x 30x 30x                                          
// @flow
 
import React, { Component } from 'react';
import noop from 'ramda/src/identity';
import compose from 'ramda/src/compose';
import concat from 'ramda/src/concat';
import partial from 'ramda/src/partial';
import converge from 'ramda/src/converge';
import head from 'ramda/src/head';
import slice from 'ramda/src/slice';
import toUpper from 'ramda/src/toUpper';
import when from 'ramda/src/when';
import not from 'ramda/src/not';
import propEq from 'ramda/src/propEq';
import HOC from './validation-component';
 
type Props = {
    name: string,
    validateOnEvents: Array<string>,
    children: any,
    setData: Function,
    getError: Function,
    className: string,
    style: Object,
    errorCodes: Object
};
 
const capitalize = converge(concat, [
    compose(toUpper, head),
    slice(1, Infinity)
]);
 
class ValidationInput extends Component {
    static defaultProps = {
        children: null,
        validateOnEvents: ['change', 'blur', 'keyUp'],
        name: ''
    };
 
    eventHandler = (e: Object) => {
        const { target: { value } } = e;
        const { name, setData } = this.props;
        setData({ name, value });
    };
 
    onEvent = when(compose(not, propEq('key', 'Tab')), this.eventHandler);
 
    props: Props;
 
    cloneElement() {
        const { validateOnEvents, children } = this.props;
        const eventNames = validateOnEvents.map(
            compose(partial(concat, ['on']), capitalize)
        );
        const props = eventNames.reduce((acc: Object, event: string) => {
            const { props: childrenProps } = children;
            acc[event] = (e: Object) => {
                (childrenProps[event] || noop)(e);
                this.onEvent(e);
            };
            return acc;
        }, {});
        return React.cloneElement(children, props);
    }
 
    render() {
        const { name, getError, className, style, errorCodes } = this.props;
        const error = getError(name);
        const element = this.cloneElement();
        return (
            <div>
                {element}
                {error &&
                    <div
                        style={{
                            color: 'red',
                            paddingTop: '4px'
                        }}
                        data-error-block
                    >
                        <div className={className} style={style}>
                            {errorCodes[error] || error}
                        </div>
                    </div>}
            </div>
        );
    }
}
 
export default HOC(ValidationInput);