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 Oct 14, 2018
1 parent 3b70a9d commit 51ee7c3
Show file tree
Hide file tree
Showing 17 changed files with 461 additions and 60 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": 5304,
"minified": 2676,
"gzipped": 1062,
"bundled": 6957,
"minified": 3516,
"gzipped": 1211,
"treeshaked": {
"rollup": {
"code": 304,
"code": 441,
"import_statements": 21
},
"webpack": {
"code": 1421
"code": 1435
}
}
},
"dist/curi-react-universal.js": {
"bundled": 5582,
"minified": 2901,
"gzipped": 1144
"bundled": 7242,
"minified": 3746,
"gzipped": 1293
},
"dist/curi-react-universal.umd.js": {
"bundled": 6037,
"minified": 2744,
"gzipped": 1120
"bundled": 7779,
"minified": 3482,
"gzipped": 1257
},
"dist/curi-react-universal.min.js": {
"bundled": 5676,
"minified": 2456,
"gzipped": 974
"bundled": 7418,
"minified": 3194,
"gzipped": 1112
}
}
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;
}

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

constructor(props: RouterProps) {
super(props);
Expand All @@ -26,6 +32,14 @@ export default function curiProvider(router: CuriRouter) {
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 @@ -35,8 +49,15 @@ export default function curiProvider(router: CuriRouter) {
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
@@ -1,10 +1,12 @@
export { ActiveProps } from "./Active";
export { BlockProps } from "./Block";
export { RouterProps, CuriRenderFn } from "./curiProvider";
export { FinishNavigationProps } from "./FinishNavigation";

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

export { Active, Block, curiProvider, Curious };
export { Active, Block, curiProvider, Curious, FinishNavigation };
2 changes: 1 addition & 1 deletion packages/react-universal/tests/Active.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import InMemory from "@hickory/in-memory";
import { curi } from "@curi/router";
import activeInteraction from "@curi/route-active";

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

describe("<Active>", () => {
Expand Down
2 changes: 1 addition & 1 deletion packages/react-universal/tests/Block.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import ReactDOM from "react-dom";
import { curi } from "@curi/router";
import InMemory from "@hickory/in-memory";

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

describe("Block", () => {
Expand Down
2 changes: 1 addition & 1 deletion packages/react-universal/tests/Curious.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import ReactDOM from "react-dom";
import InMemory from "@hickory/in-memory";
import { curi } from "@curi/router";

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

describe("<Curious>", () => {
Expand Down
86 changes: 86 additions & 0 deletions packages/react-universal/tests/FinishNavigation.spec.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
import "jest";
import React from "react";
import ReactDOM from "react-dom";
import { curi } 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 = [{ 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);
});
});
5 changes: 1 addition & 4 deletions packages/react-universal/tests/curiProvider.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import ReactDOM from "react-dom";
import { curi } from "@curi/router";
import InMemory from "@hickory/in-memory";

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

describe("curiProvider()", () => {
Expand All @@ -19,8 +19,6 @@ describe("curiProvider()", () => {
ReactDOM.unmountComponentAtNode(node);
});

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

describe("children prop", () => {
it("calls children() function when it renders", () => {
const history = InMemory();
Expand All @@ -37,7 +35,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;
6 changes: 4 additions & 2 deletions packages/react-universal/types/curiProvider.d.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import React from "react";
import { CuriRouter, Emitted } from "@curi/router";
import { CuriRouter, Response, Emitted } from "@curi/router";
export declare type CuriRenderFn = (props: Emitted) => React.ReactNode;
export interface RouterProps {
children: CuriRenderFn;
suspend?: boolean;
}
export interface RouterState {
emitted: Emitted;
Expand All @@ -11,6 +12,8 @@ export default function curiProvider(router: CuriRouter): {
new (props: RouterProps): {
stopResponding: () => void;
removed: boolean;
current: Response;
shouldComponentUpdate(nextProps: RouterProps, nextState: RouterState): boolean;
componentDidMount(): void;
setupRespond(router: CuriRouter): void;
componentWillUnmount(): void;
Expand All @@ -25,7 +28,6 @@ export default function curiProvider(router: CuriRouter): {
refs: {
[key: string]: React.ReactInstance;
};
shouldComponentUpdate?(nextProps: Readonly<RouterProps>, nextState: Readonly<RouterState>, nextContext: any): boolean;
componentDidCatch?(error: Error, errorInfo: React.ErrorInfo): void;
getSnapshotBeforeUpdate?(prevProps: Readonly<RouterProps>, prevState: Readonly<RouterState>): any;
componentDidUpdate?(prevProps: Readonly<RouterProps>, prevState: Readonly<RouterState>, snapshot?: any): void;
Expand Down
4 changes: 3 additions & 1 deletion packages/react-universal/types/index.d.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
export { ActiveProps } from "./Active";
export { BlockProps } from "./Block";
export { RouterProps, CuriRenderFn } from "./curiProvider";
export { FinishNavigationProps } from "./FinishNavigation";
import Active from "./Active";
import Block from "./Block";
import curiProvider from "./curiProvider";
import { Curious } from "./Context";
export { Active, Block, curiProvider, Curious };
import FinishNavigation from "./FinishNavigation";
export { Active, Block, curiProvider, Curious, 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": 18303,
"minified": 6609,
"gzipped": 2733,
"bundled": 19665,
"minified": 6982,
"gzipped": 2814,
"treeshaked": {
"rollup": {
"code": 45,
Expand All @@ -14,18 +14,18 @@
}
},
"dist/curi-router.js": {
"bundled": 18538,
"minified": 6792,
"gzipped": 2802
"bundled": 19900,
"minified": 7165,
"gzipped": 2885
},
"dist/curi-router.umd.js": {
"bundled": 31686,
"minified": 9252,
"gzipped": 3921
"bundled": 33188,
"minified": 9625,
"gzipped": 3995
},
"dist/curi-router.min.js": {
"bundled": 30824,
"minified": 8712,
"gzipped": 3663
"bundled": 32326,
"minified": 9085,
"gzipped": 3744
}
}
Loading

0 comments on commit 51ee7c3

Please sign in to comment.