Skip to content

Commit 34e9ad3

Browse files
committed
Add the click-outside listerner to the modal/cart
1 parent b048847 commit 34e9ad3

2 files changed

Lines changed: 37 additions & 13 deletions

File tree

src/components/bucket-modal.tsx

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,15 @@
33
import { useStore } from '@/lib/store';
44
import { X, Trash2, Package } from 'lucide-react';
55
import { VersionNote } from './version-note';
6-
import { useEffect } from 'react';
6+
import { useEffect, useRef } from 'react';
77

88
interface BucketModalProps {
99
onClose: () => void;
1010
}
1111

1212
export function BucketModal({ onClose }: BucketModalProps) {
1313
const { bucket, removeFromBucket, clearBucket, setCurrentStep, updatePackageNote } = useStore();
14+
const modalRef = useRef<HTMLDivElement>(null);
1415

1516
const handleGenerateScript = () => {
1617
onClose();
@@ -21,20 +22,28 @@ export function BucketModal({ onClose }: BucketModalProps) {
2122
const handleKey = (e: KeyboardEvent) => {
2223
if (e.key === 'Escape') onClose();
2324
};
25+
26+
const handleClickOutside = (e: MouseEvent) => {
27+
if (modalRef.current && !modalRef.current.contains(e.target as Node)) {
28+
onClose();
29+
}
30+
};
31+
2432
window.addEventListener('keydown', handleKey);
25-
return () => window.removeEventListener('keydown', handleKey);
33+
document.addEventListener('mousedown', handleClickOutside);
34+
35+
return () => {
36+
window.removeEventListener('keydown', handleKey);
37+
document.removeEventListener('mousedown', handleClickOutside);
38+
};
2639
}, [onClose]);
2740

2841
return (
2942
<>
30-
{/* Backdrop */}
31-
<div
32-
className="fixed inset-0 z-40 bg-black/40 backdrop-blur-[2px]"
33-
onClick={onClose}
34-
/>
35-
3643
{/* Modal */}
37-
<div className="absolute right-0 top-full mt-2 w-88 max-h-[520px]
44+
<div
45+
ref={modalRef}
46+
className="absolute right-0 top-full mt-2 w-88 max-h-[520px]
3847
terminal-card rounded-lg shadow-2xl z-50 border border-border flex flex-col"
3948
style={{ width: '22rem' }}>
4049
{/* Header */}

src/components/presets-modal.tsx

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import { useStore } from '@/lib/store';
44
import { presets } from '@/lib/presets';
55
import { appCatalog } from '@/lib/apps';
66
import { X, Clock, Layers, Check } from 'lucide-react';
7-
import { useState, useEffect } from 'react';
7+
import { useState, useEffect, useRef } from 'react';
88
import { estimateInstallTime } from '@/lib/script-generator';
99
import { Package } from '@/types';
1010

@@ -15,13 +15,26 @@ interface PresetsModalProps {
1515
export function PresetsModal({ onClose }: PresetsModalProps) {
1616
const { loadPreset, bucket, os } = useStore();
1717
const [applied, setApplied] = useState<string | null>(null);
18+
const modalRef = useRef<HTMLDivElement>(null);
1819

1920
useEffect(() => {
2021
const handleKey = (e: KeyboardEvent) => {
2122
if (e.key === 'Escape') onClose();
2223
};
24+
25+
const handleClickOutside = (e: MouseEvent) => {
26+
if (modalRef.current && !modalRef.current.contains(e.target as Node)) {
27+
onClose();
28+
}
29+
};
30+
2331
window.addEventListener('keydown', handleKey);
24-
return () => window.removeEventListener('keydown', handleKey);
32+
document.addEventListener('mousedown', handleClickOutside);
33+
34+
return () => {
35+
window.removeEventListener('keydown', handleKey);
36+
document.removeEventListener('mousedown', handleClickOutside);
37+
};
2538
}, [onClose]);
2639

2740
const handleApply = (presetId: string, packageIds: string[]) => {
@@ -34,9 +47,11 @@ export function PresetsModal({ onClose }: PresetsModalProps) {
3447

3548
return (
3649
<>
37-
<div className="fixed inset-0 z-40 bg-black/60 backdrop-blur-sm" onClick={onClose} />
50+
<div className="fixed inset-0 z-40 bg-black/60 backdrop-blur-sm" />
3851
<div className="fixed inset-0 z-50 flex items-center justify-center p-4">
39-
<div className="w-full max-w-3xl terminal-card rounded-xl overflow-hidden shadow-2xl"
52+
<div
53+
ref={modalRef}
54+
className="w-full max-w-3xl terminal-card rounded-xl overflow-hidden shadow-2xl"
4055
style={{ boxShadow: '0 0 60px rgba(0,255,128,0.15)' }}>
4156
{/* Header */}
4257
<div className="flex items-center justify-between p-5 border-b border-border bg-card">

0 commit comments

Comments
 (0)