I'm working on menu component storybook where i have mapped icon & text , problem is i have horizontal divider in between , how do i Map it with icons & text.From below code i'm getting divider at the bottom of the Menu. I'm trying to achieve as it is in the image. In the storybook i have to map few menu variants as in mui, for that i cannot hardcode divider, if there is any way i can manage it with Map or any other method. Thanks.
export const Menu= ({ icons }) => {
return (
<Paper sx={{ width: 320, maxWidth: '100%' }} >
<MenuList>
{icons.map((item) => (
<MenuItem>
<ListItemIcon fontSize="small">{item.icon}</ListItemIcon>
<ListItemText>{item.label}</ListItemText>
<Typography variant="body2" color="text.secondary">{item.typography}</Typography>
</MenuItem>
))}
<Divider /> /* how do i map this */
</MenuList>
</Paper >
);
}
Stories.js
icons: [
{ icon: <ContentCut fontSize="small" />, typography: "⌘X", label: "Cut" },
{ icon: <ContentCopy fontSize="small" />, typography: "⌘C", label: "Copy" },
]
Answer:
If you want the divider to be just one then don't map over it . thats the purpose of the .map() method.
and To Acheive the required results i just removed <Menu></Menu> Component and Just Kept the <Papper></Papper> Component
Notes :
In terms of how to Map the Divider with the below example ,you can just wrap it in a empty react fragment<></> and map over the <MenuItem></MenuItem> .
Only issue is that youll get an error in your key props which will say its not unique it can be fixed by assigning index key like the example below and wrap the <MenuItem></MenuItem> Component in It. However thats not best practice ,
<React.Fragment></React.Fragment> Is better practice according to Keyed Fragment React 18 Docs to add a key prop However that's giving a New Error in MUI.
Thats not an issue since were mapping over the MenuItem Component , However if we use for example in #Nathan Comments <React.Fragment key={index}></React.Fragment> or my previous answer to use <></> we would be mapping over the React.Fragment Itself or the empty fragment and would get a new error MUI: The Menu component doesn't accept a Fragment as a child. Uncomment the Examples in the Sandbox Check the sandbox console.
Check Code Code SandBox
Solution
export const MenuIcon = ({ menuicons }) => {
return (
<Paper sx={{ width: 320, maxWidth: "100%" }}>
{menuicons.map((item, index) => (
<MenuItem key={item + index}>
<ListItemIcon fontSize="small">{item.icon}</ListItemIcon>
<ListItemText>{item.label}</ListItemText>
<Typography variant="body2" color="text.secondary">
{item.typography}
</Typography>
</MenuItem>
))}
<Divider />
<ListItemIcon fontSize="small">
ClipBoard <ContentCopyIcon fontSize="small" />
</ListItemIcon>
</Paper>
);
}
References
Empty Fragment Syntax React Docs
Stack OverFlow Question MUI Icons - as props
.map() method Syntax - MDN Docs
Related
I am using the MUI V5 DataGrid component in my App and I want to customize the Footer component on the datagrid component but can't find any docs on how to go about it. This is the current default footer:
I want to achieve something resembling this:
Is there a way to reorganize the individual components and customize the styling as such? Any help is highly appreciated.
this sample code you can use for a custom footer in data grid MUI v5
first, you write your pagination component with full logic when the client clicked on the page, like this :
const RoundedPagination = () => {
return (
<Stack spacing={2}>
<Pagination
shape="rounded" page={page + 1} onChange={handleChange} count={props.numberOfPages}
renderItem={(item) => (
<PaginationItem
sx={{
color: 'main.0',
}}
components={{previous: ArrowRightRoundedIcon, next: ArrowLeftRoundedIcon}}
{...item}
/>
)}
/>
</Stack>
)
}
then you use this component in data grid like this :
<Grid container item justifyContent={'center'} alignItems={'center'} md={12}>
<DataGrid
page={page}
rows={props.dataGridValue.ROW}
columns={props.dataGridValue.COLUMNS}
autoHeight
headerHeight={52}
rowsPerPageOptions={[10]}
disableColumnMenu
Pagination
hideFooterSelectedRowCount
components={{
Pagination: RoundedPagination,
}}
/>
</Grid>
hope you get your answer good luck ;)
I am trying to customize a Tooltip component by passing a custom component like the image.
At first time, I've used Popover once, but the main reason why I am going to use Tooltip is because of the arrow of Tooltip.
Basically, I am using React and MUI v5 running on TypeScript.
I built a custom Tooltip component like this.
<Tooltip
open={open}
arrow
placement={placement}
title={
<Box component="span" p={1} width={width}>
<IconButton size="small" onClick={onClose}>
<CloseIcon />
</IconButton>
<Box my={2} px={4}>
<Typography my={2}>
{message}
</Typography>
<FormControlLabel control={<Checkbox defaultChecked />} label="Don’t show again" />
</Box>
</Box>
}
{...rest}
>
{children}
</Tooltip>
It seems to be working, but it keeps saying an error message Tooltip title. Zero-length titles string are never displayed. 'title' is specified more than once, so this usage will be overwritten.ts(2783).
How can I resolve this issue, or should I use Popover rather than Tooltip component?
You need to move title prop after {...rest} parameters.
It looks like your rest paramaters already have title property inside, so basically you are overwriting your title with something else from rest parameters (at least typescript thinks that).
It is the same as:
const foo = { title: 'aaaa', sth: 'cccc' };
const bar = { title: 'bbbb', ...foo}
console.log(bar.title); // => 'aaaa'
If you open this code in some environment with typescript support, it will also show same error as yours, see
What you need to do is:
const foo = { title: 'aaaa', sth: 'cccc' };
const bar = { ...foo, title: 'bbbb' };
console.log(bar.title); // => 'bbbb'
I'm using material-table in my React App. I want to add left and right border to the table.
Here is the code for overriding Header and Body components.
components={{
Header: props => (
<Box ml={2} mr={2}>
<MTableHeader {...props}/>
</Box>
),
Body: props => (
<Box ml={2} mr={2}>
<MTableBody {...props}/>
</Box>
),
}}
When I try to add the borders, table header and body is distorted like this:
I also tried overriding the Table component with Paper but it looks like Paper is a wrapper to the actual table.
I want to make GitHub icon <GitHubIcon /> clickable and make it redirect to external url, looking in the api it doesn't seem to have link prop ... https://material-ui.com/api/svg-icon/
<div className={classes.root}>
<AppBar position="static">
<Toolbar>
<Typography variant="h6" className={classes.title}>
Made with <FavoriteIcon /> by
<GitHubIcon /> //Not working
</Typography>
</Toolbar>
</AppBar>
</div>
How is it done usually ??
Add this:
<GitHubIcon onClick={handlePageChange} />
and on the function definition:
const handlePageChange() {
window.location.href="pagelink"
}
or directly using an arrow function:
<GitHubIcon onClick={event => window.location.href='pagelink'} />
If looking to add effects on hover with material-ui styles:
How to add stlyes on Material-UI:
Import makeStyles:
import { makeStyles } from '#material-ui/core/styles';
Create the class:
const useStyles = makeStyles(theme => ({
clickableIcon: {
color: 'green',
'&:hover': {
color: 'yellow',
},
},
}));
Add the API call on your function declaration:
const classes = useStyles();
And add this class to your element:
<GitHubIcon
onClick={event => window.location.href='pagelink'}
className={classes.clickableIcon}
/>
You could also use directly a css file.
I'm not really happy with css styling over material-ui api, specially because this horrible CSS-in-JS syntaxi, but it works well, here you'll find some documentation: Material-ui Styles
I am trying to have a fixed header where on the right side should be tabs. The <Toolbar /> component is responsible for the responsiveness of the block but doesn't allow for stretched tabs so easily.
https://codesandbox.io/s/jv8v6vwqpv
The problem is that the Toolbar responsively changes its height and the Tabs and Tab component do not (Tabs sets a min-height of 48px in its root class, Tab sets a height in its root class).
Fortunately, the behavior Toolbar uses is available in a theme mixin, so you can create classes that also use this logic:
const styles = theme => ({
fullHeight: {
...theme.mixins.toolbar,
},
});
This will create a class that has the same responsive height logic used in the Toolbar component. Using withStyles, you can make this class accessible to your component:
import { withStyles } from "material-ui/styles";
// ...
export default withStyles(styles)(Header);
This will add a classes prop, which is an object containing a string attribute for each class defined in the object provided to withStyles. You can apply this to the Tabs component and each Tab component by overriding their root classes to ensure that they fill the AppBar:
render() {
const { classes } = this.props;
return (
<AppBar>
<Toolbar>
<Grid container alignItems="center" justify="space-between">
<Grid item>
<Typography color="inherit" variant="title">
BackTube
</Typography>
</Grid>
<Grid item>
<Tabs classes={{ root: classes.fullHeight }} onChange={this.changeTab} value={this.state.currentTab}>
<Tab classes={{ root: classes.fullHeight }} icon={<Magnify />} value="search" />
<Tab classes={{ root: classes.fullHeight }} icon={<FormatListBulleted />} value="lists" />
<Tab classes={{ root: classes.fullHeight }} icon={<Settings />} value="settings" />
</Tabs>
</Grid>
</Grid>
</Toolbar>
</AppBar>
);
Please note that the above solution was written for MUI v1 beta.
UPDATED 5/2022: The same thing can be accomplished in MUI 5, here is a codesandbox