├── .editorconfig ├── .gitattributes ├── .github ├── actions │ └── setup │ │ └── action.yml ├── images │ ├── android-reader.gif │ ├── horizontal-scroll-group.gif │ ├── horizontal-scroll-view.gif │ └── ios-reader.gif └── workflows │ └── ci.yml ├── .gitignore ├── .nvmrc ├── .watchmanconfig ├── .yarnrc ├── .yarnrc.yml ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── android ├── build.gradle ├── gradle.properties └── src │ ├── main │ ├── AndroidManifest.xml │ └── java │ │ └── com │ │ └── a11yorder │ │ ├── A11yOrderPackage.java │ │ ├── services │ │ └── FocusUtil.java │ │ └── views │ │ ├── A11yGroupView │ │ └── A11yGroupViewManager.java │ │ ├── A11yIndexView │ │ ├── A11yIndexView.java │ │ ├── A11yIndexViewManager.java │ │ └── Linking │ │ │ ├── A11yOrderLinking.java │ │ │ └── LinkingQueue.java │ │ └── A11yOrderView │ │ ├── A11yOrderView.java │ │ └── A11yOrderViewManager.java │ ├── newarch │ ├── A11yGroupViewManagerSpec.java │ ├── A11yIndexViewManagerSpec.java │ └── A11yOrderViewManagerSpec.java │ └── oldarch │ ├── A11yGroupViewManagerSpec.java │ ├── A11yIndexViewManagerSpec.java │ └── A11yOrderViewManagerSpec.java ├── babel.config.js ├── example ├── .bundle │ └── config ├── .node-version ├── .watchmanconfig ├── Gemfile ├── Gemfile.lock ├── android │ ├── app │ │ ├── build.gradle │ │ ├── debug.keystore │ │ ├── proguard-rules.pro │ │ └── src │ │ │ ├── debug │ │ │ ├── AndroidManifest.xml │ │ │ └── java │ │ │ │ └── com │ │ │ │ └── a11yorderexample │ │ │ │ └── ReactNativeFlipper.java │ │ │ ├── main │ │ │ ├── AndroidManifest.xml │ │ │ ├── java │ │ │ │ └── com │ │ │ │ │ └── a11yorderexample │ │ │ │ │ ├── MainActivity.java │ │ │ │ │ └── MainApplication.java │ │ │ └── res │ │ │ │ ├── drawable │ │ │ │ └── rn_edit_text_material.xml │ │ │ │ ├── mipmap-hdpi │ │ │ │ ├── ic_launcher.png │ │ │ │ └── ic_launcher_round.png │ │ │ │ ├── mipmap-mdpi │ │ │ │ ├── ic_launcher.png │ │ │ │ └── ic_launcher_round.png │ │ │ │ ├── mipmap-xhdpi │ │ │ │ ├── ic_launcher.png │ │ │ │ └── ic_launcher_round.png │ │ │ │ ├── mipmap-xxhdpi │ │ │ │ ├── ic_launcher.png │ │ │ │ └── ic_launcher_round.png │ │ │ │ ├── mipmap-xxxhdpi │ │ │ │ ├── ic_launcher.png │ │ │ │ └── ic_launcher_round.png │ │ │ │ └── values │ │ │ │ ├── strings.xml │ │ │ │ └── styles.xml │ │ │ └── release │ │ │ └── java │ │ │ └── com │ │ │ └── a11yorderexample │ │ │ └── ReactNativeFlipper.java │ ├── build.gradle │ ├── gradle.properties │ ├── gradle │ │ └── wrapper │ │ │ ├── gradle-wrapper.jar │ │ │ └── gradle-wrapper.properties │ ├── gradlew │ ├── gradlew.bat │ └── settings.gradle ├── app.json ├── babel.config.js ├── index.js ├── ios │ ├── .xcode.env │ ├── A11yOrderExample-Bridging-Header.h │ ├── A11yOrderExample.xcodeproj │ │ ├── project.pbxproj │ │ └── xcshareddata │ │ │ └── xcschemes │ │ │ └── A11yOrderExample.xcscheme │ ├── A11yOrderExample.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata │ │ │ └── IDEWorkspaceChecks.plist │ ├── A11yOrderExample │ │ ├── AppDelegate.h │ │ ├── AppDelegate.mm │ │ ├── Images.xcassets │ │ │ ├── AppIcon.appiconset │ │ │ │ └── Contents.json │ │ │ └── Contents.json │ │ ├── Info.plist │ │ ├── LaunchScreen.storyboard │ │ └── main.m │ ├── A11yOrderExampleTests │ │ ├── A11yOrderExampleTests.m │ │ └── Info.plist │ ├── File.swift │ ├── Podfile │ └── Podfile.lock ├── metro.config.js ├── package.json ├── react-native.config.js ├── src │ ├── App.tsx │ ├── components │ │ ├── CircleExample.tsx │ │ ├── CircleNode.tsx │ │ ├── ReorderExample.tsx │ │ ├── Slide.tsx │ │ └── SliderExample.tsx │ └── constants │ │ └── circle.ts └── yarn.lock ├── ios ├── A11yOrder-Bridging-Header.h ├── A11yOrder.xcodeproj │ └── project.pbxproj ├── services │ ├── RNAOA11yOrderLinking.h │ ├── RNAOA11yOrderLinking.mm │ ├── RNAOA11yRelashioship.h │ ├── RNAOA11yRelashioship.mm │ ├── RNAOSortedMap.h │ └── RNAOSortedMap.mm └── views │ ├── RNAOA11yGroupView │ ├── RNAOA11yGroupView.h │ ├── RNAOA11yGroupView.mm │ ├── RNAOA11yGroupViewManager.h │ └── RNAOA11yGroupViewManager.mm │ ├── RNAOA11yIndexView │ ├── RNAOA11yIndexView.h │ ├── RNAOA11yIndexView.mm │ ├── RNAOA11yIndexViewManager.h │ └── RNAOA11yIndexViewManager.mm │ └── RNAOA11yOrderView │ ├── RNAOA11yOrderView.h │ ├── RNAOA11yOrderView.mm │ ├── RNAOA11yOrderViewManager.h │ └── RNAOA11yOrderViewManager.mm ├── lefthook.yml ├── package.json ├── react-native-a11y-order.podspec ├── scripts └── bootstrap.js ├── src ├── __tests__ │ └── index.test.tsx ├── components │ ├── A11yGroup │ │ ├── A11yGroup.android.tsx │ │ ├── A11yGroup.ios.tsx │ │ └── A11yGroup.tsx │ ├── A11yIndex │ │ ├── A11yIndex.tsx │ │ └── A11yIndex.web.tsx │ ├── A11yOrder │ │ └── A11yOrder.tsx │ └── A11ySequence │ │ └── A11ySequence.tsx ├── context │ └── A11ySequenceOrderContext.ts ├── index.ts ├── index.web.ts ├── nativeSpecs │ ├── A11yGroupNativeComponent.ts │ ├── A11yIndexNativeComponent.ts │ └── A11yOrderNativeComponent.ts └── types │ ├── A11yGroup.types.ts │ ├── A11yIndex.types.ts │ ├── A11yModule.types.ts │ └── A11yOrder.types.ts ├── tsconfig.build.json ├── tsconfig.json ├── types └── index.d.ts └── yarn.lock /.editorconfig: -------------------------------------------------------------------------------- 1 | # EditorConfig helps developers define and maintain consistent 2 | # coding styles between different editors and IDEs 3 | # editorconfig.org 4 | 5 | root = true 6 | 7 | [*] 8 | 9 | indent_style = space 10 | indent_size = 2 11 | 12 | end_of_line = lf 13 | charset = utf-8 14 | trim_trailing_whitespace = true 15 | insert_final_newline = true 16 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | *.pbxproj -text 2 | # specific for windows script files 3 | *.bat text eol=crlf -------------------------------------------------------------------------------- /.github/actions/setup/action.yml: -------------------------------------------------------------------------------- 1 | name: Setup 2 | description: Setup Node.js and install dependencies 3 | 4 | runs: 5 | using: composite 6 | steps: 7 | - name: Setup Node.js 8 | uses: actions/setup-node@v3 9 | with: 10 | node-version-file: .nvmrc 11 | 12 | - name: Cache dependencies 13 | id: yarn-cache 14 | uses: actions/cache@v3 15 | with: 16 | path: | 17 | **/node_modules 18 | key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }} 19 | restore-keys: | 20 | ${{ runner.os }}-yarn- 21 | 22 | - name: Install dependencies 23 | if: steps.yarn-cache.outputs.cache-hit != 'true' 24 | run: | 25 | yarn install --cwd example --frozen-lockfile 26 | yarn install --frozen-lockfile 27 | shell: bash 28 | -------------------------------------------------------------------------------- /.github/images/android-reader.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ArturKalach/react-native-a11y-order/4d68235fd01a3417cda52ef2578bddf7face4e76/.github/images/android-reader.gif -------------------------------------------------------------------------------- /.github/images/horizontal-scroll-group.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ArturKalach/react-native-a11y-order/4d68235fd01a3417cda52ef2578bddf7face4e76/.github/images/horizontal-scroll-group.gif -------------------------------------------------------------------------------- /.github/images/horizontal-scroll-view.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ArturKalach/react-native-a11y-order/4d68235fd01a3417cda52ef2578bddf7face4e76/.github/images/horizontal-scroll-view.gif -------------------------------------------------------------------------------- /.github/images/ios-reader.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ArturKalach/react-native-a11y-order/4d68235fd01a3417cda52ef2578bddf7face4e76/.github/images/ios-reader.gif -------------------------------------------------------------------------------- /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | name: CI 2 | on: 3 | push: 4 | branches: 5 | - main 6 | pull_request: 7 | branches: 8 | - main 9 | 10 | jobs: 11 | lint: 12 | runs-on: ubuntu-latest 13 | steps: 14 | - name: Checkout 15 | uses: actions/checkout@v3 16 | 17 | - name: Setup 18 | uses: ./.github/actions/setup 19 | 20 | - name: Lint files 21 | run: yarn lint 22 | 23 | - name: Typecheck files 24 | run: yarn typecheck 25 | 26 | test: 27 | runs-on: ubuntu-latest 28 | steps: 29 | - name: Checkout 30 | uses: actions/checkout@v3 31 | 32 | - name: Setup 33 | uses: ./.github/actions/setup 34 | 35 | - name: Run unit tests 36 | run: yarn test --maxWorkers=2 --coverage 37 | 38 | build: 39 | runs-on: ubuntu-latest 40 | steps: 41 | - name: Checkout 42 | uses: actions/checkout@v3 43 | 44 | - name: Setup 45 | uses: ./.github/actions/setup 46 | 47 | - name: Build package 48 | run: yarn prepack 49 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .yarn 2 | 3 | # OSX 4 | # 5 | .DS_Store 6 | 7 | # XDE 8 | .expo/ 9 | 10 | # VSCode 11 | .vscode/ 12 | jsconfig.json 13 | 14 | # Xcode 15 | # 16 | build/ 17 | *.pbxuser 18 | !default.pbxuser 19 | *.mode1v3 20 | !default.mode1v3 21 | *.mode2v3 22 | !default.mode2v3 23 | *.perspectivev3 24 | !default.perspectivev3 25 | xcuserdata 26 | *.xccheckout 27 | *.moved-aside 28 | DerivedData 29 | *.hmap 30 | *.ipa 31 | *.xcuserstate 32 | project.xcworkspace 33 | 34 | # Android/IJ 35 | # 36 | .classpath 37 | .cxx 38 | .gradle 39 | .idea 40 | .project 41 | .settings 42 | local.properties 43 | android.iml 44 | 45 | # Cocoapods 46 | # 47 | example/ios/Pods 48 | 49 | # Ruby 50 | example/vendor/ 51 | 52 | # node.js 53 | # 54 | node_modules/ 55 | npm-debug.log 56 | yarn-debug.log 57 | yarn-error.log 58 | 59 | # BUCK 60 | buck-out/ 61 | \.buckd/ 62 | android/app/libs 63 | android/keystores/debug.keystore 64 | 65 | # Expo 66 | .expo/ 67 | 68 | # Turborepo 69 | .turbo/ 70 | 71 | # generated by bob 72 | lib/ 73 | -------------------------------------------------------------------------------- /.nvmrc: -------------------------------------------------------------------------------- 1 | 16.18.1 2 | -------------------------------------------------------------------------------- /.watchmanconfig: -------------------------------------------------------------------------------- 1 | {} -------------------------------------------------------------------------------- /.yarnrc: -------------------------------------------------------------------------------- 1 | # Override Yarn command so we can automatically setup the repo on running `yarn` 2 | 3 | yarn-path "scripts/bootstrap.js" 4 | -------------------------------------------------------------------------------- /.yarnrc.yml: -------------------------------------------------------------------------------- 1 | nodeLinker: node-modules 2 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | 2 | # Contributor Covenant Code of Conduct 3 | 4 | ## Our Pledge 5 | 6 | We as members, contributors, and leaders pledge to make participation in our 7 | community a harassment-free experience for everyone, regardless of age, body 8 | size, visible or invisible disability, ethnicity, sex characteristics, gender 9 | identity and expression, level of experience, education, socio-economic status, 10 | nationality, personal appearance, race, caste, color, religion, or sexual 11 | identity and orientation. 12 | 13 | We pledge to act and interact in ways that contribute to an open, welcoming, 14 | diverse, inclusive, and healthy community. 15 | 16 | ## Our Standards 17 | 18 | Examples of behavior that contributes to a positive environment for our 19 | community include: 20 | 21 | * Demonstrating empathy and kindness toward other people 22 | * Being respectful of differing opinions, viewpoints, and experiences 23 | * Giving and gracefully accepting constructive feedback 24 | * Accepting responsibility and apologizing to those affected by our mistakes, 25 | and learning from the experience 26 | * Focusing on what is best not just for us as individuals, but for the overall 27 | community 28 | 29 | Examples of unacceptable behavior include: 30 | 31 | * The use of sexualized language or imagery, and sexual attention or advances of 32 | any kind 33 | * Trolling, insulting or derogatory comments, and personal or political attacks 34 | * Public or private harassment 35 | * Publishing others' private information, such as a physical or email address, 36 | without their explicit permission 37 | * Other conduct which could reasonably be considered inappropriate in a 38 | professional setting 39 | 40 | ## Enforcement Responsibilities 41 | 42 | Community leaders are responsible for clarifying and enforcing our standards of 43 | acceptable behavior and will take appropriate and fair corrective action in 44 | response to any behavior that they deem inappropriate, threatening, offensive, 45 | or harmful. 46 | 47 | Community leaders have the right and responsibility to remove, edit, or reject 48 | comments, commits, code, wiki edits, issues, and other contributions that are 49 | not aligned to this Code of Conduct, and will communicate reasons for moderation 50 | decisions when appropriate. 51 | 52 | ## Scope 53 | 54 | This Code of Conduct applies within all community spaces, and also applies when 55 | an individual is officially representing the community in public spaces. 56 | Examples of representing our community include using an official e-mail address, 57 | posting via an official social media account, or acting as an appointed 58 | representative at an online or offline event. 59 | 60 | ## Enforcement 61 | 62 | Instances of abusive, harassing, or otherwise unacceptable behavior may be 63 | reported to the community leaders responsible for enforcement at 64 | [INSERT CONTACT METHOD]. 65 | All complaints will be reviewed and investigated promptly and fairly. 66 | 67 | All community leaders are obligated to respect the privacy and security of the 68 | reporter of any incident. 69 | 70 | ## Enforcement Guidelines 71 | 72 | Community leaders will follow these Community Impact Guidelines in determining 73 | the consequences for any action they deem in violation of this Code of Conduct: 74 | 75 | ### 1. Correction 76 | 77 | **Community Impact**: Use of inappropriate language or other behavior deemed 78 | unprofessional or unwelcome in the community. 79 | 80 | **Consequence**: A private, written warning from community leaders, providing 81 | clarity around the nature of the violation and an explanation of why the 82 | behavior was inappropriate. A public apology may be requested. 83 | 84 | ### 2. Warning 85 | 86 | **Community Impact**: A violation through a single incident or series of 87 | actions. 88 | 89 | **Consequence**: A warning with consequences for continued behavior. No 90 | interaction with the people involved, including unsolicited interaction with 91 | those enforcing the Code of Conduct, for a specified period of time. This 92 | includes avoiding interactions in community spaces as well as external channels 93 | like social media. Violating these terms may lead to a temporary or permanent 94 | ban. 95 | 96 | ### 3. Temporary Ban 97 | 98 | **Community Impact**: A serious violation of community standards, including 99 | sustained inappropriate behavior. 100 | 101 | **Consequence**: A temporary ban from any sort of interaction or public 102 | communication with the community for a specified period of time. No public or 103 | private interaction with the people involved, including unsolicited interaction 104 | with those enforcing the Code of Conduct, is allowed during this period. 105 | Violating these terms may lead to a permanent ban. 106 | 107 | ### 4. Permanent Ban 108 | 109 | **Community Impact**: Demonstrating a pattern of violation of community 110 | standards, including sustained inappropriate behavior, harassment of an 111 | individual, or aggression toward or disparagement of classes of individuals. 112 | 113 | **Consequence**: A permanent ban from any sort of public interaction within the 114 | community. 115 | 116 | ## Attribution 117 | 118 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], 119 | version 2.1, available at 120 | [https://www.contributor-covenant.org/version/2/1/code_of_conduct.html][v2.1]. 121 | 122 | Community Impact Guidelines were inspired by 123 | [Mozilla's code of conduct enforcement ladder][Mozilla CoC]. 124 | 125 | For answers to common questions about this code of conduct, see the FAQ at 126 | [https://www.contributor-covenant.org/faq][FAQ]. Translations are available at 127 | [https://www.contributor-covenant.org/translations][translations]. 128 | 129 | [homepage]: https://www.contributor-covenant.org 130 | [v2.1]: https://www.contributor-covenant.org/version/2/1/code_of_conduct.html 131 | [Mozilla CoC]: https://github.com/mozilla/diversity 132 | [FAQ]: https://www.contributor-covenant.org/faq 133 | [translations]: https://www.contributor-covenant.org/translations 134 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing 2 | 3 | Contributions are always welcome, no matter how large or small! 4 | 5 | We want this community to be friendly and respectful to each other. Please follow it in all your interactions with the project. Before contributing, please read the [code of conduct](./CODE_OF_CONDUCT.md). 6 | 7 | ## Development workflow 8 | 9 | To get started with the project, run `yarn` in the root directory to install the required dependencies for each package: 10 | 11 | ```sh 12 | yarn 13 | ``` 14 | 15 | > While it's possible to use [`npm`](https://github.com/npm/cli), the tooling is built around [`yarn`](https://classic.yarnpkg.com/), so you'll have an easier time if you use `yarn` for development. 16 | 17 | While developing, you can run the [example app](/example/) to test your changes. Any changes you make in your library's JavaScript code will be reflected in the example app without a rebuild. If you change any native code, then you'll need to rebuild the example app. 18 | 19 | To start the packager: 20 | 21 | ```sh 22 | yarn example start 23 | ``` 24 | 25 | To run the example app on Android: 26 | 27 | ```sh 28 | yarn example android 29 | ``` 30 | 31 | To run the example app on iOS: 32 | 33 | ```sh 34 | yarn example ios 35 | ``` 36 | 37 | By default, the example is configured to build with the old architecture. To run the example with the new architecture, you can do the following: 38 | 39 | 1. For Android, run: 40 | 41 | ```sh 42 | ORG_GRADLE_PROJECT_newArchEnabled=true yarn example android 43 | ``` 44 | 45 | 2. For iOS, run: 46 | 47 | ```sh 48 | RCT_NEW_ARCH_ENABLED=1 yarn example pods 49 | yarn example ios 50 | ``` 51 | 52 | If you are building for a different architecture than your previous build, make sure to remove the build folders first. You can run the following command to cleanup all build folders: 53 | 54 | ```sh 55 | yarn clean 56 | ``` 57 | 58 | To confirm that the app is running with the new architecture, you can check the Metro logs for a message like this: 59 | 60 | ```sh 61 | Running "A11yOrderExample" with {"fabric":true,"initialProps":{"concurrentRoot":true},"rootTag":1} 62 | ``` 63 | 64 | Note the `"fabric":true` and `"concurrentRoot":true` properties. 65 | 66 | Make sure your code passes TypeScript and ESLint. Run the following to verify: 67 | 68 | ```sh 69 | yarn typecheck 70 | yarn lint 71 | ``` 72 | 73 | To fix formatting errors, run the following: 74 | 75 | ```sh 76 | yarn lint --fix 77 | ``` 78 | 79 | Remember to add tests for your change if possible. Run the unit tests by: 80 | 81 | ```sh 82 | yarn test 83 | ``` 84 | 85 | To edit the Objective-C or Swift files, open `example/ios/A11yOrderExample.xcworkspace` in XCode and find the source files at `Pods > Development Pods > react-native-a11y-order`. 86 | 87 | To edit the Java or Kotlin files, open `example/android` in Android studio and find the source files at `react-native-a11y-order` under `Android`. 88 | 89 | 90 | ### Commit message convention 91 | 92 | We follow the [conventional commits specification](https://www.conventionalcommits.org/en) for our commit messages: 93 | 94 | - `fix`: bug fixes, e.g. fix crash due to deprecated method. 95 | - `feat`: new features, e.g. add new method to the module. 96 | - `refactor`: code refactor, e.g. migrate from class components to hooks. 97 | - `docs`: changes into documentation, e.g. add usage example for the module.. 98 | - `test`: adding or updating tests, e.g. add integration tests using detox. 99 | - `chore`: tooling changes, e.g. change CI config. 100 | 101 | Our pre-commit hooks verify that your commit message matches this format when committing. 102 | 103 | ### Linting and tests 104 | 105 | [ESLint](https://eslint.org/), [Prettier](https://prettier.io/), [TypeScript](https://www.typescriptlang.org/) 106 | 107 | We use [TypeScript](https://www.typescriptlang.org/) for type checking, [ESLint](https://eslint.org/) with [Prettier](https://prettier.io/) for linting and formatting the code, and [Jest](https://jestjs.io/) for testing. 108 | 109 | Our pre-commit hooks verify that the linter and tests pass when committing. 110 | 111 | ### Publishing to npm 112 | 113 | We use [release-it](https://github.com/release-it/release-it) to make it easier to publish new versions. It handles common tasks like bumping version based on semver, creating tags and releases etc. 114 | 115 | To publish new versions, run the following: 116 | 117 | ```sh 118 | yarn release 119 | ``` 120 | 121 | ### Scripts 122 | 123 | The `package.json` file contains various scripts for common tasks: 124 | 125 | - `yarn bootstrap`: setup project by installing all dependencies and pods. 126 | - `yarn typecheck`: type-check files with TypeScript. 127 | - `yarn lint`: lint files with ESLint. 128 | - `yarn test`: run unit tests with Jest. 129 | - `yarn example start`: start the Metro server for the example app. 130 | - `yarn example android`: run the example app on Android. 131 | - `yarn example ios`: run the example app on iOS. 132 | 133 | ### Sending a pull request 134 | 135 | > **Working on your first pull request?** You can learn how from this _free_ series: [How to Contribute to an Open Source Project on GitHub](https://app.egghead.io/playlists/how-to-contribute-to-an-open-source-project-on-github). 136 | 137 | When you're sending a pull request: 138 | 139 | - Prefer small pull requests focused on one change. 140 | - Verify that linters and tests are passing. 141 | - Review the documentation to make sure it looks good. 142 | - Follow the pull request template when opening a pull request. 143 | - For pull requests that change the API or implementation, discuss with maintainers first by opening an issue. 144 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 Artur Kalach 4 | Permission is hereby granted, free of charge, to any person obtaining a copy 5 | of this software and associated documentation files (the "Software"), to deal 6 | in the Software without restriction, including without limitation the rights 7 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | copies of the Software, and to permit persons to whom the Software is 9 | furnished to do so, subject to the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be included in all 12 | copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 | SOFTWARE. 21 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # React Native A11y Order 2 | 3 | React Native A11y Order Library: Advanced control of screen reader order. 4 | 5 | Setting the right reading order can be a challenge, but there is a way to do it. The react-native-a11y-order is a native-first library designed to solve problems with the ordering of screen readers on both Android and iOS platforms. 6 | 7 | ## Breaking Changes !!! 8 | > The `A11yModule` and hooks `useFocusOrder`, `useDynamicFocusOrder`, and `useA11yOrderManager` have been removed. This API was deprecated and did not work properly with the new architecture. You can refer to the migration guide to update it. 9 | 10 | 11 | | iOS reader | Android reader | 12 | | --------------------------------------------------------- | ------------------------------------------------------------- | 13 | | | | 14 | 15 | - Bridgeless 16 | - New architecture 17 | - Backward compatibility 18 | 19 | ## Installation 20 | 21 | ```sh 22 | npm install react-native-a11y-order 23 | ``` 24 | 25 | ```sh 26 | yarn add react-native-a11y-order 27 | ``` 28 | 29 | ## Usage 30 | 31 | #### A11y.Order, A11y.Index 32 | 33 | There is always a question about how to set the focus order for a screen reader in React Native. `A11y.Order` and `A11y.Index` are designed to assist with this task. `A11y.Order` is a container component that defines an ordering group, while `A11y.Index` is a wrapper component that helps define a position within the order. 34 | 35 | To illustrate, let's look at an example: 36 | 37 | ```js 38 | import { A11y } from 'react-native-a11y-order'; 39 | 40 | // ... 41 | 42 | export default function App() { 43 | return ( 44 | 45 | 46 | 47 | 48 | First 49 | 50 | 51 | 52 | 53 | Third 54 | 55 | 56 | 57 | 58 | Second 59 | 60 | 61 | 62 | Fourth 63 | Fifth 64 | Sixth 65 | 66 | ); 67 | } 68 | ``` 69 | 70 | Additionally, for dynamic interaction scenarios, setting focus programmatically can be very useful. This can be achieved using the focus command via a component ref. 71 | 72 | ```js 73 | import { A11y, IndexCommands } from 'react-native-a11y-order'; 74 | 75 | // ... 76 | 77 | export default function App() { 78 | const ref = React.useRef(null); 79 | 80 | return ( 81 | 82 | 83 | 84 | 85 | First 86 | 87 | 88 | 89 |