@shopify/react-form-state
Advanced tools
Comparing version 0.7.1 to 0.7.2
@@ -9,2 +9,3 @@ import * as React from 'react'; | ||
export default class List<Fields> extends React.Component<Props<Fields>, never> { | ||
private changeHandlers; | ||
shouldComponentUpdate(nextProps: any): boolean; | ||
@@ -11,0 +12,0 @@ render(): JSX.Element[]; |
@@ -5,4 +5,2 @@ "use strict"; | ||
var React = tslib_1.__importStar(require("react")); | ||
var get_1 = tslib_1.__importDefault(require("lodash/get")); | ||
var lodash_decorators_1 = require("lodash-decorators"); | ||
var utilities_1 = require("../utilities"); | ||
@@ -12,3 +10,25 @@ var List = /** @class */ (function (_super) { | ||
function List() { | ||
return _super !== null && _super.apply(this, arguments) || this; | ||
var _this = _super !== null && _super.apply(this, arguments) || this; | ||
_this.changeHandlers = new Map(); | ||
_this.handleChange = function (_a) { | ||
var index = _a.index, key = _a.key; | ||
var hashKey = index + ":" + key; | ||
if (_this.changeHandlers.has(hashKey)) { | ||
return _this.changeHandlers.get(hashKey); | ||
} | ||
var handler = function (newValue) { | ||
var onChange = _this.props.field.onChange; | ||
onChange(function (value) { | ||
var _a; | ||
var existingItem = value[index]; | ||
var newItem = tslib_1.__assign({}, existingItem, (_a = {}, _a[key] = typeof newValue === 'function' | ||
? newValue(value[index][key]) | ||
: newValue, _a)); | ||
return utilities_1.replace(value, index, newItem); | ||
}); | ||
}; | ||
_this.changeHandlers.set(hashKey, handler); | ||
return handler; | ||
}; | ||
return _this; | ||
} | ||
@@ -27,3 +47,3 @@ List.prototype.shouldComponentUpdate = function (nextProps) { | ||
var innerFields = utilities_1.mapObject(fieldValues, function (value, fieldPath) { | ||
var initialFieldValue = get_1.default(initialValue, [index, fieldPath]); | ||
var initialFieldValue = initialValue[index][fieldPath]; | ||
return { | ||
@@ -35,3 +55,3 @@ value: value, | ||
dirty: value !== initialFieldValue, | ||
error: get_1.default(error, [index, fieldPath]), | ||
error: error && error[index] && error[index][fieldPath], | ||
onChange: _this.handleChange({ index: index, key: fieldPath }), | ||
@@ -46,23 +66,4 @@ }; | ||
}; | ||
List.prototype.handleChange = function (_a) { | ||
var _this = this; | ||
var index = _a.index, key = _a.key; | ||
return function (newValue) { | ||
var onChange = _this.props.field.onChange; | ||
onChange(function (value) { | ||
var _a; | ||
var existingItem = value[index]; | ||
var newItem = tslib_1.__assign({}, existingItem, (_a = {}, _a[key] = typeof newValue === 'function' | ||
? newValue(value[index][key]) | ||
: newValue, _a)); | ||
return utilities_1.replace(value, index, newItem); | ||
}); | ||
}; | ||
}; | ||
tslib_1.__decorate([ | ||
lodash_decorators_1.memoize(), | ||
lodash_decorators_1.bind() | ||
], List.prototype, "handleChange", null); | ||
return List; | ||
}(React.Component)); | ||
exports.default = List; |
@@ -8,2 +8,3 @@ import * as React from 'react'; | ||
export default class Nested<Fields> extends React.Component<Props<Fields>, never> { | ||
private changeHandlers; | ||
shouldComponentUpdate(nextProps: any): boolean; | ||
@@ -10,0 +11,0 @@ render(): React.ReactNode; |
@@ -5,4 +5,2 @@ "use strict"; | ||
var React = tslib_1.__importStar(require("react")); | ||
var get_1 = tslib_1.__importDefault(require("lodash/get")); | ||
var lodash_decorators_1 = require("lodash-decorators"); | ||
var utilities_1 = require("../utilities"); | ||
@@ -12,3 +10,21 @@ var Nested = /** @class */ (function (_super) { | ||
function Nested() { | ||
return _super !== null && _super.apply(this, arguments) || this; | ||
var _this = _super !== null && _super.apply(this, arguments) || this; | ||
_this.changeHandlers = new Map(); | ||
_this.handleChange = function (key) { | ||
if (_this.changeHandlers.has(key)) { | ||
return _this.changeHandlers.get(key); | ||
} | ||
var handler = function (newValue) { | ||
var onChange = _this.props.field.onChange; | ||
onChange(function (value) { | ||
var _a; | ||
return tslib_1.__assign({}, value, (_a = {}, _a[key] = typeof newValue === 'function' | ||
? newValue(value[key]) | ||
: newValue, _a)); | ||
}); | ||
}; | ||
_this.changeHandlers.set(key, handler); | ||
return handler; | ||
}; | ||
return _this; | ||
} | ||
@@ -33,3 +49,3 @@ Nested.prototype.shouldComponentUpdate = function (nextProps) { | ||
dirty: value !== initialFieldValue, | ||
error: get_1.default(error, fieldPath), | ||
error: error && error[fieldPath], | ||
onChange: _this.handleChange(fieldPath), | ||
@@ -40,20 +56,4 @@ }; | ||
}; | ||
Nested.prototype.handleChange = function (key) { | ||
var _this = this; | ||
return function (newValue) { | ||
var onChange = _this.props.field.onChange; | ||
onChange(function (value) { | ||
var _a; | ||
return tslib_1.__assign({}, value, (_a = {}, _a[key] = typeof newValue === 'function' | ||
? newValue(value[key]) | ||
: newValue, _a)); | ||
}); | ||
}; | ||
}; | ||
tslib_1.__decorate([ | ||
lodash_decorators_1.memoize(), | ||
lodash_decorators_1.bind() | ||
], Nested.prototype, "handleChange", null); | ||
return Nested; | ||
}(React.Component)); | ||
exports.default = Nested; |
@@ -48,2 +48,3 @@ import * as React from 'react'; | ||
private mounted; | ||
private fieldsWithHandlers; | ||
componentDidMount(): void; | ||
@@ -54,3 +55,3 @@ componentWillUnmount(): void; | ||
validateForm(): Promise<{}>; | ||
reset(): Promise<{}>; | ||
reset: () => Promise<{}>; | ||
private readonly dirty; | ||
@@ -57,0 +58,0 @@ private readonly valid; |
@@ -6,6 +6,2 @@ "use strict"; | ||
var React = tslib_1.__importStar(require("react")); | ||
var isEqual_1 = tslib_1.__importDefault(require("lodash/isEqual")); | ||
var isArray_1 = tslib_1.__importDefault(require("lodash/isArray")); | ||
var set_1 = tslib_1.__importDefault(require("lodash/set")); | ||
var lodash_decorators_1 = require("lodash-decorators"); | ||
var utilities_1 = require("./utilities"); | ||
@@ -19,2 +15,60 @@ var components_1 = require("./components"); | ||
_this.mounted = false; | ||
_this.fieldsWithHandlers = new WeakMap(); | ||
_this.reset = function () { | ||
return new Promise(function (resolve) { | ||
_this.setState(function (_state, props) { return createFormState(props.initialValues); }, function () { return resolve(); }); | ||
}); | ||
}; | ||
_this.submit = function (event) { return tslib_1.__awaiter(_this, void 0, void 0, function () { | ||
var _a, onSubmit, validateOnSubmit, formData, errors; | ||
return tslib_1.__generator(this, function (_b) { | ||
switch (_b.label) { | ||
case 0: | ||
_a = this.props, onSubmit = _a.onSubmit, validateOnSubmit = _a.validateOnSubmit; | ||
formData = this.formData; | ||
if (!this.mounted) { | ||
return [2 /*return*/]; | ||
} | ||
if (event && event.preventDefault && !event.defaultPrevented) { | ||
event.preventDefault(); | ||
} | ||
if (onSubmit == null) { | ||
return [2 /*return*/]; | ||
} | ||
this.setState({ submitting: true }); | ||
if (!validateOnSubmit) return [3 /*break*/, 2]; | ||
return [4 /*yield*/, this.validateForm()]; | ||
case 1: | ||
_b.sent(); | ||
if (this.hasClientErrors) { | ||
this.setState({ submitting: false }); | ||
return [2 /*return*/]; | ||
} | ||
_b.label = 2; | ||
case 2: return [4 /*yield*/, onSubmit(formData)]; | ||
case 3: | ||
errors = (_b.sent()) || []; | ||
if (!this.mounted) { | ||
return [2 /*return*/]; | ||
} | ||
if (errors.length > 0) { | ||
this.updateRemoteErrors(errors); | ||
this.setState({ submitting: false }); | ||
} | ||
else { | ||
this.setState({ submitting: false, errors: errors }); | ||
} | ||
return [2 /*return*/]; | ||
} | ||
}); | ||
}); }; | ||
_this.fieldWithHandlers = function (field, fieldPath) { | ||
if (_this.fieldsWithHandlers.has(field)) { | ||
// eslint-disable-next-line typescript/no-non-null-assertion | ||
return _this.fieldsWithHandlers.get(field); | ||
} | ||
var result = tslib_1.__assign({}, field, { name: String(fieldPath), onChange: _this.updateField.bind(_this, fieldPath), onBlur: _this.blurField.bind(_this, fieldPath) }); | ||
_this.fieldsWithHandlers.set(field, result); | ||
return result; | ||
}; | ||
return _this; | ||
@@ -32,3 +86,3 @@ } | ||
var oldInitialValues = initialValuesFromFields(oldState.fields); | ||
var valuesMatch = isEqual_1.default(oldInitialValues, initialValues); | ||
var valuesMatch = utilities_1.isEqual(oldInitialValues, initialValues); | ||
if (valuesMatch) { | ||
@@ -74,8 +128,2 @@ return null; | ||
}; | ||
FormState.prototype.reset = function () { | ||
var _this = this; | ||
return new Promise(function (resolve) { | ||
_this.setState(function (_state, props) { return createFormState(props.initialValues); }, function () { return resolve(); }); | ||
}); | ||
}; | ||
Object.defineProperty(FormState.prototype, "dirty", { | ||
@@ -116,50 +164,2 @@ get: function () { | ||
}); | ||
FormState.prototype.submit = function (event) { | ||
return tslib_1.__awaiter(this, void 0, void 0, function () { | ||
var _a, onSubmit, validateOnSubmit, formData, errors; | ||
return tslib_1.__generator(this, function (_b) { | ||
switch (_b.label) { | ||
case 0: | ||
_a = this.props, onSubmit = _a.onSubmit, validateOnSubmit = _a.validateOnSubmit; | ||
formData = this.formData; | ||
if (!this.mounted) { | ||
return [2 /*return*/]; | ||
} | ||
if (event && event.preventDefault && !event.defaultPrevented) { | ||
event.preventDefault(); | ||
} | ||
if (onSubmit == null) { | ||
return [2 /*return*/]; | ||
} | ||
this.setState({ submitting: true }); | ||
if (!validateOnSubmit) return [3 /*break*/, 2]; | ||
return [4 /*yield*/, this.validateForm()]; | ||
case 1: | ||
_b.sent(); | ||
if (this.hasClientErrors) { | ||
this.setState({ submitting: false }); | ||
return [2 /*return*/]; | ||
} | ||
_b.label = 2; | ||
case 2: return [4 /*yield*/, onSubmit(formData)]; | ||
case 3: | ||
errors = (_b.sent()) || []; | ||
if (!this.mounted) { | ||
return [2 /*return*/]; | ||
} | ||
if (errors.length > 0) { | ||
this.updateRemoteErrors(errors); | ||
this.setState({ submitting: false }); | ||
} | ||
else { | ||
this.setState({ submitting: false, errors: errors }); | ||
} | ||
return [2 /*return*/]; | ||
} | ||
}); | ||
}); | ||
}; | ||
FormState.prototype.fieldWithHandlers = function (field, fieldPath) { | ||
return tslib_1.__assign({}, field, { name: fieldPath, onChange: this.updateField.bind(this, fieldPath), onBlur: this.blurField.bind(this, fieldPath) }); | ||
}; | ||
FormState.prototype.updateField = function (fieldPath, value) { | ||
@@ -174,3 +174,3 @@ var _this = this; | ||
: value; | ||
var dirty = !isEqual_1.default(newValue, field.initialValue); | ||
var dirty = !utilities_1.isEqual(newValue, field.initialValue); | ||
var updatedField = _this.getUpdatedField({ | ||
@@ -255,3 +255,3 @@ fieldPath: fieldPath, | ||
} | ||
return set_1.default(accumulator, field, message); | ||
return utilities_1.set(accumulator, field, message); | ||
}, {}); | ||
@@ -268,12 +268,2 @@ return { | ||
FormState.Nested = components_1.Nested; | ||
tslib_1.__decorate([ | ||
lodash_decorators_1.bind() | ||
], FormState.prototype, "reset", null); | ||
tslib_1.__decorate([ | ||
lodash_decorators_1.bind() | ||
], FormState.prototype, "submit", null); | ||
tslib_1.__decorate([ | ||
lodash_decorators_1.memoize(), | ||
lodash_decorators_1.bind() | ||
], FormState.prototype, "fieldWithHandlers", null); | ||
return FormState; | ||
@@ -287,3 +277,3 @@ }(React.PureComponent)); | ||
var oldField = oldFields[key]; | ||
if (isEqual_1.default(value, oldField.initialValue)) { | ||
if (utilities_1.isEqual(value, oldField.initialValue)) { | ||
return oldField; | ||
@@ -327,3 +317,3 @@ } | ||
} | ||
if (!isArray_1.default(validate)) { | ||
if (!Array.isArray(validate)) { | ||
// eslint-disable-next-line consistent-return | ||
@@ -330,0 +320,0 @@ return; |
@@ -5,1 +5,3 @@ export declare function mapObject<Input, Output>(input: Input, mapper: (value: any, key: keyof Input) => any): Output; | ||
export declare function replace<T>(array: T[], targetIndex: number, newValue: T): T[]; | ||
export declare function set<InputType extends Object>(rootObject: InputType, path: string[], value: any): any; | ||
export declare function isEqual(value: any, baseline: any): boolean; |
@@ -5,5 +5,3 @@ "use strict"; | ||
function mapObject(input, mapper) { | ||
return Object.keys(input) | ||
.map(function (key) { return [key, input[key]]; }) | ||
.reduce(function (accumulator, _a) { | ||
return Object.entries(input).reduce(function (accumulator, _a) { | ||
var _b = tslib_1.__read(_a, 2), key = _b[0], value = _b[1]; | ||
@@ -36,1 +34,69 @@ accumulator[key] = mapper(value, key); | ||
exports.replace = replace; | ||
function set(rootObject, path, value) { | ||
var _a, _b; | ||
if (path.length === 0) { | ||
return rootObject; | ||
} | ||
else if (path.length === 1) { | ||
return tslib_1.__assign({}, rootObject, (_a = {}, _a[path[0]] = value, _a)); | ||
} | ||
else { | ||
var _c = tslib_1.__read(path), current = _c[0], rest = _c.slice(1); | ||
return tslib_1.__assign({}, rootObject, (_b = {}, _b[current] = set(rootObject[current], rest, value), _b)); | ||
} | ||
} | ||
exports.set = set; | ||
function isEqual(value, baseline) { | ||
var e_1, _a; | ||
if (value === baseline) { | ||
return true; | ||
} | ||
if (typeof value !== typeof baseline) { | ||
return false; | ||
} | ||
if (Array.isArray(value)) { | ||
if (!Array.isArray(baseline)) { | ||
return false; | ||
} | ||
if (value.length !== baseline.length) { | ||
return false; | ||
} | ||
for (var iter = 0; iter < value.length; iter++) { | ||
if (!isEqual(value[iter], baseline[iter])) { | ||
return false; | ||
} | ||
} | ||
return true; | ||
} | ||
if (typeof value === 'object') { | ||
if (value === null) { | ||
return baseline === null; | ||
} | ||
if (baseline === null) { | ||
return false; | ||
} | ||
var keysInValue = Object.keys(value); | ||
var keysInBaseline = Object.keys(baseline); | ||
if (!isEqual(keysInValue, keysInBaseline)) { | ||
return false; | ||
} | ||
try { | ||
for (var keysInValue_1 = tslib_1.__values(keysInValue), keysInValue_1_1 = keysInValue_1.next(); !keysInValue_1_1.done; keysInValue_1_1 = keysInValue_1.next()) { | ||
var key = keysInValue_1_1.value; | ||
if (!isEqual(value[key], baseline[key])) { | ||
return false; | ||
} | ||
} | ||
} | ||
catch (e_1_1) { e_1 = { error: e_1_1 }; } | ||
finally { | ||
try { | ||
if (keysInValue_1_1 && !keysInValue_1_1.done && (_a = keysInValue_1.return)) _a.call(keysInValue_1); | ||
} | ||
finally { if (e_1) throw e_1.error; } | ||
} | ||
return true; | ||
} | ||
return false; | ||
} | ||
exports.isEqual = isEqual; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
var tslib_1 = require("tslib"); | ||
var toString_1 = tslib_1.__importDefault(require("lodash/toString")); | ||
var isArray_1 = tslib_1.__importDefault(require("lodash/isArray")); | ||
var utilities_1 = require("./utilities"); | ||
@@ -49,3 +47,3 @@ function lengthMoreThan(length) { | ||
} | ||
if (!isArray_1.default(validate)) { | ||
if (!Array.isArray(validate)) { | ||
// eslint-disable-next-line consistent-return | ||
@@ -98,3 +96,3 @@ return; | ||
// eslint-disable-next-line consistent-return | ||
return errorContent(toString_1.default(input)); | ||
return errorContent(toString(input)); | ||
} | ||
@@ -114,3 +112,3 @@ // eslint-disable-next-line consistent-return | ||
// eslint-disable-next-line consistent-return | ||
return errorContent(toString_1.default(input)); | ||
return errorContent(toString(input)); | ||
} | ||
@@ -142,2 +140,8 @@ // eslint-disable-next-line consistent-return | ||
}; | ||
function toString(obj) { | ||
if (obj == null) { | ||
return ''; | ||
} | ||
return obj.toString(); | ||
} | ||
exports.default = validators; |
{ | ||
"name": "@shopify/react-form-state", | ||
"version": "0.7.1", | ||
"version": "0.7.2", | ||
"license": "MIT", | ||
@@ -26,4 +26,2 @@ "description": "Manage react forms tersely and type-safe with no magic.", | ||
"dependencies": { | ||
"lodash": "^4.17.10", | ||
"lodash-decorators": "^6.0.0", | ||
"tslib": "^1.9.3" | ||
@@ -30,0 +28,0 @@ }, |
/* eslint-disable no-case-declarations */ | ||
import * as React from 'react'; | ||
import isEqual from 'lodash/isEqual'; | ||
import isArray from 'lodash/isArray'; | ||
import set from 'lodash/set'; | ||
import {memoize, bind} from 'lodash-decorators'; | ||
import {mapObject} from './utilities'; | ||
import {mapObject, set, isEqual} from './utilities'; | ||
import { | ||
@@ -96,2 +92,3 @@ FieldDescriptors, | ||
private mounted = false; | ||
private fieldsWithHandlers = new WeakMap(); | ||
@@ -137,4 +134,3 @@ componentDidMount() { | ||
@bind() | ||
public reset() { | ||
public reset = () => { | ||
return new Promise(resolve => { | ||
@@ -146,3 +142,3 @@ this.setState( | ||
}); | ||
} | ||
}; | ||
@@ -178,4 +174,3 @@ private get dirty() { | ||
@bind() | ||
private async submit(event?: Event) { | ||
private submit = async (event?: Event) => { | ||
const {onSubmit, validateOnSubmit} = this.props; | ||
@@ -219,17 +214,22 @@ const {formData} = this; | ||
} | ||
} | ||
}; | ||
@memoize() | ||
@bind() | ||
private fieldWithHandlers<Key extends keyof Fields>( | ||
private fieldWithHandlers = <Key extends keyof Fields>( | ||
field: FieldStates<Fields>[Key], | ||
fieldPath: Key, | ||
) { | ||
return { | ||
) => { | ||
if (this.fieldsWithHandlers.has(field)) { | ||
// eslint-disable-next-line typescript/no-non-null-assertion | ||
return this.fieldsWithHandlers.get(field)!; | ||
} | ||
const result = { | ||
...(field as FieldState<Fields[Key]>), | ||
name: fieldPath, | ||
name: String(fieldPath), | ||
onChange: this.updateField.bind(this, fieldPath), | ||
onBlur: this.blurField.bind(this, fieldPath), | ||
}; | ||
} | ||
this.fieldsWithHandlers.set(field, result); | ||
return result; | ||
}; | ||
@@ -454,3 +454,3 @@ private updateField<Key extends keyof Fields>( | ||
if (!isArray(validate)) { | ||
if (!Array.isArray(validate)) { | ||
// eslint-disable-next-line consistent-return | ||
@@ -457,0 +457,0 @@ return; |
@@ -5,8 +5,6 @@ export function mapObject<Input, Output>( | ||
) { | ||
return Object.keys(input) | ||
.map(key => [key, input[key]]) | ||
.reduce((accumulator: any, [key, value]) => { | ||
accumulator[key] = mapper(value, key as keyof Input); | ||
return accumulator; | ||
}, {}) as Output; | ||
return Object.entries(input).reduce((accumulator: any, [key, value]) => { | ||
accumulator[key] = mapper(value, key as keyof Input); | ||
return accumulator; | ||
}, {}) as Output; | ||
} | ||
@@ -31,1 +29,65 @@ | ||
} | ||
export function set<InputType extends Object>( | ||
rootObject: InputType, | ||
path: string[], | ||
value: any, | ||
) { | ||
if (path.length === 0) { | ||
return rootObject; | ||
} else if (path.length === 1) { | ||
return { | ||
...(rootObject as any), | ||
[path[0]]: value, | ||
}; | ||
} else { | ||
const [current, ...rest] = path; | ||
return { | ||
...(rootObject as any), | ||
[current]: set(rootObject[current], rest, value), | ||
} as InputType; | ||
} | ||
} | ||
export function isEqual(value: any, baseline: any) { | ||
if (value === baseline) { | ||
return true; | ||
} | ||
if (typeof value !== typeof baseline) { | ||
return false; | ||
} | ||
if (Array.isArray(value)) { | ||
if (!Array.isArray(baseline)) { | ||
return false; | ||
} | ||
if (value.length !== baseline.length) { | ||
return false; | ||
} | ||
for (let iter = 0; iter < value.length; iter++) { | ||
if (!isEqual(value[iter], baseline[iter])) { | ||
return false; | ||
} | ||
} | ||
return true; | ||
} | ||
if (typeof value === 'object') { | ||
if (value === null) { | ||
return baseline === null; | ||
} | ||
if (baseline === null) { | ||
return false; | ||
} | ||
const keysInValue = Object.keys(value); | ||
const keysInBaseline = Object.keys(baseline); | ||
if (!isEqual(keysInValue, keysInBaseline)) { | ||
return false; | ||
} | ||
for (const key of keysInValue) { | ||
if (!isEqual(value[key], baseline[key])) { | ||
return false; | ||
} | ||
} | ||
return true; | ||
} | ||
return false; | ||
} |
@@ -1,3 +0,1 @@ | ||
import toString from 'lodash/toString'; | ||
import isArray from 'lodash/isArray'; | ||
import {mapObject} from './utilities'; | ||
@@ -56,3 +54,3 @@ | ||
if (!isArray(validate)) { | ||
if (!Array.isArray(validate)) { | ||
// eslint-disable-next-line consistent-return | ||
@@ -183,2 +181,9 @@ return; | ||
function toString(obj) { | ||
if (obj == null) { | ||
return ''; | ||
} | ||
return obj.toString(); | ||
} | ||
export default validators; |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
174845
2
3819
- Removedlodash@^4.17.10
- Removedlodash-decorators@^6.0.0
- Removedlodash@4.17.21(transitive)
- Removedlodash-decorators@6.0.1(transitive)