How to change Material UI tab button width - reactjs

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

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/

How to override Drawer in Material UI

In my component I need to override css parameter "overflow-y". This parameter is described in class .MuiDrawer-paper.
Usually to override css is piece of cake via makeStyles. But in this component has two divs. Parent container and daughter div. And when I set overrided class like:
const useStyles = makeStyles((theme) => ({
paper: {
overflowY: 'unset',
},
)};
...
className={classes.paper}
Parent div gets this class and it does not have any sense. Because I need to override daughter class.
I tried to do some thing like this:
className={{ paper: classes.paper }}
But in this case class wan't picked... What should I do?
The correct way to override material ui classes is to make use of classes prop on Drawer component instead of className.
Read more about overriding classes
const useStyles = makeStyles((theme) => ({
paper: {
overflowY: 'unset',
},
)};
...
<Drawer
classes={{
paper: classes.paper,
}}
anchor="left"
open={open}
/>
The top-voted answer in this thread contains legacy code (makeStyles). I was able to override CSS on a child element of a MUI component via the styled API (migration guide):
const StyledMUIComponent = styled(MUIComponentName)({
"& .child-class-to-target": {
overflowY: 'unset'
}
})
I have 2 options.
using !important
const useStyles = makeStyles((theme) => ({
paper: {
overflowY: 'unset !important',
},
)};
using styles property.
<Drawer style={{overflowY: 'unset'}} />
I prefer to use styles property.

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

Material-UI - Why should I use makeStyles instead of inline styles?

In Material-UI, there is the makeStyles function which can be used to get custom CSS-Styling.
Should I use it if I am not using a theme in that specific CSS?
For example:
import React from "react";
import { TextField, Paper, Button, Box } from "#material-ui/core";
const classes = {
paper: {
backgroundColor: "#eee",
marginLeft: "30%",
marginRight: "30%"
},
textField: {
backgroundColor: "#fff"
},
button: {
backgroundColor: "green",
marginLeft: 20
}
};
const Ohne = () => {
console.log(classes);
return (
<Paper style={classes.paper}>
<Box>
<TextField style={classes.textField} />
<Button style={classes.button}>abc</Button>
</Box>
</Paper>
);
};
export default Ohne;
The object was:
{
"paper": {
"backgroundColor": "#eee",
"marginLeft": "30%",
"marginRight": "30%"
},
"textField": {
"backgroundColor": "#fff"
},
"button": {
"backgroundColor": "green",
"marginLeft": 20
}
}
vs
import React from "react";
import { makeStyles } from "#material-ui/styles";
import { TextField, Paper, Button, Box } from "#material-ui/core";
const useStyles = makeStyles(theme => ({
paper: {
backgroundColor: "#eee",
marginLeft: "30%",
marginRight: "30%"
},
textField: {
backgroundColor: "#fff"
},
button: {
backgroundColor: "green",
marginLeft: 20
}
}));
const Mit = () => {
const classes = useStyles();
console.log(classes);
return (
<Paper className={classes.paper}>
<Box>
<TextField className={classes.textField} />
<Button className={classes.button}>abc</Button>
</Box>
</Paper>
);
};
export default Mit;
The object was:
{
"paper": "makeStyles-paper-85",
"textField": "makeStyles-textField-86",
"button": "makeStyles-button-87"
}
So there are 3 main points (that I see):
One way creates classes and references them, the other just uses the object as is.
In the first case an object is assigned to the style property which is inline and has a higher priority.
In the first example it is important to keep the const outside of the class, so the object is still created only once and won't trigger a rerender.
But the resulting component looks identical (in my Firefox).
My questions:
Can an example be constructed where these two approaches result in different controls?
Is there any performance aspect to it?
Any other differences?
There are a few scenarios where using CSS classes (e.g. via makeStyles or withStyles) is necessary:
If you want to use media queries in your CSS
If you want to target pseudo-classes (e.g. :hover)
If you are creating a reusable customization of one of the Material-UI components and want to customize some of the classes that are conditionally applied to the element based on props or some other context (e.g. if you want to customize the "error" look of an Input while leaving it up to the places where the custom component is used to specify the error prop either directly or via the FormControl context)
As far as performance concerns, I would expect inline styles to be faster for most use cases. Whether the difference is enough to matter would depend on a lot of specifics regarding your particular application. The team I work with uses makeStyles or withStyles for most of our styling.
Inline styles can result in a lot of duplicated CSS in the DOM if a particular component is rendered many times within the document (e.g. list items, table cells, etc.). One nice thing about always using classes is that you can change the CSS for the class in the browser's developer tools and see that change applied throughout all its usages in the document.

Resources