How to change material-ui Textfield label styles in react - javascript

I'm new to Material-UI, I couldn't able to figure it out, how to change the color of the label which is showing in grey color. I want it in black. Can anyone help me with this query?
Here is the Code :
import React from "react";
import ReactDOM from "react-dom";
import { TextField, Button, Grid } from "#material-ui/core";
class App extends React.Component {
render() {
return (
<Grid container justify={"center"} alignItems={"center"} spacing={1}>
<Grid item>
<TextField
id="outlined-name"
label="Name"
value={"Enter value"}
onChange={() => console.log("I was changed")}
margin="normal"
variant="outlined"
/>
</Grid>
<Grid item>
<Button variant="contained" color="primary">
Submit
</Button>
</Grid>
</Grid>
);
}
}
Here is the code: "https://codesandbox.io/s/fancy-morning-30owz"

If you use the selection tools in your browser, you would find out that:
The class name used is MuiFormLabel-root
<label class="MuiFormLabel-root MuiInputLabel-root MuiInputLabel-formControl MuiInputLabel-animated MuiInputLabel-shrink MuiInputLabel-outlined MuiFormLabel-filled" data-shrink="true" for="outlined-name">Name</label>
So set the styles using nesting selector to the TextField component
Functional component
import { makeStyles } from "#material-ui/core/styles";
const useStyles = makeStyles(theme => ({
root: {
"& .MuiFormLabel-root": {
color: "red" // or black
}
}
}));
...
const classes = useStyles();
Classical component
import { withStyles, createStyles } from "#material-ui/core/styles";
const styles = theme => createStyles({
root: {
"& .MuiFormLabel-root": {
color: "red"
}
}
});
...
const { classes } = this.props;
...
export default withStyles(styles)(App);
usage
<TextField
className={classes.root}
...
>
</TextField>
By this way, you can change the label color, as the screenshot is shown below (currently red)
Try it online:

If you want to leave your style in a separate file, you can write:
.MuiTextField-root > label {
background-color: $bg-color;
color: $color;
}
.MuiTextField-root > .MuiFormLabel-root.Mui-focused {
color: $color;
}

Related

How to create a dashboard grid with material-ui for react?

I have the following react code and the thing that I want is to create a dashboard, but before I need to create a Grid for it.
I have the following code (using the material-ui grid system "https://material-ui.com/components/grid/")
import React from 'react';
import { makeStyles } from '#material-ui/core/styles';
import Paper from '#material-ui/core/Paper';
import Grid from '#material-ui/core/Grid';
const useStyles = makeStyles((theme) => ({
root: {
flexGrow: 1,
},
paper: {
padding: theme.spacing(2),
textAlign: 'center',
color: theme.palette.text.secondary,
},
}));
function App() {
const classes = useStyles();
return (
<div>
<Grid container spacing={2}>
<Grid alignItems='baseline' item xs={3}>
<Paper className={`${classes.paper}`}>xs=3</Paper>
</Grid>
<Grid item xs={9}>
<Paper className={classes.paper}>xs=6</Paper>
<Paper className={`${classes.paper} ${styles.content}`} height="100%">xs=6</Paper>
</Grid>
</Grid>
</div>
);
}
export default App;
The result I want is the one from the 1 image, however the result that I have so far is the one from the second image, I am pretty sure that something is wrong with my code, I am not react expert.
Any help here will be aprecciated

React component is not re-rendering multiple time

I am making an application in which i have a button which change the theme from dark to light of the component. my application works fine for the first time but it does not work on second attempt
for example : If i click the button first time then it will change the theme to the dark mode but when i want to change the theme into light mode then it does not work
import {
Button,
createMuiTheme,
Grid,
Paper,
Switch,
ThemeProvider,
Typography,
} from "#material-ui/core";
import React, { Component } from "react";
export default class Mode extends Component {
constructor(props) {
super(props);
this.state = {
switch: false,
};
this.darkTheme = createMuiTheme({
palette: {
type: "dark",
},
});
this.lightTheme = createMuiTheme({
palette: {
type: "light",
},
});
}
componentDidUpdate() {
console.log(this.state.switch);
}
render() {
return (
<div>
<ThemeProvider
theme={this.state.switch === true ? this.darkTheme : this.lightTheme}
> // <-- **Condition for changing the mode**
<Paper style={{ height: "100vh" }}>
<Grid container direction="column">
<Typography variant="h1">this is my app</Typography>
<Button variant="contained" color="primary">
A button
</Button>
<Button variant="contained" color="secondary">
Another button
</Button>
<Switch
checked={this.state.switch}
onChange={() =>
this.setState((prev) => ({ switch: !prev.switch }))
}
name="Dark Mode"
inputProps={{ "aria-label": "secondary checkbox" }}
/>
</Grid>
</Paper>
</ThemeProvider>
</div>
);
}
}
I am using material ui for this
I'm not sure why it changes only one time. But you can fix by create theme every render.
First, create function createTheme:
const createTheme = (isDark) =>
createMuiTheme({
palette: {
type: isDark ? "dark" : "light",
},
});
Then, update ThemeProvider like this:
<ThemeProvider theme={createTheme(this.state.switch)}>

Material-UI formControlLabel whole label is clickable only text should be

I am new to the material UI. here I have the following form
<FormControl
variant="outlined"
className={css.formControl}
margin="dense"
key={"abc_" + index}
>
<FormControlLabel
control={
<Checkbox
onClick={handleClick(data)}
checked={_.some(selected, { Id: selected.Id })}
value={selected.Id}
color="default"
/>
}
label={data?.Name ?? "NO_LABEL"}
/>
</FormControl>
Now, this whole label gets clickable as the area is a bit long, so, what I am trying is the only the checkbox and the text should be clickable and the other empty space should not be clicked. Here , I have given the
max-width for that label to be 272px.
How do I add that?
Thanks.
You can prevent parent elements from click events, as well as allow the child to do it.
Use pointer-events to disable click event.
pointer-events: none;
<FormControlLabel
style={{ pointerEvents: "none" }}
control={
<Checkbox
onClick={handleClick}
style={{ pointerEvents: "auto" }}
color="default"
/>
}
label={"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"}
/>
I had the same problem with those checkboxes, see here:
With dev tools:
The label takes whole space (purple space).
That is due to the FormGroup displaying children in a column flex container.
To fix it, in my custom overloaded checkbox, I used:
import * as React from 'react';
import { makeStyles } from '#material-ui/core/styles';
import FormControlLabel from '#material-ui/core/FormControlLabel';
import FormGroup from '#material-ui/core/FormGroup';
import MUICheckbox from '#material-ui/core/Checkbox';
const useFormGroupStyles = makeStyles({
root: {
display: 'block',
},
});
const Checkbox = (props) => {
const { onCheck } = props;
const formGroupClasses = useFormGroupStyles();
const checkbox = (
<MUICheckbox
onChange={event => onCheck(event, event.target.checked)}
icon={props.uncheckedIcon}
checkedIcon={props.checkedIcon}
color="primary"
style={props.style}
/>
);
return (
<FormGroup classes={formGroupClasses}>
<FormControlLabel
control={checkbox}
label={props.label}
style={props.style}
/>
</FormGroup>
);
};
export default Checkbox;
This will do
MuiFormControlLabel: {
styleOverrides: {
root: {
width: "fit-content"
}
}
}

how to render components based on the value of props?

I have a parent component Dashboard.js. Here I have three values of state namely yesterday, lastWeek, lastMonth and I'm passing this value to my child component. Now I want to render my data depending on my child component. The problem is I'm using componentDidMount() lifecycle method which is rendering the child component only once. How do I render the data based on the props passed to the child component? The parent component is a react hook and the child component called DataFetchDetails is a class based component. Attaching their respective codes
Parent Component :- Dashboard.js
import React from 'react';
import { makeStyles } from '#material-ui/styles';
import { Tabs, Tab, Grid } from '#material-ui/core';
import AppBar from '#material-ui/core/AppBar';
import Typography from '#material-ui/core/Typography';
import Box from '#material-ui/core/Box';
import PropTypes from 'prop-types';
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'
import {
TotalUsers,
LoggedInUsers,
TimePicker,
UnregisteredUsers
} from './components';
import DataFetchDetails from './components/DataFetchDetails';
const useStyles = makeStyles(theme => ({
root: {
paddingTop: theme.spacing(4),
padding: theme.spacing(4)
},
formControl: {
margin: theme.spacing(1),
minWidth: 120,
},
selectEmpty: {
marginTop: theme.spacing(2),
},
}));
function TabPanel(props) {
const { children, value, index, ...other } = props;
return (
<Typography
component="div"
role="tabpanel"
hidden={value !== index}
id={`simple-tabpanel-${index}`}
aria-labelledby={`simple-tab-${index}`}
{...other}
>
<Box p={3}>{children}</Box>
</Typography>
);
}
function a11yProps(index) {
return {
id: `simple-tab-${index}`,
'aria-controls': `simple-tabpanel-${index}`,
};
}
const Dashboard = () => {
const classes = useStyles();
const [value, setValue] = React.useState(0);
const handleChange = (event, newValue) => {
setValue(newValue);
};
const [period, setPeriod] = React.useState("yesterday");
const handleChange1 = event => {
setPeriod(event.target.value);
};
return (
<div className={classes.root}>
<Select
labelId="demo-simple-select-label"
id="demo-sample-select"
value={time}
onChange={handleChange1}
>
<MenuItem value={"yesterday"}>Previous day</MenuItem>
<MenuItem value={"lastWeek"}>Last Week</MenuItem>
<MenuItem value={"lastMonth"}>Last Month</MenuItem>
</Select>
<div className={classes.root}>
<AppBar position="static">
<Tabs value={value} onChange={handleChange} aria-label="simple tabs example">
<Tab label="CONSENT DETAILS" {...a11yProps(0)} />
<Tab label="ACCOUNT DETAILS" {...a11yProps(1)} />
<Tab label="DATA FETCH DETAILS" {...a11yProps(2)} />
</Tabs>
</AppBar>
<TabPanel value={value} index={0}>
</TabPanel>
<TabPanel value={value} index={1}>
</TabPanel>
<TabPanel value={value} index={2}>
<DataFetchDetails period={period} handlePeriodChange1={handleChange1} />
</TabPanel>
</div>
</div>
);
};
export default Dashboard;
Child component DataFetchDetails.js :-
import React from 'react';
import {
Card,
CardHeader,
Button,
Divider,
CardContent,
TextField,
CardActions,
FormControl,
InputLabel,
Select,
MenuItem
} from '#material-ui/core';
import Paper from '#material-ui/core/Paper';
import Table from '#material-ui/core/Table';
import TableBody from '#material-ui/core/TableBody';
import TableCell from '#material-ui/core/TableCell';
import TableHead from '#material-ui/core/TableHead';
import TableRow from '#material-ui/core/TableRow';
import axios from 'axios';
import 'izitoast/dist/css/iziToast.min.css'; // loading css
import iziToast from 'izitoast/dist/js/iziToast.min.js'; // you have access to iziToast now
import 'izitoast/dist/css/iziToast.min.css';
const url = 'MY_ENDPOINT_URL';
export default class DataFetchDetails extends React.Component {
constructor(props) {
super(props);
this.state = {
items : [],
isLoaded : true,
renderJsx: false,
}
}
componentDidMount() {
this.setState({period: this.props.period});
const periodStatus = {
period : this.props.period
};
{console.log("Props period = ",this.props.period)}
axios.post(url, periodStatus)
.then((response) => {
this.setState({period : this.props.period})
this.setState({items : [response.data]});
.catch((error) => {
console.log("Error");
});
}
render() {
let {isLoaded, items, renderJsx } = this.state;
if(!isLoaded) {
return <div>Loading</div>
}
else {
return (
<div>
<div>
<Card className="Lock-user"
>
<form >
<CardHeader
title=""
/>
<Divider></Divider>
<CardContent id="form-input" className=""
>
</CardContent>
<Divider></Divider>
</form>
</Card>
</div>
<div>
<Card>
<Paper>
<Table>
<TableHead>
<TableRow>
<TableCell> success </TableCell>
<TableCell align="right">failure</TableCell>
<TableCell align="right">inProgress</TableCell>
</TableRow>
</TableHead>
<TableBody>
{ items.map(item => (
<TableRow key={item.success}>
<TableCell component="th" scope="row">
{item.success}
</TableCell>
<TableCell align="right">{item.failure}</TableCell>
<TableCell align="right">{item.inProgress}</TableCell>
</TableRow>
))}
</TableBody>
</Table>
{console.log("Props period render = ",this.props.period)}
</Paper>
</Card>
</div>
</div>
);
}
}
}
the backend and the api works fine. I want to re render my child component based on the value of the period. How do I solve this problem?
You you compare the props i.e prevProps and current props(this.props) object inside
ComponentDidUpdate
lifecycle method to re-render the child component based on props.
As ComponentWillReceiveProps is deprecated now.
https://egghead.io/lessons/react-refactor-componentwillreceiveprops-to-getderivedstatefromprops-in-react-16-3
Go through the react lifecycle docs or https://developmentarc.gitbooks.io/react-indepth/content/life_cycle/update/postrender_with_componentdidupdate.html.
Use componentWillRecieveProps in child component.
componentWillRecieveProps(props) {
// props => new props passed
// this.props => current props
}
I hope that helps.

How to make a navigationbar that contains custom Components with Material UI and React?

I am trying to use the BottomNavigation from Material UI. However, instead of showing lables and text I want to use custom-made ImageButtons components.
I have the following code from Material UI:
import React from 'react';
import { makeStyles } from '#material-ui/core/styles';
import BottomNavigation from '#material-ui/core/BottomNavigation';
import ImageButton from '.././buttons/ImageButton';
const useStyles = makeStyles({
root: {
width: 1200,
},
});
export default function CreateProjectNavigation() {
const classes = useStyles();
const [value, setValue] = React.useState(0);
return (
<BottomNavigation
value={value}
onChange={(event, newValue) => {
setValue(newValue);
}}
showLabels
className={classes.root}
>
<ImageButton buttonNr="1" text="Project Details" />
<ImageButton buttonNr="2" text="Types/Discipline" />
<ImageButton buttonNr="3" text="Fieldwork" />
<ImageButton buttonNr="4" text="Personell and Institutions" />
<ImageButton buttonNr="5" text="Summary" />
</BottomNavigation>
);
}
And here is the code for the ImageButton:
import React from 'react';
import { makeStyles } from '#material-ui/core/styles';
import EditIcon from '#material-ui/icons/Edit';
import MenuBookIcon from '#material-ui/icons/MenuBook';
import RoomIcon from '#material-ui/icons/Room';
import PeopleIcon from '#material-ui/icons/People';
import DoneIcon from '#material-ui/icons/Done';
import Button from '#material-ui/core/Button';
import Grid from '#material-ui/core/Grid';
const useStyles = makeStyles(theme => ({
root: {
margin: theme.spacing(1),
borderRadius: '50%',
height: '75px',
width: '75px',
'&$disabled': {
backgroundColor: '#0af7ff',
color: '#000000',
},
},
disabled: {},
}));
export default function ImageButton({ active, buttonNr, text, handler, link }) {
let icon;
const classes = useStyles();
switch (buttonNr) {
case '1':
icon = <EditIcon />;
break;
case '2':
icon = <MenuBookIcon />;
break;
case '3':
icon = <RoomIcon />;
break;
case '4':
icon = <PeopleIcon />;
break;
case '5':
icon = <DoneIcon />;
break;
default:
break;
}
return (
<Grid container direction="column" justify="" alignItems="center">
<Button
variant="contained"
classes={{
root: classes.root,
disabled: classes.disabled,
}}
disabled={active}
onClick={handler}
href={link}
>
{icon}
</Button>
<p>
<b>{text}</b>
</p>
</Grid>
);
}
Unfortunately, the ImageButton turns out really disorted and wrong in the BottomNavigation bar. Additionally, the text below the image button just appears next to the button instead of under the moment it is placed in the BottomNavigation.
Does anyone have an idea on what to do about this?
I'm not sure, but I think you need to wrap your buttons inside BottomNavigationAction component for BottomNavigation. BottomNavigationAction has component props. Maybe you should to pass your buttons inside this props, because children prop is unsupported for BottomnavigationAction component.
Here you can see API details https://material-ui.com/api/bottom-navigation-action/

Categories

Resources