feat(context): consolidate message UI overrides on the MessageUI slot - #3268
Conversation
The `Message` override was deprecated in favour of `MessageUI` during v14 but never removed, so two context slots and four props all resolved to the same component. Collapse them onto `MessageUI`. Removing `MessageProps.Message` is not a pure deletion: it was the transport `VirtualizedMessageList` and `Thread` used to inject their resolved component. `VirtualizedMessageList` now applies `VirtualMessage` to its own subtree's `ComponentContext` instead of drilling it through each `Message`, which also retires `VirtuosoContext.Message`, and `Thread`'s three-step resolution collapses entirely — context already carries the component. BREAKING CHANGE: - **`ComponentContext.Message` is removed.** Use the `MessageUI` slot. - **The `Message` prop is removed from `Message`, `MessageList`, `VirtualizedMessageList` and `Thread`** (and therefore from `additionalMessageListProps`, `additionalVirtualizedMessageListProps` and `additionalParentMessageProps`). Override `MessageUI` via `WithComponents`; scope it to a subtree to replace a per-component prop. `VirtualMessage` is unchanged and still takes precedence inside `VirtualizedMessageList`, but now only within that list. - **`areMessagePropsEqual` no longer compares the message UI component.** It is resolved from context, and context updates re-render consumers regardless of `React.memo`. Also in this commit: - `WithComponents` memoizes its merged override map, so a provider on the virtualized list's render path cannot defeat per-message memoization. - ai-docs: the v14 -> v15 guide gains the message-UI override section plus a previously unwritten section on the context-hook `componentName` removal. Closes REACT-1027
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Plus Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## release-v15 #3268 +/- ##
==============================================
Coverage ? 84.46%
==============================================
Files ? 526
Lines ? 15939
Branches ? 5108
==============================================
Hits ? 13463
Misses ? 2476
Partials ? 0 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
Goal
REACT-1027
ComponentContext.Messagewas deprecated in favour ofMessageUIduring v14 but never removed. Removing it surfaced four more ways to reach the same component — aMessageprop onMessage,MessageList,VirtualizedMessageListandThread— now all collapsed onto theMessageUIslot.BREAKING CHANGES:
ComponentContext.Messageremoved → use theMessageUIslot.The
Messageprop is removed fromMessage,MessageList,VirtualizedMessageListandThread, and therefore fromadditionalMessageListProps,additionalVirtualizedMessageListPropsandadditionalParentMessageProps. To replace a per-component prop, scope the slot to that subtree:areMessagePropsEqualno longer compares the message UI component — it comes from context, and context updates re-render consumers regardless ofReact.memo.VirtualMessageis unchanged and still wins insideVirtualizedMessageList, but now only within that list. Full migration detail:ai-docs/ai-migration-v14-v15.md.Implementation details
MessageProps.Messagewas the transportVirtualizedMessageListandThreadused to inject their resolved component, so deleting it naively would have silently broken theVirtualMessageslot. Instead,VirtualizedMessageListappliesVirtualMessageto its own subtree'sComponentContext— wrapping only when the slot is set — which also retiresVirtuosoContext.Message.Thread's three-step resolution collapses entirely; context already carries the component.WithComponentsnow memoizes its merged override map: required, not cosmetic, since an unmemoized provider on the list's render path would defeat per-message memoization.VirtualMessagehad no test coverage, which is what made this risky. Added three tests — precedence, subtree scoping, unset fallback — and the precedence one fails onrelease-v15. They assert whatuseComponentContext()resolves to rather than inspecting rendered items, because Virtuoso renders zero items under jsdom and an item-level assertion would pass either way.Verified:
tsc -p tsconfig.lib.json --noEmitclean ·yarn test231 files, 2828 passed / 1 skipped ·yarn lint-fixclean. Each documented failure mode was compiled to confirm it errors (TS2322for props,TS2561for override keys).Unrelated change: the v14 → v15 guide also gains a section on the context-hook
componentNameremoval from #3267, included at the author's request rather than split out.UI Changes
None — override plumbing only; the default message UI and every existing
MessageUI/VirtualMessageoverride render exactly as before.