1import React, { Component } from 'react';
2import PropTypes from 'prop-types';
4import { compose, defaultTo } from '../../lib/lib';
6// =============================================================================
9const initMessage = data => ({
15// Validation display triggers
16const displayTriggers = {
17 eagerSuccess: r => r.pass,
18 eagerFailure: r => !r.pass,
19 tactfulSuccess: r => r.pass && r.beenFocussed,
20 tactfulFailure: r => !r.pass && r.beenFocussed && !r.focussed,
23// =============================================================================
26const advancedInput = ({ WrappedComponent, validators, transformers }) => {
27 // set argument defaults
28 validators = defaultTo(validators, []);
29 transformers = defaultTo(transformers, []);
31 class AdvancedInputHOC extends Component {
38 this.onFocus = this.onFocus.bind(this);
39 this.onBlur = this.onBlur.bind(this);
40 this.onChange = this.onChange.bind(this);
43 onFocus = () => this.setState({ focussed: true });
45 onBlur = () => this.setState({ focussed: false, beenFocussed: true });
48 const { props } = this;
50 // =======================================================================
51 // 0. RUN VALUE TRANSFORMERS
53 // This applies functions to the input value and updates state with the
54 // new value. This is useful for ship/point names which technically
55 // should always have a sig prepending them, but users might not know/care
56 // about such a technicality. ValueTransformers are executed from right to
58 const newValue = compose(...transformers)(value);
60 props.onChange(newValue);
64 const { state, props } = this;
66 // =======================================================================
67 // RUN VALIDATORS AND DETERMINE STYLES
69 // Run validation chain on the transformed value. Validators are executed
70 // from right to left and exit on the first validation failure.
72 const report = compose(
77 // Makes a uniform data structure to pass to display triggers. This
78 // removes the need to rely on argument order for these functions.
81 beenFocussed: state.beenFocussed,
82 focussed: state.focussed,
83 submitted: props.submitted,
86 // Determine if the passing validation style or message should be shown
87 const displayPass = displayTriggers.eagerSuccess(stateReport);
89 // Determine if the failing validation style or message should be shown
90 const displayFailure = displayTriggers.tactfulFailure(stateReport);
92 // Generate class strings for validation state. VCN stands for validation
94 const valClassname = styleSelector(displayPass, displayFailure);
100 onFocus={this.onFocus}
102 onChange={this.onChange}
104 focussed={state.focussed}
105 beenFocussed={state.beenFocussed}
106 displayPass={displayPass}
107 displayFailure={displayFailure}
108 // 'error' prop refers to an error message string, not the presence
111 didPass={report.pass}
113 className={props.className}
114 disabled={props.disabled}
115 valClassname={valClassname}
122 AdvancedInputHOC.propTypes = {
123 className: PropTypes.string,
124 style: PropTypes.object,
125 value: PropTypes.string,
126 submitted: PropTypes.bool,
129 AdvancedInputHOC.defaultProps = {
136 return AdvancedInputHOC;
137 // END advancedInput()
140const styleSelector = (pass, fail) => {
142 return 'br-yellow outline-yellow f-br-yellow bg-yellow-light';
143 if (pass === true) return 'br-green outline-green f-br-green';
144 return 'br-gray-50 f-br-blue outline-blue';
147export default advancedInput;
keysesc to close
- j k
- move down, up
- enter
- open
- esc
- back, or up a level
- 1 2 3 4
- readme, files, commits, refs
- /
- filter
- y
- copy the clone command
- c
- compare the chosen commit with another (or shift-click both)
- ?
- show or hide this list