button disappear when hovered over - reactjs

i have this image:
so if you can see i have this image and i have created onMouseEnter and onMouseOut so the red cross appears when i get the mouse inside and disappear when the mouse is outside the image. however, this red cross also is a button and has a functionality and whenever i hover on the button it disappears even though i set the state right. my problem is that the button disappear and i don't want that cz it has functionality:
code.js:
const handleOnMouseHover = () => {
const isToggle = true
setToggleDiv(isToggle)
}
const handleOnMouseOut = () => {
const isToggle = false
setToggleDiv(isToggle)
}
<div>
<h3>preview items</h3>
<div className="image">
<img src={Url} onMouseEnter={handleOnMouseHover} onMouseOut={handleOnMouseOut} />
<div>{photoTitle}</div>
{toggleDiv === true?
<div className="delete" type="button" onClick={() => handleDelete(photoId)}>X</div>
:null}
</div>
</div>
code.css:
.image {
position: relative;
width: 50px;
margin: 0px auto;
}
.image .delete {
background-color: red;
width: 30px;
padding: 10px;
color: white;
display: block;
cursor: pointer;
position: absolute;
top: 0;
right: 0;
}
hope you can help

Try to use the onMouseEnter on the div with class "image" instead of the img itself.
Because when you hover the button then the hover from image is removed and onMouseEnter will not work.
Hope it helps

As I understand you need to move your onMouseEnter onMouseOut to the container of image and button, like that:
<h3>preview items</h3>
<div className="image" onMouseEnter={handleOnMouseHover} onMouseOut={handleOnMouseOut}>
<img src={Url} />
<div>{photoTitle}</div>
{toggleDiv === true?
<div className="delete" type="button" onClick={() => handleDelete(photoId)}>X</div>
:null}
</div>

Related

The Dialog component is not closing correctly

I have a problem with the React.js Dialog component which contains a list of items. There is also an overlay in the Dialog. It closes automatically when the user clicks on it. But the scenario is something different. The dialog also includes a list of items that have some external links wrapped around the <a> element and some with the <div>.
But the method of closing the dialog is not working properly. The Dialog automatically closes when I click inside any list item.
Please see this:
My goal was to close the dialog whenever the user clicked on the overlay or whenever the user clicked on the list item wrapped with the <a> element. Otherwise, it should not be closed.
I still can't figure out What is the correct approach to tackle this issue?
CodeSandbox link
App.js
import React, { useState } from 'react';
import Dialog from './Dialog';
import './App.css';
const App = () => {
const [isOpen, setIsOpen] = useState(false);
const onClickHandler = (isFalse) => {
if (!isFalse) {
setIsOpen(false);
} else {
setIsOpen(!isOpen);
}
};
return (
<div>
<button type="button" onClick={onClickHandler}>
Open Dialog
</button>
<Dialog isOpen={isOpen} onClick={onClickHandler} />
</div>
);
};
export default App;
Dialog.js
import React from 'react';
const Dialog = (props) => {
const { isOpen, onClick } = props;
const onCloseHandle = () => {
onClick(false);
};
return (
<div
className={isOpen ? 'dialog-wrap open' : 'dialog-wrap'}
onClick={onCloseHandle}
>
<div className="dialog">
<ul className="dialog-list">
<li>
<a
href="https://reactjs.org"
target="_blank"
rel="noopener noreferrer"
>
React.js
</a>
</li>
<li>
<a
href="https://reactjs.org"
target="_blank"
rel="noopener noreferrer"
>
Another Link
</a>
</li>
<li>
<div>Should Not Close onClick</div>
</li>
<li>
<div>Should Not Close onClick</div>
</li>
</ul>
</div>
</div>
);
};
export default Dialog;
App.css
*,:before,:after {
box-sizing: border-box;
}
.dialog-wrap.open {
display: flex;
}
.dialog-wrap {
display: none;
position: fixed;
top: 0;
right: 0;
bottom: 0;
left: 0;
z-index: 999;
overflow-y: auto;
-webkit-overflow-scrolling: touch;
padding: 16px;
background-color: rgba(0,0,0,0.66);
}
#media (min-width: 640px) {
.dialog-wrap {
padding: 48px 32px;
}
}
#media (min-width: 1024px) {
.dialog-wrap {
padding-left: 40px;
padding-right: 40px;
}
}
.dialog {
position: relative;
margin: auto;
background-color: #fff;
border: 1px solid rgba(0, 0, 0, 0.1);
box-shadow: 0 12px 16px rgba(0, 0, 0, 0.08);
border-radius: 4px;
width: 500px;
}
.dialog-list {
margin-bottom: 0;
padding-left: 0;
color: #333;
list-style: none;
}
.dialog-list > li {
border-bottom: 1px solid #eee;
padding: 24px;
}
.dialog-list > li > a {
color: #333;
display: block;
text-decoration: none;
}
.dialog-list > li > div {
cursor: pointer;
}
in this situation, I would create a .dialog-background element and give onCloseHandle to that.
I also hive my a elements the onCloseHandle as onClick prop as well
If you do not want to change your react tree you can decide that from the event like this:
<div
className={isOpen ? "dialog-wrap open" : "dialog-wrap"}
onClick={(e) => {
if (!e.target.closest('.dialog') || e.target.closest('a')) {
onClick(false)
}
}}
/>
I think your click event is propagating up the elements, and triggering onCloseHandle on your .dialog-wrap.
The simplest solution to this would be to use Event.stopPropagation() on the <div className="dialog">
E.g.
<div className="dialog" onClick={ e => e.stopPropagation() }>
(React technically uses "synthetic events", but they still include a stopPropagation option as long as it's being interacted with inside React)

How to stop the jumping jack of text change in React

How to smoothly transition from text to svg in react.
As soon as I click on next button shown in pic as ">" ,the text changes to svg.But there is some sort of jumping due to change in overall height.
How can I smoothly transition between two.
Note: Unfortunately, I can't share the code as this is not a personal
project.
You can set the height of the containing element to the heighest element. Therefore you need to place them in a row with a negative margin-right so that they overlay each other. Only the element that you make visible will be shown when you hide the other elements with visibility: hidden;
Here is an example:
var elements = document.querySelectorAll('.block__element');
document.querySelector('button').addEventListener('click', () => {
elements.forEach(element => {
if(element.classList.contains('block__element--visible')) {
element.classList.remove('block__element--visible');
} else {
element.classList.add('block__element--visible');
}
})
});
.block {
background: #aaa;
display: flex;
}
.block__element {
width: 100%;
margin-right: -100%;
visibility: hidden;
opacity: 0;
transition: visibility 1s, opacity 1s;
}
.block__element--visible {
visibility: visible;
opacity: 1;
}
<div class="block">
<div class="block__element block__element--visible">
<div style="background: #f00">Content 1</div>
</div>
<div class="block__element">
<div style="height: 200px; background: #0f0">Longer content 2</div>
</div>
</div>
<button>Toggle between elements</button>

React styled-component button does not receive focus

React styled-component button does not receive focus
This is some code I inherited (see below). There are rows with a title and corresponding button (Bookmark). Using the tab button I can focus on the title. Upon another tab the focus moves to the styled button, but there is no focus ring. On the next tab the focus goes to the next title with a focus ring, and so on.
Why is the styled.button not receiving focus?
If the IconWrapper styled component (listed below) is replaced with <button></button> then the
icon receives focus and has a focus ring.
<button
ref={node => (this.removeBookmarkBtns[i] = node)}
aria-label="Remove bookmark"
onClick={() => {this.markForRemoval(bookmark, i);}}
>
<BookmarkIcon />
</button>
Inherited code
import styled from "styled-components";
<div>
... irrelevant stuff
<IconWrapper
ref={node => (this.removeBookmarkBtns[i] = node)}
aria-label="Remove bookmark"
onClick={() => {this.markForRemoval(bookmark, i);}}
>
<BookmarkIcon />
</IconWrapper>
... irrelevant stuff
</div>
The associated button styled-components
const IconWrapper = styled.button`
color: ${theme.colors.primary};
font-size: 2em;
cursor: pointer;
margin-left: 10px;
background-color: Transparent;
background-repeat: no-repeat;
border: none;
outline: none;
`;
const BookmarkIcon = styled(Icons.BookmarkCheck)`
display: block;
overflow: visible;
`;
Icon.BookmarkCheck
Icons.BookmarkCheck = props => (
<SVG {...props}>
<path d="m256 512a254.4 ...
</SVG>
);
Have you tried adding tabIndex={0}?
<button
ref={node => (this.removeBookmarkBtns[i] = node)}
aria-label="Remove bookmark"
onClick={() => {this.markForRemoval(bookmark, i);}}
tabIndex={0}
/>
After a bit of rubber ducking it dawned on me that it isn't the styled-component causing the problem, but the CSS of the styled-component.
Remove outline: none and of course it works.

How can I see enlarged image when I click on the actual img

How can I reach to src={img.urls.small} on my image modal view?
It looks like it says img is not defined which is true but I don't know how I can make it work on my Modal view.
const Photos = ({ images }) => {
const [hovered, setHovered] = useState(false);
const Dialog = styled.div`
background: white;
border-radius: 5px;
padding: 20px;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
`;
return (
<section>
<h1>PHOTOGRAPHY</h1>
{images &&
images.map(img => (
<li key={img.id} data-key={img.id} onClick={() => setHovered(true)}>
<img
className="grid__item"
alt={img.alt_description}
src={img.urls.small}
/>
</li>
))}
{hovered && (
<Dialog onClick={() => setHovered(false)}>
<p>
<span role="img" aria-label="tada">
🎉
</span>
</p>
CLOSE MODAL
</Dialog>
)}
</section>
);
};
export default Photos;
I am not sure what the problem ist, but unfortunately I can't comment to ask. I think your are trying to find the right object structure for your images array?
var images = [
{
urls: {
small: "path/to/your/small_image.png",
big: "path/to/your/big_image.png"
}
},
{
urls: {
small: "path/to/your/small_image2.png",
big: "path/to/your/big_image2.png"
}
}
];

React-modal hides behind elements

I am trying to make use of react-modal for the first time. When I click on the sign-in button, the react-modal component is invoke but seems to be hiding behind the cover page which is a video landing page.
The React devtool displays the appropriate states before the sign-in button is clicked
before the sign-in button is clicked
When the sign-in button is now clicked, the react devtool now displays that the ModalPortal component is rendered showing the appropriate states
when the sign-in button is clicked
SignInModal.scss
.ReactModalPortal>div {
opacity: 0;
}
.ReactModalPortal .ReactModal__Overlay {
align-items: center;
display: flex;
justify-content: center;
transition: opacity 200ms ease-in-out;
}
.ReactModalPortal .ReactModal__Overlay--after-open {
opacity: 1;
}
.ReactModalPortal .ReactModal__Overlay--before-close {
opacity: 0;
}
.modal {
position: relative;
background: #464b5e;
color: white;
max-width: 90rem;
outline: none;
padding: 3.2rem;
text-align: center;
}
.modal__title {
margin: 0 0 1.6rem 0;
}
.modal__body {
font-size: 2rem;
font-weight: 300;
margin: 0 0 3.2rem 0;
word-break: break-all;
}
CoverPage.js Component
import Header from './Header';
import HeaderVideo from './HeaderVideo';
import SignInModal from './SignInModal';
import React, { Component } from 'react';
class CoverPage extends Component {
state = {
modalIsOpen: false
};
onOpenModal = () => {
this.setState(() => ({
modalIsOpen: true
}));
};
onCloseModal = () => {
this.setState(() => ({
modalIsOpen: false
}));
};
render() {
return (
<div>
<Header />
<HeaderVideo onOpenModal={this.onOpenModal} />
<SignInModal
modalIsOpen={this.state.modalIsOpen}
onOpenModal={this.onOpenModal}
onCloseModal={this.onCloseModal}
/>
</div>
);
}
}
export default CoverPage;
HeaderVideo.js Component
import React from 'react';
import Signup from './Signup';
import CoverInfo from './CoverInfo';
const HeaderVideo = props => {
return (
<div className="video-container">
<video preload="true" autoPlay loop volume="0" postoer="/images/1.jpg">
<source src="images/vine.mp4" type="video/mp4" />
<source src="images/vine1.webm" type="video/webm" />
</video>
<div className="video-content">
<div className="container content">
<div className="row">
<div className="col-md-9">
<CoverInfo onOpenModal={props.onOpenModal} />
</div>
<div className="col-md-3">
<Signup />
</div>
</div>
</div>
</div>
</div>
);
};
export default HeaderVideo;
CoverInfo.js Component
import React from 'react';
const CoverInfo = props => {
return (
<div className="info">
<div>
<h1>Welcome to EventCity!</h1>
</div>
<div>
<p>
At EventCity! we pride ourselves on the unrivalled personal {`event`} services,we provide
to our clientele. We guide you from the stressful decision making {`process`},ensuring you
are comfortable,whether it is a wedding, corporate {`function `}or even a kiddies party,we
create a buzz around you, taking you to the next level.
</p>
</div>
<div>
<h3>Innovation, {`Performance`} and Delivery</h3>
</div>
<button type="button" className="btn btn-success btn-lg" onClick={props.onOpenModal}>
Sign In here
</button>
</div>
);
};
export default CoverInfo;
video-cover.scss
video {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
min-width: 100%;
min-height: 100%;
width: auto;
height: auto;
z-index: 1;
}
.video-content {
z-index: 2;
position: absolute;
background: rgba(0, 0, 0, 0.6);
top: 0;
bottom: 0;
left: 0;
right: 0;
}
.content {
padding-top: 120px;
}
You need to set the z-index property on the Modal's overlay, which normally has a z-index of 0. The CSS class is .ReactModal__Overlay
Here is the pure-React way of doing it:
const customStyles = {
content : {
...
},
overlay: {zIndex: 1000}
};
<Modal style={customStyles}>
...
</Modal>
.modal {
position: fixed;
z-index:9999;
top :0;
left:0;
right:0;
bottom:0;
background: #464b5e;
color: white;
outline: none;
padding: 3.2rem;
text-align: center;
}
Example of react-modal inline styles Set the styles in the react-modal inline styles. The z-index to 100 but make just like below
style={{
overlay: {
zIndex: 100,
backgroundColor: 'rgba(70, 70, 70, 0.5)',
},

Resources