[0.71] Add support for announceForAccessibilityWithOptions (#12256)
* [Win32] Add support for announceForAccessibilityWithOptions (#12237) * initial commit * add NativeAccessibilityInfoWin32.js * update example * Change files * add override and .d.ts file * add another override * add comma * extend options type instead of redefine * try [prop-missing] to fix lint error * fix comment in RNTesterList.win32 * try ignoring AccessibilityInfo.js in .flowconfig * Revert flowconfig version * Lint script runs succesfully locally --------- Co-authored-by: Krystal Kramer <krsiler@microsoft.com> * Fix pipeline failing * Fix overrides.json * Change beachball change type * Correctly suppress prop-missing error --------- Co-authored-by: Krystal Kramer <krsiler@microsoft.com>
This commit is contained in:
Родитель
534a296ec0
Коммит
7f2e4a1c25
|
@ -0,0 +1,7 @@
|
|||
{
|
||||
"type": "patch",
|
||||
"comment": "add support for announceForAccessibilityWithOptions",
|
||||
"packageName": "@office-iss/react-native-win32",
|
||||
"email": "krsiler@microsoft.com",
|
||||
"dependentChangeType": "patch"
|
||||
}
|
|
@ -474,10 +474,27 @@ const AccessibilityInfoExample: React.FunctionComponent<{}> =() => {
|
|||
const onClick = React.useCallback(() => {
|
||||
AccessibilityInfo.announceForAccessibility('AccessibilityInfo announcement succeeded!');
|
||||
}, []);
|
||||
|
||||
const onClickDelayed = React.useCallback(() => {
|
||||
setTimeout(() => {
|
||||
AccessibilityInfo.announceForAccessibilityWithOptions(
|
||||
'AccessibilityInfo announcement succeeded!',
|
||||
{ nativeID: 'AnnouncementTarget' });
|
||||
}, 3000);
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<View style={styles.box}>
|
||||
<TouchableHighlight onPress={onClick}>
|
||||
<Text>AccessibilityInfo.announceForAccessibility</Text>
|
||||
<View>
|
||||
<TouchableHighlight onPress={onClick} underlayColor={'transparent'}>
|
||||
<ViewWin32 style={styles.box} accessible focusable>
|
||||
<Text>AccessibilityInfo.announceForAccessibility</Text>
|
||||
</ViewWin32>
|
||||
</TouchableHighlight>
|
||||
|
||||
<TouchableHighlight onPress={onClickDelayed} underlayColor={'transparent'}>
|
||||
<ViewWin32 style={styles.box} accessible focusable nativeID={'AnnouncementTarget'}>
|
||||
<Text>AccessibilityInfo.announceForAccessibilityWithOptions</Text>
|
||||
</ViewWin32>
|
||||
</TouchableHighlight>
|
||||
</View>
|
||||
);
|
||||
|
|
|
@ -15,6 +15,15 @@ import type {RNTesterModuleInfo} from '../types/RNTesterTypes';
|
|||
import ReactNativeFeatureFlags from 'react-native/Libraries/ReactNative/ReactNativeFeatureFlags';
|
||||
|
||||
const Components: Array<RNTesterModuleInfo> = [
|
||||
/*{
|
||||
key: 'DrawerLayoutAndroid',
|
||||
category: 'UI',
|
||||
module: require('../examples/DrawerLayoutAndroid/DrawerLayoutAndroidExample'),
|
||||
},*/
|
||||
{
|
||||
key: 'AccessibilityExampleWin32',
|
||||
module: require('../examples-win32/Accessibility/AccessibilityExampleWin32'),
|
||||
},
|
||||
{
|
||||
key: 'ActivityIndicatorExample',
|
||||
category: 'UI',
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
; initRNLibraries build step
|
||||
<PROJECT_ROOT>/index.js
|
||||
<PROJECT_ROOT>/Libraries/Alert/Alert.js
|
||||
<PROJECT_ROOT>/Libraries/Components/AccessibilityInfo/AccessibilityInfo.js
|
||||
<PROJECT_ROOT>/Libraries/Components/Pressable/Pressable.js
|
||||
<PROJECT_ROOT>/Libraries/Components/SafeAreaView/SafeAreaView.js
|
||||
<PROJECT_ROOT>/Libraries/Components/TextInput/TextInput.js
|
||||
|
|
|
@ -32,11 +32,16 @@
|
|||
"baseHash": "897569d77df852480332b7ce7ec1b594cf40aa28"
|
||||
},
|
||||
{
|
||||
"type": "patch",
|
||||
"type": "derived",
|
||||
"file": "src/Libraries/Components/AccessibilityInfo/AccessibilityInfo.d.ts",
|
||||
"baseFile": "Libraries/Components/AccessibilityInfo/AccessibilityInfo.d.ts",
|
||||
"baseHash": "7b4cf9114df53038aeb1508f77d868b45e09049b"
|
||||
},
|
||||
{
|
||||
"type": "derived",
|
||||
"file": "src/Libraries/Components/AccessibilityInfo/AccessibilityInfo.win32.js",
|
||||
"baseFile": "Libraries/Components/AccessibilityInfo/AccessibilityInfo.js",
|
||||
"baseHash": "8ed7c87f3165558abe517218143dc6f73d91cc46",
|
||||
"issue": 4578
|
||||
"baseHash": "8ed7c87f3165558abe517218143dc6f73d91cc46"
|
||||
},
|
||||
{
|
||||
"type": "copy",
|
||||
|
@ -45,6 +50,12 @@
|
|||
"baseHash": "d37b2f72125246ababf3260e99ef790ce76fe3bb",
|
||||
"issue": 4578
|
||||
},
|
||||
{
|
||||
"type": "derived",
|
||||
"file": "src/Libraries/Components/AccessibilityInfo/NativeAccessibilityInfoWin32.js",
|
||||
"baseFile": "Libraries/Components/AccessibilityInfo/NativeAccessibilityInfo.js",
|
||||
"baseHash": "9427a7feebfbe3de606b2d100439cabf2faa8661"
|
||||
},
|
||||
{
|
||||
"type": "platform",
|
||||
"file": "src/Libraries/Components/Button/ButtonWin32.Props.ts"
|
||||
|
|
161
packages/@office-iss/react-native-win32/src/Libraries/Components/AccessibilityInfo/AccessibilityInfo.d.ts
поставляемый
Normal file
161
packages/@office-iss/react-native-win32/src/Libraries/Components/AccessibilityInfo/AccessibilityInfo.d.ts
поставляемый
Normal file
|
@ -0,0 +1,161 @@
|
|||
/**
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @format
|
||||
*/
|
||||
|
||||
import type * as React from 'react';
|
||||
import {HostComponent} from '../../../types/public/ReactNativeTypes';
|
||||
import {EmitterSubscription} from '../../vendor/emitter/EventEmitter';
|
||||
|
||||
type AccessibilityChangeEventName =
|
||||
| 'change' // deprecated, maps to screenReaderChanged
|
||||
| 'boldTextChanged' // iOS-only Event
|
||||
| 'grayscaleChanged' // iOS-only Event
|
||||
| 'invertColorsChanged' // iOS-only Event
|
||||
| 'reduceMotionChanged'
|
||||
| 'screenReaderChanged'
|
||||
| 'reduceTransparencyChanged'; // iOS-only Event
|
||||
|
||||
type AccessibilityChangeEvent = boolean;
|
||||
|
||||
type AccessibilityChangeEventHandler = (
|
||||
event: AccessibilityChangeEvent,
|
||||
) => void;
|
||||
|
||||
type AccessibilityAnnouncementEventName = 'announcementFinished'; // iOS-only Event
|
||||
|
||||
type AccessibilityAnnouncementFinishedEvent = {
|
||||
announcement: string;
|
||||
success: boolean;
|
||||
};
|
||||
|
||||
type AccessibilityAnnouncementFinishedEventHandler = (
|
||||
event: AccessibilityAnnouncementFinishedEvent,
|
||||
) => void;
|
||||
|
||||
type AccessibilityEventTypes = 'click' | 'focus' | 'viewHoverEnter';
|
||||
|
||||
/**
|
||||
* @see https://reactnative.dev/docs/accessibilityinfo
|
||||
*/
|
||||
export interface AccessibilityInfoStatic {
|
||||
/**
|
||||
* Query whether bold text is currently enabled.
|
||||
*
|
||||
* @platform ios
|
||||
*/
|
||||
isBoldTextEnabled: () => Promise<boolean>;
|
||||
|
||||
/**
|
||||
* Query whether grayscale is currently enabled.
|
||||
*
|
||||
* @platform ios
|
||||
*/
|
||||
isGrayscaleEnabled: () => Promise<boolean>;
|
||||
|
||||
/**
|
||||
* Query whether invert colors is currently enabled.
|
||||
*
|
||||
* @platform ios
|
||||
*/
|
||||
isInvertColorsEnabled: () => Promise<boolean>;
|
||||
|
||||
/**
|
||||
* Query whether reduce motion is currently enabled.
|
||||
*/
|
||||
isReduceMotionEnabled: () => Promise<boolean>;
|
||||
|
||||
/**
|
||||
* Query whether reduce motion and prefer cross-fade transitions settings are currently enabled.
|
||||
*
|
||||
* Returns a promise which resolves to a boolean.
|
||||
* The result is `true` when prefer cross-fade transitions is enabled and `false` otherwise.
|
||||
*/
|
||||
prefersCrossFadeTransitions(): Promise<boolean>;
|
||||
|
||||
/**
|
||||
* Query whether reduce transparency is currently enabled.
|
||||
*
|
||||
* @platform ios
|
||||
*/
|
||||
isReduceTransparencyEnabled: () => Promise<boolean>;
|
||||
|
||||
/**
|
||||
* Query whether a screen reader is currently enabled.
|
||||
*/
|
||||
isScreenReaderEnabled: () => Promise<boolean>;
|
||||
|
||||
/**
|
||||
* Query whether Accessibility Service is currently enabled.
|
||||
*
|
||||
* Returns a promise which resolves to a boolean.
|
||||
* The result is `true` when any service is enabled and `false` otherwise.
|
||||
*
|
||||
* @platform android
|
||||
*/
|
||||
isAccessibilityServiceEnabled(): Promise<boolean>;
|
||||
|
||||
/**
|
||||
* Add an event handler. Supported events:
|
||||
* - announcementFinished: iOS-only event. Fires when the screen reader has finished making an announcement.
|
||||
* The argument to the event handler is a dictionary with these keys:
|
||||
* - announcement: The string announced by the screen reader.
|
||||
* - success: A boolean indicating whether the announcement was successfully made.
|
||||
* - AccessibilityEventName constants other than announcementFinished: Fires on accessibility feature change.
|
||||
* The argument to the event handler is a boolean.
|
||||
* The boolean is true when the related event's feature is enabled and false otherwise.
|
||||
*
|
||||
*/
|
||||
addEventListener(
|
||||
eventName: AccessibilityChangeEventName,
|
||||
handler: AccessibilityChangeEventHandler,
|
||||
): EmitterSubscription;
|
||||
addEventListener(
|
||||
eventName: AccessibilityAnnouncementEventName,
|
||||
handler: AccessibilityAnnouncementFinishedEventHandler,
|
||||
): EmitterSubscription;
|
||||
|
||||
/**
|
||||
* Set accessibility focus to a react component.
|
||||
*/
|
||||
setAccessibilityFocus: (reactTag: number) => void;
|
||||
|
||||
/**
|
||||
* Post a string to be announced by the screen reader.
|
||||
*/
|
||||
announceForAccessibility: (announcement: string) => void;
|
||||
|
||||
/**
|
||||
* Post a string to be announced by the screen reader.
|
||||
* - `announcement`: The string announced by the screen reader.
|
||||
* - `options`: An object that configures the reading options.
|
||||
* - `queue`: The announcement will be queued behind existing announcements. iOS only.
|
||||
* - `nativeID`: The nativeID of the element to send the announcement from. win32 only.
|
||||
*/
|
||||
announceForAccessibilityWithOptions(
|
||||
announcement: string,
|
||||
options: {
|
||||
queue?: boolean | undefined;
|
||||
nativeID?: string | undefined; // win32
|
||||
},
|
||||
): void;
|
||||
|
||||
/**
|
||||
* Gets the timeout in millisecond that the user needs.
|
||||
* This value is set in "Time to take action (Accessibility timeout)" of "Accessibility" settings.
|
||||
*
|
||||
* @platform android
|
||||
*/
|
||||
getRecommendedTimeoutMillis: (originalTimeout: number) => Promise<number>;
|
||||
sendAccessibilityEvent: (
|
||||
handle: React.ElementRef<HostComponent<unknown>>,
|
||||
eventType: AccessibilityEventTypes,
|
||||
) => void;
|
||||
}
|
||||
|
||||
export const AccessibilityInfo: AccessibilityInfoStatic;
|
||||
export type AccessibilityInfo = AccessibilityInfoStatic;
|
|
@ -18,6 +18,7 @@ import {sendAccessibilityEvent} from '../../ReactNative/RendererProxy';
|
|||
import Platform from '../../Utilities/Platform';
|
||||
import legacySendAccessibilityEvent from './legacySendAccessibilityEvent';
|
||||
import NativeAccessibilityInfo from './NativeAccessibilityInfo';
|
||||
import NativeAccessibilityInfoWin32 from './NativeAccessibilityInfoWin32';
|
||||
import NativeAccessibilityManagerIOS from './NativeAccessibilityManager';
|
||||
|
||||
// Events that are only supported on Android.
|
||||
|
@ -167,12 +168,18 @@ const AccessibilityInfo: AccessibilityInfoType = {
|
|||
*/
|
||||
isReduceMotionEnabled(): Promise<boolean> {
|
||||
return new Promise((resolve, reject) => {
|
||||
if (Platform.OS === 'android' || Platform.OS === 'win32') {
|
||||
if (Platform.OS === 'android') {
|
||||
if (NativeAccessibilityInfo != null) {
|
||||
NativeAccessibilityInfo.isReduceMotionEnabled(resolve);
|
||||
} else {
|
||||
reject(null);
|
||||
}
|
||||
} else if (Platform.OS === 'win32') {
|
||||
if (NativeAccessibilityInfoWin32 != null) {
|
||||
NativeAccessibilityInfoWin32.isReduceMotionEnabled(resolve);
|
||||
} else {
|
||||
reject(null);
|
||||
}
|
||||
} else {
|
||||
if (NativeAccessibilityManagerIOS != null) {
|
||||
NativeAccessibilityManagerIOS.getCurrentReduceMotionState(
|
||||
|
@ -249,12 +256,18 @@ const AccessibilityInfo: AccessibilityInfoType = {
|
|||
*/
|
||||
isScreenReaderEnabled(): Promise<boolean> {
|
||||
return new Promise((resolve, reject) => {
|
||||
if (Platform.OS === 'android' || Platform.OS === 'win32') {
|
||||
if (Platform.OS === 'android') {
|
||||
if (NativeAccessibilityInfo != null) {
|
||||
NativeAccessibilityInfo.isTouchExplorationEnabled(resolve);
|
||||
} else {
|
||||
reject(null);
|
||||
}
|
||||
} else if (Platform.OS === 'win32') {
|
||||
if (NativeAccessibilityInfoWin32 != null) {
|
||||
NativeAccessibilityInfoWin32.isTouchExplorationEnabled(resolve);
|
||||
} else {
|
||||
reject(null);
|
||||
}
|
||||
} else {
|
||||
if (NativeAccessibilityManagerIOS != null) {
|
||||
NativeAccessibilityManagerIOS.getCurrentVoiceOverState(
|
||||
|
@ -371,8 +384,10 @@ const AccessibilityInfo: AccessibilityInfoType = {
|
|||
* See https://reactnative.dev/docs/accessibilityinfo#announceforaccessibility
|
||||
*/
|
||||
announceForAccessibility(announcement: string): void {
|
||||
if (Platform.OS === 'android' || Platform.OS === 'win32') {
|
||||
if (Platform.OS === 'android') {
|
||||
NativeAccessibilityInfo?.announceForAccessibility(announcement);
|
||||
} else if (Platform.OS === 'win32') {
|
||||
NativeAccessibilityInfoWin32?.announceForAccessibility(announcement);
|
||||
} else {
|
||||
NativeAccessibilityManagerIOS?.announceForAccessibility(announcement);
|
||||
}
|
||||
|
@ -383,19 +398,35 @@ const AccessibilityInfo: AccessibilityInfoType = {
|
|||
* - `announcement`: The string announced by the screen reader.
|
||||
* - `options`: An object that configures the reading options.
|
||||
* - `queue`: The announcement will be queued behind existing announcements. iOS only.
|
||||
* - `nativeID`: The nativeID of the element to send the announcement from. win32 only.
|
||||
*/
|
||||
// $FlowIgnore[prop-missing]
|
||||
announceForAccessibilityWithOptions(
|
||||
announcement: string,
|
||||
options: {queue?: boolean},
|
||||
options: {
|
||||
queue?: boolean,
|
||||
nativeID?: string, // win32
|
||||
},
|
||||
): void {
|
||||
if (Platform.OS === 'android' || Platform.OS === 'win32') {
|
||||
if (Platform.OS === 'android') {
|
||||
NativeAccessibilityInfo?.announceForAccessibility(announcement);
|
||||
} else {
|
||||
if (NativeAccessibilityManagerIOS?.announceForAccessibilityWithOptions) {
|
||||
NativeAccessibilityManagerIOS?.announceForAccessibilityWithOptions(
|
||||
} else if (Platform.OS === 'win32') {
|
||||
if (NativeAccessibilityInfoWin32?.announceForAccessibilityWithOptions) {
|
||||
NativeAccessibilityInfoWin32?.announceForAccessibilityWithOptions(
|
||||
announcement,
|
||||
options,
|
||||
);
|
||||
} else {
|
||||
NativeAccessibilityInfoWin32?.announceForAccessibility(announcement);
|
||||
}
|
||||
} else {
|
||||
if (NativeAccessibilityManagerIOS?.announceForAccessibilityWithOptions) {
|
||||
const {nativeID: _, ...iosOptions} = options;
|
||||
// $FlowFixMe[prop-missing]
|
||||
NativeAccessibilityManagerIOS?.announceForAccessibilityWithOptions(
|
||||
announcement,
|
||||
iosOptions,
|
||||
);
|
||||
} else {
|
||||
NativeAccessibilityManagerIOS?.announceForAccessibility(announcement);
|
||||
}
|
||||
|
@ -408,7 +439,7 @@ const AccessibilityInfo: AccessibilityInfoType = {
|
|||
* See https://reactnative.dev/docs/accessibilityinfo#getrecommendedtimeoutmillis
|
||||
*/
|
||||
getRecommendedTimeoutMillis(originalTimeout: number): Promise<number> {
|
||||
if (Platform.OS === 'android' || Platform.OS === 'win32') {
|
||||
if (Platform.OS === 'android') {
|
||||
return new Promise((resolve, reject) => {
|
||||
if (NativeAccessibilityInfo?.getRecommendedTimeoutMillis) {
|
||||
NativeAccessibilityInfo.getRecommendedTimeoutMillis(
|
||||
|
@ -419,6 +450,17 @@ const AccessibilityInfo: AccessibilityInfoType = {
|
|||
resolve(originalTimeout);
|
||||
}
|
||||
});
|
||||
} else if (Platform.OS === 'win32') {
|
||||
return new Promise((resolve, reject) => {
|
||||
if (NativeAccessibilityInfoWin32?.getRecommendedTimeoutMillis) {
|
||||
NativeAccessibilityInfoWin32.getRecommendedTimeoutMillis(
|
||||
originalTimeout,
|
||||
resolve,
|
||||
);
|
||||
} else {
|
||||
resolve(originalTimeout);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
return Promise.resolve(originalTimeout);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,37 @@
|
|||
/**
|
||||
* Copyright (c) Microsoft Corporation.
|
||||
* Licensed under the MIT License.
|
||||
*
|
||||
* @format
|
||||
* @flow
|
||||
*/
|
||||
|
||||
import type {TurboModule} from '../../TurboModule/RCTExport';
|
||||
|
||||
import * as TurboModuleRegistry from '../../TurboModule/TurboModuleRegistry';
|
||||
|
||||
export interface Spec extends TurboModule {
|
||||
+isReduceMotionEnabled: (
|
||||
onSuccess: (isReduceMotionEnabled: boolean) => void,
|
||||
) => void;
|
||||
+isTouchExplorationEnabled: (
|
||||
onSuccess: (isScreenReaderEnabled: boolean) => void,
|
||||
) => void;
|
||||
+isAccessibilityServiceEnabled?: ?(
|
||||
onSuccess: (isAccessibilityServiceEnabled: boolean) => void,
|
||||
) => void;
|
||||
+setAccessibilityFocus: (reactTag: number) => void;
|
||||
+announceForAccessibility: (announcement: string) => void;
|
||||
// [Win32
|
||||
+announceForAccessibilityWithOptions?: (
|
||||
announcement: string,
|
||||
options: {queue?: boolean, nativeID?: string},
|
||||
) => void;
|
||||
// Win32]
|
||||
+getRecommendedTimeoutMillis?: (
|
||||
mSec: number,
|
||||
onSuccess: (recommendedTimeoutMillis: number) => void,
|
||||
) => void;
|
||||
}
|
||||
|
||||
export default (TurboModuleRegistry.get<Spec>('AccessibilityInfo'): ?Spec);
|
Загрузка…
Ссылка в новой задаче