refactor(ui): adopt useDismissable in ColorFilter and BulkActionBar

Replaces the hand-rolled outside-pointerdown listeners with the shared
hook. Both popovers now also close on Escape, and listeners only attach
while a panel is actually open.
This commit is contained in:
2026-07-04 07:22:09 +01:00
parent 5d46ee5b94
commit 54016df830
2 changed files with 7 additions and 19 deletions
+3 -9
View File
@@ -1,6 +1,7 @@
import { useEffect, useRef, useState } from "react";
import { useGalleryStore } from "../store";
import { BulkTagPopover } from "./bulk/BulkTagPopover";
import { useDismissable } from "./menu";
import { Tooltip } from "./Tooltip"
type Panel = "tag" | "rating" | "album" | "delete" | null;
@@ -28,15 +29,8 @@ export function BulkActionBar() {
const [newAlbumName, setNewAlbumName] = useState("");
const barRef = useRef<HTMLDivElement>(null);
// Close any open popover when clicking outside the bar.
useEffect(() => {
const onPointerDown = (event: PointerEvent) => {
if (barRef.current?.contains(event.target as Node)) return;
setPanel(null);
};
window.addEventListener("pointerdown", onPointerDown);
return () => window.removeEventListener("pointerdown", onPointerDown);
}, []);
// Close any open popover when clicking outside the bar or pressing Escape.
useDismissable(barRef, () => setPanel(null), panel !== null);
// Reset transient UI whenever the selection empties.
useEffect(() => {
+4 -10
View File
@@ -1,6 +1,7 @@
import { useEffect, useRef, useState } from "react";
import { useRef, useState } from "react";
import { AnimatePresence, motion } from "framer-motion";
import { useGalleryStore } from "../store";
import { useDismissable } from "./menu";
import { Tooltip } from "./Tooltip";
type Rgb = [number, number, number];
@@ -45,15 +46,8 @@ export function ColorFilter() {
const isActive = colorFilter !== null;
const isCustom = isActive && !SWATCHES.some((swatch) => rgbEquals(colorFilter, swatch.rgb));
// Collapse the panel when clicking elsewhere.
useEffect(() => {
if (!open) return;
const onPointerDown = (event: PointerEvent) => {
if (ref.current && !ref.current.contains(event.target as Node)) setOpen(false);
};
window.addEventListener("pointerdown", onPointerDown);
return () => window.removeEventListener("pointerdown", onPointerDown);
}, [open]);
// Collapse the panel when clicking elsewhere or pressing Escape.
useDismissable(ref, () => setOpen(false), open);
return (
<div ref={ref} className="relative ml-1 flex shrink-0 items-center border-l border-white/6 pl-2">