Skip to content

feat: add enhanced mentions#3189

Open
MartinCupela wants to merge 6 commits into
masterfrom
feat/enhanced-mentions
Open

feat: add enhanced mentions#3189
MartinCupela wants to merge 6 commits into
masterfrom
feat/enhanced-mentions

Conversation

@MartinCupela
Copy link
Copy Markdown
Contributor

@MartinCupela MartinCupela commented May 13, 2026

🎯 Goal

Depends on: GetStream/stream-chat-js#1743

Closes REACT-979

This PR brings enhanced mentions support to stream-chat-react across both the composer UI and rendered message text.

It updates the @ suggestion flow to render a mixed mention set from stream-chat-js, including direct users, built-in mentions like @channel and @here, roles, and user groups. The suggestion list now uses dedicated row components for each mention type, keeps keyboard navigation working across non-user items, and preserves accessibility and i18n behavior for the mixed result set.

It also extends the message text rendering pipeline so enhanced mentions are highlighted the same way direct user mentions are. The renderText path now accepts additive mention metadata, routes all mention kinds through a unified mention renderer contract via node.mentionedEntity, and keeps backward compatibility for older user-only mention consumers through the deprecated node.mentionedUser alias and the existing renderText(text, mentioned_users, options) signature.

Finally, the PR adds focused regression coverage for render-text behavior, quoted-message rendering, backward-compatible plugin usage, email-like mention edge cases, and multi-word mention names.

Highlights

  • Render mixed @ suggestion results from stream-chat-js:
    • direct users
    • @channel
    • @here
    • roles
    • user groups
  • Add dedicated suggestion row components:
    • MentionItem
    • SpecialMentionItem
    • RoleItem
    • UserGroupItem
  • Reuse a shared suggestion-row primitive for non-user mention rows
  • Preserve UserItem backward compatibility for existing consumers
  • Update suggestion-list accessibility copy for mixed mention results
  • Keep keyboard navigation and Enter selection working for non-user mentions
  • Extend renderText to support additive mention metadata through options.messageMentionEntities
  • Highlight built-in, role, and user-group mentions in:
    • message text
    • quoted messages
  • Unify rendered mention nodes under mention + node.mentionedEntity
  • Keep backward compatibility for:
    • node.mentionedUser
    • mentionsMarkdownPlugin(UserResponse[])
    • renderText(text, mentioned_users, options)

# Conflicts:
#	src/components/Message/__tests__/__snapshots__/MessageText.test.tsx.snap
#	src/components/Message/renderText/rehypePlugins/mentionsMarkdownPlugin.ts
#	src/components/Message/renderText/renderText.tsx
@MartinCupela MartinCupela force-pushed the feat/enhanced-mentions branch from b154ab1 to 8bc5ceb Compare June 1, 2026 11:28
Comment on lines +39 to +49
const LeadingSlot = useMemo(
() =>
function BroadcastMentionLeadingSlot() {
return (
<div className='str-chat__suggestion-list__mention-item-leading-slot'>
<IconMegaphone className='str-chat__suggestion-list__mention-item-leading-slot-icon' />
</div>
);
},
[],
);
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IMO, it would be much cleaner if we made this a top-level component. There are other cases like this, too.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

solved in 70241a5


// JSX cannot type-check a generic intrinsic element with generic root props here.
// Call sites still get RootElement-specific rootProps; createElement keeps rendering simple internally.
return React.createElement(
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

React.createElement is a legacy API:

Let's switch to JSX

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

solved in 70241a5

Comment on lines +47 to +50
const displayTitle = useMemo(
() => <TokenizedSuggestionParts tokenizedDisplayName={entity.tokenizedDisplayName} />,
[entity.tokenizedDisplayName],
);
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is something that react-compiler can optimize automatically for us.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

solved in 70241a5

@MartinCupela MartinCupela force-pushed the feat/enhanced-mentions branch from f59965d to 70241a5 Compare June 1, 2026 15:41
@MartinCupela MartinCupela requested a review from oliverlaz June 1, 2026 15:43
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.

2 participants