Search code examples
javascriptreactjsmaterial-uicomponentsjsx

How do I inject my own styling into a TabsAPI Tab Panel? Can't stop weird expansion


I'm trying to style the Tabs component provided by MUI and I'm having some trouble figuring out how to accomplish what I would like to. The first problem I'm running into is as follows:

For some reason, whenever I navigate between tabs, the tabs seem to get "bigger"? I don't know what caused this, but it seems like this only happens with tabs that have more actual content in them than other tabs. Below you'll find a video of what I mean:

Strange Tab Expansion

I've tried taking out some of the styling that I was able to figure out on my own, but nothing seems to affect this weird behavior, and I can't seem to find anything in the documentation that affects this tab-panel. Below is the code that I'm currently working with:

import * as React from 'react';
import PropTypes from 'prop-types';
import Tabs from '@mui/material/Tabs';
import Tab from '@mui/material/Tab';
import Typography from '@mui/material/Typography';
import Box from '@mui/material/Box';
import '../CSS/test.css'
import '../App.css'
import '../CSS/Work.css'

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

  return (
    <div
      role="tabpanel"
      hidden={value !== index}
      id={`vertical-tabpanel-${index}`}
      aria-labelledby={`vertical-tab-${index}`}
      {...other}
    >
      {value === index && (
        <Box sx={{ p: 3 }}>
          <Typography>{children}</Typography>
        </Box>
      )}
    </div>
  );
}

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

function a11yProps(index) {
  return {
    id: `vertical-tab-${index}`,
    'aria-controls': `vertical-tabpanel-${index}`,
  };
}

export default function VerticalTabs() {
  const [value, setValue] = React.useState(0);

  const handleChange = (event, newValue) => {
    setValue(newValue);
  };

  return (
    <Box
      sx={{ flexGrow: 1, bgcolor: '#222725', display: 'flex', height: 'fit-content', width: '100vh' }}
    >
      <Tabs
        TabIndicatorProps={{style: {background:'green'}}} // CHANGE INDICATOR COLOR HERE
        orientation="vertical"
        variant="scrollable"
        value={value}
        onChange={handleChange}
        aria-label="Vertical tabs example"
        centered
        sx={{ 
          borderRight: 1,
          borderColor: 'divider',
          '.MuiTabPanel-root': {
            width: 2000,
          },
          ".Mui-selected": {
          color: `green`, // CHANGE THE COLOR OF HIGHLIGHTED TAB HERE
          fontFamily: 'NTR, sans-serif',
          fontSize: '2vh',
          width: "50vh",
          }, 
          '& .inactiveTab': {color: '#fff', fontFamily: 'NTR, sans-serif', fontSize: '2vh', width: 400}
        }}
      >
        <Tab label="CS 128" {...a11yProps(0)} className={value !== 0 ? 'inactiveTab' : ''} />
        <Tab label="CS 173" {...a11yProps(1)} className={value !== 1 ? 'inactiveTab' : ''}/>
        <Tab label="IGL" {...a11yProps(2)} className={value !== 2 ? 'inactiveTab' : ''}/>
      </Tabs>
      <TabPanel value={value} index={0}>
        <div className='slide-tab'>
          <h1 className='job_title'>Course Assistant for CS 128 at UIUC</h1>
          <h3 className='job_date'>Fall 2022 - Present</h3>
          <ul className='tester_list'>
            <li className='job_desc'>Developed a grade management system with JavaScript that calculated class grades for the entire course</li>
            <li className='job_desc'>Helped to develop and draft the prompts for course material that explained foundational CS concepts</li>
            <li className='job_desc'>Hosted and coordinated multiple office hours every week</li>
          </ul>
        </div>
      </TabPanel>
      <TabPanel value={value} index={1}>
        <div className='slide-tab'>
          <h1 className='job_title'>Course Assistant for CS 173 at UIUC</h1>
          <h3 className='job_date'>Spring 2023 - Present</h3>
          <ul className='tester_list'>
            <li className='job_desc'>Created tutoring approach that best fit each students' learning style</li>
            <li className='job_desc'>Assess and troubleshoot conceptual misunderstandings brought by students</li>
            <li className='job_desc'>Led large gatherings of the class where new material was learned and practiced</li>
            <li className='job_desc'>Developed content that was used by the entire class</li>
          </ul>
        </div>
      </TabPanel>
      <TabPanel value={value} index={2}>
        <div className='slide-tab'>
          <h1 className='job_title'>Undergraduate Research Assistant @ IGL</h1>
          <h3 className='job_date'>Fall 2023</h3>
          <ul className='tester_list'>
            <li className='job_desc'>Working closely with Radu's Algorithm and its' application to combinatorics/number theory</li>
            <li className='job_desc'>Developing several solutions to various questions posed by this algorithm in Mathematica</li>
            <li className='job_desc'>Processing and computing new and efficient solutions to proofs that have existed on paper for some time</li>
          </ul>
        </div>
      </TabPanel>
    </Box>

   );
}

I tried multiple times to add in all sorts of different styling, like adding in a minWidth and maxWidth styling element and nothing seems to affect the weird tab expansion on that one tab that was seen in the video. I've also tried taking out some of the content in the "CS 173" tab and it doesn't seem to change based off of how much content I have in there either. I have seen suggested fixes, but they all use the makeStyles import, but that's outdated and has been for years and I can't seem to find an alternative to it. (If I can provide any additional information/code please let me know!)


Solution

  • The way the tabs are styled is that they will expand and shrink based on the TabPanel content because of the flex property at the root of the component. Basically, because the second tab "CS 173" has less content, the TabContent section is not expanding as much so the Tab width is not effected compared to the first and last. Also, if you try to make the screen smaller, the tabs will start to shrink and disappear because of how they are styled in MUI.

    If you want the left tabs sections not to be effected at all by the right side content, I suggest using a grid instead of flex to keep it fixed. Here is a quick example:

    import * as React from 'react';
    import Tabs from '@mui/material/Tabs';
    import Tab from '@mui/material/Tab';
    import Typography from '@mui/material/Typography';
    import Box from '@mui/material/Box';
    
    function TabPanel(props) {
      const { children, value, index, ...other } = props;
    
      return (
        <div
          role="tabpanel"
          hidden={value !== index}
          id={`vertical-tabpanel-${index}`}
          aria-labelledby={`vertical-tab-${index}`}
          {...other}
        >
          {value === index && (
            <Box sx={{ p: 3 }}>
              <Typography>{children}</Typography>
            </Box>
          )}
        </div>
      );
    }
    
    function a11yProps(index) {
      return {
        id: `vertical-tab-${index}`,
        'aria-controls': `vertical-tabpanel-${index}`,
      };
    }
    
    export default function VerticalTabs() {
      const [value, setValue] = React.useState(0);
    
      const handleChange = (event, newValue) => {
        setValue(newValue);
      };
    
      return (
        <Box
          sx={{
            flexGrow: 1,
            bgcolor: '#222725',
            display: 'grid',
            gridTemplateColumns: '200px 1fr',
            height: 'fit-content',
          }}
        >
          <Tabs
            TabIndicatorProps={{ style: { background: 'green' } }} // CHANGE INDICATOR COLOR HERE
            orientation="vertical"
            variant="scrollable"
            value={value}
            onChange={handleChange}
            aria-label="Vertical tabs example"
            centered
            sx={{
              borderRight: 1,
              borderColor: 'divider',
              '.Mui-selected': {
                color: `green`, // CHANGE THE COLOR OF HIGHLIGHTED TAB HERE
                fontFamily: 'NTR, sans-serif',
                fontSize: '2vh',
              },
              '& .inactiveTab': {
                color: '#fff',
                fontFamily: 'NTR, sans-serif',
                fontSize: '2vh',
              },
              '& button': {
                alignItems: 'flex-start',
              },
            }}
          >
            <Tab
              label="CS 128"
              {...a11yProps(0)}
              className={value !== 0 ? 'inactiveTab' : ''}
            />
            <Tab
              label="CS 173"
              {...a11yProps(1)}
              className={value !== 1 ? 'inactiveTab' : ''}
            />
            <Tab
              label="IGL"
              {...a11yProps(2)}
              className={value !== 2 ? 'inactiveTab' : ''}
            />
          </Tabs>
          <TabPanel value={value} index={0}>
            <div className="slide-tab">
              <h1 className="job_title">Course Assistant for CS 128 at UIUC</h1>
              <h3 className="job_date">Fall 2022 - Present</h3>
              <ul className="tester_list">
                <li className="job_desc">
                  Developed a grade management system with JavaScript that
                  calculated class grades for the entire course
                </li>
                <li className="job_desc">
                  Helped to develop and draft the prompts for course material that
                  explained foundational CS concepts
                </li>
                <li className="job_desc">
                  Hosted and coordinated multiple office hours every week
                </li>
              </ul>
            </div>
          </TabPanel>
          <TabPanel value={value} index={1}>
            <div className="slide-tab">
              <h1 className="job_title">Course Assistant for CS 173 at UIUC</h1>
              <h3 className="job_date">Spring 2023 - Present</h3>
              <ul className="tester_list">
                <li className="job_desc">
                  Created tutoring approach that best fit each students' learning
                  style
                </li>
                <li className="job_desc">
                  Assess and troubleshoot conceptual misunderstandings brought by
                  students
                </li>
                <li className="job_desc">
                  Led large gatherings of the class where new material was learned
                  and practiced
                </li>
                <li className="job_desc">
                  Developed content that was used by the entire class
                </li>
              </ul>
            </div>
          </TabPanel>
          <TabPanel value={value} index={2}>
            <div className="slide-tab">
              <h1 className="job_title">Undergraduate Research Assistant @ IGL</h1>
              <h3 className="job_date">Fall 2023</h3>
              <ul className="tester_list">
                <li className="job_desc">
                  Working closely with Radu's Algorithm and its' application to
                  combinatorics/number theory
                </li>
                <li className="job_desc">
                  Developing several solutions to various questions posed by this
                  algorithm in Mathematica
                </li>
                <li className="job_desc">
                  Processing and computing new and efficient solutions to proofs
                  that have existed on paper for some time
                </li>
              </ul>
            </div>
          </TabPanel>
        </Box>
      );
    }
    

    I've also added the code in Stackblitz to try it out. https://stackblitz.com/edit/react-bcor1l?file=demo.tsx