Tips for creating multiple row tabs in Material UI Tabs

Currently, I have close to 30 tabs housed within Material UI Tabs. In order for the user to view all tabs, they must scroll two times. I am seeking a solution to display the tabs in two rows with a scroll, as opposed to one row with scroll. This would allow users to see most of the tabs with just one glance.
I have searched through the Material UI documentation but have not found a useful solution. I attempted to manually apply CSS styles, but unfortunately, I fell short in achieving my desired layout (my CSS skills are average).
To better illustrate my idea of having multiple row tabs, please refer to this sample image:
https://i.sstatic.net/Q6WBI.png
Any assistance on this matter would be greatly appreciated.

Answer №2

Here's a little trick I used:

Instead of using one Tabs component, I used two and adjusted the indexes like this:

<Box sx={{ display: 'flex',justifyContent: 'center', flexWrap: 'wrap'}}>
    <Tabs value={value} onChange={handleChange}>
        <Tab label='Prices'/>
        <Tab label='Users'/>
        <Tab label='Plan'/>
    </Tabs>
    <Tabs value={value - 3 } onChange={handleChange2}>
        <Tab label='Employees'/>
    </Tabs>
</Box>

Then, I managed the change for this adjustment using the following code:

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

All you need to do is replace the number 3 with the number of tabs in your first component.

Regards

Answer №3

Dealing with a similar issue myself. After going through the documentation, it seems that achieving this using Tabs/Tab features is not feasible. However, there are a couple of alternatives available:

  1. Utilize properties variant="scrollable" and scrollButtons="auto" as mentioned earlier. This may not provide the expected result, but it does get the job done.
  2. Create your own tabs by leveraging Grid. The example below illustrates an approach, though it is not a final solution and can be easily customized.

const useStyles = makeStyles((theme) => ({
  navigationLinkContainer: { 
    // Customize as needed
  },
  navigationLinkButtonActive: {
    color: '#ffffff',
    // Customize as needed
  },
 
}));

const NavigationLink = (props) => {
  const classes = useStyles();
  return (
    <Grid item className={classes.navigationLinkContainer}>
      <Button
        component={Link}
        onClick={props.onClick}
      >
        {props.children}
      </Button>
    </Grid>
  );
};

const NavigationHeaders = (props) => {
  const classes = useStyles();
  const { headers, className } = props;
  const [activeTab, setActiveTab] = React.useState('');

  const isActive = (headerId) => headerId === activeTab;

  return (
    <>
     <Grid container >
      {headers.map((header) => (
        <NavigationLink
          className={classnames(isActive(header.id) && classes.navigationLinkButtonActive)}
          key={header.id}
          onClick={() => setActiveTab(header.id)}
        >
          {header.title}
        </NavigationLink>
      ))}
     </Grid>
     {/* Display content based on activeTab */}
   </>
  );
};

Answer №4

After experimenting with various methods, I have come to the realization that achieving the desired outcome with Tabs/Tab is currently not feasible. I attempted to incorporate <br />, <hr />, <Divider />, and other functions to create breaks, attempted to create multiple rows of tabs (resulting in selection issues), tried wrapping Tabs in a span with max-width (resulting in selection issues as well), and explored numerous other options. Eventually, I resolved to implement scrolling for smaller screens.

By determining the smallest screen size that could display my tabs properly, I implemented scrolling for screens that are smaller.

const mql = window.matchMedia('(max-width: 2000px)');
const smallScreen = mql.matches;

<Tabs
  value={tabValue}
  onChange={handleTabChange}
  orientation="horizontal"
  variant={smallScreen ? 'scrollable' : 'standard'}
  centered={!smallScreen}
 >
   <Tab label="1" />
   <Tab label="2" />
   <Tab label="3" />
   <Tab label="4" />
   <Tab label="5" />
  </Tabs>

Although adding an event handler to adjust on resize is an option, it was not necessary for my specific scenario.

Answer №5

Make sure to thoroughly review the documentation of any tool you utilize to prevent unnecessary issues in the future

For more in-depth information and complete code, check out https://material-ui.com/components/tabs/

<div className={classes.root}>
  <AppBar position="static">
    <Tabs value={value}
     onChange={handleChange} 
      aria-label="simple tabs example" 
      indicatorColor="primary"
      textColor="primary"
      variant="scrollable"
      scrollButtons="auto"
      aria-label="scrollable auto tabs example"
    >
      <Tab label="Item One" {...a11yProps(0)} />
      <Tab label="Item Two" {...a11yProps(1)} />
      <Tab label="Item Three" {...a11yProps(2)} />
    </Tabs>
  </AppBar>
  <TabPanel value={value} index={0}>
    Item One
  </TabPanel>
  <TabPanel value={value} index={1}>
    Item Two
  </TabPanel>
  <TabPanel value={value} index={2}>
    Item Three
  </TabPanel>
</div>

Edit: please pay attention to the variant specified in Tabs

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Function activation in Element requires a double click to initiate

I've encountered an issue with a web element I'm working on where the click function only triggers after the first click, rendering the initial click ineffective. Here's the code snippet in question: HTML: <div> <a href="#0" cla ...

What is the best way to customize the color of the <DatePicker /> component?

https://i.stack.imgur.com/JLtGz.png I am trying to customize the underline color of the DatePicker component. Below is my code snippet attempting to achieve this: import React from 'react' import PropTypes from 'prop-types' import { Da ...

Troubleshooting Div Element Width in CSS Not Functioning

When working on a form design, I encountered an issue where the text labels were not aligning to the same width. Despite setting the width, it didn't seem to work as expected: .form-label { display:inline; width: 160px; } <div class="form-label ...

Troubleshooting a background image problem in a TailwindCSS configuration file

I'm having trouble getting the background image to show up correctly using tailwind.Config.Js. Even though Tailwind.Config.Js is generating the background image perfectly, when I view it in the browser, it's displaying a 404 error for the image. ...

Adjust the width of the dropdown menu in React-Bootstrap to match the width of the dropdown when changes occur

How can I dynamically set the width of a dropdown menu to match the size of the whole dropdown when it changes? Is there a way to get the width of the dropdown itself? I attempted to align the dropdown menu to the "end" which caused it to be right aligned ...

Timeout function failing to properly clear asynchronous code

My react application is running into an issue with async calls in the setTimeout function. There's a condition where I want to clear the timeout, but even after it's cleared, the code inside still executes (I've checked and confirmed that th ...

Utilizing Props in React to Slice and Dice Data Within a Separate Component

Currently, I am in the process of creating an about text for a profile that will include an option to expand or collapse based on its length. To achieve this, I am utilizing a function from the main home component: <AboutText text={aboutData}/> Abo ...

Iterate through three images using the `background-image` property in my Div

Is there a way to modify a code that loops through images based on an Img source in order to work with the "background-image" property of a div? HTML <div id="section2"></div> CSS #section2 { background-image: 'url(..images/banner1.jp ...

prettyPhoto popup exceeds maximum width and height limitations

I am currently using the most up-to-date version from No Margin for Errors and I have set allow_resize to true. However, the size of the display is still too large. Is there a way to set a maximum width/height? I have already configured the viewport as fo ...

It is not possible to change the maximum height of a Popover in Material UI

I am currently working with the Popover component in material-ui, but I am facing an issue modifying the max-height property that is calculated as max-height: calc(100% - var). I have attempted different solutions such as using className and override, but ...

Testing a component's conditional branches within the render function before it returns

In order to prevent my table component from breaking in case no data is found during a function invocation, I have implemented a conditional "return null" before the render method. This serves as an extra safety measure. However, I am facing difficulty te ...

Is it possible to utilize rbac permissions independently of the authProvider system?

Currently, our team is utilizing react-admin and we are interested in implementing a permissions system for accessing resources. We have noticed that we can include permissions within the getPermissions function in the authProvider, but our current authent ...

What is the best way to display an input label or placeholder label consistently?

I am currently utilizing the multi-select feature with checkboxes provided by Material UI v4. By default, the settings display an array of 'SELECTED' values using the renderValue={selected => selected.join(', ') function. However, I ...

Choose the dropdown value that corresponds to the name of the subcollection from which to retrieve data

functions: const [damta, setDamta] = useState([]); const [drpcrs, setDrpcr] =useState("") console.log(drpcrs) const crsval = (value) =>{ if(drpcrs == value.fYCS){ return FYCS }else if (drpcrs == value.sYCS){ return SYC ...

What seems to be the issue at hand? Could I be making a mistake? Are there alternative methods to approach this situation?

I've encountered an error with my code, which is displayed in the attached picture. Can anyone help me identify the issue? The goal of my code is to show a message if the passcode length entered in the TextInput is less than 10 characters. Once the le ...

Send a parameter to the state from the component to access the object property key within a React array

I am managing a state that contains an array of objects: const [Value, setValue] = useState([{ Width: null, Length: null }, { Width: null, Length: null }]) In addition, I have a component where I need to retrieve the value for Value using the setValue fun ...

Every time I reload the page, the tab indicator on Material-UI returns to the first tab item

After integrating material-ui tabs with react router, I noticed that the tab indicator resets to the first tab upon page reload. I suspect this is due to the initial value of the tab being set to zero and resetting on page refresh. To visualize the issue, ...

Can CSS be used to communicate to JavaScript which media queries are currently in effect?

Is there a way for Javascript to detect when a specific CSS media query is active without repeating the conditions of the media query in Javascript? Perhaps something similar to an HTML data attribute, but for CSS. For example: CSS @media (min-width: 94 ...

Trouble encountered while trying to animate an SVG path

My attempt to animate an SVG is not working for some reason. https://i.stack.imgur.com/atTg3.png This is the component where I'm trying to load the SVG: import { JapanMap } from "../illustrations/japanMap"; export default function Home() ...

Sluggish operation of the personalized element

I have developed a unique text input component using Material UI and integrated it with Formik: import React from 'react'; import { Field } from 'formik'; import { TextField, ThemeProvider, createTheme } from '@mui/mate ...