├── .nvmrc ├── .gitattributes ├── tsconfig.build.json ├── assets └── demo.gif ├── .yarnrc.yml ├── example ├── tsconfig.json ├── babel.config.js ├── index.js ├── README.md ├── metro.config.js ├── app.json ├── package.json └── src │ └── App.tsx ├── babel.config.js ├── src ├── index.tsx ├── __tests__ │ └── index.test.tsx ├── types.tsx ├── createModalNavigator.tsx └── ModalView.tsx ├── .editorconfig ├── lefthook.yml ├── .github ├── PULL_REQUEST_TEMPLATE.md ├── workflows │ ├── versions.yml │ ├── expo.yml │ ├── expo-preview.yml │ ├── ci.yml │ ├── release.yml │ └── triage.yml ├── actions │ └── setup │ │ └── action.yml └── ISSUE_TEMPLATE │ └── bug_report.md ├── eslint.config.mjs ├── tsconfig.json ├── .gitignore ├── CHANGELOG.md ├── LICENSE ├── package.json ├── README.md └── CONTRIBUTING.md /.nvmrc: -------------------------------------------------------------------------------- 1 | v22.18.0 2 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | *.pbxproj -text 2 | # specific for windows script files 3 | *.bat text eol=crlf -------------------------------------------------------------------------------- /tsconfig.build.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig", 3 | "exclude": ["example"] 4 | } 5 | -------------------------------------------------------------------------------- /assets/demo.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/satya164/react-navigation-native-modal/HEAD/assets/demo.gif -------------------------------------------------------------------------------- /.yarnrc.yml: -------------------------------------------------------------------------------- 1 | nmHoistingLimits: workspaces 2 | 3 | nodeLinker: node-modules 4 | 5 | yarnPath: .yarn/releases/yarn-4.9.2.cjs 6 | -------------------------------------------------------------------------------- /example/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../tsconfig", 3 | "compilerOptions": { 4 | // Avoid expo-cli auto-generating a tsconfig 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | overrides: [ 3 | { 4 | exclude: /\/node_modules\//, 5 | presets: ['module:react-native-builder-bob/babel-preset'], 6 | }, 7 | { 8 | include: /\/node_modules\//, 9 | presets: ['module:@react-native/babel-preset'], 10 | }, 11 | ], 12 | }; 13 | -------------------------------------------------------------------------------- /example/babel.config.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | const { getConfig } = require('react-native-builder-bob/babel-config'); 3 | const pkg = require('../package.json'); 4 | 5 | const root = path.resolve(__dirname, '..'); 6 | 7 | module.exports = getConfig( 8 | { 9 | presets: ['babel-preset-expo'], 10 | }, 11 | { root, pkg } 12 | ); 13 | -------------------------------------------------------------------------------- /src/index.tsx: -------------------------------------------------------------------------------- 1 | /** 2 | * Navigators 3 | */ 4 | export { createModalNavigator } from './createModalNavigator'; 5 | 6 | /** 7 | * Views 8 | */ 9 | export { ModalView } from './ModalView'; 10 | 11 | /** 12 | * Types 13 | */ 14 | export type { 15 | ModalNavigationOptions, 16 | ModalNavigationProp, 17 | ModalScreenProps, 18 | } from './types'; 19 | -------------------------------------------------------------------------------- /.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 | -------------------------------------------------------------------------------- /example/index.js: -------------------------------------------------------------------------------- 1 | import { registerRootComponent } from 'expo'; 2 | 3 | import { App } from './src/App.tsx'; 4 | 5 | // registerRootComponent calls AppRegistry.registerComponent('main', () => App); 6 | // It also ensures that whether you load the app in the Expo client or in a native build, 7 | // the environment is set up appropriately 8 | registerRootComponent(App); 9 | -------------------------------------------------------------------------------- /example/README.md: -------------------------------------------------------------------------------- 1 | # Run the example 2 | 3 | - [View it with Expo](https://expo.dev/%40satya164/react-navigation-native-modal-example?serviceType=eas&distribution=expo-go&scheme=&channel=&sdkVersion=) 4 | - Run the example locally 5 | - Clone the repository and run `yarn` to install the dependencies 6 | - Run `yarn example start` to start the packager 7 | - Scan the QR Code with the Expo app 8 | -------------------------------------------------------------------------------- /lefthook.yml: -------------------------------------------------------------------------------- 1 | pre-commit: 2 | parallel: true 3 | commands: 4 | lint: 5 | glob: "*.{js,ts,tsx}" 6 | run: yarn eslint {staged_files} 7 | types: 8 | glob: "*.{json,js,ts,tsx}" 9 | run: yarn tsc --noEmit 10 | test: 11 | glob: "*.{json,js,ts,tsx}" 12 | run: yarn test 13 | commit-msg: 14 | parallel: true 15 | commands: 16 | commitlint: 17 | run: npx commitlint --edit 18 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | ### Motivation 5 | 6 | 7 | 8 | ### Test plan 9 | 10 | 11 | -------------------------------------------------------------------------------- /.github/workflows/versions.yml: -------------------------------------------------------------------------------- 1 | name: Check versions 2 | on: 3 | issues: 4 | types: [opened] 5 | 6 | jobs: 7 | check-versions: 8 | runs-on: ubuntu-latest 9 | steps: 10 | - uses: react-navigation/check-versions-action@v1.0.0 11 | with: 12 | github-token: ${{ secrets.GITHUB_TOKEN }} 13 | required-packages: | 14 | react-native 15 | react-navigation-native-modal 16 | optional-packages: | 17 | expo 18 | -------------------------------------------------------------------------------- /eslint.config.mjs: -------------------------------------------------------------------------------- 1 | import { defineConfig, globalIgnores } from 'eslint/config'; 2 | import { jest, react, recommended } from 'eslint-config-satya164'; 3 | import sort from 'eslint-plugin-simple-import-sort'; 4 | 5 | export default defineConfig([ 6 | recommended, 7 | react, 8 | jest, 9 | 10 | globalIgnores([ 11 | '**/node_modules/', 12 | '**/coverage/', 13 | '**/dist/', 14 | '**/lib/', 15 | '**/.expo/', 16 | '**/.yarn/', 17 | '**/.vscode/', 18 | ]), 19 | 20 | { 21 | plugins: { 22 | 'simple-import-sort': sort, 23 | }, 24 | }, 25 | ]); 26 | -------------------------------------------------------------------------------- /example/metro.config.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | const { getDefaultConfig } = require('@expo/metro-config'); 3 | const { withMetroConfig } = require('react-native-monorepo-config'); 4 | 5 | const root = path.resolve(__dirname, '..'); 6 | 7 | /** 8 | * Metro configuration 9 | * https://facebook.github.io/metro/docs/configuration 10 | * 11 | * @type {import('metro-config').MetroConfig} 12 | */ 13 | const config = withMetroConfig(getDefaultConfig(__dirname), { 14 | root, 15 | dirname: __dirname, 16 | }); 17 | 18 | config.resolver.unstable_enablePackageExports = true; 19 | 20 | module.exports = config; 21 | -------------------------------------------------------------------------------- /example/app.json: -------------------------------------------------------------------------------- 1 | { 2 | "expo": { 3 | "name": "react-navigation-native-modal-example", 4 | "slug": "react-navigation-native-modal-example", 5 | "description": "Example app for react-navigation-native-modal", 6 | "version": "1.0.0", 7 | "platforms": [ 8 | "ios", 9 | "android", 10 | "web" 11 | ], 12 | "ios": { 13 | "supportsTablet": true 14 | }, 15 | "assetBundlePatterns": [ 16 | "**/*" 17 | ], 18 | "extra": { 19 | "eas": { 20 | "projectId": "fa39f722-fcc0-423d-ada0-7fd5901c5b71" 21 | } 22 | }, 23 | "owner": "satya164" 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /.github/workflows/expo.yml: -------------------------------------------------------------------------------- 1 | name: Expo Publish 2 | on: 3 | push: 4 | branches: 5 | - main 6 | workflow_dispatch: 7 | 8 | jobs: 9 | publish: 10 | name: Install and publish 11 | runs-on: ubuntu-latest 12 | steps: 13 | - name: Checkout 14 | uses: actions/checkout@v5 15 | 16 | - name: Setup 17 | uses: ./.github/actions/setup 18 | 19 | - name: Setup Expo 20 | uses: expo/expo-github-action@v8 21 | with: 22 | eas-version: latest 23 | token: ${{ secrets.EXPO_TOKEN }} 24 | 25 | - name: Publish Expo app 26 | working-directory: ./example 27 | run: eas update --non-interactive --auto 28 | -------------------------------------------------------------------------------- /.github/workflows/expo-preview.yml: -------------------------------------------------------------------------------- 1 | name: Expo Preview 2 | on: 3 | pull_request: 4 | 5 | jobs: 6 | publish: 7 | name: Install and publish 8 | runs-on: ubuntu-latest 9 | if: github.event.pull_request.head.repo.owner.login == 'satya164' 10 | steps: 11 | - name: Checkout 12 | uses: actions/checkout@v5 13 | 14 | - name: Setup 15 | uses: ./.github/actions/setup 16 | 17 | - name: Setup Expo 18 | uses: expo/expo-github-action@v8 19 | with: 20 | eas-version: latest 21 | token: ${{ secrets.EXPO_TOKEN }} 22 | 23 | - name: Comment preview 24 | uses: expo/expo-github-action/preview@v8 25 | with: 26 | working-directory: ./example 27 | command: eas update --non-interactive --auto 28 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "rootDir": ".", 4 | "paths": { 5 | "react-navigation-native-modal": ["./src/index.tsx"] 6 | }, 7 | "allowUnreachableCode": false, 8 | "allowUnusedLabels": false, 9 | "esModuleInterop": true, 10 | "forceConsistentCasingInFileNames": true, 11 | "jsx": "react", 12 | "lib": ["esnext"], 13 | "module": "esnext", 14 | "moduleResolution": "node", 15 | "noFallthroughCasesInSwitch": true, 16 | "noImplicitReturns": true, 17 | "noImplicitUseStrict": false, 18 | "noStrictGenericChecks": false, 19 | "noUncheckedIndexedAccess": true, 20 | "noUnusedLocals": true, 21 | "noUnusedParameters": true, 22 | "resolveJsonModule": true, 23 | "skipLibCheck": true, 24 | "strict": true, 25 | "target": "esnext", 26 | "verbatimModuleSyntax": true 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /.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@v4 15 | with: 16 | path: | 17 | **/node_modules 18 | .yarn/install-state.gz 19 | key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }}-${{ hashFiles('**/package.json') }} 20 | restore-keys: | 21 | ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }} 22 | ${{ runner.os }}-yarn- 23 | 24 | - name: Install dependencies 25 | if: steps.yarn-cache.outputs.cache-hit != 'true' 26 | run: yarn install --immutable 27 | shell: bash 28 | -------------------------------------------------------------------------------- /example/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "react-navigation-native-modal-example", 3 | "description": "Example app for react-navigation-native-modal", 4 | "version": "0.0.1", 5 | "private": true, 6 | "main": "index", 7 | "scripts": { 8 | "android": "expo start --android", 9 | "ios": "expo start --ios", 10 | "start": "expo start", 11 | "test": "jest" 12 | }, 13 | "dependencies": { 14 | "@react-navigation/native": "^7.1.17", 15 | "expo": "^53.0.20", 16 | "react": "19.0.0", 17 | "react-native": "0.79.5", 18 | "react-navigation-native-modal": "workspace:^" 19 | }, 20 | "devDependencies": { 21 | "@babel/core": "^7.28.0", 22 | "@babel/runtime": "^7.28.2", 23 | "@expo/metro-config": "^0.20.17", 24 | "babel-preset-expo": "~13.0.0", 25 | "react-native-builder-bob": "^0.40.13", 26 | "react-native-monorepo-config": "^0.1.9" 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /.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 | # Yarn 60 | .yarn/* 61 | !.yarn/patches 62 | !.yarn/plugins 63 | !.yarn/releases 64 | !.yarn/sdks 65 | !.yarn/versions 66 | 67 | # generated by bob 68 | lib/ 69 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | ## 0.3.1 (2025-08-13) 4 | 5 | * ci: update release workflow ([5a0de06](https://github.com/satya164/react-navigation-native-modal/commit/5a0de06)) 6 | * docs: document static config api ([ade7995](https://github.com/satya164/react-navigation-native-modal/commit/ade7995)) 7 | 8 | ## 0.3.0 (2025-08-13) 9 | 10 | * feat: upgrade to react nvigation 7 ([87f4a54](https://github.com/satya164/react-navigation-native-modal/commit/87f4a54)) 11 | 12 | ## [0.1.11](https://github.com/satya164/react-navigation-native-modal/compare/v0.1.10...v0.1.11) (2023-11-02) 13 | 14 | ## [0.1.10](https://github.com/satya164/react-navigation-native-modal/compare/v0.1.9...v0.1.10) (2023-11-02) 15 | 16 | ## [0.1.9](https://github.com/satya164/react-navigation-native-modal/compare/v0.1.6...v0.1.9) (2023-11-02) 17 | 18 | 19 | ### Bug Fixes 20 | 21 | * upgrade to use react navigation 6 ([aba8c58](https://github.com/satya164/react-navigation-native-modal/commit/aba8c58305ae405eb9b8686c9e32d453f713f1a2)) 22 | -------------------------------------------------------------------------------- /.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@v5 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@v5 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-library: 39 | runs-on: ubuntu-latest 40 | steps: 41 | - name: Checkout 42 | uses: actions/checkout@v5 43 | 44 | - name: Setup 45 | uses: ./.github/actions/setup 46 | 47 | - name: Build package 48 | run: yarn prepare 49 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 Satyajit Sahoo 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 | -------------------------------------------------------------------------------- /src/__tests__/index.test.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { View, Text, Button } from 'react-native'; 3 | import { render } from '@testing-library/react-native'; 4 | import { 5 | NavigationContainer, 6 | type ParamListBase, 7 | } from '@react-navigation/native'; 8 | import { createModalNavigator, type ModalScreenProps } from '../index'; 9 | 10 | jest.useFakeTimers(); 11 | test('renders a modal navigator with screens', async () => { 12 | const Test = ({ route, navigation }: ModalScreenProps) => ( 13 | 14 | Screen {route.name} 15 |