I'm using this code in MUI for drawing Card.
<Card {...props}>
<CardHeader title="test" style={{ textAlign: 'center' }} />
<Divider />
<CardContent>
<Doughnut data={data} options={options} />
</CardContent>
</Card>
But sometimes, the data value can be empty, and the card will be blank. Who can help me, how can I set the default value of the Card if the data is empty? Like NoRowsOverlay on DataGrid
<Card {...props}>
<CardHeader title="test" style={{ textAlign: 'center' }} />
<Divider />
<CardContent>
{
data ? (
<Doughnut data={data} options={options} />
) : (
<NoRowsOverlay />
)
}
</CardContent>
</Card>
You can change data ? to whatever true/false check you need to make. Also you probably need to change <NoRowsOverlay /> to some other component you want to display instead.
You can use ??. For example: data={data ?? 'defaultValue'}.
Related
For the code below
import {
TextField,
Stack,
Button,
Box,
Grid,
SvgIcon,
Typography,
Divider,
Link
} from "#mui/material";
// import IconGoogle from "../client/images/google.svg";
export default function Home() {
return (
<Grid container justifyContent="center" padding={20}>
<Grid item>
<Stack spacing={2} width={320}>
<Typography component="label" variant="h5" alignSelf="center">
Sign In
</Typography>
<Button variant="outlined" fullwidth>
{/* <IconGoogle /> */}
Sign in to Google
</Button>
<Divider> OR </Divider>
<TextField variant="outlined" label="Email" fullwidth />
<Stack>
<TextField variant="outlined" label="Password" fullwidth />
<Typography
component="label"
variant="subtitle1"
sx={{ color: "gray", fontSize: 12 }}
>
Minimum 6 Character
</Typography>
</Stack>
<Button variant="contained">Sign In</Button>
<Link component="button" underline="none" sx={{ mt: 100 }}>
Forgot Password
</Link>
</Stack>
</Grid>
</Grid>
);
}
It gives the following screen
which I expect the red rectangle portion to be much larger, since I set sx={{ mt: 100 }}. Why it's not larger and how to rectify it?
If you use padding instead of margin, it does move the button down.
<Link component="button" underline="none" sx={{ pt: 100}}>
Forgot Password
</Link>
I am creating a navigation menu and part of it is having a Login link and "Try for Free" button on the right part of the webpage. But what is puzzling me is how to get the button aligned to the right of the Login link. Currently it looks like this:
What am I doing wrong?
<Grid item xs={4}>
{/* <Toolbar disableGutters> */}
<Tabs className={classes.tabContainer}>
<Tab className={classes.tab} component={Link} to="/analyze" label="Login" />
</Tabs>
{/* <Typography className={classes.root}>
<Link href="#" onClick={menuOptions}>
Link
</Link>
</Typography> */}
<Button
variant="contained"
color="default"
size="medium"
// style={{ marginTop: '1.1em' }}
// style={{ maxWidth: '108px', minWidth: '108px' }}
onClick={() => {
// handleClickImportPGN();
}}
>
Try for Free
</Button>
{/* </Toolbar> */}
</Grid>;
One of the handiest ways is to use CSS Flexbox
<Grid item style={{ display: "flex" }}>
<Tabs>
<Tab component={Link} label="Login" />
</Tabs>
<Button
variant="contained"
color="default"
size="medium"
// style={{ marginTop: '1.1em' }}
// style={{ maxWidth: '108px', minWidth: '108px' }}
onClick={() => {
// handleClickImportPGN();
}}
>
Try for Free
</Button>
{/* </Toolbar> */}
</Grid>;
But if you want to make use more of Material UI, you could try to have a few more Grid within each of the children elements.
Simplified Working Example:
<AppBar position="static" className={this.props.classes.appBar}>
<Toolbar
style={{
margin: "0 auto",
width: "80%"
}}
>
<Link to="/">
<img src={logo} alt="logo" width="65" height="48" />
</Link>
<NavLink
to="/about"
className={this.props.classes.link}
activeClassName={this.props.classes.activeMenu}
>
How can I move NavLink to the right side? I tried with edge, but it does not work. It is only for ImageButton available.
One approach is to use a Grid container and wrap your components in Grid item as follows
<AppBar position="static">
<Toolbar
style={{
margin: "0 auto",
width: "80%"
}}
>
<Grid direction="row" justify="space-between" alignItems="center" container>
<Grid item>
<Link to="/">
<img src={logo} alt="logo" width="65" height="48" />
</Link>
</Grid>
<Grid item>
<NavLink
to="/about"
className={this.props.classes.link}
activeClassName={this.props.classes.activeMenu}
>
// the rest of the code goes here
</Grid>
</Grid>
</Toolbar>
</AppBar>;
The Grid component uses flex and can be configured to work as you need, in your case justify is set to space-between than means that the elements will be pushed to the margin of the container and separated by the space between them.
More on Grid and aligning items can be found in the documentation HERE
I am using the Select with the multiple prop. The component works fine, and the InputLabel renders the renders the following:
However, when I add an icon at the beginning via the startAdornment prop, the InputLabel is moved above the input field.
Do you know how to show the label next do the icon when no values are selected?
The code is:
<FormControl className={classes.formControl} fullWidth variant="outlined" size="medium">
<InputLabel name={name} color="secondary" variant="outlined" htmlFor={id} id={id} className={classes.label}>{label}</InputLabel>
<Select
name={name}
labelId={id}
id={id}
multiple
autoWidth
startAdornment={icon}
color="secondary"
value={selectedValues}
onChange={handleChange}
renderValue={selectedOptions => (
<div className={classes.tags}>
{selectedOptions.map(option => (
<Chip key={option.value} label={option.label} size="small" className={classes.chipStyle} />
))}
</div>
)}
>
{options.map(option => (
<MenuItem key={option.value} value={option}>
<Checkbox checked={logicHere} color="primary" />
<ListItemText primary={option.label} />
</MenuItem>
))}
</Select>
</FormControl>
Did you try ?
<Select
InputProps={{
startAdornment: <InputAdornment position="start">Kg</InputAdornment>,
}} />
I am trying to create a form to collect input to create an event listing.
I am using the 'value' property in way it is documented in the React docs:
https://reactjs.org/docs/forms.html
,to collect user input onChange, but material-ui:
https://material-ui.com/api/input/
uses 'value' for setting value to the input field not collecting the value in the field. This is causing all sort of bugs, e.i. not being able to enter input, pickers not displaying default values and not accepting values and also not being able to collect information. I could use pointers on where I am going wrong. Thanks for having a look :-)
import React from 'react';
import PropTypes from 'prop-types';
import { withStyles } from '#material-ui/core/styles';
import Input from '#material-ui/core/Input';
import Paper from '#material-ui/core/Paper';
import Grid from '#material-ui/core/Grid';
import TextField from '#material-ui/core/TextField';
import Button from '#material-ui/core/Button';
const styles = theme => ({
container: {
display: 'flex',
flexWrap: 'wrap',
}
});
class CreateEvent extends React.Component{
constructor() {
super();
this.state = {
title: "",
description: "",
location: "",
start_time: "",
start_date: "",
end_time: "",
end_date: ""
};
}
updateInput = e => {
this.setState({
[e.target.name]: e.target.value
});
};
cancelCreation = e =>{
};
addNewEvent = e =>{
//Make db call
};
render(){
return(
<div className="form-container">
<Paper className="new-event-form">
<form className="event-form" onSubmit={this.addNewEvent}>
<Input
type="text"
placeholder="Event title"
className="event-title"
inputProps={{
'aria-label': 'Description',
}}
multiline={1}
rows={1}
onChange={this.updateInput}
value={this.state.value}
/>
<Input
type="text"
placeholder="Event description"
className="event-title"
inputProps={{
'aria-label': 'Description',
}}
multiline={true}
rows={10}
onChange={this.updateInput}
//value={this.state.description}
/*
Will allow user to provide input because 'value' is commented out. But the above component will not because value is referenced
*/
/>
<Grid container spacing={16} className="event-grid">
<Grid item xs={4}>
<Input
type="text"
item xs={4}
placeholder="Event location"
className="event-location"
inputProps={{
'aria-label': 'Description',
}}
multiline={true}
rows={4}
onChange={this.updateInput}
//value={this.state.location}
/>
</Grid>
<Grid item xs={4}>
<TextField
id="date"
label="Start date"
type="date"
defaultValue="2017-05-24"
className="event-start-date"
InputLabelProps={{
shrink: true,
}}
onChange={this.updateInput}
value={this.state.start_date}
/>
<TextField
id="time"
label="Start time"
type="time"
defaultValue="07:30"
className="event-start-time"
InputLabelProps={{
shrink: true,
}}
inputProps={{
step: 300, // 5 min
}}
/>
</Grid>
<Grid item xs={4}>
<TextField
id="date"
label="End date"
type="date"
defaultValue="2017-05-24"
className="event-start-date"
InputLabelProps={{
shrink: true,
}}
/>
<TextField
id="time"
label="End time"
type="time"
defaultValue="07:30"
className="event-start-time"
InputLabelProps={{
shrink: true,
}}
inputProps={{
step: 300, // 5 min
}}
/>
</Grid>
</Grid>
<Button className="line-spacer"/>
<Grid container className="form-buttons">
<Grid item xs={12}>
<Input type="file" name="my-event-image" id="file" className="new-event-image"> </Input>
<label htmlFor="file">CHOOSE AN IMAGE</label>
<Button className="line-spacer" onChange={this.updateInput}/>
</Grid>
</Grid>
<Grid container spacing={16} className="form-buttons">
<Grid item xs={6}>
<Button onChange={this.cancelCreation}>Cancel</Button>
</Grid>
<Grid item xs={6}>
<Button type="submit">Submit</Button>
</Grid>
</Grid>
</form>
</Paper>
</div>
);
}
}
export default withStyles(styles)(CreateEvent);
In your updateInput method you use e.target.name but none of your input fields have a name property. Add a name property on each Input component matching the name you are using in your value. For example:
<Input name="description" ... value={this.state.description} .../>