Repository: mui/material-ui (TypeScript)
Date: 2018-11-28 11:03:22+00:00
Task type: Bug Fix

Issue:
Filled TextField doesn't respect disableUnderline input prop
- [x] This is not a v0.x issue. <!-- (v0.x is no longer maintained) -->
- [x] I have searched the [issues](https://github.com/mui-org/material-ui/issues) of this repository and believe that this is not a duplicate.
**I saw #13085 issue with same problem and it's resolved, but problem is still here**

## Expected Behavior 🤔
`disableUnderline` input prop should remove underline for TextField with `variant="filled"`

## Current Behavior 😯
`disableUnderline` input prop doesn't remove underline for TextField with `variant="filled"`

## Steps to Reproduce 🕹

As I see in sources, [Input](https://github.com/mui-org/material-ui/blob/master/packages/material-ui/src/Input/Input.js#L96) component handles `disableUnderline` prop correctly, but FilledInput - not, it has only [mention](https://github.com/mui-org/material-ui/blob/master/packages/material-ui/src/FilledInput/FilledInput.js#L39) about it, but no implementation. Also in [docs](https://material-ui.com/api/filled-input/#props) there is no disableUnderline for FilledInput

Link: [https://codesandbox.io/s/vq7ywmzmv0](https://codesandbox.io/s/vq7ywmzmv0)

1. Create TextField with `variant="filled"` and `InputProps={{disableUnderline: true}}`

````jsx
<TextField
      label="Name"
      margin="normal"
      variant="filled"
      InputProps={{
        disableUnderline: true
      }}
/>
````

## Context 🔦
In my current project it's design requirement to have filled text fields without underline
![image](https://user-images.githubusercontent.com/1328473/49141697-3d633580-f308-11e8-8007-c794e898249d.png)


## Your Environment 🌎

| Tech         | Version |
|--------------|---------|
| material-ui/core  | v3.6.0  |
| React        |      v16.6.3   |
| Browser      |    Chrome for Win10     |
| TypeScript   |    no     |



Issue discussion:
Doesn't look like `FilledInput` is handling `disableUnderline` at all. Looks like we only need to apply conditional logic to the `underlined` from https://github.com/mui-org/material-ui/blob/1c8c88781c5d48915099cf4db17f255c17b052e5/packages/material-ui/src/Input/Input.js#L103 to here https://github.com/mui-org/material-ui/blob/1c8c88781c5d48915099cf4db17f255c17b052e5/packages/material-ui/src/FilledInput/FilledInput.js#L133

And stop capturing the prop in `InputBase` which would've caught the error: https://github.com/mui-org/material-ui/blob/1c8c88781c5d48915099cf4db17f255c17b052e5/packages/material-ui/src/InputBase/InputBase.js#L281 

Solution patch:
diff --git a/packages/material-ui/src/FilledInput/FilledInput.d.ts b/packages/material-ui/src/FilledInput/FilledInput.d.ts
--- a/packages/material-ui/src/FilledInput/FilledInput.d.ts
+++ b/packages/material-ui/src/FilledInput/FilledInput.d.ts
@@ -2,7 +2,9 @@ import * as React from 'react';
 import { StandardProps, PropTypes } from '..';
 import { InputBaseProps } from '../InputBase';
 
-export interface FilledInputProps extends StandardProps<InputBaseProps, FilledInputClassKey> {}
+export interface FilledInputProps extends StandardProps<InputBaseProps, FilledInputClassKey> {
+  disableUnderline?: boolean;
+}
 
 export type FilledInputClassKey =
   | 'root'
diff --git a/packages/material-ui/src/FilledInput/FilledInput.js b/packages/material-ui/src/FilledInput/FilledInput.js
--- a/packages/material-ui/src/FilledInput/FilledInput.js
+++ b/packages/material-ui/src/FilledInput/FilledInput.js
@@ -124,13 +124,15 @@ export const styles = theme => {
 };
 
 function FilledInput(props) {
-  const { classes, ...other } = props;
+  const { disableUnderline, classes, ...other } = props;
 
   return (
     <InputBase
       classes={{
         ...classes,
-        root: classNames(classes.root, classes.underline, {}),
+        root: classNames(classes.root, {
+          [classes.underline]: !disableUnderline,
+        }),
         underline: null,
       }}
       {...other}
@@ -167,6 +169,10 @@ FilledInput.propTypes = {
    * If `true`, the input will be disabled.
    */
   disabled: PropTypes.bool,
+  /**
+   * If `true`, the input will not have an underline.
+   */
+  disableUnderline: PropTypes.bool,
   /**
    * End `InputAdornment` for this component.
    */
diff --git a/packages/material-ui/src/Input/Input.d.ts b/packages/material-ui/src/Input/Input.d.ts
--- a/packages/material-ui/src/Input/Input.d.ts
+++ b/packages/material-ui/src/Input/Input.d.ts
@@ -2,7 +2,9 @@ import * as React from 'react';
 import { StandardProps, PropTypes } from '..';
 import { InputBaseProps } from '../InputBase';
 
-export interface InputProps extends StandardProps<InputBaseProps, InputClassKey> {}
+export interface InputProps extends StandardProps<InputBaseProps, InputClassKey> {
+  disableUnderline?: boolean;
+}
 
 export type InputClassKey =
   | 'root'
diff --git a/packages/material-ui/src/InputBase/InputBase.js b/packages/material-ui/src/InputBase/InputBase.js
--- a/packages/material-ui/src/InputBase/InputBase.js
+++ b/packages/material-ui/src/InputBase/InputBase.js
@@ -278,7 +278,6 @@ class InputBase extends React.Component {
       className: classNameProp,
       defaultValue,
       disabled,
-      disableUnderline,
       endAdornment,
       error,
       fullWidth,
diff --git a/packages/material-ui/src/OutlinedInput/OutlinedInput.js b/packages/material-ui/src/OutlinedInput/OutlinedInput.js
--- a/packages/material-ui/src/OutlinedInput/OutlinedInput.js
+++ b/packages/material-ui/src/OutlinedInput/OutlinedInput.js
@@ -99,7 +99,7 @@ function OutlinedInput(props) {
       )}
       classes={{
         ...classes,
-        root: classNames(classes.root, classes.underline, {}),
+        root: classNames(classes.root, classes.underline),
         notchedOutline: null,
       }}
       {...other}
diff --git a/pages/api/filled-input.md b/pages/api/filled-input.md
--- a/pages/api/filled-input.md
+++ b/pages/api/filled-input.md
@@ -24,6 +24,7 @@ import FilledInput from '@material-ui/core/FilledInput';
 | <span class="prop-name">className</span> | <span class="prop-type">string</span> |   | The CSS class name of the wrapper element. |
 | <span class="prop-name">defaultValue</span> | <span class="prop-type">union:&nbsp;string&nbsp;&#124;<br>&nbsp;number<br></span> |   | The default input value, useful when not controlling the component. |
 | <span class="prop-name">disabled</span> | <span class="prop-type">bool</span> |   | If `true`, the input will be disabled. |
+| <span class="prop-name">disableUnderline</span> | <span class="prop-type">bool</span> |   | If `true`, the input will not have an underline. |
 | <span class="prop-name">endAdornment</span> | <span class="prop-type">node</span> |   | End `InputAdornment` for this component. |
 | <span class="prop-name">error</span> | <span class="prop-type">bool</span> |   | If `true`, the input will indicate an error. This is normally obtained via context from FormControl. |
 | <span class="prop-name">fullWidth</span> | <span class="prop-type">bool</span> |   | If `true`, the input will take up the full width of its container. |


Test patch:
diff --git a/packages/material-ui/src/FilledInput/FilledInput.test.js b/packages/material-ui/src/FilledInput/FilledInput.test.js
--- a/packages/material-ui/src/FilledInput/FilledInput.test.js
+++ b/packages/material-ui/src/FilledInput/FilledInput.test.js
@@ -1,18 +1,32 @@
 import React from 'react';
 import { assert } from 'chai';
-import { createShallow } from '@material-ui/core/test-utils';
+import { createMount, createShallow, getClasses } from '@material-ui/core/test-utils';
 import InputBase from '../InputBase';
 import FilledInput from './FilledInput';
 
 describe('<FilledInput />', () => {
+  let classes;
   let shallow;
+  let mount;
 
   before(() => {
     shallow = createShallow({ untilSelector: 'FilledInput' });
+    mount = createMount();
+    classes = getClasses(<FilledInput />);
+  });
+
+  after(() => {
+    mount.cleanUp();
   });
 
   it('should render a <div />', () => {
     const wrapper = shallow(<FilledInput />);
     assert.strictEqual(wrapper.type(), InputBase);
+    assert.include(wrapper.props().classes.root, classes.underline);
+  });
+
+  it('should disable the underline', () => {
+    const wrapper = shallow(<FilledInput disableUnderline />);
+    assert.notInclude(wrapper.props().classes.root, classes.underline);
   });
 });
diff --git a/packages/material-ui/src/InputBase/InputBase.test.js b/packages/material-ui/src/InputBase/InputBase.test.js
--- a/packages/material-ui/src/InputBase/InputBase.test.js
+++ b/packages/material-ui/src/InputBase/InputBase.test.js
@@ -97,15 +97,6 @@ describe('<InputBase />', () => {
     });
   });
 
-  it('should disable the underline', () => {
-    const wrapper = mount(<InputBase disableUnderline />);
-    const input = wrapper.find('input');
-    assert.strictEqual(findOutermostIntrinsic(wrapper).hasClass(classes.inkbar), false);
-    assert.strictEqual(input.name(), 'input');
-    assert.strictEqual(input.hasClass(classes.input), true);
-    assert.strictEqual(input.hasClass(classes.underline), false);
-  });
-
   it('should fire event callbacks', () => {
     const events = ['onChange', 'onFocus', 'onBlur', 'onKeyUp', 'onKeyDown'];
     const handlers = events.reduce((result, n) => {