Spaces:
Running
Running
import { useRef, useCallback, type ReactNode } from "react"; | |
import type { GlassEffectProps } from "../types"; | |
import GlassFilters from "./GlassFilters"; | |
interface GlassContainerProps extends GlassEffectProps { | |
children: ReactNode; | |
className?: string; | |
onClick?: (e: React.MouseEvent) => void; | |
onMouseDown?: (e: React.MouseEvent) => void; | |
role?: string; | |
"aria-label"?: string; | |
"aria-labelledby"?: string; | |
style?: React.CSSProperties; | |
} | |
export default function GlassContainer({ | |
children, | |
className = "", | |
bgColor = "rgba(0, 0, 0, 0.25)", | |
highlight = "rgba(255, 255, 255, 0.15)", | |
onClick, | |
onMouseDown, | |
role, | |
style, | |
...ariaProps | |
}: GlassContainerProps) { | |
const specularRef = useRef<HTMLDivElement>(null); | |
const handleMouseMove = useCallback((e: React.MouseEvent) => { | |
if (!specularRef.current) return; | |
const rect = e.currentTarget.getBoundingClientRect(); | |
const x = e.clientX - rect.left; | |
const y = e.clientY - rect.top; | |
specularRef.current.style.background = `radial-gradient( | |
circle at ${x}px ${y}px, | |
rgba(255,255,255,0.15) 0%, | |
rgba(255,255,255,0.05) 30%, | |
rgba(255,255,255,0) 60% | |
)`; | |
}, []); | |
const handleMouseLeave = useCallback(() => { | |
if (specularRef.current) { | |
specularRef.current.style.background = "none"; | |
} | |
}, []); | |
return ( | |
<div | |
className={`glass-container relative overflow-hidden ${className}`} | |
onMouseMove={handleMouseMove} | |
onMouseLeave={handleMouseLeave} | |
onClick={onClick} | |
onMouseDown={onMouseDown} | |
role={role} | |
style={ | |
{ | |
"--bg-color": bgColor, | |
"--highlight": highlight, | |
"--text": "#ffffff", | |
...style, | |
} as React.CSSProperties | |
} | |
{...ariaProps} | |
> | |
<GlassFilters /> | |
{/* Glass layers */} | |
<div | |
className="glass-filter absolute inset-0 backdrop-blur-md z-10" | |
style={{ | |
filter: "url(#glass-distortion) saturate(120%) brightness(1.15)", | |
borderRadius: "inherit", | |
}} | |
/> | |
<div | |
className="glass-overlay absolute inset-0 z-20" | |
style={{ | |
background: "var(--bg-color)", | |
borderRadius: "inherit", | |
}} | |
/> | |
<div | |
ref={specularRef} | |
className="glass-specular absolute inset-0 z-30" | |
style={{ | |
boxShadow: "inset 1px 1px 1px var(--highlight)", | |
borderRadius: "inherit", | |
}} | |
/> | |
{/* Content */} | |
<div className="glass-content relative z-40">{children}</div> | |
</div> | |
); | |
} | |