Skip to content

Commit 8d31d48

Browse files
add hook usage to new buttons
1 parent c88dec4 commit 8d31d48

File tree

11 files changed

+82
-36
lines changed

11 files changed

+82
-36
lines changed

packages/react-components/src/Accessibility/AccessibilityProvider.tsx

+12-4
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
// Licensed under the MIT License.
33
import { IButton } from '@fluentui/react';
44
import React, { createContext, useContext, useState, useCallback, ReactNode } from 'react';
5+
import { useEffect } from 'react';
56

67
/**
78
* Type for reference to the last component used
@@ -48,10 +49,17 @@ export const AccessibilityProvider = (props: AccessibilityProviderProps): JSX.El
4849
console.log('AccessibilityProvider');
4950
const [componentRef, setComponentRef] = useState<AccessibilityComponentRef>(null);
5051

51-
const handleSetComponentRef = useCallback((ref: AccessibilityComponentRef) => {
52-
console.log(ref);
53-
setComponentRef(ref);
54-
}, []);
52+
const handleSetComponentRef = useCallback(
53+
(ref: AccessibilityComponentRef) => {
54+
console.log(ref);
55+
setComponentRef(ref);
56+
},
57+
[setComponentRef]
58+
);
59+
60+
useEffect(() => {
61+
console.log('componentRef', componentRef);
62+
}, [componentRef]);
5563

5664
return (
5765
<AccessibilityContext.Provider value={{ setComponentRef: handleSetComponentRef, componentRef }}>

packages/react-components/src/components/CameraButton.tsx

+7-1
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,15 @@
11
// Copyright (c) Microsoft Corporation.
22
// Licensed under the MIT License.
33

4-
import React, { useCallback, useState, useMemo } from 'react';
4+
import React, { useCallback, useState, useMemo, useRef } from 'react';
55
import { useLocale } from '../localization';
66
import { VideoStreamOptions } from '../types';
77
import { ControlBarButton, ControlBarButtonProps } from './ControlBarButton';
88
import { _HighContrastAwareIcon } from './HighContrastAwareIcon';
99

1010
import {
1111
ContextualMenuItemType,
12+
IButton,
1213
IButtonProps,
1314
IContextualMenuItem,
1415
IContextualMenuItemStyles,
@@ -17,6 +18,7 @@ import {
1718
import { ControlBarButtonStyles } from './ControlBarButton';
1819
import { OptionsDevice, generateDefaultDeviceMenuProps } from './DevicesButton';
1920
import { Announcer } from './Announcer';
21+
import { useAccessibility } from '../Accessibility';
2022

2123
const defaultLocalVideoViewOptions = {
2224
scalingMode: 'Crop',
@@ -177,6 +179,8 @@ export const CameraButton = (props: CameraButtonProps): JSX.Element => {
177179
const strings = { ...localeStrings, ...props.strings };
178180
const [announcerString, setAnnouncerString] = useState<string | undefined>(undefined);
179181
const [announcerPresent, setAnnouncerPresent] = useState<boolean>(false);
182+
const accessibility = useAccessibility();
183+
const cameraButtonRef = useRef<IButton | null>(null);
180184

181185
const disabled = props.disabled || waitForCamera;
182186

@@ -322,6 +326,8 @@ export const CameraButton = (props: CameraButtonProps): JSX.Element => {
322326
aria-description={strings.cameraButtonAriaDescription}
323327
aria-roledescription={props.enableDeviceSelectionMenu ? strings.cameraButtonSplitRoleDescription : undefined}
324328
ariaLabel={ariaLabel}
329+
onMenuClick={() => accessibility.setComponentRef(cameraButtonRef.current)}
330+
componentRef={cameraButtonRef}
325331
splitButtonAriaLabel={props.enableDeviceSelectionMenu ? splitButtonAriaString : undefined}
326332
splitButtonMenuProps={splitButtonMenuProps}
327333
onFocus={() => setAnnouncerPresent(true)}

packages/react-components/src/components/ControlBarButton.tsx

+2-1
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,6 @@ export const ControlBarButton = (props: ControlBarButtonProps): JSX.Element => {
141141
: props?.strings?.tooltipOffContent);
142142

143143
const tooltipId = props.tooltipId ?? props.labelKey ? props.labelKey + '-tooltip' : undefined;
144-
145144
return (
146145
<ControlButtonTooltip hidden={props.disableTooltip} content={tooltipContent} id={tooltipId}>
147146
<DefaultButton
@@ -154,6 +153,8 @@ export const ControlBarButton = (props: ControlBarButtonProps): JSX.Element => {
154153
aria-describedby={tooltipId}
155154
menuTriggerKeyCode={KeyCodes.down} // explicitly sets the keypress to activiate the split button drop down.
156155
text={undefined} // this is handled as a child of the button, without this the `showLabel` prop may be ignored.
156+
onFocus={props.onFocus}
157+
onBlur={props.onBlur}
157158
>
158159
{props.showLabel ? labelText : <></>}
159160
</DefaultButton>

packages/react-components/src/components/MicrophoneButton.tsx

+10-8
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import { ControlBarButtonStyles } from './ControlBarButton';
2222
import { OptionsDevice, generateDefaultDeviceMenuProps } from './DevicesButton';
2323
import { Announcer } from './Announcer';
2424
import { useAccessibility } from '../Accessibility';
25+
import { useRef } from 'react';
2526

2627
/**
2728
* Strings of {@link MicrophoneButton} that can be overridden.
@@ -225,8 +226,8 @@ export const MicrophoneButton = (props: MicrophoneButtonProps): JSX.Element => {
225226
};
226227
// activate the context
227228
const accessibility = useAccessibility();
228-
// create a ref for the local component
229-
const micButtonRef = React.useRef<IButton | null>(null);
229+
// create a ref for the local component - this only works when it is not a split button.
230+
const micButtonRef = useRef<IButton | null>(null);
230231

231232
const isMicOn = props.checked;
232233

@@ -319,7 +320,7 @@ export const MicrophoneButton = (props: MicrophoneButtonProps): JSX.Element => {
319320
};
320321

321322
return (
322-
<>
323+
<div>
323324
{announcerPresent && <Announcer announcementString={announcerString} ariaLive={'polite'} />}
324325
<ControlBarButton
325326
{...props}
@@ -347,14 +348,15 @@ export const MicrophoneButton = (props: MicrophoneButtonProps): JSX.Element => {
347348
splitButtonAriaLabel={props.enableDeviceSelectionMenu ? splitButtonAriaString : undefined}
348349
disabled={disabled}
349350
primaryDisabled={primaryDisabled}
350-
onFocus={() => setAnnouncerPresent(true)}
351-
onBlur={(event) => {
352-
console.log('onBlur event', event);
353-
props.onBlur?.(event);
351+
onFocus={() => {
352+
setAnnouncerPresent(true);
353+
}}
354+
onBlur={() => {
354355
accessibility.setComponentRef(micButtonRef.current);
355356
setAnnouncerPresent(false);
356357
}}
358+
componentRef={micButtonRef}
357359
/>
358-
</>
360+
</div>
359361
);
360362
};

packages/react-components/src/components/ParticipantsButton.tsx

+11-2
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,12 @@ import {
77
IContextualMenuProps,
88
IContextualMenuStyles,
99
IContextualMenuItemStyles,
10-
merge
10+
merge,
11+
IButton
1112
} from '@fluentui/react';
1213
import { _formatString } from '@internal/acs-ui-common';
1314
import copy from 'copy-to-clipboard';
14-
import React, { useCallback, useMemo, useState } from 'react';
15+
import React, { useCallback, useMemo, useState, useRef } from 'react';
1516
import {
1617
ParticipantList,
1718
ParticipantListProps,
@@ -28,6 +29,7 @@ import { ParticipantListParticipant } from '../types';
2829
import { _HighContrastAwareIcon } from './HighContrastAwareIcon';
2930
import { _preventDismissOnEvent as preventDismissOnEvent } from '@internal/acs-ui-common';
3031
import { Announcer } from './Announcer';
32+
import { useAccessibility } from '../Accessibility';
3133

3234
/**
3335
* Styles for the {@link ParticipantsButton} menu.
@@ -183,6 +185,9 @@ export const ParticipantsButton = (props: ParticipantsButtonProps): JSX.Element
183185
showParticipantOverflowTooltip
184186
} = props;
185187

188+
const accessibility = useAccessibility();
189+
const participantsButtonRef = useRef<IButton | null>(null);
190+
186191
const disabled = props.disabled;
187192

188193
const [copyInviteLinkAnnouncerStrings, setCopyInviteLinkAnnouncerStrings] = useState<string>('');
@@ -372,6 +377,10 @@ export const ParticipantsButton = (props: ParticipantsButtonProps): JSX.Element
372377
strings={strings}
373378
aria-label={strings.ariaLabel}
374379
labelKey={props.labelKey ?? 'participantsButtonLabel'}
380+
componentRef={participantsButtonRef}
381+
onBlur={() => {
382+
accessibility.setComponentRef(participantsButtonRef.current);
383+
}}
375384
/>
376385
</>
377386
);

packages/react-composites/src/composites/CallComposite/components/CallArrangement.tsx

+1-5
Original file line numberDiff line numberDiff line change
@@ -156,7 +156,6 @@ export const CallArrangement = (props: CallArrangementProps): JSX.Element => {
156156
);
157157

158158
const peopleButtonRef = useRef<IButton>(null);
159-
const cameraButtonRef = useRef<IButton>(null);
160159
const sidePaneDismissButtonRef = useRef<IButton>(null);
161160

162161
const containerRef = useRef<HTMLDivElement>(null);
@@ -430,8 +429,7 @@ export const CallArrangement = (props: CallArrangementProps): JSX.Element => {
430429
props.updateSidePaneRenderer,
431430
props.mobileView,
432431
props.latestErrors as ActiveErrorMessage[],
433-
props.onDismissError,
434-
cameraButtonRef
432+
props.onDismissError
435433
);
436434
const [showDrawer, setShowDrawer] = useState(false);
437435
const onMoreButtonClicked = useCallback(() => {
@@ -676,8 +674,6 @@ export const CallArrangement = (props: CallArrangementProps): JSX.Element => {
676674
userSetGalleryLayout={props.userSetGalleryLayout}
677675
onSetDialpadPage={props.onSetDialpadPage}
678676
dtmfDialerPresent={props.dtmfDialerPresent}
679-
peopleButtonRef={peopleButtonRef}
680-
cameraButtonRef={cameraButtonRef}
681677
onStopLocalSpotlight={
682678
!hideSpotlightButtons && localParticipant.spotlight ? onStopLocalSpotlightWithPrompt : undefined
683679
}

packages/react-composites/src/composites/CallComposite/components/LocalDeviceSettings.tsx

+12-4
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,11 @@
22
// Licensed under the MIT License.
33

44
import { AudioDeviceInfo, VideoDeviceInfo } from '@azure/communication-calling';
5-
import { Dropdown, IDropdownOption, Label, mergeStyles, Stack } from '@fluentui/react';
5+
import { Dropdown, IButton, IDropdownOption, Label, mergeStyles, Stack } from '@fluentui/react';
66

77
import { DefaultButton } from '@fluentui/react';
8-
import { useEffect } from 'react';
9-
import { useTheme, VideoStreamOptions, _DevicePermissionDropdown } from '@internal/react-components';
8+
import { useEffect, useRef } from 'react';
9+
import { useTheme, VideoStreamOptions, _DevicePermissionDropdown, useAccessibility } from '@internal/react-components';
1010
import React from 'react';
1111
import { CallCompositeIcon } from '../../common/icons';
1212
import { useLocale } from '../../localization';
@@ -105,6 +105,8 @@ export const LocalDeviceSettings = (props: LocalDeviceSettingsType): JSX.Element
105105
const theme = useTheme();
106106
const locale = useLocale();
107107
const adapter = useAdapter();
108+
const accessibility = useAccessibility();
109+
const videoEffectsButtonRef = useRef<IButton | null>(null);
108110

109111
const onResolveVideoEffectDependency = useSelector(getVideoEffectsDependency);
110112
const defaultPlaceHolder = locale.strings.call.defaultPlaceHolder;
@@ -255,8 +257,14 @@ export const LocalDeviceSettings = (props: LocalDeviceSettingsType): JSX.Element
255257
<DefaultButton
256258
iconProps={{ iconName: 'ConfigurationScreenVideoEffectsButton' }}
257259
styles={effectsButtonStyles(theme, !cameraPermissionGranted)}
258-
onClick={props.onClickVideoEffects}
260+
onClick={() => {
261+
if (props.onClickVideoEffects) {
262+
accessibility.setComponentRef(videoEffectsButtonRef.current);
263+
props.onClickVideoEffects();
264+
}
265+
}}
259266
disabled={!cameraPermissionGranted}
267+
componentRef={videoEffectsButtonRef}
260268
data-ui-id={'call-config-video-effects-button'}
261269
>
262270
{locale.strings.call.configurationPageVideoEffectsButtonLabel}

packages/react-composites/src/composites/CallWithChatComposite/ChatButton/ChatButtonWithUnreadMessagesBadge.tsx

+10-3
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
// Copyright (c) Microsoft Corporation.
22
// Licensed under the MIT License.
33

4-
import { IStackStyles, Stack } from '@fluentui/react';
4+
import { IButton, IStackStyles, Stack } from '@fluentui/react';
55
import { _formatString } from '@internal/acs-ui-common';
6-
import { ControlBarButtonProps } from '@internal/react-components';
7-
import React, { useCallback, useMemo } from 'react';
6+
import { ControlBarButtonProps, useAccessibility } from '@internal/react-components';
7+
import React, { useCallback, useMemo, useRef } from 'react';
88
import { CallWithChatCompositeIcon } from '../../common/icons';
99
import { ChatButton } from './ChatButton';
1010
import { useCallWithChatCompositeStrings } from '../hooks/useCallWithChatCompositeStrings';
@@ -30,6 +30,8 @@ export const ChatButtonWithUnreadMessagesBadge = (props: ChatButtonWithUnreadMes
3030

3131
const baseIcon = props.showLabel ? regularIcon : filledIcon;
3232
const callWithChatStrings = useCallWithChatCompositeStrings();
33+
const accessibility = useAccessibility();
34+
const chatButtonRef = useRef<IButton | null>(null);
3335

3436
const numberOfMsgToolTip =
3537
props.strings?.tooltipOffContent && unreadChatMessagesCount > 0
@@ -65,6 +67,11 @@ export const ChatButtonWithUnreadMessagesBadge = (props: ChatButtonWithUnreadMes
6567
onRenderOffIcon={notificationOnIcon}
6668
onRenderOnIcon={onRenderOnIcon}
6769
strings={chatStrings}
70+
onClick={(event) => {
71+
accessibility.setComponentRef(chatButtonRef.current);
72+
props.onClick?.(event);
73+
}}
74+
componentRef={chatButtonRef}
6875
/>
6976
);
7077
};

packages/react-composites/src/composites/common/ControlBar/CommonCallControlBar.tsx

-4
Original file line numberDiff line numberDiff line change
@@ -79,8 +79,6 @@ export interface CommonCallControlBarProps {
7979
onUserSetOverflowGalleryPositionChange?: (position: 'Responsive' | 'horizontalTop') => void;
8080
onUserSetGalleryLayout?: (layout: VideoGalleryLayout) => void;
8181
userSetGalleryLayout?: VideoGalleryLayout;
82-
peopleButtonRef?: RefObject<IButton>;
83-
cameraButtonRef?: RefObject<IButton>;
8482
videoBackgroundPickerRef?: RefObject<IButton>;
8583
onSetDialpadPage?: () => void;
8684
dtmfDialerPresent?: boolean;
@@ -449,7 +447,6 @@ export const CommonCallControlBar = (props: CommonCallControlBarMergedProps): JS
449447
splitButtonsForDeviceSelection={!props.mobileView}
450448
disabled={props.disableButtonsForHoldScreen || isDisabled(options.cameraButton)}
451449
onClickVideoEffects={props.onClickVideoEffects}
452-
componentRef={props.cameraButtonRef}
453450
disableTooltip={props.mobileView}
454451
/>
455452
)}
@@ -596,7 +593,6 @@ export const CommonCallControlBar = (props: CommonCallControlBarMergedProps): JS
596593
}
597594
strings={peopleButtonStrings}
598595
styles={commonButtonStyles}
599-
componentRef={props.peopleButtonRef}
600596
chatButtonPresent={isEnabled(options.chatButton)}
601597
peoplePaneDismissButtonRef={props.sidePaneDismissButtonRef}
602598
/>

packages/react-composites/src/composites/common/ControlBar/PeopleButton.tsx

+15-3
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,14 @@
11
// Copyright (c) Microsoft Corporation.
22
// Licensed under the MIT License.
33

4-
import React, { useCallback, useMemo, RefObject } from 'react';
5-
import { ControlBarButton, ControlBarButtonProps, ControlBarButtonStyles, useTheme } from '@internal/react-components';
4+
import React, { useCallback, useMemo, RefObject, useRef } from 'react';
5+
import {
6+
ControlBarButton,
7+
ControlBarButtonProps,
8+
ControlBarButtonStyles,
9+
useAccessibility,
10+
useTheme
11+
} from '@internal/react-components';
612
import { concatStyleSets, IButton } from '@fluentui/react';
713
import { CallCompositeIcon } from '../icons';
814

@@ -23,6 +29,8 @@ export interface PeopleButtonProps extends ControlBarButtonProps {
2329
export const PeopleButton = (props: PeopleButtonProps): JSX.Element => {
2430
const { strings, onRenderOnIcon, onRenderOffIcon, onClick, peoplePaneDismissButtonRef, chatButtonPresent } = props;
2531
const theme = useTheme();
32+
const accessibility = useAccessibility();
33+
const peopleButtonRef = useRef<IButton | null>(null);
2634
const styles: ControlBarButtonStyles = useMemo(
2735
() =>
2836
concatStyleSets(
@@ -64,9 +72,13 @@ export const PeopleButton = (props: PeopleButtonProps): JSX.Element => {
6472
labelKey={'peopleButtonLabelKey'}
6573
onRenderOnIcon={onRenderOnIcon ?? icon}
6674
onRenderOffIcon={onRenderOffIcon ?? icon}
67-
onClick={handleClick}
75+
onClick={(event: React.MouseEvent<HTMLElement>) => {
76+
accessibility.setComponentRef(peopleButtonRef.current);
77+
handleClick(event);
78+
}}
6879
onKeyDown={handleTab}
6980
styles={styles}
81+
componentRef={peopleButtonRef}
7082
/>
7183
);
7284
};

packages/react-composites/src/composites/common/SidePaneHeader.tsx

+2-1
Original file line numberDiff line numberDiff line change
@@ -72,8 +72,9 @@ export const SidePaneHeader = (props: {
7272
styles={sidePaneCloseButtonStyles}
7373
iconProps={{ iconName: 'cancel' }}
7474
onClick={() => {
75-
props.onClose();
7675
accessibility.componentRef?.focus();
76+
console.log('close', accessibility.componentRef);
77+
props.onClose();
7778
}}
7879
onKeyDown={handleShiftTab}
7980
componentRef={props.dismissButtonComponentRef}

0 commit comments

Comments
 (0)