diff --git a/src/components/FormBuilder/fields.tsx b/src/components/FormBuilder/fields.tsx index 2199d89..5c7328f 100644 --- a/src/components/FormBuilder/fields.tsx +++ b/src/components/FormBuilder/fields.tsx @@ -12,12 +12,14 @@ import { TextAreaFieldProps } from "./fields/TextAreaField"; import { FieldArrayFieldProps } from "./fields/FieldArray"; import { FieldComponentType } from "./buildForm"; +export interface Conditions { + [key: string]: any; + allOf?: Conditions[]; + anyOf?: Conditions[]; +} export interface BaseField { component?: React.ComponentType>; - conditions?: Array<{ - name: string; - value: string | Array; - }>; + conditions?: Conditions; defaultValue?: string; description?: string; disabled?: boolean | ((data: FieldValues) => boolean); @@ -44,28 +46,26 @@ export function withConditional( return (props: CommonFieldProps) => { const { form, field } = props; - const conditions = Array.isArray(field.conditions) - ? field.conditions - : null; - - if (!conditions) return ; + const evaluateConditions = (conditions: Conditions): boolean => { + if (conditions.allOf) { + return conditions.allOf.every(evaluateConditions); + } + if (conditions.anyOf) { + return conditions.anyOf.some(evaluateConditions); + } - const watchedFields = conditions.map((condition) => - condition - ? form.watch(condition.name.replace("RESOURCE_ID", String(field.index))) - : null - ); + if (Object.keys(conditions).length === 0) return true; - // determine if all conditions are satisfied - const shouldRender = conditions.every((condition, index) => { - if (!condition) return true; // No condition means always render + const key = Object.keys(conditions)[0]; + const watchField = form.watch( + key.replace("RESOURCE_ID", String(field.index)) + ); + const values = conditions[key]; + return values.includes(watchField); + }; - const watchField = watchedFields[index]; - if (condition.value instanceof Array) { - return condition.value.includes(watchField); - } - return watchField === condition.value; - }); + const conditionRoot = field.conditions ? field.conditions : {}; + const shouldRender = evaluateConditions(conditionRoot); if (!shouldRender) return null;