-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathGlassModal.tsx
More file actions
103 lines (91 loc) · 2.32 KB
/
GlassModal.tsx
File metadata and controls
103 lines (91 loc) · 2.32 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
import React, { useEffect } from 'react';
import ReactDOM from 'react-dom';
import clsx from 'clsx';
import { GlassContainer } from './GlassContainer';
import { GlassIntensity } from '../types/glass';
export interface GlassModalProps {
isOpen: boolean;
onClose: () => void;
children: React.ReactNode;
size?: 'small' | 'medium' | 'large' | 'full';
intensity?: GlassIntensity;
closeOnOverlay?: boolean;
className?: string;
}
export const GlassModal: React.FC<GlassModalProps> = ({
isOpen,
onClose,
children,
size = 'medium',
intensity = 'strong',
closeOnOverlay = true,
className,
}) => {
const [mounted, setMounted] = React.useState(false);
useEffect(() => {
setMounted(true);
return () => setMounted(false);
}, []);
useEffect(() => {
if (isOpen) {
document.body.style.overflow = 'hidden';
} else {
document.body.style.overflow = 'unset';
}
return () => {
document.body.style.overflow = 'unset';
};
}, [isOpen]);
useEffect(() => {
const handleEscape = (event: KeyboardEvent) => {
if (event.key === 'Escape') {
onClose();
}
};
if (isOpen) {
document.addEventListener('keydown', handleEscape);
}
return () => {
document.removeEventListener('keydown', handleEscape);
};
}, [isOpen, onClose]);
if (!mounted || !isOpen) return null;
const sizeClasses = {
small: 'max-w-sm',
medium: 'max-w-md',
large: 'max-w-2xl',
full: 'max-w-full mx-4',
};
const modalContent = (
<div className="fixed inset-0 z-50 flex items-center justify-center p-4">
<div
className="absolute inset-0 bg-black/20 backdrop-blur-sm"
onClick={closeOnOverlay ? onClose : undefined}
/>
<GlassContainer
intensity={intensity}
blur={32}
saturation={200}
luminosity={110}
cornerRadius={20}
borderWidth={0.5}
borderOpacity={0.25}
shadowIntensity={0.3}
className={clsx(
'glass-modal',
'relative',
'w-full',
sizeClasses[size],
'max-h-[90vh]',
'overflow-y-auto',
className
)}
>
<div className="p-6">
{children}
</div>
</GlassContainer>
</div>
);
return ReactDOM.createPortal(modalContent, document.body);
};