How to override Material-UI Popover styles? - reactjs

How can I override the default value of the max-height property for the Popover component?
I tried to add style={{'maxHeight': '365px'}}, but nothing is changed:
<Popover
style={{'maxHeight': '365px'}}
className='notif-popover'
open={this.state.notifOpen}
anchorEl={this.state.anchorEl}
anchorOrigin={{horizontal: 'left', vertical: 'bottom'}}
targetOrigin={{horizontal: 'left', vertical: 'top'}}
onRequestClose={this.handleRequestClose}
>

The only props that apply style are:
className string of classes and style object with styles.
Remember that these are applied to the root element (the Modal component).
Docs SourceCode (if you're using v1-beta). You can see in the sources that the remaining props are passed to the Modal component
const {
anchorEl,
anchorReference,
anchorPosition,
anchorOrigin,
children,
classes,
elevation,
getContentAnchorEl,
marginThreshold,
onEnter,
onEntering,
onEntered,
onExit,
onExiting,
onExited,
open,
PaperProps,
role,
transformOrigin,
transitionClasses,
transitionDuration,
...other
} = this.props;
<Modal show={open} BackdropInvisible {...other}>
You can see in the sources that MaterialUI uses the withStyles HoC from react-jss and has a styles object for the Paper component
export const styles = {
paper: {
position: 'absolute',
overflowY: 'auto',
overflowX: 'hidden',
// So we see the popover when it's empty.
// It's most likely on issue on userland.
minWidth: 16,
minHeight: 16,
maxWidth: 'calc(100vw - 32px)',
maxHeight: 'calc(100vh - 32px)'
maxHeight: 'calc(100vh - 32px)'
This is bound to a class paper and then passed to the classes prop and applied to the Paper component.
Solution:
Use the className prop on the root element with nested selector that targets the Paper component (inspect and see on which element it applies the class).
Example of possible selector (should definitely use a better one, inspect element)
.rootElement > * { max-height: '375px' }
and then you'd do <Popover className='rootElement' />

You should really override the style while building the theme...
createMuiTheme({
overrides: {
MuiTooltip: {
tooltip: {
fontSize: '1rem',
backgroundColor: '#000',
}
}
}
})

This CSS override seems to work for me:
.writeYourOwnClasHere {
.MuiPaper-root-6 {
padding: 30px;
color: pink;
}
}
Btw, it's an unbelievably crappy API.

Related

How to style Input in material ui

I am new to material ui.
I use fifth version.
<InputBase
ref={params.InputProps.ref}
inputProps={params.inputProps}
autoFocus
sx={{
...InputCSS,
}}
/>
const InputCSS = {
width: '100%',
textIndent: '17px',
py: '12px',
fontSize: '20px',
borderRadius: '3px',
border: '1.5px solid rgba(0, 0, 0, 0.4)',
'MuiInputBase-root': { // does not work
borderColor: 'red !important',
color: 'red !important',
},
'&:focus' : { // does not work
...
}
}
I could have used styled('input') and it works, I can set &:focus and it works but I can't type anything in the input.
I want to get rid of the initial border and set focus property.
How can I change the border for this class?
I know that in v5 we can style our components using variants or sx or styled.
What is the best advice for styling mui components? Because almost all the info in the internet uses outdated useStyle or makeStyles which doesn't work with react 18v.
sometimes I just struggle with components styling in mui
You have several ways to customize a Mui component, but my three favorite approaches are:
Styled utility
Sx prop
Custom global theme
So when should I use each of these approaches?
Styled utility
If you want to make a component reusable across your app, go with styled, if you had ever used styled components then styled will be very familiar to you, here is an example of how to use it:
import * as React from 'react';
import Slider, { SliderProps } from '#mui/material/Slider';
import { alpha, styled } from '#mui/material/styles';
// if you are using typescript, don't forget to pass the component props on styled
const SuccessSlider = styled(Slider)<SliderProps>(({ theme }) => ({
width: 300,
color: theme.palette.success.main,
// to override the styles of inner elements,
// you have to use the & selector followed by the class name.
'&.MuiSlider-thumb': {
'&:hover, &.Mui-focusVisible': {
boxShadow: `0px 0px 0px 8px ${alpha(theme.palette.success.main, 0.16)}`,
},
'&.Mui-active': {
boxShadow: `0px 0px 0px 14px ${alpha(theme.palette.success.main, 0.16)}`,
},
},
}));
export default function StyledCustomization() {
return <SuccessSlider defaultValue={30} />;
}
To make the component even more dynamically, you can define custom props as well, like width, color, border and so on, read the styled docs to know more about it.
Sx prop
If you want to make an one time off style in a single component, the easiest way is to use the sx prop, but be careful with this approach because it can lead to a lot of repetition in your code. Following the code you gave:
<InputBase
ref={params.InputProps.ref}
inputProps={params.inputProps}
autoFocus
sx={{
...InputCSS,
}}
/>
const InputCSS = {
width: '100%',
textIndent: '17px',
py: '12px',
fontSize: '20px',
borderRadius: '3px',
border: '1.5px solid rgba(0, 0, 0, 0.4)',
// you should pass the & selector followed by the class that you want to override
'&.MuiInputBase-root': {
// avoid the use of !important
borderColor: 'red',
color: 'red',
},
'&.MuiInputBase-root:focus': {
...
}
}
check it out on codeSandbox. Just a suggestion, depending on your case the component TextField could fit better as it comes with some good styles and you don't need to style it from scratch.
Side note:
Every mui component has an api doc with a css section where you can find all available classes to override, for instance, see the InputBase api docs, also read the docs about sx prop.
Custom theme
At last but not least, if you want to customize your whole app with custom palette, components, typography, breakpoints and so on, no doubt you should use a custom theme, as mui provides a powerful tool called createTheme to do so, what I like the most in custom theme is the possibility to make custom variants of the component, like so:
import * as React from "react";
import { createTheme, ThemeProvider } from "#mui/material/styles";
import Button from "#mui/material/Button";
import { red } from "#mui/material/colors";
// if you are using typescript, you must declare the module with the
// custom properties in order to get access of this property when using the component
declare module "#mui/material/Button" {
// define custom variants
interface ButtonPropsVariantOverrides {
dashed: true;
redVariant: true;
}
}
const defaultTheme = createTheme();
const theme = createTheme({
components: {
MuiButton: {
variants: [
{
// use the variant name defined earlier
props: { variant: "dashed" },
// set the styles for this variant
style: {
textTransform: "none",
border: `2px dashed ${defaultTheme.palette.primary.main}`,
color: defaultTheme.palette.primary.main
}
},
{
props: { variant: "redVariant" },
style: {
border: `2px solid ${red[300]}`,
color: red[600]
}
}
]
}
}
});
export default function GlobalThemeVariants() {
return (
// use the theme provider to get access of custom theme
// and variants within any child component
<ThemeProvider theme={theme}>
<Button variant="dashed" sx={{ m: 1 }}>
Dashed
</Button>
<Button variant="redVariant" color="secondary">
custom red variant
</Button>
</ThemeProvider>
);
}
See the example, also take a look at the custom theme docs. Hope I clarified the things a bit!

Mui Typography alignment based on breakpoints

Is there a way for me to change my Typography align property based on the pre-defined breakpoints?
For example:
<Typography
align={{ xs: 'left', sm: 'left', md: 'left', lg: 'right', xl: 'right' }}>
The following will cause my page to display nothing but white. I usually use that syntax to work with margins in the Box class and it works fine.
You can't set the Typography align attribute with an object.
As specified in the documentation for the Typography component, the align attribute can only be 'inherit' | 'left' | 'center' | 'right' | 'justify'.
Instead, you could use the withWidth HOC:
Sometimes you might want to change the React rendering tree based on the breakpoint value. We provide a withWidth() higher-order component for this use case.
withWidth injects a width property into your component that gives you access to the current breakpoint value. This allows you to render different props or content based on screen size.
function ResponsiveTypography({ width }) {
// This is equivalent to theme.breakpoints.down("md")
const isSmallScreen = /xs|sm|md/.test(width);
const typographyProps = {
align: isSmallScreen ? "left" : "right"
};
return (
<Typography {...typographyProps}>
Some text
</Typography>
);
}
export default withWidth()(ResponsiveTypography);
This seem to work for me, MUI v5:
import { useTheme } from '#mui/material/styles';
...
const theme = useTheme();
...
<Typography
sx={{
textAlign: 'center',
[theme.breakpoints.up('md')]: {
textAlign: 'left',
},
[theme.breakpoints.up('xl')]: {
textAlign: 'right',
},
[theme.breakpoints.between('sm', 'md')]: {
}
[theme.breakpoints.not('md')]: {
}
}}
>
Breakpoints API
https://mui.com/material-ui/customization/breakpoints/
With MUI v5, I found that sx prop has the ability to do breakpoints without importing the theme object (like in #atazmin's answer).
The breakpoints are mobile-first and get translated to min-width Media Queries. You can specify the starting value with xs and change it by breakpoint using lg and up.
<Typography
sx={{
textAlign: {
xs: 'left',
lg: 'right',
},
}}
>

Component link hover style to use hover

I use the react-router-dom to create my routes because this has use component Link in my menu, but I want to custom that component. I have customing with const and Work, but my hover does't work.
My code:
<Link className="ui-link" style={styles.menuStyle} to={'/home'}>
<MdStore size={25} color="#5f5f5f" />
<Opt>Consumidores</Opt>
</Link>
My CSS, but my hover does't work:
const styles = {
menuStyle: {
textDecoration: 'none',
display: 'flex',
alignItems: 'center',
padding: '10px',
borderRadius: '8px',
margin: '5px 0px',
'&:hover': {
backgroundColor: '#171717',
},
},
};
why do not use the className="ui-link" and create a style to class?
For example:
a.ui-link:hover {
backgroundColor: '#171717';
}
I'm not really sure if you can do it like that, You can do one of the following:
Use styled components there you can simply style your Link tag with
whichever styles you want with pure css code
Use mouseEnter, mouseLeave events
Style it the regular way you would

material ui Tooltip distance from the anchor

Is there a clear/easy way to control Tooltip's distance from the anchor element? The default positioning does not fit well for my case, the tooltip is too close to the anchor. I have checked all the props of it and PopperProps no visible option to do that.
You can customize the tooltip's margin using withStyles.
In my case (Material-UI 3), the tooltip was too far away from the anchor.
Here is what I needed :
const StyledTooltip = withStyles({
tooltipPlacementTop: {
margin: "4px 0",
},
})(Tooltip);
I targeted tooltipPlacementTop because it was the rule name when using the placement="top" prop.
You can find the adequate rule names in the Tooltip API documentation.
Last tip: I used the PopperProps={{ keepMounted: true }} prop to see in my navigator's inspector what CSS was applied to the tooltip.
Hope it helps.
For Material-UI V.5 it could be done like this:
<Tooltip
PopperProps={{
modifiers: [
{
name: "offset",
options: {
offset: [50, 0],
},
},
],
}}
.......
Follow up with Hugo's suggestion, since the tooltip position is absolute, instead of changing the margin I changed the anchor position by adjusting the properties right and top like so:
const StyledTooltip = withStyles({
tooltipPlacementTop: {
right: "1px",
top: "8px",
},
})(Tooltip);
It works as I expected. You can use left or right to adjust the tooltip horizontal position accordingly.
I was using material ui styled to adjust my tooltip properties. I used the normal theme which is available in the MUI documentation.
const LightTooltip = styled(({ className, ...props }) => (
<Tooltip {...props} classes={{ popper: className }} />))(({ theme }) => ({
[`& .${tooltipClasses.tooltip}`]: {
backgroundColor: theme.palette.common.white,
color: 'rgba(0, 0, 0, 0.87)',
boxShadow: theme.shadows[1],
fontSize: 11
},}));
I tried to adjust the position property with Mui styled, but it wasn't working.
I fixed it with my external style sheet.
.MuiTooltip-popper {
inset: -25px auto 0px auto;}
In Material-UI v4, you can add margin via style prop in the PopperProps.
<Tooltip
placement="bottom"
title="hello"
PopperProps={{ style: { marginTop: -12 } }}
>
<div>Some text</div>
</Tooltip>
I'm using Material-UI 4.x version and changed tooltip distance from the anchor using following style
const HtmlTooltip = withStyles(theme => ({
arrow: {
'&::before': {
color: 'white'
}
},
tooltip: {
backgroundColor: '#f5f5f9',
boxShadow: theme.shadows[8],
color: 'rgba(0, 0, 0, 0.87)',
fontSize: 14,
maxWidth: 800,
padding: 0,
},
tooltipPlacementTop: { // this part will change the distance
margin: '4px 0',
},
}))(Tooltip)
you can set it through the style prop
<Tooltip style={{ padding: '4px 0'}} > {children} </Tooltip>

Material UI stepper with React

I'm trying to figure out how use the Material UI v1 stepper in react, with my own font sizing.
The standard example imposes font sizing at this span class: MuiTypography-body1-99
I've tried adding fontSize properties to the label and MuiTypography classes in the const:
const styles = theme => ({
root: {
width: '80%',
marginLeft: '10%',
marginTop: '50px',
},
button: {
marginTop: theme.spacing.unit,
marginRight: theme.spacing.unit,
},
actionsContainer: {
marginBottom: theme.spacing.unit * 2,
},
resetContainer: {
padding: theme.spacing.unit * 3,
},
label: {
fontSize: '50%',
},
Typography: {
fontSize: '87%',
}
I can't add a class to the const styles with the name of the class in the UI theme, because the hyphen isn't recognised.
I can't add a fontSize attribute directly to the Typography and content elements on the page, (it gives an error saying fontSize is undefined).
<StepContent fontSize='120%'>
<Typography fontSize='120%'>{getStepContent(index)}</Typography>
How do you set a fontSize with the stepper?
if I understand your question correctly, you'd like to set the Stepper font-size so that the StepLabel or StepContent have a specific font-size.
This can be done by utilizing the style property that both the StepLabel and StepContent components have.
For example:
<Stepper>
<Step>
<StepLabel
style={{ fontSize: '150%', color: '#f00' }}
>
Create an ad
</StepLabel>
<StepContent
style={{ fontSize: '120%', color: 'hotpink' }}
>
<p>
For each ad campaign that you create, you can control how much
you're willing to spend on clicks and conversions, which networks
and geographical locations you want your ads to show on, and more.
</p>
</StepContent>
</Step>
</Stepper>
Hope that answers your question

Resources