Open
Description
Hi. I tried to implement the stories code from you challenge.
The initial stories implementation has a bug when we mix up the scroll and tap movement through the stories.
Example - tap till the end of the stories, than scroll back with mouse scroll then try to tap forward - nothing works.
i've implemented the solution to improve the gesture mix in react.
If you are accepting PRs I will adapt it to vanilla js code
/* eslint-disable react/style-prop-object */
import { useCallback, useEffect, useRef, useState } from "react";
import "./stories.css";
const storiesBreakpoints = {};
function Stories() {
const storiesRef = useRef(null);
const storiesMedian = useCallback(
() => storiesRef.current.offsetLeft + storiesRef.current.clientWidth / 2,
[storiesRef]
);
const [currentStory, setCurrentStory] = useState(null);
useEffect(() => {
for (let i = 0; i < storiesRef.current.children.length; i++) {
storiesBreakpoints[
storiesRef.current.children[i].offsetLeft -
storiesRef.current.offsetLeft
] = i;
}
}, []);
useEffect(() => {
setCurrentStory(storiesRef.current.firstElementChild.lastElementChild);
}, []);
const navigateStories = useCallback(
(direction) => {
if (currentStory === null) {
return;
}
let lastItemInUserStory;
let nextUserStory;
if (direction === "next") {
lastItemInUserStory = currentStory.parentNode.firstElementChild;
nextUserStory =
currentStory.previousElementSibling ||
currentStory.parentElement.nextElementSibling?.lastElementChild;
} else if (direction === "prev") {
lastItemInUserStory = currentStory.parentNode.lastElementChild;
nextUserStory =
currentStory.nextElementSibling ||
currentStory.parentElement.previousElementSibling?.firstElementChild;
}
if (lastItemInUserStory === currentStory && nextUserStory) {
nextUserStory.scrollIntoView({
behavior: "smooth",
});
} else if (nextUserStory) {
(direction === "prev" ? nextUserStory : currentStory).classList.toggle(
"seen"
);
}
if (nextUserStory) {
setCurrentStory(nextUserStory);
}
},
[currentStory]
);
const storiesClick = useCallback(
(e) => {
if (e.target.nodeName !== "ARTICLE") {
return;
}
navigateStories(e.clientX > storiesMedian() ? "next" : "prev");
},
[navigateStories, storiesMedian]
);
return (
<>
<div
ref={storiesRef}
className="stories"
onClick={storiesClick}
onScroll={(e) => {
const currentUserIndex =
storiesBreakpoints[e.target.scrollLeft] ?? null;
let currentStory = null;
if (currentUserIndex != null) {
const userStories = Array.from(
storiesRef.current.children[currentUserIndex]?.children
);
currentStory =
userStories.findLast((e) => !e.classList.contains("seen")) ??
null;
}
setCurrentStory(currentStory);
}}
>
<section className="user">
<article
className="story story1"
style={{ "--bg": "url(https://picsum.photos/480/840)" }}
></article>
<article
className="story story2"
style={{ "--bg": "url(https://picsum.photos/480/841)" }}
></article>
</section>
<section className="user">
<article
className="story story3"
style={{ "--bg": "url(https://picsum.photos/481/840)" }}
></article>
</section>
<section className="user">
<article
className="story story4"
style={{ "--bg": "url(https://picsum.photos/481/841)" }}
></article>
</section>
<section className="user">
<article
className="story story5"
style={{ "--bg": "url(https://picsum.photos/482/840)" }}
></article>
<article
className="story story6"
style={{ "--bg": "url(https://picsum.photos/482/843)" }}
></article>
<article
className="story story7"
style={{ "--bg": "url(https://picsum.photos/482/844)" }}
></article>
</section>
</div>
</>
);
}
export default Stories;
Metadata
Metadata
Assignees
Labels
No labels