Apply style to ButtonBase in a Tab component - css

I am trying to figure out Material UI style overriding with a nested component. Say I want to increase bottom border height on a active Tab. This border is applied by the underlying ButtonBase.
Here is the style definition:
const useStyles = makeStyles(theme => ({
root: {
// an example brutal overriding, not clean, I'd like a better approach for the button
"& .MuiSvgIcon-root": {
marginRight: "8px"
}
},
// override Tab
tabWrapper: {
flexDirection: "row"
},
tabSelected: {
color: theme.palette.primary.main
},
tabLabelIcon: theme.mixins.toolbar, // same minHeight than toolbar
// TODO override buttonBase ???
// ...
}));
An example usage:
<Tab
value="/"
classes={{
wrapper: classes.tabWrapper,
selected: classes.tabSelected,
labelIcon: classes.tabLabelIcon
}}
icon={
<React.Fragment>
<DashboardIcon />
</React.Fragment>
}
label="Home"
// TODO: is this the expected syntax? TypeScript is not happy with this prop...
buttonBaseProps={{ classes: {} }}
/>
I have no idea how to define the ButtonBase classes in this example.
How should I define my props to override the ButtonBase style?
Edit: doc is here https://material-ui.com/api/tab/, the last section describe the inheritance process but the documentation is very terse.
Edit 2: the example use case is bad as you should override ".MuiTabs-indicator" to increase the bottom border height (it's actually an additional span not a border) but the question stands. Imagine that I want to change the ButtonBase background-color for example.

So as it turns out, There is no separate ButtonBase component inside the Tab component. So you won't find prop called buttonBaseProps. The tab itself is rendered as the button component.
Whatever style you wanna pass, pass it to the root inside classes. See below
<Tab classes={{
root: classes.customButtonBaseRoot,
wrapper: classes.tabWrapper,
selected: classes.tabSelected,
labelIcon: classes.tabLabelIcon
}}
/>
https://codesandbox.io/s/apply-style-to-buttonbase-in-a-tab-component-izgj5

Related

Checkbox size in Fluent UI Northstar

What is the proper way to control the size of checkboxes in Fluent UI Northstar?
I have tried adjusting the font size and the height, but it only acts on the label, not the box itself. And I didn't find anything in the documentation.
If you want this to be a general styling that applies to all checkboxes rendered inside your provider, you can modify the checkbox component-style in the theme you pass into the provider.
Create your own theme, apply the styles you want and then merge it into the theme that you are currently using
Code snippet
import { Provider, teamsTheme, mergeThemes, ThemeInput } from '#fluentui/react-northstar';
const myTheme: ThemeInput = {
componentStyles: {
Checkbox: {
root: {
//will apply styles to the root-container component
},
checkbox: {
backgroundRepeat: "repeat",
},
label: {
//will apply styles to the label
},
}
}}
ReactDOM.render(
<Provider theme={mergeThemes(teamsTheme, myTheme)}>
<AppContainer>
<Component title={title} isOfficeInitialized={isOfficeInitialized} />
</AppContainer>
</Provider>,
document.getElementById('container')
);
the checkbox rendering issue in the picture is fixed by setting:
backgroundRepeat: "repeat"

How do you conditionally apply multiple classes to a single Material UI classes prop

I am using the Material UI Drawer and would like to apply a class called "paperStyle" to the classes prop with the rule name "paper" and then conditionally apply an additional class called "specialPaperStyle" if the user is of a particular type. But I haven't been able to apply two classes to the paper rule, let alone apply it conditionally and wondered if anyone knew what to do?
Here are the key parts of my code:
Styles
const useStyles = makeStyles(theme => ({
paperStyle: {
width: drawerWidth,
boxShadow: 'inset 0 0.3rem 1.5rem rgba(0,0,0,0.19)',
color: theme.palette.primary.main,
[theme.breakpoints.up('lg')]: {
minHeight: '100%',
position: 'relative',
},
},
specialPaperStyle:{
backgroundImage: 'linear-gradient(to bottom right, #27133f, transparent)',
},
}));
Material UI drawer
<Drawer
classes={{
paper: classes.paper,
}}
>
Contents of drawer
</Drawer>
The above works in that my paperStyle class is being applied, but how do I conditionally apply the specialPaperStyle class to paper? For example:
Doesn't work!
<Drawer
classes={{
paper: {`${classes.paperStyle isSpecial && $classes.specialPaperStyle}`},
}}
>
Contents of drawer
</Drawer>
Many thanks,
Katie
material-ui comes with a handy package clsx that makes easier to add classes based on specific conditions. You can pass several class arguments, or also objects that will display the class key if the given value is truthy:
import clsx from 'clsx';
<Drawer
classes={{
paper: {clsx(classes.paperStyle, {[classes.specialPaperStyle]: isSpecial})},
}}
>
Contents of drawer
</Drawer>
docs about clsx on material-ui
How about this?
UPDATED
<Drawer
classes={{
paper: {`${classes.paperStyle} ${isSpecial ? classes.specialPaperStyle : ''}`},
}}
>
Contents of drawer
</Drawer>

Failed to override styles with classes in material-ui

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

how to assign color to helperText material ui to highlight error in TextField

How to assign a color to helperText material-UI to highlight the error in TextField.I am unable to set the color to helperText in material-UI.
I tried to use MuiFormHelperText-root-406 to apply CSS
but it does not work
<Grid item xs={3}>
<TextField
label="EmailId"
name="emailId"
value={editItem.emailId}
onChange={this.editInputValue}
helperText={this.state.emailerror} />
</Grid>
.MuiFormHelperText-root-406{
color:rgba(255,0,0,0.5);
}
Add this code: add className={classes.textField} in TextField
textField: {
marginLeft: theme.spacing(1),
marginRight: theme.spacing(1),
width: 200,
'& p':{
color:'blue',
},
},
<TextField
id="standard-helperText"
label="Helper text"
defaultValue="Default Value"
className={classes.textField}
helperText="Some important text"
margin="normal"
/>
#arpita-patel's answer is correct but you should know that you can also just add this to your CSS:
.MuiFormHelperText-root {
color:rgba(255,0,0,0.5);
}
Or do it based on the parent:
.MuiTextField-root p {
color:rgba(255,0,0,0.5);
}
Each of the above worked for me. I am using Material UI 4.0.2
The best way which I found to style the helperText for the TextField component is similar to the way presented by Arpita Patel.
The only difference is that I am using the attribute classes instead of className as it has been described in Material-UI docs here
You can find there that TextField component can use only one CSS rule name called root (global class is called .MuiTextField-root).
So basically you need to use the below code to style helperText as you like:
JSX (based on your initial code example)
const classes = useStyles();
<TextField
label="EmailId"
name="emailId"
value={editItem.emailId}
onChange={this.editInputValue}
helperText={this.state.emailerror}
classes={{root: classes.textField}}
/>
STYLE via makeStyles
import { makeStyles } from '#material-ui/core/styles';
const useStyles = makeStyles((theme) => ({
textField: {
'& p':{
/* your style for helperText here*/
}
}
})
If #ange-loron's answer didn't work, try to add !important :
.MuiFormHelperText-root {
color: rgba(255,0,0,0.5) !important;
}

Override Material UI Tab Indicator Emotion Styled

Trying to figure out how to override the styles of the tabs indicator using styled from Emotion. I am not sure how to access nested classes. This is what I have, but it isn't getting me there:
const StyledTabs = styled(Tabs)(
{
classes: {
indicator: {
background: 'black',
},
},
}
);
Any help would be awesome!
There are a couple issues. styled from Emotion only supports generating a single class name per usage. It doesn't provide any support for the classes: {indicator: {styles}} structure in your example.
Below is a syntax that allows you to use styled to provide a class name for the "indicator" class of Tabs:
const StyledTabs = styled(({ className, ...other }) => {
return <Tabs {...other} classes={{ indicator: className }} />;
})({
backgroundColor: "black"
});
However, this does not work completely robustly because the <style> element for the Emotion styles does not consistently occur after the <style> elements from JSS (used for Material-UI's styling) in the <head> of the document. I'm not sure how to alter the insertion point for Emotion's styles, but you can read here about how to change the insertion point for JSS. I've included this approach in my sandbox below.
Here's a sandbox that shows this working:
Another syntax option is the following which will allow you to control more than one Tabs class:
const StyledTabs = styled(({ className, ...other }) => {
return <Tabs {...other} classes={{ root: className, flexContainer: "flexContainer", indicator: "indicator" }} />;
})({
"& .indicator": {
background: "black"
},
"& .flexContainer": {
flexDirection: "row-reverse"
}
});

Resources