Repository: mui/material-ui (TypeScript)
Date: 2022-01-09 13:36:47+00:00
Task type: Bug Fix

Issue:
[TextField] Notch appears when no label has been added
### Duplicates

- [X] I have searched the existing issues

### Latest version

- [X] I have tested the latest version

### Current behavior 😯

When using `TextField` without setting a `label` it seems to show a notch that spans the whole length of the Input. With a label, it looks fine.

![image](https://user-images.githubusercontent.com/4289486/146287380-f92f7661-d0da-49c6-8b54-9fc784f744c9.png)


### Expected behavior 🤔

It should not have the notch on it.

### Steps to reproduce 🕹

Add TextField using the following details:

```ts
<TextField
    placeholder='Username or Email'
    InputProps={{
        startAdornment: (
            <InputAdornment position='start'>
                <FontAwesomeIcon icon='user' />
            </InputAdornment>
        ),
    }}
    fullWidth
    margin='normal'
/>
```

### Context 🔦

Trying to render an input without a label for a login screen.

### Your environment 🌎

<details>
  <summary>`npx @mui/envinfo`</summary>

```
  System:
    OS: Linux 5.4 Ubuntu 20.04.2 LTS (Focal Fossa)
  Binaries:
    Node: 14.18.1 - ~/.nvm/versions/node/v14.18.1/bin/node
    Yarn: 1.22.5 - ~/.nvm/versions/node/v14.18.1/bin/yarn
    npm: 6.14.15 - ~/.nvm/versions/node/v14.18.1/bin/npm
  Browsers:
    Brave: 1.33.106
```
</details>



Issue discussion:
Please create an isolated reproduction using Codesandbox (https://mui.com/r/issue-template-latest).
@michaldudak 
Textfields with cutouts Version 5.2.4
(https://codesandbox.io/s/formpropstextfields-material-demo-forked-5ynnp?file=/demo.tsx)

Works fine with 5.2.3
@mbrookes why was this closed? It's still occurring in 5.2.6. Please see CodeSandbox by @mvpindev
Closed in error
I can see a regression between 5.2.3 and 5.2.4 with

```jsx
import * as React from "react";
import TextField from "@mui/material/TextField";

export default function FormPropsTextFields() {
  return <TextField label="" defaultValue="-" />;
}
```

<img width="208" alt="Screenshot 2022-01-01 at 01 44 19" src="https://user-images.githubusercontent.com/3165635/147841772-f2b6700e-a806-428d-8a73-aeaa3ada2765.png">

https://codesandbox.io/s/formpropstextfields-material-demo-forked-6tbsw

<img width="206" alt="Screenshot 2022-01-01 at 01 40 25" src="https://user-images.githubusercontent.com/3165635/147841737-cabe759d-2ebe-4b31-8148-a7ff774c0af7.png">

https://codesandbox.io/s/formpropstextfields-material-demo-forked-mup7n?file=/demo.tsx

The regression is coming from #29630 and seems easy to fix:

```diff
diff --git a/packages/mui-material/src/OutlinedInput/NotchedOutline.js b/packages/mui-material/src/OutlinedInput/NotchedOutline.js
index 9a92c04c2f..2d9a395a7e 100644
--- a/packages/mui-material/src/OutlinedInput/NotchedOutline.js
+++ b/packages/mui-material/src/OutlinedInput/NotchedOutline.js
@@ -21,7 +21,7 @@ const NotchedOutlineRoot = styled('fieldset')({

 const NotchedOutlineLegend = styled('legend', { skipSx: true })(({ ownerState, theme }) => ({
   float: 'unset', // Fix conflict with bootstrap
-  ...(ownerState.label === undefined && {
+  ...(!ownerState.label && {
     padding: 0,
     lineHeight: '11px', // sync with `height` in `legend` styles
     transition: theme.transitions.create('width', {
@@ -29,7 +29,7 @@ const NotchedOutlineLegend = styled('legend', { skipSx: true })(({ ownerState, t
       easing: theme.transitions.easing.easeOut,
     }),
   }),
-  ...(ownerState.label !== undefined && {
+  ...(ownerState.label && {
     display: 'block', // Fix conflict with normalize.css and sanitize.css
     width: 'auto', // Fix conflict with bootstrap
     padding: 0,
```

And if we want to support:

```jsx
import * as React from "react";
import TextField from "@mui/material/TextField";

export default function FormPropsTextFields() {
  return <TextField label={0} defaultValue="-" />;
}
```

<img width="220" alt="Screenshot 2022-01-01 at 01 55 50" src="https://user-images.githubusercontent.com/3165635/147841868-8ebd12c3-2a31-4e52-877b-ed5cb4ea2d0c.png">

correctly

```diff
diff --git a/packages/mui-material/src/OutlinedInput/NotchedOutline.js b/packages/mui-material/src/OutlinedInput/NotchedOutline.js
index 9a92c04c2f..7e0e9bc172 100644
--- a/packages/mui-material/src/OutlinedInput/NotchedOutline.js
+++ b/packages/mui-material/src/OutlinedInput/NotchedOutline.js
@@ -21,7 +21,7 @@ const NotchedOutlineRoot = styled('fieldset')({

 const NotchedOutlineLegend = styled('legend', { skipSx: true })(({ ownerState, theme }) => ({
   float: 'unset', // Fix conflict with bootstrap
-  ...(ownerState.label === undefined && {
+  ...(!ownerState.withLabel && {
     padding: 0,
     lineHeight: '11px', // sync with `height` in `legend` styles
     transition: theme.transitions.create('width', {
@@ -29,7 +29,7 @@ const NotchedOutlineLegend = styled('legend', { skipSx: true })(({ ownerState, t
       easing: theme.transitions.easing.easeOut,
     }),
   }),
-  ...(ownerState.label !== undefined && {
+  ...(ownerState.withLabel && {
     display: 'block', // Fix conflict with normalize.css and sanitize.css
     width: 'auto', // Fix conflict with bootstrap
     padding: 0,
@@ -63,16 +63,17 @@ const NotchedOutlineLegend = styled('legend', { skipSx: true })(({ ownerState, t
  */
 export default function NotchedOutline(props) {
   const { children, classes, className, label, notched, ...other } = props;
+  const withLabel = label != null && label !== '';
   const ownerState = {
     ...props,
     notched,
-    label,
+    withLabel,
   };
   return (
     <NotchedOutlineRoot aria-hidden className={className} ownerState={ownerState} {...other}>
       <NotchedOutlineLegend ownerState={ownerState}>
         {/* Use the nominal use case of the legend, avoid rendering artefacts. */}
-        {label ? (
+        {withLabel ? (
           <span>{label}</span>
         ) : (
           // notranslate needed while Google Translate will not fix zero-width space issue
diff --git a/packages/mui-material/src/OutlinedInput/OutlinedInput.js b/packages/mui-material/src/OutlinedInput/OutlinedInput.js
index ab0cba98ce..51ca5c5bc0 100644
--- a/packages/mui-material/src/OutlinedInput/OutlinedInput.js
+++ b/packages/mui-material/src/OutlinedInput/OutlinedInput.js
@@ -140,7 +140,7 @@ const OutlinedInput = React.forwardRef(function OutlinedInput(inProps, ref) {
         <NotchedOutlineRoot
           className={classes.notchedOutline}
           label={
-            label && fcs.required ? (
+            label != null && label !== '' && fcs.required ? (
               <React.Fragment>
                 {label}
                 &nbsp;{'*'}
diff --git a/packages/mui-material/src/TextField/TextField.js b/packages/mui-material/src/TextField/TextField.js
index ffdab8da31..f69ddc3401 100644
--- a/packages/mui-material/src/TextField/TextField.js
+++ b/packages/mui-material/src/TextField/TextField.js
@@ -188,7 +188,7 @@ const TextField = React.forwardRef(function TextField(inProps, ref) {
       ownerState={ownerState}
       {...other}
     >
-      {label && (
+      {label != null && label !== '' && (
         <InputLabel htmlFor={id} id={inputLabelId} {...InputLabelProps}>
           {label}
         </InputLabel>
```
I would like to work on this issue 
Sure, go ahead!

Solution patch:
diff --git a/packages/mui-material/src/OutlinedInput/NotchedOutline.js b/packages/mui-material/src/OutlinedInput/NotchedOutline.js
--- a/packages/mui-material/src/OutlinedInput/NotchedOutline.js
+++ b/packages/mui-material/src/OutlinedInput/NotchedOutline.js
@@ -21,7 +21,7 @@ const NotchedOutlineRoot = styled('fieldset')({
 
 const NotchedOutlineLegend = styled('legend', { skipSx: true })(({ ownerState, theme }) => ({
   float: 'unset', // Fix conflict with bootstrap
-  ...(ownerState.label === undefined && {
+  ...(!ownerState.withLabel && {
     padding: 0,
     lineHeight: '11px', // sync with `height` in `legend` styles
     transition: theme.transitions.create('width', {
@@ -29,7 +29,7 @@ const NotchedOutlineLegend = styled('legend', { skipSx: true })(({ ownerState, t
       easing: theme.transitions.easing.easeOut,
     }),
   }),
-  ...(ownerState.label !== undefined && {
+  ...(ownerState.withLabel && {
     display: 'block', // Fix conflict with normalize.css and sanitize.css
     width: 'auto', // Fix conflict with bootstrap
     padding: 0,
@@ -63,16 +63,17 @@ const NotchedOutlineLegend = styled('legend', { skipSx: true })(({ ownerState, t
  */
 export default function NotchedOutline(props) {
   const { children, classes, className, label, notched, ...other } = props;
+  const withLabel = label != null && label !== '';
   const ownerState = {
     ...props,
     notched,
-    label,
+    withLabel,
   };
   return (
     <NotchedOutlineRoot aria-hidden className={className} ownerState={ownerState} {...other}>
       <NotchedOutlineLegend ownerState={ownerState}>
         {/* Use the nominal use case of the legend, avoid rendering artefacts. */}
-        {label ? (
+        {withLabel ? (
           <span>{label}</span>
         ) : (
           // notranslate needed while Google Translate will not fix zero-width space issue
diff --git a/packages/mui-material/src/OutlinedInput/OutlinedInput.js b/packages/mui-material/src/OutlinedInput/OutlinedInput.js
--- a/packages/mui-material/src/OutlinedInput/OutlinedInput.js
+++ b/packages/mui-material/src/OutlinedInput/OutlinedInput.js
@@ -140,7 +140,7 @@ const OutlinedInput = React.forwardRef(function OutlinedInput(inProps, ref) {
         <NotchedOutlineRoot
           className={classes.notchedOutline}
           label={
-            label && fcs.required ? (
+            label != null && label !== '' && fcs.required ? (
               <React.Fragment>
                 {label}
                 &nbsp;{'*'}
diff --git a/packages/mui-material/src/TextField/TextField.js b/packages/mui-material/src/TextField/TextField.js
--- a/packages/mui-material/src/TextField/TextField.js
+++ b/packages/mui-material/src/TextField/TextField.js
@@ -188,7 +188,7 @@ const TextField = React.forwardRef(function TextField(inProps, ref) {
       ownerState={ownerState}
       {...other}
     >
-      {label && (
+      {label != null && label !== '' && (
         <InputLabel htmlFor={id} id={inputLabelId} {...InputLabelProps}>
           {label}
         </InputLabel>


Test patch:
diff --git a/packages/mui-material/src/OutlinedInput/NotchedOutline.test.js b/packages/mui-material/src/OutlinedInput/NotchedOutline.test.js
--- a/packages/mui-material/src/OutlinedInput/NotchedOutline.test.js
+++ b/packages/mui-material/src/OutlinedInput/NotchedOutline.test.js
@@ -54,4 +54,14 @@ describe('<NotchedOutline />', () => {
       paddingRight: '8px',
     });
   });
+  it('should not set padding (notch) for empty, null or undefined label props', function test() {
+    if (/jsdom/.test(window.navigator.userAgent)) {
+      this.skip();
+    }
+    const spanStyle = { paddingLeft: '0px', paddingRight: '0px' };
+    ['', undefined, null].forEach((prop) => {
+      const { container: container1 } = render(<NotchedOutline {...defaultProps} label={prop} />);
+      expect(container1.querySelector('span')).toHaveComputedStyle(spanStyle);
+    });
+  });
 });
diff --git a/packages/mui-material/src/TextField/TextField.test.js b/packages/mui-material/src/TextField/TextField.test.js
--- a/packages/mui-material/src/TextField/TextField.test.js
+++ b/packages/mui-material/src/TextField/TextField.test.js
@@ -121,6 +121,27 @@ describe('<TextField />', () => {
         outlinedInputClasses.notchedOutline,
       );
     });
+    it('should render `0` label properly', () => {
+      const { container } = render(
+        <TextField InputProps={{ classes: { notchedOutline: 'notch' } }} label={0} required />,
+      );
+
+      const notch = container.querySelector('.notch legend');
+      expect(notch).to.have.text('0\u00a0*');
+    });
+
+    it('should not set padding for empty, null or undefined label props', function test() {
+      if (/jsdom/.test(window.navigator.userAgent)) {
+        this.skip();
+      }
+      const spanStyle = { paddingLeft: '0px', paddingRight: '0px' };
+      ['', undefined, null].forEach((prop) => {
+        const { container: container1 } = render(
+          <TextField InputProps={{ classes: { notchedOutline: 'notch' } }} label={prop} />,
+        );
+        expect(container1.querySelector('span')).toHaveComputedStyle(spanStyle);
+      });
+    });
   });
 
   describe('prop: InputProps', () => {