11// Copyright (c) Microsoft Corporation.
22// Licensed under the MIT license.
33
4- import { Icon , IStyle , mergeStyles , Persona , Stack , Text } from '@fluentui/react' ;
4+ import { Icon , IStyle , mergeStyles , Persona , Stack , Text , IIconProps } from '@fluentui/react' ;
5+ /* @conditional -compile-remove(pinned-participants) */
6+ import { MoreHorizontal20Filled } from '@fluentui/react-icons' ;
57import { Ref } from '@fluentui/react-northstar' ;
68import React , { useLayoutEffect , useMemo , useRef , useState } from 'react' ;
79import { useIdentifiers } from '../identifiers' ;
@@ -23,8 +25,12 @@ import {
2325 participantStateStringStyles
2426} from './styles/VideoTile.styles' ;
2527/* @conditional -compile-remove(pinned-participants) */
26- import { pinIconStyle } from './styles/VideoTile.styles' ;
28+ import { pinIconStyle , menuButtonStyles } from './styles/VideoTile.styles' ;
2729import { getVideoTileOverrideColor } from './utils/videoTileStylesUtils' ;
30+ /* @conditional -compile-remove(pinned-participants) */
31+ import { DefaultButton , concatStyleSets , DirectionalHint } from '@fluentui/react' ;
32+ /* @conditional -compile-remove(pinned-participants) */
33+ import { mapMenuItemsToContextualMenuItems } from './utils' ;
2834
2935/**
3036 * Strings of {@link VideoTile} that can be overridden.
@@ -89,6 +95,11 @@ export interface VideoTileProps {
8995 */
9096 isMuted ?: boolean ;
9197 /* @conditional -compile-remove(pinned-participants) */
98+ /**
99+ * Display custom menu items in the VideoTile's contextual menu.
100+ */
101+ menuItems ?: VideoTileMenuItems ;
102+ /* @conditional -compile-remove(pinned-participants) */
92103 /**
93104 * If true, the video tile will show the pin icon.
94105 */
@@ -158,8 +169,39 @@ const DefaultPlaceholder = (props: CustomAvatarOptions): JSX.Element => {
158169 ) ;
159170} ;
160171
172+ /**
173+ * @beta
174+ * MenuItems to be diplayed in video tile in the contextual/drawer menu
175+ */
176+ export type VideoTileMenuItems = Array < {
177+ key : string ;
178+ ariaLabel ?: string ;
179+ text : string ;
180+ onClick : ( ) => void ;
181+ iconProps : IIconProps ;
182+ } > ;
183+
184+ /* @conditional -compile-remove(pinned-participants) */
185+ const menuIcon = ( ) : JSX . Element => < MoreHorizontal20Filled primaryFill = "currentColor" /> ;
186+
161187const defaultPersonaStyles = { root : { margin : 'auto' , maxHeight : '100%' } } ;
162188
189+ /* @conditional -compile-remove(pinned-participants) */
190+ const VideoTileMoreOptionsButton = ( props : { menuItems ?: VideoTileMenuItems ; menuStyles ?: IStyle } ) : JSX . Element => {
191+ const { menuItems, menuStyles } = props ;
192+ if ( ! menuItems || menuItems . length === 0 ) {
193+ return < > </ > ;
194+ }
195+ return (
196+ < DefaultButton
197+ styles = { concatStyleSets ( menuButtonStyles , menuStyles ?? { } ) }
198+ onRenderIcon = { menuIcon }
199+ menuIconProps = { { hidden : true } }
200+ menuProps = { { items : mapMenuItemsToContextualMenuItems ( menuItems ) , directionalHint : DirectionalHint . topRightEdge } }
201+ />
202+ ) ;
203+ } ;
204+
163205/**
164206 * A component to render the video stream for a single call participant.
165207 *
@@ -184,6 +226,8 @@ export const VideoTile = (props: VideoTileProps): JSX.Element => {
184226 userId,
185227 noVideoAvailableAriaLabel,
186228 isSpeaking,
229+ /* @conditional -compile-remove(pinned-participants) */
230+ menuItems,
187231 personaMinSize = DEFAULT_PERSONA_MIN_SIZE_PX ,
188232 personaMaxSize = DEFAULT_PERSONA_MAX_SIZE_PX
189233 } = props ;
@@ -237,7 +281,6 @@ export const VideoTile = (props: VideoTileProps): JSX.Element => {
237281
238282 const canShowLabel = showLabel && ( displayName || ( showMuteIndicator && isMuted ) ) ;
239283 const participantStateString = participantStateStringTrampoline ( props , locale ) ;
240-
241284 return (
242285 < Ref innerRef = { videoTileRef } >
243286 < Stack
@@ -304,6 +347,10 @@ export const VideoTile = (props: VideoTileProps): JSX.Element => {
304347 < Icon iconName = "VideoTileMicOff" />
305348 </ Stack >
306349 ) }
350+ {
351+ /* @conditional -compile-remove(pinned-participants) */
352+ < VideoTileMoreOptionsButton menuItems = { menuItems } menuStyles = { props . styles } />
353+ }
307354 {
308355 /* @conditional -compile-remove(pinned-participants) */
309356 isPinned && (
0 commit comments