'use client'; import { forwardRef, useEffect, useRef, HTMLAttributes } from 'react'; export interface StrataSectionProps extends HTMLAttributes { /** Depth in meters for this stratum */ depth: number; /** Background color */ color?: string; /** Text color */ textColor?: string; /** Pattern overlay type */ pattern?: 'lines' | 'lines-diagonal' | 'dots' | 'gradient' | 'fossil' | 'rust' | 'none'; /** Font family override */ font?: string; /** Section title */ title?: string; /** Section description */ description?: string; /** Statistics to display */ stats?: Array<{ label: string; value: string | number }>; /** Content position */ position?: 'left' | 'center' | 'right'; /** Show jagged edge at bottom */ showEdge?: boolean; /** Show stratum number label */ showNumber?: boolean; /** Show decorative line */ showLine?: boolean; /** Enable fade-in animation on scroll */ animate?: boolean; /** Animation threshold (0-1) */ animationThreshold?: number; /** Spacing for title in pixels */ spacing?: number; } const positionClasses = { left: 'items-start text-left', center: 'items-center text-center', right: 'items-end text-right', }; export const StrataSection = forwardRef( ( { depth, color = '#8b8680', textColor, pattern = 'none', font, title, description, stats, position = 'center', showEdge = true, showNumber = true, showLine = false, animate = true, animationThreshold = 0.3, spacing = 40, className, style, children, ...props }, ref ) => { const containerRef = useRef(null); const contentRef = useRef(null); // Merge refs const setRef = (element: HTMLElement | null) => { containerRef.current = element; if (typeof ref === 'function') { ref(element); } else if (ref) { ref.current = element; } }; // Intersection Observer for fade-in animation useEffect(() => { if (!animate || !contentRef.current) return; const observer = new IntersectionObserver( (entries) => { entries.forEach((entry) => { if (entry.isIntersecting) { entry.target.classList.add('in-view'); } }); }, { threshold: animationThreshold, rootMargin: '-10% 0px -10% 0px', } ); observer.observe(contentRef.current); return () => { observer.disconnect(); }; }, [animate, animationThreshold]); const hasContent = title || description || stats || children; // Pattern backgrounds const patternStyles = { lines: { backgroundImage: 'repeating-linear-gradient(0deg, transparent, transparent 2px, rgba(0,0,0,0.02) 2px, rgba(0,0,0,0.02) 4px)', }, 'lines-diagonal': { backgroundImage: 'repeating-linear-gradient(2deg, transparent, transparent 3px, rgba(0,0,0,0.03) 3px, rgba(0,0,0,0.03) 6px)', }, dots: { backgroundImage: 'radial-gradient(circle, currentColor 1px, transparent 1px)', backgroundSize: '20px 20px', }, gradient: { backgroundImage: 'linear-gradient(180deg, rgba(255,255,255,0.1) 0%, transparent 100%)', }, fossil: { backgroundImage: 'radial-gradient(ellipse at 30% 70%, rgba(255,255,255,0.1) 0%, transparent 50%)', }, rust: { backgroundImage: 'radial-gradient(ellipse at 80% 20%, rgba(139,105,20,0.3) 0%, transparent 40%), radial-gradient(ellipse at 20% 80%, rgba(60,40,30,0.4) 0%, transparent 40%)', }, none: {}, }; return (
{/* Pattern overlay */} {pattern !== 'none' && (
)} {/* Fossil decoration */} {pattern === 'fossil' && (
); } ); StrataSection.displayName = 'StrataSection'; export default StrataSection;