@shopify/react-form-state
Advanced tools
Comparing version 0.12.3 to 0.12.4
@@ -1,6 +0,2 @@ | ||
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
var List_1 = require("./List"); | ||
Object.defineProperty(exports, "List", { enumerable: true, get: function () { return List_1.default; } }); | ||
var Nested_1 = require("./Nested"); | ||
Object.defineProperty(exports, "Nested", { enumerable: true, get: function () { return Nested_1.default; } }); | ||
export { default as List } from './List'; | ||
export { default as Nested } from './Nested'; |
@@ -1,57 +0,47 @@ | ||
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
var tslib_1 = require("tslib"); | ||
var react_1 = tslib_1.__importDefault(require("react")); | ||
var utilities_1 = require("../utilities"); | ||
var List = /** @class */ (function (_super) { | ||
tslib_1.__extends(List, _super); | ||
function List() { | ||
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); | ||
import React from 'react'; | ||
import { mapObject, replace } from '../utilities'; | ||
export default class List extends React.PureComponent { | ||
constructor() { | ||
super(...arguments); | ||
this.changeHandlers = new Map(); | ||
this.handleChange = ({ index, key, }) => { | ||
const 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(tslib_1.__assign({}, existingItem), (_a = {}, _a[key] = typeof newValue === 'function' | ||
? newValue(value[index][key]) | ||
: newValue, _a)); | ||
return utilities_1.replace(value, index, newItem); | ||
const handler = (newValue) => { | ||
const { field: { onChange }, } = this.props; | ||
onChange(value => { | ||
const existingItem = value[index]; | ||
const newItem = Object.assign(Object.assign({}, existingItem), { [key]: typeof newValue === 'function' | ||
? newValue(value[index][key]) | ||
: newValue }); | ||
return replace(value, index, newItem); | ||
}); | ||
}; | ||
_this.changeHandlers.set(hashKey, handler); | ||
this.changeHandlers.set(hashKey, handler); | ||
return handler; | ||
}; | ||
return _this; | ||
} | ||
List.prototype.render = function () { | ||
var _this = this; | ||
var _a = this.props, _b = _a.field, value = _b.value, initialValue = _b.initialValue, error = _b.error, name = _b.name, onBlur = _b.onBlur, getChildKey = _a.getChildKey, children = _a.children; | ||
return value.map(function (fieldValues, index) { | ||
var innerFields = utilities_1.mapObject(fieldValues, function (value, fieldPath) { | ||
var initialFieldValue = initialValue && | ||
render() { | ||
const { field: { value, initialValue, error, name, onBlur }, getChildKey, children, } = this.props; | ||
return value.map((fieldValues, index) => { | ||
const innerFields = mapObject(fieldValues, (value, fieldPath) => { | ||
const initialFieldValue = initialValue && | ||
initialValue[index] && | ||
initialValue[index][fieldPath]; | ||
return { | ||
value: value, | ||
onBlur: onBlur, | ||
name: name + "." + index + "." + fieldPath, | ||
value, | ||
onBlur, | ||
name: `${name}.${index}.${fieldPath}`, | ||
initialValue: initialFieldValue, | ||
dirty: value !== initialFieldValue, | ||
error: error && error[index] && error[index][fieldPath], | ||
onChange: _this.handleChange({ index: index, key: fieldPath }), | ||
onChange: this.handleChange({ index, key: fieldPath }), | ||
}; | ||
}); | ||
var key = getChildKey ? getChildKey(fieldValues) : index; | ||
return (react_1.default.createElement(react_1.default.Fragment, { key: key }, children(innerFields, index))); | ||
const key = getChildKey ? getChildKey(fieldValues) : index; | ||
return (React.createElement(React.Fragment, { key: key }, children(innerFields, index))); | ||
}); | ||
}; | ||
return List; | ||
}(react_1.default.PureComponent)); | ||
exports.default = List; | ||
} | ||
} |
@@ -1,48 +0,39 @@ | ||
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
var tslib_1 = require("tslib"); | ||
var react_1 = tslib_1.__importDefault(require("react")); | ||
var utilities_1 = require("../utilities"); | ||
var Nested = /** @class */ (function (_super) { | ||
tslib_1.__extends(Nested, _super); | ||
function Nested() { | ||
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); | ||
import React from 'react'; | ||
import { mapObject } from '../utilities'; | ||
export default class Nested extends React.PureComponent { | ||
constructor() { | ||
super(...arguments); | ||
this.changeHandlers = new Map(); | ||
this.handleChange = (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(tslib_1.__assign({}, value), (_a = {}, _a[key] = typeof newValue === 'function' | ||
? newValue(value[key]) | ||
: newValue, _a)); | ||
const handler = (newValue) => { | ||
const { field: { onChange }, } = this.props; | ||
onChange(value => { | ||
return Object.assign(Object.assign({}, value), { [key]: typeof newValue === 'function' | ||
? newValue(value[key]) | ||
: newValue }); | ||
}); | ||
}; | ||
_this.changeHandlers.set(key, handler); | ||
this.changeHandlers.set(key, handler); | ||
return handler; | ||
}; | ||
return _this; | ||
} | ||
Nested.prototype.render = function () { | ||
var _this = this; | ||
var _a = this.props, _b = _a.field, name = _b.name, value = _b.value, onBlur = _b.onBlur, initialValue = _b.initialValue, error = _b.error, children = _a.children; | ||
var innerFields = utilities_1.mapObject(value, function (value, fieldPath) { | ||
var initialFieldValue = initialValue && initialValue[fieldPath]; | ||
render() { | ||
const { field: { name, value, onBlur, initialValue, error }, children, } = this.props; | ||
const innerFields = mapObject(value, (value, fieldPath) => { | ||
const initialFieldValue = initialValue && initialValue[fieldPath]; | ||
return { | ||
value: value, | ||
onBlur: onBlur, | ||
name: name + "." + fieldPath, | ||
value, | ||
onBlur, | ||
name: `${name}.${fieldPath}`, | ||
initialValue: initialFieldValue, | ||
dirty: value !== initialFieldValue, | ||
error: error && error[fieldPath], | ||
onChange: _this.handleChange(fieldPath), | ||
onChange: this.handleChange(fieldPath), | ||
}; | ||
}); | ||
return children(innerFields); | ||
}; | ||
return Nested; | ||
}(react_1.default.PureComponent)); | ||
exports.default = Nested; | ||
} | ||
} |
@@ -1,84 +0,69 @@ | ||
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
var tslib_1 = require("tslib"); | ||
/* eslint-disable no-case-declarations */ | ||
var react_1 = tslib_1.__importDefault(require("react")); | ||
var utilities_1 = require("./utilities"); | ||
var components_1 = require("./components"); | ||
var FormState = /** @class */ (function (_super) { | ||
tslib_1.__extends(FormState, _super); | ||
function FormState() { | ||
var _this = _super !== null && _super.apply(this, arguments) || this; | ||
_this.state = createFormState(_this.props.initialValues, _this.props.externalErrors); | ||
_this.mounted = false; | ||
_this.fieldsWithHandlers = new WeakMap(); | ||
import React from 'react'; | ||
import { mapObject, set, isEqual, flatMap } from './utilities'; | ||
import { List, Nested } from './components'; | ||
export default class FormState extends React.PureComponent { | ||
constructor() { | ||
super(...arguments); | ||
this.state = createFormState(this.props.initialValues, this.props.externalErrors); | ||
this.mounted = false; | ||
this.fieldsWithHandlers = new WeakMap(); | ||
// eslint-disable-next-line @shopify/react-prefer-private-members | ||
_this.reset = function () { | ||
return new Promise(function (resolve) { | ||
_this.setState(function (_state, props) { | ||
return createFormState(props.initialValues, props.externalErrors); | ||
}, function () { return resolve(); }); | ||
this.reset = () => { | ||
return new Promise(resolve => { | ||
this.setState((_state, props) => createFormState(props.initialValues, props.externalErrors), () => resolve()); | ||
}); | ||
}; | ||
_this.submit = function (event) { return tslib_1.__awaiter(_this, void 0, void 0, function () { | ||
var _a, onSubmit, validateOnSubmit, formData, clientErrors, 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(); | ||
clientErrors = this.clientErrors; | ||
if (clientErrors.length > 0) { | ||
this.setState({ submitting: false, errors: clientErrors }); | ||
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.submit = async (event) => { | ||
const { onSubmit, validateOnSubmit } = this.props; | ||
const { formData } = this; | ||
if (!this.mounted) { | ||
return; | ||
} | ||
if (event && event.preventDefault && !event.defaultPrevented) { | ||
event.preventDefault(); | ||
} | ||
if (onSubmit == null) { | ||
return; | ||
} | ||
this.setState({ submitting: true }); | ||
if (validateOnSubmit) { | ||
await this.validateForm(); | ||
const clientErrors = this.clientErrors; | ||
if (clientErrors.length > 0) { | ||
this.setState({ submitting: false, errors: clientErrors }); | ||
return; | ||
} | ||
}); | ||
}); }; | ||
_this.fieldWithHandlers = function (field, fieldPath) { | ||
if (_this.fieldsWithHandlers.has(field)) { | ||
return _this.fieldsWithHandlers.get(field); | ||
} | ||
var result = tslib_1.__assign(tslib_1.__assign({}, field), { name: String(fieldPath), onChange: _this.updateField.bind(_this, fieldPath), onBlur: _this.blurField.bind(_this, fieldPath) }); | ||
_this.fieldsWithHandlers.set(field, result); | ||
const errors = (await onSubmit(formData)) || []; | ||
if (!this.mounted) { | ||
return; | ||
} | ||
if (errors.length > 0) { | ||
this.updateRemoteErrors(errors); | ||
this.setState({ submitting: false }); | ||
} | ||
else { | ||
this.setState({ submitting: false, errors }); | ||
} | ||
}; | ||
this.fieldWithHandlers = (field, fieldPath) => { | ||
if (this.fieldsWithHandlers.has(field)) { | ||
return this.fieldsWithHandlers.get(field); | ||
} | ||
const result = Object.assign(Object.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; | ||
} | ||
FormState.getDerivedStateFromProps = function (newProps, oldState) { | ||
var initialValues = newProps.initialValues, onInitialValuesChange = newProps.onInitialValuesChange, _a = newProps.externalErrors, externalErrors = _a === void 0 ? [] : _a; | ||
var externalErrorsChanged = !utilities_1.isEqual(externalErrors, oldState.externalErrors); | ||
var updatedExternalErrors = externalErrorsChanged | ||
static getDerivedStateFromProps(newProps, oldState) { | ||
const { initialValues, onInitialValuesChange, externalErrors = [], } = newProps; | ||
const externalErrorsChanged = !isEqual(externalErrors, oldState.externalErrors); | ||
const updatedExternalErrors = externalErrorsChanged | ||
? { | ||
externalErrors: externalErrors, | ||
fields: fieldsWithErrors(oldState.fields, tslib_1.__spread(externalErrors, oldState.errors)), | ||
externalErrors, | ||
fields: fieldsWithErrors(oldState.fields, [ | ||
...externalErrors, | ||
...oldState.errors, | ||
]), | ||
} | ||
@@ -93,4 +78,4 @@ : null; | ||
default: | ||
var oldInitialValues = initialValuesFromFields(oldState.fields); | ||
var valuesMatch = utilities_1.isEqual(oldInitialValues, initialValues); | ||
const oldInitialValues = initialValuesFromFields(oldState.fields); | ||
const valuesMatch = isEqual(oldInitialValues, initialValues); | ||
if (valuesMatch) { | ||
@@ -101,118 +86,86 @@ return updatedExternalErrors; | ||
} | ||
}; | ||
FormState.prototype.componentDidMount = function () { | ||
} | ||
componentDidMount() { | ||
this.mounted = true; | ||
}; | ||
FormState.prototype.componentWillUnmount = function () { | ||
} | ||
componentWillUnmount() { | ||
this.mounted = false; | ||
}; | ||
FormState.prototype.render = function () { | ||
var children = this.props.children; | ||
var submitting = this.state.submitting; | ||
var _a = this, submit = _a.submit, reset = _a.reset, formData = _a.formData; | ||
return children(tslib_1.__assign(tslib_1.__assign({}, formData), { submit: submit, | ||
reset: reset, | ||
submitting: submitting })); | ||
}; | ||
} | ||
render() { | ||
const { children } = this.props; | ||
const { submitting } = this.state; | ||
const { submit, reset, formData } = this; | ||
return children(Object.assign(Object.assign({}, formData), { submit, | ||
reset, | ||
submitting })); | ||
} | ||
// eslint-disable-next-line @shopify/react-prefer-private-members | ||
FormState.prototype.validateForm = function () { | ||
var _this = this; | ||
return new Promise(function (resolve) { | ||
_this.setState(runAllValidators, function () { return resolve(); }); | ||
validateForm() { | ||
return new Promise(resolve => { | ||
this.setState(runAllValidators, () => resolve()); | ||
}); | ||
}; | ||
Object.defineProperty(FormState.prototype, "formData", { | ||
get: function () { | ||
var errors = this.state.errors; | ||
var _a = this.props.externalErrors, externalErrors = _a === void 0 ? [] : _a; | ||
var _b = this, fields = _b.fields, dirty = _b.dirty, valid = _b.valid; | ||
return { | ||
dirty: dirty, | ||
valid: valid, | ||
errors: tslib_1.__spread(errors, externalErrors), | ||
fields: fields, | ||
}; | ||
}, | ||
enumerable: false, | ||
configurable: true | ||
}); | ||
Object.defineProperty(FormState.prototype, "dirty", { | ||
get: function () { | ||
return this.state.dirtyFields.length > 0; | ||
}, | ||
enumerable: false, | ||
configurable: true | ||
}); | ||
Object.defineProperty(FormState.prototype, "valid", { | ||
get: function () { | ||
var _a = this.state, errors = _a.errors, externalErrors = _a.externalErrors; | ||
return (!this.hasClientErrors && | ||
errors.length === 0 && | ||
externalErrors.length === 0); | ||
}, | ||
enumerable: false, | ||
configurable: true | ||
}); | ||
Object.defineProperty(FormState.prototype, "hasClientErrors", { | ||
get: function () { | ||
var fields = this.state.fields; | ||
return Object.keys(fields).some(function (fieldPath) { | ||
var field = fields[fieldPath]; | ||
return field.error != null; | ||
}); | ||
}, | ||
enumerable: false, | ||
configurable: true | ||
}); | ||
Object.defineProperty(FormState.prototype, "clientErrors", { | ||
get: function () { | ||
var fields = this.state.fields; | ||
return utilities_1.flatMap(Object.values(fields), function (_a) { | ||
var error = _a.error; | ||
return collectErrors(error); | ||
}); | ||
}, | ||
enumerable: false, | ||
configurable: true | ||
}); | ||
Object.defineProperty(FormState.prototype, "fields", { | ||
get: function () { | ||
var fields = this.state.fields; | ||
var fieldDescriptors = utilities_1.mapObject(fields, this.fieldWithHandlers); | ||
return fieldDescriptors; | ||
}, | ||
enumerable: false, | ||
configurable: true | ||
}); | ||
FormState.prototype.updateField = function (fieldPath, value) { | ||
var _this = this; | ||
this.setState(function (_a) { | ||
var _b; | ||
var fields = _a.fields, dirtyFields = _a.dirtyFields; | ||
var field = fields[fieldPath]; | ||
var newValue = typeof value === 'function' | ||
} | ||
get formData() { | ||
const { errors } = this.state; | ||
const { externalErrors = [] } = this.props; | ||
const { fields, dirty, valid } = this; | ||
return { | ||
dirty, | ||
valid, | ||
errors: [...errors, ...externalErrors], | ||
fields, | ||
}; | ||
} | ||
get dirty() { | ||
return this.state.dirtyFields.length > 0; | ||
} | ||
get valid() { | ||
const { errors, externalErrors } = this.state; | ||
return (!this.hasClientErrors && | ||
errors.length === 0 && | ||
externalErrors.length === 0); | ||
} | ||
get hasClientErrors() { | ||
const { fields } = this.state; | ||
return Object.keys(fields).some(fieldPath => { | ||
const field = fields[fieldPath]; | ||
return field.error != null; | ||
}); | ||
} | ||
get clientErrors() { | ||
const { fields } = this.state; | ||
return flatMap(Object.values(fields), ({ error }) => collectErrors(error)); | ||
} | ||
get fields() { | ||
const { fields } = this.state; | ||
const fieldDescriptors = mapObject(fields, this.fieldWithHandlers); | ||
return fieldDescriptors; | ||
} | ||
updateField(fieldPath, value) { | ||
this.setState(({ fields, dirtyFields }) => { | ||
const field = fields[fieldPath]; | ||
const newValue = typeof value === 'function' | ||
? value(field.value) | ||
: value; | ||
var dirty = !utilities_1.isEqual(newValue, field.initialValue); | ||
var updatedField = _this.getUpdatedField({ | ||
fieldPath: fieldPath, | ||
field: field, | ||
const dirty = !isEqual(newValue, field.initialValue); | ||
const updatedField = this.getUpdatedField({ | ||
fieldPath, | ||
field, | ||
value: newValue, | ||
dirty: dirty, | ||
dirty, | ||
}); | ||
return { | ||
dirtyFields: _this.getUpdatedDirtyFields({ | ||
fieldPath: fieldPath, | ||
dirty: dirty, | ||
dirtyFields: dirtyFields, | ||
dirtyFields: this.getUpdatedDirtyFields({ | ||
fieldPath, | ||
dirty, | ||
dirtyFields, | ||
}), | ||
fields: updatedField === field | ||
? fields | ||
: tslib_1.__assign(tslib_1.__assign({}, fields), (_b = {}, _b[fieldPath] = updatedField, _b)), | ||
: Object.assign(Object.assign({}, fields), { [fieldPath]: updatedField }), | ||
}; | ||
}); | ||
}; | ||
FormState.prototype.getUpdatedDirtyFields = function (_a) { | ||
var fieldPath = _a.fieldPath, dirty = _a.dirty, dirtyFields = _a.dirtyFields; | ||
var dirtyFieldsSet = new Set(dirtyFields); | ||
} | ||
getUpdatedDirtyFields({ fieldPath, dirty, dirtyFields, }) { | ||
const dirtyFieldsSet = new Set(dirtyFields); | ||
if (dirty) { | ||
@@ -224,81 +177,69 @@ dirtyFieldsSet.add(fieldPath); | ||
} | ||
var newDirtyFields = Array.from(dirtyFieldsSet); | ||
const newDirtyFields = Array.from(dirtyFieldsSet); | ||
return dirtyFields.length === newDirtyFields.length | ||
? dirtyFields | ||
: newDirtyFields; | ||
}; | ||
FormState.prototype.getUpdatedField = function (_a) { | ||
var fieldPath = _a.fieldPath, field = _a.field, value = _a.value, dirty = _a.dirty; | ||
} | ||
getUpdatedField({ fieldPath, field, value, dirty, }) { | ||
// We only want to update errors as the user types if they already have an error. | ||
// https://polaris.shopify.com/patterns/error-messages#section-form-validation | ||
var skipValidation = field.error == null; | ||
var error = skipValidation | ||
const skipValidation = field.error == null; | ||
const error = skipValidation | ||
? field.error | ||
: this.validateFieldValue(fieldPath, { value: value, dirty: dirty }); | ||
: this.validateFieldValue(fieldPath, { value, dirty }); | ||
if (value === field.value && error === field.error) { | ||
return field; | ||
} | ||
return tslib_1.__assign(tslib_1.__assign({}, field), { value: value, | ||
dirty: dirty, | ||
error: error }); | ||
}; | ||
FormState.prototype.blurField = function (fieldPath) { | ||
var fields = this.state.fields; | ||
var field = fields[fieldPath]; | ||
var error = this.validateFieldValue(fieldPath, field); | ||
return Object.assign(Object.assign({}, field), { value, | ||
dirty, | ||
error }); | ||
} | ||
blurField(fieldPath) { | ||
const { fields } = this.state; | ||
const field = fields[fieldPath]; | ||
const error = this.validateFieldValue(fieldPath, field); | ||
if (error == null) { | ||
return; | ||
} | ||
this.setState(function (state) { | ||
var _a; | ||
return ({ | ||
fields: tslib_1.__assign(tslib_1.__assign({}, state.fields), (_a = {}, _a[fieldPath] = tslib_1.__assign(tslib_1.__assign({}, state.fields[fieldPath]), { error: error }), _a)), | ||
}); | ||
}); | ||
}; | ||
FormState.prototype.validateFieldValue = function (fieldPath, _a) { | ||
var value = _a.value, dirty = _a.dirty; | ||
this.setState(state => ({ | ||
fields: Object.assign(Object.assign({}, state.fields), { [fieldPath]: Object.assign(Object.assign({}, state.fields[fieldPath]), { error }) }), | ||
})); | ||
} | ||
validateFieldValue(fieldPath, { value, dirty }) { | ||
if (!dirty) { | ||
return; | ||
} | ||
var _b = this.props.validators, validators = _b === void 0 ? {} : _b; | ||
var fields = this.state.fields; | ||
const { validators = {}, } = this.props; | ||
const { fields } = this.state; | ||
return runValidator(validators[fieldPath], value, fields); | ||
}; | ||
FormState.prototype.updateRemoteErrors = function (errors) { | ||
this.setState(function (_a) { | ||
var fields = _a.fields, externalErrors = _a.externalErrors; | ||
return ({ | ||
errors: errors, | ||
fields: fieldsWithErrors(fields, tslib_1.__spread(errors, externalErrors)), | ||
}); | ||
}); | ||
}; | ||
FormState.List = components_1.List; | ||
FormState.Nested = components_1.Nested; | ||
return FormState; | ||
}(react_1.default.PureComponent)); | ||
exports.default = FormState; | ||
} | ||
updateRemoteErrors(errors) { | ||
this.setState(({ fields, externalErrors }) => ({ | ||
errors, | ||
fields: fieldsWithErrors(fields, [...errors, ...externalErrors]), | ||
})); | ||
} | ||
} | ||
FormState.List = List; | ||
FormState.Nested = Nested; | ||
function fieldsWithErrors(fields, errors) { | ||
var errorDictionary = errors.reduce(function (accumulator, _a) { | ||
var field = _a.field, message = _a.message; | ||
const errorDictionary = errors.reduce((accumulator, { field, message }) => { | ||
if (field == null) { | ||
return accumulator; | ||
} | ||
return utilities_1.set(accumulator, field, message); | ||
return set(accumulator, field, message); | ||
}, {}); | ||
return utilities_1.mapObject(fields, function (field, path) { | ||
return mapObject(fields, (field, path) => { | ||
if (!errorDictionary[path]) { | ||
return field; | ||
} | ||
return tslib_1.__assign(tslib_1.__assign({}, field), { error: errorDictionary[path] }); | ||
return Object.assign(Object.assign({}, field), { error: errorDictionary[path] }); | ||
}); | ||
} | ||
function reconcileFormState(values, oldState, externalErrors) { | ||
if (externalErrors === void 0) { externalErrors = []; } | ||
var oldFields = oldState.fields; | ||
var dirtyFields = new Set(oldState.dirtyFields); | ||
var fields = utilities_1.mapObject(values, function (value, key) { | ||
var oldField = oldFields[key]; | ||
if (utilities_1.isEqual(value, oldField.initialValue)) { | ||
function reconcileFormState(values, oldState, externalErrors = []) { | ||
const { fields: oldFields } = oldState; | ||
const dirtyFields = new Set(oldState.dirtyFields); | ||
const fields = mapObject(values, (value, key) => { | ||
const oldField = oldFields[key]; | ||
if (isEqual(value, oldField.initialValue)) { | ||
return oldField; | ||
@@ -308,3 +249,3 @@ } | ||
return { | ||
value: value, | ||
value, | ||
initialValue: value, | ||
@@ -314,9 +255,8 @@ dirty: false, | ||
}); | ||
return tslib_1.__assign(tslib_1.__assign({}, oldState), { dirtyFields: Array.from(dirtyFields), fields: fieldsWithErrors(fields, externalErrors) }); | ||
return Object.assign(Object.assign({}, oldState), { dirtyFields: Array.from(dirtyFields), fields: fieldsWithErrors(fields, externalErrors) }); | ||
} | ||
function createFormState(values, externalErrors) { | ||
if (externalErrors === void 0) { externalErrors = []; } | ||
var fields = utilities_1.mapObject(values, function (value) { | ||
function createFormState(values, externalErrors = []) { | ||
const fields = mapObject(values, value => { | ||
return { | ||
value: value, | ||
value, | ||
initialValue: value, | ||
@@ -330,3 +270,3 @@ dirty: false, | ||
submitting: false, | ||
externalErrors: externalErrors, | ||
externalErrors, | ||
fields: fieldsWithErrors(fields, externalErrors), | ||
@@ -336,9 +276,5 @@ }; | ||
function initialValuesFromFields(fields) { | ||
return utilities_1.mapObject(fields, function (_a) { | ||
var initialValue = _a.initialValue; | ||
return initialValue; | ||
}); | ||
return mapObject(fields, ({ initialValue }) => initialValue); | ||
} | ||
function runValidator(validate, value, fields) { | ||
if (validate === void 0) { validate = function () { }; } | ||
function runValidator(validate = () => { }, value, fields) { | ||
if (typeof validate === 'function') { | ||
@@ -350,5 +286,5 @@ return validate(value, fields); | ||
} | ||
var errors = validate | ||
.map(function (validator) { return validator(value, fields); }) | ||
.filter(function (input) { return input != null; }); | ||
const errors = validate | ||
.map(validator => validator(value, fields)) | ||
.filter(input => input != null); | ||
if (errors.length === 0) { | ||
@@ -360,11 +296,11 @@ return; | ||
function runAllValidators(state, props) { | ||
var fields = state.fields; | ||
var validators = props.validators; | ||
const { fields } = state; | ||
const { validators } = props; | ||
if (!validators) { | ||
return null; | ||
} | ||
var updatedFields = utilities_1.mapObject(fields, function (field, path) { | ||
return tslib_1.__assign(tslib_1.__assign({}, field), { error: runValidator(validators[path], field.value, fields) }); | ||
const updatedFields = mapObject(fields, (field, path) => { | ||
return Object.assign(Object.assign({}, field), { error: runValidator(validators[path], field.value, fields) }); | ||
}); | ||
return tslib_1.__assign(tslib_1.__assign({}, state), { fields: updatedFields }); | ||
return Object.assign(Object.assign({}, state), { fields: updatedFields }); | ||
} | ||
@@ -376,10 +312,8 @@ function collectErrors(message) { | ||
if (typeof message === 'string') { | ||
return [{ message: message }]; | ||
return [{ message }]; | ||
} | ||
if (Array.isArray(message)) { | ||
return utilities_1.flatMap(message, function (itemError) { return collectErrors(itemError); }); | ||
return flatMap(message, itemError => collectErrors(itemError)); | ||
} | ||
return utilities_1.flatMap(Object.values(message), function (nestedError) { | ||
return collectErrors(nestedError); | ||
}); | ||
return flatMap(Object.values(message), nestedError => collectErrors(nestedError)); | ||
} |
@@ -1,14 +0,9 @@ | ||
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.arrayUtils = exports.asChoiceField = void 0; | ||
var tslib_1 = require("tslib"); | ||
var FormState_1 = tslib_1.__importDefault(require("./FormState")); | ||
var utilities_1 = require("./utilities"); | ||
Object.defineProperty(exports, "asChoiceField", { enumerable: true, get: function () { return utilities_1.asChoiceField; } }); | ||
exports.arrayUtils = { push: utilities_1.push, replace: utilities_1.replace, remove: utilities_1.remove }; | ||
var validators_1 = require("./validators"); | ||
Object.defineProperty(exports, "validators", { enumerable: true, get: function () { return validators_1.default; } }); | ||
tslib_1.__exportStar(require("./validators"), exports); | ||
tslib_1.__exportStar(require("./types"), exports); | ||
tslib_1.__exportStar(require("./FormState"), exports); | ||
exports.default = FormState_1.default; | ||
import FormState from './FormState'; | ||
import { asChoiceField, push, replace, remove, } from './utilities'; | ||
export { asChoiceField }; | ||
export const arrayUtils = { push, replace, remove }; | ||
export { default as validators } from './validators'; | ||
export * from './validators'; | ||
export * from './types'; | ||
export * from './FormState'; | ||
export default FormState; |
@@ -1,10 +0,5 @@ | ||
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.asChoiceField = exports.flatMap = exports.set = exports.replace = exports.remove = exports.push = exports.mapObject = exports.isEqual = void 0; | ||
var tslib_1 = require("tslib"); | ||
var fast_deep_equal_1 = tslib_1.__importDefault(require("fast-deep-equal")); | ||
exports.isEqual = fast_deep_equal_1.default; | ||
function mapObject(input, mapper) { | ||
return Object.entries(input).reduce(function (accumulator, _a) { | ||
var _b = tslib_1.__read(_a, 2), key = _b[0], value = _b[1]; | ||
import isEqual from 'fast-deep-equal'; | ||
export { isEqual }; | ||
export function mapObject(input, mapper) { | ||
return Object.entries(input).reduce((accumulator, [key, value]) => { | ||
accumulator[key] = mapper(value, key); | ||
@@ -14,17 +9,10 @@ return accumulator; | ||
} | ||
exports.mapObject = mapObject; | ||
function push(array) { | ||
var values = []; | ||
for (var _i = 1; _i < arguments.length; _i++) { | ||
values[_i - 1] = arguments[_i]; | ||
} | ||
export function push(array, ...values) { | ||
return array.concat(values); | ||
} | ||
exports.push = push; | ||
function remove(array, targetIndex) { | ||
return array.filter(function (_, index) { return index !== targetIndex; }); | ||
export function remove(array, targetIndex) { | ||
return array.filter((_, index) => index !== targetIndex); | ||
} | ||
exports.remove = remove; | ||
function replace(array, targetIndex, newValue) { | ||
return array.map(function (value, index) { | ||
export function replace(array, targetIndex, newValue) { | ||
return array.map((value, index) => { | ||
if (index !== targetIndex) { | ||
@@ -36,5 +24,3 @@ return value; | ||
} | ||
exports.replace = replace; | ||
function set(rootObject, path, value) { | ||
var _a, _b; | ||
export function set(rootObject, path, value) { | ||
if (path.length === 0) { | ||
@@ -44,14 +30,12 @@ return rootObject; | ||
else if (path.length === 1) { | ||
return tslib_1.__assign(tslib_1.__assign({}, rootObject), (_a = {}, _a[path[0]] = value, _a)); | ||
return Object.assign(Object.assign({}, rootObject), { [path[0]]: value }); | ||
} | ||
else { | ||
var _c = tslib_1.__read(path), current = _c[0], rest = _c.slice(1); | ||
return tslib_1.__assign(tslib_1.__assign({}, rootObject), (_b = {}, _b[current] = set(rootObject[current] || {}, rest, value), _b)); | ||
const [current, ...rest] = path; | ||
return Object.assign(Object.assign({}, rootObject), { [current]: set(rootObject[current] || {}, rest, value) }); | ||
} | ||
} | ||
exports.set = set; | ||
function flatMap(array, mapper) { | ||
return array.reduce(function (acc, item, index) { return acc.concat(mapper(item, index)); }, []); | ||
export function flatMap(array, mapper) { | ||
return array.reduce((acc, item, index) => acc.concat(mapper(item, index)), []); | ||
} | ||
exports.flatMap = flatMap; | ||
/** | ||
@@ -61,6 +45,5 @@ * Transforms a boolean FieldDescriptor object to work with checkboxes and radios. | ||
*/ | ||
function asChoiceField(_a) { | ||
var checked = _a.value, fieldData = tslib_1.__rest(_a, ["value"]); | ||
return tslib_1.__assign({ checked: checked }, fieldData); | ||
export function asChoiceField(_a) { | ||
var { value: checked } = _a, fieldData = __rest(_a, ["value"]); | ||
return Object.assign({ checked }, fieldData); | ||
} | ||
exports.asChoiceField = asChoiceField; |
@@ -1,10 +0,7 @@ | ||
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.validateRequired = exports.validate = exports.validateWithFields = exports.validateList = exports.validateNested = void 0; | ||
var predicates_1 = require("@shopify/predicates"); | ||
var utilities_1 = require("./utilities"); | ||
function validateNested(validatorDictionary) { | ||
return function (input, fields) { | ||
var errors = utilities_1.mapObject(input, function (value, field) { | ||
var validate = validatorDictionary[field]; | ||
import { lengthLessThan, lengthMoreThan, notEmpty, notEmptyString, isEmpty, notNumericString, isNumericString, isPositiveNumericString, } from '@shopify/predicates'; | ||
import { mapObject } from './utilities'; | ||
export function validateNested(validatorDictionary) { | ||
return (input, fields) => { | ||
const errors = mapObject(input, (value, field) => { | ||
const validate = validatorDictionary[field]; | ||
if (validate == null) { | ||
@@ -19,5 +16,5 @@ return null; | ||
} | ||
var errors = validate | ||
.map(function (validator) { return validator(value, fields); }) | ||
.filter(function (input) { return input != null; }); | ||
const errors = validate | ||
.map(validator => validator(value, fields)) | ||
.filter(input => input != null); | ||
if (errors.length === 0) { | ||
@@ -28,5 +25,5 @@ return; | ||
}); | ||
var anyErrors = Object.keys(errors) | ||
.map(function (key) { return errors[key]; }) | ||
.some(function (value) { return value != null; }); | ||
const anyErrors = Object.keys(errors) | ||
.map(key => errors[key]) | ||
.some(value => value != null); | ||
if (anyErrors) { | ||
@@ -37,8 +34,7 @@ return errors; | ||
} | ||
exports.validateNested = validateNested; | ||
function validateList(validatorDictionary) { | ||
var validateItem = validateNested(validatorDictionary); | ||
return function (input, fields) { | ||
var errors = input.map(function (item) { return validateItem(item, fields); }); | ||
if (errors.some(function (error) { return error != null; })) { | ||
export function validateList(validatorDictionary) { | ||
const validateItem = validateNested(validatorDictionary); | ||
return (input, fields) => { | ||
const errors = input.map(item => validateItem(item, fields)); | ||
if (errors.some(error => error != null)) { | ||
return errors; | ||
@@ -48,10 +44,8 @@ } | ||
} | ||
exports.validateList = validateList; | ||
function validateWithFields(matcher, errorContent) { | ||
export function validateWithFields(matcher, errorContent) { | ||
return validate(matcher, errorContent); | ||
} | ||
exports.validateWithFields = validateWithFields; | ||
function validate(matcher, errorContent) { | ||
return function (input, fields) { | ||
var matches = matcher(input, fields); | ||
export function validate(matcher, errorContent) { | ||
return (input, fields) => { | ||
const matches = matcher(input, fields); | ||
/* | ||
@@ -61,3 +55,3 @@ always mark empty fields valid to match Polaris guidelines | ||
*/ | ||
if (predicates_1.isEmpty(input)) { | ||
if (isEmpty(input)) { | ||
return; | ||
@@ -74,6 +68,5 @@ } | ||
} | ||
exports.validate = validate; | ||
function validateRequired(matcher, errorContent) { | ||
return function (input, fields) { | ||
var matches = matcher(input, fields); | ||
export function validateRequired(matcher, errorContent) { | ||
return (input, fields) => { | ||
const matches = matcher(input, fields); | ||
if (matches) { | ||
@@ -88,24 +81,23 @@ return; | ||
} | ||
exports.validateRequired = validateRequired; | ||
var validators = { | ||
lengthMoreThan: function (length, errorContent) { | ||
return validate(predicates_1.lengthMoreThan(length), errorContent); | ||
const validators = { | ||
lengthMoreThan(length, errorContent) { | ||
return validate(lengthMoreThan(length), errorContent); | ||
}, | ||
lengthLessThan: function (length, errorContent) { | ||
return validate(predicates_1.lengthLessThan(length), errorContent); | ||
lengthLessThan(length, errorContent) { | ||
return validate(lengthLessThan(length), errorContent); | ||
}, | ||
numericString: function (errorContent) { | ||
return validate(predicates_1.isNumericString, errorContent); | ||
numericString(errorContent) { | ||
return validate(isNumericString, errorContent); | ||
}, | ||
positiveNumericString: function (errorContent) { | ||
return validate(predicates_1.isPositiveNumericString, errorContent); | ||
positiveNumericString(errorContent) { | ||
return validate(isPositiveNumericString, errorContent); | ||
}, | ||
nonNumericString: function (errorContent) { | ||
return validate(predicates_1.notNumericString, errorContent); | ||
nonNumericString(errorContent) { | ||
return validate(notNumericString, errorContent); | ||
}, | ||
requiredString: function (errorContent) { | ||
return validateRequired(predicates_1.notEmptyString, errorContent); | ||
requiredString(errorContent) { | ||
return validateRequired(notEmptyString, errorContent); | ||
}, | ||
required: function (errorContent) { | ||
return validateRequired(predicates_1.notEmpty, errorContent); | ||
required(errorContent) { | ||
return validateRequired(notEmpty, errorContent); | ||
}, | ||
@@ -119,2 +111,2 @@ }; | ||
} | ||
exports.default = validators; | ||
export default validators; |
@@ -8,6 +8,12 @@ # Changelog | ||
<!-- ## [Unreleased] --> | ||
<!-- ## Unreleased --> | ||
## [0.12.2] - 2021-03-03 | ||
## 0.12.4 - 2021-04-13 | ||
### Changed | ||
- Removed dependency on tslib, as we no-longer compile with `tsc`. [#1829](https://github.com/Shopify/quilt/pull/1829) | ||
## 0.12.2 - 2021-03-03 | ||
### Fixed | ||
@@ -17,3 +23,3 @@ | ||
## [0.12.0] - 2020-12-18 | ||
## 0.12.0 - 2020-12-18 | ||
@@ -25,3 +31,3 @@ ### Added | ||
## [0.11.28] - 2020-10-23 | ||
## 0.11.28 - 2020-10-23 | ||
@@ -32,7 +38,7 @@ ### Fixed | ||
## [0.11.27] - 2020-10-20 | ||
## 0.11.27 - 2020-10-20 | ||
- Updated `tslib` dependency to `^1.14.1`. [#1657](https://github.com/Shopify/quilt/pull/1657) | ||
## [0.11.11] - 2019-10-01 | ||
## 0.11.11 - 2019-10-01 | ||
@@ -43,3 +49,3 @@ ### Added | ||
## [0.11.8] - 2019-08-29 | ||
## 0.11.8 - 2019-08-29 | ||
@@ -50,3 +56,3 @@ ### Fixed | ||
## [0.11.3] | ||
## 0.11.3 | ||
@@ -57,3 +63,3 @@ ### Added | ||
## [0.11.2] - 2019-05-22 | ||
## 0.11.2 - 2019-05-22 | ||
@@ -64,3 +70,3 @@ ### Fixed | ||
## [0.11.1] - 2019-05-15 | ||
## 0.11.1 - 2019-05-15 | ||
@@ -71,3 +77,3 @@ ### Fixed | ||
## [0.10.0] | ||
## 0.10.0 | ||
@@ -78,3 +84,3 @@ ### Changed | ||
## [0.9.1] | ||
## 0.9.1 | ||
@@ -85,3 +91,3 @@ ### Changed | ||
## [0.9.0] | ||
## 0.9.0 | ||
@@ -92,3 +98,3 @@ ### Removed | ||
## [0.8.0] | ||
## 0.8.0 | ||
@@ -107,3 +113,3 @@ ### Added | ||
## [0.7.0] | ||
## 0.7.0 | ||
@@ -118,3 +124,3 @@ ### Added | ||
## [0.6.0] | ||
## 0.6.0 | ||
@@ -125,3 +131,3 @@ ### Added | ||
## [0.5.0] | ||
## 0.5.0 | ||
@@ -132,3 +138,3 @@ ### Added | ||
## [0.4.1] | ||
## 0.4.1 | ||
@@ -139,3 +145,3 @@ ### Fixed | ||
## [0.4.0] | ||
## 0.4.0 | ||
@@ -146,3 +152,3 @@ ### Added | ||
## [0.3.3] | ||
## 0.3.3 | ||
@@ -153,3 +159,3 @@ ### Fixed | ||
## [0.3.2] | ||
## 0.3.2 | ||
@@ -160,3 +166,3 @@ ### Fixed | ||
## [0.3.0] | ||
## 0.3.0 | ||
@@ -167,3 +173,3 @@ ### Added | ||
## [0.2.10] | ||
## 0.2.10 | ||
@@ -174,3 +180,3 @@ ### Fixed | ||
## [0.2.9] | ||
## 0.2.9 | ||
@@ -181,3 +187,3 @@ ### Fixed | ||
## [0.2.8] | ||
## 0.2.8 | ||
@@ -184,0 +190,0 @@ ### Changed |
{ | ||
"name": "@shopify/react-form-state", | ||
"version": "0.12.3", | ||
"version": "0.12.4", | ||
"license": "MIT", | ||
@@ -8,5 +8,2 @@ "description": "Manage React forms tersely and type-safely with no magic", | ||
"types": "index.d.ts", | ||
"scripts": { | ||
"build": "tsc --p tsconfig.json" | ||
}, | ||
"publishConfig": { | ||
@@ -27,5 +24,4 @@ "access": "public", | ||
"dependencies": { | ||
"@shopify/predicates": "^1.3.3", | ||
"fast-deep-equal": "^3.1.3", | ||
"tslib": "^1.14.1" | ||
"@shopify/predicates": "^1.3.4", | ||
"fast-deep-equal": "^3.1.3" | ||
}, | ||
@@ -36,4 +32,4 @@ "peerDependencies": { | ||
"devDependencies": { | ||
"@shopify/enzyme-utilities": "^2.2.3", | ||
"@shopify/useful-types": "^2.3.3", | ||
"@shopify/enzyme-utilities": "^2.2.4", | ||
"@shopify/useful-types": "^2.3.4", | ||
"faker": "^4.1.0" | ||
@@ -40,0 +36,0 @@ }, |
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
3
178756
3401
- Removedtslib@^1.14.1
- Removedtslib@1.14.1(transitive)
Updated@shopify/predicates@^1.3.4