react-router-native 6.3.0 → 6.4.0-pre.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/.eslintrc ADDED
@@ -0,0 +1,5 @@
1
+ {
2
+ "globals": {
3
+ "__DEV__": true
4
+ }
5
+ }
package/CHANGELOG.md ADDED
@@ -0,0 +1,7 @@
1
+ # react-router-native
2
+
3
+ ## 6.4.0-pre.3
4
+
5
+ ### Patch Changes
6
+
7
+ - Updated dependencies
@@ -0,0 +1,33 @@
1
+ // Jest Snapshot v1, https://goo.gl/fbAQLP
2
+
3
+ exports[`deep linking when a "url" event happens navigates to the matching route 1`] = `
4
+ <View>
5
+ <Text>
6
+ Home
7
+ </Text>
8
+ </View>
9
+ `;
10
+
11
+ exports[`deep linking when a "url" event happens navigates to the matching route 2`] = `
12
+ <View>
13
+ <Text>
14
+ About
15
+ </Text>
16
+ </View>
17
+ `;
18
+
19
+ exports[`deep linking when there is an initial URL navigates to the matching route 1`] = `
20
+ <View>
21
+ <Text>
22
+ About
23
+ </Text>
24
+ </View>
25
+ `;
26
+
27
+ exports[`deep linking when there is no initial URL stays on the initial route 1`] = `
28
+ <View>
29
+ <Text>
30
+ Home
31
+ </Text>
32
+ </View>
33
+ `;
@@ -0,0 +1,117 @@
1
+ // Jest Snapshot v1, https://goo.gl/fbAQLP
2
+
3
+ exports[`A <Link> press calls the custom onPress handler 1`] = `
4
+ <View>
5
+ <Text>
6
+ Home
7
+ </Text>
8
+ <View
9
+ accessible={true}
10
+ focusable={true}
11
+ isTVSelectable={true}
12
+ onClick={[Function]}
13
+ onResponderGrant={[Function]}
14
+ onResponderMove={[Function]}
15
+ onResponderRelease={[Function]}
16
+ onResponderTerminate={[Function]}
17
+ onResponderTerminationRequest={[Function]}
18
+ onStartShouldSetResponder={[Function]}
19
+ style={null}
20
+ >
21
+ <Text
22
+ style={null}
23
+ >
24
+ About
25
+ </Text>
26
+ </View>
27
+ </View>
28
+ `;
29
+
30
+ exports[`A <Link> press navigates to the new view 1`] = `
31
+ <View>
32
+ <Text>
33
+ Home
34
+ </Text>
35
+ <View
36
+ accessible={true}
37
+ focusable={true}
38
+ isTVSelectable={true}
39
+ onClick={[Function]}
40
+ onResponderGrant={[Function]}
41
+ onResponderMove={[Function]}
42
+ onResponderRelease={[Function]}
43
+ onResponderTerminate={[Function]}
44
+ onResponderTerminationRequest={[Function]}
45
+ onStartShouldSetResponder={[Function]}
46
+ style={null}
47
+ >
48
+ <Text
49
+ style={null}
50
+ >
51
+ About
52
+ </Text>
53
+ </View>
54
+ </View>
55
+ `;
56
+
57
+ exports[`A <Link> press navigates to the new view 2`] = `
58
+ <View>
59
+ <Text>
60
+ About
61
+ </Text>
62
+ </View>
63
+ `;
64
+
65
+ exports[`A <Link> press when event.preventDefault() is used in the onPress handler does not navigate to the new view 1`] = `
66
+ <View>
67
+ <Text>
68
+ Home
69
+ </Text>
70
+ <View
71
+ accessible={true}
72
+ focusable={true}
73
+ isTVSelectable={true}
74
+ onClick={[Function]}
75
+ onResponderGrant={[Function]}
76
+ onResponderMove={[Function]}
77
+ onResponderRelease={[Function]}
78
+ onResponderTerminate={[Function]}
79
+ onResponderTerminationRequest={[Function]}
80
+ onStartShouldSetResponder={[Function]}
81
+ style={null}
82
+ >
83
+ <Text
84
+ style={null}
85
+ >
86
+ About
87
+ </Text>
88
+ </View>
89
+ </View>
90
+ `;
91
+
92
+ exports[`A <Link> press when event.preventDefault() is used in the onPress handler does not navigate to the new view 2`] = `
93
+ <View>
94
+ <Text>
95
+ Home
96
+ </Text>
97
+ <View
98
+ accessible={true}
99
+ focusable={true}
100
+ isTVSelectable={true}
101
+ onClick={[Function]}
102
+ onResponderGrant={[Function]}
103
+ onResponderMove={[Function]}
104
+ onResponderRelease={[Function]}
105
+ onResponderTerminate={[Function]}
106
+ onResponderTerminationRequest={[Function]}
107
+ onStartShouldSetResponder={[Function]}
108
+ style={null}
109
+ >
110
+ <Text
111
+ style={null}
112
+ >
113
+ About
114
+ </Text>
115
+ </View>
116
+ </View>
117
+ `;
@@ -0,0 +1,39 @@
1
+ // Jest Snapshot v1, https://goo.gl/fbAQLP
2
+
3
+ exports[`useSearchParams reads and writes the search string 1`] = `
4
+ <View>
5
+ <Text>
6
+ The current query is "
7
+ Michael Jackson
8
+ ".
9
+ </Text>
10
+ <View>
11
+ <TextInput
12
+ allowFontScaling={true}
13
+ onChangeText={[Function]}
14
+ rejectResponderTermination={true}
15
+ underlineColorAndroid="transparent"
16
+ value="Michael Jackson"
17
+ />
18
+ </View>
19
+ </View>
20
+ `;
21
+
22
+ exports[`useSearchParams reads and writes the search string 2`] = `
23
+ <View>
24
+ <Text>
25
+ The current query is "
26
+ Ryan Florence
27
+ ".
28
+ </Text>
29
+ <View>
30
+ <TextInput
31
+ allowFontScaling={true}
32
+ onChangeText={[Function]}
33
+ rejectResponderTermination={true}
34
+ underlineColorAndroid="transparent"
35
+ value="Ryan Florence"
36
+ />
37
+ </View>
38
+ </View>
39
+ `;
@@ -0,0 +1,36 @@
1
+ // Jest Snapshot v1, https://goo.gl/fbAQLP
2
+
3
+ exports[`Custom link with useLinkPressHandler navigates to the new view 1`] = `
4
+ <View>
5
+ <Text>
6
+ Home
7
+ </Text>
8
+ <View
9
+ accessible={true}
10
+ focusable={true}
11
+ isTVSelectable={true}
12
+ onClick={[Function]}
13
+ onResponderGrant={[Function]}
14
+ onResponderMove={[Function]}
15
+ onResponderRelease={[Function]}
16
+ onResponderTerminate={[Function]}
17
+ onResponderTerminationRequest={[Function]}
18
+ onStartShouldSetResponder={[Function]}
19
+ style={null}
20
+ >
21
+ <Text
22
+ style={null}
23
+ >
24
+ About
25
+ </Text>
26
+ </View>
27
+ </View>
28
+ `;
29
+
30
+ exports[`Custom link with useLinkPressHandler navigates to the new view 2`] = `
31
+ <View>
32
+ <Text>
33
+ About
34
+ </Text>
35
+ </View>
36
+ `;
@@ -0,0 +1,157 @@
1
+ import * as React from "react";
2
+ import { mocked } from "ts-jest/utils";
3
+ import { Linking as _Linking, Text, View } from "react-native";
4
+ import * as TestRenderer from "react-test-renderer";
5
+ import {
6
+ NativeRouter,
7
+ Routes,
8
+ Route,
9
+ useDeepLinking,
10
+ } from "react-router-native";
11
+ import { MockEvent, mockPromiseThatResolvesImmediatelyWith } from "./utils";
12
+
13
+ // Ensures TypeScript understands that Linking is a mock
14
+ const Linking = mocked(_Linking);
15
+
16
+ describe("deep linking", () => {
17
+ describe("when there is no initial URL", () => {
18
+ it("stays on the initial route", () => {
19
+ Linking.getInitialURL.mockImplementation(() => {
20
+ return mockPromiseThatResolvesImmediatelyWith<string>();
21
+ });
22
+
23
+ function Home() {
24
+ useDeepLinking();
25
+ return (
26
+ <View>
27
+ <Text>Home</Text>
28
+ </View>
29
+ );
30
+ }
31
+
32
+ function About() {
33
+ return (
34
+ <View>
35
+ <Text>About</Text>
36
+ </View>
37
+ );
38
+ }
39
+
40
+ let renderer: TestRenderer.ReactTestRenderer;
41
+ TestRenderer.act(() => {
42
+ renderer = TestRenderer.create(
43
+ <NativeRouter initialEntries={["/home"]}>
44
+ <Routes>
45
+ <Route path="home" element={<Home />} />
46
+ <Route path="about" element={<About />} />
47
+ </Routes>
48
+ </NativeRouter>
49
+ );
50
+ });
51
+
52
+ expect(renderer.toJSON()).toMatchSnapshot();
53
+
54
+ Linking.getInitialURL.mockRestore();
55
+ });
56
+ });
57
+
58
+ describe("when there is an initial URL", () => {
59
+ it("navigates to the matching route", () => {
60
+ Linking.getInitialURL.mockImplementation(() => {
61
+ return mockPromiseThatResolvesImmediatelyWith("app:///about");
62
+ });
63
+
64
+ function Home() {
65
+ useDeepLinking();
66
+ return (
67
+ <View>
68
+ <Text>Home</Text>
69
+ </View>
70
+ );
71
+ }
72
+
73
+ function About() {
74
+ return (
75
+ <View>
76
+ <Text>About</Text>
77
+ </View>
78
+ );
79
+ }
80
+
81
+ let renderer: TestRenderer.ReactTestRenderer;
82
+ TestRenderer.act(() => {
83
+ renderer = TestRenderer.create(
84
+ <NativeRouter initialEntries={["/home"]}>
85
+ <Routes>
86
+ <Route path="home" element={<Home />} />
87
+ <Route path="about" element={<About />} />
88
+ </Routes>
89
+ </NativeRouter>
90
+ );
91
+ });
92
+
93
+ expect(renderer!.toJSON()).toMatchSnapshot();
94
+
95
+ Linking.getInitialURL.mockRestore();
96
+ });
97
+ });
98
+
99
+ describe('when a "url" event happens', () => {
100
+ it("navigates to the matching route", () => {
101
+ Linking.getInitialURL.mockImplementation(() => {
102
+ return mockPromiseThatResolvesImmediatelyWith<string>();
103
+ });
104
+
105
+ let listeners: Array<(...args: any[]) => any> = [];
106
+ Linking.addEventListener.mockImplementation((type, listener) => {
107
+ if (type !== "url") throw new Error(`Invalid event type: ${type}`);
108
+ listeners.push(listener);
109
+ });
110
+
111
+ function changeURL(url: string) {
112
+ let event = new MockEvent("url", { url });
113
+ listeners.forEach((listener) => listener(event));
114
+ }
115
+
116
+ function Home() {
117
+ useDeepLinking();
118
+ return (
119
+ <View>
120
+ <Text>Home</Text>
121
+ </View>
122
+ );
123
+ }
124
+
125
+ function About() {
126
+ return (
127
+ <View>
128
+ <Text>About</Text>
129
+ </View>
130
+ );
131
+ }
132
+
133
+ let renderer: TestRenderer.ReactTestRenderer;
134
+ TestRenderer.act(() => {
135
+ renderer = TestRenderer.create(
136
+ <NativeRouter initialEntries={["/home"]}>
137
+ <Routes>
138
+ <Route path="home" element={<Home />} />
139
+ <Route path="about" element={<About />} />
140
+ </Routes>
141
+ </NativeRouter>
142
+ );
143
+ });
144
+
145
+ expect(renderer.toJSON()).toMatchSnapshot();
146
+
147
+ TestRenderer.act(() => {
148
+ changeURL("app:///about");
149
+ });
150
+
151
+ expect(renderer.toJSON()).toMatchSnapshot();
152
+
153
+ Linking.addEventListener.mockRestore();
154
+ Linking.getInitialURL.mockRestore();
155
+ });
156
+ });
157
+ });
@@ -0,0 +1,10 @@
1
+ import * as ReactRouter from "react-router";
2
+ import * as ReactRouterNative from "react-router-native";
3
+
4
+ describe("react-router-native", () => {
5
+ for (let key in ReactRouter) {
6
+ it(`re-exports ${key} from react-router`, () => {
7
+ expect(ReactRouterNative[key]).toBe(ReactRouter[key]);
8
+ });
9
+ }
10
+ });
@@ -0,0 +1,147 @@
1
+ import * as React from "react";
2
+ import { Text, TouchableHighlight, View } from "react-native";
3
+ import { Link, NativeRouter, Routes, Route } from "react-router-native";
4
+ import * as TestRenderer from "react-test-renderer";
5
+
6
+ import { press } from "./utils";
7
+
8
+ describe("A <Link> press", () => {
9
+ it("navigates to the new view", () => {
10
+ function Home() {
11
+ return (
12
+ <View>
13
+ <Text>Home</Text>
14
+ <Link to="../about">
15
+ <Text>About</Text>
16
+ </Link>
17
+ </View>
18
+ );
19
+ }
20
+
21
+ function About() {
22
+ return (
23
+ <View>
24
+ <Text>About</Text>
25
+ </View>
26
+ );
27
+ }
28
+
29
+ let renderer: TestRenderer.ReactTestRenderer;
30
+ TestRenderer.act(() => {
31
+ renderer = TestRenderer.create(
32
+ <NativeRouter initialEntries={["/home"]}>
33
+ <Routes>
34
+ <Route path="home" element={<Home />} />
35
+ <Route path="about" element={<About />} />
36
+ </Routes>
37
+ </NativeRouter>
38
+ );
39
+ });
40
+
41
+ expect(renderer.toJSON()).toMatchSnapshot();
42
+
43
+ let touchable = renderer.root.findByType(TouchableHighlight);
44
+
45
+ TestRenderer.act(() => {
46
+ press(touchable);
47
+ });
48
+
49
+ expect(renderer.toJSON()).toMatchSnapshot();
50
+ });
51
+
52
+ it("calls the custom onPress handler", () => {
53
+ let spy = jest.fn();
54
+
55
+ function Home() {
56
+ return (
57
+ <View>
58
+ <Text>Home</Text>
59
+ <Link to="../about" onPress={spy}>
60
+ <Text>About</Text>
61
+ </Link>
62
+ </View>
63
+ );
64
+ }
65
+
66
+ function About() {
67
+ return (
68
+ <View>
69
+ <Text>About</Text>
70
+ </View>
71
+ );
72
+ }
73
+
74
+ let renderer: TestRenderer.ReactTestRenderer;
75
+ TestRenderer.act(() => {
76
+ renderer = TestRenderer.create(
77
+ <NativeRouter initialEntries={["/home"]}>
78
+ <Routes>
79
+ <Route path="home" element={<Home />} />
80
+ <Route path="about" element={<About />} />
81
+ </Routes>
82
+ </NativeRouter>
83
+ );
84
+ });
85
+
86
+ expect(renderer.toJSON()).toMatchSnapshot();
87
+
88
+ let touchable = renderer.root.findByType(TouchableHighlight);
89
+
90
+ let pressEvent;
91
+ TestRenderer.act(() => {
92
+ pressEvent = press(touchable);
93
+ });
94
+
95
+ expect(spy).toHaveBeenCalledWith(pressEvent);
96
+ });
97
+
98
+ describe("when event.preventDefault() is used in the onPress handler", () => {
99
+ it("does not navigate to the new view", () => {
100
+ function Home() {
101
+ return (
102
+ <View>
103
+ <Text>Home</Text>
104
+ <Link
105
+ to="../about"
106
+ onPress={(event) => {
107
+ event.preventDefault();
108
+ }}
109
+ >
110
+ <Text>About</Text>
111
+ </Link>
112
+ </View>
113
+ );
114
+ }
115
+
116
+ function About() {
117
+ return (
118
+ <View>
119
+ <Text>About</Text>
120
+ </View>
121
+ );
122
+ }
123
+
124
+ let renderer: TestRenderer.ReactTestRenderer;
125
+ TestRenderer.act(() => {
126
+ renderer = TestRenderer.create(
127
+ <NativeRouter initialEntries={["/home"]}>
128
+ <Routes>
129
+ <Route path="home" element={<Home />} />
130
+ <Route path="about" element={<About />} />
131
+ </Routes>
132
+ </NativeRouter>
133
+ );
134
+ });
135
+
136
+ expect(renderer.toJSON()).toMatchSnapshot();
137
+
138
+ let touchable = renderer.root.findByType(TouchableHighlight);
139
+
140
+ TestRenderer.act(() => {
141
+ press(touchable);
142
+ });
143
+
144
+ expect(renderer.toJSON()).toMatchSnapshot();
145
+ });
146
+ });
147
+ });
@@ -0,0 +1,68 @@
1
+ import * as React from "react";
2
+ import { View, Text, TextInput } from "react-native";
3
+ import {
4
+ NativeRouter,
5
+ Routes,
6
+ Route,
7
+ useSearchParams,
8
+ } from "react-router-native";
9
+ import * as TestRenderer from "react-test-renderer";
10
+
11
+ describe("useSearchParams", () => {
12
+ function SearchForm({
13
+ children,
14
+ }: {
15
+ children: React.ReactNode;
16
+ onSubmit?: any;
17
+ }) {
18
+ return <View>{children}</View>;
19
+ }
20
+
21
+ function SearchPage() {
22
+ let [searchParams, setSearchParams] = useSearchParams({ q: "" });
23
+ let [query, setQuery] = React.useState(searchParams.get("q")!);
24
+
25
+ function handleSubmit() {
26
+ setSearchParams({ q: query });
27
+ }
28
+
29
+ return (
30
+ <View>
31
+ <Text>The current query is "{searchParams.get("q")}".</Text>
32
+
33
+ <SearchForm onSubmit={handleSubmit}>
34
+ <TextInput value={query} onChangeText={setQuery} />
35
+ </SearchForm>
36
+ </View>
37
+ );
38
+ }
39
+
40
+ it("reads and writes the search string", () => {
41
+ let renderer: TestRenderer.ReactTestRenderer;
42
+ TestRenderer.act(() => {
43
+ renderer = TestRenderer.create(
44
+ <NativeRouter initialEntries={["/search?q=Michael+Jackson"]}>
45
+ <Routes>
46
+ <Route path="search" element={<SearchPage />} />
47
+ </Routes>
48
+ </NativeRouter>
49
+ );
50
+ });
51
+
52
+ expect(renderer.toJSON()).toMatchSnapshot();
53
+
54
+ let textInput = renderer.root.findByType(TextInput);
55
+
56
+ TestRenderer.act(() => {
57
+ textInput.props.onChangeText("Ryan Florence");
58
+ });
59
+
60
+ let searchForm = renderer.root.findByType(SearchForm);
61
+
62
+ TestRenderer.act(() => {
63
+ searchForm.props.onSubmit();
64
+ });
65
+
66
+ expect(renderer.toJSON()).toMatchSnapshot();
67
+ });
68
+ });
@@ -0,0 +1,9 @@
1
+ jest.mock("react-native/Libraries/Linking/Linking", () => {
2
+ return {
3
+ addEventListener: jest.fn(),
4
+ removeEventListener: jest.fn(),
5
+ openURL: jest.fn(),
6
+ canOpenURL: jest.fn(),
7
+ getInitialURL: jest.fn(),
8
+ };
9
+ });
@@ -0,0 +1,61 @@
1
+ import * as React from "react";
2
+ import { Text, TouchableHighlight, View } from "react-native";
3
+ import type { LinkProps } from "react-router-native";
4
+ import {
5
+ NativeRouter,
6
+ Route,
7
+ Routes,
8
+ useLinkPressHandler,
9
+ } from "react-router-native";
10
+ import * as TestRenderer from "react-test-renderer";
11
+
12
+ import { press } from "./utils";
13
+
14
+ describe("Custom link with useLinkPressHandler", () => {
15
+ function Link({ to, replace, state, ...rest }: LinkProps) {
16
+ let handlePress = useLinkPressHandler(to, { replace, state });
17
+ return <TouchableHighlight {...rest} onPress={handlePress} />;
18
+ }
19
+ it("navigates to the new view", () => {
20
+ function Home() {
21
+ return (
22
+ <View>
23
+ <Text>Home</Text>
24
+ <Link to="../about">
25
+ <Text>About</Text>
26
+ </Link>
27
+ </View>
28
+ );
29
+ }
30
+
31
+ function About() {
32
+ return (
33
+ <View>
34
+ <Text>About</Text>
35
+ </View>
36
+ );
37
+ }
38
+
39
+ let renderer: TestRenderer.ReactTestRenderer;
40
+ TestRenderer.act(() => {
41
+ renderer = TestRenderer.create(
42
+ <NativeRouter initialEntries={["/home"]}>
43
+ <Routes>
44
+ <Route path="home" element={<Home />} />
45
+ <Route path="about" element={<About />} />
46
+ </Routes>
47
+ </NativeRouter>
48
+ );
49
+ });
50
+
51
+ expect(renderer.toJSON()).toMatchSnapshot();
52
+
53
+ let touchable = renderer.root.findByType(TouchableHighlight);
54
+
55
+ TestRenderer.act(() => {
56
+ press(touchable);
57
+ });
58
+
59
+ expect(renderer.toJSON()).toMatchSnapshot();
60
+ });
61
+ });