Infinite scroll/loop/movement of an image array using React - javascript

So I've searched almost everywhere for this, and I guess just the way I've implemented it and want to continue to use it, it's making it difficult to find a solution. Any who I'm trying to have an infinite scroll of the 4 images in my array as slider items. I just don't like the way the component jumps to the first image in the array when it gets to the end. The slider images are controlled by arrows. I'm using styled components so can ignore that code, just wanted to include for full picture of the component.
I think there are packages available to solve this issue, but I would like to know how to code the solution without that assistance. Code below:
import React, { useState } from 'react'
import styled from 'styled-components';
import ArrowLeftIcon from '#mui/icons-material/ArrowLeft';
import ArrowRightIcon from '#mui/icons-material/ArrowRight';
import { sliderItems } from '../data';
import { mobile } from '../responsive';
const Container = styled.div`
width: 100%;
height: 100vh;
display: flex;
position: relative;
overflow: hidden;
`;
const Arrow = styled.div`
width: 50px;
height: 50px;
background-color: #eee;
border-radius: 50%;
display: grid;
place-items: center;
position: absolute;
top: 0;
bottom: 0;
left: ${props => props.direction === "left" && "10px"};
right: ${props => props.direction === "right" && "10px"};
margin: auto;
cursor: pointer;
opacity: 0.5;
z-index: 2;
${mobile({width:"30px", height:"30px"})}
`;
const Wrapper = styled.div`
height: 100%;
display: flex;
transform: translateX(${props =>props.slideIndex * -100}vw);
transition: transform 1.5s ease-in-out;
`;
const Slide = styled.div`
width: 100vw;
height: 100%;
display: flex;
align-items: center;
`;
const ImgContainer = styled.div`
height: 100%;
flex: 1;
`;
const Image = styled.img`
width: 100%;
height: 100%;
object-fit: cover;
`;
const InfoContainer = styled.div`
margin-left: 50px;
flex: 1;
padding: 10px;
${mobile({
display: "none"
})}
`;
const Title = styled.h1`
font-size: 60px;
`;
const Desc = styled.p`
margin: 50px 0px;
font-size: 20px;
font-weight: 500;
`;
const Button = styled.button`
padding: 10px;
font-size: 25px;
background-color: transparent;
cursor: pointer;
border-radius: 4px;
transition: all 0.25s ease;
&:hover {
transform: scale(1.05);
color: white;
background-color: black;
}
`;
const Slider = () => {
const [slideIndex, setSlideIndex] = useState(0);
const handleClick = (direction) => {
if(direction === "left"){
setSlideIndex(slideIndex > 0 ? slideIndex - 1 : 3);
}else{
setSlideIndex(slideIndex < 3 ? slideIndex + 1 : 0);
}
};
return (
<Container>
<Arrow direction="left" onClick={() => handleClick("left")}>
<ArrowLeftIcon />
</Arrow>
<Wrapper slideIndex={slideIndex}>
{sliderItems.map(item => (
<Slide key={item.id}>
<ImgContainer>
<Image src={item.img} alt={item.alt}/>
</ImgContainer>
<InfoContainer>
<Title>{item.title}</Title>
<Desc>{item.desc}</Desc>
<Button>Shop Now</Button>
</InfoContainer>
</Slide>
))}
</Wrapper>
<Arrow direction="right" onClick={() => handleClick("right")}>
<ArrowRightIcon />
</Arrow>
</Container>
)
}
export default Slider;
Any help would be appreciated

Related

How to make React Styled Component Responsive

I got this very beautiful and sleek sign-in/sign-up form with React Styled Component from Youtube. However, it is not responsive. I have tried using my inspector tool to manipulate every single css detail but it just doesn't work.
Should I give up on using the sleek form/ It's the best I've seen so far.
This is the Styled Component.js
import styled from 'styled-components';
export const Container = styled.div`
background-color: #fff;
border-radius: 10px;
box-shadow: 0 14px 28px rgba(0, 0, 0, 0.25), 0 10px 10px rgba(0, 0, 0, 0.22);
position: fixed;
overflow: hidden;
width: 678px;
max-width: 100%;
height: 500px;
`;
export const SignUpContainer = styled.div`
position: absolute;
top: 0;
height: 100%;
transition: all 0.6s ease-in-out;
left: 0;
width: 50%;
opacity: 0;
z-index: 1;
${props => props.signinIn !== true ? `
transform: translateX(100%);
opacity: 1;
z-index: 5;
`
: null}
`;
export const SignInContainer = styled.div`
position: absolute;
top: 0;
height: 100%;
transition: all 0.6s ease-in-out;
left: 0;
width: 50%;
z-index: 2;
${props => (props.signinIn !== true ? `transform: translateX(100%);` : null)}
`;
export const Form = styled.form`
background-color: #ffffff;
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
padding: 0 50px;
height: 100%;
text-align: center;
`;
export const Title = styled.h1`
font-weight: bold;
margin: 0;
`;
export const Input = styled.input`
background-color: #eee;
border: none;
padding: 12px 15px;
margin: 8px 0;
width: 100%;
`;
export const Button = styled.button`
border-radius: 20px;
border: 1px solid #ff4b2b;
background-color: #ff4b2b;
color: #ffffff;
font-size: 12px;
font-weight: bold;
padding: 12px 45px;
letter-spacing: 1px;
text-transform: uppercase;
transition: transform 80ms ease-in;
&:active{
transform: scale(0.95);
}
&:focus {
outline: none;
}
`;
export const GhostButton = styled(Button)`
background-color: transparent;
border-color: #ffffff;
`;
export const Anchor = styled.a`
color: #333;
font-size: 14px;
text-decoration: none;
margin: 15px 0;
`;
export const OverlayContainer = styled.div`
position: absolute;
top: 0;
left: 50%;
width: 50%;
height: 100%;
overflow: hidden;
transition: transform 0.6s ease-in-out;
z-index: 100;
${props =>
props.signinIn !== true ? `transform: translateX(-100%);` : null}
`;
export const Overlay = styled.div`
background: #ff416c;
background: -webkit-linear-gradient(to right, #ff4b2b, #ff416c);
background: linear-gradient(to right, #ff4b2b, #ff416c);
background-repeat: no-repeat;
background-size: cover;
background-position: 0 0;
color: #ffffff;
position: relative;
left: -100%;
height: 100%;
width: 200%;
transform: translateX(0);
transition: transform 0.6s ease-in-out;
${props => (props.signinIn !== true ? `transform: translateX(50%);` : null)}
`;
export const OverlayPanel = styled.div`
position: absolute;
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
padding: 0 40px;
text-align: center;
top: 0;
height: 100%;
width: 50%;
transform: translateX(0);
transition: transform 0.6s ease-in-out;
`;
export const LeftOverlayPanel = styled(OverlayPanel)`
transform: translateX(-20%);
${props => props.signinIn !== true ? `transform: translateX(0);` : null}
`;
export const RightOverlayPanel = styled(OverlayPanel)`
right: 0;
transform: translateX(0);
${props => props.signinIn !== true ? `transform: translateX(20%);` : null}
`;
export const Paragraph = styled.p`
font-size: 14px;
font-weight: 100;
line-height: 20px;
letter-spacing: 0.5px;
margin: 20px 0 30px
`;
This is how I implement it on my Auth2.js (the reason for Auth2 is because I had created an Auth.js but I just want to use this new sign-in/up form which is very sick).
import React from "react";
import Modal from "../Modal/AuthModal";
import * as Components from "./Components";
function Auth2() {
const [signIn, toggle] = React.useState(true);
return (
<Modal>
<Components.Container>
<Components.SignUpContainer signinIn={signIn}>
<Components.Form>
<Components.Title>Create Account</Components.Title>
<Components.Input type="text" placeholder="Name" required />
<Components.Input type="email" placeholder="Email" required />
<Components.Input type="password" placeholder="Password" required />
<Components.Input
type="number"
placeholder="Phone number"
required
/>
<Components.Input type="text" placeholder="Address" required />
<Components.Button>Sign Up</Components.Button>
</Components.Form>
</Components.SignUpContainer>
<Components.SignInContainer signinIn={signIn}>
<Components.Form>
<Components.Title>Sign in</Components.Title>
<Components.Input type="email" placeholder="Email" />
<Components.Input type="password" placeholder="Password" />
<Components.Anchor href="#">
Forgot your password?
</Components.Anchor>
<Components.Button>Sigin In</Components.Button>
</Components.Form>
</Components.SignInContainer>
<Components.OverlayContainer signinIn={signIn}>
<Components.Overlay signinIn={signIn}>
<Components.LeftOverlayPanel signinIn={signIn}>
<Components.Title>Welcome Back!</Components.Title>
<Components.Paragraph>
To keep connected with us please login with your personal info
</Components.Paragraph>
<Components.GhostButton onClick={() => toggle(true)}>
Sign In
</Components.GhostButton>
</Components.LeftOverlayPanel>
<Components.RightOverlayPanel signinIn={signIn}>
<Components.Title>Hello, Friend!</Components.Title>
<Components.Paragraph>
Enter Your personal details and start journey with us
</Components.Paragraph>
<Components.GhostButton onClick={() => toggle(false)}>
Sigin Up
</Components.GhostButton>
</Components.RightOverlayPanel>
</Components.Overlay>
</Components.OverlayContainer>
</Components.Container>
</Modal>
);
}
export default Auth2;
I passed it into a custom Modal.js reusable Component I made;
import { Fragment } from "react";
import classes from "./AuthModal.module.css";
const Backdrop = (props) => {
return <div className={classes.backdrop} onClick={props.onClose} />;
};
const ModalOverlay = (props) => {
return (
<div className={classes.modal}>
<div className={classes.content}>{props.children}</div>
</div>
);
};
const Modal = (props) => {
return (
<Fragment>
<Backdrop onClose={props.onClose} />
<ModalOverlay>{props.children}</ModalOverlay>
</Fragment>
);
};
export default Modal;
The AuthModal.module.css file
.backdrop {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: 20;
background-color: rgba(0, 0, 0, 0.8);
}
.modal {
position: relative;
top: 250px;
left: 5%;
width: 90%;
padding: 1rem;
border-radius: 14px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.25);
z-index: 30;
animation: slide-down 300ms ease-out forwards;
}
#media (min-width: 768px) {
.modal {
width: 40rem;
left: calc(50% - 20rem);
}
}
#keyframes slide-down {
from {
opacity: 0;
transform: translateY(-3rem);
}
to {
opacity: 1;
transform: translateY(0);
}
}
In the styled component, I tried using the display: flex but nothing happened. I also use inspector tool to see if I could manipulate all and sundry --- you guessed it - Nothing happened!
Please how do I make my sign in/out responsive? Please!

When making hover function by 'onMouseEnter' and 'onMouseLeave' function, how can I apply 'onMouseLeave' function at first?

You may not understand the title, but I'll explain what the question is.
I'm trying to make some buttons.
the button is changed when it's hovered.
The button originally selected does not change when other button is hovered, but changes when other button is selected.
I think you can understand what I mean immediately if you look at the code or codesandbox link below.
Question:
As you can see, I used 'onMouseOver' and 'onMouseLeave' function to implement hover.
But, when the component is first rendered, if one button is clicked, other button should change, but it doesn't change.
I'm sure this is because 'onMouseLeave' function is executed when mouse is entered to button at first.
So, when I click other button, the first one doesn't change because I didn't enter it.
I want it to work properly even if I click another button without passing the first button.
How can I modify it??
code
import { useState } from "react";
import styled from "styled-components";
export default function App() {
// declare hover state
const [choonsik, setChoonsik] = useState(true);
const [ryan, setRyan] = useState(false);
const [apeech, setApeech] = useState(false);
// declare click state
const [isChoonsik, setIsChoonsik] = useState(true);
const [isRyan, setIsRyan] = useState(false);
const [isApeech, setIsApeech] = useState(false);
// make click state true
const clickChoonsik = () => {
setIsChoonsik(true);
setIsRyan(false);
setIsApeech(false);
};
const clickRyan = () => {
setIsChoonsik(false);
setIsRyan(true);
setIsApeech(false);
};
const clickApeech = () => {
setIsChoonsik(false);
setIsRyan(false);
setIsApeech(true);
};
// make hover state true
const trueChoonsik = () => {
setChoonsik(true);
};
const trueRyan = () => {
setRyan(true);
};
const trueApeech = () => {
setApeech(true);
};
// make hover state false
const falseChoonsik = () => {
setChoonsik(false);
};
const falseRyan = () => {
setRyan(false);
};
const falseApeech = () => {
setApeech(false);
};
return (
<Wrap
choonsik={choonsik}
ryan={ryan}
apeach={apeech}
isChoonsik={isChoonsik}
isRyan={isRyan}
isApeech={isApeech}
>
<div className="characterWrap">
<ul className="characterWrap__list">
<li className="characterWrap__card">
<div
onMouseEnter={() => {
trueChoonsik();
}}
onMouseLeave={() => {
falseChoonsik();
}}
onClick={() => {
clickChoonsik();
}}
className={`characterWrap__choonsik ${
choonsik || isChoonsik ? "active" : ""
}`}
>
<div
className={`choonsik ${choonsik || isChoonsik ? "active" : ""}`}
/>
춘식이
</div>
</li>
<li className="characterWrap__card">
<div
onMouseEnter={() => {
trueRyan();
}}
onMouseLeave={() => {
falseRyan();
}}
onClick={() => {
clickRyan();
}}
className={`characterWrap__ryan ${
ryan || isRyan ? "active" : ""
}`}
>
<div className={`ryan ${ryan || isRyan ? "active" : ""}`} />
라이언
</div>
</li>
<li className="characterWrap__card">
<div
onMouseEnter={() => {
trueApeech();
}}
onMouseLeave={() => {
falseApeech();
}}
onClick={() => {
clickApeech();
}}
className={`characterWrap__apeach ${
apeech || isApeech ? "active" : ""
}`}
>
<div className={`apeach ${apeech || isApeech ? "active" : ""}`} />
어피치
</div>
</li>
</ul>
</div>
</Wrap>
);
}
const Wrap = styled.div`
position: relative;
width: 1000px;
top: calc(50vh - 100px);
.characterWrap {
padding-bottom: 20px;
margin: 0 auto;
width: 100%;
text-align: center;
}
.characterWrap__list {
display: inline-flex;
list-style: none;
}
.characterWrap__card {
margin: 0 9px;
text-align: center;
float: left;
}
.characterWrap__choonsik {
color: #999;
font-size: 13px;
position: relative;
display: inline-block;
cursor: pointer;
}
.characterWrap__choonsik.active {
color: #333;
font-size: 13px;
position: relative;
display: inline-block;
cursor: pointer;
}
.characterWrap__ryan {
color: #999;
font-size: 13px;
position: relative;
display: inline-block;
cursor: pointer;
}
.characterWrap__ryan.active {
color: #333;
font-size: 13px;
position: relative;
display: inline-block;
cursor: pointer;
}
.characterWrap__apeach {
color: #999;
font-size: 13px;
position: relative;
display: inline-block;
cursor: pointer;
}
.characterWrap__apeach.active {
color: #333;
font-size: 13px;
position: relative;
display: inline-block;
cursor: pointer;
}
.choonsik {
background-position: 0 17.647059%;
background-size: 100%;
display: block;
transition: hover 0.2s;
margin-bottom: 5px;
background-image: url(https://www.kakaofriendsgolf.com/img/v3_img_sprites_friends#3x.png);
background-repeat: no-repeat;
width: 70px;
height: 70px;
}
.choonsik.active {
background-position: 0 11.764706%;
background-size: 100%;
display: block;
transition: hover 0.2s;
margin-bottom: 5px;
background-image: url(https://www.kakaofriendsgolf.com/img/v3_img_sprites_friends#3x.png);
background-repeat: no-repeat;
width: 70px;
height: 70px;
}
.ryan {
background-position: 0 88.235295%;
background-size: 100%;
display: block;
transition: hover 0.2s;
margin-bottom: 5px;
background-image: url(https://www.kakaofriendsgolf.com/img/v3_img_sprites_friends#3x.png);
background-repeat: no-repeat;
width: 70px;
height: 70px;
}
.ryan.active {
background-position: 0 82.352941%;
background-size: 100%;
display: block;
transition: hover 0.2s;
margin-bottom: 5px;
background-image: url(https://www.kakaofriendsgolf.com/img/v3_img_sprites_friends#3x.png);
background-repeat: no-repeat;
width: 70px;
height: 70px;
}
.apeach {
background-position: 0 5.882353%;
background-size: 100%;
display: block;
transition: hover 0.2s;
margin-bottom: 5px;
background-image: url(https://www.kakaofriendsgolf.com/img/v3_img_sprites_friends#3x.png);
background-repeat: no-repeat;
width: 70px;
height: 70px;
}
.apeach.active {
background-position: 0 0%;
background-size: 100%;
display: block;
transition: hover 0.2s;
margin-bottom: 5px;
background-image: url(https://www.kakaofriendsgolf.com/img/v3_img_sprites_friends#3x.png);
background-repeat: no-repeat;
width: 70px;
height: 70px;
}
`;
codesandbox
https://codesandbox.io/s/characterselect-4o6he0?file=/src/App.js
Looked at the CodeSendbox. Looks nice!
If I understood correctly, your problem is that when you click any other icon without hovering on the first one, the first one doesn't get grayed out.
change following line
const [choonsik, setChoonsik] = useState(true);
to
const [choonsik, setChoonsik] = useState(false);

How can I make my hover dropdown menu stay visible over my carousel

Here is my code I created a dropdown menu bar where I have many dropdown menus on hover but later when I created a carousel, and when I am hovering on my dropdown menu it is behind the carousel but I want them in front of the carousel so I can access the links in the dropdown menu here the code of dropdown menu and carousel.
Dropdown.jsx
import "./dropdown.css"
import styled from "styled-components"
const Container = styled.div`
height: 50px;
left: 0px;
top: 61px;
background: #efefef;
box-shadow: 0px 4px 4px rgba(0, 0, 0, 0.25);
`
const Dropdown = () => {
return (
<div>
<Container>
<div className="menu-area">
<ul>
<li>Fashion
<ul className="dropdown">
<li>Men</li>
<li>Women</li>
<li>Kids</li>
</ul>
</li>
<li>Grocery
<ul className="dropdown">
<li>Vegetables</li>
<li>Oil</li>
<li>Bakery</li>
<li>Cerelas</li>
<li>Dairy</li>
</ul>
</li>
<li>Phone
<ul className="dropdown">
<li>Apple</li>
<li>MI</li>
<li>Samsung</li>
<li>Realme</li>
<li>Nothing</li>
<li>Oneplus</li>
</ul>
</li>
<li>Home
<ul className="dropdown">
<li > Appliances </li>
<li>Decors</li>
<li>Utensils</li>
<li>Bedroom</li>
<li>Bathroom</li>
</ul>
</li>
<li>Beauty
<ul className="dropdown">
<li>Moisturizers</li>
<li>Perfumes</li>
<li>Lipsticks</li>
<li>Hair Colors</li>
</ul>
</li>
<li>Electronics
<ul className="dropdown">
<li>Washing Machine</li>
<li>Refrigerator</li>
<li>TV</li>
<li>Microwave</li>
<li>Laptop</li>
</ul>
</li>
</ul>
</div>
</Container>
</div>
)
}
export default Dropdown
dropdown.css
.menu-area ul{
list-style: none;
}
.menu-area {
display: inline-block;
text-align: center;
position: absolute;
/* top: 10%; */
left: 50%;
transform: translate(-50%);
}
.menu-area li:hover{
background-color: rgb(216, 216, 216);
}
.menu-area > ul{
list-style: none;
padding: 0;
margin: 0;
display: flex;
align-items: center;
justify-content: center;
/* background-color: white; */
width: 100vw;
}
.menu-area > ul >li{
position: relative;
cursor: pointer;
font-size: 16px;
letter-spacing: 1px;
float: left;
width: 136px;
height: 50px;
line-height: 50px;
margin: 0px 30px;
}
.dropdown{
position: absolute;
top: 100%;
left: 0;
width: 100%;
padding: 0;
}
.dropdown li{
background: rgba(218, 218, 218, 0.332);
display: none;
}
.dropdown li:hover{
background: rgb(216, 216, 216);
opacity: 1;
}
.menu-area li:hover > .dropdown li{
display: block;
}
Slider.jsx
import styled from "styled-components"
import ArrowLeftIcon from '#mui/icons-material/ArrowLeft';
import ArrowRightIcon from '#mui/icons-material/ArrowRight';
import SliderItems from './sdata'
import { useState } from "react";
const Container = styled.div`
width: 100%;
height :40vh ;
display: flex;
position: relative;
overflow: hidden;
margin-top: 10px;
`;
const Wrapper = styled.div`
height: 80vh;
display: flex;
transition: all 1.5s ease;
transform: translateX(${props=>props.slideIndex * -100}vw);
`
const Slide = styled.div`
width: 100vw;
height: 100vh;
display: flex;
align-items: center;
`
const ImgContainer = styled.div`
height: 100%;
flex: 1;
width: 100vw;
`
const Image = styled.img`
height: 80%;
object-fit: cover;
`
const Arrow = styled.div`
width: 50px;
height: 50px;
background-color: #fff7f7;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
position: absolute;
top:0;
bottom: 0;
left: ${props => props.direction === 'right' && "10px"};
right: ${props => props.direction === 'left' && "10px"};
cursor: pointer;
margin: auto;
opacity: 0.5;
z-index: 2;
`
const Slider = () => {
const [slideIndex, setslideIndex] = useState(0)
const handleClick = (direction) => {
if (direction ==="left") {
setslideIndex(slideIndex> 0 ? slideIndex - 1 : 2)
} else {
setslideIndex(slideIndex> 2 ? slideIndex + 1 : 0)
}
}
return (
<Container>
<Arrow direction="left" onClick={() => { handleClick("left") }}>
<ArrowRightIcon />
</Arrow>
<Wrapper slideIndex={slideIndex}>
{SliderItems.map((item, index) => (
<Slide key={index}>
<ImgContainer >
<Image src={item.img} alt="image" />
</ImgContainer>
</Slide>
))}
</Wrapper>
<Arrow direction="right" onClick={() => { handleClick("right") }}>
<ArrowLeftIcon />
</Arrow>
</Container>
)
}
export default Slider
here is the code
If two positioned elements overlap without a z-index specified, the element positioned last in the HTML code will be shown on top, and from the looks of your code, your slider has a higher stack order. Source
To fix this, try giving the .dropdown a higher z-index so it goes on top of the slider.
Fix
.dropdown {
z-index: 100;
}
Or
It may be better if you give the menu itself the z-index property so the entire menu overlaps the slider and not the dropdown alone.
.menu-area {
display: inline-block;
text-align: center;
position: absolute;
left: 50%;
transform: translate(-50%);
z-index: 100;
}

How to make banner from static to autoplay with react

I have made some pure banner CSS js with react. Right now it's static not autoplay. How to make my banner autoplay properly and responsive for mobile. Autoplay and smooth transition when going to another banner.
This is the code for working static banner without autoplay things :
import { ArrowLeftOutlined, ArrowRightOutlined } from "#material-ui/icons"
import { useState } from 'react'
import styled from "styled-components"
import {sliderItems} from '../data'
const Container = styled.div`
width: 100%;
height: 80vh;
display: flex;
position: relative;
overflow: hidden;
`
const Arrow = styled.div`
width: 50px;
height: 50px;
background-color: #fff7f7;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
position: absolute;
top: 0;
bottom: 0;
left: ${props=> props.direction === "left" && "10px"};
right: ${props=> props.direction === "right" && "10px"};
margin: auto;
cursor: pointer;
opacity: 0.5;
z-index: 2;
`
const Wrapper = styled.div`
height: 100%;
display: flex;
transition: all 1.5s ease;
transform: translateX(${props=>props.slideIndex * -100}vw);
`
const Slide = styled.div`
width: 100vw;
height: 100vh;
display: flex;
align-items: center;
background: ${props => `url(${props.bg}) no-repeat top center`};
`
const ImgContainer = styled.div`
height: 80%;
flex: 1;
`
const Image = styled.img`
height: 80%;
`
const Image2 = styled.img`
height: 40%;
`
const InfoContainer = styled.div`
flex: 1;
padding: 50px;
`
const Title = styled.h1`
color: white;
font-size: 70px;
`
const Desc = styled.p`
color: white;
margin: 50px 0px;
font-size: 20px;
font-weight: bold;
letter-spacing: 3px;
`
const Button = styled.button`
border: 1px solid white;
padding: 10px;
font-size: 20px;
color: #0070ba;
background-color: white;
border-radius: 25px;
cursor: pointer;
font-weight: 800;
&:hover{
color: white;
background-color: #0070ba;
}
`
const Banner = () => {
const [slideIndex, setSlideIndex] = useState(0)
const handleClick = (direction) => {
if(direction==="left"){
setSlideIndex(slideIndex > 0 ? slideIndex-1 : 6)
} else {
setSlideIndex(slideIndex < 6 ? slideIndex +1 : 0)
}
}
return (
<Container>
<Arrow direction="left" onClick={()=>handleClick("left")}>
<ArrowLeftOutlined />
</Arrow>
<Wrapper slideIndex={slideIndex}>
{sliderItems.map(item=>(
<Slide bg={item.bg}>
<Image2 src={item.img2}/>
<InfoContainer>
<Title>{item.title}</Title>
<Desc>{item.desc}</Desc>
<Button>COBA SEKARANG</Button>
</InfoContainer>
<ImgContainer>
<Image src={item.img}/>
</ImgContainer>
</Slide>
))}
</Wrapper>
<Arrow direction="right" onClick={()=>handleClick("right")}>
<ArrowRightOutlined />
</Arrow>
</Container>
)
}
export default Banner
Thank you guys for helping!

How can i use onClick event in styled component

I have a problem with styled. I will write my problem with images. I have a image button and if i click on image button, the MenuItemContainer must be visibility.
const MenuItemContainer = styled.div`
visibility: hidden;
display: inline-block;
box-sizing: border-box;
width: 200px;
padding-left: 16px;
padding-right: 16px;
border: 1px solid ${({ theme }) => theme.palette.lightBlueGrey};
border-radius: 5px;
box-shadow: 0 12px 24px 0px ${({ theme }) => theme.palette.dark15};
`;
const ProfileNameWrapper = styled.div`
display: flex;
width: 36px;
height: 36px;
border-radius: 50%;
margin-right: 25px;
background-color: ${({ theme }) => theme.palette.darkGreyBlue};
cursor: pointer;
justify-content: center;
align-items: center;
&:hover ${TooltipText} {
visibility: visible;
}
&:????? ${MenuItemContainer} {
visibility: visible;
}
`;
can i use onClick here?
&:????? ${MenuItemContainer} {
visibility: visible;
}
Even though, I find it wrong to attach click events on divs, you can utilize the aria attributes to hack your way around your problem.
const ProfileNameWrapper = styled.div`
...
&:[aria-expanded='true'] ${MenuItemContainer} {
visibility: visible;
}
`
const Component: React.FC<Props> = (props) => {
const [expanded, setExpanded] = React.useState(false)
return (
<ProfileNameWrapper onClick={() => setExpanded(!expanded)} aria-expanded={expanded} />
)
}

Categories