I'm trying to achieve bigger tooltip arrow using Material UI v4. I saw workaround for react-tooltip library using css property border-width. Is there any workaround for MUI tooltip arrow?
You need to override two style classes.
If overriding popperArrow class, styles apply to the Popper component if arrow={true} and if overriding arrow class, styles apply to arrow element when overriding arrow class.
const useStyles = makeStyles({
popperArrow: arrowGenerator(),
arrow: {
width: 24,
height: 17, /* = width / sqrt(2) = (length of the hypotenuse) */,
}
});
export default function ArrowTooltips() {
const classes = useStyles();
return (
<Tooltip title="Add" arrow classes={classes}>
<Button>Arrow</Button>
</Tooltip>
);
}
Function arrowGenerator is defined to apply different styles based on the placement of the Tooltip.
function arrowGenerator() {
return {
'&[x-placement*="bottom"] $arrow': {
marginTop: -17
},
'&[x-placement*="top"] $arrow': {
marginBottom: "-0.71em"
},
'&[x-placement*="right"] $arrow': {
marginLeft: "-0.71em"
},
'&[x-placement*="left"] $arrow': {
marginRight: "-0.71em"
}
};
}
To have the best result you need to set margin values in this function according to the values you set for width and height when overriding arrow class.
Say you set placement="bottom" prop on your component, in '&[x-placement*="bottom"] $arrow': you need to set marginTop to the minus value of height you set for your arrow.
Reference: Tooltip file
Related
I need some help with this problem I'm having with Material-UI styled components
I'm trying to create a BottomNavigation bar on react using Material-UI v5. I want that the icon of the selected option in the bar shows a specific color, let's say red (#f00) and the not-selected icons show green (#00f), for this I'm using the styled function to generate a custom-themed component for BottomNavigationAction, following the guidelines on the documentation: styled(). The problem: For the selected button, the icon is not grabbing the correct color and is showing the default one. At this point I'm not sure if I'm using the styled function wrong or is something super obvious I'm not seeing. Thanks in advance for any advice!
PS: I don't have enough reputation to post the image directly, sorry for that
The BottomNavigation is defined as follows:
const BottomNav = () => {
return(
<BottomNavigation
showLabels
value={value}
onChange={(event, newValue) => {setValue(newValue)}}
>
<TabBarButton
id='Home'
label='Home'
icon= {home_icon? <AiFillHome size = "30" />: <AiOutlineHome size='30'/> }
onClick={
(value)=>{
iconHandler(value.currentTarget.id)
}
}
/>
<TabBarButton
id='Documentos'
label='Documentos'
icon= {documentos_icon? <RiEditBoxFill size='30'/>: <RiEditBoxLine size='30'/>}
onClick={
(value) =>
iconHandler(value.currentTarget.id)
}
}
/>
</BottomNavigation>
);
}
To define TabBarButton I firstly tried defining the component like this:
import {BottomNavigation, BottomNavigationAction} from "#mui/material";
import { styled} from '#mui/system';
// Styled BottomNavigationAction
const TabBarButton = styled(BottomNavigationAction)({
root: {
color: '#f00',
},
selected: {
color: '#0f0',
}
});
But the rule names: root and selected didn't work, resulting in the default colors being applied:
first-try-bottom-navigation-image
So I changed them to the Global Class instead : BottomNavigationAction CSS :
// Styled BottomNavigationAction
const TabBarButton = styled(BottomNavigationAction)({
color: '#0f0',
'.Mui-selected':{
color: '#f00',
}
});
Which worked with the not-selected icon and the labels:
second-try-bottom-navigation-image
But the selected icon 'Home' is still using the default colors, I tried using a variation of the answer provided on this post Bottom Navigation Material UI Override
// Styled BottomNavigationAction
const TabBarButton = styled(BottomNavigationAction)({
color: '#0f0',
'.Mui-selected, svg':{
color: '#f00',
}
});
But this affects both icons resulting in :
third-try-bottom-navigation-image
I think TabBarButton need to add '&.Mui-selected' selector to have the styles attached to itself correctly, otherwise with '.Mui-selected' the rules only apply to nested elements:
Tested the example on: stackblitz
// Styled BottomNavigationAction
const TabBarButton = styled(BottomNavigationAction)({
color: 'royalblue',
'&.Mui-selected': {
color: 'crimson',
},
});
On hover, I want to modify the styling of separate classname within the MUI makestyles function. I have seen answers related to this with plain css but not with MUI and i'm unsure as to how to make it work. In my code, I want to make spacer of a paddingTop of 2px on hover of paddingStabilizer. Here is the example that currently isn't working:
const useStyles = makeStyles((theme) => ({
paddingStabilizer: {
'&:hover ~ spacer': {
paddingTop: '2px',
},
},
spacer: {
marginRight: '5px',
},
}
Thank you!
I am currently using 'createTheme' to customize the theme of my TextField input from Material UI.
To make the changes I am looking at the Material UI default theme on https://mui.com/customization/default-theme/ and making changes to the appropriate labels.
I want to change the default border of the TextField - the border that appears when there is no hover or focus on the TextField. The border is currently grey
Does anyone know which default theme label refers to that border? I can't seem to find it
use inline styling inside a textfield.
<TextField style={{ border:"1px solid color name", }}/>
I used it on main layout :
const useStyles = makeStyles(() => (
{
root: {
"& .css-h5voop-MuiInputBase-root-MuiInput-root:before": {
borderBottom:" 1px solid rgb(215 50 50 / 70%)",
},
}
})
it is a good way and you can use !important to be sure it works
const theme = createTheme({
components: {
MuiInputBase: {
styleOverrides: {
root: {
"&:before":{
borderBottom:"1px solid yellow ",}
},
},
},
},
})
I was implementing a table with TableRow component from material-ui, which has a property called "selected". Whenever "selected" is true, a pink background-color(from the default theme) is applied for it.
I was trying to change this default pink color, according to the docs, i chose to override the css classes like:
const styles = theme => ({
rowSelected: {
backgroundColor: theme.palette.grey[700]
}
})
class CustomTableRow extends React.Component {
// basic component logic
render() {
const {classes, className, style } = this.props;
<TableRow
key={key}
component="div"
selected={true}
hover={true}
className={className}
classes={{ selected: classes.rowSelected}}
style={style}
>
// some children
</TableRow>
}
export default withStyles(styles, { withTheme: true })(CustomTableRow);
But this didn't work, which was very confusing. Because i had succeeded to do the same thing somewhere else for a Drawer component with the same method above.
I debugged every css properties with Chrome Dev Tools. What i am suspecting most now is, the pink color applied on this component with this way below:
.MuiTableRow-root.Mui-selected, .MuiTableRow-root.Mui-selected:hover {
background-color: rgba(245, 0, 87, 0.16);
And my custom class style had lower precedence than this one, which was greyed out.
UPDATE1:
My project is too big, i don't know how to simplify it for codesandbox.io.
Maybe we can check the material-ui source code directly, TableRow Source Code.
What i was doing is to override this css declaration in root
'&$selected, &$selected:hover': {
backgroundColor: fade(theme.palette.secondary.main, theme.palette.action.selectedOpacity),
},
by passing in another selected declaration below. I realized it's because this &$selected, &$selected:hover is not normally css, even if i copy this into rowSelected, it doesn't work either.
UPDATE2:
I managed to override that backgroundColor, with '!important' keyword:
const styles = theme => ({
rowSelected: {
backgroundColor: theme.palette.grey[700] + " !important",
}
})
I don't know whether this is one ideal solution. This clearly shows the problem is about css classes precedence. So how to override that already defined backgroundColor in class root with class selected.
Some help please, thank you.
To provide specifity for selected class you can apply the $selected and $selected:hover classes to your overrides like below
const styles = theme => ({
rowSelected: {
"&$selected, &$selected:hover": {
backgroundColor: theme.palette.grey[800]
}
}
})
Sample demo
I'm aware that it's possible to override Ag Grid properties by editing the CSS itself, however I'm wondering if it's possible to use the functionalities built into react to do this instead. I'm relatively new to the two frameworks, so apologies if there's something I'm not understanding.
Ultimately, what I want to do is something like this:
styles.js
---------
const styles = (theme: Theme) =>
createStyles({
root: {
position: 'relative',
height: 'calc(100vh - 128px)',
},
agHeaderCellLabel: {
agHeaderCellText: {
writingMode: 'vertical-lr',
marginTop: '100px',
},
},
})
export default styles
GridComponent.tsx
-----------------
import styles from './styles'
...
return (
<Paper className={classes.root}>
<div
id="myGrid"
style={{
height: '100%',
width: '100%',
}}
className={`ag-theme-material ${classes.agHeaderCellLabel}`}
>
<AgGridReact
// listening for events
onGridReady={onGridReady}
onRowSelected={onRowSelected}
onCellClicked={onCellClicked}
onModelUpdated={calculateRowCount}
// Data
columnDefs={cDef}
defaultColDef={defaultColumnFormat}
suppressRowClickSelection={true}
groupSelectsChildren={true}
debug={true}
rowSelection="multiple"
// rowGroupPanelShow={this.state.rowGroupPanelShow}
enableRangeSelection={true}
pagination={true}
rowData={rows}
/>
</div>
</Paper>
)
...
export withStyles(styles)(GridComponent)
In this example I'm just trying to get the header text to be displayed vertically.
I've inherited this project, and I've noticed that all of the styling has been done in this method, as there are no custom css files lying around, so I'm trying to stick with that convention of a styles file alongside the component.
Is this possible, and if so,
I ran into this same situation, and came up with the following solution. Although not necessarily ideal, it allows you to continue with the desired convention.
styles.js
---------
const styles = (theme: Theme) =>
createStyles({
root: {
position: 'relative',
height: 'calc(100vh - 128px)',
},
//Apply changes to agGrid material HeaderRoot
myClassAppliedToGrid: {
'& .ag-header[ref="headerRoot"]':{
writingMode: 'vertical-lr',
marginTop: '100px',
}
}
//OR
//Apply Changes to agGrid material header row
myClassAppliedToGrid: {
'& .ag-header-row':{
writingMode: 'vertical-lr',
marginTop: '100px',
}
}
})
export default styles
The key idea is using the & SASS syntax to "reach into" agGrid and make more specific CSS classes so you can override them. (see https://css-tricks.com/the-sass-ampersand/ for more info)
The key pieces of info are:
.parent {
& .child {}
}
turns into
.parent .child {}
and
.some-class {
&.another-class {}
}
turns into
.some-class.another-class { }
Using this sytanx, you should be able to create CSS classes that you can apply to your grid, columns, rows, etc that will properly override the material ag-grid theme.
Here is another example, but this class gets applied to a cell using agGrid cellStyleRules when a row is dragged over it, rather than applying the class to the grid as a whole. This way it only effects cells that have a row drag occuring over them:
rowDraggedOverCellsTopEdge: {
'&.ag-cell': {
borderTopColor: theme.palette.gray[50],
borderTopWidth: 8,
backgroundColor: fade(theme.palette.gray[50], 0.3)
}
},
Finally, one thing I did not do but would reccommend investigating is looking into agGrid's theme overriding, especially if you are on version 23+
https://www.ag-grid.com/javascript-grid-themes-provided/#customising-themes
It might be a good idea to get your base overrides to the theme done this way if you expect a consistent look and feel of your grids throughout the application.
Cheers!