Skip to content

Commit a09fff1

Browse files
committed
editing overlaying to scroll container
1 parent 097ec21 commit a09fff1

1 file changed

Lines changed: 38 additions & 55 deletions

File tree

scrapflow-client/src/components/ui/Modal.jsx

Lines changed: 38 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,6 @@ import * as Dialog from '@radix-ui/react-dialog'
22
import { motion, AnimatePresence } from 'framer-motion'
33
import { X } from 'lucide-react'
44

5-
/**
6-
* Accessible modal built on Radix Dialog with glass-style card.
7-
*
8-
* Usage:
9-
* <Modal open={open} onOpenChange={setOpen} title="My Modal">
10-
* <p>Content here</p>
11-
* </Modal>
12-
*/
135
export default function Modal({ open, onOpenChange, title, description, children, size = 'md' }) {
146
const widths = { sm: 'max-w-sm', md: 'max-w-lg', lg: 'max-w-2xl', xl: 'max-w-4xl' }
157

@@ -18,69 +10,60 @@ export default function Modal({ open, onOpenChange, title, description, children
1810
<AnimatePresence>
1911
{open && (
2012
<Dialog.Portal forceMount>
13+
{/* Overlay doubles as the scroll container */}
2114
<Dialog.Overlay asChild>
2215
<motion.div
2316
initial={{ opacity: 0 }}
2417
animate={{ opacity: 1 }}
2518
exit={{ opacity: 0 }}
26-
className="fixed inset-0 z-50 bg-black/40 backdrop-blur-sm"
27-
/>
28-
</Dialog.Overlay>
29-
30-
<Dialog.Content asChild>
31-
<motion.div
32-
initial={{ opacity: 0, scale: 0.96, y: 12 }}
33-
animate={{ opacity: 1, scale: 1, y: 0 }}
34-
exit={{ opacity: 0, scale: 0.96, y: 12 }}
35-
transition={{ duration: 0.2, ease: 'easeOut' }}
36-
className={`fixed z-50 left-1/2 top-1/2 -translate-x-1/2 -translate-y-1/2
37-
w-full ${widths[size] ?? widths.md} mx-4
38-
glass-card outline-none flex flex-col`}
39-
style={{ maxHeight: '90vh' }}
19+
style={{ overflowY: 'auto' }}
20+
className="fixed inset-0 z-50 bg-black/40 backdrop-blur-sm flex items-start justify-center p-4 py-8"
4021
>
41-
{/* Header */}
42-
<div className="flex-shrink-0 px-6 pt-6 pb-0">
43-
{(title || description) && (
44-
<div className="mb-5 pr-8">
45-
{title && (
46-
<Dialog.Title className="text-lg font-bold text-[var(--color-text)] leading-tight">
47-
{title}
48-
</Dialog.Title>
49-
)}
50-
{description && (
51-
<Dialog.Description className="text-sm text-[var(--color-text-muted)] mt-1">
52-
{description}
53-
</Dialog.Description>
54-
)}
55-
</div>
56-
)}
57-
</div>
22+
<Dialog.Content asChild>
23+
<motion.div
24+
initial={{ opacity: 0, scale: 0.96, y: 12 }}
25+
animate={{ opacity: 1, scale: 1, y: 0 }}
26+
exit={{ opacity: 0, scale: 0.96, y: 12 }}
27+
transition={{ duration: 0.2, ease: 'easeOut' }}
28+
className={`relative w-full ${widths[size] ?? widths.md} glass-card p-6 outline-none my-auto`}
29+
>
30+
{/* Header */}
31+
{(title || description) && (
32+
<div className="mb-5 pr-8">
33+
{title && (
34+
<Dialog.Title className="text-lg font-bold text-[var(--color-text)] leading-tight">
35+
{title}
36+
</Dialog.Title>
37+
)}
38+
{description && (
39+
<Dialog.Description className="text-sm text-[var(--color-text-muted)] mt-1">
40+
{description}
41+
</Dialog.Description>
42+
)}
43+
</div>
44+
)}
5845

59-
{/* Close */}
60-
<Dialog.Close asChild>
61-
<button className="absolute top-4 right-4 w-7 h-7 flex items-center justify-center
62-
rounded-lg text-[var(--color-text-muted)] hover:text-[var(--color-text)]
63-
hover:bg-[var(--color-surface-2)] transition-colors">
64-
<X size={16} />
65-
</button>
66-
</Dialog.Close>
46+
{/* Close */}
47+
<Dialog.Close asChild>
48+
<button className="absolute top-4 right-4 w-7 h-7 flex items-center justify-center
49+
rounded-lg text-[var(--color-text-muted)] hover:text-[var(--color-text)]
50+
hover:bg-[var(--color-surface-2)] transition-colors">
51+
<X size={16} />
52+
</button>
53+
</Dialog.Close>
6754

68-
{/* Scrollable content */}
69-
<div className="flex-1 overflow-y-auto px-6 pb-6">
70-
{children}
71-
</div>
55+
{children}
56+
</motion.div>
57+
</Dialog.Content>
7258
</motion.div>
73-
</Dialog.Content>
59+
</Dialog.Overlay>
7460
</Dialog.Portal>
7561
)}
7662
</AnimatePresence>
7763
</Dialog.Root>
7864
)
7965
}
8066

81-
/**
82-
* Convenience component for modal footer with action buttons.
83-
*/
8467
export function ModalFooter({ children }) {
8568
return (
8669
<div className="flex justify-end gap-3 mt-6 pt-4 border-t border-[var(--color-border)]">

0 commit comments

Comments
 (0)