fix: list style popover no longer clipped by card overflow:hidden

ListVisualsPopover used position:absolute which was clipped by the
weekly-someday-list card's overflow:hidden. Now uses position:fixed
anchored to the card's bounding rect. IconPicker sub-panel also
updated to position:fixed. Stabilized mousedown listener (onCloseRef
pattern, empty deps).

v1.108.3
This commit is contained in:
mARTin-B78 2026-05-11 12:19:55 +02:00
parent c3099d37c2
commit aa322dfac3
2 changed files with 17 additions and 9 deletions

View File

@ -1,6 +1,6 @@
{
"name": "my-weekly-todo-list",
"version": "1.108.2",
"version": "1.108.3",
"description": "A web-based weekly task management application that organizes to-dos and calendar events in a single, intuitive weekly view",
"main": "index.js",
"scripts": {

View File

@ -723,6 +723,7 @@ export default function WeeklyView() {
const [menuOpenListId, setMenuOpenListId] = useState<string | null>(null);
// Punkt 7+8: per-list color/icon edit popover, and per-tab settings popover
const [editingListVisualsId, setEditingListVisualsId] = useState<string | null>(null);
const [editingListVisualsRect, setEditingListVisualsRect] = useState<DOMRect | null>(null);
const [editingTabVisualsName, setEditingTabVisualsName] = useState<string | null>(null);
const [editingTabVisualsRect, setEditingTabVisualsRect] = useState<DOMRect | null>(null);
const [activeSomedayTab, setActiveSomedayTab] = useState<string | null>(null);
@ -8468,7 +8469,7 @@ export default function WeeklyView() {
</select>
</div>
{/* Edit style */}
<button onClick={(e) => { e.stopPropagation(); setEditingListVisualsId(list.id); setMenuOpenListId(null); }} style={{ width: "100%", display: "flex", alignItems: "center", gap: "8px", padding: "8px 12px", fontSize: "0.8rem", color: darkMode ? "#e5e7eb" : "#374151", background: "none", border: "none", cursor: "pointer", textAlign: "left" }}>
<button onClick={(e) => { e.stopPropagation(); setEditingListVisualsRect((e.currentTarget as HTMLElement).closest(".weekly-someday-list")?.getBoundingClientRect() ?? (e.currentTarget as HTMLElement).getBoundingClientRect()); setEditingListVisualsId(list.id); setMenuOpenListId(null); }} style={{ width: "100%", display: "flex", alignItems: "center", gap: "8px", padding: "8px 12px", fontSize: "0.8rem", color: darkMode ? "#e5e7eb" : "#374151", background: "none", border: "none", cursor: "pointer", textAlign: "left" }}>
<Pencil size={13} style={{ opacity: 0.6, flexShrink: 0 }} />
{profile.language === "de" ? "Stil bearbeiten" : "Edit style"}
</button>
@ -8513,6 +8514,7 @@ export default function WeeklyView() {
language={profile.language}
onChange={(updates) => updateListVisuals(list.id, updates)}
onClose={() => setEditingListVisualsId(null)}
anchorRect={editingListVisualsRect}
/>
)}
@ -10917,31 +10919,37 @@ function ListVisualsPopover({
language,
onChange,
onClose,
anchorRect,
}: {
list: { id: string; title: string; color?: string | null; icon?: string | null };
darkMode: boolean;
language: string;
anchorRect?: DOMRect | null;
onChange: (updates: { color?: string | null; icon?: string | null }) => void;
onClose: () => void;
}) {
const [iconPickerOpen, setIconPickerOpen] = useState(false);
const containerRef = useRef<HTMLDivElement>(null);
const onCloseRef = useRef(onClose);
useEffect(() => { onCloseRef.current = onClose; }, [onClose]);
useEffect(() => {
const onDoc = (e: MouseEvent) => {
if (containerRef.current && !containerRef.current.contains(e.target as Node)) onClose();
if (containerRef.current && !containerRef.current.contains(e.target as Node)) onCloseRef.current();
};
document.addEventListener("mousedown", onDoc);
return () => document.removeEventListener("mousedown", onDoc);
}, [onClose]);
}, []);
const de = language === "de";
const top = anchorRect ? anchorRect.top + 32 : -9999;
const left = anchorRect ? anchorRect.left + 4 : -9999;
return (
<div
ref={containerRef}
style={{
position: "absolute",
top: "32px",
right: "4px",
zIndex: 50,
position: "fixed",
top,
left,
zIndex: 10000,
background: darkMode ? "#1e1e2e" : "#fff",
border: `1px solid ${darkMode ? "#444" : "#e5e7eb"}`,
borderRadius: "10px",
@ -10981,7 +10989,7 @@ function ListVisualsPopover({
)}
</div>
{iconPickerOpen && (
<div style={{ position: "absolute", top: "78px", right: "12px", zIndex: 60 }}>
<div style={{ position: "fixed", top: top + 78, left, zIndex: 10001 }}>
<IconPicker
selectedIcon={list.icon || ""}
onSelect={(name) => { onChange({ icon: name }); setIconPickerOpen(false); }}