Skip to content

Commit 44cb5f1

Browse files
committed
[docs] Add v2 usage docs
1 parent b479a17 commit 44cb5f1

2 files changed

Lines changed: 216 additions & 0 deletions

File tree

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ React Navigation bindings for [react-native-shared-element](https://github.com/I
77
This library currently only supports `react-navigation@4` and `react-navigation-stack@1`.
88
The master branch is being rewritten to support `react-navigation-stack@2` and `react-navigation@5`. Master contains a somewhat working version of stack@2, while navigation@5 is still further away.
99

10+
[Check out this page if you are interesting in testing the v2 branch](./README_v2.md).
11+
1012

1113
## Index <!-- omit in toc -->
1214

README_v2.md

Lines changed: 214 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,214 @@
1+
## V2 branch <!-- omit in toc -->
2+
3+
This library is currently being rewritten to support `react-navigation-stack@2` and `react-navigation@5`. Master contains a somewhat working version of stack@2, while navigation@5 is still further away.
4+
5+
This readme contains the documentation for the new v2 branch. The most notable change (API-wise) is that `createSharedElementStackNavigator` no longer requires `createStackNavigator` as its first argument. Instead `react-navigation-stack@2` needs to be installed as a dependency.
6+
7+
# React Navigation Shared Element <!-- omit in toc -->
8+
9+
React Navigation bindings for [react-native-shared-element](https://github.com/IjzerenHein/react-native-shared-element) 💫
10+
11+
12+
## Index <!-- omit in toc -->
13+
14+
- [Installation](#installation)
15+
- [Usage](#usage)
16+
- [Documentation](#documentation)
17+
- [createSharedElementStackNavigator](#createsharedelementstacknavigator)
18+
- [SharedElement](#sharedelement)
19+
- [sharedElements config](#sharedelements-config)
20+
- [Demo App](#demo-app)
21+
- [License](#license)
22+
23+
## Installation
24+
25+
Open a Terminal in your project's folder and run,
26+
27+
```sh
28+
$ yarn add react-navigation-shared-element@next react-native-shared-element
29+
```
30+
31+
Enure that [react-native-shared-element](https://github.com/IjzerenHein/react-native-shared-element) is also linked into your project.
32+
33+
Finally, make sure that the compatible react-navigation dependencies are installed:
34+
35+
```sh
36+
$ yarn add react-navigation@4 react-navigation-stack@2
37+
```
38+
39+
> react-navigation@5 is not supported yet, so don't bother..
40+
41+
## Usage
42+
43+
In order to enable shared element transitions, the following steps need to be performed
44+
45+
- Create a stack-navigator using `createSharedElementStackNavigator`
46+
- Wrap your component with `<SharedElement>` and provide a unique `id`
47+
- Define a static `sharedElements` config on the Screen that you want to animate
48+
49+
```jsx
50+
import { createSharedElementStackNavigator } from 'react-navigation-shared-element';
51+
52+
const stackNavigator = createSharedElementStackNavigator(
53+
{
54+
List: ListScreen,
55+
Detail: DetailScreen,
56+
},
57+
{
58+
initialRouteName: 'List',
59+
}
60+
);
61+
62+
const AppContainer = createAppContainer(stackNavigator);
63+
```
64+
65+
```jsx
66+
// ListScreen.js
67+
import { SharedElement } from 'react-navigation-shared-element';
68+
69+
class ListScreen extends React.Component {
70+
renderItem(item) {
71+
const { navigation } = this.props;
72+
return (
73+
<TouchableOpacity onPress={() => navigation.push('Detail', { item })}>
74+
<SharedElement id={`itemPhoto.${item.id}`}>
75+
<Image source={item.photoUrl} />
76+
</SharedElement>
77+
</TouchableOpacity>
78+
);
79+
}
80+
}
81+
```
82+
83+
```jsx
84+
// DetailScreen.js
85+
const DetailScreen = (props) => {
86+
const item = props.navigation.getParam('item');
87+
return (
88+
<SharedElement id={`item.${item.id}.photo`}>
89+
<Image source={item.photoUrl} />
90+
</SharedElement>
91+
);
92+
};
93+
94+
DetailScreen.sharedElements = (navigation, otherNavigation, showing) => {
95+
const item = navigation.getParam('item');
96+
return [`item.${item.id}.photo`];
97+
};
98+
```
99+
100+
## Documentation
101+
102+
### createSharedElementStackNavigator
103+
104+
The `createSharedElementStackNavigator` function wraps an existing stack-navigator and enables shared element transitions for it.
105+
106+
It performs the following actions
107+
108+
- Creates a top-level renderer to host the shared element transitions
109+
- Wraps each route with a shared element scene
110+
- Detects route changes and trigger shared element transitions
111+
112+
**Arguments**
113+
114+
| Argument | Type | Description |
115+
| ---------------------- | -------- | ---------------------- |
116+
| `routeConfig` | `object` | Routes-config |
117+
| `stackNavigatorConfig` | `object` | Stack navigator config |
118+
119+
### SharedElement
120+
121+
The `<SharedElement>` component accepts a single child and a _"shared"_ id. The child is the element that is made available for doing shared element transitions. It can be any component, like a `<View>`, `<Text>` or `<Image>`. In case the wrapped view is an `<Image>`, special handling is performed to deal with image loading and resizing.
122+
123+
This component is synonymous for the `<SharedElement>` component as defined in `react-native-shared-element`. Instead of a `node` it uses an `id` to create a higher lever API which automatically ties in with the scenes created by `createSharedElementStackNavigator`.
124+
125+
**Props**
126+
127+
| Property | Type | Description |
128+
| --------------- | --------- | ------------------------------------------------------------------------------------ |
129+
| `children` | `element` | A single child component, which must map to a real view in the native view hierarchy |
130+
| `id` | `string` | Unique id of the shared element |
131+
| `View props...` | | Other props supported by View |
132+
133+
### sharedElements config
134+
135+
In order to trigger shared element transitions between screens, a static `sharedElements` config needs to be defined on one of the two screens. For
136+
each screen transition, both screens are evaluated and checked whether they have a `sharedElements` config. The screen that is being shown is **evaluated first**, followed by the screen that is being hidden. If `undefined` is returned, evaluation continues at the other screen.
137+
138+
The `sharedElements` function receives 3 arguments
139+
140+
| Argument | Type | Description |
141+
| ----------------- | ---------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------ |
142+
| `navigation` | `NavigationProp` | Navigation prop of the current screen. You can use this to get the params of the screen using `getParam`, or the route-name using `state.routeName` |
143+
| `otherNavigation` | `NavigationProp` | The navigation-prop of the other screen. You can use this to get the params of that screen using `getParam`, or the route-name using `state.routeName` |
144+
| `showing` | `boolean` | `true` when this screen is being shown, and `false` when this screen is being hidden. | |
145+
146+
The return value should be either `undefined` or an array of shared-element configs or identifiers. Specifying a string-identifier is shorthand for `{id: 'myid'}`.
147+
148+
**Basic example**
149+
150+
```js
151+
class DetailScreen extends Component {
152+
static sharedElements = (navigation, otherNavigation, showing) => {
153+
// Transition element `item.${item.id}.photo` when either
154+
// showing or hiding this screen (coming from any route)
155+
const item = navigation.getParam('item');
156+
return [`item.${item.id}.photo`];
157+
}
158+
159+
render() {...}
160+
}
161+
```
162+
163+
**Only transition when coming from a specific route**
164+
165+
If you only want to show a transition when pushing from a particular screen, then use the route-name and `showing` argument.
166+
167+
```js
168+
class DetailScreen extends Component {
169+
static sharedElements = (navigation, otherNavigation, showing) => {
170+
if ((otherNavigation.state.routeName === 'List') && showing) {
171+
const item = navigation.getParam('item');
172+
return [`item.${item.id}.photo`];
173+
}
174+
}
175+
...
176+
}
177+
```
178+
179+
**Customize the animation**
180+
181+
If the source- and target elements are visually distinct, the consider using a cross-fade animation.
182+
183+
```js
184+
class DetailScreen extends Component {
185+
static sharedElements = (navigation, otherNavigation, showing) => {
186+
const item = navigation.getParam('item');
187+
return [{
188+
id: `item.${item.id}.photo`,
189+
animation: 'fade'
190+
// resize: 'clip'
191+
// align: ''left-top'
192+
}];
193+
}
194+
...
195+
}
196+
```
197+
198+
The following fields can be specified in a config item
199+
200+
| Field | Type | Description |
201+
| ----------- | --------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------- |
202+
| `id` | `string` | Id that corresponds to the `id` specified in the `<SharedElement>` component |
203+
| `otherId` | `string` | Optional id that corresponds to the `id` specified in the other screen. |
204+
| `animation` | `move` \| `fade` | Type of animation to perform (default = `move`), [see SharedElementAnimation](https://github.com/IjzerenHein/react-native-shared-element#sharedelementanimation) |
205+
| `resize` | `auto` \| `stretch` \| `clip` \| `none` | Resize behavior of the transition (default = `auto`), [see SharedElementResize](https://github.com/IjzerenHein/react-native-shared-element#sharedelementresize) |
206+
| `align` | `auto` \| `top-left` \| `...` | Align behavior of the transition (default = `auto`), [see SharedElementAlign](https://github.com/IjzerenHein/react-native-shared-element#sharedelementalign) | |
207+
208+
## Demo App
209+
210+
- [react-navigation-shared-element-rn60demo](https://github.com/IjzerenHein/react-navigation-shared-element-rn60demo)
211+
212+
## License
213+
214+
React navigation shared element library is licensed under [The MIT License](./LICENSE.md).

0 commit comments

Comments
 (0)