React Hooks Example: Timer
Simple React Hooks example. A timer that pauses when you hold the mouse button. Creates and uses a custom Hook.
HTML
<div id="app"></div>
SCSS
.carousel-wrapper {
display: flex;
gap: 0.5rem;
margin-top: 0.75rem;
margin-bottom: 0.5rem;
height: 8rem;
.arrow {
height: fit-content;
align-self: center;
}
.items-wrapper {
display: grid;
/* grid-template-columns: repeat(4, 2.5rem); */
grid-template-areas: "a b c d" "e f g h";
gap: 1rem;
margin: auto 0;
.item {
display: flex;
justify-content: center;
align-items: center;
position: relative;
box-shadow: 0px 4px 4px rgba(46, 37, 37, 0.15), 0px 0px 10px 1px rgba(203, 205, 208, 0.3);
border-radius: 4px;
padding: 0.5rem;
height: 2.5rem;
transition: opacity 0.8s calc(var(--delay) + var(--delayOffset, 0s));
&.is-hidden {
/* visibility: hidden; */
opacity: 0;
--delayOffset: -0.8s;
}
&.pos0 { grid-area: a; --delay: 0.8s; }
&.pos1 { grid-area: b; --delay: 0.9s; }
&.pos2 { grid-area: c; --delay: 1.0s; }
&.pos3 { grid-area: d; --delay: 1.1s; }
&.pos4 { grid-area: e; --delay: 1.2s; }
&.pos5 { grid-area: f; --delay: 1.3s; }
&.pos6 { grid-area: g; --delay: 1.4s; }
&.pos7 { grid-area: h; --delay: 1.5s; }
}
}
}
React
const items = [
{ id: 1 },
{ id: 2 },
{ id: 3 },
{ id: 4 },
{ id: 5 },
{ id: 6 },
{ id: 7 },
{ id: 8 },
{ id: 9 },
{ id: 10 },
{ id: 11 },
{ id: 12 },
{ id: 13 },
{ id: 14 },
{ id: 15 },
{ id: 16 },
{ id: 17 },
{ id: 18 },
{ id: 19 },
{ id: 20 },
{ id: 21 },
{ id: 22 },
{ id: 23 },
{ id: 24 },
];
function isDisplayedItem(index, displayedSlice) {
return index >= displayedSlice.start && index < displayedSlice.end;
}
const Carousel = () => {
const [displayedSlice, setDisplayedSlice] = React.useState({
start: 0,
end: 8,
});
const itemsPerSlide = 8;
return (
<div className="carousel-wrapper">
<button
className="arrow"
disabled={displayedSlice.start === 0}
onClick={() =>
setDisplayedSlice((currentSlice) => ({
start: currentSlice.start - itemsPerSlide,
end: currentSlice.end - itemsPerSlide,
}))
}
>
-
</button>
<div className="items-wrapper">
{items.map((item, index) => (
<div
key={index}
className={`item
${!isDisplayedItem(index, displayedSlice) ? "is-hidden" : ""}
pos${index % itemsPerSlide}
`}
>
{index}
</div>
))}
</div>
<button
className="arrow"
disabled={displayedSlice.end > items.length - 1}
onClick={() =>
setDisplayedSlice((currentSlice) => ({
start: currentSlice.start + itemsPerSlide,
end: currentSlice.end + itemsPerSlide,
}))
}
>
+
</button>
</div>
);
};
ReactDOM.render(<Carousel />, document.querySelector("#app"));