stream-chat-react 14.11.1 → 15.0.0-rc.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (1701) hide show
  1. package/dist/cjs/ListItemLayout.60c3b287.js +2181 -0
  2. package/dist/cjs/ListItemLayout.60c3b287.js.map +1 -0
  3. package/dist/cjs/{ReactPlayerWrapper.a94a0cd1.js → ReactPlayerWrapper.f04b1d06.js} +5 -5
  4. package/dist/cjs/{ReactPlayerWrapper.a94a0cd1.js.map → ReactPlayerWrapper.f04b1d06.js.map} +1 -1
  5. package/dist/cjs/SlotLayout.de45be2d.js +1672 -0
  6. package/dist/cjs/SlotLayout.de45be2d.js.map +1 -0
  7. package/dist/cjs/Thread.373af587.js +7479 -0
  8. package/dist/cjs/Thread.373af587.js.map +1 -0
  9. package/dist/cjs/channel-detail.js +409 -389
  10. package/dist/cjs/channel-detail.js.map +1 -1
  11. package/dist/cjs/emojis.js +18 -16
  12. package/dist/cjs/emojis.js.map +1 -1
  13. package/dist/cjs/index.js +14474 -20038
  14. package/dist/cjs/index.js.map +1 -1
  15. package/dist/cjs/slot-geometry.js +145 -0
  16. package/dist/cjs/slot-geometry.js.map +1 -0
  17. package/dist/cjs/slot-layout.js +37 -0
  18. package/dist/cjs/useChannel.1004ed4c.js +18 -0
  19. package/dist/cjs/useChannel.1004ed4c.js.map +1 -0
  20. package/dist/cjs/useComponentContextIcons.d16834d9.js +1729 -0
  21. package/dist/cjs/useComponentContextIcons.d16834d9.js.map +1 -0
  22. package/dist/cjs/useIsCooldownActive.1f778bc1.js +110 -0
  23. package/dist/cjs/useIsCooldownActive.1f778bc1.js.map +1 -0
  24. package/dist/css/channel-detail.css.map +1 -1
  25. package/dist/css/index.css +228 -64
  26. package/dist/css/index.css.map +1 -1
  27. package/dist/es/_virtual/_rolldown/runtime.mjs +13 -0
  28. package/dist/es/a11y/a11yUtils.mjs +42 -0
  29. package/dist/es/a11y/a11yUtils.mjs.map +1 -0
  30. package/dist/es/a11y/accessibleLabel.mjs +31 -0
  31. package/dist/es/a11y/accessibleLabel.mjs.map +1 -0
  32. package/dist/es/a11y/hooks/useAriaIdentifiers.mjs +25 -0
  33. package/dist/es/a11y/hooks/useAriaIdentifiers.mjs.map +1 -0
  34. package/dist/es/a11y/hooks/useListboxKeyboardNavigation.mjs +85 -0
  35. package/dist/es/a11y/hooks/useListboxKeyboardNavigation.mjs.map +1 -0
  36. package/dist/es/a11y/hooks/useResolvedModalAriaProps.mjs +32 -0
  37. package/dist/es/a11y/hooks/useResolvedModalAriaProps.mjs.map +1 -0
  38. package/dist/es/a11y/hooks/useVirtualizedListboxKeyboardNavigation.mjs +68 -0
  39. package/dist/es/a11y/hooks/useVirtualizedListboxKeyboardNavigation.mjs.map +1 -0
  40. package/dist/es/channel-detail.mjs +29 -3020
  41. package/dist/es/components/AIStateIndicator/AIStateIndicator.mjs +27 -0
  42. package/dist/es/components/AIStateIndicator/AIStateIndicator.mjs.map +1 -0
  43. package/dist/es/components/AIStateIndicator/hooks/useAIState.mjs +20 -0
  44. package/dist/es/components/AIStateIndicator/hooks/useAIState.mjs.map +1 -0
  45. package/dist/es/components/Accessibility/AriaLiveAnnouncerProvider.mjs +144 -0
  46. package/dist/es/components/Accessibility/AriaLiveAnnouncerProvider.mjs.map +1 -0
  47. package/dist/es/components/Accessibility/AriaLiveOutlet.mjs +58 -0
  48. package/dist/es/components/Accessibility/AriaLiveOutlet.mjs.map +1 -0
  49. package/dist/es/components/Accessibility/AriaLiveOutletContext.mjs +8 -0
  50. package/dist/es/components/Accessibility/AriaLiveOutletContext.mjs.map +1 -0
  51. package/dist/es/components/Accessibility/NotificationAnnouncer.mjs +86 -0
  52. package/dist/es/components/Accessibility/NotificationAnnouncer.mjs.map +1 -0
  53. package/dist/es/components/Accessibility/hooks/useAudioPlaybackChangeAnnouncements.mjs +20 -0
  54. package/dist/es/components/Accessibility/hooks/useAudioPlaybackChangeAnnouncements.mjs.map +1 -0
  55. package/dist/es/components/Accessibility/hooks/useFocusReturn.mjs +37 -0
  56. package/dist/es/components/Accessibility/hooks/useFocusReturn.mjs.map +1 -0
  57. package/dist/es/components/Accessibility/hooks/useIncomingMessageAnnouncements.mjs +89 -0
  58. package/dist/es/components/Accessibility/hooks/useIncomingMessageAnnouncements.mjs.map +1 -0
  59. package/dist/es/components/Accessibility/hooks/useInertWhenHidden.mjs +85 -0
  60. package/dist/es/components/Accessibility/hooks/useInertWhenHidden.mjs.map +1 -0
  61. package/dist/es/components/Accessibility/hooks/useInteractionAnnouncements.mjs +165 -0
  62. package/dist/es/components/Accessibility/hooks/useInteractionAnnouncements.mjs.map +1 -0
  63. package/dist/es/components/Accessibility/scheduling/useAnnouncementQueue.mjs +43 -0
  64. package/dist/es/components/Accessibility/scheduling/useAnnouncementQueue.mjs.map +1 -0
  65. package/dist/es/components/Accessibility/scheduling/useDebouncedAnnounce.mjs +78 -0
  66. package/dist/es/components/Accessibility/scheduling/useDebouncedAnnounce.mjs.map +1 -0
  67. package/dist/es/components/Accessibility/scheduling/useSettledAnnouncement.mjs +90 -0
  68. package/dist/es/components/Accessibility/scheduling/useSettledAnnouncement.mjs.map +1 -0
  69. package/dist/es/components/Accessibility/useAriaLiveAnnouncer.mjs +13 -0
  70. package/dist/es/components/Accessibility/useAriaLiveAnnouncer.mjs.map +1 -0
  71. package/dist/es/components/Attachment/Attachment.mjs +89 -0
  72. package/dist/es/components/Attachment/Attachment.mjs.map +1 -0
  73. package/dist/es/components/Attachment/AttachmentActions.mjs +110 -0
  74. package/dist/es/components/Attachment/AttachmentActions.mjs.map +1 -0
  75. package/dist/es/components/Attachment/AttachmentContainer.mjs +269 -0
  76. package/dist/es/components/Attachment/AttachmentContainer.mjs.map +1 -0
  77. package/dist/es/components/Attachment/Audio.mjs +109 -0
  78. package/dist/es/components/Attachment/Audio.mjs.map +1 -0
  79. package/dist/es/components/Attachment/FileAttachment.mjs +46 -0
  80. package/dist/es/components/Attachment/FileAttachment.mjs.map +1 -0
  81. package/dist/es/components/Attachment/Geolocation.mjs +89 -0
  82. package/dist/es/components/Attachment/Geolocation.mjs.map +1 -0
  83. package/dist/es/components/Attachment/Giphy.mjs +62 -0
  84. package/dist/es/components/Attachment/Giphy.mjs.map +1 -0
  85. package/dist/es/components/Attachment/Image.mjs +19 -0
  86. package/dist/es/components/Attachment/Image.mjs.map +1 -0
  87. package/dist/es/components/Attachment/LinkPreview/Card.mjs +93 -0
  88. package/dist/es/components/Attachment/LinkPreview/Card.mjs.map +1 -0
  89. package/dist/es/components/Attachment/LinkPreview/UnableToRenderCard.mjs +22 -0
  90. package/dist/es/components/Attachment/LinkPreview/UnableToRenderCard.mjs.map +1 -0
  91. package/dist/es/components/Attachment/ModalGallery.mjs +178 -0
  92. package/dist/es/components/Attachment/ModalGallery.mjs.map +1 -0
  93. package/dist/es/components/Attachment/UnsupportedAttachment.mjs +25 -0
  94. package/dist/es/components/Attachment/UnsupportedAttachment.mjs.map +1 -0
  95. package/dist/es/components/Attachment/VideoAttachment.mjs +56 -0
  96. package/dist/es/components/Attachment/VideoAttachment.mjs.map +1 -0
  97. package/dist/es/components/Attachment/VisibilityDisclaimer.mjs +17 -0
  98. package/dist/es/components/Attachment/VisibilityDisclaimer.mjs.map +1 -0
  99. package/dist/es/components/Attachment/VoiceRecording.mjs +139 -0
  100. package/dist/es/components/Attachment/VoiceRecording.mjs.map +1 -0
  101. package/dist/es/components/Attachment/attachment-sizing.mjs +73 -0
  102. package/dist/es/components/Attachment/attachment-sizing.mjs.map +1 -0
  103. package/dist/es/components/Attachment/audioSampling.mjs +74 -0
  104. package/dist/es/components/Attachment/audioSampling.mjs.map +1 -0
  105. package/dist/es/components/Attachment/components/AttachmentUploadProgressIndicator.mjs +38 -0
  106. package/dist/es/components/Attachment/components/AttachmentUploadProgressIndicator.mjs.map +1 -0
  107. package/dist/es/components/Attachment/components/DownloadButton.mjs +35 -0
  108. package/dist/es/components/Attachment/components/DownloadButton.mjs.map +1 -0
  109. package/dist/es/components/Attachment/components/FileSizeIndicator.mjs +17 -0
  110. package/dist/es/components/Attachment/components/FileSizeIndicator.mjs.map +1 -0
  111. package/dist/es/components/Attachment/giphyAccessibility.mjs +15 -0
  112. package/dist/es/components/Attachment/giphyAccessibility.mjs.map +1 -0
  113. package/dist/es/components/Attachment/hooks/useAttachmentUploadState.mjs +80 -0
  114. package/dist/es/components/Attachment/hooks/useAttachmentUploadState.mjs.map +1 -0
  115. package/dist/es/components/Attachment/hooks/useLocalVideoDimensions.mjs +79 -0
  116. package/dist/es/components/Attachment/hooks/useLocalVideoDimensions.mjs.map +1 -0
  117. package/dist/es/components/Attachment/icons.mjs +13 -0
  118. package/dist/es/components/Attachment/icons.mjs.map +1 -0
  119. package/dist/es/components/Attachment/utils.mjs +41 -0
  120. package/dist/es/components/Attachment/utils.mjs.map +1 -0
  121. package/dist/es/components/AudioPlayback/AudioPlaybackArbiter.mjs +57 -0
  122. package/dist/es/components/AudioPlayback/AudioPlaybackArbiter.mjs.map +1 -0
  123. package/dist/es/components/AudioPlayback/AudioPlayer.mjs +472 -0
  124. package/dist/es/components/AudioPlayback/AudioPlayer.mjs.map +1 -0
  125. package/dist/es/components/AudioPlayback/AudioPlayerPool.mjs +73 -0
  126. package/dist/es/components/AudioPlayback/AudioPlayerPool.mjs.map +1 -0
  127. package/dist/es/components/AudioPlayback/WithAudioPlayback.mjs +86 -0
  128. package/dist/es/components/AudioPlayback/WithAudioPlayback.mjs.map +1 -0
  129. package/dist/es/components/AudioPlayback/components/DurationDisplay.mjs +33 -0
  130. package/dist/es/components/AudioPlayback/components/DurationDisplay.mjs.map +1 -0
  131. package/dist/es/components/AudioPlayback/components/PlaybackRateButton.mjs +15 -0
  132. package/dist/es/components/AudioPlayback/components/PlaybackRateButton.mjs.map +1 -0
  133. package/dist/es/components/AudioPlayback/components/ProgressBar.mjs +56 -0
  134. package/dist/es/components/AudioPlayback/components/ProgressBar.mjs.map +1 -0
  135. package/dist/es/components/AudioPlayback/components/WaveProgressBar.mjs +107 -0
  136. package/dist/es/components/AudioPlayback/components/WaveProgressBar.mjs.map +1 -0
  137. package/dist/es/components/AudioPlayback/components/formatTime.mjs +14 -0
  138. package/dist/es/components/AudioPlayback/components/formatTime.mjs.map +1 -0
  139. package/dist/es/components/AudioPlayback/components/keyboardSeek.mjs +36 -0
  140. package/dist/es/components/AudioPlayback/components/keyboardSeek.mjs.map +1 -0
  141. package/dist/es/components/AudioPlayback/components/progressBarA11y.mjs +19 -0
  142. package/dist/es/components/AudioPlayback/components/progressBarA11y.mjs.map +1 -0
  143. package/dist/es/components/AudioPlayback/components/useInteractiveProgressBar.mjs +77 -0
  144. package/dist/es/components/AudioPlayback/components/useInteractiveProgressBar.mjs.map +1 -0
  145. package/dist/es/components/AudioPlayback/plugins/AudioPlayerNotificationsPlugin.mjs +33 -0
  146. package/dist/es/components/AudioPlayback/plugins/AudioPlayerNotificationsPlugin.mjs.map +1 -0
  147. package/dist/es/components/Avatar/Avatar.mjs +62 -0
  148. package/dist/es/components/Avatar/Avatar.mjs.map +1 -0
  149. package/dist/es/components/Avatar/AvatarStack.mjs +32 -0
  150. package/dist/es/components/Avatar/AvatarStack.mjs.map +1 -0
  151. package/dist/es/components/Avatar/ChannelAvatar.mjs +25 -0
  152. package/dist/es/components/Avatar/ChannelAvatar.mjs.map +1 -0
  153. package/dist/es/components/Avatar/GroupAvatar.mjs +53 -0
  154. package/dist/es/components/Avatar/GroupAvatar.mjs.map +1 -0
  155. package/dist/es/components/Avatar/utils.mjs +10 -0
  156. package/dist/es/components/Avatar/utils.mjs.map +1 -0
  157. package/dist/es/components/Badge/Badge.mjs +28 -0
  158. package/dist/es/components/Badge/Badge.mjs.map +1 -0
  159. package/dist/es/components/Badge/MediaBadge.mjs +21 -0
  160. package/dist/es/components/Badge/MediaBadge.mjs.map +1 -0
  161. package/dist/es/components/BaseImage/BaseImage.mjs +35 -0
  162. package/dist/es/components/BaseImage/BaseImage.mjs.map +1 -0
  163. package/dist/es/components/BaseImage/ImagePlaceholder.mjs +21 -0
  164. package/dist/es/components/BaseImage/ImagePlaceholder.mjs.map +1 -0
  165. package/dist/es/components/BaseImage/toBaseImageDescriptors.mjs +57 -0
  166. package/dist/es/components/BaseImage/toBaseImageDescriptors.mjs.map +1 -0
  167. package/dist/es/components/Button/Button.mjs +36 -0
  168. package/dist/es/components/Button/Button.mjs.map +1 -0
  169. package/dist/es/components/Button/PlayButton.mjs +26 -0
  170. package/dist/es/components/Button/PlayButton.mjs.map +1 -0
  171. package/dist/es/components/Button/WorkspaceNavigationButtons.mjs +94 -0
  172. package/dist/es/components/Button/WorkspaceNavigationButtons.mjs.map +1 -0
  173. package/dist/es/components/Channel/Channel.mjs +66 -0
  174. package/dist/es/components/Channel/Channel.mjs.map +1 -0
  175. package/dist/es/components/Channel/constants.mjs +6 -0
  176. package/dist/es/components/Channel/constants.mjs.map +1 -0
  177. package/dist/es/components/Channel/hooks/useChannelCapabilities.mjs +21 -0
  178. package/dist/es/components/Channel/hooks/useChannelCapabilities.mjs.map +1 -0
  179. package/dist/es/components/Channel/hooks/useChannelContainerClasses.mjs +20 -0
  180. package/dist/es/components/Channel/hooks/useChannelContainerClasses.mjs.map +1 -0
  181. package/dist/es/components/ChannelHeader/ChannelHeader.mjs +71 -0
  182. package/dist/es/components/ChannelHeader/ChannelHeader.mjs.map +1 -0
  183. package/dist/es/components/ChannelHeader/hooks/useChannelHasMembersOnline.mjs +26 -0
  184. package/dist/es/components/ChannelHeader/hooks/useChannelHasMembersOnline.mjs.map +1 -0
  185. package/dist/es/components/ChannelHeader/hooks/useChannelHeaderOnlineStatus.mjs +31 -0
  186. package/dist/es/components/ChannelHeader/hooks/useChannelHeaderOnlineStatus.mjs.map +1 -0
  187. package/dist/es/components/ChannelList/ChannelList.mjs +72 -0
  188. package/dist/es/components/ChannelList/ChannelList.mjs.map +1 -0
  189. package/dist/es/components/ChannelList/ChannelListHeader.mjs +22 -0
  190. package/dist/es/components/ChannelList/ChannelListHeader.mjs.map +1 -0
  191. package/dist/es/components/ChannelList/ChannelLists.mjs +31 -0
  192. package/dist/es/components/ChannelList/ChannelLists.mjs.map +1 -0
  193. package/dist/es/components/ChannelList/ChannelNavigation.mjs +36 -0
  194. package/dist/es/components/ChannelList/ChannelNavigation.mjs.map +1 -0
  195. package/dist/es/components/ChannelList/hooks/useChannelListKeyboardNavigation.mjs +82 -0
  196. package/dist/es/components/ChannelList/hooks/useChannelListKeyboardNavigation.mjs.map +1 -0
  197. package/dist/es/components/ChannelList/hooks/useChannelMembersState.mjs +23 -0
  198. package/dist/es/components/ChannelList/hooks/useChannelMembersState.mjs.map +1 -0
  199. package/dist/es/components/ChannelList/hooks/useChannelMembershipState.mjs +15 -0
  200. package/dist/es/components/ChannelList/hooks/useChannelMembershipState.mjs.map +1 -0
  201. package/dist/es/components/ChannelList/hooks/useChannelPaginatorState.mjs +21 -0
  202. package/dist/es/components/ChannelList/hooks/useChannelPaginatorState.mjs.map +1 -0
  203. package/dist/es/components/ChannelList/hooks/useSelectedChannelState.mjs +24 -0
  204. package/dist/es/components/ChannelList/hooks/useSelectedChannelState.mjs.map +1 -0
  205. package/dist/es/components/ChannelListItem/ChannelListItem.mjs +65 -0
  206. package/dist/es/components/ChannelListItem/ChannelListItem.mjs.map +1 -0
  207. package/dist/es/components/ChannelListItem/ChannelListItemActionButtons.defaults.mjs +432 -0
  208. package/dist/es/components/ChannelListItem/ChannelListItemActionButtons.defaults.mjs.map +1 -0
  209. package/dist/es/components/ChannelListItem/ChannelListItemActionButtons.mjs +67 -0
  210. package/dist/es/components/ChannelListItem/ChannelListItemActionButtons.mjs.map +1 -0
  211. package/dist/es/components/ChannelListItem/ChannelListItemTimestamp.mjs +31 -0
  212. package/dist/es/components/ChannelListItem/ChannelListItemTimestamp.mjs.map +1 -0
  213. package/dist/es/components/ChannelListItem/ChannelListItemUI.mjs +120 -0
  214. package/dist/es/components/ChannelListItem/ChannelListItemUI.mjs.map +1 -0
  215. package/dist/es/components/ChannelListItem/hooks/useChannelDisplayName.mjs +56 -0
  216. package/dist/es/components/ChannelListItem/hooks/useChannelDisplayName.mjs.map +1 -0
  217. package/dist/es/components/ChannelListItem/hooks/useChannelPreviewInfo.mjs +51 -0
  218. package/dist/es/components/ChannelListItem/hooks/useChannelPreviewInfo.mjs.map +1 -0
  219. package/dist/es/components/ChannelListItem/hooks/useIsChannelMuted.mjs +15 -0
  220. package/dist/es/components/ChannelListItem/hooks/useIsChannelMuted.mjs.map +1 -0
  221. package/dist/es/components/ChannelListItem/hooks/useIsUserMuted.mjs +11 -0
  222. package/dist/es/components/ChannelListItem/hooks/useIsUserMuted.mjs.map +1 -0
  223. package/dist/es/components/ChannelListItem/hooks/useMessageDeliveryStatus.mjs +36 -0
  224. package/dist/es/components/ChannelListItem/hooks/useMessageDeliveryStatus.mjs.map +1 -0
  225. package/dist/es/components/ChannelListItem/utils.a11y.mjs +135 -0
  226. package/dist/es/components/ChannelListItem/utils.a11y.mjs.map +1 -0
  227. package/dist/es/components/ChannelListItem/utils.mjs +196 -0
  228. package/dist/es/components/ChannelListItem/utils.mjs.map +1 -0
  229. package/dist/es/components/Chat/Chat.mjs +89 -0
  230. package/dist/es/components/Chat/Chat.mjs.map +1 -0
  231. package/dist/es/components/Chat/hooks/useChat.mjs +44 -0
  232. package/dist/es/components/Chat/hooks/useChat.mjs.map +1 -0
  233. package/dist/es/components/Chat/hooks/useCreateChatClient.mjs +36 -0
  234. package/dist/es/components/Chat/hooks/useCreateChatClient.mjs.map +1 -0
  235. package/dist/es/components/Chat/hooks/useCreateChatContext.mjs +30 -0
  236. package/dist/es/components/Chat/hooks/useCreateChatContext.mjs.map +1 -0
  237. package/dist/es/components/Chat/hooks/useNetworkConnectionState.mjs +46 -0
  238. package/dist/es/components/Chat/hooks/useNetworkConnectionState.mjs.map +1 -0
  239. package/dist/es/components/Chat/hooks/useReportLostConnectionSystemNotification.mjs +139 -0
  240. package/dist/es/components/Chat/hooks/useReportLostConnectionSystemNotification.mjs.map +1 -0
  241. package/dist/es/components/Chat/hooks/useSplitActionSet.mjs +21 -0
  242. package/dist/es/components/Chat/hooks/useSplitActionSet.mjs.map +1 -0
  243. package/dist/es/components/Chat/hooks/useWSConnectionState.mjs +31 -0
  244. package/dist/es/components/Chat/hooks/useWSConnectionState.mjs.map +1 -0
  245. package/dist/es/components/DateSeparator/DateSeparator.mjs +36 -0
  246. package/dist/es/components/DateSeparator/DateSeparator.mjs.map +1 -0
  247. package/dist/es/components/Dialog/components/Alert.mjs +53 -0
  248. package/dist/es/components/Dialog/components/Alert.mjs.map +1 -0
  249. package/dist/es/components/Dialog/components/Callout.mjs +57 -0
  250. package/dist/es/components/Dialog/components/Callout.mjs.map +1 -0
  251. package/dist/es/components/Dialog/components/ContextMenu.mjs +551 -0
  252. package/dist/es/components/Dialog/components/ContextMenu.mjs.map +1 -0
  253. package/dist/es/components/Dialog/components/Prompt.mjs +112 -0
  254. package/dist/es/components/Dialog/components/Prompt.mjs.map +1 -0
  255. package/dist/es/components/Dialog/components/Viewer.mjs +100 -0
  256. package/dist/es/components/Dialog/components/Viewer.mjs.map +1 -0
  257. package/dist/es/components/Dialog/hooks/useDialog.mjs +53 -0
  258. package/dist/es/components/Dialog/hooks/useDialog.mjs.map +1 -0
  259. package/dist/es/components/Dialog/hooks/usePopoverPosition.mjs +57 -0
  260. package/dist/es/components/Dialog/hooks/usePopoverPosition.mjs.map +1 -0
  261. package/dist/es/components/Dialog/service/DialogAnchor.mjs +175 -0
  262. package/dist/es/components/Dialog/service/DialogAnchor.mjs.map +1 -0
  263. package/dist/es/components/Dialog/service/DialogManager.mjs +172 -0
  264. package/dist/es/components/Dialog/service/DialogManager.mjs.map +1 -0
  265. package/dist/es/components/Dialog/service/DialogPortal.mjs +63 -0
  266. package/dist/es/components/Dialog/service/DialogPortal.mjs.map +1 -0
  267. package/dist/es/components/DragAndDrop/DragAndDropContainer.mjs +90 -0
  268. package/dist/es/components/DragAndDrop/DragAndDropContainer.mjs.map +1 -0
  269. package/dist/es/components/EmptyStateIndicator/EmptyStateIndicator.mjs +39 -0
  270. package/dist/es/components/EmptyStateIndicator/EmptyStateIndicator.mjs.map +1 -0
  271. package/dist/es/components/EventComponent/EventComponent.mjs +27 -0
  272. package/dist/es/components/EventComponent/EventComponent.mjs.map +1 -0
  273. package/dist/es/components/FileIcon/FileIcon.mjs +43 -0
  274. package/dist/es/components/FileIcon/FileIcon.mjs.map +1 -0
  275. package/dist/es/components/FileIcon/FileIconSet.mjs +407 -0
  276. package/dist/es/components/FileIcon/FileIconSet.mjs.map +1 -0
  277. package/dist/es/components/FileIcon/iconMap.mjs +41 -0
  278. package/dist/es/components/FileIcon/iconMap.mjs.map +1 -0
  279. package/dist/es/components/FileIcon/mimeTypes.mjs +242 -0
  280. package/dist/es/components/FileIcon/mimeTypes.mjs.map +1 -0
  281. package/dist/es/components/Form/Checkbox.mjs +15 -0
  282. package/dist/es/components/Form/Checkbox.mjs.map +1 -0
  283. package/dist/es/components/Form/Dropdown.mjs +135 -0
  284. package/dist/es/components/Form/Dropdown.mjs.map +1 -0
  285. package/dist/es/components/Form/FieldError.mjs +13 -0
  286. package/dist/es/components/Form/FieldError.mjs.map +1 -0
  287. package/dist/es/components/Form/NumericInput.mjs +126 -0
  288. package/dist/es/components/Form/NumericInput.mjs.map +1 -0
  289. package/dist/es/components/Form/SwitchField.mjs +103 -0
  290. package/dist/es/components/Form/SwitchField.mjs.map +1 -0
  291. package/dist/es/components/Form/TextInput.mjs +113 -0
  292. package/dist/es/components/Form/TextInput.mjs.map +1 -0
  293. package/dist/es/components/Form/TextInputFieldSet.mjs +21 -0
  294. package/dist/es/components/Form/TextInputFieldSet.mjs.map +1 -0
  295. package/dist/es/components/Form/hooks/useFormState.mjs +54 -0
  296. package/dist/es/components/Form/hooks/useFormState.mjs.map +1 -0
  297. package/dist/es/components/Gallery/Gallery.mjs +60 -0
  298. package/dist/es/components/Gallery/Gallery.mjs.map +1 -0
  299. package/dist/es/components/Gallery/GalleryContext.mjs +15 -0
  300. package/dist/es/components/Gallery/GalleryContext.mjs.map +1 -0
  301. package/dist/es/components/Gallery/GalleryHeader.mjs +92 -0
  302. package/dist/es/components/Gallery/GalleryHeader.mjs.map +1 -0
  303. package/dist/es/components/Gallery/GalleryUI.mjs +206 -0
  304. package/dist/es/components/Gallery/GalleryUI.mjs.map +1 -0
  305. package/dist/es/components/Icons/BaseIcon.mjs +20 -0
  306. package/dist/es/components/Icons/BaseIcon.mjs.map +1 -0
  307. package/dist/es/components/Icons/createIcon.mjs +23 -0
  308. package/dist/es/components/Icons/createIcon.mjs.map +1 -0
  309. package/dist/es/components/Icons/icons.mjs +802 -0
  310. package/dist/es/components/Icons/icons.mjs.map +1 -0
  311. package/dist/es/components/InfiniteScrollPaginator/InfiniteScroll.mjs +81 -0
  312. package/dist/es/components/InfiniteScrollPaginator/InfiniteScroll.mjs.map +1 -0
  313. package/dist/es/components/InfiniteScrollPaginator/InfiniteScrollPaginator.mjs +75 -0
  314. package/dist/es/components/InfiniteScrollPaginator/InfiniteScrollPaginator.mjs.map +1 -0
  315. package/dist/es/components/InfiniteScrollPaginator/InfiniteScrollWithComponents.mjs +43 -0
  316. package/dist/es/components/InfiniteScrollPaginator/InfiniteScrollWithComponents.mjs.map +1 -0
  317. package/dist/es/components/InfiniteScrollPaginator/hooks/useCursorPaginator.mjs +47 -0
  318. package/dist/es/components/InfiniteScrollPaginator/hooks/useCursorPaginator.mjs.map +1 -0
  319. package/dist/es/components/ListItemLayout/ListItemLayout.mjs +62 -0
  320. package/dist/es/components/ListItemLayout/ListItemLayout.mjs.map +1 -0
  321. package/dist/es/components/LoadMore/LoadMoreButton.mjs +28 -0
  322. package/dist/es/components/LoadMore/LoadMoreButton.mjs.map +1 -0
  323. package/dist/es/components/LoadMore/LoadMorePaginator.mjs +20 -0
  324. package/dist/es/components/LoadMore/LoadMorePaginator.mjs.map +1 -0
  325. package/dist/es/components/Loading/AttachmentUploadedSizeIndicator.mjs +24 -0
  326. package/dist/es/components/Loading/AttachmentUploadedSizeIndicator.mjs.map +1 -0
  327. package/dist/es/components/Loading/LoadingChannel.mjs +59 -0
  328. package/dist/es/components/Loading/LoadingChannel.mjs.map +1 -0
  329. package/dist/es/components/Loading/LoadingChannels.mjs +28 -0
  330. package/dist/es/components/Loading/LoadingChannels.mjs.map +1 -0
  331. package/dist/es/components/Loading/LoadingErrorIndicator.mjs +17 -0
  332. package/dist/es/components/Loading/LoadingErrorIndicator.mjs.map +1 -0
  333. package/dist/es/components/Loading/LoadingIndicator.mjs +15 -0
  334. package/dist/es/components/Loading/LoadingIndicator.mjs.map +1 -0
  335. package/dist/es/components/Loading/UploadProgressIndicator.mjs +15 -0
  336. package/dist/es/components/Loading/UploadProgressIndicator.mjs.map +1 -0
  337. package/dist/es/components/Loading/UploadedSizeIndicator.mjs +22 -0
  338. package/dist/es/components/Loading/UploadedSizeIndicator.mjs.map +1 -0
  339. package/dist/es/components/Loading/progress-indicators.mjs +50 -0
  340. package/dist/es/components/Loading/progress-indicators.mjs.map +1 -0
  341. package/dist/es/components/Location/ShareLocationDialog.mjs +206 -0
  342. package/dist/es/components/Location/ShareLocationDialog.mjs.map +1 -0
  343. package/dist/es/components/Location/hooks/useLiveLocationSharingManager.mjs +58 -0
  344. package/dist/es/components/Location/hooks/useLiveLocationSharingManager.mjs.map +1 -0
  345. package/dist/es/components/MediaRecorder/AudioRecorder/AudioRecorder.mjs +32 -0
  346. package/dist/es/components/MediaRecorder/AudioRecorder/AudioRecorder.mjs.map +1 -0
  347. package/dist/es/components/MediaRecorder/AudioRecorder/AudioRecorderRecordingControls.mjs +77 -0
  348. package/dist/es/components/MediaRecorder/AudioRecorder/AudioRecorderRecordingControls.mjs.map +1 -0
  349. package/dist/es/components/MediaRecorder/AudioRecorder/AudioRecordingButtonWithNotification.mjs +58 -0
  350. package/dist/es/components/MediaRecorder/AudioRecorder/AudioRecordingButtonWithNotification.mjs.map +1 -0
  351. package/dist/es/components/MediaRecorder/AudioRecorder/AudioRecordingPlayback.mjs +71 -0
  352. package/dist/es/components/MediaRecorder/AudioRecorder/AudioRecordingPlayback.mjs.map +1 -0
  353. package/dist/es/components/MediaRecorder/AudioRecorder/AudioRecordingPreview.mjs +65 -0
  354. package/dist/es/components/MediaRecorder/AudioRecorder/AudioRecordingPreview.mjs.map +1 -0
  355. package/dist/es/components/MediaRecorder/AudioRecorder/RecordingTimer.mjs +13 -0
  356. package/dist/es/components/MediaRecorder/AudioRecorder/RecordingTimer.mjs.map +1 -0
  357. package/dist/es/components/MediaRecorder/AudioRecorder/hooks/useTimeElapsed.mjs +40 -0
  358. package/dist/es/components/MediaRecorder/AudioRecorder/hooks/useTimeElapsed.mjs.map +1 -0
  359. package/dist/es/components/MediaRecorder/AudioRecorder/recordingStateIdentity.mjs +8 -0
  360. package/dist/es/components/MediaRecorder/AudioRecorder/recordingStateIdentity.mjs.map +1 -0
  361. package/dist/es/components/MediaRecorder/RecordingPermissionDeniedNotification.mjs +31 -0
  362. package/dist/es/components/MediaRecorder/RecordingPermissionDeniedNotification.mjs.map +1 -0
  363. package/dist/es/components/MediaRecorder/classes/AmplitudeRecorder.mjs +81 -0
  364. package/dist/es/components/MediaRecorder/classes/AmplitudeRecorder.mjs.map +1 -0
  365. package/dist/es/components/MediaRecorder/classes/BrowserPermission.mjs +63 -0
  366. package/dist/es/components/MediaRecorder/classes/BrowserPermission.mjs.map +1 -0
  367. package/dist/es/components/MediaRecorder/classes/MediaRecorderController.mjs +251 -0
  368. package/dist/es/components/MediaRecorder/classes/MediaRecorderController.mjs.map +1 -0
  369. package/dist/es/components/MediaRecorder/hooks/useMediaRecorder.mjs +75 -0
  370. package/dist/es/components/MediaRecorder/hooks/useMediaRecorder.mjs.map +1 -0
  371. package/dist/es/components/MediaRecorder/observable/BehaviorSubject.mjs +28 -0
  372. package/dist/es/components/MediaRecorder/observable/BehaviorSubject.mjs.map +1 -0
  373. package/dist/es/components/MediaRecorder/observable/Observable.mjs +24 -0
  374. package/dist/es/components/MediaRecorder/observable/Observable.mjs.map +1 -0
  375. package/dist/es/components/MediaRecorder/observable/Observer.mjs +8 -0
  376. package/dist/es/components/MediaRecorder/observable/Observer.mjs.map +1 -0
  377. package/dist/es/components/MediaRecorder/observable/Subject.mjs +55 -0
  378. package/dist/es/components/MediaRecorder/observable/Subject.mjs.map +1 -0
  379. package/dist/es/components/MediaRecorder/observable/Subscription.mjs +16 -0
  380. package/dist/es/components/MediaRecorder/observable/Subscription.mjs.map +1 -0
  381. package/dist/es/components/MediaRecorder/transcode/audioProcessing.mjs +34 -0
  382. package/dist/es/components/MediaRecorder/transcode/audioProcessing.mjs.map +1 -0
  383. package/dist/es/components/MediaRecorder/transcode/index.mjs +12 -0
  384. package/dist/es/components/MediaRecorder/transcode/index.mjs.map +1 -0
  385. package/dist/es/components/MediaRecorder/transcode/wav.mjs +99 -0
  386. package/dist/es/components/MediaRecorder/transcode/wav.mjs.map +1 -0
  387. package/dist/es/components/Message/Message.mjs +113 -0
  388. package/dist/es/components/Message/Message.mjs.map +1 -0
  389. package/dist/es/components/Message/MessageAlsoSentInChannelIndicator.mjs +35 -0
  390. package/dist/es/components/Message/MessageAlsoSentInChannelIndicator.mjs.map +1 -0
  391. package/dist/es/components/Message/MessageBlocked.mjs +27 -0
  392. package/dist/es/components/Message/MessageBlocked.mjs.map +1 -0
  393. package/dist/es/components/Message/MessageBubble.mjs +12 -0
  394. package/dist/es/components/Message/MessageBubble.mjs.map +1 -0
  395. package/dist/es/components/Message/MessageDeletedBubble.mjs +21 -0
  396. package/dist/es/components/Message/MessageDeletedBubble.mjs.map +1 -0
  397. package/dist/es/components/Message/MessageEditedIndicator.mjs +42 -0
  398. package/dist/es/components/Message/MessageEditedIndicator.mjs.map +1 -0
  399. package/dist/es/components/Message/MessageRepliesCountButton.mjs +71 -0
  400. package/dist/es/components/Message/MessageRepliesCountButton.mjs.map +1 -0
  401. package/dist/es/components/Message/MessageStatus.mjs +87 -0
  402. package/dist/es/components/Message/MessageStatus.mjs.map +1 -0
  403. package/dist/es/components/Message/MessageText.mjs +101 -0
  404. package/dist/es/components/Message/MessageText.mjs.map +1 -0
  405. package/dist/es/components/Message/MessageTimestamp.mjs +21 -0
  406. package/dist/es/components/Message/MessageTimestamp.mjs.map +1 -0
  407. package/dist/es/components/Message/MessageTranslationIndicator.mjs +53 -0
  408. package/dist/es/components/Message/MessageTranslationIndicator.mjs.map +1 -0
  409. package/dist/es/components/Message/MessageUI.mjs +186 -0
  410. package/dist/es/components/Message/MessageUI.mjs.map +1 -0
  411. package/dist/es/components/Message/PinIndicator.mjs +34 -0
  412. package/dist/es/components/Message/PinIndicator.mjs.map +1 -0
  413. package/dist/es/components/Message/QuotedMessage.mjs +26 -0
  414. package/dist/es/components/Message/QuotedMessage.mjs.map +1 -0
  415. package/dist/es/components/Message/ReminderNotification.mjs +58 -0
  416. package/dist/es/components/Message/ReminderNotification.mjs.map +1 -0
  417. package/dist/es/components/Message/StreamedMessageText.mjs +36 -0
  418. package/dist/es/components/Message/StreamedMessageText.mjs.map +1 -0
  419. package/dist/es/components/Message/Timestamp.mjs +41 -0
  420. package/dist/es/components/Message/Timestamp.mjs.map +1 -0
  421. package/dist/es/components/Message/emojiRegex.mjs +20 -0
  422. package/dist/es/components/Message/emojiRegex.mjs.map +1 -0
  423. package/dist/es/components/Message/hooks/useActionHandler.mjs +31 -0
  424. package/dist/es/components/Message/hooks/useActionHandler.mjs.map +1 -0
  425. package/dist/es/components/Message/hooks/useDeleteHandler.mjs +40 -0
  426. package/dist/es/components/Message/hooks/useDeleteHandler.mjs.map +1 -0
  427. package/dist/es/components/Message/hooks/useFlagHandler.mjs +20 -0
  428. package/dist/es/components/Message/hooks/useFlagHandler.mjs.map +1 -0
  429. package/dist/es/components/Message/hooks/useMarkUnreadHandler.mjs +22 -0
  430. package/dist/es/components/Message/hooks/useMarkUnreadHandler.mjs.map +1 -0
  431. package/dist/es/components/Message/hooks/useMentionsHandler.mjs +20 -0
  432. package/dist/es/components/Message/hooks/useMentionsHandler.mjs.map +1 -0
  433. package/dist/es/components/Message/hooks/useMessageAlsoSentInChannelNavigation.mjs +72 -0
  434. package/dist/es/components/Message/hooks/useMessageAlsoSentInChannelNavigation.mjs.map +1 -0
  435. package/dist/es/components/Message/hooks/useMessageReminder.mjs +14 -0
  436. package/dist/es/components/Message/hooks/useMessageReminder.mjs.map +1 -0
  437. package/dist/es/components/Message/hooks/useMessageTextStreaming.mjs +48 -0
  438. package/dist/es/components/Message/hooks/useMessageTextStreaming.mjs.map +1 -0
  439. package/dist/es/components/Message/hooks/useMuteHandler.mjs +41 -0
  440. package/dist/es/components/Message/hooks/useMuteHandler.mjs.map +1 -0
  441. package/dist/es/components/Message/hooks/useOpenThreadHandler.mjs +25 -0
  442. package/dist/es/components/Message/hooks/useOpenThreadHandler.mjs.map +1 -0
  443. package/dist/es/components/Message/hooks/usePinHandler.mjs +50 -0
  444. package/dist/es/components/Message/hooks/usePinHandler.mjs.map +1 -0
  445. package/dist/es/components/Message/hooks/useReactionHandler.mjs +98 -0
  446. package/dist/es/components/Message/hooks/useReactionHandler.mjs.map +1 -0
  447. package/dist/es/components/Message/hooks/useReactionsFetcher.mjs +31 -0
  448. package/dist/es/components/Message/hooks/useReactionsFetcher.mjs.map +1 -0
  449. package/dist/es/components/Message/hooks/useRetryHandler.mjs +15 -0
  450. package/dist/es/components/Message/hooks/useRetryHandler.mjs.map +1 -0
  451. package/dist/es/components/Message/hooks/useUserHandler.mjs +15 -0
  452. package/dist/es/components/Message/hooks/useUserHandler.mjs.map +1 -0
  453. package/dist/es/components/Message/hooks/useUserRole.mjs +51 -0
  454. package/dist/es/components/Message/hooks/useUserRole.mjs.map +1 -0
  455. package/dist/es/components/Message/renderText/componentRenderers/Anchor.mjs +20 -0
  456. package/dist/es/components/Message/renderText/componentRenderers/Anchor.mjs.map +1 -0
  457. package/dist/es/components/Message/renderText/componentRenderers/Emoji.mjs +12 -0
  458. package/dist/es/components/Message/renderText/componentRenderers/Emoji.mjs.map +1 -0
  459. package/dist/es/components/Message/renderText/componentRenderers/Mention.mjs +14 -0
  460. package/dist/es/components/Message/renderText/componentRenderers/Mention.mjs.map +1 -0
  461. package/dist/es/components/Message/renderText/regex.mjs +22 -0
  462. package/dist/es/components/Message/renderText/regex.mjs.map +1 -0
  463. package/dist/es/components/Message/renderText/rehypePlugins/emojiMarkdownPlugin.mjs +16 -0
  464. package/dist/es/components/Message/renderText/rehypePlugins/emojiMarkdownPlugin.mjs.map +1 -0
  465. package/dist/es/components/Message/renderText/rehypePlugins/mentionsMarkdownPlugin.mjs +111 -0
  466. package/dist/es/components/Message/renderText/rehypePlugins/mentionsMarkdownPlugin.mjs.map +1 -0
  467. package/dist/es/components/Message/renderText/remarkPlugins/htmlToTextPlugin.mjs +14 -0
  468. package/dist/es/components/Message/renderText/remarkPlugins/htmlToTextPlugin.mjs.map +1 -0
  469. package/dist/es/components/Message/renderText/remarkPlugins/imageToLink.mjs +33 -0
  470. package/dist/es/components/Message/renderText/remarkPlugins/imageToLink.mjs.map +1 -0
  471. package/dist/es/components/Message/renderText/remarkPlugins/keepLineBreaksPlugin.mjs +44 -0
  472. package/dist/es/components/Message/renderText/remarkPlugins/keepLineBreaksPlugin.mjs.map +1 -0
  473. package/dist/es/components/Message/renderText/remarkPlugins/plusPlusToEmphasis.mjs +68 -0
  474. package/dist/es/components/Message/renderText/remarkPlugins/plusPlusToEmphasis.mjs.map +1 -0
  475. package/dist/es/components/Message/renderText/remarkPlugins/remarkIgnoreMarkdown.mjs +19 -0
  476. package/dist/es/components/Message/renderText/remarkPlugins/remarkIgnoreMarkdown.mjs.map +1 -0
  477. package/dist/es/components/Message/renderText/renderText.mjs +131 -0
  478. package/dist/es/components/Message/renderText/renderText.mjs.map +1 -0
  479. package/dist/es/components/Message/utils.mjs +114 -0
  480. package/dist/es/components/Message/utils.mjs.map +1 -0
  481. package/dist/es/components/MessageActions/DeleteMessageAlert.mjs +43 -0
  482. package/dist/es/components/MessageActions/DeleteMessageAlert.mjs.map +1 -0
  483. package/dist/es/components/MessageActions/DownloadSubmenu.mjs +52 -0
  484. package/dist/es/components/MessageActions/DownloadSubmenu.mjs.map +1 -0
  485. package/dist/es/components/MessageActions/MessageActions.defaults.mjs +643 -0
  486. package/dist/es/components/MessageActions/MessageActions.defaults.mjs.map +1 -0
  487. package/dist/es/components/MessageActions/MessageActions.mjs +61 -0
  488. package/dist/es/components/MessageActions/MessageActions.mjs.map +1 -0
  489. package/dist/es/components/MessageActions/QuickMessageActionButton.mjs +20 -0
  490. package/dist/es/components/MessageActions/QuickMessageActionButton.mjs.map +1 -0
  491. package/dist/es/components/MessageActions/RemindMeSubmenu.mjs +71 -0
  492. package/dist/es/components/MessageActions/RemindMeSubmenu.mjs.map +1 -0
  493. package/dist/es/components/MessageActions/downloadUtils.mjs +65 -0
  494. package/dist/es/components/MessageActions/downloadUtils.mjs.map +1 -0
  495. package/dist/es/components/MessageActions/hooks/useBaseMessageActionSetFilter.mjs +67 -0
  496. package/dist/es/components/MessageActions/hooks/useBaseMessageActionSetFilter.mjs.map +1 -0
  497. package/dist/es/components/MessageBounce/MessageBounceModal.mjs +18 -0
  498. package/dist/es/components/MessageBounce/MessageBounceModal.mjs.map +1 -0
  499. package/dist/es/components/MessageBounce/MessageBouncePrompt.mjs +67 -0
  500. package/dist/es/components/MessageBounce/MessageBouncePrompt.mjs.map +1 -0
  501. package/dist/es/components/MessageComposer/AttachmentPreviewList/AttachmentPreviewList.mjs +91 -0
  502. package/dist/es/components/MessageComposer/AttachmentPreviewList/AttachmentPreviewList.mjs.map +1 -0
  503. package/dist/es/components/MessageComposer/AttachmentPreviewList/AudioAttachmentPreview.mjs +131 -0
  504. package/dist/es/components/MessageComposer/AttachmentPreviewList/AudioAttachmentPreview.mjs.map +1 -0
  505. package/dist/es/components/MessageComposer/AttachmentPreviewList/FileAttachmentPreview.mjs +82 -0
  506. package/dist/es/components/MessageComposer/AttachmentPreviewList/FileAttachmentPreview.mjs.map +1 -0
  507. package/dist/es/components/MessageComposer/AttachmentPreviewList/GeolocationPreview.mjs +53 -0
  508. package/dist/es/components/MessageComposer/AttachmentPreviewList/GeolocationPreview.mjs.map +1 -0
  509. package/dist/es/components/MessageComposer/AttachmentPreviewList/MediaAttachmentPreview.mjs +96 -0
  510. package/dist/es/components/MessageComposer/AttachmentPreviewList/MediaAttachmentPreview.mjs.map +1 -0
  511. package/dist/es/components/MessageComposer/AttachmentPreviewList/UnsupportedAttachmentPreview.mjs +36 -0
  512. package/dist/es/components/MessageComposer/AttachmentPreviewList/UnsupportedAttachmentPreview.mjs.map +1 -0
  513. package/dist/es/components/MessageComposer/AttachmentPreviewList/VoiceRecordingPreviewSlot.mjs +29 -0
  514. package/dist/es/components/MessageComposer/AttachmentPreviewList/VoiceRecordingPreviewSlot.mjs.map +1 -0
  515. package/dist/es/components/MessageComposer/AttachmentPreviewList/utils/AttachmentPreviewRoot.mjs +53 -0
  516. package/dist/es/components/MessageComposer/AttachmentPreviewList/utils/AttachmentPreviewRoot.mjs.map +1 -0
  517. package/dist/es/components/MessageComposer/AttachmentSelector/AttachmentSelector.mjs +311 -0
  518. package/dist/es/components/MessageComposer/AttachmentSelector/AttachmentSelector.mjs.map +1 -0
  519. package/dist/es/components/MessageComposer/AttachmentSelector/CommandsMenu.mjs +99 -0
  520. package/dist/es/components/MessageComposer/AttachmentSelector/CommandsMenu.mjs.map +1 -0
  521. package/dist/es/components/MessageComposer/CommandChip.mjs +37 -0
  522. package/dist/es/components/MessageComposer/CommandChip.mjs.map +1 -0
  523. package/dist/es/components/MessageComposer/CooldownTimer.mjs +15 -0
  524. package/dist/es/components/MessageComposer/CooldownTimer.mjs.map +1 -0
  525. package/dist/es/components/MessageComposer/EditedMessagePreview.mjs +17 -0
  526. package/dist/es/components/MessageComposer/EditedMessagePreview.mjs.map +1 -0
  527. package/dist/es/components/MessageComposer/LinkPreviewList.mjs +78 -0
  528. package/dist/es/components/MessageComposer/LinkPreviewList.mjs.map +1 -0
  529. package/dist/es/components/MessageComposer/MessageComposer.mjs +61 -0
  530. package/dist/es/components/MessageComposer/MessageComposer.mjs.map +1 -0
  531. package/dist/es/components/MessageComposer/MessageComposerActions.mjs +75 -0
  532. package/dist/es/components/MessageComposer/MessageComposerActions.mjs.map +1 -0
  533. package/dist/es/components/MessageComposer/MessageComposerUI.mjs +100 -0
  534. package/dist/es/components/MessageComposer/MessageComposerUI.mjs.map +1 -0
  535. package/dist/es/components/MessageComposer/QuotedMessageIndicator.mjs +9 -0
  536. package/dist/es/components/MessageComposer/QuotedMessageIndicator.mjs.map +1 -0
  537. package/dist/es/components/MessageComposer/QuotedMessagePreview.mjs +325 -0
  538. package/dist/es/components/MessageComposer/QuotedMessagePreview.mjs.map +1 -0
  539. package/dist/es/components/MessageComposer/RemoveAttachmentPreviewButton.mjs +25 -0
  540. package/dist/es/components/MessageComposer/RemoveAttachmentPreviewButton.mjs.map +1 -0
  541. package/dist/es/components/MessageComposer/SendButton.mjs +29 -0
  542. package/dist/es/components/MessageComposer/SendButton.mjs.map +1 -0
  543. package/dist/es/components/MessageComposer/SendToChannelCheckbox.mjs +51 -0
  544. package/dist/es/components/MessageComposer/SendToChannelCheckbox.mjs.map +1 -0
  545. package/dist/es/components/MessageComposer/StopAIGenerationButton.mjs +18 -0
  546. package/dist/es/components/MessageComposer/StopAIGenerationButton.mjs.map +1 -0
  547. package/dist/es/components/MessageComposer/WithDragAndDropUpload.mjs +105 -0
  548. package/dist/es/components/MessageComposer/WithDragAndDropUpload.mjs.map +1 -0
  549. package/dist/es/components/MessageComposer/hooks/useAttachmentManagerState.mjs +37 -0
  550. package/dist/es/components/MessageComposer/hooks/useAttachmentManagerState.mjs.map +1 -0
  551. package/dist/es/components/MessageComposer/hooks/useAttachmentsForPreview.mjs +21 -0
  552. package/dist/es/components/MessageComposer/hooks/useAttachmentsForPreview.mjs.map +1 -0
  553. package/dist/es/components/MessageComposer/hooks/useCanCreatePoll.mjs +15 -0
  554. package/dist/es/components/MessageComposer/hooks/useCanCreatePoll.mjs.map +1 -0
  555. package/dist/es/components/MessageComposer/hooks/useCooldownRemaining.mjs +18 -0
  556. package/dist/es/components/MessageComposer/hooks/useCooldownRemaining.mjs.map +1 -0
  557. package/dist/es/components/MessageComposer/hooks/useCreateMessageComposerContext.mjs +33 -0
  558. package/dist/es/components/MessageComposer/hooks/useCreateMessageComposerContext.mjs.map +1 -0
  559. package/dist/es/components/MessageComposer/hooks/useIsCooldownActive.mjs +11 -0
  560. package/dist/es/components/MessageComposer/hooks/useIsCooldownActive.mjs.map +1 -0
  561. package/dist/es/components/MessageComposer/hooks/useMessageComposerBindings.mjs +23 -0
  562. package/dist/es/components/MessageComposer/hooks/useMessageComposerBindings.mjs.map +1 -0
  563. package/dist/es/components/MessageComposer/hooks/useMessageComposerCommands.mjs +27 -0
  564. package/dist/es/components/MessageComposer/hooks/useMessageComposerCommands.mjs.map +1 -0
  565. package/dist/es/components/MessageComposer/hooks/useMessageComposerController.mjs +30 -0
  566. package/dist/es/components/MessageComposer/hooks/useMessageComposerController.mjs.map +1 -0
  567. package/dist/es/components/MessageComposer/hooks/useMessageComposerHasSendableData.mjs +13 -0
  568. package/dist/es/components/MessageComposer/hooks/useMessageComposerHasSendableData.mjs.map +1 -0
  569. package/dist/es/components/MessageComposer/hooks/useMessageComposerSubmitFn.mjs +16 -0
  570. package/dist/es/components/MessageComposer/hooks/useMessageComposerSubmitFn.mjs.map +1 -0
  571. package/dist/es/components/MessageComposer/hooks/useMessageContentIsEmpty.mjs +13 -0
  572. package/dist/es/components/MessageComposer/hooks/useMessageContentIsEmpty.mjs.map +1 -0
  573. package/dist/es/components/MessageComposer/hooks/usePasteHandler.mjs +34 -0
  574. package/dist/es/components/MessageComposer/hooks/usePasteHandler.mjs.map +1 -0
  575. package/dist/es/components/MessageComposer/hooks/useTextareaRef.mjs +14 -0
  576. package/dist/es/components/MessageComposer/hooks/useTextareaRef.mjs.map +1 -0
  577. package/dist/es/components/MessageComposer/hooks/utils.mjs +16 -0
  578. package/dist/es/components/MessageComposer/hooks/utils.mjs.map +1 -0
  579. package/dist/es/components/MessageComposer/icons.mjs +62 -0
  580. package/dist/es/components/MessageComposer/icons.mjs.map +1 -0
  581. package/dist/es/components/MessageComposer/preEditSnapshot.mjs +39 -0
  582. package/dist/es/components/MessageComposer/preEditSnapshot.mjs.map +1 -0
  583. package/dist/es/components/MessageList/FloatingDateSeparator.mjs +46 -0
  584. package/dist/es/components/MessageList/FloatingDateSeparator.mjs.map +1 -0
  585. package/dist/es/components/MessageList/GiphyPreviewMessage.mjs +15 -0
  586. package/dist/es/components/MessageList/GiphyPreviewMessage.mjs.map +1 -0
  587. package/dist/es/components/MessageList/MessageList.mjs +284 -0
  588. package/dist/es/components/MessageList/MessageList.mjs.map +1 -0
  589. package/dist/es/components/MessageList/MessageListMainPanel.mjs +12 -0
  590. package/dist/es/components/MessageList/MessageListMainPanel.mjs.map +1 -0
  591. package/dist/es/components/MessageList/NewMessageNotification.mjs +36 -0
  592. package/dist/es/components/MessageList/NewMessageNotification.mjs.map +1 -0
  593. package/dist/es/components/MessageList/ScrollToLatestMessageButton.mjs +83 -0
  594. package/dist/es/components/MessageList/ScrollToLatestMessageButton.mjs.map +1 -0
  595. package/dist/es/components/MessageList/UnreadMessagesNotification.mjs +49 -0
  596. package/dist/es/components/MessageList/UnreadMessagesNotification.mjs.map +1 -0
  597. package/dist/es/components/MessageList/UnreadMessagesSeparator.mjs +44 -0
  598. package/dist/es/components/MessageList/UnreadMessagesSeparator.mjs.map +1 -0
  599. package/dist/es/components/MessageList/VirtualizedMessageList.mjs +358 -0
  600. package/dist/es/components/MessageList/VirtualizedMessageList.mjs.map +1 -0
  601. package/dist/es/components/MessageList/VirtualizedMessageListComponents.mjs +93 -0
  602. package/dist/es/components/MessageList/VirtualizedMessageListComponents.mjs.map +1 -0
  603. package/dist/es/components/MessageList/hooks/MessageList/useEnrichedMessages.mjs +38 -0
  604. package/dist/es/components/MessageList/hooks/MessageList/useEnrichedMessages.mjs.map +1 -0
  605. package/dist/es/components/MessageList/hooks/MessageList/useFloatingDateSeparatorMessageList.mjs +74 -0
  606. package/dist/es/components/MessageList/hooks/MessageList/useFloatingDateSeparatorMessageList.mjs.map +1 -0
  607. package/dist/es/components/MessageList/hooks/MessageList/useMessageListElements.mjs +66 -0
  608. package/dist/es/components/MessageList/hooks/MessageList/useMessageListElements.mjs.map +1 -0
  609. package/dist/es/components/MessageList/hooks/MessageList/useMessageListScrollManager.mjs +143 -0
  610. package/dist/es/components/MessageList/hooks/MessageList/useMessageListScrollManager.mjs.map +1 -0
  611. package/dist/es/components/MessageList/hooks/MessageList/useScrollLocationLogic.mjs +100 -0
  612. package/dist/es/components/MessageList/hooks/MessageList/useScrollLocationLogic.mjs.map +1 -0
  613. package/dist/es/components/MessageList/hooks/MessageList/useUnreadMessagesNotification.mjs +86 -0
  614. package/dist/es/components/MessageList/hooks/MessageList/useUnreadMessagesNotification.mjs.map +1 -0
  615. package/dist/es/components/MessageList/hooks/VirtualizedMessageList/useFloatingDateSeparator.mjs +70 -0
  616. package/dist/es/components/MessageList/hooks/VirtualizedMessageList/useFloatingDateSeparator.mjs.map +1 -0
  617. package/dist/es/components/MessageList/hooks/VirtualizedMessageList/useGiphyPreview.mjs +24 -0
  618. package/dist/es/components/MessageList/hooks/VirtualizedMessageList/useGiphyPreview.mjs.map +1 -0
  619. package/dist/es/components/MessageList/hooks/VirtualizedMessageList/useMessageSetKey.mjs +18 -0
  620. package/dist/es/components/MessageList/hooks/VirtualizedMessageList/useMessageSetKey.mjs.map +1 -0
  621. package/dist/es/components/MessageList/hooks/VirtualizedMessageList/useNewMessageNotification.mjs +45 -0
  622. package/dist/es/components/MessageList/hooks/VirtualizedMessageList/useNewMessageNotification.mjs.map +1 -0
  623. package/dist/es/components/MessageList/hooks/VirtualizedMessageList/usePrependMessagesCount.mjs +41 -0
  624. package/dist/es/components/MessageList/hooks/VirtualizedMessageList/usePrependMessagesCount.mjs.map +1 -0
  625. package/dist/es/components/MessageList/hooks/VirtualizedMessageList/useScrollToBottomOnNewMessage.mjs +33 -0
  626. package/dist/es/components/MessageList/hooks/VirtualizedMessageList/useScrollToBottomOnNewMessage.mjs.map +1 -0
  627. package/dist/es/components/MessageList/hooks/VirtualizedMessageList/useShouldForceScrollToBottom.mjs +27 -0
  628. package/dist/es/components/MessageList/hooks/VirtualizedMessageList/useShouldForceScrollToBottom.mjs.map +1 -0
  629. package/dist/es/components/MessageList/hooks/VirtualizedMessageList/useUnreadMessagesNotificationVirtualized.mjs +48 -0
  630. package/dist/es/components/MessageList/hooks/VirtualizedMessageList/useUnreadMessagesNotificationVirtualized.mjs.map +1 -0
  631. package/dist/es/components/MessageList/hooks/useCanPaginateReplies.mjs +47 -0
  632. package/dist/es/components/MessageList/hooks/useCanPaginateReplies.mjs.map +1 -0
  633. package/dist/es/components/MessageList/hooks/useLastDeliveredData.mjs +11 -0
  634. package/dist/es/components/MessageList/hooks/useLastDeliveredData.mjs.map +1 -0
  635. package/dist/es/components/MessageList/hooks/useLastOwnMessage.mjs +8 -0
  636. package/dist/es/components/MessageList/hooks/useLastOwnMessage.mjs.map +1 -0
  637. package/dist/es/components/MessageList/hooks/useLastReadData.mjs +11 -0
  638. package/dist/es/components/MessageList/hooks/useLastReadData.mjs.map +1 -0
  639. package/dist/es/components/MessageList/hooks/useMarkRead.mjs +105 -0
  640. package/dist/es/components/MessageList/hooks/useMarkRead.mjs.map +1 -0
  641. package/dist/es/components/MessageList/hooks/useReceiptsByMessageId.mjs +71 -0
  642. package/dist/es/components/MessageList/hooks/useReceiptsByMessageId.mjs.map +1 -0
  643. package/dist/es/components/MessageList/hooks/useThreadHead.mjs +26 -0
  644. package/dist/es/components/MessageList/hooks/useThreadHead.mjs.map +1 -0
  645. package/dist/es/components/MessageList/messageSourceKey.mjs +37 -0
  646. package/dist/es/components/MessageList/messageSourceKey.mjs.map +1 -0
  647. package/dist/es/components/MessageList/renderMessages.mjs +76 -0
  648. package/dist/es/components/MessageList/renderMessages.mjs.map +1 -0
  649. package/dist/es/components/MessageList/utils.mjs +162 -0
  650. package/dist/es/components/MessageList/utils.mjs.map +1 -0
  651. package/dist/es/components/Modal/GlobalModal.mjs +157 -0
  652. package/dist/es/components/Modal/GlobalModal.mjs.map +1 -0
  653. package/dist/es/components/Notifications/Notification.mjs +92 -0
  654. package/dist/es/components/Notifications/Notification.mjs.map +1 -0
  655. package/dist/es/components/Notifications/NotificationConfigurationContext.mjs +19 -0
  656. package/dist/es/components/Notifications/NotificationConfigurationContext.mjs.map +1 -0
  657. package/dist/es/components/Notifications/NotificationList.mjs +300 -0
  658. package/dist/es/components/Notifications/NotificationList.mjs.map +1 -0
  659. package/dist/es/components/Notifications/hooks/useNotificationApi.mjs +114 -0
  660. package/dist/es/components/Notifications/hooks/useNotificationApi.mjs.map +1 -0
  661. package/dist/es/components/Notifications/hooks/useNotificationTarget.mjs +21 -0
  662. package/dist/es/components/Notifications/hooks/useNotificationTarget.mjs.map +1 -0
  663. package/dist/es/components/Notifications/hooks/useNotifications.mjs +39 -0
  664. package/dist/es/components/Notifications/hooks/useNotifications.mjs.map +1 -0
  665. package/dist/es/components/Notifications/hooks/useSystemNotifications.mjs +22 -0
  666. package/dist/es/components/Notifications/hooks/useSystemNotifications.mjs.map +1 -0
  667. package/dist/es/components/Notifications/notificationTarget.mjs +53 -0
  668. package/dist/es/components/Notifications/notificationTarget.mjs.map +1 -0
  669. package/dist/es/components/Poll/Poll.mjs +18 -0
  670. package/dist/es/components/Poll/Poll.mjs.map +1 -0
  671. package/dist/es/components/Poll/PollActions/AddCommentPrompt.mjs +79 -0
  672. package/dist/es/components/Poll/PollActions/AddCommentPrompt.mjs.map +1 -0
  673. package/dist/es/components/Poll/PollActions/EndPollAlert.mjs +61 -0
  674. package/dist/es/components/Poll/PollActions/EndPollAlert.mjs.map +1 -0
  675. package/dist/es/components/Poll/PollActions/PollAction.mjs +27 -0
  676. package/dist/es/components/Poll/PollActions/PollAction.mjs.map +1 -0
  677. package/dist/es/components/Poll/PollActions/PollActions.mjs +98 -0
  678. package/dist/es/components/Poll/PollActions/PollActions.mjs.map +1 -0
  679. package/dist/es/components/Poll/PollActions/PollAnswerList.mjs +70 -0
  680. package/dist/es/components/Poll/PollActions/PollAnswerList.mjs.map +1 -0
  681. package/dist/es/components/Poll/PollActions/PollOptionsFullList.mjs +32 -0
  682. package/dist/es/components/Poll/PollActions/PollOptionsFullList.mjs.map +1 -0
  683. package/dist/es/components/Poll/PollActions/PollQuestion.mjs +20 -0
  684. package/dist/es/components/Poll/PollActions/PollQuestion.mjs.map +1 -0
  685. package/dist/es/components/Poll/PollActions/PollResults/PollOptionWithVotes.mjs +51 -0
  686. package/dist/es/components/Poll/PollActions/PollResults/PollOptionWithVotes.mjs.map +1 -0
  687. package/dist/es/components/Poll/PollActions/PollResults/PollOptionWithVotesHeader.mjs +48 -0
  688. package/dist/es/components/Poll/PollActions/PollResults/PollOptionWithVotesHeader.mjs.map +1 -0
  689. package/dist/es/components/Poll/PollActions/PollResults/PollOptionWithVotesList.mjs +39 -0
  690. package/dist/es/components/Poll/PollActions/PollResults/PollOptionWithVotesList.mjs.map +1 -0
  691. package/dist/es/components/Poll/PollActions/PollResults/PollResults.mjs +79 -0
  692. package/dist/es/components/Poll/PollActions/PollResults/PollResults.mjs.map +1 -0
  693. package/dist/es/components/Poll/PollActions/SuggestPollOptionPrompt.mjs +82 -0
  694. package/dist/es/components/Poll/PollActions/SuggestPollOptionPrompt.mjs.map +1 -0
  695. package/dist/es/components/Poll/PollContent.mjs +28 -0
  696. package/dist/es/components/Poll/PollContent.mjs.map +1 -0
  697. package/dist/es/components/Poll/PollCreationDialog/MultipleAnswersField.mjs +86 -0
  698. package/dist/es/components/Poll/PollCreationDialog/MultipleAnswersField.mjs.map +1 -0
  699. package/dist/es/components/Poll/PollCreationDialog/NameField.mjs +42 -0
  700. package/dist/es/components/Poll/PollCreationDialog/NameField.mjs.map +1 -0
  701. package/dist/es/components/Poll/PollCreationDialog/OptionFieldSet.mjs +194 -0
  702. package/dist/es/components/Poll/PollCreationDialog/OptionFieldSet.mjs.map +1 -0
  703. package/dist/es/components/Poll/PollCreationDialog/PollCreationDialog.mjs +77 -0
  704. package/dist/es/components/Poll/PollCreationDialog/PollCreationDialog.mjs.map +1 -0
  705. package/dist/es/components/Poll/PollCreationDialog/PollCreationDialogControls.mjs +53 -0
  706. package/dist/es/components/Poll/PollCreationDialog/PollCreationDialogControls.mjs.map +1 -0
  707. package/dist/es/components/Poll/PollCreationDialog/PollOptionReorderHandle.mjs +79 -0
  708. package/dist/es/components/Poll/PollCreationDialog/PollOptionReorderHandle.mjs.map +1 -0
  709. package/dist/es/components/Poll/PollHeader.mjs +50 -0
  710. package/dist/es/components/Poll/PollHeader.mjs.map +1 -0
  711. package/dist/es/components/Poll/PollOptionList.mjs +45 -0
  712. package/dist/es/components/Poll/PollOptionList.mjs.map +1 -0
  713. package/dist/es/components/Poll/PollOptionSelector.mjs +105 -0
  714. package/dist/es/components/Poll/PollOptionSelector.mjs.map +1 -0
  715. package/dist/es/components/Poll/PollVote.mjs +60 -0
  716. package/dist/es/components/Poll/PollVote.mjs.map +1 -0
  717. package/dist/es/components/Poll/hooks/useManagePollVotesRealtime.mjs +36 -0
  718. package/dist/es/components/Poll/hooks/useManagePollVotesRealtime.mjs.map +1 -0
  719. package/dist/es/components/Poll/hooks/usePollAnswerPagination.mjs +44 -0
  720. package/dist/es/components/Poll/hooks/usePollAnswerPagination.mjs.map +1 -0
  721. package/dist/es/components/Poll/hooks/usePollOptionVotesPagination.mjs +45 -0
  722. package/dist/es/components/Poll/hooks/usePollOptionVotesPagination.mjs.map +1 -0
  723. package/dist/es/components/Portal/Portal.mjs +17 -0
  724. package/dist/es/components/Portal/Portal.mjs.map +1 -0
  725. package/dist/es/components/ReactFileUtilities/UploadButton.mjs +54 -0
  726. package/dist/es/components/ReactFileUtilities/UploadButton.mjs.map +1 -0
  727. package/dist/es/{audioProcessing.766ca76c.mjs → components/ReactFileUtilities/utils.mjs} +2 -32
  728. package/dist/es/components/ReactFileUtilities/utils.mjs.map +1 -0
  729. package/dist/es/components/Reactions/MessageReactions.mjs +150 -0
  730. package/dist/es/components/Reactions/MessageReactions.mjs.map +1 -0
  731. package/dist/es/components/Reactions/MessageReactionsDetail.mjs +157 -0
  732. package/dist/es/components/Reactions/MessageReactionsDetail.mjs.map +1 -0
  733. package/dist/es/components/Reactions/ReactionSelector.mjs +134 -0
  734. package/dist/es/components/Reactions/ReactionSelector.mjs.map +1 -0
  735. package/dist/es/components/Reactions/ReactionSelectorWithButton.mjs +51 -0
  736. package/dist/es/components/Reactions/ReactionSelectorWithButton.mjs.map +1 -0
  737. package/dist/es/components/Reactions/SpriteImage.mjs +34 -0
  738. package/dist/es/components/Reactions/SpriteImage.mjs.map +1 -0
  739. package/dist/es/components/Reactions/hooks/useFetchReactions.mjs +61 -0
  740. package/dist/es/components/Reactions/hooks/useFetchReactions.mjs.map +1 -0
  741. package/dist/es/components/Reactions/hooks/useProcessReactions.mjs +83 -0
  742. package/dist/es/components/Reactions/hooks/useProcessReactions.mjs.map +1 -0
  743. package/dist/es/components/Reactions/reactionOptions.mjs +79 -0
  744. package/dist/es/components/Reactions/reactionOptions.mjs.map +1 -0
  745. package/dist/es/components/Reactions/utils/utils.mjs +13 -0
  746. package/dist/es/components/Reactions/utils/utils.mjs.map +1 -0
  747. package/dist/es/components/SafeAnchor/SafeAnchor.mjs +21 -0
  748. package/dist/es/components/SafeAnchor/SafeAnchor.mjs.map +1 -0
  749. package/dist/es/components/Search/Search.mjs +40 -0
  750. package/dist/es/components/Search/Search.mjs.map +1 -0
  751. package/dist/es/components/Search/SearchBar/SearchBar.mjs +114 -0
  752. package/dist/es/components/Search/SearchBar/SearchBar.mjs.map +1 -0
  753. package/dist/es/components/Search/SearchContext.mjs +17 -0
  754. package/dist/es/components/Search/SearchContext.mjs.map +1 -0
  755. package/dist/es/components/Search/SearchResults/SearchResultItem.mjs +130 -0
  756. package/dist/es/components/Search/SearchResults/SearchResultItem.mjs.map +1 -0
  757. package/dist/es/components/Search/SearchResults/SearchResults.mjs +37 -0
  758. package/dist/es/components/Search/SearchResults/SearchResults.mjs.map +1 -0
  759. package/dist/es/components/Search/SearchResults/SearchResultsHeader.mjs +55 -0
  760. package/dist/es/components/Search/SearchResults/SearchResultsHeader.mjs.map +1 -0
  761. package/dist/es/components/Search/SearchResults/SearchResultsPresearch.mjs +15 -0
  762. package/dist/es/components/Search/SearchResults/SearchResultsPresearch.mjs.map +1 -0
  763. package/dist/es/components/Search/SearchResults/SearchSourceResultList.mjs +31 -0
  764. package/dist/es/components/Search/SearchResults/SearchSourceResultList.mjs.map +1 -0
  765. package/dist/es/components/Search/SearchResults/SearchSourceResultListFooter.mjs +31 -0
  766. package/dist/es/components/Search/SearchResults/SearchSourceResultListFooter.mjs.map +1 -0
  767. package/dist/es/components/Search/SearchResults/SearchSourceResults.mjs +30 -0
  768. package/dist/es/components/Search/SearchResults/SearchSourceResults.mjs.map +1 -0
  769. package/dist/es/components/Search/SearchResults/SearchSourceResultsEmpty.mjs +15 -0
  770. package/dist/es/components/Search/SearchResults/SearchSourceResultsEmpty.mjs.map +1 -0
  771. package/dist/es/components/Search/SearchResults/SearchSourceResultsHeader.mjs +6 -0
  772. package/dist/es/components/Search/SearchResults/SearchSourceResultsHeader.mjs.map +1 -0
  773. package/dist/es/components/Search/SearchResults/SearchSourceResultsLoadingIndicator.mjs +18 -0
  774. package/dist/es/components/Search/SearchResults/SearchSourceResultsLoadingIndicator.mjs.map +1 -0
  775. package/dist/es/components/Search/SearchSourceResultsContext.mjs +17 -0
  776. package/dist/es/components/Search/SearchSourceResultsContext.mjs.map +1 -0
  777. package/dist/es/components/Search/hooks/useAnnounceSearchResultCount.mjs +57 -0
  778. package/dist/es/components/Search/hooks/useAnnounceSearchResultCount.mjs.map +1 -0
  779. package/dist/es/components/Search/hooks/useSearchQueriesInProgress.mjs +24 -0
  780. package/dist/es/components/Search/hooks/useSearchQueriesInProgress.mjs.map +1 -0
  781. package/dist/es/components/Search/hooks/useSearchResultsKeyboardNavigation.mjs +28 -0
  782. package/dist/es/components/Search/hooks/useSearchResultsKeyboardNavigation.mjs.map +1 -0
  783. package/dist/es/components/SkipNavigation/SkipNavigation.mjs +64 -0
  784. package/dist/es/components/SkipNavigation/SkipNavigation.mjs.map +1 -0
  785. package/dist/es/components/SummarizedMessagePreview/SummarizedMessagePreview.mjs +55 -0
  786. package/dist/es/components/SummarizedMessagePreview/SummarizedMessagePreview.mjs.map +1 -0
  787. package/dist/es/components/SummarizedMessagePreview/hooks/useLatestMessagePreview.mjs +141 -0
  788. package/dist/es/components/SummarizedMessagePreview/hooks/useLatestMessagePreview.mjs.map +1 -0
  789. package/dist/es/components/TextareaComposer/SuggestionList/CommandItem.mjs +26 -0
  790. package/dist/es/components/TextareaComposer/SuggestionList/CommandItem.mjs.map +1 -0
  791. package/dist/es/components/TextareaComposer/SuggestionList/EmoticonItem.mjs +26 -0
  792. package/dist/es/components/TextareaComposer/SuggestionList/EmoticonItem.mjs.map +1 -0
  793. package/dist/es/components/TextareaComposer/SuggestionList/MentionItem/BroadcastMentionItem.mjs +32 -0
  794. package/dist/es/components/TextareaComposer/SuggestionList/MentionItem/BroadcastMentionItem.mjs.map +1 -0
  795. package/dist/es/components/TextareaComposer/SuggestionList/MentionItem/MentionItem.mjs +39 -0
  796. package/dist/es/components/TextareaComposer/SuggestionList/MentionItem/MentionItem.mjs.map +1 -0
  797. package/dist/es/components/TextareaComposer/SuggestionList/MentionItem/MentionSuggestionTitle.mjs +7 -0
  798. package/dist/es/components/TextareaComposer/SuggestionList/MentionItem/MentionSuggestionTitle.mjs.map +1 -0
  799. package/dist/es/components/TextareaComposer/SuggestionList/MentionItem/RoleItem.mjs +34 -0
  800. package/dist/es/components/TextareaComposer/SuggestionList/MentionItem/RoleItem.mjs.map +1 -0
  801. package/dist/es/components/TextareaComposer/SuggestionList/MentionItem/SpecialMentionItem.mjs +6 -0
  802. package/dist/es/components/TextareaComposer/SuggestionList/MentionItem/SpecialMentionItem.mjs.map +1 -0
  803. package/dist/es/components/TextareaComposer/SuggestionList/MentionItem/UserGroupItem.mjs +31 -0
  804. package/dist/es/components/TextareaComposer/SuggestionList/MentionItem/UserGroupItem.mjs.map +1 -0
  805. package/dist/es/components/TextareaComposer/SuggestionList/MentionItem/UserItem.mjs +50 -0
  806. package/dist/es/components/TextareaComposer/SuggestionList/MentionItem/UserItem.mjs.map +1 -0
  807. package/dist/es/components/TextareaComposer/SuggestionList/SuggestionList.mjs +198 -0
  808. package/dist/es/components/TextareaComposer/SuggestionList/SuggestionList.mjs.map +1 -0
  809. package/dist/es/components/TextareaComposer/SuggestionList/SuggestionListItem.mjs +46 -0
  810. package/dist/es/components/TextareaComposer/SuggestionList/SuggestionListItem.mjs.map +1 -0
  811. package/dist/es/components/TextareaComposer/SuggestionList/TokenizedSuggestionParts.mjs +30 -0
  812. package/dist/es/components/TextareaComposer/SuggestionList/TokenizedSuggestionParts.mjs.map +1 -0
  813. package/dist/es/components/TextareaComposer/TextareaComposer.mjs +290 -0
  814. package/dist/es/components/TextareaComposer/TextareaComposer.mjs.map +1 -0
  815. package/dist/es/components/TextareaComposer/hooks/useTextareaPlaceholder.mjs +31 -0
  816. package/dist/es/components/TextareaComposer/hooks/useTextareaPlaceholder.mjs.map +1 -0
  817. package/dist/es/components/Thread/Thread.mjs +103 -0
  818. package/dist/es/components/Thread/Thread.mjs.map +1 -0
  819. package/dist/es/components/Thread/ThreadHead.mjs +27 -0
  820. package/dist/es/components/Thread/ThreadHead.mjs.map +1 -0
  821. package/dist/es/components/Thread/ThreadHeader.mjs +78 -0
  822. package/dist/es/components/Thread/ThreadHeader.mjs.map +1 -0
  823. package/dist/es/components/Thread/ThreadStart.mjs +25 -0
  824. package/dist/es/components/Thread/ThreadStart.mjs.map +1 -0
  825. package/dist/es/components/Threads/ThreadContext.mjs +13 -0
  826. package/dist/es/components/Threads/ThreadContext.mjs.map +1 -0
  827. package/dist/es/components/Threads/ThreadList/ThreadList.mjs +112 -0
  828. package/dist/es/components/Threads/ThreadList/ThreadList.mjs.map +1 -0
  829. package/dist/es/components/Threads/ThreadList/ThreadListEmptyPlaceholder.mjs +17 -0
  830. package/dist/es/components/Threads/ThreadList/ThreadListEmptyPlaceholder.mjs.map +1 -0
  831. package/dist/es/components/Threads/ThreadList/ThreadListHeader.mjs +22 -0
  832. package/dist/es/components/Threads/ThreadList/ThreadListHeader.mjs.map +1 -0
  833. package/dist/es/components/Threads/ThreadList/ThreadListItem.mjs +18 -0
  834. package/dist/es/components/Threads/ThreadList/ThreadListItem.mjs.map +1 -0
  835. package/dist/es/components/Threads/ThreadList/ThreadListItemUI.mjs +160 -0
  836. package/dist/es/components/Threads/ThreadList/ThreadListItemUI.mjs.map +1 -0
  837. package/dist/es/components/Threads/ThreadList/ThreadListLoadingIndicator.mjs +22 -0
  838. package/dist/es/components/Threads/ThreadList/ThreadListLoadingIndicator.mjs.map +1 -0
  839. package/dist/es/components/Threads/ThreadList/ThreadListUnseenThreadsBanner.mjs +34 -0
  840. package/dist/es/components/Threads/ThreadList/ThreadListUnseenThreadsBanner.mjs.map +1 -0
  841. package/dist/es/components/Threads/ThreadList/useThreadHighlighting.mjs +47 -0
  842. package/dist/es/components/Threads/ThreadList/useThreadHighlighting.mjs.map +1 -0
  843. package/dist/es/components/Threads/ThreadList/utils.a11y.mjs +91 -0
  844. package/dist/es/components/Threads/ThreadList/utils.a11y.mjs.map +1 -0
  845. package/dist/es/components/Threads/UnreadCountBadge.mjs +16 -0
  846. package/dist/es/components/Threads/UnreadCountBadge.mjs.map +1 -0
  847. package/dist/es/components/Threads/hooks/useCloseThread.mjs +30 -0
  848. package/dist/es/components/Threads/hooks/useCloseThread.mjs.map +1 -0
  849. package/dist/es/components/Tooltip/Tooltip.mjs +39 -0
  850. package/dist/es/components/Tooltip/Tooltip.mjs.map +1 -0
  851. package/dist/es/components/Tooltip/hooks/useEnterLeaveHandlers.mjs +20 -0
  852. package/dist/es/components/Tooltip/hooks/useEnterLeaveHandlers.mjs.map +1 -0
  853. package/dist/es/components/TypingIndicator/TypingIndicator.mjs +85 -0
  854. package/dist/es/components/TypingIndicator/TypingIndicator.mjs.map +1 -0
  855. package/dist/es/components/TypingIndicator/TypingIndicatorDots.mjs +33 -0
  856. package/dist/es/components/TypingIndicator/TypingIndicatorDots.mjs.map +1 -0
  857. package/dist/es/components/TypingIndicator/TypingIndicatorHeader.mjs +48 -0
  858. package/dist/es/components/TypingIndicator/TypingIndicatorHeader.mjs.map +1 -0
  859. package/dist/es/components/TypingIndicator/hooks/useDebouncedTypingActive.mjs +53 -0
  860. package/dist/es/components/TypingIndicator/hooks/useDebouncedTypingActive.mjs.map +1 -0
  861. package/dist/es/components/TypingIndicator/utils/getTypingStatusMessage.mjs +19 -0
  862. package/dist/es/components/TypingIndicator/utils/getTypingStatusMessage.mjs.map +1 -0
  863. package/dist/es/components/UtilityComponents/ErrorBoundary.mjs +22 -0
  864. package/dist/es/components/UtilityComponents/ErrorBoundary.mjs.map +1 -0
  865. package/dist/es/components/UtilityComponents/hooks/useMutationObserver.mjs +45 -0
  866. package/dist/es/components/UtilityComponents/hooks/useMutationObserver.mjs.map +1 -0
  867. package/dist/es/components/UtilityComponents/useStableId.mjs +20 -0
  868. package/dist/es/components/UtilityComponents/useStableId.mjs.map +1 -0
  869. package/dist/es/{ReactPlayerWrapper.d2ae5941.mjs → components/VideoPlayer/ReactPlayerWrapper.mjs} +3 -3
  870. package/dist/es/components/VideoPlayer/ReactPlayerWrapper.mjs.map +1 -0
  871. package/dist/es/components/VideoPlayer/VideoPlayer.mjs +30 -0
  872. package/dist/es/components/VideoPlayer/VideoPlayer.mjs.map +1 -0
  873. package/dist/es/components/VideoPlayer/VideoThumbnail.mjs +35 -0
  874. package/dist/es/components/VideoPlayer/VideoThumbnail.mjs.map +1 -0
  875. package/dist/es/components/VisuallyHidden/VisuallyHidden.mjs +29 -0
  876. package/dist/es/components/VisuallyHidden/VisuallyHidden.mjs.map +1 -0
  877. package/dist/es/constants/messageTypes.mjs +9 -0
  878. package/dist/es/constants/messageTypes.mjs.map +1 -0
  879. package/dist/es/context/AttachmentContext.mjs +16 -0
  880. package/dist/es/context/AttachmentContext.mjs.map +1 -0
  881. package/dist/es/context/AttachmentSelectorContext.mjs +13 -0
  882. package/dist/es/context/AttachmentSelectorContext.mjs.map +1 -0
  883. package/dist/es/context/ChannelInstanceContext.mjs +17 -0
  884. package/dist/es/context/ChannelInstanceContext.mjs.map +1 -0
  885. package/dist/es/context/ChannelListContext.mjs +17 -0
  886. package/dist/es/context/ChannelListContext.mjs.map +1 -0
  887. package/dist/es/context/ChatContext.mjs +14 -0
  888. package/dist/es/context/ChatContext.mjs.map +1 -0
  889. package/dist/es/context/ComponentContext.mjs +13 -0
  890. package/dist/es/context/ComponentContext.mjs.map +1 -0
  891. package/dist/es/context/DialogManagerContext.mjs +119 -0
  892. package/dist/es/context/DialogManagerContext.mjs.map +1 -0
  893. package/dist/es/context/MessageBounceContext.mjs +51 -0
  894. package/dist/es/context/MessageBounceContext.mjs.map +1 -0
  895. package/dist/es/context/MessageComposerContext.mjs +19 -0
  896. package/dist/es/context/MessageComposerContext.mjs.map +1 -0
  897. package/dist/es/context/MessageComposerControllerContext.mjs +19 -0
  898. package/dist/es/context/MessageComposerControllerContext.mjs.map +1 -0
  899. package/dist/es/context/MessageContext.mjs +14 -0
  900. package/dist/es/context/MessageContext.mjs.map +1 -0
  901. package/dist/es/context/MessageListContext.mjs +17 -0
  902. package/dist/es/context/MessageListContext.mjs.map +1 -0
  903. package/dist/es/context/MessageTranslationViewContext.mjs +73 -0
  904. package/dist/es/context/MessageTranslationViewContext.mjs.map +1 -0
  905. package/dist/es/context/ModalContext.mjs +18 -0
  906. package/dist/es/context/ModalContext.mjs.map +1 -0
  907. package/dist/es/context/PollContext.mjs +14 -0
  908. package/dist/es/context/PollContext.mjs.map +1 -0
  909. package/dist/es/context/TranslationContext.mjs +17 -0
  910. package/dist/es/context/TranslationContext.mjs.map +1 -0
  911. package/dist/es/context/VirtualizedMessageListContext.mjs +17 -0
  912. package/dist/es/context/VirtualizedMessageListContext.mjs.map +1 -0
  913. package/dist/es/context/WithComponents.mjs +23 -0
  914. package/dist/es/context/WithComponents.mjs.map +1 -0
  915. package/dist/es/context/WorkspaceNavigationContext.mjs +45 -0
  916. package/dist/es/context/WorkspaceNavigationContext.mjs.map +1 -0
  917. package/dist/es/context/requireContext.mjs +17 -0
  918. package/dist/es/context/requireContext.mjs.map +1 -0
  919. package/dist/es/context/useChannel.mjs +14 -0
  920. package/dist/es/context/useChannel.mjs.map +1 -0
  921. package/dist/es/context/useComponentContextIcons.mjs +26 -0
  922. package/dist/es/context/useComponentContextIcons.mjs.map +1 -0
  923. package/dist/es/emojis.mjs +2 -229
  924. package/dist/es/hooks/useIsDmChannel.mjs +30 -0
  925. package/dist/es/hooks/useIsDmChannel.mjs.map +1 -0
  926. package/dist/es/hooks/useMessagePaginator.mjs +14 -0
  927. package/dist/es/hooks/useMessagePaginator.mjs.map +1 -0
  928. package/dist/es/i18n/Streami18n.mjs +62 -0
  929. package/dist/es/i18n/Streami18n.mjs.map +1 -0
  930. package/dist/es/i18n/TranslationBuilder/index.mjs +3 -0
  931. package/dist/es/i18n/TranslationBuilder/notifications/NotificationTranslationTopic.mjs +49 -0
  932. package/dist/es/i18n/TranslationBuilder/notifications/NotificationTranslationTopic.mjs.map +1 -0
  933. package/dist/es/i18n/TranslationBuilder/notifications/translators.mjs +36 -0
  934. package/dist/es/i18n/TranslationBuilder/notifications/translators.mjs.map +1 -0
  935. package/dist/es/i18n/TranslationBuilder/notifications/translatorsByNotificationType.mjs +51 -0
  936. package/dist/es/i18n/TranslationBuilder/notifications/translatorsByNotificationType.mjs.map +1 -0
  937. package/dist/es/i18n/runtimeDefaults.mjs +41 -0
  938. package/dist/es/i18n/runtimeDefaults.mjs.map +1 -0
  939. package/dist/es/i18n/useStreami18n.mjs +41 -0
  940. package/dist/es/i18n/useStreami18n.mjs.map +1 -0
  941. package/dist/es/i18n/utils.mjs +14 -0
  942. package/dist/es/i18n/utils.mjs.map +1 -0
  943. package/dist/es/index.mjs +318 -20870
  944. package/dist/es/mp3-encoder.mjs +1 -1
  945. package/dist/es/plugins/ChannelDetail/AvatarWithChannelDetail.mjs +40 -0
  946. package/dist/es/plugins/ChannelDetail/AvatarWithChannelDetail.mjs.map +1 -0
  947. package/dist/es/plugins/ChannelDetail/ChannelDetail.mjs +105 -0
  948. package/dist/es/plugins/ChannelDetail/ChannelDetail.mjs.map +1 -0
  949. package/dist/es/plugins/ChannelDetail/ChannelDetailContext.mjs +20 -0
  950. package/dist/es/plugins/ChannelDetail/ChannelDetailContext.mjs.map +1 -0
  951. package/dist/es/plugins/ChannelDetail/ChannelDetailEmptyList.mjs +14 -0
  952. package/dist/es/plugins/ChannelDetail/ChannelDetailEmptyList.mjs.map +1 -0
  953. package/dist/es/plugins/ChannelDetail/ChannelDetailListLoadingIndicator.mjs +20 -0
  954. package/dist/es/plugins/ChannelDetail/ChannelDetailListLoadingIndicator.mjs.map +1 -0
  955. package/dist/es/plugins/ChannelDetail/ChannelDetailNavButton.mjs +26 -0
  956. package/dist/es/plugins/ChannelDetail/ChannelDetailNavButton.mjs.map +1 -0
  957. package/dist/es/plugins/ChannelDetail/ChannelDetailSearchInput.mjs +35 -0
  958. package/dist/es/plugins/ChannelDetail/ChannelDetailSearchInput.mjs.map +1 -0
  959. package/dist/es/plugins/ChannelDetail/SectionNavigator/SectionNavigator.mjs +164 -0
  960. package/dist/es/plugins/ChannelDetail/SectionNavigator/SectionNavigator.mjs.map +1 -0
  961. package/dist/es/plugins/ChannelDetail/SectionNavigator/SectionNavigatorHeader.mjs +49 -0
  962. package/dist/es/plugins/ChannelDetail/SectionNavigator/SectionNavigatorHeader.mjs.map +1 -0
  963. package/dist/es/plugins/ChannelDetail/Views/ChannelFilesView/ChannelFilesEmptyList.mjs +25 -0
  964. package/dist/es/plugins/ChannelDetail/Views/ChannelFilesView/ChannelFilesEmptyList.mjs.map +1 -0
  965. package/dist/es/plugins/ChannelDetail/Views/ChannelFilesView/ChannelFilesView.mjs +131 -0
  966. package/dist/es/plugins/ChannelDetail/Views/ChannelFilesView/ChannelFilesView.mjs.map +1 -0
  967. package/dist/es/plugins/ChannelDetail/Views/ChannelFilesView/ChannelFilesView.utils.mjs +64 -0
  968. package/dist/es/plugins/ChannelDetail/Views/ChannelFilesView/ChannelFilesView.utils.mjs.map +1 -0
  969. package/dist/es/plugins/ChannelDetail/Views/ChannelFilesView/useChannelFilesSearch.mjs +47 -0
  970. package/dist/es/plugins/ChannelDetail/Views/ChannelFilesView/useChannelFilesSearch.mjs.map +1 -0
  971. package/dist/es/plugins/ChannelDetail/Views/ChannelManagementView/ChannelManagementActions.defaults.mjs +568 -0
  972. package/dist/es/plugins/ChannelDetail/Views/ChannelManagementView/ChannelManagementActions.defaults.mjs.map +1 -0
  973. package/dist/es/plugins/ChannelDetail/Views/ChannelManagementView/ChannelManagementView.mjs +324 -0
  974. package/dist/es/plugins/ChannelDetail/Views/ChannelManagementView/ChannelManagementView.mjs.map +1 -0
  975. package/dist/es/plugins/ChannelDetail/Views/ChannelMediaView/ChannelMediaEmptyList.mjs +25 -0
  976. package/dist/es/plugins/ChannelDetail/Views/ChannelMediaView/ChannelMediaEmptyList.mjs.map +1 -0
  977. package/dist/es/plugins/ChannelDetail/Views/ChannelMediaView/ChannelMediaView.mjs +215 -0
  978. package/dist/es/plugins/ChannelDetail/Views/ChannelMediaView/ChannelMediaView.mjs.map +1 -0
  979. package/dist/es/plugins/ChannelDetail/Views/ChannelMediaView/ChannelMediaView.utils.mjs +42 -0
  980. package/dist/es/plugins/ChannelDetail/Views/ChannelMediaView/ChannelMediaView.utils.mjs.map +1 -0
  981. package/dist/es/plugins/ChannelDetail/Views/ChannelMediaView/useChannelMediaSearch.mjs +47 -0
  982. package/dist/es/plugins/ChannelDetail/Views/ChannelMediaView/useChannelMediaSearch.mjs.map +1 -0
  983. package/dist/es/plugins/ChannelDetail/Views/ChannelMemberDetailView/ChannelMemberActions.defaults.mjs +454 -0
  984. package/dist/es/plugins/ChannelDetail/Views/ChannelMemberDetailView/ChannelMemberActions.defaults.mjs.map +1 -0
  985. package/dist/es/plugins/ChannelDetail/Views/ChannelMemberDetailView/ChannelMemberDetail.mjs +77 -0
  986. package/dist/es/plugins/ChannelDetail/Views/ChannelMemberDetailView/ChannelMemberDetail.mjs.map +1 -0
  987. package/dist/es/plugins/ChannelDetail/Views/ChannelMembersView/ChannelMembersAddView.mjs +190 -0
  988. package/dist/es/plugins/ChannelDetail/Views/ChannelMembersView/ChannelMembersAddView.mjs.map +1 -0
  989. package/dist/es/plugins/ChannelDetail/Views/ChannelMembersView/ChannelMembersBrowseView.mjs +111 -0
  990. package/dist/es/plugins/ChannelDetail/Views/ChannelMembersView/ChannelMembersBrowseView.mjs.map +1 -0
  991. package/dist/es/plugins/ChannelDetail/Views/ChannelMembersView/ChannelMembersHeaderActions.defaults.mjs +120 -0
  992. package/dist/es/plugins/ChannelDetail/Views/ChannelMembersView/ChannelMembersHeaderActions.defaults.mjs.map +1 -0
  993. package/dist/es/plugins/ChannelDetail/Views/ChannelMembersView/ChannelMembersView.mjs +95 -0
  994. package/dist/es/plugins/ChannelDetail/Views/ChannelMembersView/ChannelMembersView.mjs.map +1 -0
  995. package/dist/es/plugins/ChannelDetail/Views/ChannelMembersView/ChannelMembersView.utils.mjs +11 -0
  996. package/dist/es/plugins/ChannelDetail/Views/ChannelMembersView/ChannelMembersView.utils.mjs.map +1 -0
  997. package/dist/es/plugins/ChannelDetail/Views/ChannelMembersView/useChannelMemberCount.mjs +22 -0
  998. package/dist/es/plugins/ChannelDetail/Views/ChannelMembersView/useChannelMemberCount.mjs.map +1 -0
  999. package/dist/es/plugins/ChannelDetail/Views/ChannelMembersView/useChannelMemberIds.mjs +23 -0
  1000. package/dist/es/plugins/ChannelDetail/Views/ChannelMembersView/useChannelMemberIds.mjs.map +1 -0
  1001. package/dist/es/plugins/ChannelDetail/Views/ChannelMembersView/useChannelMembersSearch.mjs +52 -0
  1002. package/dist/es/plugins/ChannelDetail/Views/ChannelMembersView/useChannelMembersSearch.mjs.map +1 -0
  1003. package/dist/es/plugins/ChannelDetail/Views/PinnedMessagesView/PinnedMessagesEmptyList.mjs +25 -0
  1004. package/dist/es/plugins/ChannelDetail/Views/PinnedMessagesView/PinnedMessagesEmptyList.mjs.map +1 -0
  1005. package/dist/es/plugins/ChannelDetail/Views/PinnedMessagesView/PinnedMessagesView.mjs +143 -0
  1006. package/dist/es/plugins/ChannelDetail/Views/PinnedMessagesView/PinnedMessagesView.mjs.map +1 -0
  1007. package/dist/es/plugins/ChannelDetail/Views/PinnedMessagesView/usePinnedMessagesCount.mjs +16 -0
  1008. package/dist/es/plugins/ChannelDetail/Views/PinnedMessagesView/usePinnedMessagesCount.mjs.map +1 -0
  1009. package/dist/es/plugins/ChannelDetail/Views/PinnedMessagesView/usePinnedMessagesSearch.mjs +68 -0
  1010. package/dist/es/plugins/ChannelDetail/Views/PinnedMessagesView/usePinnedMessagesSearch.mjs.map +1 -0
  1011. package/dist/es/plugins/ChannelDetail/VirtualizedList/VirtualizedList.mjs +42 -0
  1012. package/dist/es/plugins/ChannelDetail/VirtualizedList/VirtualizedList.mjs.map +1 -0
  1013. package/dist/es/plugins/Emojis/EmojiPicker.mjs +96 -0
  1014. package/dist/es/plugins/Emojis/EmojiPicker.mjs.map +1 -0
  1015. package/dist/es/plugins/Emojis/Picker.mjs +23 -0
  1016. package/dist/es/plugins/Emojis/Picker.mjs.map +1 -0
  1017. package/dist/es/plugins/Emojis/middleware/textComposerEmojiMiddleware.mjs +127 -0
  1018. package/dist/es/plugins/Emojis/middleware/textComposerEmojiMiddleware.mjs.map +1 -0
  1019. package/dist/es/plugins/SlotGeometry/SlotGeometry.mjs +141 -0
  1020. package/dist/es/plugins/SlotGeometry/SlotGeometry.mjs.map +1 -0
  1021. package/dist/es/plugins/SlotLayout/ChannelSlot.mjs +30 -0
  1022. package/dist/es/plugins/SlotLayout/ChannelSlot.mjs.map +1 -0
  1023. package/dist/es/plugins/SlotLayout/ChatView.a11y.utility.mjs +13 -0
  1024. package/dist/es/plugins/SlotLayout/ChatView.a11y.utility.mjs.map +1 -0
  1025. package/dist/es/plugins/SlotLayout/ChatView.mjs +277 -0
  1026. package/dist/es/plugins/SlotLayout/ChatView.mjs.map +1 -0
  1027. package/dist/es/plugins/SlotLayout/ChatViewNavigationContext.mjs +239 -0
  1028. package/dist/es/plugins/SlotLayout/ChatViewNavigationContext.mjs.map +1 -0
  1029. package/dist/es/plugins/SlotLayout/ThreadListSlot.mjs +42 -0
  1030. package/dist/es/plugins/SlotLayout/ThreadListSlot.mjs.map +1 -0
  1031. package/dist/es/plugins/SlotLayout/ThreadSlot.mjs +34 -0
  1032. package/dist/es/plugins/SlotLayout/ThreadSlot.mjs.map +1 -0
  1033. package/dist/es/plugins/SlotLayout/hooks/useLayoutViewState.mjs +26 -0
  1034. package/dist/es/plugins/SlotLayout/hooks/useLayoutViewState.mjs.map +1 -0
  1035. package/dist/es/plugins/SlotLayout/hooks/useSlotEntity.mjs +167 -0
  1036. package/dist/es/plugins/SlotLayout/hooks/useSlotEntity.mjs.map +1 -0
  1037. package/dist/es/plugins/SlotLayout/layout/Slot.mjs +46 -0
  1038. package/dist/es/plugins/SlotLayout/layout/Slot.mjs.map +1 -0
  1039. package/dist/es/plugins/SlotLayout/layout/WorkspaceLayout.mjs +23 -0
  1040. package/dist/es/plugins/SlotLayout/layout/WorkspaceLayout.mjs.map +1 -0
  1041. package/dist/es/plugins/SlotLayout/layoutController/LayoutController.mjs +376 -0
  1042. package/dist/es/plugins/SlotLayout/layoutController/LayoutController.mjs.map +1 -0
  1043. package/dist/es/plugins/SlotLayout/layoutController/serialization.mjs +80 -0
  1044. package/dist/es/plugins/SlotLayout/layoutController/serialization.mjs.map +1 -0
  1045. package/dist/es/plugins/SlotLayout/slotBinding.mjs +15 -0
  1046. package/dist/es/plugins/SlotLayout/slotBinding.mjs.map +1 -0
  1047. package/dist/es/plugins/SlotLayout/slotRegistry.mjs +64 -0
  1048. package/dist/es/plugins/SlotLayout/slotRegistry.mjs.map +1 -0
  1049. package/dist/es/plugins/SlotLayout/workspaceNavigationAdapter.mjs +130 -0
  1050. package/dist/es/plugins/SlotLayout/workspaceNavigationAdapter.mjs.map +1 -0
  1051. package/dist/es/slot-geometry.mjs +2 -0
  1052. package/dist/es/slot-layout.mjs +14 -0
  1053. package/dist/es/store/hooks/useStateStore.mjs +32 -0
  1054. package/dist/es/store/hooks/useStateStore.mjs.map +1 -0
  1055. package/dist/es/utils/findReverse.mjs +8 -0
  1056. package/dist/es/utils/findReverse.mjs.map +1 -0
  1057. package/dist/es/utils/getChannel.mjs +41 -0
  1058. package/dist/es/utils/getChannel.mjs.map +1 -0
  1059. package/dist/es/utils/getTextareaCaretRect.mjs +45 -0
  1060. package/dist/es/utils/getTextareaCaretRect.mjs.map +1 -0
  1061. package/dist/es/utils/getWholeChar.mjs +20 -0
  1062. package/dist/es/utils/getWholeChar.mjs.map +1 -0
  1063. package/dist/es/utils/isDmChannel.mjs +9 -0
  1064. package/dist/es/utils/isDmChannel.mjs.map +1 -0
  1065. package/dist/es/utils/mergeDeep.mjs +8 -0
  1066. package/dist/es/utils/mergeDeep.mjs.map +1 -0
  1067. package/dist/es/utils/useStableCallback.mjs +34 -0
  1068. package/dist/es/utils/useStableCallback.mjs.map +1 -0
  1069. package/dist/types/a11y/accessibleLabel.d.ts.map +1 -1
  1070. package/dist/types/components/AIStateIndicator/AIStateIndicator.d.ts.map +1 -1
  1071. package/dist/types/components/AIStateIndicator/hooks/useAIState.d.ts +3 -8
  1072. package/dist/types/components/AIStateIndicator/hooks/useAIState.d.ts.map +1 -1
  1073. package/dist/types/components/Accessibility/NotificationAnnouncer.d.ts +1 -2
  1074. package/dist/types/components/Accessibility/NotificationAnnouncer.d.ts.map +1 -1
  1075. package/dist/types/components/Accessibility/hooks/useIncomingMessageAnnouncements.d.ts.map +1 -1
  1076. package/dist/types/components/Accessibility/hooks/useInteractionAnnouncements.d.ts.map +1 -1
  1077. package/dist/types/components/Accessibility/useAriaLiveAnnouncer.d.ts +4 -0
  1078. package/dist/types/components/Accessibility/useAriaLiveAnnouncer.d.ts.map +1 -1
  1079. package/dist/types/components/Attachment/Attachment.d.ts +13 -2
  1080. package/dist/types/components/Attachment/Attachment.d.ts.map +1 -1
  1081. package/dist/types/components/Attachment/AttachmentActions.d.ts.map +1 -1
  1082. package/dist/types/components/Attachment/AttachmentContainer.d.ts +2 -2
  1083. package/dist/types/components/Attachment/AttachmentContainer.d.ts.map +1 -1
  1084. package/dist/types/components/Attachment/Audio.d.ts.map +1 -1
  1085. package/dist/types/components/Attachment/FileAttachment.d.ts.map +1 -1
  1086. package/dist/types/components/Attachment/Geolocation.d.ts +3 -3
  1087. package/dist/types/components/Attachment/Geolocation.d.ts.map +1 -1
  1088. package/dist/types/components/Attachment/Giphy.d.ts.map +1 -1
  1089. package/dist/types/components/Attachment/LinkPreview/Card.d.ts.map +1 -1
  1090. package/dist/types/components/Attachment/LinkPreview/CardAudio.d.ts +1 -1
  1091. package/dist/types/components/Attachment/LinkPreview/CardAudio.d.ts.map +1 -1
  1092. package/dist/types/components/Attachment/ModalGallery.d.ts.map +1 -1
  1093. package/dist/types/components/Attachment/UnsupportedAttachment.d.ts.map +1 -1
  1094. package/dist/types/components/Attachment/VideoAttachment.d.ts.map +1 -1
  1095. package/dist/types/components/Attachment/VisibilityDisclaimer.d.ts.map +1 -1
  1096. package/dist/types/components/Attachment/VoiceRecording.d.ts.map +1 -1
  1097. package/dist/types/components/Attachment/components/AttachmentUploadProgressIndicator.d.ts +32 -0
  1098. package/dist/types/components/Attachment/components/AttachmentUploadProgressIndicator.d.ts.map +1 -0
  1099. package/dist/types/components/Attachment/components/DownloadButton.d.ts.map +1 -1
  1100. package/dist/types/components/Attachment/components/index.d.ts +1 -0
  1101. package/dist/types/components/Attachment/components/index.d.ts.map +1 -1
  1102. package/dist/types/components/Attachment/hooks/useAttachmentUploadState.d.ts +61 -0
  1103. package/dist/types/components/Attachment/hooks/useAttachmentUploadState.d.ts.map +1 -0
  1104. package/dist/types/components/Attachment/hooks/useLocalVideoDimensions.d.ts +16 -0
  1105. package/dist/types/components/Attachment/hooks/useLocalVideoDimensions.d.ts.map +1 -0
  1106. package/dist/types/components/Attachment/index.d.ts +1 -0
  1107. package/dist/types/components/Attachment/index.d.ts.map +1 -1
  1108. package/dist/types/components/Attachment/utils.d.ts +2 -2
  1109. package/dist/types/components/Attachment/utils.d.ts.map +1 -1
  1110. package/dist/types/components/AudioPlayback/AudioPlaybackArbiter.d.ts +37 -0
  1111. package/dist/types/components/AudioPlayback/AudioPlaybackArbiter.d.ts.map +1 -0
  1112. package/dist/types/components/AudioPlayback/AudioPlayer.d.ts +1 -1
  1113. package/dist/types/components/AudioPlayback/AudioPlayer.d.ts.map +1 -1
  1114. package/dist/types/components/AudioPlayback/AudioPlayerPool.d.ts +19 -31
  1115. package/dist/types/components/AudioPlayback/AudioPlayerPool.d.ts.map +1 -1
  1116. package/dist/types/components/AudioPlayback/WithAudioPlayback.d.ts +17 -2
  1117. package/dist/types/components/AudioPlayback/WithAudioPlayback.d.ts.map +1 -1
  1118. package/dist/types/components/AudioPlayback/components/ProgressBar.d.ts.map +1 -1
  1119. package/dist/types/components/AudioPlayback/components/WaveProgressBar.d.ts.map +1 -1
  1120. package/dist/types/components/AudioPlayback/components/progressBarA11y.d.ts +2 -2
  1121. package/dist/types/components/AudioPlayback/components/progressBarA11y.d.ts.map +1 -1
  1122. package/dist/types/components/AudioPlayback/index.d.ts.map +1 -1
  1123. package/dist/types/components/AudioPlayback/plugins/AudioPlayerNotificationsPlugin.d.ts +2 -2
  1124. package/dist/types/components/AudioPlayback/plugins/AudioPlayerNotificationsPlugin.d.ts.map +1 -1
  1125. package/dist/types/components/Avatar/Avatar.d.ts +1 -5
  1126. package/dist/types/components/Avatar/Avatar.d.ts.map +1 -1
  1127. package/dist/types/components/Badge/Badge.d.ts.map +1 -1
  1128. package/dist/types/components/Badge/MediaBadge.d.ts.map +1 -1
  1129. package/dist/types/components/BaseImage/ImagePlaceholder.d.ts.map +1 -1
  1130. package/dist/types/components/Button/PlayButton.d.ts.map +1 -1
  1131. package/dist/types/components/Button/WorkspaceNavigationButtons.d.ts +11 -0
  1132. package/dist/types/components/Button/WorkspaceNavigationButtons.d.ts.map +1 -0
  1133. package/dist/types/components/Button/index.d.ts +1 -0
  1134. package/dist/types/components/Button/index.d.ts.map +1 -1
  1135. package/dist/types/components/Channel/Channel.d.ts +9 -57
  1136. package/dist/types/components/Channel/Channel.d.ts.map +1 -1
  1137. package/dist/types/components/Channel/hooks/useChannelCapabilities.d.ts +4 -0
  1138. package/dist/types/components/Channel/hooks/useChannelCapabilities.d.ts.map +1 -0
  1139. package/dist/types/components/Channel/index.d.ts +1 -2
  1140. package/dist/types/components/Channel/index.d.ts.map +1 -1
  1141. package/dist/types/components/ChannelHeader/ChannelHeader.d.ts +12 -0
  1142. package/dist/types/components/ChannelHeader/ChannelHeader.d.ts.map +1 -1
  1143. package/dist/types/components/ChannelHeader/hooks/useChannelHasMembersOnline.d.ts +8 -0
  1144. package/dist/types/components/ChannelHeader/hooks/useChannelHasMembersOnline.d.ts.map +1 -1
  1145. package/dist/types/components/ChannelHeader/hooks/useChannelHeaderOnlineStatus.d.ts +7 -8
  1146. package/dist/types/components/ChannelHeader/hooks/useChannelHeaderOnlineStatus.d.ts.map +1 -1
  1147. package/dist/types/components/ChannelList/ChannelList.d.ts +11 -78
  1148. package/dist/types/components/ChannelList/ChannelList.d.ts.map +1 -1
  1149. package/dist/types/components/ChannelList/ChannelListHeader.d.ts.map +1 -1
  1150. package/dist/types/components/ChannelList/ChannelLists.d.ts +10 -0
  1151. package/dist/types/components/ChannelList/ChannelLists.d.ts.map +1 -0
  1152. package/dist/types/components/ChannelList/ChannelNavigation.d.ts +9 -0
  1153. package/dist/types/components/ChannelList/ChannelNavigation.d.ts.map +1 -0
  1154. package/dist/types/components/ChannelList/hooks/index.d.ts +1 -2
  1155. package/dist/types/components/ChannelList/hooks/index.d.ts.map +1 -1
  1156. package/dist/types/components/ChannelList/hooks/useChannelMembersState.d.ts.map +1 -1
  1157. package/dist/types/components/ChannelList/hooks/useChannelMembershipState.d.ts.map +1 -1
  1158. package/dist/types/components/ChannelList/hooks/useChannelPaginatorState.d.ts +18 -0
  1159. package/dist/types/components/ChannelList/hooks/useChannelPaginatorState.d.ts.map +1 -0
  1160. package/dist/types/components/ChannelList/hooks/useSelectedChannelState.d.ts +3 -3
  1161. package/dist/types/components/ChannelList/hooks/useSelectedChannelState.d.ts.map +1 -1
  1162. package/dist/types/components/ChannelList/index.d.ts +3 -2
  1163. package/dist/types/components/ChannelList/index.d.ts.map +1 -1
  1164. package/dist/types/components/ChannelListItem/ChannelListItem.d.ts +9 -18
  1165. package/dist/types/components/ChannelListItem/ChannelListItem.d.ts.map +1 -1
  1166. package/dist/types/components/ChannelListItem/ChannelListItemActionButtons.defaults.d.ts.map +1 -1
  1167. package/dist/types/components/ChannelListItem/ChannelListItemTimestamp.d.ts +3 -3
  1168. package/dist/types/components/ChannelListItem/ChannelListItemTimestamp.d.ts.map +1 -1
  1169. package/dist/types/components/ChannelListItem/ChannelListItemUI.d.ts.map +1 -1
  1170. package/dist/types/components/ChannelListItem/hooks/useChannelDisplayName.d.ts +1 -1
  1171. package/dist/types/components/ChannelListItem/hooks/useChannelDisplayName.d.ts.map +1 -1
  1172. package/dist/types/components/ChannelListItem/hooks/useIsChannelMuted.d.ts +8 -5
  1173. package/dist/types/components/ChannelListItem/hooks/useIsChannelMuted.d.ts.map +1 -1
  1174. package/dist/types/components/ChannelListItem/hooks/useMessageDeliveryStatus.d.ts.map +1 -1
  1175. package/dist/types/components/ChannelListItem/utils.a11y.d.ts +14 -5
  1176. package/dist/types/components/ChannelListItem/utils.a11y.d.ts.map +1 -1
  1177. package/dist/types/components/ChannelListItem/utils.d.ts +1 -1
  1178. package/dist/types/components/ChannelListItem/utils.d.ts.map +1 -1
  1179. package/dist/types/components/Chat/Chat.d.ts +1 -4
  1180. package/dist/types/components/Chat/Chat.d.ts.map +1 -1
  1181. package/dist/types/components/Chat/hooks/useChat.d.ts +4 -16
  1182. package/dist/types/components/Chat/hooks/useChat.d.ts.map +1 -1
  1183. package/dist/types/components/Chat/hooks/useCreateChatClient.d.ts +2 -2
  1184. package/dist/types/components/Chat/hooks/useCreateChatClient.d.ts.map +1 -1
  1185. package/dist/types/components/Chat/hooks/useCreateChatContext.d.ts.map +1 -1
  1186. package/dist/types/components/Chat/hooks/useNetworkConnectionState.d.ts +34 -0
  1187. package/dist/types/components/Chat/hooks/useNetworkConnectionState.d.ts.map +1 -0
  1188. package/dist/types/components/Chat/hooks/useReportLostConnectionSystemNotification.d.ts +26 -2
  1189. package/dist/types/components/Chat/hooks/useReportLostConnectionSystemNotification.d.ts.map +1 -1
  1190. package/dist/types/components/Chat/hooks/useWSConnectionState.d.ts +22 -0
  1191. package/dist/types/components/Chat/hooks/useWSConnectionState.d.ts.map +1 -0
  1192. package/dist/types/components/Chat/index.d.ts +2 -0
  1193. package/dist/types/components/Chat/index.d.ts.map +1 -1
  1194. package/dist/types/components/Dialog/components/ContextMenu.d.ts +0 -4
  1195. package/dist/types/components/Dialog/components/ContextMenu.d.ts.map +1 -1
  1196. package/dist/types/components/Dialog/hooks/usePopoverPosition.d.ts +2 -2
  1197. package/dist/types/components/Dialog/hooks/usePopoverPosition.d.ts.map +1 -1
  1198. package/dist/types/components/Dialog/service/DialogAnchor.d.ts +8 -1
  1199. package/dist/types/components/Dialog/service/DialogAnchor.d.ts.map +1 -1
  1200. package/dist/types/components/Dialog/service/DialogManager.d.ts +1 -1
  1201. package/dist/types/components/Dialog/service/DialogManager.d.ts.map +1 -1
  1202. package/dist/types/components/EmptyStateIndicator/EmptyStateIndicator.d.ts.map +1 -1
  1203. package/dist/types/components/Form/Dropdown.d.ts +4 -1
  1204. package/dist/types/components/Form/Dropdown.d.ts.map +1 -1
  1205. package/dist/types/components/Form/NumericInput.d.ts.map +1 -1
  1206. package/dist/types/components/Gallery/GalleryContext.d.ts +5 -0
  1207. package/dist/types/components/Gallery/GalleryContext.d.ts.map +1 -1
  1208. package/dist/types/components/Gallery/GalleryHeader.d.ts.map +1 -1
  1209. package/dist/types/components/Gallery/GalleryUI.d.ts.map +1 -1
  1210. package/dist/types/components/Icons/index.d.ts +1 -1
  1211. package/dist/types/components/Icons/index.d.ts.map +1 -1
  1212. package/dist/types/components/Icons/slots.d.ts +18 -7
  1213. package/dist/types/components/Icons/slots.d.ts.map +1 -1
  1214. package/dist/types/components/InfiniteScrollPaginator/InfiniteScrollPaginator.d.ts +8 -2
  1215. package/dist/types/components/InfiniteScrollPaginator/InfiniteScrollPaginator.d.ts.map +1 -1
  1216. package/dist/types/components/InfiniteScrollPaginator/InfiniteScrollWithComponents.d.ts +43 -0
  1217. package/dist/types/components/InfiniteScrollPaginator/InfiniteScrollWithComponents.d.ts.map +1 -0
  1218. package/dist/types/components/InfiniteScrollPaginator/hooks/useCursorPaginator.d.ts +1 -1
  1219. package/dist/types/components/InfiniteScrollPaginator/hooks/useCursorPaginator.d.ts.map +1 -1
  1220. package/dist/types/components/LoadMore/LoadMoreButton.d.ts.map +1 -1
  1221. package/dist/types/components/Loading/AttachmentUploadedSizeIndicator.d.ts +23 -0
  1222. package/dist/types/components/Loading/AttachmentUploadedSizeIndicator.d.ts.map +1 -0
  1223. package/dist/types/components/Loading/LoadingErrorIndicator.d.ts.map +1 -1
  1224. package/dist/types/components/Loading/LoadingIndicator.d.ts +2 -3
  1225. package/dist/types/components/Loading/LoadingIndicator.d.ts.map +1 -1
  1226. package/dist/types/components/Loading/UploadProgressIndicator.d.ts +7 -1
  1227. package/dist/types/components/Loading/UploadProgressIndicator.d.ts.map +1 -1
  1228. package/dist/types/components/Loading/index.d.ts +1 -0
  1229. package/dist/types/components/Loading/index.d.ts.map +1 -1
  1230. package/dist/types/components/Loading/progress-indicators.d.ts.map +1 -1
  1231. package/dist/types/components/Location/ShareLocationDialog.d.ts.map +1 -1
  1232. package/dist/types/components/Location/hooks/useLiveLocationSharingManager.d.ts.map +1 -1
  1233. package/dist/types/components/MediaRecorder/AudioRecorder/AudioRecorderRecordingControls.d.ts.map +1 -1
  1234. package/dist/types/components/MediaRecorder/AudioRecorder/AudioRecordingButtonWithNotification.d.ts.map +1 -1
  1235. package/dist/types/components/MediaRecorder/AudioRecorder/AudioRecordingPlayback.d.ts.map +1 -1
  1236. package/dist/types/components/MediaRecorder/AudioRecorder/AudioRecordingPreview.d.ts.map +1 -1
  1237. package/dist/types/components/MediaRecorder/RecordingPermissionDeniedNotification.d.ts.map +1 -1
  1238. package/dist/types/components/MediaRecorder/classes/MediaRecorderController.d.ts.map +1 -1
  1239. package/dist/types/components/MediaRecorder/hooks/useMediaRecorder.d.ts +2 -2
  1240. package/dist/types/components/MediaRecorder/hooks/useMediaRecorder.d.ts.map +1 -1
  1241. package/dist/types/components/Message/Message.d.ts.map +1 -1
  1242. package/dist/types/components/Message/MessageAlsoSentInChannelIndicator.d.ts +11 -1
  1243. package/dist/types/components/Message/MessageAlsoSentInChannelIndicator.d.ts.map +1 -1
  1244. package/dist/types/components/Message/MessageDeletedBubble.d.ts.map +1 -1
  1245. package/dist/types/components/Message/MessageEditedIndicator.d.ts.map +1 -1
  1246. package/dist/types/components/Message/MessageRepliesCountButton.d.ts.map +1 -1
  1247. package/dist/types/components/Message/MessageStatus.d.ts.map +1 -1
  1248. package/dist/types/components/Message/MessageText.d.ts.map +1 -1
  1249. package/dist/types/components/Message/MessageTimestamp.d.ts.map +1 -1
  1250. package/dist/types/components/Message/MessageTranslationIndicator.d.ts.map +1 -1
  1251. package/dist/types/components/Message/MessageUI.d.ts.map +1 -1
  1252. package/dist/types/components/Message/ReminderNotification.d.ts.map +1 -1
  1253. package/dist/types/components/Message/StreamedMessageText.d.ts.map +1 -1
  1254. package/dist/types/components/Message/Timestamp.d.ts.map +1 -1
  1255. package/dist/types/components/Message/hooks/index.d.ts +1 -0
  1256. package/dist/types/components/Message/hooks/index.d.ts.map +1 -1
  1257. package/dist/types/components/Message/hooks/useActionHandler.d.ts +1 -1
  1258. package/dist/types/components/Message/hooks/useActionHandler.d.ts.map +1 -1
  1259. package/dist/types/components/Message/hooks/useDeleteHandler.d.ts +6 -2
  1260. package/dist/types/components/Message/hooks/useDeleteHandler.d.ts.map +1 -1
  1261. package/dist/types/components/Message/hooks/useMarkUnreadHandler.d.ts +6 -1
  1262. package/dist/types/components/Message/hooks/useMarkUnreadHandler.d.ts.map +1 -1
  1263. package/dist/types/components/Message/hooks/useMentionsHandler.d.ts.map +1 -1
  1264. package/dist/types/components/Message/hooks/useMessageAlsoSentInChannelNavigation.d.ts +22 -0
  1265. package/dist/types/components/Message/hooks/useMessageAlsoSentInChannelNavigation.d.ts.map +1 -0
  1266. package/dist/types/components/Message/hooks/useMuteHandler.d.ts +7 -2
  1267. package/dist/types/components/Message/hooks/useMuteHandler.d.ts.map +1 -1
  1268. package/dist/types/components/Message/hooks/useOpenThreadHandler.d.ts +1 -0
  1269. package/dist/types/components/Message/hooks/useOpenThreadHandler.d.ts.map +1 -1
  1270. package/dist/types/components/Message/hooks/usePinHandler.d.ts +23 -2
  1271. package/dist/types/components/Message/hooks/usePinHandler.d.ts.map +1 -1
  1272. package/dist/types/components/Message/hooks/useReactionHandler.d.ts +1 -1
  1273. package/dist/types/components/Message/hooks/useReactionHandler.d.ts.map +1 -1
  1274. package/dist/types/components/Message/hooks/useReactionsFetcher.d.ts +2 -2
  1275. package/dist/types/components/Message/hooks/useReactionsFetcher.d.ts.map +1 -1
  1276. package/dist/types/components/Message/hooks/useRetryHandler.d.ts +3 -2
  1277. package/dist/types/components/Message/hooks/useRetryHandler.d.ts.map +1 -1
  1278. package/dist/types/components/Message/hooks/useUserRole.d.ts +1 -0
  1279. package/dist/types/components/Message/hooks/useUserRole.d.ts.map +1 -1
  1280. package/dist/types/components/Message/types.d.ts +11 -20
  1281. package/dist/types/components/Message/types.d.ts.map +1 -1
  1282. package/dist/types/components/Message/utils.d.ts +7 -38
  1283. package/dist/types/components/Message/utils.d.ts.map +1 -1
  1284. package/dist/types/components/MessageActions/DeleteMessageAlert.d.ts.map +1 -1
  1285. package/dist/types/components/MessageActions/DownloadSubmenu.d.ts.map +1 -1
  1286. package/dist/types/components/MessageActions/MessageActions.d.ts +6 -2
  1287. package/dist/types/components/MessageActions/MessageActions.d.ts.map +1 -1
  1288. package/dist/types/components/MessageActions/MessageActions.defaults.d.ts.map +1 -1
  1289. package/dist/types/components/MessageActions/RemindMeSubmenu.d.ts.map +1 -1
  1290. package/dist/types/components/MessageActions/hooks/useBaseMessageActionSetFilter.d.ts.map +1 -1
  1291. package/dist/types/components/MessageBounce/MessageBouncePrompt.d.ts.map +1 -1
  1292. package/dist/types/components/MessageComposer/AttachmentPreviewList/AudioAttachmentPreview.d.ts.map +1 -1
  1293. package/dist/types/components/MessageComposer/AttachmentPreviewList/FileAttachmentPreview.d.ts.map +1 -1
  1294. package/dist/types/components/MessageComposer/AttachmentPreviewList/GeolocationPreview.d.ts.map +1 -1
  1295. package/dist/types/components/MessageComposer/AttachmentPreviewList/MediaAttachmentPreview.d.ts.map +1 -1
  1296. package/dist/types/components/MessageComposer/AttachmentPreviewList/UnsupportedAttachmentPreview.d.ts.map +1 -1
  1297. package/dist/types/components/MessageComposer/AttachmentPreviewList/index.d.ts +1 -1
  1298. package/dist/types/components/MessageComposer/AttachmentPreviewList/index.d.ts.map +1 -1
  1299. package/dist/types/components/MessageComposer/AttachmentPreviewList/utils/AttachmentPreviewRoot.d.ts.map +1 -1
  1300. package/dist/types/components/MessageComposer/AttachmentSelector/AttachmentSelector.d.ts.map +1 -1
  1301. package/dist/types/components/MessageComposer/AttachmentSelector/CommandsMenu.d.ts +5 -5
  1302. package/dist/types/components/MessageComposer/AttachmentSelector/CommandsMenu.d.ts.map +1 -1
  1303. package/dist/types/components/MessageComposer/CommandChip.d.ts.map +1 -1
  1304. package/dist/types/components/MessageComposer/EditMessageForm.d.ts +1 -0
  1305. package/dist/types/components/MessageComposer/EditMessageForm.d.ts.map +1 -0
  1306. package/dist/types/components/MessageComposer/MessageComposer.d.ts +1 -17
  1307. package/dist/types/components/MessageComposer/MessageComposer.d.ts.map +1 -1
  1308. package/dist/types/components/MessageComposer/MessageComposerActions.d.ts.map +1 -1
  1309. package/dist/types/components/MessageComposer/MessageComposerUI.d.ts.map +1 -1
  1310. package/dist/types/components/MessageComposer/QuotedMessagePreview.d.ts +3 -3
  1311. package/dist/types/components/MessageComposer/QuotedMessagePreview.d.ts.map +1 -1
  1312. package/dist/types/components/MessageComposer/RemoveAttachmentPreviewButton.d.ts.map +1 -1
  1313. package/dist/types/components/MessageComposer/SendButton.d.ts.map +1 -1
  1314. package/dist/types/components/MessageComposer/SendToChannelCheckbox.d.ts.map +1 -1
  1315. package/dist/types/components/MessageComposer/StopAIGenerationButton.d.ts.map +1 -1
  1316. package/dist/types/components/MessageComposer/WithDragAndDropUpload.d.ts +2 -5
  1317. package/dist/types/components/MessageComposer/WithDragAndDropUpload.d.ts.map +1 -1
  1318. package/dist/types/components/MessageComposer/hooks/index.d.ts +1 -0
  1319. package/dist/types/components/MessageComposer/hooks/index.d.ts.map +1 -1
  1320. package/dist/types/components/MessageComposer/hooks/useAttachmentManagerState.d.ts +5 -1
  1321. package/dist/types/components/MessageComposer/hooks/useAttachmentManagerState.d.ts.map +1 -1
  1322. package/dist/types/components/MessageComposer/hooks/useAttachmentsForPreview.d.ts +1 -2
  1323. package/dist/types/components/MessageComposer/hooks/useAttachmentsForPreview.d.ts.map +1 -1
  1324. package/dist/types/components/MessageComposer/hooks/useCreateMessageComposerContext.d.ts.map +1 -1
  1325. package/dist/types/components/MessageComposer/hooks/useMessageComposerBindings.d.ts +0 -1
  1326. package/dist/types/components/MessageComposer/hooks/useMessageComposerBindings.d.ts.map +1 -1
  1327. package/dist/types/components/MessageComposer/hooks/useMessageComposerCommands.d.ts +2 -2
  1328. package/dist/types/components/MessageComposer/hooks/useMessageComposerCommands.d.ts.map +1 -1
  1329. package/dist/types/components/MessageComposer/hooks/useMessageComposerController.d.ts +1 -1
  1330. package/dist/types/components/MessageComposer/hooks/useMessageComposerController.d.ts.map +1 -1
  1331. package/dist/types/components/MessageComposer/hooks/useMessageComposerSubmitFn.d.ts +7 -0
  1332. package/dist/types/components/MessageComposer/hooks/useMessageComposerSubmitFn.d.ts.map +1 -0
  1333. package/dist/types/components/MessageComposer/hooks/utils.d.ts.map +1 -1
  1334. package/dist/types/components/MessageComposer/index.d.ts +2 -1
  1335. package/dist/types/components/MessageComposer/index.d.ts.map +1 -1
  1336. package/dist/types/components/MessageList/FloatingDateSeparator.d.ts +1 -1
  1337. package/dist/types/components/MessageList/FloatingDateSeparator.d.ts.map +1 -1
  1338. package/dist/types/components/MessageList/MessageList.d.ts +24 -25
  1339. package/dist/types/components/MessageList/MessageList.d.ts.map +1 -1
  1340. package/dist/types/components/MessageList/NewMessageNotification.d.ts.map +1 -1
  1341. package/dist/types/components/MessageList/ScrollToLatestMessageButton.d.ts +0 -1
  1342. package/dist/types/components/MessageList/ScrollToLatestMessageButton.d.ts.map +1 -1
  1343. package/dist/types/components/MessageList/UnreadMessagesNotification.d.ts +1 -4
  1344. package/dist/types/components/MessageList/UnreadMessagesNotification.d.ts.map +1 -1
  1345. package/dist/types/components/MessageList/UnreadMessagesSeparator.d.ts.map +1 -1
  1346. package/dist/types/components/MessageList/VirtualizedMessageList.d.ts +23 -42
  1347. package/dist/types/components/MessageList/VirtualizedMessageList.d.ts.map +1 -1
  1348. package/dist/types/components/MessageList/VirtualizedMessageListComponents.d.ts.map +1 -1
  1349. package/dist/types/components/MessageList/hooks/MessageList/useEnrichedMessages.d.ts +3 -3
  1350. package/dist/types/components/MessageList/hooks/MessageList/useEnrichedMessages.d.ts.map +1 -1
  1351. package/dist/types/components/MessageList/hooks/MessageList/useFloatingDateSeparatorMessageList.d.ts +2 -2
  1352. package/dist/types/components/MessageList/hooks/MessageList/useFloatingDateSeparatorMessageList.d.ts.map +1 -1
  1353. package/dist/types/components/MessageList/hooks/MessageList/useMessageListElements.d.ts +1 -3
  1354. package/dist/types/components/MessageList/hooks/MessageList/useMessageListElements.d.ts.map +1 -1
  1355. package/dist/types/components/MessageList/hooks/MessageList/useMessageListScrollManager.d.ts +1 -0
  1356. package/dist/types/components/MessageList/hooks/MessageList/useMessageListScrollManager.d.ts.map +1 -1
  1357. package/dist/types/components/MessageList/hooks/MessageList/useScrollLocationLogic.d.ts +6 -25
  1358. package/dist/types/components/MessageList/hooks/MessageList/useScrollLocationLogic.d.ts.map +1 -1
  1359. package/dist/types/components/MessageList/hooks/MessageList/useUnreadMessagesNotification.d.ts +1 -1
  1360. package/dist/types/components/MessageList/hooks/MessageList/useUnreadMessagesNotification.d.ts.map +1 -1
  1361. package/dist/types/components/MessageList/hooks/VirtualizedMessageList/useFloatingDateSeparator.d.ts +2 -2
  1362. package/dist/types/components/MessageList/hooks/VirtualizedMessageList/useFloatingDateSeparator.d.ts.map +1 -1
  1363. package/dist/types/components/MessageList/hooks/VirtualizedMessageList/useNewMessageNotification.d.ts +1 -1
  1364. package/dist/types/components/MessageList/hooks/VirtualizedMessageList/useNewMessageNotification.d.ts.map +1 -1
  1365. package/dist/types/components/MessageList/hooks/VirtualizedMessageList/useUnreadMessagesNotificationVirtualized.d.ts +1 -5
  1366. package/dist/types/components/MessageList/hooks/VirtualizedMessageList/useUnreadMessagesNotificationVirtualized.d.ts.map +1 -1
  1367. package/dist/types/components/MessageList/hooks/useCanPaginateReplies.d.ts +32 -0
  1368. package/dist/types/components/MessageList/hooks/useCanPaginateReplies.d.ts.map +1 -0
  1369. package/dist/types/components/MessageList/hooks/useLastDeliveredData.d.ts +1 -0
  1370. package/dist/types/components/MessageList/hooks/useLastDeliveredData.d.ts.map +1 -1
  1371. package/dist/types/components/MessageList/hooks/useLastReadData.d.ts +1 -0
  1372. package/dist/types/components/MessageList/hooks/useLastReadData.d.ts.map +1 -1
  1373. package/dist/types/components/MessageList/hooks/useMarkRead.d.ts +5 -9
  1374. package/dist/types/components/MessageList/hooks/useMarkRead.d.ts.map +1 -1
  1375. package/dist/types/components/MessageList/hooks/useReceiptsByMessageId.d.ts +12 -0
  1376. package/dist/types/components/MessageList/hooks/useReceiptsByMessageId.d.ts.map +1 -0
  1377. package/dist/types/components/MessageList/hooks/useThreadHead.d.ts +9 -0
  1378. package/dist/types/components/MessageList/hooks/useThreadHead.d.ts.map +1 -0
  1379. package/dist/types/components/MessageList/messageSourceKey.d.ts +14 -0
  1380. package/dist/types/components/MessageList/messageSourceKey.d.ts.map +1 -0
  1381. package/dist/types/components/MessageList/renderMessages.d.ts +11 -9
  1382. package/dist/types/components/MessageList/renderMessages.d.ts.map +1 -1
  1383. package/dist/types/components/MessageList/utils.d.ts +22 -13
  1384. package/dist/types/components/MessageList/utils.d.ts.map +1 -1
  1385. package/dist/types/components/Modal/CloseButtonOnModalOverlay.d.ts.map +1 -1
  1386. package/dist/types/components/Notifications/Notification.d.ts.map +1 -1
  1387. package/dist/types/components/Notifications/NotificationList.d.ts.map +1 -1
  1388. package/dist/types/components/Notifications/hooks/useNotificationApi.d.ts +3 -0
  1389. package/dist/types/components/Notifications/hooks/useNotificationApi.d.ts.map +1 -1
  1390. package/dist/types/components/Notifications/hooks/useNotificationTarget.d.ts.map +1 -1
  1391. package/dist/types/components/Notifications/notificationTarget.d.ts.map +1 -1
  1392. package/dist/types/components/Poll/PollActions/AddCommentPrompt.d.ts.map +1 -1
  1393. package/dist/types/components/Poll/PollActions/EndPollAlert.d.ts.map +1 -1
  1394. package/dist/types/components/Poll/PollActions/PollActions.d.ts.map +1 -1
  1395. package/dist/types/components/Poll/PollActions/PollAnswerList.d.ts.map +1 -1
  1396. package/dist/types/components/Poll/PollActions/PollOptionsFullList.d.ts.map +1 -1
  1397. package/dist/types/components/Poll/PollActions/PollQuestion.d.ts.map +1 -1
  1398. package/dist/types/components/Poll/PollActions/PollResults/PollOptionWithVotes.d.ts +2 -2
  1399. package/dist/types/components/Poll/PollActions/PollResults/PollOptionWithVotes.d.ts.map +1 -1
  1400. package/dist/types/components/Poll/PollActions/PollResults/PollOptionWithVotesHeader.d.ts +2 -2
  1401. package/dist/types/components/Poll/PollActions/PollResults/PollOptionWithVotesHeader.d.ts.map +1 -1
  1402. package/dist/types/components/Poll/PollActions/PollResults/PollOptionWithVotesList.d.ts +2 -2
  1403. package/dist/types/components/Poll/PollActions/PollResults/PollOptionWithVotesList.d.ts.map +1 -1
  1404. package/dist/types/components/Poll/PollActions/PollResults/PollResults.d.ts.map +1 -1
  1405. package/dist/types/components/Poll/PollActions/SuggestPollOptionPrompt.d.ts.map +1 -1
  1406. package/dist/types/components/Poll/PollCreationDialog/MultipleAnswersField.d.ts.map +1 -1
  1407. package/dist/types/components/Poll/PollCreationDialog/NameField.d.ts.map +1 -1
  1408. package/dist/types/components/Poll/PollCreationDialog/OptionFieldSet.d.ts.map +1 -1
  1409. package/dist/types/components/Poll/PollCreationDialog/PollCreationDialog.d.ts.map +1 -1
  1410. package/dist/types/components/Poll/PollCreationDialog/PollCreationDialogControls.d.ts.map +1 -1
  1411. package/dist/types/components/Poll/PollCreationDialog/PollOptionReorderHandle.d.ts.map +1 -1
  1412. package/dist/types/components/Poll/PollHeader.d.ts.map +1 -1
  1413. package/dist/types/components/Poll/PollOptionList.d.ts.map +1 -1
  1414. package/dist/types/components/Poll/PollOptionSelector.d.ts +2 -2
  1415. package/dist/types/components/Poll/PollOptionSelector.d.ts.map +1 -1
  1416. package/dist/types/components/Poll/PollVote.d.ts +1 -1
  1417. package/dist/types/components/Poll/PollVote.d.ts.map +1 -1
  1418. package/dist/types/components/Poll/hooks/useManagePollVotesRealtime.d.ts +2 -2
  1419. package/dist/types/components/Poll/hooks/useManagePollVotesRealtime.d.ts.map +1 -1
  1420. package/dist/types/components/Poll/hooks/usePollAnswerPagination.d.ts +2 -2
  1421. package/dist/types/components/Poll/hooks/usePollAnswerPagination.d.ts.map +1 -1
  1422. package/dist/types/components/Poll/hooks/usePollOptionVotesPagination.d.ts +2 -2
  1423. package/dist/types/components/Poll/hooks/usePollOptionVotesPagination.d.ts.map +1 -1
  1424. package/dist/types/components/Reactions/MessageReactions.d.ts.map +1 -1
  1425. package/dist/types/components/Reactions/MessageReactionsDetail.d.ts +2 -2
  1426. package/dist/types/components/Reactions/MessageReactionsDetail.d.ts.map +1 -1
  1427. package/dist/types/components/Reactions/ReactionSelector.d.ts.map +1 -1
  1428. package/dist/types/components/Reactions/ReactionSelectorWithButton.d.ts +0 -5
  1429. package/dist/types/components/Reactions/ReactionSelectorWithButton.d.ts.map +1 -1
  1430. package/dist/types/components/Reactions/hooks/useFetchReactions.d.ts +2 -2
  1431. package/dist/types/components/Reactions/hooks/useFetchReactions.d.ts.map +1 -1
  1432. package/dist/types/components/Reactions/hooks/useProcessReactions.d.ts +1 -3
  1433. package/dist/types/components/Reactions/hooks/useProcessReactions.d.ts.map +1 -1
  1434. package/dist/types/components/Search/SearchBar/SearchBar.d.ts.map +1 -1
  1435. package/dist/types/components/Search/SearchContext.d.ts.map +1 -1
  1436. package/dist/types/components/Search/SearchResults/SearchResultItem.d.ts +20 -6
  1437. package/dist/types/components/Search/SearchResults/SearchResultItem.d.ts.map +1 -1
  1438. package/dist/types/components/Search/SearchResults/SearchResultsHeader.d.ts.map +1 -1
  1439. package/dist/types/components/Search/SearchResults/SearchSourceResultsEmpty.d.ts.map +1 -1
  1440. package/dist/types/components/Search/SearchResults/SearchSourceResultsLoadingIndicator.d.ts.map +1 -1
  1441. package/dist/types/components/Search/SearchSourceResultsContext.d.ts.map +1 -1
  1442. package/dist/types/components/Search/hooks/index.d.ts +0 -1
  1443. package/dist/types/components/Search/hooks/index.d.ts.map +1 -1
  1444. package/dist/types/components/SummarizedMessagePreview/SummarizedMessagePreview.d.ts +6 -0
  1445. package/dist/types/components/SummarizedMessagePreview/SummarizedMessagePreview.d.ts.map +1 -1
  1446. package/dist/types/components/SummarizedMessagePreview/hooks/useLatestMessagePreview.d.ts.map +1 -1
  1447. package/dist/types/components/TextareaComposer/SuggestionList/CommandItem.d.ts +2 -2
  1448. package/dist/types/components/TextareaComposer/SuggestionList/CommandItem.d.ts.map +1 -1
  1449. package/dist/types/components/TextareaComposer/SuggestionList/MentionItem/BroadcastMentionItem.d.ts.map +1 -1
  1450. package/dist/types/components/TextareaComposer/SuggestionList/MentionItem/RoleItem.d.ts.map +1 -1
  1451. package/dist/types/components/TextareaComposer/SuggestionList/MentionItem/UserGroupItem.d.ts.map +1 -1
  1452. package/dist/types/components/TextareaComposer/SuggestionList/SuggestionList.d.ts.map +1 -1
  1453. package/dist/types/components/TextareaComposer/TextareaComposer.d.ts.map +1 -1
  1454. package/dist/types/components/TextareaComposer/hooks/useTextareaPlaceholder.d.ts.map +1 -1
  1455. package/dist/types/components/Thread/Thread.d.ts +31 -27
  1456. package/dist/types/components/Thread/Thread.d.ts.map +1 -1
  1457. package/dist/types/components/Thread/ThreadHead.d.ts.map +1 -1
  1458. package/dist/types/components/Thread/ThreadHeader.d.ts +13 -6
  1459. package/dist/types/components/Thread/ThreadHeader.d.ts.map +1 -1
  1460. package/dist/types/components/Thread/ThreadStart.d.ts.map +1 -1
  1461. package/dist/types/components/Thread/index.d.ts +0 -1
  1462. package/dist/types/components/Thread/index.d.ts.map +1 -1
  1463. package/dist/types/components/Threads/ThreadContext.d.ts.map +1 -1
  1464. package/dist/types/components/Threads/ThreadList/ThreadList.d.ts.map +1 -1
  1465. package/dist/types/components/Threads/ThreadList/ThreadListEmptyPlaceholder.d.ts.map +1 -1
  1466. package/dist/types/components/Threads/ThreadList/ThreadListHeader.d.ts.map +1 -1
  1467. package/dist/types/components/Threads/ThreadList/ThreadListItemUI.d.ts.map +1 -1
  1468. package/dist/types/components/Threads/ThreadList/ThreadListUnseenThreadsBanner.d.ts.map +1 -1
  1469. package/dist/types/components/Threads/ThreadList/useThreadHighlighting.d.ts +15 -0
  1470. package/dist/types/components/Threads/ThreadList/useThreadHighlighting.d.ts.map +1 -0
  1471. package/dist/types/components/Threads/ThreadList/utils.a11y.d.ts.map +1 -1
  1472. package/dist/types/components/Threads/hooks/useCloseThread.d.ts +9 -0
  1473. package/dist/types/components/Threads/hooks/useCloseThread.d.ts.map +1 -0
  1474. package/dist/types/components/Threads/index.d.ts +1 -0
  1475. package/dist/types/components/Threads/index.d.ts.map +1 -1
  1476. package/dist/types/components/TypingIndicator/TypingIndicator.d.ts +4 -5
  1477. package/dist/types/components/TypingIndicator/TypingIndicator.d.ts.map +1 -1
  1478. package/dist/types/components/TypingIndicator/TypingIndicatorHeader.d.ts +1 -1
  1479. package/dist/types/components/TypingIndicator/TypingIndicatorHeader.d.ts.map +1 -1
  1480. package/dist/types/components/TypingIndicator/hooks/useDebouncedTypingActive.d.ts +2 -2
  1481. package/dist/types/components/TypingIndicator/hooks/useDebouncedTypingActive.d.ts.map +1 -1
  1482. package/dist/types/components/TypingIndicator/utils/getTypingStatusMessage.d.ts +2 -3
  1483. package/dist/types/components/TypingIndicator/utils/getTypingStatusMessage.d.ts.map +1 -1
  1484. package/dist/types/components/VideoPlayer/ReactPlayerWrapper.d.ts +1 -1
  1485. package/dist/types/components/VideoPlayer/ReactPlayerWrapper.d.ts.map +1 -1
  1486. package/dist/types/components/VideoPlayer/VideoPlayer.d.ts +7 -1
  1487. package/dist/types/components/VideoPlayer/VideoPlayer.d.ts.map +1 -1
  1488. package/dist/types/components/VideoPlayer/VideoThumbnail.d.ts.map +1 -1
  1489. package/dist/types/components/index.d.ts +0 -2
  1490. package/dist/types/components/index.d.ts.map +1 -1
  1491. package/dist/types/context/AttachmentContext.d.ts +19 -0
  1492. package/dist/types/context/AttachmentContext.d.ts.map +1 -0
  1493. package/dist/types/context/ChannelInstanceContext.d.ts +16 -0
  1494. package/dist/types/context/ChannelInstanceContext.d.ts.map +1 -0
  1495. package/dist/types/context/ChannelListContext.d.ts +9 -18
  1496. package/dist/types/context/ChannelListContext.d.ts.map +1 -1
  1497. package/dist/types/context/ChatContext.d.ts +10 -23
  1498. package/dist/types/context/ChatContext.d.ts.map +1 -1
  1499. package/dist/types/context/ComponentContext.d.ts +30 -20
  1500. package/dist/types/context/ComponentContext.d.ts.map +1 -1
  1501. package/dist/types/context/DialogManagerContext.d.ts.map +1 -1
  1502. package/dist/types/context/MessageBounceContext.d.ts +1 -1
  1503. package/dist/types/context/MessageBounceContext.d.ts.map +1 -1
  1504. package/dist/types/context/MessageComposerContext.d.ts +7 -2
  1505. package/dist/types/context/MessageComposerContext.d.ts.map +1 -1
  1506. package/dist/types/context/MessageComposerControllerContext.d.ts +13 -0
  1507. package/dist/types/context/MessageComposerControllerContext.d.ts.map +1 -0
  1508. package/dist/types/context/MessageContext.d.ts +8 -21
  1509. package/dist/types/context/MessageContext.d.ts.map +1 -1
  1510. package/dist/types/context/MessageListContext.d.ts +2 -2
  1511. package/dist/types/context/MessageListContext.d.ts.map +1 -1
  1512. package/dist/types/context/MessageTranslationViewContext.d.ts.map +1 -1
  1513. package/dist/types/context/ModalContext.d.ts +4 -0
  1514. package/dist/types/context/ModalContext.d.ts.map +1 -1
  1515. package/dist/types/context/PollContext.d.ts.map +1 -1
  1516. package/dist/types/context/TranslationContext.d.ts +21 -11
  1517. package/dist/types/context/TranslationContext.d.ts.map +1 -1
  1518. package/dist/types/context/VirtualizedMessageListContext.d.ts.map +1 -1
  1519. package/dist/types/context/WithComponents.d.ts.map +1 -1
  1520. package/dist/types/context/WorkspaceNavigationContext.d.ts +128 -0
  1521. package/dist/types/context/WorkspaceNavigationContext.d.ts.map +1 -0
  1522. package/dist/types/context/index.d.ts +6 -4
  1523. package/dist/types/context/index.d.ts.map +1 -1
  1524. package/dist/types/context/requireContext.d.ts +10 -0
  1525. package/dist/types/context/requireContext.d.ts.map +1 -0
  1526. package/dist/types/context/useChannel.d.ts +3 -0
  1527. package/dist/types/context/useChannel.d.ts.map +1 -0
  1528. package/dist/types/context/useComponentContextIcons.d.ts +4 -6
  1529. package/dist/types/context/useComponentContextIcons.d.ts.map +1 -1
  1530. package/dist/types/hooks/index.d.ts +3 -0
  1531. package/dist/types/hooks/index.d.ts.map +1 -0
  1532. package/dist/types/hooks/useIsDmChannel.d.ts +13 -0
  1533. package/dist/types/hooks/useIsDmChannel.d.ts.map +1 -0
  1534. package/dist/types/hooks/useMessagePaginator.d.ts +6 -0
  1535. package/dist/types/hooks/useMessagePaginator.d.ts.map +1 -0
  1536. package/dist/types/i18n/Streami18n.d.ts +48 -847
  1537. package/dist/types/i18n/Streami18n.d.ts.map +1 -1
  1538. package/dist/types/i18n/TranslationBuilder/index.d.ts +6 -1
  1539. package/dist/types/i18n/TranslationBuilder/index.d.ts.map +1 -1
  1540. package/dist/types/i18n/TranslationBuilder/notifications/NotificationTranslationTopic.d.ts.map +1 -1
  1541. package/dist/types/i18n/TranslationBuilder/notifications/translators.d.ts.map +1 -1
  1542. package/dist/types/i18n/TranslationBuilder/notifications/translatorsByNotificationType.d.ts +3 -1
  1543. package/dist/types/i18n/TranslationBuilder/notifications/translatorsByNotificationType.d.ts.map +1 -1
  1544. package/dist/types/i18n/index.d.ts +2 -2
  1545. package/dist/types/i18n/index.d.ts.map +1 -1
  1546. package/dist/types/i18n/keys.d.ts +583 -0
  1547. package/dist/types/i18n/keys.d.ts.map +1 -0
  1548. package/dist/types/i18n/runtimeDefaults.d.ts +37 -0
  1549. package/dist/types/i18n/runtimeDefaults.d.ts.map +1 -0
  1550. package/dist/types/i18n/types.d.ts +34 -104
  1551. package/dist/types/i18n/types.d.ts.map +1 -1
  1552. package/dist/types/i18n/useStreami18n.d.ts +19 -0
  1553. package/dist/types/i18n/useStreami18n.d.ts.map +1 -0
  1554. package/dist/types/i18n/utils.d.ts +18 -14
  1555. package/dist/types/i18n/utils.d.ts.map +1 -1
  1556. package/dist/types/plugins/ChannelDetail/AvatarWithChannelDetail.d.ts.map +1 -1
  1557. package/dist/types/plugins/ChannelDetail/ChannelDetail.d.ts.map +1 -1
  1558. package/dist/types/plugins/ChannelDetail/ChannelDetailEmptyList.d.ts.map +1 -1
  1559. package/dist/types/plugins/ChannelDetail/ChannelDetailSearchInput.d.ts.map +1 -1
  1560. package/dist/types/plugins/ChannelDetail/SectionNavigator/SectionNavigatorHeader.d.ts.map +1 -1
  1561. package/dist/types/plugins/ChannelDetail/Views/ChannelFilesView/ChannelFilesEmptyList.d.ts.map +1 -1
  1562. package/dist/types/plugins/ChannelDetail/Views/ChannelFilesView/ChannelFilesView.d.ts.map +1 -1
  1563. package/dist/types/plugins/ChannelDetail/Views/ChannelFilesView/ChannelFilesView.utils.d.ts.map +1 -1
  1564. package/dist/types/plugins/ChannelDetail/Views/ChannelManagementView/ChannelManagementActions.defaults.d.ts.map +1 -1
  1565. package/dist/types/plugins/ChannelDetail/Views/ChannelManagementView/ChannelManagementView.d.ts.map +1 -1
  1566. package/dist/types/plugins/ChannelDetail/Views/ChannelMediaView/ChannelMediaEmptyList.d.ts.map +1 -1
  1567. package/dist/types/plugins/ChannelDetail/Views/ChannelMediaView/ChannelMediaView.d.ts.map +1 -1
  1568. package/dist/types/plugins/ChannelDetail/Views/ChannelMediaView/ChannelMediaView.utils.d.ts.map +1 -1
  1569. package/dist/types/plugins/ChannelDetail/Views/ChannelMemberDetailView/ChannelMemberActions.defaults.d.ts.map +1 -1
  1570. package/dist/types/plugins/ChannelDetail/Views/ChannelMemberDetailView/ChannelMemberDetail.d.ts.map +1 -1
  1571. package/dist/types/plugins/ChannelDetail/Views/ChannelMembersView/ChannelMembersAddView.d.ts.map +1 -1
  1572. package/dist/types/plugins/ChannelDetail/Views/ChannelMembersView/ChannelMembersBrowseView.d.ts.map +1 -1
  1573. package/dist/types/plugins/ChannelDetail/Views/ChannelMembersView/ChannelMembersHeaderActions.defaults.d.ts.map +1 -1
  1574. package/dist/types/plugins/ChannelDetail/Views/ChannelMembersView/ChannelMembersView.d.ts.map +1 -1
  1575. package/dist/types/plugins/ChannelDetail/Views/ChannelMembersView/ChannelMembersView.utils.d.ts.map +1 -1
  1576. package/dist/types/plugins/ChannelDetail/Views/PinnedMessagesView/PinnedMessagesEmptyList.d.ts.map +1 -1
  1577. package/dist/types/plugins/ChannelDetail/Views/PinnedMessagesView/PinnedMessagesView.d.ts.map +1 -1
  1578. package/dist/types/plugins/ChannelDetail/Views/PinnedMessagesView/usePinnedMessagesCount.d.ts +5 -1
  1579. package/dist/types/plugins/ChannelDetail/Views/PinnedMessagesView/usePinnedMessagesCount.d.ts.map +1 -1
  1580. package/dist/types/plugins/Emojis/EmojiPicker.d.ts +0 -4
  1581. package/dist/types/plugins/Emojis/EmojiPicker.d.ts.map +1 -1
  1582. package/dist/types/plugins/SlotGeometry/SlotGeometry.d.ts +72 -0
  1583. package/dist/types/plugins/SlotGeometry/SlotGeometry.d.ts.map +1 -0
  1584. package/dist/types/plugins/SlotGeometry/index.d.ts +3 -0
  1585. package/dist/types/plugins/SlotGeometry/index.d.ts.map +1 -0
  1586. package/dist/types/plugins/SlotLayout/ChannelSlot.d.ts +24 -0
  1587. package/dist/types/plugins/SlotLayout/ChannelSlot.d.ts.map +1 -0
  1588. package/dist/types/plugins/SlotLayout/ChatView.a11y.utility.d.ts.map +1 -0
  1589. package/dist/types/plugins/SlotLayout/ChatView.d.ts +113 -0
  1590. package/dist/types/plugins/SlotLayout/ChatView.d.ts.map +1 -0
  1591. package/dist/types/plugins/SlotLayout/ChatViewNavigationContext.d.ts +111 -0
  1592. package/dist/types/plugins/SlotLayout/ChatViewNavigationContext.d.ts.map +1 -0
  1593. package/dist/types/plugins/SlotLayout/ThreadListSlot.d.ts +8 -0
  1594. package/dist/types/plugins/SlotLayout/ThreadListSlot.d.ts.map +1 -0
  1595. package/dist/types/plugins/SlotLayout/ThreadSlot.d.ts +10 -0
  1596. package/dist/types/plugins/SlotLayout/ThreadSlot.d.ts.map +1 -0
  1597. package/dist/types/plugins/SlotLayout/hooks/index.d.ts +3 -0
  1598. package/dist/types/plugins/SlotLayout/hooks/index.d.ts.map +1 -0
  1599. package/dist/types/plugins/SlotLayout/hooks/useLayoutViewState.d.ts +5 -0
  1600. package/dist/types/plugins/SlotLayout/hooks/useLayoutViewState.d.ts.map +1 -0
  1601. package/dist/types/plugins/SlotLayout/hooks/useSlotEntity.d.ts +162 -0
  1602. package/dist/types/plugins/SlotLayout/hooks/useSlotEntity.d.ts.map +1 -0
  1603. package/dist/types/plugins/SlotLayout/index.d.ts +12 -0
  1604. package/dist/types/plugins/SlotLayout/index.d.ts.map +1 -0
  1605. package/dist/types/plugins/SlotLayout/layout/Slot.d.ts +8 -0
  1606. package/dist/types/plugins/SlotLayout/layout/Slot.d.ts.map +1 -0
  1607. package/dist/types/plugins/SlotLayout/layout/WorkspaceLayout.d.ts +11 -0
  1608. package/dist/types/plugins/SlotLayout/layout/WorkspaceLayout.d.ts.map +1 -0
  1609. package/dist/types/plugins/SlotLayout/layoutController/LayoutController.d.ts +25 -0
  1610. package/dist/types/plugins/SlotLayout/layoutController/LayoutController.d.ts.map +1 -0
  1611. package/dist/types/plugins/SlotLayout/layoutController/layoutControllerTypes.d.ts +121 -0
  1612. package/dist/types/plugins/SlotLayout/layoutController/layoutControllerTypes.d.ts.map +1 -0
  1613. package/dist/types/plugins/SlotLayout/layoutController/serialization.d.ts +6 -0
  1614. package/dist/types/plugins/SlotLayout/layoutController/serialization.d.ts.map +1 -0
  1615. package/dist/types/plugins/SlotLayout/slotBinding.d.ts +85 -0
  1616. package/dist/types/plugins/SlotLayout/slotBinding.d.ts.map +1 -0
  1617. package/dist/types/plugins/SlotLayout/slotRegistry.d.ts +60 -0
  1618. package/dist/types/plugins/SlotLayout/slotRegistry.d.ts.map +1 -0
  1619. package/dist/types/plugins/SlotLayout/workspaceNavigationAdapter.d.ts +26 -0
  1620. package/dist/types/plugins/SlotLayout/workspaceNavigationAdapter.d.ts.map +1 -0
  1621. package/dist/types/store/hooks/useStateStore.d.ts +1 -1
  1622. package/dist/types/store/hooks/useStateStore.d.ts.map +1 -1
  1623. package/dist/types/types/index.d.ts +0 -1
  1624. package/dist/types/types/index.d.ts.map +1 -1
  1625. package/dist/types/types/types.d.ts +0 -10
  1626. package/dist/types/types/types.d.ts.map +1 -1
  1627. package/dist/types/utils/getChannel.d.ts +2 -2
  1628. package/dist/types/utils/getChannel.d.ts.map +1 -1
  1629. package/dist/types/utils/useStableCallback.d.ts +1 -1
  1630. package/package.json +34 -20
  1631. package/dist/cjs/NotificationList.6abbee1c.js +0 -9459
  1632. package/dist/cjs/NotificationList.6abbee1c.js.map +0 -1
  1633. package/dist/cjs/useChannelHeaderOnlineStatus.7e17671e.js +0 -961
  1634. package/dist/cjs/useChannelHeaderOnlineStatus.7e17671e.js.map +0 -1
  1635. package/dist/cjs/useInertWhenHidden.22151beb.js +0 -6426
  1636. package/dist/cjs/useInertWhenHidden.22151beb.js.map +0 -1
  1637. package/dist/es/NotificationList.db01a56d.mjs +0 -7703
  1638. package/dist/es/NotificationList.db01a56d.mjs.map +0 -1
  1639. package/dist/es/ReactPlayerWrapper.d2ae5941.mjs.map +0 -1
  1640. package/dist/es/audioProcessing.766ca76c.mjs.map +0 -1
  1641. package/dist/es/channel-detail.mjs.map +0 -1
  1642. package/dist/es/emojis.mjs.map +0 -1
  1643. package/dist/es/index.mjs.map +0 -1
  1644. package/dist/es/useChannelHeaderOnlineStatus.a9357343.mjs +0 -771
  1645. package/dist/es/useChannelHeaderOnlineStatus.a9357343.mjs.map +0 -1
  1646. package/dist/es/useInertWhenHidden.3d5fbdba.mjs +0 -5765
  1647. package/dist/es/useInertWhenHidden.3d5fbdba.mjs.map +0 -1
  1648. package/dist/types/components/Channel/channelState.d.ts +0 -90
  1649. package/dist/types/components/Channel/channelState.d.ts.map +0 -1
  1650. package/dist/types/components/Channel/hooks/useCreateChannelStateContext.d.ts +0 -6
  1651. package/dist/types/components/Channel/hooks/useCreateChannelStateContext.d.ts.map +0 -1
  1652. package/dist/types/components/Channel/hooks/useCreateTypingContext.d.ts +0 -3
  1653. package/dist/types/components/Channel/hooks/useCreateTypingContext.d.ts.map +0 -1
  1654. package/dist/types/components/Channel/hooks/useEditMessageHandler.d.ts +0 -5
  1655. package/dist/types/components/Channel/hooks/useEditMessageHandler.d.ts.map +0 -1
  1656. package/dist/types/components/Channel/hooks/useMentionsHandlers.d.ts +0 -10
  1657. package/dist/types/components/Channel/hooks/useMentionsHandlers.d.ts.map +0 -1
  1658. package/dist/types/components/Channel/utils.d.ts +0 -33
  1659. package/dist/types/components/Channel/utils.d.ts.map +0 -1
  1660. package/dist/types/components/ChannelList/ChannelListUI.d.ts +0 -18
  1661. package/dist/types/components/ChannelList/ChannelListUI.d.ts.map +0 -1
  1662. package/dist/types/components/ChannelList/hooks/useChannelListShape.d.ts +0 -61
  1663. package/dist/types/components/ChannelList/hooks/useChannelListShape.d.ts.map +0 -1
  1664. package/dist/types/components/ChannelList/hooks/useConnectionRecoveredListener.d.ts +0 -2
  1665. package/dist/types/components/ChannelList/hooks/useConnectionRecoveredListener.d.ts.map +0 -1
  1666. package/dist/types/components/ChannelList/hooks/usePaginatedChannels.d.ts +0 -29
  1667. package/dist/types/components/ChannelList/hooks/usePaginatedChannels.d.ts.map +0 -1
  1668. package/dist/types/components/ChannelList/utils.d.ts +0 -46
  1669. package/dist/types/components/ChannelList/utils.d.ts.map +0 -1
  1670. package/dist/types/components/Chat/hooks/useChannelsQueryState.d.ts +0 -12
  1671. package/dist/types/components/Chat/hooks/useChannelsQueryState.d.ts.map +0 -1
  1672. package/dist/types/components/ChatView/ChatView.a11y.utility.d.ts.map +0 -1
  1673. package/dist/types/components/ChatView/ChatView.d.ts +0 -59
  1674. package/dist/types/components/ChatView/ChatView.d.ts.map +0 -1
  1675. package/dist/types/components/ChatView/index.d.ts +0 -2
  1676. package/dist/types/components/ChatView/index.d.ts.map +0 -1
  1677. package/dist/types/components/MessageComposer/AttachmentPreviewList/AttachmentUploadedSizeIndicator.d.ts +0 -14
  1678. package/dist/types/components/MessageComposer/AttachmentPreviewList/AttachmentUploadedSizeIndicator.d.ts.map +0 -1
  1679. package/dist/types/components/MessageComposer/hooks/useSubmitHandler.d.ts +0 -5
  1680. package/dist/types/components/MessageComposer/hooks/useSubmitHandler.d.ts.map +0 -1
  1681. package/dist/types/components/Search/hooks/useSearchFocusedMessage.d.ts +0 -2
  1682. package/dist/types/components/Search/hooks/useSearchFocusedMessage.d.ts.map +0 -1
  1683. package/dist/types/components/Thread/LegacyThreadContext.d.ts +0 -9
  1684. package/dist/types/components/Thread/LegacyThreadContext.d.ts.map +0 -1
  1685. package/dist/types/components/Window/Window.d.ts +0 -13
  1686. package/dist/types/components/Window/Window.d.ts.map +0 -1
  1687. package/dist/types/components/Window/index.d.ts +0 -2
  1688. package/dist/types/components/Window/index.d.ts.map +0 -1
  1689. package/dist/types/context/ChannelActionContext.d.ts +0 -46
  1690. package/dist/types/context/ChannelActionContext.d.ts.map +0 -1
  1691. package/dist/types/context/ChannelStateContext.d.ts +0 -51
  1692. package/dist/types/context/ChannelStateContext.d.ts.map +0 -1
  1693. package/dist/types/context/TypingContext.d.ts +0 -12
  1694. package/dist/types/context/TypingContext.d.ts.map +0 -1
  1695. package/dist/types/i18n/TranslationBuilder/TranslationBuilder.d.ts +0 -36
  1696. package/dist/types/i18n/TranslationBuilder/TranslationBuilder.d.ts.map +0 -1
  1697. package/dist/types/i18n/translations.d.ts +0 -14
  1698. package/dist/types/i18n/translations.d.ts.map +0 -1
  1699. package/dist/types/utils/getChannelConfig.d.ts +0 -8
  1700. package/dist/types/utils/getChannelConfig.d.ts.map +0 -1
  1701. /package/dist/types/{components/ChatView → plugins/SlotLayout}/ChatView.a11y.utility.d.ts +0 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Thread.373af587.js","names":[],"sources":["../../src/context/ChannelListContext.tsx","../../src/components/Dialog/service/DialogManager.ts","../../src/components/Dialog/hooks/useDialog.ts","../../src/components/Portal/Portal.ts","../../src/components/Dialog/service/DialogPortal.tsx","../../src/context/DialogManagerContext.tsx","../../src/context/MessageContext.tsx","../../src/a11y/a11yUtils.ts","../../src/a11y/hooks/useVirtualizedListboxKeyboardNavigation.ts","../../src/components/Message/Timestamp.tsx","../../src/components/Avatar/Avatar.tsx","../../src/components/Badge/Badge.tsx","../../src/components/Avatar/AvatarStack.tsx","../../src/components/Avatar/ChannelAvatar.tsx","../../src/components/Avatar/GroupAvatar.tsx","../../src/components/Avatar/utils.ts","../../src/components/Accessibility/AriaLiveOutletContext.ts","../../src/components/Accessibility/useAriaLiveAnnouncer.ts","../../src/components/VisuallyHidden/VisuallyHidden.tsx","../../src/components/Accessibility/AriaLiveOutlet.tsx","../../src/components/Accessibility/scheduling/useDebouncedAnnounce.ts","../../src/components/Notifications/NotificationConfigurationContext.tsx","../../src/components/Notifications/notificationTarget.ts","../../src/components/Notifications/hooks/useNotifications.ts","../../src/components/Notifications/hooks/useNotificationTarget.ts","../../src/components/Notifications/hooks/useNotificationApi.ts","../../src/components/Notifications/Notification.tsx","../../src/components/Notifications/NotificationList.tsx","../../src/components/Accessibility/hooks/useInteractionAnnouncements.ts","../../src/components/Dialog/service/DialogAnchor.tsx","../../src/components/UtilityComponents/useStableId.ts","../../src/components/Dialog/components/ContextMenu.tsx","../../src/components/EmptyStateIndicator/EmptyStateIndicator.tsx","../../src/components/InfiniteScrollPaginator/InfiniteScrollPaginator.tsx","../../src/components/InfiniteScrollPaginator/InfiniteScrollWithComponents.tsx","../../src/components/Loading/LoadingChannels.tsx","../../src/components/Loading/LoadingIndicator.tsx","../../src/a11y/hooks/useListboxKeyboardNavigation.ts","../../src/components/ChannelList/hooks/useChannelListKeyboardNavigation.ts","../../src/components/ChannelList/ChannelList.tsx","../../src/components/ChannelList/ChannelLists.tsx","../../src/components/ChannelList/ChannelListHeader.tsx","../../src/components/Search/SearchContext.tsx","../../src/utils/useStableCallback.ts","../../src/components/UtilityComponents/hooks/useMutationObserver.ts","../../src/components/Search/hooks/useAnnounceSearchResultCount.ts","../../src/components/Search/hooks/useSearchQueriesInProgress.ts","../../src/components/Search/hooks/useSearchResultsKeyboardNavigation.ts","../../src/components/Search/SearchBar/SearchBar.tsx","../../src/components/Search/SearchResults/SearchResultItem.tsx","../../src/components/Search/SearchSourceResultsContext.tsx","../../src/components/Search/SearchResults/SearchSourceResultsLoadingIndicator.tsx","../../src/components/Search/SearchResults/SearchSourceResultListFooter.tsx","../../src/components/Search/SearchResults/SearchSourceResultList.tsx","../../src/components/Search/SearchResults/SearchSourceResultsEmpty.tsx","../../src/components/Search/SearchResults/SearchSourceResultsHeader.tsx","../../src/components/Search/SearchResults/SearchSourceResults.tsx","../../src/components/Search/SearchResults/SearchResultsHeader.tsx","../../src/components/Search/SearchResults/SearchResultsPresearch.tsx","../../src/components/Search/SearchResults/SearchResults.tsx","../../src/components/Search/Search.tsx","../../src/components/ChannelList/ChannelNavigation.tsx","../../src/components/ChannelList/hooks/useSelectedChannelState.ts","../../src/components/ChannelList/hooks/useChannelMembershipState.ts","../../src/components/ChannelList/hooks/useChannelMembersState.ts","../../src/components/ChannelListItem/hooks/useIsChannelMuted.ts","../../src/components/ChannelListItem/ChannelListItemActionButtons.defaults.tsx","../../src/components/Chat/hooks/useSplitActionSet.ts","../../src/components/ChannelListItem/ChannelListItemActionButtons.tsx","../../src/components/ChannelListItem/ChannelListItemTimestamp.tsx","../../src/a11y/accessibleLabel.ts","../../src/components/ChannelListItem/hooks/useMessageDeliveryStatus.ts","../../src/context/MessageTranslationViewContext.tsx","../../src/components/Message/emojiRegex.ts","../../src/components/Message/utils.tsx","../../src/components/Message/renderText/remarkPlugins/htmlToTextPlugin.ts","../../src/components/Message/renderText/remarkPlugins/imageToLink.ts","../../src/components/Message/renderText/remarkPlugins/plusPlusToEmphasis.ts","../../src/components/AudioPlayback/AudioPlayer.ts","../../src/components/AudioPlayback/AudioPlaybackArbiter.ts","../../src/components/AudioPlayback/AudioPlayerPool.ts","../../src/components/AudioPlayback/plugins/AudioPlayerNotificationsPlugin.ts","../../src/components/Accessibility/hooks/useAudioPlaybackChangeAnnouncements.ts","../../src/components/AudioPlayback/WithAudioPlayback.tsx","../../src/components/ChannelListItem/utils.tsx","../../src/components/ChannelListItem/utils.a11y.ts","../../src/components/SummarizedMessagePreview/hooks/useLatestMessagePreview.ts","../../src/components/SummarizedMessagePreview/SummarizedMessagePreview.tsx","../../src/components/ChannelListItem/ChannelListItemUI.tsx","../../src/components/ChannelListItem/hooks/useChannelDisplayName.ts","../../src/components/ChannelListItem/hooks/useChannelPreviewInfo.ts","../../src/components/ChannelListItem/ChannelListItem.tsx","../../src/components/Threads/ThreadList/utils.a11y.ts","../../src/components/Threads/ThreadList/ThreadListItemUI.tsx","../../src/components/Threads/ThreadList/ThreadListItem.tsx","../../src/components/Threads/ThreadList/ThreadListEmptyPlaceholder.tsx","../../src/components/Threads/ThreadList/ThreadListUnseenThreadsBanner.tsx","../../src/components/Threads/ThreadList/useThreadHighlighting.ts","../../src/components/Threads/ThreadList/ThreadListLoadingIndicator.tsx","../../src/components/Threads/ThreadList/ThreadListHeader.tsx","../../src/components/Threads/ThreadList/ThreadList.tsx","../../src/context/WorkspaceNavigationContext.tsx","../../src/components/Channel/constants.ts","../../src/components/Channel/hooks/useChannelContainerClasses.ts","../../src/components/Channel/Channel.tsx","../../src/components/Thread/Thread.tsx"],"sourcesContent":["import type { PropsWithChildren } from 'react';\nimport React, { createContext, useContext } from 'react';\n\nimport type { ChannelPaginator } from 'stream-chat';\n\nexport type ChannelListContextValue = {\n /**\n * The primary channel paginator held by the `ChannelManager` on `ChatContext`.\n * Read the loaded channels reactively with `useStateStore(paginator.state, …)`, load the next\n * page with `paginator.next()`, and mutate the loaded list (e.g. prepend a just-opened channel)\n * via `paginator.setItems({ valueOrFactory })`. Undefined when rendered outside a channel list.\n */\n paginator?: ChannelPaginator;\n};\n\nexport const ChannelListContext = createContext<ChannelListContextValue | undefined>(\n undefined,\n);\n\n/**\n * Context provider exposing the primary channel paginator to components rendered within the\n * channel list (e.g. search results, member actions, notification targeting).\n */\nexport const ChannelListContextProvider = ({\n children,\n value,\n}: PropsWithChildren<{\n value: ChannelListContextValue;\n}>) => (\n <ChannelListContext.Provider value={value}>{children}</ChannelListContext.Provider>\n);\n\nexport const useChannelListContext = (): ChannelListContextValue =>\n useContext(ChannelListContext) ?? {};\n","import { nanoid } from 'nanoid';\nimport { StateStore } from '@stream-io/state-store';\n\nexport type GetDialogParams = {\n id: DialogId;\n};\nexport type GetOrCreateDialogParams = GetDialogParams & {\n /**\n * Optional per-dialog override.\n * If undefined, manager-level `closeOnClickOutside` is used.\n */\n closeOnClickOutside?: boolean;\n};\n\ntype DialogId = string;\n\nexport type Dialog = {\n close: () => void;\n closeOnClickOutside?: boolean;\n id: DialogId;\n isOpen: boolean | undefined;\n open: (zIndex?: number) => void;\n removalTimeout: NodeJS.Timeout | undefined;\n remove: () => void;\n toggle: (closeAll?: boolean) => void;\n};\n\nexport type DialogManagerOptions = {\n /** Enables closing all dialogs in this manager when clicking overlay/outside area. */\n closeOnClickOutside?: boolean;\n id?: string;\n};\n\ntype Dialogs = Record<DialogId, Dialog>;\n\nexport type DialogManagerState = {\n dialogsById: Dialogs;\n openedDialogIds: DialogId[];\n};\n\n/**\n * Keeps a map of Dialog objects.\n * Dialog can be controlled via `Dialog` object retrieved using `useDialog()` hook.\n * The hook returns an object with the following API:\n *\n * - `dialog.open()` - opens the dialog\n * - `dialog.close()` - closes the dialog\n * - `dialog.toggle()` - toggles the dialog open state. Accepts boolean argument closeAll. If enabled closes any other dialog that would be open.\n * - `dialog.remove()` - removes the dialog object reference from the state (primarily for cleanup purposes)\n */\nexport class DialogManager {\n /** Manager-level outside click policy used by DialogPortal dismiss handlers. */\n closeOnClickOutside: boolean;\n id: string;\n state = new StateStore<DialogManagerState>({\n dialogsById: {},\n openedDialogIds: [],\n });\n\n constructor({ closeOnClickOutside = true, id }: DialogManagerOptions = {}) {\n this.closeOnClickOutside = closeOnClickOutside;\n this.id = id ?? nanoid();\n }\n\n get openDialogCount() {\n return this.state.getLatestValue().openedDialogIds.length;\n }\n\n get(id: DialogId): Dialog | undefined {\n return this.state.getLatestValue().dialogsById[id];\n }\n\n getOrCreate({ closeOnClickOutside, id }: GetOrCreateDialogParams) {\n let dialog = this.get(id);\n if (!dialog) {\n dialog = {\n close: () => {\n this.close(id);\n },\n closeOnClickOutside,\n id,\n isOpen: false,\n open: () => {\n this.open({ id });\n },\n removalTimeout: undefined,\n remove: () => {\n this.remove(id);\n },\n toggle: (closeAll = false) => {\n this.toggle({ id }, closeAll);\n },\n };\n this.state.next((current) => ({\n ...current,\n dialogsById: { ...current.dialogsById, [id]: dialog as Dialog },\n }));\n }\n\n const shouldUpdateDialogSettings =\n dialog.closeOnClickOutside !== closeOnClickOutside || !!dialog.removalTimeout;\n\n if (shouldUpdateDialogSettings) {\n if (dialog.removalTimeout) clearTimeout(dialog.removalTimeout);\n this.state.next((current) => ({\n ...current,\n dialogsById: {\n ...current.dialogsById,\n [id]: {\n ...current.dialogsById[id],\n closeOnClickOutside,\n removalTimeout: undefined,\n },\n },\n openedDialogIds: current.dialogsById[id]?.isOpen\n ? [...current.openedDialogIds.filter((dialogId) => dialogId !== id), id]\n : current.openedDialogIds,\n }));\n }\n\n return dialog;\n }\n\n open(params: GetOrCreateDialogParams, closeRest?: boolean) {\n const dialog = this.getOrCreate(params);\n if (dialog.isOpen) return;\n if (closeRest) {\n this.closeAll();\n }\n this.state.next((current) => ({\n ...current,\n dialogsById: { ...current.dialogsById, [dialog.id]: { ...dialog, isOpen: true } },\n openedDialogIds: [\n ...current.openedDialogIds.filter((dialogId) => dialogId !== dialog.id),\n dialog.id,\n ],\n }));\n }\n\n close(id: DialogId) {\n const dialog = this.state.getLatestValue().dialogsById[id];\n if (!dialog?.isOpen) return;\n this.state.next((current) => ({\n ...current,\n dialogsById: { ...current.dialogsById, [dialog.id]: { ...dialog, isOpen: false } },\n openedDialogIds: current.openedDialogIds.filter((dialogId) => dialogId !== id),\n }));\n }\n\n closeAll() {\n Object.values(this.state.getLatestValue().dialogsById).forEach((dialog) =>\n dialog.close(),\n );\n }\n\n toggle(params: GetOrCreateDialogParams, closeAll = false) {\n if (this.state.getLatestValue().dialogsById[params.id]?.isOpen) {\n this.close(params.id);\n } else {\n this.open(params, closeAll);\n }\n }\n\n remove = (id: DialogId) => {\n const dialog = this.get(id);\n if (!dialog) return;\n\n if (dialog.removalTimeout) {\n clearTimeout(dialog.removalTimeout);\n }\n\n this.state.next((current) => {\n const newDialogs = { ...current.dialogsById };\n delete newDialogs[id];\n return {\n ...current,\n dialogsById: newDialogs,\n openedDialogIds: current.openedDialogIds.filter((dialogId) => dialogId !== id),\n };\n });\n };\n\n /**\n * Marks the dialog state as unused. If the dialog id is referenced again quickly,\n * the state will not be removed. Otherwise, the state will be removed after\n * a short timeout.\n */\n markForRemoval(id: DialogId) {\n const dialog = this.get(id);\n\n if (!dialog) {\n return;\n }\n\n this.state.next((current) => ({\n ...current,\n dialogsById: {\n ...current.dialogsById,\n [id]: {\n ...dialog,\n removalTimeout: setTimeout(() => {\n this.remove(id);\n }, 16),\n },\n },\n openedDialogIds: current.openedDialogIds.filter((dialogId) => dialogId !== id),\n }));\n }\n\n cancelPendingRemoval(id: DialogId) {\n const dialog = this.get(id);\n\n if (!dialog?.removalTimeout) {\n return;\n }\n\n clearTimeout(dialog.removalTimeout);\n\n this.state.next((current) => ({\n ...current,\n dialogsById: {\n ...current.dialogsById,\n [id]: {\n ...current.dialogsById[id],\n removalTimeout: undefined,\n },\n },\n openedDialogIds: current.dialogsById[id]?.isOpen\n ? [...current.openedDialogIds.filter((dialogId) => dialogId !== id), id]\n : current.openedDialogIds,\n }));\n }\n}\n","import { useCallback, useEffect } from 'react';\nimport {\n modalDialogManagerId,\n useDialogManager,\n useNearestDialogManagerContext,\n} from '../../../context';\nimport { useStateStore } from '../../../store';\n\nimport type {\n DialogManagerState,\n GetOrCreateDialogParams,\n} from '../service/DialogManager';\n\nexport type UseDialogParams = GetOrCreateDialogParams & {\n dialogManagerId?: string;\n};\n\nexport const useDialog = ({\n closeOnClickOutside,\n dialogManagerId,\n id,\n}: UseDialogParams) => {\n const { dialogManager } = useDialogManager({ dialogManagerId });\n\n useEffect(() => {\n dialogManager.cancelPendingRemoval(id);\n\n return () => {\n // Since this cleanup can run even if the component is still mounted\n // and dialog id is unchanged (e.g. in <StrictMode />), it's safer to\n // mark state as unused and only remove it after a timeout, rather than\n // to remove it immediately.\n dialogManager.markForRemoval(id);\n };\n }, [dialogManager, id]);\n\n return dialogManager.getOrCreate({ closeOnClickOutside, id });\n};\n\nexport const useDialogOnNearestManager = ({ id }: Pick<UseDialogParams, 'id'>) => {\n const { dialogManager } = useNearestDialogManagerContext() ?? {};\n const dialog = useDialog({ dialogManagerId: dialogManager?.id, id });\n\n return {\n dialog,\n dialogManager,\n };\n};\n\nexport const modalDialogId = 'modal-dialog' as const;\n\nexport const useModalDialog = (id: string = modalDialogId) =>\n useDialog({ dialogManagerId: modalDialogManagerId, id });\n\nexport const useDialogIsOpen = (id: string, dialogManagerId?: string) => {\n const { dialogManager } = useDialogManager({ dialogManagerId });\n const dialogIsOpenSelector = useCallback(\n ({ dialogsById }: DialogManagerState) => ({ isOpen: !!dialogsById[id]?.isOpen }),\n [id],\n );\n return useStateStore(dialogManager.state, dialogIsOpenSelector).isOpen;\n};\n\nexport const useModalDialogIsOpen = (id: string = modalDialogId) =>\n useDialogIsOpen(id, modalDialogManagerId);\n\nexport const useDialogIsTopmost = (id: string, dialogManagerId?: string) => {\n const { dialogManager } = useDialogManager({ dialogManagerId });\n const dialogIsTopmostSelector = useCallback(\n ({ openedDialogIds }: DialogManagerState) => ({\n isTopmost: openedDialogIds[openedDialogIds.length - 1] === id,\n }),\n [id],\n );\n return useStateStore(dialogManager.state, dialogIsTopmostSelector).isTopmost;\n};\n\nexport const useModalDialogIsTopmost = (id: string = modalDialogId) =>\n useDialogIsTopmost(id, modalDialogManagerId);\n\nconst openedDialogCountSelector = (nextValue: DialogManagerState) => ({\n openedDialogCount: nextValue.openedDialogIds.length,\n});\n\nexport const useOpenedDialogCount = ({\n dialogManagerId,\n}: { dialogManagerId?: string } = {}) => {\n const { dialogManager } = useDialogManager({ dialogManagerId });\n return useStateStore(dialogManager.state, openedDialogCountSelector).openedDialogCount;\n};\n","import type { PropsWithChildren, ReactPortal } from 'react';\nimport { useLayoutEffect, useState } from 'react';\nimport { createPortal } from 'react-dom';\n\nexport type PortalProps = {\n getPortalDestination: () => Element | null;\n isOpen?: boolean;\n};\n\nexport const Portal = ({\n children,\n getPortalDestination,\n isOpen,\n}: PropsWithChildren<PortalProps>): ReactPortal | null => {\n const [portalDestination, setPortalDestination] = useState<Element | null>(null);\n\n useLayoutEffect(() => {\n const destination = getPortalDestination();\n if (!destination || !isOpen) return;\n setPortalDestination(destination);\n }, [getPortalDestination, isOpen]);\n\n if (!portalDestination) return null;\n\n return createPortal(children, portalDestination);\n};\n","import clsx from 'clsx';\nimport type { PropsWithChildren } from 'react';\nimport React, { useCallback, useEffect, useState } from 'react';\nimport { useDialogIsOpen, useOpenedDialogCount } from '../hooks';\nimport { Portal } from '../../Portal/Portal';\nimport {\n modalDialogManagerId,\n useDialogManager,\n useNearestDialogManagerContext,\n} from '../../../context';\n\nconst shouldCloseOnOutsideClick = ({\n dialog,\n managerCloseOnClickOutside,\n}: {\n dialog: { closeOnClickOutside?: boolean };\n managerCloseOnClickOutside: boolean;\n}) => dialog.closeOnClickOutside ?? managerCloseOnClickOutside;\n\nexport type DialogPortalDestinationProps = {\n captureOutsideClicks?: boolean;\n className?: string;\n};\n\nexport const DialogPortalDestination = ({\n captureOutsideClicks,\n className,\n}: DialogPortalDestinationProps) => {\n const { dialogManager } = useNearestDialogManagerContext() ?? {};\n const openedDialogCount = useOpenedDialogCount({ dialogManagerId: dialogManager?.id });\n const [destinationRoot, setDestinationRoot] = useState<HTMLDivElement | null>(null);\n\n // Handle clicks outside dialog contents.\n // Clicks on the overlay itself or outside it close open dialogs;\n // only clicks on dialog contents (descendants) are ignored.\n useEffect(() => {\n if (!destinationRoot || !dialogManager) return;\n\n const handleDocumentClick = (event: MouseEvent) => {\n const target = event.target as Node;\n const clickedOverlay = (target as HTMLElement).closest?.(\n '[data-str-chat__portal-id]',\n );\n if (clickedOverlay && clickedOverlay !== destinationRoot) return;\n if (target !== destinationRoot && destinationRoot.contains(target)) return;\n // Defer so target onClick handlers (e.g. context-menu toggle buttons) can run first.\n setTimeout(() => {\n Object.values(dialogManager.state.getLatestValue().dialogsById).forEach(\n (dialog) => {\n if (!dialog.isOpen) return;\n if (\n !shouldCloseOnOutsideClick({\n dialog,\n managerCloseOnClickOutside: dialogManager.closeOnClickOutside,\n })\n )\n return;\n dialogManager.close(dialog.id);\n },\n );\n }, 0);\n };\n\n document.addEventListener('click', handleDocumentClick, { capture: true });\n\n return () => {\n document.removeEventListener('click', handleDocumentClick, { capture: true });\n };\n }, [destinationRoot, dialogManager]);\n\n if (!openedDialogCount) return null;\n\n const isModalDialogManager = dialogManager?.id === modalDialogManagerId;\n\n return (\n <div\n className={clsx(\n 'str-chat__dialog-overlay',\n {\n 'str-chat__dialog-overlay--modal': isModalDialogManager,\n 'str-chat__dialog-overlay--with-outside-click-capture': captureOutsideClicks,\n },\n className,\n )}\n data-str-chat__portal-id={dialogManager?.id}\n data-testid='str-chat__dialog-overlay'\n ref={setDestinationRoot}\n style={\n {\n '--str-chat__dialog-overlay-height': openedDialogCount > 0 ? '100%' : '0',\n } as React.CSSProperties\n }\n />\n );\n};\n\ntype DialogPortalEntryProps = {\n dialogId: string;\n dialogManagerId?: string;\n};\n\nexport const DialogPortalEntry = ({\n children,\n dialogId,\n dialogManagerId,\n}: PropsWithChildren<DialogPortalEntryProps>) => {\n const { dialogManager } = useDialogManager({ dialogId, dialogManagerId });\n const dialogIsOpen = useDialogIsOpen(dialogId, dialogManagerId);\n\n const getPortalDestination = useCallback(\n () => document.querySelector(`div[data-str-chat__portal-id=\"${dialogManager.id}\"]`),\n [dialogManager.id],\n );\n\n return (\n <Portal getPortalDestination={getPortalDestination} isOpen={dialogIsOpen}>\n {children}\n </Portal>\n );\n};\n","import React, {\n type PropsWithChildren,\n useContext,\n useEffect,\n useMemo,\n useState,\n} from 'react';\nimport { StateStore } from '@stream-io/state-store';\n\nimport { DialogManager } from '../components/Dialog/service/DialogManager';\nimport {\n DialogPortalDestination,\n type DialogPortalDestinationProps,\n} from '../components/Dialog/service/DialogPortal';\nimport type { PropsWithChildrenOnly } from '../types/types';\n\ntype DialogManagerId = string;\n\ntype DialogManagersState = Record<DialogManagerId, DialogManager | undefined>;\nconst dialogManagersRegistry: StateStore<DialogManagersState> = new StateStore({});\n\nconst getDialogManager = (id: string): DialogManager | undefined =>\n dialogManagersRegistry.getLatestValue()[id];\n\nconst getOrCreateDialogManager = ({\n closeOnClickOutside,\n id,\n}: {\n closeOnClickOutside?: boolean;\n id: string;\n}) => {\n let manager = getDialogManager(id);\n if (!manager) {\n manager = new DialogManager({ closeOnClickOutside, id });\n dialogManagersRegistry.partialNext({ [id]: manager });\n } else if (typeof closeOnClickOutside === 'boolean') {\n manager.closeOnClickOutside = closeOnClickOutside;\n }\n return manager;\n};\n\nconst removeDialogManager = (id: string) => {\n if (!getDialogManager(id)) return;\n dialogManagersRegistry.partialNext({ [id]: undefined });\n};\n\ntype DialogManagerProviderContextValue = {\n dialogManager: DialogManager;\n};\n\nconst DialogManagerProviderContext = React.createContext<\n DialogManagerProviderContextValue | undefined\n>(undefined);\n\ntype DialogManagerProviderProps = PropsWithChildren<{\n /**\n * Manager-level outside click policy.\n * When `true`, clicking overlay or outside overlay-covered area closes all dialogs\n * in this manager. When `false`, outside clicks do not dismiss dialogs.\n */\n closeOnClickOutside?: boolean;\n portalDestinationProps?: DialogPortalDestinationProps;\n id?: string;\n}>;\n\n/**\n * Creates/provides a dialog manager and its portal destination.\n */\nexport const DialogManagerProvider = ({\n children,\n closeOnClickOutside,\n id,\n portalDestinationProps,\n}: DialogManagerProviderProps) => {\n const [dialogManager, setDialogManager] = useState<DialogManager | null>(() => {\n if (id) return getDialogManager(id) ?? null;\n return new DialogManager({ closeOnClickOutside }); // will not be included in the registry\n });\n\n useEffect(() => {\n if (!id) return;\n setDialogManager(getOrCreateDialogManager({ closeOnClickOutside, id }));\n return () => {\n removeDialogManager(id);\n setDialogManager(null);\n };\n }, [closeOnClickOutside, id]);\n\n // temporarily do not render until a new dialog manager is created\n if (!dialogManager) return null;\n\n return (\n <DialogManagerProviderContext.Provider value={{ dialogManager }}>\n {children}\n <DialogPortalDestination {...portalDestinationProps} />\n </DialogManagerProviderContext.Provider>\n );\n};\n\nexport type UseDialogManagerParams = {\n dialogId?: string;\n dialogManagerId?: string;\n};\n\nconst getManagerFromStore = ({\n dialogId,\n dialogManagerId,\n newState,\n previousState,\n}: UseDialogManagerParams & {\n newState: DialogManagersState;\n previousState: DialogManagersState | undefined;\n}) => {\n let managerInNewState: DialogManager | undefined;\n let managerInPrevState: DialogManager | undefined;\n if (dialogManagerId) {\n if (!dialogId) {\n managerInNewState = newState[dialogManagerId];\n managerInPrevState = previousState?.[dialogManagerId];\n } else {\n if (newState[dialogManagerId]?.get(dialogId)) {\n managerInNewState = newState[dialogManagerId];\n }\n if (previousState?.[dialogManagerId]?.get(dialogId)) {\n managerInPrevState = previousState[dialogManagerId];\n }\n }\n } else if (dialogId) {\n managerInNewState = Object.values(newState).find(\n (dialogMng) => dialogId && dialogMng?.get(dialogId),\n );\n managerInPrevState =\n previousState &&\n Object.values(previousState).find(\n (dialogMng) => dialogId && dialogMng?.get(dialogId),\n );\n }\n\n return { managerInNewState, managerInPrevState };\n};\n\n/**\n * Retrieves the nearest dialog manager or searches for the dialog manager by dialog manager id or dialog id.\n * Dialog id will take precedence over dialog manager id if both are provided and dialog manager is found by dialog id.\n */\nexport const useDialogManager = ({\n dialogId,\n dialogManagerId,\n}: UseDialogManagerParams = {}) => {\n const nearestDialogManagerContext = useContext(DialogManagerProviderContext);\n\n const [dialogManagerContext, setDialogManagerContext] = useState<\n DialogManagerProviderContextValue | undefined\n >(() => {\n const { managerInNewState } = getManagerFromStore({\n dialogId,\n dialogManagerId,\n newState: dialogManagersRegistry.getLatestValue(),\n previousState: undefined,\n });\n return managerInNewState\n ? { dialogManager: managerInNewState }\n : nearestDialogManagerContext;\n });\n\n useEffect(() => {\n if (!dialogId && !dialogManagerId) return;\n const unsubscribe = dialogManagersRegistry.subscribeWithSelector(\n (state) => state,\n (newState, previousState) => {\n const { managerInNewState, managerInPrevState } = getManagerFromStore({\n dialogId,\n dialogManagerId,\n newState,\n previousState,\n });\n\n if (!managerInPrevState || managerInNewState?.id !== managerInPrevState.id) {\n setDialogManagerContext((prevState) => {\n if (prevState?.dialogManager.id === managerInNewState?.id) return prevState;\n // an unresolved manager is caught by the guard below\n return {\n dialogManager:\n managerInNewState || nearestDialogManagerContext?.dialogManager,\n } as DialogManagerProviderContextValue;\n });\n }\n },\n );\n return () => {\n unsubscribe();\n };\n }, [dialogId, dialogManagerId, nearestDialogManagerContext?.dialogManager]);\n\n if (!dialogManagerContext?.dialogManager) {\n throw new Error(\n `useDialogManager could not resolve a dialog manager (manager id: ${dialogManagerId}, dialog id: ${dialogId}). Make sure the caller is rendered within <DialogManagerProvider>.`,\n );\n }\n\n return dialogManagerContext;\n};\n\nexport const modalDialogManagerId = 'modal-dialog-manager' as const;\n\nexport const ModalDialogManagerProvider = ({ children }: PropsWithChildrenOnly) => (\n <DialogManagerProvider id={modalDialogManagerId}>{children}</DialogManagerProvider>\n);\n\nexport const useModalDialogManager = () =>\n useMemo(() => getDialogManager(modalDialogManagerId), []);\n\nexport const useNearestDialogManagerContext = () =>\n useContext(DialogManagerProviderContext);\n","import type { PropsWithChildren } from 'react';\nimport React, { useContext } from 'react';\n\nimport type {\n DeleteMessageOptions,\n LocalMessage,\n ReactionResponse,\n SortParamRequest,\n UserResponse,\n} from 'stream-chat';\n\nimport type { ActionHandlerReturnType } from '../components/Message/hooks/useActionHandler';\nimport type { ReactEventHandler } from '../components/Message/types';\nimport type { GroupStyle } from '../components/MessageList/utils';\nimport type { ReactionsComparator, ReactionType } from '../components/Reactions/types';\n\nimport type { RenderTextFunction } from '../components/Message/renderText';\nimport { requireContext } from './requireContext';\n\nexport type MessageContextValue = {\n /** Function to send an action in a Channel */\n handleAction: ActionHandlerReturnType;\n /** Function to delete a message in a Channel */\n handleDelete: (options?: DeleteMessageOptions) => Promise<void> | void;\n /** Function to fetch the message reactions */\n handleFetchReactions: (\n reactionType?: ReactionType,\n sort?: SortParamRequest[],\n ) => Promise<Array<ReactionResponse>>;\n /** Function to flag a message in a Channel */\n handleFlag: ReactEventHandler;\n /** Function to mark message and the messages that follow it as unread in a Channel */\n handleMarkUnread: ReactEventHandler;\n /** Function to mute a user in a Channel */\n handleMute: ReactEventHandler;\n /** Function to open a thread for the message (routed through ChatView navigation) */\n handleOpenThread: ReactEventHandler;\n /** Function to pin a Message in a Channel */\n handlePin: ReactEventHandler;\n /** Function to post a reaction on a Message */\n handleReaction: (\n reactionType: string,\n event: React.BaseSyntheticEvent,\n ) => Promise<void>;\n /** Function to resend a failed message */\n handleRetry: (message: LocalMessage) => Promise<void> | void;\n /** Function that returns whether the Message belongs to the current user */\n isMyMessage: () => boolean;\n /** The message object */\n message: LocalMessage;\n /** Handler function for a click event on an @mention in Message */\n onMentionsClickMessage: ReactEventHandler;\n /** Handler function for a hover event on an @mention in Message */\n onMentionsHoverMessage: ReactEventHandler;\n /** Handler function for a click event on the user that posted the Message */\n onUserClick: ReactEventHandler;\n /** Handler function for a hover event on the user that posted the Message */\n onUserHover: ReactEventHandler;\n /** Call this function to keep message list scrolled to the bottom when the scroll height increases, e.g. an element appears below the last message (only used in the `VirtualizedMessageList`) */\n autoscrollToBottom?: () => void;\n /** Message component configuration prop. If true, picking a reaction from the `ReactionSelector` component will close the selector */\n closeReactionSelectorOnClick?: boolean;\n /** An array of user IDs that have confirmed the message delivery to their device */\n deliveredTo?: UserResponse[];\n /** If true, the message is the last one in a group sent by a specific user (only used in the `VirtualizedMessageList`) */\n endOfGroup?: boolean;\n /** If true, the message is the first one in a group sent by a specific user (only used in the `VirtualizedMessageList`) */\n firstOfGroup?: boolean;\n /** Override the default formatting of the date. This is a function that has access to the original date object, returns a string */\n formatDate?: (date: Date) => string;\n /** If true, group messages sent by each user (only used in the `VirtualizedMessageList`) */\n groupedByUser?: boolean;\n /** A list of styles to apply to this message, ie. top, bottom, single */\n groupStyles?: GroupStyle[];\n /** Whether to highlight and focus the message on load */\n highlighted?: boolean;\n /** Whether the threaded message is the first in the thread list */\n initialMessage?: boolean;\n /**\n * A factory function that determines whether a message is AI generated or not.\n */\n isMessageAIGenerated?: (message: LocalMessage) => boolean;\n /** Latest own message in currently displayed message set. */\n lastOwnMessage?: LocalMessage;\n /** Latest message id on current channel */\n lastReceivedId?: string | null;\n /** DOMRect object for parent MessageList component */\n messageListRect?: DOMRect;\n /** Sort options to provide to a reactions query */\n reactionDetailsSort?: SortParamRequest[];\n /** A list of users that have read this Message */\n readBy?: UserResponse[];\n /** When set, shows the sender avatar in a grid layout. Values: true | 'incoming' | 'outgoing'. */\n showAvatar?: boolean | 'incoming' | 'outgoing';\n /** Custom function to render message text content, defaults to the renderText function: [utils](https://github.com/GetStream/stream-chat-react/blob/master/src/utils.tsx) */\n renderText?: RenderTextFunction;\n /** Keep track of read receipts for each message sent by the user. When disabled, only the last own message delivery / read status is rendered. */\n returnAllReadData?: boolean;\n /** Comparator function to sort reactions, defaults to chronological order */\n sortReactions?: ReactionsComparator;\n /** If true, the Message is rendered inside a thread's reply list */\n threadList?: boolean;\n /** render HTML instead of markdown. Posting HTML is only allowed server-side */\n unsafeHTML?: boolean;\n /**\n * User-specific view for translated messages: which text to show.\n * - `'original'`: show `message.text` (source language).\n * - `'translated'`: show the translation for the **current user language** (from\n * `useTranslationContext().userLanguage`), i.e. `message.i18n[userLanguage + '_text']`\n * or fallback to `message.text` when missing. Resolved via `getTranslatedMessageText`.\n */\n translationView?: 'original' | 'translated';\n /** Set whether this message shows original or translated text (user-specific, does not change message data). */\n setTranslationView?: (view: 'original' | 'translated') => void;\n};\n\nexport const MessageContext = React.createContext<MessageContextValue | undefined>(\n undefined,\n);\n\nexport const MessageProvider = ({\n children,\n value,\n}: PropsWithChildren<{\n value: MessageContextValue;\n}>) => (\n <MessageContext.Provider value={value as unknown as MessageContextValue}>\n {children}\n </MessageContext.Provider>\n);\n\nexport const useMessageContext = () =>\n requireContext(useContext(MessageContext), 'useMessageContext', 'MessageProvider');\n","const MENU_KEYBOARD_NAVIGATION_KEYS = ['ArrowDown', 'ArrowUp', 'End', 'Home'] as const;\n\ntype MenuKeyboardNavigationKey = (typeof MENU_KEYBOARD_NAVIGATION_KEYS)[number];\n\nconst isMenuKeyboardNavigationKey = (key: string): key is MenuKeyboardNavigationKey =>\n (MENU_KEYBOARD_NAVIGATION_KEYS as readonly string[]).includes(key);\n\ntype GetNextRovingFocusIndexArgs = {\n activeIndex: number;\n itemCount: number;\n key: string;\n};\n\nexport const getNextRovingFocusIndex = ({\n activeIndex,\n itemCount,\n key,\n}: GetNextRovingFocusIndexArgs): number | null => {\n if (itemCount <= 0 || !isMenuKeyboardNavigationKey(key)) return null;\n\n const lastIndex = itemCount - 1;\n\n if (key === 'Home') return 0;\n if (key === 'End') return lastIndex;\n if (activeIndex === -1) return key === 'ArrowUp' ? lastIndex : 0;\n if (key === 'ArrowUp') return activeIndex <= 0 ? lastIndex : activeIndex - 1;\n\n return activeIndex >= lastIndex ? 0 : activeIndex + 1;\n};\n\ntype RovingFocusKeyboardEvent = {\n currentTarget: Element;\n key: string;\n preventDefault: () => void;\n};\n\ntype CreateRovingFocusKeyDownHandlerParams<T extends { focus: () => void }> = {\n focusItem?: (item: T, event: RovingFocusKeyboardEvent) => void;\n getActiveIndex?: (items: T[], event: RovingFocusKeyboardEvent) => number;\n getItems: (event: RovingFocusKeyboardEvent) => T[];\n};\n\nconst getDefaultActiveIndex = <T extends { focus: () => void }>(items: T[]) => {\n const activeElement = document.activeElement;\n if (!(activeElement instanceof Element)) return -1;\n\n return items.findIndex((item) => item instanceof Element && item === activeElement);\n};\n\nexport const createRovingFocusKeyDownHandler = <T extends { focus: () => void }>({\n focusItem = (item) => item.focus(),\n getActiveIndex = (items) => getDefaultActiveIndex(items),\n getItems,\n}: CreateRovingFocusKeyDownHandlerParams<T>) => {\n const handleKeyDown = (event: RovingFocusKeyboardEvent) => {\n const items = getItems(event);\n const activeIndex = getActiveIndex(items, event);\n const nextIndex = getNextRovingFocusIndex({\n activeIndex,\n itemCount: items.length,\n key: event.key,\n });\n\n if (nextIndex === null) return;\n\n event.preventDefault();\n const nextItem = items[nextIndex];\n if (!nextItem) return;\n focusItem(nextItem, event);\n };\n\n return handleKeyDown;\n};\n","import type { KeyboardEvent as ReactKeyboardEvent, RefObject } from 'react';\nimport { useCallback, useRef } from 'react';\n\nimport { getNextRovingFocusIndex } from '../a11yUtils';\n\nconst DEFAULT_OPTION_SELECTOR = '[role=\"option\"]';\n// After scrolling an off-window row into view, the row may not be in the DOM on the very next tick\n// (a virtual list's \"rendered\" callback can fire a frame before the row paints). Retry focusing it\n// across a few animation frames before giving up.\nconst MAX_FOCUS_ATTEMPTS_AFTER_SCROLL = 5;\n\n// Escape a value for use inside a quoted attribute selector (`[attr=\"value\"]`).\nconst escapeAttributeValue = (value: string) => value.replace(/([\"\\\\])/g, '\\\\$1');\n\nexport type VirtualizedListboxKeyboardNavigationParams<T> = {\n /** Stable id for an item; must equal the value the item's option carries in `itemIdAttribute`. */\n getItemId: (item: T) => string;\n /**\n * The attribute every option carries its id in (e.g. `'data-thread-id'`). Used both to read the id\n * off the focused element and to locate the target option in the DOM.\n */\n itemIdAttribute: string;\n /** The full, unvirtualized list — NOT just the rendered window. Roving indexes into this. */\n items: T[];\n /** Selector for the focusable option elements. Default `[role=\"option\"]`. */\n optionSelector?: string;\n /**\n * Bring the item at `index` into the rendered window, then invoke `onRendered` once it should be in\n * the DOM. For a virtualized list wrap the list's imperative scroll (e.g. Virtuoso's\n * `scrollIntoView({ index, done: onRendered })`); for a non-virtualized list just call\n * `onRendered()`.\n */\n scrollIndexIntoView: (index: number, onRendered: () => void) => void;\n /** Ref to the scrollable listbox container whose subtree holds the rendered options. */\n scrollerRef: RefObject<HTMLElement | null>;\n};\n\n/**\n * Vertical roving-focus keyboard navigation (ArrowUp/Down/Home/End) for a **virtualized** listbox,\n * where only a window of `role=\"option\"` rows exists in the DOM at a time.\n *\n * A DOM-query-and-`.focus()` approach (see {@link useListboxKeyboardNavigation}) can't work here: it\n * would only ever see the rendered window, so it would cycle within those rows and never scroll the\n * rest of the list into view. This hook instead indexes into the **full** `items` array, focuses the\n * target row if it is already rendered, and otherwise asks the list to scroll it into existence\n * (`scrollIndexIntoView`) and focuses it once painted (retrying across a few frames).\n *\n * Returns an `onKeyDown` to spread onto the scroll container (the `role=\"listbox\"` element). The\n * caller wires `scrollerRef` to that same element and provides `scrollIndexIntoView`. Stateless — the\n * active row is read live from `document.activeElement` on each key.\n */\nexport const useVirtualizedListboxKeyboardNavigation = <T>({\n getItemId,\n itemIdAttribute,\n items,\n optionSelector = DEFAULT_OPTION_SELECTOR,\n scrollerRef,\n scrollIndexIntoView,\n}: VirtualizedListboxKeyboardNavigationParams<T>) => {\n // Each roving key press bumps this. A deferred (post-scroll) focus chain captures the id at\n // schedule time and bails once it is superseded, so a slower older scroll can't steal focus back\n // to an outdated row after the user has pressed another key.\n const latestFocusRequestRef = useRef(0);\n\n // Focus the option for `items[index]` if it is currently in the DOM. Returns whether it was found.\n const focusOptionAt = useCallback(\n (index: number) => {\n const item = items[index];\n if (!item) return false;\n const option = scrollerRef.current?.querySelector<HTMLElement>(\n `${optionSelector}[${itemIdAttribute}=\"${escapeAttributeValue(getItemId(item))}\"]`,\n );\n if (!option) return false;\n option.focus();\n return true;\n },\n [getItemId, itemIdAttribute, items, optionSelector, scrollerRef],\n );\n\n const focusOptionAfterRender = useCallback(\n (\n index: number,\n requestId: number,\n attemptsLeft = MAX_FOCUS_ATTEMPTS_AFTER_SCROLL,\n ) => {\n // A newer key press superseded this chain — stop so it can't steal focus back.\n if (requestId !== latestFocusRequestRef.current) return;\n if (focusOptionAt(index) || attemptsLeft <= 0) return;\n requestAnimationFrame(() =>\n focusOptionAfterRender(index, requestId, attemptsLeft - 1),\n );\n },\n [focusOptionAt],\n );\n\n const onKeyDown = useCallback(\n (event: ReactKeyboardEvent<HTMLElement>) => {\n const active = document.activeElement;\n const activeId =\n active instanceof HTMLElement\n ? (active\n .closest<HTMLElement>(`[${itemIdAttribute}]`)\n ?.getAttribute(itemIdAttribute) ?? undefined)\n : undefined;\n const activeIndex =\n activeId != null ? items.findIndex((item) => getItemId(item) === activeId) : -1;\n const nextIndex = getNextRovingFocusIndex({\n activeIndex,\n itemCount: items.length,\n key: event.key,\n });\n if (nextIndex === null) return; // not a roving key — leave it alone\n\n event.preventDefault();\n event.stopPropagation();\n // Supersede any still-pending off-window focus chain from a previous key press.\n const requestId = ++latestFocusRequestRef.current;\n // Within the rendered window: focus right away (no scroll lag; native focus brings it fully\n // into view if it sat in the overscan). Otherwise scroll the row into existence, then focus it\n // once the list has painted it.\n if (focusOptionAt(nextIndex)) return;\n scrollIndexIntoView(nextIndex, () => focusOptionAfterRender(nextIndex, requestId));\n },\n [\n focusOptionAfterRender,\n focusOptionAt,\n getItemId,\n itemIdAttribute,\n items,\n scrollIndexIntoView,\n ],\n );\n\n return { onKeyDown };\n};\n","import React, { useContext, useMemo } from 'react';\n\nimport { MessageContext } from '../../context/MessageContext';\nimport { useTranslationContext } from '../../context/TranslationContext';\nimport { getDateString, isDate } from '../../i18n/utils';\nimport type { TimestampFormatterOptions } from '../../i18n/types';\n\nexport interface TimestampProps extends TimestampFormatterOptions {\n /* Adds a CSS class name to the component's outer `time` container. */\n customClass?: string;\n /* Timestamp to display */\n timestamp?: Date | string;\n}\n\nexport function Timestamp(props: TimestampProps) {\n const { calendar, calendarFormats, customClass, format, timestamp } = props;\n\n // also rendered outside a message (channel list items, composer previews)\n const { formatDate } = useContext(MessageContext) ?? {};\n const { t, tDateTimeParser } = useTranslationContext();\n\n const normalizedTimestamp =\n timestamp && isDate(timestamp) ? timestamp.toISOString() : timestamp;\n\n const when = useMemo(\n () =>\n getDateString({\n calendar,\n calendarFormats,\n format,\n formatDate,\n messageCreatedAt: normalizedTimestamp,\n t,\n tDateTimeParser,\n timestampTranslationKey: 'timestamp.MessageTimestamp',\n }),\n [\n calendar,\n calendarFormats,\n format,\n formatDate,\n normalizedTimestamp,\n t,\n tDateTimeParser,\n ],\n );\n\n if (!when) {\n return null;\n }\n\n return (\n <time\n className={customClass}\n dateTime={normalizedTimestamp}\n title={normalizedTimestamp}\n >\n {when}\n </time>\n );\n}\n","import clsx from 'clsx';\nimport React, {\n type ComponentPropsWithoutRef,\n type ComponentType,\n useEffect,\n useMemo,\n useState,\n} from 'react';\nimport { useComponentContextIcons } from '../../context';\n\nexport type AvatarProps = {\n /** Custom icon rendered when there is no image and no initials */\n FallbackIcon?: ComponentType<ComponentPropsWithoutRef<'svg'>>;\n /** URL of the avatar image */\n imageUrl?: string;\n /** Name of the user (first and last name), used for avatar image alt text and title fallback */\n userName?: string;\n /**\n * Initials that are used directly instead of generating intials from `userName` property.\n * @note Providing more than two characters will break the default UI.\n */\n initials?: string;\n /** Online status indicator, not rendered if not of type boolean */\n isOnline?: boolean;\n size: '2xl' | 'xl' | 'lg' | 'md' | 'sm' | 'xs' | (string & {}) | null;\n} & ComponentPropsWithoutRef<'div'>;\n\nconst getInitials = (name?: string) => {\n const regex = /(\\p{L}{1})\\p{L}+/gu;\n\n if (!name || name.trim().length === 0) {\n return '';\n }\n\n const initials = Array.from(name?.matchAll(regex) || []);\n\n if (!initials.length) {\n return '';\n }\n\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n const startInitial = initials.at(0)![1];\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n const endInitial = initials.length > 1 ? initials.at(-1)![1] : '';\n\n return `${startInitial}${endInitial}`;\n};\n\n/**\n * A round avatar image with fallback to username's first letter\n */\nexport const Avatar = ({\n className,\n FallbackIcon,\n imageUrl,\n initials: customInitials,\n isOnline,\n size,\n userName,\n ...rest\n}: AvatarProps) => {\n const { IconUser } = useComponentContextIcons();\n // The prop still wins over the context slot: it targets one avatar, the slot rebrands all of them.\n const ResolvedFallbackIcon = FallbackIcon ?? IconUser;\n const [error, setError] = useState(false);\n\n useEffect(() => () => setError(false), [imageUrl]);\n\n const nameString = userName?.toString().trim() || '';\n\n const sizeAwareInitials = useMemo(() => {\n const initials = customInitials || getInitials(nameString);\n\n if (size === 'sm' || size === 'xs') {\n return initials.charAt(0);\n }\n\n return initials;\n }, [nameString, size, customInitials]);\n\n const showImage = typeof imageUrl === 'string' && imageUrl && !error;\n\n return (\n <div\n className={clsx(`str-chat__avatar`, className, {\n 'str-chat__avatar--multiple-letters': sizeAwareInitials.length > 1,\n 'str-chat__avatar--no-letters': !sizeAwareInitials.length,\n 'str-chat__avatar--one-letter': sizeAwareInitials.length === 1,\n [`str-chat__avatar--size-${size}`]: typeof size === 'string',\n })}\n data-testid='avatar'\n role='button'\n title={userName}\n {...rest}\n >\n {typeof isOnline === 'boolean' && (\n <div\n className={clsx('str-chat__avatar-status-badge', {\n 'str-chat__avatar-status-badge--offline': !isOnline,\n 'str-chat__avatar-status-badge--online': isOnline,\n })}\n />\n )}\n {showImage ? (\n <img\n alt={nameString}\n className='str-chat__avatar-image'\n data-testid='avatar-img'\n onError={() => setError(true)}\n src={imageUrl}\n />\n ) : (\n <>\n {!!sizeAwareInitials.length && (\n <div className='str-chat__avatar-initials' data-testid='avatar-fallback'>\n {sizeAwareInitials}\n </div>\n )}\n {!sizeAwareInitials.length && <ResolvedFallbackIcon />}\n </>\n )}\n </div>\n );\n};\n","import clsx from 'clsx';\nimport React, { type ComponentProps } from 'react';\nimport { useComponentContextIcons } from '../../context';\n\nexport type BadgeVariant =\n | 'default'\n | 'primary'\n | 'error'\n | 'neutral'\n | 'counter'\n | 'inverse';\n\nexport type BadgeSize = 'xs' | 'sm' | 'md' | 'lg' | null;\n\nexport type BadgeProps = ComponentProps<'div'> & {\n /** Visual variant mapping to design tokens */\n variant?: BadgeVariant;\n /** Size preset (typography and padding) */\n size?: BadgeSize;\n};\n\n/**\n * Compact pill/circle badge for counts and labels.\n * Uses design tokens: --badge-bg-*, --badge-text-*, --badge-border.\n */\nexport const Badge = ({\n children,\n className,\n size = 'md',\n variant = 'default',\n ...spanProps\n}: BadgeProps) => (\n <div\n {...spanProps}\n className={clsx(\n 'str-chat__badge',\n `str-chat__badge--variant-${variant}`,\n { [`str-chat__badge--size-${size}`]: size },\n className,\n )}\n >\n {children}\n </div>\n);\n\nexport const ErrorBadge = ({\n className,\n size = 'sm',\n ...rest\n}: Omit<BadgeProps, 'variant'>) => {\n const { IconExclamationMarkFill } = useComponentContextIcons();\n\n return (\n <Badge {...rest} className={className} size={size} variant='error'>\n <IconExclamationMarkFill />\n </Badge>\n );\n};\n","import React, { type ComponentProps, type ElementType, useMemo } from 'react';\nimport { useComponentContext } from '../../context';\nimport { type AvatarProps, Avatar as DefaultAvatar } from './Avatar';\nimport clsx from 'clsx';\nimport { Badge, type BadgeSize } from '../Badge';\n\nexport function AvatarStack({\n badgeSize,\n capLimit = 3,\n component: Component = 'div',\n displayInfo = [],\n size,\n}: {\n component?: ElementType;\n displayInfo?: (Pick<AvatarProps, 'imageUrl' | 'userName'> & { id?: string })[];\n size: 'md' | 'sm' | 'xs' | null;\n badgeSize?: BadgeSize;\n capLimit?: number;\n}) {\n const { Avatar = DefaultAvatar } = useComponentContext();\n\n const displayInfoToRender = useMemo(\n () => (displayInfo.length > capLimit ? displayInfo.slice(0, capLimit) : displayInfo),\n [displayInfo, capLimit],\n );\n const overflowCount = displayInfo.length - displayInfoToRender.length;\n\n if (!displayInfo.length) {\n return null;\n }\n\n return (\n <Component\n className={clsx('str-chat__avatar-stack', {\n [`str-chat__avatar-stack--size-${size}`]: typeof size === 'string',\n })}\n data-testid='avatar-stack'\n >\n {displayInfoToRender.map((info, index) => (\n <Avatar\n imageUrl={info.imageUrl}\n key={info.id ?? `${info.userName}-${info.imageUrl}-${index}`}\n size={size}\n userName={info.userName}\n />\n ))}\n {typeof overflowCount === 'number' && overflowCount > 0 && (\n <Badge\n className='str-chat__avatar-stack__count-badge'\n data-testid='avatar-stack-count-badge'\n size={badgeSize ?? size}\n variant='counter'\n >\n +{overflowCount}\n </Badge>\n )}\n </Component>\n );\n}\n\nexport type AvatarStackProps = ComponentProps<typeof AvatarStack>;\n","import React, { useMemo } from 'react';\n\nimport { GroupAvatar } from './';\nimport type { AvatarProps, GroupAvatarProps } from './';\n\nexport type ChannelAvatarProps = Partial<Omit<GroupAvatarProps & AvatarProps, 'size'>> & {\n size: GroupAvatarProps['size'] | AvatarProps['size'];\n};\n\nexport const ChannelAvatar = ({\n displayMembers,\n imageUrl,\n size,\n userName,\n ...sharedProps\n}: ChannelAvatarProps) => {\n const displayInfo = useMemo(() => {\n // Prefer the channel's own image; only derive the avatar from members when\n // there is no channel imageUrl to display.\n if (!imageUrl && displayMembers && displayMembers.length > 0) {\n return displayMembers;\n }\n\n return [\n {\n imageUrl,\n userName,\n },\n ];\n }, [displayMembers, imageUrl, userName]);\n\n return <GroupAvatar displayMembers={displayInfo} size={size} {...sharedProps} />;\n};\n","import clsx from 'clsx';\nimport React, { type ComponentPropsWithoutRef, useMemo } from 'react';\nimport { Avatar, type AvatarProps } from './Avatar';\nimport { Badge, type BadgeSize } from '../Badge';\n\nexport type GroupAvatarMember = {\n imageUrl?: string;\n userName?: string;\n id?: string;\n};\n\nexport type GroupAvatarProps = {\n /** List of members to show as avatars; at most 2 when there's more than 4 members, otherwise 4. Defaults to [] when omitted. */\n displayMembers?: GroupAvatarMember[];\n size: '2xl' | 'xl' | 'lg' | (string & {}) | null;\n badgeSize?: BadgeSize;\n isOnline?: boolean;\n} & ComponentPropsWithoutRef<'div'>;\n\n/**\n * Avatar component to display multiple users' avatars in a group.\n * Renders a single Avatar if fewer than 2 members. Otherwise, renders up to 2 avatars (when overflowCount is set) or 4, plus an optional +N badge.\n */\nexport const GroupAvatar = ({\n badgeSize,\n className,\n displayMembers = [],\n isOnline,\n size,\n ...rest\n}: GroupAvatarProps) => {\n const displayMembersToRender = useMemo(\n () => (displayMembers.length > 4 ? displayMembers.slice(0, 2) : displayMembers),\n [displayMembers],\n );\n const overflowCount = displayMembers.length - displayMembersToRender.length;\n\n if (displayMembers.length < 2) {\n const firstUser = displayMembers[0];\n\n return (\n <Avatar\n imageUrl={firstUser?.imageUrl}\n isOnline={isOnline}\n size={size}\n userName={firstUser?.userName}\n {...rest}\n />\n );\n }\n\n let avatarSize: AvatarProps['size'] = null;\n if (size === '2xl') {\n avatarSize = 'lg';\n } else if (size === 'xl') {\n avatarSize = 'md';\n } else if (size === 'lg') {\n avatarSize = 'sm';\n }\n\n return (\n <div\n className={clsx(\n 'str-chat__avatar-group',\n {\n 'str-chat__avatar-group--offline': typeof isOnline === 'boolean' && !isOnline,\n 'str-chat__avatar-group--online': typeof isOnline === 'boolean' && isOnline,\n [`str-chat__avatar-group--size-${size}`]: typeof size === 'string',\n },\n className,\n )}\n data-testid='group-avatar'\n role='button'\n {...rest}\n >\n {displayMembersToRender.map(({ id, imageUrl, userName }, index) => (\n <Avatar\n imageUrl={imageUrl}\n key={id || `${userName}-${imageUrl}-${index}`}\n size={avatarSize}\n userName={userName}\n />\n ))}\n {typeof overflowCount === 'number' && overflowCount > 0 && (\n <Badge\n className='str-chat__avatar-group__count-badge'\n data-testid='group-avatar-count-badge'\n size={badgeSize}\n variant='counter'\n >\n +{overflowCount}\n </Badge>\n )}\n </div>\n );\n};\n","import type { ComponentContextValue } from '../../context';\n\nexport const extractDisplayInfo: NonNullable<\n ComponentContextValue['extractDisplayInfo']\n> = ({ user }) => ({\n id: user?.id,\n imageUrl: user?.image,\n userName: user?.name, // || user?.id,\n});\n","import { createContext, useContext } from 'react';\n\nimport type { AriaLivePriority } from './useAriaLiveAnnouncer';\n\nexport type LiveAnnouncement = {\n id: number;\n message: string;\n};\n\nexport type AnnouncementsByPriority = {\n [key in AriaLivePriority]: LiveAnnouncement[];\n};\n\n/**\n * Internal coordination context between {@link AriaLiveAnnouncerProvider} (which owns the\n * announcement state and the outlet stack) and the {@link AriaLiveOutlet}s that render the\n * live regions. Not part of the public API — consumers announce via `useAriaLiveAnnouncer`.\n */\nexport type AriaLiveOutletContextValue = {\n /** The id of the single outlet that should currently render the live regions. */\n activeOutletId: symbol | null;\n /** Current announcements grouped by aria-live priority. */\n announcementsByPriority: AnnouncementsByPriority;\n /** Register an outlet. Higher `layer` wins; ties resolve to the most recently registered. */\n registerOutlet: (id: symbol, layer: number) => void;\n unregisterOutlet: (id: symbol) => void;\n};\n\nexport const AriaLiveOutletContext = createContext<\n AriaLiveOutletContextValue | undefined\n>(undefined);\n\nexport const useAriaLiveOutletContext = () => useContext(AriaLiveOutletContext);\n","import { createContext, useContext } from 'react';\n\nexport type AriaLivePriority = 'assertive' | 'polite';\n\nexport type AriaLiveAnnounceOptions = {\n priority?: AriaLivePriority;\n /**\n * Delay (ms) before the message is placed in the live region. Use to let a competing\n * screen-reader utterance settle first — e.g. a dialog-identity announcement made while a\n * field is being auto-focused is otherwise superseded by the field's focus announcement.\n * Omitted/0 announces immediately.\n */\n delayMs?: number;\n /**\n * When set, an identical `message` is announced at most once per this window (ms); a repeat\n * within the window is suppressed (returns a no-op cancel). The window starts when the message\n * is actually announced. Guards against duplicate announcements — e.g. an effect double-invoked\n * by React StrictMode, or rapid re-renders firing the same message.\n */\n dedupeMs?: number;\n};\n\n/**\n * Announce `message` to assistive technology. Delivery is controlled by an options object\n * (`priority` defaults to `'polite'`). Returns a `cancel` function: for a delayed announcement it\n * prevents a still-pending message from being announced (call it from effect cleanup so a closing\n * surface does not announce after unmount); for an immediate announcement it is a no-op.\n */\nexport type AriaLiveAnnounce = (\n message: string,\n options?: AriaLiveAnnounceOptions,\n) => () => void;\n\nexport type AriaLiveAnnouncerContextValue = {\n announce: AriaLiveAnnounce;\n};\n\nconst noopAnnounce: AriaLiveAnnounce = () => () => undefined;\n\nexport const AriaLiveAnnouncerContext = createContext<\n AriaLiveAnnouncerContextValue | undefined\n>(undefined);\n\n/**\n * Announcements are a progressive enhancement: outside an `AriaLiveAnnouncerProvider` this is a\n * no-op rather than an error.\n */\nexport const useAriaLiveAnnouncer = () =>\n useContext(AriaLiveAnnouncerContext)?.announce ?? noopAnnounce;\n","import React, { type ComponentPropsWithoutRef, type CSSProperties } from 'react';\n\nexport type VisuallyHiddenProps = ComponentPropsWithoutRef<'span'>;\n\nconst visuallyHiddenStyle: CSSProperties = {\n border: 0,\n clip: 'rect(0, 0, 0, 0)',\n height: '1px',\n margin: '-1px',\n overflow: 'hidden',\n padding: 0,\n position: 'absolute',\n whiteSpace: 'nowrap',\n width: '1px',\n};\n\n/**\n * Hides content visually while preserving it for assistive technologies.\n */\nexport const VisuallyHidden = ({ children, style, ...rest }: VisuallyHiddenProps) => (\n <span {...rest} style={{ ...visuallyHiddenStyle, ...style }}>\n {children}\n </span>\n);\n","import React, { useCallback, useEffect, useRef } from 'react';\n\nimport { useAriaLiveOutletContext } from './AriaLiveOutletContext';\nimport { Portal } from '../Portal/Portal';\nimport { VisuallyHidden } from '../VisuallyHidden';\n\nexport type AriaLiveOutletProps = {\n /**\n * Stacking layer. The {@link AriaLiveAnnouncerProvider} renders into the highest-layer\n * outlet (ties resolve to the most recently registered). Outlets inside an `aria-modal`\n * subtree must use a layer above the root outlet so announcements land inside the modal\n * (assistive technologies suppress live regions outside the active modal). Defaults to `0`.\n */\n layer?: number;\n /**\n * When true, render the live region into a `document.body` portal instead of in place.\n * Use for the root outlet; modal outlets must render in place (omit) so they stay inside\n * the `aria-modal` subtree.\n */\n portal?: boolean;\n};\n\n/**\n * Dumb render target for the unified announcer. Registers itself with the nearest\n * {@link AriaLiveAnnouncerProvider} and renders the polite/assertive live regions ONLY when\n * it is the active (innermost) outlet, so exactly one region is live at a time — always in\n * the active accessibility-tree scope. Mount one at the `Chat` root and one inside each\n * `aria-modal` dialog (with a higher `layer`).\n */\nexport const AriaLiveOutlet = ({ layer = 0, portal = false }: AriaLiveOutletProps) => {\n const context = useAriaLiveOutletContext();\n\n const idRef = useRef<symbol | null>(null);\n if (idRef.current === null) {\n idRef.current = Symbol('aria-live-outlet');\n }\n\n const registerOutlet = context?.registerOutlet;\n const unregisterOutlet = context?.unregisterOutlet;\n\n useEffect(() => {\n const id = idRef.current;\n if (!id || !registerOutlet || !unregisterOutlet) return;\n\n registerOutlet(id, layer);\n return () => unregisterOutlet(id);\n }, [layer, registerOutlet, unregisterOutlet]);\n\n const getPortalDestination = useCallback(() => document.body, []);\n\n if (!context || context.activeOutletId !== idRef.current) return null;\n\n const { announcementsByPriority } = context;\n\n const liveRegions = (\n <VisuallyHidden>\n <div\n aria-atomic='false'\n aria-live='polite'\n aria-relevant='additions'\n data-testid='str-chat__aria-live-region--polite'\n role='status'\n >\n {announcementsByPriority.polite.map((announcement) => (\n <div key={announcement.id}>{announcement.message}</div>\n ))}\n </div>\n <div\n aria-atomic='false'\n aria-live='assertive'\n aria-relevant='additions'\n data-testid='str-chat__aria-live-region--assertive'\n role='alert'\n >\n {announcementsByPriority.assertive.map((announcement) => (\n <div key={announcement.id}>{announcement.message}</div>\n ))}\n </div>\n </VisuallyHidden>\n );\n\n if (!portal) return liveRegions;\n\n return (\n <Portal getPortalDestination={getPortalDestination} isOpen>\n {liveRegions}\n </Portal>\n );\n};\n","import { useCallback, useEffect, useRef } from 'react';\n\nimport type { AriaLiveAnnounce, AriaLivePriority } from '../useAriaLiveAnnouncer';\n\nexport type DebouncedAnnounceResult = {\n /**\n * Schedule an announcement on the channel identified by `key`. Each call on the same key\n * resets that key's timer, so only the last call within its `delayMs` fires. Different keys\n * debounce independently — scheduling key `a` never cancels a pending key `b`, and each may\n * use its own `delayMs`.\n */\n announce: (\n key: string,\n message: string,\n delayMs: number,\n priority?: AriaLivePriority,\n ) => void;\n /** Cancel pending announcement(s): a single `key`, or all when omitted (also runs on unmount). */\n cancel: (key?: string) => void;\n};\n\n/**\n * L2 scheduling policy: a per-key debounce over the provided `announce` (from\n * `useAriaLiveAnnouncer`). Keeps an independent timer per `key` and takes the delay per call, so\n * distinct rapidly-updating streams can coexist with different debounce windows without clobbering\n * one another (e.g. the autocomplete count, which is a consequence of typing and wants a longer\n * window to clear the screen reader's typing echo, vs. some other future debounced stream). For a\n * single stream, use a constant key.\n *\n * React 17/18/19 compatible — `useCallback`/`useRef`/`useEffect` only. All pending timers are\n * cleared on unmount.\n *\n * ## When to use this vs. {@link useSettledAnnouncement}\n *\n * Both wait out screen-reader noise (the typing echo / field re-read) before speaking, but they\n * model different problems:\n *\n * - **`useDebouncedAnnounce` — an imperative throttle for a value you announce REPEATEDLY.** You\n * call `announce(key, message, ...)` yourself whenever you have a fresh value (from an event\n * handler or effect); rapid calls on a key collapse to the last one. The message typically\n * *changes* each time, it can fire *again and again* (once per pause), and you drive it. Canonical\n * case: the autocomplete result count re-announced as the user keeps typing. It has no notion of\n * \"active\", \"once\", or re-arming — it just throttles whatever you push through it.\n *\n * - **{@link useSettledAnnouncement} — a declarative ONE-SHOT cue for a state change.** You pass\n * `{ active, message, settleKey }`; it announces *once* when `active`, deferred until `settleKey`\n * stops changing, then stays silent until `active` flips back and forth. The message is fixed and\n * the point is \"say this single fact once the UI settles\", not \"announce the latest value\".\n *\n * | | `useDebouncedAnnounce` | `useSettledAnnouncement` |\n * | --- | --- | --- |\n * | Style | Imperative — you call `announce(key, …)` | Declarative — reacts to `{ active, message, settleKey }` |\n * | Repetition | Fires repeatedly, once per pause | Once per `active` epoch (re-arms on reset) |\n * | Message | Typically changes each time | Fixed fact |\n * | Timer reset | Each explicit call | Each `settleKey` change |\n * | Streams | Many, independent per `key` | One logical cue |\n * | Canonical case | Autocomplete count while typing | \"Controls just became available\" |\n *\n * Rule of thumb: announcing the **latest value of a changing thing** → this hook. Announcing a\n * **fixed fact once, after things settle** → `useSettledAnnouncement`.\n */\nexport const useDebouncedAnnounce = (\n announce: AriaLiveAnnounce,\n): DebouncedAnnounceResult => {\n const timersRef = useRef<Map<string, ReturnType<typeof setTimeout>>>(new Map());\n\n // Keep the latest `announce` without changing the debounced callback identity.\n const announceRef = useRef(announce);\n announceRef.current = announce;\n\n const cancel = useCallback((key?: string) => {\n const timers = timersRef.current;\n if (key === undefined) {\n timers.forEach((timerId) => clearTimeout(timerId));\n timers.clear();\n return;\n }\n const timerId = timers.get(key);\n if (timerId !== undefined) {\n clearTimeout(timerId);\n timers.delete(key);\n }\n }, []);\n\n useEffect(() => () => cancel(), [cancel]);\n\n const debouncedAnnounce = useCallback(\n (key: string, message: string, delayMs: number, priority?: AriaLivePriority) => {\n const timers = timersRef.current;\n const existing = timers.get(key);\n if (existing !== undefined) clearTimeout(existing);\n const timerId = setTimeout(() => {\n timers.delete(key);\n announceRef.current(message, { priority });\n }, delayMs);\n timers.set(key, timerId);\n },\n [],\n );\n\n return { announce: debouncedAnnounce, cancel };\n};\n","import React, { useContext, useMemo } from 'react';\n\nimport type { Notification } from 'stream-chat';\nimport type { PropsWithChildrenOnly } from '../../types/types';\nimport type { NotificationTargetPanel } from './notificationTarget';\nimport type { NotificationListFilter } from './NotificationList';\n\nexport type NotificationDisplayFilterParams = {\n /** Fallback panel used by the receiving NotificationList when a notification has no explicit target. */\n fallbackPanel?: NotificationTargetPanel;\n /** Local NotificationList filter. Runs only after the display filter accepts the notification. */\n filter?: NotificationListFilter;\n /** Notification being evaluated after panel/fallback routing matched it to this list. */\n notification: Notification;\n /** Panel of the NotificationList currently evaluating the notification. */\n panel?: NotificationTargetPanel;\n};\n\nexport type NotificationDisplayFilter = (\n params: NotificationDisplayFilterParams,\n) => boolean;\n\nexport type NotificationConfigurationContextValue = {\n displayFilter: NotificationDisplayFilter;\n};\n\nconst defaultNotificationDisplayFilter: NotificationDisplayFilter = () => true;\n\nconst defaultNotificationConfigurationContextValue: NotificationConfigurationContextValue =\n {\n displayFilter: defaultNotificationDisplayFilter,\n };\n\nconst NotificationConfigurationContext =\n React.createContext<NotificationConfigurationContextValue>(\n defaultNotificationConfigurationContextValue,\n );\n\nexport type NotificationConfigurationProviderProps = PropsWithChildrenOnly & {\n displayFilter?: NotificationDisplayFilter;\n};\n\nexport const NotificationConfigurationProvider = ({\n children,\n displayFilter,\n}: NotificationConfigurationProviderProps) => {\n const parentConfiguration = useContext(NotificationConfigurationContext);\n const value = useMemo<NotificationConfigurationContextValue>(\n () => ({\n displayFilter: displayFilter ?? parentConfiguration.displayFilter,\n }),\n [displayFilter, parentConfiguration.displayFilter],\n );\n\n return (\n <NotificationConfigurationContext.Provider value={value}>\n {children}\n </NotificationConfigurationContext.Provider>\n );\n};\n\nexport const useNotificationConfigurationContext = () =>\n useContext(NotificationConfigurationContext);\n","import type { Notification } from 'stream-chat';\n\nconst NOTIFICATION_TARGET_PANELS = [\n 'channel',\n 'thread',\n 'channel-list',\n 'thread-list',\n 'modal',\n] as const;\n\n/**\n * Panel where a notification should be consumed.\n * Use in origin.context.panel when publishing so NotificationList can filter by panel.\n */\nexport type NotificationTargetPanel = (typeof NOTIFICATION_TARGET_PANELS)[number];\n\nexport const isNotificationTargetPanel = (\n value: unknown,\n): value is NotificationTargetPanel =>\n typeof value === 'string' &&\n (NOTIFICATION_TARGET_PANELS as readonly string[]).includes(value);\n\n/**\n * Panel implied by the composer that raised a notification. `stream-chat` cannot name a panel -- it\n * has no notion of one -- but every composer-scoped emitter puts the composer in `origin.context`,\n * and a thread composer's upload failure belongs in that thread rather than in the channel the\n * thread hangs off. Only the two contexts that correspond to a panel are mapped; `message` and\n * `legacy_thread` have none.\n */\nconst getPanelFromComposerContext = (\n notification: Notification,\n): NotificationTargetPanel | undefined => {\n const composer = notification.origin.context?.composer as\n | { contextType?: unknown }\n | undefined;\n\n if (composer?.contextType === 'thread') return 'thread';\n if (composer?.contextType === 'channel') return 'channel';\n return undefined;\n};\n\nexport const getNotificationTargetPanel = (\n notification: Notification,\n): NotificationTargetPanel | undefined => {\n const targetTag = notification.tags?.find((tag) => tag.startsWith('target:'));\n if (targetTag) {\n const candidate = targetTag.slice('target:'.length);\n if (isNotificationTargetPanel(candidate)) return candidate;\n }\n const panel = notification.origin.context?.panel;\n if (isNotificationTargetPanel(panel)) return panel;\n return getPanelFromComposerContext(notification);\n};\n\nexport const getNotificationTargetPanels = (\n notification: Notification,\n): NotificationTargetPanel[] => {\n const targetPanels = (notification.tags ?? [])\n .filter((tag) => tag.startsWith('target:'))\n .map((tag) => tag.slice('target:'.length))\n .filter((value): value is NotificationTargetPanel =>\n isNotificationTargetPanel(value),\n );\n\n if (targetPanels.length > 0) {\n return Array.from(new Set(targetPanels));\n }\n\n const panel = notification.origin.context?.panel;\n if (isNotificationTargetPanel(panel)) return [panel];\n\n const composerPanel = getPanelFromComposerContext(notification);\n return composerPanel ? [composerPanel] : [];\n};\n\nexport const getNotificationTargetTag = (panel: NotificationTargetPanel) =>\n `target:${panel}` as const;\n\nexport const addNotificationTargetTag = (\n panel: NotificationTargetPanel | undefined,\n tags?: string[],\n) => {\n if (!panel) return tags ?? [];\n return Array.from(new Set([getNotificationTargetTag(panel), ...(tags ?? [])]));\n};\n\nexport const isNotificationForPanel = (\n notification: Notification,\n panel: NotificationTargetPanel,\n options?: { fallbackPanel?: NotificationTargetPanel },\n) => {\n const explicitTargetPanels = getNotificationTargetPanels(notification);\n if (explicitTargetPanels.length > 0) {\n return explicitTargetPanels.includes(panel);\n }\n\n const resolvedPanel = options?.fallbackPanel ?? 'channel';\n return resolvedPanel === panel;\n};\n","import { useCallback } from 'react';\nimport { useChatContext } from '../../../context';\nimport { useStateStore } from '../../../store';\nimport type { Notification, NotificationManagerState } from 'stream-chat';\nimport { useNotificationConfigurationContext } from '../NotificationConfigurationContext';\nimport { isNotificationForPanel } from '../notificationTarget';\n\nimport type { NotificationTargetPanel } from '../notificationTarget';\n\nexport type UseNotificationsFilter = (notification: Notification) => boolean;\n\nexport type UseNotificationsOptions = {\n /**\n * When true, the configured Chat-level notificationDisplayFilter is applied after\n * panel routing and before the local filter.\n */\n applyDisplayFilter?: boolean;\n /**\n * When provided, only notifications that pass this filter are returned.\n * Use to have a given NotificationList consume only a subset of client.notifications\n * (e.g. by origin.emitter, origin.context, or metadata).\n */\n filter?: UseNotificationsFilter;\n /**\n * Panel target consumed by a specific notification list.\n */\n panel?: NotificationTargetPanel;\n /**\n * Fallback panel used when origin.context.panel is absent.\n * Defaults to `channel`.\n */\n fallbackPanel?: NotificationTargetPanel;\n};\n\n/**\n * Subscribes to client.notifications.store and returns the list of notifications.\n * Optionally pass a filter so only notifications that match are returned (e.g. for a specific NotificationList).\n */\nexport const useNotifications = (options?: UseNotificationsOptions): Notification[] => {\n const { client } = useChatContext();\n const { displayFilter } = useNotificationConfigurationContext();\n const { applyDisplayFilter, fallbackPanel, filter, panel } = options ?? {};\n const selector = useCallback(\n (state: NotificationManagerState) => {\n const notifications = state.notifications;\n return {\n notifications: notifications.filter((notification) => {\n if (\n panel &&\n !isNotificationForPanel(notification, panel, {\n fallbackPanel,\n })\n ) {\n return false;\n }\n\n if (\n applyDisplayFilter &&\n !displayFilter({\n fallbackPanel,\n filter,\n notification,\n panel,\n })\n ) {\n return false;\n }\n\n return filter ? filter(notification) : true;\n }),\n };\n },\n [applyDisplayFilter, displayFilter, fallbackPanel, filter, panel],\n );\n\n const { notifications } = useStateStore(client.notifications.store, selector);\n\n return notifications;\n};\n","import { useChannelListContext, useWorkspaceNavigation } from '../../../context';\n// MERGE-RECONCILE: the deleted ChannelStateContext's `channel` is read here only to detect\n// whether a channel is in scope; migrated to useChannelInstanceContext (safe — returns\n// undefined channel outside a Channel subtree, unlike useChannel which throws).\nimport { useChannelInstanceContext } from '../../../context/ChannelInstanceContext';\nimport { useThreadContext } from '../../Threads/ThreadContext';\n\nimport type { NotificationTargetPanel } from '../notificationTarget';\n\n/**\n * Resolves the panel target where notifications emitted by the current component should be displayed.\n */\nexport const useNotificationTarget = (): NotificationTargetPanel | undefined => {\n const { isThreadsView } = useWorkspaceNavigation();\n const { paginator } = useChannelListContext();\n const { channel } = useChannelInstanceContext();\n const threadInstance = useThreadContext();\n\n if (threadInstance) return 'thread';\n if (channel) return 'channel';\n if (isThreadsView) return 'thread-list';\n if (paginator) return 'channel-list';\n return undefined;\n};\n","import { useCallback } from 'react';\n\nimport type { Notification, NotificationAction, NotificationSeverity } from 'stream-chat';\n\nimport type { AriaLivePriority } from '../../Accessibility';\nimport { useChatContext, useModalDialogManager } from '../../../context';\nimport { useStateStore } from '../../../store';\nimport {\n addNotificationTargetTag,\n getNotificationTargetTag,\n type NotificationTargetPanel,\n} from '../notificationTarget';\nimport { useNotificationTarget } from './useNotificationTarget';\n\nimport type { DialogManagerState } from '../../Dialog/service/DialogManager';\n\nconst modalDialogManagerStateSelector = ({\n dialogsById,\n openedDialogIds,\n}: DialogManagerState) => ({\n hasOpenDialog: openedDialogIds\n ? openedDialogIds.length > 0\n : Object.values(dialogsById).some((dialog) => dialog.isOpen),\n});\n\n/** Tag used for full-width system banners (e.g. connection status). Excluded from `NotificationList` by default. */\nexport const SYSTEM_NOTIFICATION_TAG = 'system' as const;\n\nexport const hasSystemNotificationTag = (notification: Notification) =>\n notification.tags?.includes(SYSTEM_NOTIFICATION_TAG) ?? false;\n\nexport type NotificationIncidentDescriptor = {\n /** Where the incident happened (e.g. api, browser, validation, permission). */\n domain: string;\n /** Entity being operated on (e.g. message, poll, location, attachment). */\n entity: string;\n /** Attempted operation (e.g. send, end, share, upload). */\n operation: string;\n /** Status of the operation (e.g. failed, success, blocked). */\n status?: string;\n};\n\nexport type AddNotificationParams = {\n /** Optional interactive actions rendered by the notification component. */\n actions?: NotificationAction[];\n /**\n * Overrides the aria-live priority the notification is announced with. Defaults to severity-based\n * (`error` → `assertive`, otherwise `polite`). Set `assertive` for a confirmation that should be\n * heard promptly rather than queued behind a competing announcement (e.g. a focus change).\n */\n ariaLive?: AriaLivePriority;\n /** Arbitrary context metadata stored in `origin.context`. */\n context?: Record<string, unknown>;\n /** Duration in milliseconds after which the notification auto-dismisses. */\n duration?: number;\n /** Logical source emitting the notification (e.g. component or feature name). */\n emitter: string;\n /** Underlying error object attached as `options.originalError`. */\n error?: Error;\n /** Human-readable notification message. */\n message: string;\n /** Notification severity visualized by the UI. */\n severity?: NotificationSeverity;\n /** Additional tags appended to target panel tags. */\n tags?: string[];\n /** Explicit target panels; when provided, inferred panel is ignored. */\n targetPanels?: NotificationTargetPanel[];\n /** Structured descriptor of the incident this notification reports on. */\n incident?: NotificationIncidentDescriptor;\n /**\n * Optional machine-readable notification type identifier (domain:entity:operation:status).\n * Used by notification consumers to route behavior, including translation lookup\n * via notification-type registries.\n * When omitted, `type` is generated from `incident` if `incident` is provided.\n */\n type?: string;\n};\n\n/**\n * Same shape as {@link AddNotificationParams} except `targetPanels` is omitted — system\n * banners are global and do not receive `target:*` panel tags (they are filtered by the\n * `system` tag for `NotificationList` vs banner UIs).\n */\nexport type AddSystemNotificationParams = Omit<AddNotificationParams, 'targetPanels'>;\n\nexport type AddNotification = (params: AddNotificationParams) => void;\n/** Returns the notification id (for removal / timeouts). */\nexport type AddSystemNotification = (params: AddSystemNotificationParams) => string;\nexport type RemoveNotification = (id: string) => void;\nexport type StartNotificationTimeout = (id: string) => void;\n/** Starts a notification's countdown unless one is already running. */\nexport type EnsureNotificationTimeout = (id: string) => void;\n\nexport type NotificationApi = {\n addNotification: AddNotification;\n addSystemNotification: AddSystemNotification;\n ensureNotificationTimeout: EnsureNotificationTimeout;\n removeNotification: RemoveNotification;\n startNotificationTimeout: StartNotificationTimeout;\n};\n\nconst getTargetTags = (\n targetPanels: NotificationTargetPanel[] | undefined,\n inferredPanel: NotificationTargetPanel | undefined,\n tags: string[] | undefined,\n modalManagerHasOpenDialog: boolean,\n) => {\n if (targetPanels) {\n const effectiveTargetPanels =\n modalManagerHasOpenDialog && targetPanels.length > 0\n ? [...targetPanels, 'modal' as const]\n : targetPanels;\n\n return Array.from(\n new Set([...effectiveTargetPanels.map(getNotificationTargetTag), ...(tags ?? [])]),\n );\n }\n\n if (modalManagerHasOpenDialog) {\n return Array.from(\n new Set([\n ...(inferredPanel ? [getNotificationTargetTag(inferredPanel)] : []),\n getNotificationTargetTag('modal'),\n ...(tags ?? []),\n ]),\n );\n }\n\n return addNotificationTargetTag(inferredPanel, tags);\n};\n\nconst getTypeFromIncident = ({\n incident,\n severity,\n type,\n}: Pick<AddNotificationParams, 'incident' | 'severity' | 'type'>) => {\n if (type) return type;\n if (!incident) return undefined;\n\n const status =\n incident.status ??\n (severity === 'error' ? 'failed' : severity === 'success' ? 'success' : severity);\n\n return [incident.domain, incident.entity, incident.operation, status]\n .filter((segment): segment is string => !!segment)\n .join(':');\n};\n\nexport const useNotificationApi = (): NotificationApi => {\n const { client } = useChatContext();\n const inferredPanel = useNotificationTarget();\n const modalDialogManager = useModalDialogManager();\n const modalManagerHasOpenDialog =\n useStateStore(modalDialogManager?.state, modalDialogManagerStateSelector)\n ?.hasOpenDialog ?? false;\n\n const addNotification: AddNotification = useCallback(\n ({\n actions,\n ariaLive,\n context,\n duration,\n emitter,\n error,\n incident,\n message,\n severity,\n tags,\n targetPanels,\n type,\n }: AddNotificationParams) => {\n const notificationTags = getTargetTags(\n targetPanels,\n inferredPanel,\n tags,\n modalManagerHasOpenDialog,\n );\n const resolvedType = getTypeFromIncident({ incident, severity, type });\n const origin = context ? { context, emitter } : { emitter };\n\n const options = {\n ...(actions ? { actions } : {}),\n ...(typeof duration === 'number' ? { duration } : {}),\n ...(error ? { originalError: error } : {}),\n ...(ariaLive ? { metadata: { ariaLive } } : {}),\n ...(notificationTags.length > 0 ? { tags: notificationTags } : {}),\n ...(severity ? { severity } : {}),\n ...(resolvedType ? { type: resolvedType } : {}),\n };\n\n client.notifications.add({\n message,\n options,\n origin,\n });\n },\n [client, inferredPanel, modalManagerHasOpenDialog],\n );\n\n const addSystemNotification: AddSystemNotification = useCallback(\n ({\n actions,\n ariaLive,\n context,\n duration,\n emitter,\n error,\n incident,\n message,\n severity,\n tags,\n type,\n }: AddSystemNotificationParams) => {\n const notificationTags = Array.from(\n new Set([SYSTEM_NOTIFICATION_TAG, ...(tags ?? [])]),\n );\n const resolvedType = getTypeFromIncident({ incident, severity, type });\n const origin = context ? { context, emitter } : { emitter };\n\n const options = {\n ...(actions ? { actions } : {}),\n ...(typeof duration === 'number' ? { duration } : {}),\n ...(error ? { originalError: error } : {}),\n ...(ariaLive ? { metadata: { ariaLive } } : {}),\n ...(notificationTags.length > 0 ? { tags: notificationTags } : {}),\n ...(severity ? { severity } : {}),\n ...(resolvedType ? { type: resolvedType } : {}),\n };\n\n return client.notifications.add({\n message,\n options,\n origin,\n });\n },\n [client],\n );\n\n const removeNotification: RemoveNotification = useCallback(\n (id) => {\n client.notifications.remove(id);\n },\n [client],\n );\n\n const startNotificationTimeout: StartNotificationTimeout = useCallback(\n (id) => {\n client.notifications.startTimeout(id);\n },\n [client],\n );\n\n // Starting is the manager's to make idempotent: a caller that cannot know whether the countdown\n // is already running -- a component that remounts, a second view of the same notification --\n // would otherwise hand it another full lifetime and lose the original deadline.\n const ensureNotificationTimeout: EnsureNotificationTimeout = useCallback(\n (id) => {\n client.notifications.ensureTimeout(id);\n },\n [client],\n );\n\n return {\n addNotification,\n addSystemNotification,\n ensureNotificationTimeout,\n removeNotification,\n startNotificationTimeout,\n };\n};\n","import React, { type ComponentType, forwardRef } from 'react';\nimport clsx from 'clsx';\nimport type { NotificationSeverity } from 'stream-chat';\nimport { type Notification as NotificationType } from 'stream-chat';\n\nimport { useComponentContextIcons } from '../../context';\nimport { useTranslationContext } from '../../context/TranslationContext';\nimport { Button } from '../Button';\nimport { useNotificationApi } from './hooks/useNotificationApi';\n\ntype NotificationEntryDirection = 'bottom' | 'left' | 'right' | 'top';\ntype NotificationTransitionState = 'enter' | 'exit';\n\nexport type NotificationIconProps = {\n notification: NotificationType;\n};\n\nconst DefaultNotificationIcon = ({ notification }: NotificationIconProps) => {\n const { IconCheckmark, IconExclamationMark, IconExclamationTriangleFill, IconRefresh } =\n useComponentContextIcons();\n\n const IconsBySeverity: Record<NotificationSeverity, ComponentType | null> = {\n error: IconExclamationMark,\n info: null,\n loading: IconRefresh,\n success: IconCheckmark,\n warning: IconExclamationTriangleFill,\n };\n\n if (!notification.severity) return null;\n\n const Icon = IconsBySeverity[notification.severity] ?? null;\n return (\n Icon && (\n <div className='str-chat__notification-icon'>\n <Icon />\n </div>\n )\n );\n};\n\nexport type NotificationProps = {\n /** Notification from client.notifications state */\n notification: NotificationType;\n /** Optional class name */\n className?: string;\n /** Direction from which the notification enters. */\n entryDirection?: NotificationEntryDirection;\n /** Optional custom icon component. */\n Icon?: React.ComponentType<NotificationIconProps>;\n /** Optional dismiss handler */\n onDismiss?: () => void;\n /** Show close button (for persistent notifications) */\n showClose?: boolean;\n /** Optional transition state applied by NotificationList. */\n transitionState?: NotificationTransitionState;\n};\n\nexport const Notification = forwardRef<HTMLDivElement, NotificationProps>(\n (\n {\n className,\n entryDirection,\n Icon = DefaultNotificationIcon,\n notification,\n onDismiss,\n showClose = false,\n transitionState,\n }: NotificationProps,\n ref,\n ) => {\n const { removeNotification } = useNotificationApi();\n const { t } = useTranslationContext();\n const { IconXmark } = useComponentContextIcons();\n\n const displayMessage = t('translationBuilderTopic.notification', {\n notification,\n value: notification.message,\n });\n\n const handleDismiss = () => {\n if (onDismiss) {\n onDismiss();\n return;\n }\n\n removeNotification(notification.id);\n };\n\n const isPersistent = !notification.duration;\n\n const severity = notification.severity;\n // Priority defaults from severity (errors interrupt; everything else is polite), but a\n // notification may explicitly opt into a different aria-live priority via\n // `metadata.ariaLive` — e.g. a success confirmation that should be heard promptly rather than\n // queued behind a focus-change announcement (see `addNotification`'s `ariaLive` option).\n const ariaLiveOverride = notification.metadata?.ariaLive;\n const livePriority: 'assertive' | 'polite' =\n ariaLiveOverride === 'assertive' || ariaLiveOverride === 'polite'\n ? ariaLiveOverride\n : severity === 'error'\n ? 'assertive'\n : 'polite';\n\n return (\n <div\n className={clsx(\n 'str-chat__notification',\n entryDirection && `str-chat__notification--enter-from-${entryDirection}`,\n transitionState === 'enter' && 'str-chat__notification--is-entering',\n transitionState === 'exit' && 'str-chat__notification--is-exiting',\n severity && `str-chat__notification--${severity}`,\n severity === 'loading' && 'str-chat__notification--loading',\n className,\n )}\n data-testid='notification'\n ref={ref}\n >\n <div className='str-chat__notification-content'>\n {Icon && <Icon notification={notification} />}\n <div\n aria-atomic='true'\n aria-live={livePriority}\n className='str-chat__notification-message'\n role={livePriority === 'assertive' ? 'alert' : 'status'}\n >\n {displayMessage}\n </div>\n </div>\n {notification.actions && notification.actions.length > 0 && (\n <div className='str-chat__notification-actions'>\n {notification.actions.map((action, index) => (\n <Button\n appearance='outline'\n className='str-chat__notification-action'\n inverseTheme\n key={index}\n onClick={() => {\n action.handler();\n }}\n size='sm'\n variant='secondary'\n >\n {action.label}\n </Button>\n ))}\n </div>\n )}\n {(showClose || isPersistent) && (\n <Button\n appearance='ghost'\n aria-label={t(\n 'notification.dismissNotification.ariaLabel',\n 'Dismiss notification',\n )}\n circular\n className='str-chat__notification-close-button'\n inverseTheme\n onClick={handleDismiss}\n size='sm'\n variant='secondary'\n >\n <IconXmark />\n </Button>\n )}\n </div>\n );\n },\n);\n\nNotification.displayName = 'Notification';\n","import React, { useCallback, useEffect, useRef, useState } from 'react';\nimport clsx from 'clsx';\nimport type { Notification } from 'stream-chat';\n\nimport { hasSystemNotificationTag, useNotificationApi } from './hooks/useNotificationApi';\nimport { useNotifications } from './hooks/useNotifications';\nimport { Notification as DefaultNotification } from './Notification';\nimport { useComponentContext, useTranslationContext } from '../../context';\n\nimport type { NotificationTargetPanel } from './notificationTarget';\n\nexport type NotificationListFilter = (notification: Notification) => boolean;\nexport type NotificationListEnterFrom = 'bottom' | 'left' | 'right' | 'top';\nexport type NotificationListVerticalAlignment = 'bottom' | 'top';\n/**\n * Selects the candidate notification to display. Receives the current store contents and\n * the currently displayed notification (or `null` when nothing is mounted). Returning\n * `displayed` (or any notification with the same id) means \"no swap\"; returning a\n * different notification triggers a swap (immediate or after `minDisplayMs`, see the\n * scheduling effect); returning `null` triggers the empty-slot exit.\n *\n * Default: `createDefaultPickNext(pickOldest)` — applies persistent-wins,\n * same-type-refresh and FIFO queue rules from the design spec. Pass\n * `pickNext={createDefaultPickNext(pickNewest)}` to swap FIFO for LIFO without\n * reimplementing those rules, or your own `pickNext` to opt out entirely.\n */\nexport type PickNextNotification = (\n notifications: Notification[],\n displayed: Notification | null,\n) => Notification | null;\n\n/**\n * Picks the next queued notification when no higher-priority rule applies (persistent\n * wins, same-type refresh). Used by `createDefaultPickNext`.\n */\nexport type PickFromQueue = (\n notifications: Notification[],\n displayed: Notification | null,\n) => Notification | null;\n\nexport type NotificationListProps = {\n /** Optional class name for the list container */\n className?: string;\n /**\n * Direction from which the replacement notification enters the single visible slot.\n * Travel distance is configured in `ENTER_TRANSLATION` below.\n */\n enterFrom?: NotificationListEnterFrom;\n /**\n * When provided, this list only shows notifications that pass the filter.\n * Use to declare which notifications this list consumes (e.g. by origin.emitter, origin.context.channelId, or metadata).\n */\n filter?: NotificationListFilter;\n /**\n * Minimum time in milliseconds the active notification stays visible before a queued one\n * can replace it. Replacements scheduled while the dwell window is open wait until it has\n * elapsed; arrivals after that window replace the active notification immediately.\n * Same-type repeated triggers and external dismissals bypass this dwell.\n * Defaults to 1000ms.\n */\n minDisplayMs?: number;\n /**\n * Override the candidate-selection policy. The function decides which notification\n * should be displayed given the store and the currently displayed one. Defaults to\n * `createDefaultPickNext(pickOldest)`. Pass `createDefaultPickNext(pickNewest)` for LIFO.\n */\n pickNext?: PickNextNotification;\n /** Panel target consumed by this list. */\n panel?: NotificationTargetPanel;\n /** Fallback panel when emitted notifications do not include origin.context.panel. */\n fallbackPanel?: NotificationTargetPanel;\n /** Vertical alignment of the single notification slot within its parent. Defaults to `bottom`. */\n verticalAlignment?: NotificationListVerticalAlignment;\n};\n\n// Entry motion is controlled through CSS variables so the keyframe can stay shared in SCSS.\n// Use full-size percentages on the active axis to make a replacement notification slide in\n// from outside its slot. If future tuning needs more travel, prefer `calc(100% + gap)` here.\nconst ENTER_TRANSLATION: Record<NotificationListEnterFrom, { x: string; y: string }> = {\n bottom: { x: '0%', y: '100%' },\n left: { x: '-100%', y: '0%' },\n right: { x: '100%', y: '0%' },\n top: { x: '0%', y: '-100%' },\n};\n\nconst EXIT_ANIMATION_MS = 340;\nconst DEFAULT_MIN_DISPLAY_MS = 1000;\n\nconst isEnterFrom = (value: unknown): value is NotificationListEnterFrom =>\n value === 'bottom' || value === 'left' || value === 'right' || value === 'top';\n\nconst getNotificationEnterFrom = (\n notification: Notification | null,\n fallbackEnterFrom: NotificationListEnterFrom,\n) => {\n if (!notification) return fallbackEnterFrom;\n\n const metadataEnterFrom = notification.metadata?.entryDirection;\n if (isEnterFrom(metadataEnterFrom)) return metadataEnterFrom;\n\n const originEnterFrom = notification.origin.context?.entryDirection;\n if (isEnterFrom(originEnterFrom)) return originEnterFrom;\n\n return fallbackEnterFrom;\n};\n\nconst isPersistent = (notification: Notification) => !notification.duration;\n\nconst haveSameType = (a: Notification | null, b: Notification | null) =>\n !!a?.type && !!b?.type && a.type === b.type;\n\n/** FIFO queue selector — oldest `createdAt` other than `displayed` wins. */\nexport const pickOldest: PickFromQueue = (notifications, displayed) => {\n const excludeId = displayed?.id ?? null;\n let oldest: Notification | null = null;\n for (const notification of notifications) {\n if (notification.id === excludeId) continue;\n if (!oldest || notification.createdAt < oldest.createdAt) {\n oldest = notification;\n }\n }\n return oldest;\n};\n\n/** LIFO queue selector — newest `createdAt` other than `displayed` wins. */\nexport const pickNewest: PickFromQueue = (notifications, displayed) => {\n const excludeId = displayed?.id ?? null;\n let newest: Notification | null = null;\n for (const notification of notifications) {\n if (notification.id === excludeId) continue;\n if (!newest || notification.createdAt > newest.createdAt) {\n newest = notification;\n }\n }\n return newest;\n};\n\nconst pickNewestPersistent = (\n notifications: Notification[],\n excludeId: string | null,\n): Notification | null => {\n let newest: Notification | null = null;\n for (const notification of notifications) {\n if (notification.id === excludeId) continue;\n if (!isPersistent(notification)) continue;\n if (!newest || notification.createdAt > newest.createdAt) {\n newest = notification;\n }\n }\n return newest;\n};\n\nconst pickNewestOfType = (\n notifications: Notification[],\n type: string | undefined | null,\n excludeId: string | null,\n): Notification | null => {\n if (!type) return null;\n let newest: Notification | null = null;\n for (const notification of notifications) {\n if (notification.id === excludeId) continue;\n if (notification.type !== type) continue;\n if (!newest || notification.createdAt > newest.createdAt) {\n newest = notification;\n }\n }\n return newest;\n};\n\n/**\n * Builds the default `PickNextNotification` selector with a configurable queue fallback.\n * Encodes the snackbar concurrency rules from the design spec — the scheduling effect\n * only decides *when* to swap, the returned function decides *what* to swap to.\n *\n * Rules, in order of precedence:\n * 1. **Persistent wins.** Persistent variants (no `duration`) jump ahead of any\n * queued transient because they carry an action the user must acknowledge.\n * 2. **Persistent ↛ replaced by transient.** While a persistent is displayed it stays\n * put until dismissed externally or a *newer* persistent arrives.\n * 3. **Same-type refresh.** While a transient is displayed, a repeated trigger of the\n * same `type` collapses to its latest occurrence. (The scheduling effect detects\n * this via `haveSameType` and bypasses the dwell window so the refresh feels\n * instant; this function just makes sure the latest same-type is returned.)\n * 4. **Queue fallback.** Otherwise, `pickFromQueue` selects the next notification\n * (default: `pickOldest` / FIFO).\n *\n * Exported so callers that want to layer behavior on top of the design rules can wrap\n * the result instead of rewriting it.\n */\nexport const createDefaultPickNext =\n (pickFromQueue: PickFromQueue = pickOldest): PickNextNotification =>\n (notifications, displayed) => {\n if (notifications.length === 0) return null;\n\n const newestPersistent = pickNewestPersistent(notifications, null);\n\n if (!displayed) {\n return newestPersistent ?? pickFromQueue(notifications, null);\n }\n\n const displayedInStore = notifications.some(({ id }) => id === displayed.id);\n if (!displayedInStore) {\n return newestPersistent ?? pickFromQueue(notifications, null);\n }\n\n if (isPersistent(displayed)) {\n // Currently showing a persistent: only a newer persistent can replace it. Reuse the\n // earlier lookup when it already points at a different persistent.\n const newerPersistent =\n newestPersistent && newestPersistent.id !== displayed.id\n ? newestPersistent\n : pickNewestPersistent(notifications, displayed.id);\n if (newerPersistent && newerPersistent.createdAt > displayed.createdAt) {\n return newerPersistent;\n }\n return displayed;\n }\n\n // Currently showing a transient.\n // 1. Same-type \"refresh of current\" wins immediately — a repeated trigger of the\n // displayed snackbar collapses to the latest occurrence of that type.\n const sameTypeNewest = pickNewestOfType(notifications, displayed.type, displayed.id);\n if (sameTypeNewest) return sameTypeNewest;\n\n // 2. Any queued persistent jumps ahead of the queue.\n if (newestPersistent) return newestPersistent;\n\n // 3. Queue fallback.\n return pickFromQueue(notifications, displayed) ?? displayed;\n };\n\n/** Default selector — design-spec rules with FIFO queue fallback (`pickOldest`). */\nconst defaultPickNext = createDefaultPickNext(pickOldest);\n\nexport const NotificationList = ({\n className,\n enterFrom = 'bottom',\n fallbackPanel,\n filter,\n minDisplayMs = DEFAULT_MIN_DISPLAY_MS,\n panel,\n pickNext = defaultPickNext,\n verticalAlignment = 'bottom',\n}: NotificationListProps) => {\n const { Notification: NotificationComponent = DefaultNotification } =\n useComponentContext();\n const { t } = useTranslationContext();\n const { ensureNotificationTimeout, removeNotification } = useNotificationApi();\n // Holds the timer that runs the exit animation. Set when we flip `transitionState` to\n // `'exit'`; when it fires, the previously displayed notification is removed and either the\n // next candidate is mounted (entering) or the list collapses to empty. Only one exit\n // animation can be in flight at a time.\n const exitTimeoutRef = useRef<number | null>(null);\n // Holds the dwell timer that defers a swap until `minDisplayMs` has elapsed since the\n // active notification became visible. It only exists while we're waiting out the dwell\n // window; same-type triggers, external dismissals and arrivals after the dwell window\n // bypass it and trigger the exit animation directly.\n const replacementTimeoutRef = useRef<number | null>(null);\n const candidateRef = useRef<Notification | null>(null);\n const displayedAtRef = useRef<number | null>(null);\n const listRef = useRef<HTMLDivElement | null>(null);\n const observedElementRef = useRef<HTMLDivElement | null>(null);\n\n const [displayedNotification, setDisplayedNotification] = useState<Notification | null>(\n null,\n );\n const [transitionState, setTransitionState] = useState<'enter' | 'exit'>('enter');\n const combinedFilter = useCallback(\n (notification: Notification) => {\n if (hasSystemNotificationTag(notification)) return false;\n return filter ? filter(notification) : true;\n },\n [filter],\n );\n const notifications = useNotifications({\n applyDisplayFilter: true,\n fallbackPanel,\n filter: combinedFilter,\n panel,\n });\n\n const dismiss = useCallback(\n (id: string) => {\n removeNotification(id);\n },\n [removeNotification],\n );\n\n const clearReplacementTimeout = useCallback(() => {\n if (replacementTimeoutRef.current !== null) {\n window.clearTimeout(replacementTimeoutRef.current);\n replacementTimeoutRef.current = null;\n }\n }, []);\n\n // Cleanup pending timers on unmount.\n useEffect(\n () => () => {\n clearReplacementTimeout();\n if (exitTimeoutRef.current !== null) {\n window.clearTimeout(exitTimeoutRef.current);\n exitTimeoutRef.current = null;\n }\n },\n [clearReplacementTimeout],\n );\n\n // Keep the freshest candidate around so swap completion can read the latest value, even\n // when a new notification arrives mid-exit-animation.\n useEffect(() => {\n candidateRef.current = pickNext(notifications, displayedNotification);\n }, [displayedNotification, notifications, pickNext]);\n\n // Main scheduling effect — owns *when* swaps happen. The *what* is delegated entirely\n // to `pickNext` (default: `createDefaultPickNext(pickOldest)`).\n //\n // Runs on every change to `displayedNotification`, `notifications`, `pickNext`, or\n // `transitionState`, and decides one of four outcomes:\n // 1. Do nothing (the right notification is already on screen, or an exit animation\n // is mid-flight and will re-trigger this effect when it finishes).\n // 2. Mount the first notification (no `displayedNotification` yet).\n // 3. Unmount the current one (`pickNext` returned `null`, the store became empty).\n // 4. Swap the displayed one for the new candidate — either immediately or after the\n // `minDisplayMs` dwell window has elapsed.\n //\n // Timing rules applied here (independent of selection policy):\n // - **Dwell window.** When `pickNext` returns a different candidate, hold the active\n // notification on screen until at least `minDisplayMs` has passed since it became\n // visible. Replacements that arrive after that window swap immediately.\n // - **Same-type bypass.** If the candidate has the same `type` as the displayed\n // notification, swap immediately (no dwell) — this is the \"repeated trigger\n // refreshes the snackbar and resets the auto-dismiss timer\" behavior. The timer\n // reset is achieved by removing the previously displayed notification on swap\n // (which clears its `NotificationManager` timer) so the new one starts its own\n // when it next intersects the slot.\n // - **External-dismiss bypass.** If the displayed notification is no longer in the\n // store (user clicked the close button, `NotificationManager` auto-removed it,\n // etc.), swap immediately — we should not stall an empty slot for the dwell.\n useEffect(() => {\n // An exit animation is already in flight. Once its timer fires it sets new state\n // (either the next notification or `null`), which will re-run this effect from a\n // clean baseline.\n if (transitionState === 'exit') return;\n\n // No notification is mounted yet — pick whatever the candidate logic prefers and\n // mount it directly with an enter animation. No swap required.\n if (!displayedNotification) {\n const candidate = pickNext(notifications, null);\n if (candidate) {\n displayedAtRef.current = Date.now();\n setDisplayedNotification(candidate);\n setTransitionState('enter');\n }\n return;\n }\n\n const candidate = pickNext(notifications, displayedNotification);\n\n // The store has been drained while a notification was visible. Play the exit\n // animation, then unmount.\n if (!candidate) {\n clearReplacementTimeout();\n setTransitionState('exit');\n exitTimeoutRef.current = window.setTimeout(() => {\n exitTimeoutRef.current = null;\n displayedAtRef.current = null;\n setDisplayedNotification(null);\n setTransitionState('enter');\n }, EXIT_ANIMATION_MS);\n return;\n }\n\n // The candidate is the displayed notification itself — nothing to do. Cancel any\n // dwell timer that may have been queued by an earlier run that has since become\n // moot (e.g. the incoming notification was removed before its dwell expired).\n if (candidate.id === displayedNotification.id) {\n clearReplacementTimeout();\n return;\n }\n\n const displayedInStore = notifications.some(\n ({ id }) => id === displayedNotification.id,\n );\n\n // Swap routine shared by the immediate and dwell-deferred branches below. Captures\n // `previousId` / `wasInStore` from the effect's closure so the exit timer can run\n // the right cleanup even if state has moved on by the time it fires.\n const startSwap = () => {\n replacementTimeoutRef.current = null;\n setTransitionState('exit');\n const previousId = displayedNotification.id;\n const wasInStore = displayedInStore;\n exitTimeoutRef.current = window.setTimeout(() => {\n exitTimeoutRef.current = null;\n if (wasInStore) {\n // Remove the previously displayed notification from the store so it does not\n // re-appear, and so its NotificationManager auto-dismiss timer is cleared.\n removeNotification(previousId);\n }\n // Read the latest candidate at the moment the exit animation actually completes —\n // it may differ from the one decided when `startSwap` was queued because new\n // notifications could have arrived during the 340ms exit window.\n const next = candidateRef.current;\n if (next && next.id !== previousId) {\n displayedAtRef.current = Date.now();\n setDisplayedNotification(next);\n setTransitionState('enter');\n } else {\n displayedAtRef.current = null;\n setDisplayedNotification(null);\n setTransitionState('enter');\n }\n }, EXIT_ANIMATION_MS);\n };\n\n // External dismissal or auto-dismiss removed the displayed notification: swap right\n // away (no dwell wait — the slot would otherwise stall empty for `minDisplayMs`).\n if (!displayedInStore) {\n clearReplacementTimeout();\n startSwap();\n return;\n }\n\n // Repeated triggers of the same snackbar replace the active one and reset the\n // auto-dismiss timer immediately — feedback for the same condition should feel like\n // a single, persistent thing being refreshed.\n if (haveSameType(displayedNotification, candidate)) {\n clearReplacementTimeout();\n startSwap();\n return;\n }\n\n // Default branch: enforce the dwell window. `displayedAtRef` is stamped synchronously\n // every time we set `displayedNotification` (initial mount and swap completion), so it\n // is in sync with what is on screen by the time this effect runs.\n const elapsed = displayedAtRef.current ? Date.now() - displayedAtRef.current : 0;\n const remaining = Math.max(0, minDisplayMs - elapsed);\n\n if (remaining === 0) {\n // Dwell already elapsed; swap right now.\n clearReplacementTimeout();\n startSwap();\n } else if (replacementTimeoutRef.current === null) {\n // A swap is pending but the dwell hasn't elapsed yet. Schedule the swap once —\n // subsequent re-runs of this effect (e.g. as even newer notifications arrive)\n // intentionally do NOT reschedule. `candidateRef` keeps tracking the freshest\n // candidate, so when the timer fires `startSwap` → exit completes → the latest\n // candidate is picked up automatically.\n replacementTimeoutRef.current = window.setTimeout(startSwap, remaining);\n }\n }, [\n clearReplacementTimeout,\n displayedNotification,\n minDisplayMs,\n notifications,\n pickNext,\n removeNotification,\n transitionState,\n ]);\n\n const notification = displayedNotification;\n const notificationEnterFrom = getNotificationEnterFrom(notification, enterFrom);\n\n useEffect(() => {\n const element = observedElementRef.current;\n if (!element || !notification || transitionState === 'exit') return;\n\n // `ensureTimeout` leaves a running countdown alone, so this can be called whenever the\n // notification becomes visible without tracking which ones have been started already -- and\n // without a second view of the same notification pushing its deadline out.\n const startTimeout = () => {\n ensureNotificationTimeout(notification.id);\n };\n\n if (typeof IntersectionObserver === 'undefined') {\n startTimeout();\n return;\n }\n\n const observer = new IntersectionObserver(\n (entries) => {\n const [entry] = entries;\n if (!entry?.isIntersecting) return;\n\n startTimeout();\n observer.disconnect();\n },\n {\n root: listRef.current,\n threshold: 0.5,\n },\n );\n\n observer.observe(element);\n\n return () => {\n observer.disconnect();\n };\n }, [ensureNotificationTimeout, notification, transitionState]);\n\n if (!notification) return null;\n\n return (\n <div\n aria-label={t('notification.list.notifications.ariaLabel', 'Notifications')}\n className={clsx(\n 'str-chat__notification-list',\n `str-chat__notification-list--enter-from-${notificationEnterFrom}`,\n `str-chat__notification-list--position-${verticalAlignment}`,\n panel && `str-chat__notification-list--${panel}`,\n className,\n )}\n data-testid='notification-list'\n ref={listRef}\n role='region'\n style={\n {\n '--str-chat__notification-list-enter-x':\n ENTER_TRANSLATION[notificationEnterFrom].x,\n '--str-chat__notification-list-enter-y':\n ENTER_TRANSLATION[notificationEnterFrom].y,\n } as React.CSSProperties\n }\n >\n <div\n aria-hidden\n className='str-chat__notification-list__edge str-chat__notification-list__edge--top'\n />\n <NotificationComponent\n entryDirection={notificationEnterFrom}\n key={notification.id}\n notification={notification}\n onDismiss={() => dismiss(notification.id)}\n ref={(element) => {\n observedElementRef.current = element;\n }}\n showClose={!notification.duration}\n transitionState={transitionState}\n />\n <div\n aria-hidden\n className='str-chat__notification-list__edge str-chat__notification-list__edge--bottom'\n />\n </div>\n );\n};\n","import { useMemo, useRef } from 'react';\n\nimport type { AriaLivePriority } from '../useAriaLiveAnnouncer';\nimport { useAriaLiveAnnouncer } from '../useAriaLiveAnnouncer';\nimport { useDebouncedAnnounce } from '../scheduling';\nimport { useTranslationContext } from '../../../context/TranslationContext';\n\ntype TranslateFn = ReturnType<typeof useTranslationContext>['t'];\n\n/**\n * Optional delivery overrides a call site may pass ALONGSIDE an interaction's message params.\n * These are not consumed by the message resolver — they only affect how the announcement is\n * delivered. `debounceMs` overrides that interaction's default debounce ({@link\n * INTERACTION_DEBOUNCE_MS}) for THIS call, and enables debouncing for an interaction that has no\n * default. `delayMs` overrides the default delay ({@link INTERACTION_DELAY_MS}) for the\n * (non-debounced) immediate path. Param-less (discrete) interactions are always immediate and do\n * not accept overrides.\n *\n * `debounceMs` vs `delayMs`: a debounce collapses rapid repeats on a per-call-site timer and is\n * **cancelled if that call site unmounts** — right for a value that keeps changing in place (a\n * result count). `delayMs` schedules a single deferred emit in the shared announcer PROVIDER, so it\n * **survives the caller unmounting** — right for a one-shot confirmation whose origin (e.g. a list\n * row) disappears on the very action being confirmed (opening a channel/thread hides the list on\n * mobile). Both let the message land after a competing focus/typing read-out. `debounceMs` wins if\n * both are given.\n */\nexport type InteractionDeliveryOptions = { debounceMs?: number; delayMs?: number };\n\n/**\n * Parameters accepted by each parameterized interaction announcement.\n * Interactions that take no parameters map to `undefined`. Param-ful interactions additionally\n * accept {@link InteractionDeliveryOptions} (e.g. a per-call `debounceMs`).\n */\nexport type InteractionAnnouncementParams = {\n /** Audio playback speed was changed via the playback-rate button. `rate` is the new multiplier. */\n 'audioPlayer.playbackRateChanged': InteractionDeliveryOptions & { rate: number };\n /** A channel was opened from the channel list. `name` is its display title. */\n 'channel.opened': InteractionDeliveryOptions & { name: string };\n /** A slash command was activated from the Instant Commands menu. `command` is its name. */\n 'command.selected': InteractionDeliveryOptions & { command: string };\n 'giphy.canceled': undefined;\n 'giphy.sent': undefined;\n 'giphy.shuffled': InteractionDeliveryOptions & { title?: string };\n 'poll.dialogOpened': undefined;\n /** A poll option was dropped at a new position during keyboard reorder. */\n 'poll.optionDropped': InteractionDeliveryOptions & {\n option: string;\n position: number;\n };\n /** A poll option was picked up to start a keyboard reorder. `option` is its text (or a fallback). */\n 'poll.optionPickedUp': InteractionDeliveryOptions & { option: string };\n 'poll.optionRemoved': InteractionDeliveryOptions & { option: string };\n 'poll.sent': undefined;\n 'search.cleared': undefined;\n 'search.resultCount': InteractionDeliveryOptions & {\n /** Whether every active source is fully loaded — appends an \"all results loaded\" clause. */\n allResultsLoaded?: boolean;\n count: number;\n };\n 'suggestions.count': InteractionDeliveryOptions & {\n count: number;\n suggestionsLabel?: string;\n };\n /** A thread was opened from the thread list. `name` is its channel's display title. */\n 'thread.opened': InteractionDeliveryOptions & { name: string };\n 'user.selected': InteractionDeliveryOptions & { user: string };\n /** A finished voice recording was added to the composer (async multi-send: not sent yet). */\n 'voiceRecording.attached': undefined;\n 'voiceRecording.paused': undefined;\n 'voiceRecording.resumed': undefined;\n /** A finished voice recording was sent immediately as a message. */\n 'voiceRecording.sent': undefined;\n 'voiceRecording.started': undefined;\n};\n\nexport type InteractionAnnouncementType = keyof InteractionAnnouncementParams;\n\n/**\n * One entry per interaction — the single place an interaction is registered. Each\n * resolver contains a LITERAL `t(key, 'English copy')` call, which is what puts the key in the\n * catalog: `yarn build-translations` parses the call sites to generate `src/i18n/keys.ts`. Keys\n * must never be built dynamically (e.g. `t(someVariable)`) or they are missed, and an integrator\n * has no way to discover them. Adding an interaction = one line here + one\n * line in {@link InteractionAnnouncementParams} (+ an override in\n * {@link INTERACTION_PRIORITIES} only if it is not `polite`).\n */\nconst INTERACTION_MESSAGES: {\n [T in InteractionAnnouncementType]: (\n t: TranslateFn,\n params: InteractionAnnouncementParams[T],\n ) => string;\n} = {\n // Confirms the new audio playback speed after the user cycles it with the playback-rate button.\n // Reuses the existing (already-localized) button label so the spoken text matches the control.\n 'audioPlayer.playbackRateChanged': (t, params) =>\n t('common.playbackSpeedX.label', 'Playback speed {{ rate }}x', { rate: params.rate }),\n // Confirms which channel was opened after selecting it from the list. Delayed (see\n // INTERACTION_DELAY_MS) so it lands AFTER the screen reader's announcement of the newly-focused\n // element (the message composer auto-focuses on channel change) rather than competing with — and\n // being superseded by — that native focus read-out. A provider-managed delay (not a per-row\n // debounce) so it still fires when selecting the channel unmounts the list (mobile).\n 'channel.opened': (t, params) =>\n t(\n 'a11y.interactionAnnouncements.openedChannel.ariaLabel',\n 'Opened channel: {{ name }}',\n { name: params.name },\n ),\n // Confirms which slash command was activated after picking it from the Instant Commands menu.\n // Delayed (INTERACTION_DELAY_MS) for the same reason as the \"opened\" confirmations: selecting a\n // command closes the menu and focuses the composer textarea (whose name changes, e.g. to\n // \"Search GIFs\"), so the screen reader reads that focus first — this lands after it. A provider\n // delay (not a debounce) because the menu that fired it unmounts on selection.\n 'command.selected': (t, params) =>\n t(\n 'a11y.interactionAnnouncements.commandActivated.ariaLabel',\n 'Command activated: {{ command }}',\n { command: params.command },\n ),\n 'giphy.canceled': (t) =>\n t('a11y.interactionAnnouncements.giphyCanceled.ariaLabel', 'Giphy canceled'),\n 'giphy.sent': (t) =>\n t('a11y.interactionAnnouncements.giphySent.ariaLabel', 'Giphy sent'),\n // Giphy payloads rarely carry a human title, so include it only when present; otherwise a\n // generic \"changed\" confirmation. Both literal keys land in the catalog.\n 'giphy.shuffled': (t, params) =>\n params.title\n ? t(\n 'a11y.interactionAnnouncements.giphyImageChanged.withTitle.ariaLabel',\n 'Giphy image changed: {{ title }}',\n { title: params.title },\n )\n : t(\n 'a11y.interactionAnnouncements.giphyImageChanged.ariaLabel',\n 'Giphy image changed',\n ),\n // Spoken on poll-dialog open. Reuses the already-localized visible description for the middle\n // clause (so the spoken and visible text stay consistent) and adds two short aria-only phrases:\n // an explicit \"opened\" confirmation and the Enter affordance to step into the Question field.\n 'poll.dialogOpened': (t) =>\n `${t('a11y.interactionAnnouncements.pollDialogOpened.ariaLabel', 'Poll dialog opened')}. ${t(\n 'common.createQuestionAddOptions.label',\n 'Create a question, add options, and configure poll settings',\n )}. ${t('a11y.interactionAnnouncements.pressEnterStartTyping.ariaLabel', 'Press Enter to start typing')}.`,\n // Keyboard reorder pickup/drop. Assertive (see INTERACTION_PRIORITIES) — immediate drag feedback\n // that must not be queued behind other polite messages.\n 'poll.optionDropped': (t, params) =>\n t(\n 'a11y.interactionAnnouncements.droppedPosition.ariaLabel',\n 'Dropped \"{{ option }}\" at position {{ position }}.',\n {\n option: params.option,\n position: params.position,\n },\n ),\n 'poll.optionPickedUp': (t, params) =>\n t(\n 'a11y.interactionAnnouncements.pickedUpUseArrow.ariaLabel',\n 'Picked up \"{{ option }}\". Use arrow keys to reorder. Press Space or Tab to drop.',\n { option: params.option },\n ),\n // Confirms a poll option was removed, naming it by its text (or positional fallback). Polite so it\n // queues behind the focus move to the next option field instead of interrupting it.\n 'poll.optionRemoved': (t, params) =>\n t(\n 'a11y.interactionAnnouncements.removedOption.ariaLabel',\n 'Removed option {{ option }}',\n { option: params.option },\n ),\n 'poll.sent': (t) => t('a11y.interactionAnnouncements.pollSent.ariaLabel', 'Poll sent'),\n 'search.cleared': (t) =>\n t('a11y.interactionAnnouncements.searchCleared.ariaLabel', 'Search cleared'),\n // The number of items currently listed in the search results; an empty result set is spelled out\n // rather than announced as \"0\". When the list is fully loaded, the end-of-list status is folded\n // into THIS one announcement (reusing the visible footer's \"All results loaded\" text) instead of a\n // competing second live-region message that would supersede the count.\n 'search.resultCount': (t, params) => {\n if (params.count <= 0)\n return t(\n 'a11y.interactionAnnouncements.noSearchResultsFound.ariaLabel',\n 'No search results found',\n );\n const count = t('a11y.interactionAnnouncements.searchResults.ariaLabel', {\n count: params.count,\n defaultValue_one: '{{ count }} search result',\n defaultValue_other: '{{ count }} search results',\n });\n return params.allResultsLoaded\n ? `${count}. ${t('common.resultsLoaded.label', 'All results loaded')}`\n : count;\n },\n // Name the suggestion type by reusing the already-localized list label (\"5 Command\n // Suggestions\") so the user knows what the results are; fall back to the bare count when no\n // label is given. Both literal keys are extracted.\n 'suggestions.count': (t, params) =>\n params.suggestionsLabel\n ? t('a11y.interactionAnnouncements.suggestionsWithLabel.ariaLabel', {\n count: params.count,\n defaultValue_one: '{{ count }} {{ suggestionsLabel }}',\n defaultValue_other: '{{ count }} {{ suggestionsLabel }}',\n suggestionsLabel: params.suggestionsLabel,\n })\n : t('a11y.interactionAnnouncements.suggestions.ariaLabel', {\n count: params.count,\n defaultValue_one: '{{ count }} suggestion',\n defaultValue_other: '{{ count }} suggestions',\n }),\n // Confirms which thread was opened after selecting it from the list; `name` is the thread's\n // channel display title. Delayed for the same reason as `channel.opened` (the thread composer\n // auto-focuses on open, and its focus announcement would otherwise supersede this one).\n 'thread.opened': (t, params) =>\n t(\n 'a11y.interactionAnnouncements.openedThread.ariaLabel',\n 'Opened thread in {{ name }}',\n { name: params.name },\n ),\n 'user.selected': (t, params) =>\n t(\n 'a11y.interactionAnnouncements.userSelected.ariaLabel',\n 'User selected: {{ user }}',\n { user: params.user },\n ),\n // Voice recorder lifecycle — discrete, immediate, polite confirmations. Cancellation is NOT here:\n // it already emits an app notification (\"Voice message deleted\") announced by NotificationAnnouncer,\n // and recording errors surface as error notifications; adding them here would double-announce.\n 'voiceRecording.attached': (t) =>\n t(\n 'a11y.interactionAnnouncements.voiceRecordingAttached.ariaLabel',\n 'Voice recording attached',\n ),\n 'voiceRecording.paused': (t) =>\n t('a11y.interactionAnnouncements.recordingPaused.ariaLabel', 'Recording paused'),\n 'voiceRecording.resumed': (t) =>\n t('a11y.interactionAnnouncements.recordingResumed.ariaLabel', 'Recording resumed'),\n 'voiceRecording.sent': (t) =>\n t('a11y.interactionAnnouncements.voiceMessageSent.ariaLabel', 'Voice message sent'),\n 'voiceRecording.started': (t) =>\n t('a11y.interactionAnnouncements.recordingStarted.ariaLabel', 'Recording started'),\n};\n\n/**\n * Per-interaction aria-live priority. Interactions default to `polite`; list one\n * here only to override it (e.g. with `assertive`).\n */\nconst INTERACTION_PRIORITIES: Partial<\n Record<InteractionAnnouncementType, AriaLivePriority>\n> = {\n // Assertive on open: a polite update fired around the dialog's focus-entry announcement is\n // dropped; assertive interrupts and is spoken (VoiceOver demotes the aria-describedby hint).\n 'poll.dialogOpened': 'assertive',\n // Keyboard reorder feedback must be immediate (interrupt), not queued behind polite messages.\n 'poll.optionDropped': 'assertive',\n 'poll.optionPickedUp': 'assertive',\n};\n\n/**\n * Per-interaction dedupe window (ms): an identical message for this interaction is announced at\n * most once per window (see {@link AriaLiveAnnounceOptions.dedupeMs}). List an interaction here\n * only when the SAME open/mount can fire it more than once in quick succession — e.g. a mount\n * effect double-invoked by React StrictMode (dev) — so the user does not hear a duplicate.\n */\nconst INTERACTION_DEDUPE_MS: Partial<Record<InteractionAnnouncementType, number>> = {\n // The audio player is pooled: if the same asset is rendered by two widgets they share one player,\n // so a single rate change fires this from both consumers. Dedupe collapses the identical message.\n // (Cycling always lands on a different rate → different text, so this never swallows a real change.)\n 'audioPlayer.playbackRateChanged': 300,\n 'poll.dialogOpened': 1000,\n};\n\n/**\n * Default per-interaction debounce delay (ms). Only list rapidly-updating streams where just the\n * settled value should be read (e.g. the autocomplete count as the query filters). Discrete\n * confirmations (Giphy/Poll sent, user selected) are NOT listed and announce immediately. A call\n * site can override (or opt into) a delay for a single call via `params.debounceMs` — see\n * {@link InteractionDeliveryOptions}.\n *\n * `suggestions.count` is a CONSEQUENCE OF TYPING, so the delay does double duty: it coalesces\n * rapid filters into the settled value AND lets the screen reader's per-keystroke typing echo\n * (the spoken character + field re-read) finish first. A polite update that lands mid-echo gets\n * queued behind a long re-read and is perceived as buried; waiting past the echo makes the count\n * the next thing spoken once the user pauses. This is a heuristic — echo length varies with the\n * SR's \"speak typed words/characters\" setting and field content — so tune if it still collides.\n */\nconst INTERACTION_DEBOUNCE_MS: Partial<Record<InteractionAnnouncementType, number>> = {\n // Coalesce the result count as the query filters / results stream in, and let the screen reader's\n // typing echo finish first (same rationale as `suggestions.count`, slightly longer as search\n // results can arrive over the network in bursts). The end-of-list status rides along in this same\n // message (see `search.resultCount` resolver), so there is no second announcement to compete.\n 'search.resultCount': 1000,\n 'suggestions.count': 500,\n};\n\n/**\n * Default per-interaction delay (ms) for the immediate (non-debounced) path — a single deferred\n * emit scheduled in the announcer PROVIDER (see {@link AriaLiveAnnounceOptions.delayMs}), so it\n * SURVIVES the calling component unmounting (unlike a debounce, whose timer is cleared on unmount).\n *\n * Opening a channel/thread moves focus to the (auto-focusing) message composer; the screen reader\n * announces that newly-focused element first, and a live-region message emitted alongside it is\n * superseded and dropped. The delay defers the confirmation past that focus read-out so it is spoken\n * next, in a calm moment. It is a provider delay rather than a debounce specifically because\n * selecting the item can unmount its list row (and the whole list, on mobile) — a per-row debounce\n * would be cancelled mid-flight, swallowing the confirmation.\n */\nconst INTERACTION_DELAY_MS: Partial<Record<InteractionAnnouncementType, number>> = {\n 'channel.opened': 1500,\n 'command.selected': 1500,\n 'thread.opened': 1500,\n};\n\n// Overloads enforce that parameterized interactions require their params and that\n// param-less interactions reject extra arguments.\ntype AnnounceInteraction = {\n <T extends InteractionAnnouncementType>(\n interaction: InteractionAnnouncementParams[T] extends undefined ? T : never,\n ): void;\n <T extends InteractionAnnouncementType>(\n interaction: InteractionAnnouncementParams[T] extends undefined ? never : T,\n params: InteractionAnnouncementParams[T],\n ): void;\n};\n\nexport type UseInteractionAnnouncementsValue = {\n /**\n * Announce a predefined interaction event to assistive technology. The\n * interaction name maps to a localized message and a baked-in aria-live\n * priority.\n */\n announceInteraction: AnnounceInteraction;\n /**\n * Cancel pending (debounced, not-yet-spoken) announcements: a single `interaction`, or all when\n * omitted. Call this when the source of a debounced announcement is torn down (e.g. search exited)\n * so a queued message is not spoken after its context is gone. An announcement already emitted into\n * the live region cannot be recalled.\n */\n cancelInteraction: (interaction?: InteractionAnnouncementType) => void;\n};\n\n/**\n * Thin, typed wrapper over the aria-live announcer exposing intention-revealing\n * helpers for transient, user-initiated UI interactions (e.g. a Giphy being\n * sent, a poll being created, a mention being picked). They map to i18n keys with\n * baked-in priorities and reuse the existing live region via\n * {@link useAriaLiveAnnouncer}. New interactions are registered as a single entry\n * in {@link INTERACTION_MESSAGES}.\n */\nexport const useInteractionAnnouncements = (): UseInteractionAnnouncementsValue => {\n const announce = useAriaLiveAnnouncer();\n const { t } = useTranslationContext();\n // Per-interaction debounce: each type has its own timer + delay from INTERACTION_DEBOUNCE_MS,\n // so e.g. the typing-driven `suggestions.count` can wait longer (to clear the screen reader's\n // typing echo) without affecting any other debounced interaction.\n const { announce: announceDebounced, cancel: cancelDebounced } =\n useDebouncedAnnounce(announce);\n // Cancel fn of the still-pending provider-delayed emit per interaction. A second trigger of the\n // same interaction within its delay window supersedes the first (so only the latest is spoken).\n // NOT cleared on unmount on purpose — provider-delayed emits are designed to survive the caller\n // unmounting (e.g. channel.opened fires after its list row is gone).\n const pendingImmediateCancelsRef = useRef<\n Partial<Record<InteractionAnnouncementType, () => void>>\n >({});\n\n return useMemo(\n () => ({\n announceInteraction: (\n interaction: InteractionAnnouncementType,\n params?: InteractionAnnouncementParams[InteractionAnnouncementType],\n ) => {\n const resolveMessage = INTERACTION_MESSAGES[interaction] as (\n t: TranslateFn,\n params: InteractionAnnouncementParams[InteractionAnnouncementType],\n ) => string;\n\n if (!resolveMessage) return;\n\n const message = resolveMessage(t, params as never);\n const priority = INTERACTION_PRIORITIES[interaction] ?? 'polite';\n\n // A per-call `params.debounceMs` overrides the registered default (and can opt an\n // otherwise-immediate interaction into debouncing).\n const debounceMs =\n (params as InteractionDeliveryOptions | undefined)?.debounceMs ??\n INTERACTION_DEBOUNCE_MS[interaction];\n if (debounceMs === undefined) {\n // Immediate path. `delayMs` (if any) is a provider-managed deferral that survives this\n // call site unmounting — used by the \"opened\" confirmations, whose list row disappears on\n // selection. `debounceMs` takes precedence over `delayMs` when both are set.\n const delayMs =\n (params as InteractionDeliveryOptions | undefined)?.delayMs ??\n INTERACTION_DELAY_MS[interaction];\n // Supersede a still-pending delayed emit of the same interaction so a rapid re-trigger\n // (e.g. selecting a second channel within the 1500ms window) speaks only the latest.\n pendingImmediateCancelsRef.current[interaction]?.();\n pendingImmediateCancelsRef.current[interaction] = announce(message, {\n dedupeMs: INTERACTION_DEDUPE_MS[interaction],\n delayMs,\n priority,\n });\n return;\n }\n\n // Debounced stream (e.g. suggestions.count): coalesce rapid updates into the settled\n // value, on a channel keyed by interaction type with that type's own delay. We do NOT\n // dedupe an unchanged message here — whether a repeat is meaningful is the caller's call\n // (e.g. SuggestionList re-announces the count on each genuine re-filter so the user gets\n // feedback even when the count is steady, such as emoji results capped at a constant N).\n // The debounce window already collapses idle/rapid duplicates.\n announceDebounced(interaction, message, debounceMs, priority);\n },\n cancelInteraction: (interaction?: InteractionAnnouncementType) => {\n cancelDebounced(interaction);\n const pending = pendingImmediateCancelsRef.current;\n if (interaction) {\n pending[interaction]?.();\n delete pending[interaction];\n } else {\n Object.values(pending).forEach((cancel) => cancel?.());\n pendingImmediateCancelsRef.current = {};\n }\n },\n }),\n [announce, announceDebounced, cancelDebounced, t],\n );\n};\n","import clsx from 'clsx';\nimport type { ComponentProps, PropsWithChildren } from 'react';\nimport React, { useEffect, useRef, useState } from 'react';\nimport { FocusScope } from '@react-aria/focus';\nimport { DialogPortalEntry } from './DialogPortal';\nimport { useDialog, useDialogIsOpen } from '../hooks';\nimport { type OffsetOpt, usePopoverPosition } from '../hooks/usePopoverPosition';\nimport type { PopperLikePlacement } from '../hooks';\nimport type { Placement } from '@floating-ui/react';\nimport { AriaLiveOutlet } from '../../Accessibility';\n\nexport interface DialogAnchorOptions {\n open: boolean;\n placement: PopperLikePlacement;\n referenceElement: HTMLElement | null;\n allowFlip?: boolean;\n updateKey?: unknown;\n updatePositionOnContentResize?: boolean;\n offset?: OffsetOpt;\n}\n\nexport function useDialogAnchor<T extends HTMLElement>({\n allowFlip,\n offset,\n open,\n placement,\n referenceElement,\n updateKey,\n updatePositionOnContentResize = false,\n}: DialogAnchorOptions) {\n const [popperElement, setPopperElement] = useState<T | null>(null);\n // keeps track of the first \"chosen\" placement (after popperElement is set) to avoid popper \"jumping\" to a different placement when it updates and finds a better fit; resets when popperElement is unset (!open)\n const [stabilisedChosenPlacement, setStabilisedChosenPlacement] =\n useState<Placement | null>(null);\n\n const {\n placement: chosenPlacement,\n refs,\n strategy,\n update,\n x,\n y,\n } = usePopoverPosition({\n allowFlip,\n freeze: true,\n offset,\n placement: stabilisedChosenPlacement ?? placement,\n });\n\n if (!stabilisedChosenPlacement && popperElement && placement !== chosenPlacement) {\n setStabilisedChosenPlacement(chosenPlacement);\n } else if (stabilisedChosenPlacement && !popperElement) {\n setStabilisedChosenPlacement(null);\n }\n\n // Freeze reference when dialog opens so submenus (e.g. ContextMenu level 2+) stay aligned to the original anchor\n const frozenReferenceRef = useRef<HTMLElement | null>(null);\n if (open && referenceElement && !frozenReferenceRef.current) {\n frozenReferenceRef.current = referenceElement;\n }\n if (!open) {\n frozenReferenceRef.current = null;\n }\n const effectiveReference = open ? frozenReferenceRef.current : referenceElement;\n\n useEffect(() => {\n refs.setReference(effectiveReference);\n }, [effectiveReference, refs]);\n\n useEffect(() => {\n refs.setFloating(popperElement);\n }, [popperElement, refs]);\n\n useEffect(() => {\n if (open && popperElement && effectiveReference) {\n // Re-run when reference becomes available (e.g. after ref is set) or when updateKey changes (e.g. submenu open)\n // Since the popper's reference element might not be (and usually is not) visible\n // all the time, it's safer to force popper update before showing it.\n // update is non-null only if popperElement is non-null\n update?.();\n }\n }, [open, placement, popperElement, update, updateKey, effectiveReference]);\n\n useEffect(() => {\n if (!popperElement || !updatePositionOnContentResize) return;\n\n const resizeObserver = new ResizeObserver(update);\n\n resizeObserver.observe(popperElement);\n\n return () => {\n resizeObserver.disconnect();\n };\n }, [popperElement, update, updatePositionOnContentResize]);\n\n if (popperElement && !open) {\n setPopperElement(null);\n }\n\n return {\n placement: stabilisedChosenPlacement ?? chosenPlacement,\n setPopperElement,\n styles: {\n left: x ?? 0,\n position: strategy,\n top: y ?? 0,\n } as React.CSSProperties,\n };\n}\n\nexport type DialogAnchorProps = PropsWithChildren<Partial<DialogAnchorOptions>> & {\n /**\n * Optional per-dialog override for outside-click dismissal.\n * If undefined, manager-level `DialogManager.closeOnClickOutside` is used.\n */\n closeOnClickOutside?: boolean;\n /**\n * Whether pressing Escape closes the dialog. Symmetric with `closeOnClickOutside`; set to\n * `false` for a dialog that should only be dismissed through its own close control (e.g. a\n * long-lived inspector panel kept open while the user works elsewhere).\n * @default true\n */\n closeOnEscape?: boolean;\n id: string;\n /**\n * Delay (ms) before unmounting after dialog closes.\n * Use this to keep the dialog in DOM long enough for CSS exit animations.\n * `0` means immediate unmount (no exit-animation window).\n */\n closeTransitionMs?: number;\n dialogManagerId?: string;\n focus?: boolean;\n trapFocus?: boolean;\n} & ComponentProps<'div'>;\n\nexport const DialogAnchor = ({\n allowFlip = true,\n children,\n className,\n closeOnClickOutside,\n closeOnEscape = true,\n closeTransitionMs = 0,\n dialogManagerId,\n focus = true,\n id,\n offset,\n placement = 'auto',\n referenceElement = null,\n tabIndex,\n trapFocus,\n updateKey,\n updatePositionOnContentResize,\n ...restDivProps\n}: DialogAnchorProps) => {\n /**\n * Rendering lifecycle notes:\n * - `open=true` renders dialog contents immediately.\n * - `open=false` can keep contents mounted for `closeTransitionMs` to allow CSS exit\n * animations before unmount.\n *\n * State exposed to CSS:\n * - `data-str-chat-dialog-state=\"open\"` while actively open.\n * - `data-str-chat-dialog-state=\"closing\"` during delayed unmount window.\n *\n * Consumers like `ContextMenu` combine:\n * - `data-str-chat-dialog-state` from this component, and\n * - `data-str-chat-placement` (e.g. `top-start`, `right-end`)\n * to select the correct closing keyframe in CSS (horizontal vs vertical roll direction).\n * In practice, JS only toggles state and timing (`closeTransitionMs`); CSS owns the\n * visual motion details (transform/easing), so animation behavior stays declarative.\n */\n const dialog = useDialog({ closeOnClickOutside, dialogManagerId, id });\n const open = useDialogIsOpen(id, dialogManagerId);\n const [shouldRender, setShouldRender] = useState(open);\n const closeTimeoutRef = useRef<NodeJS.Timeout | null>(null);\n const isClosing = !open && shouldRender;\n\n useEffect(() => {\n if (open) {\n setShouldRender(true);\n if (closeTimeoutRef.current) {\n clearTimeout(closeTimeoutRef.current);\n closeTimeoutRef.current = null;\n }\n return;\n }\n\n if (!shouldRender) return;\n if (!closeTransitionMs) {\n setShouldRender(false);\n return;\n }\n\n closeTimeoutRef.current = setTimeout(() => {\n setShouldRender(false);\n closeTimeoutRef.current = null;\n }, closeTransitionMs);\n }, [closeTransitionMs, open, shouldRender]);\n\n useEffect(\n () => () => {\n if (closeTimeoutRef.current) clearTimeout(closeTimeoutRef.current);\n },\n [],\n );\n\n const {\n placement: chosenPlacement,\n setPopperElement,\n styles,\n } = useDialogAnchor<HTMLDivElement>({\n allowFlip,\n offset,\n open: shouldRender,\n placement,\n referenceElement,\n updateKey,\n updatePositionOnContentResize,\n });\n\n useEffect(() => {\n if (!open || !closeOnEscape) return;\n const hideOnEscape = (event: KeyboardEvent) => {\n if (event.key !== 'Escape' || event.defaultPrevented) return;\n dialog?.close();\n };\n\n document.addEventListener('keyup', hideOnEscape);\n\n return () => {\n document.removeEventListener('keyup', hideOnEscape);\n };\n }, [closeOnEscape, dialog, open]);\n\n // prevent rendering the dialog contents if the dialog should not be open / shown\n if (!shouldRender) {\n return null;\n }\n\n const {\n ['aria-describedby']: ariaDescribedBy,\n ['aria-label']: ariaLabel,\n ['aria-labelledby']: ariaLabelledBy,\n ['aria-modal']: ariaModal,\n role,\n ...anchorDivProps\n } = restDivProps;\n const resolvedRole = trapFocus ? (role ?? 'dialog') : role;\n const resolvedAriaModal = trapFocus ? true : ariaModal;\n const resolvedAriaLabel = ariaLabelledBy ? undefined : ariaLabel;\n\n return (\n <DialogPortalEntry dialogId={id} dialogManagerId={dialogManagerId}>\n <FocusScope autoFocus={focus} contain={trapFocus} restoreFocus>\n <div\n {...anchorDivProps}\n aria-describedby={ariaDescribedBy}\n aria-label={resolvedAriaLabel}\n aria-labelledby={ariaLabelledBy}\n aria-modal={resolvedAriaModal}\n className={clsx('str-chat__dialog-contents', className)}\n data-str-chat-dialog-state={isClosing ? 'closing' : 'open'}\n data-str-chat-placement={chosenPlacement}\n data-testid='str-chat__dialog-contents'\n ref={setPopperElement}\n role={resolvedRole}\n style={styles}\n tabIndex={typeof tabIndex !== 'undefined' ? tabIndex : 0}\n >\n {children}\n {/* Render the live-region outlet inside the dialog subtree only when it\n is an `aria-modal` dialog, so announcements are not suppressed by\n assistive technologies. Non-modal popovers/menus skip it. */}\n {resolvedAriaModal && <AriaLiveOutlet layer={1} />}\n </div>\n </FocusScope>\n </DialogPortalEntry>\n );\n};\n","import { nanoid } from 'nanoid';\nimport React, { useMemo } from 'react';\n\nconst reactUseId = React.useId as (() => string) | undefined;\n\n// Strips React.useId() wrapper characters so the value is safe as an HTML id:\n// from React 19.0 (`:r0:` -> `r0`) and 19.1 (`«r0»` -> `r0`);\n// 19.2+ uses `_r_1_` which is safe and doesn't need stripping\nexport const stripUseIdWrappers = (id: string): string => id.replace(/[:«»]/g, '');\n\n/**\n * Returns a stable, unique string id.\n *\n * On React 18+ this delegates to `React.useId()` (with the surrounding wrapper\n * characters stripped so the value is safe to use anywhere an HTML id is expected)\n * and is SSR-stable. On React 17, it falls back to a client-only id generated via `nanoid`.\n */\nexport const useStableId = () => {\n if (reactUseId) return stripUseIdWrappers(reactUseId());\n // eslint-disable-next-line react-hooks/rules-of-hooks\n return useMemo(() => nanoid(), []);\n};\n","import clsx from 'clsx';\nimport React, {\n type ComponentProps,\n type ComponentPropsWithoutRef,\n type ComponentType,\n type ReactNode,\n useCallback,\n useContext,\n useEffect,\n useLayoutEffect,\n useMemo,\n useRef,\n useState,\n} from 'react';\nimport { type AvatarProps, Avatar as DefaultAvatar } from '../../Avatar';\nimport type { PopperLikePlacement } from '../hooks';\nimport { useDialogIsOpen, useDialogOnNearestManager } from '../hooks';\nimport type { DialogAnchorProps } from '../service/DialogAnchor';\nimport { DialogAnchor, useDialogAnchor } from '../service/DialogAnchor';\nimport {\n useComponentContext,\n useComponentContextIcons,\n useTranslationContext,\n} from '../../../context';\nimport { createRovingFocusKeyDownHandler } from '../../../a11y/a11yUtils';\nimport { VisuallyHidden } from '../../VisuallyHidden';\nimport { useStableId } from '../../UtilityComponents/useStableId';\nimport { requireContext } from '../../../context/requireContext';\n\n/**\n * ContextMenu module\n *\n * What this file provides\n * - Primitives for contextual action UIs:\n * `ContextMenu`, `ContextMenuContent`, `ContextMenuButton`, `ContextMenuHeader`,\n * `ContextMenuBody`, `ContextMenuBackButton`, and user/emoji button variants.\n * - A small runtime context (`useContextMenuContext`) used by menu items to:\n * - close the current menu (`closeMenu`)\n * - open a submenu (`openSubmenu`)\n * - return to parent level (`returnToParentMenu`)\n *\n * Rendering modes\n * - Anchored mode (most common): pass `id` and `referenceElement`.\n * The component renders inside `DialogAnchor` and uses dialog manager state.\n * - Inline mode: omit anchor props and render as a plain contextual list.\n * - Outside click dismissal can be overridden per menu via `closeOnClickOutside`;\n * otherwise manager default is used.\n *\n * Submenu model\n * - Submenus are represented as a stack of menu levels.\n * - Each level can define `Header`, `Submenu`, `items`, `ItemsWrapper`,\n * and `menuClassName`.\n * - Opening submenu pushes a level to the stack; going back pops one level.\n * - When anchored menu closes, stack resets to root to avoid stale submenu state\n * on next open.\n *\n * Animation model\n * - Root menu open/close is handled by `DialogAnchor` transition timing.\n * - `ContextMenu` defaults `closeTransitionMs` to `130` so close animations can be visible.\n * - `DialogAnchor` marks rendered content with `data-str-chat-dialog-state`:\n * - `open` while visible\n * - `closing` during delayed unmount window (`closeTransitionMs`)\n * - Context-menu closing keyframes in `ContextMenu.scss` target\n * `[data-str-chat-dialog-state='closing']` + placement selectors.\n * - Level-to-level transitions are directional:\n * - forward: parent -> submenu\n * - backward: submenu -> parent\n * - Direction is tracked in `ContextMenu` and passed to `ContextMenuContent`.\n * - `ContextMenuContent` bumps an internal key for `ContextMenuBody` so React\n * remounts the body and CSS enter animation reliably restarts on each level change.\n * - Initial/root menu render does not apply submenu forward/backward classes;\n * directional animation classes are used only for submenu transitions.\n * - `enableAnimations` can disable content animations through data attributes/CSS.\n * - `submenuTransitionDurationMs` controls how long directional transition state is kept.\n *\n * Submenu popover behavior (`ContextMenuButton` with `Submenu`)\n * - Submenu can be rendered by passing `Submenu` (and optional placement/container props).\n * - Default submenu roll axis is `x` (override with `submenuRollAxis`).\n * - Hover/focus management uses a \"keep open\" ref flag plus lazy close timeout to avoid\n * accidental submenu dismissal when moving pointer/focus between parent and submenu.\n *\n * Customization via `ComponentContext`\n * - `ComponentContext.ContextMenu` replaces the whole menu component at SDK call sites.\n * - `ComponentContext.ContextMenuContent` replaces content-level behavior while preserving\n * default anchoring/dialog integration from `ContextMenu`.\n * - Built-in call sites (message actions, channel list action buttons, attachment selector,\n * suggestion list) resolve `ContextMenu` from `ComponentContext` with fallback to default.\n */\nexport type BaseContextMenuButtonProps = {\n details?: ReactNode;\n hasSubMenu?: boolean;\n label?: ReactNode;\n Icon?: ComponentType<ComponentProps<'svg'>>;\n SubmenuIcon?: ComponentType<ComponentProps<'svg'>>;\n variant?: 'destructive';\n} & ComponentProps<'button'>;\n\nexport const BaseContextMenuButton = ({\n children,\n className,\n details,\n hasSubMenu,\n Icon,\n label,\n role = 'menuitem',\n SubmenuIcon,\n variant,\n ...props\n}: BaseContextMenuButtonProps) => {\n const { IconChevronRight } = useComponentContextIcons();\n const ResolvedSubmenuIcon = SubmenuIcon ?? IconChevronRight;\n\n return (\n <button\n {...props}\n className={clsx(\n 'str-chat__context-menu__button',\n {\n 'str-chat__context-menu__button--with-submenu': hasSubMenu,\n [`str-chat__context-menu__button--${variant}`]: typeof variant === 'string',\n },\n className,\n )}\n role={role}\n type='button'\n >\n {Icon && <Icon className='str-chat__context-menu__button__icon' />}\n {label ? (\n <>\n <div className='str-chat__context-menu__button__label'>{label}</div>\n <div className='str-chat__context-menu__button__details'>{details}</div>\n </>\n ) : (\n <div className='str-chat__context-menu__button__label'>{children}</div>\n )}\n {!!hasSubMenu && (\n <ResolvedSubmenuIcon className='str-chat__context-menu__button__submenu-icon' />\n )}\n </button>\n );\n};\n\nexport type UserContextMenuButtonProps = Pick<AvatarProps, 'imageUrl' | 'userName'> &\n ComponentProps<'button'>;\n\nexport const UserContextMenuButton = ({\n children,\n className,\n imageUrl,\n role = 'menuitem',\n userName,\n ...props\n}: UserContextMenuButtonProps) => {\n const { Avatar = DefaultAvatar } = useComponentContext();\n return (\n <button\n {...props}\n className={clsx(\n 'str-chat__context-menu__button str-chat__user-context-menu__button',\n className,\n )}\n role={role}\n type='button'\n >\n {/* The avatar is decorative here: the button already carries the user's name as its\n label, so exposing the avatar (its fallback initials, title, and role=\"button\")\n to assistive tech only adds noise to the option's accessible name. */}\n <Avatar aria-hidden imageUrl={imageUrl} size='sm' userName={userName} />\n <div className='str-chat__context-menu__button__label'>{children ?? userName}</div>\n </button>\n );\n};\n\nexport type EmojiContextMenuButtonProps = { emoji: string } & Pick<\n BaseContextMenuButtonProps,\n 'label'\n> &\n ComponentProps<'button'>;\n\nexport const EmojiContextMenuButton = ({\n children,\n className,\n emoji,\n label,\n role = 'menuitem',\n ...props\n}: EmojiContextMenuButtonProps) => (\n <button\n {...props}\n className={clsx(\n 'str-chat__context-menu__button str-chat__emoji-context-menu__button',\n className,\n )}\n role={role}\n type='button'\n >\n <span className='str-chat__context-menu__button__emoji str-chat__emoji-item--entity'>\n {emoji}\n </span>\n <div className='str-chat__context-menu__button__label'>{children ?? label}</div>\n </button>\n);\n\ntype ButtonWithSubmenuProps = {\n Submenu: ComponentType;\n submenuContainerProps?: ComponentProps<'div'>;\n submenuPlacement?: PopperLikePlacement;\n submenuRollAxis?: 'x' | 'y';\n};\n\nconst ContextMenuButtonWithSubmenu = ({\n children,\n className,\n Submenu,\n submenuContainerProps,\n submenuPlacement = 'right-start',\n submenuRollAxis = 'x',\n ...buttonProps\n}: BaseContextMenuButtonProps & ButtonWithSubmenuProps) => {\n const { className: submenuClassName, ...submenuContainerRestProps } =\n submenuContainerProps ?? {};\n const { registerDialogSubmenu, unregisterDialogSubmenu } = useContextMenuContext();\n const buttonRef = useRef<HTMLButtonElement | null>(null);\n const [dialogContainer, setDialogContainer] = useState<HTMLDivElement | null>(null);\n const keepSubmenuOpenFlag = useRef(false);\n const dialogCloseTimeout = useRef<NodeJS.Timeout | null>(null);\n const dialogId = useMemo(() => `submenu-${Math.random().toString(36).slice(2)}`, []);\n const { dialog, dialogManager } = useDialogOnNearestManager({ id: dialogId });\n const dialogIsOpen = useDialogIsOpen(dialogId, dialogManager?.id);\n\n useEffect(() => {\n if (!dialogIsOpen) return;\n registerDialogSubmenu();\n return () => unregisterDialogSubmenu();\n }, [dialogIsOpen, registerDialogSubmenu, unregisterDialogSubmenu]);\n const {\n placement: chosenPlacement,\n setPopperElement,\n styles,\n } = useDialogAnchor<HTMLDivElement>({\n offset: 8,\n open: dialogIsOpen,\n placement: submenuPlacement,\n referenceElement: buttonRef.current,\n });\n\n const closeDialogLazily = useCallback(() => {\n if (dialogCloseTimeout.current) clearTimeout(dialogCloseTimeout.current);\n dialogCloseTimeout.current = setTimeout(() => {\n if (keepSubmenuOpenFlag.current) return;\n dialog.close();\n }, 100);\n }, [dialog]);\n\n const keepSubmenuOpen = useCallback(() => {\n keepSubmenuOpenFlag.current = true;\n }, []);\n\n const allowToCloseSubmenu = useCallback(() => {\n keepSubmenuOpenFlag.current = false;\n }, []);\n\n const closeSubmenu = useCallback(() => {\n allowToCloseSubmenu();\n closeDialogLazily();\n }, [allowToCloseSubmenu, closeDialogLazily]);\n\n const handleClose = useCallback(\n (event: Event) => {\n const parentButton = buttonRef.current;\n if (!dialogIsOpen || !parentButton) return;\n event.stopPropagation();\n closeDialogLazily();\n parentButton.focus();\n },\n [closeDialogLazily, dialogIsOpen, buttonRef],\n );\n\n const handleFocusParentButton = () => {\n if (dialogIsOpen) return;\n dialog.open();\n keepSubmenuOpen();\n };\n\n useEffect(() => {\n const parentButton = buttonRef.current;\n if (!dialogIsOpen || !parentButton) return;\n const hideOnEscape = (event: KeyboardEvent) => {\n if (event.key !== 'Escape') return;\n handleClose(event);\n closeSubmenu();\n };\n\n document.addEventListener('keyup', hideOnEscape, { capture: true });\n\n return () => {\n document.removeEventListener('keyup', hideOnEscape, { capture: true });\n };\n }, [dialogIsOpen, handleClose, closeSubmenu]);\n\n return (\n <>\n <BaseContextMenuButton\n aria-expanded={dialogIsOpen}\n aria-haspopup='menu'\n className={clsx(className, 'str_chat__button-with-submenu', {\n 'str_chat__button-with-submenu--submenu-open': dialogIsOpen,\n })}\n hasSubMenu\n onBlur={closeSubmenu}\n onClick={(event) => {\n event.stopPropagation();\n dialog.toggle();\n }}\n onFocus={handleFocusParentButton}\n onMouseEnter={handleFocusParentButton}\n onMouseLeave={closeSubmenu}\n {...buttonProps}\n ref={buttonRef}\n >\n {children}\n </BaseContextMenuButton>\n {dialogIsOpen && (\n <div\n className={clsx('str-chat__context-menu__submenu-container', submenuClassName)}\n data-str-chat-placement={chosenPlacement}\n data-str-chat-roll-axis={submenuRollAxis}\n onBlur={(event) => {\n const isBlurredDescendant =\n event.relatedTarget instanceof Node &&\n dialogContainer?.contains(event.relatedTarget);\n if (isBlurredDescendant) return;\n closeSubmenu();\n }}\n onFocus={keepSubmenuOpen}\n onMouseEnter={keepSubmenuOpen}\n onMouseLeave={closeSubmenu}\n ref={(element) => {\n setPopperElement(element);\n setDialogContainer(element);\n }}\n style={styles}\n tabIndex={-1}\n {...submenuContainerRestProps}\n >\n <Submenu />\n </div>\n )}\n </>\n );\n};\n\ntype ContextMenuButtonProps = BaseContextMenuButtonProps &\n Partial<ButtonWithSubmenuProps>;\n\nexport const ContextMenuButton = (props: ContextMenuButtonProps) => {\n const {\n Submenu,\n submenuContainerProps,\n submenuPlacement,\n submenuRollAxis,\n ...buttonProps\n } = props;\n if (Submenu) {\n return (\n <ContextMenuButtonWithSubmenu\n {...buttonProps}\n Submenu={Submenu}\n submenuContainerProps={submenuContainerProps}\n submenuPlacement={submenuPlacement}\n submenuRollAxis={submenuRollAxis}\n />\n );\n }\n\n return <BaseContextMenuButton {...buttonProps} />;\n};\n\nexport const ContextMenuBackButton = ({\n 'aria-label': ariaLabel,\n 'aria-labelledby': ariaLabelledBy,\n children,\n className,\n role = 'menuitem',\n ...props\n}: ComponentProps<'button'>) => {\n const { t } = useTranslationContext();\n const generatedBackNavigationLabelId = useStableId();\n const generatedVisibleLabelId = useStableId();\n const resolvedAriaLabel =\n ariaLabel ??\n t('dialog.contextMenu.backParentMenuButton.ariaLabel', 'Back to parent menu button');\n const resolvedAriaLabelledBy =\n ariaLabelledBy ?? `${generatedVisibleLabelId} ${generatedBackNavigationLabelId}`;\n\n return (\n <button\n {...props}\n aria-labelledby={resolvedAriaLabelledBy}\n className={clsx('str-chat__context-menu__back-button', className)}\n role={role}\n type='button'\n >\n {!ariaLabelledBy && (\n <VisuallyHidden id={generatedBackNavigationLabelId}>\n {resolvedAriaLabel}\n </VisuallyHidden>\n )}\n <span\n className='str-chat__context-menu__back-button__content'\n id={generatedVisibleLabelId}\n >\n {children}\n </span>\n </button>\n );\n};\n\nexport const ContextMenuHeader = ({\n children,\n className,\n ...props\n}: ComponentProps<'div'>) => (\n <div {...props} className={clsx('str-chat__context-menu__header', className)}>\n {children}\n </div>\n);\n\nexport const ContextMenuBody = ({\n children,\n className,\n ...props\n}: ComponentProps<'div'>) => (\n <div {...props} className={clsx('str-chat__context-menu__body', className)}>\n {children}\n </div>\n);\n\nexport const ContextMenuRoot = React.forwardRef<HTMLDivElement, ComponentProps<'div'>>(\n function ContextMenuRoot({ className, role = 'menu', ...props }, ref) {\n return (\n <div\n {...props}\n className={clsx('str-chat__context-menu', className)}\n ref={ref}\n role={role}\n />\n );\n },\n);\n\nexport type ContextMenuHeaderComponent = ComponentType;\nexport type ContextMenuSubmenu = ComponentType;\n\nexport type ContextMenuOpenSubmenuParams = Omit<\n ContextMenuLevel,\n 'focusRestoreRequest' | 'items'\n> & {\n focusReturnTarget?: HTMLElement | null;\n};\n\nexport type ContextMenuItemProps = ComponentProps<'button'>;\n\nexport type ContextMenuItemComponent = ComponentType<ContextMenuItemProps>;\n\nexport const DEFAULT_CONTEXT_MENU_KEYBOARD_NAVIGATION_ITEM_SELECTOR = [\n '[role=\"menuitem\"]:not(:disabled)',\n '[role=\"menuitemradio\"]:not(:disabled)',\n '[role=\"menuitemcheckbox\"]:not(:disabled)',\n].join(',');\n\nconst isVisibleContextMenuKeyboardNavigationItem = (item: HTMLElement) => {\n // Fast path: offsetParent is null for display:none elements (and their descendants).\n // offsetHeight covers position:fixed elements which have no offsetParent.\n if (item.offsetParent !== null || item.offsetHeight > 0) return true;\n\n // In environments without layout (e.g. jsdom), offsetParent/offsetHeight are always 0/null.\n // Fall back to checking inline style and the `hidden` attribute.\n if (item.hidden) return false;\n const display = item.style.display;\n if (display === 'none') return false;\n\n // If no layout info and no explicit hiding signal, assume visible.\n return true;\n};\n\ntype ContextMenuFocusRestoreRequest = {\n /** Positional fallback used when the target element is no longer in the DOM. */\n index: number;\n target: HTMLElement | null;\n};\n\nconst getVisibleContextMenuKeyboardNavigationItems = (\n contextMenuRoot: Element | null,\n itemSelector: string = DEFAULT_CONTEXT_MENU_KEYBOARD_NAVIGATION_ITEM_SELECTOR,\n) =>\n Array.from(contextMenuRoot?.querySelectorAll<HTMLElement>(itemSelector) ?? []).filter(\n isVisibleContextMenuKeyboardNavigationItem,\n );\n\nconst createContextMenuFocusRestoreRequest = ({\n contextMenuRoot,\n focusReturnTarget,\n}: {\n contextMenuRoot: Element | null;\n focusReturnTarget?: HTMLElement | null;\n}): ContextMenuFocusRestoreRequest => {\n const target =\n focusReturnTarget ??\n (document.activeElement instanceof HTMLElement ? document.activeElement : null);\n\n if (!target) return { index: -1, target: null };\n\n const index = getVisibleContextMenuKeyboardNavigationItems(contextMenuRoot).findIndex(\n (menuItem) => menuItem === target,\n );\n\n return { index, target };\n};\n\nconst resolveContextMenuFocusRestoreTarget = ({\n contextMenuRoot,\n request,\n}: {\n contextMenuRoot: Element | null;\n request: ContextMenuFocusRestoreRequest | null;\n}) => {\n if (!request) return null;\n\n // Prefer the original element if it's still in the DOM.\n if (request.target?.isConnected) return request.target;\n\n // Fall back to positional index when the element has been unmounted.\n if (request.index >= 0) {\n return (\n getVisibleContextMenuKeyboardNavigationItems(contextMenuRoot)[request.index] ?? null\n );\n }\n\n return null;\n};\n\nconst CONTEXT_MENU_HEADER_SELECTOR = '.str-chat__context-menu__header';\n\n/**\n * Where focus should land when a submenu OPENS (forward navigation):\n * - `'first-item'` (default): the first focusable item that is NOT in the header — i.e. the first\n * real menu option, skipping a back-button header — falling back to the very first item when the\n * body has none.\n * - `'first'`: the first focusable item overall (the back-button header when present).\n * - `'none'`: do not move focus on open.\n */\nexport type ContextMenuSubmenuInitialFocus = 'first' | 'first-item' | 'none';\n\nconst resolveSubmenuInitialFocusTarget = ({\n contextMenuRoot,\n initialFocus,\n itemSelector,\n}: {\n contextMenuRoot: Element | null;\n initialFocus: ContextMenuSubmenuInitialFocus;\n itemSelector?: string;\n}): HTMLElement | null => {\n if (initialFocus === 'none') return null;\n\n const items = getVisibleContextMenuKeyboardNavigationItems(\n contextMenuRoot,\n itemSelector,\n );\n if (initialFocus === 'first') return items[0] ?? null;\n\n // 'first-item': skip the header (e.g. the back button) and land on the first content item;\n // fall back to the first item overall if the body has no focusable item.\n return (\n items.find((item) => !item.closest(CONTEXT_MENU_HEADER_SELECTOR)) ?? items[0] ?? null\n );\n};\n\nexport type ContextMenuKeyboardNavigation = {\n /**\n * CSS selector used to collect focusable menu items.\n * Defaults to `[role=\"menuitem\"]:not(:disabled)`.\n */\n itemSelector?: string;\n};\n\ntype ContextMenuContextValue = {\n anchorReferenceElement?: HTMLElement | null;\n closeMenu: () => void;\n openSubmenu: (params: ContextMenuOpenSubmenuParams) => void;\n registerDialogSubmenu: () => void;\n returnToParentMenu: () => void;\n unregisterDialogSubmenu: () => void;\n};\n\nconst ContextMenuContext = React.createContext<ContextMenuContextValue | undefined>(\n undefined,\n);\n\nexport const useContextMenuContext = () =>\n requireContext(useContext(ContextMenuContext), 'useContextMenuContext', 'ContextMenu');\n\ntype ContextMenuLevel = {\n focusRestoreRequest?: ContextMenuFocusRestoreRequest;\n /**\n * Where focus lands when this level is opened as a submenu (forward navigation). Defaults to\n * `'first-item'`. Ignored for the root level (its initial focus is the dialog's `autoFocus`).\n */\n initialFocus?: ContextMenuSubmenuInitialFocus;\n items?: ContextMenuItemComponent[];\n Submenu?: ContextMenuSubmenu;\n Header?: ContextMenuHeaderComponent;\n ItemsWrapper?: ComponentType;\n menuClassName?: string;\n};\n\ntype ContextMenuBaseProps = ComponentPropsWithoutRef<'div'> & {\n backButtonAriaLabel?: string;\n backLabel?: ReactNode;\n enableAnimations?: boolean;\n Header?: ContextMenuHeaderComponent;\n /**\n * Customizes roving-focus keyboard navigation for menu items.\n * ArrowUp/ArrowDown/Home/End move focus across items matched by\n * `keyboardNavigation.itemSelector` (defaults to `[role=\"menuitem\"]:not(:disabled)`).\n * Navigation is always enabled; use this prop only to override the item selector.\n */\n keyboardNavigation?: ContextMenuKeyboardNavigation;\n onClose?: () => void;\n onMenuLevelChange?: (level: number) => void;\n /** Duration (ms) to keep submenu transition direction active for forward/backward animations. */\n submenuTransitionDurationMs?: number;\n} & ContextMenuLevel;\n\n/** When provided, ContextMenu renders inside DialogAnchor and wires menu level for submenu alignment. */\ntype ContextMenuAnchorProps = Partial<\n Pick<\n DialogAnchorProps,\n | 'id'\n | 'dialogManagerId'\n | 'placement'\n | 'referenceElement'\n | 'tabIndex'\n | 'trapFocus'\n | 'allowFlip'\n | 'closeOnClickOutside'\n | 'focus'\n | 'closeTransitionMs'\n | 'offset'\n >\n>;\n\nexport type ContextMenuProps = ContextMenuBaseProps & ContextMenuAnchorProps;\n\nexport type ContextMenuContentProps = ContextMenuBaseProps & {\n anchorReferenceElement?: HTMLElement | null;\n transitionDirection?: 'forward' | 'backward';\n};\n\n/**\n * Internal/default content renderer for {@link ContextMenu}.\n *\n * Override this through `ComponentContext.ContextMenuContent` when you need to\n * customize submenu/back navigation behavior while keeping the same anchor/focus\n * handling from `ContextMenu`.\n */\nexport function ContextMenuContent({\n anchorReferenceElement,\n backButtonAriaLabel,\n backLabel,\n children,\n className,\n enableAnimations = true,\n Header,\n items,\n ItemsWrapper,\n keyboardNavigation,\n menuClassName,\n onClose,\n onMenuLevelChange,\n transitionDirection,\n ...props\n}: ContextMenuContentProps) {\n const { t } = useTranslationContext();\n const { IconChevronLeft } = useComponentContextIcons();\n const resolvedBackLabel = backLabel ?? t('common.back.label', 'Back');\n const {\n ['aria-describedby']: rootAriaDescribedBy,\n ['aria-label']: rootAriaLabel,\n ['aria-labelledby']: rootAriaLabelledBy,\n ...contextMenuRootProps\n } = props;\n const rootLevel = useMemo<ContextMenuLevel>(\n () => ({\n Header,\n items,\n ItemsWrapper,\n menuClassName,\n }),\n [Header, items, ItemsWrapper, menuClassName],\n );\n const [menuStack, setMenuStack] = useState<ContextMenuLevel[]>(() => [rootLevel]);\n const [menuBodyAnimationKey, setMenuBodyAnimationKey] = useState(0);\n const contextMenuRootRef = useRef<HTMLDivElement | null>(null);\n const focusRestoreRequestRef = useRef<ContextMenuFocusRestoreRequest | null>(null);\n // Where to place focus when the NEXT level opens (forward navigation). Symmetric to\n // `focusRestoreRequestRef`, which handles returning to the parent (backward).\n const pendingForwardFocusRef = useRef<ContextMenuSubmenuInitialFocus | null>(null);\n const activeMenu = menuStack[menuStack.length - 1];\n\n const keyboardNavigationItemSelector =\n keyboardNavigation?.itemSelector ??\n DEFAULT_CONTEXT_MENU_KEYBOARD_NAVIGATION_ITEM_SELECTOR;\n\n const ActiveMenuItemsWrapper = activeMenu.ItemsWrapper ?? React.Fragment;\n\n const closeMenu = useCallback(() => {\n onClose?.();\n }, [onClose]);\n\n const openSubmenu = useCallback(\n ({\n focusReturnTarget,\n Header,\n initialFocus = 'first-item',\n ItemsWrapper: SubmenuItemsWrapper,\n menuClassName,\n Submenu,\n }: ContextMenuOpenSubmenuParams) => {\n // Record where focus should land in the opening submenu, so the level-change effect can move\n // it there once the new level has rendered (mirrors the backward focus restore). Clear any\n // backward request so the forward intent is what applies for this transition.\n pendingForwardFocusRef.current = initialFocus;\n focusRestoreRequestRef.current = null;\n const nextLevel: ContextMenuLevel = {\n focusRestoreRequest: createContextMenuFocusRestoreRequest({\n contextMenuRoot: contextMenuRootRef.current,\n focusReturnTarget,\n }),\n Header,\n initialFocus,\n ItemsWrapper: SubmenuItemsWrapper ?? ItemsWrapper,\n menuClassName,\n Submenu,\n };\n setMenuStack((current) => [...current, nextLevel]);\n },\n [ItemsWrapper],\n );\n\n const returnToParentMenu = useCallback(() => {\n setMenuStack((current) => {\n if (current.length <= 1) return current;\n focusRestoreRequestRef.current =\n current[current.length - 1]?.focusRestoreRequest ?? null;\n // Clear any forward intent so the backward restore is what applies for this transition.\n pendingForwardFocusRef.current = null;\n return current.slice(0, -1);\n });\n }, []);\n\n useEffect(() => {\n setMenuStack((current) => {\n if (current.length === 1 && current[0] === rootLevel) return current;\n return [rootLevel];\n });\n }, [rootLevel]);\n\n useEffect(() => {\n onMenuLevelChange?.(menuStack.length);\n }, [menuStack.length, onMenuLevelChange]);\n\n // Move focus on menu-level changes. Runs in a LAYOUT effect (before paint) and re-runs when the\n // body remounts (`menuBodyAnimationKey`) — the body is remounted a step after the level changes\n // to restart the enter animation, which removes the just-focused node. Re-applying focus in the\n // same commit that mounts the new body keeps focus in the menu with no `<body>` flicker (a naive\n // post-paint / single-rAF focus lands one frame before that remount and gets dropped). The\n // request refs are NOT consumed here (so this re-run can re-apply); each transition\n // (`openSubmenu`/`returnToParentMenu`) sets one ref and clears the other.\n useLayoutEffect(() => {\n const focusRestoreRequest = focusRestoreRequestRef.current;\n const pendingForwardFocus = pendingForwardFocusRef.current;\n if (!focusRestoreRequest && !pendingForwardFocus) return;\n\n const contextMenuRoot = contextMenuRootRef.current;\n // Backward (return to parent) restores the remembered element; it takes precedence.\n const target = focusRestoreRequest\n ? resolveContextMenuFocusRestoreTarget({\n contextMenuRoot,\n request: focusRestoreRequest,\n })\n : // Forward (submenu opened): move focus INTO the new level per its `initialFocus`, so it is\n // not lost to <body> when the parent item that had focus unmounts.\n resolveSubmenuInitialFocusTarget({\n contextMenuRoot,\n initialFocus: pendingForwardFocus as ContextMenuSubmenuInitialFocus,\n itemSelector: keyboardNavigationItemSelector,\n });\n\n target?.focus();\n }, [keyboardNavigationItemSelector, menuBodyAnimationKey, menuStack.length]);\n\n useEffect(() => {\n if (!transitionDirection) return;\n setMenuBodyAnimationKey((value) => value + 1);\n }, [transitionDirection, menuStack.length]);\n\n const dialogSubmenuOpenCountRef = useRef(0);\n\n const registerDialogSubmenu = useCallback(() => {\n dialogSubmenuOpenCountRef.current += 1;\n }, []);\n\n const unregisterDialogSubmenu = useCallback(() => {\n dialogSubmenuOpenCountRef.current = Math.max(\n 0,\n dialogSubmenuOpenCountRef.current - 1,\n );\n }, []);\n\n const rovingFocusKeyDownHandler = useMemo(\n () =>\n createRovingFocusKeyDownHandler<HTMLElement>({\n getItems: (event) =>\n getVisibleContextMenuKeyboardNavigationItems(\n event.currentTarget,\n keyboardNavigationItemSelector,\n ),\n }),\n [keyboardNavigationItemSelector],\n );\n\n const escapeConsumedRef = useRef(false);\n\n const keyboardNavigationHandler = useCallback(\n (event: React.KeyboardEvent<HTMLElement>) => {\n if (event.key === 'Escape') {\n if (dialogSubmenuOpenCountRef.current > 0) return;\n\n event.preventDefault();\n event.stopPropagation();\n\n if (menuStack.length > 1) {\n escapeConsumedRef.current = true;\n returnToParentMenu();\n } else {\n closeMenu();\n }\n return;\n }\n\n rovingFocusKeyDownHandler(event);\n },\n [closeMenu, menuStack.length, returnToParentMenu, rovingFocusKeyDownHandler],\n );\n\n const suppressEscapeKeyUp = useCallback((event: React.KeyboardEvent<HTMLElement>) => {\n if (event.key === 'Escape' && escapeConsumedRef.current) {\n escapeConsumedRef.current = false;\n event.stopPropagation();\n }\n }, []);\n const isSubmenuLevel = menuStack.length > 1;\n\n return (\n <ContextMenuContext.Provider\n value={{\n anchorReferenceElement,\n closeMenu,\n openSubmenu,\n registerDialogSubmenu,\n returnToParentMenu,\n unregisterDialogSubmenu,\n }}\n >\n <ContextMenuRoot\n aria-describedby={isSubmenuLevel ? undefined : rootAriaDescribedBy}\n aria-label={\n isSubmenuLevel\n ? t('dialog.contextMenu.submenu.ariaLabel', 'Submenu')\n : rootAriaLabel\n }\n aria-labelledby={isSubmenuLevel ? undefined : rootAriaLabelledBy}\n className={clsx(className, activeMenu.menuClassName)}\n data-str-chat-enable-animations={enableAnimations}\n onKeyDownCapture={keyboardNavigationHandler}\n onKeyUpCapture={suppressEscapeKeyUp}\n ref={contextMenuRootRef}\n {...contextMenuRootProps}\n >\n {activeMenu.Header ? (\n <activeMenu.Header />\n ) : menuStack.length > 1 ? (\n <ContextMenuHeader>\n <ContextMenuBackButton\n aria-label={backButtonAriaLabel}\n onClick={returnToParentMenu}\n >\n <IconChevronLeft />\n <span>{resolvedBackLabel}</span>\n </ContextMenuBackButton>\n </ContextMenuHeader>\n ) : null}\n <ContextMenuBody\n className={clsx({\n 'str-chat__context-menu__body--submenu-backward':\n transitionDirection === 'backward',\n 'str-chat__context-menu__body--submenu-forward':\n transitionDirection === 'forward',\n })}\n key={`context-menu-body-${menuStack.length}-${menuBodyAnimationKey}`}\n >\n {activeMenu.Submenu ? (\n <activeMenu.Submenu />\n ) : (\n <ActiveMenuItemsWrapper>\n {typeof children !== 'undefined'\n ? children\n : activeMenu.items?.map((Item, index) => (\n <Item key={`context-menu-item-${index}`} />\n ))}\n </ActiveMenuItemsWrapper>\n )}\n </ContextMenuBody>\n </ContextMenuRoot>\n </ContextMenuContext.Provider>\n );\n}\n\n/**\n * Contextual actions menu that can be used in two modes:\n *\n * - Anchored dialog mode: pass `id` + `referenceElement` (submenu-aware positioning).\n * - Inline mode: omit `id` and render a plain contextual list.\n *\n * Customization via `ComponentContext`:\n *\n * - `ContextMenu`: replace the whole menu container/behavior.\n * - `ContextMenuContent`: keep default container behavior but customize menu content\n * rendering (items, submenu transitions, back navigation UI).\n * - To customize outside-click dismissal via `ComponentContext`, provide a custom\n * `ContextMenu` that sets `closeOnClickOutside`:\n *\n * ```tsx\n * const CustomContextMenu = (props: ContextMenuProps) => (\n * <ContextMenu {...props} closeOnClickOutside={false} />\n * );\n *\n * <ComponentProvider value={{ ContextMenu: CustomContextMenu }}>\n * <Chat client={client}>{children}</Chat>\n * </ComponentProvider>\n * ```\n *\n * Example:\n * ```tsx\n * <ComponentProvider\n * value={{\n * ContextMenu: MyContextMenu,\n * ContextMenuContent: MyContextMenuContent,\n * }}\n * >\n * <Chat client={client}>{children}</Chat>\n * </ComponentProvider>\n * ```\n */\nexport const ContextMenu = (props: ContextMenuProps) => {\n const { ContextMenuContent: ContextMenuContentComponent = ContextMenuContent } =\n useComponentContext();\n const {\n allowFlip,\n closeOnClickOutside,\n closeTransitionMs = 130,\n dialogManagerId,\n focus,\n id,\n offset = 8,\n onMenuLevelChange: onMenuLevelChangeProp,\n placement,\n referenceElement,\n submenuTransitionDurationMs,\n tabIndex,\n trapFocus,\n ...menuProps\n } = props;\n const resolvedSubmenuTransitionDurationMs = submenuTransitionDurationMs ?? 460;\n\n const isAnchored = id != null;\n\n const [menuLevel, setMenuLevel] = useState(1);\n const [transitionDirection, setTransitionDirection] = useState<\n 'forward' | 'backward' | undefined\n >(undefined);\n const [contentResetToken, setContentResetToken] = useState(0);\n const transitionTimeoutRef = useRef<NodeJS.Timeout | null>(null);\n const previousMenuLevelRef = useRef(1);\n const open = useDialogIsOpen(id ?? '', dialogManagerId);\n const previousOpenRef = useRef(open);\n\n useEffect(() => {\n if (!isAnchored) return;\n\n if (previousOpenRef.current && !open) {\n setMenuLevel(1);\n setTransitionDirection(undefined);\n setContentResetToken((value) => value + 1);\n previousMenuLevelRef.current = 1;\n if (transitionTimeoutRef.current) {\n clearTimeout(transitionTimeoutRef.current);\n transitionTimeoutRef.current = null;\n }\n }\n previousOpenRef.current = open;\n }, [isAnchored, open]);\n\n useEffect(\n () => () => {\n if (transitionTimeoutRef.current) {\n clearTimeout(transitionTimeoutRef.current);\n }\n },\n [],\n );\n\n const handleMenuLevelChange = useCallback(\n (level: number) => {\n if (isAnchored) {\n const previousLevel = previousMenuLevelRef.current;\n if (level !== previousLevel) {\n setTransitionDirection(level > previousLevel ? 'forward' : 'backward');\n if (transitionTimeoutRef.current) clearTimeout(transitionTimeoutRef.current);\n transitionTimeoutRef.current = setTimeout(() => {\n setTransitionDirection(undefined);\n transitionTimeoutRef.current = null;\n }, resolvedSubmenuTransitionDurationMs);\n }\n previousMenuLevelRef.current = level;\n setMenuLevel(level);\n return;\n }\n onMenuLevelChangeProp?.(level);\n },\n [isAnchored, onMenuLevelChangeProp, resolvedSubmenuTransitionDurationMs],\n );\n\n const content = (\n <ContextMenuContentComponent\n anchorReferenceElement={isAnchored ? referenceElement : undefined}\n {...menuProps}\n key={`context-menu-content-${contentResetToken}`}\n onMenuLevelChange={handleMenuLevelChange}\n transitionDirection={transitionDirection}\n />\n );\n\n if (isAnchored) {\n const {\n ['aria-describedby']: ariaDescribedBy,\n ['aria-label']: ariaLabel,\n ['aria-labelledby']: ariaLabelledBy,\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n backButtonAriaLabel: _bbal,\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n backLabel: _b,\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n enableAnimations: _ea,\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n Header: _h,\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n items: _i,\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n ItemsWrapper: _w,\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n keyboardNavigation: _kn,\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n menuClassName: _m,\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n onClose: _c,\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n role: _r,\n ...anchorDivProps\n } = menuProps;\n const isSubmenuLevel = menuLevel > 1;\n return (\n <DialogAnchor\n allowFlip={allowFlip}\n aria-describedby={isSubmenuLevel ? undefined : ariaDescribedBy}\n aria-label={isSubmenuLevel ? undefined : ariaLabel}\n aria-labelledby={isSubmenuLevel ? undefined : ariaLabelledBy}\n closeOnClickOutside={closeOnClickOutside}\n closeTransitionMs={closeTransitionMs}\n dialogManagerId={dialogManagerId}\n focus={focus}\n id={id}\n offset={offset}\n placement={placement}\n referenceElement={referenceElement}\n tabIndex={tabIndex}\n trapFocus={trapFocus}\n updateKey={menuLevel}\n {...anchorDivProps}\n >\n {content}\n </DialogAnchor>\n );\n }\n\n return content;\n};\n","import React from 'react';\n\nimport { useTranslationContext } from '../../context/TranslationContext';\nimport { useComponentContextIcons } from '../../context';\nimport { asDynamicKey } from '../../i18n/utils';\n\nexport type EmptyStateIndicatorProps = {\n /** List Type: channel | message */\n listType?: 'channel' | 'message' | 'thread';\n messageText?: string;\n};\n\nconst UnMemoizedEmptyStateIndicator = (props: EmptyStateIndicatorProps) => {\n const { listType, messageText } = props;\n\n const { t } = useTranslationContext();\n const { IconMessageBubble, IconMessageBubbles } = useComponentContextIcons();\n\n if (listType === 'thread') return null;\n\n if (listType === 'channel') {\n const text = t(\n 'emptyState.indicator.noConversationsYet.label',\n 'No conversations yet',\n );\n return (\n <div className='str-chat__channel-list-empty'>\n <IconMessageBubbles />\n <p role='listitem'>{text}</p>\n </div>\n );\n }\n\n if (listType === 'message') {\n // `messageText` is integrator-supplied and may itself be a translation key, so it is\n // passed through `t` as-is; only the built-in default carries a key + inline copy.\n const text = messageText\n ? t(asDynamicKey(messageText))\n : t(\n 'emptyState.indicator.startConversation.label',\n 'Send a message to start the conversation',\n );\n return (\n <div className='str-chat__empty-channel'>\n <IconMessageBubble />\n <p className='str-chat__empty-channel-text' role='listitem'>\n {text}\n </p>\n </div>\n );\n }\n\n return <p>{t('emptyState.indicator.noItemsExist.text', 'No items exist')}</p>;\n};\n\nexport const EmptyStateIndicator = React.memo(\n UnMemoizedEmptyStateIndicator,\n) as typeof UnMemoizedEmptyStateIndicator;\n","import clsx from 'clsx';\nimport debounce from 'lodash.debounce';\nimport type { PropsWithChildren } from 'react';\nimport { forwardRef } from 'react';\nimport React, { useEffect, useMemo, useRef } from 'react';\nimport { DEFAULT_LOAD_PAGE_SCROLL_THRESHOLD } from '../../constants/limits';\n\n/**\n * Prevents Chrome hangups\n * See: https://stackoverflow.com/questions/47524205/random-high-content-download-time-in-chrome/47684257#47684257\n */\nconst mousewheelListener = (event: Event) => {\n if (event instanceof WheelEvent && event.deltaY === 1) {\n event.preventDefault();\n }\n};\n\ntype InfiniteScrollPaginatorOwnProps = {\n element?: React.ElementType;\n /**\n * Props spread onto the inner content wrapper (the element that directly wraps\n * `children`). Use this to e.g. mark the wrapper `role=\"presentation\"` so it stays\n * transparent in the accessibility tree and does not break the ownership between an\n * ancestor (`listbox`/`menu`) and its `option`/`menuitem` children.\n */\n contentProps?: React.ComponentProps<'div'>;\n listenToScroll?: (\n distanceFromBottom: number,\n distanceFromTop: number,\n threshold: number,\n ) => void;\n loadNextDebounceMs?: number;\n loadNextOnScrollToBottom?: () => void;\n loadNextOnScrollToTop?: () => void;\n /** Offset from when to start the loadNextPage call */\n threshold?: number;\n useCapture?: boolean;\n};\n\n// polymorphic props, defaulting to 'div'. `ref` is carried by `ComponentPropsWithRef<C>`\n// (it is not omitted below), so the props type already exposes the correct ref — no separate\n// `ref?` signature is needed (and the react-compat lint rule forbids a literal one; the\n// component is a real `forwardRef` below).\nexport type InfiniteScrollPaginatorProps<C extends React.ElementType = 'div'> =\n PropsWithChildren<\n InfiniteScrollPaginatorOwnProps & {\n element?: C;\n } & Omit<\n React.ComponentPropsWithRef<C>,\n keyof InfiniteScrollPaginatorOwnProps | 'element'\n >\n >;\n\ntype InfiniteScrollPaginatorComponent = <C extends React.ElementType = 'div'>(\n props: InfiniteScrollPaginatorProps<C>,\n) => React.ReactNode;\n\nconst renderPolymorphic = <C extends React.ElementType>(\n Comp: C,\n props: React.ComponentPropsWithRef<C>,\n children?: React.ReactNode,\n) => React.createElement(Comp, props, children);\n\nexport const InfiniteScrollPaginator = forwardRef(function InfiniteScrollPaginator<\n E extends React.ElementType = 'div',\n>(props: InfiniteScrollPaginatorProps<E>, ref: React.ForwardedRef<unknown>) {\n const {\n children,\n className,\n contentProps,\n element: Component = 'div' as E,\n listenToScroll,\n loadNextDebounceMs = 500,\n loadNextOnScrollToBottom,\n loadNextOnScrollToTop,\n threshold = DEFAULT_LOAD_PAGE_SCROLL_THRESHOLD,\n useCapture = false,\n ...componentProps\n } = props;\n const { className: contentClassName, ...contentRestProps } = contentProps ?? {};\n\n const rootRef = useRef<HTMLElement | null>(null);\n const childRef = useRef<HTMLDivElement | null>(null);\n\n const scrollListener = useMemo(\n () =>\n debounce(() => {\n const root = rootRef.current;\n const child = childRef.current;\n if (!root || root.offsetParent === null || !child) {\n return;\n }\n\n const distanceFromBottom =\n child.scrollHeight - root.scrollTop - root.clientHeight;\n const distanceFromTop = root.scrollTop;\n\n if (listenToScroll) {\n listenToScroll(distanceFromBottom, distanceFromTop, threshold);\n }\n\n if (distanceFromTop < Number(threshold)) {\n loadNextOnScrollToTop?.();\n }\n\n if (distanceFromBottom < Number(threshold)) {\n loadNextOnScrollToBottom?.();\n }\n }, loadNextDebounceMs),\n [\n listenToScroll,\n loadNextDebounceMs,\n loadNextOnScrollToBottom,\n loadNextOnScrollToTop,\n threshold,\n ],\n );\n\n useEffect(() => {\n const scrollElement = rootRef.current;\n if (!scrollElement) return;\n\n scrollElement.addEventListener('scroll', scrollListener, useCapture);\n\n return () => {\n scrollElement.removeEventListener('scroll', scrollListener, useCapture);\n };\n }, [scrollListener, useCapture]);\n\n useEffect(() => {\n const root = rootRef.current;\n if (!root || typeof ResizeObserver === 'undefined' || !scrollListener) return;\n const observer = new ResizeObserver(scrollListener);\n observer.observe(root as Element);\n\n return () => {\n observer.disconnect();\n };\n }, [scrollListener]);\n\n useEffect(() => {\n const root = rootRef.current;\n if (root) {\n root.addEventListener('wheel', mousewheelListener, { passive: false });\n }\n return () => {\n if (root) {\n root.removeEventListener('wheel', mousewheelListener, useCapture);\n }\n };\n }, [useCapture]);\n\n return renderPolymorphic(\n Component as E,\n {\n ...(componentProps as React.ComponentPropsWithRef<E>),\n className: clsx('str-chat__infinite-scroll-paginator', className),\n ref: (node: React.ComponentRef<E> | null) => {\n if (typeof ref === 'function') {\n ref(node);\n } else if (ref && 'current' in ref) {\n (ref as React.RefObject<React.ComponentRef<E> | null>).current = node;\n }\n rootRef.current = node && node instanceof HTMLElement ? node : null;\n },\n },\n React.createElement(\n 'div',\n {\n ...contentRestProps,\n className: clsx('str-chat__infinite-scroll-paginator__content', contentClassName),\n ref: childRef,\n },\n children,\n ),\n );\n}) as InfiniteScrollPaginatorComponent;\n","import type { ComponentType } from 'react';\nimport React, { forwardRef } from 'react';\nimport type { StateStore } from '@stream-io/state-store';\nimport type { PaginatorState } from 'stream-chat';\n\nimport { useStateStore } from '../../store';\nimport type { InfiniteScrollPaginatorProps } from './InfiniteScrollPaginator';\nimport { InfiniteScrollPaginator } from './InfiniteScrollPaginator';\n\n/** Minimal structural view of a paginator this component reads — avoids coupling\n * to `BasePaginator`'s generic variance (items only need an optional `id` for keys). */\ntype PaginatorLike<TItem> = {\n hasNext: boolean;\n hasPrev: boolean;\n state: StateStore<PaginatorState<TItem>>;\n};\n\nexport type InfiniteScrollWithComponentsProps<TItem extends { id?: string }> =\n InfiniteScrollPaginatorProps & {\n EmptyListIndicator: React.ComponentType;\n EndReachedIndicator: React.ComponentType<{\n hasEnded: boolean;\n reached: 'top' | 'bottom';\n }>;\n FirstPageLoadingIndicator: React.ComponentType;\n ListItem: ComponentType<{ item: TItem }>;\n LoadingNextPageIndicator: React.ComponentType<{ isLoading?: boolean }>;\n paginator: PaginatorLike<TItem>;\n hasReachedBottom?: (paginator: PaginatorLike<TItem>) => boolean;\n hasReachedTop?: (paginator: PaginatorLike<TItem>) => boolean;\n };\n\ntype InfiniteScrollWithComponentsComponent = <TItem extends { id?: string }>(\n props: InfiniteScrollWithComponentsProps<TItem>,\n) => React.ReactNode;\n\n/**\n * Renders any paginator-backed list with pluggable indicator/item components,\n * driven by the paginator's reactive `state`. Used by the ChannelManager-driven\n * channel list. `forwardRef` so callers can put the scroll root's DOM node to use\n * (e.g. the channel list marks it `role=\"listbox\"` and drives keyboard roving off it).\n */\nexport const InfiniteScrollWithComponents = forwardRef(\n function InfiniteScrollWithComponents<TItem extends { id?: string }>(\n props: InfiniteScrollWithComponentsProps<TItem>,\n ref: React.ForwardedRef<unknown>,\n ) {\n const {\n EmptyListIndicator,\n EndReachedIndicator,\n FirstPageLoadingIndicator,\n hasReachedBottom,\n hasReachedTop,\n ListItem,\n LoadingNextPageIndicator,\n paginator,\n ...componentProps\n } = props;\n\n const { isLoading, items } = useStateStore(paginator.state, (state) => ({\n isLoading: state.isLoading,\n items: state.items,\n }));\n const isLoadingFirstPage = items === undefined;\n const isEmpty = items?.length === 0;\n const topEndReached = hasReachedTop?.(paginator) ?? !paginator.hasPrev;\n const bottomEndReached = hasReachedBottom?.(paginator) ?? !paginator.hasNext;\n\n if (isLoadingFirstPage) return <FirstPageLoadingIndicator />;\n if (isEmpty) return <EmptyListIndicator />;\n\n return (\n <>\n <EndReachedIndicator hasEnded={topEndReached} reached='top' />\n <InfiniteScrollPaginator {...componentProps} ref={ref}>\n {items.map((item) => (\n <ListItem item={item} key={item.id} />\n ))}\n <LoadingNextPageIndicator isLoading={isLoading} />\n </InfiniteScrollPaginator>\n <EndReachedIndicator hasEnded={bottomEndReached} reached='bottom' />\n </>\n );\n },\n) as InfiniteScrollWithComponentsComponent;\n","import React from 'react';\n\nconst LoadingItems = () => (\n <div className='str-chat__channel-list-item-container'>\n <div\n aria-hidden='true'\n className='str-chat__channel-list-item str-chat__channel-list-item--loading'\n >\n <div className='str-chat__loading-channels-avatar' />\n <div className='str-chat__channel-list-item-data str-chat__channel-list-item-data--loading'>\n <div className='str-chat__loading-channels-username' />\n <div className='str-chat__loading-channels-status' />\n </div>\n </div>\n </div>\n);\n\nexport const LoadingChannels = () => (\n <div className='str-chat__loading-channels'>\n <LoadingItems />\n <LoadingItems />\n <LoadingItems />\n <LoadingItems />\n <LoadingItems />\n </div>\n);\n","import React from 'react';\nimport { useComponentContextIcons } from '../../context';\nimport type { BaseIconProps } from '../Icons/BaseIcon';\n\n// Typed off the icon contract rather than off a concrete icon: the rendered icon now comes from\n// the `IconLoading` slot, which any override can replace.\nexport type LoadingIndicatorProps = BaseIconProps;\n\nexport const LoadingIndicator = (props: LoadingIndicatorProps) => {\n const { IconLoading } = useComponentContextIcons();\n\n return <IconLoading {...props} className='str-chat__loading-indicator' />;\n};\n","import type { KeyboardEvent as ReactKeyboardEvent, RefObject } from 'react';\n\nimport { getNextRovingFocusIndex } from '../a11yUtils';\n\nconst DEFAULT_OPTION_SELECTOR = '[role=\"option\"]';\nconst VERTICAL_KEYS = ['ArrowUp', 'ArrowDown', 'Home', 'End'];\n\n/** State handed to a {@link ListboxKeyHandler} when its key is pressed inside the container. */\nexport type ListboxNavigationContext = {\n /** The focused element — guaranteed to be inside the container. */\n active: HTMLElement;\n /** The listbox container element. */\n container: HTMLElement;\n /** The current option elements (live). */\n getOptions: () => HTMLElement[];\n /** Whether {@link ListboxNavigationContext.active} is itself an option. */\n onOption: boolean;\n};\n\n/**\n * Handler for a non-roving key. Return `true` if it handled the key — the hook then\n * `preventDefault()`s and `stopPropagation()`s so nothing else acts on it. Return nothing to let the\n * key fall through (default behaviour preserved).\n */\nexport type ListboxKeyHandler = (context: ListboxNavigationContext) => boolean | void;\n\nexport type ListboxKeyboardNavigationConfig = {\n /**\n * Where the roving (vertical) keys are active:\n * - `'option'` (default): only when focus is already on an option — a plain listbox.\n * - `'container'`: anywhere inside the container, so focus can enter the list from a preceding\n * control (e.g. a filter tag); when not on an option, Down/Home land on the first, Up/End on the\n * last.\n */\n enterScope?: 'container' | 'option';\n /**\n * Extra keys to handle, beyond the built-in roving. Mapped by `event.key` to a handler that\n * receives the current {@link ListboxNavigationContext} and decides what to do. The hook does not\n * prescribe any particular keys (e.g. ArrowRight to reach a row's actions) — compose what you need,\n * optionally with {@link createRowActionKeyHandlers}. Roving keys (Up/Down/Home/End) are reserved.\n */\n keyHandlers?: Record<string, ListboxKeyHandler>;\n /** Selector for the navigable options. Default `[role=\"option\"]`. */\n optionSelector?: string;\n /**\n * Maps the focused element to the option that vertical roving (Up/Down/Home/End) should move\n * relative to. Use with `enterScope: 'container'` so those keys work while focus is on something\n * inside an option's row (e.g. its action buttons) and step to the next/previous option from that\n * row, rather than jumping to the first/last. Return `null` to fall back to that default.\n */\n resolveActiveOption?: (active: HTMLElement) => HTMLElement | null;\n};\n\n/**\n * Keyboard navigation for a list of options (the channel list, the search results, …). Returns an\n * `onKeyDown` to spread onto the container plus `getOptions` for callers that need the current\n * options (e.g. load-more focus management):\n * - **ArrowUp/ArrowDown/Home/End** rove the options (scope set by `enterScope`).\n * - any other key listed in `keyHandlers` is delegated to its handler.\n *\n * For keys, it handles it `stopPropagation()`s, so it stays authoritative — nothing downstream (a\n * parent handler, or the browser/AT \"jump to first/last focusable\" fallback) can move focus to a\n * non-option. Stateless — safe to call on every render; the handlers read the DOM live.\n */\nexport const useListboxKeyboardNavigation = (\n containerRef: RefObject<HTMLElement | null>,\n {\n enterScope = 'option',\n keyHandlers,\n optionSelector = DEFAULT_OPTION_SELECTOR,\n resolveActiveOption,\n }: ListboxKeyboardNavigationConfig = {},\n) => {\n const getOptions = () =>\n Array.from(containerRef.current?.querySelectorAll<HTMLElement>(optionSelector) ?? []);\n\n const onKeyDown = (event: ReactKeyboardEvent<HTMLElement>) => {\n const container = containerRef.current;\n const active = document.activeElement;\n if (!container || !(active instanceof HTMLElement) || !container.contains(active)) {\n return;\n }\n\n const onOption = active.matches(optionSelector);\n\n if (VERTICAL_KEYS.includes(event.key)) {\n if (enterScope === 'option' && !onOption) return;\n const options = getOptions();\n // The option the move is relative to: the focused option itself, or — when focus is on\n // something inside an option's row (e.g. an action button) — the option that row maps to.\n const current = onOption ? active : (resolveActiveOption?.(active) ?? null);\n const nextIndex = getNextRovingFocusIndex({\n activeIndex: current ? options.indexOf(current) : -1,\n itemCount: options.length,\n key: event.key,\n });\n if (nextIndex === null) return;\n event.preventDefault();\n event.stopPropagation();\n options[nextIndex]?.focus();\n return;\n }\n\n const handled = keyHandlers?.[event.key]?.({\n active,\n container,\n getOptions,\n onOption,\n });\n if (handled) {\n event.preventDefault();\n event.stopPropagation();\n }\n };\n\n return { getOptions, onKeyDown };\n};\n\n/**\n * Composable {@link ListboxKeyHandler}s for the \"each option sits in a row alongside one or more\n * action targets\" pattern (e.g. a channel row + its actions/menu buttons). The option and its\n * actions form one **horizontal cyclic group** in DOM order: from the option **ArrowRight** enters\n * the actions; **ArrowLeft/ArrowRight** move between the actions; stepping off either end returns to\n * the option (so the actions need not be in the Tab order). Rows with no actions (a lone option)\n * leave the keys unhandled. Pass the result as (part of) `keyHandlers`.\n */\nexport const createRowActionKeyHandlers = ({\n actionSelector,\n optionSelector = DEFAULT_OPTION_SELECTOR,\n rowSelector,\n}: {\n actionSelector: string;\n optionSelector?: string;\n rowSelector: string;\n}): Record<string, ListboxKeyHandler> => {\n const rove =\n (step: -1 | 1): ListboxKeyHandler =>\n ({ active }) => {\n const row = active.closest(rowSelector);\n if (!row) return;\n // The option + its action targets, in document order, as one cyclic group.\n const items = Array.from(\n row.querySelectorAll<HTMLElement>(`${optionSelector}, ${actionSelector}`),\n );\n if (items.length < 2) return; // a lone option — nothing to move between\n const index = items.indexOf(active);\n if (index === -1) return;\n items[(index + step + items.length) % items.length].focus();\n return true;\n };\n\n return { ArrowLeft: rove(-1), ArrowRight: rove(1) };\n};\n","import { useEffect, useRef } from 'react';\nimport type { MouseEvent as ReactMouseEvent, RefObject } from 'react';\n\nimport {\n createRowActionKeyHandlers,\n useListboxKeyboardNavigation,\n} from '../../../a11y/hooks/useListboxKeyboardNavigation';\n\nconst OPTION_SELECTOR = '[role=\"option\"]';\nconst ROW_SELECTOR = '.str-chat__channel-list-item-container';\nconst ACTION_BUTTON_SELECTOR = '.str-chat__channel-list-item__action-buttons button';\nconst LOAD_MORE_SELECTOR = '[data-testid=\"load-more-button\"]';\n// Roving covers the channel rows AND the Load more button, so Down from the last channel lands on\n// it (and Up/End/Home behave). The load-more \"focus the first new item\" logic below still counts\n// channel rows only, so the button being a roving target does not skew the page-boundary index.\nconst NAVIGABLE_SELECTOR = `${OPTION_SELECTOR}, ${LOAD_MORE_SELECTOR}`;\n\n// Upper bound for how long a pending \"focus the first item of the next page\" request stays armed\n// after the Load more button is pressed. If the new page hasn't rendered within this window we drop\n// the request, so an unrelated later list change (e.g. a channel arriving over the WebSocket) can't\n// trigger a stray focus move.\nconst LOAD_MORE_FOCUS_TIMEOUT_MS = 4000;\n\n/**\n * Keyboard navigation for the channel list (`role=\"listbox\"`). Returns handlers to spread onto the\n * listbox element:\n * - **ArrowUp/ArrowDown/Home/End** move focus between the channel rows (`role=\"option\"`) and the\n * **Load more** button (the last roving target when present).\n * - **ArrowRight** moves focus from a row to its actions button (the menu is then navigable with\n * Up/Down via the ContextMenu's own roving focus).\n * - **ArrowLeft** moves focus from a row's actions back to the row.\n * - When **Load more** is activated, focus moves to the **first item of the newly loaded page** once\n * it renders.\n */\nexport const useChannelListKeyboardNavigation = (\n listboxRef: RefObject<HTMLElement | null>,\n) => {\n // Shared roving (channels + Load more) + ArrowRight→actions / ArrowLeft→row. `enterScope:\n // 'container'` + `resolveActiveOption` make Up/Down/Home/End work even while focus is on a row's\n // action button — moving to the next/previous channel relative to that row.\n const { onKeyDown } = useListboxKeyboardNavigation(listboxRef, {\n enterScope: 'container',\n keyHandlers: createRowActionKeyHandlers({\n actionSelector: ACTION_BUTTON_SELECTOR,\n rowSelector: ROW_SELECTOR,\n }),\n optionSelector: NAVIGABLE_SELECTOR,\n resolveActiveOption: (active) =>\n active.closest(ROW_SELECTOR)?.querySelector<HTMLElement>(OPTION_SELECTOR) ?? null,\n });\n\n // Channel rows only (excludes the Load more button) — used to find the first item of the next page.\n const getChannelOptions = () =>\n Array.from(listboxRef.current?.querySelectorAll<HTMLElement>(OPTION_SELECTOR) ?? []);\n\n // A pending \"focus the first item of the next page\" request. Rather than keying off the raw row\n // COUNT (which a WebSocket-driven insert/reorder during the load window could satisfy with an\n // unrelated row), we snapshot the pre-load rows: `boundary` is the last pre-load option (the new\n // page is appended after it) and `preLoad` is the set of all pre-load option nodes (so a genuinely\n // new row can be told apart from a reordered existing one). Rows are keyed by cid, so React keeps\n // their DOM nodes stable across re-renders, making these references reliable identities.\n const pendingFocusRef = useRef<{\n boundary: HTMLElement | null;\n preLoad: Set<HTMLElement>;\n } | null>(null);\n const pendingTimeoutRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n\n const clearPendingFocus = () => {\n pendingFocusRef.current = null;\n if (pendingTimeoutRef.current) {\n clearTimeout(pendingTimeoutRef.current);\n pendingTimeoutRef.current = null;\n }\n };\n\n // Activating Load more (by mouse or keyboard, which both dispatch a click) arms the focus move.\n const onClickCapture = (event: ReactMouseEvent<HTMLElement>) => {\n const target = event.target;\n if (!(target instanceof Element) || !target.closest(LOAD_MORE_SELECTOR)) return;\n const options = getChannelOptions();\n pendingFocusRef.current = {\n boundary: options[options.length - 1] ?? null,\n preLoad: new Set(options),\n };\n if (pendingTimeoutRef.current) clearTimeout(pendingTimeoutRef.current);\n pendingTimeoutRef.current = setTimeout(clearPendingFocus, LOAD_MORE_FOCUS_TIMEOUT_MS);\n };\n\n // After the newly loaded page renders, focus its first item. Runs after every commit; cheap no-op\n // unless a focus move is pending. We look for the first option that is BOTH after the pre-load\n // boundary AND was not present before load — so an unrelated row arriving over the WebSocket (which\n // sorts above the boundary, and/or is not \"after\" it) does not trigger a stray focus move.\n useEffect(() => {\n const pending = pendingFocusRef.current;\n if (!pending) return;\n const options = getChannelOptions();\n // Empty list when Load more was pressed: the whole list is the new page — focus its first row.\n if (!pending.boundary) {\n if (options.length > 0) {\n options[0].focus();\n clearPendingFocus();\n }\n return;\n }\n const boundaryIndex = options.indexOf(pending.boundary);\n // Boundary row was removed (e.g. the user left that channel) — drop the request rather than\n // guessing where the page starts.\n if (boundaryIndex === -1) {\n clearPendingFocus();\n return;\n }\n const firstNewOption = options\n .slice(boundaryIndex + 1)\n .find((option) => !pending.preLoad.has(option));\n // Nothing new after the boundary yet: keep waiting (within the timeout) for the page to render.\n if (!firstNewOption) return;\n firstNewOption.focus();\n clearPendingFocus();\n });\n\n useEffect(() => () => clearPendingFocus(), []);\n\n return { onClickCapture, onKeyDown };\n};\n","import type { ComponentType } from 'react';\nimport React, { useEffect, useRef } from 'react';\nimport type { Channel, ChannelPaginator, ChannelPaginatorState } from 'stream-chat';\n\nimport { ChannelListItem } from '../ChannelListItem';\nimport { EmptyStateIndicator } from '../EmptyStateIndicator';\nimport { InfiniteScrollWithComponents } from '../InfiniteScrollPaginator/InfiniteScrollWithComponents';\nimport { LoadingChannels, LoadingIndicator } from '../Loading';\nimport { useChatContext } from '../../context/ChatContext';\nimport { useComponentContext } from '../../context/ComponentContext';\nimport { useTranslationContext } from '../../context/TranslationContext';\nimport { useChannelListKeyboardNavigation } from './hooks/useChannelListKeyboardNavigation';\nimport { useStateStore } from '../../store';\n\nexport type ChannelListProps = {\n /** The `ChannelPaginator` that supplies this list's channels (its data source). */\n paginator: ChannelPaginator;\n loadMoreDebounceMs?: number;\n loadMoreThresholdPx?: number;\n};\n\nconst channelPaginatorStateSelector = (state: ChannelPaginatorState) => ({\n // `items === undefined` means \"never queried\" — the state a paginator starts in and returns to\n // when its data is discarded (e.g. `client.disconnectUser` resets every registered list). An\n // empty array is a loaded empty page and must not trigger a query.\n isUnloaded: state.items === undefined,\n lastQueryError: state.lastQueryError,\n});\n\n/**\n * Channel list driven by a single `ChannelPaginator`. The paginator is created +\n * coordinated by the `ChannelManager` on `ChatContext`; this component\n * only renders its reactive `state` and drives pagination. Selection is not this\n * component's concern — the `ChannelListItem` default `ListItem` opens the channel via\n * ChatView navigation.\n */\nexport const ChannelList = ({\n loadMoreDebounceMs,\n loadMoreThresholdPx,\n paginator,\n}: ChannelListProps) => {\n const { channelManager, client } = useChatContext();\n const { t } = useTranslationContext();\n const { isUnloaded, lastQueryError } = useStateStore(\n paginator.state,\n channelPaginatorStateSelector,\n );\n const {\n EmptyListIndicator = DefaultEmptyChannelList,\n EndReachedIndicator = DefaultEndReachedIndicator,\n FirstPageLoadingIndicator = LoadingChannels,\n ListItem = DefaultListItem,\n LoadingNextPageIndicator = DefaultLoadingNextPageIndicator,\n } = useComponentContext();\n\n // Keyboard roving + row-action navigation for this list. The scroll container (the\n // `InfiniteScrollPaginator` root, reached via `listboxRef`) IS the `role=\"listbox\"` that owns this\n // list's `role=\"option\"` rows — so no extra wrapper element is needed. The hook reads/focuses the\n // option rows under `listboxRef`.\n // NOTE: the hook's \"focus the first item of the next page after Load more\" branch is a no-op here —\n // the list paginates on scroll-to-bottom (no rendered `load-more-button` for its `LOAD_MORE_SELECTOR`\n // to match). Accepted; keyboard roving is unaffected.\n const listboxRef = useRef<HTMLDivElement>(null);\n const { onClickCapture, onKeyDown } = useChannelListKeyboardNavigation(listboxRef);\n\n // Ref-counted: safe whether called here, from <ChannelLists/>, or from <Chat>.\n useEffect(() => channelManager.registerSubscriptions(), [channelManager]);\n\n // Loads the first page, and reloads it whenever the list is emptied back to \"never queried\" —\n // the paginator outlives this component (it is registered on `client.channelManager`), so\n // querying only on mount would leave a list reset after a disconnect/reconnect permanently empty.\n useEffect(() => {\n if (!isUnloaded) return;\n paginator.toTailDebounced();\n }, [isUnloaded, paginator]);\n\n useEffect(() => {\n if (!lastQueryError) return;\n client.notifications.addError({\n message: lastQueryError.message,\n origin: { context: { reason: 'channel query error' }, emitter: 'ChannelList' },\n });\n }, [client, lastQueryError]);\n\n return (\n <InfiniteScrollWithComponents<Channel>\n aria-label={t('channelList.channelList.ariaLabel', 'Channel list')}\n contentProps={{ role: 'presentation' }}\n EmptyListIndicator={EmptyListIndicator}\n EndReachedIndicator={EndReachedIndicator}\n FirstPageLoadingIndicator={FirstPageLoadingIndicator}\n ListItem={ListItem as ComponentType<{ item: Channel }>}\n LoadingNextPageIndicator={LoadingNextPageIndicator}\n loadNextDebounceMs={loadMoreDebounceMs}\n loadNextOnScrollToBottom={paginator.next}\n onClickCapture={onClickCapture}\n onKeyDown={onKeyDown}\n paginator={paginator}\n ref={listboxRef}\n role='listbox'\n threshold={loadMoreThresholdPx}\n />\n );\n};\n\nconst DefaultEmptyChannelList = () => <EmptyStateIndicator listType='channel' />;\n\nconst DefaultEndReachedIndicator = () => null;\n\nconst DefaultListItem = ({ item }: { item: unknown }) => (\n <ChannelListItem channel={item as Channel} />\n);\n\nconst DefaultLoadingNextPageIndicator = ({ isLoading }: { isLoading?: boolean }) =>\n isLoading ? <LoadingIndicator /> : null;\n","import React from 'react';\nimport type { ChannelManagerState } from 'stream-chat';\n\nimport { ChannelListContextProvider } from '../../context/ChannelListContext';\nimport { useChatContext } from '../../context/ChatContext';\nimport { useStateStore } from '../../store';\nimport { ChannelList } from './ChannelList';\n\nconst paginatorsSelector = (state: ChannelManagerState) => ({\n paginators: state.paginators,\n});\n\n/**\n * Renders one `<ChannelList/>` per paginator held by the `ChannelManager` on\n * `ChatContext` — i.e. its data source is the `ChannelManager` (the whole set of lists). Each child\n * `ChannelList` registers the (ref-counted) WS subscriptions. The primary (`paginators[0]`)\n * paginator is exposed through `ChannelListContext` so descendants (search results, member\n * actions, notification targeting) can read/mutate the loaded list without knowing about the\n * channel manager.\n */\nexport const ChannelLists = () => {\n const { channelManager } = useChatContext();\n const { paginators } = useStateStore(channelManager.state, paginatorsSelector);\n\n const lists = paginators.map((paginator) => (\n <ChannelList key={paginator.id} paginator={paginator} />\n ));\n\n const primaryPaginator = paginators[0];\n if (!primaryPaginator) return <>{lists}</>;\n\n return (\n <ChannelListContextProvider value={{ paginator: primaryPaginator }}>\n {lists}\n </ChannelListContextProvider>\n );\n};\n","import React from 'react';\nimport {\n useComponentContext,\n useTranslationContext,\n useWorkspaceNavigation,\n} from '../../context';\n\nexport const ChannelListHeader = () => {\n const { t } = useTranslationContext();\n const { HeaderEndContent } = useComponentContext();\n // A channel is \"active\" when one is open in the workspace (mirrors ThreadListHeader).\n const hasActiveChannel = useWorkspaceNavigation().openChannels.length > 0;\n return (\n <div className='str-chat__channel-list__header'>\n <div className='str-chat__channel-list__header__title'>\n {t('channelList.header.chats.text', 'Chats')}\n </div>\n {hasActiveChannel && HeaderEndContent && <HeaderEndContent />}\n </div>\n );\n};\n","import React, { createContext, useContext } from 'react';\nimport type { PropsWithChildren } from 'react';\nimport type { SearchController } from 'stream-chat';\nimport type { SearchProps } from './Search';\nimport { requireContext } from '../../context/requireContext';\n\nexport type SearchContextValue = {\n /** Instance of the search controller that handles the data management */\n searchController: SearchController;\n /** Reference to the container element of the search component */\n containerRef: React.RefObject<HTMLDivElement | null>;\n /** Reference to the container element of the filter buttons */\n filterButtonsContainerRef: React.RefObject<HTMLDivElement | null>;\n} & Pick<SearchProps, 'disabled' | 'inputProps' | 'placeholder'> &\n Required<Pick<SearchProps, 'exitSearchOnInputBlur' | 'directMessagingChannelType'>>;\n\nexport const SearchContext = createContext<SearchContextValue | undefined>(undefined);\n\n/**\n * Context provider for components rendered within the `Search` component\n */\nexport const SearchContextProvider = ({\n children,\n value,\n}: PropsWithChildren<{\n value: SearchContextValue;\n}>) => (\n <SearchContext.Provider value={value as unknown as SearchContextValue}>\n {children}\n </SearchContext.Provider>\n);\n\nexport const useSearchContext = () =>\n requireContext(useContext(SearchContext), 'useSearchContext', 'SearchContextProvider');\n","import { useCallback, useRef } from 'react';\n\nexport type StableCallback<A extends unknown[], R> = (...args: A) => R;\n\n/**\n * A utility hook implementing a stable callback. It takes in an unstable method that\n * is supposed to be invoked somewhere deeper in the DOM tree without making it\n * change its reference every time the parent component rerenders. It will also return\n * the value of the callback if it does return one.\n * A common use-case would be having a function whose invocation depends on state\n * somewhere high up in the DOM tree and wanting to use the same function deeper\n * down, for example in a leaf node and simply using useCallback results in\n * cascading dependency hell. If we wrap it in useStableCallback, we would be able\n * to:\n * - Use the same function as a dependency of another hook (since it is stable)\n * - Still invoke it and get the latest state\n *\n * **Caveats:**\n * - Never wrap a function that is supposed to return a React.ReactElement in\n * useStableCallback, since React will not know that the DOM needs to be updated\n * whenever the callback value changes (for example, renderItem from FlatList must\n * never be wrapped in this hook)\n * - Always prefer using a standard useCallback/stable function wherever possible\n * (the purpose of useStableCallback is to bridge the gap between top level contexts\n * and cascading re-renders in downstream components - **not** as an escape hatch)\n * @param callback - the callback we want to stabilize\n */\nexport const useStableCallback = <A extends unknown[], R>(\n callback: StableCallback<A, R>,\n): StableCallback<A, R> => {\n const ref = useRef(callback);\n ref.current = callback;\n\n return useCallback<StableCallback<A, R>>((...args) => ref.current(...args), []);\n};\n","import { useEffect, useRef } from 'react';\nimport type { RefObject } from 'react';\n\nimport { useStableCallback } from '../../../utils/useStableCallback';\n\nconst DEFAULT_INIT: MutationObserverInit = { childList: true, subtree: true };\nconst NOOP = () => undefined;\n\nexport type UseMutationObserverOptions = {\n /** When `false`, the observer is not connected (and `onDisconnect` runs if it was). Default `true`. */\n enabled?: boolean;\n /** `MutationObserver` init, read when (re)connecting. Default `{ childList: true, subtree: true }`. */\n init?: MutationObserverInit;\n /** Runs when observation stops — target/`enabled` change or unmount. Use to clean up side effects\n * started in `onMutation` (e.g. cancel a pending announcement). */\n onDisconnect?: () => void;\n /** Also invoke `onMutation` once right after connecting, to react to the current DOM. Default `true`. */\n runOnConnect?: boolean;\n};\n\n/**\n * Runs `onMutation` whenever the observed subtree of `ref` changes (and, by default, once on\n * connect). A thin, generic wrapper around `MutationObserver`: toggle with `enabled`, react to the\n * initial state with `runOnConnect`, and clean up side effects via `onDisconnect`. The latest\n * `onMutation`/`onDisconnect` are always used without reconnecting the observer.\n *\n * Note: like any `useEffect`-based hook, it (re)connects on `enabled` change or remount — not on a\n * silent `ref.current` swap. Drive remounts with a `key` or toggle `enabled` if the target changes.\n */\nexport const useMutationObserver = (\n ref: RefObject<HTMLElement | null>,\n onMutation: () => void,\n {\n enabled = true,\n init = DEFAULT_INIT,\n onDisconnect,\n runOnConnect = true,\n }: UseMutationObserverOptions = {},\n) => {\n // Stable identities that always call the latest callback, so updating either does not reconnect\n // the observer.\n const handleMutation = useStableCallback(onMutation);\n const handleDisconnect = useStableCallback(onDisconnect ?? NOOP);\n // `init` is read only when (re)connecting; keep it off the effect deps so a fresh object literal\n // each render does not reconnect.\n const initRef = useRef(init);\n initRef.current = init;\n\n useEffect(() => {\n const target = ref.current;\n if (!enabled || !target) return;\n\n if (runOnConnect) handleMutation();\n\n // `MutationObserver` is available in every browser the SDK targets (and this runs only in an\n // effect, never during SSR), but degrade gracefully if it is missing — e.g. a non-DOM test\n // environment: react to the initial state and still run the disconnect cleanup, just without\n // observing further changes.\n if (typeof MutationObserver === 'undefined') return handleDisconnect;\n\n const observer = new MutationObserver(() => handleMutation());\n observer.observe(target, initRef.current);\n\n return () => {\n observer.disconnect();\n handleDisconnect();\n };\n }, [enabled, handleDisconnect, handleMutation, ref, runOnConnect]);\n};\n","import { useRef } from 'react';\nimport type { RefObject } from 'react';\nimport type { SearchSource } from 'stream-chat';\n\nimport { useInteractionAnnouncements } from '../../Accessibility';\nimport { useMutationObserver } from '../../UtilityComponents/hooks/useMutationObserver';\n\nconst OPTION_SELECTOR = '[role=\"option\"]';\n\n/**\n * Announces how many items are listed in the search results — and, when the list is fully loaded,\n * folds the \"all results loaded\" end-of-list status into that SAME announcement.\n *\n * The count is taken from the rendered options (`[role=\"option\"]`) in `containerRef`, observed with\n * {@link useMutationObserver} — so it is source-agnostic (works across channels/messages/users and\n * any custom result component) and reflects exactly what the user sees. Delivery goes through the\n * shared {@link useInteractionAnnouncements} registry (`search.resultCount`), which debounces the\n * value so it lands once results settle (after the screen reader's typing echo) instead of on every\n * change.\n *\n * `allResultsLoaded` is derived (when the announcement fires) from the active sources' latest state:\n * true only when every active source has no next page and is not loading. Carrying it in the count\n * message — rather than as a separate live-region announcement — keeps the end-of-list status from\n * competing with (and superseding) the count.\n *\n * The observer fires on every subtree mutation, but the announcement is made only when the\n * `count`/`allResultsLoaded` SIGNATURE changes — so an in-place action (e.g. muting a channel in a\n * result, which re-renders the row without changing the count) does not re-announce. It also bails\n * while inactive: gated on `active` (an in-progress search with a query) so it never fires during\n * presearch, and the pending (debounced) count is cancelled — and the signature reset — when search\n * is exited, so a stale count is not spoken after the results are gone.\n */\nexport const useAnnounceSearchResultCount = (\n containerRef: RefObject<HTMLElement | null>,\n active: boolean,\n activeSources: SearchSource[] = [],\n) => {\n const { announceInteraction, cancelInteraction } = useInteractionAnnouncements();\n const lastSignatureRef = useRef<string | null>(null);\n\n useMutationObserver(\n containerRef,\n () => {\n if (!active) return;\n const count = containerRef.current?.querySelectorAll(OPTION_SELECTOR).length ?? 0;\n const allResultsLoaded =\n activeSources.length > 0 &&\n activeSources.every((source) => {\n const { hasNext, isLoading } = source.state.getLatestValue();\n return !hasNext && !isLoading;\n });\n\n // Announce only when the meaningful state changes, not on every re-render of a result row.\n const signature = `${count}|${allResultsLoaded}`;\n if (signature === lastSignatureRef.current) return;\n lastSignatureRef.current = signature;\n\n announceInteraction('search.resultCount', { allResultsLoaded, count });\n },\n {\n enabled: active,\n onDisconnect: () => {\n lastSignatureRef.current = null;\n cancelInteraction('search.resultCount');\n },\n },\n );\n};\n","import { useEffect, useState } from 'react';\nimport type { SearchController, SearchControllerState, SearchSource } from 'stream-chat';\n\nimport { useStateStore } from '../../../store';\n\nconst searchControllerStateSelector = (value: SearchControllerState) => ({\n sources: value.sources,\n});\n\nexport type UseSearchQueriesInProgressParams = {\n searchController: SearchController;\n};\n\nexport const useSearchQueriesInProgress = (searchController: SearchController) => {\n const [queriesInProgress, setQueriesInProgress] = useState<string[]>([]);\n const { sources } = useStateStore(\n searchController.state,\n searchControllerStateSelector,\n );\n\n useEffect(() => {\n const subscriptions = sources.map((source: SearchSource) =>\n source.state.subscribeWithSelector(\n (value) => ({ isLoading: value.isLoading }),\n ({ isLoading }) => {\n setQueriesInProgress((prev) => {\n if (isLoading) return prev.concat(source.type);\n return prev.filter((type) => type !== source.type);\n });\n },\n ),\n );\n\n return () => {\n subscriptions.forEach((unsubscribe) => unsubscribe());\n };\n }, [sources]);\n return queriesInProgress;\n};\n","import type { RefObject } from 'react';\n\nimport {\n createRowActionKeyHandlers,\n useListboxKeyboardNavigation,\n} from '../../../a11y/hooks/useListboxKeyboardNavigation';\n\n// Channel/message results render a `ChannelListItem` (same markup as the channel list), so they\n// carry a row container and action buttons. User results do not, so the horizontal keys no-op there.\nconst OPTION_SELECTOR = '[role=\"option\"]';\nconst ROW_SELECTOR = '.str-chat__channel-list-item-container';\nconst ACTION_BUTTON_SELECTOR = '.str-chat__channel-list-item__action-buttons button';\n\n/**\n * Keyboard navigation for the search results list (see {@link useListboxKeyboardNavigation}):\n * - **ArrowUp/ArrowDown/Home/End** rove the result options — from anywhere in the container, so the\n * user can enter the list from the preceding filter tags (`enterScope: 'container'`) and so they\n * keep working while focus is on a result's action button (moving relative to that result).\n * - **ArrowRight/ArrowLeft** move between a channel/message result and its actions button and back;\n * user results have no actions, so the horizontal keys do nothing for them.\n */\nexport const useSearchResultsKeyboardNavigation = (\n containerRef: RefObject<HTMLElement | null>,\n) => {\n const { onKeyDown } = useListboxKeyboardNavigation(containerRef, {\n enterScope: 'container',\n keyHandlers: createRowActionKeyHandlers({\n actionSelector: ACTION_BUTTON_SELECTOR,\n rowSelector: ROW_SELECTOR,\n }),\n resolveActiveOption: (active) =>\n active.closest(ROW_SELECTOR)?.querySelector<HTMLElement>(OPTION_SELECTOR) ?? null,\n });\n\n return { onKeyDown };\n};\n","import clsx from 'clsx';\nimport React, { useEffect, useRef, useState } from 'react';\n\nimport { useSearchContext } from '../SearchContext';\nimport { useSearchQueriesInProgress } from '../hooks';\nimport { useInteractionAnnouncements } from '../../Accessibility';\nimport { useComponentContextIcons, useTranslationContext } from '../../../context';\nimport { useStateStore } from '../../../store';\nimport { Button } from '../../../components';\n\nimport type { SearchControllerState } from 'stream-chat';\n\nconst searchControllerStateSelector = (nextValue: SearchControllerState) => ({\n isActive: nextValue.isActive,\n searchQuery: nextValue.searchQuery,\n});\n\nexport const SearchBar = () => {\n const { t } = useTranslationContext();\n const { IconSearch, IconXCircle } = useComponentContextIcons();\n const { announceInteraction } = useInteractionAnnouncements();\n const {\n containerRef,\n disabled,\n exitSearchOnInputBlur,\n inputProps,\n placeholder,\n searchController,\n } = useSearchContext();\n const queriesInProgress = useSearchQueriesInProgress(searchController);\n\n const [input, setInput] = useState<HTMLInputElement | null>(null);\n // Was the most recent pointerdown inside the search widget? Used to disambiguate a blur with a\n // null `relatedTarget`: browsers report `null` both when focus genuinely leaves the widget AND\n // when the user presses a non-focusable descendant (the search icon, wrapper padding). Only the\n // former should collapse search.\n const pointerDownInsideRef = useRef(false);\n const { isActive, searchQuery } = useStateStore(\n searchController.state,\n searchControllerStateSelector,\n );\n\n useEffect(() => {\n const handlePointerDown = (event: PointerEvent) => {\n pointerDownInsideRef.current = !!containerRef.current?.contains(\n event.target as Node | null,\n );\n };\n // Capture so it runs before the input's blur, regardless of where the press landed.\n document.addEventListener('pointerdown', handlePointerDown, true);\n return () => {\n document.removeEventListener('pointerdown', handlePointerDown, true);\n };\n }, [containerRef]);\n\n useEffect(() => {\n if (!input) return;\n const handleKeyDown = (event: KeyboardEvent) => {\n if (event.key === 'Escape') {\n searchController.exit();\n // Keep focus on the search input (it no longer re-activates search on focus), so the user\n // can keep navigating from a known place rather than having focus drop to the body.\n input.focus();\n }\n };\n\n document.addEventListener('keydown', handleKeyDown);\n return () => {\n document.removeEventListener('keydown', handleKeyDown);\n };\n }, [searchController, input]);\n\n return (\n <div className='str-chat__search-bar' data-testid='search-bar' role='search'>\n <div\n className={clsx('str-chat__search-bar__input-wrapper', {\n 'str-chat__search-bar__input-wrapper--active': isActive,\n })}\n >\n <IconSearch />\n <input\n {...inputProps}\n aria-label={t('common.search.ariaLabel', 'Search')}\n className={clsx('str-chat__search-bar__input', inputProps?.className)}\n data-testid='search-input'\n disabled={disabled}\n onBlur={({ relatedTarget }) => {\n // Exit search only when focus leaves the search widget entirely. Moving focus to a\n // control inside it — the results list, the source filter buttons, the clear button,\n // or the Cancel/exit button — is not \"leaving search\", so it must not collapse it (the\n // Cancel button exits via its own activation, per WCAG 3.2.1). This matches the\n // documented contract (\"clear on every click outside the search\") independent of\n // whether the input currently holds a query — an empty input is not activated, so the\n // previous value check only ever suppressed the exit while a query was present.\n if (!exitSearchOnInputBlur) return;\n const focusMovedInside = !!containerRef.current?.contains(relatedTarget);\n // A null relatedTarget also occurs when a non-focusable element inside the widget is\n // pressed; the preceding pointerdown tells us it was an in-widget interaction, which\n // must not collapse search.\n const pressedInside = relatedTarget === null && pointerDownInsideRef.current;\n pointerDownInsideRef.current = false;\n if (!focusMovedInside && !pressedInside) {\n searchController.exit();\n }\n }}\n onChange={(event: React.ChangeEvent<HTMLInputElement>) => {\n // Activate search on user input — NOT on focus (WCAG 3.2.1: focusing a control must not\n // change context). `search()` runs against the active sources, so activation has to\n // happen here; `activate()` is idempotent once already active.\n if (event.target.value) {\n searchController.activate();\n searchController.search(event.target.value);\n } else {\n searchController.clear();\n }\n }}\n placeholder={placeholder ?? t('common.search.ariaLabel', 'Search')}\n ref={setInput}\n type='text'\n value={searchQuery}\n />\n {searchQuery && (\n <Button\n appearance='ghost'\n aria-label={t('search.bar.clearSearch.ariaLabel', 'Clear search')}\n circular\n className='str-chat__search-bar__clear-button'\n data-testid='clear-input-button'\n disabled={queriesInProgress.length > 0} // prevent user from clearing the input while query is in progress and avoid out-of-sync UX\n onClick={() => {\n searchController.clear();\n input?.focus();\n announceInteraction('search.cleared');\n }}\n size='xs'\n variant='secondary'\n >\n <IconXCircle />\n </Button>\n )}\n </div>\n {isActive && (\n <Button\n appearance='ghost'\n aria-label={t('search.bar.exitSearch.ariaLabel', 'Exit search')}\n className='str-chat__search-bar__exit-search-button'\n data-testid='search-bar-button'\n onClick={() => {\n searchController.exit();\n // Return focus to the search input so navigation can continue from there (focusing it\n // no longer re-activates search — see RW19).\n input?.focus();\n }}\n size='sm'\n variant='secondary'\n >\n {t('common.cancel.label', 'Cancel')}\n </Button>\n )}\n </div>\n );\n};\n","import React, { useCallback, useMemo } from 'react';\nimport type { ComponentType } from 'react';\nimport { convertTimestampToDate, formatMessage } from 'stream-chat';\nimport type {\n Channel,\n ChannelResponse,\n MessageFocusSignalState,\n MessageResponse,\n UserResponse,\n} from 'stream-chat';\n\nimport { useSearchContext } from '../SearchContext';\nimport { Avatar as DefaultAvatar } from '../../../components/Avatar';\nimport { extractDisplayInfo as defaultExtractDisplayInfo } from '../../../components/Avatar/utils';\nimport { ChannelListItem } from '../../../components/ChannelListItem';\nimport {\n useChatContext,\n useComponentContext,\n useTranslationContext,\n useWorkspaceNavigation,\n} from '../../../context';\nimport { Timestamp } from '../../../components/Message/Timestamp';\nimport { useStateStore } from '../../../store';\n\ntype SearchResultMessage = MessageResponse & { channel?: ChannelResponse };\n\nconst messageFocusSignalSelector = (state: MessageFocusSignalState) => ({\n focusedMessageId: state.signal?.messageId,\n});\n\nexport type ChannelSearchResultItemProps = {\n item: Channel;\n /** Overrides selection, exactly like `ChannelListItem`'s `onSelect`: when provided it runs\n * instead of the default (open the channel into a layout slot). */\n onSelect?: (event: React.MouseEvent) => void;\n};\n\nexport const ChannelSearchResultItem = ({\n item,\n onSelect,\n}: ChannelSearchResultItemProps) => {\n const { openChannel } = useWorkspaceNavigation();\n const { channelManager } = useChatContext();\n\n const handleSelect = useCallback(\n (event: React.MouseEvent) => {\n if (onSelect) {\n onSelect(event);\n return;\n }\n // Default: open the channel in the workspace, forwarding the event so a consumer overriding\n // `openChannel` (e.g. via ChatView's `deriveWorkspaceNavigation`) can honor ⌘/ctrl-click.\n openChannel(item, { event });\n // Route the channel into the list(s) that should own it (the channel manager dedupes by cid,\n // inserts in sort order, and honors ownership/filters) so it appears without a re-query.\n channelManager.ingestChannel(item);\n },\n [item, openChannel, channelManager, onSelect],\n );\n\n return (\n <ChannelListItem\n channel={item}\n className='str-chat__search-result'\n onSelect={handleSelect}\n />\n );\n};\n\nexport type ChannelByMessageSearchResultItemProps = {\n item: SearchResultMessage;\n /** Overrides selection (see `ChannelSearchResultItem`); when provided it runs instead of the\n * default (jump to the message and open its channel). */\n onSelect?: (event: React.MouseEvent) => void;\n};\n\nexport const MessageSearchResultItem = ({\n item,\n onSelect,\n}: ChannelByMessageSearchResultItemProps) => {\n const { channelManager, client } = useChatContext();\n const { isChannelActive, openChannel } = useWorkspaceNavigation();\n\n const channel = useMemo(() => {\n const { channel: channelData } = item;\n const type = channelData?.type ?? 'unknown';\n const id = channelData?.id ?? 'unknown';\n return client.channel(type, id);\n }, [client, item]);\n\n const channelOpenInSlot = isChannelActive(channel?.cid ?? undefined);\n const { focusedMessageId } = useStateStore(\n channel?.messagePaginator.messageFocusSignal,\n messageFocusSignalSelector,\n ) ?? { focusedMessageId: undefined };\n\n const handleSelect = useCallback(\n (event: React.MouseEvent) => {\n if (onSelect) {\n onSelect(event);\n return;\n }\n if (!channel) return;\n openChannel(channel, { event });\n channelManager.ingestChannel(channel);\n void channel.messagePaginator.jumpToMessage(item.id);\n },\n [channel, item, openChannel, channelManager, onSelect],\n );\n\n // Preview the matched message itself (not the channel's latest) by overriding `previewedMessage`.\n const previewedMessage = useMemo(() => formatMessage(item), [item]);\n\n if (!channel) return null;\n\n return (\n <ChannelListItem\n active={channelOpenInSlot && focusedMessageId === item.id}\n channel={channel}\n className='str-chat__search-result'\n onSelect={handleSelect}\n previewedMessage={previewedMessage}\n />\n );\n};\n\nexport type UserSearchResultItemProps = {\n item: UserResponse;\n /** Overrides selection (see `ChannelSearchResultItem`); when provided it runs instead of the\n * default (open a direct-messaging channel with the user). */\n onSelect?: (event: React.MouseEvent) => void;\n};\n\nexport const UserSearchResultItem = ({ item, onSelect }: UserSearchResultItemProps) => {\n const { channelManager, client } = useChatContext();\n const { openChannel } = useWorkspaceNavigation();\n const { directMessagingChannelType } = useSearchContext();\n const { t } = useTranslationContext();\n const { Avatar = DefaultAvatar, extractDisplayInfo = defaultExtractDisplayInfo } =\n useComponentContext();\n\n const onClick = useCallback(\n (event: React.MouseEvent) => {\n if (onSelect) {\n onSelect(event);\n return;\n }\n const newChannel = client.channel(directMessagingChannelType, {\n members: [{ user_id: client.userId as string }, { user_id: item.id }],\n });\n newChannel.watch();\n // Default: open the DM channel in the workspace, forwarding the event so a consumer overriding\n // `openChannel` can honor ⌘/ctrl-click.\n openChannel(newChannel, { event });\n channelManager.ingestChannel(newChannel);\n },\n [client, item, openChannel, channelManager, directMessagingChannelType, onSelect],\n );\n\n return (\n <div className='str-chat__search-result-container'>\n <button\n aria-label={t(\n 'search.resultItem.selectUserChannel.ariaLabel',\n 'Select User Channel: {{ name }}',\n {\n name: item.name || '',\n },\n )}\n className='str-chat__search-result str-chat__search-result--user'\n data-testid='search-result-user'\n onClick={onClick}\n role='option'\n >\n <Avatar\n {...extractDisplayInfo({ user: item })}\n isOnline={item.online}\n size='xl'\n />\n <div className='str-chat__search-result-data'>\n <div className='str-chat__search-result__display-name'>\n {/* @ts-expect-error username is not typed */}\n {item.name || item.custom?.username || item.id}\n </div>\n <Timestamp\n customClass='str-chat__search-result__last-active-timestamp'\n timestamp={convertTimestampToDate(item.last_active)}\n />\n </div>\n </button>\n </div>\n );\n};\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport type SearchResultItemComponents = Record<string, ComponentType<{ item: any }>>;\n\nexport const DefaultSearchResultItems: SearchResultItemComponents = {\n channels: ChannelSearchResultItem,\n messages: MessageSearchResultItem,\n users: UserSearchResultItem,\n};\n","import type { PropsWithChildren } from 'react';\nimport React, { createContext, useContext } from 'react';\nimport type { SearchSource } from 'stream-chat';\nimport { requireContext } from '../../context/requireContext';\n\nexport type SearchSourceResultsContextValue = {\n searchSource: SearchSource;\n};\n\nexport const SearchSourceResultsContext = createContext<\n SearchSourceResultsContextValue | undefined\n>(undefined);\n\n/**\n * Context provider for components rendered within the `SearchSourceResults`\n */\nexport const SearchSourceResultsContextProvider = ({\n children,\n value,\n}: PropsWithChildren<{\n value: SearchSourceResultsContextValue;\n}>) => (\n <SearchSourceResultsContext.Provider\n value={value as unknown as SearchSourceResultsContextValue}\n >\n {children}\n </SearchSourceResultsContext.Provider>\n);\n\nexport const useSearchSourceResultsContext = () =>\n requireContext(\n useContext(SearchSourceResultsContext),\n 'useSearchSourceResultsContext',\n 'SearchSourceResultsProvider',\n );\n","import React from 'react';\nimport { useTranslationContext } from '../../../context';\nimport { useSearchSourceResultsContext } from '../SearchSourceResultsContext';\n\nexport const SearchSourceResultsLoadingIndicator = () => {\n const { t } = useTranslationContext();\n const { searchSource } = useSearchSourceResultsContext();\n return (\n <div\n className='str-chat__search-source-results__loading-indicator'\n data-testid='search-loading-indicator'\n >\n {t(\n 'search.sourceResults.searching.text',\n 'Searching for {{ searchSourceType }}...',\n {\n searchSourceType: searchSource.type,\n },\n )}\n </div>\n );\n};\n","import React from 'react';\nimport type { SearchSourceState } from 'stream-chat';\n\nimport { SearchSourceResultsLoadingIndicator as DefaultSearchSourceResultsLoadingIndicator } from './SearchSourceResultsLoadingIndicator';\nimport { useSearchSourceResultsContext } from '../SearchSourceResultsContext';\nimport { useComponentContext, useTranslationContext } from '../../../context';\nimport { useStateStore } from '../../../store';\n\nconst searchSourceStateSelector = (value: SearchSourceState) => ({\n hasNext: value.hasNext,\n isLoading: value.isLoading,\n});\n\nexport const SearchSourceResultListFooter = () => {\n const { t } = useTranslationContext();\n const {\n SearchSourceResultsLoadingIndicator = DefaultSearchSourceResultsLoadingIndicator,\n } = useComponentContext();\n const { searchSource } = useSearchSourceResultsContext();\n const { hasNext, isLoading } = useStateStore(\n searchSource.state,\n searchSourceStateSelector,\n );\n\n // The \"all results loaded\" end-of-list status is announced (combined with the result count) by\n // `useAnnounceSearchResultCount`; here it is visual only.\n return (\n <div\n className='str-chat__search-source-result-list__footer'\n data-testid='search-footer'\n >\n {isLoading ? (\n <SearchSourceResultsLoadingIndicator />\n ) : !hasNext ? (\n // Hidden from assistive tech: the end-of-list status is announced (combined with the result\n // count) by `useAnnounceSearchResultCount`, so the text is not read as a navigable result.\n <div aria-hidden='true' className='str-chat__search-source-results---empty'>\n {t('common.resultsLoaded.label', 'All results loaded')}\n </div>\n ) : null}\n </div>\n );\n};\n","import React from 'react';\nimport type { ComponentType } from 'react';\nimport type { SearchSourceState, SearchSourceType } from 'stream-chat';\n\nimport { DefaultSearchResultItems } from './SearchResultItem';\nimport { SearchSourceResultListFooter as DefaultSearchSourceResultListFooter } from './SearchSourceResultListFooter';\nimport { useSearchSourceResultsContext } from '../SearchSourceResultsContext';\nimport { InfiniteScrollPaginator } from '../../../components/InfiniteScrollPaginator/InfiniteScrollPaginator';\nimport { useComponentContext } from '../../../context';\nimport { useStateStore } from '../../../store';\nimport type { SearchResultItemComponents } from './SearchResultItem';\n\nconst searchSourceStateSelector = (nextValue: SearchSourceState) => ({\n items: nextValue.items,\n});\n\nexport type SearchSourceResultListProps = {\n loadMoreDebounceMs?: number;\n loadMoreThresholdPx?: number;\n SearchResultItems?: SearchResultItemComponents;\n};\n\nexport const SearchSourceResultList = ({\n loadMoreDebounceMs = 100,\n loadMoreThresholdPx = 80,\n SearchResultItems = DefaultSearchResultItems,\n}: SearchSourceResultListProps) => {\n const { SearchSourceResultListFooter = DefaultSearchSourceResultListFooter } =\n useComponentContext();\n\n const { searchSource } = useSearchSourceResultsContext();\n const { items } = useStateStore(searchSource.state, searchSourceStateSelector);\n\n const SearchResultItem = SearchResultItems[\n searchSource.type as SearchSourceType\n ] as ComponentType<{ item: unknown }>;\n\n if (!SearchResultItem) return null;\n\n return (\n <div\n className='str-chat__search-source-result-list'\n data-testid='search-source-result-list'\n >\n <InfiniteScrollPaginator\n loadNextDebounceMs={loadMoreDebounceMs}\n loadNextOnScrollToBottom={searchSource.search}\n threshold={loadMoreThresholdPx}\n >\n {items?.map((item, i) => (\n <SearchResultItem\n item={item}\n key={`source-search-result-${searchSource.type}-${i}`}\n />\n ))}\n <SearchSourceResultListFooter />\n </InfiniteScrollPaginator>\n </div>\n );\n};\n","import React from 'react';\nimport { useTranslationContext } from '../../../context';\n\nexport const SearchSourceResultsEmpty = () => {\n const { t } = useTranslationContext();\n return (\n <div className='str-chat__search-source-results-empty'>\n {t('search.sourceResults.noResultsFound.text', 'No results found')}\n </div>\n );\n};\n","export const SearchSourceResultsHeader = () => null;\n","import React from 'react';\nimport type { SearchSource, SearchSourceState } from 'stream-chat';\n\nimport { SearchSourceResultList as DefaultSearchSourceResultList } from './SearchSourceResultList';\nimport { SearchSourceResultsEmpty as DefaultSearchSourceResultsEmpty } from './SearchSourceResultsEmpty';\nimport { SearchSourceResultsHeader as DefaultSearchSourceResultsHeader } from './SearchSourceResultsHeader';\nimport { SearchSourceResultsContextProvider } from '../SearchSourceResultsContext';\nimport { useComponentContext } from '../../../context';\nimport { useStateStore } from '../../../store';\n\nconst searchSourceStateSelector = (nextValue: SearchSourceState) => ({\n isLoading: nextValue.isLoading,\n items: nextValue.items,\n});\n\nexport type SearchSourceResultsProps = { searchSource: SearchSource };\n\nexport const SearchSourceResults = ({ searchSource }: SearchSourceResultsProps) => {\n const {\n SearchSourceResultList = DefaultSearchSourceResultList,\n SearchSourceResultsEmpty = DefaultSearchSourceResultsEmpty,\n SearchSourceResultsHeader = DefaultSearchSourceResultsHeader,\n } = useComponentContext();\n const { isLoading, items } = useStateStore(\n searchSource.state,\n searchSourceStateSelector,\n );\n\n if (!items && !isLoading) return null;\n\n return (\n <SearchSourceResultsContextProvider value={{ searchSource }}>\n <div\n className='str-chat__search-source-results'\n data-testid='search-source-results'\n >\n <SearchSourceResultsHeader />\n {items?.length || isLoading ? (\n <SearchSourceResultList />\n ) : (\n <SearchSourceResultsEmpty />\n )}\n </div>\n </SearchSourceResultsContextProvider>\n );\n};\n","import clsx from 'clsx';\nimport React, { useMemo } from 'react';\nimport type { SearchSource, SearchSourceState } from 'stream-chat';\n\nimport { useSearchContext } from '../SearchContext';\nimport { useTranslationContext } from '../../../context';\nimport { useStateStore } from '../../../store';\nimport { Button } from '../../../components';\nimport { asDynamicKey } from '../../../i18n/utils';\n\nconst searchSourceStateSelector = (nextValue: SearchSourceState) => ({\n isActive: nextValue.isActive,\n});\n\ntype SearchSourceFilterButtonProps = {\n source: SearchSource;\n};\n\nconst SearchSourceFilterButton = ({ source }: SearchSourceFilterButtonProps) => {\n const { t } = useTranslationContext();\n const { searchController } = useSearchContext();\n const { isActive } = useStateStore(source.state, searchSourceStateSelector);\n const label = `search-results-header-filter-source-button-label--${source.type}`;\n\n const knownLabels = useMemo<Record<string, string>>(\n () => ({\n 'search-results-header-filter-source-button-label--channels': t(\n 'search.resultsHeader.filterSource.channels',\n 'channels',\n ),\n 'search-results-header-filter-source-button-label--messages': t(\n 'search.resultsHeader.filterSource.messages',\n 'messages',\n ),\n 'search-results-header-filter-source-button-label--users': t(\n 'search.resultsHeader.filterSource.users',\n 'users',\n ),\n }),\n [t],\n );\n\n const buttonContent = knownLabels[label] ?? t(asDynamicKey(label));\n return (\n <Button\n appearance='outline'\n aria-label={t(\n 'search.resultsHeader.ariaLabel',\n 'Search results header filter button for: {{ source }}',\n {\n source: buttonContent,\n },\n )}\n aria-pressed={isActive}\n className={clsx('str-chat__search-results-header__filter-source-button', {\n 'str-chat__search-results-header__filter-source-button--active': isActive,\n })}\n key={label}\n onClick={() => {\n if (source.isActive) {\n searchController.deactivateSource(source.type);\n } else {\n searchController.activateSource(source.type);\n if (searchController.searchQuery && !source.items?.length)\n source.search(searchController.searchQuery);\n }\n }}\n size='xs'\n variant='secondary'\n >\n {buttonContent}\n </Button>\n );\n};\n\nexport const SearchResultsHeader = () => {\n const { filterButtonsContainerRef, searchController } = useSearchContext();\n\n // render nothing if there's only one source (can't change filters)\n if (searchController.sources.length < 2) return null;\n\n return (\n <div className='str-chat__search-results-header' data-testid='search-results-header'>\n <div\n className='str-chat__search-results-header__filter-source-buttons'\n data-testid='filter-source-buttons'\n ref={filterButtonsContainerRef}\n >\n {searchController.sources.map((source) => (\n <SearchSourceFilterButton key={source.type} source={source} />\n ))}\n </div>\n </div>\n );\n};\n","import React from 'react';\n\nimport { useTranslationContext } from '../../../context';\n\nimport type { SearchSource } from 'stream-chat';\n\nexport type SearchResultsPresearchProps = {\n activeSources: SearchSource[];\n};\n\nexport const SearchResultsPresearch = () => {\n const { t } = useTranslationContext();\n return (\n <div className='str-chat__search-results-presearch'>\n {t('search.resultsPresearch.startTypingSearch.text', 'Start typing to search')}\n </div>\n );\n};\n","import React, { useRef } from 'react';\nimport type { SearchControllerState } from 'stream-chat';\n\nimport { SearchSourceResults as DefaultSourceSearchResults } from './SearchSourceResults';\nimport { SearchResultsHeader as DefaultSearchResultsHeader } from './SearchResultsHeader';\nimport { SearchResultsPresearch as DefaultSearchResultsPresearch } from './SearchResultsPresearch';\nimport { useSearchContext } from '../SearchContext';\nimport {\n useAnnounceSearchResultCount,\n useSearchResultsKeyboardNavigation,\n} from '../hooks';\nimport { useComponentContext, useTranslationContext } from '../../../context';\nimport { useStateStore } from '../../../store';\n\nconst searchControllerStateSelector = (nextValue: SearchControllerState) => ({\n activeSources: nextValue.sources.filter((s) => s.isActive),\n isActive: nextValue.isActive,\n searchQuery: nextValue.searchQuery,\n});\n\nexport const SearchResults = () => {\n const { t } = useTranslationContext();\n const {\n SearchResultsHeader = DefaultSearchResultsHeader,\n SearchResultsPresearch = DefaultSearchResultsPresearch,\n SearchSourceResults = DefaultSourceSearchResults,\n } = useComponentContext();\n const { searchController } = useSearchContext();\n const { activeSources, isActive, searchQuery } = useStateStore(\n searchController.state,\n searchControllerStateSelector,\n );\n\n const resultsRef = useRef<HTMLDivElement | null>(null);\n const { onKeyDown } = useSearchResultsKeyboardNavigation(resultsRef);\n // Announce the number of listed results once the list settles (only while a query is in progress,\n // not during presearch); the end-of-list status rides along in that same announcement.\n useAnnounceSearchResultCount(resultsRef, isActive && !!searchQuery, activeSources);\n\n return !isActive ? null : (\n <div\n aria-label={t('search.results.searchResults.ariaLabel', 'Search results')}\n className='str-chat__search-results'\n onKeyDown={onKeyDown}\n ref={resultsRef}\n >\n <SearchResultsHeader />\n {!searchQuery ? (\n <SearchResultsPresearch activeSources={activeSources} />\n ) : (\n activeSources.map((source) => (\n <SearchSourceResults key={source.type} searchSource={source} />\n ))\n )}\n </div>\n );\n};\n","import clsx from 'clsx';\nimport React, { useRef } from 'react';\nimport type { SearchControllerState } from 'stream-chat';\n\nimport { SearchBar as DefaultSearchBar } from './SearchBar/SearchBar';\nimport { SearchResults as DefaultSearchResults } from './SearchResults/SearchResults';\nimport { SearchContextProvider } from './SearchContext';\nimport { useChatContext, useComponentContext } from '../../context';\nimport { useStateStore } from '../../store';\n\ntype SearchControllerStateSelectorReturnValue = {\n isActive: boolean;\n};\n\nconst searchControllerStateSelector = (\n nextValue: SearchControllerState,\n): SearchControllerStateSelectorReturnValue => ({ isActive: nextValue.isActive });\n\nexport type SearchProps = {\n /** The type of channel to create on user result select, defaults to `messaging` */\n directMessagingChannelType?: string;\n /** Sets the input element into disabled state */\n disabled?: boolean;\n /** Clear the search state/results on every click outside the search input, defaults to `false` */\n exitSearchOnInputBlur?: boolean;\n /**\n * Extra props spread onto the search `<input>` element — e.g. to opt the field out of password\n * managers (`data-1p-ignore`, `data-lpignore`, `autoComplete: 'off'`) or add `name`/`aria-*`\n * attributes. The component's own controlled props (`value`, `onChange`, `onBlur`, `type`, `id`,\n * `disabled`, `ref`) take precedence and cannot be overridden; `className` is merged.\n */\n inputProps?: React.ComponentPropsWithoutRef<'input'>;\n /** Custom placeholder text to be displayed in the search input */\n placeholder?: string;\n};\n\nexport const Search = ({\n directMessagingChannelType = 'messaging',\n disabled,\n exitSearchOnInputBlur = false,\n inputProps,\n placeholder,\n}: SearchProps) => {\n const { SearchBar = DefaultSearchBar, SearchResults = DefaultSearchResults } =\n useComponentContext();\n const containerRef = useRef<HTMLDivElement | null>(null);\n const filterButtonsContainerRef = useRef<HTMLDivElement | null>(null);\n\n const { searchController } = useChatContext();\n\n const { isActive } = useStateStore<\n SearchControllerState,\n SearchControllerStateSelectorReturnValue\n >(searchController.state, searchControllerStateSelector);\n\n return (\n <SearchContextProvider\n value={{\n containerRef,\n directMessagingChannelType,\n disabled,\n exitSearchOnInputBlur,\n filterButtonsContainerRef,\n inputProps,\n placeholder,\n searchController,\n }}\n >\n <div\n className={clsx('str-chat__search', {\n 'str-chat__search--active': isActive,\n })}\n data-testid='search'\n ref={containerRef}\n >\n <SearchBar />\n <SearchResults />\n </div>\n </SearchContextProvider>\n );\n};\n","import React from 'react';\nimport type { SearchControllerState } from 'stream-chat';\n\nimport { ChannelListHeader as DefaultChannelListHeader } from './ChannelListHeader';\nimport { ChannelLists } from './ChannelLists';\nimport { NotificationList as DefaultNotificationList } from '../Notifications';\nimport { Search as DefaultSearch } from '../Search';\nimport { useChatContext, useComponentContext } from '../../context';\nimport { useStateStore } from '../../store';\n\nconst searchControllerStateSelector = (state: SearchControllerState) => ({\n isActive: state.isActive,\n});\n\n/**\n * Channel navigation region: owns the search-results ↔ channel-list swap so the\n * list components stay pure. Renders the `ChannelListHeader`, then `Search` (bar\n * always; results while active), then the paginator-driven `ChannelLists` only while\n * search is inactive. Mapped to the channel-navigation slot; `Search` is customizable\n * via the `ComponentContext` `Search` slot.\n */\nexport const ChannelNavigation = () => {\n const {\n ChannelListHeader = DefaultChannelListHeader,\n NotificationList = DefaultNotificationList,\n Search = DefaultSearch,\n } = useComponentContext();\n const { searchController } = useChatContext();\n const { isActive } = useStateStore(\n searchController.state,\n searchControllerStateSelector,\n );\n\n return (\n <div className='str-chat__channel-list'>\n <ChannelListHeader />\n <Search />\n {!isActive && <ChannelLists />}\n <NotificationList panel='channel-list' />\n </div>\n );\n};\n","import { useCallback } from 'react';\nimport { useSyncExternalStore } from 'use-sync-external-store/shim';\nimport type { Channel, EventType } from 'stream-chat';\n\n// eslint-disable-next-line @typescript-eslint/no-empty-function\nconst noop = () => {};\n\nexport function useSelectedChannelState<O>(_: {\n channel: Channel;\n selector: (channel: Channel) => O;\n stateChangeEventKeys?: EventType[];\n}): O;\nexport function useSelectedChannelState<O>(_: {\n selector: (channel: Channel) => O;\n channel?: Channel | undefined;\n stateChangeEventKeys?: EventType[];\n}): O | undefined;\nexport function useSelectedChannelState<O>({\n channel,\n selector,\n stateChangeEventKeys = ['all'],\n}: {\n selector: (channel: Channel) => O;\n channel?: Channel;\n stateChangeEventKeys?: EventType[];\n}): O | undefined {\n const subscribe = useCallback(\n (onStoreChange: (value: O) => void) => {\n if (!channel) return noop;\n\n const subscriptions = stateChangeEventKeys.map((et) =>\n channel.on(et, () => {\n onStoreChange(selector(channel));\n }),\n );\n\n return () => subscriptions.forEach((subscription) => subscription.unsubscribe());\n },\n [channel, selector, stateChangeEventKeys],\n );\n\n const getSnapshot = useCallback(() => {\n if (!channel) return undefined;\n\n return selector(channel);\n }, [channel, selector]);\n\n return useSyncExternalStore(subscribe, getSnapshot);\n}\n","import type { Channel, ChannelMemberResponse, EventType } from 'stream-chat';\nimport { useSelectedChannelState } from './useSelectedChannelState';\n\nconst selector = (c: Channel) => c.state.membership;\nconst keys: EventType[] = ['member.updated'];\n\nexport function useChannelMembershipState(channel: Channel): ChannelMemberResponse;\nexport function useChannelMembershipState(\n channel?: Channel | undefined,\n): ChannelMemberResponse | undefined;\nexport function useChannelMembershipState(channel?: Channel) {\n return useSelectedChannelState({ channel, selector, stateChangeEventKeys: keys });\n}\n","import type { Channel, ChannelMemberResponse, EventType } from 'stream-chat';\nimport { useSelectedChannelState } from './useSelectedChannelState';\n\nconst selector = (c: Channel) => c.state.members;\nconst keys: EventType[] = [\n 'member.updated',\n 'member.added',\n 'member.removed',\n 'user.banned',\n 'user.unbanned',\n 'user.deleted',\n 'user.presence.changed',\n];\n\nexport function useChannelMembersState(\n channel: Channel,\n): Record<string, ChannelMemberResponse>;\nexport function useChannelMembersState(\n channel?: Channel | undefined,\n): Record<string, ChannelMemberResponse> | undefined;\nexport function useChannelMembersState(channel?: Channel) {\n return useSelectedChannelState({ channel, selector, stateChangeEventKeys: keys });\n}\n","import type { Channel, MuteStatusState } from 'stream-chat';\n\nimport { useStateStore } from '../../../store';\n\nconst muteStatusSelector = (nextValue: MuteStatusState) => ({\n muteStatus: nextValue.muteStatus,\n});\n\n/**\n * Reactively reports whether the channel is muted for the current user.\n *\n * Reads the channel's `muteStatus` state slice, which the client keeps in sync with its own\n * `mutedChannels` (on `notification.channel_mutes_updated` and `health.check`) and republishes only\n * when the status actually changes.\n */\nexport const useIsChannelMuted = (channel: Channel) =>\n useStateStore(channel.state, muteStatusSelector).muteStatus;\n","import {\n type ComponentPropsWithoutRef,\n type ComponentPropsWithRef,\n forwardRef,\n useMemo,\n useRef,\n useState,\n} from 'react';\n\nimport {\n useChatContext,\n useComponentContextIcons,\n useTranslationContext,\n} from '../../context';\nimport { useChannelMembershipState, useChannelMembersState } from '../ChannelList';\nimport { useChannelListItemContext } from './ChannelListItem';\nimport { Button } from '../Button';\nimport { useIsChannelMuted } from './hooks/useIsChannelMuted';\nimport {\n ContextMenuButton,\n useContextMenuContext,\n useDialogIsOpen,\n useDialogOnNearestManager,\n} from '../Dialog';\nimport { useNotificationApi } from '../Notifications';\nimport { ChannelListItemActionButtons } from './ChannelListItemActionButtons';\n\ntype ChannelActionBehavior = {\n /** Toggle state for actions that have one (mute/archive/pin); omit for one-shot actions (leave). */\n 'aria-pressed'?: boolean;\n title: string;\n toggle: () => Promise<void>;\n};\n\n// Core mute/unmute action — performs the API call and reports the result. No UI state: the placement\n// wrappers below own the busy/disabled affordance and the menu-close behavior.\nconst useMuteAction = (): ChannelActionBehavior => {\n const { addNotification } = useNotificationApi();\n const { channel } = useChannelListItemContext();\n const { t } = useTranslationContext();\n const { muted: isMuted } = useIsChannelMuted(channel);\n\n const toggle = async () => {\n try {\n if (isMuted) {\n await channel.unmute();\n addNotification({\n context: { channel },\n emitter: ChannelListItemActionButtons.name,\n message: t('common.channelUnmuted.text', 'Channel unmuted'),\n severity: 'success',\n type: 'api:channel:unmute:success',\n });\n } else {\n await channel.mute();\n addNotification({\n context: { channel },\n emitter: ChannelListItemActionButtons.name,\n message: t('common.channelMuted.text', 'Channel muted'),\n severity: 'success',\n type: 'api:channel:mute:success',\n });\n }\n } catch (error) {\n addNotification({\n context: { channel },\n emitter: ChannelListItemActionButtons.name,\n error: error instanceof Error ? error : new Error('An unknown error occurred'),\n message: t(\n 'channelListItem.failedUpdateChannelMute.text',\n 'Failed to update channel mute status',\n ),\n severity: 'error',\n type: 'api:channel:mute:failed',\n });\n }\n };\n\n return {\n 'aria-pressed': isMuted,\n title: isMuted ? t('common.unmute.title', 'Unmute') : t('common.mute.title', 'Mute'),\n toggle,\n };\n};\n\n// Core archive/unarchive action — performs the API call and reports the result.\nconst useArchiveAction = (): ChannelActionBehavior => {\n const { channel } = useChannelListItemContext();\n const { addNotification } = useNotificationApi();\n const membership = useChannelMembershipState(channel);\n const { t } = useTranslationContext();\n\n const toggle = async () => {\n try {\n if (membership.archived_at != null) {\n await channel.unarchive();\n addNotification({\n context: { channel },\n emitter: ChannelListItemActionButtons.name,\n message: t('channelListItem.channelUnarchived.text', 'Channel unarchived'),\n severity: 'success',\n type: 'api:channel:unarchive:success',\n });\n } else {\n await channel.archive();\n addNotification({\n context: { channel },\n emitter: ChannelListItemActionButtons.name,\n message: t('channelListItem.channelArchived.text', 'Channel archived'),\n severity: 'success',\n type: 'api:channel:archive:success',\n });\n }\n } catch (error) {\n addNotification({\n context: { channel },\n emitter: ChannelListItemActionButtons.name,\n error: error instanceof Error ? error : new Error('An unknown error occurred'),\n message: t(\n 'channelListItem.failedUpdateChannelArchive.text',\n 'Failed to update channel archive status',\n ),\n severity: 'error',\n type: 'api:channel:archive:failed',\n });\n }\n };\n\n return {\n 'aria-pressed': membership.archived_at != null,\n title:\n membership.archived_at != null\n ? t('channelListItem.unarchive.title', 'Unarchive')\n : t('channelListItem.archive.title', 'Archive'),\n toggle,\n };\n};\n\n// Quick (hover/focus-revealed) action button. Marks itself busy with `aria-disabled`/`aria-busy` —\n// NOT the native `disabled` attribute, which would blur the button and collapse its hover-revealed\n// row, leaving it un-focusable. Keeps focus and guards against re-activation while in flight.\nconst useQuickActionButtonProps = ({\n 'aria-pressed': ariaPressed,\n title,\n toggle,\n}: ChannelActionBehavior) => {\n // Ref latch flips synchronously in the handler so two clicks in the same tick (before the\n // `setInProgress(true)` rerender commits) can't both call `toggle()` — the `aria-busy`/\n // `aria-disabled` state only guards after the rerender, which is too late for non-idempotent\n // actions (archive/leave/mute).\n const inProgressRef = useRef(false);\n const [inProgress, setInProgress] = useState(false);\n\n return {\n 'aria-busy': inProgress || undefined,\n 'aria-disabled': inProgress || undefined,\n 'aria-pressed': ariaPressed,\n onClick: async (e: React.MouseEvent<HTMLButtonElement>) => {\n e.stopPropagation();\n if (inProgressRef.current) return; // busy: ignore re-activation while in flight\n inProgressRef.current = true;\n try {\n setInProgress(true);\n await toggle();\n } finally {\n inProgressRef.current = false;\n setInProgress(false);\n }\n },\n title,\n } satisfies ComponentPropsWithoutRef<'button'>;\n};\n\n// Dropdown menu item. Standard menu behavior: activating closes the menu (which returns focus to the\n// toggle) and runs the action in the background, reporting via its notification — so the item needs\n// no busy/disabled state, it unmounts with the menu.\n//\n// The action is deferred to after the close commits, on the next animation frame. The open menu is an\n// aria-modal dialog with its OWN `AriaLiveOutlet` (the inert root outlet is ignored by assistive tech\n// while it is open); running the action synchronously can route its notification into that outlet\n// just as it is torn down — so the notification is never spoken. Deferring lets the menu (and its\n// outlet) unmount and focus return to the toggle first, so the notification lands in the root outlet,\n// in a calm window after the focus re-read.\nconst useDropdownActionButtonProps = ({\n 'aria-pressed': ariaPressed,\n title,\n toggle,\n}: ChannelActionBehavior) => {\n const { closeMenu } = useContextMenuContext();\n\n return {\n 'aria-pressed': ariaPressed,\n onClick: (e: React.MouseEvent<HTMLButtonElement>) => {\n e.stopPropagation();\n closeMenu();\n requestAnimationFrame(() => void toggle());\n },\n title,\n } satisfies ComponentPropsWithoutRef<'button'>;\n};\n\n// Core block/unblock action for the other member of a DM.\nconst useBanAction = (): ChannelActionBehavior => {\n const { client } = useChatContext();\n const { addNotification } = useNotificationApi();\n const { t } = useTranslationContext();\n const { channel } = useChannelListItemContext();\n const members = useChannelMembersState(channel);\n const isUserBanned = Object.values(members || {}).some(\n (member) => member.user?.id !== client.userID && member.banned,\n );\n\n const toggle = async () => {\n try {\n const otherUserId = Object.keys(channel.state.members).find(\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n (userId) => userId !== client.userID!,\n );\n if (!otherUserId) return;\n if (isUserBanned) {\n await channel.unbanUser(otherUserId);\n addNotification({\n context: { channel },\n emitter: ChannelListItemActionButtons.name,\n message: t('common.userUnblocked.text', 'User unblocked'),\n severity: 'success',\n type: 'api:user:unban:success',\n });\n } else {\n await channel.banUser(otherUserId, {});\n addNotification({\n context: { channel },\n emitter: ChannelListItemActionButtons.name,\n message: t('common.userBlocked.text', 'User blocked'),\n severity: 'success',\n type: 'api:user:ban:success',\n });\n }\n } catch (error) {\n addNotification({\n context: { channel },\n emitter: ChannelListItemActionButtons.name,\n error: error instanceof Error ? error : new Error('An unknown error occurred'),\n message: t('channelListItem.failedBlockUser.text', 'Failed to block user'),\n severity: 'error',\n type: 'api:user:ban:failed',\n });\n }\n };\n\n return {\n 'aria-pressed': isUserBanned,\n title: isUserBanned\n ? t('channelListItem.unblockUser.title', 'Unblock User')\n : t('common.blockUser.title', 'Block User'),\n toggle,\n };\n};\n\n// Core leave-channel action (one-shot — not a toggle).\nconst useLeaveAction = (): ChannelActionBehavior => {\n const { t } = useTranslationContext();\n const { channel } = useChannelListItemContext();\n const { client } = useChatContext();\n const { addNotification } = useNotificationApi();\n\n const toggle = async () => {\n try {\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n await channel.removeMembers([client.userID!]);\n addNotification({\n context: { channel },\n emitter: ChannelListItemActionButtons.name,\n message: t('common.leftChannel.text', 'Left channel'),\n severity: 'success',\n type: 'api:channel:leave:success',\n });\n } catch (error) {\n addNotification({\n context: { channel },\n emitter: ChannelListItemActionButtons.name,\n error: error instanceof Error ? error : new Error('An unknown error occurred'),\n message: t('common.failedLeaveChannel.text', 'Failed to leave channel'),\n severity: 'error',\n type: 'api:channel:leave:failed',\n });\n }\n };\n\n return { title: t('channelListItem.leaveChannel.title', 'Leave Channel'), toggle };\n};\n\n// Core pin/unpin action.\nconst usePinAction = (): ChannelActionBehavior => {\n const { t } = useTranslationContext();\n const { addNotification } = useNotificationApi();\n const { channel } = useChannelListItemContext();\n const membership = useChannelMembershipState(channel);\n\n const toggle = async () => {\n try {\n if (membership.pinned_at != null) {\n await channel.unpin();\n addNotification({\n context: { channel },\n emitter: ChannelListItemActionButtons.name,\n message: t('channelListItem.channelUnpinned.text', 'Channel unpinned'),\n severity: 'success',\n type: 'api:channel:unpin:success',\n });\n } else {\n await channel.pin();\n addNotification({\n context: { channel },\n emitter: ChannelListItemActionButtons.name,\n message: t('channelListItem.channelPinned.text', 'Channel pinned'),\n severity: 'success',\n type: 'api:channel:pin:success',\n });\n }\n } catch (error) {\n addNotification({\n context: { channel },\n emitter: ChannelListItemActionButtons.name,\n error: error instanceof Error ? error : new Error('An unknown error occurred'),\n message: t(\n 'channelListItem.failedUpdateChannelPinned.text',\n 'Failed to update channel pinned status',\n ),\n severity: 'error',\n type: 'api:channel:pin:failed',\n });\n }\n };\n\n return {\n 'aria-pressed': membership.pinned_at != null,\n title:\n membership.pinned_at != null\n ? t('common.unpin.title', 'Unpin')\n : t('common.pin.title', 'Pin'),\n toggle,\n };\n};\n\ntype ChannelActionItem =\n | (({ placement: 'quick' } | { placement: 'dropdown' }) & {\n type: string;\n Component: React.ComponentType;\n })\n | {\n placement: 'quick-dropdown-toggle';\n Component: React.ComponentType<ComponentPropsWithRef<'button'>>;\n };\n\nconst defaultComponents = {\n dropdown: {\n Archive() {\n const { IconArchive } = useComponentContextIcons();\n const behaviorProps = useDropdownActionButtonProps(useArchiveAction());\n\n return (\n <ContextMenuButton\n aria-label={behaviorProps.title}\n data-testid='dropdown-action-archive'\n Icon={IconArchive}\n {...behaviorProps}\n >\n {behaviorProps.title}\n </ContextMenuButton>\n );\n },\n Ban() {\n const { IconNoSign } = useComponentContextIcons();\n const behaviorProps = useDropdownActionButtonProps(useBanAction());\n\n return (\n <ContextMenuButton\n aria-label={behaviorProps.title}\n data-testid='dropdown-action-ban'\n Icon={IconNoSign}\n {...behaviorProps}\n >\n {behaviorProps.title}\n </ContextMenuButton>\n );\n },\n Leave() {\n const { IconLeave } = useComponentContextIcons();\n const behaviorProps = useDropdownActionButtonProps(useLeaveAction());\n\n return (\n <ContextMenuButton\n aria-label={behaviorProps.title}\n data-testid='dropdown-action-leave'\n Icon={IconLeave}\n variant='destructive'\n {...behaviorProps}\n >\n {behaviorProps.title}\n </ContextMenuButton>\n );\n },\n Mute() {\n const { IconMute } = useComponentContextIcons();\n const behaviorProps = useDropdownActionButtonProps(useMuteAction());\n\n return (\n <ContextMenuButton\n aria-label={behaviorProps.title}\n data-testid='dropdown-action-mute'\n Icon={IconMute}\n {...behaviorProps}\n >\n {behaviorProps.title}\n </ContextMenuButton>\n );\n },\n Pin() {\n const { IconPin } = useComponentContextIcons();\n const behaviorProps = useDropdownActionButtonProps(usePinAction());\n\n return (\n <ContextMenuButton\n aria-label={behaviorProps.title}\n data-testid='dropdown-action-pin'\n Icon={IconPin}\n {...behaviorProps}\n >\n {behaviorProps.title}\n </ContextMenuButton>\n );\n },\n },\n quick: {\n Archive() {\n const { IconArchive } = useComponentContextIcons();\n const behaviorProps = useQuickActionButtonProps(useArchiveAction());\n\n return (\n <Button\n appearance='ghost'\n aria-label={behaviorProps.title}\n circular\n data-testid='quick-action-archive'\n size='sm'\n variant='secondary'\n {...behaviorProps}\n >\n <IconArchive />\n </Button>\n );\n },\n Mute() {\n const { IconMute } = useComponentContextIcons();\n const behaviorProps = useQuickActionButtonProps(useMuteAction());\n\n return (\n <Button\n appearance='ghost'\n aria-label={behaviorProps.title}\n circular\n data-testid='quick-action-mute'\n size='sm'\n variant='secondary'\n {...behaviorProps}\n >\n <IconMute />\n </Button>\n );\n },\n },\n QuickDropdownToggle: forwardRef<HTMLButtonElement>((_, ref) => {\n const { IconMore } = useComponentContextIcons();\n const { channel } = useChannelListItemContext();\n const { t } = useTranslationContext();\n\n const dialogId = ChannelListItemActionButtons.getDialogId({\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n channelId: channel.id!,\n });\n const { dialog, dialogManager } = useDialogOnNearestManager({ id: dialogId });\n const dialogIsOpen = useDialogIsOpen(dialogId, dialogManager?.id);\n\n return (\n <Button\n appearance='ghost'\n aria-expanded={dialogIsOpen}\n aria-label={t(\n 'channelListItem.openChannelActionsMenu.ariaLabel',\n 'Open Channel Actions Menu',\n )}\n aria-pressed={dialogIsOpen}\n circular\n data-testid='channel-list-item-dropdown-toggle'\n onClick={(e) => {\n e.stopPropagation();\n\n dialog.toggle();\n }}\n ref={ref}\n size='sm'\n variant='secondary'\n >\n <IconMore />\n </Button>\n );\n }),\n};\n\ndefaultComponents.QuickDropdownToggle.displayName = 'QuickDropdownToggle';\n\nexport const defaultChannelActionSet: ChannelActionItem[] = [\n {\n Component: defaultComponents.QuickDropdownToggle,\n placement: 'quick-dropdown-toggle',\n },\n {\n Component: defaultComponents.quick.Mute,\n placement: 'quick',\n type: 'mute',\n },\n {\n Component: defaultComponents.dropdown.Archive,\n placement: 'dropdown',\n type: 'archive',\n },\n {\n Component: defaultComponents.dropdown.Ban,\n placement: 'dropdown',\n type: 'ban',\n },\n {\n Component: defaultComponents.dropdown.Pin,\n placement: 'dropdown',\n type: 'pin',\n },\n {\n Component: defaultComponents.dropdown.Leave,\n placement: 'dropdown',\n type: 'leave',\n },\n];\n\nexport const useBaseChannelActionSetFilter = (channelActionSet: ChannelActionItem[]) => {\n const { channel } = useChannelListItemContext();\n const membership = useChannelMembershipState(channel);\n const memberCount = channel.data?.member_count ?? 0;\n const connectedUserIsMember = typeof membership.user !== 'undefined';\n const isDirectMessageChannel = connectedUserIsMember && memberCount === 2;\n\n const ownCapabilities = channel.data?.own_capabilities;\n\n return useMemo(() => {\n const filtered = channelActionSet.filter((action) => {\n if (action.placement === 'quick-dropdown-toggle') return true;\n\n switch (action.type) {\n case 'archive':\n return connectedUserIsMember;\n case 'mute':\n return ownCapabilities?.includes('mute-channel');\n case 'ban':\n return (\n isDirectMessageChannel && ownCapabilities?.includes('ban-channel-members')\n );\n case 'leave':\n return ownCapabilities?.includes('leave-channel');\n case 'pin':\n return connectedUserIsMember;\n default:\n return true;\n }\n });\n\n return filtered;\n }, [channelActionSet, connectedUserIsMember, ownCapabilities, isDirectMessageChannel]);\n};\n","import { useMemo } from 'react';\n\nexport const useSplitActionSet = <\n T extends\n | { placement: 'quick' }\n | { placement: 'dropdown' }\n | { placement: 'quick-dropdown-toggle' },\n>(\n actionSet: T[],\n) =>\n useMemo(() => {\n const quickActionSet: Extract<T, { placement: 'quick' }>[] = [];\n const dropdownActionSet: Extract<T, { placement: 'dropdown' }>[] = [];\n let quickDropdownToggleAction:\n | Extract<T, { placement: 'quick-dropdown-toggle' }>\n | undefined;\n\n for (const action of actionSet) {\n if (action.placement === 'quick')\n quickActionSet.push(action as (typeof quickActionSet)[number]);\n if (action.placement === 'dropdown')\n dropdownActionSet.push(action as (typeof dropdownActionSet)[number]);\n if (action.placement === 'quick-dropdown-toggle') {\n quickDropdownToggleAction ??= action as Extract<\n T,\n { placement: 'quick-dropdown-toggle' }\n >;\n }\n }\n\n return { dropdownActionSet, quickActionSet, quickDropdownToggleAction } as const;\n }, [actionSet]);\n","import React, { type ComponentProps, type ComponentType, type ReactNode } from 'react';\n\nimport clsx from 'clsx';\nimport { ContextMenu, useDialogIsOpen, useDialogOnNearestManager } from '../Dialog';\nimport { useComponentContext, useTranslationContext } from '../../context';\nimport {\n defaultChannelActionSet,\n useBaseChannelActionSetFilter,\n} from './ChannelListItemActionButtons.defaults';\nimport { useSplitActionSet } from '../Chat/hooks/useSplitActionSet';\nimport { useChannelListItemContext } from './ChannelListItem';\n\nexport type ChannelListItemActionButtonsProps = ComponentProps<ComponentType>; // hack to allow empty props\n\ninterface ChannelListItemActionButtonsInterface {\n (props: ChannelListItemActionButtonsProps): ReactNode;\n getDialogId: (_: { channelId: string }) => string;\n displayName: string;\n}\n\nexport const ChannelListItemActionButtons: ChannelListItemActionButtonsInterface = () => {\n const { ContextMenu: ContextMenuComponent = ContextMenu } = useComponentContext();\n const { t } = useTranslationContext();\n const { channel } = useChannelListItemContext();\n const [referenceElement, setReferenceElement] =\n React.useState<HTMLButtonElement | null>(null);\n const [isRestoringFocus, setIsRestoringFocus] = React.useState(false);\n const dialogId = ChannelListItemActionButtons.getDialogId({\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n channelId: channel.id!,\n });\n const { dialog, dialogManager } = useDialogOnNearestManager({ id: dialogId });\n const dialogIsOpen = useDialogIsOpen(dialogId, dialogManager?.id);\n\n const closeContextMenu = React.useCallback(() => {\n setIsRestoringFocus(true);\n dialog?.close();\n\n requestAnimationFrame(() => {\n if (!referenceElement?.isConnected) {\n setIsRestoringFocus(false);\n return;\n }\n\n referenceElement.focus();\n\n requestAnimationFrame(() => {\n if (document.activeElement !== referenceElement) {\n setIsRestoringFocus(false);\n }\n });\n });\n }, [dialog, referenceElement]);\n\n const filteredActionSet = useBaseChannelActionSetFilter(defaultChannelActionSet);\n const { dropdownActionSet, quickActionSet, quickDropdownToggleAction } =\n useSplitActionSet(filteredActionSet);\n\n if (quickActionSet.length + dropdownActionSet.length === 0) {\n // no buttons to render, omit rendering wrapper\n return null;\n }\n\n return (\n <div\n className={clsx('str-chat__channel-list-item__action-buttons', {\n 'str-chat__channel-list-item__action-buttons--active':\n dialogIsOpen || isRestoringFocus,\n })}\n data-testid='channel-list-item-action-buttons'\n onFocusCapture={() => {\n setIsRestoringFocus(false);\n }}\n >\n {quickDropdownToggleAction && dropdownActionSet.length > 0 && (\n <quickDropdownToggleAction.Component ref={setReferenceElement} />\n )}\n {quickActionSet.map(({ Component, type }) => (\n <Component key={type} />\n ))}\n <ContextMenuComponent\n aria-label={t('channelListItem.channelActions.ariaLabel', 'Channel Actions')}\n className='str-chat__channel-list-item__action-buttons-context-menu'\n data-testid='channel-list-item-context-menu'\n dialogManagerId={dialogManager?.id}\n id={dialog.id}\n onClose={closeContextMenu}\n placement='bottom-start'\n referenceElement={referenceElement}\n tabIndex={-1}\n trapFocus\n >\n {dropdownActionSet.map(({ Component, type }) => (\n <Component key={type} />\n ))}\n </ContextMenuComponent>\n </div>\n );\n};\n\nChannelListItemActionButtons.getDialogId = ({ channelId }) =>\n `channel-action-buttons-${channelId}`;\n\nChannelListItemActionButtons.displayName = 'ChannelListItemActionButtons';\n","import React, { useMemo } from 'react';\nimport type { LocalMessage } from 'stream-chat';\n\nimport { useTranslationContext } from '../../context/TranslationContext';\nimport { getDateString } from '../../i18n/utils';\nimport { convertTimestampToDate } from 'stream-chat';\n\nexport type ChannelListItemTimestampProps = {\n /** The message previewed by the item, used to extract the timestamp */\n previewedMessage?: LocalMessage;\n};\n\nexport function ChannelListItemTimestamp({\n previewedMessage,\n}: ChannelListItemTimestampProps) {\n const { t, tDateTimeParser } = useTranslationContext();\n\n const timestamp = previewedMessage?.created_at;\n // `isDate` correctly reports that a wire number is not a `Date`, so the old idiom here returned\n // `undefined` for every message and the timestamp vanished from the list. Convert instead.\n const normalizedTimestamp =\n timestamp != null ? convertTimestampToDate(timestamp)?.toISOString() : undefined;\n\n const when = useMemo(\n () =>\n getDateString({\n messageCreatedAt: normalizedTimestamp,\n t,\n tDateTimeParser,\n timestampTranslationKey: 'timestamp.ChannelPreviewTimestamp',\n }),\n [normalizedTimestamp, t, tDateTimeParser],\n );\n\n if (!when) return null;\n\n return (\n <time\n className='str-chat__channel-list-item-timestamp'\n dateTime={normalizedTimestamp}\n >\n {when}\n </time>\n );\n}\n","import type { TranslationContextValue } from '../context/TranslationContext';\n\n/** Produces one segment of a composed accessible name; return `undefined`/empty to omit it. */\nexport type AccessibleLabelPart<TData> = (data: TData) => string | undefined;\n\n/** Customization for a part-composed accessible name (the channel/thread list-row labels). */\nexport type AccessibleLabelConfig<TData> = {\n /** Full override — return the entire label; ignores `order`/`parts`/`separator`. */\n build?: (data: TData) => string;\n /** Which parts to include, in what order. A part not listed here is never rendered. */\n order?: ReadonlyArray<string>;\n /** Override or add individual part generators; merged over the defaults. */\n parts?: Record<string, AccessibleLabelPart<TData>>;\n /** Joiner between non-empty parts. Defaults to \". \". */\n separator?: string;\n};\n\n/**\n * Composes a single accessible name from named parts: applies `config.build` if present, otherwise\n * merges `config.parts` over `defaultParts`, walks `config.order ?? defaultOrder`, and joins the\n * non-empty segments with `config.separator ?? '. '`. Shared by the channel and thread list-row\n * labels so the assembly logic lives in one place.\n */\nexport const composeAccessibleLabel = <TData>(\n data: TData,\n defaultParts: Record<string, AccessibleLabelPart<TData>>,\n defaultOrder: ReadonlyArray<string>,\n config: AccessibleLabelConfig<TData> = {},\n): string => {\n if (config.build) return config.build(data);\n const parts: Record<string, AccessibleLabelPart<TData>> = {\n ...defaultParts,\n ...config.parts,\n };\n const order = config.order ?? defaultOrder;\n return order\n .map((key) => parts[key]?.(data))\n .filter((value): value is string => !!value)\n .join(config.separator ?? '. ');\n};\n\n// Parts shared verbatim across list-row labels. Typed over the minimal data each needs; function\n// parameter contravariance makes them assignable to the wider channel/thread part types.\ntype WithT = { t: TranslationContextValue['t'] };\n\n/**\n * Announces the active (currently open) row. The active state is announced here (not left to the\n * row's `aria-selected` alone, which is not reliably spoken across screen readers for an option with\n * a custom name); `aria-selected` is kept on the active row for listbox semantics.\n */\nexport const activeLabelPart: AccessibleLabelPart<WithT & { active?: boolean }> = ({\n active,\n t,\n}) => (active ? t('a11y.accessibleLabel.active.ariaLabel', 'Active') : undefined);\n\n/** Announces the unread count when there is one. */\nexport const unreadCountLabelPart: AccessibleLabelPart<\n WithT & { unreadCount?: number }\n> = ({ t, unreadCount }) =>\n typeof unreadCount === 'number' && unreadCount > 0\n ? t('a11y.accessibleLabel.unreadMessage.ariaLabel', {\n count: unreadCount,\n defaultValue_one: '{{ count }} unread message',\n defaultValue_other: '{{ count }} unread messages',\n })\n : undefined;\n","import { useCallback, useMemo } from 'react';\nimport type {\n Channel,\n LocalMessage,\n MessageReceiptsSnapshot,\n MsgRef,\n UserResponse,\n} from 'stream-chat';\n\nimport { useChatContext } from '../../../context';\nimport { useStateStore } from '../../../store/hooks/useStateStore';\n\nexport enum MessageDeliveryStatus {\n SENT = 'sent',\n DELIVERED = 'delivered',\n READ = 'read',\n}\n\ntype UseMessageStatusParamsChannelPreviewProps = {\n channel: Channel;\n /** The last message received in a channel */\n lastMessage?: LocalMessage;\n};\n\n/** Whether a cursor has reached this message. */\nconst hasCursorReached = (message: LocalMessage, cursor: MsgRef | null) =>\n !!cursor && message.created_at <= cursor.timestamp;\n\nconst trackerSnapshotSelector = (next: MessageReceiptsSnapshot) => ({\n lastDeliveredRefByOthers: next.lastDeliveredRefByOthers,\n lastReadRefByOthers: next.lastReadRefByOthers,\n});\n\nexport const useMessageDeliveryStatus = ({\n channel,\n lastMessage,\n}: UseMessageStatusParamsChannelPreviewProps) => {\n const { client } = useChatContext();\n const trackerSnapshot = useStateStore(\n channel.messageReceiptsTracker.snapshotStore,\n trackerSnapshotSelector,\n );\n\n const isOwnMessage = useCallback(\n (message?: { user?: UserResponse | null }) =>\n client.user && message && message.user?.id === client.user.id,\n [client],\n );\n\n const messageDeliveryStatus = useMemo(() => {\n // empty channel\n if (!lastMessage) return undefined;\n\n const lastMessageIsOwn = isOwnMessage(lastMessage);\n if (!lastMessageIsOwn) return undefined;\n\n // Read against the cursors rather than asking who sits on this message: a member whose cursor\n // is behind the latest message has still received everything up to it, and the old lookup\n // reported that as `SENT`.\n if (hasCursorReached(lastMessage, trackerSnapshot?.lastReadRefByOthers ?? null)) {\n return MessageDeliveryStatus.READ;\n }\n if (\n hasCursorReached(lastMessage, trackerSnapshot?.lastDeliveredRefByOthers ?? null)\n ) {\n return MessageDeliveryStatus.DELIVERED;\n }\n return MessageDeliveryStatus.SENT;\n }, [isOwnMessage, lastMessage, trackerSnapshot]);\n\n return {\n messageDeliveryStatus,\n };\n};\n","/**\n * Message translation view context: user-specific state for whether each message\n * shows original text or a translation.\n *\n * ## Spec\n *\n * - **State**: Per message list (channel vs thread), we store a map\n * `messageId → 'original' | 'translated'`. Default for messages with `message.i18n`\n * is `'translated'`; otherwise `'original'`.\n *\n * - **Provider placement**: The provider is tied to the **message list**, not the channel.\n * It is rendered inside `MessageList` and `VirtualizedMessageList`. That way the\n * main channel list and the thread list each have their own translation view state\n * (e.g. Thread.tsx gets correct behavior without sharing channel state).\n *\n * - **Multiple translations**: `message.i18n` can contain multiple languages, e.g.:\n * `{ en_text: \"Good morning\", fr_text: \"Bonjour\", it_text: \"Buongiorno\", language: \"en\" }`.\n * Which translation is shown is determined by the app’s **user language**\n * (`useTranslationContext().userLanguage`). We use `message.i18n[userLanguage + '_text']`;\n * if missing, we fall back to `message.text`. Only one translation is shown at a time.\n *\n * - **Source language**: When present, `message.i18n.language` is the original/source\n * language of `message.text`. It can be used for the indicator label, e.g.\n * \"Translated from English · View original\".\n *\n * - **Invariants**: The original message content, layout, grouping, and order stay\n * unchanged. Removing or toggling translation only changes the annotation and which\n * text is displayed. \"View original\" / \"View translation\" switch the displayed\n * text and update the annotation (e.g. \"Original · View translation\" when showing\n * original).\n *\n * - **Translation indicator visibility**: The translation indicator (e.g. \"Translated ·\n * View original\") is **not** shown when the currently viewed text already corresponds\n * to `userLanguage` — for example when viewing original and the original text is the\n * user-language version (i.e. `getTranslatedMessageText({ language: userLanguage, message })`\n * equals `message.text`). In that case there is no meaningful original/translated choice,\n * so the indicator is hidden.\n */\n\nimport React, { createContext, useCallback, useContext, useState } from 'react';\nimport type { LocalMessage, TranslationLanguage } from 'stream-chat';\n\n/**\n * Returns the translated message text for a given language from `message.i18n`, or\n * undefined if not present. Used to resolve which of the multiple translations to show.\n */\nexport const getTranslatedMessageText = ({\n language,\n message,\n}: {\n language: string;\n message?: LocalMessage;\n}): string | undefined =>\n message?.i18n?.[`${language}_text` as `${TranslationLanguage}_text`];\n\n/**\n * Which message text to show.\n * - `'original'`: `message.text` (source language).\n * - `'translated'`: translation for the **current user language** (TranslationContext’s\n * `userLanguage`), i.e. `getTranslatedMessageText({ language: userLanguage, message })`\n * or fallback to `message.text`.\n */\nexport type TranslationView = 'original' | 'translated';\n\nexport type MessageTranslationViewContextValue = {\n getTranslationView: (messageId: string, hasI18n: boolean) => TranslationView;\n setTranslationView: (messageId: string, view: TranslationView) => void;\n};\n\nconst defaultContextValue: MessageTranslationViewContextValue = {\n getTranslationView: (_messageId, hasI18n) => (hasI18n ? 'translated' : 'original'),\n // eslint-disable-next-line @typescript-eslint/no-empty-function\n setTranslationView: () => {},\n};\n\nexport const MessageTranslationViewContext =\n createContext<MessageTranslationViewContextValue>(defaultContextValue);\n\nexport const MessageTranslationViewProvider = ({\n children,\n}: {\n children: React.ReactNode;\n}) => {\n const [viewByMessageId, setViewByMessageId] = useState<Record<string, TranslationView>>(\n {},\n );\n\n const setTranslationView = useCallback((messageId: string, view: TranslationView) => {\n setViewByMessageId((prev) => ({ ...prev, [messageId]: view }));\n }, []);\n\n const getTranslationView = useCallback(\n (messageId: string, hasI18n: boolean): TranslationView =>\n viewByMessageId[messageId] ?? (hasI18n ? 'translated' : 'original'),\n [viewByMessageId],\n );\n\n const stableValue = React.useMemo(\n () => ({ getTranslationView, setTranslationView }),\n [getTranslationView, setTranslationView],\n );\n\n return (\n <MessageTranslationViewContext.Provider value={stableValue}>\n {children}\n </MessageTranslationViewContext.Provider>\n );\n};\n\n// created with a default value, so there is no missing-provider case\nexport const useMessageTranslationViewContext = () =>\n useContext(MessageTranslationViewContext);\n","import emojiRegex from 'emoji-regex';\n\n/**\n * `emojiRegex()` compiles a ~15KB regex source on every call, so we build a\n * single shared instance at module load and reuse it everywhere an emoji match\n * is needed.\n *\n * The instance is global (carries the `g` flag and therefore a mutable\n * `lastIndex`), so it is only safe to reuse with consumers that reset\n * `lastIndex` before scanning:\n * - `String#match` / `String#replace` reset it internally;\n * - `hast-util-find-and-replace` resets it before each use.\n *\n * Do NOT use it directly with stateful `.test()` / `.exec()` loops.\n */\nexport const EMOJI_REGEX = emojiRegex();\n","import deepequal from 'react-fast-compare';\n\nimport { EMOJI_REGEX } from './emojiRegex';\n\nimport type {\n LocalMessage,\n MessageResponse,\n StreamChat,\n UserMuteResponse,\n UserResponse,\n} from 'stream-chat';\nimport type { MessageProps } from './types';\nimport type { MessageContextValue } from '../../context';\nimport type { StreamTFunction } from '../../i18n/types';\n\n/**\n * Following function validates a function which returns notification message.\n * It validates if the first parameter is function and also if return value of function is string or no.\n */\nexport const validateAndGetMessage = <T extends unknown[]>(\n func: (...args: T) => unknown,\n args: T,\n) => {\n if (!func || typeof func !== 'function') return null;\n\n // below is due to tests passing a single argument\n // rather than an array.\n if (!Array.isArray(args)) {\n args = [args] as unknown as T;\n }\n\n const returnValue = func(...args);\n\n if (typeof returnValue !== 'string') return null;\n\n return returnValue;\n};\n\n/**\n * Tell if the owner of the current message is muted\n */\nexport const isUserMuted = (message: LocalMessage, mutes?: UserMuteResponse[]) => {\n if (!mutes || !message) return false;\n\n return mutes.some(({ target }) => target?.id === message.user?.id);\n};\n\n/** `MessageActionSetItem['type']`s that a thread reply does not support. */\nexport const ACTIONS_NOT_WORKING_IN_THREAD: string[] = ['pin', 'reply', 'markUnread'];\n\nfunction areMessagesEqual(prevMessage: LocalMessage, nextMessage: LocalMessage): boolean {\n if (prevMessage === nextMessage) return true;\n\n const areBaseMessagesEqual = (prevMessage: LocalMessage, nextMessage: LocalMessage) =>\n prevMessage.deleted_at === nextMessage.deleted_at &&\n prevMessage.attachments === nextMessage.attachments &&\n prevMessage.latest_reactions === nextMessage.latest_reactions &&\n prevMessage.own_reactions === nextMessage.own_reactions &&\n prevMessage.reaction_groups === nextMessage.reaction_groups &&\n prevMessage.shared_location === nextMessage.shared_location &&\n prevMessage.pinned === nextMessage.pinned &&\n prevMessage.reply_count === nextMessage.reply_count &&\n prevMessage.show_in_channel === nextMessage.show_in_channel &&\n prevMessage.status === nextMessage.status &&\n prevMessage.text === nextMessage.text &&\n prevMessage.type === nextMessage.type &&\n prevMessage.updated_at === nextMessage.updated_at &&\n prevMessage.user?.updated_at === nextMessage.user?.updated_at;\n\n return (\n areBaseMessagesEqual(prevMessage, nextMessage) &&\n Boolean(prevMessage.quoted_message) === Boolean(nextMessage.quoted_message) &&\n ((!prevMessage.quoted_message && !nextMessage.quoted_message) ||\n areBaseMessagesEqual(\n prevMessage.quoted_message as LocalMessage,\n nextMessage.quoted_message as LocalMessage,\n ))\n );\n}\n\nexport const areMessagePropsEqual = (\n prevProps: MessageProps & {\n showDetailedReactions?: boolean;\n },\n nextProps: MessageProps & {\n showDetailedReactions?: boolean;\n },\n) => {\n const { message: prevMessage } = prevProps;\n const { message: nextMessage } = nextProps;\n\n // The message UI component itself is not compared here: it is resolved from\n // `ComponentContext`, and context updates re-render consumers regardless of `React.memo`.\n if (nextProps.showDetailedReactions !== prevProps.showDetailedReactions) {\n return false;\n }\n\n if (nextProps.closeReactionSelectorOnClick !== prevProps.closeReactionSelectorOnClick) {\n return false;\n }\n\n const messagesAreEqual = areMessagesEqual(prevMessage, nextMessage);\n if (!messagesAreEqual) return false;\n\n const deepEqualProps =\n deepequal(nextProps.readBy, prevProps.readBy) &&\n deepequal(nextProps.deliveredTo, prevProps.deliveredTo) &&\n deepequal(nextProps.highlighted, prevProps.highlighted) &&\n deepequal(nextProps.groupStyles, prevProps.groupStyles) && // last 3 messages can have different group styles\n deepequal(nextProps.lastReceivedId, prevProps.lastReceivedId);\n\n if (!deepEqualProps) return false;\n\n return (\n prevProps.messageListRect === nextProps.messageListRect // MessageList wrapper layout changes\n );\n};\n\nexport const areMessageUIPropsEqual = (\n prevProps: MessageContextValue & {\n showDetailedReactions?: boolean;\n },\n nextProps: MessageContextValue & {\n showDetailedReactions?: boolean;\n },\n) => {\n const { lastReceivedId: prevLastReceivedId, message: prevMessage } = prevProps;\n const { lastReceivedId: nextLastReceivedId, message: nextMessage } = nextProps;\n\n if (prevProps.highlighted !== nextProps.highlighted) return false;\n if (prevProps.endOfGroup !== nextProps.endOfGroup) return false;\n if (prevProps.readBy?.length !== nextProps.readBy?.length) return false;\n if (prevProps.deliveredTo?.length !== nextProps.deliveredTo?.length) return false;\n if (prevProps.groupStyles !== nextProps.groupStyles) return false;\n\n if (prevProps.showDetailedReactions !== nextProps.showDetailedReactions) {\n return false;\n }\n\n if (\n (prevMessage.id === prevLastReceivedId || prevMessage.id === nextLastReceivedId) &&\n prevLastReceivedId !== nextLastReceivedId\n ) {\n return false;\n }\n\n return areMessagesEqual(prevMessage, nextMessage);\n};\n\nexport const messageHasReactions = (message?: LocalMessage) =>\n Object.values(message?.reaction_groups ?? {}).some(({ count }) => count > 0);\n\nexport const messageHasQuotedMessage = (message?: LocalMessage) =>\n !!message?.quoted_message;\n\nexport const messageHasAttachments = (message?: LocalMessage) =>\n !!message?.attachments && !!message.attachments.length;\n\nexport const messageHasSingleAttachment = (message?: LocalMessage) =>\n message?.attachments?.length === 1;\n\nexport const messageHasGiphyAttachment = (message?: LocalMessage) =>\n !!message?.attachments?.some((att) => att.type === 'giphy');\n\nexport const getImages = (message?: MessageResponse) => {\n if (!message?.attachments) {\n return [];\n }\n return message.attachments.filter((item) => item.type === 'image');\n};\n\nexport const getNonImageAttachments = (message?: MessageResponse) => {\n if (!message?.attachments) {\n return [];\n }\n return message.attachments.filter((item) => item.type !== 'image');\n};\n\nexport interface TooltipUsernameMapper {\n (user: UserResponse): string;\n}\n\n/**\n * Default Tooltip Username mapper implementation.\n *\n * @param user the user.\n */\nexport const mapToUserNameOrId: TooltipUsernameMapper = (user) => user.name || user.id;\n\nexport const getReadByTooltipText = (\n users: UserResponse[],\n t: StreamTFunction,\n client: StreamChat,\n tooltipUserNameMapper: TooltipUsernameMapper,\n) => {\n let outStr = '';\n\n if (!t) {\n throw new Error(\n 'getReadByTooltipText was called, but translation function is not available',\n );\n }\n\n if (!tooltipUserNameMapper) {\n throw new Error(\n 'getReadByTooltipText was called, but tooltipUserNameMapper function is not available',\n );\n }\n // first filter out client user, so restLength won't count it\n const otherUsers = users\n .filter((item) => item && client?.user && item.id !== client.user.id)\n .map(tooltipUserNameMapper);\n\n const slicedArr = otherUsers.slice(0, 5);\n const restLength = otherUsers.length - slicedArr.length;\n\n if (slicedArr.length === 1) {\n outStr = `${slicedArr[0]} `;\n } else if (slicedArr.length === 2) {\n // joins all with \"and\" but =no commas\n // example: \"bob and sam\"\n outStr = t(\n 'message.and.withFirstUserAndSecondUser.label',\n '{{ firstUser }} and {{ secondUser }}',\n {\n firstUser: slicedArr[0],\n secondUser: slicedArr[1],\n },\n );\n } else if (slicedArr.length > 2) {\n // joins all with commas, but last one gets \", and\" (oxford comma!)\n // example: \"bob, joe, sam and 4 more\"\n if (restLength === 0) {\n // mutate slicedArr to remove last user to display it separately\n const [lastUser] = slicedArr.splice(slicedArr.length - 1, 1);\n outStr = t(\n 'message.and.withCommaSeparatedUsersAndLastUser.label',\n '{{ commaSeparatedUsers }}, and {{ lastUser }}',\n {\n commaSeparatedUsers: slicedArr.join(', '),\n lastUser,\n },\n );\n } else {\n outStr = t(\n 'message.more.label',\n '{{ commaSeparatedUsers }} and {{ moreCount }} more',\n {\n commaSeparatedUsers: slicedArr.join(', '),\n moreCount: restLength,\n },\n );\n }\n }\n\n return outStr;\n};\n\nexport const countEmojis = (text?: string) => {\n const matches = text?.match(EMOJI_REGEX);\n return matches ? matches.length : 0;\n};\n\nexport const messageTextHasEmojisOnly = (message: LocalMessage) => {\n if (!message.text) return false;\n\n const noEmojis = message.text.replace(EMOJI_REGEX, '');\n const noSpace = noEmojis.replace(/[\\s\\n]/gm, '');\n\n return !noSpace;\n};\n\nexport const isMessageErrorRetryable = (message: LocalMessage) =>\n message.status === 'failed' && message.error?.status !== 403;\n\nexport const isNetworkSendFailure = (message: Pick<LocalMessage, 'error' | 'status'>) =>\n message.status === 'failed' && message.error?.status === 0;\n\nexport const isMessageBounced = (message: Pick<LocalMessage, 'type' | 'moderation'>) =>\n message.type === 'error' && message.moderation?.action === 'bounce';\n\nexport const isMessageBlocked = (\n message: Pick<LocalMessage, 'type' | 'moderation' | 'shadowed'>,\n) =>\n message.shadowed ||\n (message.type === 'error' && message.moderation?.action === 'remove');\n\nexport const isMessageDeleted = (message: LocalMessage): boolean =>\n Boolean(\n message.deleted_at != null || message.type === 'deleted' || message.deleted_for_me,\n );\n\nexport const isMessageEdited = (message: Pick<LocalMessage, 'message_text_updated_at'>) =>\n message.message_text_updated_at != null;\n","import type { Visitor } from 'unist-util-visit';\nimport { visit } from 'unist-util-visit';\n\n// `Nodes` is not part of hast-util-find-and-replace's public surface; derive\n// the visit-compatible tree type from `visit` itself.\ntype Nodes = Parameters<typeof visit>[0];\n\nconst visitor: Visitor = (node) => {\n if (node.type !== 'html') return;\n\n node.type = 'text';\n};\nconst transform = (tree: Nodes) => {\n visit(tree, visitor);\n};\n\nexport const htmlToTextPlugin = () => transform;\n","import { SKIP, visit, type VisitorResult } from 'unist-util-visit';\nimport type { Image, Link, Parent, Text } from 'mdast';\nimport type { Node } from 'unist';\n\ntype ImgVisitor = (\n node: Image,\n index: number | null,\n parent: Parent | null,\n) => VisitorResult;\n\nexport type ImageToLinkPluginOptions = {\n getTextLabelFrom?: 'alt' | 'title' | 'url';\n};\n\nconst text = (value: string): Text => ({ type: 'text', value });\n\n/**\n * Converts image Markdown links (![Minion](https://octodex.github.com/images/minion.png))\n * to HTML <a href={url}>{url | title | alt}</a>\n *\n * By default, the anchor text content is the image url so that image preview can be generated / enriched on the server.\n * @param getTextLabelFrom\n */\nexport function imageToLink({ getTextLabelFrom = 'url' }: ImageToLinkPluginOptions = {}) {\n return (tree: Node) => {\n const visitor: ImgVisitor = (node, index, parent) => {\n if (parent == null || index == null) return;\n\n const label = node[getTextLabelFrom] ?? node.url; // node.alt || node.title || node.url;\n const link: Link = {\n children: [text(label)],\n title: node.title ?? node.alt ?? node.url,\n type: 'link',\n url: node.url,\n };\n\n parent.children.splice(index, 1, link);\n return [SKIP, index + 1] as const;\n };\n\n visit(tree, 'image', visitor);\n };\n}\n","// remark-plusplus-ins.ts\nimport type { Plugin } from 'unified';\nimport { SKIP, visit } from 'unist-util-visit';\nimport type { Visitor } from 'unist-util-visit';\nimport type { Parent, PhrasingContent, Text } from 'mdast';\n\n/**\n * \\S → first char must be non-whitespace\n * (?:...)?→ optional middle+closing when length > 1\n * [\\s\\S]*?→ anything (including newlines), lazy\n * final \\S→ last char non-whitespace (only required when there’s more than 1)\n *\n * Matches:\n * ++a++\n * Does not match:\n * ++++\n * ++ ++\n */\nconst INS_REGEX = /\\+\\+(\\S(?:[\\s\\S]*?\\S)?)\\+\\+/g;\nconst IGNORE_NODE_TYPES = new Set([\n 'code',\n 'inlineCode',\n 'link',\n 'linkReference',\n 'definition',\n 'math',\n 'inlineMath',\n]);\n\n/**\n * Converts MD \"++Some text++\" to inserted text element rendered in HTML as <ins>Some text</ins>\n * https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Elements/ins\n */\nexport const plusPlusToEmphasis: Plugin<[]> = () => {\n const visitor: Visitor = (node, index, parent) => {\n // 1) Don’t traverse inside ignored nodes\n if (IGNORE_NODE_TYPES.has(node.type)) return SKIP;\n\n // 2) Only transform text nodes with a valid parent + index\n if (node.type !== 'text' || parent == null || typeof index !== 'number') return;\n\n const value = (node as Text).value;\n\n // Reset lastIndex to 0 per node so each node is scanned from the beginning\n INS_REGEX.lastIndex = 0;\n\n let match: RegExpExecArray | null;\n let last = 0;\n const out: PhrasingContent[] = [];\n\n while ((match = INS_REGEX.exec(value))) {\n const [full, inner] = match;\n const start = match.index;\n\n if (start > last) out.push({ type: 'text', value: value.slice(last, start) });\n\n // Render as <ins>…</ins> (remark-rehype respects data.hName)\n out.push({\n children: [{ type: 'text', value: inner }],\n data: { hName: 'ins' },\n type: 'emphasis',\n });\n\n last = start + full.length;\n }\n\n if (out.length === 0) return; // nothing to change\n if (last < value.length) out.push({ type: 'text', value: value.slice(last) });\n\n (parent as Parent).children.splice(index, 1, ...out);\n\n // Skip re-visiting the replaced range; continue after inserted nodes\n return [SKIP, index + out.length];\n };\n\n return (tree) => visit(tree, visitor);\n};\n","import { StateStore } from '@stream-io/state-store';\nimport throttle from 'lodash.throttle';\nimport type { AudioPlayerPlugin } from './plugins';\nimport type { AudioPlayerPool } from './AudioPlayerPool';\n\nexport type AudioPlayerErrorCode =\n | 'failed-to-start'\n | 'not-playable'\n | 'seek-not-supported'\n | (string & {});\n\nexport type RegisterAudioPlayerErrorParams = {\n error?: Error;\n errCode?: AudioPlayerErrorCode;\n};\n\nexport type AudioPlayerDescriptor = {\n id: string;\n src: string;\n /** Audio duration in seconds. */\n durationSeconds?: number;\n fileSize?: number | string;\n mimeType?: string;\n title?: string;\n waveformData?: number[];\n};\n\nexport type AudioPlayerPlayAudioParams = {\n currentPlaybackRate?: number;\n playbackRates?: number[];\n};\n\nexport type AudioPlayerState = {\n /** Signals whether the browser can play the record. */\n canPlayRecord: boolean;\n /** Current playback speed. Initiated with the first item of the playbackRates array. */\n currentPlaybackRate: number;\n /** Audio duration in seconds, from descriptor or loaded metadata. */\n durationSeconds?: number;\n /** The audio element ref */\n elementRef: HTMLAudioElement | null;\n /** Signals whether the playback is in progress. */\n isPlaying: boolean;\n /** Keeps the latest playback error reference. */\n playbackError: Error | null;\n /** An array of fractional numeric values of playback speed to override the defaults (1.0, 1.5, 2.0) */\n playbackRates: number[];\n /** Playback progress expressed in percent. */\n progressPercent: number;\n /** Playback progress expressed in seconds. */\n secondsElapsed: number;\n};\n\nexport type AudioPlayerOptions = AudioPlayerDescriptor & {\n /** An array of fractional numeric values of playback speed to override the defaults (1.0, 1.5, 2.0) */\n playbackRates?: number[];\n plugins?: AudioPlayerPlugin[];\n pool: AudioPlayerPool;\n};\n\nconst DEFAULT_PLAYBACK_RATES = [1.0, 1.5, 2.0];\n\nconst isSeekable = (audioElement: HTMLAudioElement) =>\n !(audioElement.duration === Infinity || isNaN(audioElement.duration));\n\nexport const defaultRegisterAudioPlayerError = ({\n error,\n}: RegisterAudioPlayerErrorParams = {}) => {\n if (!error) return;\n console.error('[AUDIO PLAYER]', error);\n};\n\nexport const elementIsPlaying = (audioElement: HTMLAudioElement | null) =>\n audioElement && !(audioElement.paused || audioElement.ended);\n\nexport type SeekFn = (params: {\n clientX: number;\n currentTarget: HTMLDivElement;\n}) => Promise<void>;\n\nexport class AudioPlayer {\n state: StateStore<AudioPlayerState>;\n /** The audio MIME type that is checked before the audio is played. If the type is not supported the controller registers error in playbackError. */\n private _data: AudioPlayerDescriptor;\n private _plugins = new Map<string, AudioPlayerPlugin>();\n private playTimeout: ReturnType<typeof setTimeout> | undefined = undefined;\n private unsubscribeEventListeners: (() => void) | null = null;\n private _pool: AudioPlayerPool;\n private _disposed = false;\n private _pendingLoadedMeta?: { element: HTMLAudioElement; onLoaded: () => void };\n private _elementIsReadyPromise?: Promise<boolean>;\n private _metadataProbe: HTMLAudioElement | null = null;\n private _metadataProbePromise?: Promise<void>;\n private _restoringPosition = false;\n private _removalTimeout: ReturnType<typeof setTimeout> | undefined = undefined;\n\n constructor({\n durationSeconds,\n fileSize,\n id,\n mimeType,\n playbackRates: customPlaybackRates,\n plugins,\n pool,\n src,\n title,\n waveformData,\n }: AudioPlayerOptions) {\n this._data = {\n durationSeconds,\n fileSize,\n id,\n mimeType,\n src,\n title,\n waveformData,\n };\n this._pool = pool;\n this.setPlugins(() => plugins ?? []);\n\n const playbackRates = customPlaybackRates?.length\n ? customPlaybackRates\n : DEFAULT_PLAYBACK_RATES;\n\n // do not create element here; only evaluate canPlayRecord cheaply\n const canPlayRecord = mimeType ? !!new Audio().canPlayType(mimeType) : true;\n\n this.state = new StateStore<AudioPlayerState>({\n canPlayRecord,\n currentPlaybackRate: playbackRates[0],\n durationSeconds,\n elementRef: null,\n isPlaying: false,\n playbackError: null,\n playbackRates,\n progressPercent: 0,\n secondsElapsed: 0,\n });\n\n this.plugins.forEach((p) => p.onInit?.({ player: this }));\n this.preloadMetadata();\n }\n\n private get plugins(): AudioPlayerPlugin[] {\n return Array.from(this._plugins.values());\n }\n\n get canPlayRecord() {\n return this.state.getLatestValue().canPlayRecord;\n }\n\n get elementRef() {\n return this.state.getLatestValue().elementRef;\n }\n\n get isPlaying(): boolean {\n return this.state.getLatestValue().isPlaying;\n }\n\n get currentPlaybackRate() {\n return this.state.getLatestValue().currentPlaybackRate;\n }\n\n get playbackRates() {\n return this.state.getLatestValue().playbackRates;\n }\n\n get durationSeconds() {\n return this.state.getLatestValue().durationSeconds;\n }\n\n get fileSize() {\n return this._data.fileSize;\n }\n\n get id() {\n return this._data.id;\n }\n\n get src() {\n return this._data.src;\n }\n\n get mimeType() {\n return this._data.mimeType;\n }\n\n get title() {\n return this._data.title;\n }\n\n get waveformData() {\n return this._data.waveformData;\n }\n\n get secondsElapsed() {\n return this.state.getLatestValue().secondsElapsed;\n }\n\n get progressPercent() {\n return this.state.getLatestValue().progressPercent;\n }\n\n get disposed() {\n return this._disposed;\n }\n\n private setDurationSeconds = (durationSeconds?: number) => {\n this._data.durationSeconds = durationSeconds;\n this.state.partialNext({ durationSeconds });\n };\n\n private ensureElementRef(): HTMLAudioElement {\n if (this._disposed) {\n throw new Error('AudioPlayer is disposed');\n }\n if (!this.elementRef) {\n const el = this._pool.acquireElement({\n owner: this,\n src: this.src,\n });\n this.setRef(el);\n }\n return this.elementRef as HTMLAudioElement;\n }\n private setPlaybackStartSafetyTimeout = () => {\n clearTimeout(this.playTimeout);\n this.playTimeout = setTimeout(() => {\n if (!this.elementRef) return;\n try {\n this.elementRef.pause();\n this.state.partialNext({ isPlaying: false });\n } catch (e) {\n this.registerError({ errCode: 'failed-to-start' });\n }\n }, 2000);\n };\n\n private updateDurationFromElement = (element: HTMLAudioElement) => {\n const duration = element.duration;\n if (\n typeof duration !== 'number' ||\n isNaN(duration) ||\n !isFinite(duration) ||\n duration <= 0\n ) {\n return;\n }\n this.setDurationSeconds(duration);\n };\n\n private clearMetadataProbe = () => {\n const probe = this._metadataProbe;\n this._metadataProbe = null;\n this._metadataProbePromise = undefined;\n\n if (!probe) return;\n\n try {\n probe.pause();\n } catch {\n // ignore\n }\n\n probe.removeAttribute('src');\n try {\n probe.load();\n } catch {\n // ignore\n }\n };\n\n private preloadMetadata = () => {\n if (\n this._disposed ||\n this.durationSeconds != null ||\n !this.src ||\n this._metadataProbePromise ||\n typeof document === 'undefined'\n ) {\n return;\n }\n\n const probe = document.createElement('audio');\n probe.preload = 'metadata';\n this._metadataProbe = probe;\n this._metadataProbePromise = new Promise((resolve) => {\n const cleanup = () => {\n probe.removeEventListener('loadedmetadata', handleLoadedMetadata);\n probe.removeEventListener('error', handleError);\n if (this._metadataProbe === probe) {\n this.clearMetadataProbe();\n } else {\n this._metadataProbePromise = undefined;\n }\n resolve();\n };\n\n const handleLoadedMetadata = () => {\n this.updateDurationFromElement(probe);\n cleanup();\n };\n\n const handleError = () => {\n cleanup();\n };\n\n probe.addEventListener('loadedmetadata', handleLoadedMetadata, { once: true });\n probe.addEventListener('error', handleError, { once: true });\n probe.src = this.src;\n try {\n probe.load();\n } catch {\n cleanup();\n }\n });\n };\n\n private clearPlaybackStartSafetyTimeout = () => {\n if (!this.elementRef) return;\n clearTimeout(this.playTimeout);\n this.playTimeout = undefined;\n };\n\n private clearPendingLoadedMeta = () => {\n const pending = this._pendingLoadedMeta;\n if (pending?.element && pending.onLoaded) {\n pending.element.removeEventListener('loadedmetadata', pending.onLoaded);\n }\n this._pendingLoadedMeta = undefined;\n };\n\n private restoreSavedPosition = (elementRef: HTMLAudioElement) => {\n const saved = this.secondsElapsed;\n if (!saved || saved <= 0) return;\n const apply = () => {\n const duration = elementRef.duration;\n const clamped =\n typeof duration === 'number' && !isNaN(duration) && isFinite(duration)\n ? Math.min(saved, duration)\n : saved;\n try {\n if (elementRef.currentTime === clamped) return;\n elementRef.currentTime = clamped;\n // Preempt UI with restored position to avoid flicker\n this.setSecondsElapsed(clamped);\n } catch {\n // ignore\n }\n };\n // No information is available about the media resource.\n if (elementRef.readyState < 1) {\n this.clearPendingLoadedMeta();\n this._restoringPosition = true;\n const onLoaded = () => {\n // Ensure this callback still belongs to the same pending registration and same element\n if (this._pendingLoadedMeta?.onLoaded !== onLoaded) return;\n this._pendingLoadedMeta = undefined;\n if (this.elementRef !== elementRef) {\n this._restoringPosition = false;\n return;\n }\n apply();\n this._restoringPosition = false;\n };\n elementRef.addEventListener('loadedmetadata', onLoaded, { once: true });\n this._pendingLoadedMeta = { element: elementRef, onLoaded };\n } else {\n this._restoringPosition = true;\n apply();\n this._restoringPosition = false;\n }\n };\n\n setDescriptor(descriptor: AudioPlayerDescriptor) {\n const previousSrc = this.src;\n this._data = { ...this._data, ...descriptor };\n if (descriptor.src !== previousSrc && this.elementRef) {\n this.elementRef.src = descriptor.src;\n }\n if (descriptor.src && descriptor.src !== previousSrc) {\n this.clearMetadataProbe();\n if (descriptor.durationSeconds == null) {\n this.setDurationSeconds(undefined);\n this.preloadMetadata();\n } else {\n this.setDurationSeconds(descriptor.durationSeconds);\n }\n return;\n }\n if (descriptor.durationSeconds != null) {\n this.setDurationSeconds(descriptor.durationSeconds);\n }\n }\n\n private releaseElement({ resetState }: { resetState: boolean }) {\n this.clearPendingLoadedMeta();\n this.clearMetadataProbe();\n this._restoringPosition = false;\n if (resetState) {\n this.stop();\n } else {\n // Ensure isPlaying reflects reality, but keep progress/seconds\n this.state.partialNext({ isPlaying: false });\n if (this.elementRef) {\n try {\n this.elementRef.pause();\n } catch {\n // ignore\n }\n }\n }\n if (this.elementRef) {\n this._pool.releaseElement(this);\n this.setRef(null);\n }\n }\n\n private elementIsReady = (): Promise<boolean> => {\n if (this._elementIsReadyPromise) return this._elementIsReadyPromise;\n\n this._elementIsReadyPromise = new Promise((resolve) => {\n if (!this.elementRef) return resolve(false);\n const element = this.elementRef;\n const handleLoaded = () => {\n element.removeEventListener('loadedmetadata', handleLoaded);\n resolve(element.readyState > 0);\n };\n element.addEventListener('loadedmetadata', handleLoaded);\n });\n\n return this._elementIsReadyPromise;\n };\n\n private setRef = (elementRef: HTMLAudioElement | null) => {\n if (elementIsPlaying(this.elementRef)) {\n // preserve state during swap\n this.releaseElement({ resetState: false });\n }\n this.clearPendingLoadedMeta();\n this.clearMetadataProbe();\n this._restoringPosition = false;\n this._elementIsReadyPromise = undefined;\n this.state.partialNext({ elementRef });\n // When a new element is attached, make sure listeners are wired to it\n if (elementRef) {\n this.registerSubscriptions();\n }\n };\n\n setSecondsElapsed = (secondsElapsed: number) => {\n const duration = this.elementRef?.duration ?? this.durationSeconds;\n this.state.partialNext({\n progressPercent: duration && secondsElapsed ? (secondsElapsed / duration) * 100 : 0,\n secondsElapsed,\n });\n };\n\n setPlugins(setter: (currentPlugins: AudioPlayerPlugin[]) => AudioPlayerPlugin[]) {\n this._plugins = setter(this.plugins).reduce((acc, plugin) => {\n if (plugin.id) {\n acc.set(plugin.id, plugin);\n }\n return acc;\n }, new Map<string, AudioPlayerPlugin>());\n }\n\n canPlayMimeType = (mimeType: string) => {\n if (!mimeType) return false;\n if (this.elementRef) return !!this.elementRef.canPlayType(mimeType);\n return !!new Audio().canPlayType(mimeType);\n };\n\n play = async (params?: AudioPlayerPlayAudioParams) => {\n if (this._disposed) return;\n const elementRef = this.ensureElementRef();\n if (elementIsPlaying(this.elementRef)) {\n if (this.isPlaying) return;\n this.state.partialNext({ isPlaying: true });\n return;\n }\n\n const { currentPlaybackRate, playbackRates } = {\n currentPlaybackRate: this.currentPlaybackRate,\n playbackRates: this.playbackRates,\n ...params,\n };\n\n if (!this.canPlayRecord) {\n this.registerError({ errCode: 'not-playable' });\n return;\n }\n\n // Restore last known position for this player before attempting to play\n this.restoreSavedPosition(elementRef);\n\n elementRef.playbackRate = currentPlaybackRate ?? this.currentPlaybackRate;\n\n this.setPlaybackStartSafetyTimeout();\n\n try {\n await elementRef.play();\n this.state.partialNext({\n currentPlaybackRate,\n isPlaying: true,\n playbackRates,\n });\n this._pool.setActiveAudioPlayer(this);\n } catch (e) {\n this.registerError({ error: e as Error });\n this.state.partialNext({ isPlaying: false });\n } finally {\n this.clearPlaybackStartSafetyTimeout();\n }\n };\n\n pause = () => {\n if (!elementIsPlaying(this.elementRef)) return;\n this.clearPlaybackStartSafetyTimeout();\n\n // existence of the element already checked by elementIsPlaying\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n this.elementRef!.pause();\n this.state.partialNext({ isPlaying: false });\n };\n\n stop = () => {\n this.pause();\n this.state.partialNext({ isPlaying: false });\n this.setSecondsElapsed(0);\n if (this.elementRef) this.elementRef.currentTime = 0;\n };\n\n togglePlay = async () => (this.isPlaying ? this.pause() : await this.play());\n\n increasePlaybackRate = () => {\n let currentPlaybackRateIndex = this.state\n .getLatestValue()\n .playbackRates.findIndex((rate) => rate === this.currentPlaybackRate);\n if (currentPlaybackRateIndex === -1) {\n currentPlaybackRateIndex = 0;\n }\n const nextIndex =\n currentPlaybackRateIndex === this.playbackRates.length - 1\n ? 0\n : currentPlaybackRateIndex + 1;\n const currentPlaybackRate = this.playbackRates[nextIndex];\n this.state.partialNext({ currentPlaybackRate });\n if (this.elementRef) {\n this.elementRef.playbackRate = currentPlaybackRate;\n }\n };\n\n seek = throttle<SeekFn>(async ({ clientX, currentTarget }) => {\n let element = this.elementRef;\n if (!this.elementRef) {\n element = this.ensureElementRef();\n const isReady = await this.elementIsReady();\n if (!isReady) return;\n }\n if (!currentTarget || !element) return;\n if (!isSeekable(element)) {\n this.registerError({ errCode: 'seek-not-supported' });\n return;\n }\n\n const { width, x } = currentTarget.getBoundingClientRect();\n\n const ratio = (clientX - x) / width;\n if (ratio > 1 || ratio < 0) return;\n const currentTime = ratio * element.duration;\n this.setSecondsElapsed(currentTime);\n element.currentTime = currentTime;\n }, 16);\n\n registerError = (params: RegisterAudioPlayerErrorParams) => {\n defaultRegisterAudioPlayerError(params);\n this.plugins.forEach(({ onError }) => onError?.({ player: this, ...params }));\n };\n\n /**\n * Removes the audio element reference, event listeners and audio player from the player pool.\n * Helpful when only a single AudioPlayer instance is to be removed from the AudioPlayerPool.\n */\n requestRemoval = () => {\n this._disposed = true;\n this.cancelScheduledRemoval();\n this.clearPendingLoadedMeta();\n this.clearMetadataProbe();\n this._restoringPosition = false;\n this.releaseElement({ resetState: true });\n this.unsubscribeEventListeners?.();\n this.unsubscribeEventListeners = null;\n this.plugins.forEach(({ onRemove }) => onRemove?.({ player: this }));\n this._pool.deregister(this.id);\n };\n\n cancelScheduledRemoval = () => {\n clearTimeout(this._removalTimeout);\n this._removalTimeout = undefined;\n };\n\n scheduleRemoval = (ms: number = 0) => {\n this.cancelScheduledRemoval();\n this._removalTimeout = setTimeout(() => {\n if (this.disposed) return;\n this.requestRemoval();\n }, ms);\n };\n\n /**\n * Releases only the underlying element back to the pool without disposing the player instance.\n * Used by the pool to hand off the shared element in single-playback mode.\n */\n releaseElementForHandoff = () => {\n if (!this.elementRef) return;\n this.releaseElement({ resetState: false });\n this.unsubscribeEventListeners?.();\n this.unsubscribeEventListeners = null;\n };\n\n registerSubscriptions = () => {\n this.unsubscribeEventListeners?.();\n\n const audioElement = this.elementRef;\n if (!audioElement) return;\n\n const handleEnded = () => {\n if (audioElement) {\n this.updateDurationFromElement(audioElement);\n }\n this.stop();\n };\n\n const handleError = (e: HTMLMediaElementEventMap['error']) => {\n // if fired probably is one of these (e.srcElement.error.code)\n // 1 = MEDIA_ERR_ABORTED (fetch aborted by user/JS)\n // 2 = MEDIA_ERR_NETWORK (network failed while fetching)\n // 3 = MEDIA_ERR_DECODE (data fetched but couldn’t decode)\n // 4 = MEDIA_ERR_SRC_NOT_SUPPORTED (no resource supported / bad type)\n // reported during the mount so only logging to the console\n const audio = e.currentTarget as HTMLAudioElement | null;\n const state: Partial<AudioPlayerState> = { isPlaying: false };\n\n if (!audio?.error?.code) {\n this.state.partialNext(state);\n return;\n }\n\n if (audio.error.code === 4) {\n state.canPlayRecord = false;\n this.state.partialNext(state);\n }\n\n const errorMsg = [\n undefined,\n 'MEDIA_ERR_ABORTED: fetch aborted by user',\n 'MEDIA_ERR_NETWORK: network failed while fetching',\n 'MEDIA_ERR_DECODE: audio fetched but couldn’t decode',\n 'MEDIA_ERR_SRC_NOT_SUPPORTED: source not supported',\n ][audio?.error?.code];\n if (!errorMsg) return;\n\n defaultRegisterAudioPlayerError({ error: new Error(errorMsg + ` (${audio.src})`) });\n };\n\n const handleTimeupdate = () => {\n const t = audioElement?.currentTime ?? 0;\n // Ignore spurious zero during restore/handoff to avoid UI flicker\n if (this._restoringPosition && t === 0) return;\n // Also avoid regressing UI to zero if we already have non-zero progress and we're not playing\n if (!this.isPlaying && t === 0 && this.secondsElapsed > 0) return;\n this.setSecondsElapsed(t);\n };\n\n const handleLoadedMetadata = () => {\n if (audioElement) {\n this.updateDurationFromElement(audioElement);\n }\n };\n\n audioElement.addEventListener('ended', handleEnded);\n audioElement.addEventListener('error', handleError);\n audioElement.addEventListener('loadedmetadata', handleLoadedMetadata);\n audioElement.addEventListener('timeupdate', handleTimeupdate);\n\n this.unsubscribeEventListeners = () => {\n audioElement.pause();\n audioElement.removeEventListener('ended', handleEnded);\n audioElement.removeEventListener('error', handleError);\n audioElement.removeEventListener('loadedmetadata', handleLoadedMetadata);\n audioElement.removeEventListener('timeupdate', handleTimeupdate);\n };\n };\n}\n","import { StateStore } from '@stream-io/state-store';\nimport type { AudioPlayer } from './AudioPlayer';\n\nexport type AudioPlaybackArbiterState = {\n activeAudioPlayer: AudioPlayer | null;\n};\n\n/**\n * Decides who is allowed to play, across every {@link AudioPlayerPool} that shares it.\n *\n * It owns the single `Audio` element and hands ownership between players: starting one pauses\n * whoever held the element. Exclusivity has to live here rather than in the pool because a pool is\n * scoped to a surface -- `Channel` and `Thread` each mount their own -- and two voice messages\n * playing over each other is exactly what happens when each surface arbitrates for itself.\n *\n * Reusing one element is also what keeps playback working on iOS, where an element must be unlocked\n * by a user gesture before it can be played programmatically.\n */\nexport class AudioPlaybackArbiter {\n state = new StateStore<AudioPlaybackArbiterState>({ activeAudioPlayer: null });\n\n private element: HTMLAudioElement | null = null;\n private owner: AudioPlayer | null = null;\n\n get activeAudioPlayer() {\n return this.state.getLatestValue().activeAudioPlayer;\n }\n\n /**\n * Hands the shared element to `owner`, pausing the previous holder, and loads `src` into it.\n */\n acquire = ({ owner, src }: { owner: AudioPlayer; src: string }) => {\n if (!this.element) {\n this.element = new Audio();\n }\n\n if (this.owner && this.owner !== owner) {\n // Pause and drop the reference, but leave the player registered in its own pool.\n this.owner.pause();\n this.owner.releaseElementForHandoff();\n }\n this.owner = owner;\n\n if (this.element.src !== src) {\n // setting src starts loading; avoid explicit load() to prevent currentTime reset flicker\n this.element.src = src;\n }\n return this.element;\n };\n\n /**\n * Drops `owner`'s claim on the shared element and pauses it. A release from anyone who is not the\n * current holder is ignored, so a player torn down in the background cannot stop the one that has\n * since taken over.\n */\n release = (owner: AudioPlayer) => {\n if (this.owner !== owner) return;\n if (this.element) {\n try {\n this.element.pause();\n } catch {\n // ignore\n }\n this.element.removeAttribute('src');\n this.element.load();\n }\n // Keep the element instance for reuse\n this.owner = null;\n };\n\n setActivePlayer = (activeAudioPlayer: AudioPlayer | null) => {\n this.state.partialNext({ activeAudioPlayer });\n };\n}\n","import { AudioPlayer, type AudioPlayerOptions } from './AudioPlayer';\nimport { AudioPlaybackArbiter } from './AudioPlaybackArbiter';\nimport type { AudioPlaybackArbiterState } from './AudioPlaybackArbiter';\n\nexport type AudioPlayerPoolState = AudioPlaybackArbiterState;\n\nexport type AudioPlayerPoolOptions = {\n /**\n * Decides which player may play, and owns the element they share. Pools given the same arbiter\n * cannot play over each other -- which is how `Channel` and `Thread`, each with their own pool,\n * stay exclusive. Left out, the pool arbitrates alone.\n */\n arbiter?: AudioPlaybackArbiter;\n};\n\nexport class AudioPlayerPool {\n private pool = new Map<string, AudioPlayer>();\n private readonly arbiter: AudioPlaybackArbiter;\n\n constructor({ arbiter }: AudioPlayerPoolOptions = {}) {\n this.arbiter = arbiter ?? new AudioPlaybackArbiter();\n }\n\n /** Playback state is the arbiter's, so every pool sharing one reports the same active player. */\n get state() {\n return this.arbiter.state;\n }\n\n get players() {\n return Array.from(this.pool.values());\n }\n\n get activeAudioPlayer() {\n return this.arbiter.activeAudioPlayer;\n }\n\n getOrAdd = (params: Omit<AudioPlayerOptions, 'pool'>) => {\n const { playbackRates, plugins, ...descriptor } = params;\n let player = this.pool.get(params.id);\n if (player) {\n if (!player.disposed) {\n player.setDescriptor(descriptor);\n return player;\n }\n this.deregister(params.id);\n }\n player = new AudioPlayer({\n playbackRates,\n plugins,\n ...descriptor,\n pool: this,\n });\n this.pool.set(params.id, player);\n return player;\n };\n\n /** @see {@link AudioPlaybackArbiter.acquire} */\n acquireElement = ({ owner, src }: { owner: AudioPlayer; src: string }) =>\n this.arbiter.acquire({ owner, src });\n\n /** @see {@link AudioPlaybackArbiter.release} */\n releaseElement = (owner: AudioPlayer) => this.arbiter.release(owner);\n\n setActiveAudioPlayer = (activeAudioPlayer: AudioPlayer | null) =>\n this.arbiter.setActivePlayer(activeAudioPlayer);\n\n /** Removes the AudioPlayer instance from the pool of players */\n deregister(id: string) {\n if (this.pool.has(id)) {\n this.pool.delete(id);\n }\n if (this.activeAudioPlayer?.id === id) {\n this.setActiveAudioPlayer(null);\n }\n }\n\n /** Performs all the necessary cleanup actions and removes the player from the pool */\n remove = (id: string) => {\n const player = this.pool.get(id);\n if (!player) return;\n player.requestRemoval();\n };\n\n /** Removes and cleans up all the players from the pool */\n clear = () => {\n this.players.forEach((player) => {\n this.remove(player.id);\n });\n };\n\n registerSubscriptions = () => {\n // Only register subscriptions for players that have an attached element -- every other player\n // would otherwise cross-wire listeners onto the shared element it does not currently own.\n this.players.forEach((p) => {\n if (p.elementRef) {\n p.registerSubscriptions();\n }\n });\n };\n}\n","import type { AudioPlayerPlugin } from './AudioPlayerPlugin';\nimport { type AudioPlayerErrorCode } from '../AudioPlayer';\nimport type { AddNotification } from '../../Notifications/hooks/useNotificationApi';\nimport type { NotificationTargetPanel } from '../../Notifications/notificationTarget';\nimport type { StreamTFunction } from '../../../i18n/types';\n\nconst SEEK_NOT_SUPPORTED_NOTIFICATION_DEBOUNCE_INTERVAL_MS = 1000;\n\nexport const audioPlayerNotificationsPluginFactory = ({\n addNotification,\n panel = 'channel',\n t,\n}: {\n addNotification: AddNotification;\n panel?: NotificationTargetPanel;\n t: StreamTFunction;\n}): AudioPlayerPlugin => {\n const errors: Record<AudioPlayerErrorCode, Error> = {\n 'failed-to-start': new Error(\n t(\n 'audioPlayback.audioPlayerNotifications.failedPlayRecording.label',\n 'Failed to play the recording',\n ),\n ),\n 'not-playable': new Error(\n t(\n 'audioPlayback.audioPlayerNotifications.recordingFormatNotSupported.label',\n 'Recording format is not supported and cannot be reproduced',\n ),\n ),\n 'seek-not-supported': new Error(\n t(\n 'audioPlayback.audioPlayerNotifications.cannotSeekRecording.label',\n 'Cannot seek in the recording',\n ),\n ),\n };\n let lastSeekNotSupportedNotificationAt: number | undefined;\n\n return {\n id: 'AudioPlayerNotificationsPlugin',\n onError: ({ errCode, error: e }) => {\n if (errCode === 'seek-not-supported') {\n const now = Date.now();\n\n if (\n typeof lastSeekNotSupportedNotificationAt === 'number' &&\n now - lastSeekNotSupportedNotificationAt <\n SEEK_NOT_SUPPORTED_NOTIFICATION_DEBOUNCE_INTERVAL_MS\n ) {\n return;\n }\n\n lastSeekNotSupportedNotificationAt = now;\n }\n\n const error =\n (errCode && errors[errCode]) ??\n e ??\n new Error(\n t('notification.audioPlaybackError', 'Error reproducing the recording'),\n );\n\n addNotification({\n emitter: 'AudioPlayer',\n error,\n message: error.message,\n severity: 'error',\n targetPanels: [panel],\n type: 'browser:audio:playback:error',\n });\n },\n };\n};\n","import type { AudioPlayer, AudioPlayerState } from '../../AudioPlayback';\nimport { useInteractionAnnouncements } from './useInteractionAnnouncements';\nimport { useStateStore } from '../../../store';\nimport { useEffect, useRef } from 'react';\n\nconst playbackRateSelector = (state: AudioPlayerState) => ({\n currentPlaybackRate: state.currentPlaybackRate,\n});\n\nexport const useAudioPlaybackChangeAnnouncements = (\n audioPlayer: AudioPlayer | undefined,\n) => {\n const { announceInteraction } = useInteractionAnnouncements();\n\n // Announce a playback-speed change to assistive tech. The rate button only changes an icon/label\n // in place, so a screen reader gets no confirmation; announce off the state so it reflects the new\n // rate regardless of which widget's button was pressed (voice recording or audio attachment).\n const { currentPlaybackRate } =\n useStateStore(audioPlayer?.state, playbackRateSelector) ?? {};\n const previousPlaybackRateRef = useRef(currentPlaybackRate);\n useEffect(() => {\n const previous = previousPlaybackRateRef.current;\n previousPlaybackRateRef.current = currentPlaybackRate;\n // Skip the initial value and no-op re-renders; announce only a real change to a defined rate.\n if (\n currentPlaybackRate === undefined ||\n previous === undefined ||\n previous === currentPlaybackRate\n )\n return;\n announceInteraction('audioPlayer.playbackRateChanged', { rate: currentPlaybackRate });\n }, [announceInteraction, currentPlaybackRate]);\n};\n","import React, { useContext, useEffect, useState } from 'react';\nimport type { AudioPlayerOptions } from './AudioPlayer';\nimport type { AudioPlayerPoolState } from './AudioPlayerPool';\nimport { AudioPlayerPool } from './AudioPlayerPool';\nimport { AudioPlaybackArbiter } from './AudioPlaybackArbiter';\nimport { audioPlayerNotificationsPluginFactory } from './plugins/AudioPlayerNotificationsPlugin';\nimport { useNotificationApi, useNotificationTarget } from '../Notifications';\nimport { useTranslationContext } from '../../context';\nimport { useStateStore } from '../../store';\nimport { useAudioPlaybackChangeAnnouncements } from '../Accessibility/hooks/useAudioPlaybackChangeAnnouncements';\n\nexport type WithAudioPlaybackProps = {\n children?: React.ReactNode;\n /**\n * What the playback belongs to. When it changes, everything this provider started is stopped and\n * discarded.\n *\n * Unmounting already does that, but a provider is not always unmounted when its subject changes:\n * `Channel` keeps one mounted across a channel switch (since v15 the subtree is re-rendered, not\n * rebuilt), so without this a voice message from the channel you just left would keep playing.\n *\n * `Thread` passes its thread even though a key on `ThreadInner` happens to remount it today --\n * stating the dependency here is what keeps the cleanup correct if that wrapper is ever removed,\n * which the code already contemplates.\n */\n playbackScope?: unknown;\n};\n\nconst AudioPlayerContext = React.createContext<{ audioPlayers: AudioPlayerPool | null }>({\n audioPlayers: null,\n});\n\n/**\n * The arbiter every pool below shares, so no two surfaces play at once. `Chat` provides one; a\n * `WithAudioPlayback` mounted outside a `Chat` falls back to a pool that arbitrates alone.\n */\nconst SharedAudioPlaybackContext = React.createContext<AudioPlaybackArbiter | null>(null);\n\nexport const SharedAudioPlaybackProvider = ({\n children,\n}: {\n children?: React.ReactNode;\n}) => {\n const [arbiter] = useState(() => new AudioPlaybackArbiter());\n return (\n <SharedAudioPlaybackContext.Provider value={arbiter}>\n {children}\n </SharedAudioPlaybackContext.Provider>\n );\n};\n\nexport const WithAudioPlayback = ({\n children,\n playbackScope,\n}: WithAudioPlaybackProps) => {\n const arbiter = useContext(SharedAudioPlaybackContext);\n const [audioPlayers] = useState(\n () => new AudioPlayerPool({ arbiter: arbiter ?? undefined }),\n );\n\n // Cleanup runs on unmount *and* whenever the scope changes, which is the point: the players\n // belong to the scope, not to this provider's lifetime.\n useEffect(\n () => () => {\n audioPlayers.clear();\n },\n [audioPlayers, playbackScope],\n );\n\n return (\n <AudioPlayerContext.Provider value={{ audioPlayers }}>\n {children}\n </AudioPlayerContext.Provider>\n );\n};\n\nexport type UseAudioPlayerProps = {\n /**\n * Identifier of the entity that requested the audio playback, e.g. message ID.\n * Asset to specific audio player is a many-to-many relationship\n * - one URL can be associated with multiple UI elements,\n * - one UI element can display multiple audio sources.\n * Therefore, the AudioPlayer ID is a combination of request:src.\n *\n * The requester string can take into consideration whether there are multiple instances of\n * the same URL requested by the same requester (message has multiple attachments with the same asset URL).\n * In reality the fact that one message has multiple attachments with the same asset URL\n * could be considered a bad practice or a bug.\n */\n requester?: string;\n} & Partial<Omit<AudioPlayerOptions, 'id' | 'pool'>>;\n\nconst makeAudioPlayerId = ({ requester, src }: { src: string; requester?: string }) =>\n `${requester ?? 'requester-unknown'}:${src}`;\n\nexport const useAudioPlayer = ({\n durationSeconds,\n fileSize,\n mimeType,\n playbackRates,\n plugins,\n requester = '',\n src,\n title,\n waveformData,\n}: UseAudioPlayerProps) => {\n const { addNotification } = useNotificationApi();\n const panel = useNotificationTarget();\n const { t } = useTranslationContext();\n const { audioPlayers } = useContext(AudioPlayerContext);\n\n const audioPlayer =\n src && audioPlayers\n ? audioPlayers.getOrAdd({\n durationSeconds,\n fileSize,\n id: makeAudioPlayerId({ requester, src }),\n mimeType,\n playbackRates,\n plugins,\n src,\n title,\n waveformData,\n })\n : undefined;\n\n useAudioPlaybackChangeAnnouncements(audioPlayer);\n\n useEffect(() => {\n if (!audioPlayer) return;\n /**\n * Avoid having to pass client and translation function to AudioPlayer instances\n * and instead provide plugin that takes care of translated notifications.\n */\n const notificationsPlugin = audioPlayerNotificationsPluginFactory({\n addNotification,\n panel,\n t,\n });\n audioPlayer.setPlugins((currentPlugins) => [\n ...currentPlugins.filter((plugin) => plugin.id !== notificationsPlugin.id),\n notificationsPlugin,\n ]);\n }, [addNotification, audioPlayer, panel, t]);\n\n return audioPlayer;\n};\n\nconst activeAudioPlayerSelector = ({ activeAudioPlayer }: AudioPlayerPoolState) => ({\n activeAudioPlayer,\n});\n\nexport const useActiveAudioPlayer = () => {\n const { audioPlayers } = useContext(AudioPlayerContext);\n const { activeAudioPlayer } =\n useStateStore(audioPlayers?.state, activeAudioPlayerSelector) ?? {};\n return activeAudioPlayer;\n};\n","import type { ReactNode } from 'react';\nimport React from 'react';\nimport ReactMarkdown from 'react-markdown';\nimport type { Channel, LocalMessage, PollVoteResponseData } from 'stream-chat';\nimport { toString as mdastToString } from 'mdast-util-to-string';\nimport remarkParse from 'remark-parse';\nimport { unified } from 'unified';\n\nimport type { ChatContextValue } from '../../context';\nimport { getTranslatedMessageText } from '../../context/MessageTranslationViewContext';\nimport type { TranslationContextValue } from '../../context/TranslationContext';\nimport type { PluggableList } from 'unified';\nimport { htmlToTextPlugin, imageToLink, plusPlusToEmphasis } from '../Message';\nimport { isMessageDeleted } from '../Message/utils';\nimport remarkGfm from 'remark-gfm';\nimport { extractDisplayInfo } from '../Avatar/utils';\n\nconst remarkPlugins: PluggableList = [\n htmlToTextPlugin,\n [remarkGfm, { singleTilde: false }],\n plusPlusToEmphasis,\n imageToLink,\n];\n\nexport const renderPreviewText = (text: string) => (\n <ReactMarkdown remarkPlugins={remarkPlugins} skipHtml>\n {text}\n </ReactMarkdown>\n);\n\n// Strips markdown to plain text for screen-reader announcements, using the SAME remark plugins as\n// the visible preview so the announced text matches what is shown (e.g. \"**hi**\" -> \"hi\"). The\n// processor is built lazily (not at module load) so importing this file never evaluates\n// `remarkPlugins` — mirroring `renderPreviewText`, and avoiding import-time failures in test files\n// that mock the plugin modules. Falls back to the raw text if processing throws.\nconst createPlainTextProcessor = () => unified().use(remarkParse).use(remarkPlugins);\nlet plainTextProcessor: ReturnType<typeof createPlainTextProcessor> | undefined;\n\nconst stripMarkdownToText = (text: string): string => {\n try {\n const processor = (plainTextProcessor ??= createPlainTextProcessor());\n return mdastToString(processor.runSync(processor.parse(text))) || text;\n } catch {\n return text;\n }\n};\n\nconst getLatestPollVote = (\n latestVotesByOption: Record<string, PollVoteResponseData[]>,\n) => {\n let latestVote: PollVoteResponseData | undefined;\n for (const optionVotes of Object.values(latestVotesByOption)) {\n optionVotes.forEach((vote) => {\n if (latestVote && latestVote.updated_at >= vote.created_at) return;\n latestVote = vote;\n });\n }\n\n return latestVote;\n};\n\ntype LatestMessagePreviewKind =\n | 'attachment'\n | 'command'\n | 'deleted'\n | 'empty'\n | 'location'\n | 'poll'\n | 'text';\n\ntype LatestMessagePreviewParts = {\n /**\n * True only for the plain user-message-text branch — the one the display variant renders as\n * markdown (unless AI-generated). Every other branch (deleted/poll/attachment/etc.) is a\n * localized phrase used verbatim.\n */\n isUserMessageText: boolean;\n /** What the latest message is, so consumers can phrase it (display vs. announcement) differently. */\n kind: LatestMessagePreviewKind;\n latestMessage?: LocalMessage;\n /** Poll question, for the `poll` kind. */\n pollName?: string;\n /** The localized DISPLAY preview as a plain string. */\n text: string;\n};\n\n/**\n * Resolves the channel's latest-message preview once: the localized DISPLAY string, a `kind`\n * discriminant, and the bits announcements need (poll question, attachment type). Single source of\n * truth for the display variant ({@link getLatestMessagePreview}) and the announcement variant\n * ({@link getLatestMessagePreviewText}), so the translation lookup and branching run once per call.\n */\nconst getLatestMessagePreviewParts = (\n channel: Channel,\n t: TranslationContextValue['t'],\n userLanguage: TranslationContextValue['userLanguage'] = 'en',\n latestMessageArg?: LocalMessage,\n): LatestMessagePreviewParts => {\n // Prefer an explicitly supplied message so the preview stays consistent with the sender/status/\n // time a caller derives from the same message; fall back to the channel's latest.\n const latestMessage =\n latestMessageArg ??\n channel.messagePaginator.aggregateState.getLatestValue().lastMessage ??\n undefined;\n\n const previewTextToRender =\n getTranslatedMessageText({ language: userLanguage, message: latestMessage }) ||\n latestMessage?.text;\n const poll = latestMessage?.poll;\n\n if (!latestMessage) {\n return {\n isUserMessageText: false,\n kind: 'empty',\n latestMessage,\n text: t('common.nothingYet.text', 'Nothing yet...'),\n };\n }\n\n if (isMessageDeleted(latestMessage)) {\n return {\n isUserMessageText: false,\n kind: 'deleted',\n latestMessage,\n text: t('common.messageDeleted.text', 'Message deleted'),\n };\n }\n\n if (poll) {\n if (!poll.vote_count) {\n const createdBy =\n poll.created_by?.id === channel.getClient().userID\n ? t('common.you.label', 'You')\n : (poll.created_by?.name ?? t('common.poll.label', 'Poll'));\n return {\n isUserMessageText: false,\n kind: 'poll',\n latestMessage,\n pollName: poll.name,\n text: t(\n 'channelListItem.created.text',\n '📊 {{createdBy}} created: {{ pollName}}',\n {\n createdBy,\n pollName: poll.name,\n },\n ),\n };\n } else {\n const latestVote = getLatestPollVote(\n poll.latest_votes_by_option as Record<string, PollVoteResponseData[]>,\n );\n const option =\n latestVote && poll.options.find((opt) => opt.id === latestVote.option_id);\n\n if (option && latestVote) {\n return {\n isUserMessageText: false,\n kind: 'poll',\n latestMessage,\n pollName: poll.name,\n text: t(\n 'channelListItem.voted.text',\n '📊 {{votedBy}} voted: {{pollOptionText}}',\n {\n pollOptionText: option.text,\n votedBy:\n latestVote?.user?.id === channel.getClient().userID\n ? t('common.you.label', 'You')\n : (latestVote.user?.name ?? t('common.poll.label', 'Poll')),\n },\n ),\n };\n }\n }\n }\n\n if (previewTextToRender) {\n return {\n isUserMessageText: true,\n kind: 'text',\n latestMessage,\n text: previewTextToRender,\n };\n }\n\n if (latestMessage.command) {\n return {\n isUserMessageText: false,\n kind: 'command',\n latestMessage,\n text: `/${latestMessage.command}`,\n };\n }\n\n if (latestMessage.attachments?.length) {\n return {\n isUserMessageText: false,\n kind: 'attachment',\n latestMessage,\n text: t('channelListItem.attachment.text', '🏙 Attachment...'),\n };\n }\n\n if (latestMessage.shared_location) {\n return {\n isUserMessageText: false,\n kind: 'location',\n latestMessage,\n text: t('channelListItem.sharedLocation.text', '📍Shared location'),\n };\n }\n\n return {\n isUserMessageText: false,\n kind: 'text',\n latestMessage,\n text: t('common.emptyMessage.text', 'Empty message...'),\n };\n};\n\n/**\n * Maps a known attachment `type` to a localized, human-readable word (e.g. \"image\" → \"Image\"). The\n * cases are literal `t()` calls so the catalog generator sees them -- `i18next-cli` and the `aria/`\n * prefix are both gone. Unknown/custom types return `undefined`, so the announcement falls back to a\n * generic \"Attachment\".\n */\nconst getAttachmentTypeLabel = (\n type: string | undefined,\n t: TranslationContextValue['t'],\n): string | undefined => {\n switch (type) {\n case 'audio':\n return t('channelListItem.audio.ariaLabel', 'audio');\n case 'file':\n return t('channelListItem.file.ariaLabel', 'file');\n case 'giphy':\n return t('channelListItem.gif.ariaLabel', 'GIF');\n case 'image':\n return t('channelListItem.image.ariaLabel', 'image');\n case 'video':\n return t('channelListItem.video.ariaLabel', 'video');\n case 'voiceRecording':\n return t('channelListItem.voiceMessage.ariaLabel', 'voice message');\n default:\n return undefined;\n }\n};\n\n/**\n * The text announced for the channel's latest message (for an accessible name / live region).\n * Non-text content gets a concise, screen-reader-friendly phrasing that may differ from the visible\n * preview: a poll announces its question, an attachment its type, a shared location and a deleted\n * message a plain phrase. User-message text is stripped of markdown so the words are read, not the\n * syntax (AI-generated text is returned verbatim, matching the display path).\n */\nexport const getLatestMessagePreviewText = (\n channel: Channel,\n t: TranslationContextValue['t'],\n userLanguage: TranslationContextValue['userLanguage'] = 'en',\n isMessageAIGenerated?: ChatContextValue['isMessageAIGenerated'],\n latestMessage?: LocalMessage,\n): string => {\n const {\n isUserMessageText,\n kind,\n latestMessage: resolvedLatestMessage,\n pollName,\n text,\n } = getLatestMessagePreviewParts(channel, t, userLanguage, latestMessage);\n\n switch (kind) {\n case 'poll':\n return t('channelListItem.poll.ariaLabel', 'Poll: {{ pollName }}', {\n pollName: pollName ?? '',\n });\n case 'attachment': {\n // Link previews are announced separately (see the `linkPreview` label part); decide by the\n // count of real attachments. Multiple → a generic phrase (the count is announced alongside);\n // a single one → its localized type.\n const realAttachments =\n resolvedLatestMessage?.attachments?.filter(\n (attachment) => !attachment.og_scrape_url,\n ) ?? [];\n if (realAttachments.length > 1)\n return t(\n 'channelListItem.messageAttachments.ariaLabel',\n 'Message with attachments',\n );\n const typeLabel = getAttachmentTypeLabel(realAttachments[0]?.type, t);\n return typeLabel\n ? t(\n 'channelListItem.attachment.withAttachmentType.ariaLabel',\n 'Attachment {{ attachmentType }}',\n { attachmentType: typeLabel },\n )\n : t('channelListItem.attachment.ariaLabel', 'Attachment');\n }\n case 'location':\n return t('channelListItem.sharedLocation.ariaLabel', 'Shared location');\n case 'empty':\n // The visible preview says \"Nothing yet...\"; spell it out for assistive tech.\n return t(\n 'channelListItem.noMessagesChat.ariaLabel',\n 'There are no messages in this chat.',\n );\n case 'text':\n // `resolvedLatestMessage` guard is redundant at runtime (isUserMessageText implies it) but\n // narrows the optional type for `isMessageAIGenerated`.\n return isUserMessageText &&\n resolvedLatestMessage &&\n !isMessageAIGenerated?.(resolvedLatestMessage)\n ? stripMarkdownToText(text)\n : text;\n default:\n // 'deleted' (\"Message deleted\") and 'command' (\"/cmd\") read as-is.\n return text;\n }\n};\n\nexport const getLatestMessagePreview = (\n channel: Channel,\n t: TranslationContextValue['t'],\n userLanguage: TranslationContextValue['userLanguage'] = 'en',\n isMessageAIGenerated?: ChatContextValue['isMessageAIGenerated'],\n latestMessage?: LocalMessage,\n): ReactNode => {\n const {\n isUserMessageText,\n latestMessage: resolvedLatestMessage,\n text,\n } = getLatestMessagePreviewParts(channel, t, userLanguage, latestMessage);\n\n // Only the plain user-message text is rendered as markdown — unless it is AI-generated, which is\n // returned verbatim. Every other branch is a localized phrase used as-is. (guard is redundant at\n // runtime but narrows the optional type for `isMessageAIGenerated`.)\n return isUserMessageText &&\n resolvedLatestMessage &&\n !isMessageAIGenerated?.(resolvedLatestMessage)\n ? renderPreviewText(text)\n : text;\n};\n\nexport type GroupChannelDisplayInfoMember = {\n imageUrl?: string;\n userName?: string;\n};\n\nexport type GroupChannelDisplayInfo = {\n members: GroupChannelDisplayInfoMember[];\n /** When members.length > 4, count for the \"+N\" badge (members.length - 2). */\n overflowCount?: number;\n};\n\n/**\n * Channel display image: channel.data.custom.image, or for DM (2 members) the other member's user.image.\n */\nexport const getChannelDisplayImage = (\n channel: Channel,\n currentUserId?: string,\n): string | undefined => {\n const image = channel.data?.custom?.image;\n if (image && typeof image === 'string') return image;\n\n const memberList = Object.values(channel.state.members);\n if (memberList.length === 2) {\n const other = memberList.find((m) => m.user?.id !== currentUserId);\n const image = other?.user?.image;\n if (image && typeof image === 'string') return image;\n }\n return undefined;\n};\n\nexport const getGroupChannelDisplayInfo = (\n channel: Channel,\n): GroupChannelDisplayInfo | undefined => {\n const members = Object.values(channel.state.members);\n if (members.length <= 2) return;\n\n const memberList: GroupChannelDisplayInfoMember[] = [];\n for (const member of members) {\n const { user } = member;\n\n if (!user?.name && !user?.image) continue;\n\n memberList.push(extractDisplayInfo(member));\n }\n return {\n members: memberList,\n };\n};\n","import type { Channel, LocalMessage, StreamChat } from 'stream-chat';\n\nimport type { ChatContextValue } from '../../context';\nimport type { TranslationContextValue } from '../../context/TranslationContext';\nimport {\n type AccessibleLabelConfig,\n type AccessibleLabelPart,\n activeLabelPart,\n composeAccessibleLabel,\n unreadCountLabelPart,\n} from '../../a11y/accessibleLabel';\nimport { getDateString } from '../../i18n/utils';\nimport { MessageDeliveryStatus } from './hooks/useMessageDeliveryStatus';\nimport { getLatestMessagePreviewText } from './utils';\nimport { convertTimestampToDate } from 'stream-chat';\n\n/**\n * Everything a label part needs. Gathered by `ChannelListItemUI` from its props + contexts and\n * handed to each {@link ChannelListItemLabelPart}.\n */\nexport type ChannelListItemLabelData = {\n /** Whether the row is the active (currently open) channel. */\n active?: boolean;\n /** The channel whose latest message is summarized. */\n channel: Channel;\n /** Client, used to detect whether the latest message is the current user's own. */\n client: StreamChat;\n /** Channel display name. */\n displayTitle?: string;\n isMessageAIGenerated?: ChatContextValue['isMessageAIGenerated'];\n /**\n * The channel's latest message. {@link composeChannelListItemAccessibleLabel} resolves this once\n * (to the last entry of `channel.state.latestMessages` when omitted) and passes the SAME message\n * to every part, so all segments (sender, preview, attachments, time) describe one message.\n */\n latestMessage?: LocalMessage;\n /** Delivery/read status of the latest message when it is the current user's own. */\n messageDeliveryStatus?: MessageDeliveryStatus;\n t: TranslationContextValue['t'];\n tDateTimeParser: TranslationContextValue['tDateTimeParser'];\n /** Unread count for the channel. */\n unreadCount?: number;\n userLanguage?: TranslationContextValue['userLanguage'];\n};\n\n/** Produces one segment of the accessible name; return `undefined`/empty to omit it. */\nexport type ChannelListItemLabelPart = AccessibleLabelPart<ChannelListItemLabelData>;\n\n/**\n * The default, named label parts. Each is independently overridable via\n * {@link ChannelListItemLabelConfig.parts}. The active (currently open) state is announced here (not\n * left to the row's `aria-selected` alone, which is not reliably spoken across screen readers for an\n * option with a custom name); `aria-selected` is kept on the active row for listbox semantics.\n */\nexport const defaultChannelListItemLabelParts = {\n active: activeLabelPart,\n // Announced alongside the last message text: the number of attachments. Link previews are\n // excluded (the linkPreview part announces those). A single attachment with no text is skipped\n // here because the lastMessage part already conveys it as \"Attachment <type>\".\n attachments: ({ latestMessage, t }) => {\n const count =\n latestMessage?.attachments?.filter((attachment) => !attachment.og_scrape_url)\n .length ?? 0;\n if (count === 0 || (count === 1 && !latestMessage?.text)) return undefined;\n return t('channelListItem.attachmentCount.ariaLabel', {\n count,\n defaultValue_one: '{{ count }} attachment',\n defaultValue_other: '{{ count }} attachments',\n });\n },\n deliveryStatus: ({ messageDeliveryStatus, t }) => {\n if (!messageDeliveryStatus) return undefined;\n const statusLabelByStatus: Record<MessageDeliveryStatus, string> = {\n [MessageDeliveryStatus.SENT]: t('channelListItem.sent.ariaLabel', 'Sent'),\n [MessageDeliveryStatus.DELIVERED]: t(\n 'channelListItem.delivered.ariaLabel',\n 'Delivered',\n ),\n [MessageDeliveryStatus.READ]: t('channelListItem.read.ariaLabel', 'Read'),\n };\n return t(\n 'channelListItem.deliveryStatus.ariaLabel',\n 'Delivery status: {{ deliveryStatus }}',\n {\n deliveryStatus: statusLabelByStatus[messageDeliveryStatus],\n },\n );\n },\n lastMessage: ({\n channel,\n client,\n isMessageAIGenerated,\n latestMessage,\n t,\n userLanguage,\n }) => {\n const preview = getLatestMessagePreviewText(\n channel,\n t,\n userLanguage,\n isMessageAIGenerated,\n // `latestMessage` is pre-resolved by the composer, so the announced preview describes the same\n // message as the sender/status/time segments.\n latestMessage,\n );\n // Empty channel: announce there are no messages (\"Nothing yet...\").\n if (!latestMessage) return preview;\n const isOwn = !!client.userID && latestMessage.user?.id === client.userID;\n // Use the sender's name (or \"You\" for the current user). When the name is unknown we omit the\n // sender rather than reading out a raw user id.\n const sender = isOwn ? t('common.you.label', 'You') : latestMessage.user?.name;\n return sender\n ? t(\n 'channelListItem.lastMessage.withSenderAndMessagePreview.ariaLabel',\n 'Last message from {{ sender }}: {{ messagePreview }}',\n {\n messagePreview: preview,\n sender,\n },\n )\n : t(\n 'channelListItem.lastMessage.withMessagePreview.ariaLabel',\n 'Last message: {{ messagePreview }}',\n { messagePreview: preview },\n );\n },\n linkPreview: ({ latestMessage, t }) => {\n const link = latestMessage?.attachments?.find(\n (attachment) => attachment.og_scrape_url,\n );\n if (!link) return undefined;\n return link.title\n ? t(\n 'channelListItem.sharedLinkTitle.ariaLabel',\n 'Shared a link with title: {{ linkTitle }}',\n { linkTitle: link.title },\n )\n : t('channelListItem.sharedLink.ariaLabel', 'Shared a link');\n },\n name: ({ displayTitle }) => displayTitle || undefined,\n time: ({ latestMessage, t, tDateTimeParser }) => {\n const createdAt = latestMessage?.created_at;\n if (createdAt == null) return undefined;\n const when = getDateString({\n messageCreatedAt: convertTimestampToDate(createdAt)?.toISOString(),\n t,\n tDateTimeParser,\n timestampTranslationKey: 'timestamp.ChannelPreviewTimestamp',\n });\n // Prefix the time so it is clearly its own segment (not read as part of the preceding\n // delivery-status segment).\n return when\n ? t('common.lastActivity.ariaLabel', 'Last activity: {{ time }}', {\n time: String(when),\n })\n : undefined;\n },\n unreadCount: unreadCountLabelPart,\n} satisfies Record<string, ChannelListItemLabelPart>;\n\n/** Default order the parts are assembled in (reading order). */\nexport const DEFAULT_CHANNEL_LIST_ITEM_LABEL_ORDER = [\n 'name',\n 'active',\n 'unreadCount',\n 'lastMessage',\n 'attachments',\n 'linkPreview',\n 'deliveryStatus',\n 'time',\n] as const;\n\nexport type ChannelListItemLabelConfig = AccessibleLabelConfig<ChannelListItemLabelData>;\n\n/**\n * Composes a single, coherent accessible name for a channel list row from named parts. The default\n * reading order is name → unread → last message (sender + preview) → delivery status → time.\n *\n * ## Customizing the label\n *\n * The label is generated by `ChannelListItemUI`, which accepts an `accessibleLabelConfig` prop. To\n * customize it, supply your own `ChannelListItemUI` through `ComponentContext` (the same way the\n * component is overridden) and forward the config — no new plumbing:\n *\n * ```tsx\n * const MyChannelPreview = (props) => (\n * <DefaultChannelListItemUI {...props} accessibleLabelConfig={accessibleLabelConfig} />\n * );\n * // <ComponentProvider value={{ ChannelListItemUI: MyChannelPreview }}> … </ComponentProvider>\n * ```\n *\n * ### Adding custom parts (e.g. Pinned, Muted, Frozen)\n *\n * - {@link ChannelListItemLabelConfig.parts} is merged over {@link defaultChannelListItemLabelParts},\n * so a new key is *added* and a same-named key *overrides* the default.\n * - A part returns its segment string, or `undefined`/`''` to be omitted (so e.g. \"Pinned\" is only\n * spoken when actually pinned).\n * - {@link ChannelListItemLabelConfig.order} decides which parts are included AND their sequence —\n * **a part not listed in `order` is never rendered**, even if defined. Spread\n * {@link DEFAULT_CHANNEL_LIST_ITEM_LABEL_ORDER} to keep the defaults and insert your own.\n * - Each part receives {@link ChannelListItemLabelData}. `active`/`unreadCount`/\n * `messageDeliveryStatus` are passed directly and `latestMessage` is pre-resolved by the composer\n * (see its doc); everything else (mute/pin state, `frozen`, member count, custom `channel.data`) is\n * read off `channel`. The SDK does not ship `Pinned`/`Muted`/`Frozen` strings, so return plain\n * strings or your own keys. `t` only accepts keys in {@link TranslationKey}; wrap your own in\n * {@link asDynamicKey} (exported from `stream-chat-react`) and pass the English copy as the\n * second argument, exactly as SDK call sites do.\n *\n * ```tsx\n * const accessibleLabelConfig: ChannelListItemLabelConfig = {\n * parts: {\n * pinned: ({ channel, t }) =>\n * channel.state.membership?.pinned_at\n * ? t(asDynamicKey('myApp.channelList.pinned'), 'Pinned')\n * : undefined,\n * muted: ({ channel, t }) =>\n * channel.muteStatus().muted\n * ? t(asDynamicKey('myApp.channelList.muted'), 'Muted')\n * : undefined,\n * frozen: ({ channel, t }) =>\n * channel.data?.frozen ? t(asDynamicKey('myApp.channelList.frozen'), 'Frozen') : undefined,\n * },\n * order: ['name', 'pinned', 'muted', 'frozen', ...DEFAULT_CHANNEL_LIST_ITEM_LABEL_ORDER.slice(1)],\n * };\n * // → \"General. Pinned. Muted. 3 unread messages. Last message from Alice: hi. 2 days ago\"\n * ```\n *\n * For full control, set {@link ChannelListItemLabelConfig.build} (return the entire string), or\n * write a custom `ChannelListItemUI` that calls this function directly — importing\n * {@link defaultChannelListItemLabelParts} to reuse the built-ins.\n */\nexport const composeChannelListItemAccessibleLabel = (\n data: ChannelListItemLabelData,\n config: ChannelListItemLabelConfig = {},\n): string =>\n composeAccessibleLabel(\n // Resolve the latest message ONCE here so every part is handed the same message (sender,\n // preview, attachments, link, time all stay in sync) instead of each re-deriving the channel's\n // latest — which only stayed consistent as long as the duplicated fallbacks matched.\n {\n ...data,\n latestMessage:\n data.latestMessage ??\n data.channel.messagePaginator.aggregateState.getLatestValue().lastMessage ??\n undefined,\n },\n defaultChannelListItemLabelParts,\n DEFAULT_CHANNEL_LIST_ITEM_LABEL_ORDER,\n config,\n );\n","import { useMemo } from 'react';\nimport type { Attachment, LocalMessage, VoiceRecordingAttachment } from 'stream-chat';\nimport {\n isAudioAttachment,\n isFileAttachment,\n isImageAttachment,\n isScrapedContent,\n isVideoAttachment,\n isVoiceRecordingAttachment,\n} from 'stream-chat';\n\nimport {\n getTranslatedMessageText,\n type TranslationContextValue,\n useChatContext,\n useTranslationContext,\n} from '../../../context';\nimport { isMessageDeleted } from '../../Message/utils';\n\nimport type { MessageDeliveryStatus } from '../../ChannelListItem';\n\nexport type ChannelPreviewMessageType =\n | 'text'\n | 'deleted'\n | 'error'\n | 'empty'\n | 'image'\n | 'giphy'\n | 'video'\n | 'voice'\n | 'file'\n | 'unsupported'\n | 'link'\n | 'location'\n | 'poll';\n\nconst SUPPORTED_VIDEO_FORMATS: string[] = [\n 'video/mp4',\n 'video/ogg',\n 'video/webm',\n 'video/quicktime',\n];\n\n/**\n * Delivery status of the last own message.\n * Determines which delivery status icon to render in the preview.\n *\n * - `sending` — Clock icon\n * - `sent` — Single checkmark icon\n * - `delivered` — Double checkmark icon\n * - `read` — Double checkmark icon (with distinct color)\n */\nexport type ChannelPreviewDeliveryStatus = 'sending' | 'sent' | 'delivered' | 'read';\n\nexport type LatestMessagePreviewData = {\n /**\n * The type of content being previewed.\n * Use this to render the appropriate content-type icon.\n */\n type: ChannelPreviewMessageType;\n /**\n * The preview text to display.\n */\n text: string;\n /**\n * Delivery status of own message.\n * Only present for own messages that are not in error state.\n * Use this to render the delivery status icon (clock, checkmark, double checkmark).\n */\n deliveryStatus?: ChannelPreviewDeliveryStatus;\n /**\n * Sender name prefix.\n * - `\"You\"` (translated) for own messages\n * - Sender's display name for incoming messages in group channels (>2 members)\n * - `undefined` for incoming messages in direct conversations\n */\n senderName?: string;\n};\n\nfunction getAttachmentContentType(attachment: Attachment): ChannelPreviewMessageType {\n if (!attachment) return 'text';\n\n if (attachment.type === 'giphy') return 'giphy';\n if (isScrapedContent(attachment)) return 'link';\n if (isImageAttachment(attachment)) return 'image';\n if (isVideoAttachment(attachment, SUPPORTED_VIDEO_FORMATS)) return 'video';\n if (isVoiceRecordingAttachment(attachment)) return 'voice';\n if (\n isAudioAttachment(attachment) ||\n isFileAttachment(attachment, SUPPORTED_VIDEO_FORMATS)\n ) {\n return 'file';\n }\n\n return 'unsupported';\n}\n\nfunction getAttachmentFallbackText(\n type: ChannelPreviewMessageType,\n count: number,\n t: TranslationContextValue['t'],\n): string {\n switch (type) {\n case 'image':\n return t('messagePreview.latestMessagePreview.imageCount.label', {\n count,\n defaultValue_one: 'Image',\n defaultValue_other: '{{ count }} images',\n });\n case 'video':\n return t('messagePreview.latestMessagePreview.videoCount.label', {\n count,\n defaultValue_one: 'Video',\n defaultValue_other: '{{ count }} videos',\n });\n case 'voice':\n return t('messagePreview.latestMessagePreview.voiceMessageCount.label', {\n count,\n defaultValue_one: 'Voice message',\n defaultValue_other: '{{ count }} voice messages',\n });\n case 'link':\n return t('messagePreview.latestMessagePreview.linkCount.label', {\n count,\n defaultValue_one: 'Link',\n defaultValue_other: '{{ count }} links',\n });\n case 'file':\n return t('messagePreview.latestMessagePreview.fileCount.label', {\n count,\n defaultValue_one: 'File',\n defaultValue_other: '{{ count }} files',\n });\n case 'unsupported':\n return t('common.unsupportedAttachment.text', 'Unsupported attachment');\n default:\n return t('messagePreview.latestMessagePreview.fileCount.label', {\n count,\n defaultValue_one: 'File',\n defaultValue_other: '{{ count }} files',\n });\n }\n}\n\nexport type UseLatestMessagePreviewParams = {\n /** The channel to generate preview for */\n participantCount?: number;\n /** The latest message in the channel */\n latestMessage?: LocalMessage;\n /**\n * Delivery status from the `useMessageDeliveryStatus` hook.\n * When provided, used to determine the delivery status icon.\n * When omitted, delivery status icons are not shown.\n */\n messageDeliveryStatus?: MessageDeliveryStatus;\n};\n\nexport const useLatestMessagePreview = ({\n latestMessage,\n messageDeliveryStatus,\n participantCount,\n}: UseLatestMessagePreviewParams): LatestMessagePreviewData => {\n const { client } = useChatContext();\n const { t, userLanguage } = useTranslationContext();\n\n return useMemo(() => {\n if (!latestMessage) {\n return {\n text: t('common.nothingYet.text', 'Nothing yet...'),\n type: 'empty' as const,\n };\n }\n\n if (latestMessage.status === 'failed' || latestMessage.type === 'error') {\n return {\n text: t(\n 'messagePreview.latestMessagePreview.messageFailedSend.text',\n 'Message failed to send',\n ),\n type: 'error' as const,\n };\n }\n\n const isOwnMessage = latestMessage.user?.id === client.user?.id;\n\n let deliveryStatus: ChannelPreviewDeliveryStatus | undefined;\n if (isOwnMessage) {\n deliveryStatus = messageDeliveryStatus ?? (latestMessage.status as 'sending');\n }\n\n let senderName: string | undefined;\n if (isOwnMessage) {\n senderName = t('common.you.label', 'You');\n } else if (!isOwnMessage && participantCount !== undefined && participantCount > 2) {\n senderName = latestMessage.user?.name || latestMessage.user?.id;\n }\n\n if (isMessageDeleted(latestMessage)) {\n return {\n deliveryStatus,\n senderName,\n text: t('common.messageDeleted.text', 'Message deleted'),\n type: 'deleted' as const,\n };\n }\n\n if (latestMessage.poll) {\n return {\n deliveryStatus,\n senderName,\n text: t('common.poll.label', 'Poll'),\n type: 'poll' as const,\n };\n }\n\n const textContent =\n getTranslatedMessageText({ language: userLanguage, message: latestMessage }) ||\n latestMessage.text;\n\n if (latestMessage.shared_location) {\n return {\n deliveryStatus,\n senderName,\n text: textContent || t('common.location.text', 'Location'),\n type: 'location' as const,\n };\n }\n\n if (latestMessage.attachments && latestMessage.attachments.length) {\n const attachments = latestMessage.attachments;\n\n let contentType: ChannelPreviewMessageType;\n\n const [firstAttachment] = attachments;\n const firstAttachmentType = getAttachmentContentType(firstAttachment);\n\n if (\n attachments.every(\n (attachment) => getAttachmentContentType(attachment) === firstAttachmentType,\n )\n ) {\n contentType = firstAttachmentType;\n } else {\n contentType = 'file';\n }\n\n let text =\n contentType === 'giphy'\n ? `GIPHY ${firstAttachment.title ?? ''}`.trim()\n : // prioritize message text content if available\n textContent ||\n // then fallback text of the single attachment if only one attachment is present and it's not a voice recording (fallback text is generic for voice recordings, so not useful in the preview)\n (attachments.length === 1 &&\n contentType !== 'voice' &&\n contentType !== 'unsupported'\n ? firstAttachment.fallback || firstAttachment.title\n : '') ||\n // then generic fallback text based on attachment type and count\n getAttachmentFallbackText(contentType, attachments.length, t);\n\n // attach duration for audio/video attachments if available\n // `Attachment.custom` is typed as required by the OpenAPI models, but it is not guaranteed\n // at runtime (og-scraped, giphy and custom-integration attachments arrive without it), and\n // this cast is applied to attachments of ANY type - so it must be read defensively.\n const firstAttachmentDuration = (firstAttachment as VoiceRecordingAttachment).custom\n ?.duration;\n if (attachments.length === 1 && typeof firstAttachmentDuration === 'number') {\n const minutes = Math.floor(firstAttachmentDuration / 60);\n const seconds = Math.ceil(firstAttachmentDuration) % 60;\n const durationString = `${minutes}:${seconds.toString().padStart(2, '0')}`;\n text += ` (${durationString})`;\n }\n\n return {\n deliveryStatus,\n senderName,\n text,\n type: contentType,\n };\n }\n\n if (textContent) {\n return {\n deliveryStatus,\n senderName,\n text: textContent,\n type: 'text' as const,\n };\n }\n\n return {\n text: t('common.emptyMessage.text', 'Empty message...'),\n type: 'empty' as const,\n };\n }, [\n client.user?.id,\n latestMessage,\n messageDeliveryStatus,\n participantCount,\n t,\n userLanguage,\n ]);\n};\n","import React from 'react';\nimport clsx from 'clsx';\nimport {\n type ChannelPreviewDeliveryStatus,\n type ChannelPreviewMessageType,\n useLatestMessagePreview,\n type UseLatestMessagePreviewParams,\n} from './hooks/useLatestMessagePreview';\nimport { useComponentContextIcons } from '../../context';\n\n/**\n * Props for {@link SummarizedMessagePreview}. Override the component via `ComponentContext`\n * (`<Chat>`/`<Channel>` prop `SummarizedMessagePreview`) to customize how a channel-list item renders\n * the preview of its latest message.\n */\nexport type SummarizedMessagePreviewProps = UseLatestMessagePreviewParams;\n\nexport const SummarizedMessagePreview = ({\n latestMessage,\n messageDeliveryStatus,\n participantCount,\n}: UseLatestMessagePreviewParams) => {\n const {\n IconCamera,\n IconCheckmark1Small,\n IconChecks,\n IconClock,\n IconExclamationCircleFill,\n IconFile,\n IconGiphy,\n IconLink,\n IconLocation,\n IconNoSign,\n IconUnsupportedAttachment,\n IconVideo,\n IconVoice,\n } = useComponentContextIcons();\n\n const deliveryStatusIconMap: Record<ChannelPreviewDeliveryStatus, React.ComponentType> =\n {\n delivered: IconChecks,\n read: IconChecks,\n sending: IconClock,\n sent: IconCheckmark1Small,\n };\n\n const contentTypeIconMap: Partial<\n Record<ChannelPreviewMessageType, React.ComponentType>\n > = {\n deleted: IconNoSign,\n error: IconExclamationCircleFill,\n file: IconFile,\n giphy: IconGiphy,\n image: IconCamera,\n link: IconLink,\n location: IconLocation,\n unsupported: IconUnsupportedAttachment,\n video: IconVideo,\n voice: IconVoice,\n };\n\n const { deliveryStatus, senderName, text, type } = useLatestMessagePreview({\n latestMessage,\n messageDeliveryStatus,\n participantCount,\n });\n\n const DeliveryStatusIcon = deliveryStatus\n ? deliveryStatusIconMap[deliveryStatus]\n : undefined;\n const ContentTypeIcon = contentTypeIconMap[type];\n\n return (\n <div\n className={clsx('str-chat__summarized-message-preview', {\n [`str-chat__summarized-message-preview--${type}`]: type,\n })}\n >\n {type !== 'error' && (\n <>\n {DeliveryStatusIcon && (\n <span\n className={clsx('str-chat__summarized-message-preview__delivery-status', {\n [`str-chat__summarized-message-preview__delivery-status--${deliveryStatus}`]:\n deliveryStatus,\n })}\n >\n <DeliveryStatusIcon />\n </span>\n )}\n {senderName && (\n <span className='str-chat__summarized-message-preview__sender'>\n {senderName}:\n </span>\n )}\n </>\n )}\n {ContentTypeIcon && <ContentTypeIcon />}\n <span className='str-chat__summarized-message-preview__text'>{text}</span>\n </div>\n );\n};\n","import React, { useMemo, useRef } from 'react';\nimport clsx from 'clsx';\n\nimport { ChannelListItemActionButtons as DefaultChannelListItemActionButtons } from './ChannelListItemActionButtons';\nimport { ChannelListItemTimestamp } from './ChannelListItemTimestamp';\n\nimport { ChannelAvatar as DefaultChannelAvatar } from '../Avatar';\nimport { Badge } from '../Badge';\nimport { useInteractionAnnouncements } from '../Accessibility';\nimport {\n useChatContext,\n useComponentContext,\n useComponentContextIcons,\n useTranslationContext,\n useWorkspaceNavigation,\n} from '../../context';\nimport type { ChannelListItemUIProps } from './ChannelListItem';\nimport { composeChannelListItemAccessibleLabel } from './utils.a11y';\nimport { SummarizedMessagePreview as DefaultSummarizedMessagePreview } from '../SummarizedMessagePreview';\n\nconst UnMemoizedChannelListItemUI = (props: ChannelListItemUIProps) => {\n const { IconMute, IconPin } = useComponentContextIcons();\n const {\n accessibleLabelConfig,\n active,\n channel,\n className: customClassName = '',\n displayImage,\n displayTitle,\n groupChannelDisplayInfo,\n messageDeliveryStatus,\n muted,\n onSelect: customOnSelectChannel,\n pinned,\n previewedMessage,\n unread,\n } = props;\n\n const {\n Avatar = DefaultChannelAvatar,\n ChannelListItemActionButtons = DefaultChannelListItemActionButtons,\n SummarizedMessagePreview = DefaultSummarizedMessagePreview,\n } = useComponentContext();\n const { client, isMessageAIGenerated } = useChatContext();\n const { t, tDateTimeParser, userLanguage } = useTranslationContext();\n const { openChannel } = useWorkspaceNavigation();\n const { announceInteraction } = useInteractionAnnouncements();\n\n const channelPreviewButton = useRef<HTMLButtonElement | null>(null);\n\n // Composed accessible name for the row. Built here (the overridable presentation component) so a\n // `ComponentContext`-supplied `ChannelListItemUI` can configure it via `accessibleLabelConfig`.\n const accessibleLabel = useMemo(\n () =>\n composeChannelListItemAccessibleLabel(\n {\n active,\n channel,\n client,\n displayTitle,\n isMessageAIGenerated,\n latestMessage: previewedMessage,\n messageDeliveryStatus,\n t,\n tDateTimeParser,\n unreadCount: unread,\n userLanguage,\n },\n accessibleLabelConfig,\n ),\n // `muted`/`pinned` are intentional recompute triggers: the parts read\n // `channel.state` / channel mute & membership state (which ESLint can't see and which do not\n // themselves trigger a re-render), so we key on the state ChannelListItem already tracks.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [\n accessibleLabelConfig,\n active,\n channel,\n client,\n displayTitle,\n isMessageAIGenerated,\n messageDeliveryStatus,\n muted,\n pinned,\n previewedMessage,\n t,\n tDateTimeParser,\n unread,\n userLanguage,\n ],\n );\n\n const avatarName = displayTitle || channel.messagePaginator.headmostItem?.user?.id;\n\n const onSelectChannel = (e: React.MouseEvent<HTMLButtonElement>) => {\n if (customOnSelectChannel) {\n customOnSelectChannel(e);\n } else {\n // Selection is one navigation model: open the channel in the workspace. Forward the event so a\n // consumer overriding `openChannel` (e.g. via ChatView's `deriveWorkspaceNavigation`) can honor\n // ⌘/ctrl-click.\n openChannel(channel, { event: e });\n // Confirm the opened channel to assistive tech. Only when actually switching (not re-selecting\n // the open one) and only via the default selection path — a custom `onSelect` owns its own\n // feedback. Debounced in the registry so it lands after the composer's focus announcement.\n if (!active && displayTitle) {\n announceInteraction('channel.opened', { name: displayTitle });\n }\n }\n if (channelPreviewButton?.current) {\n channelPreviewButton.current.blur();\n }\n };\n\n return (\n <div className='str-chat__channel-list-item-container'>\n <button\n aria-label={accessibleLabel}\n // Single-select list: set aria-selected only on the active row. Setting it (false) on every\n // other row makes screen readers announce \"not selected\" on each one — noise.\n aria-selected={active || undefined}\n className={clsx(\n 'str-chat__channel-list-item',\n {\n 'str-chat__channel-list-item--muted': muted,\n 'str-chat__channel-list-item--pinned': pinned,\n 'str-chat__channel-list-item--unread':\n typeof unread === 'number' && unread > 0,\n },\n customClassName,\n )}\n data-testid='channel-list-item-button'\n onClick={onSelectChannel}\n ref={channelPreviewButton}\n role='option'\n >\n <Avatar\n aria-hidden='true'\n displayMembers={groupChannelDisplayInfo?.members}\n imageUrl={displayImage}\n size='xl'\n userName={avatarName}\n />\n <div className='str-chat__channel-list-item-data'>\n <div className='str-chat__channel-list-item-data__first-row'>\n <div className='str-chat__channel-list-item-data__title'>\n <span>{displayTitle || 'N/A'}</span>\n {pinned && <IconPin />}\n {muted && <IconMute />}\n </div>\n <div className='str-chat__channel-list-item-data__timestamp-and-badge'>\n <ChannelListItemTimestamp previewedMessage={previewedMessage} />\n {typeof unread === 'number' && unread > 0 && (\n <Badge data-testid='unread-badge' size='md' variant='primary'>\n {unread}\n </Badge>\n )}\n </div>\n </div>\n <SummarizedMessagePreview\n latestMessage={previewedMessage}\n messageDeliveryStatus={messageDeliveryStatus}\n participantCount={channel.data?.member_count}\n />\n </div>\n </button>\n <ChannelListItemActionButtons />\n </div>\n );\n};\n\n/**\n * Used as preview component for channel item in [ChannelList](#channellist) component.\n * Its best suited for messenger type chat.\n */\nexport const ChannelListItemUI = React.memo(\n UnMemoizedChannelListItemUI,\n) as typeof UnMemoizedChannelListItemUI;\n","import { useEffect, useState } from 'react';\nimport type { Channel } from 'stream-chat';\n\nimport { useChatContext } from '../../../context';\nimport { useTranslationContext } from '../../../context/TranslationContext';\n\n/**\n * 1. channel.data.custom.name\n * 2. DM (exactly 2 members): other member's name, then directMessageLabel\n * 3. Group (3+ members): comma-separated list of 2 other members' names (no ellipsis)\n * 4. undefined otherwise\n */\nfunction computeChannelDisplayName(\n channel: Channel,\n directMessageLabel: string,\n currentUserId: string | undefined,\n): string | undefined {\n const name = channel.data?.custom?.name;\n if (name && typeof name === 'string') return name;\n\n const memberList = Object.values(channel.state.members);\n const otherMembers = memberList.filter((m) => m.user?.id !== currentUserId);\n\n if (memberList.length === 2 && otherMembers.length === 1) {\n const name = otherMembers[0].user?.name;\n return name || directMessageLabel;\n }\n if (otherMembers.length >= 2) {\n const names = otherMembers\n .map((m) => m.user?.name)\n .filter(Boolean)\n .slice(0, 2) as string[];\n if (names.length > 0) return names.join(', ');\n }\n return undefined;\n}\n\n/**\n * Channel display name with translation context.\n * 1. channel.data.custom.name\n * 2. DM (exactly 2 members): other member's name, then translated \"Direct message\"\n * 3. Group (3+ members): comma-separated list of 2 other members' names (no ellipsis)\n * 4. undefined otherwise\n */\nexport const useChannelDisplayName = (\n channel: Channel | undefined,\n): string | undefined => {\n const { client } = useChatContext();\n const { t } = useTranslationContext();\n const directMessageLabel = t(\n 'channelListItem.channelDisplayName.directMessage.label',\n 'Direct message',\n );\n\n const [displayName, setDisplayName] = useState<string | undefined>(() =>\n channel\n ? computeChannelDisplayName(channel, directMessageLabel, client.userID ?? undefined)\n : undefined,\n );\n\n useEffect(() => {\n if (!channel) {\n setDisplayName(undefined);\n return;\n }\n const updateDisplayName = () =>\n setDisplayName(\n computeChannelDisplayName(\n channel,\n directMessageLabel,\n client.userID ?? undefined,\n ),\n );\n updateDisplayName();\n client.on('user.updated', updateDisplayName);\n return () => {\n client.off('user.updated', updateDisplayName);\n };\n }, [channel, channel?.data, client, directMessageLabel]);\n\n return displayName;\n};\n","import { useEffect, useMemo, useState } from 'react';\nimport type { Channel } from 'stream-chat';\n\nimport { useChatContext } from '../../../context';\nimport {\n getChannelDisplayImage,\n getGroupChannelDisplayInfo,\n type GroupChannelDisplayInfo,\n} from '../utils';\nimport { useChannelDisplayName } from './useChannelDisplayName';\n\nconst emptyGroupInfo: GroupChannelDisplayInfo = {\n members: [],\n overflowCount: undefined,\n};\n\nexport type ChannelPreviewInfoParams = {\n /** Channel to read display info from; when undefined, returns undefined display title/image */\n channel?: Channel;\n /** Manually set the image to render, defaults to the Channel image */\n overrideImage?: string;\n /** Set title manually */\n overrideTitle?: string;\n};\n\nexport const useChannelPreviewInfo = (props: ChannelPreviewInfoParams) => {\n const { channel, overrideImage, overrideTitle } = props;\n const { client } = useChatContext();\n\n const channelDisplayName = useChannelDisplayName(channel);\n const displayTitle = overrideTitle ?? channelDisplayName;\n\n const [displayImage, setDisplayImage] = useState<string | undefined>(() =>\n channel\n ? (overrideImage ?? getChannelDisplayImage(channel, client.userID ?? undefined))\n : undefined,\n );\n const [groupChannelDisplayInfo, setGroupChannelDisplayInfo] =\n useState<GroupChannelDisplayInfo>(() =>\n channel ? (getGroupChannelDisplayInfo(channel) ?? emptyGroupInfo) : emptyGroupInfo,\n );\n\n useEffect(() => {\n if (!channel) return;\n if (overrideImage) return;\n\n const updateInfo = () => {\n setDisplayImage(getChannelDisplayImage(channel, client.userID ?? undefined));\n setGroupChannelDisplayInfo(getGroupChannelDisplayInfo(channel) ?? emptyGroupInfo);\n };\n\n updateInfo();\n const { unsubscribe: unsubscribeChannelUpdated } = channel.on(\n 'channel.updated',\n updateInfo,\n );\n const { unsubscribe: unsubscribeUserUpdated } = client.on('user.updated', updateInfo);\n return () => {\n unsubscribeChannelUpdated();\n unsubscribeUserUpdated();\n };\n }, [channel, channel?.data, client, overrideImage]);\n\n return useMemo(\n () => ({\n displayImage: overrideImage ?? displayImage,\n displayTitle,\n groupChannelDisplayInfo,\n }),\n [displayImage, displayTitle, groupChannelDisplayInfo, overrideImage],\n );\n};\n","import throttle from 'lodash.throttle';\nimport React, { useContext, useEffect, useMemo, useState } from 'react';\nimport type { Channel, LocalMessage, MessagePaginatorAggregateState } from 'stream-chat';\n\nimport { useStateStore } from '../../store';\n\nimport { ChannelListItemUI as DefaultChannelListItemUI } from './ChannelListItemUI';\nimport { useIsChannelMuted } from './hooks/useIsChannelMuted';\nimport { useChannelPreviewInfo } from './hooks/useChannelPreviewInfo';\nimport type { MessageDeliveryStatus } from './hooks/useMessageDeliveryStatus';\nimport { useMessageDeliveryStatus } from './hooks/useMessageDeliveryStatus';\nimport type { GroupChannelDisplayInfo } from './utils';\nimport type { ChannelListItemLabelConfig } from './utils.a11y';\nimport {\n useChatContext,\n useComponentContext,\n useWorkspaceNavigation,\n} from '../../context';\nimport { useChannelMembershipState } from '../ChannelList';\nimport { requireContext } from '../../context/requireContext';\n\nexport type ChannelListItemUIProps = ChannelListItemProps & {\n /**\n * Configures the row's composed accessible name (part overrides, order, separator, or a full\n * `build`). Supply it from a `ComponentContext`-provided `ChannelListItemUI` to customize the\n * announcement. See `composeChannelListItemAccessibleLabel`.\n */\n accessibleLabelConfig?: ChannelListItemLabelConfig;\n /** Image of Channel to display */\n displayImage?: string;\n /** Title of Channel to display */\n displayTitle?: string;\n /** Title of Channel to display */\n groupChannelDisplayInfo?: GroupChannelDisplayInfo;\n /** The message previewed by this item — see {@link ChannelListItemProps.previewedMessage}. */\n previewedMessage?: LocalMessage;\n /** Status describing whether own message has been delivered or read by another. If the last message is not an own message, then the status is undefined. */\n messageDeliveryStatus?: MessageDeliveryStatus;\n /** Whether the channel is muted by the current user */\n muted?: boolean;\n /** Whether the channel is pinned by the current user */\n pinned?: boolean;\n /** Number of unread Messages */\n unread?: number;\n};\n\nexport type ChannelListItemProps = {\n /** Comes from either the `channelRenderFilterFn` or `usePaginatedChannels` call from [ChannelList](https://github.com/GetStream/stream-chat-react/blob/master/src/components/ChannelList/ChannelList.tsx) */\n channel: Channel;\n /** If the component's channel is the active (selected) Channel */\n active?: boolean;\n /** Current selected channel object */\n activeChannel?: Channel;\n /** Custom class for the channel preview root */\n className?: string;\n /**\n * The message previewed by this item. Defaults to the channel's reactive latest message\n * (`channel.messagePaginator.aggregateState.lastMessage`); pass a specific message to preview it\n * instead — e.g. a search result previewing the matched message, where the channel's latest message\n * would be misleading.\n */\n previewedMessage?: LocalMessage;\n /** Custom ChannelListItem click handler function */\n onSelect?: (event: React.MouseEvent) => void;\n};\n\nconst ChannelListItemContext = React.createContext<{ channel: Channel } | undefined>(\n undefined,\n);\n\nexport const useChannelListItemContext = () =>\n requireContext(\n useContext(ChannelListItemContext),\n 'useChannelListItemContext',\n 'ChannelListItemUI',\n );\n\nconst lastMessageSelector = ({ lastMessage }: MessagePaginatorAggregateState) => ({\n lastMessage: lastMessage ?? undefined,\n});\n\nexport const ChannelListItem = (props: ChannelListItemProps) => {\n const { active, channel } = props;\n const { ChannelListItemUI = DefaultChannelListItemUI } = useComponentContext();\n const { client } = useChatContext();\n // Active = THIS channel is currently open in the workspace. Keyed on the channel's own\n // cid (never \"the first channel slot\"), so multiple open channels each highlight independently.\n const channelOpenInSlot = useWorkspaceNavigation().isChannelActive(\n channel.cid ?? undefined,\n );\n const { displayImage, displayTitle, groupChannelDisplayInfo } = useChannelPreviewInfo({\n channel,\n });\n const membership = useChannelMembershipState(channel);\n\n const { lastMessage: trackedLastMessage } = useStateStore(\n channel.messagePaginator.aggregateState,\n lastMessageSelector,\n );\n // A caller may override the previewed message per instance (e.g. a search result previewing the\n // matched message); otherwise use the channel's reactive tracked latest.\n const previewedMessage = props.previewedMessage ?? trackedLastMessage;\n\n const { messageDeliveryStatus } = useMessageDeliveryStatus({\n channel,\n lastMessage: previewedMessage,\n });\n\n const isActive = typeof active === 'undefined' ? !!channelOpenInSlot : active;\n const { muted } = useIsChannelMuted(channel);\n\n // The channel already owns this number: `countUnread()` with no argument returns\n // `read[ownUserId].unread_messages`, and everything that moves it - a new message, a read from\n // any device, an explicit mark-unread, a truncation, mark-all-read - writes there first. Reading\n // the store means the guards that come with those writes (a thread read is not a channel read, a\n // read by somebody else is not ours) hold here too, rather than being restated per event.\n const [unreadCount, setUnreadCount] = useState(() => channel.countUnread());\n\n useEffect(() => {\n const ownUserId = client.user?.id;\n // Throttled rather than rendered per change: a backfill or a burst of traffic can move the\n // count many times in a frame, and a badge only has to keep up with the eye. Leading edge, so\n // the first change still lands at once.\n const apply = throttle(setUnreadCount, 400);\n\n const unsubscribe = channel.state.subscribeWithSelector(\n ({ read }) => ({\n unreadCount: ownUserId ? (read[ownUserId]?.unread_messages ?? 0) : 0,\n }),\n ({ unreadCount }) => apply(unreadCount),\n );\n\n return () => {\n apply.cancel();\n unsubscribe();\n };\n }, [channel, client]);\n\n // A muted channel still counts unread; it just does not advertise it. Applied at render rather\n // than inside the subscription so muting and unmuting show up without waiting on the throttle.\n const unread = muted ? 0 : unreadCount;\n\n const channelPreviewContextValue = useMemo(() => ({ channel }), [channel]);\n\n if (!ChannelListItemUI) return null;\n\n return (\n <ChannelListItemContext.Provider value={channelPreviewContextValue}>\n <ChannelListItemUI\n {...props}\n active={isActive}\n displayImage={displayImage}\n displayTitle={displayTitle}\n groupChannelDisplayInfo={groupChannelDisplayInfo}\n messageDeliveryStatus={messageDeliveryStatus}\n muted={muted}\n pinned={membership.pinned_at != null}\n previewedMessage={previewedMessage}\n unread={unread}\n />\n </ChannelListItemContext.Provider>\n );\n};\n","import type { Channel, LocalMessage, StreamChat } from 'stream-chat';\n\nimport type { ChatContextValue } from '../../../context';\nimport type { TranslationContextValue } from '../../../context/TranslationContext';\nimport {\n type AccessibleLabelConfig,\n type AccessibleLabelPart,\n activeLabelPart,\n composeAccessibleLabel,\n unreadCountLabelPart,\n} from '../../../a11y/accessibleLabel';\nimport { getDateString } from '../../../i18n/utils';\nimport { convertTimestampToDate } from 'stream-chat';\n\n/**\n * Everything a label part needs. Gathered by `ThreadListItemUI` from the thread state + contexts and\n * handed to each {@link ThreadListItemLabelPart}.\n */\nexport type ThreadListItemLabelData = {\n /** Whether the row is the active (currently open) thread. */\n active?: boolean;\n /** The channel the thread belongs to. */\n channel?: Channel;\n /** Client, used to detect whether a message is the current user's own. */\n client: StreamChat;\n /** The channel's display name (the thread row's title). */\n displayTitle?: string;\n isMessageAIGenerated?: ChatContextValue['isMessageAIGenerated'];\n /** The most recent reply in the thread. */\n latestReply?: LocalMessage;\n /** The message the thread is attached to (its subject); available for custom parts. */\n parentMessage?: LocalMessage;\n /**\n * The parent message's display preview text — the SAME string the visible subtitle shows (from\n * `useLatestMessagePreview`, covering text/attachment/poll/etc.). Used by the default\n * `parentMessage` part so the announcement matches what is shown.\n */\n parentMessagePreview?: string;\n /** The parent message's sender prefix, when the visible preview shows one (e.g. \"You\", a name). */\n parentMessageSender?: string;\n /** Number of participants in the thread. */\n participantCount?: number;\n /** Number of replies in the thread. */\n replyCount?: number;\n t: TranslationContextValue['t'];\n tDateTimeParser: TranslationContextValue['tDateTimeParser'];\n /** The current user's unread reply count for the thread. */\n unreadCount?: number;\n userLanguage?: TranslationContextValue['userLanguage'];\n};\n\n/** Produces one segment of the accessible name; return `undefined`/empty to omit it. */\nexport type ThreadListItemLabelPart = AccessibleLabelPart<ThreadListItemLabelData>;\n\n/**\n * The default, named label parts. Each is independently overridable via\n * {@link ThreadListItemLabelConfig.parts}. The active (currently open) state is announced here (not\n * left to the row's `aria-selected` alone, which is not reliably spoken across screen readers for an\n * option with a custom name); `aria-selected` is kept on the active row for listbox semantics.\n */\nexport const defaultThreadListItemLabelParts = {\n active: activeLabelPart,\n name: ({ displayTitle, t }) =>\n displayTitle\n ? t('threadList.chat.ariaLabel', 'Chat: {{ channelName }}', {\n channelName: displayTitle,\n })\n : undefined,\n // The message the thread is about (shown as the row's subtitle); same preview the subtitle shows.\n parentMessage: ({ parentMessagePreview, parentMessageSender, t }) => {\n if (!parentMessagePreview) return undefined;\n const preview = parentMessageSender\n ? `${parentMessageSender}: ${parentMessagePreview}`\n : parentMessagePreview;\n return t('threadList.thread.ariaLabel', 'Thread: {{ messagePreview }}', {\n messagePreview: preview,\n });\n },\n replyCount: ({ replyCount, t }) =>\n typeof replyCount === 'number' && replyCount > 0\n ? t('common.replyCount.label', {\n count: replyCount,\n defaultValue_one: '1 reply',\n defaultValue_other: '{{ count }} replies',\n })\n : undefined,\n time: ({ latestReply, t, tDateTimeParser }) => {\n const createdAt = latestReply?.created_at;\n if (createdAt == null) return undefined;\n const when = getDateString({\n messageCreatedAt: convertTimestampToDate(createdAt)?.toISOString(),\n t,\n tDateTimeParser,\n timestampTranslationKey: 'timestamp.ChannelPreviewTimestamp',\n });\n return when\n ? t('common.lastActivity.ariaLabel', 'Last activity: {{ time }}', {\n time: String(when),\n })\n : undefined;\n },\n unreadCount: unreadCountLabelPart,\n} satisfies Record<string, ThreadListItemLabelPart>;\n\n/** Default order the parts are assembled in (reading order). */\nexport const DEFAULT_THREAD_LIST_ITEM_LABEL_ORDER = [\n 'name',\n 'active',\n 'unreadCount',\n 'parentMessage',\n 'replyCount',\n 'time',\n] as const;\n\nexport type ThreadListItemLabelConfig = AccessibleLabelConfig<ThreadListItemLabelData>;\n\n/**\n * Composes a single, coherent accessible name for a thread list row from named parts. The default\n * reading order is name (channel) → active → unread → parent message → reply count → last activity.\n *\n * ## Customizing the label\n *\n * The label is generated by `ThreadListItemUI`, which accepts an `accessibleLabelConfig` prop. To\n * customize it, supply your own `ThreadListItemUI` through `ComponentContext` (the same way the\n * component is overridden) and forward the config — no new plumbing:\n *\n * ```tsx\n * const MyThreadListItemUI = (props) => (\n * <DefaultThreadListItemUI {...props} accessibleLabelConfig={accessibleLabelConfig} />\n * );\n * // <ComponentProvider value={{ ThreadListItemUI: MyThreadListItemUI }}> … </ComponentProvider>\n * ```\n *\n * ### Adding custom parts\n *\n * - {@link ThreadListItemLabelConfig.parts} is merged over {@link defaultThreadListItemLabelParts},\n * so a new key is *added* and a same-named key *overrides* the default.\n * - A part returns its segment string, or `undefined`/`''` to be omitted.\n * - {@link ThreadListItemLabelConfig.order} decides which parts are included AND their sequence —\n * **a part not listed in `order` is never rendered**. Spread\n * {@link DEFAULT_THREAD_LIST_ITEM_LABEL_ORDER} to keep the defaults and insert your own.\n * - Each part receives {@link ThreadListItemLabelData}. Parts call `t`, so provide your own i18n keys\n * (or return plain strings).\n *\n * ```tsx\n * const accessibleLabelConfig: ThreadListItemLabelConfig = {\n * parts: {\n * participants: ({ participantCount, t }) =>\n * participantCount ? t('{{ count }} participants', { count: participantCount }) : undefined,\n * },\n * order: ['name', 'participants', ...DEFAULT_THREAD_LIST_ITEM_LABEL_ORDER.slice(1)],\n * };\n * ```\n *\n * For full control, set {@link ThreadListItemLabelConfig.build} (return the entire string), or write\n * a custom `ThreadListItemUI` that calls this function directly — importing\n * {@link defaultThreadListItemLabelParts} to reuse the built-ins.\n */\nexport const composeThreadListItemAccessibleLabel = (\n data: ThreadListItemLabelData,\n config: ThreadListItemLabelConfig = {},\n): string =>\n composeAccessibleLabel(\n data,\n defaultThreadListItemLabelParts,\n DEFAULT_THREAD_LIST_ITEM_LABEL_ORDER,\n config,\n );\n","import { convertTimestampToDate } from 'stream-chat';\nimport type { ComponentPropsWithoutRef } from 'react';\nimport React, { useCallback, useEffect, useMemo } from 'react';\nimport clsx from 'clsx';\n\nimport type { MessagePaginatorAggregateState, ThreadState } from 'stream-chat';\n\nimport { Timestamp } from '../../Message/Timestamp';\nimport {\n Avatar,\n type AvatarProps,\n AvatarStack as DefaultAvatarStack,\n} from '../../Avatar';\nimport { extractDisplayInfo as defaultExtractDisplayInfo } from '../../Avatar/utils';\nimport { useInteractionAnnouncements } from '../../Accessibility';\nimport { useChannelPreviewInfo } from '../../ChannelListItem';\nimport {\n useChatContext,\n useComponentContext,\n useTranslationContext,\n useWorkspaceNavigation,\n} from '../../../context';\nimport { useThreadListItemContext } from './ThreadListItem';\nimport { useStateStore } from '../../../store';\nimport { Badge } from '../../Badge';\nimport {\n SummarizedMessagePreview,\n useLatestMessagePreview,\n} from '../../SummarizedMessagePreview';\nimport {\n composeThreadListItemAccessibleLabel,\n type ThreadListItemLabelConfig,\n} from './utils.a11y';\n\nexport type ThreadListItemUIProps = ComponentPropsWithoutRef<'button'> & {\n /**\n * Configures the row's composed accessible name (the `aria-label`). Override individual parts, the\n * order, the separator, or supply a full `build`. See `composeThreadListItemAccessibleLabel`.\n */\n accessibleLabelConfig?: ThreadListItemLabelConfig;\n resetHighlighting?: () => void;\n};\n\nexport const ThreadListItemUI = ({\n accessibleLabelConfig,\n resetHighlighting,\n ...props\n}: ThreadListItemUIProps) => {\n const { onClick: onClickFromProps, ...buttonProps } = props;\n const { client, isMessageAIGenerated } = useChatContext();\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n const thread = useThreadListItemContext()!;\n\n const selector = useCallback(\n (nextValue: ThreadState) => ({\n channel: nextValue.channel,\n deletedAt: nextValue.deletedAt,\n ownUnreadMessageCount:\n (client.userID && nextValue.read[client.userID]?.unreadMessageCount) || 0,\n parentMessage: nextValue.parentMessage,\n participants: nextValue.participants,\n replyCount: nextValue.replyCount,\n }),\n [client],\n );\n\n const {\n channel,\n deletedAt,\n ownUnreadMessageCount,\n parentMessage,\n participants,\n replyCount,\n } = useStateStore(thread.state, selector);\n\n // Replies live in the thread's message paginator. The latest reply is tracked on the paginator's\n // `aggregateState` (advanced on every ingest), NOT derived from the pagination `state`: a reply\n // arriving via WS lands in the head interval, which is not the active window here, so the\n // pagination store would not emit. `aggregateState` is written directly on each advance, so this\n // subscription stays reactive.\n const latestReplySelector = useCallback(\n (state: MessagePaginatorAggregateState) => ({ latestReply: state.lastMessage }),\n [],\n );\n\n const { latestReply } = useStateStore(\n thread.messagePaginator.aggregateState,\n latestReplySelector,\n );\n\n const { displayTitle: channelDisplayTitle } = useChannelPreviewInfo({ channel });\n const { t, tDateTimeParser, userLanguage } = useTranslationContext();\n const { announceInteraction } = useInteractionAnnouncements();\n const { isThreadActive, openThread } = useWorkspaceNavigation();\n const {\n AvatarStack = DefaultAvatarStack,\n extractDisplayInfo = defaultExtractDisplayInfo,\n } = useComponentContext();\n const isSelected = isThreadActive(thread.id);\n\n // Reuse the SAME preview the visible subtitle renders (text + sender, all message kinds), so the\n // announced parent message matches what is shown.\n const { senderName: parentMessageSender, text: parentMessagePreview } =\n useLatestMessagePreview({\n latestMessage: parentMessage,\n participantCount: participants?.length,\n });\n\n const accessibleLabel = useMemo(\n () =>\n composeThreadListItemAccessibleLabel(\n {\n active: isSelected,\n channel,\n client,\n displayTitle: channelDisplayTitle,\n isMessageAIGenerated,\n latestReply: latestReply ?? undefined,\n parentMessage: parentMessage ?? undefined,\n parentMessagePreview: parentMessage ? parentMessagePreview : undefined,\n parentMessageSender: parentMessage ? parentMessageSender : undefined,\n participantCount: participants?.length,\n replyCount,\n t,\n tDateTimeParser,\n unreadCount: ownUnreadMessageCount,\n userLanguage,\n },\n accessibleLabelConfig,\n ),\n [\n accessibleLabelConfig,\n channel,\n channelDisplayTitle,\n client,\n isMessageAIGenerated,\n isSelected,\n latestReply,\n ownUnreadMessageCount,\n parentMessage,\n parentMessagePreview,\n parentMessageSender,\n participants,\n replyCount,\n t,\n tDateTimeParser,\n userLanguage,\n ],\n );\n\n const avatarProps: Partial<AvatarProps> | undefined = deletedAt\n ? undefined\n : ({\n imageUrl: latestReply?.user?.image,\n userName: latestReply?.user?.name || latestReply?.user?.id,\n } as const);\n\n const displayInfo = useMemo(() => {\n if (!participants) return [];\n\n return participants.slice(0, 3).map(extractDisplayInfo);\n }, [extractDisplayInfo, participants]);\n\n useEffect(() => {\n if (!resetHighlighting) return;\n\n const reset = resetHighlighting;\n\n const timeout = setTimeout(() => {\n reset();\n }, 2000);\n\n return () => clearTimeout(timeout);\n }, [resetHighlighting]);\n\n return (\n <div className='str-chat__thread-list-item-container'>\n <button\n aria-label={accessibleLabel}\n aria-selected={isSelected}\n className={clsx('str-chat__thread-list-item', {\n 'str-chat__thread-list-item--highlighted':\n typeof resetHighlighting !== 'undefined',\n })}\n data-thread-id={thread.id}\n onClick={(event) => {\n // ⌘/ctrl-click opens the thread beside the current one; a plain click replaces it.\n void openThread(thread, { additive: event.ctrlKey || event.metaKey });\n // Confirm the opened thread to assistive tech, debounced in the registry so it lands after\n // the thread composer's focus announcement rather than competing with it. Skip when the\n // row is already the active thread (re-selecting announces nothing new).\n if (!isSelected && channelDisplayTitle) {\n announceInteraction('thread.opened', { name: channelDisplayTitle });\n }\n onClickFromProps?.(event);\n }}\n role='option'\n {...buttonProps}\n >\n <Avatar size='xl' {...avatarProps} />\n <div className='str-chat__thread-list-item__content'>\n <div className='str-chat__thread-list-item__content-leading'>\n <span className='str-chat__thread-list-item__title'>\n {channelDisplayTitle}\n </span>\n <SummarizedMessagePreview\n latestMessage={parentMessage}\n participantCount={participants?.length}\n />\n </div>\n <div className='str-chat__thread-list-item__content-trailing'>\n <div className='str-chat__thread-list-item__reply-information'>\n <AvatarStack displayInfo={displayInfo} size='sm' />\n <span className='str-chat__thread-list-item__reply-count'>\n {t('common.replyCount.label', {\n count: replyCount,\n defaultValue_one: '1 reply',\n defaultValue_other: '{{ count }} replies',\n })}\n </span>\n </div>\n <Timestamp\n customClass='str-chat__thread-list-item__timestamp'\n timestamp={convertTimestampToDate(latestReply?.created_at)}\n />\n </div>\n </div>\n {ownUnreadMessageCount > 0 && (\n <Badge size='md' variant='primary'>\n {ownUnreadMessageCount}\n </Badge>\n )}\n </button>\n </div>\n );\n};\n","import React, { createContext, useContext } from 'react';\n\nimport type { Thread } from 'stream-chat';\n\nimport { useComponentContext } from '../../../context';\nimport { ThreadListItemUI as DefaultThreadListItemUI } from './ThreadListItemUI';\n\nimport type { ThreadListItemUIProps } from './ThreadListItemUI';\n\nexport type ThreadListItemProps = {\n thread: Thread;\n threadListItemUIProps?: ThreadListItemUIProps;\n};\n\nconst ThreadListItemContext = createContext<Thread | undefined>(undefined);\n\nexport const useThreadListItemContext = () => useContext(ThreadListItemContext);\n\nexport const ThreadListItem = ({\n thread,\n threadListItemUIProps,\n}: ThreadListItemProps) => {\n const { ThreadListItemUI = DefaultThreadListItemUI } = useComponentContext();\n\n return (\n <ThreadListItemContext.Provider value={thread}>\n <ThreadListItemUI {...threadListItemUIProps} />\n </ThreadListItemContext.Provider>\n );\n};\n","import React from 'react';\n\nimport { useComponentContextIcons, useTranslationContext } from '../../../context';\n\nexport const ThreadListEmptyPlaceholder = () => {\n const { IconMessageBubbles } = useComponentContextIcons();\n const { t } = useTranslationContext();\n\n return (\n <div className='str-chat__thread-list-empty-placeholder'>\n <IconMessageBubbles />\n <p>{t('threadList.empty.text', 'Reply to a message to start a thread')}</p>\n </div>\n );\n};\n","import React from 'react';\nimport clsx from 'clsx';\n\nimport type { ThreadManagerState } from 'stream-chat';\n\nimport {\n useChatContext,\n useComponentContextIcons,\n useTranslationContext,\n} from '../../../context';\nimport { useStateStore } from '../../../store';\nimport { LoadingIndicator } from '../../Loading';\n\nconst selector = (nextValue: ThreadManagerState) => ({\n isLoading: nextValue.pagination.isLoading,\n unseenThreadIds: nextValue.unseenThreadIds,\n});\n\nexport const ThreadListUnseenThreadsBanner = () => {\n const { IconRefresh } = useComponentContextIcons();\n const { client } = useChatContext();\n const { t } = useTranslationContext();\n const { isLoading, unseenThreadIds } = useStateStore(client.threads.state, selector);\n\n if (!unseenThreadIds.length) return null;\n\n return (\n <button\n className={clsx('str-chat__unseen-threads-banner', {\n 'str-chat__unseen-threads-banner--loading': isLoading,\n })}\n disabled={isLoading}\n onClick={() => client.threads.reload()}\n >\n {!isLoading && (\n <>\n <IconRefresh />\n <span>\n {t('threadList.unseenBanner.unreadThreads', {\n count: unseenThreadIds.length,\n defaultValue_one: '{{ count }} unread thread',\n defaultValue_other: '{{ count }} unread threads',\n })}\n </span>\n </>\n )}\n {isLoading && (\n <>\n <LoadingIndicator />\n <span>{t('threadList.unseenBanner.loading', 'Loading...')}</span>\n </>\n )}\n </button>\n );\n};\n","import { useEffect, useRef, useState } from 'react';\nimport type { ThreadManager } from 'stream-chat';\n\n/**\n * The threads to flash as newly arrived, as a map of id to a callback that ends the flash.\n *\n * Arrival is taken from the manager's `unseenThreadIds`, which is appended to only when a thread\n * the list does not hold receives a message. Diffing the threads array instead would call every\n * thread that merely *appeared* new -- so the whole first page would flash on load, and so would\n * each page while scrolling, neither of which is an arrival.\n *\n * The ids have to be remembered as they are reported, because `reload()` clears `unseenThreadIds`\n * in the same update that puts those threads into the list: by the time they are on screen the\n * manager no longer calls them unseen.\n */\nexport const useThreadHighlighting = (threadManager: ThreadManager) => {\n const [threadsToHighlight, setThreadsToHighlight] = useState<\n Record<string, () => void>\n >({});\n const awaitingArrival = useRef(new Set<string>());\n\n useEffect(() => {\n const unsubscribeUnseen = threadManager.state.subscribeWithSelector(\n (state) => ({ unseenThreadIds: state.unseenThreadIds }),\n ({ unseenThreadIds }) => {\n unseenThreadIds.forEach((id) => awaitingArrival.current.add(id));\n },\n );\n\n const unsubscribeThreads = threadManager.state.subscribeWithSelector(\n (state) => ({ threads: state.threads }),\n ({ threads }) => {\n if (!awaitingArrival.current.size) return;\n\n const arrived = threads.filter(({ id }) => awaitingArrival.current.has(id));\n if (!arrived.length) return;\n\n arrived.forEach(({ id }) => awaitingArrival.current.delete(id));\n\n // Merged, not replaced: a second arrival while the first is still flashing must not cut\n // the first one short.\n setThreadsToHighlight((current) => {\n const next = { ...current };\n for (const { id } of arrived) {\n next[id] = () =>\n setThreadsToHighlight((pv) => {\n const copy = { ...pv };\n delete copy[id];\n return copy;\n });\n }\n return next;\n });\n },\n );\n\n return () => {\n unsubscribeUnseen();\n unsubscribeThreads();\n };\n }, [threadManager]);\n\n return threadsToHighlight;\n};\n","import React from 'react';\n\nimport type { ThreadManagerState } from 'stream-chat';\n\nimport { LoadingIndicator as DefaultLoadingIndicator } from '../../Loading';\nimport { useChatContext, useComponentContext } from '../../../context';\nimport { useStateStore } from '../../../store';\n\nconst selector = (nextValue: ThreadManagerState) => ({\n isLoadingNext: nextValue.pagination.isLoadingNext,\n});\n\nexport const ThreadListLoadingIndicator = () => {\n const { LoadingIndicator = DefaultLoadingIndicator } = useComponentContext();\n const { client } = useChatContext();\n const { isLoadingNext } = useStateStore(client.threads.state, selector);\n\n if (!isLoadingNext) return null;\n\n return (\n <div className='str-chat__thread-list-loading-indicator'>\n <LoadingIndicator />\n </div>\n );\n};\n","import React from 'react';\nimport {\n useComponentContext,\n useTranslationContext,\n useWorkspaceNavigation,\n} from '../../../context';\n\nexport const ThreadListHeader = () => {\n const { t } = useTranslationContext();\n const { HeaderEndContent } = useComponentContext();\n // A thread is \"active\" when one is open in the workspace.\n const hasActiveThread = useWorkspaceNavigation().openThreads.length > 0;\n return (\n <div className='str-chat__thread-list__header'>\n <div className='str-chat__thread-list__header__title'>\n {t('common.threads.text', 'Threads')}\n </div>\n {hasActiveThread && HeaderEndContent && <HeaderEndContent />}\n </div>\n );\n};\n","import React, { useCallback, useEffect, useRef } from 'react';\nimport type { ComputeItemKey, VirtuosoHandle, VirtuosoProps } from 'react-virtuoso';\nimport { Virtuoso } from 'react-virtuoso';\nimport type { Thread, ThreadManagerState } from 'stream-chat';\n\nimport { useVirtualizedListboxKeyboardNavigation } from '../../../a11y/hooks/useVirtualizedListboxKeyboardNavigation';\nimport { ThreadListItem as DefaultThreadListItem } from './ThreadListItem';\nimport { ThreadListEmptyPlaceholder as DefaultThreadListEmptyPlaceholder } from './ThreadListEmptyPlaceholder';\nimport { ThreadListUnseenThreadsBanner as DefaultThreadListUnseenThreadsBanner } from './ThreadListUnseenThreadsBanner';\nimport { useThreadHighlighting } from './useThreadHighlighting';\nimport { ThreadListLoadingIndicator as DefaultThreadListLoadingIndicator } from './ThreadListLoadingIndicator';\nimport { LoadingChannels } from '../../Loading';\nimport { NotificationList } from '../../Notifications';\nimport {\n useChatContext,\n useComponentContext,\n useTranslationContext,\n} from '../../../context';\nimport { useStateStore } from '../../../store';\nimport { ThreadListHeader } from './ThreadListHeader';\n\nconst selector = (nextValue: ThreadManagerState) => ({\n isLoading: nextValue.pagination.isLoading,\n threads: nextValue.threads,\n});\n\nconst computeItemKey: ComputeItemKey<Thread, unknown> = (_, item) => item.id;\n\ntype ThreadListProps = {\n virtuosoProps?: VirtuosoProps<Thread, unknown>;\n};\n\nexport const useThreadList = () => {\n const { client } = useChatContext();\n\n useEffect(() => {\n // Reset derived pagination inputs before initial reload so the first mount requests\n // the default first page size, rather than a limit inferred from cached/unseen threads.\n const { pagination } = client.threads.state.getLatestValue();\n client.threads.state.partialNext({\n isThreadOrderStale: false,\n pagination: {\n ...pagination,\n nextCursor: null,\n },\n ready: false,\n threads: [],\n unseenThreadIds: [],\n });\n void client.threads.reload({ force: true });\n\n const handleVisibilityChange = () => {\n if (document.visibilityState === 'visible') {\n client.threads.activate();\n }\n if (document.visibilityState === 'hidden') {\n client.threads.deactivate();\n }\n };\n\n handleVisibilityChange();\n\n document.addEventListener('visibilitychange', handleVisibilityChange);\n return () => {\n client.threads.deactivate();\n document.removeEventListener('visibilitychange', handleVisibilityChange);\n };\n }, [client]);\n};\n\nexport const ThreadList = ({ virtuosoProps }: ThreadListProps) => {\n const { client } = useChatContext();\n const { t } = useTranslationContext();\n const {\n NotificationList: NotificationListFromContext = NotificationList,\n ThreadListEmptyPlaceholder = DefaultThreadListEmptyPlaceholder,\n ThreadListItem = DefaultThreadListItem,\n ThreadListLoadingIndicator = DefaultThreadListLoadingIndicator,\n ThreadListUnseenThreadsBanner = DefaultThreadListUnseenThreadsBanner,\n } = useComponentContext();\n const { isLoading, threads } = useStateStore(client.threads.state, selector);\n\n const resetByThreadId = useThreadHighlighting(client.threads);\n\n // Keyboard roving for the thread list (a `role=\"listbox\"` of `role=\"option\"` rows, no row actions\n // → ArrowUp/Down/Home/End only). The list is virtualized, so only a window of rows exists in the\n // DOM at a time; `useVirtualizedListboxKeyboardNavigation` indexes into the full `threads` array\n // and drives Virtuoso's `scrollIntoView` to bring off-window rows into existence before focusing.\n const virtuosoRef = useRef<VirtuosoHandle>(null);\n const scrollerRef = useRef<HTMLElement | null>(null);\n\n const scrollIndexIntoView = useCallback((index: number, onRendered: () => void) => {\n virtuosoRef.current?.scrollIntoView({ done: onRendered, index });\n }, []);\n\n const { onKeyDown } = useVirtualizedListboxKeyboardNavigation({\n getItemId: (thread) => thread.id,\n itemIdAttribute: 'data-thread-id',\n items: threads,\n scrollerRef,\n scrollIndexIntoView,\n });\n\n useThreadList();\n\n if (isLoading && !threads.length) {\n return (\n <div className='str-chat__thread-list-container'>\n <ThreadListHeader />\n <div className='str-chat__thread-list str-chat__thread-list--loading'>\n <LoadingChannels />\n </div>\n </div>\n );\n }\n\n return (\n <div className='str-chat__thread-list-container'>\n <ThreadListHeader />\n {/* TODO: allow re-load on stale ThreadManager state */}\n <ThreadListUnseenThreadsBanner />\n <Virtuoso\n aria-label={t('threadList.threadList.ariaLabel', 'Thread list')}\n atBottomStateChange={(atBottom) => atBottom && client.threads.loadNextPage()}\n className='str-chat__thread-list'\n components={{\n EmptyPlaceholder: ThreadListEmptyPlaceholder,\n Footer: ThreadListLoadingIndicator,\n }}\n computeItemKey={computeItemKey}\n data={threads}\n itemContent={(_, thread) => (\n <ThreadListItem\n thread={thread}\n threadListItemUIProps={{\n resetHighlighting: resetByThreadId[thread.id],\n }}\n />\n )}\n onKeyDown={(event) =>\n onKeyDown(event as unknown as React.KeyboardEvent<HTMLElement>)\n }\n ref={virtuosoRef}\n role='listbox'\n scrollerRef={(el) => {\n scrollerRef.current = el instanceof HTMLElement ? el : null;\n }}\n // TODO: handle visibility (for a button that scrolls to the unread thread)\n // itemsRendered={(items) => console.log({ items })}\n {...virtuosoProps}\n />\n <NotificationListFromContext panel='thread-list' />\n </div>\n );\n};\n","import React, { createContext, useContext } from 'react';\n\nimport type { PropsWithChildren } from 'react';\nimport type {\n LocalMessage,\n Channel as StreamChannel,\n Thread as StreamThread,\n} from 'stream-chat';\n\n/**\n * Target for {@link WorkspaceNavigation.openThread}: an existing thread instance, or the channel +\n * parent message from which one is derived.\n */\nexport type OpenThreadTarget =\n | StreamThread\n | { channel: StreamChannel; message: LocalMessage };\n\n/**\n * A DOM event that may have triggered a workspace navigation. Restricted to the React event types\n * that expose modifier keys (`metaKey`/`ctrlKey`/…) — the reason the event is forwarded at all — so\n * overrides can read them without narrowing. `PointerEvent`, `DragEvent`, and `WheelEvent` extend\n * `MouseEvent` and are accepted through it; `TouchEvent` and `KeyboardEvent` are the other carriers.\n */\nexport type WorkspaceNavigationTriggerEvent =\n | React.MouseEvent\n | React.KeyboardEvent\n | React.TouchEvent;\n\n/** Identifies a panel of the workspace layout (for the slot layout, a slot name). */\nexport type WorkspacePanelId = string;\n\nconst WorkspacePanelContext = createContext<WorkspacePanelId | undefined>(undefined);\n\n/**\n * Declares the panel its subtree renders in. The layout provides it around each panel's content,\n * so controls inside (e.g. a header's back and close buttons) act on their own panel even when the\n * same channel or thread is open in more than one.\n */\nexport const WorkspacePanelProvider = ({\n children,\n panel,\n}: PropsWithChildren<{ panel?: WorkspacePanelId }>) => (\n <WorkspacePanelContext.Provider value={panel}>\n {children}\n </WorkspacePanelContext.Provider>\n);\n\n/** The panel the calling component renders in, or `undefined` outside one. */\nexport const useWorkspacePanel = (): WorkspacePanelId | undefined =>\n useContext(WorkspacePanelContext);\n\n/** Options shared by the workspace navigation operations. */\nexport type WorkspaceNavigationOptions = {\n /**\n * Open *beside* the current content (e.g. ctrl/⌘-click) instead of replacing it, when the active\n * workspace layout has room for a secondary panel. Ignored in single-panel layouts.\n */\n additive?: boolean;\n /**\n * The DOM event that triggered the navigation, when there is one. Forwarded by the SDK components\n * that initiate navigation from a user gesture (channel-list / search-result selection, …) so a\n * consumer overriding these operations (e.g. via `ChatView`'s `deriveWorkspaceNavigation`) can read\n * modifier keys — deciding `additive` from ⌘/ctrl-click — without tracking key state globally.\n */\n event?: WorkspaceNavigationTriggerEvent;\n /**\n * Open *over* the current content as a transient layer instead of replacing it; dismissing the\n * entity restores what was beneath. Ignored by layouts that do not support layering.\n */\n layer?: boolean;\n /**\n * The panel the operation is triggered from (see {@link WorkspacePanelProvider}). Resolves which\n * panel an entity is in when the same channel or thread is open in more than one; without it, the\n * first panel showing the entity is used.\n */\n panel?: WorkspacePanelId;\n};\n\n/**\n * Slot-agnostic, intent-level navigation abstraction that core components depend on instead of the\n * ChatView slot system (D1). The `slot-layout` plugin implements it over its layout controller; with\n * no plugin installed the default is an inert no-op (D2) — core renders, navigation does nothing.\n */\nexport type WorkspaceNavigation = {\n /**\n * Whether the panel showing the channel or thread with `key` (a channel's `cid`, a thread's id)\n * is stacked over other content that {@link WorkspaceNavigation.goBack} would reveal.\n */\n canGoBack: (key?: string, panel?: WorkspacePanelId) => boolean;\n /**\n * Dismiss the channel with `cid` from the workspace: close the panel showing it, together with\n * anything stacked beneath it. Accepts the triggering event (see\n * {@link WorkspaceNavigationOptions.event}).\n */\n closeChannel: (cid?: string, options?: WorkspaceNavigationOptions) => void;\n /**\n * Dismiss a thread from the workspace. With `threadId`, dismiss that thread's panel — together\n * with anything stacked beneath it — otherwise the active thread panel. Does not deactivate the\n * thread instance — the caller owns that. Accepts the triggering event (see\n * {@link WorkspaceNavigationOptions.event}).\n */\n closeThread: (threadId?: string, options?: WorkspaceNavigationOptions) => void;\n /**\n * Step back from the channel or thread with `key`: remove it from the panel, revealing what it is\n * stacked over. No-op when {@link WorkspaceNavigation.canGoBack} is false. Accepts the triggering\n * event (see {@link WorkspaceNavigationOptions.event}).\n */\n goBack: (key?: string, options?: WorkspaceNavigationOptions) => void;\n /**\n * Whether the channel with `cid` is shown in the workspace: open in a panel and not covered by\n * something stacked over it there.\n */\n isChannelActive: (cid?: string) => boolean;\n /**\n * Whether the channel panel for `cid` can be dismissed by the user — i.e. it is a secondary\n * panel opened beside another channel, rather than the primary channel surface.\n */\n isChannelDismissable: (cid?: string, panel?: WorkspacePanelId) => boolean;\n /**\n * Whether the thread with `threadId` is shown in the workspace: open in a panel and not covered by\n * something stacked over it there.\n */\n isThreadActive: (threadId?: string) => boolean;\n /**\n * Whether the thread panel for `threadId` (or the active thread) can be dismissed by the user —\n * i.e. it is a closable side/secondary panel rather than the primary thread surface.\n */\n isThreadDismissable: (threadId?: string, panel?: WorkspacePanelId) => boolean;\n /** Whether the thread-list (\"threads\") workspace view is the active one. */\n isThreadsView: boolean;\n /** Open `channel` in the workspace. */\n openChannel: (channel: StreamChannel, options?: WorkspaceNavigationOptions) => void;\n /** Channels currently open in the workspace (empty when none / no plugin). */\n openChannels: StreamChannel[];\n /** Open a thread — by instance, or derived from `{ channel, message }`. */\n openThread: (target: OpenThreadTarget, options?: WorkspaceNavigationOptions) => void;\n /** Threads currently open in the workspace (empty when none / no plugin). */\n openThreads: StreamThread[];\n};\n\nconst NOOP_OPEN_CHANNELS: WorkspaceNavigation['openChannels'] = [];\nconst NOOP_OPEN_THREADS: WorkspaceNavigation['openThreads'] = [];\n\n/** Inert no-op default (D2): used when no `slot-layout` plugin provides an implementation. */\nexport const defaultWorkspaceNavigation: WorkspaceNavigation = {\n canGoBack: () => false,\n closeChannel: () => undefined,\n closeThread: () => undefined,\n goBack: () => undefined,\n isChannelActive: () => false,\n isChannelDismissable: () => false,\n isThreadActive: () => false,\n isThreadDismissable: () => false,\n isThreadsView: false,\n openChannel: () => undefined,\n openChannels: NOOP_OPEN_CHANNELS,\n openThread: () => undefined,\n openThreads: NOOP_OPEN_THREADS,\n};\n\nconst WorkspaceNavigationContext = createContext<WorkspaceNavigation>(\n defaultWorkspaceNavigation,\n);\n\nexport const WorkspaceNavigationProvider = ({\n children,\n value,\n}: PropsWithChildren<{ value: WorkspaceNavigation }>) => (\n <WorkspaceNavigationContext.Provider value={value}>\n {children}\n </WorkspaceNavigationContext.Provider>\n);\n\n/**\n * Access the workspace navigation abstraction. Returns the inert no-op default outside a\n * `slot-layout` provider, so callers can navigate unconditionally without guarding for a provider.\n */\nexport const useWorkspaceNavigation = (): WorkspaceNavigation =>\n useContext(WorkspaceNavigationContext);\n","export const CHANNEL_CONTAINER_ID = 'str-chat__channel';\n","import { useChatContext } from '../../../context/ChatContext';\nimport type { ChatContextValue } from '../../../context/ChatContext';\n\nexport const useImageFlagEmojisOnWindowsClass = () => {\n const { useImageFlagEmojisOnWindows } = useChatContext();\n return useImageFlagEmojisOnWindows && navigator.userAgent.match(/Win/)\n ? 'str-chat--windows-flags'\n : '';\n};\n\nexport const getChatContainerClass = (customClass?: string) =>\n customClass ?? 'str-chat__container';\n\nexport const useChannelContainerClasses = ({\n customClasses,\n}: Pick<ChatContextValue, 'customClasses'>) => {\n const windowsEmojiClass = useImageFlagEmojisOnWindowsClass();\n return {\n channelClass: customClasses?.channel ?? 'str-chat__channel',\n chatClass: customClasses?.chat ?? 'str-chat',\n chatContainerClass: getChatContainerClass(customClasses?.chatContainer),\n windowsEmojiClass,\n };\n};\n","import type { ComponentProps, PropsWithChildren } from 'react';\nimport React, { useEffect, useMemo } from 'react';\nimport clsx from 'clsx';\nimport type { Channel as StreamChannel } from 'stream-chat';\n\nimport { ChannelInstanceProvider, useChatContext } from '../../context';\n\nimport { CHANNEL_CONTAINER_ID } from './constants';\nimport { DEFAULT_NEXT_CHANNEL_PAGE_SIZE } from '../../constants/limits';\n\nimport {\n useChannelContainerClasses,\n useImageFlagEmojisOnWindowsClass,\n} from './hooks/useChannelContainerClasses';\nimport { WithAudioPlayback } from '../AudioPlayback';\n\nexport type ChannelProps = {\n /**\n * The channel to bind this subtree to. Required -- render `<ChannelPlaceholder />` (or nothing)\n * while none is selected. Initialize it before passing it in; `Channel` does not query.\n */\n channel: StreamChannel;\n};\n\n/**\n * The channel's content column (`.str-chat__channel`) with no channel bound, for filling the same\n * layout slot while none is selected.\n */\nexport const ChannelPlaceholder = ({\n children,\n className: additionalClassName,\n ...props\n}: PropsWithChildren<ComponentProps<'div'>>) => {\n const { customClasses, theme } = useChatContext();\n const { channelClass, chatClass } = useChannelContainerClasses({\n customClasses,\n });\n const className = clsx(chatClass, theme, channelClass, additionalClassName);\n return (\n <div id={CHANNEL_CONTAINER_ID} {...props} className={className}>\n {children}\n </div>\n );\n};\n\n// One component: `channel` is required and nothing is keyed, so there is no early return needing a\n// wrapper to sit in front of the hooks.\nexport const Channel = (props: PropsWithChildren<ChannelProps>) => {\n const { channel, children } = props;\n\n const { client } = useChatContext();\n const windowsEmojiClass = useImageFlagEmojisOnWindowsClass();\n\n // Claim the channel while mounted (refcounted, so several consumers are fine). The client skips\n // re-seeding an active channel's message list on hydration, leaving the larger loaded window to\n // `channel.reload()`.\n useEffect(() => {\n channel.activate();\n return () => {\n channel.deactivate();\n };\n }, [channel]);\n\n // Keyed on the instance, not the cid: children subscribe to *this* channel's stores.\n const channelInstanceContextValue = useMemo(() => ({ channel }), [channel]);\n\n useEffect(() => {\n // Re-seed the unread boundary the separator and \"N new\" banner render from: a cached channel\n // is not re-queried on reopen, so the LLC's auto-seed never runs and the boundary would be\n // stale. Skipped when the channel is deliberately flagged unread, since seeding clears that\n // flag. Marking read is `useMarkRead`'s job, not this one's.\n if (\n !channel.messagePaginator.unreadStateSnapshot.getLatestValue().firstUnreadMessageId\n ) {\n channel.messagePaginator.seedUnreadSnapshot();\n }\n\n // One subscription per event, each released by its own handle, so subscribing and\n // unsubscribing cannot drift apart and nothing has to filter events it never asked for.\n const subscriptions = [\n // Channel state is not normalized, so rather than hunting this user's references through it\n // we re-query. Note what that does and does not do: it refreshes members, read state and\n // watchers, but not the loaded messages -- the page it asks for is older than the window.\n // todo: remove with REACT-1175 (single source of truth for user references)\n client.on('user.deleted', async () => {\n const oldestID = channel.messagePaginator.items?.[0]?.id;\n\n await channel.query({\n messages: { id_lt: oldestID, limit: DEFAULT_NEXT_CHANNEL_PAGE_SIZE },\n watchers: { limit: DEFAULT_NEXT_CHANNEL_PAGE_SIZE },\n });\n }),\n ];\n\n return () => {\n subscriptions.forEach((subscription) => subscription.unsubscribe());\n };\n }, [channel, client]);\n\n return (\n <ChannelPlaceholder className={windowsEmojiClass}>\n <ChannelInstanceProvider value={channelInstanceContextValue}>\n <WithAudioPlayback playbackScope={channel}>{children}</WithAudioPlayback>\n </ChannelInstanceProvider>\n </ChannelPlaceholder>\n );\n};\n","import React, { useCallback, useEffect } from 'react';\nimport type { PropsWithChildren } from 'react';\n\nimport { WithAudioPlayback } from '../AudioPlayback';\n\nimport { useChatContext } from '../../context';\nimport { ThreadProvider } from '../Threads';\nimport { useStateStore } from '../../store';\n\nimport type {\n LocalMessage,\n Thread as StreamThread,\n ThreadManagerState,\n ThreadState,\n} from 'stream-chat';\nimport type { ChannelConfig } from 'stream-chat';\n\nconst repliesStateSelector = ({ replies }: ChannelConfig) => ({\n repliesEnabled: replies.enabled,\n});\n\nexport type ThreadProps = PropsWithChildren<{\n /**\n * The thread to render. Initialize it before passing it in; `Thread` does not query for it --\n * it loads the replies of a thread the `ThreadManager` does not already hold.\n */\n thread: StreamThread;\n}>;\n\nconst selector = ({ isStateStale, parentMessage, replyCount }: ThreadState) => ({\n // A thread exists server-side only once its parent has a reply. Selected as a boolean so the\n // panel does not re-render on every incoming reply -- only on the transition that matters.\n hasServerSideThread: replyCount > 0,\n isStateStale,\n parentMessage,\n});\n\n// Same reasoning: the effects below only ask whether the replies have loaded, never what they are.\nconst messagePaginatorSelector = ({\n isLoading,\n items,\n lastQueryError,\n}: {\n isLoading: boolean;\n items: LocalMessage[] | undefined;\n lastQueryError?: Error;\n}) => ({\n hasLoadedReplies: items !== undefined,\n isLoading,\n lastQueryError,\n});\n\n/**\n * The container for a thread panel: it provides the thread to its subtree, loads it, registers it\n * with the `ThreadManager`, scopes audio playback to it, and renders whatever you compose inside.\n *\n * It renders no UI of its own, the way `Channel` does not -- put the parts you want in as\n * children, and their own props say how they behave:\n *\n * ```tsx\n * <Thread thread={thread}>\n * <ThreadHeader />\n * <MessageList withDateSeparator={false} />\n * <MessageComposer focus />\n * </Thread>\n * ```\n *\n * The parent message is not composed here: a message list renders it above its replies (see\n * `useThreadHead`), because it has to sit inside the list's scroll container.\n *\n * One component: the wrapper that used to sit here existed only to key this subtree on the thread,\n * which rebuilt everything below on a thread switch -- including parts that hold no per-thread\n * state. The reset now lives in the message list, which is what actually carries state scoped to\n * the replies it shows.\n */\nexport const Thread = ({ children, thread }: ThreadProps) => {\n const { client, customClasses } = useChatContext();\n const { repliesEnabled } = useStateStore(\n thread.channel.configState,\n repliesStateSelector,\n );\n // `hasServerSideThread`: reloading a thread whose parent has no reply yet can only 404 --\n // `Thread.reload()` swallows that and returns without state.\n //\n // Deferred, not cancelled: only a successful reload clears `isStateStale`, so a thread that\n // stays stale reloads via the effect below as soon as the parent reports its first reply -- the\n // same moment the rest of the UI learns about replies missed while unwatched.\n const { hasServerSideThread, isStateStale, parentMessage } = useStateStore(\n thread.state,\n selector,\n );\n const { hasLoadedReplies, isLoading, lastQueryError } = useStateStore(\n thread.messagePaginator.state,\n messagePaginatorSelector,\n );\n\n const isThreadManagedSelector = useCallback(\n ({ threads }: ThreadManagerState) => ({\n isThreadManaged: threads.some((managedThread) => managedThread.id === thread.id),\n }),\n [thread.id],\n );\n const { isThreadManaged } = useStateStore(\n client.threads.state,\n isThreadManagedSelector,\n );\n\n // Only an unmanaged thread is loaded here. The `ThreadManager` already loads and refreshes the\n // ones it holds; an instance from `getThreadAndHydrate()` is registered nowhere, so it has no\n // other owner.\n useEffect(() => {\n if (isThreadManaged) return;\n if (!hasServerSideThread) return;\n if (hasLoadedReplies || isLoading) return;\n void thread.reload();\n }, [hasLoadedReplies, hasServerSideThread, isLoading, isThreadManaged, thread]);\n\n // Deliberately a separate effect rather than a branch of the one above: catching up a stale\n // thread depends on `isStateStale` alone, so it fires once per staleness episode. Merged in, it\n // would also re-run whenever the load branch's inputs change -- registering the thread flips\n // `isThreadManaged`, which would request a second reload while the first is still in flight.\n useEffect(() => {\n if (isStateStale && hasServerSideThread) {\n void thread.reload();\n }\n }, [hasServerSideThread, isStateStale, thread]);\n\n useEffect(() => {\n if (isThreadManaged) return;\n if (isLoading) return;\n if (lastQueryError) return;\n if (!hasLoadedReplies) return;\n\n client.threads.state.next((current) => {\n if (current.threads.some((managedThread) => managedThread.id === thread.id)) {\n return current;\n }\n return {\n ...current,\n threads: [thread, ...current.threads],\n };\n });\n }, [\n client.threads.state,\n hasLoadedReplies,\n isLoading,\n isThreadManaged,\n lastQueryError,\n thread,\n ]);\n\n if (!parentMessage || repliesEnabled === false) return null;\n\n // The thread owns its audio-player pool (rather than inheriting one from an ambient <Channel>)\n // because a slot-bound Thread is a sibling of the channel, not nested inside it. Scoping it here\n // means thread audio stops when the thread closes.\n return (\n <div\n className={customClasses?.thread || 'str-chat__thread-container str-chat__thread'}\n >\n <ThreadProvider thread={thread}>\n <WithAudioPlayback playbackScope={thread}>{children}</WithAudioPlayback>\n </ThreadProvider>\n </div>\n );\n};\n"],"mappings":"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"}