Repository: callstack/react-native-paper
Pull request #1014 (2019-04-23 14:21:32)

fix: use theme font in TextInputFlat
### Motivation

`TextInput` did not use the new types of font definition.

### Test plan

n/a

callstack-bot: Hey @jaulz, thank you for your pull request 🤗. The documentation from this branch can be viewed [here](https://9841-71323749-gh.circle-artifacts.com/0/docs/index.html). Please remember to update Typescript types if you changed API.

Patch:
diff --git a/example/src/Examples/ListSectionExample.js b/example/src/Examples/ListSectionExample.js
index a44097ac6..2fa17b5b3 100644
--- a/example/src/Examples/ListSectionExample.js
+++ b/example/src/Examples/ListSectionExample.js
@@ -29,6 +29,11 @@ class ListSectionExample extends React.Component<Props> {
             left={props => <List.Icon {...props} icon="redeem" />}
             title="List item 2"
           />
+          <List.Item
+            title="List item 3"
+            left={props => <List.Icon {...props} icon="folder" />}
+            right={props => <List.Icon {...props} icon="drag-handle" />}
+          />
         </List.Section>
         <Divider />
         <List.Section>
diff --git a/example/src/Examples/TextInputExample.js b/example/src/Examples/TextInputExample.js
index 084addf40..3c7e6533b 100644
--- a/example/src/Examples/TextInputExample.js
+++ b/example/src/Examples/TextInputExample.js
@@ -87,6 +87,24 @@ class TextInputExample extends React.Component<Props, State> {
               Error: Only letters are allowed
             </HelperText>
           </View>
+          <View style={styles.inputContainerStyle}>
+            <TextInput
+              label="Input with no padding"
+              style={{ backgroundColor: 'transparent' }}
+              padding="none"
+              placeholder="Enter username, only letters"
+              value={this.state.name}
+              error={!this._isUsernameValid()}
+              onChangeText={name => this.setState({ name })}
+            />
+            <HelperText
+              type="error"
+              padding="none"
+              visible={!this._isUsernameValid()}
+            >
+              Error: Only letters are allowed
+            </HelperText>
+          </View>
         </ScrollView>
       </KeyboardAvoidingView>
     );
diff --git a/src/components/HelperText.js b/src/components/HelperText.js
index f63cc1c50..5df8c1412 100644
--- a/src/components/HelperText.js
+++ b/src/components/HelperText.js
@@ -19,6 +19,10 @@ type Props = React.ElementConfig<typeof Text> & {
    * Whether to display the helper text.
    */
   visible?: boolean,
+  /**
+   * Whether to apply padding to the helper text.
+   */
+  padding?: 'none' | 'normal',
   /**
    * Text content of the HelperText.
    */
@@ -76,6 +80,7 @@ type State = {
 class HelperText extends React.PureComponent<Props, State> {
   static defaultProps = {
     type: 'info',
+    padding: 'normal',
     visible: true,
   };
 
@@ -121,7 +126,15 @@ class HelperText extends React.PureComponent<Props, State> {
   };
 
   render() {
-    const { style, type, visible, theme, onLayout, ...rest } = this.props;
+    const {
+      style,
+      type,
+      visible,
+      theme,
+      onLayout,
+      padding,
+      ...rest
+    } = this.props;
     const { colors, dark } = theme;
 
     const textColor =
@@ -137,6 +150,7 @@ class HelperText extends React.PureComponent<Props, State> {
         onLayout={this._handleTextLayout}
         style={[
           styles.text,
+          padding !== 'none' ? styles.padding : {},
           {
             color: textColor,
             opacity: this.state.shown,
@@ -166,6 +180,8 @@ const styles = StyleSheet.create({
   text: {
     fontSize: 12,
     paddingVertical: 4,
+  },
+  padding: {
     paddingHorizontal: 12,
   },
 });
diff --git a/src/components/List/ListIcon.js b/src/components/List/ListIcon.js
index 83df2333a..b67dced72 100644
--- a/src/components/List/ListIcon.js
+++ b/src/components/List/ListIcon.js
@@ -48,7 +48,7 @@ export default class ListIcon extends React.Component<Props> {
 
 const styles = StyleSheet.create({
   item: {
-    marginRight: 16,
+    margin: 8,
     height: 40,
     width: 40,
     alignItems: 'center',
diff --git a/src/components/List/ListItem.js b/src/components/List/ListItem.js
index af825bf32..876a3fa41 100644
--- a/src/components/List/ListItem.js
+++ b/src/components/List/ListItem.js
@@ -121,7 +121,9 @@ class ListItem extends React.Component<Props> {
           {left
             ? left({
                 color: descriptionColor,
-                style: description ? styles.iconMargin : null,
+                style: description
+                  ? styles.iconMarginLeft
+                  : { ...styles.iconMarginLeft, ...styles.marginVerticalNone },
               })
             : null}
           <View style={[styles.item, styles.content]} pointerEvents="none">
@@ -151,7 +153,9 @@ class ListItem extends React.Component<Props> {
           {right
             ? right({
                 color: descriptionColor,
-                style: description ? styles.iconMargin : null,
+                style: description
+                  ? styles.iconMarginRight
+                  : { ...styles.iconMarginRight, ...styles.marginVerticalNone },
               })
             : null}
         </View>
@@ -173,7 +177,9 @@ const styles = StyleSheet.create({
   description: {
     fontSize: 14,
   },
-  iconMargin: { marginVertical: 8 },
+  marginVerticalNone: { marginVertical: 0 },
+  iconMarginLeft: { marginLeft: 0, marginRight: 16 },
+  iconMarginRight: { marginRight: 0 },
   item: {
     marginVertical: 6,
     paddingLeft: 8,
diff --git a/src/components/TextInput/TextInput.js b/src/components/TextInput/TextInput.js
index 0f9fc85a9..9c8081132 100644
--- a/src/components/TextInput/TextInput.js
+++ b/src/components/TextInput/TextInput.js
@@ -52,6 +52,10 @@ export type TextInputProps = {|
    * Underline color of the input.
    */
   underlineColor?: string,
+  /**
+   * Whether to apply padding to label and input.
+   */
+  padding?: 'none' | 'normal',
   /**
    * Whether the input can have multiple lines.
    */
@@ -148,6 +152,7 @@ export type TextInputProps = {|
 class TextInput extends React.Component<TextInputProps, State> {
   static defaultProps = {
     mode: 'flat',
+    padding: 'normal',
     disabled: false,
     error: false,
     multiline: false,
@@ -368,7 +373,7 @@ class TextInput extends React.Component<TextInputProps, State> {
   }
 
   render() {
-    const { mode, ...rest } = this.props;
+    const { mode, padding, ...rest } = this.props;
 
     return mode === 'outlined' ? (
       <TextInputOutlined
@@ -389,6 +394,7 @@ class TextInput extends React.Component<TextInputProps, State> {
         innerRef={ref => {
           this._root = ref;
         }}
+        padding={padding}
         onFocus={this._handleFocus}
         onBlur={this._handleBlur}
         onChangeText={this._handleChangeText}
diff --git a/src/components/TextInput/TextInputFlat.js b/src/components/TextInput/TextInputFlat.js
index ab6414f5e..d72285e98 100644
--- a/src/components/TextInput/TextInputFlat.js
+++ b/src/components/TextInput/TextInputFlat.js
@@ -37,6 +37,7 @@ class TextInputFlat extends React.Component<ChildTextInputProps, {}> {
       error,
       selectionColor,
       underlineColor,
+      padding,
       style,
       theme,
       render,
@@ -51,8 +52,9 @@ class TextInputFlat extends React.Component<ChildTextInputProps, {}> {
     } = this.props;
 
     const { colors, fonts } = theme;
-    const fontFamily = fonts.regular;
+    const font = fonts.regular;
     const hasActiveOutline = parentState.focused || error;
+    const paddingOffset = padding !== 'none' ? styles.paddingOffset : null;
 
     let inputTextColor, activeColor, underlineColorCustom, placeholderColor;
 
@@ -91,7 +93,7 @@ class TextInputFlat extends React.Component<ChildTextInputProps, {}> {
       labelHalfWidth;
 
     const labelStyle = {
-      fontFamily,
+      ...font,
       fontSize: MAXIMIZED_LABEL_FONT_SIZE,
       transform: [
         {
@@ -133,7 +135,7 @@ class TextInputFlat extends React.Component<ChildTextInputProps, {}> {
                   RANDOM_VALUE_TO_CENTER_LABEL
                 : baseLabelTranslateX -
                   labelHalfWidth / LABEL_PADDING_HORIZONTAL +
-                  RANDOM_VALUE_TO_CENTER_LABEL,
+                  (paddingOffset ? RANDOM_VALUE_TO_CENTER_LABEL : 0),
               0,
             ],
           }),
@@ -182,6 +184,7 @@ class TextInputFlat extends React.Component<ChildTextInputProps, {}> {
                 styles.placeholder,
                 styles.placeholderFlat,
                 labelStyle,
+                paddingOffset,
                 {
                   color: activeColor,
                   opacity: parentState.labeled.interpolate({
@@ -199,6 +202,7 @@ class TextInputFlat extends React.Component<ChildTextInputProps, {}> {
                 styles.placeholder,
                 styles.placeholderFlat,
                 labelStyle,
+                paddingOffset,
                 {
                   color: placeholderColor,
                   opacity: hasActiveOutline ? parentState.labeled : 1,
@@ -234,9 +238,10 @@ class TextInputFlat extends React.Component<ChildTextInputProps, {}> {
               this.props.label
                 ? styles.inputFlatWithLabel
                 : styles.inputFlatWithoutLabel,
+              paddingOffset,
               {
                 color: inputTextColor,
-                fontFamily,
+                ...font,
                 textAlignVertical: multiline ? 'top' : 'center',
               },
             ],
@@ -254,7 +259,6 @@ const styles = StyleSheet.create({
     position: 'absolute',
     left: 0,
     fontSize: 16,
-    paddingHorizontal: LABEL_PADDING_HORIZONTAL,
   },
   placeholderFlat: {
     top: 19,
@@ -268,7 +272,6 @@ const styles = StyleSheet.create({
   },
   input: {
     flexGrow: 1,
-    paddingHorizontal: 12,
     fontSize: 16,
     margin: 0,
     minHeight: 58,
@@ -282,4 +285,7 @@ const styles = StyleSheet.create({
   inputFlatWithoutLabel: {
     paddingVertical: 15,
   },
+  paddingOffset: {
+    paddingHorizontal: LABEL_PADDING_HORIZONTAL,
+  },
 });
diff --git a/src/components/TextInput/TextInputOutlined.js b/src/components/TextInput/TextInputOutlined.js
index 43ed8295c..38a16a478 100644
--- a/src/components/TextInput/TextInputOutlined.js
+++ b/src/components/TextInput/TextInputOutlined.js
@@ -51,7 +51,7 @@ class TextInputOutlined extends React.Component<ChildTextInputProps, {}> {
     } = this.props;
 
     const { colors, fonts } = theme;
-    const fontFamily = fonts.regular;
+    const font = fonts.regular;
     const hasActiveOutline = parentState.focused || error;
     const { backgroundColor = colors.background } =
       StyleSheet.flatten(style) || {};
@@ -81,7 +81,7 @@ class TextInputOutlined extends React.Component<ChildTextInputProps, {}> {
       labelHalfWidth;
 
     const labelStyle = {
-      fontFamily,
+      ...font,
       fontSize: MAXIMIZED_LABEL_FONT_SIZE,
       transform: [
         {
@@ -161,7 +161,7 @@ class TextInputOutlined extends React.Component<ChildTextInputProps, {}> {
               styles.outlinedLabelBackground,
               {
                 backgroundColor,
-                fontFamily,
+                ...font,
                 fontSize: MINIMIZED_LABEL_FONT_SIZE,
                 // Hide the background when scale will be 0
                 // There's a bug in RN which makes scale: 0 act weird
@@ -262,7 +262,7 @@ class TextInputOutlined extends React.Component<ChildTextInputProps, {}> {
               styles.inputOutlined,
               {
                 color: inputTextColor,
-                fontFamily,
+                ...font,
                 textAlignVertical: multiline ? 'top' : 'center',
               },
             ],
diff --git a/typings/components/HelperText.d.ts b/typings/components/HelperText.d.ts
index 08f8ec932..9237bad03 100644
--- a/typings/components/HelperText.d.ts
+++ b/typings/components/HelperText.d.ts
@@ -4,6 +4,7 @@ import { ThemeShape } from '../types';
 export interface HelperTextProps {
   type?: 'error' | 'info';
   visible?: boolean;
+  padding?: 'none'|'normal',
   children: React.ReactNode;
   style?: any;
   theme?: ThemeShape;
diff --git a/typings/components/TextInput.d.ts b/typings/components/TextInput.d.ts
index 5cca1e0e5..e9773b80d 100644
--- a/typings/components/TextInput.d.ts
+++ b/typings/components/TextInput.d.ts
@@ -10,6 +10,7 @@ export interface TextInputProps extends NativeTextInputProps {
   error?: boolean;
   onChangeText?: (text: string) => void;
   underlineColor?: string;
+  padding?: 'none'|'normal',
   multiline?: boolean;
   numberOfLines?: number;
   onFocus?: (e: NativeSyntheticEvent<TextInputFocusEventData>) => void;


Test patch:
diff --git a/src/components/__tests__/__snapshots__/ListAccordion.test.js.snap b/src/components/__tests__/__snapshots__/ListAccordion.test.js.snap
index 3c0df9cc4..3fb2b43e5 100644
--- a/src/components/__tests__/__snapshots__/ListAccordion.test.js.snap
+++ b/src/components/__tests__/__snapshots__/ListAccordion.test.js.snap
@@ -233,7 +233,7 @@ exports[`renders list accordion with children 1`] = `
               "alignItems": "center",
               "height": 40,
               "justifyContent": "center",
-              "marginRight": 16,
+              "margin": 8,
               "width": 40,
             },
             undefined,
@@ -404,7 +404,7 @@ exports[`renders list accordion with left items 1`] = `
               "alignItems": "center",
               "height": 40,
               "justifyContent": "center",
-              "marginRight": 16,
+              "margin": 8,
               "width": 40,
             },
             undefined,
diff --git a/src/components/__tests__/__snapshots__/ListItem.test.js.snap b/src/components/__tests__/__snapshots__/ListItem.test.js.snap
index 538686a2f..296892037 100644
--- a/src/components/__tests__/__snapshots__/ListItem.test.js.snap
+++ b/src/components/__tests__/__snapshots__/ListItem.test.js.snap
@@ -209,11 +209,11 @@ exports[`renders list item with left and right items 1`] = `
             "alignItems": "center",
             "height": 40,
             "justifyContent": "center",
-            "marginRight": 16,
+            "margin": 8,
             "width": 40,
           },
           Object {
-            "marginVertical": 8,
+            "marginRight": 0,
           },
         ]
       }
@@ -294,10 +294,14 @@ exports[`renders list item with left item 1`] = `
             "alignItems": "center",
             "height": 40,
             "justifyContent": "center",
-            "marginRight": 16,
+            "margin": 8,
             "width": 40,
           },
-          null,
+          Object {
+            "marginLeft": 0,
+            "marginRight": 16,
+            "marginVertical": 0,
+          },
         ]
       }
     >
diff --git a/src/components/__tests__/__snapshots__/ListSection.test.js.snap b/src/components/__tests__/__snapshots__/ListSection.test.js.snap
index 2937b4b4b..9817ddbf0 100644
--- a/src/components/__tests__/__snapshots__/ListSection.test.js.snap
+++ b/src/components/__tests__/__snapshots__/ListSection.test.js.snap
@@ -114,10 +114,14 @@ exports[`renders list section with subheader 1`] = `
               "alignItems": "center",
               "height": 40,
               "justifyContent": "center",
-              "marginRight": 16,
+              "margin": 8,
               "width": 40,
             },
-            null,
+            Object {
+              "marginLeft": 0,
+              "marginRight": 16,
+              "marginVertical": 0,
+            },
           ]
         }
       >
@@ -235,10 +239,14 @@ exports[`renders list section with subheader 1`] = `
               "alignItems": "center",
               "height": 40,
               "justifyContent": "center",
-              "marginRight": 16,
+              "margin": 8,
               "width": 40,
             },
-            null,
+            Object {
+              "marginLeft": 0,
+              "marginRight": 16,
+              "marginVertical": 0,
+            },
           ]
         }
       >
@@ -409,10 +417,14 @@ exports[`renders list section without subheader 1`] = `
               "alignItems": "center",
               "height": 40,
               "justifyContent": "center",
-              "marginRight": 16,
+              "margin": 8,
               "width": 40,
             },
-            null,
+            Object {
+              "marginLeft": 0,
+              "marginRight": 16,
+              "marginVertical": 0,
+            },
           ]
         }
       >
@@ -530,10 +542,14 @@ exports[`renders list section without subheader 1`] = `
               "alignItems": "center",
               "height": 40,
               "justifyContent": "center",
-              "marginRight": 16,
+              "margin": 8,
               "width": 40,
             },
-            null,
+            Object {
+              "marginLeft": 0,
+              "marginRight": 16,
+              "marginVertical": 0,
+            },
           ]
         }
       >