Mega menu using Material UI - reactjs

I am trying to do something like this using react.js Material UI. I know we can use the menu component in Material UI But how can we have multiple columns and rows as shown in the image below?

Material-Ui allows you to target the <ul> generated by the <Menu> component via class MuiList-root. All we need to do is set it to display: flex and set the flex-direction to row.
Then all MenuItems we set inside divs will be their own columns.
<Menu
id="my-menu"
anchorEl={myAnchor}
open={Open}
onClose={handleClose}
sx={{
"& .MuiList-root": { // Target the <ul>
display: "flex",
flexDirection: "row",
},
}}
>
// Column One
<div style={{ display: "flex", flexDirection: "column" }}>
<MenuItem>Item #1</MenuItem>
</div>
// Column Two
<div style={{ display: "flex", flexDirection: "column" }}>
<MenuItem>Item #2</MenuItem>
</div>
</Menu>

To do this you use a pop-up dialog instead of a menu.
But to use it with a menu you could just create the view separately and pass it to the menu as a child.
Like.
custom_menu.js <- menu view code in this file
const CustomMenu = () => {
return (
<div>
{/* menu code here */}
</div>
}
export default CustomMenu;
import this js file to the js file which will have the definition of the menu.
x.js <- custom_menu.js used in this file
import CustomMenu from "..." // path/to/custom_menu.js
const X = () => {
return (
<MenuItem>
<CustomMenu />
</MenuItem>
)
}
export default X;

Related

Rendering a component within another component

I am trying to render components inside another component in the following way. Even when I try to render div elements within the component it's not being displayed.
const Sandbox = () => {
return (
<div>
<RenderHtml
Title="This is the title"
Description="This is the description">
<Example message="Hello World" />
<h1>Render somthing here</h1>
</RenderHtml>
</div>
);
};
export default Sandbox;
Below is the code for RenderHtml component
const MyCard = styled(Card)();
const RenderHtml = (props: any) => {
return (
<MyCard>
<div
style={{
display: "flex",
justifyContent: "space-between",
flexDirection: "column",
}}
>
<Typography variant="h1" sx={{ textAlign: "center" }}>
{props.Title}
</Typography>
<Typography variant="subtitle1" sx={{ textAlign: "center" }}>
{props.Description}
</Typography>
</div>
</MyCard>
);
};
export default RenderHtml;
I went through different examples and tutorials couldn't understand how I can render. If someone could help me out with this please.
You have to add {props.children} into the component if you want to render what's inside like this:
for Component1
const Test=(props)=>{
return <>
{props.children}
</>
}
for Component2
const Test2=(props)=>{
return <>
{props.children}
</>
}
for App.js
<Test>
<Test2>
asd
</Test2>
</Test>
When you render components inside another component, these get passed to the outer component as the prop children. For the inner components to have any effect, the outer component needs to do something with the children prop, which your RenderHtml component currently doesn't do.
For example, if you want the children to be rendered after the title but inside the div you can do this:
const RenderHtml = (props: any) => {
return (
<MyCard>
<div
style={{
display: "flex",
justifyContent: "space-between",
flexDirection: "column",
}}
>
<Typography variant="h1" sx={{ textAlign: "center" }}>
{props.Title}
</Typography>
<Typography variant="subtitle1" sx={{ textAlign: "center" }}>
{props.Description}
</Typography>
{props.children}
</div>
</MyCard>
);
};

Material-UI: How to center pagination button?

I tried to get Pagination from Material-UI
but I want to center the buttons of the arrow and number of page.
I tried to center by creating a <div style={{textAlign: "center"}}> but it doesn't work because it came all in one box.
there is any way to get inside the this component and make the numbers and button to get in the center?
If you're using TablePagination, you need to remove the spacer div which push the pagination content to the right and set the container justify-content to center:
import TablePagination, {
tablePaginationClasses
} from "#mui/material/TablePagination";
<TablePagination
sx={{
[`& .${tablePaginationClasses.spacer}`]: {
display: "none"
},
[`& .${tablePaginationClasses.toolbar}`]: {
justifyContent: "center"
}
}}
{...}
/>
If you're using the Pagination from DataGrid, just set the justify-content to center because the container is already flex:
import { makeStyles } from "#mui/styles";
import { paginationClasses } from "#mui/material/Pagination";
const useStyles = makeStyles({
root: {
[`& .${gridClasses.footerContainer}`]: {
justifyContent: "center"
}
}
});
<DataGrid pagination {...data} className={classes.root} />
Their Pagination component is using display: flex. Adding the following style rule should achieve what you're trying to do
.MuiPagination-ul { justify-content: center; }
using below code
<Box display="flex" justifyContent="center">
<Pagination ... />
</Box>
To center pagination, i suggest you wrap it inside a Grid System, then put it in the middle of two grid items with the flexGrow property equal to 1.
<Grid container>
<Grid item sx={{ flexGrow: 1 }}></Grid>
<Grid item>
<Pagination />
</Grid>
<Grid item sx={{ flexGrow: 1 }}></Grid>
</Grid>

Align text in AccordionSummary to the right?

I'm working with the Accordion component from Material-UI (https://material-ui.com/api/expansion-panel-summary/). It seems like by default, regardless of what I do, the text (specifically the word 'Filter' which appears in AccordionSummary) is aligned to the left. How can I change this so it aligned to the right?
<Accordion>
<AccordionSummary expandIcon={<FilterListIcon style={{color: 'white'}} />}
style={{backgroundColor: 'black', color: 'white', textAlign: "right"}}>
Filter
</AccordionSummary>
<AccordionDetails style={{backgroundColor: 'black', color: 'white'}}>
//Some details here
</AccordionDetails>
</Accordion>
The AccordionSummary component primarily uses flex containers so textAlign won't do that work for you. You can use justifyContent instead. You may target the content rule name to specifically target the content (i.e., your Filter text) of AccordionSummary
const useStyles = makeStyles({
customAccordionSummary: {
justifyContent: "flex-end"
}
})
function App() {
const classes = useStyles();
return (
<Accordion>
<AccordionSummary
classes={{ content: classes.customAccordionSummary }}
...

How can I remove line above the accordion of Material UI?

I'm trying to implement an Accordion component with Material UI.
The problem I'm facing is that a gray line is automatically inserted above the component although I prefer white background. How can I remove it? Here is demo code.Material UI accordion component demo
With the release of Material-UI v5.0.0-beta.0, custom styling has become much easier via use of the new sx prop.
The sx prop may be used on all Material-UI components as of v5. In our world, this has eliminated the need for hack-ish style overrides and custom classes.
Here's how to remove the "line above the accordion" with the sx={} prop.
return (
<Accordion
disableGutters
elevation={0}
sx={{
'&:before': {
display: 'none',
}
}}>
<AccordionSummary expandIcon={<ExpandMore/>}>
...your summary here...
</AccordionSummary>
<AccordionDetails sx={{ maxWidth: '480px' }}>
...your details here...
</AccordionDetails>
</Accordion>
);
Note that I've passed the sx prop to <AccordionDetails/> as well.
You must pass an object to sx so you're always going to have a double set of curly braces...
sx={{ borderBottom: '1px solid #dddddd', borderRadius: '4px' }}
To make gray line white you have to override the css classes of Accordion element.
The grey line comes from .MuiAccordion-root:before style. So at first change Accordion props adding classes props like:
...
<Accordion
elevation={0}
classes={{
root: classes.MuiAccordionroot
}}
>
...
And then on your useStyles add:
MuiAccordionroot: {
"&.MuiAccordion-root:before": {
backgroundColor: "white"
}
}
and grey line becames white. Here your code modified.
Try adding some css file and access this class MuiAccordion-root:before and change it's height to 0px. It's the pseudo-element that's showing the gray line above the Accordian.
// in my TS project i did it like this:
const useStyles = makeStyles((theme: Theme) =>
createStyles({
test: {
'&:before': {
display: 'none',
},
);
<Accordion
classes={{
root: classes.test,
}}
expanded={expanded}
>
To remove line between Accordion summary and Accordion details you just need to pass borderBottom='none !important'
const useStyles = makeStyles({
Summary:{
borderBottom:'none !important'
});
const AccordionComp=()=>{
const classes = useStyles();
return(
<Accordion>
<AccordionSummary className={classes.Summary}>
......
</AccordionSummary>
<AccordionDetails>......</AccordionDetails>
</Accordian>
)}
export default AccordionComp;
You can wrap the Accordion component in a div and it will remove the line. It comes from a :before property that I imagine is helpful when you have more than one in a row to visually divide.

How to apply custom CSS in material table in react?

Hi I am trying to apply custom CSS over material table but It is not working properly.
I tried to do that using makeStyles function in material UI but still it's not working. I want the sorting arrow right after the text. Right now sorting arrow is coming left to the text. I also want both arrow together up arrow and down arrow together.
I have created a function -
const useStylesTableSort = makeStyles({
root: {
flexDirection: "unset",
},
});
This is my material table code -
<MaterialTable
className={{useStylesTableSort.root}}
style={{ flexDirection: "unset" }}
title=""
/>
I want to add this function using className in material table but material table does not support className. style tag also not working. So how can I achieve this ? I want to change root css of MuiTableSortLabel. Any help would be appreciated.
You can override the Container component and add a className to the <Paper/>, this is the main container of the Material-table.
<MaterialTable
columns={[]}
data={data}
components={{
Container: (props) => <Paper className={classes.filterTable} {...props}/>
}}
/>
Another way is to use the Style property.
<MaterialTable
columns={[]}
data={data}
style={{
marginTop:'50px'
}}
/>
const styles = {
materialStyle: {
flexDirection: "unset"
}
}
};
function Table(props) {
return (
<MaterialTable
className={props.classes.materialStyle}
/>
);
}
export default withStyles(styles)(Table);
You can also refer on the this link: Add Styling on Material-UI

Resources