How to apply custom CSS in material table in react? - reactjs

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

Related

MaterialUI v5 -> How to style Autocomplete options

I'm trying to apply some basic styles to the options inside the Autocomplete component from MUI v5. I'm just trying to change the background color on hover, and based on whether or not it is selected. I've tried 2 approaches based on the documentation, using a theme, and applying the sx prop to Autocomplete.
Using Theme almost has me there, code below:
import { createTheme, ThemeProvider } from '#mui/material/styles';
const theme = createTheme({
components: {
MuiAutocomplete: {
styleOverrides: {
option: {
'&[aria-selected="true"]': {
backgroundColor: '#e3abed',
},
'&:hover': {
backgroundColor: '#9c27b0',
},
backgroundColor: '#fff',
},
},
},
},
})
I have the ThemeProvider wrapped around my entire app
and the component:
<Autocomplete
options={['1', '2', '3']}
renderInput={(params) => <TextField {...params} label="Priority" />}
onChange={(_e, val) => setPriority(val)}
/>
So, this almost works. However the [aria-selected="true"] styling is only being applied when I am also hovering over another option in the dropdown. Otherwise it's the default grey that comes with the component and I don't understand why.
The second path I have tried is to use the sx prop on the Autocomplete component. In the docs it says you can target child components by their class name: https://mui.com/material-ui/customization/how-to-customize/#overriding-styles-with-class-names
Here is my component:
<Autocomplete
options={['1', '2', '3']}
renderInput={(params) => <TextField {...params} label="Priority" />}
onChange={(_e, val) => setPriority(val)}
sx={{
'& .MuiAutocomplete-option': {
backgroundColor: '#000',
},
'& .Mui-focused': {
backgroundColor: 'red',
},
}}
open
/>
That doesn't appear to be having any effect. I've been working on this for almost 2 hours and can't seem to get to the finish line here. Any help would be greatly appreciated.
I had the same problem; turns out I just needed to explore the Autocomplete API docs' Props section a bit further. There are several customization possibilities if you don't want to deal with global theme customization:
The PaperComponent prop allows customization of "[t]he component used to render the body of the popup." Note that simply using sx on Autocomplete does not work here because (as #bnays-mhz pointed out) the PopperComponent that the PaperComponent is nested in lives outside the main DOM tree (for z-index/modal UX purposes).
The renderGroup prop allows overriding the rendering of option group headers.
The renderOption prop allows overriding the rendering of individual options.
function CustomPaper({ children }) {
return (
<Paper
sx={{
"& .MuiAutocomplete-listbox": {
"& .MuiAutocomplete-option[aria-selected='true']": {
bgcolor: "purple",
"&.Mui-focused": {
bgcolor: "purple",
}
}
},
"& .MuiAutocomplete-listbox .MuiAutocomplete-option.Mui-focused": {
bgcolor: "red",
}
}}
>
{children}
</Paper>
);
}
Following up on Lars' answer, here's an example using a custom Paper component. Just pass in the custom Paper component name to the PaperComponent prop on Autocomplete <Autocomplete PaperComponent={CustomPaper} {...blahBlahOtherProps} />. This way is nice if you don't want to override the theme for all Autocomplete components.
You can override Autocomplete options css by targeting class
'.MuiAutocomplete-popper'
You will have to apply css globally because this node is created outside the root element in DOM.
I too faced this issue and found a solution.
You Can try this to set the css for options, single option and while hovered (focused) in the Autocomplete using 'sx' prop
Easy Way to customize your AutoComplete component which can be used in Mui V5
<Autocomplete
limitTags={1}
disablePortal
id="simple-search"
value={select.region}
onChange={handleChange("region")}
options={region}
sx={{
width: { sm: "100%", md: 340 },
"& + .MuiAutocomplete-popper .MuiAutocomplete-option":
{
backgroundColor: "#363636",
},
"& + .MuiAutocomplete-popper .MuiAutocomplete-option[aria-selected='true']":
{
backgroundColor: "#4396e6",
},
"& + .MuiAutocomplete-popper .MuiAutocomplete-option[aria-selected ='true'] .Mui-focused":
{
backgroundColor: "#3878b4",
},
}}
disableCloseOnSelect
multiple
renderInput={(params) => (
<TextField {...params} label="Region" color="info" />
)}
/>

How could I change mui x-data-grid sorting icon and menu icon color

I see that there are filterIcon, menuIcon and menuIconButton properties, but I do not have any idea how to apply them.
<DataGrid
rows={rows}
columns={columns}
rowsPerPageOptions={rowsPerPage}
disableSelectionOnClick
// should be some stuff here
/>
I have tried this approach. First define the styles
const styles = theme => ({
activeSortIcon: {
opacity: 1,
color : 'blue',
},
inactiveSortIcon: {
opacity: 0.4,
color : 'green',
},
});
Then use these styles in DataGrid component according to your logic how to use it
<DataGrid
rows={rows}
columns={columns}
rowsPerPageOptions={rowsPerPage}
disableSelectionOnClick
classes={{
icon: ((orderBy === column.id) ? classes.activeSortIcon :
classes.inactiveSortIcon )
}}
// should be some stuff here
/>
You can add different icons in styles instead of colors using this approach. Hope this approach might be helpful. Please let me know if this worked.
Reference : How to change the style of sorting icon in Material UI table?
For those still interested in styling the MUI-data grid icons, you can also utilize a styled component vs. using classes.
const StyledDataGrid = styled(DataGrid)((theme) => ({
"& .MuiDataGrid-sortIcon": {
opacity: 1,
color: "white",
},
"& .MuiDataGrid-menuIconButton": {
opacity: 1,
color: "white"
},
}));
Now you return your styled component since we've declared the styles accordingly:
<StyledDataGrid
rows={x}
columns={columnDef}
autoHeight
...more stuff if you want...
/>
There you go! You don't need to declare classes or anything.
Also, the styled component allows you to style everything in the data grid with the proper referencing (MuiDataGrid-columnHeaders, MuiDataGrid-columnHeaderTitle, Mui-selected, etc.)
Feel free to take a look at this explanation on MUI styled components:
https://mui.com/system/styled/

Mega menu using Material UI

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;

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 change Material UI tab button width

Is there a way of changing the button's min-width property that's rendered inside a <Tab /> in Material UI?
There doesn't seem to be a property that allows that or I cannot find it.
And since I'm new to React, I'm not quite sure what's the proper way of overriding the property.
I've never used this library before, but according to the docs you can use the classes prop to add any custom styles.
In react we usually use the className property to add or overwrite styles for components, according to the material-ui docs, you can use classes which receives an object with the styles you need.
First you need to create the styles:
const styles = theme => ({
root: {
flexGrow: 1,
marginTop: theme.spacing.unit * 3,
backgroundColor: theme.palette.background.paper,
},
tabRoot: {
minWidth: 10,
},
});
The in the tab you use the classes prop like this:
<Tab label="X" classes={{ root: classes.tabRoot }} />
Here's an example: https://codesandbox.io/s/l52rw252rm
You can use classes prop to apply width to Tab component.
const style = {
root: {
minWidth: 500
}
}
<Tab classes={style.root} />
Check here for more details.
OR
You can also use inline-style like below
const style = {
minWidth: 500
}
<Tab style={style} />
OR
If you feel inline-styles are lil difficult then customize your components using muitheme. check here for more details.
See if you can override it by using withStyles HOC.
const styles = {
tab: {
width: 140px
}
}
export const MyTab = (props) => {
return (
<Tab className={props.classes.tab} label="Item One" />
);
}
export default withStyles(styles)(MyTab);
Please check this doc regarding overriding classes

Resources