1 | import React from 'react';
|
2 | import {DeferTiming} from '@shopify/async';
|
3 | import {Preconnect} from '@shopify/react-html';
|
4 |
|
5 | import {useImportRemote, Status} from './hooks';
|
6 |
|
7 | export interface Props<Imported = any> {
|
8 | source: string;
|
9 | nonce?: string;
|
10 | preconnect?: boolean;
|
11 | getImport(window: Window): Imported;
|
12 | onImported(imported: Imported | Error): void;
|
13 | defer?: DeferTiming;
|
14 | }
|
15 |
|
16 | export default function ImportRemote<T = unknown>({
|
17 | source,
|
18 | nonce,
|
19 | preconnect,
|
20 | getImport,
|
21 | onImported,
|
22 | defer,
|
23 | }: Props<T>) {
|
24 | const {result, intersectionRef} = useImportRemote<T>(source, {
|
25 | defer,
|
26 | nonce,
|
27 | getImport,
|
28 | });
|
29 |
|
30 | const intersectionObserver =
|
31 | defer === DeferTiming.InViewport && intersectionRef ? (
|
32 | <div ref={intersectionRef as React.RefObject<HTMLDivElement>} />
|
33 | ) : null;
|
34 |
|
35 | React.useEffect(() => {
|
36 | switch (result.status) {
|
37 | case Status.Failed:
|
38 | onImported(result.error);
|
39 | return;
|
40 | case Status.Complete:
|
41 | onImported(result.imported);
|
42 | }
|
43 | }, [result, onImported]);
|
44 |
|
45 | if (preconnect) {
|
46 | const url = new URL(source);
|
47 | return (
|
48 | <>
|
49 | <Preconnect source={url.origin} />
|
50 | {intersectionObserver}
|
51 | </>
|
52 | );
|
53 | }
|
54 |
|
55 | return intersectionObserver;
|
56 | }
|