When I add grid and grid items, the vertical tabs get covered like this: image1, I want the contents to achieve this: image2. Any help would be so greatly appreciated! I just started with Material UI.
This is my code:
import React, { useState, useEffect } from "react";
import { Box, Grid, Tab, Tabs, Typography } from "#material-ui/core";
import { makeStyles } from "#material-ui/core/styles";
import Product from "../components/Product";
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 p={3}>
<Typography>{children}</Typography>
</Box>
)}
</div>
);
}
function a11yProps(index) {
return {
id: `vertical-tab-${index}`,
"aria-controls": `vertical-tabpanel-${index}`,
};
}
const useStyles = makeStyles((theme) => ({
root: {
flexGrow: 1,
backgroundColor: theme.palette.background.paper,
display: "flex",
height: 500,
},
tabs: {
borderRight: `1px solid ${theme.palette.divider}`,
},
productsContainer: {
paddingTop: "20px",
paddingLeft: "50px",
paddingRight: "50px",
margin: "auto",
},
}));
const HomeScreen = () => {
const [value, setValue] = React.useState(0);
const handleChange = (event, newValue) => {
setValue(newValue);
};
//UI
const classes = useStyles();
return (
<React.Fragment>
<div className={classes.root}>
<Tabs
orientation="vertical"
variant="scrollable"
value={value}
onChange={handleChange}
aria-label="Vertical tabs example"
className={classes.tabs}
>
<Tab label="All Items" {...a11yProps(0)} />
<Tab label="Hand" {...a11yProps(1)} />
<Tab label="Skin" {...a11yProps(2)} />
<Tab label="Face" {...a11yProps(3)} />
<Tab label="Body" {...a11yProps(4)} />
<Tab label="Fragrance" {...a11yProps(5)} />
<Tab label="Home" {...a11yProps(6)} />
</Tabs>
<TabPanel value={value} index={0}>
<Grid container spacing={4} className={classes.productsContainer}>
{products.map((product) => (
<Grid item xs={12} sm={10} md={6} lg={4} key={product._id}>
<Product product={product} />
</Grid>
))}
</Grid>
</TabPanel>
<TabPanel value={value} index={1}>
Item Two
</TabPanel>
<TabPanel value={value} index={2}>
Item Three
</TabPanel>
<TabPanel value={value} index={3}>
Item Four
</TabPanel>
<TabPanel value={value} index={4}>
Item Five
</TabPanel>
<TabPanel value={value} index={5}>
Item Six
</TabPanel>
<TabPanel value={value} index={6}>
Item Seven
</TabPanel>
</div>
</React.Fragment>
);
};
export default HomeScreen;
Related
I need to change the thickness of label inside a tab using MUI 5.
Here are what I tried:
interface TabPanelProps {
children?: React.ReactNode;
index: number;
value: number;
}
function TabPanel(props: TabPanelProps) {
const { children, value, index, ...other } = props;
return (
<div
role="tabpanel"
hidden={value !== index}
id={`simple-tabpanel-${index}`}
aria-labelledby={`simple-tab-${index}`}
{...other}
>
{value === index && (
<Box sx={{ p: 3 }}>
<Typography>{children}</Typography>
</Box>
)}
</div>
);
}
function a11yProps(index: number) {
return {
id: `simple-tab-${index}`,
'aria-controls': `simple-tabpanel-${index}`,
};
}
export default function UsersGroupsManagement() {
const [value, setValue] = React.useState(0);
const handleChange = (event: React.SyntheticEvent, newValue: number) => {
setValue(newValue);
};
const StyledTab = styled(Tab)<TabProps>(({theme}) => ({
'& .MuiButtonBase-root-MuiTab-root': {
fontWeight: 'bold'
}
}));
const styledLabel = styled('label')({
color: 'darkslategray',
backgroundColor: 'aliceblue',
padding: 8,
borderRadius: 4,
});
return (
<Box sx={styles.userAccounts}>
<Box sx={styles.tabbox}>
<Tabs value={value} onChange={handleChange} aria-label="User Management Tabs" >
<Tab label="ADD NEW USER" {...a11yProps(0)} sx={{
'& .MuiButtonBase-root-MuiTab-root': {
color: 'black',
backgroundColor: 'red',
fontWeight: 'bold'
}
}}/>
<Tab label="MANAGE USERS" {...a11yProps(1)} sx={{
'& .MuiButtonBase-root-MuiTab-root': {
fontWeight: 'bold'
}
}}/>
</Tabs>
</Box>
<TabPanel value={value} index={0}>
<AddNewUser />
</TabPanel>
<TabPanel value={value} index={1}>
Item Two
</TabPanel>
</Box>
);
}
I tried to create a StyledTab but didnt work.
I tried to create a styled label didnt work at all.
I tried to give css from sx props using but didnt work.
Can you please explain me how can I manage to make thicker labeled tabs in Material UI v5?
u can follow something like this..
<Tabs
sx={{
"& .MuiTabs-indicator": { backgroundColor: "#E86826" },
"& .MuiTab-root.Mui-selected": { color: "#E86826", fontWeight:"700" },
}}
value={value}
onChange={handleChange}
aria-label="nav tabs example"
centered
>
Just Edit the tabs and u work is done...hope it helps
I only want to show the text of the tab on selection.
This is from the MUI documentation. How can I only show labels on selection? I assume I can use the state below and translate it somehow, how on the selection the color appears with the element.
Please see the code where I have tried to establish. I am new to this framework. If anyone can provide tips let me know!
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}`,
};
}
//
const JobPostBuild = () => {
const [value, setValue] = React.useState(0);
const handleChange = (event, newValue) => {
setValue(newValue);
};
return (
<Box
sx={{ flexGrow: 1, bgcolor: 'gray', display: 'flex', height: 500 }}
>
<Tabs
orientation="vertical"
variant="scrollable"
centered
value={value}
onChange={handleChange}
sx={{ borderRight: 1, borderColor: 'divider' }}
>
<Tab icon={<WorkIcon/>} label={"Role"} {...a11yProps(0)} />
<Tab icon={<AccountBoxIcon/>} label="People" {...a11yProps(1)} />
<Tab icon={<ViewCompactIcon/>} label="Build" {...a11yProps(2)} />
<Tab icon={<PostAddIcon/>} label="Post" {...a11yProps(3)} />
</Tabs>
<TabPanel value={value} index={0}>
Role
</TabPanel>
<TabPanel value={value} index={1}>
People
</TabPanel>
<TabPanel value={value} index={2}>
Build
</TabPanel>
<TabPanel value={value} index={3}>
Post
</TabPanel>
</Box>
);
}
export default JobPostBuild
Happy to discuss this over Discord please let me know!
You can check the value of selected tab to set a condition for displaying tab label:
<Tab label={value === 0 ? "Role" : ""} {...a11yProps(0)} />
Demo
By default, text inside the wrapper is aligned center.
How can I modify the wrapper rule in
<span class="MuiTab-wrapper">Item One</span>
to make the tab text aligned left (like I did in the devtools, i.e. make the flex-direction to "row") ?
I tried "Specific variation for a one-time situation" using $ruleName in Material UI Customizing components documentation and in-line styling but to no avail.
Here's the sandbox link
(Note: I commented out the $ruleName on useStyles and just left the in-line styling. You cant try it yourself by commenting out and trying one option after another. None of the options work for me).
Below is one way to target the "wrapper" element within each of the tabs:
const useStyles = makeStyles((theme) => ({
tabs: {
"& .MuiTab-wrapper": {
flexDirection: "row",
justifyContent: "flex-start"
}
}
}));
Here's the entire code of my modified version of your sandbox:
import React from "react";
import PropTypes from "prop-types";
import { makeStyles } from "#material-ui/core/styles";
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";
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 p={3}>
<Typography>{children}</Typography>
</Box>
)}
</div>
);
}
TabPanel.propTypes = {
children: PropTypes.node,
index: PropTypes.any.isRequired,
value: PropTypes.any.isRequired
};
function a11yProps(index) {
return {
id: `vertical-tab-${index}`,
"aria-controls": `vertical-tabpanel-${index}`
};
}
const useStyles = makeStyles((theme) => ({
root: {
flexGrow: 1,
backgroundColor: theme.palette.background.paper,
display: "flex",
height: 224
},
tabs: {
borderRight: `1px solid ${theme.palette.divider}`,
"& .MuiTab-wrapper": {
flexDirection: "row",
justifyContent: "flex-start"
}
}
}));
export default function VerticalTabs() {
const classes = useStyles();
const [value, setValue] = React.useState(0);
const handleChange = (event, newValue) => {
setValue(newValue);
};
return (
<div className={classes.root}>
<Tabs
orientation="vertical"
variant="scrollable"
value={value}
onChange={handleChange}
aria-label="Vertical tabs example"
className={classes.tabs}
>
<Tab label="Item One" {...a11yProps(0)} />
<Tab label="Item Two" {...a11yProps(1)} />
<Tab label="Item Three" {...a11yProps(2)} />
<Tab label="Item Four" {...a11yProps(3)} />
<Tab label="Item Five" {...a11yProps(4)} />
<Tab label="Item Six" {...a11yProps(5)} />
<Tab label="Item Seven" {...a11yProps(6)} />
</Tabs>
<TabPanel value={value} index={0}>
Item One
</TabPanel>
<TabPanel value={value} index={1}>
Item Two
</TabPanel>
<TabPanel value={value} index={2}>
Item Three
</TabPanel>
<TabPanel value={value} index={3}>
Item Four
</TabPanel>
<TabPanel value={value} index={4}>
Item Five
</TabPanel>
<TabPanel value={value} index={5}>
Item Six
</TabPanel>
<TabPanel value={value} index={6}>
Item Seven
</TabPanel>
</div>
);
}
In my React application, I have a Navigation bar where in there are multiple Tabs, which are created with the use of Marerial UI's AppBar, Tabs and Tab component (in sequence), as below:
function associatedProps(index) {
return {
id: `nav-tab-${index}`,
'aria-controls': `nav-tabpanel-${index}`
};
}
function LinkTab(props) {
const history = useHistory();
const route = props.route;
console.log(props);
return (
<>
<Tab
component="a"
onClick={(event) => {
event.preventDefault();
history.push(route)
}}
{...props}
/>
</>
);
}
const useStyles = makeStyles((theme) => ({
root: {
flexGrow: 1,
backgroundColor: theme.palette.background.paper,
height: theme.navBarHeight
},
tabIndicator: {
backgroundColor: PRIMARY_RED.default
},
tabBar: {
top: '80px'
}
}));
export default function NavTabs() {
const classes = useStyles();
const [value, setValue] = React.useState(0);
const handleChange = (event, newValue) => {
setValue(newValue);
};
return (
<div className={classes.root}>
<AppBar position="fixed" className={classes.tabBar}>
<Tabs
variant=""
classes={{indicator: classes.tabIndicator}}
value={value}
onChange={handleChange}
aria-label="nav tabs example"
>
<LinkTab {...PRIMARY_NAVIGATION.MY_LIST} {...associatedProps(0)} />
<LinkTab {...PRIMARY_NAVIGATION.MY_REQUESTS} {...associatedProps(1)} />
<LinkTab {...PRIMARY_NAVIGATION.REPORT} {...associatedProps(2)} />
</Tabs>
</AppBar>
</div>
);
}
Now herein this setup I wanted my REPORT tab to be aligned right of the App Bar. I do not see any CSS Rule or Prop which in Documentation, which can help me here.
Please suggest how can I achieve this in current setup.
You should set a class for Tabs like this:
const useStyles = makeStyles((theme) => ({
tabs: {
'&:last-child': {
position: 'absolute',
right: '0'
}
}
}));
export default function NavTabs() {
...
return (
<div className={classes.root}>
<AppBar position="fixed" className={classes.tabBar}>
<Tabs
variant=""
classes={classes.tabs}
value={value}
onChange={handleChange}
aria-label="nav tabs example"
>
<LinkTab {...PRIMARY_NAVIGATION.MY_LIST} {...associatedProps(0)} />
<LinkTab {...PRIMARY_NAVIGATION.MY_REQUESTS} {...associatedProps(1)} />
<LinkTab {...PRIMARY_NAVIGATION.REPORT} {...associatedProps(2)} />
</Tabs>
</AppBar>
</div>
);
Tabs do not provide a property to align a specific item to the start or end. But you can leverage css to achieve your result.
Add a className to the item to be right aligned and define a marginLeft property on it
const useStyles = makeStyles((theme) => ({
root: {
flexGrow: 1,
backgroundColor: theme.palette.background.paper,
height: theme.navBarHeight
},
tabIndicator: {
backgroundColor: PRIMARY_RED.default
},
tabBar: {
top: '80px'
},
rightAlign: {
marginLeft: 'auto',
}
}));
export default function NavTabs() {
const classes = useStyles();
const [value, setValue] = React.useState(0);
const handleChange = (event, newValue) => {
setValue(newValue);
};
return (
<div className={classes.root}>
<AppBar position="fixed" className={classes.tabBar}>
<Tabs
variant=""
classes={{indicator: classes.tabIndicator}}
value={value}
onChange={handleChange}
aria-label="nav tabs example"
>
<LinkTab {...PRIMARY_NAVIGATION.MY_LIST} {...associatedProps(0)} />
<LinkTab {...PRIMARY_NAVIGATION.MY_REQUESTS} {...associatedProps(1)} />
<LinkTab {...PRIMARY_NAVIGATION.REPORT} {...associatedProps(2)} className={classes.rightAlign}/>
</Tabs>
</AppBar>
</div>
);
}
Sample working demo
I want to left-align the text of my list items. I also want to make all the icons the same size. The size of the envelope icon used with the Gmail list item. Currently, I have this:
How can I accomplish this?
import React from 'react';
import PropTypes from 'prop-types';
import { withStyles } from '#material-ui/core/styles';
import List from '#material-ui/core/List';
import ListItem from '#material-ui/core/ListItem';
import ListItemIcon from '#material-ui/core/ListItemIcon';
import ListItemText from '#material-ui/core/ListItemText';
import DraftsIcon from '#material-ui/icons/Drafts';
import { FontAwesomeIcon } from '#fortawesome/react-fontawesome';
import { faFacebook, faGoogle, faGooglePlus, faTwitter, faYoutube, } from '#fortawesome/free-brands-svg-icons';
const styles = theme => ({
root: {
width: '100%',
maxWidth: 360,
backgroundColor: theme.palette.background.paper,
},
container: {
width: '20px', // this does not work
}
});
function SimpleList(props) {
const { classes } = props;
return (
<div className={classes.root}>
<List component="nav">
<ListItem button>
<ListItemIcon className="container">
<FontAwesomeIcon icon={faGoogle} />
</ListItemIcon>
<ListItemText primary="Login with Google" />
</ListItem>
<ListItem button>
<ListItemIcon className="container">
<FontAwesomeIcon icon={faTwitter} />
</ListItemIcon>
<ListItemText primary="Login with Twitter" />
</ListItem>
<ListItem button>
<ListItemIcon className="container">
<DraftsIcon />
</ListItemIcon>
<ListItemText primary="Login with Gmail" />
</ListItem>
<ListItem button>
<ListItemIcon className="container">
<FontAwesomeIcon icon={faFacebook} />
</ListItemIcon>
<ListItemText primary="Login with Facebook" />
</ListItem>
<ListItem button>
<ListItemIcon className="container">
<FontAwesomeIcon icon={faYoutube} />
</ListItemIcon>
<ListItemText primary="Login with Youtube" />
</ListItem>
<ListItem button>
<ListItemIcon className="container">
<FontAwesomeIcon icon={faGooglePlus} />
</ListItemIcon>
<ListItemText primary="Login with Google Plus" />
</ListItem>
</List>
</div>
);
}
SimpleList.propTypes = {
classes: PropTypes.object.isRequired,
};
export default withStyles(styles)(SimpleList);
Using fontSize CSS on the FontAwesomeIcon and DraftsIcon should do the trick. You most likely will also need to override any default padding and margin on the icons.
...
const styles = theme => ({
root: {
width: '100%',
maxWidth: 360,
backgroundColor: theme.palette.background.paper,
},
faIcon: {
fontSize: 18,
// padding if needed (e.g., theme.spacing.unit * 2)
// margin if needed
},
muiIcon: {
fontSize: 18,
// padding if needed
// margin if needed
}
});
class SimpleList extends React.Component {
render() {
const { classes } = this.props;
const list = [
{
label: 'label 1',
icon: <FontAwesomeIcon className={classes.faIcon} icon={faTwitter} />
},
{
label: 'label 2',
icon: <DraftsIcon className={classes.muiIcon} />
}
];
return <div className={classes.root}>
<List component='nav'>
{
list.map((item, key) => (
<ListItem button>
<ListItemIcon>
{ item.icon }
</ListItemIcon>
<ListItemText primary={ item.label } />
</ListItem>
))
}
</List>
</div>;
}
}
SimpleList.propTypes = {
classes: PropTypes.object.isRequired,
};
export default withStyles(styles)(SimpleList);