简体   繁体   中英

Material UI TextField border overlaps with Label

I'm using Material UI TextField and Material UI Tab . I have two tabs and each has a text field inside them. After I click on the TextField , the border should open for the label, but this doesn't happen if the current Tab is not the Tab1 !!

I managed to reproduce this problem in this CodeSandBox and the code is also included below.

import React from "react";
import PropTypes from "prop-types";
import { makeStyles } from "@material-ui/core/styles";
import AppBar from "@material-ui/core/AppBar";
import Tabs from "@material-ui/core/Tabs";
import Tab from "@material-ui/core/Tab";
import Typography from "@material-ui/core/Typography";
import Box from "@material-ui/core/Box";
import TextField from "@material-ui/core/TextField";

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

  return (
    <Typography
      component="div"
      role="tabpanel"
      hidden={value !== index}
      id={`scrollable-force-tabpanel-${index}`}
      aria-labelledby={`scrollable-force-tab-${index}`}
      {...other}
    >
      <Box p={1}>{children}</Box>
    </Typography>
  );
}

TabPanel.propTypes = {
  children: PropTypes.node,
  index: PropTypes.any.isRequired,
  value: PropTypes.any.isRequired
};

function a11yProps(index) {
  return {
    id: `scrollable-force-tab-${index}`,
    "aria-controls": `scrollable-force-tabpanel-${index}`
  };
}

const useStyles = makeStyles(theme => ({
  root: {
    flexGrow: 1,
    width: "100%",
    backgroundColor: theme.palette.background.paper,
    padding: 0,
    margin: 0
  },
  Tab: {
    MuiTab: {
      root: {
        minWidth: "130px"
      }
    }
  }
}));

export default function Demo(props) {
  const classes = useStyles();
  const [value, setValue] = React.useState(0);

  function handleChange(event, newValue) {
    setValue(newValue);
    console.log(newValue);
  }

  return (
    <div className={classes.root}>
      <AppBar position="static" color="default">
        <Tabs
          key={"tabs"}
          value={value}
          onChange={handleChange}
          variant="scrollable"
          scrollButtons="on"
          indicatorColor="primary"
          textColor="primary"
          aria-label="scrollable force tabs example"
        >
          <Tab
            key={"tab1"}
            className={classes.Tab}
            label={0}
            {...a11yProps(0)}
          />
          <Tab
            key={"tab2"}
            className={classes.Tab}
            label={1}
            {...a11yProps(1)}
          />
        </Tabs>
      </AppBar>
      <TabPanel
        key={"panel1"}
        value={value}
        index={0}
        style={{ padding: 0, margin: 0 }}
      >
        <div key={"div1"}>
          hi im tab1{" "}
          <TextField
            key={"textfield1"}
            variant={"outlined"}
            margin={"dense"}
            label={"im tab 0 textfield"}
          />
        </div>
      </TabPanel>
      <TabPanel
        key={"panel2"}
        value={value}
        index={1}
        style={{ padding: 0, margin: 0 }}
      >
        <div key={"div2"}>
          hi im tab2
          <TextField
            key={"textfield2"}
            variant={"outlined"}
            margin={"dense"}
            label={"im tab 1 textfield"}
          />
        </div>
      </TabPanel>
    </div>
  );
}

Edit1:

I managed to find a similar question...,
Material-UI TextField Outline Label is overlapping with border when conditionally rendered
It seems this is not related to tabs as it is related to conditional rendering, which for me happened when i was using tabs

Edit2:
I tried giving the Textfield a key, but the problem still remains and there is an overlap between Textfield border and label, i updated the sandbox so it can reflect this

The label width is calculated during the initial rendering of the TextField and is only recalculated if the label changes. During the initial rendering of the TextField on your second tab, the TextField is not visible and thus the label's width is 0. Switching the TabPanel to visible does not cause a re-calculation of the label width, so no space is allotted for it in the outline.

You can fix this by using the same approach within your TabPanel as is used in the demos which is to only render the children of the panel when it is visible. This allows the label width to be correctly calculated after the initial rendering.

So instead of

<Box p={1}>{children}</Box>

you should instead have

{value === index && <Box p={1}>{children}</Box>}

编辑 TextFieldOnTabs

I had the overlap problem with the select. Slightly different scenario though. I went through numerous pages and just couldn't find a solution to these problems:

  1. Label text overlapping with the border - when the focus is received
  2. Placeholder text touching the left border
  3. If not problem # 1 - then Placeholder text staying inside the borders even when the value is selected/entered

在此处输入图片说明

在此处输入图片说明

在此处输入图片说明

A simple solution to all this are the following checks that worked for me -

  1. <FormControl variant="outlined">

Make sure variant is added.

  1. <InputLabel id="input_designationselected" style={{backgroundColor:'white'}}>Designation*</InputLabel>

Make sure that background is set for the label. Or refer to this link here https://github.com/mui-org/material-ui/issues/14530

  1. the attribute labelId for the input control/select control matches the ID of the InputLabel

Final output is as we need it.

在此处输入图片说明

It drove me crazy for days - and It thought I will share it for others also. Sorry if this is the wrong place to post it.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM