custom styling for material UI tooltip arrow? - css

I would like to add a custom style for Material UI tooltip arrow but I can not set the border color and the background color.
This is the configuration I have - react:
const useStylesBootstrap = makeStyles(theme => ({
arrow: {
// color: '#E6E8ED',
border: '1px solid #E6E8ED',
},
tooltip: {
backgroundColor: theme.palette.common.white,
border: '1px solid #E6E8ED',
color: '#4A4A4A'
},
}));
This is what I want to achieve:
I want to apply a gray color in the triangle border and the background will be white.
On the arrow configuration, the border config will not work, it will apply a border color in the square that's housing the triangle. Without material UI, the issue could be solved using the pseudo :before and :after to achieve the desired output. I would like to know if there is a solution to this using material UI custom configuration. Not too familiar with Material UI, your help will be appreciated

You are right, You need to override &:before pseudoselector like this.
Here is the code sandbox project link
import React from "react";
import Button from "#material-ui/core/Button";
import Tooltip from "#material-ui/core/Tooltip";
import { makeStyles } from "#material-ui/core/styles";
const useStyles = makeStyles(theme => ({
arrow: {
"&:before": {
border: "1px solid #E6E8ED"
},
color: theme.palette.common.white
},
tooltip: {
backgroundColor: theme.palette.common.white,
border: "1px solid #E6E8ED",
color: "#4A4A4A"
}
}));
export default function ArrowTooltips() {
let classes = useStyles();
return (
<Tooltip
title="Add"
arrow
classes={{ arrow: classes.arrow, tooltip: classes.tooltip }}
>
<Button>Arrow</Button>
</Tooltip>
);
}

See tooltip css. Use arrow and &::before to target the arrow and apply your styles. (note the double :: there)
makeStyles - style
arrow: {
fontSize: 20,
color: "#4A4A4A",
"&::before": {
backgroundColor: "blue",
border: "2px solid red"
}
}
JSX
<Tooltip classes={{ arrow: classes.arrow }} title="Delete" arrow>
<IconButton aria-label="delete">
<DeleteIcon />
</IconButton>
</Tooltip>
Working demo

FYI on material ui 5 makestyles is deprecated.
Because tooltip is in portal you cannot style it directly
const StyledTooltip = styled<typeof Tooltip>(({ className, ...props }) => (
<Tooltip {...props} classes={{ popper: className }} />
))``;
then in reder function you can use sx, by setting popper you can access child props via sx
<StyledTooltip
open
arrow
sx={{
'& .MuiTooltip-arrow': {
background: 'red',
},
}}
/>

Using the official MUI customization examples:
https://mui.com/material-ui/react-tooltip/#customization
const LightTooltip = styled(({ className, ...props }: TooltipProps) => (
<Tooltip {...props} classes={{ popper: className }} />
))(({ theme }) => ({
[`& .${tooltipClasses.arrow}`]: {
color: theme.palette.common.white,
"&::before": {
backgroundColor: theme.palette.common.white,
border: "1px solid #999"
}
},
[`& .${tooltipClasses.tooltip}`]: {
backgroundColor: theme.palette.common.white,
color: 'rgba(0, 0, 0, 0.87)',
boxShadow: theme.shadows[1],
fontSize: 11,
},
}));

We can do a custom styling in the following way
import Tooltip from '#material-ui/core/Tooltip'
import { withStyles } from '#material-ui/core/styles'
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: {
margin: '4px 0',
},
}))(Tooltip)
<HtmlTooltip
title={
<React.Fragment>
<Typography color="inherit">Tooltip with HTML</Typography>
<em>{"And here's"}</em> <b>{'some'}</b> <u>{'amazing content'}</u>.{' '}
{"It's very engaging. Right?"}
</React.Fragment>
}
>
<Button>HTML</Button>
</HtmlTooltip>

Related

Styling the DatePicker from MUI

I'm using a DatePicker component from Mui Lab and I am trying to style the Calendar component by adding some border or background color. I used the PaperProps prop for DatePicker but it's not styling it. Trying to understand why I cant just use an SX prop for it
this is the calendar where i want to add a border to
import PropTypes from 'prop-types';
import { TextField } from '#material-ui/core';
import { alpha } from '#material-ui/core/styles';
import DatePicker from '#material-ui/lab/DatePicker';
import { AppBorderStyle } from '../theme';
export const DateField = (props) => {
const {
error,
fullWidth,
helperText,
label,
onChange,
onBlur,
placeholder,
disabled,
value,
name,
...other
} = props;
return (
<DatePicker
PopperProps={{
sx: {
'& .MuiPaper-root': {
backgroundColor: 'red',
border: '1px solid black',
}
}
}}
onChange={onChange}
renderInput={({ InputProps, ...rest }) => (
<TextField
{...rest}
disabled={disabled}
onBlur={onBlur}
name={name}
error={error}
fullWidth={fullWidth}
helperText={helperText}
label={label}
placeholder={placeholder}
sx={{
'& .MuiFilledInput-root': {
backgroundColor: 'background.paper',
borderRadius: 1,
border: AppBorderStyle,
px: 1.5,
py: 0.75,
transition: (theme) => theme.transitions.create([
'border-color',
]),
'&:hover': {
backgroundColor: 'background.paper'
},
'&.Mui-focused': {
backgroundColor: 'background.paper',
boxShadow: (theme) => `${alpha(theme.palette.primary.main,
0.25)} 0 0 0 0.2rem`
},
'& .MuiFilledInput-input': {
fontSize: 14,
height: 'unset',
lineHeight: 1.6,
p: 0
},
'&.Mui-disabled': {
backgroundColor: 'action.disabledBackground',
boxShadow: 'none',
borderColor: alpha('#D6DBE1', 0.5)
}
}
}}
variant="filled"
InputProps={{
disableUnderline: true,
...InputProps
}}
InputLabelProps={{
shrink: true,
sx: {
color: 'text.primary',
fontSize: 14,
fontWeight: 500,
mb: 0.5,
position: 'relative',
transform: 'none'
}
}}
/>
)}
value={value}
{...other}
/>
);
};
DateField.defaultProps = {
disabled: false,
};
DateField.propTypes = {
disabled: PropTypes.bool,
error: PropTypes.bool,
fullWidth: PropTypes.bool,
helperText: PropTypes.string,
label: PropTypes.string,
name: PropTypes.string,
onChange: PropTypes.func.isRequired,
onBlur: PropTypes.func.isRequired,
placeholder: PropTypes.string,
value: PropTypes.instanceOf(Date)
};
I noticed you're using depecrated version of mui as you can check here. For newer versions of material UI components, we import material components from #mui and not from #material-ui.
I'm not sure if the classes are the same in your version or not. But the issue for your case looks like you are targeting the wrong class to add a border. You need to target MuiPickersPopper-root class to change the border.
PopperProps={{
sx: {'&.MuiPickersPopper-root': {border: '4px solid red'},},
}}
I created a solution of DatePicker with the border here. Cheers!

Conditionally applying css not working in React JS using Typescript

I have the following code whereas onclick I should make the Box stay highlighted with the black border.
interface BigButtonProps {
onClick(): void;
Title: string;
Description?: string;
startIcon?: React.ElementType;
}
const BigButton: FC<BigButtonProps> = (props: BigButtonProps, { active }) => {
const [isClicked, setClicked] = useState(false);
const clickMe = () => {
setClicked(!isClicked);
console.log("say hello");
};
const SvgIconStyles: CSS.Properties = {
display: "block",
};
const BoxStyles: CSS.Properties = {
border: "1.5px solid black",
};
const BoxStylesActive: CSS.Properties = {
border: "1.5px solid black",
};
return (
<Box
sx={{
height: {
xs: "45px",
md: "100px",
},
width: {
xs: "45px",
md: "300px",
},
borderRadius: "10px",
boxShadow: "0 2px 3px 2px rgba(0, 0, 0, .125)",
display: "flex",
alignItems: "center",
justifyContent: "center",
flexDirection: "column",
":hover": {
border: "1.5px solid blue",
},
}}
className={classNames("BoxStyles", { BoxStylesActive: isClicked })}
onClick={() => {
clickMe();
}}
>
<Typography variant="h1">{props.Title}</Typography>
<Typography variant="subtitle1">{props.Description}</Typography>
<SvgIcon
component={CheckCircleIcon}
sx={{
display: "block",
}}
/>
</Box>
);
};
export default BigButton;
When I click on the button it should change the border color to solid black. When I do CSS active it does change on click but doesn't remain changed to black. So I have to apply CSS conditionally so I did create the CSS methods with the property type CSS.Properties; I'm using typescript and this is a react component I'm working on with. I'm not really sure what am I doing wrong here?
You can try something like
<Box styles={isClicked ? BoxStylesActive : BoxStyles}>
// ...
Notice that BoxStylesActive and BoxStyles are the same in your pasted code. So don't be surprised if you see no changes.
<Box sx={{border: isClicked ? "1.5px solid black" : none}}>
// ...
This can be used alternatively.
You are mixing sx prop and styles here. Also your BoxStylesActive is an object and no css class. So using classNames() won't have an effect on it.

Changing underline style Link

I would like to change the underline style while hovering. To be more specific what I am trying to do is to change the color and the size of the underlined link.
const useStyles = makeStyles(theme => ({
button: {
marginLeft: theme.spacing(2),
},
}));
<MaterialLink
component="button"
aria-owns={anchorEl ? 'mouse-over-popover' : undefined}
onMouseEnter={handlePopperOpen}
onClick={handlePopperOpen}
color="inherit"
>
<Typography variant="subtitle1" color="inherit" >Buisness Services</Typography>
</MaterialLink>
Could anyone guide me on how can I customize the underline while hovering?
Example:
This is what I was looking for:
const theme = createMuiTheme({
overrides: {
MuiLink: {
button: {
"&:hover": {
borderBottom: '2px solid #3F51B5'
}
},
}
}
});

How to override default MaterialUI styles with React?

I canĀ“t style the Outline Select component with the properties I want when using Material UI with react, how can override default styles?
I have used withStyles but I can't achieve the expected look and feel.
For example if I change the border using a custom Input in the Select, then the Label doesn't work as expected, the border and the label touch instead of the label like floating.
import { createStyles, makeStyles, withStyles } from '#material-ui/core/styles';
import OutlinedInput from '#material-ui/core/OutlinedInput';
import InputLabel from '#material-ui/core/InputLabel';
import MenuItem from '#material-ui/core/MenuItem';
import FormControl from '#material-ui/core/FormControl';
import Select from '#material-ui/core/Select';
export const StyledSelect = ({ name, value, onChange, items }) => {
const classes = useStyles();
const inputLabel = React.useRef<HTMLLabelElement>(null);
const [labelWidth, setLabelWidth] = React.useState(0);
React.useEffect(() => {
setLabelWidth(inputLabel.current!.offsetWidth);
}, []);
return (
<FormControl variant="outlined" />
<InputLabel
ref={inputLabel}
htmlFor={name}
>
{name}
</InputLabel>
<Select
value={value || ''}
onChange={onChange}
input={<CustomInput labelWidth={labelWidth} />}
>
{items.map(item => {
return (
<MenuItem key={item.key} value={item}>
{item.label}
</MenuItem>
);
})}
</Select>
</FormControl>
);
};
const CustomInput = withStyles(theme => ({
root: {
'label + &': {
/* marginTop: theme.spacing(3), */
},
},
/* label: {
width: '',
}, */
input: {
'borderRadius': 4,
'position': 'relative',
/* 'backgroundColor': theme.palette.background.paper, */
'border': '2px solid #ced4da',
/* 'fontSize': 16, */
/* 'transition': theme.transitions.create(['border-color', 'box-shadow']), */
// Use the system font instead of the default Roboto font.
'fontFamily': [
'-apple-system',
'BlinkMacSystemFont',
'"Segoe UI"',
'Roboto',
'"Helvetica Neue"',
'Arial',
'sans-serif',
'"Apple Color Emoji"',
'"Segoe UI Emoji"',
'"Segoe UI Symbol"',
].join(','),
'&:hover': {
border: '2px solid red',
borderRadius: 4,
},
'&:focus': {
border: '2px solid #ced4da',
borderRadius: 4,
borderRadius: 4,
borderColor: "#80bdff",
boxShadow: "0 0 0 0.2rem rgba(0,123,255,.25)"
},
},
}))(OutlinedInput);
I expect to style only what I need and don't break the functionality of the OutlineSelect component.
When you click an input field in material UI the class names is changed and a different style is applied to the label field.
More specifically the class .MuiInputLabel-shrink is added to the label element. If you want to target this styling, you must reference this class in your withStyles()
See the imput-label API here:
https://material-ui.com/api/input-label/#main-content

How to disable the hover effect of material-ui button inside of a styled component

I added the css hover property to disable the button's hover effect, but it seems not work for my case, how should I fix this?
import Button from 'material-ui/Button'
import styled from 'styled-components'
const StyledButton = styled(Button)`
&:hover {
background: none;
}
`
export const SubmitButton = ({ onClick }) => {
return (
<StyledButton
variant="raised"
onClick={onClick}>
login
</StyledButton>
)
}
You can solve this problem by adding an inline style
export const SubmitButton = ({ onClick }) => {
return (
<StyledButton
variant="raised"
onClick={onClick}
style={{ backgroundColor: 'transparent' }} >
login
</StyledButton>
)
}
Try setting it to the same color as the background:
root = {
backgroundColor: "#FFF"
"&:hover": {
//you want this to be the same as the backgroundColor above
backgroundColor: "#FFF"
}
}
this is solution for v5 if anyone needs it
<IconButton
disableElevation
disableRipple
size="small"
sx={{
ml: 1,
"&.MuiButtonBase-root:hover": {
bgcolor: "transparent"
}
}}
>
</IconButton>
You can try setting the background of the button as none
button: {
'&:hover': {
background: 'none',
},
}
If you used the origin Button component with className instead, you could have added disableRipple to the button like that.
<Button disableRipple>
You can just override it via a styled component:
const StyledButton = styled(Button)`
&:hover {
background-color: transparent;
}
`;
This should work
const StyledButton = styled(Button)`
&&.MuiButton-root {
&:hover {
background: none;
}
}
`

Resources