UNPKG

@azure/communication-react

Version:

React library for building modern communication user experiences utilizing Azure Communication Services

56 lines 3.88 kB
// Copyright (c) Microsoft Corporation. // Licensed under the MIT License. import { Stack, FocusZone, Spinner, useTheme } from '@fluentui/react'; import React, { useEffect, useRef, useState, useCallback } from 'react'; import { _Caption } from './Caption'; import { captionContainerClassName, captionsBannerClassName, captionsBannerFullHeightClassName, captionsContainerClassName, loadingBannerFullHeightStyles, loadingBannerStyles } from './styles/Captions.style'; import { useLocale } from '../localization'; const SCROLL_OFFSET_ALLOWANCE = 20; /** * @public * A component for displaying a CaptionsBanner with user icon, displayName and captions text. */ export const CaptionsBanner = (props) => { const { captions, isCaptionsOn, startCaptionsInProgress, onRenderAvatar, formFactor = 'default', captionsOptions } = props; const localeStrings = useLocale().strings.captionsBanner; const strings = Object.assign(Object.assign({}, localeStrings), props.strings); const captionsScrollDivRef = useRef(null); const [isAtBottomOfScroll, setIsAtBottomOfScroll] = useState(true); const theme = useTheme(); const scrollToBottom = () => { if (captionsScrollDivRef.current) { captionsScrollDivRef.current.scrollTop = captionsScrollDivRef.current.scrollHeight; } }; const handleScrollToTheBottom = useCallback(() => { if (!captionsScrollDivRef.current) { return; } const atBottom = Math.ceil(captionsScrollDivRef.current.scrollTop) >= captionsScrollDivRef.current.scrollHeight - captionsScrollDivRef.current.clientHeight - SCROLL_OFFSET_ALLOWANCE; setIsAtBottomOfScroll(atBottom); }, []); useEffect(() => { const captionsScrollDiv = captionsScrollDivRef.current; captionsScrollDiv === null || captionsScrollDiv === void 0 ? void 0 : captionsScrollDiv.addEventListener('scroll', handleScrollToTheBottom); return () => { captionsScrollDiv === null || captionsScrollDiv === void 0 ? void 0 : captionsScrollDiv.removeEventListener('scroll', handleScrollToTheBottom); }; }, [handleScrollToTheBottom, isCaptionsOn]); useEffect(() => { // only auto scroll to bottom is already is at bottom of scroll before new caption comes in if (isAtBottomOfScroll) { scrollToBottom(); } }, [captions, isAtBottomOfScroll]); const captionsTrampoline = () => { return React.createElement(React.Fragment, null, captions.map(caption => { return React.createElement("li", { key: caption.id, className: captionContainerClassName, "data-is-focusable": true }, React.createElement(_Caption, Object.assign({}, caption, { onRenderAvatar: onRenderAvatar }))); })); }; return React.createElement(React.Fragment, null, (startCaptionsInProgress || isCaptionsOn) && React.createElement(FocusZone, { shouldFocusOnMount: true, className: captionsContainerClassName, "data-ui-id": "captions-banner" }, isCaptionsOn && React.createElement("ul", { ref: captionsScrollDivRef, className: (captionsOptions === null || captionsOptions === void 0 ? void 0 : captionsOptions.height) === 'full' ? captionsBannerFullHeightClassName(theme) : captionsBannerClassName(formFactor), "data-ui-id": "captions-banner-inner" }, captionsTrampoline()), !isCaptionsOn && React.createElement(Stack, { verticalAlign: "center", styles: (captionsOptions === null || captionsOptions === void 0 ? void 0 : captionsOptions.height) === 'full' ? loadingBannerFullHeightStyles(theme) : loadingBannerStyles(formFactor), "data-is-focusable": true }, React.createElement(Spinner, { label: strings === null || strings === void 0 ? void 0 : strings.captionsBannerSpinnerText, ariaLive: "assertive", labelPosition: "right" })))); }; //# sourceMappingURL=CaptionsBanner.js.map