how to change only current component style on hover - reactjs

I have a requirement where I need to highlight the component on hover
I have two styles defined baseStyle and highlight
<div style={{ background: '#fff' }}>
<div
onMouseEnter={(e) => setToolStyle({ ...baseStyle, ...highlight })}
onMouseLeave={e => setToolStyle(baseStyle)}
style={toolStyle}>
<FontAwesomeIcon icon={faMousePointer} style={{ fontSize: "20px" }} />
</div>
<div
onMouseEnter={(e) => setToolStyle({ ...baseStyle, ...highlight })}
onMouseLeave={e => setToolStyle(baseStyle)}
style={toolStyle}>
<FontAwesomeIcon icon={faMousePointer} style={{ fontSize: "20px" }} />
</div>
</div>
Expected Output:
on hovering any of the component only that component must be highlighted(i.e just need to add highlight css class to it).
but right now all the component is getting highlighted because of toolStyle state. can anyone help me on this by giving some logic.

Here is an example
you can create a small component with the highlight effect
and use it component any number of times and from anywhere
(As I said in comments )
https://codesandbox.io/s/laughing-mclaren-4i8en?file=/src/highlight.js
child.js
import { useState } from "react";
const baseStyle = { color: "black", fontSize: 14 };
const highlight = { color: "red" };
export default function Highlight({ text }) {
const [toolStyle, setToolStyle] = useState(baseStyle);
return (
<div
onMouseEnter={(e) => setToolStyle({ ...baseStyle, ...highlight })}
onMouseLeave={(e) => setToolStyle(baseStyle)}
style={toolStyle}
>
{text}
</div>
);
}
parent.js
import Highlight from "./highlight";
import "./styles.css";
export default function App() {
return (
<div>
<Highlight text="text 1" />
<Highlight text="text 2" />
<Highlight text="text 3" />
</div>
);
}
This is the best way to implement this with code reusability and
less of code duplication

You can do something like this:
export default function App() {
let [hovered, setHovered] = React.useState({ div1: false, div2: false });
return (
<div>
<div
className={hovered.div1 ? 'hovered' : ''}
onMouseEnter={(e) => setHovered((ps) => ({ ...ps, div1: true }))}
onMouseLeave={(e) => setHovered((ps) => ({ ...ps, div1: false }))}
>
Hello
</div>
<div
className={hovered.div2 ? 'hovered' : ''}
onMouseEnter={(e) => setHovered((ps) => ({ ...ps, div2: true }))}
onMouseLeave={(e) => setHovered((ps) => ({ ...ps, div2: false }))}
>
Hello
</div>
</div>
);
}

You can move your styles to CSS file and avoid extra complexity:
App.js
import { FontAwesomeIcon } from "#fortawesome/react-fontawesome";
import { faCoffee } from "#fortawesome/free-solid-svg-icons";
import "./App.css";
function App() {
return (
<div className="wrapper">
<div>
<FontAwesomeIcon icon={faCoffee} />
</div>
<div>
<FontAwesomeIcon icon={faCoffee} />
</div>
</div>
);
}
export default App;
App.css
.wrapper {
background: #fff;
}
.wrapper > div {
color: red;
font-size: 20px;
}
.wrapper > div:hover {
color: green;
cursor: pointer;
}

Related

How can I change two different buttons' text if I switch between two language buttons?

My main problem is that when I switch from "ENG" to "HUN" button, the "Home" and the "New Game" text button don't transform to the Hungarian equivalent.
{ LangButton } component switches "ENG" to "HUN". When the "HUN" button active, should transform any innerText. Those innerText changes are stored in { languages } object, what is also a different js file.
Buttons
Current codes are here, LangButton used as a Child component in Header.js file;
LangButton.js file:
import React from 'react';
import ".././Header_module.css";
export const LangButton = ({ hunLang, setHunLang, num, text, onClick }) => (
<button
onClick={() => setHunLang(num)}
className="button"
style={{
backgroundColor: hunLang === num ? 'white' : 'black',
color: hunLang === num ? 'red' : 'rgb(112, 255, 0)',
borderRadius: num === 1 ? '5px 0 0 5px' : '0 5px 5px 0',
marginRight: num === 2 ? '10px' : '0px',
onClick: {onClick}
}}
>
{text}
</button>
);
Header.js file:
import "./Header_module.css";
import React, { useState } from "react";
import { LangButton } from "./Language/LangButton";
import { languages } from ".././languages";
const Header = (props) => {
const [hunLang, setHunLang] = useState(1);
const [homeButton, setHomeButton] = useState(languages.en.home_btn);
const [newGameButton, setNewGameButton] = useState(languages.en.new_game_btn);
const engButtonClick = () => {
setHomeButton(languages.en.home_btn);
setNewGameButton(languages.en.new_game_btn);
};
const hunButtonClick = () => {
setHomeButton(languages.hu.home_btn);
setNewGameButton(languages.hu.new_game_btn);
};
return (
<div className="header-bg">
<div className="btn-container">
<button className="button">{homeButton}</button>
<button className="button">{newGameButton}</button>
<LangButton
hunLang={hunLang}
setHunLang={setHunLang}
num={1}
text="ENG"
onClick={engButtonClick}
/>
<LangButton
hunLang={hunLang}
setHunLang={setHunLang}
num={2}
text="HUN"
onClick={hunButtonClick}
/>
</div>
</div>
);
};
export default Header;
You have added two onClick handlers including one inside a style block of LangButton component.
It works after fixing it:
const languages = {
en: {
home_btn: "Home",
new_game_btn: "Game"
},
hu: {
home_btn: "Home hu",
new_game_btn: "Game hu"
}
};
const LangButton = ({ hunLang, num, text, onClick }) => (
<button
onClick={onClick}
className="button"
style={{
backgroundColor: hunLang === num ? "white" : "black",
color: hunLang === num ? "red" : "rgb(112, 255, 0)",
borderRadius: num === 1 ? "5px 0 0 5px" : "0 5px 5px 0",
marginRight: num === 2 ? "10px" : "0px"
}}
>
{text}
</button>
);
const Header = (props) => {
const [hunLang, setHunLang] = React.useState(1);
const [homeButton, setHomeButton] = React.useState(languages.en.home_btn);
const [newGameButton, setNewGameButton] = React.useState(
languages.en.new_game_btn
);
const engButtonClick = () => {
setHunLang(1);
setHomeButton(languages.en.home_btn);
setNewGameButton(languages.en.new_game_btn);
};
const hunButtonClick = () => {
setHunLang(2);
setHomeButton(languages.hu.home_btn);
setNewGameButton(languages.hu.new_game_btn);
};
return (
<div className="header-bg">
<div className="btn-container">
<button className="button">{homeButton}</button>
<button className="button">{newGameButton}</button>
<LangButton
hunLang={hunLang}
setHunLang={setHunLang}
num={1}
text="ENG"
onClick={engButtonClick}
/>
<LangButton
hunLang={hunLang}
setHunLang={setHunLang}
num={2}
text="HUN"
onClick={hunButtonClick}
/>
</div>
</div>
);
};
ReactDOM.render(<Header />, document.querySelector('.react'));
<script crossorigin src="https://unpkg.com/react#16/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom#16/umd/react-dom.development.js"></script>
<div class='react'></div>

using a value through react components

I'm new to React and been struggling with new challenges. Please write me your opinion and help me to get out of this challenge. I need to take the input value and append it in list area. Basically getting that state.inputValue and append it in ul of listArea.
This is InputTask component.
import React from 'react';
class InputTask extends React.Component {
state = { inputValue: ''}
onInputSubmit = (e) => {
this.setState({inputValue: e.target.value})
}
handleSubmit = (e) => {
e.preventDefault();
console.log('A name was submitted: ' + this.state.inputValue);
}
render() {
return (
<form className="ui input" onSubmit={this.handleSubmit} style={{marginRight:10}}>
<input type="text" value={ this.state.inputValue } onChange={this.onInputSubmit}/>
</form>
)
}
}
export default InputTask;
And this is listArea component.
import React from 'react';
class ListArea extends React.Component{
render() {
const style={
backgroundColor: "#f5d556",
height: "400px",
padding: "40px",
borderRadius: "20px"
};
const listStyle = {
backgroundColor: "green",
color: "white",
listStyle: "none",
textAlign: "left",
padding: "5px",
marginBottom: "10px",
borderRadius: "5px"
}
const iconStyle = {
float: "right"
}
const labelStyle = {
color: "white"
}
return(
<div className="ui form" style={{marginBottom:10}}>
<div className="field">
<div style={style}>
<ul style={{paddingLeft: 0}}>
<li style={listStyle}>
<div className="ui checkbox">
<input type="checkbox" name="example"/>
<label style={labelStyle}> hello there!</label>
</div>
<i className="white trash icon" style={iconStyle}></i>
</li>
</ul>
</div>
</div>
</div>
)
}
}
export default ListArea;
this is App component
import React from 'react';
import ReactDOM from 'react-dom';
import InputTask from "./components/inputTask";
import ListArea from "./components/listArea";
class App extends React.Component {
render() {
return (
<div className="ui container" style={{textAlign:'center'}}>
<h1>Tasks</h1>
<ListArea />
<InputTask />
</div>
);
}
}
ReactDOM.render(<App />,document.getElementById('root'));
In InputTask component at handleSubmit with this.props.InputSelected(this.state.inputValue);
I sent back selected input to it's parent(App.js)
import React from "react";
class InputTask extends React.Component {
state = { inputValue: "" };
onInputSubmit = (e) => {
this.setState({ inputValue: e.target.value });
};
handleSubmit = (e) => {
e.preventDefault();
console.log("A name was submitted: " + this.state.inputValue);
this.props.InputSelected(this.state.inputValue);
this.setState({ inputValue: "" });
};
render() {
return (
<form
className="ui input"
onSubmit={this.handleSubmit}
style={{ marginRight: 10 }}
>
<input
type="text"
value={this.state.inputValue}
onChange={this.onInputSubmit}
/>
</form>
);
}
}
export default InputTask;
In App component I got selected value with handleInputSelected and added it to list to send to ListArea component
import React from "react";
import InputTask from "./components/inputTask";
import ListArea from "./components/listArea";
class App extends React.Component {
state = { list: [] };
handleInputSelected = (input) => {
const { list } = { ...this.state };
list.push(input);
this.setState(list);
};
render() {
return (
<div className="ui container" style={{ textAlign: "center" }}>
<h1>Tasks</h1>
<ListArea list={this.state.list} />
<InputTask InputSelected={(input) => this.handleInputSelected(input)} />
</div>
);
}
}
export default App;
And finally in ListArea component with map on list I just append li element to ul.
import React from "react";
class ListArea extends React.Component {
render() {
console.log("data: ", this.props.data);
const style = {
backgroundColor: "#f5d556",
height: "400px",
padding: "40px",
borderRadius: "20px",
overflow: "scroll"
};
const listStyle = {
backgroundColor: "green",
color: "white",
listStyle: "none",
textAlign: "left",
padding: "5px",
marginBottom: "10px",
borderRadius: "5px"
};
const iconStyle = {
float: "right"
};
const labelStyle = {
color: "white"
};
console.log(this.props.data);
return (
<div className="ui form" style={{ marginBottom: 10 }}>
<div className="field">
<div style={style}>
<ul style={{ paddingLeft: 0 }}>
<li style={listStyle}>
<div className="ui checkbox">
<input type="checkbox" name="example" />
<label style={labelStyle}> hello there!</label>
</div>
<i className="white trash icon" style={iconStyle}></i>
</li>
{this.props.list.map((m) => (
<li style={listStyle}>
<div className="ui checkbox">
<input type="checkbox" name="example" />
<label style={labelStyle}> {m}</label>
</div>
<i className="white trash icon" style={iconStyle}></i>
</li>
))}
</ul>
</div>
</div>
</div>
);
}
}
export default ListArea;

How to get ref of google-maps-react map and panto to latlng

My objective is to pan google-maps-react map to a latlng position, after getting a latlong from react-places-autocomplete when a user selects an address suggestion.
I am facing difficulty in setting ref of map from a child functional component, so that I can call map.panTo(location) in the parent functional component.
Following is my Google-Maps and PlaceAutoComplete child Component:
import React, { useEffect } from 'react';
import { Map, GoogleApiWrapper, Marker } from 'google-maps-react';
import { FormGroup, Label, Input, Spinner, Container, Row, Col } from 'reactstrap';
import PlacesAutocomplete from 'react-places-autocomplete';
const InputAndMap = React.forwardRef((props, ref) => {
return (
<div>
<PlacesAutocomplete
value={props.address}
onChange={props.handleInputChange}
onSelect={props.handleInputSelect}
>
{({ getInputProps, suggestions, getSuggestionItemProps, loading }) => (
<div>
<FormGroup>
<Label for="exampleSearch">Search Address</Label>
<Input
{...getInputProps({
className: 'location-search-input',
})}
type="search"
name="search"
id="exampleSearch"
placeholder="Enter Store Location"
/>
</FormGroup>
<div className="autocomplete-dropdown-container">
{loading && (
<div>
<Spinner size="sm" color="primary" />
Loading...
</div>
)}
{suggestions.map(suggestion => {
const className = suggestion.active ? 'suggestion-item--active' : 'suggestion-item';
const style = suggestion.active
? { backgroundColor: '#007bff', cursor: 'pointer', color: 'white' }
: { backgroundColor: '#ffffff', cursor: 'pointer' };
return (
<div
{...getSuggestionItemProps(suggestion, {
className,
style,
})}
>
<span>{suggestion.description}</span>
</div>
);
})}
</div>
</div>
)}
</PlacesAutocomplete>
<Row className="mb-3" style={{ width: '100%', height: '200px' }}>
<Col>
<Map
id="google-map"
ref={ref} // <<=== setting ref here
style={{ width: '100%', height: '200px' }}
google={props.google}
zoom={8}
initialCenter={{ lat: 47.444, lng: -122.176 }}
onClick={(t, map, e) => props.updateMarker(e.latLng, map)}
>
{props.markerLatLong && <Marker position={props.markerLatLong} />}
</Map>
</Col>
</Row>
</div>
);
});
export default GoogleApiWrapper({
apiKey: process.env.REACT_APP_GOOGLE_API_KEY,
libraries: ['places'],
})(InputAndMap);
This is my parent component, where I want to call the map panto function.
import React, { useState, useEffect } from 'react';
import { Button, Form, Spinner, Container } from 'reactstrap';
import { Redirect } from 'react-router-dom';
import { geocodeByAddress, getLatLng } from 'react-places-autocomplete';
import firebase from 'firebase/app';
import NavBarMenu from '../components/NavBarMenu';
import InputAndMap from '../components/InputAndMap';
import fire from '../config/fire';
function StoreScreen(props) {
const [isLoading, setIsLoading] = useState(false);
const [markerLatLong, setMarkerLatLong] = useState(null);
const [city, setCity] = useState('');
const [address, setAddress] = useState('');
const [redirect, setRedirect] = useState(false);
const ref = React.createRef();
const handleInputChange = address => {
setAddress(address);
};
const handleInputSelect = address => {
setAddress(address);
geocodeByAddress(address)
.then(results => {
processCity(results);
getLatLng(results[0])
.then(latLng => {
console.log('Success', latLng);
console.log(ref);// ==============> this return {current: null}
// ref.current.panTo(latLng);// ==> So I am unable to call this
})
.catch(error => console.error('Error', error));
})
.catch(error => console.error('Error', error));
};
return (
<div>
<NavBarMenu isShopKeeper />
<Container className="h-100">
<Form onSubmit={handleSubmit}>
<h5 className="text-center">Add Store</h5>
<InputAndMap
ref={ref}
markerLatLong={markerLatLong}
updateMarker={updateMarker}
handleInputChange={handleInputChange}
handleInputSelect={handleInputSelect}
address={address}
/>
{isLoading ? (
<div className="row mx-auto justify-content-center align-items-center flex-column">
<Spinner color="secondary" />
</div>
) : (
<Button
disabled={!markerLatLong || !city || !address}
className="mb-4"
color="primary"
size="lg"
block
>
Add Store
</Button>
)}
</Form>
</Container>
</div>
);
}
export default StoreScreen;
I am also attaching the image for better visualizing my problem.
Map.panTo changes the center of the map to the given LatLng in Maps JavaScript API. Since you are using google-maps-react library, you can use react states as value of the center parameter of this library to change the value of the Map's center everytime the state changes. In my example code below, I use the code from the getting started docs of react-places-autocomplete and incorporated it with a simple google-maps-react code.
Here's how I declare the state of the center which currently have a value:
state = {
center: {
lat: 40.854885,
lng: -88.081807
},
address: ""
};
Here's the handleSelect event from the react-places-autocomplete library where it geocodes the selected place from the autocomplete. Then you can see that I set the state of the center to the latLng of the geocoded address.
handleSelect = address => {
geocodeByAddress(address)
.then(results => getLatLng(results[0]))
.then(latLng => this.setState({ center: latLng }))
.catch(error => console.error("Error", error));
};
Here's how I call the Map component of the google-maps-react library where the value of center parameter is the value of the state named center.
<Map
className="map"
google={this.props.google}
onClick={this.onMapClicked}
center={this.state.center}
style={{ height: "100%", position: "relative", width: "100%" }}
zoom={13}
/>
Here's a complete code snippet and the working code on how I incorporated the 2 libraries you are using to change the center of the map everytime you choose an address from autocomplete:
import React, { Component } from "react";
import { Map, GoogleApiWrapper } from "google-maps-react";
import PlacesAutocomplete, {
geocodeByAddress,
getLatLng
} from "react-places-autocomplete";
export class MapContainer extends Component {
state = {
center: {
lat: 40.854885,
lng: -88.081807
},
address: ""
};
handleChange = address => {
this.setState({ address });
};
handleSelect = address => {
geocodeByAddress(address)
.then(results => getLatLng(results[0]))
.then(latLng => this.setState({ center: latLng }))
.catch(error => console.error("Error", error));
};
render() {
if (!this.props.loaded) return <div>Loading...</div>;
return (
<div>
<PlacesAutocomplete
value={this.state.address}
onChange={this.handleChange}
onSelect={this.handleSelect}
>
{({
getInputProps,
suggestions,
getSuggestionItemProps,
loading
}) => (
<div>
<input
{...getInputProps({
placeholder: "Search Places ...",
className: "location-search-input"
})}
/>
<div className="autocomplete-dropdown-container">
{loading && <div>Loading...</div>}
{suggestions.map(suggestion => {
const className = suggestion.active
? "suggestion-item--active"
: "suggestion-item";
// inline style for demonstration purpose
const style = suggestion.active
? { backgroundColor: "#fafafa", cursor: "pointer" }
: { backgroundColor: "#ffffff", cursor: "pointer" };
return (
<div
{...getSuggestionItemProps(suggestion, {
className,
style
})}
>
<span>{suggestion.description}</span>
</div>
);
})}
</div>
</div>
)}
</PlacesAutocomplete>
<Map
className="map"
google={this.props.google}
center={this.state.center}
style={{ height: "100%", position: "relative", width: "100%" }}
zoom={13}
/>
</div>
);
}
}
export default GoogleApiWrapper({
apiKey: "YOUR_API_KEY"
})(MapContainer);

How can I use two transitions with material ui?

What I'm trying to do is use Fade and Slide in the same component.
<Slide in={isValid} timeout={timeout} direction="left">
<Fade in={isValid} timeout={timeout}>
<Foo />
</Fade>
</Slide>
But it doesn't work.
When isValid is true, it slides the component without the fade effect and when it's false, the component just blinks and disappears.
How can I make it work? I don't want to use makeStyle.
The Slide and the Fade components both change the style.transition property, so if they act on the same element they clobber portions of the other's work.
The way to get this to work is for them to act on different elements. Introducing a div between the two transitions gets the desired behavior.
import React from "react";
import { makeStyles } from "#material-ui/core/styles";
import Switch from "#material-ui/core/Switch";
import Paper from "#material-ui/core/Paper";
import Fade from "#material-ui/core/Fade";
import Slide from "#material-ui/core/Slide";
import FormControlLabel from "#material-ui/core/FormControlLabel";
const useStyles = makeStyles(theme => ({
root: {
height: 180
},
container: {
display: "flex"
},
paper: {
margin: theme.spacing(1),
backgroundColor: "lightblue"
},
svg: {
width: 100,
height: 100
},
polygon: {
fill: theme.palette.primary.main,
stroke: theme.palette.divider,
strokeWidth: 1
}
}));
export default function SlideAndFade() {
const classes = useStyles();
const [checked, setChecked] = React.useState(false);
const handleChange = () => {
setChecked(prev => !prev);
};
return (
<div className={classes.root}>
<FormControlLabel
control={<Switch checked={checked} onChange={handleChange} />}
label="Show"
/>
<div className={classes.container}>
<Slide in={checked} timeout={1000}>
<div>
<Fade in={checked} timeout={1000}>
<Paper elevation={4} className={classes.paper}>
<svg className={classes.svg}>
<polygon
points="0,100 50,00, 100,100"
className={classes.polygon}
/>
</svg>
</Paper>
</Fade>
</div>
</Slide>
</div>
</div>
);
}
I realized that if you wrap the transition in a div or other element to make it as a container, it will work.
<Slide in={isValid} timeout={timeout} direction="left">
<div> // adding this div will make it work
<Fade in={isValid} timeout={timeout}>
<Foo />
</Fade>
</div>
</Slide>
And then you can just create your own Fade component that wraps a div.
const MyFade = React.forwardRef(
({ children, in: In, timeout, ...otherProps }, ref) => {
return (
<div ref={ref} {...otherProps}>
<Fade in={In} timeout={timeout}>
{children}
</Fade>
</div>
);
}
);
Thanks to #Ryan Cogswe that also helped in this.

Full screen drag and drop files in React

In this official example of react-dropzone, a full screen drop zone is achieved by wrapping the whole app inside the <Dropzone /> component. I am creating a multi route app and feel that wrapping everything inside the <Dropzone /> component is not a very clean solution.
Is there a way to create a full screen/page drop zone in React without placing the <Dropzone /> component on the root level?
Create a route to a Dropzone form and adjust the height and size of the field by utilizing CSS.
Working example: https://codesandbox.io/s/l77212orwz (this example uses Redux Form, but you don't have to)
container/UploadForm.js
import React, { Component } from "react";
import { reduxForm } from "redux-form";
import ShowForm from "../components/showForm";
class UploadImageForm extends Component {
state = { imageFile: [] };
handleFormSubmit = formProps => {
const fd = new FormData();
fd.append("imageFile", formProps.imageToUpload[0]);
// append any additional Redux form fields
// create an AJAX request here with the created formData
};
handleOnDrop = newImageFile => this.setState({ imageFile: newImageFile });
resetForm = () => {
this.setState({ imageFile: [] });
this.props.reset();
};
render = () => (
<div style={{ padding: 10 }}>
<ShowForm
handleOnDrop={this.handleOnDrop}
resetForm={this.resetForm}
handleFormSubmit={this.handleFormSubmit}
{...this.props}
{...this.state}
/>
</div>
);
}
export default reduxForm({ form: "UploadImageForm" })(UploadImageForm);
components/showForm.js
import isEmpty from "lodash/isEmpty";
import React from "react";
import { Form, Field } from "redux-form";
import DropZoneField from "./dropzoneField";
const imageIsRequired = value => (isEmpty(value) ? "Required" : undefined);
export default ({
handleFormSubmit,
handleOnDrop,
handleSubmit,
imageFile,
pristine,
resetForm,
submitting
}) => (
<Form onSubmit={handleSubmit(handleFormSubmit)}>
<Field
name="imageToUpload"
component={DropZoneField}
type="file"
imagefile={imageFile}
handleOnDrop={handleOnDrop}
validate={[imageIsRequired]}
/>
<button
type="submit"
className="uk-button uk-button-primary uk-button-large"
disabled={submitting}
>
Submit
</button>
<button
type="button"
className="uk-button uk-button-default uk-button-large"
disabled={pristine || submitting}
onClick={resetForm}
style={{ float: "right" }}
>
Clear
</button>
</Form>
);
components/dropzoneField.js
import React, { Fragment } from "react";
import DropZone from "react-dropzone";
import { MdCloudUpload } from "react-icons/md";
import RenderImagePreview from "./renderImagePreview";
export default ({
handleOnDrop,
input,
imagefile,
meta: { error, touched }
}) => (
<div>
<DropZone
accept="image/jpeg, image/png, image/gif, image/bmp"
className="upload-container"
onDrop={handleOnDrop}
onChange={file => input.onChange(file)}
>
<div className="dropzone-container">
<div className="dropzone-area">
{imagefile && imagefile.length > 0 ? (
<RenderImagePreview imagefile={imagefile} />
) : (
<Fragment>
<MdCloudUpload style={{ fontSize: 100, marginBottom: 0 }} />
<p>Click or drag image file to this area to upload.</p>
</Fragment>
)}
</div>
</div>
</DropZone>
{touched && error && <div style={{ color: "red" }}>{error}</div>}
</div>
);
components/renderImagePreview.js
import map from "lodash/map";
import React from "react";
export default ({ imagefile }) =>
map(imagefile, ({ name, preview, size }) => (
<ul key={name}>
<li>
<img src={preview} alt={name} />
</li>
<li style={{ textAlign: "center" }} key="imageDetails">
{name} - {size} bytes
</li>
</ul>
));
styles.css
.dropzone-container {
text-align: center;
background-color: #efebeb;
height: 100%;
width: 100%;
}
.dropzone-area {
margin: 0;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
.upload-container {
height: 100vh;
width: 100%;
margin-bottom: 10px;
}
ul {
list-style-type: none;
}
p {
margin-top: 0;
}

Resources