1import React, { Component } from 'react';
2import PropTypes from 'prop-types';
4import { compose, defaultTo, t, f } from '../lib/lib';
6// =============================================================================
9const initMessage = data => ({
15// Validation display triggers
16const displayTriggers = {
17 eagerSuccess: r => t(r.pass),
18 eagerFailure: r => f(r.pass),
19 tactfulSuccess: r => t(r.pass) && t(r.beenFocussed),
20 tactfulFailure: r => f(r.pass) && t(r.beenFocussed) && f(r.focussed),
23// =============================================================================
26const advancedInput = ({
32 // set argument defaults
33 validators = defaultTo(validators, [])
34 transformers = defaultTo(transformers, [])
36 class AdvancedInputHOC extends Component {
43 this.onFocus = this.onFocus.bind(this)
44 this.onBlur = this.onBlur.bind(this)
45 this.onChange = this.onChange.bind(this)
48 onFocus = () => this.setState({ focussed: true });
50 onBlur = () => this.setState({ focussed: false, beenFocussed: true });
54 const { props } = this
56 // =======================================================================
57 // 0. RUN VALUE TRANSFORMERS
59 // This applies functions to the input value and updates state with the
60 // new value. This is useful for ship/point names which technically
61 // should always have a sig prepending them, but users might not know/care
62 // about such a technicality. ValueTransformers are executed from right to
64 const newValue = compose(...transformers)(value)
66 props.onChange(newValue)
71 const { state, props } = this
73 // =======================================================================
74 // RUN VALIDATORS AND DETERMINE STYLES
76 // Run validation chain on the transformed value. Validators are executed
77 // from right to left and exit on the first validation failure.
78 const report = compose(...validators, initMessage)(props.value)
80 // Makes a uniform data structure to pass to display triggers. This
81 // removes the need to rely on argument order for these functions.
84 beenFocussed: state.beenFocussed,
85 focussed: state.focussed,
86 submitted: props.submitted,
89 // Determine if the passing validation style or message should be shown
90 const displayPass = displayTriggers.eagerSuccess(stateReport);
92 // Determine if the failing validation style or message should be shown
93 const displayFailure = displayTriggers.tactfulFailure(stateReport);
95 // Generate class strings for validation state. VCN stands for validation
97 const valClassname = styleSelector(
106 onFocus={ this.onFocus }
107 onBlur={ this.onBlur }
108 onChange={ this.onChange }
111 focussed={ state.focussed }
112 beenFocussed={ state.beenFocussed }
113 displayPass={ displayPass }
114 displayFailure={ displayFailure }
115 // 'error' prop refers to an error message string, not the presence
117 error={ report.error }
118 didPass={ report.pass }
120 className={ props.className }
121 disabled={ props.disabled }
122 valClassname={valClassname}
128 AdvancedInputHOC.propTypes = {
129 className: PropTypes.string,
130 style: PropTypes.object,
131 value: PropTypes.string,
132 submitted: PropTypes.bool,
135 AdvancedInputHOC.defaultProps = {
142 return AdvancedInputHOC;
143 // END advancedInput()
146const styleSelector = (pass, fail) => {
147 if (fail === true) return 'br-yellow outline-yellow f-br-yellow bg-yellow-light';
148 if (pass === true) return 'br-green outline-green f-br-green';
149 return 'br-gray-50 f-br-blue outline-blue'
152export 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