Skip to content

Commit

Permalink
Support suspended route navigation
Browse files Browse the repository at this point in the history
  • Loading branch information
pshrmn committed Nov 2, 2018
1 parent c8cf3f6 commit 15fd71a
Show file tree
Hide file tree
Showing 15 changed files with 494 additions and 66 deletions.
28 changes: 14 additions & 14 deletions packages/react-universal/.size-snapshot.json
Original file line number Diff line number Diff line change
@@ -1,31 +1,31 @@
{
"dist/curi-react-universal.es.js": {
"bundled": 6794,
"minified": 3460,
"gzipped": 1205,
"bundled": 8447,
"minified": 4296,
"gzipped": 1349,
"treeshaked": {
"rollup": {
"code": 441,
"code": 453,
"import_statements": 21
},
"webpack": {
"code": 1435
"code": 1449
}
}
},
"dist/curi-react-universal.js": {
"bundled": 7093,
"minified": 3704,
"gzipped": 1292
"bundled": 8753,
"minified": 4545,
"gzipped": 1435
},
"dist/curi-react-universal.umd.js": {
"bundled": 7632,
"minified": 3460,
"gzipped": 1250
"bundled": 9374,
"minified": 4194,
"gzipped": 1375
},
"dist/curi-react-universal.min.js": {
"bundled": 7271,
"minified": 3172,
"gzipped": 1102
"bundled": 9013,
"minified": 3906,
"gzipped": 1226
}
}
41 changes: 41 additions & 0 deletions packages/react-universal/src/FinishNavigation.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import React from "react";

import { Curious } from "./Context";

import { Navigation } from "@curi/router";

export interface FinishNavigationProps {
children: any;
}

export interface BaseFinishNavigationProps extends FinishNavigationProps {
navigation: Navigation;
}

class FinishNavigation extends React.Component<BaseFinishNavigationProps> {
componentDidMount() {
this.finish();
}

componentDidUpdate() {
this.finish();
}

finish() {
if (this.props.navigation.finish) {
this.props.navigation.finish();
}
}

render() {
return this.props.children;
}
}

export default (props: FinishNavigationProps) => (
<Curious>
{({ navigation }) => (
<FinishNavigation {...props} navigation={navigation} />
)}
</Curious>
);
25 changes: 23 additions & 2 deletions packages/react-universal/src/curiProvider.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,17 @@
import React from "react";
import { Provider } from "./Context";

import { CuriRouter, Emitted } from "@curi/router";
import {
CuriRouter,
Response,
Emitted,
} from "@curi/router";

export type CuriRenderFn = (props: Emitted) => React.ReactNode;

export interface RouterProps {
children: CuriRenderFn;
suspend?: boolean;
}

interface RouterState {
Expand All @@ -19,6 +24,7 @@ export default function curiProvider(
return class Router extends React.Component<RouterProps, RouterState> {
stopResponding: () => void;
removed: boolean;
current: Response;

constructor(props: RouterProps) {
super(props);
Expand All @@ -28,6 +34,14 @@ export default function curiProvider(
router
}
};
this.current = this.state.emitted.response;
}

shouldComponentUpdate(nextProps: RouterProps, nextState: RouterState) {
if (nextProps.suspend) {
return nextState.emitted.response === this.current;
}
return true;
}

componentDidMount() {
Expand All @@ -37,8 +51,15 @@ export default function curiProvider(
setupRespond(router: CuriRouter) {
this.stopResponding = router.observe(
(emitted: Emitted) => {
this.current = emitted.response;
if (!this.removed) {
this.setState({ emitted });
if (this.props.suspend) {
setTimeout(() => {
this.setState({ emitted });
});
} else {
this.setState({ emitted });
}
}
},
{ initial: false }
Expand Down
4 changes: 3 additions & 1 deletion packages/react-universal/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,13 @@ export { ActiveProps } from "./Active";
export { BlockProps } from "./Block";
export { RouterProps, CuriRenderFn } from "./curiProvider";
export { NavigatingProps } from "./Navigating";
export { FinishNavigationProps } from "./FinishNavigation";

import Active from "./Active";
import Block from "./Block";
import curiProvider from "./curiProvider";
import { Curious } from "./Context";
import Navigating from "./Navigating";
import FinishNavigation from "./FinishNavigation";

export { Active, Block, curiProvider, Curious, Navigating };
export { Active, Block, curiProvider, Curious, Navigating, FinishNavigation };
89 changes: 89 additions & 0 deletions packages/react-universal/tests/FinishNavigation.spec.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
import "jest";
import React from "react";
import ReactDOM from "react-dom";
import { curi, prepareRoutes } from "@curi/router";
import InMemory from "@hickory/in-memory";

// @ts-ignore (resolved by jest)
import { curiProvider, FinishNavigation } from "@curi/react-universal";

describe("<FinishNavigation>", () => {
let node;
const routes = prepareRoutes([
{ name: "Home", path: "" },
{ name: "About", path: "about" }
]);

beforeEach(() => {
node = document.createElement("div");
});

afterEach(() => {
ReactDOM.unmountComponentAtNode(node);
});

it('"finishes" navigation after mounting', () => {
const history = InMemory();
const router = curi(history, routes, { suspend: true });
const Router = curiProvider(router);

let navigations = [];
// intercept and mock navigation.finish()
router.observe(
({ navigation }) => {
navigation.finish = jest.fn();
navigations.push(navigation);
}
);

ReactDOM.render(
<Router>
{({ navigation }) => {
expect(navigation.finish.mock.calls.length).toBe(0);
return (
<FinishNavigation>
<div>Yo</div>
</FinishNavigation>
);
}}
</Router>,
node,
() => {
expect(navigations[0].finish.mock.calls.length).toBe(1);
}
);
});

it('"finishes" navigation after updating', () => {
const history = InMemory();
const router = curi(history, routes, { suspend: true });
const Router = curiProvider(router);

let navigations = [];
// intercept and mock navigation.finish()
router.observe(
({ navigation }) => {
navigation.finish = jest.fn();
navigations.push(navigation);
}
);

ReactDOM.render(
<Router>
{({ navigation }) => {
expect(navigation.finish.mock.calls.length).toBe(0);
return (
<FinishNavigation>
<div>Yo</div>
</FinishNavigation>
);
}}
</Router>,
node
);
expect(navigations[0].finish.mock.calls.length).toBe(1);

router.navigate({ name: "About" });
expect(navigations[1].finish.mock.calls.length).toBe(1);
});
});
6 changes: 3 additions & 3 deletions packages/react-universal/tests/Navigating.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,14 @@ import "jest";
import React from "react";
import ReactDOM from "react-dom";
import InMemory from "@hickory/in-memory";
import { curi } from "@curi/router";
import { curi, prepareRoutes } from "@curi/router";

// resolved by jest
import { curiProvider, Navigating } from "@curi/react-universal";

describe("<Navigating>", () => {
let node;
const routes = [
const routes = prepareRoutes([
{ name: "Home", path: "" },
{ name: "Sync", path: "sync" },
{
Expand All @@ -35,7 +35,7 @@ describe("<Navigating>", () => {
}
},
{ name: "Catch All", path: "(.*)" }
];
]);

beforeEach(() => {
node = document.createElement("div");
Expand Down
3 changes: 0 additions & 3 deletions packages/react-universal/tests/curiProvider.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,6 @@ describe("curiProvider()", () => {
ReactDOM.unmountComponentAtNode(node);
});

describe("router argument", () => {});

describe("children prop", () => {
it("calls children() function when it renders", () => {
const history = InMemory();
Expand All @@ -42,7 +40,6 @@ describe("curiProvider()", () => {
it("re-renders when the location changes", done => {
const history = InMemory();
const router = curi(history, routes);
let pushedHistory = false;
let firstCall = true;
const fn = jest.fn(({ response }) => {
if (firstCall) {
Expand Down
10 changes: 10 additions & 0 deletions packages/react-universal/types/FinishNavigation.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
/// <reference types="react" />
import { Navigation } from "@curi/router";
export interface FinishNavigationProps {
children: any;
}
export interface BaseFinishNavigationProps extends FinishNavigationProps {
navigation: Navigation;
}
declare const _default: (props: FinishNavigationProps) => JSX.Element;
export default _default;
1 change: 1 addition & 0 deletions packages/react-universal/types/curiProvider.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,6 @@ import { CuriRouter, Emitted } from "@curi/router";
export declare type CuriRenderFn = (props: Emitted) => React.ReactNode;
export interface RouterProps {
children: CuriRenderFn;
suspend?: boolean;
}
export default function curiProvider(router: CuriRouter): React.ComponentType<RouterProps>;
4 changes: 3 additions & 1 deletion packages/react-universal/types/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,11 @@ export { ActiveProps } from "./Active";
export { BlockProps } from "./Block";
export { RouterProps, CuriRenderFn } from "./curiProvider";
export { NavigatingProps } from "./Navigating";
export { FinishNavigationProps } from "./FinishNavigation";
import Active from "./Active";
import Block from "./Block";
import curiProvider from "./curiProvider";
import { Curious } from "./Context";
import Navigating from "./Navigating";
export { Active, Block, curiProvider, Curious, Navigating };
import FinishNavigation from "./FinishNavigation";
export { Active, Block, curiProvider, Curious, Navigating, FinishNavigation };
24 changes: 12 additions & 12 deletions packages/router/.size-snapshot.json
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
{
"dist/curi-router.es.js": {
"bundled": 21411,
"minified": 7965,
"gzipped": 3142,
"bundled": 22773,
"minified": 8338,
"gzipped": 3222,
"treeshaked": {
"rollup": {
"code": 45,
Expand All @@ -14,18 +14,18 @@
}
},
"dist/curi-router.js": {
"bundled": 21670,
"minified": 8170,
"gzipped": 3218
"bundled": 23032,
"minified": 8543,
"gzipped": 3298
},
"dist/curi-router.umd.js": {
"bundled": 35046,
"minified": 10391,
"gzipped": 4295
"bundled": 36548,
"minified": 10764,
"gzipped": 4380
},
"dist/curi-router.min.js": {
"bundled": 33252,
"minified": 9237,
"gzipped": 3807
"bundled": 34754,
"minified": 9610,
"gzipped": 3892
}
}
Loading

0 comments on commit 15fd71a

Please sign in to comment.