@theguild/components
Version:
107 lines (106 loc) • 2.96 kB
JavaScript
"use client";
import { jsx, jsxs } from "react/jsx-runtime";
import { cn } from "@theguild/components";
import { useTweenPlaybackRate } from "./use-tween-playback-rate";
const PresetSpeedToMs = {
fast: 2e4,
normal: 4e4,
slow: 6e4
};
function Marquee({
direction = "left",
speed = "normal",
pauseOnHover = false,
className,
children,
pauseDurationSeconds = 1,
...rest
}) {
const animationDuration = typeof speed === "number" ? speed : PresetSpeedToMs[speed];
const tweenPlaybackRate = useTweenPlaybackRate();
const STEP = 1 / (pauseDurationSeconds * 1e3);
return /* @__PURE__ */ jsxs(
"div",
{
className: cn(
"[mask-image:linear-gradient(to_right,transparent,white_20%,white_80%,transparent)]",
className
),
...rest,
children: [
/* @__PURE__ */ jsxs(
"div",
{
className: cn(
"flex w-max animate-[marquee_var(--animation-duration)_var(--animation-direction)_linear_infinite] gap-1 py-0.5 sm:gap-2 sm:py-1"
),
style: {
"--animation-duration": `${animationDuration}ms`,
"--animation-direction": direction === "left" ? "forwards" : "reverse"
// eslint-disable-next-line @typescript-eslint/no-empty-object-type
},
onMouseEnter: pauseOnHover ? (event) => {
const animation = event.currentTarget.getAnimations()[0];
if (animation) tweenPlaybackRate(animation, -STEP);
} : void 0,
onMouseLeave: pauseOnHover ? (event) => {
const animation = event.currentTarget.getAnimations()[0];
if (animation) tweenPlaybackRate(animation, STEP);
} : void 0,
children: [
children,
children
]
}
),
/* @__PURE__ */ jsx("style", {
href: "Marquee-keyframes",
/* css */
children: `
@keyframes marquee {
to {
translate: calc(-50% - .5rem);
}
}
`
})
]
}
);
}
function MarqueeRows({
children,
rows,
pauseOnHover,
speed,
className,
...rest
}) {
const chunkSize = Math.floor(children.length / rows);
const remainder = children.length % rows;
const chunks = [];
let start = 0;
for (let i = 0; i < rows; i++) {
const end = start + chunkSize + (i < remainder ? 1 : 0);
chunks.push(children.slice(start, end));
start = end;
}
return /* @__PURE__ */ jsx("div", { className: cn("overflow-hidden", className), ...rest, children: chunks.map((chunk, index) => /* @__PURE__ */ jsxs(
Marquee,
{
direction: index % 2 ? "left" : "right",
pauseOnHover,
speed,
children: [
chunk,
index === chunks.length - 1 && chunk
]
},
index
)) });
}
MarqueeRows.Rows = MarqueeRows;
export {
Marquee,
MarqueeRows
};