feat(frontend): hide children of connected array and object fields

(#11770)

### Changes 🏗️

- Added conditional rendering for array and object field children based
on connection status
- Implemented `shouldShowChildren` logic in `ArrayFieldTemplate` and
`ObjectFieldTemplate` components
- Modified the `shouldShowChildren` condition in `FieldTemplate` to
handle different schema types
- Imported and utilized `cleanUpHandleId` and `useEdgeStore` to check if
inputs are connected
- Added connection status checks to hide form fields when their inputs
are connected to other nodes

![Screenshot 2026-01-15 at
12.55.32 PM.png](https://app.graphite.com/user-attachments/assets/d3fffade-872e-4fd8-a347-28d1bae3072e.png)

### Checklist 📋

#### For code changes:
- [x] I have clearly listed my changes in the PR description
- [x] I have made a test plan
- [x] I have tested my changes according to the test plan:
- [x] Verified that object and array fields hide their children when
connected to other nodes
- [x] Confirmed that unconnected fields display their children properly
- [x] Tested with various schema types to ensure correct rendering
behavior
- [x] Checked that the connection status is properly detected and
applied
This commit is contained in:
Abhimanyu Yadav
2026-01-15 13:40:52 +05:30
committed by GitHub
parent 631f1bd50a
commit af63b3678e
3 changed files with 79 additions and 53 deletions

View File

@@ -4,7 +4,8 @@ import {
getTemplate,
getUiOptions,
} from "@rjsf/utils";
import { getHandleId, updateUiOption } from "../../helpers";
import { cleanUpHandleId, getHandleId, updateUiOption } from "../../helpers";
import { useEdgeStore } from "@/app/(platform)/build/stores/edgeStore";
export default function ArrayFieldTemplate(props: ArrayFieldTemplateProps) {
const {
@@ -23,6 +24,7 @@ export default function ArrayFieldTemplate(props: ArrayFieldTemplateProps) {
} = props;
const uiOptions = getUiOptions(uiSchema);
const { isInputConnected } = useEdgeStore();
const ArrayFieldDescriptionTemplate = getTemplate(
"ArrayFieldDescriptionTemplate",
@@ -51,6 +53,11 @@ export default function ArrayFieldTemplate(props: ArrayFieldTemplateProps) {
handleId: handleId,
});
const shouldShowChildren = !isInputConnected(
registry.formContext.nodeId,
cleanUpHandleId(handleId),
);
return (
<div>
<div className="m-0 flex p-0">
@@ -79,25 +86,29 @@ export default function ArrayFieldTemplate(props: ArrayFieldTemplateProps) {
/>
</div>
)}
<div
key={`array-item-list-${fieldPathId.$id}`}
className="m-0 mb-2 w-full p-0"
>
{!showOptionalDataControlInTitle ? optionalDataControl : undefined}
{items}
{canAdd && (
<div className="mt-4 flex justify-end">
<AddButton
id={buttonId(fieldPathId, "add")}
className="rjsf-array-item-add"
onClick={onAddClick}
disabled={disabled || readonly}
uiSchema={updatedUiSchema}
registry={registry}
/>
</div>
)}
</div>
{shouldShowChildren && (
<div
key={`array-item-list-${fieldPathId.$id}`}
className="m-0 mb-2 w-full p-0"
>
{!showOptionalDataControlInTitle
? optionalDataControl
: undefined}
{items}
{canAdd && (
<div className="mt-4 flex justify-end">
<AddButton
id={buttonId(fieldPathId, "add")}
className="rjsf-array-item-add"
onClick={onAddClick}
disabled={disabled || readonly}
uiSchema={updatedUiSchema}
registry={registry}
/>
</div>
)}
</div>
)}
</div>
</div>
</div>

View File

@@ -8,8 +8,9 @@ import {
ObjectFieldTemplateProps,
titleId,
} from "@rjsf/utils";
import { getHandleId, updateUiOption } from "../../helpers";
import { cleanUpHandleId, getHandleId, updateUiOption } from "../../helpers";
import React from "react";
import { useEdgeStore } from "@/app/(platform)/build/stores/edgeStore";
export default function ObjectFieldTemplate(props: ObjectFieldTemplateProps) {
const {
@@ -29,6 +30,8 @@ export default function ObjectFieldTemplate(props: ObjectFieldTemplateProps) {
} = props;
const uiOptions = getUiOptions(uiSchema);
const { isInputConnected } = useEdgeStore();
const TitleFieldTemplate = getTemplate(
"TitleFieldTemplate",
registry,
@@ -58,6 +61,11 @@ export default function ObjectFieldTemplate(props: ObjectFieldTemplateProps) {
handleId: handleId,
});
const shouldShowChildren = !isInputConnected(
registry.formContext.nodeId,
cleanUpHandleId(handleId),
);
return (
<>
<div className="flex items-center gap-2">
@@ -83,40 +91,42 @@ export default function ObjectFieldTemplate(props: ObjectFieldTemplateProps) {
)}
</div>
<div className="flex flex-col">
{!showOptionalDataControlInTitle ? optionalDataControl : undefined}
{shouldShowChildren && (
<div className="flex flex-col">
{!showOptionalDataControlInTitle ? optionalDataControl : undefined}
{/* I have cloned it - so i could pass updated uiSchema to the nested children */}
{properties.map((element: any, index: number) => {
const clonedContent = React.cloneElement(element.content, {
...element.content.props,
uiSchema: updateUiOption(element.content.props.uiSchema, {
handleId: handleId,
}),
});
{/* I have cloned it - so i could pass updated uiSchema to the nested children */}
{properties.map((element: any, index: number) => {
const clonedContent = React.cloneElement(element.content, {
...element.content.props,
uiSchema: updateUiOption(element.content.props.uiSchema, {
handleId: handleId,
}),
});
return (
<div
key={index}
className={`${element.hidden ? "hidden" : ""} flex`}
>
<div className="w-full">{clonedContent}</div>
return (
<div
key={index}
className={`${element.hidden ? "hidden" : ""} flex`}
>
<div className="w-full">{clonedContent}</div>
</div>
);
})}
{canExpand(schema, uiSchema, formData) ? (
<div className="mt-2 flex justify-end">
<AddButton
id={buttonId(fieldPathId, "add")}
onClick={onAddProperty}
disabled={disabled || readonly}
className="rjsf-object-property-expand"
uiSchema={updatedUiSchema}
registry={registry}
/>
</div>
);
})}
{canExpand(schema, uiSchema, formData) ? (
<div className="mt-2 flex justify-end">
<AddButton
id={buttonId(fieldPathId, "add")}
onClick={onAddProperty}
disabled={disabled || readonly}
className="rjsf-object-property-expand"
uiSchema={updatedUiSchema}
registry={registry}
/>
</div>
) : null}
</div>
) : null}
</div>
)}
</>
);
}

View File

@@ -78,7 +78,12 @@ export default function FieldTemplate(props: FieldTemplateProps) {
displayLabel ||
(schema.type === "boolean" && !isAnyOfChild(uiSchema as any));
const shouldShowTitleSection = !isAnyOfSchema(schema) && !additional;
const shouldShowChildren = isAnyOfSchema(schema) || !isHandleConnected;
const shouldShowChildren =
schema.type === "object" ||
schema.type === "array" ||
isAnyOfSchema(schema) ||
!isHandleConnected;
const isAdvancedField = (schema as any).advanced === true;
if (!showAdvanced && isAdvancedField && !isHandleConnected) {