diff --git a/packages/react-native/Libraries/Components/View/ViewAccessibility.js b/packages/react-native/Libraries/Components/View/ViewAccessibility.js index 813fe8f443d2..92a09052ead4 100644 --- a/packages/react-native/Libraries/Components/View/ViewAccessibility.js +++ b/packages/react-native/Libraries/Components/View/ViewAccessibility.js @@ -123,9 +123,38 @@ export type Role = | 'treegrid' | 'treeitem'; +export type AccessibilityActionName = + /** + * Generated when a screen reader user double taps the component. + */ + | 'activate' + /** + * Generated when a screen reader user increments an adjustable component. + */ + | 'increment' + /** + * Generated when a screen reader user decrements an adjustable component. + */ + | 'decrement' + /** + * Generated when a TalkBack user places accessibility focus on the component and double taps and holds one finger on the screen. + * @platform android + */ + | 'longpress' + /** + * Generated when a VoiceOver user places focus on or inside the component and double taps with two fingers. + * @platform ios + * */ + | 'magicTap' + /** + * Generated when a VoiceOver user places focus on or inside the component and performs a two finger scrub gesture (left, right, left). + * @platform ios + * */ + | 'escape'; + // the info associated with an accessibility action export type AccessibilityActionInfo = $ReadOnly<{ - name: string, + name: AccessibilityActionName | string, label?: string, ... }>; @@ -136,10 +165,25 @@ export type AccessibilityActionEvent = SyntheticEvent< >; export type AccessibilityState = { + /** + * When true, informs accessible tools if the element is disabled + */ disabled?: ?boolean, + /** + * When true, informs accessible tools if the element is selected + */ selected?: ?boolean, + /** + * For items like Checkboxes and Toggle switches, reports their state to accessible tools + */ checked?: ?boolean | 'mixed', + /** + * When present, informs accessible tools if the element is busy + */ busy?: ?boolean, + /** + * When present, informs accessible tools the element is expanded or collapsed + */ expanded?: ?boolean, ... }; @@ -165,3 +209,199 @@ export type AccessibilityValue = $ReadOnly<{ */ text?: Stringish, }>; + +export type AccessibilityPropsAndroid = $ReadOnly<{ + /** + * Identifies the element that labels the element it is applied to. When the assistive technology focuses on the component with this props, + * the text is read aloud. The value should should match the nativeID of the related element. + * + * @platform android + */ + accessibilityLabelledBy?: ?string | ?Array, + + /** + * Identifies the element that labels the element it is applied to. When the assistive technology focuses on the component with this props, + * the text is read aloud. The value should should match the nativeID of the related element. + * + * @platform android + */ + 'aria-labelledby'?: ?string, + + /** + * Indicates to accessibility services whether the user should be notified + * when this view changes. Works for Android API >= 19 only. + * + * @platform android + * + * See https://reactnative.dev/docs/view#accessibilityliveregion + */ + accessibilityLiveRegion?: ?('none' | 'polite' | 'assertive'), + + /** + * Indicates to accessibility services whether the user should be notified + * when this view changes. Works for Android API >= 19 only. + * + * @platform android + * + * See https://reactnative.dev/docs/view#accessibilityliveregion + */ + 'aria-live'?: ?('polite' | 'assertive' | 'off'), + + /** + * Controls how view is important for accessibility which is if it + * fires accessibility events and if it is reported to accessibility services + * that query the screen. Works for Android only. + * + * @platform android + * + * See https://reactnative.dev/docs/view#importantforaccessibility + */ + importantForAccessibility?: ?('auto' | 'yes' | 'no' | 'no-hide-descendants'), +}>; + +export type AccessibilityPropsIOS = $ReadOnly<{ + /** + * Prevents view from being inverted if set to true and color inversion is turned on. + * + * @platform ios + */ + accessibilityIgnoresInvertColors?: ?boolean, + + /** + * A value indicating whether VoiceOver should ignore the elements + * within views that are siblings of the receiver. + * Default is `false`. + * + * @platform ios + * + * See https://reactnative.dev/docs/view#accessibilityviewismodal + */ + accessibilityViewIsModal?: ?boolean, + + /** + * @platform ios + * + * See https://reactnative.dev/docs/view#accessibilityshowslargecontentviewer + */ + accessibilityShowsLargeContentViewer?: ?boolean, + + /** + * @platform ios + * + * See https://reactnative.dev/docs/view#accessibilitylargecontenttitle + */ + accessibilityLargeContentTitle?: ?string, + + /** + * The aria-modal attribute indicates content contained within a modal with aria-modal="true" + * should be accessible to the user. + * Default is `false`. + * + * @platform ios + */ + 'aria-modal'?: ?boolean, + + /** + * A value indicating whether the accessibility elements contained within + * this accessibility element are hidden. + * + * @platform ios + * + * See https://reactnative.dev/docs/view#accessibilityElementsHidden + */ + accessibilityElementsHidden?: ?boolean, + + /** + * Indicates to the accessibility services that the UI component is in + * a specific language. The provided string should be formatted following + * the BCP 47 specification (https://www.rfc-editor.org/info/bcp47). + * + * @platform ios + */ + accessibilityLanguage?: ?Stringish, +}>; + +export type AccessibilityProps = $ReadOnly<{ + ...AccessibilityPropsAndroid, + ...AccessibilityPropsIOS, + /** + * When `true`, indicates that the view is an accessibility element. + * By default, all the touchable elements are accessible. + * + * See https://reactnative.dev/docs/view#accessible + */ + accessible?: ?boolean, + + /** + * Overrides the text that's read by the screen reader when the user interacts + * with the element. By default, the label is constructed by traversing all + * the children and accumulating all the `Text` nodes separated by space. + * + * See https://reactnative.dev/docs/view#accessibilitylabel + */ + accessibilityLabel?: ?Stringish, + + /** + * An accessibility hint helps users understand what will happen when they perform + * an action on the accessibility element when that result is not obvious from the + * accessibility label. + * + * + * See https://reactnative.dev/docs/view#accessibilityHint + */ + accessibilityHint?: ?Stringish, + + /** + * Alias for accessibilityLabel https://reactnative.dev/docs/view#accessibilitylabel + * https://github.com/facebook/react-native/issues/34424 + */ + 'aria-label'?: ?Stringish, + + /** + * Indicates to accessibility services to treat UI component like a specific role. + */ + accessibilityRole?: ?AccessibilityRole, + + /** + * Alias for accessibilityRole + */ + role?: ?Role, + + /** + * Indicates to accessibility services that UI Component is in a specific State. + */ + accessibilityState?: ?AccessibilityState, + accessibilityValue?: ?AccessibilityValue, + + /** + * alias for accessibilityState + * It represents textual description of a component's value, or for range-based components, such as sliders and progress bars. + */ + 'aria-valuemax'?: ?AccessibilityValue['max'], + 'aria-valuemin'?: ?AccessibilityValue['min'], + 'aria-valuenow'?: ?AccessibilityValue['now'], + 'aria-valuetext'?: ?AccessibilityValue['text'], + + /** + * Provides an array of custom actions available for accessibility. + * + */ + accessibilityActions?: ?$ReadOnlyArray, + + /** + * alias for accessibilityState + * + * see https://reactnative.dev/docs/accessibility#accessibilitystate + */ + 'aria-busy'?: ?boolean, + 'aria-checked'?: ?boolean | 'mixed', + 'aria-disabled'?: ?boolean, + 'aria-expanded'?: ?boolean, + 'aria-selected'?: ?boolean, + /** A value indicating whether the accessibility elements contained within + * this accessibility element are hidden. + * + * See https://reactnative.dev/docs/view#aria-hidden + */ + 'aria-hidden'?: ?boolean, +}>; diff --git a/packages/react-native/Libraries/Components/View/ViewPropTypes.js b/packages/react-native/Libraries/Components/View/ViewPropTypes.js index 8f5a93eb8fd2..f4f7f7269fbd 100644 --- a/packages/react-native/Libraries/Components/View/ViewPropTypes.js +++ b/packages/react-native/Libraries/Components/View/ViewPropTypes.js @@ -23,11 +23,7 @@ import type { } from '../../Types/CoreEventTypes'; import type { AccessibilityActionEvent, - AccessibilityActionInfo, - AccessibilityRole, - AccessibilityState, - AccessibilityValue, - Role, + AccessibilityProps, } from './ViewAccessibility'; import type {Node} from 'react'; @@ -134,7 +130,7 @@ type TouchEventProps = $ReadOnly<{ * `TouchableHighlight` or `TouchableOpacity`. Check out `Touchable.js`, * `ScrollResponder.js` and `ResponderEventPlugin.js` for more discussion. */ -type GestureResponderEventProps = $ReadOnly<{ +export type GestureResponderHandlers = $ReadOnly<{ /** * Does this view want to "claim" touch responsiveness? This is called for * every touch move on the `View` when it is not the responder. @@ -265,43 +261,7 @@ type AndroidDrawableRipple = $ReadOnly<{ type AndroidDrawable = AndroidDrawableThemeAttr | AndroidDrawableRipple; -type AndroidViewProps = $ReadOnly<{ - /** - * Identifies the element that labels the element it is applied to. When the assistive technology focuses on the component with this props, - * the text is read aloud. The value should should match the nativeID of the related element. - * - * @platform android - */ - accessibilityLabelledBy?: ?string | ?Array, - - /** - * Identifies the element that labels the element it is applied to. When the assistive technology focuses on the component with this props, - * the text is read aloud. The value should should match the nativeID of the related element. - * - * @platform android - */ - 'aria-labelledby'?: ?string, - - /** - * Indicates to accessibility services whether the user should be notified - * when this view changes. Works for Android API >= 19 only. - * - * @platform android - * - * See https://reactnative.dev/docs/view#accessibilityliveregion - */ - accessibilityLiveRegion?: ?('none' | 'polite' | 'assertive'), - - /** - * Indicates to accessibility services whether the user should be notified - * when this view changes. Works for Android API >= 19 only. - * - * @platform android - * - * See https://reactnative.dev/docs/view#accessibilityliveregion - */ - 'aria-live'?: ?('polite' | 'assertive' | 'off'), - +export type ViewPropsAndroid = $ReadOnly<{ nativeBackgroundAndroid?: ?AndroidDrawable, nativeForegroundAndroid?: ?AndroidDrawable, @@ -315,17 +275,6 @@ type AndroidViewProps = $ReadOnly<{ */ renderToHardwareTextureAndroid?: ?boolean, - /** - * Controls how view is important for accessibility which is if it - * fires accessibility events and if it is reported to accessibility services - * that query the screen. Works for Android only. - * - * @platform android - * - * See https://reactnative.dev/docs/view#importantforaccessibility - */ - importantForAccessibility?: ?('auto' | 'yes' | 'no' | 'no-hide-descendants'), - /** * Whether to force the Android TV focus engine to move focus to this view. * @@ -396,67 +345,7 @@ type AndroidViewProps = $ReadOnly<{ onClick?: ?(event: PressEvent) => mixed, }>; -type IOSViewProps = $ReadOnly<{ - /** - * Prevents view from being inverted if set to true and color inversion is turned on. - * - * @platform ios - */ - accessibilityIgnoresInvertColors?: ?boolean, - - /** - * A value indicating whether VoiceOver should ignore the elements - * within views that are siblings of the receiver. - * Default is `false`. - * - * @platform ios - * - * See https://reactnative.dev/docs/view#accessibilityviewismodal - */ - accessibilityViewIsModal?: ?boolean, - - /** - * @platform ios - * - * See https://reactnative.dev/docs/view#accessibilityshowslargecontentviewer - */ - accessibilityShowsLargeContentViewer?: ?boolean, - - /** - * @platform ios - * - * See https://reactnative.dev/docs/view#accessibilitylargecontenttitle - */ - accessibilityLargeContentTitle?: ?string, - - /** - * The aria-modal attribute indicates content contained within a modal with aria-modal="true" - * should be accessible to the user. - * Default is `false`. - * - * @platform ios - */ - 'aria-modal'?: ?boolean, - - /** - * A value indicating whether the accessibility elements contained within - * this accessibility element are hidden. - * - * @platform ios - * - * See https://reactnative.dev/docs/view#accessibilityElementsHidden - */ - accessibilityElementsHidden?: ?boolean, - - /** - * Indicates to the accessibility services that the UI component is in - * a specific language. The provided string should be formatted following - * the BCP 47 specification (https://www.rfc-editor.org/info/bcp47). - * - * @platform ios - */ - accessibilityLanguage?: ?Stringish, - +export type ViewPropsIOS = $ReadOnly<{ /** * Whether this `View` should be rendered as a bitmap before compositing. * @@ -469,98 +358,18 @@ type IOSViewProps = $ReadOnly<{ export type ViewProps = $ReadOnly<{ ...DirectEventProps, - ...GestureResponderEventProps, + ...GestureResponderHandlers, ...MouseEventProps, ...PointerEventProps, ...FocusEventProps, ...TouchEventProps, - ...AndroidViewProps, - ...IOSViewProps, + ...ViewPropsAndroid, + ...ViewPropsIOS, + ...AccessibilityProps, children?: Node, style?: ?ViewStyleProp, - /** - * When `true`, indicates that the view is an accessibility element. - * By default, all the touchable elements are accessible. - * - * See https://reactnative.dev/docs/view#accessible - */ - accessible?: ?boolean, - - /** - * Overrides the text that's read by the screen reader when the user interacts - * with the element. By default, the label is constructed by traversing all - * the children and accumulating all the `Text` nodes separated by space. - * - * See https://reactnative.dev/docs/view#accessibilitylabel - */ - accessibilityLabel?: ?Stringish, - - /** - * An accessibility hint helps users understand what will happen when they perform - * an action on the accessibility element when that result is not obvious from the - * accessibility label. - * - * - * See https://reactnative.dev/docs/view#accessibilityHint - */ - accessibilityHint?: ?Stringish, - - /** - * Alias for accessibilityLabel https://reactnative.dev/docs/view#accessibilitylabel - * https://github.com/facebook/react-native/issues/34424 - */ - 'aria-label'?: ?Stringish, - - /** - * Indicates to accessibility services to treat UI component like a specific role. - */ - accessibilityRole?: ?AccessibilityRole, - - /** - * Alias for accessibilityRole - */ - role?: ?Role, - - /** - * Indicates to accessibility services that UI Component is in a specific State. - */ - accessibilityState?: ?AccessibilityState, - accessibilityValue?: ?AccessibilityValue, - - /** - * alias for accessibilityState - * It represents textual description of a component's value, or for range-based components, such as sliders and progress bars. - */ - 'aria-valuemax'?: ?AccessibilityValue['max'], - 'aria-valuemin'?: ?AccessibilityValue['min'], - 'aria-valuenow'?: ?AccessibilityValue['now'], - 'aria-valuetext'?: ?AccessibilityValue['text'], - - /** - * Provides an array of custom actions available for accessibility. - * - */ - accessibilityActions?: ?$ReadOnlyArray, - - /** - * alias for accessibilityState - * - * see https://reactnative.dev/docs/accessibility#accessibilitystate - */ - 'aria-busy'?: ?boolean, - 'aria-checked'?: ?boolean | 'mixed', - 'aria-disabled'?: ?boolean, - 'aria-expanded'?: ?boolean, - 'aria-selected'?: ?boolean, - /** A value indicating whether the accessibility elements contained within - * this accessibility element are hidden. - * - * See https://reactnative.dev/docs/view#aria-hidden - */ - 'aria-hidden'?: ?boolean, - /** * Views that are only used to layout their children or otherwise don't draw * anything may be automatically removed from the native hierarchy as an diff --git a/packages/react-native/Libraries/__tests__/__snapshots__/public-api-test.js.snap b/packages/react-native/Libraries/__tests__/__snapshots__/public-api-test.js.snap index 16c1b2773075..20cd8b29a9fa 100644 --- a/packages/react-native/Libraries/__tests__/__snapshots__/public-api-test.js.snap +++ b/packages/react-native/Libraries/__tests__/__snapshots__/public-api-test.js.snap @@ -3700,8 +3700,15 @@ export type Role = | \\"tree\\" | \\"treegrid\\" | \\"treeitem\\"; +export type AccessibilityActionName = + | \\"activate\\" + | \\"increment\\" + | \\"decrement\\" + | \\"longpress\\" + | \\"magicTap\\" + | \\"escape\\"; export type AccessibilityActionInfo = $ReadOnly<{ - name: string, + name: AccessibilityActionName | string, label?: string, ... }>; @@ -3722,6 +3729,45 @@ export type AccessibilityValue = $ReadOnly<{ now?: number, text?: Stringish, }>; +export type AccessibilityPropsAndroid = $ReadOnly<{ + accessibilityLabelledBy?: ?string | ?Array, + \\"aria-labelledby\\"?: ?string, + accessibilityLiveRegion?: ?(\\"none\\" | \\"polite\\" | \\"assertive\\"), + \\"aria-live\\"?: ?(\\"polite\\" | \\"assertive\\" | \\"off\\"), + importantForAccessibility?: ?(\\"auto\\" | \\"yes\\" | \\"no\\" | \\"no-hide-descendants\\"), +}>; +export type AccessibilityPropsIOS = $ReadOnly<{ + accessibilityIgnoresInvertColors?: ?boolean, + accessibilityViewIsModal?: ?boolean, + accessibilityShowsLargeContentViewer?: ?boolean, + accessibilityLargeContentTitle?: ?string, + \\"aria-modal\\"?: ?boolean, + accessibilityElementsHidden?: ?boolean, + accessibilityLanguage?: ?Stringish, +}>; +export type AccessibilityProps = $ReadOnly<{ + ...AccessibilityPropsAndroid, + ...AccessibilityPropsIOS, + accessible?: ?boolean, + accessibilityLabel?: ?Stringish, + accessibilityHint?: ?Stringish, + \\"aria-label\\"?: ?Stringish, + accessibilityRole?: ?AccessibilityRole, + role?: ?Role, + accessibilityState?: ?AccessibilityState, + accessibilityValue?: ?AccessibilityValue, + \\"aria-valuemax\\"?: ?AccessibilityValue[\\"max\\"], + \\"aria-valuemin\\"?: ?AccessibilityValue[\\"min\\"], + \\"aria-valuenow\\"?: ?AccessibilityValue[\\"now\\"], + \\"aria-valuetext\\"?: ?AccessibilityValue[\\"text\\"], + accessibilityActions?: ?$ReadOnlyArray, + \\"aria-busy\\"?: ?boolean, + \\"aria-checked\\"?: ?boolean | \\"mixed\\", + \\"aria-disabled\\"?: ?boolean, + \\"aria-expanded\\"?: ?boolean, + \\"aria-selected\\"?: ?boolean, + \\"aria-hidden\\"?: ?boolean, +}>; " `; @@ -3791,7 +3837,7 @@ type TouchEventProps = $ReadOnly<{ onTouchStart?: ?(e: PressEvent) => void, onTouchStartCapture?: ?(e: PressEvent) => void, }>; -type GestureResponderEventProps = $ReadOnly<{ +export type GestureResponderHandlers = $ReadOnly<{ onMoveShouldSetResponder?: ?(e: PressEvent) => boolean, onMoveShouldSetResponderCapture?: ?(e: PressEvent) => boolean, onResponderGrant?: ?(e: PressEvent) => void | boolean, @@ -3816,15 +3862,10 @@ type AndroidDrawableRipple = $ReadOnly<{ rippleRadius?: ?number, }>; type AndroidDrawable = AndroidDrawableThemeAttr | AndroidDrawableRipple; -type AndroidViewProps = $ReadOnly<{ - accessibilityLabelledBy?: ?string | ?Array, - \\"aria-labelledby\\"?: ?string, - accessibilityLiveRegion?: ?(\\"none\\" | \\"polite\\" | \\"assertive\\"), - \\"aria-live\\"?: ?(\\"polite\\" | \\"assertive\\" | \\"off\\"), +export type ViewPropsAndroid = $ReadOnly<{ nativeBackgroundAndroid?: ?AndroidDrawable, nativeForegroundAndroid?: ?AndroidDrawable, renderToHardwareTextureAndroid?: ?boolean, - importantForAccessibility?: ?(\\"auto\\" | \\"yes\\" | \\"no\\" | \\"no-hide-descendants\\"), hasTVPreferredFocus?: ?boolean, nextFocusDown?: ?number, nextFocusForward?: ?number, @@ -3835,46 +3876,21 @@ type AndroidViewProps = $ReadOnly<{ tabIndex?: 0 | -1, onClick?: ?(event: PressEvent) => mixed, }>; -type IOSViewProps = $ReadOnly<{ - accessibilityIgnoresInvertColors?: ?boolean, - accessibilityViewIsModal?: ?boolean, - accessibilityShowsLargeContentViewer?: ?boolean, - accessibilityLargeContentTitle?: ?string, - \\"aria-modal\\"?: ?boolean, - accessibilityElementsHidden?: ?boolean, - accessibilityLanguage?: ?Stringish, +export type ViewPropsIOS = $ReadOnly<{ shouldRasterizeIOS?: ?boolean, }>; export type ViewProps = $ReadOnly<{ ...DirectEventProps, - ...GestureResponderEventProps, + ...GestureResponderHandlers, ...MouseEventProps, ...PointerEventProps, ...FocusEventProps, ...TouchEventProps, - ...AndroidViewProps, - ...IOSViewProps, + ...ViewPropsAndroid, + ...ViewPropsIOS, + ...AccessibilityProps, children?: Node, style?: ?ViewStyleProp, - accessible?: ?boolean, - accessibilityLabel?: ?Stringish, - accessibilityHint?: ?Stringish, - \\"aria-label\\"?: ?Stringish, - accessibilityRole?: ?AccessibilityRole, - role?: ?Role, - accessibilityState?: ?AccessibilityState, - accessibilityValue?: ?AccessibilityValue, - \\"aria-valuemax\\"?: ?AccessibilityValue[\\"max\\"], - \\"aria-valuemin\\"?: ?AccessibilityValue[\\"min\\"], - \\"aria-valuenow\\"?: ?AccessibilityValue[\\"now\\"], - \\"aria-valuetext\\"?: ?AccessibilityValue[\\"text\\"], - accessibilityActions?: ?$ReadOnlyArray, - \\"aria-busy\\"?: ?boolean, - \\"aria-checked\\"?: ?boolean | \\"mixed\\", - \\"aria-disabled\\"?: ?boolean, - \\"aria-expanded\\"?: ?boolean, - \\"aria-selected\\"?: ?boolean, - \\"aria-hidden\\"?: ?boolean, collapsable?: ?boolean, collapsableChildren?: ?boolean, id?: string,