Modal
modal-1779394643382.tsx
'use client'
import { useState, useEffect } from 'react'
export default function Modal({
title = 'Confirm Action',
body = 'Are you sure you want to proceed? This action cannot be undone.',
confirmLabel = 'Confirm',
cancelLabel = 'Cancel',
danger = false,
}) {
const [open, setOpen] = useState(false)
const [loading, setLoading] = useState(false)
useEffect(() => {
if (open) document.body.style.overflow = 'hidden'
else document.body.style.overflow = ''
return () => { document.body.style.overflow = '' }
}, [open])
const confirm = () => {
setLoading(true)
setTimeout(() => { setLoading(false); setOpen(false) }, 1500)
}
return (
<>
<button onClick={()=>setOpen(true)} style={{ background:danger?'#ef4444':'#6d28d9', color:'#fff', border:'none', borderRadius:'10px', padding:'10px 22px', cursor:'pointer', fontWeight:700, fontSize:'14px' }}>
Open Modal
</button>
{open && (
<div style={{ position:'fixed', inset:0, zIndex:1000, display:'flex', alignItems:'center', justifyContent:'center', padding:'20px' }}>
<div onClick={()=>setOpen(false)} style={{ position:'absolute', inset:0, background:'rgba(0,0,0,0.5)', backdropFilter:'blur(4px)' }}/>
<div style={{
position:'relative', background:'#fff', borderRadius:'20px',
padding:'28px 24px', maxWidth:'420px', width:'100%',
boxShadow:'0 25px 80px rgba(0,0,0,0.3)',
animation:'slideUp 0.25s ease',
}}>
<style>{'@keyframes slideUp{from{opacity:0;transform:translateY(20px)}to{opacity:1;transform:none}}'}</style>
<div style={{ fontSize:'32px', marginBottom:'14px' }}>{danger?'⚠️':'ℹ️'}</div>
<h2 style={{ margin:'0 0 10px', fontSize:'18px', fontWeight:700, color:'#1e293b' }}>{title}</h2>
<p style={{ margin:'0 0 24px', fontSize:'14px', color:'#64748b', lineHeight:1.6 }}>{body}</p>
<div style={{ display:'flex', gap:'10px', justifyContent:'flex-end' }}>
<button onClick={()=>setOpen(false)} style={{ padding:'9px 20px', border:'1px solid #e2e8f0', borderRadius:'10px', background:'#fff', cursor:'pointer', fontWeight:600, color:'#374151', fontSize:'14px' }}>{cancelLabel}</button>
<button onClick={confirm} disabled={loading} style={{ padding:'9px 20px', border:'none', borderRadius:'10px', background:danger?'#ef4444':'#6d28d9', color:'#fff', cursor:loading?'wait':'pointer', fontWeight:700, fontSize:'14px', minWidth:'90px' }}>
{loading ? '⏳' : confirmLabel}
</button>
</div>
</div>
</div>
)}
</>
)
}Component info
CategoryOverlays
Frameworkreact
TierFREE
Views0
Copies0
About
Accessible modal dialog with backdrop, focus trap and animations
More from Overlays
'use client';
import React, { useState } from 'react';
interface AlertDialogProps {
isOpen: boolean;
onClose: () => void;
onConfirm: () => void;
title: string;
description: string;
}
const AlertDialog: React.FC<AlertDialogProps> = ({
iAlertDialog
Overlays
'use client';
import { useState, useEffect } from 'react';
interface Command {
id: number;
title: string;
description: string;
}
const commands: Command[] = [
{ id: 1, title: 'New File', description: 'Create a new file' },
{ id: 2, titleCommandPalette
Overlays
'use client'
import { useState, useEffect } from 'react'
const notifications = [
{ id: 1, type: '🎉', title: 'New component published', time: '2m ago', read: false },
{ id: 2, type: '💰', title: 'Pro subscription active', time: '1h ago', read: fDrawerPanel
Overlays
'use client';
import { useState } from 'react';
interface BottomSheetProps {
isOpen: boolean;
onClose: () => void;
}
const BottomSheet = ({ isOpen, onClose }: BottomSheetProps) => {
const [isDragging, setIsDragging] = useState(false);
consBottomSheet
Overlays