feat(ui): composant Modal réutilisable (overlay + Escape)
This commit is contained in:
@@ -0,0 +1,72 @@
|
|||||||
|
import { useEffect } from 'react'
|
||||||
|
|
||||||
|
interface ModalProps {
|
||||||
|
title: string
|
||||||
|
onClose: () => void
|
||||||
|
children: React.ReactNode
|
||||||
|
width?: number
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function Modal({ title, onClose, children, width = 480 }: ModalProps) {
|
||||||
|
useEffect(() => {
|
||||||
|
function onKey(e: KeyboardEvent) {
|
||||||
|
if (e.key === 'Escape') onClose()
|
||||||
|
}
|
||||||
|
window.addEventListener('keydown', onKey)
|
||||||
|
return () => window.removeEventListener('keydown', onKey)
|
||||||
|
}, [onClose])
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
onClick={onClose}
|
||||||
|
style={{
|
||||||
|
position: 'fixed',
|
||||||
|
inset: 0,
|
||||||
|
background: 'rgba(0,0,0,0.6)',
|
||||||
|
display: 'flex',
|
||||||
|
alignItems: 'center',
|
||||||
|
justifyContent: 'center',
|
||||||
|
zIndex: 200,
|
||||||
|
padding: 16,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
onClick={e => e.stopPropagation()}
|
||||||
|
className="glass"
|
||||||
|
style={{
|
||||||
|
width: '100%',
|
||||||
|
maxWidth: width,
|
||||||
|
borderRadius: 12,
|
||||||
|
padding: 20,
|
||||||
|
display: 'flex',
|
||||||
|
flexDirection: 'column',
|
||||||
|
gap: 16,
|
||||||
|
maxHeight: '90dvh',
|
||||||
|
overflowY: 'auto',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between' }}>
|
||||||
|
<h2 style={{ margin: 0, color: 'var(--accent)', fontFamily: 'var(--font-mono)', fontSize: 16 }}>
|
||||||
|
{title}
|
||||||
|
</h2>
|
||||||
|
<button
|
||||||
|
onClick={onClose}
|
||||||
|
style={{
|
||||||
|
background: 'transparent',
|
||||||
|
border: 'none',
|
||||||
|
color: 'var(--ink-3)',
|
||||||
|
fontSize: 20,
|
||||||
|
cursor: 'pointer',
|
||||||
|
lineHeight: 1,
|
||||||
|
padding: 4,
|
||||||
|
}}
|
||||||
|
aria-label="Fermer"
|
||||||
|
>
|
||||||
|
✕
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
{children}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user