How to style Material UI's Tab component label? - css

I'm looking for a way to customize the color of the text inside the Tab component but at the same time retaining the ability for it to be colored over when selected as an active Tab.
Example code:
<Tabs centered onChange={handleChange} value={value} textColor={'secondary'} indicatorColor={'secondary'}>
<Tab label={'Hello There'} style={{color: '#fff'}}/>
<Tab label={'Hello There'} style={{color: '#fff'}}/>
<Tab label={'Hello There'} style={{color: '#fff'}}/>
</Tabs>
The above code will result in the change of the text color BUT when the Tab becomes active, it won't be overridden.
If it helps, I'm also using styled-components for ease of use.

You can use the makeStyles export of material-ui to create your custom class for the label
import { makeStyles } from "#material-ui/core";
const useStyles = makeStyles({
customLabelColor: {
color: "#fff"
}
});
export default function App() {
const classes = useStyles();
return (
...
<Tab
label={"Hello There"}
classes={{
textColorSecondary: classes.customLabelColor
}}
/>
...
);
}
CodeSandBox: https://codesandbox.io/s/quirky-kowalevski-xzf7g?file=/src/App.js
Refer here for other methods on how to override the CSS for Tab.
On the same reference I linked, have a look at the textColorSecondary rule name. This is specific to your question since you are using textColor="secondary" on your parent component Tabs

Related

Material UI tab selected has different color than the rest of tabs

New to Material UI so hopefully this question makes sense. I am using Material UI Tabs and have been able to customize the css as per need. see below:
I have an issue where the selected tab and the other tabs have different opacity(?) even though they are the same color. Cannot find any material UI documentation online to make them uniform, I tried several things [TabIndicatorProps] or even adding below to the Tabs class
"&.Mui-selected": {
color: "1D4659",
opacity: "70%"
}
Does anyone know how to fix this? I can change either the selected tab or the Other tabs. I just want to make sure they are uniform.
you can override MuiTab-root instead of Mui-selected.
1- declare your custom style
const useStyles = makeStyles({
customTabs: {
"& .MuiTab-root": {
color: "#1D4659",
opacity: "70%"
}
}
});
2- use your custom style in <Tabs>
const classes = useStyles();
<Tabs
classes={{ root: classes.customTabs }}
...
>
<Tab ... />
<Tab ... />
<Tab ... />
<Tab ... />
<Tab ... />
</Tabs>
here is the code: https://codesandbox.io/s/gracious-framework-xo1cp?file=/src/App.js

Material-UI styling the button variant outlined

I'm new to Material UI and I'm struggling.
I have a button component
export default function TheButton(props: PropsWithChildren<Props>) {
const { className, hover, level,...rest } = props;
const classes = useStyles();
return (
<Button
{...rest}
className={clsx(classes.root, className, hover === 'contained' && classes.hoverContained)}
>
{props.children}
</Button>
);
}
From this component, I'd like to have two variants: contained and outlined. Here is my outlined button.
<TheButton
variant="outlined"
color="secondary"
>
secondary
</TheButton>
When the variant outlined is selected the button has the class Muibutton-outlined. I'd like to override this class to change the border (only in the outlined variant, so only on this class).
So far I've tried something like:
const useStyles = makeStyles((theme: Theme) =>
createStyles({
'.MuiButton-outlinedSecondary':{
border:"2px solid red" ,
},
}
)
It doesn't work.
I have a similar setting, and I tried:
adding a class submit to my button component
<Button
type="submit"
variant="outlined"
disabled={isSaving || invalid || unchanged}
color="secondary"
className={classes.submit}
>
SAVE CHANGES
</Button>
since I have the submit class I can be more precise in my styling like so:
const useStyles = makeStyles({
submit: {
marginTop: padding.medium,
marginLeft: padding.small,
'&.MuiButton-outlinedSecondary': {
border: '1px solid pink',
},
},
});
Here is the result:
Material-ui button with pink border image
As long as I have used Ant design ui kit and I have overrided styles on its default style like this:
<Button type="primary" className={styles.custom_css}>click</Button>
This has done in react and custom_css class overrides its styles on default
This might can help you, if not please let me know

Material UI TextField border overlaps with Label

I'm using Material UI TextField and Material UI Tab. I have two tabs and each has a text field inside them. After I click on the TextField, the border should open for the label, but this doesn't happen if the current Tab is not the Tab1 !!
I managed to reproduce this problem in this CodeSandBox and the code is also included below.
import React from "react";
import PropTypes from "prop-types";
import { makeStyles } from "#material-ui/core/styles";
import AppBar from "#material-ui/core/AppBar";
import Tabs from "#material-ui/core/Tabs";
import Tab from "#material-ui/core/Tab";
import Typography from "#material-ui/core/Typography";
import Box from "#material-ui/core/Box";
import TextField from "#material-ui/core/TextField";
function TabPanel(props) {
const { children, value, index, ...other } = props;
return (
<Typography
component="div"
role="tabpanel"
hidden={value !== index}
id={`scrollable-force-tabpanel-${index}`}
aria-labelledby={`scrollable-force-tab-${index}`}
{...other}
>
<Box p={1}>{children}</Box>
</Typography>
);
}
TabPanel.propTypes = {
children: PropTypes.node,
index: PropTypes.any.isRequired,
value: PropTypes.any.isRequired
};
function a11yProps(index) {
return {
id: `scrollable-force-tab-${index}`,
"aria-controls": `scrollable-force-tabpanel-${index}`
};
}
const useStyles = makeStyles(theme => ({
root: {
flexGrow: 1,
width: "100%",
backgroundColor: theme.palette.background.paper,
padding: 0,
margin: 0
},
Tab: {
MuiTab: {
root: {
minWidth: "130px"
}
}
}
}));
export default function Demo(props) {
const classes = useStyles();
const [value, setValue] = React.useState(0);
function handleChange(event, newValue) {
setValue(newValue);
console.log(newValue);
}
return (
<div className={classes.root}>
<AppBar position="static" color="default">
<Tabs
key={"tabs"}
value={value}
onChange={handleChange}
variant="scrollable"
scrollButtons="on"
indicatorColor="primary"
textColor="primary"
aria-label="scrollable force tabs example"
>
<Tab
key={"tab1"}
className={classes.Tab}
label={0}
{...a11yProps(0)}
/>
<Tab
key={"tab2"}
className={classes.Tab}
label={1}
{...a11yProps(1)}
/>
</Tabs>
</AppBar>
<TabPanel
key={"panel1"}
value={value}
index={0}
style={{ padding: 0, margin: 0 }}
>
<div key={"div1"}>
hi im tab1{" "}
<TextField
key={"textfield1"}
variant={"outlined"}
margin={"dense"}
label={"im tab 0 textfield"}
/>
</div>
</TabPanel>
<TabPanel
key={"panel2"}
value={value}
index={1}
style={{ padding: 0, margin: 0 }}
>
<div key={"div2"}>
hi im tab2
<TextField
key={"textfield2"}
variant={"outlined"}
margin={"dense"}
label={"im tab 1 textfield"}
/>
</div>
</TabPanel>
</div>
);
}
Edit1:
I managed to find a similar question...,
Material-UI TextField Outline Label is overlapping with border when conditionally rendered
It seems this is not related to tabs as it is related to conditional rendering, which for me happened when i was using tabs
Edit2:
I tried giving the Textfield a key, but the problem still remains and there is an overlap between Textfield border and label, i updated the sandbox so it can reflect this
The label width is calculated during the initial rendering of the TextField and is only recalculated if the label changes. During the initial rendering of the TextField on your second tab, the TextField is not visible and thus the label's width is 0. Switching the TabPanel to visible does not cause a re-calculation of the label width, so no space is allotted for it in the outline.
You can fix this by using the same approach within your TabPanel as is used in the demos which is to only render the children of the panel when it is visible. This allows the label width to be correctly calculated after the initial rendering.
So instead of
<Box p={1}>{children}</Box>
you should instead have
{value === index && <Box p={1}>{children}</Box>}
I had the overlap problem with the select. Slightly different scenario though. I went through numerous pages and just couldn't find a solution to these problems:
Label text overlapping with the border - when the focus is received
Placeholder text touching the left border
If not problem # 1 - then Placeholder text staying inside the borders even when the value is selected/entered
A simple solution to all this are the following checks that worked for me -
<FormControl variant="outlined">
Make sure variant is added.
<InputLabel id="input_designationselected" style={{backgroundColor:'white'}}>Designation*</InputLabel>
Make sure that background is set for the label. Or refer to this link here https://github.com/mui-org/material-ui/issues/14530
the attribute labelId for the input control/select control matches the ID of the InputLabel
Final output is as we need it.
It drove me crazy for days - and It thought I will share it for others also. Sorry if this is the wrong place to post it.

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;
}

React hover style not working when used with Radium and Material-UI

I am using Radium library for inline styling in react . Using it works fine for other components but i am having issues with Material-UI components. When i hover my mouse over the Paper , it doesn't change the color to green . What's wrong here ? How do I fix this ?
import React, { Component, Fragment } from 'react';
import { Grid, GridList, Paper, ListItem, List, ListItemIcon, ListItemText } from '#material-ui/core';
import { connect } from 'react-redux';
import Radium from 'radium';
class AchievementsHome extends Component {
render() {
return <>
<Grid container alignItems="center" direction="column">
<h1>Achievements</h1>
<Paper
style={{backgroundColor:'red' , ':hover':{backgroundColor:'green' }}
>
<h1>Hi</h1>
</Paper>
</Grid>
</>
}
}
const mapStateToProps = (state) => {
return {
achievements: state.achievements
}
}
export default connect(mapStateToProps)(Radium(AchievementsHome));
With Material UI external styles ( so styles not directly from the Material UI library ) hardly ever work, to change the color on hover you will have to set a theme as explained in the Themes section of the docs
First grab the import withStyles and define a theme.
import { withStyles } from "#material-ui/core/styles";
const customStyles = theme => ({
root: {
backgroundColor: "red",
"&:hover": {
backgroundColor: "green"
}
}
});
Than define a new component that is wrapped with withStyles:
const CustomPaper = withStyles(customStyles)(Paper);
In your render use the component you defined:
<CustomPaper
/>
Hope this helps.
Material UI provides its own way of styling using CSS in JS (JSS). It provides a withStyles higher order component and a withTheme and lets you style at a global theme level. You can also pass class names for some components for custom styling.
You do not need to use Radium to style Material UI components.
Also your CSS selector for hovering needs to include the parent CSS selector:
const paperStyle = {
backgroundColor: 'red',
'&:hover': {
backgroundColor: 'green'
}
}
return (
<Paper styles={paperStyle}>
<Typography variant="h1">Hi</Typography>
</Paper>
);

Resources