Skip to content
This repository has been archived by the owner on May 12, 2021. It is now read-only.

Commit

Permalink
Merge pull request #25 from clocasto/release-1.0.0
Browse files Browse the repository at this point in the history
Release 1.0.0
  • Loading branch information
clocasto committed Feb 13, 2017
2 parents 112ea93 + 5cf37c7 commit 5411090
Show file tree
Hide file tree
Showing 14 changed files with 407 additions and 137 deletions.
36 changes: 22 additions & 14 deletions dist/components/Field.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@ var Field = function (_React$Component) {
debounce: Math.floor(Math.pow(Math.pow(+props.debounce, 2), 0.5)) || 0, //eslint-disable-line
validators: (0, _utilities.assembleValidators)(props)
};

_this.finalValue = null;

_this.onChange = _this.onChange.bind(_this);
Expand All @@ -52,7 +51,7 @@ var Field = function (_React$Component) {
_createClass(Field, [{
key: 'componentWillUpdate',
value: function componentWillUpdate(nextProps) {
if (nextProps.value !== this.props.value && nextProps.value !== this.finalValue) {
if (nextProps.value !== this.props.value && nextProps.value !== this.state.value) {
this.cancelBroadcast();
this.setState({ value: nextProps.value });
this.finalValue = nextProps.value;
Expand All @@ -66,7 +65,7 @@ var Field = function (_React$Component) {
}, {
key: 'shouldComponentUpdate',
value: function shouldComponentUpdate(nextProps) {
if (nextProps.value !== this.finalValue) return true;
if (nextProps.value !== this.state.value) return true;
if (this.state.value !== this.finalValue) return true;
if (this.props.match !== nextProps.match) return true;
return false;
Expand All @@ -81,21 +80,24 @@ var Field = function (_React$Component) {
key: 'onChange',
value: function onChange(e) {
var value = e.target.value;
this.finalValue = value;

var validators = (0, _utilities.getValuesOf)(this.state.validators);

this.setState({ value: value, valid: (0, _utilities.isValid)(value, validators), pristine: false });
this.finalValue = value;
this.debouncedBroadcastChange();
this.setState({
value: value,
valid: (0, _utilities.isValid)(value, validators),
pristine: false
}, this.debouncedBroadcastChange);
}
}, {
key: 'broadcastChange',
value: function broadcastChange() {
if (this.props.onChange) {
this.props.onChange({
name: this.props.name,
value: this.finalValue,
status: this.state.valid,
value: this.state.value,
valid: this.state.valid,
pristine: this.state.pristine
});
}
Expand Down Expand Up @@ -123,16 +125,22 @@ var Field = function (_React$Component) {

if (!childCount) {
return _react2.default.createElement(
'label',
{ htmlFor: this.props.name },
_react2.default.createElement('input', inputProps)
'div',
null,
_react2.default.createElement(
'label',
{ htmlFor: this.props.name },
_react2.default.createElement('input', inputProps)
)
);
}
return _react2.default.createElement(
'div',
{ htmlFor: this.props.name },
null,
_react2.default.Children.map(this.props.children, function (child) {
return (0, _utilities.mapPropsToChild)(child, 'input', inputProps);
return (0, _utilities.mapPropsToChild)(child, 'input', function () {
return inputProps;
});
})
);
}
Expand All @@ -148,7 +156,7 @@ Field.propTypes = {
onFocus: _react2.default.PropTypes.func,
onBlur: _react2.default.PropTypes.func,
debounce: _react2.default.PropTypes.oneOfType([_react2.default.PropTypes.string, _react2.default.PropTypes.number]),
match: _react2.default.PropTypes.string,
match: _react2.default.PropTypes.any, // eslint-disable-line
children: _react2.default.PropTypes.oneOfType([_react2.default.PropTypes.element, _react2.default.PropTypes.arrayOf(_react2.default.PropTypes.element), _react2.default.PropTypes.object]),
type: _react2.default.PropTypes.string
};
Expand Down
41 changes: 31 additions & 10 deletions dist/components/Form.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ var _utilities = require('../helpers/utilities');

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
Expand All @@ -30,37 +32,56 @@ var Form = function (_React$Component) {

var _this = _possibleConstructorReturn(this, (Form.__proto__ || Object.getPrototypeOf(Form)).call(this, props));

_this.addFieldToState = _utilities.addFieldToState.bind(_this);
_this.addFieldsToState = _utilities.addFieldsToState.bind(_this);
_this.onSubmit = _this.onSubmit.bind(_this);
_this.onFieldChange = _this.onFieldChange.bind(_this);
_this.reset = _this.reset.bind(_this);

_this.state = {};
var fieldsToAdd = _react2.default.Children.toArray(props.children).filter(function (child) {
return child.type.name === 'Field';

_react2.default.Children.map(props.children, function (child) {
return _this.addFieldsToState(_this, child, false);
});
_this.addFieldToState(fieldsToAdd);
return _this;
}

_createClass(Form, [{
key: 'onFieldChange',
value: function onFieldChange(_ref) {
var name = _ref.name,
value = _ref.value,
valid = _ref.valid,
pristine = _ref.pristine;

this.setState(_defineProperty({}, name, { value: value, valid: valid, pristine: pristine }));
}
}, {
key: 'onSubmit',
value: function onSubmit(e) {
e.preventDefault();
if (this.props.onSubmit) this.props.onSubmit(_extends({}, this.state));
}
}, {
key: 'reset',
value: function reset() {
var _this2 = this;

_react2.default.Children.map(this.props.children, function (child) {
return _this2.addFieldsToState(_this2, child, true);
});
}
}, {
key: 'render',
value: function render() {
var _this2 = this;
var _this3 = this;

return _react2.default.createElement(
'form',
{ onSubmit: this.onSubmit },
_react2.default.Children.map(this.props.children, function (child) {
var name = child.props.name;

var value = _this2.state[name].value;
var fieldProps = { key: child.props.name, value: value, name: name };
return (0, _utilities.mapPropsToChild)(child, 'Field', fieldProps);
return (0, _utilities.mapPropsToChild)(child, 'Field', function (grandChild) {
return (0, _utilities.makeFieldProps)(grandChild, _this3.onFieldChange, _this3.state);
});
})
);
}
Expand Down
71 changes: 43 additions & 28 deletions dist/helpers/utilities.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,13 @@
Object.defineProperty(exports, "__esModule", {
value: true
});

var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };

exports.assembleValidators = assembleValidators;
exports.updateValidators = updateValidators;
exports.isValid = isValid;
exports.addFieldToState = addFieldToState;
exports.buildStateForField = buildStateForField;
exports.addFieldsToState = addFieldsToState;
exports.getValuesOf = getValuesOf;
exports.makeFieldProps = makeFieldProps;
exports.mapPropsToChild = mapPropsToChild;

var _react = require('react');
Expand All @@ -25,6 +24,8 @@ function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj;

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }

function assembleValidators(_ref) {
var email = _ref.email,
length = _ref.length,
Expand Down Expand Up @@ -76,29 +77,34 @@ function isValid(value, validators) {
}, true);
}

function addFieldToState(field) {
var _this = this;
function buildStateForField(fieldProps) {
var value = fieldProps.value,
valid = fieldProps.valid,
pristine = fieldProps.pristine;

if (!field) return;
var newState = { value: '', valid: false, pristine: true };

if (Array.isArray(field)) {
field.forEach(function (name) {
return _this.addFieldToState(name);
});
} else if ((typeof field === 'undefined' ? 'undefined' : _typeof(field)) === 'object') {
var _field$props = field.props,
name = _field$props.name,
value = _field$props.value,
valid = _field$props.valid,
pristine = _field$props.pristine;

var newState = { value: '', valid: false, pristine: false };

if (value !== undefined) Object.assign(newState, { value: value });
if (valid !== undefined) Object.assign(newState, { valid: valid });
if (pristine !== undefined) Object.assign(newState, { pristine: pristine });
if (value !== undefined) Object.assign(newState, { value: value });
if (valid !== undefined) Object.assign(newState, { valid: valid });
if (pristine !== undefined) Object.assign(newState, { pristine: pristine });
return newState;
}

this.state[name] = newState;
function addFieldsToState(component, child) {
var mounted = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;

if (typeof child.type === 'function' && child.type.name === 'Field') {
var name = child.props.name;
var fieldState = buildStateForField(child.props);
if (mounted) {
component.setState(_defineProperty({}, name, fieldState));
} else {
component.state[name] = fieldState; // eslint-disable-line
}
} else if (child.props && child.props.children) {
_react2.default.Children.forEach(child.props.children, function (nextChild) {
return addFieldsToState(component, nextChild, mounted);
});
}
}

Expand All @@ -110,12 +116,21 @@ function getValuesOf() {
});
}

function mapPropsToChild(child, type, props) {
function makeFieldProps(child, onChange, state) {
if (typeof child.type === 'function' && child.type.name === 'Field') {
var name = child.props.name;
return { name: name, onChange: onChange, key: name, value: state[name] ? state[name].value : null };
}
return null;
}

function mapPropsToChild(child, type, propFunction) {
if (child.type === type || typeof child.type === 'function' && child.type.name === type) {
return _react2.default.cloneElement(child, props);
} else if (child.props && child.props.children) {
return _react2.default.cloneElement(child, propFunction(child));
}
if (child.props && child.props.children) {
var newChildren = _react2.default.Children.map(child.props.children, function (nestedChild) {
return mapPropsToChild(nestedChild, type, props);
return mapPropsToChild(nestedChild, type, propFunction);
});
return _react2.default.cloneElement(child, null, newChildren);
}
Expand Down
3 changes: 1 addition & 2 deletions dist/helpers/validators.js
Original file line number Diff line number Diff line change
Expand Up @@ -75,9 +75,8 @@ function alpha() {
}

function numeric() {
var numericRegex = /[^0-9\s]/i;
return function (value) {
return typeof value === 'number' || typeof value === 'string' && !numericRegex.test(value);
return typeof value === 'number' || typeof value === 'string' && (!value || !value.replace(/([-+]{0,1})[0-9]+(\.[0-9]+)?([eE]([+-]{0,1})[0-9]+)?/, ''));
};
}

Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "formulize-react",
"version": "0.0.1",
"version": "1.0.0",
"description": "A simple form validation library for React.js which wires up custom, controlled inputs through a declarative API.",
"main": "dist/index",
"keywords": [
Expand Down

0 comments on commit 5411090

Please sign in to comment.