Skip to content

Instantly share code, notes, and snippets.

@gourav-singhal
Forked from louy/AccessibilityWrapper.tsx
Created February 24, 2023 11:33
Show Gist options
  • Select an option

  • Save gourav-singhal/588f25e50148b11d9767173a1b806a2a to your computer and use it in GitHub Desktop.

Select an option

Save gourav-singhal/588f25e50148b11d9767173a1b806a2a to your computer and use it in GitHub Desktop.

Revisions

  1. @louy louy revised this gist Nov 20, 2021. 5 changed files with 8 additions and 3 deletions.
    4 changes: 4 additions & 0 deletions AccessibilityWrapper.tsx
    Original file line number Diff line number Diff line change
    @@ -1,3 +1,7 @@
    /**
    * @author Louay Alakkad (github.com/louy)
    * @license MIT https://opensource.org/licenses/MIT
    */
    import React from 'react'
    import PropTypes from 'prop-types'
    import {
    2 changes: 1 addition & 1 deletion RNAccessibilityWrapper.h
    Original file line number Diff line number Diff line change
    @@ -2,7 +2,7 @@
    // RNAccessibilityWrapper.h
    //
    // Created by Louay Alakkad on 10/04/2019.
    // Copyright © 2019 Facebook. All rights reserved.
    // License: MIT https://opensource.org/licenses/MIT
    //

    #import <UIKit/UIKit.h>
    2 changes: 1 addition & 1 deletion RNAccessibilityWrapper.m
    Original file line number Diff line number Diff line change
    @@ -2,7 +2,7 @@
    // RNAccessibilityWrapper.m
    //
    // Created by Louay Alakkad on 10/04/2019.
    // Copyright © 2019 Facebook. All rights reserved.
    // License: MIT https://opensource.org/licenses/MIT
    //

    #import <Foundation/Foundation.h>
    2 changes: 1 addition & 1 deletion RNAccessibilityWrapperManager.h
    Original file line number Diff line number Diff line change
    @@ -2,7 +2,7 @@
    // RNAccessibilityViewManager
    //
    // Created by Louay Alakkad on 10/04/2019.
    // Copyright © 2019 Facebook. All rights reserved.
    // License: MIT https://opensource.org/licenses/MIT
    //

    #import <React/RCTViewManager.h>
    1 change: 1 addition & 0 deletions RNAccessibilityWrapperManager.m
    Original file line number Diff line number Diff line change
    @@ -2,6 +2,7 @@
    // RNAccessibilityWrapper.m
    //
    // Created by Louay Alakkad on 10/04/2019.
    // License: MIT https://opensource.org/licenses/MIT
    //

    #import <Foundation/Foundation.h>
  2. @louy louy revised this gist Jul 8, 2019. No changes.
  3. @louy louy created this gist Jul 8, 2019.
    105 changes: 105 additions & 0 deletions AccessibilityWrapper.tsx
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,105 @@
    import React from 'react'
    import PropTypes from 'prop-types'
    import {
    NativeModules,
    ViewProps,
    ViewPropTypes,
    findNodeHandle,
    requireNativeComponent,
    Platform,
    View
    } from 'react-native'

    const { RNAccessibilityWrapperManager } = NativeModules

    const RNAccessibilityWrapper = requireNativeComponent(
    'RNAccessibilityWrapper'
    ) as React.ComponentClass<any>

    interface AccessibilityWrapperProps extends ViewProps {
    fieldsRefs?: React.RefObject<React.Component>[]
    }

    const AccessibilityWrapperPropTypes = {
    ...ViewPropTypes,
    fieldsRefs: PropTypes.arrayOf(PropTypes.shape({
    current: PropTypes.object
    }) as PropTypes.Validator<React.RefObject<React.Component>>)
    }

    class AccessibilityWrapperIOS extends React.Component<
    AccessibilityWrapperProps
    > {
    public static propTypes = AccessibilityWrapperPropTypes

    private ref = React.createRef<React.Component<any>>()

    public componentDidMount() {
    if (this.props.fieldsRefs) {
    this.setAccessibilityFields(this.props.fieldsRefs.map(ref => ref.current))
    }
    }
    public componentDidUpdate() {
    if (this.props.fieldsRefs) {
    this.setAccessibilityFields(this.props.fieldsRefs.map(ref => ref.current))
    }
    }

    private setAccessibilityFields = (
    fields: (React.Component<any> | null)[]
    ) => {
    const fieldTags =
    fields && fields.map(component => component && findNodeHandle(component))
    return RNAccessibilityWrapperManager.setAccessibilityFields(
    findNodeHandle(this.ref.current),
    fieldTags
    )
    }

    public render() {
    return <RNAccessibilityWrapper {...this.props} ref={this.ref} />
    }
    }

    const AccessibilityWrapperAndroid: React.FunctionComponent<
    AccessibilityWrapperProps
    > = ({ fieldsRefs, ...props }) => <View {...props} />
    AccessibilityWrapperAndroid.propTypes = AccessibilityWrapperPropTypes

    /**
    * The AccessibilityWrapper component allows you to adjust the behaviour of the native platform
    * when it comes to accessibility. Using this component you can tell the native platform to
    * group all subviews together for accessibility purposes (since it's not always done by
    * default), and you can even override the focus order of subviews
    *
    * @example
    * export default class App extends Component<{}> {
    * fooRef = React.createRef<Text>();
    * barRef = React.createRef<Text>();
    * bazRef = React.createRef<Text>();
    *
    * public render() {
    * return (
    * <AccessibilityWrapper fieldsRefs={[
    * this.barRef,
    * this.fooRef,
    * this.bazRef,
    * ]}>
    * <SafeAreaView>
    * <Text ref={this.fooRef}>Foo</Text>
    * <Text ref={this.barRef}>Bar</Text>
    * <Text ref={this.bazRef}>Baz</Text>
    * </SafeAreaView>
    * </AccessibilityWrapper>
    * );
    * }
    * }
    */
    export default Platform.select<React.ComponentType<AccessibilityWrapperProps>>({
    ios: AccessibilityWrapperIOS as React.ComponentType<
    AccessibilityWrapperProps
    >,
    android: AccessibilityWrapperAndroid as React.ComponentType<
    AccessibilityWrapperProps
    >
    })
    17 changes: 17 additions & 0 deletions RNAccessibilityWrapper.h
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,17 @@
    //
    // RNAccessibilityWrapper.h
    //
    // Created by Louay Alakkad on 10/04/2019.
    // Copyright © 2019 Facebook. All rights reserved.
    //

    #import <UIKit/UIKit.h>
    #import <UIKit/UIAccessibilityContainer.h>

    #import <React/RCTView.h>

    @interface RNAccessibilityWrapper : RCTView

    - (void) setAccessibilityFields: (NSArray *)reactTags;

    @end
    28 changes: 28 additions & 0 deletions RNAccessibilityWrapper.m
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,28 @@
    //
    // RNAccessibilityWrapper.m
    //
    // Created by Louay Alakkad on 10/04/2019.
    // Copyright © 2019 Facebook. All rights reserved.
    //

    #import <Foundation/Foundation.h>
    #import "RNAccessibilityWrapper.h"
    #import <UIKit/UIKit.h>

    @implementation RNAccessibilityWrapper

    - (void) setAccessibilityFields: (NSArray *)fields
    {
    NSMutableArray *accessibleElements = [NSMutableArray arrayWithCapacity:[fields count]];
    [fields enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL * stop) {
    UIView *field = obj;
    [accessibleElements addObject:field];
    }];
    self.accessibilityElements = (NSArray *)accessibleElements;
    }

    - (bool) shouldGroupAccessibilityChildren {
    return YES;
    }

    @end
    10 changes: 10 additions & 0 deletions RNAccessibilityWrapperManager.h
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,10 @@
    //
    // RNAccessibilityViewManager
    //
    // Created by Louay Alakkad on 10/04/2019.
    // Copyright © 2019 Facebook. All rights reserved.
    //

    #import <React/RCTViewManager.h>
    @interface RNAccessibilityWrapperManager : RCTViewManager
    @end
    37 changes: 37 additions & 0 deletions RNAccessibilityWrapperManager.m
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,37 @@
    //
    // RNAccessibilityWrapper.m
    //
    // Created by Louay Alakkad on 10/04/2019.
    //

    #import <Foundation/Foundation.h>
    #import <React/RCTUIManager.h>
    #import "RNAccessibilityWrapper.h"
    #import "RNAccessibilityWrapperManager.h"

    @implementation RNAccessibilityWrapperManager

    RCT_EXPORT_MODULE()

    - (UIView *)view {
    return [[RNAccessibilityWrapper alloc] init];
    }

    RCT_EXPORT_METHOD(setAccessibilityFields:(nonnull NSNumber *)reactTag
    fieldsReactTags: (nonnull NSArray *)fieldsReactTags) {
    dispatch_async(dispatch_get_main_queue(), ^{
    RNAccessibilityWrapper *component = (RNAccessibilityWrapper *)[self.bridge.uiManager viewForReactTag:reactTag];

    NSMutableArray *fields = [NSMutableArray arrayWithCapacity:[fieldsReactTags count]];

    [fieldsReactTags enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL * stop) {
    NSNumber *tag = (NSNumber *)obj;
    UIView *field = [self.bridge.uiManager viewForReactTag:tag];
    [fields addObject:field];
    }];

    [component setAccessibilityFields: fields];
    });
    }

    @end