├── .changeset ├── README.md └── config.json ├── .editorconfig ├── .eslintrc.js ├── .gitattributes ├── .github ├── FUNDING.yml ├── ISSUE_TEMPLATE │ ├── config.yml │ ├── custom.yaml │ ├── feature_request.yaml │ └── question.yaml └── workflows │ ├── android.yml │ ├── deploy-docs.yml │ ├── ios.yml │ ├── nodejs.yml │ └── support.yml ├── .gitignore ├── .prettierignore ├── .prettierrc.js ├── .yarn └── releases │ └── yarn-4.6.0.cjs ├── .yarnrc.yml ├── LICENSE.md ├── README.md ├── babel.config.js ├── docs ├── .gitignore ├── README.md ├── babel.config.js ├── blog │ ├── 2021-08-01-mdx-blog-post.mdx │ └── authors.yml ├── docs │ ├── doc-picker-api │ │ ├── index.md │ │ └── typedoc-sidebar.cjs │ ├── doc-viewer-api │ │ ├── index.md │ │ └── typedoc-sidebar.cjs │ ├── install.mdx │ └── sponsor-only │ │ ├── errors.md │ │ ├── intro.md │ │ ├── jest-mocks.md │ │ ├── license.md │ │ ├── migration.md │ │ ├── other-libs.md │ │ ├── picker │ │ ├── _category_.json │ │ ├── _optionalFieldsNote.mdx │ │ ├── _pickResultTable.mdx │ │ ├── _releasing.mdx │ │ ├── directory-picker.mdx │ │ ├── import-mode.mdx │ │ ├── integrating-on-android.mdx │ │ ├── keeping-local-copy.mdx │ │ ├── limiting-selectable-files.md │ │ ├── open-mode.mdx │ │ ├── save-as-dialog.mdx │ │ └── virtual-files.md │ │ └── viewer.mdx ├── docusaurus.config.ts ├── package.json ├── sidebars.ts ├── src │ ├── components │ │ └── HomepageFeatures │ │ │ ├── index.tsx │ │ │ └── styles.module.css │ ├── css │ │ └── custom.css │ └── pages │ │ ├── index.module.css │ │ └── index.tsx ├── static │ ├── .nojekyll │ └── img │ │ ├── android_screenshot.jpg │ │ ├── favicon-16x16.png │ │ ├── favicon-32x32.png │ │ ├── favicon.ico │ │ ├── ios_screenshot.jpeg │ │ ├── logo.png │ │ ├── modes │ │ ├── import-pdf.jpg │ │ ├── import-unrestricted.jpg │ │ ├── open-pdf.jpg │ │ └── open-unrestricted.jpg │ │ ├── save-as-android.png │ │ ├── save-as-ios.png │ │ ├── undraw_docusaurus_mountain.svg │ │ ├── undraw_docusaurus_react.svg │ │ └── undraw_docusaurus_tree.svg ├── tsconfig.json └── yarn.lock ├── jest.config.ts ├── lefthook.yml ├── package.json ├── packages ├── document-picker │ ├── CHANGELOG.md │ ├── LICENSE.md │ ├── android │ │ ├── build.gradle │ │ └── src │ │ │ ├── main │ │ │ ├── AndroidManifest.xml │ │ │ └── java │ │ │ │ └── com │ │ │ │ └── reactnativedocumentpicker │ │ │ │ ├── CopyDestination.kt │ │ │ │ ├── DocumentMetadataBuilder.kt │ │ │ │ ├── FileOperations.kt │ │ │ │ ├── IntentFactory.kt │ │ │ │ ├── IsKnownTypeImpl.kt │ │ │ │ ├── MetadataGetter.kt │ │ │ │ ├── PickOptions.kt │ │ │ │ ├── PromiseWrapper.java │ │ │ │ ├── RNDocumentPickerModule.kt │ │ │ │ └── RNDocumentPickerPackage.java │ │ │ └── paper │ │ │ └── java │ │ │ └── com │ │ │ └── reactnativedocumentpicker │ │ │ └── NativeDocumentPickerSpec.java │ ├── ios │ │ ├── RCTConvert+RNDocumentPicker.h │ │ ├── RCTConvert+RNDocumentPicker.mm │ │ ├── RNDocumentPicker.h │ │ ├── RNDocumentPicker.mm │ │ └── swift │ │ │ ├── DocPicker.swift │ │ │ ├── DocSaver.swift │ │ │ ├── DocumentMetadataBuilder.swift │ │ │ ├── FileOperations.swift │ │ │ ├── IsKnownTypeImpl.swift │ │ │ ├── LocalCopyResponse.swift │ │ │ ├── PickerBase.swift │ │ │ ├── PickerOptions.swift │ │ │ ├── PromiseSupport.swift │ │ │ ├── PromiseWrapper.swift │ │ │ └── SaverOptions.swift │ ├── jest │ │ ├── setup.ts │ │ └── tsconfig.json │ ├── package.json │ ├── react-native-document-picker.podspec │ ├── src │ │ ├── __tests__ │ │ │ ├── __snapshots__ │ │ │ │ └── index.test.ts.snap │ │ │ └── index.test.ts │ │ ├── errors.ts │ │ ├── fileTypes.ts │ │ ├── index.ts │ │ ├── isKnownType.ts │ │ ├── keepLocalCopy.ts │ │ ├── pick.ts │ │ ├── pickDirectory.ts │ │ ├── release.ts │ │ ├── saveDocuments.ts │ │ ├── spec │ │ │ └── NativeDocumentPicker.ts │ │ ├── types.ts │ │ └── validateTypes.ts │ └── tsconfig.build.json ├── document-viewer │ ├── CHANGELOG.md │ ├── LICENSE.md │ ├── android │ │ ├── build.gradle │ │ └── src │ │ │ ├── main │ │ │ ├── AndroidManifest.xml │ │ │ ├── java │ │ │ │ └── com │ │ │ │ │ └── reactnativedocumentviewer │ │ │ │ │ ├── RNDocumentViewerModule.kt │ │ │ │ │ └── RNDocumentViewerPackage.java │ │ │ └── res │ │ │ │ └── xml │ │ │ │ └── file_paths.xml │ │ │ └── paper │ │ │ └── java │ │ │ └── com │ │ │ └── reactnativedocumentviewer │ │ │ └── NativeDocumentViewerSpec.java │ ├── ios │ │ ├── RNDPreviewController.h │ │ ├── RNDPreviewController.mm │ │ ├── RNDPreviewItem.h │ │ ├── RNDPreviewItem.mm │ │ ├── RNDocumentViewer.h │ │ └── RNDocumentViewer.mm │ ├── jest │ │ ├── setup.ts │ │ └── tsconfig.json │ ├── package.json │ ├── react-native-document-viewer.podspec │ ├── src │ │ ├── errors.ts │ │ ├── index.ts │ │ └── spec │ │ │ └── NativeDocumentViewer.ts │ └── tsconfig.build.json └── example │ ├── .gitignore │ ├── .watchmanconfig │ ├── android │ ├── build.gradle │ ├── gradle.properties │ ├── gradle │ │ └── wrapper │ │ │ ├── gradle-wrapper.jar │ │ │ └── gradle-wrapper.properties │ ├── gradlew │ ├── gradlew.bat │ └── settings.gradle │ ├── app.json │ ├── babel.config.js │ ├── debug.keystore │ ├── index.js │ ├── ios │ ├── Podfile │ └── Podfile.lock │ ├── metro.config.js │ ├── package.json │ ├── react-native.config.js │ ├── src │ ├── ImportExamples.tsx │ ├── OpenExamples.tsx │ ├── SaveAsExamples.tsx │ ├── Utils.tsx │ └── components │ │ ├── Box.tsx │ │ ├── SegmentedControl.ts │ │ └── SelectableText.tsx │ ├── test │ ├── .eslintrc.js │ ├── fileFactory │ │ ├── sampleDocx.ts │ │ ├── sampleFileFactory.ts │ │ ├── sampleMp4.ts │ │ ├── samplePdf.ts │ │ └── samplePng.ts │ ├── pageobjects │ │ ├── import.page.ts │ │ ├── intro.page.ts │ │ ├── nativePickerPage.ts │ │ ├── nativeViewerPage.ts │ │ ├── open.page.ts │ │ └── page.ts │ ├── specs │ │ ├── importTest.e2e.ts │ │ └── openTest.e2e.ts │ └── utils.ts │ └── tsconfig.json ├── tsconfig.build.json ├── tsconfig.json └── yarn.lock /.changeset/README.md: -------------------------------------------------------------------------------- 1 | # Changesets 2 | 3 | Hello and welcome! This folder has been automatically generated by `@changesets/cli`, a build tool that works 4 | with multi-package repos, or single-package repos to help you version and publish your code. You can 5 | find the full documentation for it [in our repository](https://github.com/changesets/changesets) 6 | 7 | We have a quick list of common questions to get you started engaging with this project in 8 | [our documentation](https://github.com/changesets/changesets/blob/main/docs/common-questions.md) 9 | -------------------------------------------------------------------------------- /.changeset/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://unpkg.com/@changesets/config@3.0.5/schema.json", 3 | "changelog": "@changesets/cli/changelog", 4 | "commit": false, 5 | "fixed": [], 6 | "linked": [], 7 | "access": "public", 8 | "baseBranch": "main", 9 | "updateInternalDependencies": "patch", 10 | "ignore": [] 11 | } 12 | -------------------------------------------------------------------------------- /.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 | -------------------------------------------------------------------------------- /.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | root: true, 3 | extends: ['@react-native', 'plugin:prettier/recommended', 'plugin:jest/recommended'], 4 | rules: { 5 | // flags jest.config.ts as a problem 6 | 'jest/no-jest-import': 'off', 7 | }, 8 | ignorePatterns: ['**/lib/*', 'node_modules/*', '**/build/*'], 9 | } 10 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | *.pbxproj -text 2 | # specific for windows script files 3 | *.bat text eol=crlf 4 | 5 | # https://stackoverflow.com/a/51564689/2070942 to avoid git grep result 6 | .yarn/**/*.* binary 7 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | github: [vonovak] -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/config.yml: -------------------------------------------------------------------------------- 1 | blank_issues_enabled: false 2 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/custom.yaml: -------------------------------------------------------------------------------- 1 | name: "\U0001F41B Bug Report" 2 | description: 'Report a bug' 3 | body: 4 | - type: markdown 5 | attributes: 6 | value: Thanks for taking the time to file a bug report! Please fill out this entire form. 7 | - type: checkboxes 8 | attributes: 9 | label: I have searched open and closed issues for this issue. 10 | options: 11 | - label: I have searched open and closed issues. 12 | required: true 13 | - type: checkboxes 14 | attributes: 15 | label: I have read and understood the license (link below). 16 | options: 17 | - label: I have read and understood the [license](https://github.com/react-native-documents/document-picker/blob/main/LICENSE.md). 18 | required: true 19 | - type: input 20 | attributes: 21 | label: Minimal reproducible example 22 | description: | 23 | A link to a GitHub repository containing a minimal reproducible example. This repository should include as little code as possible and not include extraneous dependencies. 24 | 25 | Try to reproduce the bugs on the provided example app. Either provide a link to the repo that reproduces the bug or provide your version of the `App.tsx` file that reproduces the issue and that we can easily use. 26 | 27 | If a reproducible example is not provided, your issue is likely to be closed. 28 | [Learn more about creating a minimal reproducible example](https://stackoverflow.com/help/mcve). 29 | validations: 30 | required: true 31 | - type: dropdown 32 | attributes: 33 | label: What platform(s) does this occur on? 34 | multiple: true 35 | options: 36 | - Android 37 | - iOS 38 | validations: 39 | required: true 40 | - type: dropdown 41 | attributes: 42 | label: Did you reproduce on a real device or emulator / simulator? 43 | multiple: false 44 | options: 45 | - Select an option 46 | - real device 47 | - emulator / simulator 48 | validations: 49 | required: true 50 | - type: textarea 51 | attributes: 52 | label: Steps to reproduce 53 | description: | 54 | Explain the steps we need to take to reproduce the issue. Include a video or screenshots if you think it may help. 55 | Clearly describe what the expected behavior is and what instead is actually happening. Be concise and precise in your description. 56 | validations: 57 | required: true 58 | - type: checkboxes 59 | attributes: 60 | label: If the issue is related to specific file(s), I have linked the files so that others can reproduce exactly what I see. 61 | options: 62 | - label: I have attached files necessary to reproduce the problem (if applicable). 63 | required: true 64 | - type: textarea 65 | attributes: 66 | label: Stacktrace of the crash (if applicable) 67 | description: | 68 | Give the stacktrace of the crash, or explain the error message you are seeing. 69 | validations: 70 | required: true 71 | - type: textarea 72 | attributes: 73 | render: text 74 | label: Your computer environment 75 | description: Run the `npx react-native info` command and paste its output in the field below. 76 | validations: 77 | required: true 78 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.yaml: -------------------------------------------------------------------------------- 1 | name: "Feature request template" 2 | description: 'Request a feature' 3 | body: 4 | - type: markdown 5 | attributes: 6 | value: Thanks for taking the time to file a feature request! Please fill out this form. 7 | - type: textarea 8 | attributes: 9 | label: Feature description 10 | description: | 11 | Please describe what feature you think is missing and link to the documentation of the underlying operating system APIs which cover the functionality. 12 | 13 | Thank you! 14 | validations: 15 | required: true 16 | - type: dropdown 17 | attributes: 18 | label: What platform(s) should this be implemented on? 19 | multiple: true 20 | options: 21 | - Android 22 | - iOS 23 | - web 24 | validations: 25 | required: true 26 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/question.yaml: -------------------------------------------------------------------------------- 1 | name: "Question template" 2 | description: 'Ask a question' 3 | labels: ['question'] 4 | body: 5 | - type: markdown 6 | attributes: 7 | value: Please use the [GH discussions](https://github.com/react-native-google-signin/google-signin/discussions) for questions. Thank you! 8 | - type: dropdown 9 | attributes: 10 | label: I will post my question to GH discussions. 11 | options: 12 | - 'Yes' 13 | validations: 14 | required: true 15 | -------------------------------------------------------------------------------- /.github/workflows/android.yml: -------------------------------------------------------------------------------- 1 | name: Android build 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | paths: 8 | - '.github/workflows/android.yml' 9 | - 'packages/**/android**' 10 | pull_request: 11 | paths: 12 | - '.github/workflows/android.yml' 13 | - 'packages/**/android/**' 14 | 15 | jobs: 16 | android-build: 17 | runs-on: ubuntu-latest 18 | steps: 19 | - uses: actions/checkout@v4 20 | - name: Use Node.js lts 21 | uses: actions/setup-node@v4 22 | with: 23 | node-version: lts/* 24 | - uses: actions/setup-java@v4 25 | with: 26 | distribution: 'temurin' 27 | java-version: '17' 28 | - name: Install dependencies 29 | run: yarn install --immutable 30 | - name: Build android example app on old architecture 31 | run: ./gradlew app:assembleDebug -PnewArchEnabled=false 32 | working-directory: packages/example/android 33 | android-build-new-arch: 34 | runs-on: ubuntu-latest 35 | steps: 36 | - uses: actions/checkout@v3 37 | - name: Use Node.js lts 38 | uses: actions/setup-node@v4 39 | with: 40 | node-version: lts/* 41 | - uses: actions/setup-java@v4 42 | with: 43 | distribution: 'temurin' 44 | java-version: '17' 45 | - name: Install dependencies 46 | run: yarn install --immutable 47 | - name: Build android example app on new architecture 48 | run: ./gradlew app:assembleDebug -PnewArchEnabled=true 49 | working-directory: packages/example/android 50 | -------------------------------------------------------------------------------- /.github/workflows/deploy-docs.yml: -------------------------------------------------------------------------------- 1 | name: Deploy to GitHub Pages 2 | 3 | on: 4 | push: 5 | branches: [main] 6 | paths: 7 | - 'docs/**' 8 | pull_request: 9 | branches: [main] 10 | paths: 11 | - 'docs/**' 12 | 13 | permissions: 14 | contents: write 15 | 16 | defaults: 17 | run: 18 | working-directory: ./docs 19 | 20 | jobs: 21 | test-docusaurus-build: 22 | if: github.event_name != 'push' 23 | runs-on: ubuntu-latest 24 | steps: 25 | - uses: actions/checkout@v4 26 | with: 27 | fetch-depth: 0 28 | - uses: actions/setup-node@v4 29 | with: 30 | node-version: lts/* 31 | cache: yarn 32 | - name: Install dependencies and build website 33 | run: | 34 | yarn install --immutable 35 | yarn build 36 | deploy: 37 | if: github.event_name != 'pull_request' 38 | runs-on: ubuntu-latest 39 | steps: 40 | - uses: actions/checkout@v4 41 | with: 42 | fetch-depth: 0 43 | - uses: actions/setup-node@v4 44 | with: 45 | node-version: lts/* 46 | cache: yarn 47 | - uses: webfactory/ssh-agent@v0.5.0 48 | with: 49 | ssh-private-key: ${{ secrets.ACTIONS_DEPLOY_KEY }} 50 | - name: Deploy to GitHub Pages 51 | env: 52 | USE_SSH: true 53 | run: | 54 | git config --global user.email "vonovak@gmail.com" 55 | git config --global user.name "Vojtech Novak" 56 | yarn install --immutable 57 | yarn deploy 58 | -------------------------------------------------------------------------------- /.github/workflows/ios.yml: -------------------------------------------------------------------------------- 1 | name: iOS build 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | paths: 8 | - '.github/workflows/ios.yml' 9 | - 'packages/**/ios**' 10 | - 'packages/**/*.podspec' 11 | pull_request: 12 | paths: 13 | - '.github/workflows/ios.yml' 14 | - 'packages/**/ios**' 15 | - 'packages/**/*.podspec' 16 | 17 | jobs: 18 | ios-build: 19 | runs-on: macos-latest 20 | steps: 21 | - uses: actions/checkout@v4 22 | - name: Use Node.js lts 23 | uses: actions/setup-node@v4 24 | with: 25 | node-version: lts/* 26 | - uses: ruby/setup-ruby@v1 27 | with: 28 | ruby-version: 2.7 29 | working-directory: packages/example/ios 30 | bundler-cache: true 31 | - name: Install dependencies 32 | run: yarn install --immutable 33 | - name: Install pods 34 | run: RCT_NEW_ARCH_ENABLED=0 npx pod-install 35 | working-directory: packages/example/ios 36 | - name: Build ios example app on old architecture 37 | run: xcodebuild -scheme ReactTestApp -workspace document-picker-example.xcworkspace ONLY_ACTIVE_ARCH=NO -sdk iphonesimulator -configuration Debug 38 | working-directory: packages/example/ios 39 | ios-build-new-arch: 40 | runs-on: macos-latest 41 | steps: 42 | - uses: actions/checkout@v4 43 | - name: Use Node.js lts 44 | uses: actions/setup-node@v4 45 | with: 46 | node-version: lts/* 47 | - uses: ruby/setup-ruby@v1 48 | with: 49 | ruby-version: 2.7 50 | working-directory: packages/example/ios 51 | bundler-cache: true 52 | - name: Install dependencies 53 | run: yarn install --immutable 54 | - name: Install pods for new arch 55 | run: RCT_NEW_ARCH_ENABLED=1 npx pod-install 56 | working-directory: packages/example/ios 57 | - name: Build ios example app on new architecture 58 | run: xcodebuild -scheme ReactTestApp -workspace document-picker-example.xcworkspace ONLY_ACTIVE_ARCH=NO -sdk iphonesimulator -configuration Debug 59 | working-directory: packages/example/ios 60 | -------------------------------------------------------------------------------- /.github/workflows/nodejs.yml: -------------------------------------------------------------------------------- 1 | # This workflow will run tests using node and then publish a package to GitHub Packages when a release is created 2 | # For more information see: https://help.github.com/actions/language-and-framework-guides/publishing-nodejs-packages 3 | 4 | name: test and publish 5 | 6 | on: 7 | push: 8 | branches: [master, main] 9 | pull_request: 10 | 11 | # Allows you to run this workflow manually from the Actions tab 12 | workflow_dispatch: 13 | 14 | jobs: 15 | build: 16 | runs-on: ubuntu-latest 17 | steps: 18 | - uses: actions/checkout@v4 19 | - uses: actions/setup-node@v4 20 | with: 21 | node-version: lts/* 22 | - run: yarn install --immutable 23 | - run: yarn typescript 24 | - run: yarn prettier:check 25 | - run: yarn lint 26 | - run: yarn test 27 | - run: yarn build 28 | 29 | publish-npm: 30 | needs: build 31 | if: github.ref == 'refs/heads/master' || github.ref == 'refs/heads/main' 32 | runs-on: ubuntu-latest 33 | steps: 34 | - name: Checkout 35 | uses: actions/checkout@v4 36 | with: 37 | fetch-depth: 0 # fetch all history 38 | - name: Setup Node.js 39 | uses: actions/setup-node@v4 40 | with: 41 | node-version: lts/* 42 | cache: 'yarn' 43 | - name: Install Dependencies 44 | run: yarn install --immutable 45 | 46 | - name: Create Release Pull Request or Publish 47 | id: changesets 48 | uses: changesets/action@v1 49 | with: 50 | publish: yarn run release-packages 51 | env: 52 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 53 | NPM_TOKEN: ${{ secrets.NPM_TOKEN_NEW }} 54 | -------------------------------------------------------------------------------- /.github/workflows/support.yml: -------------------------------------------------------------------------------- 1 | name: 'Support requests' 2 | 3 | on: 4 | issues: 5 | types: [labeled, unlabeled, reopened] 6 | 7 | jobs: 8 | support: 9 | runs-on: ubuntu-latest 10 | steps: 11 | - uses: dessant/support-requests@v4 12 | with: 13 | github-token: ${{ github.token }} 14 | support-label: 'repro-required' 15 | issue-comment: > 16 | :wave: @{issue-author}, sorry you're having an issue. As the issue template explains, it's required that you provide a runnable example that reproduces your issue (see the [issue template](../blob/main/.github/ISSUE_TEMPLATE/custom.yaml)). 17 | 18 | The reason is that a bug report is not actionable without a reproducer. Try to minimize the superfluous code and focus only on reproducing the bug. 19 | 20 | Please create a new issue with this and the maintainer will do his best to review it!. 21 | close-issue: true 22 | lock-issue: true 23 | - uses: dessant/support-requests@v4 24 | with: 25 | github-token: ${{ github.token }} 26 | support-label: 'question' 27 | issue-comment: > 28 | :wave: @{issue-author}, please post your question to [discussions](https://github.com/react-native-documents/document-picker/discussions) instead. 29 | close-issue: true 30 | lock-issue: true 31 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # OSX 2 | # 3 | .DS_Store 4 | 5 | # XDE 6 | .expo/ 7 | 8 | # VSCode 9 | .vscode/ 10 | jsconfig.json 11 | 12 | # Xcode 13 | # 14 | build/ 15 | *.pbxuser 16 | !default.pbxuser 17 | *.mode1v3 18 | !default.mode1v3 19 | *.mode2v3 20 | !default.mode2v3 21 | *.perspectivev3 22 | !default.perspectivev3 23 | xcuserdata 24 | *.xccheckout 25 | *.moved-aside 26 | DerivedData 27 | *.hmap 28 | *.ipa 29 | *.xcuserstate 30 | project.xcworkspace 31 | 32 | # Android/IJ 33 | # 34 | .idea 35 | .gradle 36 | local.properties 37 | android.iml 38 | 39 | # Cocoapods 40 | # 41 | example/ios/Pods 42 | 43 | # node.js 44 | # 45 | node_modules/ 46 | npm-debug.log 47 | yarn-debug.log 48 | yarn-error.log 49 | 50 | # BUCK 51 | buck-out/ 52 | \.buckd/ 53 | android/app/libs 54 | android/keystores/debug.keystore 55 | 56 | # Expo 57 | .expo/* 58 | 59 | # generated by bob 60 | lib/ 61 | 62 | # https://github.com/yarnpkg/berry/issues/454#issuecomment-530312089 63 | .yarn/* 64 | !.yarn/releases 65 | !.yarn/plugins 66 | 67 | -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | # Ignore artifacts: 2 | **/build 3 | **/dist 4 | **/coverage 5 | **/.next 6 | **/.vscode 7 | **/.expo 8 | **/ios 9 | **/android 10 | docs/.docusaurus 11 | 12 | # usually fails bcs prettier likes to have empty lines at the end of files 13 | # TODO? might need to add prettier:write to release-packages to format changelog files 14 | .changeset 15 | 16 | # these are auto-generated 17 | docs/docs/doc-picker-api/index.md 18 | docs/docs/doc-viewer-api/index.md 19 | -------------------------------------------------------------------------------- /.prettierrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | printWidth: 100, 3 | singleQuote: true, 4 | trailingComma: 'all', 5 | quoteProps: 'consistent', 6 | useTabs: false, 7 | semi: false, 8 | } 9 | -------------------------------------------------------------------------------- /.yarnrc.yml: -------------------------------------------------------------------------------- 1 | nodeLinker: node-modules 2 | 3 | yarnPath: .yarn/releases/yarn-4.6.0.cjs 4 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2025 Vojtech Novak 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # react-native-documents 2 | 3 | React Native modules for document picking and viewing. 4 | 5 | If this is useful to you, [say thanks](https://github.com/sponsors/vonovak). Your support is greatly appreciated! 6 | 7 | Read the docs at https://react-native-documents.github.io 8 | 9 | Ask questions and engage in discussions at https://github.com/react-native-documents/document-picker/discussions 10 | -------------------------------------------------------------------------------- /babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: ['module:@react-native/babel-preset'], 3 | } 4 | -------------------------------------------------------------------------------- /docs/.gitignore: -------------------------------------------------------------------------------- 1 | # Dependencies 2 | /node_modules 3 | 4 | # Production 5 | /build 6 | 7 | # Generated files 8 | .docusaurus 9 | .cache-loader 10 | 11 | # Misc 12 | .DS_Store 13 | .env.local 14 | .env.development.local 15 | .env.test.local 16 | .env.production.local 17 | 18 | npm-debug.log* 19 | yarn-debug.log* 20 | yarn-error.log* 21 | 22 | # https://github.com/yarnpkg/berry/issues/454#issuecomment-530312089 23 | .yarn/* 24 | !.yarn/releases 25 | !.yarn/plugins 26 | -------------------------------------------------------------------------------- /docs/README.md: -------------------------------------------------------------------------------- 1 | # Website 2 | 3 | This website is built using [Docusaurus 3](https://docusaurus.io/), a modern static website generator. 4 | 5 | ### Installation 6 | 7 | ``` 8 | $ yarn 9 | ``` 10 | 11 | ### Local Development 12 | 13 | ``` 14 | $ yarn start 15 | ``` 16 | 17 | This command starts a local development server and opens up a browser window. Most changes are reflected live without having to restart the server. 18 | 19 | ### Build 20 | 21 | ``` 22 | $ yarn build 23 | ``` 24 | 25 | This command generates static content into the `build` directory and can be served using any static contents hosting service. 26 | 27 | ### Deployment 28 | 29 | Using SSH: 30 | 31 | ``` 32 | $ USE_SSH=true yarn deploy 33 | ``` 34 | 35 | Not using SSH: 36 | 37 | ``` 38 | $ GIT_USER= yarn deploy 39 | ``` 40 | 41 | If you are using GitHub pages for hosting, this command is a convenient way to build the website and push to the `gh-pages` branch. 42 | 43 | ## TODO 44 | 45 | links to put somewhere: 46 | 47 | https://developer.android.com/guide/topics/providers/document-provider#addt-resources 48 | 49 | https://developer.android.com/guide/components/intents-common#Storage 50 | -------------------------------------------------------------------------------- /docs/babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: [require.resolve('@docusaurus/core/lib/babel/preset')], 3 | } 4 | -------------------------------------------------------------------------------- /docs/blog/2021-08-01-mdx-blog-post.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | slug: mdx-blog-post 3 | title: MDX Blog Post 4 | authors: [vonovak] 5 | tags: [docusaurus] 6 | --- 7 | 8 | We're live! :) 9 | -------------------------------------------------------------------------------- /docs/blog/authors.yml: -------------------------------------------------------------------------------- 1 | vonovak: 2 | name: Vojtech Novak 3 | title: maintainer 4 | url: https://twitter.com/vonovak 5 | image_url: https://pbs.twimg.com/profile_images/1012246067809804289/U-wW3ryc_400x400.jpg 6 | -------------------------------------------------------------------------------- /docs/docs/doc-picker-api/typedoc-sidebar.cjs: -------------------------------------------------------------------------------- 1 | // @ts-check 2 | /** @type {import('@docusaurus/plugin-content-docs').SidebarsConfig} */ 3 | const typedocSidebar = { items: []}; 4 | module.exports = typedocSidebar.items; -------------------------------------------------------------------------------- /docs/docs/doc-viewer-api/index.md: -------------------------------------------------------------------------------- 1 | # document-viewer API 2 | 3 | ## Type Aliases 4 | 5 | ### BaseOptions 6 | 7 | > **BaseOptions**: \{`grantPermissions`: `"read"` \| `"write"`;`headerTitle`: `string`;`mimeType`: `string`;`presentationStyle`: [`PresentationStyle`](index.md#presentationstyle); \} 8 | 9 | #### Type declaration 10 | 11 | | Name | Type | Description | 12 | | ------ | ------ | ------ | 13 | | `grantPermissions`? | `"read"` \| `"write"` | Android only: The type of permission to grant to the receiving app that will open the document. This only has effect if you're viewing a file that lives in the app's sandboxed storage. | 14 | | `headerTitle`? | `string` | iOS only: The title to display in the header of the document viewer. If not provided, the filename will be used. | 15 | | `mimeType`? | `string` | Optional, but recommended: the mimetype of the document. This will help the Android OS to find the right app(s) to open the document. | 16 | | `presentationStyle`? | [`PresentationStyle`](index.md#presentationstyle) | iOS only - Controls how the picker is presented, e.g. on an iPad you may want to present it fullscreen. Defaults to `pageSheet`. | 17 | 18 | *** 19 | 20 | ### OptionsViewBookmark 21 | 22 | > **OptionsViewBookmark**: [`BaseOptions`](index.md#baseoptions) & \{`bookmark`: `string`; \} 23 | 24 | BaseOptions with the bookmark data from the DocumentPicker module. Obtain the bookmark using the "open" mode, with `requestLongTermAccess` flag set to true. 25 | 26 | A bookmark enables long-term access to a file. 27 | 28 | #### Type declaration 29 | 30 | | Name | Type | Description | 31 | | ------ | ------ | ------ | 32 | | `bookmark` | `string` | bookmark data from the DocumentPicker module. Obtain it using the "open" mode, with `requestLongTermAccess` flag set to true. A bookmark allows a long-term permission to access a file. | 33 | 34 | *** 35 | 36 | ### OptionsViewUri 37 | 38 | > **OptionsViewUri**: [`BaseOptions`](index.md#baseoptions) & \{`uri`: `string`; \} 39 | 40 | BaseOptions with the uri of the document to view 41 | 42 | #### Type declaration 43 | 44 | | Name | Type | Description | 45 | | ------ | ------ | ------ | 46 | | `uri` | `string` | The uri of the document to view | 47 | 48 | *** 49 | 50 | ### PresentationStyle 51 | 52 | > **PresentationStyle**: `"fullScreen"` \| `"pageSheet"` \| `"formSheet"` \| `"overFullScreen"` \| `undefined` 53 | 54 | iOS only. Configure the presentation style of the picker. 55 | 56 | *** 57 | 58 | ### ViewDocumentOptions 59 | 60 | > **ViewDocumentOptions**: [`OptionsViewBookmark`](index.md#optionsviewbookmark) \| [`OptionsViewUri`](index.md#optionsviewuri) 61 | 62 | options for viewing a document 63 | 64 | If you're trying to open a file that you have long-term permission to access, you should use the `bookmark` option (provided by the DocumentPicker module). 65 | 66 | ## Variables 67 | 68 | ### errorCodes 69 | 70 | > `const` **errorCodes**: `Readonly`\<\{`IN_PROGRESS`: `"ASYNC_OP_IN_PROGRESS"`;`OPERATION_CANCELED`: `"OPERATION_CANCELED"`;`UNABLE_TO_OPEN_FILE_TYPE`: `"UNABLE_TO_OPEN_FILE_TYPE"`; \}\> 71 | 72 | #### Type declaration 73 | 74 | | Name | Type | 75 | | ------ | ------ | 76 | | `IN_PROGRESS` | `"ASYNC_OP_IN_PROGRESS"` | 77 | | `OPERATION_CANCELED` | `"OPERATION_CANCELED"` | 78 | | `UNABLE_TO_OPEN_FILE_TYPE` | `"UNABLE_TO_OPEN_FILE_TYPE"` | 79 | 80 | ## Functions 81 | 82 | ### isErrorWithCode() 83 | 84 | > **isErrorWithCode**(`error`: `any`): `error is NativeModuleError` 85 | 86 | TypeScript helper to check if an object has the `code` property. 87 | This is used to avoid `as` casting when you access the `code` property on errors returned by the module. 88 | 89 | #### Parameters 90 | 91 | | Parameter | Type | 92 | | ------ | ------ | 93 | | `error` | `any` | 94 | 95 | #### Returns 96 | 97 | `error is NativeModuleError` 98 | 99 | *** 100 | 101 | ### viewDocument() 102 | 103 | > **viewDocument**(`data`: [`ViewDocumentOptions`](index.md#viewdocumentoptions)): `Promise`\<`null`\> 104 | 105 | #### Parameters 106 | 107 | | Parameter | Type | 108 | | ------ | ------ | 109 | | `data` | [`ViewDocumentOptions`](index.md#viewdocumentoptions) | 110 | 111 | #### Returns 112 | 113 | `Promise`\<`null`\> 114 | -------------------------------------------------------------------------------- /docs/docs/doc-viewer-api/typedoc-sidebar.cjs: -------------------------------------------------------------------------------- 1 | // @ts-check 2 | /** @type {import('@docusaurus/plugin-content-docs').SidebarsConfig} */ 3 | const typedocSidebar = { items: []}; 4 | module.exports = typedocSidebar.items; -------------------------------------------------------------------------------- /docs/docs/install.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 1 3 | sidebar_label: Installation & Setup 4 | --- 5 | 6 | # Installation 7 | 8 | Depending on what module you need, install one or both of the packages: 9 | 10 | ```bash 11 | yarn add @react-native-documents/picker 12 | ``` 13 | 14 | ```bash 15 | yarn add @react-native-documents/viewer 16 | ``` 17 | 18 | ## Setting up 19 | 20 | The packages are designed to support last 3 stable versions of RN. However, they very likely work with RN 0.73 and up. 21 | 22 | :::warning 23 | The document picker package requires iOS 14 or later. If you use Expo, use Expo SDK >=52 or [Expo build properties](https://docs.expo.dev/versions/latest/sdk/build-properties/#example-appjson-with-config-plugin) to update the `deploymentTarget` to `14`. 24 | 25 | In regular React Native projects, use RN >= 0.76 or update the [settings in Xcode](https://stackoverflow.com/a/66798215/2070942). 26 | ::: 27 | 28 | ### Expo 29 | 30 | :::info 31 | 32 | These packages cannot be used in ["Expo Go"](https://docs.expo.dev/workflow/overview/#expo-go-an-optional-tool-for-learning) because they include custom native code. 33 | 34 | However, you can add custom native code to an Expo app through a [development build](https://docs.expo.dev/workflow/overview/#development-builds). That is the officially recommended approach for building Expo apps. See the commands below to do this. 35 | 36 | ::: 37 | 38 | ```bash 39 | # install the package first 40 | 41 | # Build the app locally 42 | expo prebuild --clean 43 | expo run:ios 44 | expo run:android 45 | ``` 46 | 47 | ### React Native 48 | 49 | Install the package and then run `pod install` from the ios directory. Then rebuild your project with Xcode. 50 | 51 | If you're using the [New Architecture](https://reactnative.dev/docs/new-architecture-intro), it's strongly recommended to use the latest stable release of RN. 52 | -------------------------------------------------------------------------------- /docs/docs/sponsor-only/jest-mocks.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 50 3 | --- 4 | 5 | # Jest module mocks 6 | 7 | You will need to mock the functionality of the native modules once you require them from your test files - otherwise you'll get [this error](https://github.com/rnmods/react-native-document-picker/issues/702). 8 | 9 | The packages provide Jest mocks that you can add to the [`setupFiles`](https://jestjs.io/docs/configuration#setupfiles-array) array in the Jest config. 10 | 11 | By default, the mocks behave as if the calls were successful and return mock document data. 12 | 13 | ```json title="jest.config" 14 | { 15 | "setupFiles": [ 16 | "./node_modules/@react-native-documents/picker/jest/build/jest/setup.js", 17 | "./node_modules/@react-native-documents/viewer/jest/build/jest/setup.js" 18 | ] 19 | } 20 | ``` 21 | -------------------------------------------------------------------------------- /docs/docs/sponsor-only/license.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 80 3 | sidebar_label: License 4 | --- 5 | 6 | # License 7 | 8 | The module is licensed under MIT, giving you the ability to use all of it for free in your projects, allowing modifications to your liking. 9 | -------------------------------------------------------------------------------- /docs/docs/sponsor-only/migration.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 2 3 | --- 4 | 5 | # Migrating from the old document-picker 6 | 7 | The new package has a new name (`@react-native-documents/picker`), so you need to update your import statements. 8 | 9 | ### Migrating your code 10 | 11 | Good news: You need to make only a few changes: 12 | 13 | 1. update import statements 14 | 15 | ```ts 16 | import { ... } from 'react-native-document-picker' 17 | ``` 18 | 19 | becomes 20 | 21 | ```ts 22 | import { ... } from '@react-native-documents/picker' 23 | ``` 24 | 25 | 2. remove `pickSingle` 26 | 27 | Replace `pickSingle` with `pick`: 28 | 29 | ```ts 30 | const result = await pickSingle(options) 31 | ``` 32 | 33 | becomes: 34 | 35 | ```ts 36 | const [result] = await pick(options) 37 | ``` 38 | 39 | 3. replace `copyTo` with [`keepLocalCopy`](picker/keeping-local-copy.mdx) 40 | 41 | > This change makes your app more responsive: previously you'd use the `copyTo` option and before the returned `Promise` resolved, you needed to wait not only for the user to pick the file, but also for the file to be copied to your app's directory. For large files or with slow network, this could be a problem that you, as a dev don't see, but your users do. 42 | 43 | ```ts 44 | const localCopy = await pick({ 45 | copyTo: 'documentDirectory', 46 | }) 47 | ``` 48 | 49 | becomes 50 | 51 | ```ts 52 | const [file] = await pick() 53 | 54 | const [localCopy] = await keepLocalCopy({ 55 | files: [ 56 | { 57 | uri: file.uri, 58 | fileName: file.name ?? 'fallbackName', 59 | }, 60 | ], 61 | destination: 'documentDirectory', 62 | }) 63 | ``` 64 | -------------------------------------------------------------------------------- /docs/docs/sponsor-only/other-libs.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 100 3 | sidebar_label: Other libraries 4 | --- 5 | 6 | # Other libraries 7 | 8 | This is a non-exhaustive list of other libraries which are authored / maintained by the author of this library. Maybe you'll find something useful :). 9 | 10 | ### [react-native-theme-control](https://github.com/vonovak/react-native-theme-control) 11 | 12 | Natively control react native application theme at runtime and persist it for the next app start. 13 | 14 | ### [react-navigation-header-buttons](https://github.com/vonovak/react-navigation-header-buttons) 15 | 16 | Easily render header buttons for react-navigation. 17 | 18 | ### [react-to-imperative](https://github.com/vonovak/react-to-imperative) 19 | 20 | Convert React (Native) components for imperative use. 21 | 22 | ### [react-native-datetimepicker](https://github.com/react-native-datetimepicker/datetimepicker) 23 | 24 | React Native date & time picker component for iOS and Android. 25 | 26 | ### [JS-lingui](https://github.com/lingui/js-lingui) 27 | 28 | A readable, automated, and optimized internationalization for JavaScript. 29 | 30 | ### [react-native-google-signin](https://react-native-google-signin.github.io/) 31 | 32 | Google Sign In for React Native. 33 | -------------------------------------------------------------------------------- /docs/docs/sponsor-only/picker/_category_.json: -------------------------------------------------------------------------------- 1 | { 2 | "label": "Document Picker", 3 | "position": 20, 4 | "collapsed": false, 5 | "link": { 6 | "type": "generated-index" 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /docs/docs/sponsor-only/picker/_optionalFieldsNote.mdx: -------------------------------------------------------------------------------- 1 | :::note 2 | Many of the fields are nullable because the file metadata might not be available in some cases. While it's unlikely, it can happen - especially on Android - if a user picks a file from a [Document Provider](https://developer.android.com/guide/topics/providers/create-document-provider) that doesn't make the information available. 3 | ::: 4 | -------------------------------------------------------------------------------- /docs/docs/sponsor-only/picker/_releasing.mdx: -------------------------------------------------------------------------------- 1 | ### Releasing Long Term Access 2 | 3 | This is an Android-only feature. When you no longer need access to the file or location, you should release the long-term access by calling `releaseLongTermAccess`. Calling this on iOS will resolve. 4 | 5 | See [Android documentation]() for more information. 6 | 7 | ### Releasing (stopping) Secure Access 8 | 9 | This is an iOS-only feature. When you no longer need access to the file or location, you should release the secure access by calling `releaseSecureAccess`. Calling this on Android will resolve. 10 | 11 | See [iOS documentation](https://developer.apple.com/documentation/foundation/nsurl/1413736-stopaccessingsecurityscopedresou) for more information. 12 | -------------------------------------------------------------------------------- /docs/docs/sponsor-only/picker/directory-picker.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 6 3 | --- 4 | 5 | # Directory picker 6 | 7 | This module allows you to pick a directory from the file system. The chosen directory can then be used for file I/O operations. 8 | 9 | When `requestLongTermAccess` is set to `true`, your app will be able to access the directory even after the app is restarted. 10 | 11 | If you've requested long-term access to a directory or file, the response object will contain [BookmarkingResponse](/docs/doc-picker-api#bookmarkingresponse). 12 | 13 | Please note there are some [security limitations](https://developer.android.com/training/data-storage/shared/documents-files#document-tree-access-restrictions). 14 | 15 | ```tsx title="Selecting a directory" 16 | import { pickDirectory } from '@react-native-documents/picker' 17 | 18 | return ( 19 |