hide images by hovering another image in ReactJS using css - css

I have following react code.
My code
What I would like is to when I hover first image than other image should hide (or become transparent, so that the positioning does not collapse).
Аnd so it would be for other pictures, for example if you make a hover on a third picture, then the first, second and fourth pictures should become hide or transparent.
I look in other topics like:
How to affect other elements when one element is hovered and Hide element on hover of another element but I can't fix my code.
Maybe it will be more easy to fix using some reactJS code?
Please help me.

I would do it like this:
Track the index of hovered item, and changeing the style opacity depending on that hovered index.
// SolutionBox.jsx
import React, { useState } from "react";
import SolutionItem from "./SolutionItem";
import Ecommerce from "../img/a.png";
import Middleware from "../img/b.png";
import SalesMarketing from "../img/c.png";
import Analytics from "../img/d.png";
import _ from "lodash";
function SolutionsSectionBox({ onBGChanged }) {
const [focused, setFocused] = useState(0);
let callBGChanged = menuName => {
if (_.isFunction(onBGChanged)) {
onBGChanged(menuName);
}
};
return (
<div className="solutions-section-box-box">
<SolutionItem
solutionIMG={Ecommerce}
onHover={state => {
setFocused(1);
callBGChanged(state === true ? "Ecommerce" : "default");
}}
focused={focused}
index={1}
onLeave={() => setFocused(0)}
/>
<SolutionItem
solutionIMG={SalesMarketing}
onHover={state => {
setFocused(2);
callBGChanged(state === true ? "SalesMarketing" : "default");
}}
focused={focused}
index={2}
onLeave={() => setFocused(0)}
/>
<SolutionItem
solutionIMG={Analytics}
onHover={state => {
setFocused(3);
callBGChanged(state === true ? "Analytics" : "default");
}}
focused={focused}
index={3}
onLeave={() => setFocused(0)}
/>
<SolutionItem
solutionIMG={Middleware}
onHover={state => {
setFocused(4);
callBGChanged(state === true ? "Middleware" : "default");
}}
focused={focused}
index={4}
onLeave={() => setFocused(0)}
/>
</div>
);
}
export default SolutionsSectionBox;
Solution Item:
// Solution Item:
import React from "react";
import _ from "lodash";
function SolutionsSectionBoxItem({
onLeave,
solutionIMG,
onHover,
index = 0,
focused = 0
}) {
let callOnHover = state => {
if (_.isFunction(onHover)) {
onHover(state);
}
};
return (
<div className="solutions-section-item-box">
<img
style={{
opacity: focused && focused !== index ? 0.5 : 1
}}
src={solutionIMG}
alt=""
onMouseEnter={() => {
callOnHover(true);
}}
onMouseLeave={() => {
callOnHover(false);
onLeave();
}}
className="solutions-section-item-img"
/>
</div>
);
}
export default SolutionsSectionBoxItem;

You can use your existing bgImg state to infer which is visible.
If you pass it as a prop to SolutionBox like
<SolutionBox bgImage={bgImage} onBGChanged={onBGChanged} />
and then for each SolutionItem
<SolutionItem
solutionIMG={Ecommerce}
visible={bgImage === Ecommerce}
onHover={state => {
callBGChanged(state === true ? "Ecommerce" : "default");
}}
/>
and use it to style in SolutionItem
<div className="solutions-section-item-box" style={{ opacity: visible ? 1 : 0.5}}>

Related

Dots are not showing react swiper slider

Actually I wanna create slider with dots, slider is working, but dots are hidden. How should I make dots visible while using react swipper slider.
I am using styled components for css. The thing is, I cannot find what is false in this part of code. please help me to figure out with this problem.
I tried to make my slider dots visible, however they are not showing.
this is my code
import { Pagination, Navigation, Scrollbar, A11y } from 'swiper';
import { Images } from 'assets/images';
import { useWindowDimensions } from 'hooks/useWindowDimensions';
import { useNavigate } from 'react-router-dom';
import { ROUTES } from 'utils/routeNames';
import { Swiper, SwiperSlide } from 'swiper/react';
// Import Swiper styles
import 'swiper/swiper.scss';
import {
CardAndDescriptionBlock,
CardBlock,
CountryImage,
TripDurationAndPrice,
TripDuration,
CardDescription,
TripCountryAndPrice,
CountryStarsPriceWrapper,
TripCountryAndStars,
TripPrice,
PricePerPerson,
TripCountry,
ReadMore,
DescriptionContainer,
} from './styled';
export const HotOffersCarousel = ({ hotOffers }) => {
const navigate = useNavigate();
const { width } = useWindowDimensions();
const navigateToTour = (id) => {
navigate(`${ROUTES.HOT_TOURS}/${id}`);
};
return (
<Swiper
slidesPerView={width < 768 ? 2 : 1}
spaceBetween={10}
slidesPerGroup={width < 768 ? 2 : 1}
loop={true}
pagination={{
dynamicBullets: true,
}}
modules={[Pagination, Navigation, Scrollbar, A11y]}
className="mySwiper"
>
{hotOffers?.map((item) => (
<SwiperSlide key={item.id}>
<CardAndDescriptionBlock>
<CardBlock>
<CountryImage background={item?.main_image}>
<TripDurationAndPrice>
<TripDuration>
{item?.stay_days} Days / {item?.stay_nights} nights
</TripDuration>
<PricePerPerson> $ {item?.price}/Person </PricePerPerson>
</TripDurationAndPrice>
</CountryImage>
<TripCountryAndPrice>
<CountryStarsPriceWrapper>
<TripCountryAndStars>
<TripCountry> {item?.title} </TripCountry>
<img src={Images.stars} />
</TripCountryAndStars>
<TripPrice>$ {item?.price} </TripPrice>
</CountryStarsPriceWrapper>
<DescriptionContainer
isMedia
dangerouslySetInnerHTML={{ __html: item.description }}
/>
<ReadMore onClick={() => navigateToTour(item?.id)} isMedia>
Read More <img src={Images.mainColorRightArrow} />
</ReadMore>
</TripCountryAndPrice>
</CardBlock>
<CardDescription>
<TripCountryAndStars>
<TripCountry> Venice Italy </TripCountry>
<img src={Images.stars} />
</TripCountryAndStars>
<DescriptionContainer
dangerouslySetInnerHTML={{ __html: item.description }}
/>
<ReadMore onClick={() => navigateToTour(item?.id)}>
Read More <img src={Images.mainColorRightArrow} />
</ReadMore>
</CardDescription>
</CardAndDescriptionBlock>
</SwiperSlide>
))}
</Swiper>
);
};

When I make a request to the server with query parameters nothing changes. A different number of users should be displayed

In this project I am using FireBase database. I need to change the number of users per page for example 5, Change the number of pages according to the total number of users / number of users per page. To do this, I change the query params, but it does not want to change. I don't know how to enter the parameters correctly so that they appear to me as they should, maybe I didn't write them correctly or I need to write them differently
import React, {Component} from "react";
import classes from "./users.module.css";
import * as axios from "axios";
import userPhoto from "../../assect/image/standartAvatar.jpg";
class Users extends Component {
componentDidMount() {
axios
.get(
`https://kabzda-cff30-default-rtdb.europe-west1.firebasedatabase.app/users.json?page=${this.props.currentPage}&count=${this.props.pageSize}`
)
.then((response) => {
this.props.setUsers(response.data.items);
this.props.setTotalUsersCount(response.data.totalCount);
})
}
onPageChanged = (pageNumber) => {
this.props.setCurrentPage(pageNumber)
axios
.get(
`https://kabzda-cff30-default-rtdb.europe-west1.firebasedatabase.app/users.json?page=${pageNumber}&count=${this.props.pageSize}`
)
.then((response) => {
this.props.setUsers(response.data.items);
})
}
render() {
let pagesCount = Math.ceil(this.props.totalUsersCount / this.props.pageSize)
let pages = [];
for(let i = 1; i <= pagesCount; i++){
pages.push(i)
}
return (
<div>
<div className={classes.counter}>
{pages.map(p => (
<span className={(this.props.currentPage === p && classes.selectedPage) || classes.pointer}
onClick={() => {this.onPageChanged(p)}}
>
| {p} |</span>
))}
</div>
{this.props.users.map((u, i) => (
<div key={i+1}>
<span>
<div>
<img
src={u.photos.small !== "" ? u.photos.small : userPhoto}
className={classes.userPhoto}
alt="avatar"
/>
</div>
<div>
{u.followed ? (
<button
onClick={() => {
this.props.unfollow(u.id);
}}
>
UnFollow
</button>
) : (
<button
onClick={() => {
this.props.follow(u.id);
}}
>
Follow
</button>
)}
</div>
</span>
<span>
<span>
<div>{u.name}</div>
<div>{u.status}</div>
</span>
<span>
<div>{"u.location.country"}</div>
<div>{"u.location.city"}</div>
</span>
</span>
</div>
))}
</div>
);
}
}
export default Users;

Framer Motion Page Transition Next JS Router.push

I made the following using the nextjs and framer motion
I have a list of images that I'm mapping over and assigning them a layoutid and an optional variant to animate. The layoutid corresponds to the layoutid on the model1, model2, model3 pages.
Current Behaviour
When first going to the home page and clicking on an image I update some state and set the variant animation to false, this then tells that image to use the layoutid, it then fades out the other images and animates the clicked image into place on the component that is loaded (model1, model2, model3)...Great it works!
If you then click home in the navigation and try clicking an item again it doesn't work, all images are faded out and the clicked image doesn't animated.
Click refresh on the homepage and it works as desired!
here is the code for the page, I suspect it could be something to do with the routing or settings in _app.js
export default function Home() {
const router = useRouter();
const [isClicked, setIsClicked] = useState(null);
const onHandlerClick = (item, href, e) => {
e.preventDefault();
setIsClicked(item);
router.push(href, { scroll: false });
};
return (
<div className="l-grid l-grid-outter">
<div className="c-home-maincontent">
<div>
<main>
<motion.div className="l-grid-3-col" initial="initial" animate="enter" exit="exit" variants={{ exit: { transition: { staggerChildren: 0.1 } } }}>
{images.map((item, index) => {
return (
<motion.div
key={index}
className="c-home-overflowimage c-home-overflowimage2"
layoutId={`imageAnimation${item}`}
variants={isClicked === item ? false : postVariants}
transition={{ ...transition }}
>
<a href={`/model${item}`} onClick={(event) => onHandlerClick(item, `/model${item}`, event)}>
<motion.img
src="/yasmeen.webp"
whileHover={{
scale: 1.1,
}}
/>
</a>
</motion.div>
);
})}
</motion.div>
</main>
</div>
</div>
<Footer />
</div>
);
}
function MyApp({ Component, pageProps }) {
const router = useRouter();
return (
<>
<DefaultSeo {...Seo} />
<AnimateSharedLayout type="crossfade">
<AnimatePresence exitBeforeEnter initial={false}>
<Component {...pageProps} key={router.asPath} />
</AnimatePresence>
</AnimateSharedLayout>
</>
);
}
export default MyApp;
Updated the code to include an animate set to false if its the clicked item
<motion.div className="l-grid-3-col" initial="initial" animate="enter" exit="exit">
{images.map((item, index) => {
return (
<motion.div
key={index}
className="c-home-overflowimage c-home-overflowimage2"
layoutId={`imageAnimation${item}`}
animate={isClicked === item ? false : true}
variants={isClicked === item ? false : postVariants}
transition={{ ...transition }}
>
<a href={`/model${item}`} onClick={(event) => onHandlerClick(item, `/model${item}`, event)}>
<motion.img
src="/yasmeen.webp"
whileHover={{
scale: 1.1,
}}
/>
</a>
</motion.div>
);
})}
</motion.div>

How can I change className for specific element when mapping?

I am trying to change the index 5 and 6 to opacity 0.2 but I do not know how to change specific className when mapping in react
Here is my following code:
const tabs = [
"Mission",
"Agreement",
"Calendar",
"Managers",
"Members",
"Invitees",
"Applicants",
"Sub-Team",
];
const [activeTab, setActiveTab] = useState(0);
<div className="team-management-tab-items">
{tabs.map((tab, index) => (
<div
className={
activeTab === index
? "team-management-tab-item selected"
: "team-management-tab-item"
}
key={tab}
role="button"
tabIndex={tab}
onKeyPress={() => {
return;
}}
onClick={() => {
if (editable === true) {
setActiveTab(index);
} else if (index !== 5 && index !== 6) {
setActiveTab(index);
}
}}
>
<span className="tab-item-text">{tab}</span>
<span className="tab-item-indicator" />
</div>
))}
</div>
</div>
<div className="team-management-tab-panes">
{tabs[activeTab] === "Mission" && (
<Mission
editable={editable}
teamId={teamId}
teamData={teamData}
fetchTeamData={fetchTeamData}
/>
)}
{tabs[activeTab] === "Agreement" && (
<Agreement
teamData={teamData}
agreement={agreement}
editable={editable}
teamId={teamId}
fetchTeamData={fetchTeamData}
/>
)}
...
);
Here is how my project look like:
So basically I want to change opacity Invitees and Applicants to 0.2. How can I do that?
There are a few ways to do this, the easiest would likely be adding an id tag to the div like:
{tabs.map((tab, index) => (
<div
id = {tab}
className={
activeTab === index
? "team-management-tab-item selected"
: "team-management-tab-item"
}
and then in your css just add
#Invitees, #Applicants{
opacity: 0.2;
}

Material-UI dialog font overwriting

I've made a custom User Confirmation Dialog from Material UI Dialog component like here
I faced a problem to overwrite the Dialog's font. I can overwrite color or background color, but fonts in Dialog's header or buttons are inherited from Material-UI. I successfully overwrote Material-UI fonts in other components, but not in this part with callback:
const UserConfirmation = (
message: string,
callback: (shouldNavigate: boolean) => void
) => {
const container = document.createElement('div')
container.setAttribute('custom-confirmation-navigation', '')
document.body.appendChild(container)
const closeModal = (shouldNavigate: boolean) => {
ReactDOM.unmountComponentAtNode(container)
callback(shouldNavigate)
}
ReactDOM.render(
<>
<Dialog
fullWidth={true}
maxWidth="sm"
open={true}
aria-labelledby="alert-dialog-title"
aria-describedby="alert-dialog-description"
>
<DialogTitleWrapper
style={{fontFamily: `BuenosAires !important`, color: `orange`}}
>
Discard draft?
</DialogTitleWrapper>
<DialogContent>
<p> {message} </p>
</DialogContent>
<DialogActionsWrapper>
<Button
onClick={() => closeModal(true)}
fullWidth={true}
variant="outlined"
label="Discard"
/>
<div style={{ width: '80%' }} />
<Button
onClick={() => closeModal(false)}
fullWidth={true}
variant="contained"
label="Cancel"
/>
</DialogActionsWrapper>
</Dialog>
</>,
container
)
}
export default UserConfirmation
Thank Alex
That works brilliant for me:
<DialogTitle disableTypography="true">
Also, buttons' labels were fixed by that:
label={<h5 style={{ textTransform: 'none' }}>Cancel</h5>}
You can use classes object to Override or extend the styles applied to the component.
here
create custom styles like below
const useStyles = makeStyles({
customDialogTitle: {
fontFamily:'Impact'//sans-serif
}
});
and assign to classes
<DialogTitle disableTypography="true"
classes={{
root: classes.customDialogTitle
}}
>
.....
</DialogTitle>
sample sandbox

Resources