1- import React , { type ComponentPropsWithoutRef , useMemo , useState } from 'react' ;
1+ import React , {
2+ type ComponentPropsWithoutRef ,
3+ type ComponentRef ,
4+ useMemo ,
5+ useRef ,
6+ useState ,
7+ } from 'react' ;
28import clsx from 'clsx' ;
39
4- import type { ReactionsListModalProps } from './ReactionsListModal' ;
510import { ReactionsListModal as DefaultReactionsListModal } from './ReactionsListModal' ;
611import { useProcessReactions } from './hooks/useProcessReactions' ;
712import type { MessageContextValue } from '../../context' ;
8- import { useComponentContext , useTranslationContext } from '../../context' ;
13+ import {
14+ useComponentContext ,
15+ useMessageContext ,
16+ useTranslationContext ,
17+ } from '../../context' ;
918
1019import { MAX_MESSAGE_REACTIONS_TO_FETCH } from '../Message/hooks' ;
1120
@@ -16,6 +25,7 @@ import type {
1625 ReactionsComparator ,
1726 ReactionType ,
1827} from './types' ;
28+ import { DialogAnchor , useDialogOnNearestManager } from '../Dialog' ;
1929
2030export type ReactionsListProps = Partial <
2131 Pick < MessageContextValue , 'handleFetchReactions' | 'reactionDetailsSort' >
@@ -87,13 +97,20 @@ const UnMemoizedReactionsList = (props: ReactionsListProps) => {
8797 ) ;
8898 const { t } = useTranslationContext ( 'ReactionsList' ) ;
8999 const { ReactionsListModal = DefaultReactionsListModal } = useComponentContext ( ) ;
100+ const { isMyMessage, message } = useMessageContext ( 'ReactionsList' ) ;
101+
102+ const divRef = useRef < ComponentRef < 'div' > > ( null ) ;
103+ const dialogId = `message-reactions-detail-${ message . id } ` ;
104+ const { dialog, dialogManager } = useDialogOnNearestManager ( { id : dialogId } ) ;
90105
91106 const handleReactionButtonClick = ( reactionType : ReactionType | null ) => {
92107 if ( totalReactionCount > MAX_MESSAGE_REACTIONS_TO_FETCH ) {
93108 return ;
94109 }
95110
96111 setSelectedReactionType ( reactionType ) ;
112+
113+ dialog . open ( ) ;
97114 } ;
98115
99116 /**
@@ -127,13 +144,14 @@ const UnMemoizedReactionsList = (props: ReactionsListProps) => {
127144 [ `str-chat__message-reactions--${ visualStyle } ` ] :
128145 typeof visualStyle === 'string' ,
129146 } ) }
147+ ref = { divRef }
130148 role = 'figure'
131149 >
132150 < FragmentOrButton
133151 buttonIf = { visualStyle === 'clustered' }
134152 className = 'str-chat__message-reactions__list-button'
135153 onClick = { ( ) =>
136- setSelectedReactionType ( existingReactions [ 0 ] ?. reactionType ?? null )
154+ handleReactionButtonClick ( existingReactions [ 0 ] ?. reactionType ?? null )
137155 }
138156 >
139157 < ul className = 'str-chat__message-reactions__list' >
@@ -149,12 +167,12 @@ const UnMemoizedReactionsList = (props: ReactionsListProps) => {
149167 className = 'str-chat__message-reactions__list-item-button'
150168 onClick = { ( ) => handleReactionButtonClick ( reactionType ) }
151169 >
152- < span className = 'str-chat__message-reactions__item -icon' >
170+ < span className = 'str-chat__message-reactions__list-item -icon' >
153171 < EmojiComponent />
154172 </ span >
155173 { visualStyle === 'segmented' && reactionCount > 1 && (
156174 < span
157- className = 'str-chat__message-reactions__item -count'
175+ className = 'str-chat__message-reactions__list-item -count'
158176 data-testclass = 'message-reactions-item-count'
159177 >
160178 { reactionCount }
@@ -174,7 +192,9 @@ const UnMemoizedReactionsList = (props: ReactionsListProps) => {
174192 )
175193 }
176194 >
177- +{ totalReactionCount - cappedExistingReactions . reactionCountToDisplay }
195+ < span className = 'str-chat__message-reactions__overflow-count' >
196+ +{ totalReactionCount - cappedExistingReactions . reactionCountToDisplay }
197+ </ span >
178198 </ button >
179199 </ li >
180200 ) }
@@ -186,19 +206,25 @@ const UnMemoizedReactionsList = (props: ReactionsListProps) => {
186206 ) }
187207 </ FragmentOrButton >
188208 </ div >
189- { selectedReactionType !== null && (
209+
210+ < DialogAnchor
211+ dialogManagerId = { dialogManager ?. id }
212+ id = { dialogId }
213+ offset = { 8 }
214+ placement = { isMyMessage ( ) ? 'bottom-end' : 'bottom-start' }
215+ referenceElement = { divRef . current }
216+ trapFocus
217+ updatePositionOnContentResize
218+ >
190219 < ReactionsListModal
191220 handleFetchReactions = { handleFetchReactions }
192- onClose = { ( ) => setSelectedReactionType ( null ) }
193- onSelectedReactionTypeChange = {
194- setSelectedReactionType as ReactionsListModalProps [ 'onSelectedReactionTypeChange' ]
195- }
196- open = { selectedReactionType !== null }
221+ onSelectedReactionTypeChange = { setSelectedReactionType }
197222 reactions = { existingReactions }
198223 selectedReactionType = { selectedReactionType }
199224 sortReactionDetails = { sortReactionDetails }
225+ totalReactionCount = { totalReactionCount }
200226 />
201- ) }
227+ </ DialogAnchor >
202228 </ >
203229 ) ;
204230} ;
0 commit comments