From b53ac0bdf7be01afe892fca676755666a99081ca Mon Sep 17 00:00:00 2001 From: devjoaov Date: Mon, 6 May 2024 15:08:48 -0300 Subject: [PATCH 1/2] chore: refactor withConditional to have multiple conditions types --- src/components/FormBuilder/fields.tsx | 46 +++++++++++++-------------- 1 file changed, 23 insertions(+), 23 deletions(-) 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; From 8ff4941f457cb575caa9b3a4508853310b0d7cfa Mon Sep 17 00:00:00 2001 From: devjoaov Date: Mon, 6 May 2024 15:38:32 -0300 Subject: [PATCH 2/2] test: update withCondition component tests --- tests/components/FormBuilder/withConditional.test.tsx | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/tests/components/FormBuilder/withConditional.test.tsx b/tests/components/FormBuilder/withConditional.test.tsx index ceddac4..7315842 100644 --- a/tests/components/FormBuilder/withConditional.test.tsx +++ b/tests/components/FormBuilder/withConditional.test.tsx @@ -13,7 +13,9 @@ describe("withConditional", () => { name: "test", type: "input", value: "", - conditions: [{ name: "test", value: "value" }], + conditions: { + allOf: [{ test: ["value"] }], + }, }; const form = renderHook(() => useForm({ @@ -31,7 +33,9 @@ describe("withConditional", () => { name: "test", type: "input", value: "", - conditions: [{ name: "test", value: "value" }], + conditions: { + allOf: [{ test: ["value"] }], + }, }; const form = renderHook(() => useForm()).result.current; render();