stream-chat-react-native-core 9.1.3-beta.2 → 9.2.0-beta.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 (315) hide show
  1. package/lib/commonjs/a11y/a11yUtils.js +40 -0
  2. package/lib/commonjs/a11y/a11yUtils.js.map +1 -0
  3. package/lib/commonjs/a11y/hooks/useA11yLabel.js +15 -0
  4. package/lib/commonjs/a11y/hooks/useA11yLabel.js.map +1 -0
  5. package/lib/commonjs/a11y/hooks/useAnnounceOnStateChange.js +36 -0
  6. package/lib/commonjs/a11y/hooks/useAnnounceOnStateChange.js.map +1 -0
  7. package/lib/commonjs/a11y/hooks/useReducedMotionPreference.js +34 -0
  8. package/lib/commonjs/a11y/hooks/useReducedMotionPreference.js.map +1 -0
  9. package/lib/commonjs/a11y/hooks/useResolvedModalAccessibilityProps.js +20 -0
  10. package/lib/commonjs/a11y/hooks/useResolvedModalAccessibilityProps.js.map +1 -0
  11. package/lib/commonjs/a11y/hooks/useScreenReaderEnabled.js +37 -0
  12. package/lib/commonjs/a11y/hooks/useScreenReaderEnabled.js.map +1 -0
  13. package/lib/commonjs/a11y/index.js +70 -0
  14. package/lib/commonjs/a11y/index.js.map +1 -0
  15. package/lib/commonjs/components/AITypingIndicatorView/AITypingIndicatorView.js +10 -0
  16. package/lib/commonjs/components/AITypingIndicatorView/AITypingIndicatorView.js.map +1 -1
  17. package/lib/commonjs/components/Accessibility/NotificationAnnouncer.js +37 -0
  18. package/lib/commonjs/components/Accessibility/NotificationAnnouncer.js.map +1 -0
  19. package/lib/commonjs/components/Accessibility/hooks/useIncomingMessageAnnouncements.js +109 -0
  20. package/lib/commonjs/components/Accessibility/hooks/useIncomingMessageAnnouncements.js.map +1 -0
  21. package/lib/commonjs/components/Accessibility/index.js +37 -0
  22. package/lib/commonjs/components/Accessibility/index.js.map +1 -0
  23. package/lib/commonjs/components/Accessibility/useAccessibilityAnnouncer.js +15 -0
  24. package/lib/commonjs/components/Accessibility/useAccessibilityAnnouncer.js.map +1 -0
  25. package/lib/commonjs/components/Channel/Channel.js +2 -1
  26. package/lib/commonjs/components/Channel/Channel.js.map +1 -1
  27. package/lib/commonjs/components/ChannelPreview/ChannelMessagePreviewDeliveryStatus.js +4 -0
  28. package/lib/commonjs/components/ChannelPreview/ChannelMessagePreviewDeliveryStatus.js.map +1 -1
  29. package/lib/commonjs/components/Indicators/LoadingDots.js +2 -0
  30. package/lib/commonjs/components/Indicators/LoadingDots.js.map +1 -1
  31. package/lib/commonjs/components/Indicators/LoadingErrorIndicator.js +3 -0
  32. package/lib/commonjs/components/Indicators/LoadingErrorIndicator.js.map +1 -1
  33. package/lib/commonjs/components/Indicators/LoadingIndicator.js +2 -0
  34. package/lib/commonjs/components/Indicators/LoadingIndicator.js.map +1 -1
  35. package/lib/commonjs/components/MessageList/MessageList.js +13 -6
  36. package/lib/commonjs/components/MessageList/MessageList.js.map +1 -1
  37. package/lib/commonjs/components/MessageList/ScrollToBottomButton.js +5 -0
  38. package/lib/commonjs/components/MessageList/ScrollToBottomButton.js.map +1 -1
  39. package/lib/commonjs/components/MessageMenu/MessageActionList.js +4 -1
  40. package/lib/commonjs/components/MessageMenu/MessageActionList.js.map +1 -1
  41. package/lib/commonjs/components/MessageMenu/MessageActionListItem.js +1 -0
  42. package/lib/commonjs/components/MessageMenu/MessageActionListItem.js.map +1 -1
  43. package/lib/commonjs/components/MessageMenu/MessageReactionPicker.js +1 -0
  44. package/lib/commonjs/components/MessageMenu/MessageReactionPicker.js.map +1 -1
  45. package/lib/commonjs/components/MessageMenu/ReactionButton.js +6 -1
  46. package/lib/commonjs/components/MessageMenu/ReactionButton.js.map +1 -1
  47. package/lib/commonjs/components/Poll/components/PollOption.js +15 -0
  48. package/lib/commonjs/components/Poll/components/PollOption.js.map +1 -1
  49. package/lib/commonjs/components/ProgressControl/ProgressControl.js +10 -0
  50. package/lib/commonjs/components/ProgressControl/ProgressControl.js.map +1 -1
  51. package/lib/commonjs/components/Reply/Reply.js +2 -0
  52. package/lib/commonjs/components/Reply/Reply.js.map +1 -1
  53. package/lib/commonjs/components/UIComponents/BottomSheetModal.js +6 -3
  54. package/lib/commonjs/components/UIComponents/BottomSheetModal.js.map +1 -1
  55. package/lib/commonjs/components/index.js +11 -0
  56. package/lib/commonjs/components/index.js.map +1 -1
  57. package/lib/commonjs/components/ui/Avatar/Avatar.js +14 -2
  58. package/lib/commonjs/components/ui/Avatar/Avatar.js.map +1 -1
  59. package/lib/commonjs/components/ui/Avatar/ChannelAvatar.js +3 -1
  60. package/lib/commonjs/components/ui/Avatar/ChannelAvatar.js.map +1 -1
  61. package/lib/commonjs/components/ui/Avatar/UserAvatar.js +1 -0
  62. package/lib/commonjs/components/ui/Avatar/UserAvatar.js.map +1 -1
  63. package/lib/commonjs/components/ui/Button/Button.js +49 -19
  64. package/lib/commonjs/components/ui/Button/Button.js.map +1 -1
  65. package/lib/commonjs/components/ui/Input/Input.js +63 -21
  66. package/lib/commonjs/components/ui/Input/Input.js.map +1 -1
  67. package/lib/commonjs/contexts/accessibilityContext/AccessibilityContext.js +114 -0
  68. package/lib/commonjs/contexts/accessibilityContext/AccessibilityContext.js.map +1 -0
  69. package/lib/commonjs/contexts/accessibilityContext/index.js +15 -0
  70. package/lib/commonjs/contexts/accessibilityContext/index.js.map +1 -0
  71. package/lib/commonjs/contexts/index.js +11 -0
  72. package/lib/commonjs/contexts/index.js.map +1 -1
  73. package/lib/commonjs/contexts/overlayContext/OverlayContext.js.map +1 -1
  74. package/lib/commonjs/contexts/overlayContext/OverlayProvider.js +19 -14
  75. package/lib/commonjs/contexts/overlayContext/OverlayProvider.js.map +1 -1
  76. package/lib/commonjs/hooks/index.js +11 -0
  77. package/lib/commonjs/hooks/index.js.map +1 -1
  78. package/lib/commonjs/i18n/en.json +23 -1
  79. package/lib/commonjs/i18n/es.json +23 -1
  80. package/lib/commonjs/i18n/fr.json +23 -1
  81. package/lib/commonjs/i18n/he.json +23 -1
  82. package/lib/commonjs/i18n/hi.json +23 -1
  83. package/lib/commonjs/i18n/it.json +23 -1
  84. package/lib/commonjs/i18n/ja.json +23 -1
  85. package/lib/commonjs/i18n/ko.json +23 -1
  86. package/lib/commonjs/i18n/nl.json +23 -1
  87. package/lib/commonjs/i18n/pt-br.json +23 -1
  88. package/lib/commonjs/i18n/ru.json +23 -1
  89. package/lib/commonjs/i18n/tr.json +23 -1
  90. package/lib/commonjs/version.json +1 -1
  91. package/lib/module/a11y/a11yUtils.js +40 -0
  92. package/lib/module/a11y/a11yUtils.js.map +1 -0
  93. package/lib/module/a11y/hooks/useA11yLabel.js +15 -0
  94. package/lib/module/a11y/hooks/useA11yLabel.js.map +1 -0
  95. package/lib/module/a11y/hooks/useAnnounceOnStateChange.js +36 -0
  96. package/lib/module/a11y/hooks/useAnnounceOnStateChange.js.map +1 -0
  97. package/lib/module/a11y/hooks/useReducedMotionPreference.js +34 -0
  98. package/lib/module/a11y/hooks/useReducedMotionPreference.js.map +1 -0
  99. package/lib/module/a11y/hooks/useResolvedModalAccessibilityProps.js +20 -0
  100. package/lib/module/a11y/hooks/useResolvedModalAccessibilityProps.js.map +1 -0
  101. package/lib/module/a11y/hooks/useScreenReaderEnabled.js +37 -0
  102. package/lib/module/a11y/hooks/useScreenReaderEnabled.js.map +1 -0
  103. package/lib/module/a11y/index.js +70 -0
  104. package/lib/module/a11y/index.js.map +1 -0
  105. package/lib/module/components/AITypingIndicatorView/AITypingIndicatorView.js +10 -0
  106. package/lib/module/components/AITypingIndicatorView/AITypingIndicatorView.js.map +1 -1
  107. package/lib/module/components/Accessibility/NotificationAnnouncer.js +37 -0
  108. package/lib/module/components/Accessibility/NotificationAnnouncer.js.map +1 -0
  109. package/lib/module/components/Accessibility/hooks/useIncomingMessageAnnouncements.js +109 -0
  110. package/lib/module/components/Accessibility/hooks/useIncomingMessageAnnouncements.js.map +1 -0
  111. package/lib/module/components/Accessibility/index.js +37 -0
  112. package/lib/module/components/Accessibility/index.js.map +1 -0
  113. package/lib/module/components/Accessibility/useAccessibilityAnnouncer.js +15 -0
  114. package/lib/module/components/Accessibility/useAccessibilityAnnouncer.js.map +1 -0
  115. package/lib/module/components/Channel/Channel.js +2 -1
  116. package/lib/module/components/Channel/Channel.js.map +1 -1
  117. package/lib/module/components/ChannelPreview/ChannelMessagePreviewDeliveryStatus.js +4 -0
  118. package/lib/module/components/ChannelPreview/ChannelMessagePreviewDeliveryStatus.js.map +1 -1
  119. package/lib/module/components/Indicators/LoadingDots.js +2 -0
  120. package/lib/module/components/Indicators/LoadingDots.js.map +1 -1
  121. package/lib/module/components/Indicators/LoadingErrorIndicator.js +3 -0
  122. package/lib/module/components/Indicators/LoadingErrorIndicator.js.map +1 -1
  123. package/lib/module/components/Indicators/LoadingIndicator.js +2 -0
  124. package/lib/module/components/Indicators/LoadingIndicator.js.map +1 -1
  125. package/lib/module/components/MessageList/MessageList.js +13 -6
  126. package/lib/module/components/MessageList/MessageList.js.map +1 -1
  127. package/lib/module/components/MessageList/ScrollToBottomButton.js +5 -0
  128. package/lib/module/components/MessageList/ScrollToBottomButton.js.map +1 -1
  129. package/lib/module/components/MessageMenu/MessageActionList.js +4 -1
  130. package/lib/module/components/MessageMenu/MessageActionList.js.map +1 -1
  131. package/lib/module/components/MessageMenu/MessageActionListItem.js +1 -0
  132. package/lib/module/components/MessageMenu/MessageActionListItem.js.map +1 -1
  133. package/lib/module/components/MessageMenu/MessageReactionPicker.js +1 -0
  134. package/lib/module/components/MessageMenu/MessageReactionPicker.js.map +1 -1
  135. package/lib/module/components/MessageMenu/ReactionButton.js +6 -1
  136. package/lib/module/components/MessageMenu/ReactionButton.js.map +1 -1
  137. package/lib/module/components/Poll/components/PollOption.js +15 -0
  138. package/lib/module/components/Poll/components/PollOption.js.map +1 -1
  139. package/lib/module/components/ProgressControl/ProgressControl.js +10 -0
  140. package/lib/module/components/ProgressControl/ProgressControl.js.map +1 -1
  141. package/lib/module/components/Reply/Reply.js +2 -0
  142. package/lib/module/components/Reply/Reply.js.map +1 -1
  143. package/lib/module/components/UIComponents/BottomSheetModal.js +6 -3
  144. package/lib/module/components/UIComponents/BottomSheetModal.js.map +1 -1
  145. package/lib/module/components/index.js +11 -0
  146. package/lib/module/components/index.js.map +1 -1
  147. package/lib/module/components/ui/Avatar/Avatar.js +14 -2
  148. package/lib/module/components/ui/Avatar/Avatar.js.map +1 -1
  149. package/lib/module/components/ui/Avatar/ChannelAvatar.js +3 -1
  150. package/lib/module/components/ui/Avatar/ChannelAvatar.js.map +1 -1
  151. package/lib/module/components/ui/Avatar/UserAvatar.js +1 -0
  152. package/lib/module/components/ui/Avatar/UserAvatar.js.map +1 -1
  153. package/lib/module/components/ui/Button/Button.js +49 -19
  154. package/lib/module/components/ui/Button/Button.js.map +1 -1
  155. package/lib/module/components/ui/Input/Input.js +63 -21
  156. package/lib/module/components/ui/Input/Input.js.map +1 -1
  157. package/lib/module/contexts/accessibilityContext/AccessibilityContext.js +114 -0
  158. package/lib/module/contexts/accessibilityContext/AccessibilityContext.js.map +1 -0
  159. package/lib/module/contexts/accessibilityContext/index.js +15 -0
  160. package/lib/module/contexts/accessibilityContext/index.js.map +1 -0
  161. package/lib/module/contexts/index.js +11 -0
  162. package/lib/module/contexts/index.js.map +1 -1
  163. package/lib/module/contexts/overlayContext/OverlayContext.js.map +1 -1
  164. package/lib/module/contexts/overlayContext/OverlayProvider.js +19 -14
  165. package/lib/module/contexts/overlayContext/OverlayProvider.js.map +1 -1
  166. package/lib/module/hooks/index.js +11 -0
  167. package/lib/module/hooks/index.js.map +1 -1
  168. package/lib/module/i18n/en.json +23 -1
  169. package/lib/module/i18n/es.json +23 -1
  170. package/lib/module/i18n/fr.json +23 -1
  171. package/lib/module/i18n/he.json +23 -1
  172. package/lib/module/i18n/hi.json +23 -1
  173. package/lib/module/i18n/it.json +23 -1
  174. package/lib/module/i18n/ja.json +23 -1
  175. package/lib/module/i18n/ko.json +23 -1
  176. package/lib/module/i18n/nl.json +23 -1
  177. package/lib/module/i18n/pt-br.json +23 -1
  178. package/lib/module/i18n/ru.json +23 -1
  179. package/lib/module/i18n/tr.json +23 -1
  180. package/lib/module/version.json +1 -1
  181. package/lib/typescript/a11y/a11yUtils.d.ts +31 -0
  182. package/lib/typescript/a11y/a11yUtils.d.ts.map +1 -0
  183. package/lib/typescript/a11y/hooks/useA11yLabel.d.ts +12 -0
  184. package/lib/typescript/a11y/hooks/useA11yLabel.d.ts.map +1 -0
  185. package/lib/typescript/a11y/hooks/useAnnounceOnStateChange.d.ts +14 -0
  186. package/lib/typescript/a11y/hooks/useAnnounceOnStateChange.d.ts.map +1 -0
  187. package/lib/typescript/a11y/hooks/useReducedMotionPreference.d.ts +6 -0
  188. package/lib/typescript/a11y/hooks/useReducedMotionPreference.d.ts.map +1 -0
  189. package/lib/typescript/a11y/hooks/useResolvedModalAccessibilityProps.d.ts +18 -0
  190. package/lib/typescript/a11y/hooks/useResolvedModalAccessibilityProps.d.ts.map +1 -0
  191. package/lib/typescript/a11y/hooks/useScreenReaderEnabled.d.ts +10 -0
  192. package/lib/typescript/a11y/hooks/useScreenReaderEnabled.d.ts.map +1 -0
  193. package/lib/typescript/a11y/index.d.ts +7 -0
  194. package/lib/typescript/a11y/index.d.ts.map +1 -0
  195. package/lib/typescript/components/AITypingIndicatorView/AITypingIndicatorView.d.ts.map +1 -1
  196. package/lib/typescript/components/Accessibility/NotificationAnnouncer.d.ts +12 -0
  197. package/lib/typescript/components/Accessibility/NotificationAnnouncer.d.ts.map +1 -0
  198. package/lib/typescript/components/Accessibility/hooks/useIncomingMessageAnnouncements.d.ts +20 -0
  199. package/lib/typescript/components/Accessibility/hooks/useIncomingMessageAnnouncements.d.ts.map +1 -0
  200. package/lib/typescript/components/Accessibility/index.d.ts +4 -0
  201. package/lib/typescript/components/Accessibility/index.d.ts.map +1 -0
  202. package/lib/typescript/components/Accessibility/useAccessibilityAnnouncer.d.ts +15 -0
  203. package/lib/typescript/components/Accessibility/useAccessibilityAnnouncer.d.ts.map +1 -0
  204. package/lib/typescript/components/Channel/Channel.d.ts.map +1 -1
  205. package/lib/typescript/components/ChannelPreview/ChannelMessagePreviewDeliveryStatus.d.ts.map +1 -1
  206. package/lib/typescript/components/Indicators/LoadingDots.d.ts.map +1 -1
  207. package/lib/typescript/components/Indicators/LoadingErrorIndicator.d.ts.map +1 -1
  208. package/lib/typescript/components/MessageList/MessageList.d.ts.map +1 -1
  209. package/lib/typescript/components/MessageList/ScrollToBottomButton.d.ts.map +1 -1
  210. package/lib/typescript/components/MessageMenu/MessageActionList.d.ts.map +1 -1
  211. package/lib/typescript/components/MessageMenu/MessageActionListItem.d.ts.map +1 -1
  212. package/lib/typescript/components/MessageMenu/MessageReactionPicker.d.ts.map +1 -1
  213. package/lib/typescript/components/MessageMenu/ReactionButton.d.ts.map +1 -1
  214. package/lib/typescript/components/Poll/components/PollOption.d.ts.map +1 -1
  215. package/lib/typescript/components/ProgressControl/ProgressControl.d.ts.map +1 -1
  216. package/lib/typescript/components/Reply/Reply.d.ts.map +1 -1
  217. package/lib/typescript/components/UIComponents/BottomSheetModal.d.ts.map +1 -1
  218. package/lib/typescript/components/index.d.ts +1 -0
  219. package/lib/typescript/components/index.d.ts.map +1 -1
  220. package/lib/typescript/components/ui/Avatar/Avatar.d.ts +12 -1
  221. package/lib/typescript/components/ui/Avatar/Avatar.d.ts.map +1 -1
  222. package/lib/typescript/components/ui/Avatar/ChannelAvatar.d.ts.map +1 -1
  223. package/lib/typescript/components/ui/Avatar/UserAvatar.d.ts.map +1 -1
  224. package/lib/typescript/components/ui/Button/Button.d.ts.map +1 -1
  225. package/lib/typescript/components/ui/Input/Input.d.ts.map +1 -1
  226. package/lib/typescript/contexts/accessibilityContext/AccessibilityContext.d.ts +34 -0
  227. package/lib/typescript/contexts/accessibilityContext/AccessibilityContext.d.ts.map +1 -0
  228. package/lib/typescript/contexts/accessibilityContext/index.d.ts +2 -0
  229. package/lib/typescript/contexts/accessibilityContext/index.d.ts.map +1 -0
  230. package/lib/typescript/contexts/index.d.ts +1 -0
  231. package/lib/typescript/contexts/index.d.ts.map +1 -1
  232. package/lib/typescript/contexts/overlayContext/OverlayContext.d.ts +7 -0
  233. package/lib/typescript/contexts/overlayContext/OverlayContext.d.ts.map +1 -1
  234. package/lib/typescript/contexts/overlayContext/OverlayProvider.d.ts.map +1 -1
  235. package/lib/typescript/hooks/index.d.ts +1 -0
  236. package/lib/typescript/hooks/index.d.ts.map +1 -1
  237. package/lib/typescript/hooks/useTranslatedMessage.d.ts +2 -2
  238. package/lib/typescript/i18n/en.json +23 -1
  239. package/lib/typescript/i18n/es.json +23 -1
  240. package/lib/typescript/i18n/fr.json +23 -1
  241. package/lib/typescript/i18n/he.json +23 -1
  242. package/lib/typescript/i18n/hi.json +23 -1
  243. package/lib/typescript/i18n/it.json +23 -1
  244. package/lib/typescript/i18n/ja.json +23 -1
  245. package/lib/typescript/i18n/ko.json +23 -1
  246. package/lib/typescript/i18n/nl.json +23 -1
  247. package/lib/typescript/i18n/pt-br.json +23 -1
  248. package/lib/typescript/i18n/ru.json +23 -1
  249. package/lib/typescript/i18n/tr.json +23 -1
  250. package/lib/typescript/utils/i18n/Streami18n.d.ts +22 -0
  251. package/lib/typescript/utils/i18n/Streami18n.d.ts.map +1 -1
  252. package/package.json +1 -1
  253. package/src/a11y/__tests__/a11yUtils.test.ts +70 -0
  254. package/src/a11y/a11yUtils.ts +50 -0
  255. package/src/a11y/hooks/useA11yLabel.ts +19 -0
  256. package/src/a11y/hooks/useAnnounceOnStateChange.ts +47 -0
  257. package/src/a11y/hooks/useReducedMotionPreference.ts +38 -0
  258. package/src/a11y/hooks/useResolvedModalAccessibilityProps.ts +30 -0
  259. package/src/a11y/hooks/useScreenReaderEnabled.ts +44 -0
  260. package/src/a11y/index.ts +6 -0
  261. package/src/components/AITypingIndicatorView/AITypingIndicatorView.tsx +17 -2
  262. package/src/components/AITypingIndicatorView/__tests__/AITypingIndicatorView.test.tsx +73 -0
  263. package/src/components/Accessibility/NotificationAnnouncer.tsx +43 -0
  264. package/src/components/Accessibility/__tests__/AccessibilityAnnouncer.test.tsx +75 -0
  265. package/src/components/Accessibility/hooks/useIncomingMessageAnnouncements.ts +157 -0
  266. package/src/components/Accessibility/index.ts +3 -0
  267. package/src/components/Accessibility/useAccessibilityAnnouncer.ts +30 -0
  268. package/src/components/Channel/Channel.tsx +3 -0
  269. package/src/components/ChannelPreview/ChannelMessagePreviewDeliveryStatus.tsx +14 -1
  270. package/src/components/Indicators/LoadingDots.tsx +5 -1
  271. package/src/components/Indicators/LoadingErrorIndicator.tsx +7 -1
  272. package/src/components/Indicators/LoadingIndicator.tsx +1 -1
  273. package/src/components/Message/MessageItemView/__tests__/__snapshots__/MessageAuthor.test.tsx.snap +2 -0
  274. package/src/components/MessageInput/__tests__/__snapshots__/AttachButton.test.tsx.snap +30 -15
  275. package/src/components/MessageInput/__tests__/__snapshots__/SendButton.test.tsx.snap +20 -10
  276. package/src/components/MessageList/MessageList.tsx +9 -0
  277. package/src/components/MessageList/ScrollToBottomButton.tsx +6 -0
  278. package/src/components/MessageList/__tests__/__snapshots__/ScrollToBottomButton.test.tsx.snap +2 -1
  279. package/src/components/MessageList/__tests__/__snapshots__/TypingIndicator.test.tsx.snap +6 -0
  280. package/src/components/MessageMenu/MessageActionList.tsx +4 -1
  281. package/src/components/MessageMenu/MessageActionListItem.tsx +1 -0
  282. package/src/components/MessageMenu/MessageReactionPicker.tsx +1 -0
  283. package/src/components/MessageMenu/ReactionButton.tsx +9 -1
  284. package/src/components/Poll/components/PollOption.tsx +11 -0
  285. package/src/components/ProgressControl/ProgressControl.tsx +8 -0
  286. package/src/components/Reply/Reply.tsx +5 -1
  287. package/src/components/Thread/__tests__/__snapshots__/Thread.test.tsx.snap +20 -6
  288. package/src/components/UIComponents/BottomSheetModal.tsx +4 -0
  289. package/src/components/index.ts +2 -0
  290. package/src/components/ui/Avatar/Avatar.tsx +23 -2
  291. package/src/components/ui/Avatar/ChannelAvatar.tsx +3 -0
  292. package/src/components/ui/Avatar/UserAvatar.tsx +1 -0
  293. package/src/components/ui/Button/Button.tsx +24 -0
  294. package/src/components/ui/Input/Input.tsx +35 -0
  295. package/src/contexts/accessibilityContext/AccessibilityContext.tsx +165 -0
  296. package/src/contexts/accessibilityContext/__tests__/AccessibilityContext.test.tsx +65 -0
  297. package/src/contexts/accessibilityContext/index.ts +1 -0
  298. package/src/contexts/index.ts +1 -0
  299. package/src/contexts/overlayContext/OverlayContext.tsx +7 -0
  300. package/src/contexts/overlayContext/OverlayProvider.tsx +18 -14
  301. package/src/contexts/overlayContext/__tests__/OverlayProvider.test.tsx +51 -0
  302. package/src/hooks/index.ts +1 -0
  303. package/src/i18n/en.json +23 -1
  304. package/src/i18n/es.json +23 -1
  305. package/src/i18n/fr.json +23 -1
  306. package/src/i18n/he.json +23 -1
  307. package/src/i18n/hi.json +23 -1
  308. package/src/i18n/it.json +23 -1
  309. package/src/i18n/ja.json +23 -1
  310. package/src/i18n/ko.json +23 -1
  311. package/src/i18n/nl.json +23 -1
  312. package/src/i18n/pt-br.json +23 -1
  313. package/src/i18n/ru.json +23 -1
  314. package/src/i18n/tr.json +23 -1
  315. package/src/version.json +1 -1
@@ -236,5 +236,27 @@
236
236
  "Unsupported Attachment": "Неподдерживаемое вложение",
237
237
  "+{{count}} More Options_one": "+ещё {{count}} вариант",
238
238
  "+{{count}} More Options_other": "+ещё {{count}} варианта",
239
- "+{{count}} More Options_many": "+ещё {{count}} вариантов"
239
+ "+{{count}} More Options_many": "+ещё {{count}} вариантов",
240
+ "a11y/AI is generating": "ИИ генерирует ответ",
241
+ "a11y/AI is thinking": "ИИ думает",
242
+ "a11y/Avatar of {{name}}": "Аватар {{name}}",
243
+ "a11y/Connected": "Подключено",
244
+ "a11y/Delivered": "Доставлено",
245
+ "a11y/Loading": "Загрузка",
246
+ "a11y/Loading failed": "Не удалось загрузить",
247
+ "a11y/Message actions": "Действия с сообщением",
248
+ "a11y/New message from {{user}}": "Новое сообщение от {{user}}",
249
+ "a11y/Offline": "Не в сети",
250
+ "a11y/Open message actions": "Открыть действия с сообщением",
251
+ "a11y/Reaction {{emoji}} by {{count}} users": "Реакция {{emoji}} от {{count}} пользователей",
252
+ "a11y/Read": "Прочитано",
253
+ "a11y/Reconnecting": "Повторное подключение",
254
+ "a11y/Reply to {{user}}": "Ответить {{user}}",
255
+ "a11y/Scroll to latest": "Перейти к последнему сообщению",
256
+ "a11y/Scroll to latest, {{count}} unread": "Перейти к последнему сообщению, {{count}} непрочитанных",
257
+ "a11y/Send message": "Отправить сообщение",
258
+ "a11y/Sending": "Отправка",
259
+ "a11y/Sent": "Отправлено",
260
+ "a11y/Voice message recording. Hold to record.": "Запись голосового сообщения. Удерживайте, чтобы записать.",
261
+ "a11y/{{count}} new messages": "{{count}} новых сообщений"
240
262
  }
@@ -236,5 +236,27 @@
236
236
  "Unsupported Attachment": "Desteklenmeyen ek",
237
237
  "+{{count}} More Options_one": "+{{count}} seçenek daha",
238
238
  "+{{count}} More Options_other": "+{{count}} seçenek daha",
239
- "+{{count}} More Options_many": "+{{count}} seçenek daha"
239
+ "+{{count}} More Options_many": "+{{count}} seçenek daha",
240
+ "a11y/AI is generating": "Yapay zeka oluşturuyor",
241
+ "a11y/AI is thinking": "Yapay zeka düşünüyor",
242
+ "a11y/Avatar of {{name}}": "{{name}} avatarı",
243
+ "a11y/Connected": "Bağlandı",
244
+ "a11y/Delivered": "Teslim edildi",
245
+ "a11y/Loading": "Yükleniyor",
246
+ "a11y/Loading failed": "Yükleme başarısız",
247
+ "a11y/Message actions": "Mesaj eylemleri",
248
+ "a11y/New message from {{user}}": "{{user}} kullanıcısından yeni mesaj",
249
+ "a11y/Offline": "Çevrimdışı",
250
+ "a11y/Open message actions": "Mesaj eylemlerini aç",
251
+ "a11y/Reaction {{emoji}} by {{count}} users": "{{count}} kullanıcıdan {{emoji}} tepkisi",
252
+ "a11y/Read": "Okundu",
253
+ "a11y/Reconnecting": "Yeniden bağlanıyor",
254
+ "a11y/Reply to {{user}}": "{{user}} kullanıcısına yanıt ver",
255
+ "a11y/Scroll to latest": "En son mesaja git",
256
+ "a11y/Scroll to latest, {{count}} unread": "En son mesaja git, {{count}} okunmamış",
257
+ "a11y/Send message": "Mesaj gönder",
258
+ "a11y/Sending": "Gönderiliyor",
259
+ "a11y/Sent": "Gönderildi",
260
+ "a11y/Voice message recording. Hold to record.": "Sesli mesaj kaydı. Kaydetmek için basılı tutun.",
261
+ "a11y/{{count}} new messages": "{{count}} yeni mesaj"
240
262
  }
@@ -372,6 +372,28 @@ export declare class Streami18n {
372
372
  "+{{count}} More Options_one": string;
373
373
  "+{{count}} More Options_other": string;
374
374
  "+{{count}} More Options_many": string;
375
+ "a11y/AI is generating": string;
376
+ "a11y/AI is thinking": string;
377
+ "a11y/Avatar of {{name}}": string;
378
+ "a11y/Connected": string;
379
+ "a11y/Delivered": string;
380
+ "a11y/Loading": string;
381
+ "a11y/Loading failed": string;
382
+ "a11y/Message actions": string;
383
+ "a11y/New message from {{user}}": string;
384
+ "a11y/Offline": string;
385
+ "a11y/Open message actions": string;
386
+ "a11y/Reaction {{emoji}} by {{count}} users": string;
387
+ "a11y/Read": string;
388
+ "a11y/Reconnecting": string;
389
+ "a11y/Reply to {{user}}": string;
390
+ "a11y/Scroll to latest": string;
391
+ "a11y/Scroll to latest, {{count}} unread": string;
392
+ "a11y/Send message": string;
393
+ "a11y/Sending": string;
394
+ "a11y/Sent": string;
395
+ "a11y/Voice message recording. Hold to record.": string;
396
+ "a11y/{{count}} new messages": string;
375
397
  }>;
376
398
  };
377
399
  };
@@ -1 +1 @@
1
- {"version":3,"file":"Streami18n.d.ts","sourceRoot":"","sources":["../../../../src/utils/i18n/Streami18n.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"Streami18n.d.ts","sourceRoot":"","sources":["../../../../src/utils/i18n/Streami18n.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "stream-chat-react-native-core",
3
3
  "description": "The official React Native and Expo components for Stream Chat, a service for building chat applications",
4
- "version": "9.1.3-beta.2",
4
+ "version": "9.2.0-beta.1",
5
5
  "author": {
6
6
  "company": "Stream.io Inc",
7
7
  "name": "Stream.io Inc"
@@ -0,0 +1,70 @@
1
+ import {
2
+ composeAccessibilityLabel,
3
+ formatAccessibilityValue,
4
+ mergeAccessibilityActions,
5
+ } from '../a11yUtils';
6
+
7
+ describe('composeAccessibilityLabel', () => {
8
+ it('joins non-empty parts with comma+space', () => {
9
+ expect(composeAccessibilityLabel('Alice', '12:34', 'Hello')).toBe('Alice, 12:34, Hello');
10
+ });
11
+
12
+ it('drops empty strings, null, undefined, false', () => {
13
+ expect(composeAccessibilityLabel('A', '', null, undefined, false, 'B')).toBe('A, B');
14
+ });
15
+
16
+ it('returns empty string when nothing to join', () => {
17
+ expect(composeAccessibilityLabel(null, undefined, '')).toBe('');
18
+ });
19
+ });
20
+
21
+ describe('formatAccessibilityValue', () => {
22
+ it('clamps now between min and max', () => {
23
+ expect(formatAccessibilityValue({ max: 100, now: 200 })).toEqual({
24
+ max: 100,
25
+ min: 0,
26
+ now: 100,
27
+ });
28
+ expect(formatAccessibilityValue({ max: 100, min: 10, now: 5 })).toEqual({
29
+ max: 100,
30
+ min: 10,
31
+ now: 10,
32
+ });
33
+ });
34
+
35
+ it('attaches optional text', () => {
36
+ expect(formatAccessibilityValue({ max: 60, now: 30, text: '00:30 of 01:00' })).toEqual({
37
+ max: 60,
38
+ min: 0,
39
+ now: 30,
40
+ text: '00:30 of 01:00',
41
+ });
42
+ });
43
+
44
+ it('omits text when not provided', () => {
45
+ const result = formatAccessibilityValue({ max: 60, now: 30 });
46
+ expect(result).not.toHaveProperty('text');
47
+ });
48
+ });
49
+
50
+ describe('mergeAccessibilityActions', () => {
51
+ it('merges and deduplicates by name (later wins)', () => {
52
+ const merged = mergeAccessibilityActions(
53
+ [{ name: 'activate', label: 'old' }, { name: 'react' }],
54
+ [{ name: 'activate', label: 'new' }, { name: 'reply' }],
55
+ );
56
+ expect(merged).toEqual([
57
+ { name: 'activate', label: 'new' },
58
+ { name: 'react' },
59
+ { name: 'reply' },
60
+ ]);
61
+ });
62
+
63
+ it('skips undefined inputs', () => {
64
+ expect(mergeAccessibilityActions(undefined, [{ name: 'a' }])).toEqual([{ name: 'a' }]);
65
+ });
66
+
67
+ it('returns empty array when no inputs', () => {
68
+ expect(mergeAccessibilityActions()).toEqual([]);
69
+ });
70
+ });
@@ -0,0 +1,50 @@
1
+ /**
2
+ * Compose a single accessibility label from multiple parts.
3
+ * Empty/null/undefined parts are filtered out, the remainder joined with a comma+space
4
+ * so screen readers add a brief pause between segments.
5
+ */
6
+ export const composeAccessibilityLabel = (
7
+ ...parts: Array<string | null | undefined | false>
8
+ ): string => parts.filter((p): p is string => typeof p === 'string' && p.length > 0).join(', ');
9
+
10
+ /**
11
+ * Build the value object passed to `accessibilityValue` for progress/seek surfaces.
12
+ * Mirrors the React SDK's `progressBarA11y.ts` shape.
13
+ */
14
+ export const formatAccessibilityValue = ({
15
+ max,
16
+ min = 0,
17
+ now,
18
+ text,
19
+ }: {
20
+ max: number;
21
+ now: number;
22
+ min?: number;
23
+ text?: string;
24
+ }): { max: number; min: number; now: number; text?: string } => {
25
+ const value: { max: number; min: number; now: number; text?: string } = {
26
+ max,
27
+ min,
28
+ now: Math.min(Math.max(min, now), max),
29
+ };
30
+ if (text) value.text = text;
31
+ return value;
32
+ };
33
+
34
+ /**
35
+ * Merge two `accessibilityActions` arrays, deduplicating by `name` (later wins).
36
+ */
37
+ type A11yAction = { name: string; label?: string };
38
+
39
+ export const mergeAccessibilityActions = (
40
+ ...actionLists: Array<A11yAction[] | undefined>
41
+ ): A11yAction[] => {
42
+ const byName = new Map<string, A11yAction>();
43
+ for (const list of actionLists) {
44
+ if (!list) continue;
45
+ for (const action of list) {
46
+ byName.set(action.name, action);
47
+ }
48
+ }
49
+ return Array.from(byName.values());
50
+ };
@@ -0,0 +1,19 @@
1
+ import { useAccessibilityContext } from '../../contexts/accessibilityContext/AccessibilityContext';
2
+ import { useTranslationContext } from '../../contexts/translationContext/TranslationContext';
3
+
4
+ /**
5
+ * Returns the translated `a11y/...` label when the AccessibilityContext is enabled,
6
+ * or `undefined` when disabled. Components pass the result straight to
7
+ * `accessibilityLabel` so the i18n lookup is skipped on hot list paths in the
8
+ * default disabled-state.
9
+ *
10
+ * Example:
11
+ * const label = useA11yLabel('a11y/Avatar of {{name}}', { name });
12
+ * <Image accessibilityLabel={label} />
13
+ */
14
+ export const useA11yLabel = (key: string, params?: Record<string, unknown>): string | undefined => {
15
+ const { enabled } = useAccessibilityContext();
16
+ const { t } = useTranslationContext();
17
+ if (!enabled) return undefined;
18
+ return t(key, params);
19
+ };
@@ -0,0 +1,47 @@
1
+ import { useEffect, useRef } from 'react';
2
+
3
+ import { useAccessibilityAnnouncer } from '../../components/Accessibility/useAccessibilityAnnouncer';
4
+ import { useAccessibilityContext } from '../../contexts/accessibilityContext/AccessibilityContext';
5
+
6
+ const DEFAULT_DEBOUNCE_MS = 250;
7
+
8
+ type UseAnnounceOnStateChangeOptions = {
9
+ debounceMs?: number;
10
+ priority?: 'polite' | 'assertive';
11
+ };
12
+
13
+ /**
14
+ * Announces `message` whenever it changes (and is non-empty), with a debounce
15
+ * to avoid spamming the screen reader on rapid transitions.
16
+ *
17
+ * Used by `AITypingIndicatorView` ("Thinking…" → "Generating…" → idle) and
18
+ * the `Indicators` family (loading → loaded → error).
19
+ */
20
+ export const useAnnounceOnStateChange = (
21
+ message: string | null | undefined,
22
+ options: UseAnnounceOnStateChangeOptions = {},
23
+ ) => {
24
+ const { debounceMs = DEFAULT_DEBOUNCE_MS, priority = 'polite' } = options;
25
+ const { enabled } = useAccessibilityContext();
26
+ const announce = useAccessibilityAnnouncer();
27
+ const timeoutRef = useRef<ReturnType<typeof setTimeout> | null>(null);
28
+ const lastAnnouncedRef = useRef<string | null>(null);
29
+
30
+ useEffect(() => {
31
+ if (!enabled || !message || message === lastAnnouncedRef.current) return;
32
+
33
+ if (timeoutRef.current) clearTimeout(timeoutRef.current);
34
+ timeoutRef.current = setTimeout(() => {
35
+ announce(message, priority);
36
+ lastAnnouncedRef.current = message;
37
+ timeoutRef.current = null;
38
+ }, debounceMs);
39
+
40
+ return () => {
41
+ if (timeoutRef.current) {
42
+ clearTimeout(timeoutRef.current);
43
+ timeoutRef.current = null;
44
+ }
45
+ };
46
+ }, [announce, debounceMs, enabled, message, priority]);
47
+ };
@@ -0,0 +1,38 @@
1
+ import { useEffect, useState } from 'react';
2
+ import { AccessibilityInfo } from 'react-native';
3
+
4
+ import { useAccessibilityContext } from '../../contexts/accessibilityContext/AccessibilityContext';
5
+
6
+ /**
7
+ * Subscribes to AccessibilityInfo reduce-motion changes and returns the live state.
8
+ * Returns false when the AccessibilityContext is disabled.
9
+ */
10
+ export const useReducedMotionPreference = (): boolean => {
11
+ const { enabled } = useAccessibilityContext();
12
+ const [reduceMotion, setReduceMotion] = useState<boolean>(false);
13
+
14
+ useEffect(() => {
15
+ if (!enabled) {
16
+ setReduceMotion(false);
17
+ return;
18
+ }
19
+
20
+ let cancelled = false;
21
+ AccessibilityInfo.isReduceMotionEnabled?.()
22
+ .then((value) => {
23
+ if (!cancelled) setReduceMotion(value);
24
+ })
25
+ .catch(() => {
26
+ // Older RN or platforms without the API.
27
+ });
28
+
29
+ const subscription = AccessibilityInfo.addEventListener('reduceMotionChanged', setReduceMotion);
30
+
31
+ return () => {
32
+ cancelled = true;
33
+ subscription?.remove?.();
34
+ };
35
+ }, [enabled]);
36
+
37
+ return enabled && reduceMotion;
38
+ };
@@ -0,0 +1,30 @@
1
+ import { Platform } from 'react-native';
2
+
3
+ import { useAccessibilityContext } from '../../contexts/accessibilityContext/AccessibilityContext';
4
+
5
+ export type ResolvedModalAccessibilityProps = {
6
+ accessibilityViewIsModal?: boolean;
7
+ importantForAccessibility?: 'auto' | 'yes' | 'no' | 'no-hide-descendants';
8
+ accessibilityRole?: 'none' | 'button' | 'image' | 'text' | 'alert' | 'menu' | 'menuitem';
9
+ };
10
+
11
+ /**
12
+ * Returns the platform-appropriate set of a11y props for a modal/sheet root.
13
+ * Equivalent of stream-chat-react's `useResolvedModalAriaProps` — but aware of
14
+ * RN's iOS-vs-Android split:
15
+ * - iOS uses `accessibilityViewIsModal` to trap focus.
16
+ * - Android uses `importantForAccessibility="yes"` on the modal root and
17
+ * `"no-hide-descendants"` on background siblings (caller's responsibility).
18
+ *
19
+ * Returns an empty object when AccessibilityContext is disabled, so the modal
20
+ * stays a no-op for integrators that haven't opted in.
21
+ */
22
+ export const useResolvedModalAccessibilityProps = (): ResolvedModalAccessibilityProps => {
23
+ const { enabled } = useAccessibilityContext();
24
+ if (!enabled) return {};
25
+
26
+ if (Platform.OS === 'ios') {
27
+ return { accessibilityViewIsModal: true };
28
+ }
29
+ return { importantForAccessibility: 'yes' };
30
+ };
@@ -0,0 +1,44 @@
1
+ import { useEffect, useState } from 'react';
2
+ import { AccessibilityInfo } from 'react-native';
3
+
4
+ import { useAccessibilityContext } from '../../contexts/accessibilityContext/AccessibilityContext';
5
+
6
+ /**
7
+ * Subscribes to AccessibilityInfo screen-reader changes and returns the live state.
8
+ * Returns false when the AccessibilityContext is disabled, regardless of the OS state,
9
+ * so consumers don't pay the listener cost when the SDK's a11y is opted out.
10
+ *
11
+ * `forceScreenReaderMode: true` in the config short-circuits to true (used in tests
12
+ * and for integrator preview).
13
+ */
14
+ export const useScreenReaderEnabled = (): boolean => {
15
+ const { enabled, forceScreenReaderMode } = useAccessibilityContext();
16
+ const [isEnabled, setIsEnabled] = useState<boolean>(false);
17
+
18
+ useEffect(() => {
19
+ if (!enabled) {
20
+ setIsEnabled(false);
21
+ return;
22
+ }
23
+
24
+ let cancelled = false;
25
+ AccessibilityInfo.isScreenReaderEnabled()
26
+ .then((value) => {
27
+ if (!cancelled) setIsEnabled(value);
28
+ })
29
+ .catch(() => {
30
+ // Some platforms / environments may not implement this; fall back to false.
31
+ });
32
+
33
+ const subscription = AccessibilityInfo.addEventListener('screenReaderChanged', setIsEnabled);
34
+
35
+ return () => {
36
+ cancelled = true;
37
+ subscription?.remove?.();
38
+ };
39
+ }, [enabled]);
40
+
41
+ if (!enabled) return false;
42
+ if (forceScreenReaderMode) return true;
43
+ return isEnabled;
44
+ };
@@ -0,0 +1,6 @@
1
+ export * from './a11yUtils';
2
+ export * from './hooks/useScreenReaderEnabled';
3
+ export * from './hooks/useReducedMotionPreference';
4
+ export * from './hooks/useResolvedModalAccessibilityProps';
5
+ export * from './hooks/useAnnounceOnStateChange';
6
+ export * from './hooks/useA11yLabel';
@@ -6,7 +6,13 @@ import { Channel } from 'stream-chat';
6
6
 
7
7
  import { AIStates, useAIState } from './hooks/useAIState';
8
8
 
9
- import { useChannelContext, useTheme, useTranslationContext } from '../../contexts';
9
+ import { useAnnounceOnStateChange } from '../../a11y/hooks/useAnnounceOnStateChange';
10
+ import {
11
+ useAccessibilityContext,
12
+ useChannelContext,
13
+ useTheme,
14
+ useTranslationContext,
15
+ } from '../../contexts';
10
16
  import { primitives } from '../../theme';
11
17
 
12
18
  export type AITypingIndicatorViewProps = {
@@ -20,15 +26,24 @@ export const AITypingIndicatorView = ({
20
26
  const { channel: channelFromContext } = useChannelContext();
21
27
  const channel = channelFromProps || channelFromContext;
22
28
  const { aiState } = useAIState(channel);
29
+ const { announceTypingIndicator, enabled } = useAccessibilityContext();
23
30
  const allowedStates = {
24
31
  [AIStates.Thinking]: t('Thinking...'),
25
32
  [AIStates.Generating]: t('Generating...'),
26
33
  };
27
34
 
28
35
  const styles = useStyles();
36
+ const announceableState = aiState in allowedStates ? allowedStates[aiState] : null;
37
+ const shouldAnnounceTypingIndicator = enabled && announceTypingIndicator;
38
+ const typingAnnouncement = announceTypingIndicator ? announceableState : null;
39
+ useAnnounceOnStateChange(typingAnnouncement);
29
40
 
30
41
  return aiState in allowedStates ? (
31
- <View style={styles.container}>
42
+ <View
43
+ accessibilityLiveRegion={shouldAnnounceTypingIndicator ? 'polite' : undefined}
44
+ accessibilityRole='text'
45
+ style={styles.container}
46
+ >
32
47
  <Text style={styles.text}>{allowedStates[aiState]}</Text>
33
48
  </View>
34
49
  ) : null;
@@ -0,0 +1,73 @@
1
+ import React from 'react';
2
+
3
+ import { render } from '@testing-library/react-native';
4
+ import type { Channel } from 'stream-chat';
5
+
6
+ import { useAnnounceOnStateChange } from '../../../a11y/hooks/useAnnounceOnStateChange';
7
+ import { AccessibilityProvider } from '../../../contexts/accessibilityContext/AccessibilityContext';
8
+ import { ThemeProvider } from '../../../contexts/themeContext/ThemeContext';
9
+ import { defaultTheme } from '../../../contexts/themeContext/utils/theme';
10
+ import { AITypingIndicatorView } from '../AITypingIndicatorView';
11
+ import { AIStates, useAIState } from '../hooks/useAIState';
12
+
13
+ jest.mock('../../../a11y/hooks/useAnnounceOnStateChange', () => ({
14
+ useAnnounceOnStateChange: jest.fn(),
15
+ }));
16
+
17
+ jest.mock('../hooks/useAIState', () => {
18
+ const actual = jest.requireActual('../hooks/useAIState');
19
+ return {
20
+ ...actual,
21
+ useAIState: jest.fn(),
22
+ };
23
+ });
24
+
25
+ const mockUseAIState = useAIState as jest.MockedFunction<typeof useAIState>;
26
+ const mockUseAnnounceOnStateChange = useAnnounceOnStateChange as jest.MockedFunction<
27
+ typeof useAnnounceOnStateChange
28
+ >;
29
+
30
+ const renderComponent = (
31
+ accessibility?: React.ComponentProps<typeof AccessibilityProvider>['value'],
32
+ ) =>
33
+ render(
34
+ <ThemeProvider theme={defaultTheme}>
35
+ <AccessibilityProvider value={accessibility}>
36
+ <AITypingIndicatorView channel={{} as Channel} />
37
+ </AccessibilityProvider>
38
+ </ThemeProvider>,
39
+ );
40
+
41
+ describe('AITypingIndicatorView', () => {
42
+ beforeEach(() => {
43
+ mockUseAIState.mockReturnValue({ aiState: AIStates.Thinking });
44
+ jest.clearAllMocks();
45
+ });
46
+
47
+ it('does not announce typing state by default', () => {
48
+ const { UNSAFE_queryByProps } = renderComponent();
49
+
50
+ expect(mockUseAnnounceOnStateChange).toHaveBeenCalledWith(null);
51
+ expect(UNSAFE_queryByProps({ accessibilityLiveRegion: 'polite' })).toBeNull();
52
+ });
53
+
54
+ it('does not announce typing state when a11y is enabled but typing announcements are off', () => {
55
+ const { UNSAFE_queryByProps } = renderComponent({
56
+ announceTypingIndicator: false,
57
+ enabled: true,
58
+ });
59
+
60
+ expect(mockUseAnnounceOnStateChange).toHaveBeenCalledWith(null);
61
+ expect(UNSAFE_queryByProps({ accessibilityLiveRegion: 'polite' })).toBeNull();
62
+ });
63
+
64
+ it('announces typing state when the typing announcement toggle is enabled', () => {
65
+ const { UNSAFE_queryByProps } = renderComponent({
66
+ announceTypingIndicator: true,
67
+ enabled: true,
68
+ });
69
+
70
+ expect(mockUseAnnounceOnStateChange).toHaveBeenCalledWith('Thinking...');
71
+ expect(UNSAFE_queryByProps({ accessibilityLiveRegion: 'polite' })).toBeTruthy();
72
+ });
73
+ });
@@ -0,0 +1,43 @@
1
+ import { useEffect, useRef } from 'react';
2
+
3
+ import { useAccessibilityAnnouncer } from './useAccessibilityAnnouncer';
4
+
5
+ import { useAccessibilityContext } from '../../contexts/accessibilityContext/AccessibilityContext';
6
+ import { useChatContext } from '../../contexts/chatContext/ChatContext';
7
+ import { useTranslationContext } from '../../contexts/translationContext/TranslationContext';
8
+
9
+ /**
10
+ * Mirrors stream-chat-react's `<NotificationAnnouncer />`. RN does not yet have a
11
+ * unified Notification queue, so this component currently announces only
12
+ * connection-state transitions (offline → online and back) gated on
13
+ * `accessibility.announceConnectionState`. Per-channel error announcements can
14
+ * be wired in by a future PR via `useChannelContext().error`.
15
+ *
16
+ * Renders nothing. Mount once inside `<Channel>` (or wherever the active chat
17
+ * surface lives).
18
+ */
19
+ export const NotificationAnnouncer = () => {
20
+ const { announceConnectionState, enabled } = useAccessibilityContext();
21
+ const { connectionRecovering, isOnline } = useChatContext();
22
+ const announce = useAccessibilityAnnouncer();
23
+ const { t } = useTranslationContext();
24
+ const previousIsOnlineRef = useRef<boolean | null | undefined>(undefined);
25
+
26
+ useEffect(() => {
27
+ if (!enabled || !announceConnectionState) return;
28
+ if (previousIsOnlineRef.current === undefined) {
29
+ previousIsOnlineRef.current = isOnline;
30
+ return;
31
+ }
32
+ if (previousIsOnlineRef.current === isOnline) return;
33
+ previousIsOnlineRef.current = isOnline;
34
+
35
+ if (isOnline) {
36
+ announce(t('a11y/Connected'), 'polite');
37
+ } else {
38
+ announce(connectionRecovering ? t('a11y/Reconnecting') : t('a11y/Offline'), 'assertive');
39
+ }
40
+ }, [announce, announceConnectionState, connectionRecovering, enabled, isOnline, t]);
41
+
42
+ return null;
43
+ };
@@ -0,0 +1,75 @@
1
+ import React from 'react';
2
+ import { AccessibilityInfo } from 'react-native';
3
+
4
+ import { renderHook, waitFor } from '@testing-library/react-native';
5
+
6
+ import { AccessibilityProvider } from '../../../contexts/accessibilityContext/AccessibilityContext';
7
+ import { useAccessibilityAnnouncer } from '../useAccessibilityAnnouncer';
8
+
9
+ jest.mock('react-native/Libraries/Components/AccessibilityInfo/AccessibilityInfo', () => ({
10
+ __esModule: true,
11
+ default: {
12
+ announceForAccessibility: jest.fn(),
13
+ addEventListener: jest.fn().mockReturnValue({ remove: jest.fn() }),
14
+ isScreenReaderEnabled: jest.fn().mockResolvedValue(false),
15
+ isReduceMotionEnabled: jest.fn().mockResolvedValue(false),
16
+ },
17
+ }));
18
+
19
+ const wrapper =
20
+ (enabled: boolean) =>
21
+ ({ children }: { children: React.ReactNode }) => (
22
+ <AccessibilityProvider value={{ enabled }}>{children}</AccessibilityProvider>
23
+ );
24
+
25
+ describe('AccessibilityProvider announcer', () => {
26
+ beforeEach(() => {
27
+ (AccessibilityInfo.announceForAccessibility as jest.Mock).mockClear();
28
+ });
29
+
30
+ it('returns a no-op when enabled is false', async () => {
31
+ const { result } = renderHook(() => useAccessibilityAnnouncer(), { wrapper: wrapper(false) });
32
+ result.current('hello');
33
+ await new Promise((r) => setTimeout(r, 80));
34
+ expect(AccessibilityInfo.announceForAccessibility).not.toHaveBeenCalled();
35
+ });
36
+
37
+ it('announces via AccessibilityInfo when enabled', async () => {
38
+ const { result } = renderHook(() => useAccessibilityAnnouncer(), { wrapper: wrapper(true) });
39
+ result.current('hello');
40
+ await waitFor(() =>
41
+ expect(AccessibilityInfo.announceForAccessibility).toHaveBeenCalledWith('hello'),
42
+ );
43
+ });
44
+
45
+ it('flushes only the latest message per priority within the debounce window', async () => {
46
+ const { result } = renderHook(() => useAccessibilityAnnouncer(), { wrapper: wrapper(true) });
47
+ result.current('first');
48
+ result.current('second');
49
+ result.current('third');
50
+ await waitFor(() =>
51
+ expect(AccessibilityInfo.announceForAccessibility).toHaveBeenCalledWith('third'),
52
+ );
53
+ expect(AccessibilityInfo.announceForAccessibility).not.toHaveBeenCalledWith('first');
54
+ expect(AccessibilityInfo.announceForAccessibility).not.toHaveBeenCalledWith('second');
55
+ });
56
+
57
+ it('ignores empty messages', async () => {
58
+ const { result } = renderHook(() => useAccessibilityAnnouncer(), { wrapper: wrapper(true) });
59
+ result.current('');
60
+ await new Promise((r) => setTimeout(r, 80));
61
+ expect(AccessibilityInfo.announceForAccessibility).not.toHaveBeenCalled();
62
+ });
63
+
64
+ it('clears pending announcements on unmount', async () => {
65
+ const { result, unmount } = renderHook(() => useAccessibilityAnnouncer(), {
66
+ wrapper: wrapper(true),
67
+ });
68
+
69
+ result.current('hello');
70
+ unmount();
71
+
72
+ await new Promise((r) => setTimeout(r, 80));
73
+ expect(AccessibilityInfo.announceForAccessibility).not.toHaveBeenCalled();
74
+ });
75
+ });