@react-form-builder/core
Version:
React JSON Schema Form Builder to create complex, validated, reusable forms with no deep React knowledge required
235 lines (234 loc) • 6.34 kB
JavaScript
import { makeAutoObservable as h, observable as c, autorun as m, reaction as p } from "mobx";
import { isComputedProperty as V, dataKey as f } from "../../../stores/ComponentStore.js";
import { isString as v } from "../../../utils/isString.js";
import { needRender as y } from "../../../utils/needRender.js";
import { nameObservable as r, nameAutorun as g } from "../../../utils/observableNaming.js";
import { isUndefined as S, isNull as D } from "../../../utils/tools.js";
import { autoConvertField as C } from "./autoConvertField.js";
class n {
/**
* Creates the field with form data for the component.
* @param componentData the component data.
* @param calculateValue the function for calculating the value of the field.
* @param createDataValidator the function to create a data validator.
* @param getInitialData the function to get initial data for the field.
* @param deferFieldCalculation if true, then the calculated field must be explicitly initialized.
*/
constructor(e, i, t, l, u) {
this.componentData = e, this.calculateValue = i, this.createDataValidator = t, this.getInitialData = l, this.deferFieldCalculation = u;
const { model: a, store: o } = e;
if (this.componentStore = o, this.model = a, !a.valued) throw new Error("'model.valued' is falsy");
if (!a.valueType) throw new Error("'model.typeOfValue' is undefined");
this.valued = a.valued, this.valueType = a.valueType;
const s = "SimpleField";
h(this, {
model: !1,
dataValidator: c.ref
}, { name: r(s, { key: o.key }), autoBind: !0 }), this.value = this.isComputed ? this.computedValue : this.initialDataValue, this.#t = [
m(
() => {
this.dataValidator = this.createDataValidator(
e,
this.valueType,
(d) => this.error = d
);
},
{ name: g(s, "setValidator", { key: o.key }) }
)
], this.#e = this.createDataChangeReaction();
}
componentData;
calculateValue;
createDataValidator;
getInitialData;
deferFieldCalculation;
/**
* @inheritDoc
*/
error;
/**
* @inheritDoc
*/
touched = !1;
/**
* @inheritDoc
*/
value = void 0;
/**
* @inheritDoc
*/
valued;
/**
* The type of the field value.
*/
valueType;
dataValidator;
#t;
#e;
componentStore;
model;
/**
* @inheritDoc
*/
get fieldType() {
return "simple";
}
/**
* @inheritDoc
*/
init() {
if (this.deferFieldCalculation = !1, this.isComputed) {
setTimeout(() => {
this.value = this.computedValue;
}, 0);
return;
}
this.value = this.initialDataValue;
}
/**
* @returns the initial value for the field.
*/
get initialValue() {
return this.componentStore.props[this.valued]?.value ?? this.modelValue;
}
/**
* @returns the default value for the field from {@link Model}.
*/
get modelValue() {
return this.model.defaultProps?.[this.valued];
}
/**
* @inheritDoc
*/
dispose() {
this.#t.forEach((e) => e()), this.disableReaction();
}
/**
* @inheritDoc
*/
setValue(e) {
if (this.innerSetValue(C(e, this.valueType)), this.updateSiblings(e), !this.needValidate) {
this.clearError();
return;
}
this.componentStore.schema?.autoValidate !== !1 && this.dataValidator?.sendValidationEvent?.(this.value);
}
/**
* @inheritDoc
*/
setTouched() {
this.touched = !0;
}
/**
* @inheritDoc
*/
async validate() {
if (!this.needValidate) {
this.clearError();
return;
}
await this.dataValidator?.validate?.(this.value);
}
/**
* @inheritDoc
*/
async getValidationResult() {
if (this.needValidate)
return this.dataValidator?.getValidationResult?.(this.value);
}
/**
* @inheritDoc
*/
reset() {
this.innerSetValue(this.initialValue ?? this.modelValue), this.clearError();
}
/**
* @inheritDoc
*/
clear() {
this.innerSetValue(void 0), this.touched = !1, this.clearError();
}
/**
* @returns true if the field should be validated, false otherwise.
*/
get needValidate() {
return y(this.componentStore, this.componentData.dataRoot);
}
/**
* Clears the error message for this field.
*/
clearError() {
this.error = void 0;
}
/**
* Sets the error value.
* @param error the error value to be set. If the error is `undefined` or `null`, the error value will be reset to `undefined`.
* @throws {Error} throws an error if the provided value is not a string, undefined, or null.
*/
setError = (e) => {
if (v(e))
this.error = e;
else if (S(e) || D(e))
this.error = void 0;
else
throw new Error(`Expected 'string | undefined | null' type, got '${typeof e}'`);
};
/**
* @returns the initial data value for the field.
*/
get initialDataValue() {
return this.getInitialData() ?? this.initialValue;
}
/**
* @returns the computed value for the field.
*/
get computedValue() {
if (this.deferFieldCalculation) return this.initialDataValue;
const [, e] = this.calculateValue(this.componentStore, this.valued);
return e;
}
/**
* @returns true if the field value is calculated, otherwise false.
*/
get isComputed() {
return V(this.componentStore.props[this.valued]);
}
/**
* Sets the value of the field without converting it.
* @param value the value to be set.
*/
innerSetValue(e) {
this.value = e;
}
/**
* @inheritDoc
*/
disableReaction() {
this.#e?.();
}
/**
* @inheritDoc
*/
enableReaction() {
this.#e = this.createDataChangeReaction();
}
createDataChangeReaction() {
return p(() => ({
isComputed: this.isComputed,
computedValue: this.computedValue,
initialDataValue: this.initialDataValue
}), (e) => {
this.value = e.isComputed ? e.computedValue : e.initialDataValue;
}, { name: r("SimpleField", { key: this.componentStore.key }) });
}
updateSiblings(e) {
const i = f(this.componentStore);
this.componentData.dataRoot.allComponentFields.filter(({ dataKey: t, field: l }) => t === i && l !== this).forEach(({ field: t }) => {
t instanceof n && t.innerSetValue(e);
});
}
}
export {
n as SimpleField
};
//# sourceMappingURL=SimpleField.js.map