Want to display images from API into 3 columns - css

I am pulling images from an API and wanted to beautifully display them in the browser in 3 columns. But I have 1 column after using react semantic UI of Grid and react-boostrap element of CardColumns
import React, { useEffect } from 'react';
import PropTypes from 'prop-types';
import { Link } from 'react-router-dom';
import { useSelector, useDispatch } from 'react-redux';
import { Grid, Container } from 'semantic-ui-react';
import Button from 'react-bootstrap/Button';
import { CardColumns } from 'react-bootstrap';
import Card from 'react-bootstrap/Card';
import { fetchMealsStartAsync } from '../actions/getMeals';
const MealList = (props) => {
const { cat } = props;
const meals = useSelector((state) => state.meals.meals);
const dispatch = useDispatch();
useEffect(() => {
dispatch(fetchMealsStartAsync(cat));
}, [cat]);
return (
<Container textalign="center" style={{ marginTop: 40 }}>
<Grid>
<Grid.Row>
{
meals && meals.map((meal) => (
<CardColumns
key={meal.strMeal}
style={{ marginTop: 20 }}
as={Link}
to={{
pathname: `/ingredients/${meal.idMeal}`,
id: meal.idMeal,
}}
>
<Card className="m-2 pb-1" style={{ width: '18rem' }}>
<Card.Img variant="top" src={meal.strMealThumb} />
<Card.Body>
<Card.Title>
{meal.strMeal}
</Card.Title>
<Button variant="primary">
Get Recipe
</Button>
</Card.Body>
</Card>
</CardColumns>
))
}
</Grid.Row>
</Grid>
</Container>
);
};
MealList.propTypes = {
cat: PropTypes.string,
};
MealList.defaultProps = {
cat: '',
};
export default MealList;

Try doing this put your three(or maybe more) fetched items in a parent div(e.g container) and using css selector give that parent div display: flex; flex-direction: row;

I changed <Grid.Row> to <Grid.Column> and added bootstrap to it as follows: <Grid.Column className="d-flex flex-wrap">

you can simply make 3 column in browser display by putting
i.e.
<Grid columns={3}>
<Grid.Column>
<Segment>Content</Segment>
</Grid.Column>
<Grid.Column>
<Segment>Content</Segment>
</Grid.Column>
<Grid.Column>
<Segment>Content</Segment>
</Grid.Column>
<Grid.Column>
<Segment>Content</Segment>
</Grid.Column>
<Grid.Column>
<Segment>Content</Segment>
</Grid.Column>
<Grid.Column>
<Segment>Content</Segment>
</Grid.Column>
</Grid>
or replace whole code with this
import React, { useEffect } from 'react';
import PropTypes from 'prop-types';
import { Link } from 'react-router-dom';
import { useSelector, useDispatch } from 'react-redux';
import { Grid, Container } from 'semantic-ui-react';
import Button from 'react-bootstrap/Button';
import { CardColumns } from 'react-bootstrap';
import Card from 'react-bootstrap/Card';
import { fetchMealsStartAsync } from '../actions/getMeals';
const MealList = (props) => {
const { cat } = props;
const meals = useSelector((state) => state.meals.meals);
const dispatch = useDispatch();
useEffect(() => {
dispatch(fetchMealsStartAsync(cat));
}, [cat]);
return (
<Container textalign="center" style={{ marginTop: 40 }}>
<Grid>
<Grid.Row columns={3}>
{
meals && meals.map((meal) => (
<Grid.Column>
<CardColumns
key={meal.strMeal}
style={{ marginTop: 20 }}
as={Link}
to={{
pathname: `/ingredients/${meal.idMeal}`,
id: meal.idMeal,
}}
>
<Card className="m-2 pb-1" style={{ width: '18rem' }}>
<Card.Img variant="top" src={meal.strMealThumb} />
<Card.Body>
<Card.Title>
{meal.strMeal}
</Card.Title>
<Button variant="primary">
Get Recipe
</Button>
</Card.Body>
</Card>
</CardColumns>
</Grid.Column>
))
}
</Grid.Row>
</Grid>
</Container>
);
};
MealList.propTypes = {
cat: PropTypes.string,
};
MealList.defaultProps = {
cat: '',
};
export default MealList;

Related

Auto-size and drag items into panel

I want to implement panel where items are placed using the following layout:
I tried the following code:
import React, { useCallback, useEffect } from "react";
import { Box, Grid, Tab, Tabs, Typography } from "#material-ui/core";
import { makeStyles, Theme } from "#material-ui/core/styles";
import { sizing } from "#material-ui/system";
const useStyles1 = makeStyles((theme: Theme) => ({
color: {
backgroundColor: "green",
border: "1px solid black"
}
}));
const useStyles2 = makeStyles((theme: Theme) => ({
color: {
backgroundColor: "mediumvioletred",
border: "1px solid black"
}
}));
const useStyles3 = makeStyles((theme: Theme) => ({
color: {
backgroundColor: "orange",
border: "1px solid black"
}
}));
export default function Hello() {
const classes1 = useStyles1();
const classes2 = useStyles2();
const classes3 = useStyles3();
return (
<>
<Grid
spacing={0}
container
direction="row"
justifyContent="flex-start"
xs={12}
alignItems={"stretch"}
style={{ height: "100vh", overflow: "auto", flexGrow: 1 }}
>
<Grid
// spacing={0}
// container
// direction="row"
// xs={3}
// style={{ height: "100%", overflow: "auto" }}
>
<Grid item xs={12}>
<Grid
className={classes1.color}
container
direction="column"
justifyContent="flex-start"
alignItems="center"
>
<Grid item xs={12}>
<Box m={2}>item link 1</Box>
</Grid>
<Grid item xs={12}>
<Box m={2}>item link 2</Box>
</Grid>
<Grid item xs={12}>
<Box m={2}>item link 3</Box>
</Grid>
<Grid item xs={12}>
<Box m={2}>item link 4</Box>
</Grid>
</Grid>
</Grid>
</Grid>
<Grid
spacing={0}
container
direction="row"
xs={2}
className={classes2.color}
style={{ height: "100%", overflow: "auto" }}
>
<Grid item xs={12}>
<Box m={10}>item 11</Box>
</Grid>
<Grid item xs={12}>
<Box m={10}>item 11</Box>
</Grid>
<Grid item xs={12}>
<Box m={10}>item 13</Box>
</Grid>
<Grid item xs={12}>
<Box m={10}>item 14</Box>
</Grid>
<Grid item xs={12}>
<Box m={10}>item 15</Box>
</Grid>
<Grid item xs={12}>
<Box m={10}>item 16</Box>
</Grid>
</Grid>
<Grid
container
direction="row"
xs={4}
alignItems={"stretch"}
style={{ height: "100%", overflow: "auto" }}
>
<Grid item xs={12}>
<Grid
className={classes3.color}
container
direction="row"
justifyContent="space-around"
alignItems="center"
style={{ width: "100%", overflow: "auto" }}
>
<Grid item xs={12}>
<Box m={2}>item area 1</Box>
</Grid>
<Grid item xs={12}>
<Box m={2}>item area 2</Box>
</Grid>
</Grid>
</Grid>
</Grid>
</Grid>
</>
);
}
Full code: https://stackblitz.com/edit/react-ts-k6hpuf?file=Hello.tsx
Do you know how I can implement drag for the borders and proper layout using typescript?
Here's a working example using Material UI and react-beautiful-dnd
Using drag and drop based on a ticket-based system like Jira
App.js
import React, { useState } from "react";
import makeStyles from "#material-ui/core/styles/makeStyles";
import Grid from "#material-ui/core/Grid";
import { DragDropContext } from "react-beautiful-dnd";
import Column from "./Column";
const App = () => {
function range(start, end) {
return Array(end - start + 1)
.fill()
.map((_, idx) => start + idx);
}
const initialColumns = {
links: {
id: "links",
list: [
{ id: "1", text: "text1" },
{ id: "2", text: "text2" },
{ id: "3", text: "text3" }
]
},
items: {
id: "items",
list: []
},
area1: {
id: "area1",
list: []
},
area2: {
id: "area2",
list: [
{ id: "7", text: "text7" },
{ id: "8", text: "text8" },
{ id: "9", text: "text9" }
]
}
};
range(4, 25).forEach((idx) => {
initialColumns.area1.list.push({
id: idx.toString(),
text: "text" + idx.toString()
});
});
range(24, 60).forEach((idx) => {
initialColumns.items.list.push({
id: idx.toString(),
text: "text" + idx.toString()
});
});
const [columns, setColumns] = useState(initialColumns);
const onDragEnd = ({ source, destination }) => {
// Make sure we have a valid destination
if (destination === undefined || destination === null) return null;
// Make sure we're actually moving the item
if (
source.droppableId === destination.droppableId &&
destination.index === source.index
)
return null;
// Set start and end variables
const start = columns[source.droppableId];
const end = columns[destination.droppableId];
// If start is the same as end, we're in the same column
if (start === end) {
// Move the item within the list
// Start by making a new list without the dragged item
console.log(start);
const newList = start.list.filter((_, idx) => idx !== source.index);
// Then insert the item at the right location
newList.splice(destination.index, 0, start.list[source.index]);
// Then create a new copy of the column object
const newCol = {
id: start.id,
list: newList
};
// Update the state
setColumns((state) => ({ ...state, [newCol.id]: newCol }));
return null;
} else {
// If start is different from end, we need to update multiple columns
// Filter the start list like before
const newStartList = start.list.filter((_, idx) => idx !== source.index);
// Create a new start column
const newStartCol = {
id: start.id,
list: newStartList
};
// Make a new end list array
const newEndList = end.list;
// Insert the item into the end list
newEndList.splice(destination.index, 0, start.list[source.index]);
// Create a new end column
const newEndCol = {
id: end.id,
list: newEndList
};
// Update the state
setColumns((state) => ({
...state,
[newStartCol.id]: newStartCol,
[newEndCol.id]: newEndCol
}));
return null;
}
};
return (
<DragDropContext onDragEnd={onDragEnd}>
<Grid
container
direction="row"
justifyContent="space-around"
alignItems="stretch"
>
<Grid item xs={1}>
<Column
isLinks={true}
backgroundColor={"lightgreen"}
height={"90vh"}
width={"100%"}
column={columns.links}
key={columns.links.id}
/>
</Grid>
<Grid item xs={1}>
<Column
backgroundColor={"salmon"}
height={"90vh"}
width={"100%"}
column={columns.items}
key={columns.items.id}
/>
</Grid>
<Grid item xs={9}>
<Column
className={"flex-col-scroll"}
height={"42vh"}
width={"100%"}
backgroundColor={"darkorange"}
column={columns.area1}
key={columns.area1.id}
/>
<Column
className={"flex-col-scroll"}
height={"42vh"}
width={"100%"}
backgroundColor={"darkorange"}
column={columns.area2}
key={columns.area2.id}
/>
</Grid>
</Grid>
</DragDropContext>
);
};
export default App;
const useStyles = makeStyles((theme) => ({}));
Column.js
import React from "react";
import { Droppable } from "react-beautiful-dnd";
import RootRef from "#material-ui/core/RootRef";
import List from "#material-ui/core/List";
import ListItemCustom from "./ListItemCustom";
import Typography from "#material-ui/core/Typography";
const Column = ({ isLinks, height, width, backgroundColor, column }) => {
const linksStyle = !isLinks
? {
maxHeight: "85%",
overflow: "auto"
}
: {};
return (
<div
style={{
height: height,
width: width,
backgroundColor: backgroundColor,
margin: 10,
padding: 20,
color: "white"
}}
>
<Typography variant={"h4"}>{column.id}</Typography>
<Droppable droppableId={column.id}>
{(provided) => (
<RootRef rootRef={provided.innerRef}>
<List style={linksStyle}>
{column.list.map((itemObject, index) => {
return <ListItemCustom index={index} itemObject={itemObject} />;
})}
{provided.placeholder}
</List>
</RootRef>
)}
</Droppable>
</div>
);
};
export default Column;
ListItemCustom.js
import React from "react";
import ListItem from "#material-ui/core/ListItem";
import ListItemText from "#material-ui/core/ListItemText";
import ListItemSecondaryAction from "#material-ui/core/ListItemSecondaryAction";
import IconButton from "#material-ui/core/IconButton";
import { Draggable } from "react-beautiful-dnd";
const ListItemCustom = ({ itemObject, index }) => {
return (
<Draggable draggableId={itemObject.id} key={itemObject.id} index={index}>
{(provided) => (
<ListItem
key={itemObject.id}
role={undefined}
dense
button
ContainerComponent="li"
ContainerProps={{ ref: provided.innerRef }}
{...provided.draggableProps}
{...provided.dragHandleProps}
>
<ListItemText
sytles={{ fontFamily: "Quicksand" }}
primary={`${itemObject.text}`}
/>
<ListItemSecondaryAction>
<IconButton
edge="end"
aria-label="comments"
question-uid={itemObject.id}
>
{/* <DeleteIcon /> */}
</IconButton>
</ListItemSecondaryAction>
</ListItem>
)}
</Draggable>
);
};
export default ListItemCustom;
Update 1: added bad scrolling
Update 2: added scrolling and another vertical sidebar like in the architecture
Update 3: reordered layout spacing using material UI grid API
Update 4: added main Code in case code sandbox link breaks

Reactjs material ui Select item inside dialog with weird style

I am trying to create a "Dialog" box which contain a "Select" inside it.
As you can see from image "Select" component is showing item so weird!
I tried to style the items but I couldn't find the way to show item regular (Vertical items with white background color and black foreground color).
I have to mention that I copied the exact code in material ui website for "Dialog" and
"Select"
When I use "Select" inside "Dialog" this weird style happen.
This is my code:
import React, {useState} from 'react';
import {makeStyles, withStyles} from '#material-ui/core/styles';
import Button from '#material-ui/core/Button';
import Dialog from '#material-ui/core/Dialog';
import MuiDialogTitle from '#material-ui/core/DialogTitle';
import MuiDialogContent from '#material-ui/core/DialogContent';
import MuiDialogActions from '#material-ui/core/DialogActions';
import IconButton from '#material-ui/core/IconButton';
import CloseIcon from '#material-ui/icons/Close';
import Typography from '#material-ui/core/Typography';
import Card from "#material-ui/core/Card";
import CardActionArea from "#material-ui/core/CardActionArea";
import CardMedia from "#material-ui/core/CardMedia";
import CardContent from "#material-ui/core/CardContent";
import CardActions from "#material-ui/core/CardActions";
import {Col, Row} from "react-bootstrap";
import {FormControl, InputLabel, MenuItem, Select, TextField} from "#material-ui/core";
const styles = (theme) => ({
root: {
margin: 0,
padding: theme.spacing(2),
},
closeButton: {
position: 'absolute',
right: theme.spacing(1),
top: theme.spacing(1),
color: theme.palette.grey[500],
},
});
const DialogTitle = withStyles(styles)((props) => {
const { children, classes, onClose, ...other } = props;
return (
<MuiDialogTitle disableTypography className={classes.root} {...other}>
<Typography variant="h6">{children}</Typography>
{onClose ? (
<IconButton aria-label="close" className={classes.closeButton} onClick={onClose}>
<CloseIcon />
</IconButton>
) : null}
</MuiDialogTitle>
);
});
const DialogContent = withStyles((theme) => ({
root: {
padding: theme.spacing(2),
},
}))(MuiDialogContent);
const DialogActions = withStyles((theme) => ({
root: {
margin: 0,
padding: theme.spacing(1),
},
}))(MuiDialogActions);
export default function SdWanDialog(props) {
const {
status,
handleClose,
company
} = props;
const useStyles2 = makeStyles((theme) => ({
formControl: {
margin: theme.spacing(1),
minWidth: 185,
},
selectEmpty: {
marginTop: theme.spacing(2),
},
}));
const classes2 = useStyles2();
const [subnet, setSubnet] = useState('');
const handleChange = (event) => {
setSubnet(event.target.value);
};
return (
<div>
{/*<Button variant="outlined" color="primary" onClick={handleClickOpen}>*/}
{/* Open dialog*/}
{/*</Button>*/}
<Dialog onClose={handleClose} aria-labelledby="customized-dialog-title" open={status}>
<DialogTitle id="customized-dialog-title" onClose={handleClose}>
TITLE
</DialogTitle>
<DialogContent >
<Row>
<Col>
<FormControl variant="outlined">
<InputLabel id="select-label">Subnet</InputLabel>
<Select
labelId="select-label"
id="select-id"
value={subnet}
onChange={handleChange}
label="Subnet"
>
<MenuItem value=""><em>None</em></MenuItem>
<MenuItem value={'value1'}>value1</MenuItem>
<MenuItem value={'value2'}>value2</MenuItem>
<MenuItem value={'value3'}>value3</MenuItem>
</Select>
<br/>
<TextField
id="branchName"
label="Branch name"
variant="outlined"
color="primary"
/>
</FormControl>
</Col>
</Row>
</DialogContent>
<DialogActions>
<Button onClick={handleClose} variant="contained" color="primary">
Save changes
</Button>
</DialogActions>
</Dialog>
</div>
);
}

Element positioned absolute inside Dialog Material UI React

I have Dialog component where I have a button(bottom right corner) which shows another div with an item list. The problem I'm facing is that the list is being rendered inside the Dialog component and it's being cropped. I set the position: absolute, z-index and set the position: relative to the parent but it does not work. Here is how it looks like. Any helpful tips I would appreciate it.
1) Before I click the button to show the list
2) After I click the button. Highlighted css properties for the list element
And the code for Dialog component :
import React, { useState } from "react";
import { makeStyles } from "#material-ui/core";
import Button from "#material-ui/core/Button";
import Dialog from "#material-ui/core/Dialog";
import DialogContent from "#material-ui/core/DialogContent";
import DialogContentText from "#material-ui/core/DialogContentText";
import DialogTitle from "#material-ui/core/DialogTitle";
import IconButton from "#material-ui/core/IconButton";
import CloseIcon from "#material-ui/icons/Close";
import Typography from "#material-ui/core/Typography";
import OutlinedInput from "#material-ui/core/OutlinedInput";
import { ProjectTreeWindow } from "../index";
const useStyles = makeStyles(theme => ({
addTaskButton: {
marginTop: 10
},
dialog: {
width: "40%",
maxHeight: 435
},
closeButton: {
position: "absolute",
right: theme.spacing(1),
top: theme.spacing(1),
color: theme.palette.grey[500]
},
controlsWrapper: {
display: "flex",
alignItems: "center",
justifyContent: "space-between"
}
}));
const AddQuickTaskDialog = props => {
const classes = useStyles(props);
const { open, close } = props;
const [quickTaskDescription, setQuickTaskDescription] = useState("");
const [textInputRef, setTextInputRef] = useState(null);
const handleChangeQuickTaskDescription = event => {
setQuickTaskDescription(event.target.value);
};
const handleAddQuickTaskSubmit = () => {
alert("Quick task submitted");
close(textInputRef);
};
return (
<Dialog
data-testid="add-task-quick"
classes={{
paper: classes.dialog
}}
maxWidth="lg"
open={open}
keepMounted
onClose={() => {
close(textInputRef);
}}
aria-labelledby="quick-task-dialog"
aria-describedby="quick-task-dialog-description"
>
<DialogTitle id="quick-task-dialog-title">
<Typography variant="h6">Quick Add Task</Typography>
{close ? (
<IconButton
aria-label="close"
className={classes.closeButton}
onClick={() => {
close(textInputRef);
}}
>
<CloseIcon />
</IconButton>
) : null}
</DialogTitle>
<DialogContent>
<div className={classes.wrapper}>
<OutlinedInput
onChange={handleChangeQuickTaskDescription}
inputRef={input => {
setTextInputRef(input);
return input && input.focus();
}}
fullWidth
// className={showAddTaskInput ? classes.show : classes.hide}
placeholder="e.g. Take the dog out for a walk"
inputProps={{ "aria-label": "add task" }}
/>
<div className={classes.controlsWrapper}>
<Button
className={classes.addTaskButton}
disabled={quickTaskDescription.length === 0}
data-testId="quick-add-task-submit"
// onClick={handleAddTaskSubmit}
color="primary"
onClick={handleAddQuickTaskSubmit}
>
Add Task
</Button>
<ProjectTreeWindow />
</div>
</div>
</DialogContent>
</Dialog>
);
};
export default AddQuickTaskDialog;
and for the List component:
import React, { useState } from "react";
import { makeStyles } from "#material-ui/core";
import ListAltTwoToneIcon from "#material-ui/icons/ListAltTwoTone";
import IconButton from "#material-ui/core/IconButton";
import { CustomizedToolTip } from "../index";
import OutlinedInput from "#material-ui/core/OutlinedInput";
import DoneTwoToneIcon from "#material-ui/icons/DoneTwoTone";
import List from "#material-ui/core/List";
import ListItem from "#material-ui/core/ListItem";
import ListItemIcon from "#material-ui/core/ListItemIcon";
import ListItemText from "#material-ui/core/ListItemText";
import FiberManualRecordTwoToneIcon from "#material-ui/icons/FiberManualRecordTwoTone";
import { useProjectsValue, useSelectedProjectValue } from "../../context";
const useStyles = makeStyles(theme => ({
root: {
position: "absolute",
zIndex: 9999,
top: 200,
left: 0,
display: "flex",
flexDirection: "column",
"&:hover $child": {
visibility: "visible"
}
},
wrapper: {
position: "relative !important"
},
selected: {
"& $child": {
visibility: "visible !important"
}
},
hidden: {
visibility: "hidden"
},
listItemIcon: {
minWidth: 30
}
}));
const ProjectTreeWindowList = props => {
const [textInputRef, setTextInputRef] = useState(null);
const [typeProject, setTypedProject] = useState("");
const classes = useStyles(props);
const { projects } = useProjectsValue();
return (
<div className={classes.root}>
<OutlinedInput
// onChange={handleChangeQuickTaskDescription}
inputRef={input => {
setTextInputRef(input);
return input && input.focus();
}}
placeholder="Type a project"
inputProps={{ "aria-label": "select project" }}
/>
<List>
{projects &&
projects.map((project, index) => (
<ListItem
onClick={() => {
alert("move selected project to input");
}}
// selected={active === project.projectId}
button
// classes={{
// root: classes.root,
// selected: classes.selected
// }}
>
<ListItemIcon
className={classes.listItemIcon}
style={{ color: project.color }}
>
<FiberManualRecordTwoToneIcon />
</ListItemIcon>
<ListItemText primary={project.name} />
<ListItemIcon
className={`${classes.listItemIcon} ${classes.hidden}`}
>
<DoneTwoToneIcon />
</ListItemIcon>
</ListItem>
))}
</List>
</div>
);
};
const ProjectTreeWindow = props => {
const classes = useStyles(props);
const [showProjectTreeWindow, setShowProjectTreeWindow] = useState(false);
const handleShowProjectWindow = () => {
setShowProjectTreeWindow(!showProjectTreeWindow);
};
const handleCloseProjectWindow = () => {
setShowProjectTreeWindow(false);
};
return (
<div className={classes.wrapper}>
<CustomizedToolTip title="Select a project">
<IconButton onClick={handleShowProjectWindow} aria-label="add-project">
<ListAltTwoToneIcon />
</IconButton>
</CustomizedToolTip>
{showProjectTreeWindow ? <ProjectTreeWindowList /> : null}
</div>
);
};
export default ProjectTreeWindow;
It is because of the combinaison of position: relative and overflow-y: auto from the <Paper> component. If you override one of this property, it won't be hidden anymore.
To do this, there is a PaperProps property in <Dialog>.
Example:
<Dialog {...otherProps} PaperProps={{style: {position: 'static'} }}/>

Extra Line coming inside Textfield component of material-ui with outlined borders

I am trying to use Textfield component of material ui package. I am using variant="outlined" property of it. But inside that Textfield line is also coming so looks bad from ui prespective.
Any idea how to show only ouline boundary.
(source: imggmi.com)
I guess Textfield by default puts that line. Its is the line just below Phone*.
import React, { Component } from "react";
import { connect } from "react-redux";
import { signIn } from "../../store/actions/authActions";
import { trySignUp } from "../../store/actions/authActions";
import { Redirect } from "react-router-dom";
import Container from "#material-ui/core/Container";
import CssBaseline from "#material-ui/core/CssBaseline";
import Avatar from "#material-ui/core/Avatar";
import Typography from "#material-ui/core/Typography";
import LockOutlinedIcon from "#material-ui/icons/LockOutlined";
import { withStyles } from "#material-ui/styles";
import FormControlLabel from "#material-ui/core/FormControlLabel";
import Checkbox from "#material-ui/core/Checkbox";
import TextField from "#material-ui/core/TextField";
import Button from "#material-ui/core/Button";
class SignIn extends Component {
render() {
const { authError, auth, classes } = this.props;
if (auth.uid) return <Redirect to="/" />;
return (
<Container component="main" maxWidth="xs">
<CssBaseline />
<div className={classes.paper}>
<Avatar className={classes.avatar}>
<LockOutlinedIcon />
</Avatar>
<Typography component="h1" variant="h5">
Sign in
</Typography>
<form onSubmit={this.handleSubmit} className={classes.form}>
{!this.state.isOTPSent && (
<TextField
variant="outlined"
margin="normal"
required
fullWidth
type="tel"
id="phone"
label="Phone"
name="phone"
autoComplete="phone"
autoFocus
onChange={this.handleChange}
/>
)}
{this.state.isOTPSent && (
<TextField
variant="outlined"
margin="normal"
required
fullWidth
id="otp"
label="OTP"
name="otp"
autoFocus
onChange={this.handleChange}
/>
)}
<FormControlLabel
control={<Checkbox value="remember" color="primary" />}
label="Remember me"
/>
<div className="input-field">
<Button
type="submit"
fullWidth
variant="contained"
color="primary"
id="loginButtonId"
onClick={this.state.isOTPSent ? this.handleSubmit : null}
className={classes.submit}
>
{this.state.isOTPSent ? "Login" : "Get OTP"}
</Button>
<div className="red-text center">
{authError ? <p>{authError}</p> : null}
</div>
</div>
</form>
</div>
</Container>
);
}
}
const styles = theme => ({
"#global": {
body: {
backgroundColor: "white"
}
},
paper: {
marginTop: 50,
display: "flex",
flexDirection: "column",
alignItems: "center"
},
avatar: {
margin: 1,
backgroundColor: "red"
},
form: {
width: "100%", // Fix IE 11 issue.
marginTop: 1
},
submit: {
margin: (3, 0, 2)
}
});
const mapStateToProps = state => {
return {
authError: state.auth.authError,
auth: state.firebase.auth
};
};
const mapDispatchToProps = dispatch => {
return {
signIn: phoneNumber => dispatch(signIn(phoneNumber)),
trySignUp: () => dispatch(trySignUp())
};
};
export default connect(
mapStateToProps,
mapDispatchToProps
)(withStyles(styles)(SignIn));
Need to remove the line.

How to increase the vertical spacing between a Material UI FormLabel and Slider?

I'm working on a map with an image overlay that has adjustable opacity. Here is the component code:
import React from 'react'
import PropTypes from 'prop-types'
import { MapWithGroundOverlay } from './MapWithGroundOverlay'
import { withStyles } from '#material-ui/core/styles'
import Box from '#material-ui/core/Box'
import FormLabel from '#material-ui/core/FormLabel'
import Slider from '#material-ui/lab/Slider'
import Grid from '#material-ui/core/Grid'
import Paper from '#material-ui/core/Paper'
const styles = theme => ({
root: {
flexGrow: 1,
},
paper: {
padding: theme.spacing(2),
textAlign: 'center',
color: theme.palette.text.secondary,
},
label: {
padding: theme.spacing(3),
}
})
class AdjustableGroundoverlay extends React.PureComponent {
constructor(props, context) {
super(props, context)
this.state = {opacity: 0.5}
this.handleChange = this.handleChange.bind(this);
}
handleChange(event, value) {
this.setState(state => ({
opacity: value
}));
}
render() {
return (
<Grid container className={this.props.classes.root} spacing={2}>
<Grid item xs={12}>
<MapWithGroundOverlay
googleMapURL={`https://maps.googleapis.com/maps/api/js?key=${process.env.REACT_APP_GOOGLE_MAPS_API_KEY}&v=3.exp&libraries=geometry,drawing,places`}
loadingElement={<div style={{ height: `100%` }} />}
containerElement={<div style={{ height: `600px` }} />}
mapElement={<div style={{ height: `100%` }} />}
opacity={this.state.opacity}
/>
</Grid>
<Grid item xs={6}>
<Paper className={this.props.classes.paper}>
<Box flexDirection="column">
<FormLabel className={this.props.classes.label}>Overlay opacity</FormLabel>
<Slider
value={this.state.opacity}
min={0}
max={1}
onChange={this.handleChange}
/>
</Box>
</Paper>
</Grid>
</Grid>
);
}
}
AdjustableGroundoverlay.propTypes = {
classes: PropTypes.object.isRequired,
}
export default withStyles(styles)(AdjustableGroundoverlay)
The problem is that the FormLabel and Slider are too close together. If I hover over them, I see that the Slider has a negative margin of -24px:
It seems like the content of the FormLabel therefore sits directly on top of it:
I've tried to change the styling of the Slider by adding these classes to the component in accordance with https://material-ui.com/api/slider/#css:
<Slider
classes={{container: {marginTop: -12}}}
value={this.state.opacity}
min={0}
max={1}
onChange={this.handleChange}
/>
but the spacing between the FormLabel and the Slider remains the same. Any idea what is wrong with this implementation?
Update
I've noticed in the console that there is this error:
I'm not sure why the key 'container' is not valid though since it is mentioned in https://material-ui.com/api/slider/#css.
I resolved this by putting the slider in a Box with mt set to 1:
<Paper className={this.props.classes.paper}>
<Box flexDirection="column">
<FormLabel className={this.props.classes.label}>Overlay opacity</FormLabel>
<Box mt={1}>
<Slider
value={this.state.opacity}
min={0}
max={1}
onChange={this.handleChange}
/>
</Box>
</Box>
</Paper>
Now there is more spacing between the label and the slider:

Resources