Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

The label value in outlined overlaps the border #14530

Closed
Andrew-Zn opened this issue Feb 14, 2019 · 21 comments · Fixed by #17217
Closed

The label value in outlined overlaps the border #14530

Andrew-Zn opened this issue Feb 14, 2019 · 21 comments · Fixed by #17217
Labels
component: text field This is the name of the generic UI component, not the React module! support: question Community support but can be turned into an improvement

Comments

@Andrew-Zn
Copy link

  • [x ] This is not a v0.x issue.
  • [x ] I have searched the issues of this repository and believe that this is not a duplicate.

Expected Behavior 🤔

image

Current Behavior 😯

image

Steps to Reproduce 🕹

https://codesandbox.io/s/7m8vm8yxm6

Link:

Context 🔦

There are a lot of tabs that need to be display on and off,I'm not sure if it's my problem or bug

Your Environment 🌎

Tech Version
Material-UI 3.9.2
React yes
Browser
TypeScript
etc.
@oliviertassinari
Copy link
Member

oliviertassinari commented Feb 14, 2019

@Andrew-Zn This is a visibility issue. We are measuring the label dimension to display the right gap. We have 3 class of solutions available:

  1. Remount the component every time it's displayed. For instance, this can be achieved with a key:
        <div className={this.state.flag ? classes.root : classes.hidden}>
          <TextField
+           key={this.state.flag}
            id="one"
            label="No.1"
            value="This is one" //这里是函数 如果有存在传入值。就是传入值的效果,还有默认效果
            fullWidth
            margin="normal"
            variant="outlined"
          />
        </div>
        <div className={!this.state.flag ? classes.root : classes.hidden}>
          <TextField
+           key={this.state.flag}
            id="two"
            label="No.2"
            value="This is two" //这里是函数 如果有存在传入值。就是传入值的效果,还有默认效果
            fullWidth
            margin="normal"
            variant="outlined"
          />
        </div>
  1. Use a background white color like Google is doing with it's official signin inputs:
import React, { Component } from "react";
import ReactDOM from "react-dom";
import { withStyles } from "@material-ui/core/styles";
import TextField from "@material-ui/core/TextField";
import Button from "@material-ui/core/Button";

import "./styles.css";

const styles = theme => ({
  root: {
    display: "flex",
    textAlign: "center",
    width: 300,
    marginLeft: 100,
    marginTop: 200
  },
  hidden: {
    display: "none"
  },
  button: {
    background: "green"
  },
+ label: {
+   backgroundColor: "white"
+  }
});

class App extends Component {
  state = {
    flag: true
  };
  handle = () => {
    this.setState({
      flag: !this.state.flag
    });
  };
  render() {
    const { classes } = this.props;
    return (
      <div className="App">
        <div className={this.state.flag ? classes.root : classes.hidden}>
          <TextField
+           InputLabelProps={{
+             classes: {
+               root: classes.label
+             }
+            }}
            id="one"
            label="No.1"
            value="This is one" //这里是函数 如果有存在传入值。就是传入值的效果,还有默认效果
            fullWidth
            margin="normal"
            variant="outlined"
          />
        </div>
        <div className={!this.state.flag ? classes.root : classes.hidden}>
          <TextField
+           InputLabelProps={{
+             classes: {
+               root: classes.label
+             }
+            }}
            id="two"
            label="No.2"
            value="This is two" //这里是函数 如果有存在传入值。就是传入值的效果,还有默认效果
            fullWidth
            margin="normal"
            variant="outlined"
          />
        </div>
        <Button className={classes.button} onClick={this.handle}>
          Change
        </Button>
      </div>
    );
  }
}
  1. Use the intersection Observer API internally, but requires a polyfill 👎

@oliviertassinari oliviertassinari added the component: text field This is the name of the generic UI component, not the React module! label Feb 14, 2019
@oliviertassinari
Copy link
Member

oliviertassinari commented Feb 14, 2019

What do you think of 1.? It's probably good enough for now.

@Andrew-Zn
Copy link
Author

Thank you very much for your solutions. The second solution is most helpful for my question, so I take this suggestion. Thanks again. Best wishes!

@kamami
Copy link

kamami commented Sep 3, 2019

Still same problem with material-ui 4.4.0.

@oliviertassinari
Copy link
Member

Do you have a reproduction?

@kamami
Copy link

kamami commented Sep 4, 2019

Here I have two Tabcontainer with one Textfield each. When changing the Tab, the label of the second Textfield still overlaps its border. First Textfield is working fine. Sorry for ugly code, but I have no beautifier on my phone... Hope it helps!

react: "^16.8.0"

material-ui: "^4.4.0"

import React from 'react';
import { TextField, Button, Typography, withStyles } from '@material-ui/core';

const styles = theme => ({

});

function TabContainer(props) {
  const { children, value, index, ...other } = props;

  return (
    <Typography
      component="div"
      role="tabpanel"
      hidden={value !== index}
      id={`full-width-tabpanel-${index}`}
      aria-labelledby={`full-width-tab-${index}`}
      {...other}
    >
      <div p={3} style={{ padding: '0px' }}>
        {children}
      </div>
    </Typography>
  );
}

class CheckoutPage extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      openDrawer: false,
      name: '',
      street: '',
      value: 0,
    };
  }

  handleChange = index => {
    this.setState({ value: index, activeStep: index });
  };

  onChangeName = event => {
    this.setState({ name: event.target.value });
  };

  onChangeStreet = event => {
    this.setState({ street: event.target.value });
  };

  render() {
    const { theme } = this.props;
    const { name, street,  value } = this.state;

    return (
          <div>
            <TabContainer
              value={value}
              index={0}
              dir={theme.direction}
            >
              <TextField
                id="outlined-name"
                label="Vor- und Nachname"
                value={name}
                onChange={this.onChangeName}
                margin="normal"
                variant="outlined"
                fullWidth
                type="email"
                style={{ marginBottom: 20, marginTop: 20 }}
              />
              <div>
                <Button
                  variant="contained"
                  onClick={event => {this.handleChange(value + 1); }}>
                  Next
                </Button>
              </div>
            </TabContainer>
            <TabContainer
              value={value}
              index={1}
              dir={theme.direction}
            >
              <TextField
                id="street"
                label="Straße und Hausnr."
                value={street}
                onChange={this.onChangeStreet}
                variant="outlined"
                fullWidth
                style={{ marginBottom: 20, marginTop: 20 }}
              />

            </TabContainer>
      </div>
    );
  }
}
export default withStyles(styles, { withTheme: true })(CheckoutPage);

@oliviertassinari
Copy link
Member

oliviertassinari commented Sep 4, 2019

@kamami Thanks for sharing, at this point, the solution 3. in #16465 (comment) could be a great long term approach. Today, you could add a key={activeStep} prop on the TextField element. We could imagine the following fix tomorrow in the core:

diff --git a/packages/material-ui/src/TextField/TextField.js b/packages/material-ui/src/TextField/TextField.js
index a8f3cadaea..fe8e39103c 100644
--- a/packages/material-ui/src/TextField/TextField.js
+++ b/packages/material-ui/src/TextField/TextField.js
@@ -94,13 +94,14 @@ const TextField = React.forwardRef(function TextField(props, ref) {

   const [labelWidth, setLabelWidth] = React.useState(0);
   const labelRef = React.useRef(null);
+  // eslint-disable-next-line react-hooks/exhaustive-deps
   React.useEffect(() => {
     if (variant === 'outlined') {
       // #StrictMode ready
       const labelNode = ReactDOM.findDOMNode(labelRef.current);
       setLabelWidth(labelNode != null ? labelNode.offsetWidth : 0);
     }
-  }, [variant, required, label]);
+  });

   warning(

cc @eps1lon

@kamami
Copy link

kamami commented Sep 4, 2019

@oliviertassinari This works fine.

Unfortunatly it breaks my autofocus method...
I added inputRef={el => { this.street = el; }}
to my textfield. My button triggers then this.street.focus(); This does not work, when I give Textfield the key={activeStep}.

@eps1lon
Copy link
Member

eps1lon commented Sep 4, 2019

@kamami Please open a separate issue. A codesandbox to reproduce the issue would help a lot.

@n3ps
Copy link

n3ps commented Sep 25, 2019

Same issue in Vue's version of Material - vuetifyjs/vuetify#7470

@oliviertassinari
Copy link
Member

There is an good first issue open to update the logic to compute the label width at each render.

@aleccaputo
Copy link
Contributor

@oliviertassinari
Noticed this is closed, but i'm having this issue with 4.4.3 on a . Using the solution above to set the background color to white for now, but seems like a hack. I'm not sure i'm understanding the root cause of the issue, because in other projects i've definitely used outlined inputs without the background color solution and it's worked fine. Does it have anything to do with long/slow renders?

@oliviertassinari
Copy link
Member

@aleccaputo Do you have a reproduction we can have a look at?

@aleccaputo
Copy link
Contributor

aleccaputo commented Oct 9, 2019

@oliviertassinari only other thing this is wrapped in is reach router

import React, {useState} from 'react';
import {makeStyles} from '@material-ui/core';
import FormControl from '@material-ui/core/FormControl';
import InputLabel from '@material-ui/core/InputLabel';
import Select from '@material-ui/core/Select';
import MenuItem from '@material-ui/core/MenuItem';

const useStyles = makeStyles(() => ({
    select: {
        minWidth: 250
    }
}));

const Home = () => {
    const classes = useStyles();
    const [myThing, setMyThing] = useState('');
    const stuff = ['foo', 'bar', 'baz'];
    return (
        <FormControl
            className={classes.select}
            variant={'outlined'}
            style={{marginTop: '100px'}}
        >
            <InputLabel>
                {'My Stuff!'}
            </InputLabel>
            <Select
                onChange={e => setMyThing(e.target.value)}
                value={myThing}
                variant={'outlined'}
            >
                {
                    stuff.map(thing => (
                        <MenuItem value={thing}>
                            {thing}
                        </MenuItem>
                    ))
                }
            </Select>
        </FormControl>
    );
};

export default Home;

image

theme:

import error from '@material-ui/core/colors/red';

export const defaultTheme = {
    themeName: 'default',
    typography: {
        fontSize: 16,
        htmlFontSize: 16,
        fontFamily: '"proxima-nova"'
    },
    palette: {
        type: 'light',
        primary: {
            main: '#0C66C6'
        },
        secondary: {
            main: '#09919D'
        },
        error: {
            main: error['500']
        },
        background: {
            default: '#F0F3F5'
        }
    }
};

App.js

// @flow
import React from 'react';
import {Router} from '@reach/router';
import Navigation from './screens/navigation';
import IncidentMappings from './screens/incident-mappings';
import OnboardNewState from './screens/onboard-new-state';
import CarrierMapping from './screens/carrier-mapping';
import {Provider} from 'react-redux';
import {store} from './store';
import {ThemeProvider} from '@material-ui/styles';
import {createMuiTheme, Typography} from '@material-ui/core';
import {defaultTheme} from './theme';
import Authed from './components/authed';
import NotAuthed from './components/not-authed';
import Login from './screens/login';
import AppBar from '@material-ui/core/AppBar';
import Home from './screens/home';
import './App.css';

const App = () => (
    <Provider store={store}>
        <ThemeProvider theme={createMuiTheme(defaultTheme)}>
            <AppBar position={'static'} style={{flexGrow: 1}}>
                <Typography>
                    {'Label issue'}
                </Typography>
            </AppBar>
            <Authed>
                <Navigation />
                <Router>
                    <Home path={'home'} />
                </Router>
            </Authed>
            <NotAuthed>
                <Login/>
            </NotAuthed>
        </ThemeProvider>
    </Provider>
);

export default App;

@oliviertassinari
Copy link
Member

oliviertassinari commented Oct 9, 2019

@aleccaputo It's expected, you need to manually measure the label width in this configuration. #17680 explore a solution that relies 100% on CSS.

@aleccaputo
Copy link
Contributor

aleccaputo commented Oct 9, 2019

@oliviertassinari interesting, is it because i'm mapping over an array? What is the configuration that i would need to do that? Thanks for the response, will take a look at the PR

@oliviertassinari
Copy link
Member

oliviertassinari commented Oct 9, 2019

@aleccaputo No, it's because you need to measure the label width a provide this value to the select component, you can find an example in the demos, only the TextField does it for you.

If the effort in #17680 fail, we should push the documentation solution forward: #17305 (comment).

@aleccaputo
Copy link
Contributor

@oliviertassinari ahhhh got it, that makes sense. Thank you!

@abhi1d
Copy link

abhi1d commented Apr 20, 2020

Option 2 really saved my day.

@SkyHacks
Copy link

I had to explicitly set the label on the <Select> in addition to using the <InputLabel>

<FormControl variant="outlined">
  <InputLabel id="demo-simple-select-outlined-label">Age</InputLabel>
  <Select
    labelId="demo-simple-select-outlined-label"
    id="demo-simple-select-outlined"
    value=""
    onChange={() => {}}
    label="Age"    /* <==== Adding this fixed the issue for me */
  >
    <MenuItem value={10}>Ten</MenuItem>
    <MenuItem value={20}>Twenty</MenuItem>
    <MenuItem value={30}>Thirty</MenuItem>
  </Select>
</FormControl>

@oliviertassinari oliviertassinari added the support: question Community support but can be turned into an improvement label Apr 29, 2020
orangecms added a commit to fossasia/pslab-desktop that referenced this issue Jun 14, 2020
Use CSS background-color instead. Factor out form styles to utils. See also
mui/material-ui#14530 (comment).
orangecms added a commit to orangecms/pslab-desktop that referenced this issue Oct 14, 2020
Use CSS background-color instead. Factor out form styles to utils. See also
mui/material-ui#14530 (comment).
Abhijay007 pushed a commit to Abhijay007/pslab-desktop that referenced this issue Oct 31, 2020
Use CSS background-color instead. Factor out form styles to utils. See also
mui/material-ui#14530 (comment).
cynthi8 pushed a commit to cynthi8/pslab-desktop that referenced this issue Dec 16, 2020
Use CSS background-color instead. Factor out form styles to utils. See also
mui/material-ui#14530 (comment).
@amrithmmh
Copy link

I had to explicitly set the label on the <Select> in addition to using the <InputLabel>

<FormControl variant="outlined">
  <InputLabel id="demo-simple-select-outlined-label">Age</InputLabel>
  <Select
    labelId="demo-simple-select-outlined-label"
    id="demo-simple-select-outlined"
    value=""
    onChange={() => {}}
    label="Age"    /* <==== Adding this fixed the issue for me */
  >
    <MenuItem value={10}>Ten</MenuItem>
    <MenuItem value={20}>Twenty</MenuItem>
    <MenuItem value={30}>Thirty</MenuItem>
  </Select>
</FormControl>

This is similar to the example in react material ui select example code. But it fails to work for me.

"@material-ui/core": "^4.12.3"

lprichar added a commit to Election-Tech-Initiative/electionguard-ui that referenced this issue Jan 20, 2022
lprichar added a commit to Election-Tech-Initiative/electionguard-ui that referenced this issue Jan 20, 2022
* Fix key selection page to work with nswag

* Fixed all the annoying warnings

* Set keyCeremony on selection

* npm upgrades and npm audit fix

* Deprecate the old KeyCeremony to resolve conflicts

* Add mui v5 packages

* variant-prop codemod

* Update react-scripts in api-client

* Upgrade all the linters

* Reverting accidental change to library

* Fixing UI overlap problem in input style

see also: mui/material-ui#14530 (comment)

* npm audit fix --force

* Fix "Function component is not a function declaration"

https://stackoverflow.com/a/69931909/40783

* Migrate data grid to mui 5

* Fix linting errors in default layout

* Fix error on reload ERROR in Plugin "react" was conflicted between ".eslintrc.json" and "BaseConfig

https://stackoverflow.com/a/70790903/40783

* Fix data grid error with no rows overlay

* Fix mui error on election setup wizard page

* Fixing new linting errors from upgrade to eslint ^8.7 and airbnb to ^19

* Fix linting errors in AuthenticatedLayout

* Fix linting error ESLint couldn't determine the plugin "@typescript-eslint" uniquely.

https://stackoverflow.com/a/68270742/40783

* Fixing yet more linting problems in admin-app and result-app

* Fix linting errors in /library, mostly by deleting duplicate components

* Fix tests
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
component: text field This is the name of the generic UI component, not the React module! support: question Community support but can be turned into an improvement
Projects
None yet
Development

Successfully merging a pull request may close this issue.

9 participants