use-form
Version:
335 lines (334 loc) • 15.8 kB
JavaScript
"use strict";
var __assign = (this && this.__assign) || function () {
__assign = Object.assign || function(t) {
for (var s, i = 1, n = arguments.length; i < n; i++) {
s = arguments[i];
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
t[p] = s[p];
}
return t;
};
return __assign.apply(this, arguments);
};
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __generator = (this && this.__generator) || function (thisArg, body) {
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
function verb(n) { return function (v) { return step([n, v]); }; }
function step(op) {
if (f) throw new TypeError("Generator is already executing.");
while (_) try {
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
if (y = 0, t) op = [op[0] & 2, t.value];
switch (op[0]) {
case 0: case 1: t = op; break;
case 4: _.label++; return { value: op[1], done: false };
case 5: _.label++; y = op[1]; op = [0]; continue;
case 7: op = _.ops.pop(); _.trys.pop(); continue;
default:
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
if (t[2]) _.ops.pop();
_.trys.pop(); continue;
}
op = body.call(thisArg, _);
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
}
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
exports.__esModule = true;
var nest_deep_1 = require("nest-deep");
var get_1 = __importDefault(require("./helpers/get"));
var isEmpty_1 = __importDefault(require("./helpers/isEmpty"));
var isEqual_1 = __importDefault(require("./helpers/isEqual"));
var isEvent_1 = __importDefault(require("./helpers/isEvent"));
var noop_1 = __importDefault(require("./helpers/noop"));
var typeOf_1 = require("./helpers/typeOf");
function mapped(map) {
return Array.from(map.entries()).reduce(function (accumulator, _a) {
var _b;
var key = _a[0], value = _a[1];
return (__assign({}, accumulator, (_b = {}, _b[key] = value, _b)));
}, {});
}
var keys = Object.keys;
var Api = /** @class */ (function () {
function Api(_a) {
var _this = this;
var _b = _a.validate, validate = _b === void 0 ? noop_1["default"] : _b, _c = _a.onSubmit, onSubmit = _c === void 0 ? noop_1["default"] : _c, _d = _a.initialValues, initialValues = _d === void 0 ? {} : _d, _e = _a.initialErrors, initialErrors = _e === void 0 ? {} : _e;
this.listener = {
on: function (name, callback) { return _this.listeners.set(name, callback); },
off: function (name) { return _this.listeners["delete"](name); },
emit: function () { return __awaiter(_this, void 0, void 0, function () { return __generator(this, function (_a) {
return [2 /*return*/, this.listeners.forEach(function (listener) { return listener(); })];
}); }); }
};
this.listeners = new Map();
this.initialValues = new Map();
this.initialErrors = new Map();
this.fields = new Map();
this.values = new Map();
this.meta = {
errors: new Map(),
touched: new Map(),
validations: new Map()
};
this.submitting = false;
this.handleReset = function (event) { return __awaiter(_this, void 0, void 0, function () {
var prevValues, prevValueKeys, nextValues_1, nextErrors_1;
var _this = this;
return __generator(this, function (_a) {
prevValues = mapped(this.values);
prevValueKeys = keys(__assign({}, prevValues, nest_deep_1.flatten(prevValues)));
this.values.clear();
this.meta.errors.clear();
this.meta.touched.clear();
if (isEvent_1["default"](event)) {
event.preventDefault();
event.stopPropagation();
prevValueKeys.map(function (key) {
_this.setValue(key, _this.getDefaultValue(key));
});
keys(mapped(this.initialErrors)).map(function (key) {
_this.setError(key, _this.getDefaultError(key));
});
}
else if (typeOf_1.isObject(event) && !isEmpty_1["default"](event)) {
this.initialValues.clear();
this.initialErrors.clear();
nextValues_1 = nest_deep_1.flatten(event.values);
nextErrors_1 = nest_deep_1.flatten(event.errors);
keys(nextValues_1).map(function (key) {
_this.initialValues.set(key, nextValues_1[key]);
_this.setValue(key, _this.getDefaultValue(key));
});
keys(nextErrors_1).map(function (key) {
_this.initialErrors.set(key, nextErrors_1[key]);
_this.setError(key, nextErrors_1[key]);
});
}
this.listener.emit();
return [2 /*return*/];
});
}); };
this.handleSubmit = function (event) { return __awaiter(_this, void 0, void 0, function () {
var _a, errors, values;
return __generator(this, function (_b) {
switch (_b.label) {
case 0:
if (isEvent_1["default"](event)) {
event.preventDefault();
event.stopPropagation();
}
this.submitting = true;
return [4 /*yield*/, this.listener.emit()];
case 1:
_b.sent();
this.handleValidate(this.getState().values);
_a = this.getState(), errors = _a.errors, values = _a.values;
if (!(!errors || isEmpty_1["default"](errors))) return [3 /*break*/, 3];
return [4 /*yield*/, this.onSubmit(values)];
case 2:
_b.sent();
_b.label = 3;
case 3:
this.submitting = false;
this.listener.emit();
return [2 /*return*/];
}
});
}); };
this.getState = function () {
var errors = nest_deep_1.nested(mapped(_this.meta.errors));
var State = {
fields: nest_deep_1.nested(mapped(_this.fields)),
values: nest_deep_1.nested(mapped(_this.values)),
errors: errors,
touched: nest_deep_1.nested(mapped(_this.meta.touched)),
valid: keys(errors).length === 0,
submitting: _this.submitting
};
return State;
};
this.getField = function (name) {
return __assign({ value: get_1["default"](nest_deep_1.nested(mapped(_this.values)), name, '') }, get_1["default"](nest_deep_1.nested(mapped(_this.fields)), name, {}));
};
this.setField = function (name) { return ({
mount: function (_a) {
var _b = _a.type, type = _b === void 0 ? 'text' : _b, _c = _a.validate, validate = _c === void 0 ? noop_1["default"] : _c, multiple = _a.multiple;
_this.fields.set(name, {
type: type,
name: name,
multiple: multiple
});
_this.setValue(name, _this.getDefaultValue(name));
var defaultError = _this.getDefaultError(name);
_this.setError(name, defaultError);
_this.setMeta(name, 'validations', validate);
return _this.getField(name);
},
unmount: function () {
_this.fields["delete"](name);
_this.values["delete"](name);
_this.meta.errors["delete"](name);
_this.meta.touched["delete"](name);
_this.meta.validations["delete"](name);
},
value: function (event) {
var _a;
var value = _this.getValue(name, event);
var state = _this.setValue(name, value);
_this.setError(name);
_this.handleValidate((_a = {},
_a[name] = value,
_a));
_this.listener.emit();
return state;
},
error: function (error) {
var state = _this.setError(name, error);
_this.listener.emit();
return state;
},
meta: function (metaKey, metaValue) {
_this.setMeta(name, metaKey, metaValue);
var state = _this.getField(name);
_this.listener.emit();
return state;
}
}); };
this.getMeta = function (name) {
var State = {
error: get_1["default"](nest_deep_1.nested(mapped(_this.meta.errors)), name),
touched: _this.meta.touched.get(name),
validate: _this.meta.validations.get(name)
};
return State;
};
this.setMeta = function (name, metaKey, metaValue) {
if (metaValue) {
_this.meta[metaKey].set(name, metaValue);
}
else {
_this.meta[metaKey]["delete"](name);
}
return _this.getField(name);
};
this.getDefaultValue = function (name) {
var _a = _this.getField(name), type = _a.type, multiple = _a.multiple;
var defaultValue;
switch (type) {
case 'checkbox':
defaultValue = false;
break;
case 'select':
defaultValue = '';
if (multiple) {
defaultValue = [];
}
break;
default:
defaultValue = '';
break;
}
return get_1["default"](nest_deep_1.nested(mapped(_this.initialValues)), name, defaultValue);
};
this.getValue = function (name, event) {
if (isEvent_1["default"](event)) {
var _a = event.target, value = _a.value, checked = _a.checked, options = _a.options;
var _b = _this.getField(name), type = _b.type, multiple = _b.multiple;
switch (type) {
case 'checkbox':
case 'radio':
return checked;
case 'select':
if (multiple) {
var selected = [];
if (options && options.length) {
// tslint:disable-next-line:prefer-for-of
for (var index = 0; index < options.length; index++) {
var option = options[index];
if (option.selected) {
selected.push(option.value);
}
}
}
return selected;
}
return value;
default:
return value;
}
}
return event;
};
this.setValue = function (name, value) {
var _a, _b;
if (Array.isArray(value)) {
var prevValues = nest_deep_1.flatten((_a = {},
_a[name] = get_1["default"](nest_deep_1.nested(mapped(_this.values)), name),
_a));
var nextValues = nest_deep_1.flatten((_b = {}, _b[name] = value, _b));
if (!isEqual_1["default"](prevValues, nextValues)) {
for (var key in prevValues) {
if (prevValues.hasOwnProperty(key)) {
_this.values["delete"](key);
}
}
for (var key in nextValues) {
if (nextValues.hasOwnProperty(key)) {
_this.values.set(key, nextValues[key]);
}
}
}
}
_this.values.set(name, value);
return _this.getField(name);
};
this.getDefaultError = function (name) {
return get_1["default"](nest_deep_1.nested(mapped(_this.initialErrors)), name);
};
this.setError = function (name, error) {
_this.setMeta(name, 'touched', Boolean(error));
return _this.setMeta(name, 'errors', error);
};
this.handleValidate = function (valuesForValidate) {
if (valuesForValidate === void 0) { valuesForValidate = {}; }
var values = _this.getState().values;
var allValues = __assign({}, values, nest_deep_1.flatten(values));
var errors = nest_deep_1.flatten(_this.validate(allValues) || {});
keys(__assign({}, valuesForValidate, nest_deep_1.flatten(valuesForValidate))).forEach(function (name) {
var value = _this.getField(name).value;
var validate = _this.getMeta(name).validate;
var error = (validate && validate(value, allValues)) || errors[name];
_this.setError(name, error);
});
};
this.validate = validate;
this.onSubmit = onSubmit;
var values = nest_deep_1.flatten(initialValues);
var errors = nest_deep_1.flatten(initialErrors);
keys(values).map(function (key) {
_this.initialValues.set(key, values[key]);
_this.setValue(key, values[key]);
});
keys(errors).map(function (key) {
_this.initialErrors.set(key, errors[key]);
_this.setError(key, errors[key]);
});
}
return Api;
}());
exports["default"] = Api;