https://codesandbox.io/s/7m8vm8yxm6
Link:
1.
2.
3.
4.
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
| Tech | Version |
|--------------|---------|
| Material-UI | 3.9.2|
| React | yes |
| Browser | |
| TypeScript | |
| etc. | |
@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:
<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>
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>
);
}
}
What do you think of 1.? It's probably good enough for now.
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!
Still same problem with material-ui 4.4.0.
Do you have a reproduction?
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);
@kamami Thanks for sharing, at this point, the solution 3. in https://github.com/mui-org/material-ui/issues/16465#issuecomment-508080692 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
@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}.
@kamami Please open a separate issue. A codesandbox to reproduce the issue would help a lot.
Same issue in Vue's version of Material - https://github.com/vuetifyjs/vuetify/issues/7470
There is an good first issue open to update the logic to compute the label width at each render.
@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?
@aleccaputo Do you have a reproduction we can have a look at?
@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;
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;
@aleccaputo It's expected, you need to manually measure the label width in this configuration. #17680 explore a solution that relies 100% on CSS.
@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
@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: https://github.com/mui-org/material-ui/issues/17305#issuecomment-527836886.
@oliviertassinari ahhhh got it, that makes sense. Thank you!
Option 2 really saved my day.
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>
Most helpful comment
I had to explicitly set the label on the
<Select>
in addition to using the<InputLabel>