Framer Motion Animate Presence vertically inline - reactjs

I am trying to display a count where when a digit changes the original digit exits downwards and the new digit comes in from the top. When I try to do this, the numbers appear side by side briefly. I have tried using position absolute but then the digits don't exit downwards.
Here is a codesandbox showing the issue I am having.
Thanks!

You need to wrap your motion.divs in a container so the width doesn't change on the animation. Then give the container position relative and a fixed width and every motion.div a position absolute and for each motion.div higher left px.
<div className="myComponent">
<div className="counts-container">
<AnimatePresence>
{counts.map((count, index) => (
<motion.div
key={index + Math.random()}
className={`count count-${index}`}
animate={{ y: 0 }}
initial={{ y: -50 }}
exit={{ y: 50 }}
transition={{ duration: 0.5 }}
>
{count}
</motion.div>
))}
</AnimatePresence>
</div>
<button onClick={() => setCounts((c) => [...c].reverse())}>
Change Counts
</button>
</div>
your css:
body {
margin: 0;
padding: 0;
}
#root {
font-family: sans-serif;
text-align: center;
width: 100vw;
height: 100vh;
display: flex;
place-content: center;
place-items: center;
background: rgba(0, 85, 255, 1);
margin: 0;
padding: 0;
}
.myComponent {
display: flex;
}
.counts-container {
display: flex;
position: relative;
width: 40px;
background-color: yellow;
}
.count {
position: absolute;
}
.count-0 {
left: 0px;
}
.count-1 {
left: 15px;
}
.count-2 {
left: 30px;
}
MIGHT NOT BE THE BEST SOLUTION BUT IT IS A SOLUTION! :D

Related

How to fix the scroll when increasing the width?

I need that as the width increases, the elements inside remain in place. For some reason, this does not always happen, sometimes the scroll starts moving to the right.
How to fix the scroll when increasing the width?
<reactResizable.ResizableBox
className="box"
width={200}
height={200}
axis="x"
resizeHandles={["e"]}
>
<div className="inner">
{Array.from(generateSequence(1, 6)).map((e) => {
return (
<div>
<span className="text">BLOCK {e}</span>
</div>
);
})}
</div>
</reactResizable.ResizableBox>
.box {
background: white;
overflow: auto hidden;
}
.box .react-resizable-handle-e {
height: 100%;
background-color: red;
transform: rotate(0);
top: 0;
}
.inner {
height: 200px;
color: black;
display: flex;
overflow-x: overlay;
}
.inner > div {
min-width: 150px;
height: 100px;
border: 4px solid black;
}
CodePen
Demo
I tried to debug it. I don't understand why this is happening
Instead of increasing width for box react-resizable class container. Increase the width for inner container. It will work

How do I stop my image from stretching on larger screen sizes?

I have a hero section that displays an image loaded from an API. It works fine on smaller screen sizes but stretches on bigger screens. How do I prevent this from happening and make sure that the image doesn't look stretched?
Apologies in advance if if my code is confusing, this was my first React project.
Thanks!
<div className="hero-section">
<Slideshow movies={movies}/>
</div>
.hero-section {
width: 100vw;
height: 100vh;
}
<div className="slideshow">
<div className="slideshowSlider" style={{ transform: `translate3d(${-index * 100}%, 0, 0)` }}>
{posters.map((poster, index) => (
<img src={'https://image.tmdb.org/t/p/w500' + poster} className="slide" key={index} style={{ poster }}/>
))}
</div>
.slideshow {
margin: 0 auto;
overflow: hidden;
max-width: 100vw;
background-color: #222222;
}
.slideshowSlider {
white-space: nowrap;
transition: ease 1000ms;
height: 50vh;
width: 100vw;
object-fit: cover;
}
.slide {
display: inline-block;
height: 50vh;
width: 100%;
}
You should change height: 50vh; to height: auto; in .slide styles.
.slideshow {
margin: 0 auto;
overflow: hidden;
max-width: 100vw;
background-color: #222222;
}
.slideshowSlider {
white-space: nowrap;
transition: ease 1000ms;
height: 50vh;
width: 100vw;
object-fit: cover;
}
.slide {
display: inline-block;
height: auto; // fixed!
width: 100%;
}

How to make react slick carousel resizable when I zoom out?

So like the title says, what I am trying to achieve is that when I zoom out, I want my carousel to be 100% width of the screen all time, here is what I mean by that. Right now when I zoom out, my carousel looks like this:
But when it is 100% zoom, a.k.a my normal screen it looks like this:
So, how do I make this be resizable meaning it is going to be like it is on a normal screen (100%) on every zoom.
Here is my code:
const Works = () => {
var settings = {
centerMode: true,
dots: true,
infinite: true,
speed: 500,
slidesToShow: 4,
slidesToScroll: 1,
centerPadding: "10px",
customPaging: (i) => <div className="works-dots"></div>,
arrows: false,
};
return (
<div className="mainWorks-container">
<div className="works-popup-container">
<h3 className="works-title">WORKS</h3>
<div className="works-popup-image-container">
<Slider {...settings}>
{worksImages.map((image, index) => {
return (
<div key={index} className="works-image">
<img
src={image.image}
alt={image.alt}
className="works-popup-image"
/>
<div className="image-overlay">
<h3>{image.title}</h3>
</div>
</div>
);
})}
</Slider>
</div>
</div>
<div className="works-button-container">
<a href="/">
<Button text="View Works" isFilled={false} type="border" />
</a>
</div>
</div>
);
};
export default Works;
This is my Works.js component.
.mainWorks-container {
height: 675px;
position: relative;
}
.works-popup-container {
height: 780px;
width: 986px;
background: url("../../../images/gradient-background.jpg") no-repeat;
background-size: cover;
position: absolute;
top: 10%;
left: 50%;
transform: translate(-50%, -50%);
border-radius: 10px;
}
.works-title {
margin-top: 50px;
letter-spacing: 0.5em;
font-size: 12px;
color: white;
text-align: center;
}
.works-popup-image-container {
.slick-list {
position: relative;
left: -30%;
width: 105rem;
}
.works-image {
position: relative;
margin-bottom: 8rem;
width: 385px;
height: 513px;
border-radius: 3px;
box-shadow: 0px 70px 100px -40px rgba(0, 0, 0, 0.5);
img {
width: 385px;
height: 100%;
object-fit: contain;
cursor: pointer;
}
.image-overlay {
position: absolute;
top: 0;
left: 0;
width: 91.7%;
background: rgba(0, 0, 0, 0.5);
height: 100%;
display: flex;
justify-content: center;
align-items: center;
color: white;
opacity: 0;
cursor: pointer;
text-align: center;
font-size: 1.2rem;
word-break: break-word;
}
.image-overlay:hover {
opacity: 1;
}
}
}
.works-dots {
background: rgba(247, 247, 247, 0.75);
border-radius: 50%;
width: 8px;
height: 8px;
margin: 0 5px;
}
.works-dots:hover {
height: 10px;
width: 10px;
transition: all 0.2s ease;
}
.slick-active {
.works-dots {
height: 10px;
width: 10px;
}
}
.works-button-container {
position: absolute;
top: 90%;
left: 50%;
transform: translate(-50%, -50%);
}
And this is my worksStyles.scss file.
If anyone knows how to do this, I would be thankful.

Modal is displayed below the items

I have come into a strange issue that has stopped me for a few hours. I have created a MERN app in which I have a page that I introduce members of a team. I also have a modal for each member triggered by click on member. The problem is that when I create a new member, the modals related to previous members is displayed behind the latter added members. I will attach pictures to more clearly demonstrate what happens.
enter image description here
enter image description here
Here is how I have defined the modal:
const Modal = ({ closeModal, children }) => {
const closeIcon = () => (
<FontAwesome
name='times'
onClick={closeModal}
className='modal-font-awesome'
/>
)
return (
<div id='overlay'>
<div className='content'>
{closeIcon()}
{children}
</div>
</div>
)
}
Here is my scss code for styling the modal:
#overlay {
position: fixed;
display: block;
overflow: hidden;
width: 100%;
height: 100%;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: rgba(0, 0, 0, 0.5);
}
.content {
margin: 120px auto;
background-color: white;
border-radius: 0.25rem;
width: 70vw;
padding: 2rem;
position: relative;
border-left: 5px solid rgb(37, 153, 124);
}
Do you have any suggestions about what is happening?
Thank you in advance.

How to convert from TSX to JSX in this Codesandbox

I am learning React and JavaScript and now I have this CodeSandbox but I can't convert it to JavaScript React I have tried this for the Card Component:
import React, { useState } from "react";
const Card = props => {
const [expanded, setExpanded] = useState(false);
const RenderCard = (className) => {
return (
<div
className={`card ${className}${expanded ? " expanded" : ""}`}
onClick={() => {
setExpanded(!expanded);
}}
>
<div className="image">
<img alt="digger" src={props.image} />
</div>
<div className="info">
<div
className="bg1"
style={{ backgroundImage: "url('" + props.image + "')" }}
/>
<div
className="bg2"
style={{ backgroundImage: "url('" + props.image + "')" }}
/>
<div
className="bg3"
style={{ backgroundImage: "url('" + props.image + "')" }}
/>
<h1>JCB OES System</h1>
<h2>Report Number #1</h2>
<h3>Load lifter work area</h3>
<div className="button">Open</div>
</div>
</div>
);
};
return (
<div className={`card-container${expanded ? " expanded" : ""}`}>
{expanded && <div className="background" />}
{<RenderCard className="card1"/>}
{<RenderCard className="card2"/>}
</div>
);
};
export default Card;
And I show the Card like this. It's very simple, it's just that when I click a card it does not pop up like the CodeSandbox does.
import Card from "./Card";
import "./styles.scss";
const CreateContent = () => {
return (
<div className="app">
<link rel="stylesheet" href="https://use.typekit.net/jli8mqj.css" />
<Card image="https://www.thetimes.co.uk/imageserver/image/methode%2Fsundaytimes%2Fprodmigration%2Fweb%2Fbin%2Fbeae8dfb-0a41-4f8e-b076-ffd68417287b.jpg?crop=1024%2C683%2C0%2C0&resize=685" />
<Card image="https://www.virginexperiencedays.co.uk/content/img/product/large/PJCBRA__01.jpg" />
<Card image="https://www.toyfarmers.co.uk/images/britains-jcb-3cx-backhoe-loader.jpg" />
<Card image="https://seatylive.blob.core.windows.net/eventimages/2019-Aug-20-Tue_18-37-31-969.png" />
</div>
);
};
export default CreateContent;
The styles is the same, with no changes: I understand that the expanded background when set to expanded=true using the hook that the scss style for background should be in effect but all I get is a black screen.
.app {
font-family: sans-serif;
text-align: center;
padding: 4em 0;
}
* {
box-sizing: border-box;
padding: 0;
margin: 0;
border: 0;
}
.card-container {
font-family: niveau-grotesk, sans-serif !important;
position: relative;
z-index: 0;
&.expanded {
z-index: 3;
#keyframes fade-in {
0% { opacity: 0; }
100% { opacity: 1; }
}
.background {
animation: fade-in .3s ease-out;
z-index: 2;
position: fixed;
background: black;
top: 0;
left: 0;
right: 0;
bottom: 0;
width: 100%;
height: 100%;
}
}
.card {
margin: 0 auto;
width: 25em;
cursor: pointer;
border-radius: .5em;
box-shadow: 0 50px 100px -20px rgba(50,50,93,.25),
0 30px 60px -30px rgba(0,0,0,.3),
0 -18px 60px -10px rgba(0,0,0,.03);
margin-bottom: 4em;
&.card2 {
transition: .2s ease-out;
position: absolute;
top: 0;
width: 25em;
left: 50%;
z-index: 4;
transform: translateX(-50%);
&.expanded {
width: 40em;
}
}
.image {
img {
display: block;
border-top-left-radius: .5em;
border-top-right-radius: .5em;
width: 100%;
}
}
$button-color: rgb(87, 87, 228);
&:hover {
.info .button {
color: white;
background: $button-color;
}
}
.info {
background: white;
position: relative;
border-bottom-left-radius: .5em;
border-bottom-right-radius: .5em;
overflow: hidden;
padding: .9em 1.2em;
text-align: left;
$darkness: 0;
&:after {
content: '';
position: absolute;
top: -20%;
left: -20%;
right: -20%;
bottom: -20%;
height: 140%;
width: 140%;
// filter: blur(8px);
// -webkit-filter: blur(8px);
background: linear-gradient(to right,
rgba(0, 0, 0, 0.4) 30%,
rgba(0, 0, 0, 0) 100%);
}
.bg1, .bg2 {
position: absolute;
top: -20%;
left: -20%;
right: -20%;
bottom: -20%;
height: 140%;
width: 140%;
z-index: 0;
background-position: center;
background-repeat: no-repeat;
background-size: 100%;
transform: rotate(180deg);
filter: blur(16px);
}
.bg2 {
background-position: bottom;
transform: rotate(0deg);
opacity:0.4;
}
.bg3 {
background-position: top;
transform: rotate(180deg);
opacity:0.4;
}
.button {
transition: .2s ease-out;
text-transform: uppercase;
line-height: 1.2em;
position: absolute;
top: 50%;
transform: translateY(-50%);
right: 1.8em;
z-index: 1;
background: white;
border-radius: 1em;
padding: .4em 1.1em;
font-weight: 600;
color: $button-color;
}
h1, h2, h3 {
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
max-width: 13em;
color: white;
position: relative;
z-index: 1;
text-shadow: 1px 1px 1px rgba(0,0,0,0.8);
}
h1 {
line-height: .8em;
letter-spacing: .03em;
font-size: 1.1em;
font-weight: 900;
padding: .1em 0;
}
h2 {
letter-spacing: .02em;
font-size: 1.0em;
font-weight: 400;
padding: .1em 0;
opacity: 0.6;
}
h3 {
letter-spacing: .02em;
font-size: .9em;
font-weight: 400;
padding: .1em 0;
}
}
}
}
What am I missing?
To swap your Code Sandbox from TypeScript to JavaScript you should just need to:
Remove all typescript specific syntax from your ".ts" and ".tsx" files (interfaces, typings, etc)
Change all the file extensions to their JavaScript equivalent i.e. ".ts" -> ".js" and ".tsx" -> ".jsx".
Update the "main" property of the "package.json" file to point to the renamed entry point. i.e. "src/index.jsx".
I created a quick CodeSandbox with this already done.

Resources