1*641d0767SEvan Baconimport React from 'react';
2*641d0767SEvan Baconimport { Platform, StyleSheet, Text } from 'react-native';
3*641d0767SEvan Bacon
4*641d0767SEvan Baconfunction useChildren(inputChildren: React.ReactNode) {
5*641d0767SEvan Bacon  return React.useMemo(() => {
6*641d0767SEvan Bacon    const children: React.ReactNode[] = [];
7*641d0767SEvan Bacon    React.Children.forEach(inputChildren, (child) => {
8*641d0767SEvan Bacon      if (child == null || typeof child === 'boolean') {
9*641d0767SEvan Bacon      } else if (typeof child === 'string' || typeof child === 'number') {
10*641d0767SEvan Bacon        // Wrap text in a Text component.
11*641d0767SEvan Bacon        let message = `Invalid raw text as a child of View: "${child}"${
12*641d0767SEvan Bacon          child === '' ? ` [empty string]` : ''
13*641d0767SEvan Bacon        }.`;
14*641d0767SEvan Bacon        message += ' Wrap the text contents with a Text element or remove it.';
15*641d0767SEvan Bacon        console.warn(message);
16*641d0767SEvan Bacon        children.push(
17*641d0767SEvan Bacon          <Text style={[StyleSheet.absoluteFill, styles.error]}>
18*641d0767SEvan Bacon            Unwrapped text: "<Text style={{ fontWeight: 'bold' }}>{child}</Text>"
19*641d0767SEvan Bacon          </Text>
20*641d0767SEvan Bacon        );
21*641d0767SEvan Bacon      } else if ('type' in child && typeof child?.type === 'string' && Platform.OS !== 'web') {
22*641d0767SEvan Bacon        // Disallow untransformed react-dom elements on native.
23*641d0767SEvan Bacon        throw new Error(`Using unsupported React DOM element: <${child.type} />`);
24*641d0767SEvan Bacon      } else {
25*641d0767SEvan Bacon        children.push(child);
26*641d0767SEvan Bacon      }
27*641d0767SEvan Bacon    });
28*641d0767SEvan Bacon    return children;
29*641d0767SEvan Bacon  }, [inputChildren]);
30*641d0767SEvan Bacon}
31*641d0767SEvan Bacon
32*641d0767SEvan Bacon/** Extend a view with a `children` filter that asserts more helpful warnings/errors. */
33*641d0767SEvan Baconexport function createDevView<TView extends React.ComponentType<any>>(View: TView) {
34*641d0767SEvan Bacon  return React.forwardRef(({ children, ...props }: any, forwardedRef: React.Ref<TView>) => {
35*641d0767SEvan Bacon    return <View ref={forwardedRef} {...props} children={useChildren(children)} />;
36*641d0767SEvan Bacon  });
37*641d0767SEvan Bacon}
38*641d0767SEvan Bacon
39*641d0767SEvan Baconconst styles = StyleSheet.create({
40*641d0767SEvan Bacon  error: {
41*641d0767SEvan Bacon    backgroundColor: 'firebrick',
42*641d0767SEvan Bacon    color: 'white',
43*641d0767SEvan Bacon  },
44*641d0767SEvan Bacon});
45