Skip to content

Commit

Permalink
Merge pull request #99 from corydeppen/comp-options-ts
Browse files Browse the repository at this point in the history
Add missing properties to Options TS type
  • Loading branch information
faceyspacey authored Jan 31, 2018
2 parents 3c1c855 + 1a3649c commit bfb83e3
Show file tree
Hide file tree
Showing 4 changed files with 122 additions and 93 deletions.
3 changes: 2 additions & 1 deletion __test-helpers__/index.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import path from 'path'
import React from 'react'
import slash from 'slash'

// fake delay so we can test different stages of async loading lifecycle
export const waitFor = ms => new Promise(resolve => setTimeout(resolve, ms))

// normalize the required path so tests pass in all environments
export const normalizePath = path => path.split('__fixtures__')[1]
export const normalizePath = path => slash(path.split('__fixtures__')[1])

export const createPath = name => path.join(__dirname, '../__fixtures__', name)

Expand Down
207 changes: 117 additions & 90 deletions index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@ declare module 'react-universal-component' {
/** Whether the imported component is already available from previous usage and required synchronsouly */
isSync: boolean;

/*
/**
* Very rarely will you want to do stuff on the server.
*
*
* _Note: server will always be sync_
*/
isServer: boolean;
Expand All @@ -31,14 +31,18 @@ declare module 'react-universal-component' {
* loads/changes on both `componentWillMount` and `componentWillReceiveProps`.
* This enables you to display loading indicators elsewhere in the UI.
*/
onBefore(info: Info): void;
onBefore(
info: Info
): void;

/**
* `onBefore`/`onAfter` are callbacks called before and after the wrapped component
* loads/changes on both `componentWillMount` and `componentWillReceiveProps`.
* This enables you to display loading indicators elsewhere in the UI.
*/
onAfter(info: Info): void;
onAfter(
info: Info
): void;

/**
* `onError` is similar to the onError static option, except it operates at the component
Expand All @@ -47,7 +51,9 @@ declare module 'react-universal-component' {
* Again, it's use case is for when you want to show error information elsewhere in the
* UI besides just the place that the universal component would otherwise render.
*/
onError(error: Error): void;
onError(
error: Error
): void;
};

type UniversalComponent<P> = React.StatelessComponent<
Expand All @@ -66,90 +72,111 @@ declare module 'react-universal-component' {
[x: string]: any;
};

type Options<P, C, Export> = Partial<{
/**
* Lets you specify the export from the module you want to be your component
* if it's not `default` in ES6 or `module.exports` in ES5.
* It can be a string corresponding to the export key, or a function that's
* passed the entire module and returns the export that will become the component.
*/
key: keyof Export | ((module: Export) => ComponentType<P>);

/**
* Allows you to specify a maximum amount of time before the error component
* is displayed. The default is 15 seconds.
*/
timeout: number;

/**
* `minDelay` is essentially the minimum amount of time the loading component
* will always show for. It's good for enforcing silky smooth animations, such as
* during a 500ms sliding transition. It insures the re-render won't happen
* until the animation is complete. It's often a good idea to set this to something
* like 300ms even if you don't have a transition, just so the loading spinner
* shows for an appropriate amount of time without jank.
*/
minDelay: number;

/**
* `alwaysDelay` is a boolean you can set to true (default: `false`) to guarantee the
* `minDelay` is always used (i.e. even when components cached from previous imports
* and therefore synchronously and instantly required). This can be useful for
* guaranteeing animations operate as you want without having to wire up other
* components to perform the task.
* _Note: this only applies to the client when
* your `UniversalComponent` uses dynamic expressions to switch between multiple
* components._
*
* default: `false`
*/
alwaysDelay: boolean;

/**
* When set to `false` allows you to keep showing the current component when the
* loading component would otherwise show during transitions from one component to
* the next.
*/
loadingTransition: boolean;

/**
* A callback called if async imports fail.
* It does not apply to sync requires.
*/
onError(error: Error, options: { isServer: boolean }): void;

/**
* A callback function that receives the entire module.
* It allows you to export and put to use things other than your
* default component export, like reducers, sagas, etc.
*
* `onLoad` is fired directly before the component is rendered so you can setup
* any reducers/etc it depends on. Unlike the `onAfter` prop, this option to the
* `universal` HOC is only fired the first time the module is received. Also
* note: it will fire on the server, so do if (!isServer) if you have to.
* But also keep in mind you will need to do things like replace reducers on
* both the server + client for the imported component that uses new reducers
* to render identically in both places.
*/
onLoad(
module: Export,
options: { isSync: boolean; isServer: boolean },
): void;

/**
* The component class or function corresponding to your stateless component
* that displays while the primary import is loading.
* While testing out this package, you can leave it out as a simple default one is used.
*/
loading: ((p: P) => JSX.Element | ComponentType<P>) | (JSX.Element | ComponentType<P>);

/**
* The component that displays if there are any errors that occur during
* your aynschronous import. While testing out this package,
* you can leave it out as a simple default one is used.
*/
error: ((p: P) => JSX.Element | ComponentType<P & { error: Error }>) | (JSX.Element | ComponentType<P & { error: Error }>);
}>;
type Options<P, C, Export> = Partial<
{
/**
* Lets you specify the export from the module you want to be your component
* if it's not `default` in ES6 or `module.exports` in ES5.
* It can be a string corresponding to the export key, or a function that's
* passed the entire module and returns the export that will become the component.
*/
key: keyof Export | ((module: Export) => ComponentType<P>);

/**
* Allows you to specify a maximum amount of time before the error component
* is displayed. The default is 15 seconds.
*/
timeout: number;

/**
* `minDelay` is essentially the minimum amount of time the loading component
* will always show for. It's good for enforcing silky smooth animations, such as
* during a 500ms sliding transition. It insures the re-render won't happen
* until the animation is complete. It's often a good idea to set this to something
* like 300ms even if you don't have a transition, just so the loading spinner
* shows for an appropriate amount of time without jank.
*/
minDelay: number;

/**
* `alwaysDelay` is a boolean you can set to true (default: `false`) to guarantee the
* `minDelay` is always used (i.e. even when components cached from previous imports
* and therefore synchronously and instantly required). This can be useful for
* guaranteeing animations operate as you want without having to wire up other
* components to perform the task.
* _Note: this only applies to the client when
* your `UniversalComponent` uses dynamic expressions to switch between multiple
* components._
*
* default: `false`
*/
alwaysDelay: boolean;

/**
* When set to `false` allows you to keep showing the current component when the
* loading component would otherwise show during transitions from one component to
* the next.
*/
loadingTransition: boolean;

testBabelPlugin: boolean;

resolve: string | number | ((props: P) => number | string);

path: string | ((props: P) => string);

chunkName: string | ((props: P) => string);

alwaysUpdate: boolean;

id: string;

/**
* A callback called if async imports fail.
* It does not apply to sync requires.
*/
onError(
error: Error,
options: { isServer: boolean }
): void;

/**
* A callback function that receives the entire module.
* It allows you to export and put to use things other than your
* default component export, like reducers, sagas, etc.
*
* `onLoad` is fired directly before the component is rendered so you can setup
* any reducers/etc it depends on. Unlike the `onAfter` prop, this option to the
* `universal` HOC is only fired the first time the module is received. Also
* note: it will fire on the server, so do if (!isServer) if you have to.
* But also keep in mind you will need to do things like replace reducers on
* both the server + client for the imported component that uses new reducers
* to render identically in both places.
*/
onLoad(
module: Export,
options: { isSync: boolean; isServer: boolean }
): void;

/**
* The component class or function corresponding to your stateless component
* that displays while the primary import is loading.
* While testing out this package, you can leave it out as a simple default one is used.
*/
loading:
| ((p: P) => JSX.Element | ComponentType<P>)
| (JSX.Element | ComponentType<P>);

/**
* The component that displays if there are any errors that occur during
* your aynschronous import. While testing out this package,
* you can leave it out as a simple default one is used.
*/
error:
| ((p: P) => JSX.Element | ComponentType<P & { error: Error }>)
| (JSX.Element | ComponentType<P & { error: Error }>);
}
>;

export default function universal<
P,
Expand All @@ -162,7 +189,7 @@ declare module 'react-universal-component' {
| {
load(props: P): PromiseLike<Export>;
},
options?: Options<P, C, Export>,
options?: Options<P, C, Export>
): UniversalComponent<P>;
}

Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@
"react-test-renderer": "^15.6.1",
"rimraf": "^2.5.4",
"semantic-release": "^6.3.6",
"slash": "^1.0.0",
"travis-github-status": "^1.6.3"
},
"peerDependencies": {
Expand Down
4 changes: 2 additions & 2 deletions src/flowTypes.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ export type ModuleOptions = {
}

export type ComponentOptions = {
loading?: LoadingCompponent,
loading?: LoadingComponent,
error?: ErrorComponent,
minDelay?: number,
alwaysDelay?: boolean,
Expand Down Expand Up @@ -110,7 +110,7 @@ export type GenericComponent<Props> =
| React$Element<any>

export type Component<Props> = GenericComponent<Props>
export type LoadingCompponent = GenericComponent<{}>
export type LoadingComponent = GenericComponent<{}>
export type ErrorComponent = GenericComponent<{}>

// babel-plugin-universal-import
Expand Down

0 comments on commit bfb83e3

Please sign in to comment.