Files
reui-blocks/blocks/feature248.tsx
T

104 lines
3.2 KiB
TypeScript

"use client";
import type { MotionValue } from "motion/react";
import { motion, useScroll, useTransform } from "motion/react";
import type { ComponentPropsWithoutRef, FC, ReactNode } from "react";
import React from "react";
import { useRef } from "react";
import { cn } from "@/lib/utils";
const REVEAL_TEXT =
"تمام تعاملات، سرنخ‌ها و قراردادها در یک فضای کاری متمرکز جمع می‌شود. تیم فروش بدون جابجایی بین ابزارها، سریع‌تر پیش‌بینی می‌کند و معاملات بیشتری می‌بندد.";
const Feature248 = () => {
return (
<section dir="rtl" lang="fa" className="dark bg-background py-32">
<div className="container flex flex-col items-center justify-center">
<TextReveal className="font-medium xl:text-3xl" maxWidth="86rem">
{REVEAL_TEXT}
</TextReveal>
</div>
</section>
);
};
export { Feature248 };
// Below is the modified component from Magic UI
// Original source: https://magicui.design/docs/components/text-reveal
// Modified to follow our coding standards and design system
// We respect copyright and attribution to the original creators
interface TextRevealProps extends ComponentPropsWithoutRef<"div"> {
children: string;
title?: string;
maxWidth?: string;
}
const TextReveal: FC<TextRevealProps> = ({
children,
title,
className,
maxWidth,
}) => {
const targetRef = useRef<HTMLDivElement | null>(null);
const { scrollYProgress } = useScroll({
target: targetRef,
});
const words = children.split(" ");
return (
<div
ref={targetRef}
className={cn("relative z-0 h-[200vh]", className)}
style={{ maxWidth: maxWidth || "56rem" }}
>
<div className="sticky top-0 mx-auto flex h-[50%] items-center bg-transparent px-4 py-20">
<div className="flex flex-col justify-center">
{title ? (
<span className="text-center text-lg font-medium tracking-tight text-foreground">
{title}
</span>
) : null}
<span
className={cn(
"flex flex-wrap p-5 text-xl font-semibold text-balance text-black/20 md:p-8 md:text-3xl lg:p-10 lg:text-xl xl:text-2xll dark:text-white/20",
className,
)}
>
{words.map((word, i) => {
const start = i / words.length;
const end = start + 1 / words.length;
return (
<Word key={`${word}-${i}`} progress={scrollYProgress} range={[start, end]}>
{word}
</Word>
);
})}
</span>
</div>
</div>
</div>
);
};
interface WordProps {
children: ReactNode;
progress: MotionValue<number>;
range: [number, number];
}
const Word: FC<WordProps> = ({ children, progress, range }) => {
const opacity = useTransform(progress, range, [0, 1]);
return (
<span className="relative mx-1 lg:mx-1.5">
<span className="absolute opacity-30">{children}</span>
<motion.span style={{ opacity }} className="text-black dark:text-white">
{children}
</motion.span>
</span>
);
};