Repository: callstack/react-native-paper
Pull request #1304 (2019-08-26 10:05:07)

refactor: banner - icon prop instead of image
I changed the banner's prop `image` to `icon` to make the component more reusable

### Motivation

@Trancever motivated me.

### Test plan

The current solution can be reviewed using an example app.


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

Patch:
diff --git a/babel.js b/babel.js
index 3ddfa4d58..ab674dd00 100644
--- a/babel.js
+++ b/babel.js
@@ -1,1 +1,1 @@
-module.exports = require('./src/babel');
+module.exports = require('./lib/module/babel/index.js');
diff --git a/example/src/Examples/BannerExample.tsx b/example/src/Examples/BannerExample.tsx
index 2e9a4af5e..3fcf3664d 100644
--- a/example/src/Examples/BannerExample.tsx
+++ b/example/src/Examples/BannerExample.tsx
@@ -54,15 +54,7 @@ class BannerExample extends React.Component<Props, State> {
                 },
               },
             ]}
-            image={({ size }) => (
-              <Image
-                source={require('../../assets/images/email-icon.png')}
-                style={{
-                  width: size,
-                  height: size,
-                }}
-              />
-            )}
+            icon={require('../../assets/images/email-icon.png')}
             visible={this.state.visible}
           >
             Two line text string with two actions. One to two lines is
diff --git a/example/src/Examples/ButtonExample.tsx b/example/src/Examples/ButtonExample.tsx
index 0ce4d7d12..4b0d98cd3 100644
--- a/example/src/Examples/ButtonExample.tsx
+++ b/example/src/Examples/ButtonExample.tsx
@@ -80,6 +80,17 @@ class ButtonExample extends React.Component<Props, State> {
             >
               Loading
             </Button>
+            <Button
+              mode="outlined"
+              onPress={() => {}}
+              style={styles.button}
+              labelStyle={{
+                fontWeight: '800',
+                fontSize: 18,
+              }}
+            >
+              Custom Font
+            </Button>
           </View>
         </List.Section>
         <List.Section title="Contained button">
diff --git a/package.json b/package.json
index 6ea4aa679..bcca9004c 100644
--- a/package.json
+++ b/package.json
@@ -5,9 +5,9 @@
   "main": "lib/module/index.js",
   "types": "lib/typescript/src/index.d.ts",
   "files": [
-    "src",
     "lib",
-    "dist"
+    "dist",
+    "babel.js"
   ],
   "sideEffects": false,
   "repository": {
@@ -134,4 +134,4 @@
       "src/"
     ]
   }
-}
+}
\ No newline at end of file
diff --git a/src/components/Banner.tsx b/src/components/Banner.tsx
index 99c6394cc..6076975e9 100644
--- a/src/components/Banner.tsx
+++ b/src/components/Banner.tsx
@@ -3,6 +3,7 @@ import { View, ViewStyle, StyleSheet, StyleProp, Animated } from 'react-native';
 import Surface from './Surface';
 import Text from './Typography/Text';
 import Button from './Button';
+import Icon, { IconSource } from './Icon';
 import { withTheme } from '../core/theming';
 import { Theme, $RemoveChildren } from '../types';
 import shadow from '../styles/shadow';
@@ -20,9 +21,9 @@ type Props = $RemoveChildren<typeof Surface> & {
    */
   children: string;
   /**
-   * Callback that returns an image to display inside banner.
+   * Icon to display for the `Banner`. Can be an image.
    */
-  image?: (props: { size: number }) => React.ReactNode;
+  icon?: IconSource;
   /**
    * Action items to shown in the banner.
    * An action item should contain the following properties:
@@ -162,7 +163,7 @@ class Banner extends React.Component<Props, State> {
   render() {
     const {
       visible,
-      image,
+      icon,
       children,
       actions,
       contentStyle,
@@ -186,7 +187,6 @@ class Banner extends React.Component<Props, State> {
       Animated.add(position, -1),
       layout.height
     );
-
     return (
       <Surface
         {...rest}
@@ -211,8 +211,12 @@ class Banner extends React.Component<Props, State> {
             ]}
           >
             <View style={styles.content}>
-              {image ? (
-                <View style={styles.image}>{image({ size: 40 })}</View>
+              {icon ? (
+                <View style={styles.icon}>
+                  {/* 
+                  // @ts-ignore */}
+                  <Icon source={icon} size={40} />
+                </View>
               ) : null}
               <Text style={styles.message}>{children}</Text>
             </View>
@@ -258,7 +262,7 @@ const styles = StyleSheet.create({
     marginTop: 16,
     marginBottom: 0,
   },
-  image: {
+  icon: {
     margin: 8,
   },
   message: {
diff --git a/src/components/Button.tsx b/src/components/Button.tsx
index 91885c71d..218b270ea 100644
--- a/src/components/Button.tsx
+++ b/src/components/Button.tsx
@@ -1,5 +1,12 @@
 import * as React from 'react';
-import { Animated, View, ViewStyle, StyleSheet, StyleProp } from 'react-native';
+import {
+  Animated,
+  View,
+  ViewStyle,
+  StyleSheet,
+  StyleProp,
+  TextStyle,
+} from 'react-native';
 import color from 'color';
 
 import ActivityIndicator from './ActivityIndicator';
@@ -66,6 +73,10 @@ type Props = React.ComponentProps<typeof Surface> & {
    */
   contentStyle?: StyleProp<ViewStyle>;
   style?: StyleProp<ViewStyle>;
+  /**
+   * Style for the button text.
+   */
+  labelStyle?: StyleProp<TextStyle>;
   /**
    * @optional
    */
@@ -152,6 +163,7 @@ class Button extends React.Component<Props, State> {
       style,
       theme,
       contentStyle,
+      labelStyle,
       ...rest
     } = this.props;
     const { colors, roundness } = theme;
@@ -268,15 +280,13 @@ class Button extends React.Component<Props, State> {
               style={[
                 styles.label,
                 compact && styles.compactLabel,
+                uppercase && styles.uppercaseLabel,
                 textStyle,
                 font,
+                labelStyle,
               ]}
             >
-              {React.Children.map(children, child =>
-                typeof child === 'string' && uppercase
-                  ? child.toUpperCase()
-                  : child
-              )}
+              {children}
             </Text>
           </View>
         </TouchableRipple>
@@ -312,6 +322,9 @@ const styles = StyleSheet.create({
   compactLabel: {
     marginHorizontal: 8,
   },
+  uppercaseLabel: {
+    textTransform: 'uppercase',
+  },
 });
 
 export default withTheme(Button);
diff --git a/src/components/Chip.tsx b/src/components/Chip.tsx
index ed962039d..6fd5e953c 100644
--- a/src/components/Chip.tsx
+++ b/src/components/Chip.tsx
@@ -302,7 +302,7 @@ class Chip extends React.Component<Props, State> {
                 accessibilityComponentType="button"
               >
                 <View style={styles.icon}>
-                  <Icon source="cancel" size={16} color={iconColor} />
+                  <Icon source="close-circle" size={16} color={iconColor} />
                 </View>
               </TouchableWithoutFeedback>
             ) : null}
diff --git a/src/components/FAB/FAB.tsx b/src/components/FAB/FAB.tsx
index a01b52754..dc8479d65 100644
--- a/src/components/FAB/FAB.tsx
+++ b/src/components/FAB/FAB.tsx
@@ -217,7 +217,7 @@ class FAB extends React.Component<Props, State> {
             {icon && loading !== true ? (
               <CrossFadeIcon source={icon} size={24} color={foregroundColor} />
             ) : null}
-            {loading && label ? (
+            {loading ? (
               <ActivityIndicator size={18} color={foregroundColor} />
             ) : null}
             {label ? (
diff --git a/src/components/List/ListAccordion.tsx b/src/components/List/ListAccordion.tsx
index 6acde24d9..7a31217a2 100644
--- a/src/components/List/ListAccordion.tsx
+++ b/src/components/List/ListAccordion.tsx
@@ -56,6 +56,16 @@ type Props = {
    * Style that is passed to Description element.
    */
   descriptionStyle?: StyleProp<TextStyle>;
+  /**
+   * Truncate Title text such that the total number of lines does not
+   * exceed this number.
+   */
+  titleNumberOfLines?: number;
+  /**
+   * Truncate Description text such that the total number of lines does not
+   * exceed this number.
+   */
+  descriptionNumberOfLines?: number;
 };
 
 type State = {
@@ -117,6 +127,11 @@ type State = {
 class ListAccordion extends React.Component<Props, State> {
   static displayName = 'List.Accordion';
 
+  static defaultProps: Partial<Props> = {
+    titleNumberOfLines: 1,
+    descriptionNumberOfLines: 2,
+  };
+
   state = {
     expanded: this.props.expanded || false,
   };
@@ -142,6 +157,8 @@ class ListAccordion extends React.Component<Props, State> {
       theme,
       titleStyle,
       descriptionStyle,
+      titleNumberOfLines,
+      descriptionNumberOfLines,
       style,
     } = this.props;
     const titleColor = color(theme.colors.text)
@@ -175,7 +192,7 @@ class ListAccordion extends React.Component<Props, State> {
               : null}
             <View style={[styles.item, styles.content]}>
               <Text
-                numberOfLines={1}
+                numberOfLines={titleNumberOfLines}
                 style={[
                   styles.title,
                   {
@@ -188,7 +205,7 @@ class ListAccordion extends React.Component<Props, State> {
               </Text>
               {description && (
                 <Text
-                  numberOfLines={2}
+                  numberOfLines={descriptionNumberOfLines}
                   style={[
                     styles.description,
                     {
diff --git a/src/components/List/ListItem.tsx b/src/components/List/ListItem.tsx
index e569ac108..0c18b42a1 100644
--- a/src/components/List/ListItem.tsx
+++ b/src/components/List/ListItem.tsx
@@ -71,10 +71,19 @@ type Props = $RemoveChildren<typeof TouchableRipple> & {
    * Style that is passed to Description element.
    */
   descriptionStyle?: StyleProp<TextStyle>;
+  /**
+   * Truncate Title text such that the total number of lines does not
+   * exceed this number.
+   */
+  titleNumberOfLines?: number;
+  /**
+   * Truncate Description text such that the total number of lines does not
+   * exceed this number.
+   */
+  descriptionNumberOfLines?: number;
   /**
    * Ellipsize Mode for the Title
    */
-
   titleEllipsizeMode?: EllipsizeProp;
   /**
    * Ellipsize Mode for the Description
@@ -110,11 +119,20 @@ type Props = $RemoveChildren<typeof TouchableRipple> & {
 class ListItem extends React.Component<Props> {
   static displayName = 'List.Item';
 
+  static defaultProps: Partial<Props> = {
+    titleNumberOfLines: 1,
+    descriptionNumberOfLines: 2,
+  };
+
   renderDescription(
     descriptionColor: string,
     description?: Description | null
   ) {
-    const { descriptionEllipsizeMode, descriptionStyle } = this.props;
+    const {
+      descriptionEllipsizeMode,
+      descriptionStyle,
+      descriptionNumberOfLines,
+    } = this.props;
 
     return typeof description === 'function' ? (
       description({
@@ -124,7 +142,7 @@ class ListItem extends React.Component<Props> {
       })
     ) : (
       <Text
-        numberOfLines={2}
+        numberOfLines={descriptionNumberOfLines}
         ellipsizeMode={descriptionEllipsizeMode}
         style={[
           styles.description,
@@ -147,6 +165,7 @@ class ListItem extends React.Component<Props> {
       theme,
       style,
       titleStyle,
+      titleNumberOfLines,
       titleEllipsizeMode,
       ...rest
     } = this.props;
@@ -180,7 +199,7 @@ class ListItem extends React.Component<Props> {
           <View style={[styles.item, styles.content]} pointerEvents="none">
             <Text
               ellipsizeMode={titleEllipsizeMode}
-              numberOfLines={1}
+              numberOfLines={titleNumberOfLines}
               style={[styles.title, { color: titleColor }, titleStyle]}
             >
               {title}
diff --git a/src/components/Snackbar.tsx b/src/components/Snackbar.tsx
index 1c29f8d65..3f6ad950b 100644
--- a/src/components/Snackbar.tsx
+++ b/src/components/Snackbar.tsx
@@ -257,7 +257,7 @@ class Snackbar extends React.Component<Props, State> {
               compact
               mode="text"
             >
-              {action.label.toUpperCase()}
+              {action.label}
             </Button>
           ) : null}
         </Surface>


Test patch:
diff --git a/src/components/__tests__/__snapshots__/Banner.test.js.snap b/src/components/__tests__/__snapshots__/Banner.test.js.snap
index 294f76703..4a7a8ebbf 100644
--- a/src/components/__tests__/__snapshots__/Banner.test.js.snap
+++ b/src/components/__tests__/__snapshots__/Banner.test.js.snap
@@ -99,6 +99,7 @@ exports[`renders hidden banner, without action buttons and without image 1`] = `
 
 exports[`renders visible banner, with action buttons and with image 1`] = `
 <View
+  image={[Function]}
   style={
     Object {
       "backgroundColor": "#ffffff",
@@ -148,27 +149,6 @@ exports[`renders visible banner, with action buttons and with image 1`] = `
           }
         }
       >
-        <View
-          style={
-            Object {
-              "margin": 8,
-            }
-          }
-        >
-          <Image
-            source={
-              Object {
-                "uri": "https://callstack.com/images/team/Satya.png",
-              }
-            }
-            style={
-              Object {
-                "height": 40,
-                "width": 40,
-              }
-            }
-          />
-        </View>
         <Text
           style={
             Array [
@@ -267,6 +247,9 @@ exports[`renders visible banner, with action buttons and with image 1`] = `
                       Object {
                         "marginHorizontal": 8,
                       },
+                      Object {
+                        "textTransform": "uppercase",
+                      },
                       Object {
                         "color": "#6200ee",
                         "fontFamily": "System",
@@ -276,11 +259,12 @@ exports[`renders visible banner, with action buttons and with image 1`] = `
                         "fontFamily": "System",
                         "fontWeight": "500",
                       },
+                      undefined,
                     ],
                   ]
                 }
               >
-                FIRST
+                first
               </Text>
             </View>
           </View>
@@ -440,6 +424,9 @@ exports[`renders visible banner, with action buttons and without image 1`] = `
                       Object {
                         "marginHorizontal": 8,
                       },
+                      Object {
+                        "textTransform": "uppercase",
+                      },
                       Object {
                         "color": "#6200ee",
                         "fontFamily": "System",
@@ -449,11 +436,12 @@ exports[`renders visible banner, with action buttons and without image 1`] = `
                         "fontFamily": "System",
                         "fontWeight": "500",
                       },
+                      undefined,
                     ],
                   ]
                 }
               >
-                FIRST
+                first
               </Text>
             </View>
           </View>
@@ -527,6 +515,9 @@ exports[`renders visible banner, with action buttons and without image 1`] = `
                       Object {
                         "marginHorizontal": 8,
                       },
+                      Object {
+                        "textTransform": "uppercase",
+                      },
                       Object {
                         "color": "#6200ee",
                         "fontFamily": "System",
@@ -536,11 +527,12 @@ exports[`renders visible banner, with action buttons and without image 1`] = `
                         "fontFamily": "System",
                         "fontWeight": "500",
                       },
+                      undefined,
                     ],
                   ]
                 }
               >
-                SECOND
+                second
               </Text>
             </View>
           </View>
@@ -553,6 +545,7 @@ exports[`renders visible banner, with action buttons and without image 1`] = `
 
 exports[`renders visible banner, without action buttons and with image 1`] = `
 <View
+  image={[Function]}
   style={
     Object {
       "backgroundColor": "#ffffff",
@@ -602,27 +595,6 @@ exports[`renders visible banner, without action buttons and with image 1`] = `
           }
         }
       >
-        <View
-          style={
-            Object {
-              "margin": 8,
-            }
-          }
-        >
-          <Image
-            source={
-              Object {
-                "uri": "https://callstack.com/images/team/Satya.png",
-              }
-            }
-            style={
-              Object {
-                "height": 40,
-                "width": 40,
-              }
-            }
-          />
-        </View>
         <Text
           style={
             Array [
diff --git a/src/components/__tests__/__snapshots__/Button.test.js.snap b/src/components/__tests__/__snapshots__/Button.test.js.snap
index 13eff66aa..2296f0751 100644
--- a/src/components/__tests__/__snapshots__/Button.test.js.snap
+++ b/src/components/__tests__/__snapshots__/Button.test.js.snap
@@ -67,6 +67,9 @@ exports[`renders button with color 1`] = `
                 "textAlign": "center",
               },
               undefined,
+              Object {
+                "textTransform": "uppercase",
+              },
               Object {
                 "color": "#e91e63",
                 "fontFamily": "System",
@@ -76,11 +79,12 @@ exports[`renders button with color 1`] = `
                 "fontFamily": "System",
                 "fontWeight": "500",
               },
+              undefined,
             ],
           ]
         }
       >
-        CUSTOM BUTTON
+        Custom Button
       </Text>
     </View>
   </View>
@@ -198,6 +202,9 @@ exports[`renders button with icon 1`] = `
                 "textAlign": "center",
               },
               undefined,
+              Object {
+                "textTransform": "uppercase",
+              },
               Object {
                 "color": "#6200ee",
                 "fontFamily": "System",
@@ -207,11 +214,12 @@ exports[`renders button with icon 1`] = `
                 "fontFamily": "System",
                 "fontWeight": "500",
               },
+              undefined,
             ],
           ]
         }
       >
-        ICON BUTTON
+        Icon Button
       </Text>
     </View>
   </View>
@@ -292,6 +300,9 @@ exports[`renders contained contained with mode 1`] = `
                 "textAlign": "center",
               },
               undefined,
+              Object {
+                "textTransform": "uppercase",
+              },
               Object {
                 "color": "#ffffff",
                 "fontFamily": "System",
@@ -301,11 +312,12 @@ exports[`renders contained contained with mode 1`] = `
                 "fontFamily": "System",
                 "fontWeight": "500",
               },
+              undefined,
             ],
           ]
         }
       >
-        CONTAINED BUTTON
+        Contained Button
       </Text>
     </View>
   </View>
@@ -383,6 +395,9 @@ exports[`renders disabled button 1`] = `
                 "textAlign": "center",
               },
               undefined,
+              Object {
+                "textTransform": "uppercase",
+              },
               Object {
                 "color": "rgba(0, 0, 0, 0.32)",
                 "fontFamily": "System",
@@ -392,11 +407,12 @@ exports[`renders disabled button 1`] = `
                 "fontFamily": "System",
                 "fontWeight": "500",
               },
+              undefined,
             ],
           ]
         }
       >
-        DISABLED BUTTON
+        Disabled Button
       </Text>
     </View>
   </View>
@@ -653,6 +669,9 @@ exports[`renders loading button 1`] = `
                 "textAlign": "center",
               },
               undefined,
+              Object {
+                "textTransform": "uppercase",
+              },
               Object {
                 "color": "#6200ee",
                 "fontFamily": "System",
@@ -662,11 +681,12 @@ exports[`renders loading button 1`] = `
                 "fontFamily": "System",
                 "fontWeight": "500",
               },
+              undefined,
             ],
           ]
         }
       >
-        LOADING BUTTON
+        Loading Button
       </Text>
     </View>
   </View>
@@ -740,6 +760,9 @@ exports[`renders outlined button with mode 1`] = `
                 "textAlign": "center",
               },
               undefined,
+              Object {
+                "textTransform": "uppercase",
+              },
               Object {
                 "color": "#6200ee",
                 "fontFamily": "System",
@@ -749,11 +772,12 @@ exports[`renders outlined button with mode 1`] = `
                 "fontFamily": "System",
                 "fontWeight": "500",
               },
+              undefined,
             ],
           ]
         }
       >
-        OUTLINED BUTTON
+        Outlined Button
       </Text>
     </View>
   </View>
@@ -827,6 +851,9 @@ exports[`renders text button by default 1`] = `
                 "textAlign": "center",
               },
               undefined,
+              Object {
+                "textTransform": "uppercase",
+              },
               Object {
                 "color": "#6200ee",
                 "fontFamily": "System",
@@ -836,11 +863,12 @@ exports[`renders text button by default 1`] = `
                 "fontFamily": "System",
                 "fontWeight": "500",
               },
+              undefined,
             ],
           ]
         }
       >
-        TEXT BUTTON
+        Text Button
       </Text>
     </View>
   </View>
@@ -914,6 +942,9 @@ exports[`renders text button with mode 1`] = `
                 "textAlign": "center",
               },
               undefined,
+              Object {
+                "textTransform": "uppercase",
+              },
               Object {
                 "color": "#6200ee",
                 "fontFamily": "System",
@@ -923,11 +954,12 @@ exports[`renders text button with mode 1`] = `
                 "fontFamily": "System",
                 "fontWeight": "500",
               },
+              undefined,
             ],
           ]
         }
       >
-        TEXT BUTTON
+        Text Button
       </Text>
     </View>
   </View>
diff --git a/src/components/__tests__/__snapshots__/Chip.test.js.snap b/src/components/__tests__/__snapshots__/Chip.test.js.snap
index 0d1b156a4..594883973 100644
--- a/src/components/__tests__/__snapshots__/Chip.test.js.snap
+++ b/src/components/__tests__/__snapshots__/Chip.test.js.snap
@@ -169,7 +169,7 @@ exports[`renders chip with close button 1`] = `
             ]
           }
         >
-          
+          
         </Text>
       </View>
     </View>
diff --git a/src/components/__tests__/__snapshots__/Menu.test.js.snap b/src/components/__tests__/__snapshots__/Menu.test.js.snap
index b38af75e8..df2ae0511 100644
--- a/src/components/__tests__/__snapshots__/Menu.test.js.snap
+++ b/src/components/__tests__/__snapshots__/Menu.test.js.snap
@@ -70,6 +70,9 @@ exports[`renders menu with content styles 1`] = `
                   "textAlign": "center",
                 },
                 undefined,
+                Object {
+                  "textTransform": "uppercase",
+                },
                 Object {
                   "color": "#6200ee",
                   "fontFamily": "System",
@@ -79,11 +82,12 @@ exports[`renders menu with content styles 1`] = `
                   "fontFamily": "System",
                   "fontWeight": "500",
                 },
+                undefined,
               ],
             ]
           }
         >
-          OPEN MENU
+          Open menu
         </Text>
       </View>
     </View>
@@ -161,6 +165,9 @@ exports[`renders not visible menu 1`] = `
                   "textAlign": "center",
                 },
                 undefined,
+                Object {
+                  "textTransform": "uppercase",
+                },
                 Object {
                   "color": "#6200ee",
                   "fontFamily": "System",
@@ -170,11 +177,12 @@ exports[`renders not visible menu 1`] = `
                   "fontFamily": "System",
                   "fontWeight": "500",
                 },
+                undefined,
               ],
             ]
           }
         >
-          OPEN MENU
+          Open menu
         </Text>
       </View>
     </View>
@@ -252,6 +260,9 @@ exports[`renders visible menu 1`] = `
                   "textAlign": "center",
                 },
                 undefined,
+                Object {
+                  "textTransform": "uppercase",
+                },
                 Object {
                   "color": "#6200ee",
                   "fontFamily": "System",
@@ -261,11 +272,12 @@ exports[`renders visible menu 1`] = `
                   "fontFamily": "System",
                   "fontWeight": "500",
                 },
+                undefined,
               ],
             ]
           }
         >
-          OPEN MENU
+          Open menu
         </Text>
       </View>
     </View>
diff --git a/src/components/__tests__/__snapshots__/Snackbar.test.js.snap b/src/components/__tests__/__snapshots__/Snackbar.test.js.snap
index 451ef410d..11951c3a0 100644
--- a/src/components/__tests__/__snapshots__/Snackbar.test.js.snap
+++ b/src/components/__tests__/__snapshots__/Snackbar.test.js.snap
@@ -212,6 +212,9 @@ exports[`renders snackbar with action button 1`] = `
                   Object {
                     "marginHorizontal": 8,
                   },
+                  Object {
+                    "textTransform": "uppercase",
+                  },
                   Object {
                     "color": "#03dac4",
                     "fontFamily": "System",
@@ -221,11 +224,12 @@ exports[`renders snackbar with action button 1`] = `
                     "fontFamily": "System",
                     "fontWeight": "500",
                   },
+                  undefined,
                 ],
               ]
             }
           >
-            UNDO
+            Undo
           </Text>
         </View>
       </View>