Repository: callstack/react-native-paper
Pull request #1180 (2019-07-05 10:47:48)

fix: add $Omit for lower Typescript versions

### Motivation

Only recently Typescript introduced `Omit`. If you are still with a lower version you will encounter several type issues. This PR will add a local helper `$Omit`.

### Test plan

n/a


callstack-bot: Hey @jaulz, thank you for your pull request 🤗. The documentation from this branch can be viewed [here](https://11473-71323749-gh.circle-artifacts.com/0/docs/index.html).

Patch:
diff --git a/src/components/Appbar/AppbarBackAction.tsx b/src/components/Appbar/AppbarBackAction.tsx
index f985e0e1e..55b40e82a 100644
--- a/src/components/Appbar/AppbarBackAction.tsx
+++ b/src/components/Appbar/AppbarBackAction.tsx
@@ -8,10 +8,10 @@ import {
   StyleProp,
   ViewStyle,
 } from 'react-native';
-
+import { $Omit } from './../../types';
 import AppbarAction from './AppbarAction';
 
-type Props = Omit<
+type Props = $Omit<
   React.ComponentProps<typeof AppbarAction> & {
     /**
      *  Custom color for back icon.
diff --git a/src/components/Appbar/AppbarHeader.tsx b/src/components/Appbar/AppbarHeader.tsx
index 8b8a18982..53aa6e4a8 100644
--- a/src/components/Appbar/AppbarHeader.tsx
+++ b/src/components/Appbar/AppbarHeader.tsx
@@ -34,7 +34,6 @@ type Props = React.ComponentProps<typeof Appbar> & {
    */
   theme: Theme;
   style?: StyleProp<ViewStyle>;
-  __expo?: any;
 };
 
 /**
diff --git a/src/components/Banner.tsx b/src/components/Banner.tsx
index ee0b67c1d..99c6394cc 100644
--- a/src/components/Banner.tsx
+++ b/src/components/Banner.tsx
@@ -8,6 +8,7 @@ import { Theme, $RemoveChildren } from '../types';
 import shadow from '../styles/shadow';
 
 const ELEVATION = 1;
+const DEFAULT_MAX_WIDTH = 960;
 
 type Props = $RemoveChildren<typeof Surface> & {
   /**
@@ -35,6 +36,11 @@ type Props = $RemoveChildren<typeof Surface> & {
     label: string;
     onPress: () => void;
   }>;
+  /**
+   * Style of banner's inner content.
+   * Use this prop to apply custom width for wide layouts.
+   */
+  contentStyle?: StyleProp<ViewStyle>;
   style?: StyleProp<ViewStyle>;
   /**
    * @optional
@@ -159,6 +165,7 @@ class Banner extends React.Component<Props, State> {
       image,
       children,
       actions,
+      contentStyle,
       style,
       // eslint-disable-next-line @typescript-eslint/no-unused-vars
       theme,
@@ -185,7 +192,7 @@ class Banner extends React.Component<Props, State> {
         {...rest}
         style={[styles.container, shadow(ELEVATION) as ViewStyle, style]}
       >
-        <View style={styles.wrapper}>
+        <View style={[styles.wrapper, contentStyle]}>
           <Animated.View style={{ height }} />
           <Animated.View
             onLayout={this._handleLayout}
@@ -235,6 +242,9 @@ const styles = StyleSheet.create({
   },
   wrapper: {
     overflow: 'hidden',
+    alignSelf: 'center',
+    width: '100%',
+    maxWidth: DEFAULT_MAX_WIDTH,
   },
   absolute: {
     position: 'absolute',
diff --git a/src/components/HelperText.tsx b/src/components/HelperText.tsx
index b588e6f55..2a092b342 100644
--- a/src/components/HelperText.tsx
+++ b/src/components/HelperText.tsx
@@ -9,10 +9,10 @@ import {
 } from 'react-native';
 import AnimatedText from './Typography/AnimatedText';
 import { withTheme } from '../core/theming';
-import { Theme } from '../types';
+import { Theme, $Omit } from '../types';
 
-type Props = Omit<
-  Omit<React.ComponentProps<typeof Animated.Text>, 'padding'>,
+type Props = $Omit<
+  $Omit<React.ComponentProps<typeof Animated.Text>, 'padding'>,
   'type'
 > & {
   /**
diff --git a/src/components/Menu/Menu.tsx b/src/components/Menu/Menu.tsx
index 75703749e..f1d0aef7b 100644
--- a/src/components/Menu/Menu.tsx
+++ b/src/components/Menu/Menu.tsx
@@ -16,7 +16,7 @@ import {
 } from 'react-native';
 
 import { withTheme } from '../../core/theming';
-import { Theme } from '../../types';
+import { Theme, $Omit } from '../../types';
 import Portal from '../Portal/Portal';
 import Surface from '../Surface';
 // eslint-disable-next-line @typescript-eslint/no-unused-vars
@@ -54,7 +54,7 @@ type Props = {
   theme: Theme;
 };
 
-type Layout = Omit<Omit<LayoutRectangle, 'x'>, 'y'>;
+type Layout = $Omit<$Omit<LayoutRectangle, 'x'>, 'y'>;
 
 type State = {
   rendered: boolean;
diff --git a/src/components/TextInput/types.tsx b/src/components/TextInput/types.tsx
index be470f018..03ed6576d 100644
--- a/src/components/TextInput/types.tsx
+++ b/src/components/TextInput/types.tsx
@@ -1,5 +1,6 @@
 import { TextInput as NativeTextInput, Animated } from 'react-native';
 import { TextInputProps } from './TextInput';
+import { $Omit } from './../../types';
 
 export type RenderProps = {
   ref: (a: NativeTextInput | null | undefined) => void;
@@ -17,7 +18,7 @@ export type RenderProps = {
   value?: string;
   adjustsFontSizeToFit?: boolean;
 };
-type TextInputTypesWithoutMode = Omit<TextInputProps, 'mode'>;
+type TextInputTypesWithoutMode = $Omit<TextInputProps, 'mode'>;
 export type State = {
   labeled: Animated.Value;
   error: Animated.Value;
diff --git a/src/types.tsx b/src/types.tsx
index 9a1e638a4..9f2dc0901 100644
--- a/src/types.tsx
+++ b/src/types.tsx
@@ -44,7 +44,8 @@ export type Theme = {
   };
 };
 
-export type $RemoveChildren<T extends React.ComponentType<any>> = Omit<
+export type $Omit<T, K> = Pick<T, Exclude<keyof T, K>>;
+export type $RemoveChildren<T extends React.ComponentType<any>> = $Omit<
   React.ComponentProps<T>,
   'children'
 >;


Test patch:
diff --git a/src/components/__tests__/ListItem.test.js b/src/components/__tests__/ListItem.test.js
index 425158e2f..ab0c77a59 100644
--- a/src/components/__tests__/ListItem.test.js
+++ b/src/components/__tests__/ListItem.test.js
@@ -1,8 +1,9 @@
 import * as React from 'react';
 import renderer from 'react-test-renderer';
-import { Text } from 'react-native';
+import { Text, View } from 'react-native';
 import ListItem from '../List/ListItem.tsx';
 import ListIcon from '../List/ListIcon.tsx';
+import Chip from '../Chip';
 
 it('renders list item with title and description', () => {
   const tree = renderer
@@ -64,3 +65,32 @@ it('renders list item with custom title and description styles', () => {
 
   expect(tree).toMatchSnapshot();
 });
+
+it('renders list item with custom description', () => {
+  const tree = renderer
+    .create(
+      <ListItem
+        title="List Item with custom description"
+        description={({ ellipsizeMode, color: descriptionColor, fontSize }) => (
+          <View>
+            <Text
+              numberOfLines={2}
+              ellipsizeMode={ellipsizeMode}
+              style={{ color: descriptionColor, fontSize }}
+            >
+              React Native Paper is a high-quality, standard-compliant Design
+              Design library that has you covered in all major use-cases.
+            </Text>
+            <View>
+              <Chip icon="picture-as-pdf" onPress={() => {}}>
+                DOCS.pdf
+              </Chip>
+            </View>
+          </View>
+        )}
+      />
+    )
+    .toJSON();
+
+  expect(tree).toMatchSnapshot();
+});
diff --git a/src/components/__tests__/__snapshots__/Banner.test.js.snap b/src/components/__tests__/__snapshots__/Banner.test.js.snap
index a6bc36490..6be3f901b 100644
--- a/src/components/__tests__/__snapshots__/Banner.test.js.snap
+++ b/src/components/__tests__/__snapshots__/Banner.test.js.snap
@@ -18,9 +18,15 @@ exports[`renders hidden banner, without action buttons and without image 1`] = `
 >
   <View
     style={
-      Object {
-        "overflow": "hidden",
-      }
+      Array [
+        Object {
+          "alignSelf": "center",
+          "maxWidth": 960,
+          "overflow": "hidden",
+          "width": "100%",
+        },
+        undefined,
+      ]
     }
   >
     <View
@@ -109,9 +115,15 @@ exports[`renders visible banner, with action buttons and with image 1`] = `
 >
   <View
     style={
-      Object {
-        "overflow": "hidden",
-      }
+      Array [
+        Object {
+          "alignSelf": "center",
+          "maxWidth": 960,
+          "overflow": "hidden",
+          "width": "100%",
+        },
+        undefined,
+      ]
     }
   >
     <View
@@ -296,9 +308,15 @@ exports[`renders visible banner, with action buttons and without image 1`] = `
 >
   <View
     style={
-      Object {
-        "overflow": "hidden",
-      }
+      Array [
+        Object {
+          "alignSelf": "center",
+          "maxWidth": 960,
+          "overflow": "hidden",
+          "width": "100%",
+        },
+        undefined,
+      ]
     }
   >
     <View
@@ -548,9 +566,15 @@ exports[`renders visible banner, without action buttons and with image 1`] = `
 >
   <View
     style={
-      Object {
-        "overflow": "hidden",
-      }
+      Array [
+        Object {
+          "alignSelf": "center",
+          "maxWidth": 960,
+          "overflow": "hidden",
+          "width": "100%",
+        },
+        undefined,
+      ]
     }
   >
     <View
@@ -648,9 +672,15 @@ exports[`renders visible banner, without action buttons and without image 1`] =
 >
   <View
     style={
-      Object {
-        "overflow": "hidden",
-      }
+      Array [
+        Object {
+          "alignSelf": "center",
+          "maxWidth": 960,
+          "overflow": "hidden",
+          "width": "100%",
+        },
+        undefined,
+      ]
     }
   >
     <View
diff --git a/src/components/__tests__/__snapshots__/ListItem.test.js.snap b/src/components/__tests__/__snapshots__/ListItem.test.js.snap
index 296892037..23093e960 100644
--- a/src/components/__tests__/__snapshots__/ListItem.test.js.snap
+++ b/src/components/__tests__/__snapshots__/ListItem.test.js.snap
@@ -1,5 +1,215 @@
 // Jest Snapshot v1, https://goo.gl/fbAQLP
 
+exports[`renders list item with custom description 1`] = `
+<View
+  accessible={true}
+  isTVSelectable={true}
+  onResponderGrant={[Function]}
+  onResponderMove={[Function]}
+  onResponderRelease={[Function]}
+  onResponderTerminate={[Function]}
+  onResponderTerminationRequest={[Function]}
+  onStartShouldSetResponder={[Function]}
+  style={
+    Array [
+      false,
+      Array [
+        Object {
+          "padding": 8,
+        },
+        undefined,
+      ],
+    ]
+  }
+>
+  <View
+    style={
+      Object {
+        "flexDirection": "row",
+      }
+    }
+  >
+    <View
+      pointerEvents="none"
+      style={
+        Array [
+          Object {
+            "marginVertical": 6,
+            "paddingLeft": 8,
+          },
+          Object {
+            "flex": 1,
+            "justifyContent": "center",
+          },
+        ]
+      }
+    >
+      <Text
+        numberOfLines={1}
+        style={
+          Array [
+            Object {
+              "color": "#000000",
+              "fontFamily": "System",
+              "fontWeight": "400",
+              "textAlign": "left",
+              "writingDirection": "ltr",
+            },
+            Array [
+              Object {
+                "fontSize": 16,
+              },
+              Object {
+                "color": "rgba(0, 0, 0, 0.87)",
+              },
+              undefined,
+            ],
+          ]
+        }
+      >
+        List Item with custom description
+      </Text>
+      <View>
+        <Text
+          numberOfLines={2}
+          style={
+            Object {
+              "color": "rgba(0, 0, 0, 0.54)",
+              "fontSize": 14,
+            }
+          }
+        >
+          React Native Paper is a high-quality, standard-compliant Design Design library that has you covered in all major use-cases.
+        </Text>
+        <View>
+          <View
+            style={
+              Object {
+                "backgroundColor": "#ebebeb",
+                "borderColor": "#ebebeb",
+                "borderRadius": 16,
+                "borderStyle": "solid",
+                "borderWidth": 0.5,
+                "elevation": 0,
+              }
+            }
+          >
+            <View
+              accessibilityRole="button"
+              accessibilityStates={Array []}
+              accessible={true}
+              isTVSelectable={true}
+              onResponderGrant={[Function]}
+              onResponderMove={[Function]}
+              onResponderRelease={[Function]}
+              onResponderTerminate={[Function]}
+              onResponderTerminationRequest={[Function]}
+              onStartShouldSetResponder={[Function]}
+              style={
+                Array [
+                  Object {
+                    "overflow": "hidden",
+                  },
+                  Object {
+                    "borderRadius": 16,
+                  },
+                ]
+              }
+            >
+              <View
+                style={
+                  Object {
+                    "alignItems": "center",
+                    "flexDirection": "row",
+                    "paddingHorizontal": 4,
+                  }
+                }
+              >
+                <View
+                  style={
+                    Array [
+                      Object {
+                        "padding": 4,
+                      },
+                      null,
+                    ]
+                  }
+                >
+                  <Text
+                    accessibilityElementsHidden={true}
+                    allowFontScaling={false}
+                    importantForAccessibility="no-hide-descendants"
+                    pointerEvents="none"
+                    style={
+                      Array [
+                        Object {
+                          "color": "rgba(0, 0, 0, 0.54)",
+                          "fontSize": 18,
+                        },
+                        Array [
+                          Object {
+                            "transform": Array [
+                              Object {
+                                "scaleX": 1,
+                              },
+                            ],
+                          },
+                          Object {
+                            "backgroundColor": "transparent",
+                          },
+                        ],
+                        Object {
+                          "fontFamily": "Material Icons",
+                          "fontStyle": "normal",
+                          "fontWeight": "normal",
+                        },
+                        Object {},
+                      ]
+                    }
+                  >
+                    
+                  </Text>
+                </View>
+                <Text
+                  numberOfLines={1}
+                  style={
+                    Array [
+                      Object {
+                        "color": "#000000",
+                        "fontFamily": "System",
+                        "fontWeight": "400",
+                        "textAlign": "left",
+                        "writingDirection": "ltr",
+                      },
+                      Array [
+                        Object {
+                          "lineHeight": 24,
+                          "marginVertical": 4,
+                          "minHeight": 24,
+                          "textAlignVertical": "center",
+                        },
+                        Object {
+                          "color": "rgba(0, 0, 0, 0.87)",
+                          "marginLeft": 4,
+                          "marginRight": 8,
+                        },
+                        undefined,
+                      ],
+                    ]
+                  }
+                >
+                  DOCS.pdf
+                </Text>
+              </View>
+            </View>
+          </View>
+        </View>
+      </View>
+    </View>
+  </View>
+</View>
+`;
+
 exports[`renders list item with custom title and description styles 1`] = `
 <View
   accessible={true}