Compare commits

...

44 Commits

Author SHA1 Message Date
Satyajit Sahoo
7ac4c13d44 chore: publish
- @react-navigation/bottom-tabs@5.5.1
 - @react-navigation/compat@5.1.25
 - @react-navigation/core@5.9.0
 - @react-navigation/drawer@5.8.1
 - @react-navigation/material-bottom-tabs@5.2.9
 - @react-navigation/material-top-tabs@5.2.9
 - @react-navigation/native@5.5.0
 - @react-navigation/stack@5.4.1
2020-05-27 18:32:30 +02:00
Raviraj
a0b9f94120 refactor: remove unnecessary check for type of bottom tab bar label 2020-05-27 18:12:21 +02:00
Satyajit Sahoo
717dffdb81 chore: improve caching of yarn on gh actions 2020-05-27 13:31:50 +02:00
Satyajit Sahoo
9016ba00e3 chore: improve caching of yarn on circleci 2020-05-27 13:19:41 +02:00
Satyajit Sahoo
9d822b95a6 fix: fix type of style for various options 2020-05-26 17:33:50 +02:00
Satyajit Sahoo
52d5cb4179 chore: add an example for SSR (#8298)
<img width="740" alt="Screen Shot 2020-05-20 at 16 31 30" src="https://user-images.githubusercontent.com/1174278/82458770-673d8880-9ab7-11ea-81d3-8ac0c1e52705.png">
2020-05-26 16:07:47 +02:00
Satyajit Sahoo
af1722d1e9 fix: export types from /native 2020-05-26 14:11:48 +02:00
Satyajit Sahoo
0b1a718756 feat: add ref to get current options in ServerContainer (#8333)
User can pass a `ref` to the container to get current options, like they can with `NavigationContainer`:

```js
const ref = React.createRef();

const html = renderToString(
  <ServerContainer ref={ref}>
    <App />
  </ServerContainer>
);

ref.current.getCurrentOptions(); // Options for screen
```
2020-05-26 13:55:06 +02:00
Michał Osadnik
9ab29558d0 refactor: remove useless callback arg in useSubscription (#8332) 2020-05-26 13:21:51 +02:00
Bright Lee
00c23f2c9e fix: allow HeaderBackground's subViews to be touchable (#8317) 2020-05-25 15:50:24 +02:00
Satyajit Sahoo
68e750d5a6 feat: add a ServerContainer component for SSR (#8297)
When doing SSR, the app needs to be aware of request URL to render correct navigation state.
The `ServerContainer` component lets us pass the `location` object to use for SSR.
The shape of the `location` object matches the `location` object in the browser.

Usage:

```js
ReactDOM.renderToString(
  <ServerContainer location={{ pathname: req.path, search: req.search }}>
    <App />
  </ServerContainer>
);
```

Updated example: https://github.com/react-navigation/react-navigation/pull/8298
2020-05-24 14:28:16 +02:00
Satyajit Sahoo
ced2a24aa6 chore: publish
- @react-navigation/bottom-tabs@5.5.0
 - @react-navigation/compat@5.1.24
 - @react-navigation/core@5.8.2
 - @react-navigation/drawer@5.8.0
 - @react-navigation/material-bottom-tabs@5.2.8
 - @react-navigation/material-top-tabs@5.2.8
 - @react-navigation/native@5.4.3
 - @react-navigation/routers@5.4.7
 - @react-navigation/stack@5.4.0
2020-05-23 18:36:57 +02:00
Satyajit Sahoo
ebf1345b39 refactor: simplify bottom tab bar 2020-05-23 18:34:12 +02:00
Satyajit Sahoo
df3544d9b4 Revert "fix: allow HeaderBackground's subViews to be touchable" (#8316) 2020-05-23 18:22:35 +02:00
Ashoat Tevosyan
c1e46f8e33 feat: animate changes to tabBarVisible in BottomTabBar (#8286)
## Motivation

Some designs call for custom keyboard inputs, or other bottom-aligned views meant overlap over the keyboard. Right now the best option on Android for this case is to set `tabBarVisible`. However changes to `tabBarVisible` doesn't get animated currently, which makes the custom-keyboard-open experience a bit more jarring than the native-keyboard-open one.

## Approach

I basically cribbed the `Animated.Value` we were using for `keyboardHidesTabBar` and made it depend on both. Note that the offset height depends on which of the two uses cases we're dealing with, which is explained in the code.

## Test plan

I played around with the `BottomTabs` example, setting certain screens to `tabBarVisible: true` and making sure it animated.
2020-05-23 18:16:30 +02:00
Bright Lee
021a9111d7 fix: allow HeaderBackground's subViews to be touchable (#8314)
When you're using the following options on `Stack`, the touch event goes to the behind of the Header and we can't really solve this problem in given `headerBackground` component level.
```
 options={{
          headerTransparent: true,
          headerBackground: 
```

### Problem
![May-23-2020 09-31-01](https://user-images.githubusercontent.com/916690/82726502-ebc11e80-9ce4-11ea-81d0-cc6a18bd70a7.gif)
2020-05-23 18:14:59 +02:00
Satyajit Sahoo
d3ace96981 chore: add linking prefix for expo to slience the warning 2020-05-23 17:37:45 +02:00
Satyajit Sahoo
edbc6b1e84 chore: tweak metro config 2020-05-23 17:33:34 +02:00
Satyajit Sahoo
c52d19bec8 chore: add example to hide and show bottom tab bar 2020-05-21 15:31:34 +02:00
Satyajit Sahoo
6dd45fcff9 fix: don't ignore previous header heights on layout update 2020-05-21 12:54:12 +02:00
Janic Duplessis
d62fbfe255 feat: update react-native-safe-area-context to 1.0.0 (#8182)
I made sure 1.0 is backwards compatible with react-navigation, which means using rn-safe-area-context@1+ with older versions of react-navigation will still work.
2020-05-21 11:25:36 +02:00
Evan Bacon
b14094619f chore: ignore __tests__ in prod builds (#8307)
The tests are being bundled and shipped in prod, this adds a bit of unneeded weight to npm installs. Now they won't be included.

```
@react-navigation/core
- before: 274 files - pkg: 211.0 kB - unpkg: 1 MB
- after: 238 files - pkg: 192.1 kB - unpkg: 827.3 kB
```
2020-05-21 11:15:12 +02:00
Ashoat Tevosyan
4c4d864af2 refactor: memoize initializedState in useNavigationBuilder (#8281) 2020-05-21 11:13:06 +02:00
Michał Osadnik
e1969f4e17 refactor: extract NavigationStateContext (#8304) 2020-05-21 10:41:34 +02:00
Satyajit Sahoo
175c07a28c chore: publish
- @react-navigation/example@5.1.0
 - @react-navigation/bottom-tabs@5.4.7
 - @react-navigation/compat@5.1.23
 - @react-navigation/core@5.8.1
 - @react-navigation/drawer@5.7.7
 - @react-navigation/material-bottom-tabs@5.2.7
 - @react-navigation/material-top-tabs@5.2.7
 - @react-navigation/native@5.4.2
 - @react-navigation/routers@5.4.6
 - @react-navigation/stack@5.3.9
2020-05-20 13:27:29 +02:00
osdnk
2980627cbf chore: publish
- @react-navigation/bottom-tabs@5.4.6
 - @react-navigation/compat@5.1.22
 - @react-navigation/core@5.8.0
 - @react-navigation/drawer@5.7.6
 - @react-navigation/material-bottom-tabs@5.2.6
 - @react-navigation/material-top-tabs@5.2.6
 - @react-navigation/native@5.4.1
 - @react-navigation/routers@5.4.5
 - @react-navigation/stack@5.3.8
2020-05-20 10:29:05 +02:00
Michał Osadnik
d024ec6d74 feat: add getCurrentOptions (#8277) 2020-05-19 20:53:08 +02:00
Satyajit Sahoo
4d1b85c751 chore: limit height of material top tabs example 2020-05-19 19:27:05 +02:00
Satyajit Sahoo
4a818fdfb3 chore: tweak master-detail example 2020-05-19 18:56:51 +02:00
Satyajit Sahoo
0194de1061 chore: upgrade bob 2020-05-19 14:25:20 +02:00
Michał Osadnik
7b25c8eb2e feat: add getCurrentRoute (#8254) 2020-05-18 01:55:09 +02:00
Satyajit Sahoo
9304a8a16c chore: publish
- @react-navigation/bottom-tabs@5.4.5
 - @react-navigation/compat@5.1.21
 - @react-navigation/core@5.7.0
 - @react-navigation/drawer@5.7.5
 - @react-navigation/material-bottom-tabs@5.2.5
 - @react-navigation/material-top-tabs@5.2.5
 - @react-navigation/native@5.4.0
 - @react-navigation/stack@5.3.7
2020-05-17 01:20:24 +02:00
Satyajit Sahoo
51b40879bd fix: center icons in material tab bar. fixes #8248 2020-05-17 01:06:29 +02:00
Satyajit Sahoo
51f4d11fdf fix: don't use Object.fromEntries 2020-05-17 00:56:19 +02:00
Satyajit Sahoo
c2aa4bb2eb test: fix integration tests 2020-05-16 21:18:42 +02:00
Satyajit Sahoo
199a892a6d chore: fix the links in the example 2020-05-16 01:58:05 +02:00
Satyajit Sahoo
60cb3c9ba7 feat: add a PathConfig type 2020-05-15 18:57:28 +02:00
Satyajit Sahoo
6ccceaea8b chore: tweak linking config in the example 2020-05-15 18:48:03 +02:00
Satyajit Sahoo
d14f38b80a fix: fix types for linking options 2020-05-15 18:37:58 +02:00
Satyajit Sahoo
c481748f00 chore: publish
- @react-navigation/stack@5.3.6
2020-05-15 17:39:47 +02:00
Satyajit Sahoo
d45dbe97dc fix: reduce header title margin. fixes #8267 2020-05-15 17:39:33 +02:00
Janic Duplessis
7623945f6e chore: fix repo url in readme (#8235) 2020-05-14 19:10:08 +02:00
Satyajit Sahoo
1dddaff45c chore: publish
- @react-navigation/bottom-tabs@5.4.4
 - @react-navigation/compat@5.1.20
 - @react-navigation/core@5.6.1
 - @react-navigation/drawer@5.7.4
 - @react-navigation/material-bottom-tabs@5.2.4
 - @react-navigation/material-top-tabs@5.2.4
 - @react-navigation/native@5.3.2
 - @react-navigation/stack@5.3.5
2020-05-14 13:22:54 +02:00
Satyajit Sahoo
21b397f0d6 fix: don't use flat since it's not supported in node 2020-05-14 13:22:14 +02:00
80 changed files with 2504 additions and 580 deletions

View File

@@ -22,13 +22,14 @@ jobs:
- attach_project - attach_project
- restore_cache: - restore_cache:
keys: keys:
- v2-dependencies-{{ checksum "yarn.lock" }} - yarn-packages-v1-{{ .Branch }}-{{ checksum "yarn.lock" }}
- v2-dependencies- - yarn-packages-v1-{{ .Branch }}-
- yarn-packages-v1-
- run: - run:
name: Install project dependencies name: Install project dependencies
command: yarn install --frozen-lockfile command: yarn install --frozen-lockfile
- save_cache: - save_cache:
key: v2-dependencies-{{ checksum "yarn.lock" }} key: yarn-packages-v1-{{ .Branch }}-{{ checksum "yarn.lock" }}
paths: ~/.cache/yarn paths: ~/.cache/yarn
- persist_to_workspace: - persist_to_workspace:
root: . root: .

View File

@@ -23,20 +23,18 @@ jobs:
expo-password: ${{ secrets.EXPO_CLI_PASSWORD }} expo-password: ${{ secrets.EXPO_CLI_PASSWORD }}
expo-cache: true expo-cache: true
- name: Get yarn cache - name: Restore yarn cache
id: yarn-cache id: yarn-cache
run: echo "::set-output name=dir::$(yarn cache dir)" uses: actions/cache@master
- name: Check yarn cache
uses: actions/cache@v1
with: with:
path: ${{ steps.yarn-cache.outputs.dir }} path: |
key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }} node_modules
restore-keys: | */*/node_modules
${{ runner.os }}-yarn- key: ${{ runner.os }}-yarn-v1-${{ hashFiles('**/yarn.lock') }}
- name: Install dependencies - name: Install dependencies
run: yarn if: steps.yarn-cache.outputs.cache-hit != 'true'
run: yarn install --frozen-lockfile
- name: Publish Expo app - name: Publish Expo app
working-directory: ./example working-directory: ./example

View File

@@ -25,19 +25,18 @@ jobs:
expo-password: ${{ secrets.EXPO_CLI_PASSWORD }} expo-password: ${{ secrets.EXPO_CLI_PASSWORD }}
expo-cache: true expo-cache: true
- name: Get yarn cache - name: Restore yarn cache
id: yarn-cache id: yarn-cache
run: echo "::set-output name=dir::$(yarn cache dir)" uses: actions/cache@master
- uses: actions/cache@v1
with: with:
path: ${{ steps.yarn-cache.outputs.dir }} path: |
key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }} node_modules
restore-keys: | */*/node_modules
${{ runner.os }}-yarn- key: ${{ runner.os }}-yarn-v1-${{ hashFiles('**/yarn.lock') }}
- name: Install dependencies - name: Install dependencies
run: yarn if: steps.yarn-cache.outputs.cache-hit != 'true'
run: yarn install --frozen-lockfile
- name: Publish Expo app - name: Publish Expo app
working-directory: ./example working-directory: ./example

View File

@@ -1,6 +1,10 @@
import 'react-native-gesture-handler'; import 'react-native-gesture-handler';
import { registerRootComponent } from 'expo'; import { registerRootComponent } from 'expo';
import { Asset } from 'expo-asset';
import { Assets as StackAssets } from '@react-navigation/stack';
import App from './src/index'; import App from './src/index';
Asset.loadAsync(StackAssets);
registerRootComponent(App); registerRootComponent(App);

41
example/CHANGELOG.md Normal file
View File

@@ -0,0 +1,41 @@
# Change Log
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
# [5.1.0](https://github.com/react-navigation/react-navigation/compare/@react-navigation/example@5.0.0-alpha.23...@react-navigation/example@5.1.0) (2020-05-20)
### Bug Fixes
* add config to enable redux devtools integration ([c9c825b](https://github.com/react-navigation/react-navigation/commit/c9c825bee61426635a28ee149eeeff3d628171cd))
* clamp interpolated styles ([67798af](https://github.com/react-navigation/react-navigation/commit/67798af869dcbbf323629fc7e7cc9062d1e12c29))
* disable screens when mode is modal on older expo versions ([94d7b28](https://github.com/react-navigation/react-navigation/commit/94d7b28c0b2ce0d56c99b224610f305be6451626))
* dispatch pop early when screen is closed with gesture ([#336](https://github.com/react-navigation/react-navigation/issues/336)) ([3d937d1](https://github.com/react-navigation/react-navigation/commit/3d937d1e6571cd613e830d64f7b2e7426076d371)), closes [#267](https://github.com/react-navigation/react-navigation/issues/267)
* provide initial values for safe area to prevent blank screen ([#238](https://github.com/react-navigation/react-navigation/issues/238)) ([77b7570](https://github.com/react-navigation/react-navigation/commit/77b757091c0451e20bca01138629669c7da544a8))
* render fallback only if linking is enabled. closes [#8161](https://github.com/react-navigation/react-navigation/issues/8161) ([1c075ff](https://github.com/react-navigation/react-navigation/commit/1c075ffb169d233ed0515efea264a5a69b4de52e))
* return onPress instead of onClick for useLinkProps ([ae5442e](https://github.com/react-navigation/react-navigation/commit/ae5442ebe812b91fa1f12164f27d1aeed918ab0e))
* rtl in native app example ([50b366e](https://github.com/react-navigation/react-navigation/commit/50b366e7341f201d29a44f20b7771b3a832b0045))
* screens integration on Android ([#294](https://github.com/react-navigation/react-navigation/issues/294)) ([9bfb295](https://github.com/react-navigation/react-navigation/commit/9bfb29562020c61b4d5c9bee278bcb1c7bdb8b67))
* spread parent params to children in compat navigator ([24febf6](https://github.com/react-navigation/react-navigation/commit/24febf6ea99be2e5f22005fdd2a82136d647255c)), closes [#6785](https://github.com/react-navigation/react-navigation/issues/6785)
* update screens for native stack ([5411816](https://github.com/react-navigation/react-navigation/commit/54118161885738a6d20b062c7e6679f3bace8424))
* wrap navigators in gesture handler root ([41a5e1a](https://github.com/react-navigation/react-navigation/commit/41a5e1a385aa5180abc3992a4c67077c37b998b9))
### Features
* add `animationTypeForReplace` option ([#297](https://github.com/react-navigation/react-navigation/issues/297)) ([6262f72](https://github.com/react-navigation/react-navigation/commit/6262f7298bff843571fb4b1a677d3beabe29833e))
* add `screens` prop for nested configs ([#308](https://github.com/react-navigation/react-navigation/issues/308)) ([b931ae6](https://github.com/react-navigation/react-navigation/commit/b931ae62dfb2c5253c94ea5ace73e9070ec17c4a))
* add `useLinkBuilder` hook to build links ([2792f43](https://github.com/react-navigation/react-navigation/commit/2792f438fe45428fe193e3708fee7ad61966cbf4))
* add a useLinkProps hook ([f2291d1](https://github.com/react-navigation/react-navigation/commit/f2291d110faa2aa8e10c9133c1c0c28d54af7917))
* add action prop to Link ([942d2be](https://github.com/react-navigation/react-navigation/commit/942d2be2c72720469475ce12ec8df23825994dbf))
* add custom theme support ([#211](https://github.com/react-navigation/react-navigation/issues/211)) ([00fc616](https://github.com/react-navigation/react-navigation/commit/00fc616de0572bade8aa85052cdc8290360b1d7f))
* add deeplinking to native example ([#309](https://github.com/react-navigation/react-navigation/issues/309)) ([e55e866](https://github.com/react-navigation/react-navigation/commit/e55e866af2f2163ee89bc527997cda13ffeb2abe))
* add headerStatusBarHeight option to stack ([b201fd2](https://github.com/react-navigation/react-navigation/commit/b201fd20716a2f03cb9373c72281f5d396a9356d))
* add Link component as useLinkTo hook for navigating to links ([2573b5b](https://github.com/react-navigation/react-navigation/commit/2573b5beaac1240434e52f3f57bb29da2f541c88))
* add openByDefault option to drawer ([36689e2](https://github.com/react-navigation/react-navigation/commit/36689e24c21b474692bb7ecd0b901c8afbbe9a20))
* add permanent drawer type ([#7818](https://github.com/react-navigation/react-navigation/issues/7818)) ([6a5d0a0](https://github.com/react-navigation/react-navigation/commit/6a5d0a035afae60d91aef78401ec8826295746fe))
* add preventDefault functionality in material bottom tabs ([3dede31](https://github.com/react-navigation/react-navigation/commit/3dede316ccab3b2403a475f60ce20b5c4e4cc068))
* emit appear and dismiss events for native stack ([f1df4a0](https://github.com/react-navigation/react-navigation/commit/f1df4a080877b3642e748a41a5ffc2da8c449a8c))
* initialState should take priority over deep link ([039017b](https://github.com/react-navigation/react-navigation/commit/039017bc2af69120d2d10e8f2c8a62919c37eb65))
* integrate with history API on web ([5a3f835](https://github.com/react-navigation/react-navigation/commit/5a3f8356b05bff7ed20893a5db6804612da3e568))

View File

@@ -7,12 +7,6 @@
"slug": "react-navigation-example", "slug": "react-navigation-example",
"description": "Demo app to showcase various functionality of React Navigation", "description": "Demo app to showcase various functionality of React Navigation",
"privacy": "public", "privacy": "public",
"sdkVersion": "37.0.0",
"platforms": [
"ios",
"android",
"web"
],
"version": "1.0.0", "version": "1.0.0",
"icon": "./assets/icon.png", "icon": "./assets/icon.png",
"splash": { "splash": {
@@ -20,15 +14,16 @@
"resizeMode": "contain", "resizeMode": "contain",
"backgroundColor": "#ffffff" "backgroundColor": "#ffffff"
}, },
"updates": { "sdkVersion": "37.0.0",
"fallbackToCacheTimeout": 0 "platforms": ["ios", "android", "web"],
},
"assetBundlePatterns": [
"**/*"
],
"ios": { "ios": {
"supportsTablet": true "supportsTablet": true
}, },
"updates": {
"fallbackToCacheTimeout": 0
},
"assetBundlePatterns": ["**/*"],
"scheme": "rne",
"entryPoint": "App.tsx" "entryPoint": "App.tsx"
} }
} }

View File

@@ -6,7 +6,7 @@ beforeEach(async () => {
it('loads the article page', async () => { it('loads the article page', async () => {
expect(await page.evaluate(() => location.pathname + location.search)).toBe( expect(await page.evaluate(() => location.pathname + location.search)).toBe(
'/link-component/Article?author=Gandalf' '/link-component/article/gandalf'
); );
expect( expect(
((await page.accessibility.snapshot()) as any)?.children?.find( ((await page.accessibility.snapshot()) as any)?.children?.find(
@@ -16,24 +16,24 @@ it('loads the article page', async () => {
}); });
it('goes to the album page and goes back', async () => { it('goes to the album page and goes back', async () => {
await page.click('[href="/link-component/Album"]'); await page.click('[href="/link-component/music"]');
expect(await page.evaluate(() => location.pathname + location.search)).toBe( expect(await page.evaluate(() => location.pathname + location.search)).toBe(
'/link-component/Album' '/link-component/music'
); );
expect( expect(
((await page.accessibility.snapshot()) as any)?.children?.find( ((await page.accessibility.snapshot()) as any)?.children?.find(
(it: any) => it.role === 'heading' (it: any) => it.role === 'heading'
)?.name )?.name
).toBe('Album'); ).toBe('Albums');
await page.click('[aria-label="Article by Gandalf, back"]'); await page.click('[aria-label="Article by Gandalf, back"]');
await page.waitForNavigation(); await page.waitForNavigation();
expect(await page.evaluate(() => location.pathname + location.search)).toBe( expect(await page.evaluate(() => location.pathname + location.search)).toBe(
'/link-component/Article?author=Gandalf' '/link-component/article/gandalf'
); );
expect( expect(

View File

@@ -0,0 +1,13 @@
import fetch from 'node-fetch';
import cheerio from 'cheerio';
const server = 'http://localhost:3275';
it('renders the home page', async () => {
const res = await fetch(server);
const html = await res.text();
const $ = cheerio.load(html);
expect($('title').text()).toBe('Examples');
});

View File

@@ -1,8 +1,16 @@
import { setup } from 'jest-dev-server'; import { setup } from 'jest-dev-server';
export default async function () { export default async function () {
await setup({ await setup([
{
command: 'yarn serve -l 3579 web-build', command: 'yarn serve -l 3579 web-build',
launchTimeout: 50000,
port: 3579, port: 3579,
}); },
{
command: 'yarn server',
launchTimeout: 50000,
port: 3275,
},
]);
} }

View File

@@ -1,35 +1,38 @@
PODS: PODS:
- boost-for-react-native (1.63.0) - boost-for-react-native (1.63.0)
- DoubleConversion (1.1.6) - DoubleConversion (1.1.6)
- EXAppLoaderProvider (8.0.0) - EXBlur (8.1.0):
- EXBlur (8.0.0):
- UMCore - UMCore
- EXConstants (8.0.0): - EXConstants (9.0.0):
- UMConstantsInterface - UMConstantsInterface
- UMCore - UMCore
- EXErrorRecovery (1.0.0): - EXErrorRecovery (1.1.0):
- UMCore - UMCore
- EXFileSystem (8.0.0): - EXFileSystem (8.1.0):
- UMCore - UMCore
- UMFileSystemInterface - UMFileSystemInterface
- EXFont (8.0.0): - EXFont (8.1.0):
- UMCore - UMCore
- UMFontInterface - UMFontInterface
- EXKeepAwake (8.0.0): - EXImageLoader (1.0.1):
- React-Core
- UMCore - UMCore
- EXLinearGradient (8.0.0): - UMImageLoaderInterface
- EXKeepAwake (8.1.0):
- UMCore - UMCore
- EXLocation (8.0.0): - EXLinearGradient (8.1.0):
- UMCore
- EXLocation (8.1.0):
- UMCore - UMCore
- UMPermissionsInterface - UMPermissionsInterface
- UMTaskManagerInterface - UMTaskManagerInterface
- EXPermissions (8.0.0): - EXPermissions (8.1.0):
- UMCore - UMCore
- UMPermissionsInterface - UMPermissionsInterface
- EXSQLite (8.0.0): - EXSQLite (8.1.0):
- UMCore - UMCore
- UMFileSystemInterface - UMFileSystemInterface
- EXWebBrowser (8.0.0): - EXWebBrowser (8.2.1):
- UMCore - UMCore
- FBLazyVector (0.61.5) - FBLazyVector (0.61.5)
- FBReactNativeSpec (0.61.5): - FBReactNativeSpec (0.61.5):
@@ -50,8 +53,6 @@ PODS:
- glog - glog
- glog (0.3.5) - glog (0.3.5)
- RCTRequired (0.61.5) - RCTRequired (0.61.5)
- RCTRestart (0.0.13):
- React
- RCTTypeSafety (0.61.5): - RCTTypeSafety (0.61.5):
- FBLazyVector (= 0.61.5) - FBLazyVector (= 0.61.5)
- Folly (= 2018.10.22.00) - Folly (= 2018.10.22.00)
@@ -214,7 +215,9 @@ PODS:
- React-cxxreact (= 0.61.5) - React-cxxreact (= 0.61.5)
- React-jsi (= 0.61.5) - React-jsi (= 0.61.5)
- React-jsinspector (0.61.5) - React-jsinspector (0.61.5)
- react-native-safe-area-context (0.6.2): - react-native-restart (0.0.15):
- React
- react-native-safe-area-context (1.0.0):
- React - React
- React-RCTActionSheet (0.61.5): - React-RCTActionSheet (0.61.5):
- React-Core/RCTActionSheetHeaders (= 0.61.5) - React-Core/RCTActionSheetHeaders (= 0.61.5)
@@ -251,39 +254,41 @@ PODS:
- React-cxxreact (= 0.61.5) - React-cxxreact (= 0.61.5)
- React-jsi (= 0.61.5) - React-jsi (= 0.61.5)
- ReactCommon/jscallinvoker (= 0.61.5) - ReactCommon/jscallinvoker (= 0.61.5)
- RNCMaskedView (0.1.5): - RNCMaskedView (0.1.10):
- React - React
- RNGestureHandler (1.5.5): - RNGestureHandler (1.6.1):
- React - React
- RNReanimated (1.4.0): - RNReanimated (1.8.0):
- React - React
- RNScreens (2.0.0-alpha.33): - RNScreens (2.7.0):
- React - React
- UMBarCodeScannerInterface (5.0.0) - UMAppLoader (1.0.2)
- UMCameraInterface (5.0.0) - UMBarCodeScannerInterface (5.1.0)
- UMConstantsInterface (5.0.0) - UMCameraInterface (5.1.0)
- UMCore (5.0.0) - UMConstantsInterface (5.1.0)
- UMFaceDetectorInterface (5.0.0) - UMCore (5.1.2)
- UMFileSystemInterface (5.0.0) - UMFaceDetectorInterface (5.1.0)
- UMFontInterface (5.0.0) - UMFileSystemInterface (5.1.0)
- UMImageLoaderInterface (5.0.0) - UMFontInterface (5.1.0)
- UMPermissionsInterface (5.0.0) - UMImageLoaderInterface (5.1.0)
- UMReactNativeAdapter (5.0.0): - UMPermissionsInterface (5.1.0):
- UMCore
- UMReactNativeAdapter (5.2.0):
- React-Core - React-Core
- UMCore - UMCore
- UMFontInterface - UMFontInterface
- UMSensorsInterface (5.0.0) - UMSensorsInterface (5.1.0)
- UMTaskManagerInterface (5.0.0) - UMTaskManagerInterface (5.1.0)
- Yoga (1.14.0) - Yoga (1.14.0)
DEPENDENCIES: DEPENDENCIES:
- DoubleConversion (from `../../node_modules/react-native/third-party-podspecs/DoubleConversion.podspec`) - DoubleConversion (from `../../node_modules/react-native/third-party-podspecs/DoubleConversion.podspec`)
- EXAppLoaderProvider (from `../../node_modules/expo-app-loader-provider/ios`)
- EXBlur (from `../../node_modules/expo-blur/ios`) - EXBlur (from `../../node_modules/expo-blur/ios`)
- EXConstants (from `../../node_modules/expo-constants/ios`) - EXConstants (from `../../node_modules/expo-constants/ios`)
- EXErrorRecovery (from `../../node_modules/expo-error-recovery/ios`) - EXErrorRecovery (from `../../node_modules/expo-error-recovery/ios`)
- EXFileSystem (from `../../node_modules/expo-file-system/ios`) - EXFileSystem (from `../../node_modules/expo-file-system/ios`)
- EXFont (from `../../node_modules/expo-font/ios`) - EXFont (from `../../node_modules/expo-font/ios`)
- EXImageLoader (from `../../node_modules/expo-image-loader/ios`)
- EXKeepAwake (from `../../node_modules/expo-keep-awake/ios`) - EXKeepAwake (from `../../node_modules/expo-keep-awake/ios`)
- EXLinearGradient (from `../../node_modules/expo-linear-gradient/ios`) - EXLinearGradient (from `../../node_modules/expo-linear-gradient/ios`)
- EXLocation (from `../../node_modules/expo-location/ios`) - EXLocation (from `../../node_modules/expo-location/ios`)
@@ -295,7 +300,6 @@ DEPENDENCIES:
- Folly (from `../../node_modules/react-native/third-party-podspecs/Folly.podspec`) - Folly (from `../../node_modules/react-native/third-party-podspecs/Folly.podspec`)
- glog (from `../../node_modules/react-native/third-party-podspecs/glog.podspec`) - glog (from `../../node_modules/react-native/third-party-podspecs/glog.podspec`)
- RCTRequired (from `../../node_modules/react-native/Libraries/RCTRequired`) - RCTRequired (from `../../node_modules/react-native/Libraries/RCTRequired`)
- RCTRestart (from `../../node_modules/react-native-restart/ios`)
- RCTTypeSafety (from `../../node_modules/react-native/Libraries/TypeSafety`) - RCTTypeSafety (from `../../node_modules/react-native/Libraries/TypeSafety`)
- React (from `../../node_modules/react-native/`) - React (from `../../node_modules/react-native/`)
- React-Core (from `../../node_modules/react-native/`) - React-Core (from `../../node_modules/react-native/`)
@@ -306,6 +310,7 @@ DEPENDENCIES:
- React-jsi (from `../../node_modules/react-native/ReactCommon/jsi`) - React-jsi (from `../../node_modules/react-native/ReactCommon/jsi`)
- React-jsiexecutor (from `../../node_modules/react-native/ReactCommon/jsiexecutor`) - React-jsiexecutor (from `../../node_modules/react-native/ReactCommon/jsiexecutor`)
- React-jsinspector (from `../../node_modules/react-native/ReactCommon/jsinspector`) - React-jsinspector (from `../../node_modules/react-native/ReactCommon/jsinspector`)
- react-native-restart (from `../../node_modules/react-native-restart`)
- react-native-safe-area-context (from `../../node_modules/react-native-safe-area-context`) - react-native-safe-area-context (from `../../node_modules/react-native-safe-area-context`)
- React-RCTActionSheet (from `../../node_modules/react-native/Libraries/ActionSheetIOS`) - React-RCTActionSheet (from `../../node_modules/react-native/Libraries/ActionSheetIOS`)
- React-RCTAnimation (from `../../node_modules/react-native/Libraries/NativeAnimation`) - React-RCTAnimation (from `../../node_modules/react-native/Libraries/NativeAnimation`)
@@ -322,10 +327,11 @@ DEPENDENCIES:
- RNGestureHandler (from `../../node_modules/react-native-gesture-handler`) - RNGestureHandler (from `../../node_modules/react-native-gesture-handler`)
- RNReanimated (from `../../node_modules/react-native-reanimated`) - RNReanimated (from `../../node_modules/react-native-reanimated`)
- RNScreens (from `../../node_modules/react-native-screens`) - RNScreens (from `../../node_modules/react-native-screens`)
- UMAppLoader (from `../../node_modules/unimodules-app-loader/ios`)
- UMBarCodeScannerInterface (from `../../node_modules/unimodules-barcode-scanner-interface/ios`) - UMBarCodeScannerInterface (from `../../node_modules/unimodules-barcode-scanner-interface/ios`)
- UMCameraInterface (from `../../node_modules/unimodules-camera-interface/ios`) - UMCameraInterface (from `../../node_modules/unimodules-camera-interface/ios`)
- UMConstantsInterface (from `../../node_modules/unimodules-constants-interface/ios`) - UMConstantsInterface (from `../../node_modules/unimodules-constants-interface/ios`)
- "UMCore (from `../../node_modules/@unimodules/core/ios`)" - "UMCore (from `../../node_modules/react-native-unimodules/node_modules/@unimodules/core/ios`)"
- UMFaceDetectorInterface (from `../../node_modules/unimodules-face-detector-interface/ios`) - UMFaceDetectorInterface (from `../../node_modules/unimodules-face-detector-interface/ios`)
- UMFileSystemInterface (from `../../node_modules/unimodules-file-system-interface/ios`) - UMFileSystemInterface (from `../../node_modules/unimodules-file-system-interface/ios`)
- UMFontInterface (from `../../node_modules/unimodules-font-interface/ios`) - UMFontInterface (from `../../node_modules/unimodules-font-interface/ios`)
@@ -343,42 +349,30 @@ SPEC REPOS:
EXTERNAL SOURCES: EXTERNAL SOURCES:
DoubleConversion: DoubleConversion:
:podspec: "../../node_modules/react-native/third-party-podspecs/DoubleConversion.podspec" :podspec: "../../node_modules/react-native/third-party-podspecs/DoubleConversion.podspec"
EXAppLoaderProvider:
:path: !ruby/object:Pathname
path: "../../node_modules/expo-app-loader-provider/ios"
EXBlur: EXBlur:
:path: !ruby/object:Pathname :path: "../../node_modules/expo-blur/ios"
path: "../../node_modules/expo-blur/ios"
EXConstants: EXConstants:
:path: !ruby/object:Pathname :path: "../../node_modules/expo-constants/ios"
path: "../../node_modules/expo-constants/ios"
EXErrorRecovery: EXErrorRecovery:
:path: !ruby/object:Pathname :path: "../../node_modules/expo-error-recovery/ios"
path: "../../node_modules/expo-error-recovery/ios"
EXFileSystem: EXFileSystem:
:path: !ruby/object:Pathname :path: "../../node_modules/expo-file-system/ios"
path: "../../node_modules/expo-file-system/ios"
EXFont: EXFont:
:path: !ruby/object:Pathname :path: "../../node_modules/expo-font/ios"
path: "../../node_modules/expo-font/ios" EXImageLoader:
:path: "../../node_modules/expo-image-loader/ios"
EXKeepAwake: EXKeepAwake:
:path: !ruby/object:Pathname :path: "../../node_modules/expo-keep-awake/ios"
path: "../../node_modules/expo-keep-awake/ios"
EXLinearGradient: EXLinearGradient:
:path: !ruby/object:Pathname :path: "../../node_modules/expo-linear-gradient/ios"
path: "../../node_modules/expo-linear-gradient/ios"
EXLocation: EXLocation:
:path: !ruby/object:Pathname :path: "../../node_modules/expo-location/ios"
path: "../../node_modules/expo-location/ios"
EXPermissions: EXPermissions:
:path: !ruby/object:Pathname :path: "../../node_modules/expo-permissions/ios"
path: "../../node_modules/expo-permissions/ios"
EXSQLite: EXSQLite:
:path: !ruby/object:Pathname :path: "../../node_modules/expo-sqlite/ios"
path: "../../node_modules/expo-sqlite/ios"
EXWebBrowser: EXWebBrowser:
:path: !ruby/object:Pathname :path: "../../node_modules/expo-web-browser/ios"
path: "../../node_modules/expo-web-browser/ios"
FBLazyVector: FBLazyVector:
:path: "../../node_modules/react-native/Libraries/FBLazyVector" :path: "../../node_modules/react-native/Libraries/FBLazyVector"
FBReactNativeSpec: FBReactNativeSpec:
@@ -389,8 +383,6 @@ EXTERNAL SOURCES:
:podspec: "../../node_modules/react-native/third-party-podspecs/glog.podspec" :podspec: "../../node_modules/react-native/third-party-podspecs/glog.podspec"
RCTRequired: RCTRequired:
:path: "../../node_modules/react-native/Libraries/RCTRequired" :path: "../../node_modules/react-native/Libraries/RCTRequired"
RCTRestart:
:path: "../../node_modules/react-native-restart/ios"
RCTTypeSafety: RCTTypeSafety:
:path: "../../node_modules/react-native/Libraries/TypeSafety" :path: "../../node_modules/react-native/Libraries/TypeSafety"
React: React:
@@ -407,6 +399,8 @@ EXTERNAL SOURCES:
:path: "../../node_modules/react-native/ReactCommon/jsiexecutor" :path: "../../node_modules/react-native/ReactCommon/jsiexecutor"
React-jsinspector: React-jsinspector:
:path: "../../node_modules/react-native/ReactCommon/jsinspector" :path: "../../node_modules/react-native/ReactCommon/jsinspector"
react-native-restart:
:path: "../../node_modules/react-native-restart"
react-native-safe-area-context: react-native-safe-area-context:
:path: "../../node_modules/react-native-safe-area-context" :path: "../../node_modules/react-native-safe-area-context"
React-RCTActionSheet: React-RCTActionSheet:
@@ -437,66 +431,55 @@ EXTERNAL SOURCES:
:path: "../../node_modules/react-native-reanimated" :path: "../../node_modules/react-native-reanimated"
RNScreens: RNScreens:
:path: "../../node_modules/react-native-screens" :path: "../../node_modules/react-native-screens"
UMAppLoader:
:path: "../../node_modules/unimodules-app-loader/ios"
UMBarCodeScannerInterface: UMBarCodeScannerInterface:
:path: !ruby/object:Pathname :path: "../../node_modules/unimodules-barcode-scanner-interface/ios"
path: "../../node_modules/unimodules-barcode-scanner-interface/ios"
UMCameraInterface: UMCameraInterface:
:path: !ruby/object:Pathname :path: "../../node_modules/unimodules-camera-interface/ios"
path: "../../node_modules/unimodules-camera-interface/ios"
UMConstantsInterface: UMConstantsInterface:
:path: !ruby/object:Pathname :path: "../../node_modules/unimodules-constants-interface/ios"
path: "../../node_modules/unimodules-constants-interface/ios"
UMCore: UMCore:
:path: !ruby/object:Pathname :path: "../../node_modules/react-native-unimodules/node_modules/@unimodules/core/ios"
path: "../../node_modules/@unimodules/core/ios"
UMFaceDetectorInterface: UMFaceDetectorInterface:
:path: !ruby/object:Pathname :path: "../../node_modules/unimodules-face-detector-interface/ios"
path: "../../node_modules/unimodules-face-detector-interface/ios"
UMFileSystemInterface: UMFileSystemInterface:
:path: !ruby/object:Pathname :path: "../../node_modules/unimodules-file-system-interface/ios"
path: "../../node_modules/unimodules-file-system-interface/ios"
UMFontInterface: UMFontInterface:
:path: !ruby/object:Pathname :path: "../../node_modules/unimodules-font-interface/ios"
path: "../../node_modules/unimodules-font-interface/ios"
UMImageLoaderInterface: UMImageLoaderInterface:
:path: !ruby/object:Pathname :path: "../../node_modules/unimodules-image-loader-interface/ios"
path: "../../node_modules/unimodules-image-loader-interface/ios"
UMPermissionsInterface: UMPermissionsInterface:
:path: !ruby/object:Pathname :path: "../../node_modules/unimodules-permissions-interface/ios"
path: "../../node_modules/unimodules-permissions-interface/ios"
UMReactNativeAdapter: UMReactNativeAdapter:
:path: !ruby/object:Pathname :path: "../../node_modules/@unimodules/react-native-adapter/ios"
path: "../../node_modules/@unimodules/react-native-adapter/ios"
UMSensorsInterface: UMSensorsInterface:
:path: !ruby/object:Pathname :path: "../../node_modules/unimodules-sensors-interface/ios"
path: "../../node_modules/unimodules-sensors-interface/ios"
UMTaskManagerInterface: UMTaskManagerInterface:
:path: !ruby/object:Pathname :path: "../../node_modules/unimodules-task-manager-interface/ios"
path: "../../node_modules/unimodules-task-manager-interface/ios"
Yoga: Yoga:
:path: "../../node_modules/react-native/ReactCommon/yoga" :path: "../../node_modules/react-native/ReactCommon/yoga"
SPEC CHECKSUMS: SPEC CHECKSUMS:
boost-for-react-native: 39c7adb57c4e60d6c5479dd8623128eb5b3f0f2c boost-for-react-native: 39c7adb57c4e60d6c5479dd8623128eb5b3f0f2c
DoubleConversion: 5805e889d232975c086db112ece9ed034df7a0b2 DoubleConversion: 5805e889d232975c086db112ece9ed034df7a0b2
EXAppLoaderProvider: ebdb6bc2632c1ccadbe49f5e4104d8d690969c49 EXBlur: aa14d84bff6e9c2232fbcaf54ad809eee1cc41dc
EXBlur: d1604f66f89a9414f5ee65dfb23874437c1bb147 EXConstants: 5304709b1bea70a4828f48ba4c7fc3ec3b2d9b17
EXConstants: 4051b16c17ef3defa03c541d42811dc92b249146 EXErrorRecovery: 8f4c21ab2f51bf75defe4536f841a37de59b0661
EXErrorRecovery: d36db99ec6a3808f313f01b0890eb443796dd1c2 EXFileSystem: cf4232ba7c62dc49b78c2d36005f97b6fddf0b01
EXFileSystem: 6e0d9bb6cc4ea404dbb8f583c1a8a2dcdf4b83b6 EXFont: 8326ecf966be559f7ced7c8e221a32fc4d9ed8b0
EXFont: 6187b5ab46ee578d5f8e7f2ea092752e78772235 EXImageLoader: 5ad6896fa1ef2ee814b551873cbf7a7baccc694a
EXKeepAwake: 66e9f80b6d129633725a0e42f8d285c229876811 EXKeepAwake: d045bc2cf1ad5a04f0323cc7c894b95b414042e0
EXLinearGradient: 75f302f9d6484267a3f6d3252df2e7a5f00e716a EXLinearGradient: 97d8095d1e4ad96f7893e010e564796ed8aeea42
EXLocation: 3c75d012ca92eed94d4338778d79c49d1252393a EXLocation: bbd487fd96a18a3ad9725389bbb94c4a5f78edf3
EXPermissions: 9bc08859a675d291e89be9a0870155c27c16ac35 EXPermissions: 24b97f734ce9172d245a5be38ad9ccfcb6135964
EXSQLite: 220226a354912b100dfe913f5fe6f31762c8927e EXSQLite: 877ad6c8eb169353a2f94d5ad26510ffadd46a1f
EXWebBrowser: db32607359fb7b55b7b7b91df32dd3d8355bb3b7 EXWebBrowser: 5902f99ac5ac551e5c82ff46f13a337b323aa9ea
FBLazyVector: aaeaf388755e4f29cd74acbc9e3b8da6d807c37f FBLazyVector: aaeaf388755e4f29cd74acbc9e3b8da6d807c37f
FBReactNativeSpec: 118d0d177724c2d67f08a59136eb29ef5943ec75 FBReactNativeSpec: 118d0d177724c2d67f08a59136eb29ef5943ec75
Folly: 30e7936e1c45c08d884aa59369ed951a8e68cf51 Folly: 30e7936e1c45c08d884aa59369ed951a8e68cf51
glog: 1f3da668190260b06b429bb211bfbee5cd790c28 glog: 1f3da668190260b06b429bb211bfbee5cd790c28
RCTRequired: b153add4da6e7dbc44aebf93f3cf4fcae392ddf1 RCTRequired: b153add4da6e7dbc44aebf93f3cf4fcae392ddf1
RCTRestart: dd19aab87fc1118e05b6b5b91b959105647f56b4
RCTTypeSafety: 9aa1b91d7f9310fc6eadc3cf95126ffe818af320 RCTTypeSafety: 9aa1b91d7f9310fc6eadc3cf95126ffe818af320
React: b6a59ef847b2b40bb6e0180a97d0ca716969ac78 React: b6a59ef847b2b40bb6e0180a97d0ca716969ac78
React-Core: 688b451f7d616cc1134ac95295b593d1b5158a04 React-Core: 688b451f7d616cc1134ac95295b593d1b5158a04
@@ -505,7 +488,8 @@ SPEC CHECKSUMS:
React-jsi: cb2cd74d7ccf4cffb071a46833613edc79cdf8f7 React-jsi: cb2cd74d7ccf4cffb071a46833613edc79cdf8f7
React-jsiexecutor: d5525f9ed5f782fdbacb64b9b01a43a9323d2386 React-jsiexecutor: d5525f9ed5f782fdbacb64b9b01a43a9323d2386
React-jsinspector: fa0ecc501688c3c4c34f28834a76302233e29dc0 React-jsinspector: fa0ecc501688c3c4c34f28834a76302233e29dc0
react-native-safe-area-context: 25260c5d0b9c53fd7aa88e569e2edae72af1f6a3 react-native-restart: fff228304625f55de2ebd4de43938110f4c888ed
react-native-safe-area-context: a346c75f2288147527365ce27b59ca6d38c27805
React-RCTActionSheet: 600b4d10e3aea0913b5a92256d2719c0cdd26d76 React-RCTActionSheet: 600b4d10e3aea0913b5a92256d2719c0cdd26d76
React-RCTAnimation: 791a87558389c80908ed06cc5dfc5e7920dfa360 React-RCTAnimation: 791a87558389c80908ed06cc5dfc5e7920dfa360
React-RCTBlob: d89293cc0236d9cb0933d85e430b0bbe81ad1d72 React-RCTBlob: d89293cc0236d9cb0933d85e430b0bbe81ad1d72
@@ -516,24 +500,25 @@ SPEC CHECKSUMS:
React-RCTText: 9ccc88273e9a3aacff5094d2175a605efa854dbe React-RCTText: 9ccc88273e9a3aacff5094d2175a605efa854dbe
React-RCTVibration: a49a1f42bf8f5acf1c3e297097517c6b3af377ad React-RCTVibration: a49a1f42bf8f5acf1c3e297097517c6b3af377ad
ReactCommon: 198c7c8d3591f975e5431bec1b0b3b581aa1c5dd ReactCommon: 198c7c8d3591f975e5431bec1b0b3b581aa1c5dd
RNCMaskedView: dd13f9f7b146a9ad82f9b7eb6c9b5548fcf6e990 RNCMaskedView: 5a8ec07677aa885546a0d98da336457e2bea557f
RNGestureHandler: d2270608171c868581b840cfc692f2962c05cd17 RNGestureHandler: 8f09cd560f8d533eb36da5a6c5a843af9f056b38
RNReanimated: b2ab0b693dddd2339bd2f300e770f6302d2e960c RNReanimated: 955cf4068714003d2f1a6e2bae3fb1118f359aff
RNScreens: 1c7fd499b915c77c21e8e6c327890c5af9b4cf7e RNScreens: cf198f915f8a2bf163de94ca9f5bfc8d326c3706
UMBarCodeScannerInterface: 3802c8574ef119c150701d679ab386e2266d6a54 UMAppLoader: ee77a072f9e15128f777ccd6d2d00f52ab4387e6
UMCameraInterface: 985d301f688ed392f815728f0dd906ca34b7ccb1 UMBarCodeScannerInterface: 9dc692b87e5f20fe277fa57aa47f45d418c3cc6c
UMConstantsInterface: bda5f8bd3403ad99e663eb3c4da685d063c5653c UMCameraInterface: 625878bbf2ba188a8548675e1d1d2e438a653e6d
UMCore: 7ab08669a8bb2e61f557c1fe9784521cb5aa28e3 UMConstantsInterface: 64060cf86587bcd90b1dbd804cceb6d377a308c1
UMFaceDetectorInterface: ce14e8e597f6a52aa66e4ab956cb5bff4fa8acf8 UMCore: eb200e882eadafcd31ead290770835fd648c0945
UMFileSystemInterface: 2ed004c9620f43f0b36b33c42ce668500850d6a4 UMFaceDetectorInterface: d6677d6ddc9ab95a0ca857aa7f8ba76656cc770f
UMFontInterface: 24fbc0a02ade6c60ad3ee3e2b5d597c8dcfc3208 UMFileSystemInterface: c70ea7147198b9807080f3597f26236be49b0165
UMImageLoaderInterface: 3976a14c588341228881ff75970fbabf122efca4 UMFontInterface: d9d3b27af698c5389ae9e20b99ef56a083f491fb
UMPermissionsInterface: 2abf9f7f4aa7110e27beaf634a7deda2d50ff3d7 UMImageLoaderInterface: 14dd2c46c67167491effc9e91250e9510f12709e
UMReactNativeAdapter: 230406e3335a8dbd4c9c0e654488a1cf3b44552f UMPermissionsInterface: 5e83a9167c177e4a0f0a3539345983cc749efb3e
UMSensorsInterface: d708a892ef1500bdd9fc3ff03f7836c66d1634d3 UMReactNativeAdapter: 126da3486c1a1f11945b649d557d6c2ebb9407b2
UMTaskManagerInterface: a98e37a576a5220bf43b8faf33cfdc129d2f441d UMSensorsInterface: 48941f70175e2975af1a9386c6d6cb16d8126805
UMTaskManagerInterface: cb890c79c63885504ddc0efd7a7d01481760aca2
Yoga: f2a7cd4280bfe2cca5a7aed98ba0eb3d1310f18b Yoga: f2a7cd4280bfe2cca5a7aed98ba0eb3d1310f18b
PODFILE CHECKSUM: c48a21ff513d3eadafa50f8797207ef2be75e234 PODFILE CHECKSUM: c48a21ff513d3eadafa50f8797207ef2be75e234
COCOAPODS: 1.8.4 COCOAPODS: 1.9.1

View File

@@ -8,25 +8,24 @@ const blacklist = require('metro-config/src/defaults/blacklist');
const root = path.resolve(__dirname, '..'); const root = path.resolve(__dirname, '..');
const packages = path.resolve(root, 'packages'); const packages = path.resolve(root, 'packages');
// Get the list of dependencies for all packages in the monorepo const workspaces = fs
const modules = ['@expo/vector-icons']
.concat(
...fs
// List all packages under `packages/` // List all packages under `packages/`
.readdirSync(packages) .readdirSync(packages)
// Ignore hidden files such as .DS_Store // Ignore hidden files such as .DS_Store
.filter((p) => !p.startsWith('.')) .filter((p) => !p.startsWith('.'))
.map((p) => { .map((p) => path.join(packages, p));
// Get the list of dependencies for all packages in the monorepo
const modules = ['@expo/vector-icons']
.concat(
...workspaces.map((it) => {
const pak = JSON.parse( const pak = JSON.parse(
fs.readFileSync(path.join(packages, p, 'package.json'), 'utf8') fs.readFileSync(path.join(it, 'package.json'), 'utf8')
); );
// We need to collect list of deps that this package imports // We need to make sure that only one version is loaded for peerDependencies
// Collecting both dependencies are peerDependencies should do it // So we blacklist them at the root, and alias them to the versions in example's node_modules
return Object.keys({ return pak.peerDependencies ? Object.keys(pak.peerDependencies) : [];
...pak.dependencies,
...pak.peerDependencies,
});
}) })
) )
.sort() .sort()
@@ -45,14 +44,15 @@ module.exports = {
watchFolders: [root], watchFolders: [root],
resolver: { resolver: {
// We need to blacklist `node_modules` of all our packages // We need to blacklist the peerDependencies we've collected in packages' node_modules
// This will avoid Metro throwing duplicate module errors
blacklistRE: blacklist( blacklistRE: blacklist(
fs [].concat(
.readdirSync(packages) ...workspaces.map((it) =>
.map((p) => path.join(packages, p)) modules.map(
.map( (m) =>
(it) => new RegExp(`^${escape(path.join(it, 'node_modules'))}\\/.*$`) new RegExp(`^${escape(path.join(it, 'node_modules', m))}\\/.*$`)
)
)
) )
), ),

View File

@@ -1,7 +1,7 @@
{ {
"name": "@react-navigation/example", "name": "@react-navigation/example",
"description": "Demo app to showcase various functionality of React Navigation", "description": "Demo app to showcase various functionality of React Navigation",
"version": "5.0.0", "version": "5.1.0",
"private": true, "private": true,
"scripts": { "scripts": {
"start": "expo start", "start": "expo start",
@@ -9,6 +9,7 @@
"native": "react-native start", "native": "react-native start",
"android": "react-native run-android", "android": "react-native run-android",
"ios": "react-native run-ios", "ios": "react-native run-ios",
"server": "nodemon -e '.js,.ts,.tsx' --exec \"babel-node -i '/node_modules[/\\](?react-native)/' -x '.web.tsx,.web.ts,.web.js,.tsx,.ts,.js' --config-file ./server/babel.config.js server\"",
"test": "jest" "test": "jest"
}, },
"dependencies": { "dependencies": {
@@ -18,6 +19,7 @@
"expo": "^37.0.8", "expo": "^37.0.8",
"expo-asset": "~8.1.3", "expo-asset": "~8.1.3",
"expo-blur": "~8.1.0", "expo-blur": "~8.1.0",
"koa": "^2.12.0",
"react": "~16.9.0", "react": "~16.9.0",
"react-dom": "~16.9.0", "react-dom": "~16.9.0",
"react-native": "~0.61.5", "react-native": "~0.61.5",
@@ -25,21 +27,32 @@
"react-native-paper": "^3.10.1", "react-native-paper": "^3.10.1",
"react-native-reanimated": "^1.8.0", "react-native-reanimated": "^1.8.0",
"react-native-restart": "^0.0.15", "react-native-restart": "^0.0.15",
"react-native-safe-area-context": "^0.7.3", "react-native-safe-area-context": "^1.0.0",
"react-native-screens": "^2.7.0", "react-native-screens": "^2.7.0",
"react-native-tab-view": "2.14.0", "react-native-tab-view": "2.14.0",
"react-native-unimodules": "~0.9.1", "react-native-unimodules": "~0.9.1",
"react-native-vector-icons": "^6.6.0",
"react-native-web": "^0.11.7" "react-native-web": "^0.11.7"
}, },
"devDependencies": { "devDependencies": {
"@babel/node": "^7.8.7",
"@expo/webpack-config": "^0.11.19", "@expo/webpack-config": "^0.11.19",
"@types/cheerio": "^0.22.18",
"@types/jest-dev-server": "^4.2.0", "@types/jest-dev-server": "^4.2.0",
"@types/koa": "^2.11.3",
"@types/node-fetch": "^2.5.7",
"@types/react": "^16.9.34", "@types/react": "^16.9.34",
"@types/react-dom": "^16.9.8",
"@types/react-native": "^0.62.7", "@types/react-native": "^0.62.7",
"babel-plugin-module-resolver": "^4.0.0",
"babel-preset-expo": "^8.1.0", "babel-preset-expo": "^8.1.0",
"cheerio": "^1.0.0-rc.3",
"expo-cli": "^3.20.1", "expo-cli": "^3.20.1",
"jest": "^26.0.1", "jest": "^26.0.1",
"jest-dev-server": "^4.4.0", "jest-dev-server": "^4.4.0",
"mock-require-assets": "^0.0.1",
"node-fetch": "^2.6.0",
"nodemon": "^2.0.4",
"playwright": "^0.14.0", "playwright": "^0.14.0",
"serve": "^11.3.0", "serve": "^11.3.0",
"typescript": "^3.8.3" "typescript": "^3.8.3"

View File

@@ -0,0 +1,40 @@
const path = require('path');
const fs = require('fs');
const packages = path.resolve(__dirname, '..', '..', 'packages');
const alias = Object.fromEntries(
fs
.readdirSync(packages)
.filter((name) => !name.startsWith('.'))
.map((name) => [
`@react-navigation/${name}`,
path.resolve(
packages,
name,
require(`../../packages/${name}/package.json`).source
),
])
);
module.exports = {
presets: [
'@babel/preset-env',
'@babel/preset-flow',
'@babel/preset-typescript',
'@babel/preset-react',
],
plugins: [
'@babel/plugin-proposal-class-properties',
[
'module-resolver',
{
root: ['..'],
alias: {
'react-native': 'react-native-web',
...alias,
},
},
],
],
};

54
example/server/index.tsx Normal file
View File

@@ -0,0 +1,54 @@
import './resolve-hooks';
import Koa from 'koa';
import * as React from 'react';
import ReactDOMServer from 'react-dom/server';
import { AppRegistry } from 'react-native-web';
import { ServerContainer, ServerContainerRef } from '@react-navigation/native';
import App from '../src/index';
AppRegistry.registerComponent('App', () => App);
const PORT = process.env.PORT || 3275;
const app = new Koa();
app.use(async (ctx) => {
const { element, getStyleElement } = AppRegistry.getApplication('App');
const ref = React.createRef<ServerContainerRef>();
const html = ReactDOMServer.renderToString(
<ServerContainer
ref={ref}
location={{ pathname: ctx.path, search: ctx.search }}
>
{element}
</ServerContainer>
);
const css = ReactDOMServer.renderToStaticMarkup(getStyleElement());
const document = `
<!DOCTYPE html>
<html style="height: 100%">
<meta charset="utf-8">
<meta httpEquiv="X-UA-Compatible" content="IE=edge">
<meta
name="viewport"
content="width=device-width, initial-scale=1, minimum-scale=1, maximum-scale=1.00001, viewport-fit=cover"
>
${css}
<title>${ref.current?.getCurrentOptions()?.title}</title>
<body style="height: 100%">
<div id="root" style="display: flex; height: 100%">
${html}
</div>
`;
ctx.body = document;
});
app.listen(PORT, () => {
console.log(`Running at http://localhost:${PORT}`);
});

View File

@@ -0,0 +1,12 @@
import 'mock-require-assets';
import Module from 'module';
// We need to make sure that .web.xx extensions are resolved before .xx
// @ts-ignore
Module._extensions = Object.fromEntries(
// @ts-ignore
Object.entries(Module._extensions).sort((a, b) => {
return b[0].split('.').length - a[0].split('.').length;
})
);

View File

@@ -0,0 +1,11 @@
import RNRestart from 'react-native-restart';
import { Updates } from 'expo';
export function restartApp() {
// @ts-ignore
if (global.Expo) {
Updates.reloadFromCache();
} else {
RNRestart.Restart();
}
}

1
example/src/Restart.tsx Normal file
View File

@@ -0,0 +1 @@
export function restartApp() {}

View File

@@ -1,7 +1,11 @@
import * as React from 'react'; import * as React from 'react';
import { Platform } from 'react-native'; import { View, ScrollView, StyleSheet, Platform } from 'react-native';
import { MaterialCommunityIcons } from '@expo/vector-icons'; import { Button } from 'react-native-paper';
import { createBottomTabNavigator } from '@react-navigation/bottom-tabs'; import MaterialCommunityIcons from 'react-native-vector-icons/MaterialCommunityIcons';
import {
createBottomTabNavigator,
BottomTabNavigationProp,
} from '@react-navigation/bottom-tabs';
import TouchableBounce from '../Shared/TouchableBounce'; import TouchableBounce from '../Shared/TouchableBounce';
import Albums from '../Shared/Albums'; import Albums from '../Shared/Albums';
import Contacts from '../Shared/Contacts'; import Contacts from '../Shared/Contacts';
@@ -23,6 +27,36 @@ type BottomTabParams = {
Chat: undefined; Chat: undefined;
}; };
const scrollEnabled = Platform.select({ web: true, default: false });
const AlbumsScreen = ({
navigation,
}: {
navigation: BottomTabNavigationProp<BottomTabParams>;
}) => {
return (
<ScrollView>
<View style={styles.buttons}>
<Button
mode="outlined"
onPress={() => navigation.setOptions({ tabBarVisible: false })}
style={styles.button}
>
Hide tab bar
</Button>
<Button
mode="outlined"
onPress={() => navigation.setOptions({ tabBarVisible: true })}
style={styles.button}
>
Show tab bar
</Button>
</View>
<Albums scrollEnabled={scrollEnabled} />
</ScrollView>
);
};
const BottomTabs = createBottomTabNavigator<BottomTabParams>(); const BottomTabs = createBottomTabNavigator<BottomTabParams>();
export default function BottomTabsScreen() { export default function BottomTabsScreen() {
@@ -62,7 +96,7 @@ export default function BottomTabsScreen() {
/> />
<BottomTabs.Screen <BottomTabs.Screen
name="Albums" name="Albums"
component={Albums} component={AlbumsScreen}
options={{ options={{
title: 'Albums', title: 'Albums',
tabBarIcon: getTabBarIcon('image-album'), tabBarIcon: getTabBarIcon('image-album'),
@@ -71,3 +105,13 @@ export default function BottomTabsScreen() {
</BottomTabs.Navigator> </BottomTabs.Navigator>
); );
} }
const styles = StyleSheet.create({
buttons: {
flexDirection: 'row',
padding: 8,
},
button: {
margin: 8,
},
});

View File

@@ -1,7 +1,7 @@
import * as React from 'react'; import * as React from 'react';
import { View, StyleSheet } from 'react-native'; import { View, StyleSheet } from 'react-native';
import { Title, Button } from 'react-native-paper'; import { Title, Button } from 'react-native-paper';
import { Feather } from '@expo/vector-icons'; import Feather from 'react-native-vector-icons/Feather';
import { createBottomTabNavigator } from '@react-navigation/bottom-tabs'; import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
type BottomTabParams = { type BottomTabParams = {

View File

@@ -17,7 +17,7 @@ import Albums from '../Shared/Albums';
type SimpleStackParams = { type SimpleStackParams = {
Article: { author: string }; Article: { author: string };
Album: undefined; Albums: undefined;
}; };
type SimpleStackNavigation = StackNavigationProp<SimpleStackParams>; type SimpleStackNavigation = StackNavigationProp<SimpleStackParams>;
@@ -53,24 +53,24 @@ const ArticleScreen = ({
<ScrollView> <ScrollView>
<View style={styles.buttons}> <View style={styles.buttons}>
<Link <Link
to="/link-component/Album" to="/link-component/music"
style={[styles.button, { padding: 8 }]} style={[styles.button, { padding: 8 }]}
> >
Go to /link-component/Album Go to /link-component/music
</Link> </Link>
<Link <Link
to="/link-component/Album" to="/link-component/music"
action={StackActions.replace('Album')} action={StackActions.replace('Albums')}
style={[styles.button, { padding: 8 }]} style={[styles.button, { padding: 8 }]}
> >
Replace with /link-component/Album Replace with /link-component/music
</Link> </Link>
<LinkButton <LinkButton
to="/link-component/Album" to="/link-component/music"
mode="contained" mode="contained"
style={styles.button} style={styles.button}
> >
Go to /link-component/Album Go to /link-component/music
</LinkButton> </LinkButton>
<Button <Button
mode="outlined" mode="outlined"
@@ -97,17 +97,17 @@ const AlbumsScreen = ({
<ScrollView> <ScrollView>
<View style={styles.buttons}> <View style={styles.buttons}>
<Link <Link
to="/link-component/Article?author=Babel" to="/link-component/article/babel"
style={[styles.button, { padding: 8 }]} style={[styles.button, { padding: 8 }]}
> >
Go to /link-component/Article Go to /link-component/article
</Link> </Link>
<LinkButton <LinkButton
to="/link-component/Article?author=Babel" to="/link-component/article/babel"
mode="contained" mode="contained"
style={styles.button} style={styles.button}
> >
Go to /link-component/Article Go to /link-component/article
</LinkButton> </LinkButton>
<Button <Button
mode="outlined" mode="outlined"
@@ -144,9 +144,9 @@ export default function SimpleStackScreen({ navigation, ...rest }: Props) {
initialParams={{ author: 'Gandalf' }} initialParams={{ author: 'Gandalf' }}
/> />
<SimpleStack.Screen <SimpleStack.Screen
name="Album" name="Albums"
component={AlbumsScreen} component={AlbumsScreen}
options={{ title: 'Album' }} options={{ title: 'Albums' }}
/> />
</SimpleStack.Navigator> </SimpleStack.Navigator>
); );

View File

@@ -1,12 +1,18 @@
import * as React from 'react'; import * as React from 'react';
import { Dimensions, ScaledSize } from 'react-native'; import { Dimensions, ScaledSize } from 'react-native';
import { Appbar } from 'react-native-paper'; import { Appbar } from 'react-native-paper';
import { ParamListBase } from '@react-navigation/native'; import {
useTheme,
useNavigation,
ParamListBase,
} from '@react-navigation/native';
import { StackNavigationProp } from '@react-navigation/stack'; import { StackNavigationProp } from '@react-navigation/stack';
import { import {
createDrawerNavigator, createDrawerNavigator,
DrawerNavigationProp, DrawerNavigationProp,
DrawerContent, DrawerContent,
DrawerContentComponentProps,
DrawerContentOptions,
} from '@react-navigation/drawer'; } from '@react-navigation/drawer';
import Article from '../Shared/Article'; import Article from '../Shared/Article';
import Albums from '../Shared/Albums'; import Albums from '../Shared/Albums';
@@ -15,7 +21,7 @@ import NewsFeed from '../Shared/NewsFeed';
type DrawerParams = { type DrawerParams = {
Article: undefined; Article: undefined;
NewsFeed: undefined; NewsFeed: undefined;
Album: undefined; Albums: undefined;
}; };
type DrawerNavigation = DrawerNavigationProp<DrawerParams>; type DrawerNavigation = DrawerNavigationProp<DrawerParams>;
@@ -43,10 +49,11 @@ const Header = ({
onGoBack: () => void; onGoBack: () => void;
title: string; title: string;
}) => { }) => {
const { colors } = useTheme();
const isLargeScreen = useIsLargeScreen(); const isLargeScreen = useIsLargeScreen();
return ( return (
<Appbar.Header> <Appbar.Header style={{ backgroundColor: colors.card, elevation: 1 }}>
{isLargeScreen ? null : <Appbar.BackAction onPress={onGoBack} />} {isLargeScreen ? null : <Appbar.BackAction onPress={onGoBack} />}
<Appbar.Content title={title} /> <Appbar.Content title={title} />
</Appbar.Header> </Appbar.Header>
@@ -80,6 +87,23 @@ const AlbumsScreen = ({ navigation }: { navigation: DrawerNavigation }) => {
); );
}; };
const CustomDrawerContent = (
props: DrawerContentComponentProps<DrawerContentOptions>
) => {
const { colors } = useTheme();
const navigation = useNavigation();
return (
<>
<Appbar.Header style={{ backgroundColor: colors.card, elevation: 1 }}>
<Appbar.Action icon="close" onPress={() => navigation.goBack()} />
<Appbar.Content title="Pages" />
</Appbar.Header>
<DrawerContent {...props} />
</>
);
};
const Drawer = createDrawerNavigator<DrawerParams>(); const Drawer = createDrawerNavigator<DrawerParams>();
type Props = Partial<React.ComponentProps<typeof Drawer.Navigator>> & { type Props = Partial<React.ComponentProps<typeof Drawer.Navigator>> & {
@@ -100,15 +124,7 @@ export default function DrawerScreen({ navigation, ...rest }: Props) {
drawerType={isLargeScreen ? 'permanent' : 'back'} drawerType={isLargeScreen ? 'permanent' : 'back'}
drawerStyle={isLargeScreen ? null : { width: '100%' }} drawerStyle={isLargeScreen ? null : { width: '100%' }}
overlayColor="transparent" overlayColor="transparent"
drawerContent={(props) => ( drawerContent={(props) => <CustomDrawerContent {...props} />}
<>
<Appbar.Header>
<Appbar.Action icon="close" onPress={() => navigation.goBack()} />
<Appbar.Content title="Pages" />
</Appbar.Header>
<DrawerContent {...props} />
</>
)}
{...rest} {...rest}
> >
<Drawer.Screen name="Article" component={ArticleScreen} /> <Drawer.Screen name="Article" component={ArticleScreen} />
@@ -118,9 +134,9 @@ export default function DrawerScreen({ navigation, ...rest }: Props) {
options={{ title: 'Feed' }} options={{ title: 'Feed' }}
/> />
<Drawer.Screen <Drawer.Screen
name="Album" name="Albums"
component={AlbumsScreen} component={AlbumsScreen}
options={{ title: 'Album' }} options={{ title: 'Albums' }}
/> />
</Drawer.Navigator> </Drawer.Navigator>
); );

View File

@@ -1,4 +1,6 @@
import * as React from 'react'; import * as React from 'react';
import { ParamListBase } from '@react-navigation/native';
import { StackNavigationProp } from '@react-navigation/stack';
import { createMaterialTopTabNavigator } from '@react-navigation/material-top-tabs'; import { createMaterialTopTabNavigator } from '@react-navigation/material-top-tabs';
import Albums from '../Shared/Albums'; import Albums from '../Shared/Albums';
import Contacts from '../Shared/Contacts'; import Contacts from '../Shared/Contacts';
@@ -12,7 +14,15 @@ type MaterialTopTabParams = {
const MaterialTopTabs = createMaterialTopTabNavigator<MaterialTopTabParams>(); const MaterialTopTabs = createMaterialTopTabNavigator<MaterialTopTabParams>();
export default function MaterialTopTabsScreen() { type Props = {
navigation: StackNavigationProp<ParamListBase>;
};
export default function MaterialTopTabsScreen({ navigation }: Props) {
navigation.setOptions({
cardStyle: { flex: 1 },
});
return ( return (
<MaterialTopTabs.Navigator> <MaterialTopTabs.Navigator>
<MaterialTopTabs.Screen <MaterialTopTabs.Screen

View File

@@ -12,7 +12,7 @@ import Albums from '../Shared/Albums';
type ModalStackParams = { type ModalStackParams = {
Article: { author: string }; Article: { author: string };
Album: undefined; Albums: undefined;
}; };
type ModalStackNavigation = StackNavigationProp<ModalStackParams>; type ModalStackNavigation = StackNavigationProp<ModalStackParams>;
@@ -31,7 +31,7 @@ const ArticleScreen = ({
<View style={styles.buttons}> <View style={styles.buttons}>
<Button <Button
mode="contained" mode="contained"
onPress={() => navigation.push('Album')} onPress={() => navigation.push('Albums')}
style={styles.button} style={styles.button}
> >
Push album Push album
@@ -112,9 +112,9 @@ export default function SimpleStackScreen({ navigation, options }: Props) {
initialParams={{ author: 'Gandalf' }} initialParams={{ author: 'Gandalf' }}
/> />
<ModalPresentationStack.Screen <ModalPresentationStack.Screen
name="Album" name="Albums"
component={AlbumsScreen} component={AlbumsScreen}
options={{ title: 'Album' }} options={{ title: 'Albums' }}
/> />
</ModalPresentationStack.Navigator> </ModalPresentationStack.Navigator>
); );

View File

@@ -13,7 +13,7 @@ import NewsFeed from '../Shared/NewsFeed';
type SimpleStackParams = { type SimpleStackParams = {
Article: { author: string }; Article: { author: string };
NewsFeed: undefined; NewsFeed: undefined;
Album: undefined; Albums: undefined;
}; };
type SimpleStackNavigation = StackNavigationProp<SimpleStackParams>; type SimpleStackNavigation = StackNavigationProp<SimpleStackParams>;
@@ -63,7 +63,7 @@ const NewsFeedScreen = ({
<View style={styles.buttons}> <View style={styles.buttons}>
<Button <Button
mode="contained" mode="contained"
onPress={() => navigation.navigate('Album')} onPress={() => navigation.navigate('Albums')}
style={styles.button} style={styles.button}
> >
Navigate to album Navigate to album
@@ -136,9 +136,9 @@ export default function SimpleStackScreen({ navigation, ...rest }: Props) {
options={{ title: 'Feed' }} options={{ title: 'Feed' }}
/> />
<SimpleStack.Screen <SimpleStack.Screen
name="Album" name="Albums"
component={AlbumsScreen} component={AlbumsScreen}
options={{ title: 'Album' }} options={{ title: 'Albums' }}
/> />
</SimpleStack.Navigator> </SimpleStack.Navigator>
); );

View File

@@ -1,8 +1,7 @@
import * as React from 'react'; import * as React from 'react';
import { View, StyleSheet, ScrollView, Alert, Platform } from 'react-native'; import { View, StyleSheet, ScrollView, Alert, Platform } from 'react-native';
import { Button, Appbar } from 'react-native-paper'; import { Button, Appbar } from 'react-native-paper';
import { BlurView } from 'expo-blur'; import MaterialCommunityIcons from 'react-native-vector-icons/MaterialCommunityIcons';
import { MaterialCommunityIcons } from '@expo/vector-icons';
import { RouteProp, ParamListBase } from '@react-navigation/native'; import { RouteProp, ParamListBase } from '@react-navigation/native';
import { import {
createStackNavigator, createStackNavigator,
@@ -10,12 +9,13 @@ import {
HeaderBackground, HeaderBackground,
useHeaderHeight, useHeaderHeight,
} from '@react-navigation/stack'; } from '@react-navigation/stack';
import BlurView from '../Shared/BlurView';
import Article from '../Shared/Article'; import Article from '../Shared/Article';
import Albums from '../Shared/Albums'; import Albums from '../Shared/Albums';
type SimpleStackParams = { type SimpleStackParams = {
Article: { author: string }; Article: { author: string };
Album: undefined; Albums: undefined;
}; };
type SimpleStackNavigation = StackNavigationProp<SimpleStackParams>; type SimpleStackNavigation = StackNavigationProp<SimpleStackParams>;
@@ -34,7 +34,7 @@ const ArticleScreen = ({
<View style={styles.buttons}> <View style={styles.buttons}>
<Button <Button
mode="contained" mode="contained"
onPress={() => navigation.push('Album')} onPress={() => navigation.push('Albums')}
style={styles.button} style={styles.button}
> >
Push album Push album
@@ -131,10 +131,10 @@ export default function SimpleStackScreen({ navigation, ...rest }: Props) {
initialParams={{ author: 'Gandalf' }} initialParams={{ author: 'Gandalf' }}
/> />
<SimpleStack.Screen <SimpleStack.Screen
name="Album" name="Albums"
component={AlbumsScreen} component={AlbumsScreen}
options={{ options={{
title: 'Album', title: 'Albums',
headerBackTitle: 'Back', headerBackTitle: 'Back',
headerTransparent: true, headerTransparent: true,
headerBackground: () => ( headerBackground: () => (

View File

@@ -0,0 +1,3 @@
import { BlurView } from 'expo-blur';
export default BlurView;

View File

@@ -0,0 +1,12 @@
import * as React from 'react';
import { View, ViewProps } from 'react-native';
type Props = ViewProps & {
tint: 'light' | 'dark';
intensity: number;
};
// eslint-disable-next-line @typescript-eslint/no-unused-vars
export default function BlurView({ tint, intensity, ...rest }: Props) {
return <View {...rest} />;
}

View File

@@ -11,10 +11,7 @@ import {
} from 'react-native'; } from 'react-native';
// eslint-disable-next-line import/no-unresolved // eslint-disable-next-line import/no-unresolved
import { enableScreens } from 'react-native-screens'; import { enableScreens } from 'react-native-screens';
import RNRestart from 'react-native-restart'; import MaterialIcons from 'react-native-vector-icons/MaterialIcons';
import { Updates } from 'expo';
import { Asset } from 'expo-asset';
import { MaterialIcons } from '@expo/vector-icons';
import { import {
Provider as PaperProvider, Provider as PaperProvider,
DefaultTheme as PaperLightTheme, DefaultTheme as PaperLightTheme,
@@ -36,11 +33,11 @@ import {
} from '@react-navigation/drawer'; } from '@react-navigation/drawer';
import { import {
createStackNavigator, createStackNavigator,
Assets as StackAssets,
StackNavigationProp, StackNavigationProp,
HeaderStyleInterpolators, HeaderStyleInterpolators,
} from '@react-navigation/stack'; } from '@react-navigation/stack';
import { restartApp } from './Restart';
import AsyncStorage from './AsyncStorage'; import AsyncStorage from './AsyncStorage';
import LinkingPrefixes from './LinkingPrefixes'; import LinkingPrefixes from './LinkingPrefixes';
import SettingsItem from './Shared/SettingsItem'; import SettingsItem from './Shared/SettingsItem';
@@ -126,12 +123,10 @@ const Stack = createStackNavigator<RootStackParamList>();
const NAVIGATION_PERSISTENCE_KEY = 'NAVIGATION_STATE'; const NAVIGATION_PERSISTENCE_KEY = 'NAVIGATION_STATE';
const THEME_PERSISTENCE_KEY = 'THEME_TYPE'; const THEME_PERSISTENCE_KEY = 'THEME_TYPE';
Asset.loadAsync(StackAssets);
export default function App() { export default function App() {
const [theme, setTheme] = React.useState(DefaultTheme); const [theme, setTheme] = React.useState(DefaultTheme);
const [isReady, setIsReady] = React.useState(false); const [isReady, setIsReady] = React.useState(Platform.OS === 'web');
const [initialState, setInitialState] = React.useState< const [initialState, setInitialState] = React.useState<
InitialState | undefined InitialState | undefined
>(); >();
@@ -239,6 +234,22 @@ export default function App() {
{ Home: '' } { Home: '' }
), ),
}, },
Article: {
path: 'article/:author?',
parse: {
author: (author) =>
author.charAt(0).toUpperCase() +
author.slice(1).replace(/-/g, ' '),
},
stringify: {
author: (author: string) =>
author.toLowerCase().replace(/\s/g, '-'),
},
},
Albums: 'music',
Chat: 'chat',
Contacts: 'people',
NewsFeed: 'feed',
}, },
}} }}
fallback={<Text>Loading</Text>} fallback={<Text>Loading</Text>}
@@ -291,12 +302,7 @@ export default function App() {
value={I18nManager.isRTL} value={I18nManager.isRTL}
onValueChange={() => { onValueChange={() => {
I18nManager.forceRTL(!I18nManager.isRTL); I18nManager.forceRTL(!I18nManager.isRTL);
// @ts-ignore restartApp();
if (global.Expo) {
Updates.reloadFromCache();
} else {
RNRestart.Restart();
}
}} }}
/> />
<Divider /> <Divider />

16
example/types/react-native-web.d.ts vendored Normal file
View File

@@ -0,0 +1,16 @@
declare module 'react-native-web' {
export const AppRegistry: {
registerComponent(
name: string,
callback: () => React.ComponentType<any>
): void;
getApplication(
name: string,
options?: { initialProps: object }
): {
element: React.ReactElement;
getStyleElement(): React.ReactElement;
};
};
}

View File

@@ -13,7 +13,7 @@
"license": "MIT", "license": "MIT",
"repository": { "repository": {
"type": "git", "type": "git",
"url": "git+https://github.com/satya164/react-navigation.git" "url": "git+https://github.com/react-navigation/react-navigation.git"
}, },
"author": "Satyajit Sahoo <satyajit.happy@gmail.com> (https://github.com/satya164/), Michał Osadnik <micosa97@gmail.com> (https://github.com/osdnk/)", "author": "Satyajit Sahoo <satyajit.happy@gmail.com> (https://github.com/satya164/), Michał Osadnik <micosa97@gmail.com> (https://github.com/osdnk/)",
"scripts": { "scripts": {

View File

@@ -3,6 +3,61 @@
All notable changes to this project will be documented in this file. All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [5.5.1](https://github.com/react-navigation/react-navigation/tree/master/packages/bottom-tabs/compare/@react-navigation/bottom-tabs@5.5.0...@react-navigation/bottom-tabs@5.5.1) (2020-05-27)
### Bug Fixes
* fix type of style for various options ([9d822b9](https://github.com/react-navigation/react-navigation/tree/master/packages/bottom-tabs/commit/9d822b95a6df797e2e63e481573e64ea7d0f9386))
# [5.5.0](https://github.com/react-navigation/react-navigation/tree/master/packages/bottom-tabs/compare/@react-navigation/bottom-tabs@5.4.7...@react-navigation/bottom-tabs@5.5.0) (2020-05-23)
### Features
* animate changes to tabBarVisible in BottomTabBar ([#8286](https://github.com/react-navigation/react-navigation/tree/master/packages/bottom-tabs/issues/8286)) ([c1e46f8](https://github.com/react-navigation/react-navigation/tree/master/packages/bottom-tabs/commit/c1e46f8e331e0054995aa476455af204d02d4170))
* update react-native-safe-area-context to 1.0.0 ([#8182](https://github.com/react-navigation/react-navigation/tree/master/packages/bottom-tabs/issues/8182)) ([d62fbfe](https://github.com/react-navigation/react-navigation/tree/master/packages/bottom-tabs/commit/d62fbfe255140f16b182e8b54b276a7c96f2aec6))
## [5.4.7](https://github.com/react-navigation/react-navigation/tree/master/packages/bottom-tabs/compare/@react-navigation/bottom-tabs@5.4.6...@react-navigation/bottom-tabs@5.4.7) (2020-05-20)
**Note:** Version bump only for package @react-navigation/bottom-tabs
## [5.4.6](https://github.com/react-navigation/react-navigation/tree/master/packages/bottom-tabs/compare/@react-navigation/bottom-tabs@5.4.5...@react-navigation/bottom-tabs@5.4.6) (2020-05-20)
**Note:** Version bump only for package @react-navigation/bottom-tabs
## [5.4.5](https://github.com/react-navigation/react-navigation/tree/master/packages/bottom-tabs/compare/@react-navigation/bottom-tabs@5.4.4...@react-navigation/bottom-tabs@5.4.5) (2020-05-16)
**Note:** Version bump only for package @react-navigation/bottom-tabs
## [5.4.4](https://github.com/react-navigation/react-navigation/tree/master/packages/bottom-tabs/compare/@react-navigation/bottom-tabs@5.4.3...@react-navigation/bottom-tabs@5.4.4) (2020-05-14)
**Note:** Version bump only for package @react-navigation/bottom-tabs
## [5.4.3](https://github.com/react-navigation/react-navigation/tree/master/packages/bottom-tabs/compare/@react-navigation/bottom-tabs@5.4.2...@react-navigation/bottom-tabs@5.4.3) (2020-05-14) ## [5.4.3](https://github.com/react-navigation/react-navigation/tree/master/packages/bottom-tabs/compare/@react-navigation/bottom-tabs@5.4.2...@react-navigation/bottom-tabs@5.4.3) (2020-05-14)
**Note:** Version bump only for package @react-navigation/bottom-tabs **Note:** Version bump only for package @react-navigation/bottom-tabs

View File

@@ -1,7 +1,7 @@
{ {
"name": "@react-navigation/bottom-tabs", "name": "@react-navigation/bottom-tabs",
"description": "Bottom tab navigator following iOS design guidelines", "description": "Bottom tab navigator following iOS design guidelines",
"version": "5.4.3", "version": "5.5.1",
"keywords": [ "keywords": [
"react-native-component", "react-native-component",
"react-component", "react-component",
@@ -20,7 +20,8 @@
"types": "lib/typescript/src/index.d.ts", "types": "lib/typescript/src/index.d.ts",
"files": [ "files": [
"src", "src",
"lib" "lib",
"!**/__tests__"
], ],
"sideEffects": false, "sideEffects": false,
"publishConfig": { "publishConfig": {
@@ -35,15 +36,15 @@
"react-native-iphone-x-helper": "^1.2.1" "react-native-iphone-x-helper": "^1.2.1"
}, },
"devDependencies": { "devDependencies": {
"@react-native-community/bob": "^0.13.1", "@react-native-community/bob": "^0.14.3",
"@react-navigation/native": "^5.3.1", "@react-navigation/native": "^5.5.0",
"@types/color": "^3.0.1", "@types/color": "^3.0.1",
"@types/react": "^16.9.34", "@types/react": "^16.9.34",
"@types/react-native": "^0.62.7", "@types/react-native": "^0.62.7",
"del-cli": "^3.0.0", "del-cli": "^3.0.0",
"react": "~16.9.0", "react": "~16.9.0",
"react-native": "~0.61.5", "react-native": "~0.61.5",
"react-native-safe-area-context": "^0.7.3", "react-native-safe-area-context": "^1.0.0",
"react-native-screens": "^2.7.0", "react-native-screens": "^2.7.0",
"typescript": "^3.8.3" "typescript": "^3.8.3"
}, },

View File

@@ -1,5 +1,6 @@
import * as React from 'react'; import * as React from 'react';
import { import {
Animated,
TouchableWithoutFeedbackProps, TouchableWithoutFeedbackProps,
StyleProp, StyleProp,
TextStyle, TextStyle,
@@ -197,7 +198,7 @@ export type BottomTabBarOptions = {
/** /**
* Style object for the tab bar container. * Style object for the tab bar container.
*/ */
style?: StyleProp<ViewStyle>; style?: Animated.WithAnimatedValue<StyleProp<ViewStyle>>;
}; };
export type BottomTabBarProps = BottomTabBarOptions & { export type BottomTabBarProps = BottomTabBarOptions & {

View File

@@ -53,52 +53,60 @@ export default function BottomTabBar({
const { colors } = useTheme(); const { colors } = useTheme();
const buildLink = useLinkBuilder(); const buildLink = useLinkBuilder();
const [dimensions, setDimensions] = React.useState(() => { const focusedRoute = state.routes[state.index];
const { height = 0, width = 0 } = Dimensions.get('window'); const focusedDescriptor = descriptors[focusedRoute.key];
const focusedOptions = focusedDescriptor.options;
return { height, width }; const [isKeyboardShown, setIsKeyboardShown] = React.useState(false);
});
const [layout, setLayout] = React.useState({ const shouldShowTabBar =
height: 0, focusedOptions.tabBarVisible !== false &&
width: dimensions.width, !(keyboardHidesTabBar && isKeyboardShown);
});
const [keyboardShown, setKeyboardShown] = React.useState(false);
const [visible] = React.useState(() => new Animated.Value(1)); const [isTabBarHidden, setIsTabBarHidden] = React.useState(!shouldShowTabBar);
const { routes } = state; const [visible] = React.useState(
() => new Animated.Value(shouldShowTabBar ? 1 : 0)
);
React.useEffect(() => { React.useEffect(() => {
if (keyboardShown) { if (shouldShowTabBar) {
Animated.timing(visible, {
toValue: 0,
duration: 200,
useNativeDriver,
}).start();
}
}, [keyboardShown, visible]);
React.useEffect(() => {
const handleOrientationChange = ({ window }: { window: ScaledSize }) => {
setDimensions(window);
};
const handleKeyboardShow = () => setKeyboardShown(true);
const handleKeyboardHide = () =>
Animated.timing(visible, { Animated.timing(visible, {
toValue: 1, toValue: 1,
duration: 250, duration: 250,
useNativeDriver, useNativeDriver,
}).start(({ finished }) => { }).start(({ finished }) => {
if (finished) { if (finished) {
setKeyboardShown(false); setIsTabBarHidden(false);
} }
}); });
} else {
setIsTabBarHidden(true);
Animated.timing(visible, {
toValue: 0,
duration: 200,
useNativeDriver,
}).start();
}
}, [shouldShowTabBar, visible]);
const [dimensions, setDimensions] = React.useState(() => {
const { height = 0, width = 0 } = Dimensions.get('window');
return { height, width };
});
React.useEffect(() => {
const handleOrientationChange = ({ window }: { window: ScaledSize }) => {
setDimensions(window);
};
Dimensions.addEventListener('change', handleOrientationChange); Dimensions.addEventListener('change', handleOrientationChange);
const handleKeyboardShow = () => setIsKeyboardShown(true);
const handleKeyboardHide = () => setIsKeyboardShown(false);
if (Platform.OS === 'ios') { if (Platform.OS === 'ios') {
Keyboard.addListener('keyboardWillShow', handleKeyboardShow); Keyboard.addListener('keyboardWillShow', handleKeyboardShow);
Keyboard.addListener('keyboardWillHide', handleKeyboardHide); Keyboard.addListener('keyboardWillHide', handleKeyboardHide);
@@ -118,7 +126,12 @@ export default function BottomTabBar({
Keyboard.removeListener('keyboardDidHide', handleKeyboardHide); Keyboard.removeListener('keyboardDidHide', handleKeyboardHide);
} }
}; };
}, [visible]); }, []);
const [layout, setLayout] = React.useState({
height: 0,
width: dimensions.width,
});
const handleLayout = (e: LayoutChangeEvent) => { const handleLayout = (e: LayoutChangeEvent) => {
const { height, width } = e.nativeEvent.layout; const { height, width } = e.nativeEvent.layout;
@@ -135,6 +148,7 @@ export default function BottomTabBar({
}); });
}; };
const { routes } = state;
const shouldUseHorizontalLabels = () => { const shouldUseHorizontalLabels = () => {
if (labelPosition) { if (labelPosition) {
return labelPosition === 'beside-icon'; return labelPosition === 'beside-icon';
@@ -183,22 +197,19 @@ export default function BottomTabBar({
backgroundColor: colors.card, backgroundColor: colors.card,
borderTopColor: colors.border, borderTopColor: colors.border,
}, },
keyboardHidesTabBar {
? {
// When the keyboard is shown, slide down the tab bar
transform: [ transform: [
{ {
translateY: visible.interpolate({ translateY: visible.interpolate({
inputRange: [0, 1], inputRange: [0, 1],
outputRange: [layout.height, 0], outputRange: [layout.height + insets.bottom, 0],
}), }),
}, },
], ],
// Absolutely position the tab bar so that the content is below it // Absolutely position the tab bar so that the content is below it
// This is needed to avoid gap at bottom when the tab bar is hidden // This is needed to avoid gap at bottom when the tab bar is hidden
position: keyboardShown ? 'absolute' : null, position: isTabBarHidden ? 'absolute' : null,
} },
: null,
{ {
height: DEFAULT_TABBAR_HEIGHT + insets.bottom, height: DEFAULT_TABBAR_HEIGHT + insets.bottom,
paddingBottom: insets.bottom, paddingBottom: insets.bottom,
@@ -206,7 +217,7 @@ export default function BottomTabBar({
}, },
style, style,
]} ]}
pointerEvents={keyboardHidesTabBar && keyboardShown ? 'none' : 'auto'} pointerEvents={isTabBarHidden ? 'none' : 'auto'}
> >
<View style={styles.content} onLayout={handleLayout}> <View style={styles.content} onLayout={handleLayout}>
{routes.map((route, index) => { {routes.map((route, index) => {

View File

@@ -1,8 +1,8 @@
import React from 'react'; import React from 'react';
import { import {
View, View,
Text,
TouchableWithoutFeedback, TouchableWithoutFeedback,
Animated,
StyleSheet, StyleSheet,
Platform, Platform,
StyleProp, StyleProp,
@@ -191,7 +191,7 @@ export default function BottomTabBarItem({
if (typeof label === 'string') { if (typeof label === 'string') {
return ( return (
<Animated.Text <Text
numberOfLines={1} numberOfLines={1}
style={[ style={[
styles.label, styles.label,
@@ -202,14 +202,10 @@ export default function BottomTabBarItem({
allowFontScaling={allowFontScaling} allowFontScaling={allowFontScaling}
> >
{label} {label}
</Animated.Text> </Text>
); );
} }
if (typeof label === 'string') {
return label;
}
return label({ focused, color }); return label({ focused, color });
}; };

View File

@@ -75,17 +75,8 @@ export default class BottomTabView extends React.Component<Props, State> {
tabBarOptions, tabBarOptions,
state, state,
navigation, navigation,
descriptors,
} = this.props; } = this.props;
const { descriptors } = this.props;
const route = state.routes[state.index];
const descriptor = descriptors[route.key];
const options = descriptor.options;
if (options.tabBarVisible === false) {
return null;
}
return tabBar({ return tabBar({
...tabBarOptions, ...tabBarOptions,
state: state, state: state,

View File

@@ -3,6 +3,54 @@
All notable changes to this project will be documented in this file. All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [5.1.25](https://github.com/react-navigation/react-navigation/tree/master/packages/compat/compare/@react-navigation/compat@5.1.24...@react-navigation/compat@5.1.25) (2020-05-27)
**Note:** Version bump only for package @react-navigation/compat
## [5.1.24](https://github.com/react-navigation/react-navigation/tree/master/packages/compat/compare/@react-navigation/compat@5.1.23...@react-navigation/compat@5.1.24) (2020-05-23)
**Note:** Version bump only for package @react-navigation/compat
## [5.1.23](https://github.com/react-navigation/react-navigation/tree/master/packages/compat/compare/@react-navigation/compat@5.1.22...@react-navigation/compat@5.1.23) (2020-05-20)
**Note:** Version bump only for package @react-navigation/compat
## [5.1.22](https://github.com/react-navigation/react-navigation/tree/master/packages/compat/compare/@react-navigation/compat@5.1.21...@react-navigation/compat@5.1.22) (2020-05-20)
**Note:** Version bump only for package @react-navigation/compat
## [5.1.21](https://github.com/react-navigation/react-navigation/tree/master/packages/compat/compare/@react-navigation/compat@5.1.20...@react-navigation/compat@5.1.21) (2020-05-16)
**Note:** Version bump only for package @react-navigation/compat
## [5.1.20](https://github.com/react-navigation/react-navigation/tree/master/packages/compat/compare/@react-navigation/compat@5.1.19...@react-navigation/compat@5.1.20) (2020-05-14)
**Note:** Version bump only for package @react-navigation/compat
## [5.1.19](https://github.com/react-navigation/react-navigation/tree/master/packages/compat/compare/@react-navigation/compat@5.1.18...@react-navigation/compat@5.1.19) (2020-05-14) ## [5.1.19](https://github.com/react-navigation/react-navigation/tree/master/packages/compat/compare/@react-navigation/compat@5.1.18...@react-navigation/compat@5.1.19) (2020-05-14)
**Note:** Version bump only for package @react-navigation/compat **Note:** Version bump only for package @react-navigation/compat

View File

@@ -1,7 +1,7 @@
{ {
"name": "@react-navigation/compat", "name": "@react-navigation/compat",
"description": "Compatibility layer to write navigator definitions in static configuration format", "description": "Compatibility layer to write navigator definitions in static configuration format",
"version": "5.1.19", "version": "5.1.25",
"license": "MIT", "license": "MIT",
"repository": "https://github.com/react-navigation/react-navigation/tree/master/packages/compat", "repository": "https://github.com/react-navigation/react-navigation/tree/master/packages/compat",
"bugs": { "bugs": {
@@ -15,7 +15,8 @@
"types": "lib/typescript/src/index.d.ts", "types": "lib/typescript/src/index.d.ts",
"files": [ "files": [
"src", "src",
"lib" "lib",
"!**/__tests__"
], ],
"sideEffects": false, "sideEffects": false,
"publishConfig": { "publishConfig": {
@@ -26,8 +27,8 @@
"clean": "del lib" "clean": "del lib"
}, },
"devDependencies": { "devDependencies": {
"@react-native-community/bob": "^0.13.1", "@react-native-community/bob": "^0.14.3",
"@react-navigation/native": "^5.3.1", "@react-navigation/native": "^5.5.0",
"@types/react": "^16.9.34", "@types/react": "^16.9.34",
"react": "~16.9.0", "react": "~16.9.0",
"typescript": "^3.8.3" "typescript": "^3.8.3"

View File

@@ -3,6 +3,72 @@
All notable changes to this project will be documented in this file. All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
# [5.9.0](https://github.com/react-navigation/react-navigation/tree/master/packages/core/compare/@react-navigation/core@5.8.2...@react-navigation/core@5.9.0) (2020-05-27)
### Features
* add ref to get current options in `ServerContainer` ([#8333](https://github.com/react-navigation/react-navigation/tree/master/packages/core/issues/8333)) ([0b1a718](https://github.com/react-navigation/react-navigation/tree/master/packages/core/commit/0b1a718756e208d84b20e45ca56004332308ad54))
## [5.8.2](https://github.com/react-navigation/react-navigation/tree/master/packages/core/compare/@react-navigation/core@5.8.1...@react-navigation/core@5.8.2) (2020-05-23)
**Note:** Version bump only for package @react-navigation/core
## [5.8.1](https://github.com/react-navigation/react-navigation/tree/master/packages/core/compare/@react-navigation/core@5.8.0...@react-navigation/core@5.8.1) (2020-05-20)
**Note:** Version bump only for package @react-navigation/core
# [5.8.0](https://github.com/react-navigation/react-navigation/tree/master/packages/core/compare/@react-navigation/core@5.7.0...@react-navigation/core@5.8.0) (2020-05-20)
### Features
* add getCurrentOptions ([#8277](https://github.com/react-navigation/react-navigation/tree/master/packages/core/issues/8277)) ([d024ec6](https://github.com/react-navigation/react-navigation/tree/master/packages/core/commit/d024ec6d74dffe481ce6fde732c729e20c1668f4))
* add getCurrentRoute ([#8254](https://github.com/react-navigation/react-navigation/tree/master/packages/core/issues/8254)) ([7b25c8e](https://github.com/react-navigation/react-navigation/tree/master/packages/core/commit/7b25c8eb2e6f96128fd86b92615346ce55bedeca))
# [5.7.0](https://github.com/react-navigation/react-navigation/tree/master/packages/core/compare/@react-navigation/core@5.6.1...@react-navigation/core@5.7.0) (2020-05-16)
### Bug Fixes
* don't use Object.fromEntries ([51f4d11](https://github.com/react-navigation/react-navigation/tree/master/packages/core/commit/51f4d11fdf4bd2bb06f8cd4094f051816590e62c))
### Features
* add a PathConfig type ([60cb3c9](https://github.com/react-navigation/react-navigation/tree/master/packages/core/commit/60cb3c9ba76d7ef166c9fe8b55f23728975b5b6e))
## [5.6.1](https://github.com/react-navigation/react-navigation/tree/master/packages/core/compare/@react-navigation/core@5.6.0...@react-navigation/core@5.6.1) (2020-05-14)
### Bug Fixes
* don't use flat since it's not supported in node ([21b397f](https://github.com/react-navigation/react-navigation/tree/master/packages/core/commit/21b397f0d6b96ec4875d3172f47533130bb08009))
# [5.6.0](https://github.com/react-navigation/react-navigation/tree/master/packages/core/compare/@react-navigation/core@5.5.2...@react-navigation/core@5.6.0) (2020-05-14) # [5.6.0](https://github.com/react-navigation/react-navigation/tree/master/packages/core/compare/@react-navigation/core@5.5.2...@react-navigation/core@5.6.0) (2020-05-14)

View File

@@ -1,7 +1,7 @@
{ {
"name": "@react-navigation/core", "name": "@react-navigation/core",
"description": "Core utilities for building navigators", "description": "Core utilities for building navigators",
"version": "5.6.0", "version": "5.9.0",
"keywords": [ "keywords": [
"react", "react",
"react-native", "react-native",
@@ -20,7 +20,8 @@
"types": "lib/typescript/src/index.d.ts", "types": "lib/typescript/src/index.d.ts",
"files": [ "files": [
"src", "src",
"lib" "lib",
"!**/__tests__"
], ],
"publishConfig": { "publishConfig": {
"access": "public" "access": "public"
@@ -30,7 +31,7 @@
"clean": "del lib" "clean": "del lib"
}, },
"dependencies": { "dependencies": {
"@react-navigation/routers": "^5.4.4", "@react-navigation/routers": "^5.4.7",
"escape-string-regexp": "^4.0.0", "escape-string-regexp": "^4.0.0",
"nanoid": "^3.1.5", "nanoid": "^3.1.5",
"query-string": "^6.12.1", "query-string": "^6.12.1",
@@ -38,7 +39,7 @@
"use-subscription": "^1.4.0" "use-subscription": "^1.4.0"
}, },
"devDependencies": { "devDependencies": {
"@react-native-community/bob": "^0.13.1", "@react-native-community/bob": "^0.14.3",
"@types/react": "^16.9.34", "@types/react": "^16.9.34",
"@types/react-is": "^16.7.1", "@types/react-is": "^16.7.1",
"@types/use-subscription": "^1.0.0", "@types/use-subscription": "^1.0.0",

View File

@@ -13,49 +13,22 @@ import { ScheduleUpdateContext } from './useScheduleUpdate';
import useFocusedListeners from './useFocusedListeners'; import useFocusedListeners from './useFocusedListeners';
import useDevTools from './useDevTools'; import useDevTools from './useDevTools';
import useStateGetters from './useStateGetters'; import useStateGetters from './useStateGetters';
import useOptionsGetters from './useOptionsGetters';
import useEventEmitter from './useEventEmitter'; import useEventEmitter from './useEventEmitter';
import useSyncState from './useSyncState'; import useSyncState from './useSyncState';
import isSerializable from './isSerializable'; import isSerializable from './isSerializable';
import { NavigationContainerRef, NavigationContainerProps } from './types'; import { NavigationContainerRef, NavigationContainerProps } from './types';
import NavigationStateContext from './NavigationStateContext';
type State = NavigationState | PartialState<NavigationState> | undefined; type State = NavigationState | PartialState<NavigationState> | undefined;
const DEVTOOLS_CONFIG_KEY = const DEVTOOLS_CONFIG_KEY =
'REACT_NAVIGATION_REDUX_DEVTOOLS_EXTENSION_INTEGRATION_ENABLED'; 'REACT_NAVIGATION_REDUX_DEVTOOLS_EXTENSION_INTEGRATION_ENABLED';
const MISSING_CONTEXT_ERROR =
"Couldn't find a navigation context. Have you wrapped your app with 'NavigationContainer'? See https://reactnavigation.org/docs/getting-started for setup instructions.";
const NOT_INITIALIZED_ERROR = const NOT_INITIALIZED_ERROR =
"The 'navigation' object hasn't been initialized yet. This might happen if you don't have a navigator mounted, or if the navigator hasn't finished mounting. See https://reactnavigation.org/docs/navigating-without-navigation-prop#handling-initialization for more details."; "The 'navigation' object hasn't been initialized yet. This might happen if you don't have a navigator mounted, or if the navigator hasn't finished mounting. See https://reactnavigation.org/docs/navigating-without-navigation-prop#handling-initialization for more details.";
export const NavigationStateContext = React.createContext<{
isDefault?: true;
state?: NavigationState | PartialState<NavigationState>;
getKey: () => string | undefined;
setKey: (key: string) => void;
getState: () => NavigationState | PartialState<NavigationState> | undefined;
setState: (
state: NavigationState | PartialState<NavigationState> | undefined
) => void;
}>({
isDefault: true,
get getKey(): any {
throw new Error(MISSING_CONTEXT_ERROR);
},
get setKey(): any {
throw new Error(MISSING_CONTEXT_ERROR);
},
get getState(): any {
throw new Error(MISSING_CONTEXT_ERROR);
},
get setState(): any {
throw new Error(MISSING_CONTEXT_ERROR);
},
});
let hasWarnedForSerialization = false; let hasWarnedForSerialization = false;
/** /**
@@ -199,8 +172,21 @@ const BaseNavigationContainer = React.forwardRef(
return getStateForRoute('root'); return getStateForRoute('root');
}, [getStateForRoute]); }, [getStateForRoute]);
const getCurrentRoute = React.useCallback(() => {
let state = getRootState();
if (state === undefined) {
return undefined;
}
while (state.routes[state.index].state !== undefined) {
state = state.routes[state.index].state as NavigationState;
}
return state.routes[state.index];
}, [getRootState]);
const emitter = useEventEmitter(); const emitter = useEventEmitter();
const { addOptionsGetter, getCurrentOptions } = useOptionsGetters({});
React.useImperativeHandle(ref, () => ({ React.useImperativeHandle(ref, () => ({
...(Object.keys(CommonActions) as (keyof typeof CommonActions)[]).reduce< ...(Object.keys(CommonActions) as (keyof typeof CommonActions)[]).reduce<
any any
@@ -221,6 +207,8 @@ const BaseNavigationContainer = React.forwardRef(
getRootState, getRootState,
dangerouslyGetState: () => state, dangerouslyGetState: () => state,
dangerouslyGetParent: () => undefined, dangerouslyGetParent: () => undefined,
getCurrentRoute,
getCurrentOptions,
})); }));
const builderContext = React.useMemo( const builderContext = React.useMemo(
@@ -244,8 +232,9 @@ const BaseNavigationContainer = React.forwardRef(
setState, setState,
getKey, getKey,
setKey, setKey,
addOptionsGetter,
}), }),
[getKey, getState, setKey, setState, state] [getKey, getState, setKey, setState, state, addOptionsGetter]
); );
React.useEffect(() => { React.useEffect(() => {

View File

@@ -0,0 +1,11 @@
import * as React from 'react';
/**
* Context which holds the values for the current navigation tree.
* Intended for use in SSR. This is not safe to use on the client.
*/
const CurrentRenderContext = React.createContext<
{ options?: object } | undefined
>(undefined);
export default CurrentRenderContext;

View File

@@ -0,0 +1,35 @@
import * as React from 'react';
import { NavigationState, PartialState } from '@react-navigation/routers';
const MISSING_CONTEXT_ERROR =
"Couldn't find a navigation context. Have you wrapped your app with 'NavigationContainer'? See https://reactnavigation.org/docs/getting-started for setup instructions.";
export default React.createContext<{
isDefault?: true;
state?: NavigationState | PartialState<NavigationState>;
getKey: () => string | undefined;
setKey: (key: string) => void;
getState: () => NavigationState | PartialState<NavigationState> | undefined;
setState: (
state: NavigationState | PartialState<NavigationState> | undefined
) => void;
addOptionsGetter?: (
key: string,
getter: () => object | undefined | null
) => void;
}>({
isDefault: true,
get getKey(): any {
throw new Error(MISSING_CONTEXT_ERROR);
},
get setKey(): any {
throw new Error(MISSING_CONTEXT_ERROR);
},
get getState(): any {
throw new Error(MISSING_CONTEXT_ERROR);
},
get setState(): any {
throw new Error(MISSING_CONTEXT_ERROR);
},
});

View File

@@ -5,12 +5,13 @@ import {
NavigationState, NavigationState,
PartialState, PartialState,
} from '@react-navigation/routers'; } from '@react-navigation/routers';
import { NavigationStateContext } from './BaseNavigationContainer'; import NavigationStateContext from './NavigationStateContext';
import NavigationContext from './NavigationContext'; import NavigationContext from './NavigationContext';
import NavigationRouteContext from './NavigationRouteContext'; import NavigationRouteContext from './NavigationRouteContext';
import StaticContainer from './StaticContainer'; import StaticContainer from './StaticContainer';
import EnsureSingleNavigator from './EnsureSingleNavigator'; import EnsureSingleNavigator from './EnsureSingleNavigator';
import { NavigationProp, RouteConfig, EventMapBase } from './types'; import { NavigationProp, RouteConfig, EventMapBase } from './types';
import useOptionsGetters from './useOptionsGetters';
type Props< type Props<
State extends NavigationState, State extends NavigationState,
@@ -24,6 +25,7 @@ type Props<
}; };
getState: () => State; getState: () => State;
setState: (state: State) => void; setState: (state: State) => void;
options: object;
}; };
/** /**
@@ -40,11 +42,24 @@ export default function SceneView<
navigation, navigation,
getState, getState,
setState, setState,
options,
}: Props<State, ScreenOptions, EventMap>) { }: Props<State, ScreenOptions, EventMap>) {
const navigatorKeyRef = React.useRef<string | undefined>(); const navigatorKeyRef = React.useRef<string | undefined>();
const getKey = React.useCallback(() => navigatorKeyRef.current, []); const getKey = React.useCallback(() => navigatorKeyRef.current, []);
const optionsRef = React.useRef<object | undefined>(options);
React.useEffect(() => {
optionsRef.current = options;
}, [options]);
const getOptions = React.useCallback(() => optionsRef.current, []);
const { addOptionsGetter } = useOptionsGetters({
key: route.key,
getOptions,
});
const setKey = React.useCallback((key: string) => { const setKey = React.useCallback((key: string) => {
navigatorKeyRef.current = key; navigatorKeyRef.current = key;
}, []); }, []);
@@ -77,8 +92,16 @@ export default function SceneView<
setState: setCurrentState, setState: setCurrentState,
getKey, getKey,
setKey, setKey,
addOptionsGetter,
}), }),
[getCurrentState, getKey, route.state, setCurrentState, setKey] [
getCurrentState,
getKey,
route.state,
setCurrentState,
setKey,
addOptionsGetter,
]
); );
return ( return (

View File

@@ -5,9 +5,8 @@ import {
NavigationState, NavigationState,
Router, Router,
} from '@react-navigation/routers'; } from '@react-navigation/routers';
import BaseNavigationContainer, { import BaseNavigationContainer from '../BaseNavigationContainer';
NavigationStateContext, import NavigationStateContext from '../NavigationStateContext';
} from '../BaseNavigationContainer';
import MockRouter, { MockActions } from './__fixtures__/MockRouter'; import MockRouter, { MockActions } from './__fixtures__/MockRouter';
import useNavigationBuilder from '../useNavigationBuilder'; import useNavigationBuilder from '../useNavigationBuilder';
import Screen from '../Screen'; import Screen from '../Screen';

View File

@@ -1490,3 +1490,128 @@ it("doesn't throw if children is null", () => {
expect(() => render(element).update(element)).not.toThrowError(); expect(() => render(element).update(element)).not.toThrowError();
}); });
it('returns currently focused route with getCurrentRoute', () => {
const TestNavigator = (props: any): any => {
const { state, descriptors } = useNavigationBuilder(MockRouter, props);
return descriptors[state.routes[state.index].key].render();
};
const TestScreen = () => null;
const navigation = React.createRef<NavigationContainerRef>();
const container = (
<BaseNavigationContainer ref={navigation}>
<TestNavigator>
<Screen name="bar" options={{ a: 'b' }}>
{() => (
<TestNavigator initialRouteName="bar-a">
<Screen
name="bar-a"
component={TestScreen}
options={{ sample: 'data' }}
/>
</TestNavigator>
)}
</Screen>
<Screen name="xux" component={TestScreen} />
</TestNavigator>
</BaseNavigationContainer>
);
render(container).update(container);
expect(navigation.current?.getCurrentRoute()).toEqual({
key: 'bar-a',
name: 'bar-a',
});
});
it("returns currently focused route's options with getCurrentOptions", () => {
const TestNavigator = (props: any): any => {
const { state, descriptors } = useNavigationBuilder(MockRouter, props);
return descriptors[state.routes[state.index].key].render();
};
const TestScreen = () => null;
const navigation = React.createRef<NavigationContainerRef>();
const container = (
<BaseNavigationContainer ref={navigation}>
<TestNavigator>
<Screen name="bar" options={{ a: 'b' }}>
{() => (
<TestNavigator
initialRouteName="bar-a"
screenOptions={() => ({ sample2: 'data' })}
>
<Screen
name="bar-a"
component={TestScreen}
options={{ sample: 'data' }}
/>
</TestNavigator>
)}
</Screen>
<Screen name="xux" component={TestScreen} />
</TestNavigator>
</BaseNavigationContainer>
);
render(container).update(container);
expect(navigation.current?.getCurrentOptions()).toEqual({
sample: 'data',
sample2: 'data',
});
});
it('does not throw if while getting current options with no options defined', () => {
const TestNavigator = (props: any): any => {
const { state, descriptors } = useNavigationBuilder(MockRouter, props);
return descriptors[state.routes[state.index].key].render();
};
const TestScreen = () => null;
const navigation = React.createRef<NavigationContainerRef>();
const container = (
<BaseNavigationContainer ref={navigation}>
<TestNavigator>
<Screen name="bar" options={{ a: 'b' }}>
{() => (
<TestNavigator initialRouteName="bar-a">
<Screen
name="bar-b"
component={TestScreen}
options={{ wrongKey: true }}
/>
<Screen name="bar-a" component={TestScreen} />
</TestNavigator>
)}
</Screen>
</TestNavigator>
</BaseNavigationContainer>
);
render(container).update(container);
expect(navigation.current?.getCurrentOptions()).toEqual({});
});
it('does not throw if while getting current options with empty container', () => {
const navigation = React.createRef<NavigationContainerRef>();
// @ts-ignore
const container = <BaseNavigationContainer ref={navigation} />;
render(container).update(container);
expect(navigation.current?.getCurrentOptions()).toEqual(undefined);
});

View File

@@ -4,19 +4,19 @@ import {
PartialState, PartialState,
Route, Route,
} from '@react-navigation/routers'; } from '@react-navigation/routers';
import { PathConfig } from './types';
type State = NavigationState | Omit<PartialState<NavigationState>, 'stale'>; type State = NavigationState | Omit<PartialState<NavigationState>, 'stale'>;
type StringifyConfig = Record<string, (value: any) => string>; type StringifyConfig = Record<string, (value: any) => string>;
type OptionsItem = { type OptionsItem = PathConfig[string];
path?: string;
exact?: boolean;
stringify?: StringifyConfig;
screens?: Options;
};
type Options = Record<string, string | OptionsItem>; type ConfigItem = {
pattern?: string;
stringify?: StringifyConfig;
screens?: Record<string, ConfigItem>;
};
/** /**
* Utility to serialize a navigation state object to a path string. * Utility to serialize a navigation state object to a path string.
@@ -47,7 +47,7 @@ type Options = Record<string, string | OptionsItem>;
*/ */
export default function getPathFromState( export default function getPathFromState(
state?: State, state?: State,
options: Options = {} options: PathConfig = {}
): string { ): string {
if (state === undefined) { if (state === undefined) {
throw Error('NavigationState not passed'); throw Error('NavigationState not passed');
@@ -85,7 +85,7 @@ export default function getPathFromState(
if (route.params) { if (route.params) {
const stringify = currentOptions[route.name]?.stringify; const stringify = currentOptions[route.name]?.stringify;
currentParams = Object.fromEntries( currentParams = fromEntries(
Object.entries(route.params).map(([key, value]) => [ Object.entries(route.params).map(([key, value]) => [
key, key,
stringify?.[key] ? stringify[key](value) : String(value), stringify?.[key] ? stringify[key](value) : String(value),
@@ -182,24 +182,23 @@ export default function getPathFromState(
return path; return path;
} }
type ConfigItem = { // Object.fromEntries is not available in older iOS versions
pattern?: string; const fromEntries = <K extends string, V>(entries: (readonly [K, V])[]) =>
stringify?: StringifyConfig; entries.reduce((acc, [k, v]) => {
screens?: Record<string, ConfigItem>; acc[k] = v;
}; return acc;
}, {} as Record<K, V>);
function joinPaths(...paths: string[]): string { const joinPaths = (...paths: string[]): string =>
return paths ([] as string[])
.map((p) => p.split('/')) .concat(...paths.map((p) => p.split('/')))
.flat()
.filter(Boolean) .filter(Boolean)
.join('/'); .join('/');
}
function createConfigItem( const createConfigItem = (
config: OptionsItem | string, config: OptionsItem | string,
parentPattern?: string parentPattern?: string
): ConfigItem { ): ConfigItem => {
if (typeof config === 'string') { if (typeof config === 'string') {
// If a string is specified as the value of the key(e.g. Foo: '/path'), use it as the pattern // If a string is specified as the value of the key(e.g. Foo: '/path'), use it as the pattern
const pattern = parentPattern ? joinPaths(parentPattern, config) : config; const pattern = parentPattern ? joinPaths(parentPattern, config) : config;
@@ -224,17 +223,16 @@ function createConfigItem(
stringify: config.stringify, stringify: config.stringify,
screens, screens,
}; };
} };
function createNormalizedConfigs( const createNormalizedConfigs = (
options: Options, options: PathConfig,
pattern?: string pattern?: string
): Record<string, ConfigItem> { ): Record<string, ConfigItem> =>
return Object.fromEntries( fromEntries(
Object.entries(options).map(([name, c]) => { Object.entries(options).map(([name, c]) => {
const result = createConfigItem(c, pattern); const result = createConfigItem(c, pattern);
return [name, result]; return [name, result];
}) })
); );
}

View File

@@ -5,21 +5,10 @@ import {
PartialState, PartialState,
InitialState, InitialState,
} from '@react-navigation/routers'; } from '@react-navigation/routers';
import { PathConfig } from './types';
type ParseConfig = Record<string, (value: string) => any>; type ParseConfig = Record<string, (value: string) => any>;
type Options = {
[routeName: string]:
| string
| {
path?: string;
exact?: boolean;
parse?: ParseConfig;
screens?: Options;
initialRouteName?: string;
};
};
type RouteConfig = { type RouteConfig = {
screen: string; screen: string;
regex?: RegExp; regex?: RegExp;
@@ -59,14 +48,17 @@ type ResultState = PartialState<NavigationState> & {
*/ */
export default function getStateFromPath( export default function getStateFromPath(
path: string, path: string,
options: Options = {} options: PathConfig = {}
): ResultState | undefined { ): ResultState | undefined {
let initialRoutes: InitialRouteConfig[] = []; let initialRoutes: InitialRouteConfig[] = [];
// Create a normalized configs array which will be easier to use // Create a normalized configs array which will be easier to use
const configs = Object.keys(options) const configs = ([] as RouteConfig[])
.map((key) => createNormalizedConfigs(key, options, [], initialRoutes)) .concat(
.flat() ...Object.keys(options).map((key) =>
createNormalizedConfigs(key, options, [], initialRoutes)
)
)
.sort( .sort(
(a, b) => (a, b) =>
// Sort configs so the most exhaustive is always first to be chosen // Sort configs so the most exhaustive is always first to be chosen
@@ -231,21 +223,19 @@ export default function getStateFromPath(
return result; return result;
} }
function joinPaths(...paths: string[]): string { const joinPaths = (...paths: string[]): string =>
return paths ([] as string[])
.map((p) => p.split('/')) .concat(...paths.map((p) => p.split('/')))
.flat()
.filter(Boolean) .filter(Boolean)
.join('/'); .join('/');
}
function createNormalizedConfigs( const createNormalizedConfigs = (
screen: string, screen: string,
routeConfig: Options, routeConfig: PathConfig,
routeNames: string[] = [], routeNames: string[] = [],
initials: InitialRouteConfig[], initials: InitialRouteConfig[],
parentPattern?: string parentPattern?: string
): RouteConfig[] { ): RouteConfig[] => {
const configs: RouteConfig[] = []; const configs: RouteConfig[] = [];
routeNames.push(screen); routeNames.push(screen);
@@ -286,7 +276,7 @@ function createNormalizedConfigs(
Object.keys(config.screens).forEach((nestedConfig) => { Object.keys(config.screens).forEach((nestedConfig) => {
const result = createNormalizedConfigs( const result = createNormalizedConfigs(
nestedConfig, nestedConfig,
config.screens as Options, config.screens as PathConfig,
routeNames, routeNames,
initials, initials,
pattern pattern
@@ -300,15 +290,15 @@ function createNormalizedConfigs(
routeNames.pop(); routeNames.pop();
return configs; return configs;
} };
function createConfigItem( const createConfigItem = (
screen: string, screen: string,
routeNames: string[], routeNames: string[],
pattern: string, pattern: string,
path: string, path: string,
parse?: ParseConfig parse?: ParseConfig
): RouteConfig { ): RouteConfig => {
// Normalize pattern to remove any leading, trailing slashes, duplicate slashes etc. // Normalize pattern to remove any leading, trailing slashes, duplicate slashes etc.
pattern = pattern.split('/').filter(Boolean).join('/'); pattern = pattern.split('/').filter(Boolean).join('/');
@@ -336,25 +326,26 @@ function createConfigItem(
routeNames: [...routeNames], routeNames: [...routeNames],
parse, parse,
}; };
} };
function findParseConfigForRoute( const findParseConfigForRoute = (
routeName: string, routeName: string,
flatConfig: RouteConfig[] flatConfig: RouteConfig[]
): ParseConfig | undefined { ): ParseConfig | undefined => {
for (const config of flatConfig) { for (const config of flatConfig) {
if (routeName === config.routeNames[config.routeNames.length - 1]) { if (routeName === config.routeNames[config.routeNames.length - 1]) {
return config.parse; return config.parse;
} }
} }
return undefined;
}
// tries to find an initial route connected with the one passed return undefined;
function findInitialRoute( };
// Try to find an initial route connected with the one passed
const findInitialRoute = (
routeName: string, routeName: string,
initialRoutes: InitialRouteConfig[] initialRoutes: InitialRouteConfig[]
): string | undefined { ): string | undefined => {
for (const config of initialRoutes) { for (const config of initialRoutes) {
if (config.connectedRoutes.includes(routeName)) { if (config.connectedRoutes.includes(routeName)) {
return config.initialRouteName === routeName return config.initialRouteName === routeName
@@ -363,16 +354,16 @@ function findInitialRoute(
} }
} }
return undefined; return undefined;
} };
// returns state object with values depending on whether // returns state object with values depending on whether
// it is the end of state and if there is initialRoute for this level // it is the end of state and if there is initialRoute for this level
function createStateObject( const createStateObject = (
initialRoute: string | undefined, initialRoute: string | undefined,
routeName: string, routeName: string,
params: Record<string, any> | undefined, params: Record<string, any> | undefined,
isEmpty: boolean isEmpty: boolean
): InitialState { ): InitialState => {
if (isEmpty) { if (isEmpty) {
if (initialRoute) { if (initialRoute) {
return { return {
@@ -399,12 +390,12 @@ function createStateObject(
}; };
} }
} }
} };
function createNestedStateObject( const createNestedStateObject = (
routes: { name: string; params?: object }[], routes: { name: string; params?: object }[],
initialRoutes: InitialRouteConfig[] initialRoutes: InitialRouteConfig[]
) { ) => {
let state: InitialState; let state: InitialState;
let route = routes.shift() as { name: string; params?: object }; let route = routes.shift() as { name: string; params?: object };
let initialRoute = findInitialRoute(route.name, initialRoutes); let initialRoute = findInitialRoute(route.name, initialRoutes);
@@ -440,9 +431,9 @@ function createNestedStateObject(
} }
return state; return state;
} };
function findFocusedRoute(state: InitialState) { const findFocusedRoute = (state: InitialState) => {
let current: InitialState | undefined = state; let current: InitialState | undefined = state;
while (current?.routes[current.index || 0].state) { while (current?.routes[current.index || 0].state) {
@@ -455,12 +446,12 @@ function findFocusedRoute(state: InitialState) {
]; ];
return route; return route;
} };
function parseQueryParams( const parseQueryParams = (
path: string, path: string,
parseConfig?: Record<string, (value: string) => any> parseConfig?: Record<string, (value: string) => any>
) { ) => {
const query = path.split('?')[1]; const query = path.split('?')[1];
const params = queryString.parse(query); const params = queryString.parse(query);
@@ -473,4 +464,4 @@ function parseQueryParams(
} }
return Object.keys(params).length ? params : undefined; return Object.keys(params).length ? params : undefined;
} };

View File

@@ -7,6 +7,8 @@ export { default as NavigationHelpersContext } from './NavigationHelpersContext'
export { default as NavigationContext } from './NavigationContext'; export { default as NavigationContext } from './NavigationContext';
export { default as NavigationRouteContext } from './NavigationRouteContext'; export { default as NavigationRouteContext } from './NavigationRouteContext';
export { default as CurrentRenderContext } from './CurrentRenderContext';
export { default as useNavigationBuilder } from './useNavigationBuilder'; export { default as useNavigationBuilder } from './useNavigationBuilder';
export { default as useNavigation } from './useNavigation'; export { default as useNavigation } from './useNavigation';
export { default as useRoute } from './useRoute'; export { default as useRoute } from './useRoute';

View File

@@ -422,6 +422,14 @@ export type NavigationContainerRef = NavigationHelpers<ParamListBase> &
* Get the rehydrated navigation state of the navigation tree. * Get the rehydrated navigation state of the navigation tree.
*/ */
getRootState(): NavigationState; getRootState(): NavigationState;
/**
* Get the currently focused navigation route.
*/
getCurrentRoute(): Route<string> | undefined;
/**
* Get the currently focused route's options.
*/
getCurrentOptions(): object | undefined;
}; };
export type TypedNavigator< export type TypedNavigator<
@@ -462,3 +470,16 @@ export type TypedNavigator<
_: RouteConfig<ParamList, RouteName, State, ScreenOptions, EventMap> _: RouteConfig<ParamList, RouteName, State, ScreenOptions, EventMap>
) => null; ) => null;
}; };
export type PathConfig = {
[routeName: string]:
| string
| {
path?: string;
exact?: boolean;
parse?: Record<string, (value: string) => any>;
stringify?: Record<string, (value: any) => string>;
screens?: PathConfig;
initialRouteName?: string;
};
};

View File

@@ -0,0 +1,28 @@
import * as React from 'react';
import { NavigationState, ParamListBase } from '@react-navigation/routers';
import CurrentRenderContext from './CurrentRenderContext';
import { Descriptor, NavigationHelpers } from './types';
type Options = {
state: NavigationState;
navigation: NavigationHelpers<ParamListBase>;
descriptors: {
[key: string]: Descriptor<ParamListBase, string, NavigationState, object>;
};
};
/**
* Write the current options, so that server renderer can get current values
* Mutating values like this is not safe in async mode, but it doesn't apply to SSR
*/
export default function useCurrentRender({
state,
navigation,
descriptors,
}: Options) {
const current = React.useContext(CurrentRenderContext);
if (current && navigation.isFocused()) {
current.options = descriptors[state.routes[state.index].key].options;
}
}

View File

@@ -117,22 +117,7 @@ export default function useDescriptors<
const screen = screens[route.name]; const screen = screens[route.name];
const navigation = navigations[route.key]; const navigation = navigations[route.key];
acc[route.key] = { const routeOptions = {
navigation,
render() {
return (
<NavigationBuilderContext.Provider key={route.key} value={context}>
<SceneView
navigation={navigation}
route={route}
screen={screen}
getState={getState}
setState={setState}
/>
</NavigationBuilderContext.Provider>
);
},
options: {
// The default `screenOptions` passed to the navigator // The default `screenOptions` passed to the navigator
...(typeof screenOptions === 'object' || screenOptions == null ...(typeof screenOptions === 'object' || screenOptions == null
? screenOptions ? screenOptions
@@ -152,7 +137,25 @@ export default function useDescriptors<
})), })),
// The options set via `navigation.setOptions` // The options set via `navigation.setOptions`
...options[route.key], ...options[route.key],
};
acc[route.key] = {
navigation,
render() {
return (
<NavigationBuilderContext.Provider key={route.key} value={context}>
<SceneView
navigation={navigation}
route={route}
screen={screen}
getState={getState}
setState={setState}
options={routeOptions}
/>
</NavigationBuilderContext.Provider>
);
}, },
options: routeOptions,
}; };
return acc; return acc;

View File

@@ -12,14 +12,10 @@ export default function useIsFocused(): boolean {
// eslint-disable-next-line react-hooks/exhaustive-deps // eslint-disable-next-line react-hooks/exhaustive-deps
const getCurrentValue = React.useCallback(navigation.isFocused, [navigation]); const getCurrentValue = React.useCallback(navigation.isFocused, [navigation]);
const subscribe = React.useCallback( const subscribe = React.useCallback(
(callback: (value: boolean) => void) => { (callback: () => void) => {
const unsubscribeFocus = navigation.addListener('focus', () => const unsubscribeFocus = navigation.addListener('focus', callback);
callback(true)
);
const unsubscribeBlur = navigation.addListener('blur', () => const unsubscribeBlur = navigation.addListener('blur', callback);
callback(false)
);
return () => { return () => {
unsubscribeFocus(); unsubscribeFocus();

View File

@@ -11,7 +11,7 @@ import {
NavigationAction, NavigationAction,
Route, Route,
} from '@react-navigation/routers'; } from '@react-navigation/routers';
import { NavigationStateContext } from './BaseNavigationContainer'; import NavigationStateContext from './NavigationStateContext';
import NavigationRouteContext from './NavigationRouteContext'; import NavigationRouteContext from './NavigationRouteContext';
import Screen from './Screen'; import Screen from './Screen';
import useEventEmitter from './useEventEmitter'; import useEventEmitter from './useEventEmitter';
@@ -33,6 +33,7 @@ import {
import useStateGetters from './useStateGetters'; import useStateGetters from './useStateGetters';
import useOnGetState from './useOnGetState'; import useOnGetState from './useOnGetState';
import useScheduleUpdate from './useScheduleUpdate'; import useScheduleUpdate from './useScheduleUpdate';
import useCurrentRender from './useCurrentRender';
// This is to make TypeScript compiler happy // This is to make TypeScript compiler happy
// eslint-disable-next-line babel/no-unused-expressions // eslint-disable-next-line babel/no-unused-expressions
@@ -264,41 +265,36 @@ export default function useNavigationBuilder<
getKey, getKey,
} = React.useContext(NavigationStateContext); } = React.useContext(NavigationStateContext);
const previousStateRef = React.useRef< const [initializedState, isFirstStateInitialization] = React.useMemo(() => {
NavigationState | PartialState<NavigationState> | undefined
>();
const initializedStateRef = React.useRef<State>();
let isFirstStateInitialization = false;
if (
initializedStateRef.current === undefined ||
currentState !== previousStateRef.current
) {
// If the current state isn't initialized on first render, we initialize it // If the current state isn't initialized on first render, we initialize it
// We also need to re-initialize it if the state passed from parent was changed (maybe due to reset) // We also need to re-initialize it if the state passed from parent was changed (maybe due to reset)
// Otherwise assume that the state was provided as initial state // Otherwise assume that the state was provided as initial state
// So we need to rehydrate it to make it usable // So we need to rehydrate it to make it usable
if (currentState === undefined || !isStateValid(currentState)) { if (currentState === undefined || !isStateValid(currentState)) {
isFirstStateInitialization = true; return [
initializedStateRef.current = router.getInitialState({ router.getInitialState({
routeNames, routeNames,
routeParamList, routeParamList,
}); }),
true,
];
} else { } else {
initializedStateRef.current = router.getRehydratedState( return [
currentState as PartialState<State>, router.getRehydratedState(currentState as PartialState<State>, {
{
routeNames, routeNames,
routeParamList, routeParamList,
}),
false,
];
} }
); // We explicitly don't include routeNames/routeParamList in the dep list
} // below. We want to avoid forcing a new state to be calculated in cases
} // where routeConfigs change without affecting routeNames/routeParamList.
// Instead, we handle changes to these in the nextState code below. Note
React.useEffect(() => { // that some changes to routeConfigs are explicitly ignored, such as changes
previousStateRef.current = currentState; // to initialParams
}, [currentState]); // eslint-disable-next-line react-hooks/exhaustive-deps
}, [currentState, router, isStateValid]);
let state = let state =
// If the state isn't initialized, or stale, use the state we initialized instead // If the state isn't initialized, or stale, use the state we initialized instead
@@ -306,7 +302,7 @@ export default function useNavigationBuilder<
// So it'll be `undefined` or stale untill the first navigation event happens // So it'll be `undefined` or stale untill the first navigation event happens
isStateInitialized(currentState) isStateInitialized(currentState)
? (currentState as State) ? (currentState as State)
: (initializedStateRef.current as State); : (initializedState as State);
let nextState: State = state; let nextState: State = state;
@@ -374,6 +370,12 @@ export default function useNavigationBuilder<
// eslint-disable-next-line react-hooks/exhaustive-deps // eslint-disable-next-line react-hooks/exhaustive-deps
}, []); }, []);
// We initialize this ref here to avoid a new getState getting initialized
// whenever initializedState changes. We want getState to have access to the
// latest initializedState, but don't need it to change when that happens
const initializedStateRef = React.useRef<State>();
initializedStateRef.current = initializedState;
const getState = React.useCallback((): State => { const getState = React.useCallback((): State => {
const currentState = getCurrentState(); const currentState = getCurrentState();
@@ -497,6 +499,12 @@ export default function useNavigationBuilder<
emitter, emitter,
}); });
useCurrentRender({
state,
navigation,
descriptors,
});
return { return {
state, state,
navigation, navigation,

View File

@@ -0,0 +1,70 @@
import * as React from 'react';
import NavigationStateContext from './NavigationStateContext';
import { NavigationState } from '@react-navigation/routers';
export default function useOptionsGetters({
key,
getOptions,
getState,
}: {
key?: string;
getOptions?: () => object | undefined;
getState?: () => NavigationState;
}) {
const optionsGettersFromChild = React.useRef<
Record<string, (() => object | undefined | null) | undefined>
>({});
const { addOptionsGetter: parentAddOptionsGetter } = React.useContext(
NavigationStateContext
);
const getOptionsFromListener = React.useCallback(() => {
for (let key in optionsGettersFromChild.current) {
if (optionsGettersFromChild.current.hasOwnProperty(key)) {
const result = optionsGettersFromChild.current[key]?.();
// null means unfocused route
if (result !== null) {
return result;
}
}
}
return null;
}, []);
const getCurrentOptions = React.useCallback(() => {
if (getState) {
const state = getState();
if (state.routes[state.index].key !== key) {
// null means unfocused route
return null;
}
}
const optionsFromListener = getOptionsFromListener();
if (optionsFromListener !== null) {
return optionsFromListener;
}
return getOptions?.() ?? undefined;
}, [getState, getOptionsFromListener, getOptions, key]);
React.useEffect(() => {
return parentAddOptionsGetter?.(key!, getCurrentOptions);
}, [getCurrentOptions, parentAddOptionsGetter, key]);
const addOptionsGetter = React.useCallback(
(key: string, getter: () => object | undefined | null) => {
optionsGettersFromChild.current[key] = getter;
return () => {
optionsGettersFromChild.current[key] = undefined;
};
},
[]
);
return {
addOptionsGetter,
getCurrentOptions,
};
}

View File

@@ -3,6 +3,57 @@
All notable changes to this project will be documented in this file. All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [5.8.1](https://github.com/react-navigation/react-navigation/tree/master/packages/drawer/compare/@react-navigation/drawer@5.8.0...@react-navigation/drawer@5.8.1) (2020-05-27)
**Note:** Version bump only for package @react-navigation/drawer
# [5.8.0](https://github.com/react-navigation/react-navigation/tree/master/packages/drawer/compare/@react-navigation/drawer@5.7.7...@react-navigation/drawer@5.8.0) (2020-05-23)
### Features
* update react-native-safe-area-context to 1.0.0 ([#8182](https://github.com/react-navigation/react-navigation/tree/master/packages/drawer/issues/8182)) ([d62fbfe](https://github.com/react-navigation/react-navigation/tree/master/packages/drawer/commit/d62fbfe255140f16b182e8b54b276a7c96f2aec6))
## [5.7.7](https://github.com/react-navigation/react-navigation/tree/master/packages/drawer/compare/@react-navigation/drawer@5.7.6...@react-navigation/drawer@5.7.7) (2020-05-20)
**Note:** Version bump only for package @react-navigation/drawer
## [5.7.6](https://github.com/react-navigation/react-navigation/tree/master/packages/drawer/compare/@react-navigation/drawer@5.7.5...@react-navigation/drawer@5.7.6) (2020-05-20)
**Note:** Version bump only for package @react-navigation/drawer
## [5.7.5](https://github.com/react-navigation/react-navigation/tree/master/packages/drawer/compare/@react-navigation/drawer@5.7.4...@react-navigation/drawer@5.7.5) (2020-05-16)
**Note:** Version bump only for package @react-navigation/drawer
## [5.7.4](https://github.com/react-navigation/react-navigation/tree/master/packages/drawer/compare/@react-navigation/drawer@5.7.3...@react-navigation/drawer@5.7.4) (2020-05-14)
**Note:** Version bump only for package @react-navigation/drawer
## [5.7.3](https://github.com/react-navigation/react-navigation/tree/master/packages/drawer/compare/@react-navigation/drawer@5.7.2...@react-navigation/drawer@5.7.3) (2020-05-14) ## [5.7.3](https://github.com/react-navigation/react-navigation/tree/master/packages/drawer/compare/@react-navigation/drawer@5.7.2...@react-navigation/drawer@5.7.3) (2020-05-14)
**Note:** Version bump only for package @react-navigation/drawer **Note:** Version bump only for package @react-navigation/drawer

View File

@@ -1,7 +1,7 @@
{ {
"name": "@react-navigation/drawer", "name": "@react-navigation/drawer",
"description": "Drawer navigator component with animated transitions and gesturess", "description": "Drawer navigator component with animated transitions and gesturess",
"version": "5.7.3", "version": "5.8.1",
"keywords": [ "keywords": [
"react-native-component", "react-native-component",
"react-component", "react-component",
@@ -25,7 +25,8 @@
"types": "lib/typescript/src/index.d.ts", "types": "lib/typescript/src/index.d.ts",
"files": [ "files": [
"src", "src",
"lib" "lib",
"!**/__tests__"
], ],
"sideEffects": false, "sideEffects": false,
"publishConfig": { "publishConfig": {
@@ -40,8 +41,8 @@
"react-native-iphone-x-helper": "^1.2.1" "react-native-iphone-x-helper": "^1.2.1"
}, },
"devDependencies": { "devDependencies": {
"@react-native-community/bob": "^0.13.1", "@react-native-community/bob": "^0.14.3",
"@react-navigation/native": "^5.3.1", "@react-navigation/native": "^5.5.0",
"@types/react": "^16.9.34", "@types/react": "^16.9.34",
"@types/react-native": "^0.62.7", "@types/react-native": "^0.62.7",
"del-cli": "^3.0.0", "del-cli": "^3.0.0",
@@ -49,7 +50,7 @@
"react-native": "~0.61.5", "react-native": "~0.61.5",
"react-native-gesture-handler": "^1.6.0", "react-native-gesture-handler": "^1.6.0",
"react-native-reanimated": "^1.8.0", "react-native-reanimated": "^1.8.0",
"react-native-safe-area-context": "^0.7.3", "react-native-safe-area-context": "^1.0.0",
"react-native-screens": "^2.7.0", "react-native-screens": "^2.7.0",
"typescript": "^3.8.3" "typescript": "^3.8.3"
}, },

View File

@@ -3,6 +3,57 @@
All notable changes to this project will be documented in this file. All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [5.2.9](https://github.com/react-navigation/react-navigation/tree/master/packages/material-bottom-tabs/compare/@react-navigation/material-bottom-tabs@5.2.8...@react-navigation/material-bottom-tabs@5.2.9) (2020-05-27)
**Note:** Version bump only for package @react-navigation/material-bottom-tabs
## [5.2.8](https://github.com/react-navigation/react-navigation/tree/master/packages/material-bottom-tabs/compare/@react-navigation/material-bottom-tabs@5.2.7...@react-navigation/material-bottom-tabs@5.2.8) (2020-05-23)
**Note:** Version bump only for package @react-navigation/material-bottom-tabs
## [5.2.7](https://github.com/react-navigation/react-navigation/tree/master/packages/material-bottom-tabs/compare/@react-navigation/material-bottom-tabs@5.2.6...@react-navigation/material-bottom-tabs@5.2.7) (2020-05-20)
**Note:** Version bump only for package @react-navigation/material-bottom-tabs
## [5.2.6](https://github.com/react-navigation/react-navigation/tree/master/packages/material-bottom-tabs/compare/@react-navigation/material-bottom-tabs@5.2.5...@react-navigation/material-bottom-tabs@5.2.6) (2020-05-20)
**Note:** Version bump only for package @react-navigation/material-bottom-tabs
## [5.2.5](https://github.com/react-navigation/react-navigation/tree/master/packages/material-bottom-tabs/compare/@react-navigation/material-bottom-tabs@5.2.4...@react-navigation/material-bottom-tabs@5.2.5) (2020-05-16)
### Bug Fixes
* center icons in material tab bar. fixes [#8248](https://github.com/react-navigation/react-navigation/tree/master/packages/material-bottom-tabs/issues/8248) ([51b4087](https://github.com/react-navigation/react-navigation/tree/master/packages/material-bottom-tabs/commit/51b40879bdb9cea5462a2291955513a88eb87340))
## [5.2.4](https://github.com/react-navigation/react-navigation/tree/master/packages/material-bottom-tabs/compare/@react-navigation/material-bottom-tabs@5.2.3...@react-navigation/material-bottom-tabs@5.2.4) (2020-05-14)
**Note:** Version bump only for package @react-navigation/material-bottom-tabs
## [5.2.3](https://github.com/react-navigation/react-navigation/tree/master/packages/material-bottom-tabs/compare/@react-navigation/material-bottom-tabs@5.2.2...@react-navigation/material-bottom-tabs@5.2.3) (2020-05-14) ## [5.2.3](https://github.com/react-navigation/react-navigation/tree/master/packages/material-bottom-tabs/compare/@react-navigation/material-bottom-tabs@5.2.2...@react-navigation/material-bottom-tabs@5.2.3) (2020-05-14)
**Note:** Version bump only for package @react-navigation/material-bottom-tabs **Note:** Version bump only for package @react-navigation/material-bottom-tabs

View File

@@ -1,7 +1,7 @@
{ {
"name": "@react-navigation/material-bottom-tabs", "name": "@react-navigation/material-bottom-tabs",
"description": "Integration for bottom navigation component from react-native-paper", "description": "Integration for bottom navigation component from react-native-paper",
"version": "5.2.3", "version": "5.2.9",
"keywords": [ "keywords": [
"react-native-component", "react-native-component",
"react-component", "react-component",
@@ -25,7 +25,8 @@
"types": "lib/typescript/src/index.d.ts", "types": "lib/typescript/src/index.d.ts",
"files": [ "files": [
"src", "src",
"lib" "lib",
"!**/__tests__"
], ],
"sideEffects": false, "sideEffects": false,
"publishConfig": { "publishConfig": {
@@ -36,8 +37,8 @@
"clean": "del lib" "clean": "del lib"
}, },
"devDependencies": { "devDependencies": {
"@react-native-community/bob": "^0.13.1", "@react-native-community/bob": "^0.14.3",
"@react-navigation/native": "^5.3.1", "@react-navigation/native": "^5.5.0",
"@types/react": "^16.9.34", "@types/react": "^16.9.34",
"@types/react-native": "^0.62.7", "@types/react-native": "^0.62.7",
"@types/react-native-vector-icons": "^6.4.5", "@types/react-native-vector-icons": "^6.4.5",

View File

@@ -69,6 +69,7 @@ function MaterialBottomTabViewInner({
borderless: _1, borderless: _1,
centered: _2, centered: _2,
rippleColor: _3, rippleColor: _3,
style,
...rest ...rest
}) => { }) => {
return ( return (
@@ -86,6 +87,7 @@ function MaterialBottomTabViewInner({
onPress?.(e); onPress?.(e);
} }
}} }}
style={[styles.touchable, style]}
/> />
); );
} }
@@ -153,4 +155,8 @@ const styles = StyleSheet.create({
icon: { icon: {
backgroundColor: 'transparent', backgroundColor: 'transparent',
}, },
touchable: {
display: 'flex',
justifyContent: 'center',
},
}); });

View File

@@ -3,6 +3,54 @@
All notable changes to this project will be documented in this file. All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [5.2.9](https://github.com/react-navigation/react-navigation/tree/master/packages/material-top-tabs/compare/@react-navigation/material-top-tabs@5.2.8...@react-navigation/material-top-tabs@5.2.9) (2020-05-27)
**Note:** Version bump only for package @react-navigation/material-top-tabs
## [5.2.8](https://github.com/react-navigation/react-navigation/tree/master/packages/material-top-tabs/compare/@react-navigation/material-top-tabs@5.2.7...@react-navigation/material-top-tabs@5.2.8) (2020-05-23)
**Note:** Version bump only for package @react-navigation/material-top-tabs
## [5.2.7](https://github.com/react-navigation/react-navigation/tree/master/packages/material-top-tabs/compare/@react-navigation/material-top-tabs@5.2.6...@react-navigation/material-top-tabs@5.2.7) (2020-05-20)
**Note:** Version bump only for package @react-navigation/material-top-tabs
## [5.2.6](https://github.com/react-navigation/react-navigation/tree/master/packages/material-top-tabs/compare/@react-navigation/material-top-tabs@5.2.5...@react-navigation/material-top-tabs@5.2.6) (2020-05-20)
**Note:** Version bump only for package @react-navigation/material-top-tabs
## [5.2.5](https://github.com/react-navigation/react-navigation/tree/master/packages/material-top-tabs/compare/@react-navigation/material-top-tabs@5.2.4...@react-navigation/material-top-tabs@5.2.5) (2020-05-16)
**Note:** Version bump only for package @react-navigation/material-top-tabs
## [5.2.4](https://github.com/react-navigation/react-navigation/tree/master/packages/material-top-tabs/compare/@react-navigation/material-top-tabs@5.2.3...@react-navigation/material-top-tabs@5.2.4) (2020-05-14)
**Note:** Version bump only for package @react-navigation/material-top-tabs
## [5.2.3](https://github.com/react-navigation/react-navigation/tree/master/packages/material-top-tabs/compare/@react-navigation/material-top-tabs@5.2.2...@react-navigation/material-top-tabs@5.2.3) (2020-05-14) ## [5.2.3](https://github.com/react-navigation/react-navigation/tree/master/packages/material-top-tabs/compare/@react-navigation/material-top-tabs@5.2.2...@react-navigation/material-top-tabs@5.2.3) (2020-05-14)
**Note:** Version bump only for package @react-navigation/material-top-tabs **Note:** Version bump only for package @react-navigation/material-top-tabs

View File

@@ -1,7 +1,7 @@
{ {
"name": "@react-navigation/material-top-tabs", "name": "@react-navigation/material-top-tabs",
"description": "Integration for the animated tab view component from react-native-tab-view", "description": "Integration for the animated tab view component from react-native-tab-view",
"version": "5.2.3", "version": "5.2.9",
"keywords": [ "keywords": [
"react-native-component", "react-native-component",
"react-component", "react-component",
@@ -25,7 +25,8 @@
"types": "lib/typescript/src/index.d.ts", "types": "lib/typescript/src/index.d.ts",
"files": [ "files": [
"src", "src",
"lib" "lib",
"!**/__tests__"
], ],
"sideEffects": false, "sideEffects": false,
"publishConfig": { "publishConfig": {
@@ -39,8 +40,8 @@
"color": "^3.1.2" "color": "^3.1.2"
}, },
"devDependencies": { "devDependencies": {
"@react-native-community/bob": "^0.13.1", "@react-native-community/bob": "^0.14.3",
"@react-navigation/native": "^5.3.1", "@react-navigation/native": "^5.5.0",
"@types/react": "^16.9.34", "@types/react": "^16.9.34",
"@types/react-native": "^0.62.7", "@types/react-native": "^0.62.7",
"del-cli": "^3.0.0", "del-cli": "^3.0.0",

View File

@@ -3,6 +3,71 @@
All notable changes to this project will be documented in this file. All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
# [5.5.0](https://github.com/react-navigation/react-navigation/tree/master/packages/native/compare/@react-navigation/native@5.4.3...@react-navigation/native@5.5.0) (2020-05-27)
### Bug Fixes
* export types from /native ([af1722d](https://github.com/react-navigation/react-navigation/tree/master/packages/native/commit/af1722d1e915f3ec234df202f74c4b4c631472c7))
### Features
* add a `ServerContainer` component for SSR ([#8297](https://github.com/react-navigation/react-navigation/tree/master/packages/native/issues/8297)) ([68e750d](https://github.com/react-navigation/react-navigation/tree/master/packages/native/commit/68e750d5a6d198a2f5bdb86ba631de0a27732943))
* add ref to get current options in `ServerContainer` ([#8333](https://github.com/react-navigation/react-navigation/tree/master/packages/native/issues/8333)) ([0b1a718](https://github.com/react-navigation/react-navigation/tree/master/packages/native/commit/0b1a718756e208d84b20e45ca56004332308ad54))
## [5.4.3](https://github.com/react-navigation/react-navigation/tree/master/packages/native/compare/@react-navigation/native@5.4.2...@react-navigation/native@5.4.3) (2020-05-23)
**Note:** Version bump only for package @react-navigation/native
## [5.4.2](https://github.com/react-navigation/react-navigation/tree/master/packages/native/compare/@react-navigation/native@5.4.1...@react-navigation/native@5.4.2) (2020-05-20)
**Note:** Version bump only for package @react-navigation/native
## [5.4.1](https://github.com/react-navigation/react-navigation/tree/master/packages/native/compare/@react-navigation/native@5.4.0...@react-navigation/native@5.4.1) (2020-05-20)
**Note:** Version bump only for package @react-navigation/native
# [5.4.0](https://github.com/react-navigation/react-navigation/tree/master/packages/native/compare/@react-navigation/native@5.3.2...@react-navigation/native@5.4.0) (2020-05-16)
### Bug Fixes
* fix types for linking options ([d14f38b](https://github.com/react-navigation/react-navigation/tree/master/packages/native/commit/d14f38b80ad569d5828c1919cea426c659173924))
### Features
* add a PathConfig type ([60cb3c9](https://github.com/react-navigation/react-navigation/tree/master/packages/native/commit/60cb3c9ba76d7ef166c9fe8b55f23728975b5b6e))
## [5.3.2](https://github.com/react-navigation/react-navigation/tree/master/packages/native/compare/@react-navigation/native@5.3.1...@react-navigation/native@5.3.2) (2020-05-14)
**Note:** Version bump only for package @react-navigation/native
## [5.3.1](https://github.com/react-navigation/react-navigation/tree/master/packages/native/compare/@react-navigation/native@5.3.0...@react-navigation/native@5.3.1) (2020-05-14) ## [5.3.1](https://github.com/react-navigation/react-navigation/tree/master/packages/native/compare/@react-navigation/native@5.3.0...@react-navigation/native@5.3.1) (2020-05-14)
**Note:** Version bump only for package @react-navigation/native **Note:** Version bump only for package @react-navigation/native

View File

@@ -1,7 +1,7 @@
{ {
"name": "@react-navigation/native", "name": "@react-navigation/native",
"description": "React Native integration for React Navigation", "description": "React Native integration for React Navigation",
"version": "5.3.1", "version": "5.5.0",
"keywords": [ "keywords": [
"react-native", "react-native",
"react-navigation", "react-navigation",
@@ -21,7 +21,8 @@
"types": "lib/typescript/src/index.d.ts", "types": "lib/typescript/src/index.d.ts",
"files": [ "files": [
"src", "src",
"lib" "lib",
"!**/__tests__"
], ],
"sideEffects": false, "sideEffects": false,
"publishConfig": { "publishConfig": {
@@ -32,14 +33,16 @@
"clean": "del lib" "clean": "del lib"
}, },
"dependencies": { "dependencies": {
"@react-navigation/core": "^5.6.0" "@react-navigation/core": "^5.9.0"
}, },
"devDependencies": { "devDependencies": {
"@react-native-community/bob": "^0.13.1", "@react-native-community/bob": "^0.14.3",
"@types/react": "^16.9.34", "@types/react": "^16.9.34",
"@types/react-dom": "^16.9.8",
"@types/react-native": "^0.62.7", "@types/react-native": "^0.62.7",
"del-cli": "^3.0.0", "del-cli": "^3.0.0",
"react": "~16.9.0", "react": "~16.9.0",
"react-dom": "^16.13.1",
"react-native": "~0.61.5", "react-native": "~0.61.5",
"react-native-testing-library": "^1.13.2", "react-native-testing-library": "^1.13.2",
"typescript": "^3.8.3" "typescript": "^3.8.3"

View File

@@ -0,0 +1,55 @@
import * as React from 'react';
import { CurrentRenderContext } from '@react-navigation/core';
import ServerContext, { ServerContextType } from './ServerContext';
import { ServerContainerRef } from './types';
type Props = ServerContextType & {
children: React.ReactNode;
};
/**
* Container component for server rendering.
*
* @param props.location Location object to base the initial URL for SSR.
* @param props.children Child elements to render the content.
* @param props.ref Ref object which contains helper methods.
*/
export default React.forwardRef(function ServerContainer(
{ children, location }: Props,
ref: React.Ref<ServerContainerRef>
) {
React.useEffect(() => {
console.error(
"'ServerContainer' should only be used on the server with 'react-dom/server' for SSR."
);
}, []);
const current: { options?: object } = {};
if (ref) {
const value = {
getCurrentOptions() {
return current.options;
},
};
// We write to the `ref` during render instead of `React.useImperativeHandle`
// This is because `useImperativeHandle` will update the ref after 'commit',
// and there's no 'commit' phase during SSR.
// Mutating ref during render is unsafe in concurrent mode, but we don't care about it for SSR.
if (typeof ref === 'function') {
ref(value);
} else {
// @ts-ignore: the TS types are incorrect and say that ref.current is readonly
ref.current = value;
}
}
return (
<ServerContext.Provider value={{ location }}>
<CurrentRenderContext.Provider value={current}>
{children}
</CurrentRenderContext.Provider>
</ServerContext.Provider>
);
});

View File

@@ -0,0 +1,14 @@
import * as React from 'react';
export type ServerContextType = {
location?: {
pathname: string;
search: string;
};
};
const ServerContext = React.createContext<ServerContextType | undefined>(
undefined
);
export default ServerContext;

View File

@@ -0,0 +1,185 @@
import * as React from 'react';
import {
useNavigationBuilder,
createNavigatorFactory,
StackRouter,
TabRouter,
NavigationHelpersContext,
} from '@react-navigation/core';
import { renderToString } from 'react-dom/server';
import NavigationContainer from '../NavigationContainer';
import ServerContainer from '../ServerContainer';
import { ServerContainerRef } from '../types';
// @ts-ignore
global.window = global;
window.addEventListener = () => {};
window.removeEventListener = () => {};
// We want to use the web version of useLinking
jest.mock('../useLinking', () => require('../useLinking.tsx').default);
it('renders correct state with location', () => {
const createStackNavigator = createNavigatorFactory((props: any) => {
const { navigation, state, descriptors } = useNavigationBuilder(
StackRouter,
props
);
return (
<NavigationHelpersContext.Provider value={navigation}>
{state.routes.map((route) => (
<div key={route.key}>{descriptors[route.key].render()}</div>
))}
</NavigationHelpersContext.Provider>
);
});
const Stack = createStackNavigator();
const TestScreen = ({ route }: any): any =>
`${route.name} ${JSON.stringify(route.params)}`;
const NestedStack = () => {
return (
<Stack.Navigator initialRouteName="Feed">
<Stack.Screen name="Profile" component={TestScreen} />
<Stack.Screen name="Settings" component={TestScreen} />
<Stack.Screen name="Feed" component={TestScreen} />
<Stack.Screen name="Updates" component={TestScreen} />
</Stack.Navigator>
);
};
const element = (
<NavigationContainer
linking={{
prefixes: [],
config: {
Home: {
initialRouteName: 'Profile',
screens: {
Settings: {
path: ':user/edit',
},
Updates: {
path: ':user/updates',
},
},
},
},
}}
>
<Stack.Navigator>
<Stack.Screen name="Home" component={NestedStack} />
<Stack.Screen name="Chat" component={TestScreen} />
</Stack.Navigator>
</NavigationContainer>
);
// @ts-ignore
window.location = { pathname: '/jane/edit', search: '' };
const client = renderToString(element);
expect(client).toMatchInlineSnapshot(
`"<div><div>Profile undefined</div><div>Settings {&quot;user&quot;:&quot;jane&quot;}</div></div>"`
);
const server = renderToString(
<ServerContainer location={{ pathname: '/john/updates', search: '' }}>
{element}
</ServerContainer>
);
expect(server).toMatchInlineSnapshot(
`"<div><div>Profile undefined</div><div>Updates {&quot;user&quot;:&quot;john&quot;}</div></div>"`
);
});
it('gets the current options', () => {
const createTabNavigator = createNavigatorFactory((props: any) => {
const { navigation, state, descriptors } = useNavigationBuilder(
TabRouter,
props
);
return (
<NavigationHelpersContext.Provider value={navigation}>
{state.routes.map((route) => (
<div key={route.key}>{descriptors[route.key].render()}</div>
))}
</NavigationHelpersContext.Provider>
);
});
const Tab = createTabNavigator();
const TestScreen = ({ route }: any): any =>
`${route.name} ${JSON.stringify(route.params)}`;
const NestedStack = () => {
return (
<Tab.Navigator initialRouteName="Feed">
<Tab.Screen
name="Profile"
component={TestScreen}
options={{ title: 'My profile' }}
/>
<Tab.Screen
name="Settings"
component={TestScreen}
options={{ title: 'Configure' }}
/>
<Tab.Screen
name="Feed"
component={TestScreen}
options={{ title: 'News feed' }}
/>
<Tab.Screen
name="Updates"
component={TestScreen}
options={{ title: 'Updates from cloud', description: 'Woah' }}
/>
</Tab.Navigator>
);
};
const ref = React.createRef<ServerContainerRef>();
renderToString(
<ServerContainer ref={ref}>
<NavigationContainer
initialState={{
routes: [
{
name: 'Others',
state: {
routes: [{ name: 'Updates' }],
},
},
],
}}
>
<Tab.Navigator>
<Tab.Screen
name="Home"
component={TestScreen}
options={{ title: 'My app' }}
/>
<Tab.Screen
name="Others"
component={NestedStack}
options={{ title: 'Other stuff' }}
/>
</Tab.Navigator>
</NavigationContainer>
</ServerContainer>
);
expect(ref.current?.getCurrentOptions()).toEqual({
title: 'Updates from cloud',
description: 'Woah',
});
});

View File

@@ -15,3 +15,7 @@ export { default as useLinking } from './useLinking';
export { default as useLinkTo } from './useLinkTo'; export { default as useLinkTo } from './useLinkTo';
export { default as useLinkProps } from './useLinkProps'; export { default as useLinkProps } from './useLinkProps';
export { default as useLinkBuilder } from './useLinkBuilder'; export { default as useLinkBuilder } from './useLinkBuilder';
export { default as ServerContainer } from './ServerContainer';
export * from './types';

View File

@@ -1,6 +1,7 @@
import { import {
getStateFromPath as getStateFromPathDefault, getStateFromPath as getStateFromPathDefault,
getPathFromState as getPathFromStateDefault, getPathFromState as getPathFromStateDefault,
PathConfig,
} from '@react-navigation/core'; } from '@react-navigation/core';
export type Theme = { export type Theme = {
@@ -39,7 +40,7 @@ export type LinkingOptions = {
* } * }
* ``` * ```
*/ */
config?: Parameters<typeof getStateFromPathDefault>[1]; config?: PathConfig;
/** /**
* Custom function to parse the URL to a valid navigation state (advanced). * Custom function to parse the URL to a valid navigation state (advanced).
* Only applicable on Web. * Only applicable on Web.
@@ -50,3 +51,7 @@ export type LinkingOptions = {
*/ */
getPathFromState?: typeof getPathFromStateDefault; getPathFromState?: typeof getPathFromStateDefault;
}; };
export type ServerContainerRef = {
getCurrentOptions(): Record<string, any> | undefined;
};

View File

@@ -6,6 +6,7 @@ import {
NavigationState, NavigationState,
getActionFromState, getActionFromState,
} from '@react-navigation/core'; } from '@react-navigation/core';
import ServerContext from './ServerContext';
import { LinkingOptions } from './types'; import { LinkingOptions } from './types';
type ResultState = ReturnType<typeof getStateFromPathDefault>; type ResultState = ReturnType<typeof getStateFromPathDefault>;
@@ -84,11 +85,17 @@ export default function useLinking(
getPathFromStateRef.current = getPathFromState; getPathFromStateRef.current = getPathFromState;
}, [config, enabled, getPathFromState, getStateFromPath]); }, [config, enabled, getPathFromState, getStateFromPath]);
const server = React.useContext(ServerContext);
const getInitialState = React.useCallback(() => { const getInitialState = React.useCallback(() => {
let value: ResultState | undefined; let value: ResultState | undefined;
if (enabledRef.current) { if (enabledRef.current) {
const path = location.pathname + location.search; const location =
server?.location ??
(typeof window !== 'undefined' ? window.location : undefined);
const path = location ? location.pathname + location.search : undefined;
if (path) { if (path) {
value = getStateFromPathRef.current(path, configRef.current); value = getStateFromPathRef.current(path, configRef.current);
@@ -106,6 +113,7 @@ export default function useLinking(
}; };
return thenable as PromiseLike<ResultState | undefined>; return thenable as PromiseLike<ResultState | undefined>;
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []); }, []);
const previousStateLengthRef = React.useRef<number | undefined>(undefined); const previousStateLengthRef = React.useRef<number | undefined>(undefined);

View File

@@ -3,6 +3,30 @@
All notable changes to this project will be documented in this file. All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [5.4.7](https://github.com/react-navigation/react-navigation/tree/master/packages/routers/compare/@react-navigation/routers@5.4.6...@react-navigation/routers@5.4.7) (2020-05-23)
**Note:** Version bump only for package @react-navigation/routers
## [5.4.6](https://github.com/react-navigation/react-navigation/tree/master/packages/routers/compare/@react-navigation/routers@5.4.5...@react-navigation/routers@5.4.6) (2020-05-20)
**Note:** Version bump only for package @react-navigation/routers
## [5.4.5](https://github.com/react-navigation/react-navigation/tree/master/packages/routers/compare/@react-navigation/routers@5.4.4...@react-navigation/routers@5.4.5) (2020-05-20)
**Note:** Version bump only for package @react-navigation/routers
## [5.4.4](https://github.com/react-navigation/react-navigation/tree/master/packages/routers/compare/@react-navigation/routers@5.4.3...@react-navigation/routers@5.4.4) (2020-05-08) ## [5.4.4](https://github.com/react-navigation/react-navigation/tree/master/packages/routers/compare/@react-navigation/routers@5.4.3...@react-navigation/routers@5.4.4) (2020-05-08)

View File

@@ -1,7 +1,7 @@
{ {
"name": "@react-navigation/routers", "name": "@react-navigation/routers",
"description": "Routers to help build custom navigators", "description": "Routers to help build custom navigators",
"version": "5.4.4", "version": "5.4.7",
"keywords": [ "keywords": [
"react", "react",
"react-native", "react-native",
@@ -20,7 +20,8 @@
"types": "lib/typescript/src/index.d.ts", "types": "lib/typescript/src/index.d.ts",
"files": [ "files": [
"src", "src",
"lib" "lib",
"!**/__tests__"
], ],
"sideEffects": false, "sideEffects": false,
"publishConfig": { "publishConfig": {
@@ -34,7 +35,7 @@
"nanoid": "^3.1.5" "nanoid": "^3.1.5"
}, },
"devDependencies": { "devDependencies": {
"@react-native-community/bob": "^0.13.1", "@react-native-community/bob": "^0.14.3",
"del-cli": "^3.0.0", "del-cli": "^3.0.0",
"typescript": "^3.8.3" "typescript": "^3.8.3"
}, },

View File

@@ -3,6 +3,78 @@
All notable changes to this project will be documented in this file. All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [5.4.1](https://github.com/react-navigation/react-navigation/tree/master/packages/stack/compare/@react-navigation/stack@5.4.0...@react-navigation/stack@5.4.1) (2020-05-27)
### Bug Fixes
* allow HeaderBackground's subViews to be touchable ([#8317](https://github.com/react-navigation/react-navigation/tree/master/packages/stack/issues/8317)) ([00c23f2](https://github.com/react-navigation/react-navigation/tree/master/packages/stack/commit/00c23f2c9ed22fa4d010ffb427f2b52e061d8df4))
* fix type of style for various options ([9d822b9](https://github.com/react-navigation/react-navigation/tree/master/packages/stack/commit/9d822b95a6df797e2e63e481573e64ea7d0f9386))
# [5.4.0](https://github.com/react-navigation/react-navigation/tree/master/packages/stack/compare/@react-navigation/stack@5.3.9...@react-navigation/stack@5.4.0) (2020-05-23)
### Bug Fixes
* allow HeaderBackground's subViews to be touchable ([#8314](https://github.com/react-navigation/react-navigation/tree/master/packages/stack/issues/8314)) ([021a911](https://github.com/react-navigation/react-navigation/tree/master/packages/stack/commit/021a9111d76b9b0d940c8829f7caebeb292fec2a))
* don't ignore previous header heights on layout update ([6dd45fc](https://github.com/react-navigation/react-navigation/tree/master/packages/stack/commit/6dd45fcff98a0c222d120d6f76a37130de45b92f))
### Features
* update react-native-safe-area-context to 1.0.0 ([#8182](https://github.com/react-navigation/react-navigation/tree/master/packages/stack/issues/8182)) ([d62fbfe](https://github.com/react-navigation/react-navigation/tree/master/packages/stack/commit/d62fbfe255140f16b182e8b54b276a7c96f2aec6))
## [5.3.9](https://github.com/react-navigation/react-navigation/tree/master/packages/stack/compare/@react-navigation/stack@5.3.8...@react-navigation/stack@5.3.9) (2020-05-20)
**Note:** Version bump only for package @react-navigation/stack
## [5.3.8](https://github.com/react-navigation/react-navigation/tree/master/packages/stack/compare/@react-navigation/stack@5.3.7...@react-navigation/stack@5.3.8) (2020-05-20)
**Note:** Version bump only for package @react-navigation/stack
## [5.3.7](https://github.com/react-navigation/react-navigation/tree/master/packages/stack/compare/@react-navigation/stack@5.3.6...@react-navigation/stack@5.3.7) (2020-05-16)
**Note:** Version bump only for package @react-navigation/stack
## [5.3.6](https://github.com/react-navigation/react-navigation/tree/master/packages/stack/compare/@react-navigation/stack@5.3.5...@react-navigation/stack@5.3.6) (2020-05-15)
### Bug Fixes
* reduce header title margin. fixes [#8267](https://github.com/react-navigation/react-navigation/tree/master/packages/stack/issues/8267) ([d45dbe9](https://github.com/react-navigation/react-navigation/tree/master/packages/stack/commit/d45dbe97dc6625c6a8e80b5e658ab5a95045e5e8))
## [5.3.5](https://github.com/react-navigation/react-navigation/tree/master/packages/stack/compare/@react-navigation/stack@5.3.4...@react-navigation/stack@5.3.5) (2020-05-14)
**Note:** Version bump only for package @react-navigation/stack
## [5.3.4](https://github.com/react-navigation/react-navigation/tree/master/packages/stack/compare/@react-navigation/stack@5.3.3...@react-navigation/stack@5.3.4) (2020-05-14) ## [5.3.4](https://github.com/react-navigation/react-navigation/tree/master/packages/stack/compare/@react-navigation/stack@5.3.3...@react-navigation/stack@5.3.4) (2020-05-14)
**Note:** Version bump only for package @react-navigation/stack **Note:** Version bump only for package @react-navigation/stack

View File

@@ -1,7 +1,7 @@
{ {
"name": "@react-navigation/stack", "name": "@react-navigation/stack",
"description": "Stack navigator component for iOS and Android with animated transitions and gestures", "description": "Stack navigator component for iOS and Android with animated transitions and gestures",
"version": "5.3.4", "version": "5.4.1",
"keywords": [ "keywords": [
"react-native-component", "react-native-component",
"react-component", "react-component",
@@ -24,7 +24,8 @@
"types": "lib/typescript/src/index.d.ts", "types": "lib/typescript/src/index.d.ts",
"files": [ "files": [
"src", "src",
"lib" "lib",
"!**/__tests__"
], ],
"sideEffects": false, "sideEffects": false,
"publishConfig": { "publishConfig": {
@@ -39,9 +40,9 @@
"react-native-iphone-x-helper": "^1.2.1" "react-native-iphone-x-helper": "^1.2.1"
}, },
"devDependencies": { "devDependencies": {
"@react-native-community/bob": "^0.13.1", "@react-native-community/bob": "^0.14.3",
"@react-native-community/masked-view": "^0.1.10", "@react-native-community/masked-view": "^0.1.10",
"@react-navigation/native": "^5.3.1", "@react-navigation/native": "^5.5.0",
"@types/color": "^3.0.1", "@types/color": "^3.0.1",
"@types/react": "^16.9.34", "@types/react": "^16.9.34",
"@types/react-native": "^0.62.7", "@types/react-native": "^0.62.7",
@@ -49,7 +50,7 @@
"react": "~16.9.0", "react": "~16.9.0",
"react-native": "~0.61.5", "react-native": "~0.61.5",
"react-native-gesture-handler": "^1.6.0", "react-native-gesture-handler": "^1.6.0",
"react-native-safe-area-context": "^0.7.3", "react-native-safe-area-context": "^1.0.0",
"react-native-screens": "^2.7.0", "react-native-screens": "^2.7.0",
"typescript": "^3.8.3" "typescript": "^3.8.3"
}, },

View File

@@ -119,7 +119,7 @@ export type StackHeaderOptions = {
* This may lead to white space or overlap between `headerLeft` and `headerTitle` if a customized `headerLeft` is used. * This may lead to white space or overlap between `headerLeft` and `headerTitle` if a customized `headerLeft` is used.
* It can be solved by adjusting `left` and `right` style in `headerTitleContainerStyle` and `marginHorizontal` in `headerTitleStyle`. * It can be solved by adjusting `left` and `right` style in `headerTitleContainerStyle` and `marginHorizontal` in `headerTitleStyle`.
*/ */
headerTitleContainerStyle?: StyleProp<ViewStyle>; headerTitleContainerStyle?: Animated.WithAnimatedValue<StyleProp<ViewStyle>>;
/** /**
* Tint color for the header. * Tint color for the header.
*/ */
@@ -157,7 +157,7 @@ export type StackHeaderOptions = {
/** /**
* Style object for the container of the `headerLeft` component, for example to add padding. * Style object for the container of the `headerLeft` component, for example to add padding.
*/ */
headerLeftContainerStyle?: StyleProp<ViewStyle>; headerLeftContainerStyle?: Animated.WithAnimatedValue<StyleProp<ViewStyle>>;
/** /**
* Function which returns a React Element to display on the right side of the header. * Function which returns a React Element to display on the right side of the header.
*/ */
@@ -165,7 +165,7 @@ export type StackHeaderOptions = {
/** /**
* Style object for the container of the `headerRight` component, for example to add padding. * Style object for the container of the `headerRight` component, for example to add padding.
*/ */
headerRightContainerStyle?: StyleProp<ViewStyle>; headerRightContainerStyle?: Animated.WithAnimatedValue<StyleProp<ViewStyle>>;
/** /**
* Function which returns a React Element to display custom image in header's back button. * Function which returns a React Element to display custom image in header's back button.
* It receives the `tintColor` in in the options object as an argument. object. * It receives the `tintColor` in in the options object as an argument. object.
@@ -187,7 +187,7 @@ export type StackHeaderOptions = {
/** /**
* Style object for the header. You can specify a custom background color here, for example. * Style object for the header. You can specify a custom background color here, for example.
*/ */
headerStyle?: StyleProp<ViewStyle>; headerStyle?: Animated.WithAnimatedValue<StyleProp<ViewStyle>>;
/** /**
* Defaults to `false`. If `true`, the header will not have a background unless you explicitly provide it with `headerBackground`. * Defaults to `false`. If `true`, the header will not have a background unless you explicitly provide it with `headerBackground`.
* The header will also float over the screen so that it overlaps the content underneath. * The header will also float over the screen so that it overlaps the content underneath.
@@ -380,7 +380,7 @@ export type StackHeaderLeftButtonProps = {
/** /**
* Style object for the label. * Style object for the label.
*/ */
labelStyle?: React.ComponentProps<typeof Animated.Text>['style']; labelStyle?: Animated.WithAnimatedValue<StyleProp<TextStyle>>;
/** /**
* Whether label font should scale to respect Text Size accessibility settings. * Whether label font should scale to respect Text Size accessibility settings.
*/ */

View File

@@ -1,8 +1,16 @@
import * as React from 'react'; import * as React from 'react';
import { Animated, StyleSheet, Platform, ViewProps } from 'react-native'; import {
Animated,
StyleSheet,
Platform,
ViewProps,
StyleProp,
ViewStyle,
} from 'react-native';
import { useTheme } from '@react-navigation/native'; import { useTheme } from '@react-navigation/native';
type Props = ViewProps & { type Props = ViewProps & {
style?: Animated.WithAnimatedValue<StyleProp<ViewStyle>>;
children?: React.ReactNode; children?: React.ReactNode;
}; };

View File

@@ -312,8 +312,8 @@ export default class HeaderSegment extends React.Component<Props, State> {
return ( return (
<React.Fragment> <React.Fragment>
<Animated.View <Animated.View
pointerEvents="none" pointerEvents="box-none"
style={[StyleSheet.absoluteFill, backgroundStyle]} style={[StyleSheet.absoluteFill, { zIndex: 0 }, backgroundStyle]}
> >
{headerBackground ? ( {headerBackground ? (
headerBackground({ style: safeStyles }) headerBackground({ style: safeStyles })
@@ -355,7 +355,9 @@ export default class HeaderSegment extends React.Component<Props, State> {
: { : {
marginHorizontal: marginHorizontal:
(leftButton ? 32 : 16) + (leftButton ? 32 : 16) +
(leftLabelLayout?.width || 0) + (leftButton && headerBackTitleVisible !== false
? 40
: 0) +
Math.max(insets.left, insets.right), Math.max(insets.left, insets.right),
}, },
titleStyle, titleStyle,

View File

@@ -46,7 +46,9 @@ type Props = ViewProps & {
onGestureCanceled?: () => void; onGestureCanceled?: () => void;
onGestureEnd?: () => void; onGestureEnd?: () => void;
children: React.ReactNode; children: React.ReactNode;
overlay: (props: { style: StyleProp<ViewStyle> }) => React.ReactNode; overlay: (props: {
style: Animated.WithAnimatedValue<StyleProp<ViewStyle>>;
}) => React.ReactNode;
overlayEnabled: boolean; overlayEnabled: boolean;
shadowEnabled: boolean; shadowEnabled: boolean;
gestureEnabled: boolean; gestureEnabled: boolean;
@@ -83,7 +85,11 @@ export default class Card extends React.Component<Props> {
shadowEnabled: true, shadowEnabled: true,
gestureEnabled: true, gestureEnabled: true,
gestureVelocityImpact: GESTURE_VELOCITY_IMPACT, gestureVelocityImpact: GESTURE_VELOCITY_IMPACT,
overlay: ({ style }: { style: StyleProp<ViewStyle> }) => overlay: ({
style,
}: {
style: Animated.WithAnimatedValue<StyleProp<ViewStyle>>;
}) =>
style ? ( style ? (
<Animated.View pointerEvents="none" style={[styles.overlay, style]} /> <Animated.View pointerEvents="none" style={[styles.overlay, style]} />
) : null, ) : null,

View File

@@ -83,9 +83,10 @@ const getHeaderHeights = (
) => { ) => {
return routes.reduce<Record<string, number>>((acc, curr) => { return routes.reduce<Record<string, number>>((acc, curr) => {
const { options = {} } = descriptors[curr.key] || {}; const { options = {} } = descriptors[curr.key] || {};
const { height = previous[curr.key] } = StyleSheet.flatten( const style: any = StyleSheet.flatten(options.headerStyle || {});
options.headerStyle || {}
); const height =
typeof style.height === 'number' ? style.height : previous[curr.key];
const safeAreaInsets = { const safeAreaInsets = {
...insets, ...insets,
@@ -299,7 +300,7 @@ export default class CardStack extends React.Component<Props, State> {
props.insets, props.insets,
state.descriptors, state.descriptors,
layout, layout,
{} state.headerHeights
), ),
}; };
}); });

649
yarn.lock

File diff suppressed because it is too large Load Diff