Repository navigation
Conversation
Two built-in adapters that ship with @mui/x-chat-headless: a simple echo adapter for examples and an AI SDK adapter that bridges Vercel AI SDK UIMessage streams into ChatMessageChunk events. Wire both through the headless core barrel so they can be imported from '@mui/x-chat-headless' and '@mui/x-chat-headless/core'.
Deploy preview
Bundle size
Check out the code infra dashboard for more information about this PR. |
e5c6424 to
a421025
Compare
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: a42102514d
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
There was a problem hiding this comment.
Pull request overview
This PR expands the X Chat component composition surface by introducing nested “layout slots” for ChatBox (and related components), and ships a v9 codemod (chat/migrate-slots) + preset-safe wiring to migrate existing flat slot keys to the new nested structure. It also introduces/exports new message error primitives and message-scoped error state, and updates docs/API generation outputs and demos to match.
Changes:
- Add nested slot families to
ChatBox(conversation/messagesList/message/composer + layout regions) and update Material components to accept/forwardsxwhere needed. - Add message-scoped errors (
messageErrorsById, selectors/hooks, primitives) and newChatMessageErrorsurface + theme augmentation. - Add
v9.0.0/chat/migrate-slotscodemod, wire intov9.0.0/preset-safe, and update docs/API pages + demos accordingly.
Reviewed changes
Copilot reviewed 223 out of 223 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| scripts/x-chat.exports.json | Updates the exported symbol list for new chat types/components/functions. |
| scripts/buildApiDocs/chatSettings/index.ts | Excludes new internal implementation file from API docs generation. |
| packages/x-codemod/src/v9.0.0/preset-safe/index.ts | Adds chat preset into the v9 safe preset pipeline. |
| packages/x-codemod/src/v9.0.0/chat/preset-safe/index.ts | New chat preset runner that applies chat codemods. |
| packages/x-codemod/src/v9.0.0/chat/migrate-slots/index.ts | Implements the slot migration codemod (flat → nested families) with idempotency. |
| packages/x-codemod/src/v9.0.0/chat/migrate-slots/migrate-slots.test.ts | Adds unit tests for the codemod runner and idempotency. |
| packages/x-codemod/src/v9.0.0/chat/migrate-slots/actual.spec.tsx | Codemod “actual” fixture for post-rename flat keys. |
| packages/x-codemod/src/v9.0.0/chat/migrate-slots/expected.spec.tsx | Codemod “expected” fixture for nested-family output. |
| packages/x-codemod/src/v9.0.0/chat/migrate-slots/pre-rename.actual.spec.tsx | Codemod “actual” fixture for pre-rename flat keys. |
| packages/x-codemod/src/v9.0.0/chat/migrate-slots/pre-rename.expected.spec.tsx | Codemod “expected” fixture for nested-family output from pre-rename keys. |
| packages/x-codemod/README.md | Documents the new chat codemod and usage. |
| packages/x-chat/src/themeAugmentation/props.ts | Adds theme defaultProps typing for MuiChatMessageError. |
| packages/x-chat/src/themeAugmentation/overrides.ts | Adds class key typing for MuiChatMessageError overrides. |
| packages/x-chat/src/themeAugmentation/components.ts | Adds MuiChatMessageError entry to theme components augmentation. |
| packages/x-chat/src/internals/useCopyToClipboard.ts | Adds reusable clipboard hook used by message/code surfaces. |
| packages/x-chat/src/index.ts | Exports new chat types, error surfaces, and re-exports built-in adapters. |
| packages/x-chat/src/ChatSuggestions/ChatSuggestions.tsx | Adds sx support and surfaces alwaysVisible docs/propTypes. |
| packages/x-chat/src/ChatSuggestions/ChatSuggestions.test.tsx | Updates expectations: suggestions can render even with existing messages. |
| packages/x-chat/src/ChatMessageSources/ChatMessageSources.tsx | Adds sx prop support. |
| packages/x-chat/src/ChatMessageSkeleton/ChatMessageSkeleton.tsx | Adds sx prop support. |
| packages/x-chat/src/ChatMessageList/DefaultMessageItem.tsx | Adds shared default row component used by ChatBox and ChatMessageList. |
| packages/x-chat/src/ChatMessageList/ChatMessageList.test.tsx | Adds tests for standalone default row, custom renderItem, and slot overrides. |
| packages/x-chat/src/ChatMessageError/index.ts | Adds barrel exports for ChatMessageError and its classes. |
| packages/x-chat/src/ChatMessageError/chatMessageErrorClasses.ts | Adds utility classes + hook for ChatMessageError. |
| packages/x-chat/src/ChatMessage/index.ts | Re-exports ChatMessageError via ChatMessage barrel. |
| packages/x-chat/src/ChatMessage/ChatMessageMeta.tsx | Switches alignment logic to isOwnMessage ownerState. |
| packages/x-chat/src/ChatMessage/ChatMessageInlineMeta.tsx | Switches contrast logic to isOwnMessage ownerState. |
| packages/x-chat/src/ChatMessage/ChatMessageGroup.test.tsx | Adds tests for author label default/override/null behavior via nested slots. |
| packages/x-chat/src/ChatMessage/ChatMessageContent.test.tsx | Updates locale expectations and tool-part rendering tests. |
| packages/x-chat/src/ChatMessage/chatMessageClasses.ts | Adds noAvatar utility class and docs. |
| packages/x-chat/src/ChatMessage/ChatMessageActions.tsx | Aligns actions based on isOwnMessage ownerState. |
| packages/x-chat/src/ChatMessage/ChatMessage.test.tsx | Updates slotProps shape test; adds “own message” resolution test. |
| packages/x-chat/src/ChatMessage/ChatDateDivider.tsx | Adds sx prop support. |
| packages/x-chat/src/ChatIndicators/ChatUnreadMarker.tsx | Adds sx prop support. |
| packages/x-chat/src/ChatIndicators/ChatTypingIndicator.tsx | Adds sx prop support. |
| packages/x-chat/src/ChatIndicators/ChatScrollToBottomAffordance.tsx | Adds sx prop support. |
| packages/x-chat/src/ChatConversationList/ChatConversationList.test.tsx | Enables conversation list feature in tests; stabilizes async selection assertions. |
| packages/x-chat/src/ChatConfirmation/ChatConfirmation.tsx | Adds sx prop support. |
| packages/x-chat/src/ChatComposer/ChatComposerTextArea.test.tsx | Updates slotProps path to nested composer family. |
| packages/x-chat/src/ChatComposer/ChatComposerSendButton.test.tsx | Updates slotProps path to nested composer family. |
| packages/x-chat/src/ChatComposer/ChatComposerAttachmentList.tsx | Reads composer state via store hook to support layouts without ChatComposer. |
| packages/x-chat/src/ChatComposer/ChatComposerAttachButton.test.tsx | Updates slotProps path to nested composer family. |
| packages/x-chat/src/ChatComposer/ChatComposer.tsx | Removes z-index; documents external onSubmit behavior in propTypes. |
| packages/x-chat/src/ChatComposer/ChatComposer.test.tsx | Updates slotProps path to nested composer family. |
| packages/x-chat/src/ChatCodeBlock/ChatCodeBlock.tsx | Adds sx prop + refactors clipboard logic to useCopyToClipboard. |
| packages/x-chat/src/ChatBox/index.ts | Exposes new layout-mode types from ChatBox.types. |
| packages/x-chat-headless/src/types/chat-state.ts | Adds message-scoped error map to internal state. |
| packages/x-chat-headless/src/types/chat-entities.ts | Adds message author getter types/props and docs. |
| packages/x-chat-headless/src/suggestions/SuggestionsRoot.tsx | Adds alwaysVisible behavior and prop. |
| packages/x-chat-headless/src/stream/streamTextDeltaBuffer.ts | Fixes parallel stream isolation and “revive done part” issues via streamId mapping. |
| packages/x-chat-headless/src/stream/streamHelpers.ts | Ensures streamed assistant messages get a createdAt timestamp. |
| packages/x-chat-headless/src/stream/processStream.test.ts | Adds regression test for interleaved parallel streams. |
| packages/x-chat-headless/src/store/ChatStore.test.ts | Adds coverage for message-scoped error lifecycle and dispose cleanup. |
| packages/x-chat-headless/src/selectors/chatSelectors.ts | Adds messageAuthor and messageError selectors + export. |
| packages/x-chat-headless/src/selectors/chatSelectors.test.ts | Adds tests for message-scoped errors vs global runtime error. |
| packages/x-chat-headless/src/message/parts/ToolPart.tsx | Adds sectionSummary slot + preview metadata in ownerState; expands input visibility rules. |
| packages/x-chat-headless/src/message/parts/MessageParts.test.tsx | Updates reasoning label expectation; tests sectionSummary ownerState. |
| packages/x-chat-headless/src/message/MessageRoot.tsx | Introduces resolved author, isOwnMessage, and data attribute + aria-label updates. |
| packages/x-chat-headless/src/message/MessageMeta.tsx | Suppresses generic “Error” status when a per-message error is present. |
| packages/x-chat-headless/src/message/MessageError.tsx | Adds headless per-message error primitive with retry action binding. |
| packages/x-chat-headless/src/message/MessageContent.tsx | Refactors default render helpers for data/step-start parts (typing clarity). |
| packages/x-chat-headless/src/message/MessageAvatar.tsx | Uses resolved author fields for avatar URL + display name. |
| packages/x-chat-headless/src/message/MessageAuthorLabel.tsx | Uses resolved author displayName (no raw role/id fallback here). |
| packages/x-chat-headless/src/message/message.types.ts | Adds resolved author, own-message flag, and MessageError ownerState typing. |
| packages/x-chat-headless/src/message/internals/MessageContext.tsx | Extends default context values for resolved author and isOwnMessage. |
| packages/x-chat-headless/src/message/index.ts | Exports MessageError primitive and ownerState types. |
| packages/x-chat-headless/src/message-list/useMessageListBehavior.ts | Adds SSR/rAF guards and StrictMode-safe mount tracking for resize-driven auto-scroll. |
| packages/x-chat-headless/src/message-list/MessageListRoot.tsx | Adds rAF/cancelAnimationFrame guards in ResizeObserver path. |
| packages/x-chat-headless/src/message-list/MessageListRoot.test.tsx | Adds streaming row growth tests (skipped in JSDOM) incl. StrictMode regression. |
| packages/x-chat-headless/src/message-group/messageGroup.types.ts | Adds isOwnMessage to group ownerState. |
| packages/x-chat-headless/src/message-group/MessageGroup.tsx | Resolves author for grouping and ownership; updates author label source. |
| packages/x-chat-headless/src/message-group/MessageGroup.test.tsx | Adds member resolution + getter-based grouping tests; ensures role label isn’t shown spuriously. |
| packages/x-chat-headless/src/internals/useChatInstance/useChatInstance.ts | Adds explicit controlled/uncontrolled tracking for activeConversationId. |
| packages/x-chat-headless/src/internals/useChatInstance/useChatInstance.test.tsx | Updates tests for new controlled flag + rerender-with-undefined behavior. |
| packages/x-chat-headless/src/internals/useChatController/useChatControllerHelpers.ts | Adds helper to extract messageId from errors. |
| packages/x-chat-headless/src/internals/useChatController/useChatController.ts | Routes messageId-scoped runtime errors to message error state; adds stream-producer error dedupe; adds rollback for tool approval optimistic update. |
| packages/x-chat-headless/src/internals/useChatController/realtimeActions.test.ts | Adds end-to-end test for discarding in-flight load after realtime removal. |
| packages/x-chat-headless/src/internals/useChatController/conversationActions.ts | Avoids eager message reset during conversation switch to prevent blanking wrong thread. |
| packages/x-chat-headless/src/index.ts | Exports new hooks/selectors/primitives + adapter exports + author getter types. |
| packages/x-chat-headless/src/hooks/useMessageError.ts | Adds hook for per-message error selection. |
| packages/x-chat-headless/src/hooks/useMessageError.test.tsx | Adds coverage for message-scoped error selection rules. |
| packages/x-chat-headless/src/hooks/useMessageAuthor.ts | Adds hook for resolved author selection with locale-driven role labels. |
| packages/x-chat-headless/src/hooks/useChatComposer.ts | Fixes preview URL lifecycle/ownership transfer and cleanup on message removal. |
| packages/x-chat-headless/src/hooks/useChat.test.tsx | Updates expectations for createdAt; adds regression test for double-load on mount. |
| packages/x-chat-headless/src/hooks/index.ts | Re-exports useMessageError. |
| packages/x-chat-headless/src/core/index.ts | Exports built-in adapters + author getter types from core entry. |
| packages/x-chat-headless/src/conversation-list/ConversationListRoot.tsx | Adds PageUp/PageDown + type-ahead navigation and cleanup. |
| packages/x-chat-headless/src/conversation-list/ConversationListItem.tsx | Adds data-conversation-id attribute for automation/styling hooks. |
| packages/x-chat-headless/src/composer/ComposerSendButton.tsx | Allows sending when draft has attachments even if text is empty. |
| packages/x-chat-headless/src/composer/ComposerRoot.tsx | Adds external onSubmit semantics while always preventing native navigation. |
| packages/x-chat-headless/src/composer/ComposerRoot.test.tsx | Adds tests for attachment-only submit and onSubmit suppression behavior. |
| packages/x-chat-headless/src/composer/ComposerHelperText.tsx | Ensures helper text uses role="alert" when showing error content. |
| packages/x-chat-headless/src/ChatProvider.tsx | Adds controlled tracking for activeConversationId; threads author getters into store params. |
| packages/x-chat-headless/src/ChatProvider.test.tsx | Strengthens streamFlushInterval behavior test using fake timers + buffered deltas. |
| packages/x-chat-headless/src/chat/internals/chatLocaleText.ts | Adds new locale labels and updates default wording (“Thoughts”, “Tool called/result”). |
| packages/x-chat-headless/src/chat/ChatRoot.tsx | Avoids passing activeConversationId prop when uncontrolled; threads author getters. |
| packages/x-chat-headless/src/chat/ChatLayout.tsx | Adjusts layout containers to flex-column and hides overflow to support responsive panes. |
| packages/x-chat-headless/src/chat/ChatComposition.test.tsx | Updates variable names in focus/keyboard tests (no behavior change). |
| packages/x-chat-headless/src/adapters/index.ts | Exports built-in adapters from adapters entrypoint. |
| packages/x-chat-headless/src/adapters/createEchoAdapter.ts | Adds built-in demo echo adapter implementation. |
| docs/translations/api-docs/chat/message-error/message-error.json | Adds API translation stub for new MessageError primitive. |
| docs/translations/api-docs/chat/composer-root/composer-root.json | Documents new onSubmit behavior. |
| docs/translations/api-docs/chat/chat-suggestions/chat-suggestions.json | Documents new alwaysVisible prop. |
| docs/translations/api-docs/chat/chat-root/chat-root.json | Updates generated propDescriptions (removes stale entries). |
| docs/translations/api-docs/chat/chat-provider/chat-provider.json | Updates generated propDescriptions (removes stale entries). |
| docs/translations/api-docs/chat/chat-message-meta/chat-message-meta.json | Adds noAvatar class description. |
| docs/translations/api-docs/chat/chat-message-list/chat-message-list.json | Documents renderItem and autoScroll behavior. |
| docs/translations/api-docs/chat/chat-message-group/chat-message-group.json | Adds noAvatar class description. |
| docs/translations/api-docs/chat/chat-message-error/chat-message-error.json | Adds API translation stub for ChatMessageError. |
| docs/translations/api-docs/chat/chat-message-content/chat-message-content.json | Adds noAvatar class description. |
| docs/translations/api-docs/chat/chat-message-avatar/chat-message-avatar.json | Adds noAvatar class description. |
| docs/translations/api-docs/chat/chat-message-author-label/chat-message-author-label.json | Adds noAvatar class description. |
| docs/translations/api-docs/chat/chat-message-actions/chat-message-actions.json | Adds noAvatar class description. |
| docs/translations/api-docs/chat/chat-date-divider/chat-date-divider.json | Adds noAvatar class description. |
| docs/translations/api-docs/chat/chat-box/chat-box.json | Updates ChatBox docs for nested slots/slotProps, author getters, and layout settings. |
| docs/src/modules/components/overview/chat/mainDemo/MessengerDemo.tsx | Migrates demo usage to nested slots/slotProps + enables conversationList feature. |
| docs/src/modules/components/overview/chat/mainDemo/AgentDemo.tsx | Migrates demo usage to nested slots/slotProps + enables conversationList feature. |
| docs/pages/x/api/chat/message-error.json | Adds generated API page content for MessageError (headless). |
| docs/pages/x/api/chat/message-error.js | Adds API page wrapper for MessageError (headless). |
| docs/pages/x/api/chat/chat-suggestions.json | Adds generated prop entry for alwaysVisible. |
| docs/pages/x/api/chat/chat-message-meta.json | Adds noAvatar class entry. |
| docs/pages/x/api/chat/chat-message-list.json | Adds generated prop entry for renderItem. |
| docs/pages/x/api/chat/chat-message-group.json | Adds noAvatar class entry. |
| docs/pages/x/api/chat/chat-message-error.json | Adds generated API page content for ChatMessageError (material). |
| docs/pages/x/api/chat/chat-message-error.js | Adds API page wrapper for ChatMessageError (material). |
| docs/pages/x/api/chat/chat-message-content.json | Adds noAvatar class entry. |
| docs/pages/x/api/chat/chat-message-avatar.json | Adds noAvatar class entry. |
| docs/pages/x/api/chat/chat-message-author-label.json | Adds noAvatar class entry. |
| docs/pages/x/api/chat/chat-message-actions.json | Adds noAvatar class entry. |
| docs/pages/x/api/chat/chat-date-divider.json | Adds noAvatar class entry. |
| docs/data/chatApiPages.ts | Registers new API page routes for ChatMessageError and MessageError. |
| docs/data/chat/material/thread/PaperBubble.tsx | Migrates demo to nested slots.message.content. |
| docs/data/chat/material/thread/PaperBubble.js | Generated JS demo updated for nested slot shape. |
| docs/data/chat/material/thread/GradientHeader.tsx | Migrates demo to nested slots.conversation.header. |
| docs/data/chat/material/thread/GradientHeader.js | Generated JS demo updated for nested slot shape. |
| docs/data/chat/material/thread/BubbleWithStatus.tsx | Migrates demo to nested slots.message.content. |
| docs/data/chat/material/thread/BubbleWithStatus.js | Generated JS demo updated for nested slot shape. |
| docs/data/chat/material/thread/AdaptiveSendButton.tsx | Migrates demo to nested slots.composer.send. |
| docs/data/chat/material/thread/AdaptiveSendButton.js | Generated JS demo updated for nested slot shape. |
| docs/data/chat/material/slot-overrides/ThemeAndSlotCombination.tsx | Migrates demo to nested slots.message.avatar. |
| docs/data/chat/material/slot-overrides/ThemeAndSlotCombination.js | Generated JS demo updated for nested slot shape. |
| docs/data/chat/material/slot-overrides/SlotPropsCustomization.tsx | Migrates demo to nested slotProps.messagesList.root and slotProps.composer.input. |
| docs/data/chat/material/slot-overrides/SlotPropsCustomization.js | Generated JS demo updated for nested slotProps shape. |
| docs/data/chat/material/slot-overrides/SlotBasicReplacement.tsx | Migrates demo to nested slots.message.avatar. |
| docs/data/chat/material/slot-overrides/SlotBasicReplacement.js | Generated JS demo updated for nested slot shape. |
| docs/data/chat/material/message-list/MessageGrouping.tsx | Migrates demo to nested slotProps.messagesList.group. |
| docs/data/chat/material/message-list/MessageGrouping.js | Generated JS demo updated for nested slotProps shape. |
| docs/data/chat/material/message-list/DateDividerFormat.tsx | Migrates demo to nested slotProps.messagesList.dateDivider. |
| docs/data/chat/material/message-list/DateDividerFormat.js | Generated JS demo updated for nested slotProps shape. |
| docs/data/chat/material/hooks/CustomComposer.tsx | Migrates demo to nested slots.composer.root. |
| docs/data/chat/material/hooks/CustomComposer.js | Generated JS demo updated for nested slot shape. |
| docs/data/chat/material/examples/slot-overrides/SlotOverrides.tsx | Migrates demo to nested slots.message.content. |
| docs/data/chat/material/examples/slot-overrides/SlotOverrides.js | Generated JS demo updated for nested slot shape. |
| docs/data/chat/material/examples/responsive-drawer/ResponsiveDrawer.tsx | Enables built-in conversation list feature for the demo. |
| docs/data/chat/material/examples/responsive-drawer/ResponsiveDrawer.js | Generated JS demo updated accordingly. |
| docs/data/chat/material/examples/multi-conversation/MultiConversation.tsx | Enables built-in conversation list feature for the demo. |
| docs/data/chat/material/examples/multi-conversation/MultiConversation.js | Generated JS demo updated accordingly. |
| docs/data/chat/material/examples/model-selector/ModelSelector.tsx | Migrates demo to nested slots.conversation.headerActions. |
| docs/data/chat/material/examples/model-selector/ModelSelector.js | Generated JS demo updated for nested slot shape. |
| docs/data/chat/material/examples/compact-variant/CompactVariant.tsx | Enables built-in conversation list feature for the demo. |
| docs/data/chat/material/examples/compact-variant/CompactVariant.js | Generated JS demo updated accordingly. |
| docs/data/chat/material/examples/agentic-code/ToolStylingC.tsx | Enables conversation list feature; migrates message content slotProps nesting. |
| docs/data/chat/material/examples/agentic-code/ToolStylingC.js | Generated JS demo updated accordingly. |
| docs/data/chat/material/examples/agentic-code/ToolStylingB.tsx | Enables conversation list feature; migrates message content slotProps nesting. |
| docs/data/chat/material/examples/agentic-code/ToolStylingB.js | Generated JS demo updated accordingly. |
| docs/data/chat/material/examples/agentic-code/ToolStylingA.tsx | Enables conversation list feature; migrates message content slotProps nesting. |
| docs/data/chat/material/examples/agentic-code/ToolStylingA.js | Generated JS demo updated accordingly. |
| docs/data/chat/material/examples/agentic-code/AgenticCode.tsx | Enables built-in conversation list feature for the demo. |
| docs/data/chat/material/examples/agentic-code/AgenticCode.js | Generated JS demo updated accordingly. |
| docs/data/chat/material/conversation-list/ThemedAvatar.tsx | Enables conversation list feature; migrates nested conversation list slotProps. |
| docs/data/chat/material/conversation-list/ThemedAvatar.js | Generated JS demo updated accordingly. |
| docs/data/chat/material/conversation-list/RichItemContent.tsx | Enables conversation list feature; migrates nested conversation list slotProps. |
| docs/data/chat/material/conversation-list/RichItemContent.js | Generated JS demo updated accordingly. |
| docs/data/chat/material/conversation-list/FullCustomRow.tsx | Enables conversation list feature; migrates nested conversation list slotProps. |
| docs/data/chat/material/conversation-list/FullCustomRow.js | Generated JS demo updated accordingly. |
| docs/data/chat/material/conversation-list/CompactRow.tsx | Enables conversation list feature; migrates nested conversation list slotProps. |
| docs/data/chat/material/conversation-list/CompactRow.js | Generated JS demo updated accordingly. |
| docs/data/chat/material/composer/ComposerDisabled.tsx | Migrates demo to nested slotProps.composer.root. |
| docs/data/chat/material/composer/ComposerDisabled.js | Generated JS demo updated accordingly. |
| docs/data/chat/material/composer/ComposerCustomPlaceholder.tsx | Migrates demo to nested slotProps.composer.input. |
| docs/data/chat/material/composer/ComposerCustomPlaceholder.js | Generated JS demo updated accordingly. |
| docs/data/chat/display/message-actions/RoleBasedMessageActions.tsx | Migrates demo to nested slots.message.actions. |
| docs/data/chat/display/message-actions/RoleBasedMessageActions.js | Generated JS demo updated accordingly. |
| docs/data/chat/display/message-actions/BasicMessageActions.tsx | Migrates demo to nested slots.message.actions. |
| docs/data/chat/display/message-actions/BasicMessageActions.js | Generated JS demo updated accordingly. |
| docs/data/chat/behavior/error-handling/error-handling.md | Updates docs frontmatter to include new error components. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
a421025 to
2593e1e
Compare
2593e1e to
0781c8b
Compare
0781c8b to
07b4810
Compare
|
@codex review. Report all actionable issues, including lower-severity ones, but skip subjective style nits. Group findings by severity and explain why each one matters. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 729e5aac64
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
The master merge brought in chat demos whose generated .tsx.preview outputs were not committed (their .js was newer than the .tsx, so the cached formattedTSDemos run skipped them). CI regenerates them with --disable-cache and fails the 'docs:typescript:formatted changes committed?' gate. Generate and commit the six missing previews (all flat slot vocabulary).
The responsive-layout assertion checked `scroller` for `width: '100%'`, which only holds in JSDOM (it returns the specified value). A real browser resolves it against the 220px layout pane, so test_browser failed with '220px'. Gate the test with `it.skipIf(isJSDOM)` and assert the resolved `220px` — the value the pane's --ChatBox-conversationListWidth drives.
- DefaultMessageItem: spread `slotProps.messageGroup` before the required row props (messageId/index/items/slots/slotProps) so a consumer's group slotProps can no longer clobber them. - Rename test descriptions to the flat ChatBox slot keys (messageRoot, messageAuthorName) to match the keys the test bodies actually use.
- Add JSDoc descriptions to every ChatBox slot so the API docs no longer render blank slot documentation; regenerate chat-box API docs/translations. - ChatBox: type innerRef as `useRef<HTMLDivElement | null>` and use `useCallback` for the ref callback, dropping the MutableRefObject cast.
- ChatBox renderItem now forwards the rendered `index`/`items` to
DefaultMessageItem so the message group computes prev/next grouping against
the rendered list — fixes wrong grouping when `slotProps.messageList.items`
narrows the thread. useMessageIds() is a stable ref, so row memoization holds.
- Remove the conversation-list scroller's width-based `@container { display:none }`:
the headless ConversationListRoot pins an inline `display: flex` that always
overrode it, and ChatBox already switches to a drawer in narrow modes — the
rule was dead and would only have blanked a forced `layoutMode="standard"` sidebar.
- Add tests: filtered-items grouping, and forced-standard sidebar stays visible.
… demos These two overview demos still configured ChatBox with the nested-by-family slots/slotProps (conversation.list, composer.root) — leftover from the earlier nested experiment that the docs flatten pass missed (they live under docs/src, not docs/data/chat). They failed the docs typescript check against the flat ChatBoxSlots. Rewrite to the flat keys (conversationList, conversationHeader, composerRoot); CopilotDemo/WidgetDemo already matched master.
…n, meta classes - DefaultMessageItem always renders ChatMessageGroup, which consumes slots.messageGroup as the group's wrapper element. Previously a documented wrapper override (e.g. slots.messageGroup='section') replaced the entire row and rendered empty, leaking internal messageId/index/items onto the DOM. - Compact author label is now delivered to ChatMessage via a dedicated groupAuthorName prop instead of being merged into children, so a consumer's custom ChatMessage children render children-only in every variant (compact no longer appends the built-in avatar/content/meta tree). - ChatMessageMeta no longer advertises the shared MuiChatMessage-* root classes (noAvatar, role/state, …) it never applies; its classes prop is narrowed to the meta class it owns. Regenerated chat-message-meta API docs. - Adds tests for all three; toggle-verified as regression guards.
The ChatMessage family shares one CSS namespace (`MuiChatMessage-*`): every sub-part is styled with name 'MuiChatMessage'. But each sub-component exposed its own `classes` prop typed as the full `Partial<ChatMessageClasses>`, so the API docs advertised all 18 shared classes per component — and under each component's own (wrong) prefix (e.g. `MuiChatMessageContent-content` vs the runtime `MuiChatMessage-content`). Remove the per-instance `classes` prop from the slot sub-parts (ChatMessageContent, ChatMessageAvatar, ChatMessageMeta, ChatMessageActions, ChatDateDivider, ChatMessageGroup); they still emit the shared `MuiChatMessage-*` classes and stay styleable via theme `styleOverrides` and `slotProps`. `ChatMessage` keeps the full `classes` (it owns the namespace) and `ChatMessageError` keeps its own correct `MuiChatMessageError-*` namespace. Regenerated API docs (those pages now list no classes instead of wrong ones).
…g control
The tool Input/Output <details> in ChatMessageContent is internally
controlled (open={open} + setOpen). A consumer-supplied
partProps.tool.slotProps.section.onToggle flowed through useSlotProps into
...rest, which was spread after the internal handler and replaced setOpen.
Because the disclosure is controlled, the section then could no longer be
expanded/collapsed in that customization scenario.
Spread ...rest before the controlled open/onToggle so the control can't be
overridden, ignore a consumer-supplied open, and chain the consumer onToggle
after the internal updater so the disclosure stays observable. Adds a
regression test (consumer handler fires AND the section still toggles).
The headless MessageGroup clones a `groupAuthorName` prop onto compact group children so the Material ChatMessage can place the author label in its CSS grid. It is a private MessageGroup->ChatMessage channel (ChatMessage marks it @ignore). A headless MessageRoot composition (the documented <MessageGroup><Message.Root/></MessageGroup> pattern) owns its own layout and does not consume the prop, so it previously forwarded `groupAuthorName` through ...other onto the root element, triggering a React 'unrecognized prop' warning in the compact variant. Drop `groupAuthorName` in MessageRoot (declare it as an @ignore internal prop and pull it out of ...other) so it can never reach the DOM. Headless composers that want a compact author label render it themselves. Adds a regression test that fails on the leak.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: d3c37af83c
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
… root slotProps
Two fixes from a codex review pass on the chat slots stack:
- ComposerAttachmentList gated on the ComposerContext attachment count, whose
default is empty outside a ChatComposer. Since the default list content reads
attachments from the store (to support custom layouts / isolated previews),
the wrapper now also reads the store (the source of truth), so the list renders
standalone instead of returning null.
- A function-valued slotProps.suggestions.slotProps.root (the supported
SlotComponentProps callback form) was silently dropped in two places: the
above-composer (active-thread) path in ChatBoxContent spread it into { sx }, and
ChatSuggestions spread it via '...(slotProps.root as object)'. Both now preserve
the callback form (composing the default class/sx onto its resolved result), so
owner-state-driven root props survive. The object form is unchanged.
Adds regression tests for both (each fails on the prior behavior).
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: dbb93bdb29
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
…omposerRoot demo Three fixes from a codex review pass: - ChatBoxContent resolved slots.emptyState's slotProps as a plain object, dropping the supported (ownerState) => props callback form (the slot is typed SlotComponentProps). Resolve the callback before spreading. - The back/menu navigation lived only inside DefaultConversationHeader, which returns null when features.conversationHeader is false. In split layout that left narrow users with no way back to the conversation list. Render the nav affordances in a minimal bar even when the header chrome is disabled. - The CustomComposer demo passed a plain (non-forwardRef) component to the now wrapper-only slots.composerRoot, producing a React ref warning and dropping the injected form/data props. Make it forwardRef and spread the injected props (it still renders its own composer UI via the headless hook). Adds regression tests for the two source fixes.
…ders
Consolidated follow-up to the per-component codex findings:
- Add a shared `mergeSlotProps(base, consumer)` helper that preserves the
`(ownerState) => props` callback form of `SlotComponentProps`. Material chat
components pre-merged their default className/sx as a plain object and spread the
consumer slot prop with `...(slotProps?.x as object)`, which silently flattened a
callback to {} and dropped owner-state-driven props. Apply the helper across all
~18 affected slots (ChatMessage*, ChatComposer*, ChatConversation*, ChatIndicators*,
ChatMessageError, ChatSuggestions). The object form is unchanged.
- Render the row-level `dateDivider` and `unreadMarker` slots in the default message
row (DefaultMessageItem). Both headless components are self-suppressing: they read
messageId/index/items and render only at their boundary (a new calendar day, or the
first unread message derived from the conversation's unreadCount/readState),
returning null otherwise. `slots.X = null` hides them. Previously these row slots were
declared and partitioned but never rendered in the default-list path.
Adds a unit test for the helper and regression tests for ChatMessageError's callback
root slotProp and the date-divider / unread-marker rendering.
DefaultMessageItem already treats `slots.dateDivider`/`slots.unreadMarker = null`
as 'hide this row affordance' (matching the other presentational slots), but the
slot types were `React.ElementType` (non-nullable), so `slots={{ dateDivider: null }}`
failed to type-check. Widen both to `React.ElementType | null` and document the
null-to-hide behavior. Regenerated the ChatBox API docs.
The overlay's drawer-close was wired only into the conversation item's onClick (createConversationListSlotProps). ConversationListRoot also selects on Enter, calling setActiveConversation directly without firing the item onClick, so a keyboard user who opened the overlay, focused an item, and pressed Enter changed the active conversation but left the overlay open with focus trapped. Close the drawer whenever activeConversationId changes while it is open (covers both the pointer and keyboard paths), guarded on a previous-id ref so opening the overlay on an already-active conversation does not self-close. Adds a regression test that drives the keyboard Enter path.
…asses on sub-parts - slotProps.messageGroup is typed Partial<ChatMessageGroupProps>, so it can carry MessageGroup-primitive props (notably groupKey for time-window grouping). The flat plumbing spread the whole object into the group wrapper's DOM slot, so groupKey never reached the headless <MessageGroup> (default author grouping was used) and leaked onto the wrapper. Split it: route groupKey/index/items to <MessageGroup> (row-structural props still win) and keep only wrapper props on the group slot. Adds a regression test (groupKey changes grouping → avatars). - The ChatMessage sub-parts that share the MuiChatMessage-* namespace (Content, Avatar, Meta, Actions, DateDivider, Group) intentionally dropped their classes prop (Option B). Defensively destructure a JS/theme-injected classes out so it can't flow downstream through ...other. (No behavior change — it was absorbed harmlessly by a downstream styled component — but this keeps it from leaking.)
The type doc documented slots.messageList as wrapper-only, but ChatBoxContent
resolved it as a whole-component replacement (slots.messageList ?? ChatMessageList)
invoked with items/renderItem. Following the documented API — e.g.
slots={{ messageList: 'section' }} — produced a bare element with the list props
leaked onto it and no messages rendered.
Always render ChatMessageList and route slots.messageList into its own messageList
root slot (merged with any slotProps.messageList.slots), so a plain element wraps
the scrollable list while the default rows still render inside. This also fixes the
existing Tailwind demo (slots={{ messageList: 'div' }}). Clarified the type doc and
regenerated the ChatBox API docs; added a regression test.
The ChatLayout pane markers live on the headless ConversationListRoot/ConversationRoot, but ChatBoxContent renders the Material ChatConversationList/ChatConversation wrappers, which were unmarked. In split layout with the list visible and no active conversation (e.g. after the back button, or init without an active id) the list is ChatLayout's only child, and an unmarked single child falls back to the thread pane — so conversationsPane slot/styles were skipped exactly in that view. Export markChatLayoutPane from @mui/x-chat-headless and mark the Material wrappers (ChatConversationList → conversations, ChatConversation → thread) plus the narrow ChatBoxConversationOverlay (conversations). Marking every direct ChatLayout child keeps pane resolution unambiguous (a mixed marked/unmarked set warns). Updated the headless exports snapshot; added a regression test.
AboveComposerSuggestions injects the above-composer layout via slotProps.root.sx,
and ChatSuggestions applies slotProps.root after its own top-level sx — so a
consumer's top-level slotProps={{ suggestions: { sx } }} was overwritten in the
active-thread path (the empty-state path still honored it).
Fold the consumer's top-level sx into the composed root sx (defaults → top-level →
nested root, later wins) and stop spreading it separately. Adds a browser
regression test (computed color survives in the active-thread path).
|
Solved by #22488 |
Summary
ChatBoxlayout slots plus the related conversation, message, composer, indicator, suggestions, and confirmation slot surface.ChatSlotsProvider/useChatSlotscontext instead of prop-drilling, so a top-level override reaches deep message rows (including the virtualized list) without threading.messageAvatar,conversationHeader,composerSendButton, …) — consistent withGridSlotsComponent/ Charts and with what@mui/x-chatalready ships.What changed from the earlier iteration of this PR
An earlier revision nested the slots by family (
message.avatar,composer.send, …) and added av9.0.0/chat/migrate-slotscodemod. That has been reverted:9.0.0-alpha).chat/migrate-slotscodemod and itspreset-safeentry were removed. The nested vocabulary was never released (it lived only on this branch), so there is nothing for a codemod to migrate.masteris additive — four new optional slots (conversationRoot,messageInlineMeta,messageError,messageAuthorName) plus the context refactor. No renames, no removals, no breaking change.Details
ChatBoxSlots/ChatBoxSlotPropsare composed from prefixed per-family interfaces; only the composed types are public.ChatBox,ChatMessageList,ChatMessageGroup) uses the flat prefixed keys; leaf components (ChatMessage,ChatComposer,ChatConversation) keep their short local keys, with the flat→short translation at a single seam.nullto hide-and-collapse; thefeaturesobject toggles capabilities — both preserved.{ ...slots, <key>: slots?.<key> ?? Default }so anundefinedoverride no longer clobbers the default root, and compactChatMessagerenders the slot-driven tree alongside the headless group's injected author label.Addressed review feedback
Refinements from the review pass on this PR:
ChatBoxslot with JSDoc so the API docs no longer render blank slot descriptions.DefaultMessageItemspreadsslotProps.messageGroupbefore the required row props, andChatBox'srenderItemforwards the renderedindex/itemsso grouping is computed against the rendered list (correct whenslotProps.messageList.itemsnarrows the thread).@container { display: none }(the headlessConversationListRootalways pins an inlinedisplay: flex, so it never fired and would only have blanked a forcedlayoutMode="standard"sidebar).innerReftyped asuseRef<HTMLDivElement | null>with auseCallbackref callback (noMutableRefObjectcast); test descriptions aligned to the flat slot keys.Validation
pnpm --filter "@mui/x-chat" run typescriptpnpm --filter "@mui/x-codemod" run typescriptpnpm test:unit --project "x-chat" --run(170 passed / 5 skipped)pnpm test:browser --project "x-chat" --run(175 passed)pnpm test:unit --project "x-codemod" --run(275 passed)pnpm proptypespnpm docs:apipnpm docs:typescript:formattedpnpm eslint(changed chat / docs / codemod paths)pnpm valelintBatch merge structure
Merge top to bottom.
#22478can merge independently, but it should land before#22483because#22483assumes the new docs IA.