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:
parent
c3099d37c2
commit
aa322dfac3
@ -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": {
|
||||
|
||||
@ -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); }}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user