botframework-webchat-component 4.13.0 → 4.15.0

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 (698) hide show
  1. package/.eslintrc.yml +4 -100
  2. package/.prettierrc.yml +1 -1
  3. package/lib/Activity/Avatar.d.ts +10 -0
  4. package/lib/Activity/Avatar.d.ts.map +1 -0
  5. package/lib/Activity/Avatar.js +2 -1
  6. package/lib/Activity/Bubble.d.ts +11 -0
  7. package/lib/Activity/Bubble.d.ts.map +1 -0
  8. package/lib/Activity/Bubble.js +2 -2
  9. package/lib/Activity/CarouselFilmStrip.js +21 -31
  10. package/lib/Activity/CarouselFilmStripAttachment.js +120 -0
  11. package/lib/Activity/CarouselLayout.js +5 -5
  12. package/lib/Activity/Speak.d.ts +10 -0
  13. package/lib/Activity/Speak.d.ts.map +1 -0
  14. package/lib/Activity/Speak.js +11 -13
  15. package/lib/Activity/StackedLayout.d.ts +18 -0
  16. package/lib/Activity/StackedLayout.d.ts.map +1 -0
  17. package/lib/Activity/StackedLayout.js +19 -15
  18. package/lib/Assets/TypingAnimation.js +2 -2
  19. package/lib/Attachment/Assets/DownloadIcon.js +3 -1
  20. package/lib/Attachment/AudioAttachment.js +2 -2
  21. package/lib/Attachment/AudioContent.d.ts +11 -0
  22. package/lib/Attachment/AudioContent.d.ts.map +1 -0
  23. package/lib/Attachment/AudioContent.js +4 -4
  24. package/lib/Attachment/FileAttachment.js +2 -2
  25. package/lib/Attachment/FileContent.d.ts +10 -0
  26. package/lib/Attachment/FileContent.d.ts.map +1 -0
  27. package/lib/Attachment/FileContent.js +14 -9
  28. package/lib/Attachment/HTMLVideoContent.d.ts +11 -0
  29. package/lib/Attachment/HTMLVideoContent.d.ts.map +1 -0
  30. package/lib/Attachment/HTMLVideoContent.js +2 -2
  31. package/lib/Attachment/ImageContent.d.ts +8 -0
  32. package/lib/Attachment/ImageContent.d.ts.map +1 -0
  33. package/lib/Attachment/ImageContent.js +2 -2
  34. package/lib/Attachment/TextContent.d.ts +8 -0
  35. package/lib/Attachment/TextContent.d.ts.map +1 -0
  36. package/lib/Attachment/TextContent.js +4 -4
  37. package/lib/Attachment/VideoAttachment.js +2 -2
  38. package/lib/Attachment/VideoContent.d.ts +11 -0
  39. package/lib/Attachment/VideoContent.d.ts.map +1 -0
  40. package/lib/Attachment/VideoContent.js +1 -1
  41. package/lib/Attachment/VimeoContent.d.ts +10 -0
  42. package/lib/Attachment/VimeoContent.d.ts.map +1 -0
  43. package/lib/Attachment/VimeoContent.js +8 -8
  44. package/lib/Attachment/YouTubeContent.d.ts +10 -0
  45. package/lib/Attachment/YouTubeContent.d.ts.map +1 -0
  46. package/lib/Attachment/YouTubeContent.js +5 -5
  47. package/lib/Avatar/ImageAvatar.js +2 -2
  48. package/lib/Avatar/InitialsAvatar.js +2 -2
  49. package/lib/BasicConnectivityStatus.js +2 -2
  50. package/lib/BasicSendBox.d.ts +9 -0
  51. package/lib/BasicSendBox.d.ts.map +1 -0
  52. package/lib/BasicSendBox.js +7 -6
  53. package/lib/BasicToast.js +4 -4
  54. package/lib/BasicToaster.js +8 -5
  55. package/lib/BasicTranscript.d.ts +7 -0
  56. package/lib/BasicTranscript.d.ts.map +1 -0
  57. package/lib/BasicTranscript.js +406 -743
  58. package/lib/BasicTypingIndicator.d.ts +6 -0
  59. package/lib/BasicTypingIndicator.d.ts.map +1 -0
  60. package/lib/BasicTypingIndicator.js +13 -5
  61. package/lib/BasicWebChat.d.ts +9 -0
  62. package/lib/BasicWebChat.d.ts.map +1 -0
  63. package/lib/BasicWebChat.js +6 -4
  64. package/lib/Composer.d.ts +23 -0
  65. package/lib/Composer.d.ts.map +1 -0
  66. package/lib/Composer.js +65 -82
  67. package/lib/ConnectivityStatus/Assets/ErrorNotificationIcon.js +2 -2
  68. package/lib/ConnectivityStatus/Assets/SpinnerAnimation.js +2 -2
  69. package/lib/ConnectivityStatus/Assets/WarningNotificationIcon.js +2 -2
  70. package/lib/ConnectivityStatus/Connected.js +1 -1
  71. package/lib/ConnectivityStatus/Connecting.js +4 -4
  72. package/lib/ConnectivityStatus/FailedToConnect.js +2 -2
  73. package/lib/ConnectivityStatus/JavaScriptError.js +2 -2
  74. package/lib/Dictation.js +13 -4
  75. package/lib/ErrorBox.d.ts +8 -0
  76. package/lib/ErrorBox.d.ts.map +1 -0
  77. package/lib/ErrorBox.js +2 -2
  78. package/lib/Middleware/Activity/createCoreMiddleware.d.ts +3 -0
  79. package/lib/Middleware/Activity/createCoreMiddleware.d.ts.map +1 -0
  80. package/lib/Middleware/Activity/createCoreMiddleware.js +1 -1
  81. package/lib/Middleware/ActivityStatus/AbsoluteTime.js +1 -1
  82. package/lib/Middleware/ActivityStatus/RelativeTime.js +1 -1
  83. package/lib/Middleware/ActivityStatus/SendStatus/SendFailedRetry.js +3 -3
  84. package/lib/Middleware/ActivityStatus/SendStatus/SendStatus.d.ts +11 -0
  85. package/lib/Middleware/ActivityStatus/SendStatus/SendStatus.d.ts.map +1 -0
  86. package/lib/Middleware/ActivityStatus/SendStatus/SendStatus.js +5 -5
  87. package/lib/Middleware/ActivityStatus/Timestamp.d.ts +9 -0
  88. package/lib/Middleware/ActivityStatus/Timestamp.d.ts.map +1 -0
  89. package/lib/Middleware/ActivityStatus/Timestamp.js +2 -2
  90. package/lib/Middleware/ActivityStatus/createCoreMiddleware.d.ts +3 -0
  91. package/lib/Middleware/ActivityStatus/createCoreMiddleware.d.ts.map +1 -0
  92. package/lib/Middleware/ActivityStatus/createCoreMiddleware.js +1 -1
  93. package/lib/Middleware/ActivityStatus/createSendStatusMiddleware.js +21 -16
  94. package/lib/Middleware/ActivityStatus/createTimestampMiddleware.js +1 -1
  95. package/lib/Middleware/Attachment/createCoreMiddleware.d.ts +3 -0
  96. package/lib/Middleware/Attachment/createCoreMiddleware.d.ts.map +1 -0
  97. package/lib/Middleware/Attachment/createCoreMiddleware.js +10 -13
  98. package/lib/Middleware/AttachmentForScreenReader/AudioAttachment.js +1 -1
  99. package/lib/Middleware/AttachmentForScreenReader/FileAttachment.js +1 -1
  100. package/lib/Middleware/AttachmentForScreenReader/ImageAttachment.js +1 -1
  101. package/lib/Middleware/AttachmentForScreenReader/TextAttachment.js +1 -1
  102. package/lib/Middleware/AttachmentForScreenReader/VideoAttachment.js +1 -1
  103. package/lib/Middleware/AttachmentForScreenReader/createCoreMiddleware.d.ts +3 -0
  104. package/lib/Middleware/AttachmentForScreenReader/createCoreMiddleware.d.ts.map +1 -0
  105. package/lib/Middleware/AttachmentForScreenReader/createCoreMiddleware.js +9 -5
  106. package/lib/Middleware/Avatar/createCoreMiddleware.d.ts +11 -0
  107. package/lib/Middleware/Avatar/createCoreMiddleware.d.ts.map +1 -0
  108. package/lib/Middleware/Avatar/createCoreMiddleware.js +3 -4
  109. package/lib/Middleware/CardAction/createCoreMiddleware.js +11 -4
  110. package/lib/Middleware/GroupActivities/createCoreMiddleware.js +1 -1
  111. package/lib/Middleware/ScrollToEndButton/ScrollToEndButton.js +71 -0
  112. package/lib/Middleware/ScrollToEndButton/createScrollToEndButtonMiddleware.d.ts +3 -0
  113. package/lib/Middleware/ScrollToEndButton/createScrollToEndButtonMiddleware.d.ts.map +1 -0
  114. package/lib/Middleware/ScrollToEndButton/createScrollToEndButtonMiddleware.js +27 -0
  115. package/lib/Middleware/Toast/createCoreMiddleware.d.ts +4 -0
  116. package/lib/Middleware/Toast/createCoreMiddleware.d.ts.map +1 -0
  117. package/lib/Middleware/Toast/createCoreMiddleware.js +1 -1
  118. package/lib/Middleware/TypingIndicator/createCoreMiddleware.d.ts +3 -0
  119. package/lib/Middleware/TypingIndicator/createCoreMiddleware.d.ts.map +1 -0
  120. package/lib/Middleware/TypingIndicator/createCoreMiddleware.js +9 -6
  121. package/lib/ReactWebChat.d.ts +10 -0
  122. package/lib/ReactWebChat.d.ts.map +1 -0
  123. package/lib/ReactWebChat.js +19 -7
  124. package/lib/ScreenReaderActivity.js +76 -48
  125. package/lib/ScreenReaderText.d.ts +9 -0
  126. package/lib/ScreenReaderText.d.ts.map +1 -0
  127. package/lib/ScreenReaderText.js +22 -8
  128. package/lib/SendBox/Assets/AttachmentIcon.js +3 -1
  129. package/lib/SendBox/Assets/MicrophoneIcon.js +3 -1
  130. package/lib/SendBox/Assets/SendIcon.js +2 -2
  131. package/lib/SendBox/AutoResizeTextArea.d.ts +23 -0
  132. package/lib/SendBox/AutoResizeTextArea.d.ts.map +1 -0
  133. package/lib/SendBox/AutoResizeTextArea.js +6 -6
  134. package/lib/SendBox/DictationInterims.d.ts +9 -0
  135. package/lib/SendBox/DictationInterims.d.ts.map +1 -0
  136. package/lib/SendBox/DictationInterims.js +3 -3
  137. package/lib/SendBox/IconButton.d.ts +11 -0
  138. package/lib/SendBox/IconButton.d.ts.map +1 -0
  139. package/lib/SendBox/IconButton.js +27 -7
  140. package/lib/SendBox/MicrophoneButton.d.ts +11 -0
  141. package/lib/SendBox/MicrophoneButton.d.ts.map +1 -0
  142. package/lib/SendBox/MicrophoneButton.js +25 -24
  143. package/lib/SendBox/SendButton.d.ts +9 -0
  144. package/lib/SendBox/SendButton.d.ts.map +1 -0
  145. package/lib/SendBox/SendButton.js +8 -6
  146. package/lib/SendBox/SuggestedAction.d.ts +17 -0
  147. package/lib/SendBox/SuggestedAction.d.ts.map +1 -0
  148. package/lib/SendBox/SuggestedAction.js +29 -24
  149. package/lib/SendBox/SuggestedActions.d.ts +5 -0
  150. package/lib/SendBox/SuggestedActions.d.ts.map +1 -0
  151. package/lib/SendBox/SuggestedActions.js +33 -13
  152. package/lib/SendBox/TextBox.d.ts +28 -0
  153. package/lib/SendBox/TextBox.d.ts.map +1 -0
  154. package/lib/SendBox/TextBox.js +13 -8
  155. package/lib/SendBox/UploadButton.d.ts +9 -0
  156. package/lib/SendBox/UploadButton.d.ts.map +1 -0
  157. package/lib/SendBox/UploadButton.js +6 -6
  158. package/lib/Styles/StyleSet/Activities.d.ts +5 -0
  159. package/lib/Styles/StyleSet/Activities.d.ts.map +1 -0
  160. package/lib/Styles/StyleSet/AudioAttachment.d.ts +6 -0
  161. package/lib/Styles/StyleSet/AudioAttachment.d.ts.map +1 -0
  162. package/lib/Styles/StyleSet/AudioContent.d.ts +4 -0
  163. package/lib/Styles/StyleSet/AudioContent.d.ts.map +1 -0
  164. package/lib/Styles/StyleSet/AutoResizeTextArea.d.ts +37 -0
  165. package/lib/Styles/StyleSet/AutoResizeTextArea.d.ts.map +1 -0
  166. package/lib/Styles/StyleSet/Avatar.d.ts +9 -0
  167. package/lib/Styles/StyleSet/Avatar.d.ts.map +1 -0
  168. package/lib/Styles/StyleSet/BasicTranscript.d.ts +85 -0
  169. package/lib/Styles/StyleSet/BasicTranscript.d.ts.map +1 -0
  170. package/lib/Styles/StyleSet/BasicTranscript.js +21 -9
  171. package/lib/Styles/StyleSet/Bubble.d.ts +5 -0
  172. package/lib/Styles/StyleSet/Bubble.d.ts.map +1 -0
  173. package/lib/Styles/StyleSet/Bubble.js +2 -2
  174. package/lib/Styles/StyleSet/CarouselFilmStrip.d.ts +5 -0
  175. package/lib/Styles/StyleSet/CarouselFilmStrip.d.ts.map +1 -0
  176. package/lib/Styles/StyleSet/CarouselFilmStrip.js +2 -18
  177. package/lib/Styles/StyleSet/CarouselFilmStripAttachment.d.ts +3 -0
  178. package/lib/Styles/StyleSet/CarouselFilmStripAttachment.d.ts.map +1 -0
  179. package/lib/Styles/StyleSet/CarouselFilmStripAttachment.js +63 -0
  180. package/lib/Styles/StyleSet/CarouselFlipper.d.ts +27 -0
  181. package/lib/Styles/StyleSet/CarouselFlipper.d.ts.map +1 -0
  182. package/lib/Styles/StyleSet/ConnectivityNotification.d.ts +13 -0
  183. package/lib/Styles/StyleSet/ConnectivityNotification.d.ts.map +1 -0
  184. package/lib/Styles/StyleSet/DictationInterims.d.ts +13 -0
  185. package/lib/Styles/StyleSet/DictationInterims.d.ts.map +1 -0
  186. package/lib/Styles/StyleSet/ErrorBox.d.ts +33 -0
  187. package/lib/Styles/StyleSet/ErrorBox.d.ts.map +1 -0
  188. package/lib/Styles/StyleSet/ErrorNotification.d.ts +23 -0
  189. package/lib/Styles/StyleSet/ErrorNotification.d.ts.map +1 -0
  190. package/lib/Styles/StyleSet/FileContent.d.ts +32 -0
  191. package/lib/Styles/StyleSet/FileContent.d.ts.map +1 -0
  192. package/lib/Styles/StyleSet/ImageAvatar.d.ts +7 -0
  193. package/lib/Styles/StyleSet/ImageAvatar.d.ts.map +1 -0
  194. package/lib/Styles/StyleSet/InitialsAvatar.d.ts +19 -0
  195. package/lib/Styles/StyleSet/InitialsAvatar.d.ts.map +1 -0
  196. package/lib/Styles/StyleSet/KeyboardHelp.d.ts +123 -0
  197. package/lib/Styles/StyleSet/KeyboardHelp.d.ts.map +1 -0
  198. package/lib/Styles/StyleSet/KeyboardHelp.js +145 -0
  199. package/lib/Styles/StyleSet/MicrophoneButton.d.ts +13 -0
  200. package/lib/Styles/StyleSet/MicrophoneButton.d.ts.map +1 -0
  201. package/lib/Styles/StyleSet/Root.d.ts +8 -0
  202. package/lib/Styles/StyleSet/Root.d.ts.map +1 -0
  203. package/lib/Styles/StyleSet/ScrollToEndButton.d.ts +36 -0
  204. package/lib/Styles/StyleSet/ScrollToEndButton.d.ts.map +1 -0
  205. package/lib/Styles/StyleSet/ScrollToEndButton.js +36 -34
  206. package/lib/Styles/StyleSet/SendBox.d.ts +24 -0
  207. package/lib/Styles/StyleSet/SendBox.d.ts.map +1 -0
  208. package/lib/Styles/StyleSet/SendBoxButton.d.ts +79 -0
  209. package/lib/Styles/StyleSet/SendBoxButton.d.ts.map +1 -0
  210. package/lib/Styles/StyleSet/SendBoxButton.js +76 -12
  211. package/lib/Styles/StyleSet/SendBoxTextBox.d.ts +41 -0
  212. package/lib/Styles/StyleSet/SendBoxTextBox.d.ts.map +1 -0
  213. package/lib/Styles/StyleSet/SendBoxTextBox.js +3 -3
  214. package/lib/Styles/StyleSet/SendStatus.d.ts +8 -0
  215. package/lib/Styles/StyleSet/SendStatus.d.ts.map +1 -0
  216. package/lib/Styles/StyleSet/SingleAttachmentActivity.d.ts +11 -0
  217. package/lib/Styles/StyleSet/SingleAttachmentActivity.d.ts.map +1 -0
  218. package/lib/Styles/StyleSet/SpinnerAnimation.d.ts +15 -0
  219. package/lib/Styles/StyleSet/SpinnerAnimation.d.ts.map +1 -0
  220. package/lib/Styles/StyleSet/StackedLayout.d.ts +63 -0
  221. package/lib/Styles/StyleSet/StackedLayout.d.ts.map +1 -0
  222. package/lib/Styles/StyleSet/StackedLayout.js +1 -1
  223. package/lib/Styles/StyleSet/SuggestedAction.d.ts +94 -0
  224. package/lib/Styles/StyleSet/SuggestedAction.d.ts.map +1 -0
  225. package/lib/Styles/StyleSet/SuggestedAction.js +116 -41
  226. package/lib/Styles/StyleSet/SuggestedActions.d.ts +125 -0
  227. package/lib/Styles/StyleSet/SuggestedActions.d.ts.map +1 -0
  228. package/lib/Styles/StyleSet/SuggestedActions.js +13 -6
  229. package/lib/Styles/StyleSet/TextContent.d.ts +28 -0
  230. package/lib/Styles/StyleSet/TextContent.d.ts.map +1 -0
  231. package/lib/Styles/StyleSet/Toast.d.ts +65 -0
  232. package/lib/Styles/StyleSet/Toast.d.ts.map +1 -0
  233. package/lib/Styles/StyleSet/Toaster.d.ts +111 -0
  234. package/lib/Styles/StyleSet/Toaster.d.ts.map +1 -0
  235. package/lib/Styles/StyleSet/TypingAnimation.d.ts +8 -0
  236. package/lib/Styles/StyleSet/TypingAnimation.d.ts.map +1 -0
  237. package/lib/Styles/StyleSet/TypingIndicator.d.ts +11 -0
  238. package/lib/Styles/StyleSet/TypingIndicator.d.ts.map +1 -0
  239. package/lib/Styles/StyleSet/UploadButton.d.ts +14 -0
  240. package/lib/Styles/StyleSet/UploadButton.d.ts.map +1 -0
  241. package/lib/Styles/StyleSet/VideoAttachment.d.ts +2 -0
  242. package/lib/Styles/StyleSet/VideoAttachment.d.ts.map +1 -0
  243. package/lib/Styles/StyleSet/VideoContent.d.ts +6 -0
  244. package/lib/Styles/StyleSet/VideoContent.d.ts.map +1 -0
  245. package/lib/Styles/StyleSet/VimeoContent.d.ts +7 -0
  246. package/lib/Styles/StyleSet/VimeoContent.d.ts.map +1 -0
  247. package/lib/Styles/StyleSet/WarningNotification.d.ts +22 -0
  248. package/lib/Styles/StyleSet/WarningNotification.d.ts.map +1 -0
  249. package/lib/Styles/StyleSet/YouTubeContent.d.ts +7 -0
  250. package/lib/Styles/StyleSet/YouTubeContent.d.ts.map +1 -0
  251. package/lib/Styles/createStyleSet.d.ts +1372 -0
  252. package/lib/Styles/createStyleSet.d.ts.map +1 -0
  253. package/lib/Styles/createStyleSet.js +47 -41
  254. package/lib/Styles/mirrorStyle.js +13 -4
  255. package/lib/Toast/CollapseIcon.js +3 -1
  256. package/lib/Toast/DismissIcon.js +3 -1
  257. package/lib/Toast/ExpandIcon.js +3 -1
  258. package/lib/Toast/NotificationIcon.js +7 -3
  259. package/lib/Toast/createToastMiddleware.d.ts +4 -0
  260. package/lib/Toast/createToastMiddleware.d.ts.map +1 -0
  261. package/lib/Toast/createToastMiddleware.js +2 -2
  262. package/lib/Transcript/ActivityRow.d.ts +9 -0
  263. package/lib/Transcript/ActivityRow.d.ts.map +1 -0
  264. package/lib/Transcript/ActivityRow.js +157 -0
  265. package/lib/Transcript/ActivityTextAlt.js +57 -0
  266. package/lib/Transcript/FocusTrap.d.ts +8 -0
  267. package/lib/Transcript/FocusTrap.d.ts.map +1 -0
  268. package/lib/Transcript/FocusTrap.js +74 -0
  269. package/lib/Transcript/KeyboardHelp.d.ts +4 -0
  270. package/lib/Transcript/KeyboardHelp.d.ts.map +1 -0
  271. package/lib/Transcript/KeyboardHelp.js +550 -0
  272. package/lib/Transcript/LiveRegionTranscript.d.ts +8 -0
  273. package/lib/Transcript/LiveRegionTranscript.d.ts.map +1 -0
  274. package/lib/Transcript/LiveRegionTranscript.js +214 -0
  275. package/lib/Transcript/types.d.ts +2 -0
  276. package/lib/Transcript/types.d.ts.map +1 -0
  277. package/lib/Transcript/types.js +2 -0
  278. package/lib/Transcript/useActivityAccessibleName.d.ts +4 -0
  279. package/lib/Transcript/useActivityAccessibleName.d.ts.map +1 -0
  280. package/lib/Transcript/useActivityAccessibleName.js +97 -0
  281. package/lib/Utils/AccessKeySink/Surface.js +7 -5
  282. package/lib/Utils/AccessibleButton.d.ts +11 -0
  283. package/lib/Utils/AccessibleButton.d.ts.map +1 -0
  284. package/lib/Utils/AccessibleButton.js +15 -8
  285. package/lib/Utils/AccessibleInputText.d.ts +21 -0
  286. package/lib/Utils/AccessibleInputText.d.ts.map +1 -0
  287. package/lib/Utils/AccessibleInputText.js +29 -25
  288. package/lib/Utils/AccessibleTextArea.d.ts +20 -0
  289. package/lib/Utils/AccessibleTextArea.d.ts.map +1 -0
  290. package/lib/Utils/AccessibleTextArea.js +35 -24
  291. package/lib/Utils/CroppedImage.js +2 -2
  292. package/lib/Utils/Fade.js +2 -2
  293. package/lib/Utils/FocusRedirector.d.ts +9 -0
  294. package/lib/Utils/FocusRedirector.d.ts.map +1 -0
  295. package/lib/Utils/FocusRedirector.js +18 -15
  296. package/lib/Utils/InlineMarkdown.js +17 -10
  297. package/lib/Utils/TypeFocusSink/FocusBox.js +6 -4
  298. package/lib/Utils/TypeFocusSink/getTabIndex.d.ts +2 -0
  299. package/lib/Utils/TypeFocusSink/getTabIndex.d.ts.map +1 -0
  300. package/lib/Utils/TypeFocusSink/getTabIndex.js +1 -1
  301. package/lib/Utils/TypeFocusSink/inputtableKey.d.ts +2 -0
  302. package/lib/Utils/TypeFocusSink/inputtableKey.d.ts.map +1 -0
  303. package/lib/Utils/TypeFocusSink/inputtableKey.js +5 -2
  304. package/lib/Utils/TypeFocusSink/navigableEvent.js +1 -1
  305. package/lib/Utils/activityAltText.d.ts +8 -0
  306. package/lib/Utils/activityAltText.d.ts.map +1 -0
  307. package/lib/Utils/activityAltText.js +100 -0
  308. package/lib/Utils/addTargetBlankToHyperlinksMarkdown.js +1 -1
  309. package/lib/Utils/createCustomEvent.js +9 -3
  310. package/lib/Utils/debounce.js +1 -1
  311. package/lib/Utils/detectBrowser.js +4 -2
  312. package/lib/Utils/downscaleImageToDataURL/downscaleImageToDataURLUsingWorker.js +3 -3
  313. package/lib/Utils/downscaleImageToDataURL/index.js +2 -2
  314. package/lib/Utils/filterMap.js +1 -1
  315. package/lib/Utils/findAncestor.js +17 -0
  316. package/lib/Utils/getActivityUniqueId.js +4 -2
  317. package/lib/Utils/intersectionOf.d.ts +5 -0
  318. package/lib/Utils/intersectionOf.d.ts.map +1 -0
  319. package/lib/Utils/intersectionOf.js +17 -2
  320. package/lib/Utils/isZeroOrPositive.d.ts +5 -0
  321. package/lib/Utils/isZeroOrPositive.d.ts.map +1 -0
  322. package/lib/Utils/isZeroOrPositive.js +4 -1
  323. package/lib/Utils/mapMap.js +10 -3
  324. package/lib/Utils/readDataURIToBlob.js +3 -3
  325. package/lib/Utils/scrollIntoViewWithBlockNearest.d.ts +7 -0
  326. package/lib/Utils/scrollIntoViewWithBlockNearest.d.ts.map +1 -0
  327. package/lib/Utils/scrollIntoViewWithBlockNearest.js +48 -0
  328. package/lib/Utils/shallowEquals.js +7 -3
  329. package/lib/Utils/singleToArray.js +1 -1
  330. package/lib/Utils/supportPseudoClass.d.ts +2 -0
  331. package/lib/Utils/supportPseudoClass.d.ts.map +1 -0
  332. package/lib/Utils/supportPseudoClass.js +23 -0
  333. package/lib/Utils/tabbableElements.d.ts +2 -0
  334. package/lib/Utils/tabbableElements.d.ts.map +1 -0
  335. package/lib/Utils/tabbableElements.js +2 -2
  336. package/lib/connectToWebChat.js +17 -7
  337. package/lib/hooks/index.d.ts +21 -0
  338. package/lib/hooks/index.d.ts.map +1 -0
  339. package/lib/hooks/index.js +25 -25
  340. package/lib/hooks/internal/BypassSpeechSynthesisPonyfill.js +100 -41
  341. package/lib/hooks/internal/UITracker.js +2 -2
  342. package/lib/hooks/internal/useChanged.js +8 -1
  343. package/lib/hooks/internal/useDispatchScrollPosition.js +3 -7
  344. package/lib/hooks/internal/useDispatchTranscriptFocusByActivityKey.d.ts +2 -0
  345. package/lib/hooks/internal/useDispatchTranscriptFocusByActivityKey.d.ts.map +1 -0
  346. package/lib/hooks/internal/useDispatchTranscriptFocusByActivityKey.js +15 -0
  347. package/lib/hooks/internal/useEnterKeyHint.js +1 -1
  348. package/lib/hooks/internal/useFocusVisible.d.ts +3 -0
  349. package/lib/hooks/internal/useFocusVisible.d.ts.map +1 -0
  350. package/lib/hooks/internal/useFocusVisible.js +48 -0
  351. package/lib/hooks/internal/useForceRender.js +2 -2
  352. package/lib/hooks/internal/useForceRenderAtInterval.js +2 -2
  353. package/lib/hooks/internal/useInternalRenderMarkdownInline.js +1 -1
  354. package/lib/hooks/internal/useLocalizeAccessKey.js +2 -2
  355. package/lib/hooks/internal/useMemoWithPrevious.d.ts +3 -0
  356. package/lib/hooks/internal/useMemoWithPrevious.d.ts.map +1 -0
  357. package/lib/hooks/internal/useMemoWithPrevious.js +22 -0
  358. package/lib/hooks/internal/useMemoize.d.ts +14 -0
  359. package/lib/hooks/internal/useMemoize.d.ts.map +1 -0
  360. package/lib/hooks/internal/useMemoize.js +12 -3
  361. package/lib/hooks/internal/useNavigatorPlatform.js +1 -1
  362. package/lib/hooks/internal/useNonce.js +1 -1
  363. package/lib/hooks/internal/useObserveFocusVisible.d.ts +3 -0
  364. package/lib/hooks/internal/useObserveFocusVisible.d.ts.map +1 -0
  365. package/lib/hooks/internal/useObserveFocusVisible.js +208 -0
  366. package/lib/hooks/internal/usePrevious.d.ts +2 -0
  367. package/lib/hooks/internal/usePrevious.d.ts.map +1 -0
  368. package/lib/hooks/internal/usePrevious.js +18 -0
  369. package/lib/hooks/internal/useRegisterFocusSendBox.js +1 -1
  370. package/lib/hooks/internal/useRegisterFocusTranscript.js +1 -1
  371. package/lib/hooks/internal/useRegisterScrollRelative.js +1 -1
  372. package/lib/hooks/internal/useRegisterScrollTo.js +1 -1
  373. package/lib/hooks/internal/useRegisterScrollToEnd.js +1 -1
  374. package/lib/hooks/internal/useReplaceEmoticon.js +2 -2
  375. package/lib/hooks/internal/useResumeAudioContext.js +33 -0
  376. package/lib/hooks/internal/useScrollRelative.js +1 -1
  377. package/lib/hooks/internal/useSettableDictateAbortable.js +1 -1
  378. package/lib/hooks/internal/useStateRef.d.ts +3 -0
  379. package/lib/hooks/internal/useStateRef.d.ts.map +1 -0
  380. package/lib/hooks/internal/useStateRef.js +40 -0
  381. package/lib/hooks/internal/useSuggestedActionsAccessKey.js +1 -1
  382. package/lib/hooks/internal/useUniqueId.d.ts +2 -0
  383. package/lib/hooks/internal/useUniqueId.d.ts.map +1 -0
  384. package/lib/hooks/internal/useUniqueId.js +1 -1
  385. package/lib/hooks/internal/useValueRef.d.ts +3 -0
  386. package/lib/hooks/internal/useValueRef.d.ts.map +1 -0
  387. package/lib/hooks/internal/useValueRef.js +25 -0
  388. package/lib/hooks/useDictateAbortable.d.ts +2 -0
  389. package/lib/hooks/useDictateAbortable.d.ts.map +1 -0
  390. package/lib/hooks/useDictateAbortable.js +2 -2
  391. package/lib/hooks/useFocus.d.ts +2 -0
  392. package/lib/hooks/useFocus.d.ts.map +1 -0
  393. package/lib/hooks/useFocus.js +1 -1
  394. package/lib/hooks/useFocusSendBox.d.ts +3 -0
  395. package/lib/hooks/useFocusSendBox.d.ts.map +1 -0
  396. package/lib/hooks/useFocusSendBox.js +2 -1
  397. package/lib/hooks/useObserveScrollPosition.d.ts +3 -0
  398. package/lib/hooks/useObserveScrollPosition.d.ts.map +1 -0
  399. package/lib/hooks/useObserveScrollPosition.js +2 -2
  400. package/lib/hooks/useObserveTranscriptFocus.d.ts +5 -0
  401. package/lib/hooks/useObserveTranscriptFocus.d.ts.map +1 -0
  402. package/lib/hooks/useObserveTranscriptFocus.js +2 -2
  403. package/lib/hooks/useRenderMarkdownAsHTML.d.ts +5 -0
  404. package/lib/hooks/useRenderMarkdownAsHTML.d.ts.map +1 -0
  405. package/lib/hooks/useRenderMarkdownAsHTML.js +2 -2
  406. package/lib/hooks/useScrollDown.d.ts +4 -0
  407. package/lib/hooks/useScrollDown.d.ts.map +1 -0
  408. package/lib/hooks/useScrollDown.js +1 -1
  409. package/lib/hooks/useScrollTo.d.ts +5 -0
  410. package/lib/hooks/useScrollTo.d.ts.map +1 -0
  411. package/lib/hooks/useScrollTo.js +1 -1
  412. package/lib/hooks/useScrollToEnd.d.ts +2 -0
  413. package/lib/hooks/useScrollToEnd.d.ts.map +1 -0
  414. package/lib/hooks/useScrollToEnd.js +1 -1
  415. package/lib/hooks/useScrollUp.d.ts +4 -0
  416. package/lib/hooks/useScrollUp.d.ts.map +1 -0
  417. package/lib/hooks/useScrollUp.js +1 -1
  418. package/lib/hooks/useSendFiles.d.ts +2 -0
  419. package/lib/hooks/useSendFiles.d.ts.map +1 -0
  420. package/lib/hooks/useSendFiles.js +3 -3
  421. package/lib/hooks/useStyleSet.d.ts +2 -0
  422. package/lib/hooks/useStyleSet.d.ts.map +1 -0
  423. package/lib/hooks/useStyleSet.js +1 -1
  424. package/lib/hooks/useWebSpeechPonyfill.d.ts +3 -0
  425. package/lib/hooks/useWebSpeechPonyfill.d.ts.map +1 -0
  426. package/lib/hooks/useWebSpeechPonyfill.js +1 -1
  427. package/lib/index.d.ts +219 -22
  428. package/lib/index.d.ts.map +1 -1
  429. package/lib/index.js +22 -20
  430. package/lib/providers/ActivityTree/ActivityTreeComposer.d.ts +5 -0
  431. package/lib/providers/ActivityTree/ActivityTreeComposer.d.ts.map +1 -0
  432. package/lib/providers/ActivityTree/ActivityTreeComposer.js +86 -0
  433. package/lib/providers/ActivityTree/private/Context.d.ts +9 -0
  434. package/lib/providers/ActivityTree/private/Context.d.ts.map +1 -0
  435. package/lib/providers/ActivityTree/private/Context.js +13 -0
  436. package/lib/providers/ActivityTree/private/types.d.ts +10 -0
  437. package/lib/providers/ActivityTree/private/types.d.ts.map +1 -0
  438. package/lib/providers/ActivityTree/private/types.js +2 -0
  439. package/lib/providers/ActivityTree/private/useActivitiesWithRenderer.d.ts +4 -0
  440. package/lib/providers/ActivityTree/private/useActivitiesWithRenderer.d.ts.map +1 -0
  441. package/lib/providers/ActivityTree/private/useActivitiesWithRenderer.js +58 -0
  442. package/lib/providers/ActivityTree/private/useActivityTreeWithRenderer.d.ts +5 -0
  443. package/lib/providers/ActivityTree/private/useActivityTreeWithRenderer.d.ts.map +1 -0
  444. package/lib/providers/ActivityTree/private/useActivityTreeWithRenderer.js +166 -0
  445. package/lib/providers/ActivityTree/private/useContext.d.ts +3 -0
  446. package/lib/providers/ActivityTree/private/useContext.d.ts.map +1 -0
  447. package/lib/providers/ActivityTree/private/useContext.js +24 -0
  448. package/lib/providers/ActivityTree/useActivityTreeWithRenderer.d.ts +8 -0
  449. package/lib/providers/ActivityTree/useActivityTreeWithRenderer.d.ts.map +1 -0
  450. package/lib/providers/ActivityTree/useActivityTreeWithRenderer.js +17 -0
  451. package/lib/providers/LiveRegionTwin/LiveRegionTwinComposer.d.ts +35 -0
  452. package/lib/providers/LiveRegionTwin/LiveRegionTwinComposer.d.ts.map +1 -0
  453. package/lib/providers/LiveRegionTwin/LiveRegionTwinComposer.js +156 -0
  454. package/lib/providers/LiveRegionTwin/private/Context.d.ts +10 -0
  455. package/lib/providers/LiveRegionTwin/private/Context.d.ts.map +1 -0
  456. package/lib/providers/LiveRegionTwin/private/Context.js +13 -0
  457. package/lib/providers/LiveRegionTwin/private/LiveRegionTwinContainer.d.ts +11 -0
  458. package/lib/providers/LiveRegionTwin/private/LiveRegionTwinContainer.d.ts.map +1 -0
  459. package/lib/providers/LiveRegionTwin/private/LiveRegionTwinContainer.js +86 -0
  460. package/lib/providers/LiveRegionTwin/private/types.d.ts +8 -0
  461. package/lib/providers/LiveRegionTwin/private/types.d.ts.map +1 -0
  462. package/lib/providers/LiveRegionTwin/private/types.js +2 -0
  463. package/lib/providers/LiveRegionTwin/private/useContext.d.ts +3 -0
  464. package/lib/providers/LiveRegionTwin/private/useContext.d.ts.map +1 -0
  465. package/lib/providers/LiveRegionTwin/private/useContext.js +24 -0
  466. package/lib/providers/LiveRegionTwin/private/useMarkAllAsRenderedEffect.d.ts +2 -0
  467. package/lib/providers/LiveRegionTwin/private/useMarkAllAsRenderedEffect.d.ts.map +1 -0
  468. package/lib/providers/LiveRegionTwin/private/useMarkAllAsRenderedEffect.js +24 -0
  469. package/lib/providers/LiveRegionTwin/private/useStaticElementEntries.d.ts +3 -0
  470. package/lib/providers/LiveRegionTwin/private/useStaticElementEntries.d.ts.map +1 -0
  471. package/lib/providers/LiveRegionTwin/private/useStaticElementEntries.js +15 -0
  472. package/lib/providers/LiveRegionTwin/useQueueStaticElement.d.ts +8 -0
  473. package/lib/providers/LiveRegionTwin/useQueueStaticElement.d.ts.map +1 -0
  474. package/lib/providers/LiveRegionTwin/useQueueStaticElement.js +20 -0
  475. package/lib/providers/TranscriptFocus/TranscriptFocusComposer.d.ts +7 -0
  476. package/lib/providers/TranscriptFocus/TranscriptFocusComposer.d.ts.map +1 -0
  477. package/lib/providers/TranscriptFocus/TranscriptFocusComposer.js +184 -0
  478. package/lib/providers/TranscriptFocus/private/Context.d.ts +12 -0
  479. package/lib/providers/TranscriptFocus/private/Context.d.ts.map +1 -0
  480. package/lib/providers/TranscriptFocus/private/Context.js +13 -0
  481. package/lib/providers/TranscriptFocus/private/useContext.d.ts +2 -0
  482. package/lib/providers/TranscriptFocus/private/useContext.d.ts.map +1 -0
  483. package/lib/providers/TranscriptFocus/private/useContext.js +24 -0
  484. package/lib/providers/TranscriptFocus/useActiveDescendantId.d.ts +2 -0
  485. package/lib/providers/TranscriptFocus/useActiveDescendantId.d.ts.map +1 -0
  486. package/lib/providers/TranscriptFocus/useActiveDescendantId.js +15 -0
  487. package/lib/providers/TranscriptFocus/useFocusByActivityKey.d.ts +8 -0
  488. package/lib/providers/TranscriptFocus/useFocusByActivityKey.d.ts.map +1 -0
  489. package/lib/providers/TranscriptFocus/useFocusByActivityKey.js +21 -0
  490. package/lib/providers/TranscriptFocus/useFocusRelativeActivity.d.ts +2 -0
  491. package/lib/providers/TranscriptFocus/useFocusRelativeActivity.d.ts.map +1 -0
  492. package/lib/providers/TranscriptFocus/useFocusRelativeActivity.js +15 -0
  493. package/lib/providers/TranscriptFocus/useFocusedActivityKey.d.ts +2 -0
  494. package/lib/providers/TranscriptFocus/useFocusedActivityKey.d.ts.map +1 -0
  495. package/lib/providers/TranscriptFocus/useFocusedActivityKey.js +15 -0
  496. package/lib/providers/TranscriptFocus/useFocusedExplicitly.d.ts +2 -0
  497. package/lib/providers/TranscriptFocus/useFocusedExplicitly.d.ts.map +1 -0
  498. package/lib/providers/TranscriptFocus/useFocusedExplicitly.js +15 -0
  499. package/lib/providers/TranscriptFocus/useGetDescendantIdByActivityKey.d.ts +2 -0
  500. package/lib/providers/TranscriptFocus/useGetDescendantIdByActivityKey.d.ts.map +1 -0
  501. package/lib/providers/TranscriptFocus/useGetDescendantIdByActivityKey.js +15 -0
  502. package/lib/tsconfig.json +1 -1
  503. package/lib/types/ScrollPosition.d.ts +6 -0
  504. package/lib/types/ScrollPosition.d.ts.map +1 -0
  505. package/lib/types/ScrollPosition.js +2 -0
  506. package/package.json +33 -40
  507. package/src/Activity/{Avatar.js → Avatar.tsx} +9 -2
  508. package/src/Activity/{Bubble.js → Bubble.tsx} +10 -2
  509. package/src/Activity/CarouselFilmStrip.js +20 -29
  510. package/src/Activity/CarouselFilmStripAttachment.js +91 -0
  511. package/src/Activity/{Speak.js → Speak.tsx} +12 -5
  512. package/src/Activity/{StackedLayout.js → StackedLayout.tsx} +46 -20
  513. package/src/Attachment/Assets/DownloadIcon.js +8 -1
  514. package/src/Attachment/{AudioContent.js → AudioContent.tsx} +12 -3
  515. package/src/Attachment/FileAttachment.js +1 -1
  516. package/src/Attachment/{FileContent.js → FileContent.tsx} +22 -7
  517. package/src/Attachment/{HTMLVideoContent.js → HTMLVideoContent.tsx} +10 -2
  518. package/src/Attachment/{ImageContent.js → ImageContent.tsx} +7 -2
  519. package/src/Attachment/{TextContent.js → TextContent.tsx} +14 -7
  520. package/src/Attachment/{VideoContent.js → VideoContent.tsx} +10 -2
  521. package/src/Attachment/{VimeoContent.js → VimeoContent.tsx} +15 -8
  522. package/src/Attachment/{YouTubeContent.js → YouTubeContent.tsx} +12 -5
  523. package/src/{BasicSendBox.js → BasicSendBox.tsx} +9 -5
  524. package/src/BasicToaster.js +9 -5
  525. package/src/BasicTranscript.tsx +878 -0
  526. package/src/{BasicTypingIndicator.js → BasicTypingIndicator.tsx} +4 -3
  527. package/src/{BasicWebChat.js → BasicWebChat.tsx} +13 -4
  528. package/src/{Composer.js → Composer.tsx} +82 -71
  529. package/src/Dictation.js +13 -4
  530. package/src/{ErrorBox.js → ErrorBox.tsx} +7 -2
  531. package/src/Middleware/Activity/createCoreMiddleware.tsx +78 -0
  532. package/src/Middleware/ActivityStatus/SendStatus/{SendStatus.js → SendStatus.tsx} +8 -3
  533. package/src/Middleware/ActivityStatus/{Timestamp.js → Timestamp.tsx} +8 -2
  534. package/src/Middleware/ActivityStatus/{createCoreMiddleware.js → createCoreMiddleware.tsx} +3 -1
  535. package/src/Middleware/ActivityStatus/createSendStatusMiddleware.js +10 -6
  536. package/src/Middleware/ActivityStatus/createTimestampMiddleware.js +10 -8
  537. package/src/Middleware/Attachment/createCoreMiddleware.tsx +44 -0
  538. package/src/Middleware/AttachmentForScreenReader/createCoreMiddleware.tsx +40 -0
  539. package/src/Middleware/Avatar/{createCoreMiddleware.js → createCoreMiddleware.tsx} +19 -11
  540. package/src/Middleware/CardAction/createCoreMiddleware.js +51 -42
  541. package/src/Middleware/GroupActivities/createCoreMiddleware.js +6 -4
  542. package/src/Middleware/ScrollToEndButton/ScrollToEndButton.js +45 -0
  543. package/src/Middleware/ScrollToEndButton/createScrollToEndButtonMiddleware.ts +19 -0
  544. package/src/Middleware/Toast/createCoreMiddleware.tsx +24 -0
  545. package/src/Middleware/TypingIndicator/{createCoreMiddleware.js → createCoreMiddleware.tsx} +10 -5
  546. package/src/{ReactWebChat.js → ReactWebChat.tsx} +25 -7
  547. package/src/ScreenReaderActivity.js +65 -40
  548. package/src/{ScreenReaderText.js → ScreenReaderText.tsx} +27 -9
  549. package/src/SendBox/Assets/AttachmentIcon.js +1 -1
  550. package/src/SendBox/Assets/MicrophoneIcon.js +1 -1
  551. package/src/SendBox/{AutoResizeTextArea.js → AutoResizeTextArea.tsx} +30 -4
  552. package/src/SendBox/{DictationInterims.js → DictationInterims.tsx} +6 -2
  553. package/src/SendBox/{IconButton.js → IconButton.tsx} +19 -3
  554. package/src/SendBox/{MicrophoneButton.js → MicrophoneButton.tsx} +35 -25
  555. package/src/SendBox/{SendButton.js → SendButton.tsx} +8 -3
  556. package/src/SendBox/{SuggestedAction.js → SuggestedAction.tsx} +62 -39
  557. package/src/SendBox/{SuggestedActions.js → SuggestedActions.tsx} +70 -22
  558. package/src/SendBox/{TextBox.js → TextBox.tsx} +21 -7
  559. package/src/SendBox/{UploadButton.js → UploadButton.tsx} +7 -3
  560. package/src/Styles/StyleSet/BasicTranscript.ts +34 -20
  561. package/src/Styles/StyleSet/Bubble.ts +0 -1
  562. package/src/Styles/StyleSet/CarouselFilmStrip.ts +12 -30
  563. package/src/Styles/StyleSet/CarouselFilmStripAttachment.ts +57 -0
  564. package/src/Styles/StyleSet/KeyboardHelp.ts +157 -0
  565. package/src/Styles/StyleSet/ScrollToEndButton.ts +33 -31
  566. package/src/Styles/StyleSet/SendBoxButton.ts +84 -13
  567. package/src/Styles/StyleSet/SendBoxTextBox.ts +1 -2
  568. package/src/Styles/StyleSet/StackedLayout.ts +13 -11
  569. package/src/Styles/StyleSet/SuggestedAction.ts +130 -43
  570. package/src/Styles/StyleSet/SuggestedActions.ts +13 -5
  571. package/src/Styles/createStyleSet.ts +43 -40
  572. package/src/Styles/mirrorStyle.js +10 -2
  573. package/src/Toast/CollapseIcon.js +9 -1
  574. package/src/Toast/DismissIcon.js +9 -1
  575. package/src/Toast/ExpandIcon.js +9 -1
  576. package/src/Toast/NotificationIcon.js +4 -1
  577. package/src/Toast/createToastMiddleware.tsx +15 -0
  578. package/src/Transcript/ActivityRow.tsx +124 -0
  579. package/src/Transcript/ActivityTextAlt.tsx +32 -0
  580. package/src/Transcript/FocusTrap.tsx +64 -0
  581. package/src/Transcript/KeyboardHelp.tsx +282 -0
  582. package/src/Transcript/LiveRegionTranscript.tsx +181 -0
  583. package/src/Transcript/types.ts +1 -0
  584. package/src/Transcript/useActivityAccessibleName.ts +85 -0
  585. package/src/Utils/{AccessibleButton.js → AccessibleButton.tsx} +19 -4
  586. package/src/Utils/{AccessibleInputText.js → AccessibleInputText.tsx} +48 -5
  587. package/src/Utils/{AccessibleTextArea.js → AccessibleTextArea.tsx} +67 -6
  588. package/src/Utils/{FocusRedirector.js → FocusRedirector.tsx} +21 -8
  589. package/src/Utils/InlineMarkdown.js +18 -2
  590. package/src/Utils/TypeFocusSink/FocusBox.js +4 -4
  591. package/src/Utils/TypeFocusSink/getTabIndex.ts +1 -1
  592. package/src/Utils/TypeFocusSink/inputtableKey.ts +5 -1
  593. package/src/Utils/activityAltText.ts +135 -0
  594. package/src/Utils/createCustomEvent.js +7 -1
  595. package/src/Utils/detectBrowser.js +2 -1
  596. package/src/Utils/findAncestor.ts +12 -0
  597. package/src/Utils/getActivityUniqueId.ts +5 -0
  598. package/src/Utils/intersectionOf.spec.js +2 -0
  599. package/src/Utils/intersectionOf.ts +14 -0
  600. package/src/Utils/isZeroOrPositive.ts +7 -0
  601. package/src/Utils/mapMap.js +7 -1
  602. package/src/Utils/mapMap.spec.js +2 -0
  603. package/src/Utils/removeInline.spec.js +2 -0
  604. package/src/Utils/scrollIntoViewWithBlockNearest.ts +20 -0
  605. package/src/Utils/shallowEquals.js +8 -1
  606. package/src/Utils/{singleToArray.js → singleToArray.ts} +1 -1
  607. package/src/Utils/supportPseudoClass.ts +17 -0
  608. package/src/Utils/{tabbableElements.js → tabbableElements.ts} +6 -5
  609. package/src/Utils/walkMarkdownTokens.spec.js +3 -3
  610. package/src/connectToWebChat.js +11 -4
  611. package/src/hooks/{index.js → index.ts} +1 -0
  612. package/src/hooks/internal/BypassSpeechSynthesisPonyfill.js +70 -17
  613. package/src/hooks/internal/useChanged.ts +17 -0
  614. package/src/hooks/internal/useDispatchScrollPosition.js +1 -3
  615. package/src/hooks/internal/useDispatchTranscriptFocusByActivityKey.ts +5 -0
  616. package/src/hooks/internal/useFocusVisible.ts +22 -0
  617. package/src/hooks/internal/useMemoWithPrevious.ts +16 -0
  618. package/src/hooks/internal/useMemoize.spec.js +3 -1
  619. package/src/hooks/internal/useMemoize.ts +53 -0
  620. package/src/hooks/internal/useObserveFocusVisible.ts +252 -0
  621. package/src/hooks/internal/usePrevious.ts +12 -0
  622. package/src/hooks/internal/useResumeAudioContext.ts +7 -0
  623. package/src/hooks/internal/useScrollRelative.js +4 -3
  624. package/src/hooks/internal/useStateRef.ts +31 -0
  625. package/src/hooks/internal/{useUniqueId.js → useUniqueId.ts} +1 -1
  626. package/src/hooks/internal/useValueRef.ts +22 -0
  627. package/src/hooks/{useDictateAbortable.js → useDictateAbortable.ts} +1 -1
  628. package/src/hooks/{useFocus.js → useFocus.ts} +1 -1
  629. package/src/hooks/{useFocusSendBox.js → useFocusSendBox.ts} +2 -1
  630. package/src/hooks/{useObserveScrollPosition.js → useObserveScrollPosition.ts} +6 -1
  631. package/src/hooks/{useObserveTranscriptFocus.js → useObserveTranscriptFocus.ts} +6 -1
  632. package/src/hooks/useRenderMarkdownAsHTML.ts +23 -0
  633. package/src/hooks/{useScrollDown.js → useScrollDown.ts} +1 -1
  634. package/src/hooks/useScrollTo.ts +16 -0
  635. package/src/hooks/useScrollToEnd.ts +12 -0
  636. package/src/hooks/{useScrollUp.js → useScrollUp.ts} +1 -1
  637. package/src/hooks/{useSendFiles.js → useSendFiles.ts} +3 -2
  638. package/src/hooks/{useStyleSet.js → useStyleSet.ts} +1 -1
  639. package/src/hooks/useWebSpeechPonyfill.ts +7 -0
  640. package/src/index.ts +7 -12
  641. package/src/providers/ActivityTree/ActivityTreeComposer.tsx +74 -0
  642. package/src/providers/ActivityTree/private/Context.ts +12 -0
  643. package/src/providers/ActivityTree/private/types.ts +12 -0
  644. package/src/providers/ActivityTree/private/useActivitiesWithRenderer.ts +66 -0
  645. package/src/providers/ActivityTree/private/useActivityTreeWithRenderer.ts +140 -0
  646. package/src/providers/ActivityTree/private/useContext.ts +15 -0
  647. package/src/providers/ActivityTree/useActivityTreeWithRenderer.ts +16 -0
  648. package/src/providers/LiveRegionTwin/LiveRegionTwinComposer.tsx +154 -0
  649. package/src/providers/LiveRegionTwin/private/Context.ts +15 -0
  650. package/src/providers/LiveRegionTwin/private/LiveRegionTwinContainer.tsx +64 -0
  651. package/src/providers/LiveRegionTwin/private/types.ts +10 -0
  652. package/src/providers/LiveRegionTwin/private/useContext.ts +15 -0
  653. package/src/providers/LiveRegionTwin/private/useMarkAllAsRenderedEffect.ts +13 -0
  654. package/src/providers/LiveRegionTwin/private/useStaticElementEntries.ts +7 -0
  655. package/src/providers/LiveRegionTwin/useQueueStaticElement.ts +12 -0
  656. package/src/providers/TranscriptFocus/TranscriptFocusComposer.tsx +180 -0
  657. package/src/providers/TranscriptFocus/private/Context.ts +16 -0
  658. package/src/providers/TranscriptFocus/private/useContext.ts +13 -0
  659. package/src/providers/TranscriptFocus/useActiveDescendantId.ts +5 -0
  660. package/src/providers/TranscriptFocus/useFocusByActivityKey.ts +14 -0
  661. package/src/providers/TranscriptFocus/useFocusRelativeActivity.ts +5 -0
  662. package/src/providers/TranscriptFocus/useFocusedActivityKey.ts +5 -0
  663. package/src/providers/TranscriptFocus/useFocusedExplicitly.ts +5 -0
  664. package/src/providers/TranscriptFocus/useGetDescendantIdByActivityKey.ts +5 -0
  665. package/src/tsconfig.json +1 -1
  666. package/src/types/ScrollPosition.ts +6 -0
  667. package/.eslintignore +0 -9
  668. package/lib/Activity/ScrollToEndButton.js +0 -81
  669. package/lib/Attachment/Assets/ErrorIcon.js +0 -22
  670. package/lib/Utils/findLastIndex.js +0 -32
  671. package/lib/Utils/remarkStripMarkdown.js +0 -26
  672. package/lib/hooks/internal/useAcknowledgedActivity.js +0 -90
  673. package/lib/hooks/internal/useDispatchTranscriptFocus.js +0 -19
  674. package/lib/hooks/internal/useStripMarkdown.js +0 -19
  675. package/src/Activity/ScrollToEndButton.js +0 -58
  676. package/src/Attachment/Assets/ErrorIcon.js +0 -9
  677. package/src/BasicTranscript.js +0 -1123
  678. package/src/Middleware/Activity/createCoreMiddleware.js +0 -71
  679. package/src/Middleware/Attachment/createCoreMiddleware.js +0 -43
  680. package/src/Middleware/AttachmentForScreenReader/createCoreMiddleware.js +0 -37
  681. package/src/Middleware/Toast/createCoreMiddleware.js +0 -20
  682. package/src/Toast/createToastMiddleware.js +0 -11
  683. package/src/Utils/findLastIndex.js +0 -11
  684. package/src/Utils/findLastIndex.spec.js +0 -29
  685. package/src/Utils/getActivityUniqueId.js +0 -3
  686. package/src/Utils/intersectionOf.js +0 -11
  687. package/src/Utils/isZeroOrPositive.js +0 -4
  688. package/src/Utils/remarkStripMarkdown.js +0 -13
  689. package/src/hooks/internal/useAcknowledgedActivity.js +0 -65
  690. package/src/hooks/internal/useChanged.js +0 -10
  691. package/src/hooks/internal/useDispatchTranscriptFocus.js +0 -7
  692. package/src/hooks/internal/useMemoize.js +0 -37
  693. package/src/hooks/internal/useStripMarkdown.js +0 -7
  694. package/src/hooks/useRenderMarkdownAsHTML.js +0 -20
  695. package/src/hooks/useScrollTo.js +0 -11
  696. package/src/hooks/useScrollToEnd.js +0 -11
  697. package/src/hooks/useWebSpeechPonyfill.js +0 -5
  698. package/src/index.tsx +0 -35
@@ -1,1123 +0,0 @@
1
- /* eslint no-magic-numbers: ["error", { "ignore": [-1, 0, 1, 2, 5, 36] }] */
2
-
3
- import { hooks } from 'botframework-webchat-api';
4
- import {
5
- Composer as ReactScrollToBottomComposer,
6
- Panel as ReactScrollToBottomPanel,
7
- useAnimatingToEnd,
8
- useObserveScrollPosition,
9
- useScrollTo,
10
- useScrollToEnd,
11
- useSticky
12
- } from 'react-scroll-to-bottom';
13
- import classNames from 'classnames';
14
- import PropTypes from 'prop-types';
15
- import random from 'math-random';
16
- import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';
17
-
18
- import BasicTypingIndicator from './BasicTypingIndicator';
19
- import Fade from './Utils/Fade';
20
- import FocusRedirector from './Utils/FocusRedirector';
21
- import getActivityUniqueId from './Utils/getActivityUniqueId';
22
- import getTabIndex from './Utils/TypeFocusSink/getTabIndex';
23
- import inputtableKey from './Utils/TypeFocusSink/inputtableKey';
24
- import intersectionOf from './Utils/intersectionOf';
25
- import isZeroOrPositive from './Utils/isZeroOrPositive';
26
- import removeInline from './Utils/removeInline';
27
- import ScreenReaderActivity from './ScreenReaderActivity';
28
- import ScreenReaderText from './ScreenReaderText';
29
- import ScrollToEndButton from './Activity/ScrollToEndButton';
30
- import SpeakActivity from './Activity/Speak';
31
- import tabbableElements from './Utils/tabbableElements';
32
- import useAcknowledgedActivity from './hooks/internal/useAcknowledgedActivity';
33
- import useDispatchScrollPosition from './hooks/internal/useDispatchScrollPosition';
34
- import useDispatchTranscriptFocus from './hooks/internal/useDispatchTranscriptFocus';
35
- import useFocus from './hooks/useFocus';
36
- import useMemoize from './hooks/internal/useMemoize';
37
- import useRegisterFocusTranscript from './hooks/internal/useRegisterFocusTranscript';
38
- import useRegisterScrollRelative from './hooks/internal/useRegisterScrollRelative';
39
- import useRegisterScrollTo from './hooks/internal/useRegisterScrollTo';
40
- import useRegisterScrollToEnd from './hooks/internal/useRegisterScrollToEnd';
41
- import useStyleSet from './hooks/useStyleSet';
42
- import useStyleToEmotionObject from './hooks/internal/useStyleToEmotionObject';
43
- import useUniqueId from './hooks/internal/useUniqueId';
44
-
45
- const {
46
- useActivities,
47
- useCreateActivityRenderer,
48
- useCreateActivityStatusRenderer,
49
- useCreateAvatarRenderer,
50
- useDirection,
51
- useGroupActivities,
52
- useLocalizer,
53
- useStyleOptions
54
- } = hooks;
55
-
56
- const ROOT_STYLE = {
57
- '&.webchat__basic-transcript': {
58
- display: 'flex',
59
- flexDirection: 'column',
60
- overflow: 'hidden',
61
- // Make sure to set "position: relative" here to form another stacking context for the scroll-to-end button.
62
- // Stacking context help isolating elements that use "z-index" from global pollution.
63
- // https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Positioning/Understanding_z_index/The_stacking_context
64
- position: 'relative',
65
-
66
- '& .webchat__basic-transcript__filler': {
67
- flex: 1
68
- },
69
-
70
- '& .webchat__basic-transcript__scrollable': {
71
- display: 'flex',
72
- flexDirection: 'column',
73
- overflowX: 'hidden',
74
- WebkitOverflowScrolling: 'touch'
75
- },
76
-
77
- '& .webchat__basic-transcript__transcript': {
78
- listStyleType: 'none'
79
- }
80
- }
81
- };
82
-
83
- function validateAllActivitiesTagged(activities, bins) {
84
- return activities.every(activity => bins.some(bin => bin.includes(activity)));
85
- }
86
-
87
- const InternalTranscript = ({ activityElementsRef, className }) => {
88
- const [{ basicTranscript: basicTranscriptStyleSet }] = useStyleSet();
89
- const [
90
- { bubbleFromUserNubOffset, bubbleNubOffset, groupTimestamp, internalLiveRegionFadeAfter, showAvatarInGroup }
91
- ] = useStyleOptions();
92
- const [focusedActivityKey, setFocusedActivityKey] = useState();
93
- const [activities] = useActivities();
94
- const [direction] = useDirection();
95
- const createActivityRenderer = useCreateActivityRenderer();
96
- const createActivityStatusRenderer = useCreateActivityStatusRenderer();
97
- const createAvatarRenderer = useCreateAvatarRenderer();
98
- const focus = useFocus();
99
- const groupActivities = useGroupActivities();
100
- const localize = useLocalizer();
101
- const rootClassName = useStyleToEmotionObject()(ROOT_STYLE) + '';
102
- const rootElementRef = useRef();
103
- const terminatorRef = useRef();
104
-
105
- const activityInteractiveAlt = localize('ACTIVITY_INTERACTIVE_LABEL_ALT');
106
- const terminatorText = localize('TRANSCRIPT_TERMINATOR_TEXT');
107
- const transcriptAriaLabel = localize('TRANSCRIPT_ARIA_LABEL_ALT');
108
- const transcriptRoleDescription = localize('TRANSCRIPT_ARIA_ROLE_ALT');
109
-
110
- const hideAllTimestamps = groupTimestamp === false;
111
-
112
- // Gets renderer for every activity.
113
- // Activities that are not visible will return a falsy renderer.
114
-
115
- // Converted from createActivityRenderer({ activity, nextVisibleActivity }) to createActivityRenderer(activity, nextVisibleActivity).
116
- // This is for the memoization function to cache the arguments. Memoizer can only cache literal arguments.
117
- const createActivityRendererWithLiteralArgs = useCallback(
118
- (activity, nextVisibleActivity) => createActivityRenderer({ activity, nextVisibleActivity }),
119
- [createActivityRenderer]
120
- );
121
-
122
- // Create a memoized context of the createActivityRenderer function.
123
- const activitiesWithRenderer = useMemoize(
124
- createActivityRendererWithLiteralArgs,
125
- createActivityRendererWithLiteralArgsMemoized => {
126
- // All calls to createActivityRendererWithLiteralArgsMemoized() in this function will be memoized (LRU = 1).
127
- // In the next render cycle, calls to createActivityRendererWithLiteralArgsMemoized() might return the memoized result instead.
128
- // This is an improvement to React useMemo(), because it only allows 1 memoization.
129
- // useMemoize() allows any number of memoization.
130
-
131
- const activitiesWithRenderer = [];
132
- let nextVisibleActivity;
133
-
134
- for (let index = activities.length - 1; index >= 0; index--) {
135
- const activity = activities[index];
136
- const renderActivity = createActivityRendererWithLiteralArgsMemoized(activity, nextVisibleActivity);
137
-
138
- if (renderActivity) {
139
- activitiesWithRenderer.splice(0, 0, {
140
- activity,
141
- renderActivity
142
- });
143
-
144
- nextVisibleActivity = activity;
145
- }
146
- }
147
-
148
- return activitiesWithRenderer;
149
- },
150
- [activities]
151
- );
152
-
153
- const visibleActivities = useMemo(() => activitiesWithRenderer.map(({ activity }) => activity), [
154
- activitiesWithRenderer
155
- ]);
156
-
157
- // Tag activities based on types.
158
- // The default implementation tag into 2 types: sender and status.
159
-
160
- const { activitiesGroupBySender, activitiesGroupByStatus } = useMemo(() => {
161
- const { sender: activitiesGroupBySender, status: activitiesGroupByStatus } = groupActivities({
162
- activities: visibleActivities
163
- });
164
-
165
- if (!validateAllActivitiesTagged(visibleActivities, activitiesGroupBySender)) {
166
- console.warn(
167
- 'botframework-webchat: Not every activities are grouped in the "sender" property. Please fix "groupActivitiesMiddleware" and group every activities.'
168
- );
169
- }
170
-
171
- if (!validateAllActivitiesTagged(visibleActivities, activitiesGroupByStatus)) {
172
- console.warn(
173
- 'botframework-webchat: Not every activities are grouped in the "status" property. Please fix "groupActivitiesMiddleware" and group every activities.'
174
- );
175
- }
176
-
177
- return {
178
- activitiesGroupBySender,
179
- activitiesGroupByStatus
180
- };
181
- }, [groupActivities, visibleActivities]);
182
-
183
- // Create a tree of activities with 2 dimensions: sender, followed by status.
184
-
185
- const activityTree = useMemo(() => {
186
- const visibleActivitiesPendingGrouping = [...visibleActivities];
187
- const activityTree = [];
188
-
189
- while (visibleActivitiesPendingGrouping.length) {
190
- const [activity] = visibleActivitiesPendingGrouping;
191
- const senderTree = [];
192
- const activitiesWithSameSender = activitiesGroupBySender.find(activities => activities.includes(activity));
193
-
194
- activityTree.push(senderTree);
195
-
196
- activitiesWithSameSender.forEach(activity => {
197
- const activitiesWithSameStatus = activitiesGroupByStatus.find(activities => activities.includes(activity));
198
-
199
- const activitiesWithSameSenderAndStatus = intersectionOf(
200
- visibleActivitiesPendingGrouping,
201
- activitiesWithSameSender,
202
- activitiesWithSameStatus
203
- );
204
-
205
- if (activitiesWithSameSenderAndStatus.length) {
206
- senderTree.push(activitiesWithSameSenderAndStatus);
207
- removeInline(visibleActivitiesPendingGrouping, ...activitiesWithSameSenderAndStatus);
208
- }
209
- });
210
- }
211
-
212
- // Assertion: All activities in visibleActivities, must be assigned to the activityTree
213
- if (
214
- !visibleActivities.every(activity =>
215
- activityTree.some(activitiesWithSameSender =>
216
- activitiesWithSameSender.some(activitiesWithSameSenderAndStatus =>
217
- activitiesWithSameSenderAndStatus.includes(activity)
218
- )
219
- )
220
- )
221
- ) {
222
- console.warn('botframework-webchat internal: Not all visible activities are grouped in the activityTree.', {
223
- visibleActivities,
224
- activityTree
225
- });
226
- }
227
-
228
- return activityTree;
229
- }, [activitiesGroupBySender, activitiesGroupByStatus, visibleActivities]);
230
-
231
- // Flatten the tree back into an array with information related to rendering.
232
-
233
- const renderingElements = useMemo(() => {
234
- const renderingElements = [];
235
- const topSideBotNub = isZeroOrPositive(bubbleNubOffset);
236
- const topSideUserNub = isZeroOrPositive(bubbleFromUserNubOffset);
237
-
238
- activityTree.forEach(activitiesWithSameSender => {
239
- const [[firstActivity]] = activitiesWithSameSender;
240
- const renderAvatar = createAvatarRenderer({ activity: firstActivity });
241
-
242
- activitiesWithSameSender.forEach((activitiesWithSameSenderAndStatus, indexWithinSenderGroup) => {
243
- const firstInSenderGroup = !indexWithinSenderGroup;
244
- const lastInSenderGroup = indexWithinSenderGroup === activitiesWithSameSender.length - 1;
245
-
246
- activitiesWithSameSenderAndStatus.forEach((activity, indexWithinSenderAndStatusGroup) => {
247
- // We only show the timestamp at the end of the sender group. But we always show the "Send failed, retry" prompt.
248
- const renderActivityStatus = createActivityStatusRenderer({
249
- activity
250
- });
251
-
252
- const firstInSenderAndStatusGroup = !indexWithinSenderAndStatusGroup;
253
- const lastInSenderAndStatusGroup =
254
- indexWithinSenderAndStatusGroup === activitiesWithSameSenderAndStatus.length - 1;
255
-
256
- const { renderActivity } = activitiesWithRenderer.find(entry => entry.activity === activity);
257
- const key = getActivityUniqueId(activity) || renderingElements.length;
258
- const {
259
- channelData: { messageBack: { displayText: messageBackDisplayText } = {} } = {},
260
- from: { role },
261
- text
262
- } = activity;
263
-
264
- const topSideNub = role === 'user' ? topSideUserNub : topSideBotNub;
265
-
266
- let showCallout;
267
-
268
- // Depending on the "showAvatarInGroup" setting, the avatar will render in different positions.
269
- if (showAvatarInGroup === 'sender') {
270
- if (topSideNub) {
271
- showCallout = firstInSenderGroup && firstInSenderAndStatusGroup;
272
- } else {
273
- showCallout = lastInSenderGroup && lastInSenderAndStatusGroup;
274
- }
275
- } else if (showAvatarInGroup === 'status') {
276
- if (topSideNub) {
277
- showCallout = firstInSenderAndStatusGroup;
278
- } else {
279
- showCallout = lastInSenderAndStatusGroup;
280
- }
281
- } else {
282
- showCallout = true;
283
- }
284
-
285
- const focusActivity = () => {
286
- setFocusedActivityKey(getActivityUniqueId(activity));
287
-
288
- // IE11 need to manually focus on the transcript.
289
- const { current: rootElement } = rootElementRef;
290
-
291
- rootElement && rootElement.focus();
292
- };
293
-
294
- renderingElements.push({
295
- activity,
296
-
297
- // After the element is mounted, set it to activityElementsRef.
298
- callbackRef: activityElement => {
299
- const entry = activityElementsRef.current.find(({ activityID }) => activityID === activity.id);
300
-
301
- if (entry) {
302
- entry.element = activityElement;
303
- }
304
- },
305
-
306
- // Calling this function will put the focus on the transcript and the activity.
307
- focusActivity,
308
-
309
- // When a child of the activity receives focus, notify the transcript to set the aria-activedescendant to this activity.
310
- handleFocus: () => {
311
- setFocusedActivityKey(getActivityUniqueId(activity));
312
- },
313
-
314
- handleKeyDown: event => {
315
- if (event.key === 'Escape') {
316
- event.preventDefault();
317
- event.stopPropagation();
318
-
319
- setFocusedActivityKey(getActivityUniqueId(activity));
320
-
321
- const { current } = rootElementRef;
322
-
323
- current && current.focus();
324
- }
325
- },
326
-
327
- // For accessibility: when the user press up/down arrow keys, we put a visual focus indicator around the focused activity.
328
- // We should do the same for mouse, that is why we have the click handler here.
329
- // We are doing it in event capture phase to prevent other components from stopping event propagation to us.
330
- handleMouseDownCapture: ({ target }) => {
331
- const tabIndex = getTabIndex(target);
332
-
333
- if (typeof tabIndex !== 'number' || tabIndex < 0 || target.getAttribute('aria-disabled') === 'true') {
334
- focusActivity();
335
- }
336
- },
337
-
338
- // "hideTimestamp" is a render-time parameter for renderActivityStatus().
339
- // If true, it will hide the timestamp, but it will continue to show the
340
- // retry prompt. And show the screen reader version of the timestamp.
341
- hideTimestamp:
342
- hideAllTimestamps || indexWithinSenderAndStatusGroup !== activitiesWithSameSenderAndStatus.length - 1,
343
- key,
344
-
345
- // When "liveRegionKey" changes, it will show up in the live region momentarily.
346
- liveRegionKey: key + '|' + (messageBackDisplayText || text),
347
- renderActivity,
348
- renderActivityStatus,
349
- renderAvatar,
350
- role,
351
-
352
- // TODO: [P2] #2858 We should use core/definitions/speakingActivity for this predicate instead
353
- shouldSpeak: activity.channelData && activity.channelData.speak,
354
- showCallout
355
- });
356
- });
357
- });
358
- });
359
-
360
- const { current: activityElements } = activityElementsRef;
361
-
362
- // Update activityElementRef with new sets of activity, while retaining the existing referencing element if exists.
363
- activityElementsRef.current = renderingElements.map(({ activity, activity: { id }, elementId, key }) => {
364
- const existingEntry = activityElements.find(entry => entry.key === key);
365
-
366
- return {
367
- activity,
368
- activityID: id,
369
- ariaLabelID: existingEntry
370
- ? existingEntry.ariaLabelID
371
- : `webchat__basic-transcript__activity-label-${random().toString(36).substr(2, 5)}`,
372
- element: existingEntry && existingEntry.element,
373
- elementId,
374
- key
375
- };
376
- });
377
-
378
- // There must be one focused (a.k.a. aria-activedescendant) designated. We default it to the last one.
379
- if (!renderingElements.find(({ focused }) => focused)) {
380
- const lastElement = renderingElements[renderingElements.length - 1];
381
-
382
- if (lastElement) {
383
- lastElement.focused = true;
384
- }
385
- }
386
-
387
- return renderingElements;
388
- }, [
389
- activitiesWithRenderer,
390
- activityElementsRef,
391
- activityTree,
392
- bubbleFromUserNubOffset,
393
- bubbleNubOffset,
394
- createActivityStatusRenderer,
395
- createAvatarRenderer,
396
- hideAllTimestamps,
397
- rootElementRef,
398
- showAvatarInGroup
399
- ]);
400
-
401
- const renderingActivities = useMemo(() => renderingElements.map(({ activity }) => activity), [renderingElements]);
402
-
403
- const scrollToBottomScrollTo = useScrollTo();
404
- const scrollToBottomScrollToEnd = useScrollToEnd();
405
-
406
- const scrollTo = useCallback(
407
- (position, { behavior = 'auto' } = {}) => {
408
- if (!position) {
409
- throw new Error(
410
- 'botframework-webchat: First argument passed to "useScrollTo" must be a ScrollPosition object.'
411
- );
412
- }
413
-
414
- const { activityID, scrollTop } = position;
415
-
416
- if (typeof scrollTop !== 'undefined') {
417
- scrollToBottomScrollTo(scrollTop, { behavior });
418
- } else if (typeof activityID !== 'undefined') {
419
- const { current: rootElement } = rootElementRef;
420
- const { element: activityElement } =
421
- activityElementsRef.current.find(entry => entry.activityID === activityID) || {};
422
-
423
- const scrollableElement = rootElement.querySelector('.webchat__basic-transcript__scrollable');
424
-
425
- if (scrollableElement && activityElement) {
426
- const [{ height: activityElementHeight, y: activityElementY }] = activityElement.getClientRects();
427
- const [{ height: scrollableHeight }] = scrollableElement.getClientRects();
428
-
429
- const activityElementOffsetTop = activityElementY + scrollableElement.scrollTop;
430
-
431
- const scrollTop = Math.min(
432
- activityElementOffsetTop,
433
- activityElementOffsetTop - scrollableHeight + activityElementHeight
434
- );
435
-
436
- scrollToBottomScrollTo(scrollTop, { behavior });
437
- }
438
- }
439
- },
440
- [activityElementsRef, rootElementRef, scrollToBottomScrollTo]
441
- );
442
-
443
- const scrollRelative = useCallback(
444
- (direction, { displacement } = {}) => {
445
- const { current: rootElement } = rootElementRef;
446
-
447
- if (!rootElement) {
448
- return;
449
- }
450
-
451
- const scrollable = rootElement.querySelector('.webchat__basic-transcript__scrollable');
452
- let nextScrollTop;
453
-
454
- if (typeof displacement === 'number') {
455
- nextScrollTop = scrollable.scrollTop + (direction === 'down' ? 1 : -1) * displacement;
456
- } else {
457
- nextScrollTop = scrollable.scrollTop + (direction === 'down' ? 1 : -1) * scrollable.offsetHeight;
458
- }
459
-
460
- scrollTo(
461
- {
462
- scrollTop: Math.max(0, Math.min(scrollable.scrollHeight - scrollable.offsetHeight, nextScrollTop))
463
- },
464
- { behavior: 'smooth' }
465
- );
466
- },
467
- [rootElementRef, scrollTo]
468
- );
469
-
470
- // Since there could be multiple instances of <BasicTranscript> inside the <Composer>, when the developer calls `scrollXXX`, we need to call it on all instances.
471
- // We call `useRegisterScrollXXX` to register a callback function, the `useScrollXXX` will multiplex the call into each instance of <BasicTranscript>.
472
- useRegisterScrollTo(scrollTo);
473
- useRegisterScrollToEnd(scrollToBottomScrollToEnd);
474
- useRegisterScrollRelative(scrollRelative);
475
-
476
- const dispatchScrollPosition = useDispatchScrollPosition();
477
- const patchedDispatchScrollPosition = useMemo(() => {
478
- if (!dispatchScrollPosition) {
479
- return;
480
- }
481
-
482
- return ({ scrollTop }) => {
483
- const { current: rootElement } = rootElementRef;
484
-
485
- if (!rootElement) {
486
- return;
487
- }
488
-
489
- const scrollableElement = rootElement.querySelector('.webchat__basic-transcript__scrollable');
490
-
491
- const [{ height: offsetHeight } = {}] = scrollableElement.getClientRects();
492
-
493
- // Find the activity just above scroll view bottom.
494
- // If the scroll view is already on top, get the first activity.
495
- const entry = scrollableElement.scrollTop
496
- ? [...activityElementsRef.current].reverse().find(({ element }) => {
497
- if (!element) {
498
- return false;
499
- }
500
-
501
- const [{ y } = {}] = element.getClientRects();
502
-
503
- return y < offsetHeight;
504
- })
505
- : activityElementsRef.current[0];
506
-
507
- const { activityID } = entry || {};
508
-
509
- dispatchScrollPosition({ ...(activityID ? { activityID } : {}), scrollTop });
510
- };
511
- }, [activityElementsRef, dispatchScrollPosition, rootElementRef]);
512
-
513
- useObserveScrollPosition(patchedDispatchScrollPosition);
514
-
515
- const [lastInteractedActivity] = useAcknowledgedActivity();
516
-
517
- const indexOfLastInteractedActivity = activities.indexOf(lastInteractedActivity);
518
-
519
- // Create a new ID for aria-activedescendant every time the active descendant change.
520
- // In our design, the transcript will only have 1 focused activity and it has an ID. Other blurred activities will not have ID assigned.
521
- // This help with performance.
522
- // But browser usually do noop if the value of aria-activedescendant doesn't change.
523
- // That means, if we assign the same ID to another element, browser will do noop.
524
- // We need to generate a new ID so the browser see there is a change in aria-activedescendant value and perform accordingly.
525
- const activeDescendantElementId = useMemo(
526
- () => focusedActivityKey && `webchat__basic-transcript__active-descendant-${random().toString(36).substr(2, 5)}`,
527
- [focusedActivityKey]
528
- );
529
-
530
- const scrollActiveDescendantIntoView = useCallback(() => {
531
- const activeDescendant = activeDescendantElementId && document.getElementById(activeDescendantElementId);
532
-
533
- // Don't scroll active descendant into view if the focus is already inside it.
534
- // Otherwise, given the focus is on the send box, clicking on any <input> inside the Adaptive Cards may cause the view to move.
535
- // This UX is not desirable because click should not cause scroll.
536
- if (activeDescendant && !activeDescendant.contains(document.activeElement)) {
537
- // Checks if scrollIntoView support options or not.
538
- // - https://github.com/Modernizr/Modernizr/issues/1568#issuecomment-419457972
539
- // - https://stackoverflow.com/questions/46919627/is-it-possible-to-test-for-scrollintoview-browser-compatibility
540
- if ('scrollBehavior' in document.documentElement.style) {
541
- activeDescendant.scrollIntoView({ block: 'nearest' });
542
- } else {
543
- // This is for browser that does not support options passed to scrollIntoView(), possibly IE11.
544
- const scrollableElement = rootElementRef.current.querySelector('.webchat__basic-transcript__scrollable');
545
- const scrollTopAtTopSide = activeDescendant.offsetTop;
546
- const scrollTopAtBottomSide = activeDescendant.offsetTop + activeDescendant.offsetHeight;
547
-
548
- if (scrollTopAtTopSide < scrollableElement.scrollTop) {
549
- scrollableElement.scrollTop = scrollTopAtTopSide;
550
- } else if (scrollTopAtBottomSide > scrollableElement.scrollTop + scrollableElement.offsetHeight) {
551
- scrollableElement.scrollTop = scrollTopAtBottomSide - scrollableElement.offsetHeight;
552
- }
553
- }
554
- }
555
- }, [activeDescendantElementId, rootElementRef]);
556
-
557
- const handleTranscriptFocus = useCallback(
558
- event => {
559
- const { currentTarget, target } = event;
560
-
561
- // When focus is placed on the transcript, scroll active descendant into the view.
562
- currentTarget === target && scrollActiveDescendantIntoView();
563
- },
564
- [scrollActiveDescendantIntoView]
565
- );
566
-
567
- // After new aria-activedescendant is assigned, we will need to scroll it into view.
568
- // User agent will scroll automatically for focusing element, but not for aria-activedescendant.
569
- // We need to do the scrolling manually.
570
- useEffect(() => scrollActiveDescendantIntoView(), [scrollActiveDescendantIntoView]);
571
-
572
- // If any activities has changed, reset the active descendant.
573
- useEffect(() => setFocusedActivityKey(undefined), [activities, setFocusedActivityKey]);
574
-
575
- const focusRelativeActivity = useCallback(
576
- delta => {
577
- if (isNaN(delta) || !renderingElements.length) {
578
- return setFocusedActivityKey(undefined);
579
- }
580
-
581
- const index = renderingElements.findIndex(({ key }) => key === focusedActivityKey);
582
- const nextIndex = ~index
583
- ? Math.max(0, Math.min(renderingElements.length - 1, index + delta))
584
- : renderingElements.length - 1;
585
- const nextFocusedActivity = renderingElements[nextIndex];
586
-
587
- setFocusedActivityKey(nextFocusedActivity.key);
588
- rootElementRef.current && rootElementRef.current.focus();
589
- },
590
- [focusedActivityKey, renderingElements, rootElementRef, setFocusedActivityKey]
591
- );
592
-
593
- const handleTranscriptKeyDown = useCallback(
594
- event => {
595
- const { target } = event;
596
-
597
- const fromEndOfTranscriptIndicator = target === terminatorRef.current;
598
- const fromTranscript = target === event.currentTarget;
599
-
600
- if (!fromEndOfTranscriptIndicator && !fromTranscript) {
601
- return;
602
- }
603
-
604
- let handled = true;
605
-
606
- switch (event.key) {
607
- case 'ArrowDown':
608
- focusRelativeActivity(fromEndOfTranscriptIndicator ? 0 : 1);
609
- break;
610
-
611
- case 'ArrowUp':
612
- focusRelativeActivity(fromEndOfTranscriptIndicator ? 0 : -1);
613
- break;
614
-
615
- case 'End':
616
- focusRelativeActivity(Infinity);
617
- break;
618
-
619
- case 'Enter':
620
- if (!fromEndOfTranscriptIndicator) {
621
- const focusedActivityEntry = renderingElements.find(({ key }) => key === focusedActivityKey);
622
-
623
- if (focusedActivityEntry) {
624
- const { element: focusedActivityElement } =
625
- activityElementsRef.current.find(({ activity }) => activity === focusedActivityEntry.activity) || {};
626
-
627
- if (focusedActivityElement) {
628
- const [firstTabbableElement] = tabbableElements(focusedActivityElement).filter(
629
- ({ className }) => className !== 'webchat__basic-transcript__activity-sentinel'
630
- );
631
-
632
- firstTabbableElement && firstTabbableElement.focus();
633
- }
634
- }
635
- }
636
-
637
- break;
638
-
639
- case 'Escape':
640
- focus('sendBoxWithoutKeyboard');
641
- break;
642
-
643
- case 'Home':
644
- focusRelativeActivity(-Infinity);
645
- break;
646
-
647
- default:
648
- handled = false;
649
- break;
650
- }
651
-
652
- if (handled) {
653
- event.preventDefault();
654
-
655
- // If a custom HTML control wants to handle up/down arrow, we will prevent them from listening to this event to prevent bugs due to handling arrow keys twice.
656
- event.stopPropagation();
657
- }
658
- },
659
- [focusedActivityKey, activityElementsRef, focusRelativeActivity, focus, terminatorRef, renderingElements]
660
- );
661
-
662
- const labelId = useUniqueId('webchat__basic-transcript__label');
663
-
664
- // If SHIFT-TAB from "End of transcript" indicator, if focusedActivityKey is not set (or no longer exists), set it the the bottommost activity.
665
- const setBottommostFocusedActivityKeyIfNeeded = useCallback(() => {
666
- if (!~renderingElements.findIndex(({ key }) => key === focusedActivityKey)) {
667
- const { key: lastActivityKey } = renderingElements[renderingElements.length - 1] || {};
668
-
669
- setFocusedActivityKey(lastActivityKey);
670
- }
671
- }, [focusedActivityKey, renderingElements, setFocusedActivityKey]);
672
-
673
- const handleTranscriptKeyDownCapture = useCallback(
674
- event => {
675
- const { altKey, ctrlKey, key, metaKey, target } = event;
676
-
677
- if (altKey || (ctrlKey && key !== 'v') || metaKey || (!inputtableKey(key) && key !== 'Backspace')) {
678
- // Ignore if one of the utility key (except SHIFT) is pressed
679
- // E.g. CTRL-C on a link in one of the message should not jump to chat box
680
- // E.g. "A" or "Backspace" should jump to chat box
681
- return;
682
- }
683
-
684
- // Send keystrokes to send box if we are focusing on the transcript or terminator.
685
- if (target === event.currentTarget || target === terminatorRef.current) {
686
- event.stopPropagation();
687
-
688
- focus('sendBox');
689
- }
690
- },
691
- [focus]
692
- );
693
-
694
- const focusTranscriptCallback = useCallback(() => rootElementRef.current && rootElementRef.current.focus(), [
695
- rootElementRef
696
- ]);
697
-
698
- useRegisterFocusTranscript(focusTranscriptCallback);
699
-
700
- const handleFocusActivity = useCallback(
701
- key => {
702
- setFocusedActivityKey(key);
703
- rootElementRef.current && rootElementRef.current.focus();
704
- },
705
- [setFocusedActivityKey]
706
- );
707
-
708
- // When the focusing activity has changed, dispatch an event to observers of "useObserveTranscriptFocus".
709
- const dispatchTranscriptFocus = useDispatchTranscriptFocus();
710
- const focusedActivity = useMemo(() => {
711
- const { activity } = renderingElements.find(({ key }) => key === focusedActivityKey) || {};
712
-
713
- return activity;
714
- }, [focusedActivityKey, renderingElements]);
715
-
716
- useMemo(() => dispatchTranscriptFocus && dispatchTranscriptFocus({ activity: focusedActivity }), [
717
- dispatchTranscriptFocus,
718
- focusedActivity
719
- ]);
720
-
721
- // This is required by IE11.
722
- // When the user clicks on and empty space (a.k.a. filler) in an empty transcript, IE11 says the focus is on the <div className="filler">,
723
- // despite the fact there are no "tabIndex" attributes set on the filler.
724
- // We need to artificially send the focus back to the transcript.
725
- const handleFocusFiller = useCallback(() => {
726
- const { current } = rootElementRef;
727
-
728
- current && current.focus();
729
- }, [rootElementRef]);
730
-
731
- return (
732
- <div
733
- aria-activedescendant={focusedActivityKey ? activeDescendantElementId : undefined}
734
- aria-labelledby={labelId}
735
- className={classNames(
736
- 'webchat__basic-transcript',
737
- basicTranscriptStyleSet + '',
738
- rootClassName,
739
- (className || '') + ''
740
- )}
741
- dir={direction}
742
- onFocus={handleTranscriptFocus}
743
- onKeyDown={handleTranscriptKeyDown}
744
- onKeyDownCapture={handleTranscriptKeyDownCapture}
745
- ref={rootElementRef}
746
- // "aria-activedescendant" will only works with a number of roles and it must be explicitly set.
747
- // https://www.w3.org/TR/wai-aria/#aria-activedescendant
748
- role="group"
749
- // For up/down arrow key navigation across activities, this component must be included in the tab sequence.
750
- // Otherwise, "aria-activedescendant" will not be narrated when the user press up/down arrow keys.
751
- // https://www.w3.org/TR/wai-aria-practices-1.1/#kbd_focus_activedescendant
752
- tabIndex={0}
753
- >
754
- <ScreenReaderText id={labelId} text={transcriptAriaLabel} />
755
- {/* This <section> is for live region only. Content is made invisible through CSS. */}
756
- <section
757
- aria-atomic={false}
758
- aria-live="polite"
759
- aria-relevant="additions"
760
- aria-roledescription={transcriptRoleDescription}
761
- role="log"
762
- >
763
- {renderingElements.map(({ activity, liveRegionKey }) => (
764
- <Fade fadeAfter={internalLiveRegionFadeAfter} key={liveRegionKey}>
765
- {() => <ScreenReaderActivity activity={activity} />}
766
- </Fade>
767
- ))}
768
- </section>
769
- {/* TODO: [P2] Fix ESLint error `no-use-before-define` */}
770
- {/* eslint-disable-next-line @typescript-eslint/no-use-before-define */}
771
- <InternalTranscriptScrollable
772
- activities={renderingActivities}
773
- onFocusActivity={handleFocusActivity}
774
- onFocusFiller={handleFocusFiller}
775
- terminatorRef={terminatorRef}
776
- >
777
- {renderingElements.map(
778
- (
779
- {
780
- activity,
781
- callbackRef,
782
- focusActivity,
783
- handleFocus,
784
- handleKeyDown,
785
- handleMouseDownCapture,
786
- hideTimestamp,
787
- key,
788
- renderActivity,
789
- renderActivityStatus,
790
- renderAvatar,
791
- role,
792
- shouldSpeak,
793
- showCallout
794
- },
795
- index
796
- ) => {
797
- const { ariaLabelID, element } =
798
- activityElementsRef.current.find(entry => entry.activity === activity) || {};
799
- const activeDescendant = focusedActivityKey === key;
800
- const isContentInteractive = !!(element
801
- ? tabbableElements(element.querySelector('.webchat__basic-transcript__activity-box')).length
802
- : 0);
803
-
804
- return (
805
- <li
806
- aria-labelledby={ariaLabelID}
807
- className={classNames('webchat__basic-transcript__activity', {
808
- 'webchat__basic-transcript__activity--acknowledged': index <= indexOfLastInteractedActivity,
809
- 'webchat__basic-transcript__activity--from-bot': role !== 'user',
810
- 'webchat__basic-transcript__activity--from-user': role === 'user'
811
- })}
812
- // Set "id" for valid for accessibility.
813
- /* eslint-disable-next-line react/forbid-dom-props */
814
- id={activeDescendant ? activeDescendantElementId : undefined}
815
- key={key}
816
- onFocus={handleFocus}
817
- onKeyDown={handleKeyDown}
818
- onMouseDownCapture={handleMouseDownCapture}
819
- ref={callbackRef}
820
- >
821
- <ScreenReaderActivity activity={activity} id={ariaLabelID} renderAttachments={false}>
822
- {!!isContentInteractive && <p>{activityInteractiveAlt}</p>}
823
- </ScreenReaderActivity>
824
- <FocusRedirector
825
- className="webchat__basic-transcript__activity-sentinel"
826
- onFocus={focusActivity}
827
- redirectRef={rootElementRef}
828
- />
829
- <div className="webchat__basic-transcript__activity-box">
830
- {renderActivity({
831
- hideTimestamp,
832
- renderActivityStatus,
833
- renderAvatar,
834
- showCallout
835
- })}
836
- </div>
837
- {shouldSpeak && <SpeakActivity activity={activity} />}
838
- <FocusRedirector
839
- className="webchat__basic-transcript__activity-sentinel"
840
- onFocus={focusActivity}
841
- redirectRef={rootElementRef}
842
- />
843
- <div
844
- className={classNames('webchat__basic-transcript__activity-indicator', {
845
- 'webchat__basic-transcript__activity-indicator--first': !index,
846
- 'webchat__basic-transcript__activity-indicator--focus': activeDescendant
847
- })}
848
- />
849
- </li>
850
- );
851
- }
852
- )}
853
- </InternalTranscriptScrollable>
854
- {!!renderingElements.length && (
855
- <React.Fragment>
856
- <FocusRedirector
857
- className="webchat__basic-transcript__sentinel"
858
- onFocus={setBottommostFocusedActivityKeyIfNeeded}
859
- redirectRef={rootElementRef}
860
- />
861
- <div className="webchat__basic-transcript__terminator" ref={terminatorRef} tabIndex={0}>
862
- <div className="webchat__basic-transcript__terminator-body">
863
- <div className="webchat__basic-transcript__terminator-text">{terminatorText}</div>
864
- </div>
865
- </div>
866
- </React.Fragment>
867
- )}
868
- <div className="webchat__basic-transcript__focus-indicator" />
869
- </div>
870
- );
871
- };
872
-
873
- InternalTranscript.defaultProps = {
874
- className: ''
875
- };
876
-
877
- InternalTranscript.propTypes = {
878
- activityElementsRef: PropTypes.shape({
879
- current: PropTypes.array.isRequired
880
- }).isRequired,
881
- className: PropTypes.string
882
- };
883
-
884
- const InternalScreenReaderTranscript = ({ renderingElements }) => {
885
- const localize = useLocalizer();
886
- const [internalLiveRegionFadeAfter] = useStyleOptions();
887
-
888
- const transcriptRoleDescription = localize('TRANSCRIPT_ARIA_ROLE_ALT');
889
-
890
- return (
891
- <section
892
- aria-atomic={false}
893
- aria-live="polite"
894
- aria-relevant="additions"
895
- aria-roledescription={transcriptRoleDescription}
896
- role="log"
897
- >
898
- {renderingElements.map(({ activity, liveRegionKey }) => (
899
- <Fade fadeAfter={internalLiveRegionFadeAfter} key={liveRegionKey}>
900
- {() => <ScreenReaderActivity activity={activity} />}
901
- </Fade>
902
- ))}
903
- </section>
904
- );
905
- };
906
-
907
- InternalScreenReaderTranscript.propTypes = {
908
- renderingElements: PropTypes.arrayOf(
909
- PropTypes.shape({
910
- activity: PropTypes.any,
911
- liveRegionKey: PropTypes.string
912
- })
913
- ).isRequired
914
- };
915
-
916
- // Separating high-frequency hooks to improve performance.
917
- const InternalTranscriptScrollable = ({ activities, children, onFocusActivity, onFocusFiller, terminatorRef }) => {
918
- const [{ activities: activitiesStyleSet }] = useStyleSet();
919
- const [{ hideScrollToEndButton }] = useStyleOptions();
920
- const [animatingToEnd] = useAnimatingToEnd();
921
- const [sticky] = useSticky();
922
- const lastVisibleActivityId = getActivityUniqueId(activities[activities.length - 1] || {}); // Activity ID of the last visible activity in the list.
923
- const localize = useLocalizer();
924
- const scrollToEndButtonRef = useRef();
925
-
926
- const lastReadActivityIdRef = useRef(lastVisibleActivityId);
927
- const transcriptRoleDescription = localize('TRANSCRIPT_ARIA_ROLE_ALT');
928
-
929
- const allActivitiesRead = lastVisibleActivityId === lastReadActivityIdRef.current;
930
-
931
- const handleScrollToEndButtonClick = useCallback(() => {
932
- // After the "New message" button is clicked, focus on the first unread activity.
933
- const index = activities.findIndex(({ id }) => id === lastReadActivityIdRef.current);
934
-
935
- if (~index) {
936
- const firstUnreadActivity = activities[index + 1];
937
-
938
- if (firstUnreadActivity) {
939
- return onFocusActivity(getActivityUniqueId(firstUnreadActivity));
940
- }
941
- }
942
-
943
- const { current } = terminatorRef;
944
-
945
- current && current.focus();
946
- }, [activities, lastReadActivityIdRef, onFocusActivity, terminatorRef]);
947
-
948
- if (sticky) {
949
- // If it is sticky, the user is at the bottom of the transcript, everything is read.
950
- // So mark the activity ID as read.
951
- lastReadActivityIdRef.current = lastVisibleActivityId;
952
- }
953
-
954
- // Finds where we should render the "New messages" button, in index. Returns -1 to hide the button.
955
- const renderSeparatorAfterIndex = useMemo(() => {
956
- // Don't show the button if:
957
- // - All activities have been read
958
- // - Currently animating towards bottom
959
- // - "New messages" button must not flash when: 1. Type "help", 2. Scroll to top, 3. Type "help" again, 4. Expect the "New messages" button not flashy
960
- // - Hidden by style options
961
- // - It is already at the bottom (sticky)
962
-
963
- // Any changes to this logic, verify:
964
- // - "New messages" button should persist while programmatically scrolling to mid-point of the transcript:
965
- // 1. Type "help"
966
- // 2. Type "proactive", then immediately scroll to top
967
- // Expect: the "New messages" button should appear
968
- // 3. Run hook "useScrollTo({ scrollTop: 500 })"
969
- // Expect: when the scroll is animating to 500px, the "New messages" button should kept on the screen
970
- // - "New messages" button must not flashy:
971
- // 1. Type "help"
972
- // 2. Scroll to top
973
- // Expect: no "New messages" button is shown
974
- // 3. Type "help" again
975
- // Expect: "New messages" button must not flash-appear
976
-
977
- if (allActivitiesRead || animatingToEnd || hideScrollToEndButton || sticky) {
978
- return -1;
979
- }
980
-
981
- return activities.findIndex(activity => getActivityUniqueId(activity) === lastReadActivityIdRef.current);
982
- }, [activities, allActivitiesRead, animatingToEnd, hideScrollToEndButton, lastReadActivityIdRef, sticky]);
983
-
984
- return (
985
- <React.Fragment>
986
- {renderSeparatorAfterIndex !== -1 && (
987
- <ScrollToEndButton onClick={handleScrollToEndButtonClick} ref={scrollToEndButtonRef} />
988
- )}
989
- {!!React.Children.count(children) && (
990
- <FocusRedirector className="webchat__basic-transcript__sentinel" redirectRef={terminatorRef} />
991
- )}
992
- <ReactScrollToBottomPanel className="webchat__basic-transcript__scrollable">
993
- <div aria-hidden={true} className="webchat__basic-transcript__filler" onFocus={onFocusFiller} />
994
- <ul
995
- aria-roledescription={transcriptRoleDescription}
996
- className={classNames(activitiesStyleSet + '', 'webchat__basic-transcript__transcript')}
997
- role="list"
998
- >
999
- {children}
1000
- </ul>
1001
- <BasicTypingIndicator />
1002
- </ReactScrollToBottomPanel>
1003
- </React.Fragment>
1004
- );
1005
- };
1006
-
1007
- InternalTranscriptScrollable.propTypes = {
1008
- activities: PropTypes.array.isRequired,
1009
- children: PropTypes.any.isRequired,
1010
- onFocusActivity: PropTypes.func.isRequired,
1011
- onFocusFiller: PropTypes.func.isRequired,
1012
- terminatorRef: PropTypes.any.isRequired
1013
- };
1014
-
1015
- const SetScroller = ({ activityElementsRef, scrollerRef }) => {
1016
- const [
1017
- { autoScrollSnapOnActivity, autoScrollSnapOnActivityOffset, autoScrollSnapOnPage, autoScrollSnapOnPageOffset }
1018
- ] = useStyleOptions();
1019
- const [lastAcknowledgedActivity] = useAcknowledgedActivity();
1020
-
1021
- const lastAcknowledgedActivityRef = useRef(lastAcknowledgedActivity);
1022
-
1023
- lastAcknowledgedActivityRef.current = lastAcknowledgedActivity;
1024
-
1025
- scrollerRef.current = useCallback(
1026
- ({ offsetHeight, scrollTop }) => {
1027
- const patchedAutoScrollSnapOnActivity =
1028
- typeof autoScrollSnapOnActivity === 'number'
1029
- ? Math.max(0, autoScrollSnapOnActivity)
1030
- : autoScrollSnapOnActivity
1031
- ? 1
1032
- : 0;
1033
- const patchedAutoScrollSnapOnPage =
1034
- typeof autoScrollSnapOnPage === 'number'
1035
- ? Math.max(0, Math.min(1, autoScrollSnapOnPage))
1036
- : autoScrollSnapOnPage
1037
- ? 1
1038
- : 0;
1039
- const patchedAutoScrollSnapOnActivityOffset =
1040
- typeof autoScrollSnapOnActivityOffset === 'number' ? autoScrollSnapOnActivityOffset : 0;
1041
- const patchedAutoScrollSnapOnPageOffset =
1042
- typeof autoScrollSnapOnPageOffset === 'number' ? autoScrollSnapOnPageOffset : 0;
1043
-
1044
- if (patchedAutoScrollSnapOnActivity || patchedAutoScrollSnapOnPage) {
1045
- const { current: lastAcknowledgedActivity } = lastAcknowledgedActivityRef;
1046
-
1047
- const values = [];
1048
-
1049
- if (patchedAutoScrollSnapOnActivity) {
1050
- const { element: nthUnacknowledgedActivityElement } =
1051
- activityElementsRef.current[
1052
- activityElementsRef.current.findIndex(({ activity }) => activity === lastAcknowledgedActivity) +
1053
- patchedAutoScrollSnapOnActivity
1054
- ] || {};
1055
-
1056
- if (nthUnacknowledgedActivityElement) {
1057
- values.push(
1058
- nthUnacknowledgedActivityElement.offsetTop +
1059
- nthUnacknowledgedActivityElement.offsetHeight -
1060
- offsetHeight -
1061
- scrollTop +
1062
- patchedAutoScrollSnapOnActivityOffset
1063
- );
1064
- }
1065
- }
1066
-
1067
- if (patchedAutoScrollSnapOnPage) {
1068
- const { element: firstUnacknowledgedActivityElement } =
1069
- activityElementsRef.current[
1070
- activityElementsRef.current.findIndex(({ activity }) => activity === lastAcknowledgedActivity) + 1
1071
- ] || {};
1072
-
1073
- if (firstUnacknowledgedActivityElement) {
1074
- values.push(
1075
- firstUnacknowledgedActivityElement.offsetTop -
1076
- scrollTop -
1077
- offsetHeight * (1 - patchedAutoScrollSnapOnPage) +
1078
- patchedAutoScrollSnapOnPageOffset
1079
- );
1080
- }
1081
- }
1082
-
1083
- return values.reduce((minValue, value) => Math.min(minValue, value), Infinity);
1084
- }
1085
-
1086
- return Infinity;
1087
- },
1088
- [
1089
- activityElementsRef,
1090
- autoScrollSnapOnActivity,
1091
- autoScrollSnapOnActivityOffset,
1092
- autoScrollSnapOnPage,
1093
- autoScrollSnapOnPageOffset,
1094
- lastAcknowledgedActivityRef
1095
- ]
1096
- );
1097
-
1098
- return false;
1099
- };
1100
-
1101
- const BasicTranscript = ({ className }) => {
1102
- const activityElementsRef = useRef([]);
1103
- const scrollerRef = useRef(() => Infinity);
1104
-
1105
- const scroller = useCallback((...args) => scrollerRef.current(...args), [scrollerRef]);
1106
-
1107
- return (
1108
- <ReactScrollToBottomComposer scroller={scroller}>
1109
- <SetScroller activityElementsRef={activityElementsRef} scrollerRef={scrollerRef} />
1110
- <InternalTranscript activityElementsRef={activityElementsRef} className={className} />
1111
- </ReactScrollToBottomComposer>
1112
- );
1113
- };
1114
-
1115
- BasicTranscript.defaultProps = {
1116
- className: ''
1117
- };
1118
-
1119
- BasicTranscript.propTypes = {
1120
- className: PropTypes.string
1121
- };
1122
-
1123
- export default BasicTranscript;