@imtf/rjsf-conditionals
Version:
Extension of @rjsf/core with conditional field support
133 lines (129 loc) • 3.75 kB
JavaScript
function _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); }
import React, { Component } from "react";
import useFormWithConditionnals from "./useFormWithConditionnals";
import rulesRunner from "./rulesRunner";
export class FormWithConditionals extends Component {
constructor(props) {
super(props);
this.state = {
schema: props.initialSchema || props.schema,
uiSchema: props.initialUiSchema || props.uiSchema
};
}
componentDidMount() {
this.updateConf(this.props.formData);
}
componentDidUpdate(prevProps) {
if (prevProps.formData !== this.props.formData) {
this.updateConf(this.props.formData);
}
}
updateConf(formData) {
const {
rulesRunner: runRules,
extraActions
} = this.props;
if (runRules) {
const result = runRules(formData, extraActions);
// Handle both Promise and direct object returns
if (result && typeof result.then === "function") {
result.then(({
schema,
uiSchema
}) => {
this.setState({
schema,
uiSchema
});
});
} else if (result) {
const {
schema,
uiSchema
} = result;
this.setState({
schema,
uiSchema
});
}
}
}
handleChange(e) {
const {
onChange,
rulesRunner: runRules,
extraActions
} = this.props;
// First, update the schema based on the new formData
if (runRules) {
const result = runRules(e.formData, extraActions);
const processResult = ({
schema,
uiSchema
}) => {
this.setState({
schema,
uiSchema
}, () => {
// Call user's onChange with updated schema after state is set
if (onChange) {
onChange({
...e,
schema,
uiSchema
});
}
});
};
// Handle both Promise and direct object returns
if (result && typeof result.then === "function") {
result.then(processResult);
} else if (result) {
processResult(result);
}
} else {
// No rules, just call onChange
if (onChange) {
onChange(e);
}
}
}
render() {
const {
formComponent: FormComponent,
forwardedRef,
...rest
} = this.props;
const {
schema,
uiSchema
} = this.state;
// Bind handleChange to preserve 'this' context
const boundHandleChange = this.handleChange.bind(this);
return /*#__PURE__*/React.createElement(FormComponent, _extends({}, rest, {
ref: forwardedRef,
schema: schema,
uiSchema: uiSchema,
onChange: boundHandleChange
}));
}
}
/**
* HOC that wraps a form component with conditional logic
*/
const applyRules = (schema, uiSchema, rules, Engine, extraActions) => FormComponent => {
const FormWithRules = /*#__PURE__*/React.forwardRef((props, ref) => {
const runRules = rulesRunner(schema, uiSchema, rules, Engine, extraActions);
return /*#__PURE__*/React.createElement(FormWithConditionals, _extends({}, props, {
formComponent: FormComponent,
initialSchema: schema,
initialUiSchema: uiSchema,
rulesRunner: runRules,
extraActions: extraActions,
forwardedRef: ref
}));
});
FormWithRules.displayName = `FormWithRules(${FormComponent.displayName || FormComponent.name || "Component"})`;
return FormWithRules;
};
export default applyRules;