Phase 6
This commit is contained in:
@@ -0,0 +1,73 @@
|
||||
import { h } from 'preact';
|
||||
import { useEffect, useRef } from 'preact/hooks';
|
||||
import type { SignalRef, SignalMeta } from './lib/types';
|
||||
import { getMetaStore } from './lib/stores';
|
||||
import { useState } from 'preact/hooks';
|
||||
|
||||
interface Props {
|
||||
visible: boolean;
|
||||
x: number;
|
||||
y: number;
|
||||
signal: SignalRef | null;
|
||||
onClose: () => void;
|
||||
}
|
||||
|
||||
export default function ContextMenu({ visible, x, y, signal, onClose }: Props) {
|
||||
const [meta, setMeta] = useState<SignalMeta | null>(null);
|
||||
const menuRef = useRef<HTMLDivElement>(null);
|
||||
|
||||
useEffect(() => {
|
||||
if (!signal) { setMeta(null); return; }
|
||||
const unsub = getMetaStore(signal).subscribe(setMeta);
|
||||
return unsub;
|
||||
}, [signal?.ds, signal?.name]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!visible) return;
|
||||
function handleClick(e: MouseEvent) {
|
||||
if (menuRef.current && !menuRef.current.contains(e.target as Node)) {
|
||||
onClose();
|
||||
}
|
||||
}
|
||||
document.addEventListener('mousedown', handleClick);
|
||||
return () => document.removeEventListener('mousedown', handleClick);
|
||||
}, [visible, onClose]);
|
||||
|
||||
if (!visible) return null;
|
||||
|
||||
function copySignalName() {
|
||||
if (signal) {
|
||||
navigator.clipboard.writeText(signal.name).catch(() => {});
|
||||
}
|
||||
onClose();
|
||||
}
|
||||
|
||||
function exportCSV() {
|
||||
// Phase 5+: export CSV data
|
||||
onClose();
|
||||
}
|
||||
|
||||
return (
|
||||
<div
|
||||
class="ctx-menu"
|
||||
ref={menuRef}
|
||||
style={`left:${x}px;top:${y}px;`}
|
||||
>
|
||||
{signal ? (
|
||||
<div>
|
||||
<div class="ctx-signal-info">
|
||||
<div>{signal.ds} / {signal.name}</div>
|
||||
{meta && (
|
||||
<div>{meta.type}{meta.unit ? ` [${meta.unit}]` : ''}</div>
|
||||
)}
|
||||
</div>
|
||||
<div class="ctx-divider" />
|
||||
<button class="ctx-item" onClick={copySignalName}>Copy signal name</button>
|
||||
<button class="ctx-item" onClick={exportCSV}>Export data to CSV</button>
|
||||
</div>
|
||||
) : (
|
||||
<button class="ctx-item" onClick={onClose}>Close</button>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user