botframework-webchat-component 4.14.0 → 4.15.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.
- package/.eslintrc.yml +4 -106
- package/.prettierrc.yml +1 -1
- package/lib/Activity/Bubble.js +2 -2
- package/lib/Activity/CarouselFilmStrip.js +3 -3
- package/lib/Activity/CarouselFilmStripAttachment.js +2 -2
- package/lib/Activity/CarouselLayout.js +5 -5
- package/lib/Activity/Speak.js +6 -6
- package/lib/Activity/StackedLayout.d.ts.map +1 -1
- package/lib/Activity/StackedLayout.js +3 -3
- package/lib/Assets/TypingAnimation.js +2 -2
- package/lib/Attachment/AudioAttachment.js +2 -2
- package/lib/Attachment/AudioContent.js +2 -2
- package/lib/Attachment/FileAttachment.js +2 -2
- package/lib/Attachment/FileContent.d.ts.map +1 -1
- package/lib/Attachment/FileContent.js +12 -2
- package/lib/Attachment/HTMLVideoContent.js +2 -2
- package/lib/Attachment/ImageContent.js +2 -2
- package/lib/Attachment/TextContent.js +2 -2
- package/lib/Attachment/VideoAttachment.js +2 -2
- package/lib/Attachment/VideoContent.js +1 -1
- package/lib/Attachment/VimeoContent.js +2 -2
- package/lib/Attachment/YouTubeContent.js +2 -2
- package/lib/Avatar/ImageAvatar.js +2 -2
- package/lib/Avatar/InitialsAvatar.js +2 -2
- package/lib/BasicConnectivityStatus.js +2 -2
- package/lib/BasicSendBox.js +3 -3
- package/lib/BasicToast.js +4 -4
- package/lib/BasicToaster.js +8 -5
- package/lib/BasicTranscript.d.ts +7 -0
- package/lib/BasicTranscript.d.ts.map +1 -0
- package/lib/BasicTranscript.js +387 -729
- package/lib/BasicTypingIndicator.d.ts +2 -1
- package/lib/BasicTypingIndicator.d.ts.map +1 -1
- package/lib/BasicTypingIndicator.js +13 -5
- package/lib/BasicWebChat.js +2 -2
- package/lib/Composer.d.ts.map +1 -1
- package/lib/Composer.js +42 -35
- package/lib/ConnectivityStatus/Assets/ErrorNotificationIcon.js +2 -2
- package/lib/ConnectivityStatus/Assets/SpinnerAnimation.js +2 -2
- package/lib/ConnectivityStatus/Assets/WarningNotificationIcon.js +2 -2
- package/lib/ConnectivityStatus/Connected.js +1 -1
- package/lib/ConnectivityStatus/Connecting.js +4 -4
- package/lib/ConnectivityStatus/FailedToConnect.js +2 -2
- package/lib/ConnectivityStatus/JavaScriptError.js +2 -2
- package/lib/Dictation.js +4 -4
- package/lib/ErrorBox.js +2 -2
- package/lib/Middleware/Activity/createCoreMiddleware.d.ts.map +1 -1
- package/lib/Middleware/Activity/createCoreMiddleware.js +1 -1
- package/lib/Middleware/ActivityStatus/AbsoluteTime.js +1 -1
- package/lib/Middleware/ActivityStatus/RelativeTime.js +1 -1
- package/lib/Middleware/ActivityStatus/SendStatus/SendFailedRetry.js +3 -3
- package/lib/Middleware/ActivityStatus/SendStatus/SendStatus.js +5 -5
- package/lib/Middleware/ActivityStatus/Timestamp.js +2 -2
- package/lib/Middleware/ActivityStatus/createSendStatusMiddleware.js +21 -16
- package/lib/Middleware/ActivityStatus/createTimestampMiddleware.js +1 -1
- package/lib/Middleware/Attachment/createCoreMiddleware.js +2 -5
- package/lib/Middleware/AttachmentForScreenReader/AudioAttachment.js +1 -1
- package/lib/Middleware/AttachmentForScreenReader/FileAttachment.js +1 -1
- package/lib/Middleware/AttachmentForScreenReader/ImageAttachment.js +1 -1
- package/lib/Middleware/AttachmentForScreenReader/TextAttachment.js +1 -1
- package/lib/Middleware/AttachmentForScreenReader/VideoAttachment.js +1 -1
- package/lib/Middleware/AttachmentForScreenReader/createCoreMiddleware.d.ts.map +1 -1
- package/lib/Middleware/AttachmentForScreenReader/createCoreMiddleware.js +1 -1
- package/lib/Middleware/Avatar/createCoreMiddleware.d.ts.map +1 -1
- package/lib/Middleware/Avatar/createCoreMiddleware.js +3 -4
- package/lib/Middleware/CardAction/createCoreMiddleware.js +10 -3
- package/lib/Middleware/GroupActivities/createCoreMiddleware.js +1 -1
- package/lib/Middleware/ScrollToEndButton/ScrollToEndButton.js +2 -2
- package/lib/Middleware/ScrollToEndButton/createScrollToEndButtonMiddleware.d.ts.map +1 -1
- package/lib/Middleware/ScrollToEndButton/createScrollToEndButtonMiddleware.js +1 -1
- package/lib/Middleware/Toast/createCoreMiddleware.d.ts.map +1 -1
- package/lib/Middleware/Toast/createCoreMiddleware.js +1 -1
- package/lib/Middleware/TypingIndicator/createCoreMiddleware.d.ts.map +1 -1
- package/lib/Middleware/TypingIndicator/createCoreMiddleware.js +9 -7
- package/lib/ReactWebChat.js +5 -3
- package/lib/ScreenReaderActivity.js +17 -8
- package/lib/ScreenReaderText.d.ts +9 -0
- package/lib/ScreenReaderText.d.ts.map +1 -0
- package/lib/ScreenReaderText.js +22 -8
- package/lib/SendBox/Assets/SendIcon.js +2 -2
- package/lib/SendBox/AutoResizeTextArea.js +4 -4
- package/lib/SendBox/DictationInterims.js +3 -3
- package/lib/SendBox/IconButton.d.ts +11 -0
- package/lib/SendBox/IconButton.d.ts.map +1 -0
- package/lib/SendBox/IconButton.js +27 -7
- package/lib/SendBox/MicrophoneButton.js +5 -5
- package/lib/SendBox/SendButton.js +5 -5
- package/lib/SendBox/SuggestedAction.d.ts +17 -0
- package/lib/SendBox/SuggestedAction.d.ts.map +1 -0
- package/lib/SendBox/SuggestedAction.js +28 -19
- package/lib/SendBox/SuggestedActions.d.ts.map +1 -1
- package/lib/SendBox/SuggestedActions.js +33 -12
- package/lib/SendBox/TextBox.js +6 -6
- package/lib/SendBox/UploadButton.js +6 -6
- package/lib/Styles/StyleSet/BasicTranscript.d.ts +13 -5
- package/lib/Styles/StyleSet/BasicTranscript.d.ts.map +1 -1
- package/lib/Styles/StyleSet/BasicTranscript.js +21 -9
- package/lib/Styles/StyleSet/Bubble.d.ts.map +1 -1
- package/lib/Styles/StyleSet/Bubble.js +2 -2
- package/lib/Styles/StyleSet/CarouselFilmStrip.d.ts.map +1 -1
- package/lib/Styles/StyleSet/CarouselFilmStrip.js +2 -2
- package/lib/Styles/StyleSet/CarouselFilmStripAttachment.d.ts.map +1 -1
- package/lib/Styles/StyleSet/CarouselFilmStripAttachment.js +2 -2
- package/lib/Styles/StyleSet/KeyboardHelp.d.ts +123 -0
- package/lib/Styles/StyleSet/KeyboardHelp.d.ts.map +1 -0
- package/lib/Styles/StyleSet/KeyboardHelp.js +145 -0
- package/lib/Styles/StyleSet/ScrollToEndButton.d.ts +1 -1
- package/lib/Styles/StyleSet/ScrollToEndButton.js +2 -2
- package/lib/Styles/StyleSet/SendBoxButton.d.ts +56 -10
- package/lib/Styles/StyleSet/SendBoxButton.d.ts.map +1 -1
- package/lib/Styles/StyleSet/SendBoxButton.js +76 -12
- package/lib/Styles/StyleSet/SendBoxTextBox.d.ts +1 -1
- package/lib/Styles/StyleSet/SendBoxTextBox.d.ts.map +1 -1
- package/lib/Styles/StyleSet/SendBoxTextBox.js +3 -3
- package/lib/Styles/StyleSet/StackedLayout.d.ts.map +1 -1
- package/lib/Styles/StyleSet/StackedLayout.js +1 -1
- package/lib/Styles/StyleSet/SuggestedAction.d.ts +73 -28
- package/lib/Styles/StyleSet/SuggestedAction.d.ts.map +1 -1
- package/lib/Styles/StyleSet/SuggestedAction.js +116 -41
- package/lib/Styles/StyleSet/SuggestedActions.d.ts +13 -6
- package/lib/Styles/StyleSet/SuggestedActions.d.ts.map +1 -1
- package/lib/Styles/StyleSet/SuggestedActions.js +13 -6
- package/lib/Styles/createStyleSet.d.ts +323 -54
- package/lib/Styles/createStyleSet.d.ts.map +1 -1
- package/lib/Styles/createStyleSet.js +5 -2
- package/lib/Styles/mirrorStyle.js +13 -4
- package/lib/Toast/NotificationIcon.js +7 -3
- package/lib/Toast/createToastMiddleware.d.ts.map +1 -1
- package/lib/Toast/createToastMiddleware.js +1 -1
- package/lib/Transcript/ActivityRow.d.ts +9 -0
- package/lib/Transcript/ActivityRow.d.ts.map +1 -0
- package/lib/Transcript/ActivityRow.js +157 -0
- package/lib/Transcript/ActivityTextAlt.js +57 -0
- package/lib/Transcript/FocusTrap.d.ts +8 -0
- package/lib/Transcript/FocusTrap.d.ts.map +1 -0
- package/lib/Transcript/FocusTrap.js +74 -0
- package/lib/Transcript/KeyboardHelp.d.ts +4 -0
- package/lib/Transcript/KeyboardHelp.d.ts.map +1 -0
- package/lib/Transcript/KeyboardHelp.js +550 -0
- package/lib/Transcript/LiveRegionTranscript.d.ts +8 -0
- package/lib/Transcript/LiveRegionTranscript.d.ts.map +1 -0
- package/lib/Transcript/LiveRegionTranscript.js +214 -0
- package/lib/Transcript/types.d.ts +2 -0
- package/lib/Transcript/types.d.ts.map +1 -0
- package/lib/Transcript/types.js +2 -0
- package/lib/Transcript/useActivityAccessibleName.d.ts +4 -0
- package/lib/Transcript/useActivityAccessibleName.d.ts.map +1 -0
- package/lib/Transcript/useActivityAccessibleName.js +97 -0
- package/lib/Utils/AccessKeySink/Surface.js +7 -5
- package/lib/Utils/AccessibleButton.d.ts +11 -0
- package/lib/Utils/AccessibleButton.d.ts.map +1 -0
- package/lib/Utils/AccessibleButton.js +15 -8
- package/lib/Utils/AccessibleInputText.js +6 -4
- package/lib/Utils/AccessibleTextArea.js +6 -4
- package/lib/Utils/CroppedImage.js +2 -2
- package/lib/Utils/Fade.js +2 -2
- package/lib/Utils/FocusRedirector.d.ts +9 -0
- package/lib/Utils/FocusRedirector.d.ts.map +1 -0
- package/lib/Utils/FocusRedirector.js +18 -15
- package/lib/Utils/InlineMarkdown.js +17 -10
- package/lib/Utils/TypeFocusSink/FocusBox.js +6 -4
- package/lib/Utils/TypeFocusSink/getTabIndex.js +1 -1
- package/lib/Utils/TypeFocusSink/inputtableKey.d.ts +2 -0
- package/lib/Utils/TypeFocusSink/inputtableKey.d.ts.map +1 -0
- package/lib/Utils/TypeFocusSink/inputtableKey.js +5 -2
- package/lib/Utils/TypeFocusSink/navigableEvent.js +1 -1
- package/lib/Utils/activityAltText.d.ts +8 -0
- package/lib/Utils/activityAltText.d.ts.map +1 -0
- package/lib/Utils/activityAltText.js +2 -2
- package/lib/Utils/addTargetBlankToHyperlinksMarkdown.js +1 -1
- package/lib/Utils/createCustomEvent.js +9 -3
- package/lib/Utils/debounce.js +1 -1
- package/lib/Utils/detectBrowser.js +4 -2
- package/lib/Utils/downscaleImageToDataURL/downscaleImageToDataURLUsingWorker.js +3 -3
- package/lib/Utils/downscaleImageToDataURL/index.js +2 -2
- package/lib/Utils/filterMap.js +1 -1
- package/lib/Utils/findAncestor.js +17 -0
- package/lib/Utils/getActivityUniqueId.js +4 -2
- package/lib/Utils/intersectionOf.d.ts +5 -0
- package/lib/Utils/intersectionOf.d.ts.map +1 -0
- package/lib/Utils/intersectionOf.js +17 -2
- package/lib/Utils/isZeroOrPositive.d.ts +5 -0
- package/lib/Utils/isZeroOrPositive.d.ts.map +1 -0
- package/lib/Utils/isZeroOrPositive.js +4 -1
- package/lib/Utils/mapMap.js +10 -3
- package/lib/Utils/readDataURIToBlob.js +3 -3
- package/lib/Utils/scrollIntoViewWithBlockNearest.d.ts +7 -0
- package/lib/Utils/scrollIntoViewWithBlockNearest.d.ts.map +1 -0
- package/lib/Utils/scrollIntoViewWithBlockNearest.js +48 -0
- package/lib/Utils/shallowEquals.js +7 -3
- package/lib/Utils/supportPseudoClass.d.ts +2 -0
- package/lib/Utils/supportPseudoClass.d.ts.map +1 -0
- package/lib/Utils/supportPseudoClass.js +23 -0
- package/lib/Utils/tabbableElements.d.ts +2 -0
- package/lib/Utils/tabbableElements.d.ts.map +1 -0
- package/lib/Utils/tabbableElements.js +2 -2
- package/lib/connectToWebChat.js +17 -7
- package/lib/hooks/index.js +24 -24
- package/lib/hooks/internal/BypassSpeechSynthesisPonyfill.js +100 -41
- package/lib/hooks/internal/UITracker.js +2 -2
- package/lib/hooks/internal/useChanged.js +8 -1
- package/lib/hooks/internal/useDispatchScrollPosition.js +3 -7
- package/lib/hooks/internal/useDispatchTranscriptFocusByActivityKey.d.ts +2 -0
- package/lib/hooks/internal/useDispatchTranscriptFocusByActivityKey.d.ts.map +1 -0
- package/lib/hooks/internal/useDispatchTranscriptFocusByActivityKey.js +15 -0
- package/lib/hooks/internal/useEnterKeyHint.js +1 -1
- package/lib/hooks/internal/useFocusVisible.d.ts +3 -0
- package/lib/hooks/internal/useFocusVisible.d.ts.map +1 -0
- package/lib/hooks/internal/useFocusVisible.js +48 -0
- package/lib/hooks/internal/useForceRender.js +2 -2
- package/lib/hooks/internal/useForceRenderAtInterval.js +2 -2
- package/lib/hooks/internal/useInternalRenderMarkdownInline.js +1 -1
- package/lib/hooks/internal/useLocalizeAccessKey.js +2 -2
- package/lib/hooks/internal/useMemoWithPrevious.d.ts +3 -0
- package/lib/hooks/internal/useMemoWithPrevious.d.ts.map +1 -0
- package/lib/hooks/internal/useMemoWithPrevious.js +22 -0
- package/lib/hooks/internal/useMemoize.d.ts +14 -0
- package/lib/hooks/internal/useMemoize.d.ts.map +1 -0
- package/lib/hooks/internal/useMemoize.js +12 -3
- package/lib/hooks/internal/useNavigatorPlatform.js +1 -1
- package/lib/hooks/internal/useNonce.js +1 -1
- package/lib/hooks/internal/useObserveFocusVisible.d.ts +3 -0
- package/lib/hooks/internal/useObserveFocusVisible.d.ts.map +1 -0
- package/lib/hooks/internal/useObserveFocusVisible.js +208 -0
- package/lib/hooks/internal/usePrevious.d.ts +2 -0
- package/lib/hooks/internal/usePrevious.d.ts.map +1 -0
- package/lib/hooks/internal/usePrevious.js +18 -0
- package/lib/hooks/internal/useRegisterFocusSendBox.js +1 -1
- package/lib/hooks/internal/useRegisterFocusTranscript.js +1 -1
- package/lib/hooks/internal/useRegisterScrollRelative.js +1 -1
- package/lib/hooks/internal/useRegisterScrollTo.js +1 -1
- package/lib/hooks/internal/useRegisterScrollToEnd.js +1 -1
- package/lib/hooks/internal/useReplaceEmoticon.js +2 -2
- package/lib/hooks/internal/useResumeAudioContext.js +2 -2
- package/lib/hooks/internal/useScrollRelative.js +1 -1
- package/lib/hooks/internal/useSettableDictateAbortable.js +1 -1
- package/lib/hooks/internal/useStateRef.d.ts +3 -0
- package/lib/hooks/internal/useStateRef.d.ts.map +1 -0
- package/lib/hooks/internal/useStateRef.js +40 -0
- package/lib/hooks/internal/useSuggestedActionsAccessKey.js +1 -1
- package/lib/hooks/internal/useValueRef.d.ts +3 -0
- package/lib/hooks/internal/useValueRef.d.ts.map +1 -0
- package/lib/hooks/internal/useValueRef.js +25 -0
- package/lib/hooks/useDictateAbortable.js +2 -2
- package/lib/hooks/useFocus.d.ts +1 -1
- package/lib/hooks/useFocus.d.ts.map +1 -1
- package/lib/hooks/useFocus.js +1 -1
- package/lib/hooks/useObserveScrollPosition.js +2 -2
- package/lib/hooks/useObserveTranscriptFocus.js +2 -2
- package/lib/hooks/useRenderMarkdownAsHTML.d.ts.map +1 -1
- package/lib/hooks/useRenderMarkdownAsHTML.js +2 -2
- package/lib/hooks/useScrollTo.d.ts.map +1 -1
- package/lib/hooks/useScrollTo.js +1 -1
- package/lib/hooks/useScrollToEnd.d.ts.map +1 -1
- package/lib/hooks/useScrollToEnd.js +1 -1
- package/lib/hooks/useSendFiles.js +3 -3
- package/lib/index.d.ts +10 -0
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +20 -18
- package/lib/providers/ActivityTree/ActivityTreeComposer.d.ts +5 -0
- package/lib/providers/ActivityTree/ActivityTreeComposer.d.ts.map +1 -0
- package/lib/providers/ActivityTree/ActivityTreeComposer.js +86 -0
- package/lib/providers/ActivityTree/private/Context.d.ts +9 -0
- package/lib/providers/ActivityTree/private/Context.d.ts.map +1 -0
- package/lib/providers/ActivityTree/private/Context.js +13 -0
- package/lib/providers/ActivityTree/private/types.d.ts +10 -0
- package/lib/providers/ActivityTree/private/types.d.ts.map +1 -0
- package/lib/providers/ActivityTree/private/types.js +2 -0
- package/lib/providers/ActivityTree/private/useActivitiesWithRenderer.d.ts +4 -0
- package/lib/providers/ActivityTree/private/useActivitiesWithRenderer.d.ts.map +1 -0
- package/lib/providers/ActivityTree/private/useActivitiesWithRenderer.js +58 -0
- package/lib/providers/ActivityTree/private/useActivityTreeWithRenderer.d.ts +5 -0
- package/lib/providers/ActivityTree/private/useActivityTreeWithRenderer.d.ts.map +1 -0
- package/lib/providers/ActivityTree/private/useActivityTreeWithRenderer.js +166 -0
- package/lib/providers/ActivityTree/private/useContext.d.ts +3 -0
- package/lib/providers/ActivityTree/private/useContext.d.ts.map +1 -0
- package/lib/providers/ActivityTree/private/useContext.js +24 -0
- package/lib/providers/ActivityTree/useActivityTreeWithRenderer.d.ts +8 -0
- package/lib/providers/ActivityTree/useActivityTreeWithRenderer.d.ts.map +1 -0
- package/lib/providers/ActivityTree/useActivityTreeWithRenderer.js +17 -0
- package/lib/providers/LiveRegionTwin/LiveRegionTwinComposer.d.ts +35 -0
- package/lib/providers/LiveRegionTwin/LiveRegionTwinComposer.d.ts.map +1 -0
- package/lib/providers/LiveRegionTwin/LiveRegionTwinComposer.js +156 -0
- package/lib/providers/LiveRegionTwin/private/Context.d.ts +10 -0
- package/lib/providers/LiveRegionTwin/private/Context.d.ts.map +1 -0
- package/lib/providers/LiveRegionTwin/private/Context.js +13 -0
- package/lib/providers/LiveRegionTwin/private/LiveRegionTwinContainer.d.ts +11 -0
- package/lib/providers/LiveRegionTwin/private/LiveRegionTwinContainer.d.ts.map +1 -0
- package/lib/providers/LiveRegionTwin/private/LiveRegionTwinContainer.js +86 -0
- package/lib/providers/LiveRegionTwin/private/types.d.ts +8 -0
- package/lib/providers/LiveRegionTwin/private/types.d.ts.map +1 -0
- package/lib/providers/LiveRegionTwin/private/types.js +2 -0
- package/lib/providers/LiveRegionTwin/private/useContext.d.ts +3 -0
- package/lib/providers/LiveRegionTwin/private/useContext.d.ts.map +1 -0
- package/lib/providers/LiveRegionTwin/private/useContext.js +24 -0
- package/lib/providers/LiveRegionTwin/private/useMarkAllAsRenderedEffect.d.ts +2 -0
- package/lib/providers/LiveRegionTwin/private/useMarkAllAsRenderedEffect.d.ts.map +1 -0
- package/lib/providers/LiveRegionTwin/private/useMarkAllAsRenderedEffect.js +24 -0
- package/lib/providers/LiveRegionTwin/private/useStaticElementEntries.d.ts +3 -0
- package/lib/providers/LiveRegionTwin/private/useStaticElementEntries.d.ts.map +1 -0
- package/lib/providers/LiveRegionTwin/private/useStaticElementEntries.js +15 -0
- package/lib/providers/LiveRegionTwin/useQueueStaticElement.d.ts +8 -0
- package/lib/providers/LiveRegionTwin/useQueueStaticElement.d.ts.map +1 -0
- package/lib/providers/LiveRegionTwin/useQueueStaticElement.js +20 -0
- package/lib/providers/TranscriptFocus/TranscriptFocusComposer.d.ts +7 -0
- package/lib/providers/TranscriptFocus/TranscriptFocusComposer.d.ts.map +1 -0
- package/lib/providers/TranscriptFocus/TranscriptFocusComposer.js +184 -0
- package/lib/providers/TranscriptFocus/private/Context.d.ts +12 -0
- package/lib/providers/TranscriptFocus/private/Context.d.ts.map +1 -0
- package/lib/providers/TranscriptFocus/private/Context.js +13 -0
- package/lib/providers/TranscriptFocus/private/useContext.d.ts +2 -0
- package/lib/providers/TranscriptFocus/private/useContext.d.ts.map +1 -0
- package/lib/providers/TranscriptFocus/private/useContext.js +24 -0
- package/lib/providers/TranscriptFocus/useActiveDescendantId.d.ts +2 -0
- package/lib/providers/TranscriptFocus/useActiveDescendantId.d.ts.map +1 -0
- package/lib/providers/TranscriptFocus/useActiveDescendantId.js +15 -0
- package/lib/providers/TranscriptFocus/useFocusByActivityKey.d.ts +8 -0
- package/lib/providers/TranscriptFocus/useFocusByActivityKey.d.ts.map +1 -0
- package/lib/providers/TranscriptFocus/useFocusByActivityKey.js +21 -0
- package/lib/providers/TranscriptFocus/useFocusRelativeActivity.d.ts +2 -0
- package/lib/providers/TranscriptFocus/useFocusRelativeActivity.d.ts.map +1 -0
- package/lib/providers/TranscriptFocus/useFocusRelativeActivity.js +15 -0
- package/lib/providers/TranscriptFocus/useFocusedActivityKey.d.ts +2 -0
- package/lib/providers/TranscriptFocus/useFocusedActivityKey.d.ts.map +1 -0
- package/lib/providers/TranscriptFocus/useFocusedActivityKey.js +15 -0
- package/lib/providers/TranscriptFocus/useFocusedExplicitly.d.ts +2 -0
- package/lib/providers/TranscriptFocus/useFocusedExplicitly.d.ts.map +1 -0
- package/lib/providers/TranscriptFocus/useFocusedExplicitly.js +15 -0
- package/lib/providers/TranscriptFocus/useGetDescendantIdByActivityKey.d.ts +2 -0
- package/lib/providers/TranscriptFocus/useGetDescendantIdByActivityKey.d.ts.map +1 -0
- package/lib/providers/TranscriptFocus/useGetDescendantIdByActivityKey.js +15 -0
- package/package.json +25 -33
- package/src/Activity/CarouselFilmStrip.js +2 -3
- package/src/Activity/CarouselFilmStripAttachment.js +0 -1
- package/src/Activity/StackedLayout.tsx +10 -9
- package/src/Attachment/FileAttachment.js +1 -1
- package/src/Attachment/FileContent.tsx +12 -0
- package/src/BasicToaster.js +9 -5
- package/src/BasicTranscript.tsx +898 -0
- package/src/BasicTypingIndicator.tsx +3 -2
- package/src/Composer.tsx +41 -29
- package/src/Dictation.js +4 -3
- package/src/Middleware/Activity/createCoreMiddleware.tsx +50 -44
- package/src/Middleware/ActivityStatus/createSendStatusMiddleware.js +10 -6
- package/src/Middleware/ActivityStatus/createTimestampMiddleware.js +10 -8
- package/src/Middleware/Attachment/createCoreMiddleware.tsx +28 -28
- package/src/Middleware/AttachmentForScreenReader/createCoreMiddleware.tsx +25 -23
- package/src/Middleware/Avatar/createCoreMiddleware.tsx +9 -8
- package/src/Middleware/CardAction/createCoreMiddleware.js +50 -41
- package/src/Middleware/GroupActivities/createCoreMiddleware.js +6 -4
- package/src/Middleware/ScrollToEndButton/createScrollToEndButtonMiddleware.ts +11 -9
- package/src/Middleware/Toast/createCoreMiddleware.tsx +12 -10
- package/src/Middleware/TypingIndicator/createCoreMiddleware.tsx +8 -2
- package/src/ScreenReaderActivity.js +20 -6
- package/src/{ScreenReaderText.js → ScreenReaderText.tsx} +27 -9
- package/src/SendBox/{IconButton.js → IconButton.tsx} +19 -3
- package/src/SendBox/{SuggestedAction.js → SuggestedAction.tsx} +72 -35
- package/src/SendBox/SuggestedActions.tsx +64 -21
- package/src/Styles/StyleSet/BasicTranscript.ts +34 -20
- package/src/Styles/StyleSet/Bubble.ts +0 -1
- package/src/Styles/StyleSet/CarouselFilmStrip.ts +12 -10
- package/src/Styles/StyleSet/CarouselFilmStripAttachment.ts +4 -3
- package/src/Styles/StyleSet/KeyboardHelp.ts +157 -0
- package/src/Styles/StyleSet/ScrollToEndButton.ts +1 -1
- package/src/Styles/StyleSet/SendBoxButton.ts +84 -13
- package/src/Styles/StyleSet/SendBoxTextBox.ts +1 -2
- package/src/Styles/StyleSet/StackedLayout.ts +13 -11
- package/src/Styles/StyleSet/SuggestedAction.ts +129 -42
- package/src/Styles/StyleSet/SuggestedActions.ts +13 -5
- package/src/Styles/createStyleSet.ts +2 -1
- package/src/Styles/mirrorStyle.js +10 -2
- package/src/Toast/NotificationIcon.js +4 -1
- package/src/Toast/createToastMiddleware.tsx +4 -1
- package/src/Transcript/ActivityRow.tsx +124 -0
- package/src/Transcript/ActivityTextAlt.tsx +32 -0
- package/src/Transcript/FocusTrap.tsx +64 -0
- package/src/Transcript/KeyboardHelp.tsx +282 -0
- package/src/Transcript/LiveRegionTranscript.tsx +181 -0
- package/src/Transcript/types.ts +1 -0
- package/src/Transcript/useActivityAccessibleName.ts +85 -0
- package/src/Utils/{AccessibleButton.js → AccessibleButton.tsx} +19 -4
- package/src/Utils/{FocusRedirector.js → FocusRedirector.tsx} +21 -8
- package/src/Utils/InlineMarkdown.js +18 -2
- package/src/Utils/TypeFocusSink/FocusBox.js +4 -4
- package/src/Utils/TypeFocusSink/inputtableKey.ts +5 -1
- package/src/Utils/createCustomEvent.js +7 -1
- package/src/Utils/detectBrowser.js +2 -1
- package/src/Utils/findAncestor.ts +12 -0
- package/src/Utils/getActivityUniqueId.ts +5 -0
- package/src/Utils/intersectionOf.ts +14 -0
- package/src/Utils/isZeroOrPositive.ts +7 -0
- package/src/Utils/mapMap.js +7 -1
- package/src/Utils/scrollIntoViewWithBlockNearest.ts +20 -0
- package/src/Utils/shallowEquals.js +8 -1
- package/src/Utils/supportPseudoClass.ts +17 -0
- package/src/Utils/{tabbableElements.js → tabbableElements.ts} +6 -5
- package/src/connectToWebChat.js +11 -4
- package/src/hooks/internal/BypassSpeechSynthesisPonyfill.js +70 -17
- package/src/hooks/internal/useChanged.ts +17 -0
- package/src/hooks/internal/useDispatchScrollPosition.js +1 -3
- package/src/hooks/internal/useDispatchTranscriptFocusByActivityKey.ts +5 -0
- package/src/hooks/internal/useFocusVisible.ts +22 -0
- package/src/hooks/internal/useMemoWithPrevious.ts +16 -0
- package/src/hooks/internal/useMemoize.spec.js +1 -1
- package/src/hooks/internal/useMemoize.ts +53 -0
- package/src/hooks/internal/useObserveFocusVisible.ts +252 -0
- package/src/hooks/internal/usePrevious.ts +12 -0
- package/src/hooks/internal/useScrollRelative.js +4 -3
- package/src/hooks/internal/useStateRef.ts +31 -0
- package/src/hooks/internal/useValueRef.ts +22 -0
- package/src/hooks/useFocus.ts +1 -1
- package/src/hooks/useRenderMarkdownAsHTML.ts +4 -5
- package/src/hooks/useScrollTo.ts +4 -3
- package/src/hooks/useScrollToEnd.ts +4 -3
- package/src/index.ts +0 -1
- package/src/providers/ActivityTree/ActivityTreeComposer.tsx +74 -0
- package/src/providers/ActivityTree/private/Context.ts +12 -0
- package/src/providers/ActivityTree/private/types.ts +12 -0
- package/src/providers/ActivityTree/private/useActivitiesWithRenderer.ts +66 -0
- package/src/providers/ActivityTree/private/useActivityTreeWithRenderer.ts +140 -0
- package/src/providers/ActivityTree/private/useContext.ts +15 -0
- package/src/providers/ActivityTree/useActivityTreeWithRenderer.ts +16 -0
- package/src/providers/LiveRegionTwin/LiveRegionTwinComposer.tsx +154 -0
- package/src/providers/LiveRegionTwin/private/Context.ts +15 -0
- package/src/providers/LiveRegionTwin/private/LiveRegionTwinContainer.tsx +64 -0
- package/src/providers/LiveRegionTwin/private/types.ts +10 -0
- package/src/providers/LiveRegionTwin/private/useContext.ts +15 -0
- package/src/providers/LiveRegionTwin/private/useMarkAllAsRenderedEffect.ts +13 -0
- package/src/providers/LiveRegionTwin/private/useStaticElementEntries.ts +7 -0
- package/src/providers/LiveRegionTwin/useQueueStaticElement.ts +12 -0
- package/src/providers/TranscriptFocus/TranscriptFocusComposer.tsx +180 -0
- package/src/providers/TranscriptFocus/private/Context.ts +16 -0
- package/src/providers/TranscriptFocus/private/useContext.ts +13 -0
- package/src/providers/TranscriptFocus/useActiveDescendantId.ts +5 -0
- package/src/providers/TranscriptFocus/useFocusByActivityKey.ts +14 -0
- package/src/providers/TranscriptFocus/useFocusRelativeActivity.ts +5 -0
- package/src/providers/TranscriptFocus/useFocusedActivityKey.ts +5 -0
- package/src/providers/TranscriptFocus/useFocusedExplicitly.ts +5 -0
- package/src/providers/TranscriptFocus/useGetDescendantIdByActivityKey.ts +5 -0
- package/.eslintignore +0 -1
- package/lib/Utils/findLastIndex.js +0 -32
- package/lib/hooks/internal/useAcknowledgedActivity.js +0 -90
- package/lib/hooks/internal/useDispatchTranscriptFocus.js +0 -19
- package/src/BasicTranscript.js +0 -1140
- package/src/Utils/findLastIndex.js +0 -11
- package/src/Utils/findLastIndex.spec.js +0 -31
- package/src/Utils/getActivityUniqueId.js +0 -3
- package/src/Utils/intersectionOf.js +0 -11
- package/src/Utils/isZeroOrPositive.js +0 -4
- package/src/hooks/internal/useAcknowledgedActivity.js +0 -65
- package/src/hooks/internal/useChanged.js +0 -10
- package/src/hooks/internal/useDispatchTranscriptFocus.js +0 -7
- package/src/hooks/internal/useMemoize.js +0 -37
|
@@ -6,11 +6,12 @@
|
|
|
6
6
|
/* eslint max-classes-per-file: ["error", 4] */
|
|
7
7
|
/* eslint no-empty-function: "off" */
|
|
8
8
|
|
|
9
|
-
import EventTarget, {
|
|
9
|
+
import EventTarget, { Event, getEventAttributeValue, setEventAttributeValue } from 'event-target-shim/es5';
|
|
10
10
|
|
|
11
|
-
class SpeechSynthesisEvent {
|
|
11
|
+
class SpeechSynthesisEvent extends Event {
|
|
12
12
|
constructor(type, utterance) {
|
|
13
|
-
|
|
13
|
+
super(type);
|
|
14
|
+
|
|
14
15
|
this._utterance = utterance;
|
|
15
16
|
}
|
|
16
17
|
|
|
@@ -22,10 +23,8 @@ class SpeechSynthesisEvent {
|
|
|
22
23
|
return 0;
|
|
23
24
|
}
|
|
24
25
|
|
|
25
|
-
get name() {
|
|
26
|
-
|
|
27
|
-
get type() {
|
|
28
|
-
return this._type;
|
|
26
|
+
get name() {
|
|
27
|
+
// It is expected to return `undefined`, keeping the function empty to reduce footprint.
|
|
29
28
|
}
|
|
30
29
|
|
|
31
30
|
get utterance() {
|
|
@@ -92,15 +91,63 @@ class SpeechSynthesisUtterance extends EventTarget {
|
|
|
92
91
|
set volume(value) {
|
|
93
92
|
this._volume = value;
|
|
94
93
|
}
|
|
95
|
-
}
|
|
96
94
|
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
95
|
+
get onboundary() {
|
|
96
|
+
return getEventAttributeValue(this, 'boundary');
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
set onboundary(value) {
|
|
100
|
+
setEventAttributeValue(this, 'boundary', value);
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
get onend() {
|
|
104
|
+
return getEventAttributeValue(this, 'end');
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
set onend(value) {
|
|
108
|
+
setEventAttributeValue(this, 'end', value);
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
get onerror() {
|
|
112
|
+
return getEventAttributeValue(this, 'error');
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
set onerror(value) {
|
|
116
|
+
setEventAttributeValue(this, 'error', value);
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
get onmark() {
|
|
120
|
+
return getEventAttributeValue(this, 'mark');
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
set onmark(value) {
|
|
124
|
+
setEventAttributeValue(this, 'mark', value);
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
get onpause() {
|
|
128
|
+
return getEventAttributeValue(this, 'pause');
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
set onpause(value) {
|
|
132
|
+
setEventAttributeValue(this, 'pause', value);
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
get onresume() {
|
|
136
|
+
return getEventAttributeValue(this, 'resume');
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
set onresume(value) {
|
|
140
|
+
setEventAttributeValue(this, 'resume', value);
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
get onstart() {
|
|
144
|
+
return getEventAttributeValue(this, 'start');
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
set onstart(value) {
|
|
148
|
+
setEventAttributeValue(this, 'start', value);
|
|
149
|
+
}
|
|
150
|
+
}
|
|
104
151
|
|
|
105
152
|
class SpeechSynthesisVoice {
|
|
106
153
|
get default() {
|
|
@@ -155,9 +202,15 @@ class SpeechSynthesis extends EventTarget {
|
|
|
155
202
|
utterance.dispatchEvent(new SpeechSynthesisEvent('start', utterance));
|
|
156
203
|
utterance.dispatchEvent(new SpeechSynthesisEvent('end', utterance));
|
|
157
204
|
}
|
|
158
|
-
}
|
|
159
205
|
|
|
160
|
-
|
|
206
|
+
get onvoiceschanged() {
|
|
207
|
+
return getEventAttributeValue(this, 'voiceschanged');
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
set onvoiceschanged(value) {
|
|
211
|
+
setEventAttributeValue(this, 'voiceschanged', value);
|
|
212
|
+
}
|
|
213
|
+
}
|
|
161
214
|
|
|
162
215
|
const speechSynthesis = new SpeechSynthesis();
|
|
163
216
|
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { useRef } from 'react';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Returns `true` if the `value` has changed, otherwise, `false`.
|
|
5
|
+
*
|
|
6
|
+
* Note: on initial call, this will return `true`.
|
|
7
|
+
*
|
|
8
|
+
* @param {T} value - The `value` to detect for changes.
|
|
9
|
+
*/
|
|
10
|
+
export default function useChanged<T>(value: T): boolean {
|
|
11
|
+
const prevValueRef = useRef(value);
|
|
12
|
+
const changed = value !== prevValueRef.current;
|
|
13
|
+
|
|
14
|
+
prevValueRef.current = value;
|
|
15
|
+
|
|
16
|
+
return changed;
|
|
17
|
+
}
|
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
import useWebChatUIContext from './useWebChatUIContext';
|
|
2
2
|
|
|
3
3
|
export default function useDispatchScrollPosition() {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
return numScrollPositionObservers ? dispatchScrollPosition : undefined;
|
|
4
|
+
return useWebChatUIContext().dispatchScrollPosition;
|
|
7
5
|
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { RefObject, useCallback, useEffect, useState } from 'react';
|
|
2
|
+
|
|
3
|
+
import useObserveFocusVisible from './useObserveFocusVisible';
|
|
4
|
+
|
|
5
|
+
export default function useFocusVisible(targetRef: RefObject<HTMLElement>): [boolean] {
|
|
6
|
+
const [focusVisible, setFocusVisible] = useState(false);
|
|
7
|
+
|
|
8
|
+
const handleBlur = useCallback(() => setFocusVisible(false), [setFocusVisible]);
|
|
9
|
+
const handleFocusVisible = useCallback(() => setFocusVisible(true), [setFocusVisible]);
|
|
10
|
+
|
|
11
|
+
useObserveFocusVisible(targetRef, handleFocusVisible);
|
|
12
|
+
|
|
13
|
+
useEffect(() => {
|
|
14
|
+
const { current } = targetRef;
|
|
15
|
+
|
|
16
|
+
current.addEventListener('blur', handleBlur);
|
|
17
|
+
|
|
18
|
+
return () => current.removeEventListener('blur', handleBlur);
|
|
19
|
+
}, [handleBlur, targetRef]);
|
|
20
|
+
|
|
21
|
+
return [focusVisible];
|
|
22
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { useEffect, useMemo, useRef } from 'react';
|
|
2
|
+
|
|
3
|
+
import type { DependencyList } from 'react';
|
|
4
|
+
|
|
5
|
+
export default function useMemoWithPrevious<T>(factory: (prevValue: T) => T, deps: DependencyList): T {
|
|
6
|
+
const prevValueRef = useRef<T>();
|
|
7
|
+
// We are building a `useMemo`-like hook, `deps` is passed as-is and `factory` is not one fo the dependencies.
|
|
8
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
9
|
+
const value = useMemo<T>(() => factory(prevValueRef.current), deps);
|
|
10
|
+
|
|
11
|
+
useEffect(() => {
|
|
12
|
+
prevValueRef.current = value;
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
return value;
|
|
16
|
+
}
|
|
@@ -7,7 +7,7 @@ jest.mock('react', () => {
|
|
|
7
7
|
let lastResult;
|
|
8
8
|
|
|
9
9
|
function arrayEquals(x, y) {
|
|
10
|
-
return x.length === y.length &&
|
|
10
|
+
return x.length === y.length && [].every.call(x, (item, index) => Object.is(item, y[+index]));
|
|
11
11
|
}
|
|
12
12
|
|
|
13
13
|
return {
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { DependencyList, useMemo } from 'react';
|
|
2
|
+
|
|
3
|
+
type Cache<TArgs, TResult> = { args: TArgs[]; result: TResult };
|
|
4
|
+
type Fn<TArgs, TResult> = (...args: TArgs[]) => TResult;
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* `useMemoize` will memoize multiple calls to the same memoize function.
|
|
8
|
+
*
|
|
9
|
+
* This is similar to `useMemo`. But instead of calling it once, `useMemoize` enables multiple calls while the `callback` function is executed.
|
|
10
|
+
*
|
|
11
|
+
* @param {Fn<TArgs, TIntermediate>} fn - The function to be memoized.
|
|
12
|
+
* @param {(fn: Fn<TArgs, TIntermediate>) => TFinal} callback - When called, this function should execute the memoizing function.
|
|
13
|
+
* @param {DependencyList[]} deps - Dependencies to detect for chagnes.
|
|
14
|
+
*/
|
|
15
|
+
export default function useMemoize<TArgs extends [], TIntermediate, TFinal>(
|
|
16
|
+
fn: Fn<TArgs, TIntermediate>,
|
|
17
|
+
callback: (fn: Fn<TArgs, TIntermediate>) => TFinal,
|
|
18
|
+
deps: DependencyList[]
|
|
19
|
+
): TFinal {
|
|
20
|
+
if (typeof fn !== 'function') {
|
|
21
|
+
throw new Error('The first argument must be a function.');
|
|
22
|
+
} else if (typeof callback !== 'function') {
|
|
23
|
+
throw new Error('The second argument must be a function.');
|
|
24
|
+
} else if (!Array.isArray(deps)) {
|
|
25
|
+
throw new Error('The third argument must be an array.');
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
const memoizedFn = useMemo(() => {
|
|
29
|
+
let cache: Cache<TArgs, TIntermediate>[] = [];
|
|
30
|
+
|
|
31
|
+
return (run: (fn: Fn<TArgs, TIntermediate>) => TFinal) => {
|
|
32
|
+
const nextCache: Cache<TArgs, TIntermediate>[] = [];
|
|
33
|
+
const result = run((...args) => {
|
|
34
|
+
const { result } = [...cache, ...nextCache].find(
|
|
35
|
+
({ args: cachedArgs }) =>
|
|
36
|
+
args.length === cachedArgs.length && args.every((arg, index) => Object.is(arg, cachedArgs[+index]))
|
|
37
|
+
) || { result: fn(...args) };
|
|
38
|
+
|
|
39
|
+
nextCache.push({ args, result });
|
|
40
|
+
|
|
41
|
+
return result;
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
cache = nextCache;
|
|
45
|
+
|
|
46
|
+
return result;
|
|
47
|
+
};
|
|
48
|
+
// We are manually creating the deps here. The "callback" arg is also designed not to be impact deps, similar to useEffect(fn), where "fn" is not in deps.
|
|
49
|
+
/* eslint-disable-next-line react-hooks/exhaustive-deps */
|
|
50
|
+
}, [fn, ...deps]);
|
|
51
|
+
|
|
52
|
+
return memoizedFn(callback);
|
|
53
|
+
}
|
|
@@ -0,0 +1,252 @@
|
|
|
1
|
+
import { MutableRefObject, RefObject, useCallback, useEffect, useMemo, useRef } from 'react';
|
|
2
|
+
|
|
3
|
+
import supportPseudoClass from '../../Utils/supportPseudoClass';
|
|
4
|
+
import useNonce from './useNonce';
|
|
5
|
+
import useValueRef from './useValueRef';
|
|
6
|
+
|
|
7
|
+
const INPUT_TYPES_ALLOW_LIST = [
|
|
8
|
+
'date',
|
|
9
|
+
'datetime-local',
|
|
10
|
+
'datetime',
|
|
11
|
+
'email',
|
|
12
|
+
'month',
|
|
13
|
+
'number',
|
|
14
|
+
'password',
|
|
15
|
+
'search',
|
|
16
|
+
'tel',
|
|
17
|
+
'text',
|
|
18
|
+
'time',
|
|
19
|
+
'url',
|
|
20
|
+
'week'
|
|
21
|
+
];
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Computes whether the given element should automatically trigger the
|
|
25
|
+
* `focus-visible` class being added, i.e. whether it should always match
|
|
26
|
+
* `:focus-visible` when focused.
|
|
27
|
+
* @param {Element} el
|
|
28
|
+
* @return {boolean}
|
|
29
|
+
*/
|
|
30
|
+
function focusTriggersKeyboardModality(el: HTMLInputElement | HTMLTextAreaElement): boolean {
|
|
31
|
+
const { isContentEditable, readOnly, tagName, type } = el;
|
|
32
|
+
|
|
33
|
+
return (
|
|
34
|
+
(tagName === 'INPUT' && INPUT_TYPES_ALLOW_LIST.includes(type) && !readOnly) ||
|
|
35
|
+
(tagName === 'TEXTAREA' && !readOnly) ||
|
|
36
|
+
isContentEditable
|
|
37
|
+
);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
function createEventSubscription(
|
|
41
|
+
target: Element | Node,
|
|
42
|
+
types: string[],
|
|
43
|
+
handler: (event: Event) => void
|
|
44
|
+
): {
|
|
45
|
+
pause: () => void;
|
|
46
|
+
resume: () => void;
|
|
47
|
+
} {
|
|
48
|
+
let subscribed: true;
|
|
49
|
+
|
|
50
|
+
const subscribe = () => {
|
|
51
|
+
if (!subscribed) {
|
|
52
|
+
types.forEach(type => target.addEventListener(type, handler));
|
|
53
|
+
subscribed = true;
|
|
54
|
+
}
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
const unsubscribe = () => {
|
|
58
|
+
if (subscribed) {
|
|
59
|
+
types.forEach(type => target.removeEventListener(type, handler));
|
|
60
|
+
subscribed = undefined;
|
|
61
|
+
}
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
return {
|
|
65
|
+
pause: unsubscribe,
|
|
66
|
+
resume: subscribe
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
// TODO: Add tests
|
|
71
|
+
// 1. Focus via keyboard vs. mouse
|
|
72
|
+
// 2. Focus via keyboard, switch app, switch back (expect to get another focusVisible after switch back)
|
|
73
|
+
// 3. Focus via mouse, switch app, switch back (do NOT expect to get another focusVisible after switch back)
|
|
74
|
+
function useObserveFocusVisibleForLegacyBrowsers(
|
|
75
|
+
targetRef: RefObject<HTMLElement>,
|
|
76
|
+
onFocusVisibleRef: MutableRefObject<() => void>
|
|
77
|
+
) {
|
|
78
|
+
// This polyfill algorithm is adopted from https://github.com/WICG/focus-visible.
|
|
79
|
+
const blurSinceRef = useRef(0);
|
|
80
|
+
const hadKeyboardEventRef = useRef(true);
|
|
81
|
+
const hasFocusVisibleRef = useRef(false);
|
|
82
|
+
|
|
83
|
+
const eventSubscription = useMemo(
|
|
84
|
+
() =>
|
|
85
|
+
createEventSubscription(
|
|
86
|
+
document,
|
|
87
|
+
[
|
|
88
|
+
'mousemove',
|
|
89
|
+
'mousedown',
|
|
90
|
+
'mouseup',
|
|
91
|
+
'pointermove',
|
|
92
|
+
'pointerdown',
|
|
93
|
+
'pointerup',
|
|
94
|
+
'touchmove',
|
|
95
|
+
'touchstart',
|
|
96
|
+
'touchend'
|
|
97
|
+
],
|
|
98
|
+
event => {
|
|
99
|
+
if ((event.target as HTMLElement).nodeName?.toLowerCase() !== 'html') {
|
|
100
|
+
hadKeyboardEventRef.current = false;
|
|
101
|
+
eventSubscription.pause();
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
),
|
|
105
|
+
[hadKeyboardEventRef]
|
|
106
|
+
);
|
|
107
|
+
|
|
108
|
+
const setHasFocusVisible = useCallback(
|
|
109
|
+
nextHasFocusVisible => {
|
|
110
|
+
if (hasFocusVisibleRef.current !== nextHasFocusVisible) {
|
|
111
|
+
hasFocusVisibleRef.current = nextHasFocusVisible;
|
|
112
|
+
nextHasFocusVisible && onFocusVisibleRef?.current();
|
|
113
|
+
}
|
|
114
|
+
},
|
|
115
|
+
[hasFocusVisibleRef, onFocusVisibleRef]
|
|
116
|
+
);
|
|
117
|
+
|
|
118
|
+
const handleKeyDown = useCallback(
|
|
119
|
+
(event: KeyboardEvent) => {
|
|
120
|
+
if (event.altKey || event.ctrlKey || event.metaKey) {
|
|
121
|
+
return;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
if (event.target === targetRef.current) {
|
|
125
|
+
setHasFocusVisible(true);
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
hadKeyboardEventRef.current = true;
|
|
129
|
+
},
|
|
130
|
+
[hadKeyboardEventRef, setHasFocusVisible, targetRef]
|
|
131
|
+
);
|
|
132
|
+
|
|
133
|
+
const handlePointerDown = useCallback(() => {
|
|
134
|
+
hadKeyboardEventRef.current = false;
|
|
135
|
+
}, [hadKeyboardEventRef]);
|
|
136
|
+
|
|
137
|
+
const handleFocus = useCallback(
|
|
138
|
+
({ target }: Event) => {
|
|
139
|
+
target === targetRef.current &&
|
|
140
|
+
(hadKeyboardEventRef.current || focusTriggersKeyboardModality(target as HTMLInputElement)) &&
|
|
141
|
+
setHasFocusVisible(true);
|
|
142
|
+
},
|
|
143
|
+
[hadKeyboardEventRef, setHasFocusVisible, targetRef]
|
|
144
|
+
);
|
|
145
|
+
|
|
146
|
+
const handleBlur = useCallback(
|
|
147
|
+
(event: Event) => {
|
|
148
|
+
if (event.target === targetRef.current && hasFocusVisibleRef.current) {
|
|
149
|
+
blurSinceRef.current = Date.now();
|
|
150
|
+
|
|
151
|
+
setHasFocusVisible(false);
|
|
152
|
+
}
|
|
153
|
+
},
|
|
154
|
+
[blurSinceRef, hasFocusVisibleRef, setHasFocusVisible, targetRef]
|
|
155
|
+
);
|
|
156
|
+
|
|
157
|
+
const handleVisibilityChange = useCallback(() => {
|
|
158
|
+
if (document.visibilityState === 'hidden') {
|
|
159
|
+
// The element is blurred due to "visibilityState" set to "hidden".
|
|
160
|
+
// 100ms is referenced from the WICG polyfill.
|
|
161
|
+
// eslint-disable-next-line no-magic-numbers
|
|
162
|
+
if (Date.now() - blurSinceRef.current < 100) {
|
|
163
|
+
hadKeyboardEventRef.current = true;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
eventSubscription.resume();
|
|
167
|
+
}
|
|
168
|
+
}, [blurSinceRef, eventSubscription, hadKeyboardEventRef]);
|
|
169
|
+
|
|
170
|
+
useEffect(() => {
|
|
171
|
+
document.addEventListener('keydown', handleKeyDown, true);
|
|
172
|
+
document.addEventListener('mousedown', handlePointerDown, true);
|
|
173
|
+
document.addEventListener('pointerdown', handlePointerDown, true);
|
|
174
|
+
document.addEventListener('touchstart', handlePointerDown, true);
|
|
175
|
+
document.addEventListener('visibilitychange', handleVisibilityChange, true);
|
|
176
|
+
|
|
177
|
+
return () => {
|
|
178
|
+
document.removeEventListener('keydown', handleKeyDown);
|
|
179
|
+
document.removeEventListener('mousedown', handlePointerDown);
|
|
180
|
+
document.removeEventListener('pointerdown', handlePointerDown);
|
|
181
|
+
document.removeEventListener('touchstart', handlePointerDown);
|
|
182
|
+
document.removeEventListener('visibilitychange', handleVisibilityChange);
|
|
183
|
+
};
|
|
184
|
+
}, [handleKeyDown, handlePointerDown, handleVisibilityChange]);
|
|
185
|
+
|
|
186
|
+
useEffect(() => {
|
|
187
|
+
const { current: target } = targetRef;
|
|
188
|
+
|
|
189
|
+
target.addEventListener('blur', handleBlur, true);
|
|
190
|
+
target.addEventListener('focus', handleFocus, true);
|
|
191
|
+
|
|
192
|
+
return () => {
|
|
193
|
+
target.removeEventListener('blur', handleBlur);
|
|
194
|
+
target.removeEventListener('focus', handleFocus);
|
|
195
|
+
};
|
|
196
|
+
|
|
197
|
+
// We specifically add "targetRef.current" here.
|
|
198
|
+
// If the target element changed, we should reattach our event listeners.
|
|
199
|
+
}, [handleBlur, handleFocus, targetRef]);
|
|
200
|
+
|
|
201
|
+
useEffect(() => {
|
|
202
|
+
eventSubscription.resume();
|
|
203
|
+
|
|
204
|
+
return () => eventSubscription.pause();
|
|
205
|
+
}, [eventSubscription]);
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
function useObserveFocusVisibleForModernBrowsers(
|
|
209
|
+
targetRef: RefObject<HTMLElement>,
|
|
210
|
+
onFocusVisibleRef: MutableRefObject<() => void>
|
|
211
|
+
) {
|
|
212
|
+
const handleFocus = useCallback(() => {
|
|
213
|
+
if (targetRef.current.matches(':focus-visible')) {
|
|
214
|
+
onFocusVisibleRef?.current();
|
|
215
|
+
}
|
|
216
|
+
}, [onFocusVisibleRef, targetRef]);
|
|
217
|
+
|
|
218
|
+
useEffect(() => {
|
|
219
|
+
const { current: target } = targetRef;
|
|
220
|
+
|
|
221
|
+
target.addEventListener('focus', handleFocus);
|
|
222
|
+
|
|
223
|
+
return () => target.removeEventListener('focus', handleFocus);
|
|
224
|
+
|
|
225
|
+
// We specifically add "targetRef.current" here.
|
|
226
|
+
// If the target element changed, we should reattach our event listeners.
|
|
227
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
228
|
+
}, [handleFocus, targetRef, targetRef.current]);
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
export default function useObserveFocusVisible(targetRef: RefObject<HTMLElement>, onFocusVisible: () => void) {
|
|
232
|
+
const [nonce] = useNonce();
|
|
233
|
+
const onFocusVisibleRef = useValueRef(onFocusVisible);
|
|
234
|
+
|
|
235
|
+
// The nonce is use for browser capabilities. Just in case the "nonce" had changed unexpectedly, the capabilities of the browser should never change.
|
|
236
|
+
// Thus, we are using an initial version of "nonce". In case web devs changed the "nonce" to an invalid value, we won't break rules of hooks (as stated below).
|
|
237
|
+
const nonceRef = useRef(nonce);
|
|
238
|
+
|
|
239
|
+
// ":focus-visible" selector is supported from Chrome/Edge 86+ and not supported in IE11 or Safari.
|
|
240
|
+
// Doing a capability check on pseudo classes requires injecting a stylesheet, thus nonce is needed.
|
|
241
|
+
const supportFocusVisible = useMemo(() => supportPseudoClass(':focus-visible', nonceRef.current), [nonceRef]);
|
|
242
|
+
|
|
243
|
+
// Since "supportPseudoClass" is a browser capability, the result should be constant during the page lifetime.
|
|
244
|
+
// Thus, running hooks conditionally is okay here.
|
|
245
|
+
if (supportFocusVisible) {
|
|
246
|
+
// eslint-disable-next-line react-hooks/rules-of-hooks
|
|
247
|
+
useObserveFocusVisibleForModernBrowsers(targetRef, onFocusVisibleRef);
|
|
248
|
+
} else {
|
|
249
|
+
// eslint-disable-next-line react-hooks/rules-of-hooks
|
|
250
|
+
useObserveFocusVisibleForLegacyBrowsers(targetRef, onFocusVisibleRef);
|
|
251
|
+
}
|
|
252
|
+
}
|
|
@@ -5,7 +5,8 @@ import useWebChatUIContext from './useWebChatUIContext';
|
|
|
5
5
|
export default function useScrollRelative() {
|
|
6
6
|
const { scrollRelativeCallbacksRef } = useWebChatUIContext();
|
|
7
7
|
|
|
8
|
-
return useCallback(
|
|
9
|
-
scrollRelativeCallbacksRef
|
|
10
|
-
|
|
8
|
+
return useCallback(
|
|
9
|
+
(...args) => scrollRelativeCallbacksRef.current.forEach(callback => callback(...args)),
|
|
10
|
+
[scrollRelativeCallbacksRef]
|
|
11
|
+
);
|
|
11
12
|
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { useCallback, useRef, useState } from 'react';
|
|
2
|
+
|
|
3
|
+
import type { Dispatch, MutableRefObject, SetStateAction } from 'react';
|
|
4
|
+
|
|
5
|
+
export default function useStateRef<T>(
|
|
6
|
+
initialValue?: T
|
|
7
|
+
): readonly [T, Dispatch<SetStateAction<T>>, MutableRefObject<T>] {
|
|
8
|
+
const [_, forceRender] = useState<{}>();
|
|
9
|
+
const valueRef: MutableRefObject<T> = useRef<T>(initialValue);
|
|
10
|
+
|
|
11
|
+
const setter: Dispatch<SetStateAction<T>> = useCallback(
|
|
12
|
+
(value: SetStateAction<T>) => {
|
|
13
|
+
const { current } = valueRef;
|
|
14
|
+
|
|
15
|
+
value = value instanceof Function ? value(current) : value;
|
|
16
|
+
|
|
17
|
+
if (current !== value) {
|
|
18
|
+
valueRef.current = value;
|
|
19
|
+
|
|
20
|
+
forceRender({});
|
|
21
|
+
}
|
|
22
|
+
},
|
|
23
|
+
[forceRender, valueRef]
|
|
24
|
+
);
|
|
25
|
+
|
|
26
|
+
return Object.freeze([valueRef.current, setter, valueRef]) as readonly [
|
|
27
|
+
T,
|
|
28
|
+
Dispatch<SetStateAction<T>>,
|
|
29
|
+
MutableRefObject<T>
|
|
30
|
+
];
|
|
31
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
// TODO: [P0] #4133 Don't copy.
|
|
2
|
+
import { RefObject, useMemo, useRef } from 'react';
|
|
3
|
+
|
|
4
|
+
export default function useValueRef<T>(value: T): RefObject<T> {
|
|
5
|
+
const ref = useRef<T>();
|
|
6
|
+
const readOnlyRef = useMemo(
|
|
7
|
+
() =>
|
|
8
|
+
Object.create(
|
|
9
|
+
{},
|
|
10
|
+
{
|
|
11
|
+
current: {
|
|
12
|
+
get: () => ref.current
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
),
|
|
16
|
+
[]
|
|
17
|
+
);
|
|
18
|
+
|
|
19
|
+
ref.current = value;
|
|
20
|
+
|
|
21
|
+
return readOnlyRef;
|
|
22
|
+
}
|
package/src/hooks/useFocus.ts
CHANGED
|
@@ -2,7 +2,7 @@ import { useCallback } from 'react';
|
|
|
2
2
|
|
|
3
3
|
import useWebChatUIContext from './internal/useWebChatUIContext';
|
|
4
4
|
|
|
5
|
-
export default function useFocus(): (where?: 'sendBox' | 'sendBoxWithoutKeyboard') => void {
|
|
5
|
+
export default function useFocus(): (where?: 'main' | 'sendBox' | 'sendBoxWithoutKeyboard') => void {
|
|
6
6
|
const { focusSendBoxCallbacksRef, focusTranscriptCallbacksRef } = useWebChatUIContext();
|
|
7
7
|
|
|
8
8
|
return useCallback(
|
|
@@ -16,9 +16,8 @@ export default function useRenderMarkdownAsHTML(): (
|
|
|
16
16
|
|
|
17
17
|
const externalLinkAlt = localize('MARKDOWN_EXTERNAL_LINK_ALT');
|
|
18
18
|
|
|
19
|
-
return useMemo(
|
|
20
|
-
externalLinkAlt,
|
|
21
|
-
renderMarkdown,
|
|
22
|
-
|
|
23
|
-
]);
|
|
19
|
+
return useMemo(
|
|
20
|
+
() => renderMarkdown && (markdown => renderMarkdown(markdown, styleOptions, { externalLinkAlt })),
|
|
21
|
+
[externalLinkAlt, renderMarkdown, styleOptions]
|
|
22
|
+
);
|
|
24
23
|
}
|
package/src/hooks/useScrollTo.ts
CHANGED
|
@@ -9,7 +9,8 @@ export default function useScrollTo(): (
|
|
|
9
9
|
) => void {
|
|
10
10
|
const { scrollToCallbacksRef } = useWebChatUIContext();
|
|
11
11
|
|
|
12
|
-
return useCallback(
|
|
13
|
-
scrollToCallbacksRef
|
|
14
|
-
|
|
12
|
+
return useCallback(
|
|
13
|
+
(...args) => scrollToCallbacksRef.current.forEach(callback => callback(...args)),
|
|
14
|
+
[scrollToCallbacksRef]
|
|
15
|
+
);
|
|
15
16
|
}
|
|
@@ -5,7 +5,8 @@ import useWebChatUIContext from './internal/useWebChatUIContext';
|
|
|
5
5
|
export default function useScrollToEnd(): () => void {
|
|
6
6
|
const { scrollToEndCallbacksRef } = useWebChatUIContext();
|
|
7
7
|
|
|
8
|
-
return useCallback(
|
|
9
|
-
scrollToEndCallbacksRef
|
|
10
|
-
|
|
8
|
+
return useCallback(
|
|
9
|
+
() => scrollToEndCallbacksRef.current.forEach(callback => callback({ behavior: 'smooth' })),
|
|
10
|
+
[scrollToEndCallbacksRef]
|
|
11
|
+
);
|
|
11
12
|
}
|