Je crée un composant modal personnalisé dans React + Typescript.
// src/components/ui/Modal.tsx import React, { useState, useEffect, useRef } from 'react'; interface ModalProps { isOpen: boolean; onClose: () => void; children: React.ReactNode; dismissable?: boolean; closeOnEsc?: boolean; closeButtonLabel?: string; size?: 'small' | 'medium' | 'large'; position?: 'center' | 'top' | 'bottom'; } const Modal: React.FC<ModalProps> = ({ isOpen, onClose, children, dismissable = true, closeOnEsc = true, closeButtonLabel = '×', size = 'medium', position = 'center', }) => { const [isModalOpen, setIsModalOpen] = useState(isOpen); const modalRef = useRef<HTMLDivElement>(null); useEffect(() => { setIsModalOpen(isOpen); }, [isOpen]); useEffect(() => { const handleOutsideClick = (event: MouseEvent) => { if (dismissable && modalRef.current && !modalRef.current.contains(event.target as Node)) { onClose(); } }; const handleEscKey = (event: KeyboardEvent) => { if (closeOnEsc && event.key === 'Escape') { onClose(); } }; if (isModalOpen) { document.addEventListener('mousedown', handleOutsideClick); document.addEventListener('keydown', handleEscKey); } return () => { document.removeEventListener('mousedown', handleOutsideClick); document.removeEventListener('keydown', handleEscKey); }; }, [isModalOpen, onClose, dismissable, closeOnEsc]); if (!isModalOpen) { return null; } const getSizeStyle = () => { switch (size) { case 'small': return { width: '300px', maxWidth: '100%' }; case 'large': return { width: '800px', maxWidth: '100%' }; default: return { width: '500px', maxWidth: '100%' }; } }; const getPositionStyle = () => { switch (position) { case 'top': return { alignItems: 'flex-start' }; case 'bottom': return { alignItems: 'flex-end' }; default: return { alignItems: 'center' }; } }; return ( <div style={{ position: 'fixed', top: 0, left: 0, right: 0, bottom: 0, backgroundColor: 'rgba(0, 0, 0, 0.5)', display: 'flex', justifyContent: 'center', zIndex: 1000, ...getPositionStyle(), }}> <div ref={modalRef} style={{ backgroundColor: 'white', padding: '20px', borderRadius: '8px', maxHeight: '80vh', overflow: 'auto', position: 'relative', ...getSizeStyle(), }} > <button onClick={onClose} style={{ position: 'absolute', top: '10px', right: '10px', background: 'none', border: 'none', fontSize: '18px', cursor: 'pointer', }} > {closeButtonLabel} </button> {children} </div> </div> ); }; export default Modal;
import Modal from "@/components/ui/Modal"; import { useState } from "react"; export default function Home() { const [visible, setVisible] = useState(false); return ( <main> <button onClick={() => setVisible(true)}>isOpen</button> <Modal position="bottom" isOpen={visible} onClose={() => setVisible(false)}> <h2>Modal Content</h2> <p>This is a simple modal component.</p> </Modal> </main> ); }
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!