@shopify/react-form
Version:
Manage React forms tersely and safely-typed with no magic using React hooks
116 lines (113 loc) • 2.78 kB
JavaScript
import { useReducer } from 'react';
import { shallowArrayComparison, defaultDirtyComparator } from '../../utilities.mjs';
function updateAction(value) {
return {
type: 'update',
payload: value
};
}
function resetAction() {
return {
type: 'reset'
};
}
function newDefaultAction(value) {
return {
type: 'newDefaultValue',
payload: value
};
}
function updateErrorAction(error) {
return {
type: 'updateError',
payload: error
};
}
const shallowFieldReducer = makeFieldReducer({
dirtyStateComparator: defaultDirtyComparator
});
function reduceField(prevState, action) {
return shallowFieldReducer(prevState, action);
}
function makeFieldReducer({
dirtyStateComparator = defaultDirtyComparator
}) {
return (state, action) => {
switch (action.type) {
case 'update':
{
const newValue = action.payload;
const {
defaultValue
} = state;
const dirty = dirtyStateComparator(defaultValue, newValue);
return {
...state,
dirty,
value: newValue,
touched: true
};
}
case 'updateError':
{
const payload = Array.isArray(action.payload) ? action.payload : [action.payload];
const [firstError] = payload;
const allErrors = firstError ? payload : [];
if (shallowArrayComparison(allErrors, state.allErrors)) {
return {
...state,
error: firstError
};
} else {
return {
...state,
error: firstError,
allErrors
};
}
}
case 'reset':
{
const {
defaultValue
} = state;
return {
...state,
error: undefined,
value: defaultValue,
dirty: false,
touched: false,
allErrors: []
};
}
case 'newDefaultValue':
{
const newDefaultValue = action.payload;
return {
...state,
error: undefined,
value: newDefaultValue,
defaultValue: newDefaultValue,
touched: false,
dirty: false
};
}
}
};
}
function useFieldReducer(value, dirtyStateComparator) {
return useReducer(makeFieldReducer({
dirtyStateComparator
}), initialFieldState(value));
}
function initialFieldState(value) {
return {
value,
defaultValue: value,
error: undefined,
touched: false,
dirty: false,
allErrors: []
};
}
export { initialFieldState, makeFieldReducer, newDefaultAction, reduceField, resetAction, updateAction, updateErrorAction, useFieldReducer };