Nicholai 8d2620e0c1 feat(components): initialize custom component library with foundational files
- Added essential configuration files including components.json, package.json, and tsconfig.json to establish the component library structure.
- Introduced global styles in globals.css and layout structure in layout.tsx for consistent design application.
- Implemented various UI components such as Accordion, AlertDialog, Button, Card, and more, enhancing the component library for future development.
- Included utility functions and hooks to support component functionality and responsiveness.

This commit sets up the groundwork for a comprehensive UI component library, facilitating a modular and scalable design system.
2025-11-25 03:01:30 -07:00

57 lines
1.4 KiB
TypeScript

"use client"
import * as React from "react"
import { cn } from "@/lib/utils"
import { useEffect, useRef, useState } from "react"
export interface RevealProps extends React.HTMLAttributes<HTMLDivElement> {
delay?: number
}
const Reveal = React.forwardRef<HTMLDivElement, RevealProps>(({ className, delay = 0, children, ...props }, ref) => {
const elementRef = useRef<HTMLDivElement>(null)
const [isVisible, setIsVisible] = useState(false)
useEffect(() => {
const observer = new IntersectionObserver(
(entries) => {
entries.forEach((entry) => {
if (entry.isIntersecting) {
setTimeout(() => setIsVisible(true), delay)
observer.unobserve(entry.target)
}
})
},
{ threshold: 0.15, rootMargin: "0px 0px -50px 0px" },
)
if (elementRef.current) {
observer.observe(elementRef.current)
}
return () => observer.disconnect()
}, [delay])
return (
<div
ref={(node) => {
elementRef.current = node
if (typeof ref === "function") ref(node)
else if (ref) ref.current = node
}}
className={cn(
"transition-all duration-[0.8s] ease-out",
isVisible ? "opacity-100 translate-y-0" : "opacity-0 translate-y-[60px]",
className,
)}
style={{ transitionDelay: `${delay}ms` }}
{...props}
>
{children}
</div>
)
})
Reveal.displayName = "Reveal"
export { Reveal }