1
1
// Copyright (c) Microsoft Corporation.
2
2
// Licensed under the MIT License.
3
- import { Stack , FocusZone , Spinner } from '@fluentui/react' ;
3
+ import { Stack , FocusZone , Spinner , useTheme } from '@fluentui/react' ;
4
4
import React , { useEffect , useRef , useState , useCallback } from 'react' ;
5
5
import { _Caption } from './Caption' ;
6
6
import {
7
7
captionContainerClassName ,
8
8
captionsBannerClassName ,
9
+ captionsBannerFullHeightClassName ,
9
10
captionsContainerClassName ,
11
+ loadingBannerFullHeightStyles ,
10
12
loadingBannerStyles
11
13
} from './styles/Captions.style' ;
12
14
import { OnRenderAvatarCallback } from '../types' ;
@@ -50,16 +52,30 @@ export interface _CaptionsBannerProps {
50
52
* @defaultValue 'default'
51
53
*/
52
54
formFactor ?: 'default' | 'compact' ;
55
+ captionsOptions ?: {
56
+ height : 'full' | 'default' ;
57
+ } ;
53
58
}
54
59
60
+ const SCROLL_OFFSET_ALLOWANCE = 20 ;
61
+
55
62
/**
56
63
* @internal
57
64
* A component for displaying a CaptionsBanner with user icon, displayName and captions text.
58
65
*/
59
66
export const _CaptionsBanner = ( props : _CaptionsBannerProps ) : JSX . Element => {
60
- const { captions, isCaptionsOn, startCaptionsInProgress, onRenderAvatar, strings, formFactor = 'default' } = props ;
67
+ const {
68
+ captions,
69
+ isCaptionsOn,
70
+ startCaptionsInProgress,
71
+ onRenderAvatar,
72
+ strings,
73
+ formFactor = 'default' ,
74
+ captionsOptions
75
+ } = props ;
61
76
const captionsScrollDivRef = useRef < HTMLDivElement > ( null ) ;
62
77
const [ isAtBottomOfScroll , setIsAtBottomOfScroll ] = useState < boolean > ( true ) ;
78
+ const theme = useTheme ( ) ;
63
79
64
80
const scrollToBottom = ( ) : void => {
65
81
if ( captionsScrollDivRef . current ) {
@@ -73,7 +89,7 @@ export const _CaptionsBanner = (props: _CaptionsBannerProps): JSX.Element => {
73
89
}
74
90
const atBottom =
75
91
Math . ceil ( captionsScrollDivRef . current . scrollTop ) >=
76
- captionsScrollDivRef . current . scrollHeight - captionsScrollDivRef . current . clientHeight ;
92
+ captionsScrollDivRef . current . scrollHeight - captionsScrollDivRef . current . clientHeight - SCROLL_OFFSET_ALLOWANCE ;
77
93
78
94
setIsAtBottomOfScroll ( atBottom ) ;
79
95
} , [ ] ) ;
@@ -97,9 +113,17 @@ export const _CaptionsBanner = (props: _CaptionsBannerProps): JSX.Element => {
97
113
return (
98
114
< >
99
115
{ startCaptionsInProgress && (
100
- < FocusZone as = "ul" className = { captionsContainerClassName } >
116
+ < FocusZone as = "ul" className = { captionsContainerClassName } data-ui-id = "captions-banner" >
101
117
{ isCaptionsOn && (
102
- < div ref = { captionsScrollDivRef } className = { captionsBannerClassName ( formFactor ) } >
118
+ < div
119
+ ref = { captionsScrollDivRef }
120
+ className = {
121
+ captionsOptions ?. height === 'full'
122
+ ? captionsBannerFullHeightClassName ( theme )
123
+ : captionsBannerClassName ( formFactor )
124
+ }
125
+ data-ui-id = "captions-banner-inner"
126
+ >
103
127
{ captions . map ( ( caption ) => {
104
128
return (
105
129
< div key = { caption . id } className = { captionContainerClassName } data-is-focusable = { true } >
@@ -110,7 +134,15 @@ export const _CaptionsBanner = (props: _CaptionsBannerProps): JSX.Element => {
110
134
</ div >
111
135
) }
112
136
{ ! isCaptionsOn && (
113
- < Stack verticalAlign = "center" styles = { loadingBannerStyles ( formFactor ) } data-is-focusable = { true } >
137
+ < Stack
138
+ verticalAlign = "center"
139
+ styles = {
140
+ captionsOptions ?. height === 'full'
141
+ ? loadingBannerFullHeightStyles ( theme )
142
+ : loadingBannerStyles ( formFactor )
143
+ }
144
+ data-is-focusable = { true }
145
+ >
114
146
< Spinner label = { strings ?. captionsBannerSpinnerText } ariaLive = "assertive" labelPosition = "right" />
115
147
</ Stack >
116
148
) }
0 commit comments