'use client'; import { forwardRef, HTMLAttributes } from 'react'; export interface PaperEdgesProps extends HTMLAttributes { /** Edge style */ style?: 'aged' | 'torn' | 'burnt' | 'ink' | 'frayed'; /** Edge intensity */ intensity?: 'light' | 'medium' | 'heavy'; /** Corner style */ corners?: 'rounded' | 'sharp' | 'ragged'; /** Background color */ backgroundColor?: string; /** Show deckle edge */ deckle?: boolean; } const cornerClasses = { rounded: 'rounded-lg', sharp: 'rounded-none', ragged: 'rounded-sm', }; const intensityShadows = { light: 'shadow-sm', medium: 'shadow-md', heavy: 'shadow-xl', }; const noiseSvg = ``; const burnSvg = ``; const fraySvg = ``; const deckleSvg = ``; export const PaperEdges = forwardRef( ( { style: edgeStyle = 'aged', intensity = 'medium', corners = 'rounded', backgroundColor = '#f5f0e6', deckle = false, className, children, ...props }, ref ) => { // Base classes const baseClasses = `relative p-6 ${cornerClasses[corners]} ${intensityShadows[intensity]}`; // Style-specific additions const styleAdditions: Record = { aged: '', torn: '', burnt: '', ink: '', frayed: '', }; // Build inline styles const getInlineStyle = (): React.CSSProperties => { const baseStyle: React.CSSProperties = { backgroundColor }; switch (edgeStyle) { case 'aged': baseStyle.background = `linear-gradient(135deg, rgba(0,0,0,0.05) 0%, transparent 20%, transparent 80%, rgba(0,0,0,0.1) 100%), ${backgroundColor}`; break; case 'burnt': baseStyle.background = `linear-gradient(135deg, rgba(139,0,0,0.15) 0%, transparent 15%, transparent 85%, rgba(139,0,0,0.2) 100%), ${backgroundColor}`; break; case 'torn': baseStyle.clipPath = 'polygon(0% 2%, 3% 0%, 5% 3%, 7% 1%, 9% 4%, 11% 0%, 100% 0%, 100% 98%, 97% 100%, 95% 97%, 93% 99%, 91% 96%, 89% 100%, 0% 100%)'; break; case 'frayed': baseStyle.backgroundImage = `url("data:image/svg+xml,${encodeURIComponent(fraySvg)}")`; break; case 'deckle': baseStyle.backgroundImage = `url("data:image/svg+xml,${encodeURIComponent(deckleSvg)}")`; break; } return baseStyle; }; return (
{children} {/* Texture overlays */} {edgeStyle === 'aged' && ( <>
)} {edgeStyle === 'burnt' && ( <>
)} {edgeStyle === 'ink' && ( <>
)} {edgeStyle === 'frayed' && (
)} {deckle && (
)}
); } ); PaperEdges.displayName = 'PaperEdges'; export default PaperEdges;