Skip to content

fix(ui): forward forceRender into CollapsibleField's nested RenderFields - #17786

Open
okxint wants to merge 2 commits into
payloadcms:mainfrom
okxint:fix/collapsible-field-force-render
Open

fix(ui): forward forceRender into CollapsibleField's nested RenderFields#17786
okxint wants to merge 2 commits into
payloadcms:mainfrom
okxint:fix/collapsible-field-force-render

Conversation

@okxint

@okxint okxint commented Aug 14, 2026

Copy link
Copy Markdown

What

Closes #17473

CollapsibleField receives forceRender from the field dispatcher (RenderField.tsx) but never destructures or forwards it — it's silently dropped before reaching the nested <RenderFields> call.

Why it matters

Without forceRender, each nested field is wrapped in RenderIfInViewport, which defers rendering until an IntersectionObserver reports the element as visible. Browsers suspend IntersectionObserver callbacks when document.hidden is true (backgrounded tabs, embedded webviews, visibility-throttled automation). So hasRendered stays false indefinitely and the collapsible's children never appear — no error, no warning.

DocumentFields explicitly passes forceRender: true for a document's own fields (at both the main and sidebar call sites), intending that field trees are never subject to lazy viewport-gated rendering. Row, Tabs, and Array already honor this by forwarding the prop; Collapsible was the only container type that didn't.

Fix

Two lines, mirroring the existing pattern in Row/index.tsx:

+    forceRender = false,
     indexPath,
           <RenderFields
             fields={fields}
+            forceRender={forceRender}

Verification

# Confirm the prop was absent before
grep -rn "forceRender" node_modules/@payloadcms/ui/dist/fields/Collapsible/
# (no output)

# Confirm Row already does this correctly
grep -n "forceRender" packages/ui/src/fields/Row/index.tsx
# 17:    forceRender = false,
# 34:          forceRender={forceRender}

CollapsibleField received the forceRender prop from the field dispatcher
but silently dropped it, causing nested fields to never render when
document.hidden is true at mount time (backgrounded tabs, embedded
webviews, or visibility-throttled automation). Without forceRender,
RenderIfInViewport waits on an IntersectionObserver that browsers
suppress for hidden documents, so hasRendered stays false indefinitely.

Row, Tabs, and Array already forward forceRender correctly; this brings
Collapsible in line with those siblings.

Fixes payloadcms#17473

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…cument hidden

Adds a Playwright test that overrides document.hidden to true via
addInitScript before the page loads, reproducing the condition where
IntersectionObserver callbacks are suppressed. Without the forceRender
fix, nested fields inside a collapsible would never render under this
condition. With the fix they render immediately.

Relates to payloadcms#17473

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

CollapsibleField doesn't forward forceRender, so its children never render while the tab is backgrounded

1 participant