xref: /expo/docs/components/plugins/SnackEmbed.tsx (revision 428b6b44)
1586106d6SBartłomiej Klocekimport * as React from 'react';
2586106d6SBartłomiej Klocek
3586106d6SBartłomiej Klocekimport { SNACK_URL } from '../../common/snack';
4586106d6SBartłomiej Klocek
5*428b6b44SAlbertotype Props = React.PropsWithChildren<{
6586106d6SBartłomiej Klocek  snackId?: string;
7586106d6SBartłomiej Klocek  name?: string;
8586106d6SBartłomiej Klocek  description?: string;
9586106d6SBartłomiej Klocek  platform?: string;
10586106d6SBartłomiej Klocek  preview?: boolean;
11586106d6SBartłomiej Klocek  theme?: string;
12586106d6SBartłomiej Klocek  style?: React.CSSProperties;
13*428b6b44SAlberto}>;
14586106d6SBartłomiej Klocek
15*428b6b44SAlbertoconst SnackEmbed = ({
16*428b6b44SAlberto  snackId,
17*428b6b44SAlberto  name,
18*428b6b44SAlberto  description,
19*428b6b44SAlberto  platform,
20*428b6b44SAlberto  preview,
21*428b6b44SAlberto  theme,
22*428b6b44SAlberto  style,
23*428b6b44SAlberto  children,
24*428b6b44SAlberto}: Props) => {
25*428b6b44SAlberto  React.useEffect(() => {
26586106d6SBartłomiej Klocek    let script = document.getElementById('snack') as HTMLScriptElement;
27586106d6SBartłomiej Klocek    // inject script if it hasn't been loaded by a previous page
28586106d6SBartłomiej Klocek    if (!script) {
29586106d6SBartłomiej Klocek      script = document.createElement('script');
30*428b6b44SAlberto      script.src = `${snackId ? 'https://snack.expo.dev' : SNACK_URL}/embed.js`;
31586106d6SBartłomiej Klocek      script.async = true;
32586106d6SBartłomiej Klocek      script.id = 'snack';
33586106d6SBartłomiej Klocek
34586106d6SBartłomiej Klocek      document.body.appendChild(script);
35586106d6SBartłomiej Klocek      script.addEventListener('load', () => {
36586106d6SBartłomiej Klocek        window.ExpoSnack.initialize();
37586106d6SBartłomiej Klocek      });
38586106d6SBartłomiej Klocek    }
39586106d6SBartłomiej Klocek
40586106d6SBartłomiej Klocek    if (window.ExpoSnack) {
41586106d6SBartłomiej Klocek      window.ExpoSnack.initialize();
42586106d6SBartłomiej Klocek    }
43*428b6b44SAlberto  }, [snackId]);
44586106d6SBartłomiej Klocek
45586106d6SBartłomiej Klocek  // TODO(abi): Handle `data-snack-sdk-version` somehow
46586106d6SBartłomiej Klocek  // maybe using `context`?
47586106d6SBartłomiej Klocek
48586106d6SBartłomiej Klocek  // get snack data from snack id or from inline code
49586106d6SBartłomiej Klocek  // TODO (barthap): Type all possible keys for this
50586106d6SBartłomiej Klocek  let embedProps: Record<string, any>;
51*428b6b44SAlberto  if (snackId) {
52*428b6b44SAlberto    embedProps = { 'data-snack-id': snackId };
53586106d6SBartłomiej Klocek  } else {
54*428b6b44SAlberto    const code = React.Children.toArray(children).join('').trim();
55586106d6SBartłomiej Klocek    embedProps = {
56586106d6SBartłomiej Klocek      'data-snack-code': code,
57586106d6SBartłomiej Klocek    };
58*428b6b44SAlberto    if (name) {
59*428b6b44SAlberto      embedProps['data-snack-name'] = name;
60586106d6SBartłomiej Klocek    }
61*428b6b44SAlberto    if (description) {
62*428b6b44SAlberto      embedProps['data-snack-description'] = description;
63586106d6SBartłomiej Klocek    }
64586106d6SBartłomiej Klocek  }
65586106d6SBartłomiej Klocek
66586106d6SBartłomiej Klocek  // fill in default options for snack styling
67*428b6b44SAlberto  if (platform) {
68*428b6b44SAlberto    embedProps['data-snack-platform'] = platform;
69586106d6SBartłomiej Klocek  } else {
70586106d6SBartłomiej Klocek    embedProps['data-snack-platform'] = 'ios';
71586106d6SBartłomiej Klocek  }
72586106d6SBartłomiej Klocek
73*428b6b44SAlberto  if (preview) {
74*428b6b44SAlberto    embedProps['data-snack-preview'] = preview;
75586106d6SBartłomiej Klocek  } else {
76586106d6SBartłomiej Klocek    embedProps['data-snack-preview'] = false;
77586106d6SBartłomiej Klocek  }
78586106d6SBartłomiej Klocek
79*428b6b44SAlberto  if (theme) {
80*428b6b44SAlberto    embedProps['data-snack-theme'] = theme;
81586106d6SBartłomiej Klocek  } else {
82586106d6SBartłomiej Klocek    embedProps['data-snack-theme'] = 'light';
83586106d6SBartłomiej Klocek  }
84586106d6SBartłomiej Klocek
85*428b6b44SAlberto  const embedStyle = style ? style! : {};
86586106d6SBartłomiej Klocek
87586106d6SBartłomiej Klocek  return (
88586106d6SBartłomiej Klocek    <div
89586106d6SBartłomiej Klocek      {...embedProps}
90586106d6SBartłomiej Klocek      style={{
91586106d6SBartłomiej Klocek        overflow: 'hidden',
92586106d6SBartłomiej Klocek        background: '#fafafa',
93586106d6SBartłomiej Klocek        borderWidth: 1,
94586106d6SBartłomiej Klocek        borderStyle: 'solid',
95586106d6SBartłomiej Klocek        height: 505,
96586106d6SBartłomiej Klocek        maxWidth: '1200px',
97586106d6SBartłomiej Klocek        borderRadius: 4,
98586106d6SBartłomiej Klocek        borderColor: 'rgba(0,0,0,.16)',
99586106d6SBartłomiej Klocek        ...embedStyle,
100586106d6SBartłomiej Klocek      }}
101586106d6SBartłomiej Klocek    />
102586106d6SBartłomiej Klocek  );
103*428b6b44SAlberto};
104*428b6b44SAlberto
105*428b6b44SAlbertoexport default SnackEmbed;
106