material ui Tooltip distance from the anchor - reactjs

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>

Related

how to remove vertical line from the marerial ui permanent drawer

I'm trying to remove the vertical line from the permanent drawer of material-UI, any suggestion please.
Had the same problem, hopefully the Solution is not too late for you.
To remove the Border, simply add "& .MuiDrawer-paper": { borderWidth: 0 } as an entry to your sx property.
<Drawer
sx={{
width: drawerWidth,
flexShrink: 0,
'& .MuiDrawer-paper': {
width: drawerWidth,
boxSizing: 'border-box',
},
border:"none"
}}
variant="permanent"
anchor="left"
>
I was working on Mini variant drawer, and I added
border:"none"
in both drawerOpen and drawerClose, it works for me.
You can try the code above.
Take a look at overriding styles with withStyles HOC: https://material-ui.com/guides/typescript/#usage-of-withstyles
For a complete list of classes you can see: https://material-ui.com/api/drawer/
You want something like this:
const StyledDrawer = withStyles(theme => ({
// css classes overrides goes here
})(props => <Drawer {...props} />);
Target the PaperProps to remove the border or for background modifications.
<Drawer PaperProps={{style: {border: 'none'}}}>...</Drawer>
`

How do I add a hover selector to a style object?

I created a style object in react that I will pass through a style prop:
const iconStyle = {
color: "#464545",
fontSize: "24px",
margin: "20px",
transitionProperty: "color",
transitionDuration: "1s",
}
Any idea on how I could add a hover selector inside of it, because I've looked around and I still have no clue.
probably this pseudo selector will help.
const iconStyle = {
color: "#464545",
fontSize: "24px",
margin: "20px",
transitionProperty: "color",
transitionDuration: "1s",
"&:hover": {
background: "#efefef"
},
}
In React.js there is no such way hover.
You can accomplish your goal with these two states.
onMouseEnter={() => this.setState({hover: true})}
onMouseLeave={() => this.setState({hover: false})}
And you can use "hover" state(for example) to specify styles like
style = this.state.hover ? style1 : style2
Hope this helps you to understand!

react-select background color issues

Having a problem with using className prop.
What's happening for me is that only the parent div gets the class and the children divs don't. As a result, they end up having background color white instead of the override color.
<Select
className="games-dropdown-2"
defaultValue={colourOptions[0]}
name="color"
options={colourOptions}
/>
Below is the css class
.games-dropdown-2 {
background-color: #023950;
color: #FFFFFF;
padding-left: 15px;
width: 93%;
}
Another problem is that the child div seems to be inheriting border css from the grandparent div which is weird.
Attaching an image to give idea.
react-select-classname-issue
For v2 it's way easier to use style-in-JS in order to customize your select. So in your case you can try something like this:
const customStyles = {
control: (base, state) => ({
...base,
background: "#023950",
// match with the menu
borderRadius: state.isFocused ? "3px 3px 0 0" : 3,
// Overwrittes the different states of border
borderColor: state.isFocused ? "yellow" : "green",
// Removes weird border around container
boxShadow: state.isFocused ? null : null,
"&:hover": {
// Overwrittes the different states of border
borderColor: state.isFocused ? "red" : "blue"
}
}),
menu: base => ({
...base,
// override border radius to match the box
borderRadius: 0,
// kill the gap
marginTop: 0
}),
menuList: base => ({
...base,
// kill the white space on first and last option
padding: 0
})
};
<Select styles={customStyles} options={options} />
If you need to use thus select in different files I would recommend to create a custom component so you won't have to repeat the style everywhere.
By default the text will take the color define in your general CSS file.
Here the live example.
UPDATE
Following your request in comment I have updated the code above and here a new live example.
you can solve your background color issue like below and people have also faced some issue of z-index that also solved
const colourStyles = {
menuList: styles => ({
...styles,
background: 'papayawhip'
}),
option: (styles, {isFocused, isSelected}) => ({
...styles,
background: isFocused
? 'hsla(291, 64%, 42%, 0.5)'
: isSelected
? 'hsla(291, 64%, 42%, 1)'
: undefined,
zIndex: 1
}),
menu: base => ({
...base,
zIndex: 100
})
}
const options = [
{value: 'chocolate', label: 'Chocolate'},
{value: 'strawberry', label: 'Strawberry'},
]
<Select
// defaultValue={[colourOptions[2], colourOptions[3]]}
name="colors"
options={options}
className="basic-multi-select"
classNamePrefix="select"
styles={colourStyles}
/>

How can I disable multiline for autocomplete material-ui demo?

Country select of
autocomplete demo at material-ui
uses react-select and material-ui controls,
shows multiline text, select control changes it's dimensions when country doesn't fit in one line.
I see this behaviour at CodeSandbox when I decrease width of web browser.
How can I modify demo so that country will always fit in one line,
select control will not change it's dimensions?
TextField has props multiline, rows and rowsMax props that can be changed.
If that isn't what you need then you could add the following css to the text in the TextField so the text does not wrap:
overflow: hidden;
white-space: nowrap;
I managed this by mixing a few different things:
First create a class like so:
const useStyles = makeStyles((theme: Theme) =>
createStyles({
closed: {
flexWrap: "nowrap",
overflowX: "hidden",
},
// Add a linear gradient behind the buttons and over the Chips (if applies)
endAdornment: {
background:
"linear-gradient(90deg, rgba(255,255,255,0) 0%, rgba(255,255,255,.6) 22%, rgba(255,255,255,1) 60%)",
bottom: 0,
display: "flex",
alignItems: "center",
right: "0 !important",
paddingRight: 9,
paddingLeft: theme.spacing(2),
top: 0,
},
})
);
Then in your static function add this :
const onOpenChange = (open: boolean | null) => {
setIsOpen(open);
};
const inputStyle = clsx({
[classes.closed]: !isOpen, //only when isOpen === false
});
Finally on the Autocomplete component itself use:
classes={{ inputRoot: inputStyle, endAdornment: classes.endAdornment }}
onOpen={() => onOpenChange(true)}
onClose={() => onOpenChange(false)}
If you are wondering how to make each option be displayed in just one line with ellipsis, you can do the follow:
<Autocomplete
...
getOptionLabel={(option: any) => `${option.label} (${option.code})`}
renderOption={(option) => (
<React.Fragment>
<div style={{ textOverflow: 'ellipsis', overflow: "hidden", whiteSpace: "nowrap" }}>
{option.label} ({option.code})
</div>
</React.Fragment>
)}
...
/>
For the Country Demo example, you can check what I did here: https://codesandbox.io/s/autocomplete-with-ellipsis-i8hnw

react-select styling issues with style props

I wanted to use react-select and ran into a whole array of issues after I changed the page background color from white to custom. (The issues aren't so evident on the white background as on react-select's github page)
I'm doing the above through styles prop as the className prop wouldn't work properly.
Here is the styles prop.
const colourStyles = {
control: styles => ({ ...styles, backgroundColor: '#023950', color: 'white', border: 0 }),
option: (styles) => {
return {
backgroundColor: '#023950',
color: 'white'
};
},
singleValue: styles => ({ ...styles, color: 'white' }),
};
Here is a list of issues and if someone could help out on how to fix them. Please refer to attached image.
Notice the gap between the dropdown and the options (when you click on the dropdown to open the options)
If you see here, http://jedwatson.github.io/react-select/, there is no gap but you also can't see the source code. Clicking the source link gives a 404.
All demos here, https://react-select.com/styles, have this gap problem.
There is a white gap (within the options itself) at the top and bottom. This is different from the gap from the dropdown as mentioned in point 1. That gap is transparent showing what's behind. This one is white.
A long text resulted in options results in the whole options box having a weird whitespace issue. Is there a way to clip the text and turn it into ellipsis instead of making the options box wider and have horizontal scroll?
Related to the above problem. How to turn off horizontal scroll. Want text clipping instead.
Regarding the problem with using className prop, the class does get applied. However only to 1 of the topmost divs. It doesn't apply to the children div, which end up staying white in backgroundColor.
react-select-styling-issues
In the following live example you will find the answer to your different points.
The first 4 points you mentioned can be solved by editing the style-in-JS as following:
const customStyles = {
control: (base, state) => ({
...base,
background: "#023950",
// match with the menu
borderRadius: state.isFocused ? "3px 3px 0 0" : 3,
// Overwrittes the different states of border
borderColor: state.isFocused ? "yellow" : "green",
// Removes weird border around container
boxShadow: state.isFocused ? null : null,
"&:hover": {
// Overwrittes the different states of border
borderColor: state.isFocused ? "red" : "blue"
}
}),
menu: base => ({
...base,
// override border radius to match the box
borderRadius: 0,
// beautify the word cut by adding a dash see https://caniuse.com/#search=hyphens for the compatibility
hyphens: "auto",
// kill the gap
marginTop: 0,
textAlign: "left",
// prevent menu to scroll y
wordWrap: "break-word"
}),
menuList: base => ({
...base,
// kill the white space on first and last option
padding: 0
})
};
For the last one, as the select is supposed to be styled through JS using className props will only put a class on the outer container as mentioned here. If you really want you can still prefix the component with classNamePrefix but it won't really help you for styling.
you should try it
const colourStyles = {
menuList: styles => ({
...styles,
background: 'papayawhip'
}),
option: (styles, {isFocused, isSelected}) => ({
...styles,
background: isFocused
? 'hsla(291, 64%, 42%, 0.5)'
: isSelected
? 'hsla(291, 64%, 42%, 1)'
: undefined,
zIndex: 1
}),
menu: base => ({
...base,
zIndex: 100
})
}
const options = [
{value: 'chocolate', label: 'Chocolate'},
{value: 'strawberry', label: 'Strawberry'},
]
<Select
// defaultValue={[colourOptions[2], colourOptions[3]]}
name="colors"
options={options}
className="basic-multi-select"
classNamePrefix="select"
styles={colourStyles}
/>
This code solves my issue
const colourStyles = {
menuList: styles => ({
...styles,
background: 'papayawhip'
}),
option: (styles, {isFocused, isSelected}) => ({
...styles,
background: isFocused
? 'hsla(291, 64%, 42%, 0.5)'
: isSelected
? 'hsla(291, 64%, 42%, 1)'
: undefined,
zIndex: 1
}),
menu: base => ({
...base,
zIndex: 100
})
}
const options = [
{value: 'chocolate', label: 'Chocolate'},
{value: 'strawberry', label: 'Strawberry'},
]
<Select
// defaultValue={[colourOptions[2], colourOptions[3]]}
name="colors"
options={options}
className="basic-multi-select"
classNamePrefix="select"
styles={colourStyles}
/>
thanks..

Resources