1 | /// <reference types="react" />
|
2 |
|
3 | declare namespace LoadableExport {
|
4 | interface LoadingComponentProps {
|
5 | isLoading: boolean;
|
6 | pastDelay: boolean;
|
7 | timedOut: boolean;
|
8 | error: any;
|
9 | retry: () => void;
|
10 | }
|
11 |
|
12 | type Options<Props, Exports extends object> = OptionsWithoutRender<Props> | OptionsWithRender<Props, Exports>;
|
13 |
|
14 | interface CommonOptions {
|
15 | /**
|
16 | * React component displayed after delay until loader() succeeds. Also responsible for displaying errors.
|
17 | *
|
18 | * If you don't want to render anything you can pass a function that returns null
|
19 | * (this is considered a valid React component).
|
20 | */
|
21 | loading: React.ComponentType<LoadingComponentProps>;
|
22 | /**
|
23 | * Defaults to 200, in milliseconds.
|
24 | *
|
25 | * Only show the loading component if the loader() has taken this long to succeed or error.
|
26 | */
|
27 | delay?: number | false | null | undefined;
|
28 | /**
|
29 | * Disabled by default.
|
30 | *
|
31 | * After the specified time in milliseconds passes, the component's `timedOut` prop will be set to true.
|
32 | */
|
33 | timeout?: number | false | null | undefined;
|
34 |
|
35 | /**
|
36 | * Optional array of module paths that `Loadable.Capture`'s `report` function will be applied on during
|
37 | * server-side rendering. This helps the server know which modules were imported/used during SSR.
|
38 | * ```ts
|
39 | * Loadable({
|
40 | * loader: () => import('./my-component'),
|
41 | * modules: ['./my-component'],
|
42 | * });
|
43 | * ```
|
44 | */
|
45 | modules?: string[] | undefined;
|
46 |
|
47 | /**
|
48 | * An optional function which returns an array of Webpack module ids which you can get
|
49 | * with require.resolveWeak. This is used by the client (inside `Loadable.preloadReady`) to
|
50 | * guarantee each webpack module is preloaded before the first client render.
|
51 | * ```ts
|
52 | * Loadable({
|
53 | * loader: () => import('./Foo'),
|
54 | * webpack: () => [require.resolveWeak('./Foo')],
|
55 | * });
|
56 | * ```
|
57 | */
|
58 | webpack?: (() => Array<string | number>) | undefined;
|
59 | }
|
60 |
|
61 | interface OptionsWithoutRender<Props> extends CommonOptions {
|
62 | /**
|
63 | * Function returning a promise which returns a React component displayed on success.
|
64 | *
|
65 | * Resulting React component receives all the props passed to the generated component.
|
66 | */
|
67 | loader(): Promise<React.ComponentType<Props> | { default: React.ComponentType<Props> }>;
|
68 | }
|
69 |
|
70 | interface OptionsWithRender<Props, Exports extends object> extends CommonOptions {
|
71 | /**
|
72 | * Function returning a promise which returns an object to be passed to `render` on success.
|
73 | */
|
74 | loader(): Promise<Exports>;
|
75 | /**
|
76 | * If you want to customize what gets rendered from your loader you can also pass `render`.
|
77 | *
|
78 | * Note: If you want to load multiple resources at once, you can also use `Loadable.Map`.
|
79 | *
|
80 | * ```ts
|
81 | * Loadable({
|
82 | * // ...
|
83 | * render(loaded, props) {
|
84 | * const Component = loaded.default;
|
85 | * return <Component {...props} />
|
86 | * }
|
87 | * });
|
88 | * ```
|
89 | */
|
90 | render(loaded: Exports, props: Props): React.ReactNode;
|
91 |
|
92 | // NOTE: render is not optional if the loader return type is not compatible with the type
|
93 | // expected in `OptionsWithoutRender`. If you do not want to provide a render function, ensure that your
|
94 | // function is returning a promise for a React.ComponentType or is the result of import()ing a module
|
95 | // that has a component as its `default` export.
|
96 | }
|
97 |
|
98 | interface OptionsWithMap<Props, Exports extends { [key: string]: any }> extends CommonOptions {
|
99 | /**
|
100 | * An object containing functions which return promises, which resolve to an object to be passed to `render` on success.
|
101 | */
|
102 | loader: {
|
103 | [P in keyof Exports]: () => Promise<Exports[P]>;
|
104 | };
|
105 | /**
|
106 | * If you want to customize what gets rendered from your loader you can also pass `render`.
|
107 | *
|
108 | * Note: If you want to load multiple resources at once, you can also use `Loadable.Map`.
|
109 | *
|
110 | * ```ts
|
111 | * Loadable({
|
112 | * // ...
|
113 | * render(loaded, props) {
|
114 | * const Component = loaded.default;
|
115 | * return <Component {...props} />
|
116 | * }
|
117 | * });
|
118 | * ```
|
119 | */
|
120 | render(loaded: Exports, props: Props): React.ReactNode;
|
121 | }
|
122 |
|
123 | interface LoadableComponent {
|
124 | /**
|
125 | * The generated component has a static method preload() for calling the loader function ahead of time.
|
126 | * This is useful for scenarios where you think the user might do something next and want to load the
|
127 | * next component eagerly.
|
128 | *
|
129 | * Note: preload() intentionally does not return a promise. You should not be depending on the timing of
|
130 | * preload(). It's meant as a performance optimization, not for creating UI logic.
|
131 | */
|
132 | preload(): void;
|
133 | }
|
134 |
|
135 | interface LoadableCaptureProps {
|
136 | /**
|
137 | * Function called for every moduleName that is rendered via React Loadable.
|
138 | */
|
139 | report: (moduleName: string) => void;
|
140 | }
|
141 |
|
142 | interface Loadable {
|
143 | <Props, Exports extends object>(
|
144 | options: Options<Props, Exports>,
|
145 | ): React.ComponentType<Props> & LoadableComponent;
|
146 | Map<Props, Exports extends { [key: string]: any }>(
|
147 | options: OptionsWithMap<Props, Exports>,
|
148 | ): React.ComponentType<Props> & LoadableComponent;
|
149 |
|
150 | /**
|
151 | * This will call all of the LoadableComponent.preload methods recursively until they are all
|
152 | * resolved. Allowing you to preload all of your dynamic modules in environments like the server.
|
153 | * ```ts
|
154 | * Loadable.preloadAll().then(() => {
|
155 | * app.listen(3000, () => {
|
156 | * console.log('Running on http://localhost:3000/');
|
157 | * });
|
158 | * });
|
159 | * ```
|
160 | */
|
161 | preloadAll(): Promise<void>;
|
162 |
|
163 | /**
|
164 | * Check for modules that are already loaded in the browser and call the matching
|
165 | * `LoadableComponent.preload` methods.
|
166 | * ```ts
|
167 | * window.main = () => {
|
168 | * Loadable.preloadReady().then(() => {
|
169 | * ReactDOM.hydrate(
|
170 | * <App/>,
|
171 | * document.getElementById('app'),
|
172 | * );
|
173 | * });
|
174 | * };
|
175 | * ```
|
176 | */
|
177 | preloadReady(): Promise<void>;
|
178 |
|
179 | Capture: React.ComponentType<LoadableCaptureProps>;
|
180 | }
|
181 | }
|
182 |
|
183 | declare const LoadableExport: LoadableExport.Loadable;
|
184 |
|
185 | /* eslint-disable-next-line @definitelytyped/no-declare-current-package */
|
186 | declare module "react-loadable" {
|
187 | export = LoadableExport;
|
188 | }
|