diff --git a/frontend/src/components/FocusView/DeliverableCard.jsx b/frontend/src/components/FocusView/DeliverableCard.jsx
index 239df78..8f51905 100644
--- a/frontend/src/components/FocusView/DeliverableCard.jsx
+++ b/frontend/src/components/FocusView/DeliverableCard.jsx
@@ -17,10 +17,15 @@ export default function DeliverableCard({ deliverable, isActive, index, projectC
x: e.clientX,
y: e.clientY,
items: [
- { icon: '\u270e', label: 'Edit Deliverable', highlight: true, action: () => onEdit(deliverable) },
+ {
+ icon: '✎',
+ label: 'Edit Deliverable',
+ highlight: true,
+ action: () => onEdit(deliverable),
+ },
{ separator: true },
...STATUS_OPTIONS.map(s => ({
- icon: s.value === deliverable.status ? '\u25cf' : '\u25cb',
+ icon: s.value === deliverable.status ? '●' : '○',
label: `Mark ${s.label}`,
action: async () => {
storeUpdate(await updateDeliverable(deliverable.id, { status: s.value }))
@@ -28,7 +33,7 @@ export default function DeliverableCard({ deliverable, isActive, index, projectC
})),
{ separator: true },
{
- icon: '\u2715',
+ icon: '✕',
label: 'Delete Deliverable',
danger: true,
action: async () => {
@@ -60,7 +65,6 @@ export default function DeliverableCard({ deliverable, isActive, index, projectC
Selected
)}
-
Deliverable {index + 1}
{deliverable.title}
{formatDate(deliverable.due_date)}
@@ -68,7 +72,12 @@ export default function DeliverableCard({ deliverable, isActive, index, projectC
{ctxMenu && (
- setCtxMenu(null)} />
+ setCtxMenu(null)}
+ />
)}
>
)
diff --git a/frontend/src/components/UI/ContextMenu.jsx b/frontend/src/components/UI/ContextMenu.jsx
index fe97c5a..4c3a2bd 100644
--- a/frontend/src/components/UI/ContextMenu.jsx
+++ b/frontend/src/components/UI/ContextMenu.jsx
@@ -1,11 +1,16 @@
import { useEffect, useRef } from 'react'
+import { createPortal } from 'react-dom'
export default function ContextMenu({ x, y, items, onClose }) {
const ref = useRef(null)
useEffect(() => {
- const onMouseDown = (e) => { if (ref.current && !ref.current.contains(e.target)) onClose() }
- const onKey = (e) => { if (e.key === 'Escape') onClose() }
+ const onMouseDown = (e) => {
+ if (ref.current && !ref.current.contains(e.target)) onClose()
+ }
+ const onKey = (e) => {
+ if (e.key === 'Escape') onClose()
+ }
document.addEventListener('mousedown', onMouseDown)
document.addEventListener('keydown', onKey)
return () => {
@@ -15,41 +20,41 @@ export default function ContextMenu({ x, y, items, onClose }) {
}, [onClose])
// Keep menu inside viewport
- const W = 192
- const H = items.length * 34
+ const W = 192
+ const H = items.length * 34
const adjX = Math.min(x, window.innerWidth - W - 8)
const adjY = Math.min(y, window.innerHeight - H - 8)
- return (
+ // Portal to document.body — escapes any CSS transform stacking context
+ // (e.g. the Drawer slide-in animation uses translateX which traps fixed children)
+ return createPortal(
{items.map((item, i) =>
item.separator ? (
-
+
) : (
)
)}
-
+ ,
+ document.body
)
}