Ali Ahmadi
Ali Ahmadi

Reputation: 731

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

Upvotes: 3

Views: 7864

Answers (2)

KManish
KManish

Reputation: 1861

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

enter image description here

enter image description here

enter image description here

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.

enter image description here

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.

Upvotes: 6

Ryan Cogswell
Ryan Cogswell

Reputation: 81006

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>}

Edit TextFieldOnTabs

Upvotes: 5

Related Questions