NeonClary
Add settings menu for diagram layout and panel visibility
ebbd1a5
Raw
History Blame Contribute Delete
3.17 kB
import React, { useState, useEffect, useRef } from 'react';
import { Settings } from 'lucide-react';
import { LAYOUT_MODES, PANEL_KEYS, PANEL_LABELS } from '../utils/settings';
const LAYOUT_OPTIONS = [
{ id: LAYOUT_MODES.RANDOM, label: 'Random seed (default)', hint: 'Layout may shift on each run' },
{ id: LAYOUT_MODES.FIXED_SEED, label: 'Fixed seed', hint: 'Same layout every run unless topology changes' },
{ id: LAYOUT_MODES.EXPLICIT, label: 'Explicit coordinates', hint: 'Fixed positions; physics off' },
];
export default function SettingsMenu({ settings, onChange }) {
const [open, setOpen] = useState(false);
const wrapRef = useRef(null);
useEffect(() => {
if (!open) return undefined;
const onDocClick = (e) => {
if (wrapRef.current && !wrapRef.current.contains(e.target)) {
setOpen(false);
}
};
document.addEventListener('mousedown', onDocClick);
return () => document.removeEventListener('mousedown', onDocClick);
}, [open]);
const setLayoutMode = (layoutMode) => {
onChange({ ...settings, layoutMode });
};
const togglePanel = (key) => {
onChange({
...settings,
panels: { ...settings.panels, [key]: !settings.panels[key] },
});
};
return (
<div className="ccai-dropdown-wrap decidron-settings-wrap" ref={wrapRef}>
<button
type="button"
className="btn-sm btn-outline icon-btn decidron-settings-trigger"
onClick={() => setOpen((v) => !v)}
title="Settings"
aria-expanded={open}
aria-haspopup="true"
>
<Settings size={16} />
</button>
{open && (
<div className="ccai-dropdown-panel decidron-settings-panel" role="menu">
<div className="ccai-dropdown-section">
<div className="ccai-dropdown-section-title">Diagram node placement</div>
{LAYOUT_OPTIONS.map((opt) => (
<label key={opt.id} className="decidron-settings-radio">
<input
type="radio"
name="layoutMode"
checked={settings.layoutMode === opt.id}
onChange={() => setLayoutMode(opt.id)}
/>
<span>
<strong>{opt.label}</strong>
<span className="decidron-settings-hint">{opt.hint}</span>
</span>
</label>
))}
</div>
<div className="ccai-dropdown-divider" />
<div className="ccai-dropdown-section">
<div className="ccai-dropdown-section-title">Right-side panels</div>
{PANEL_KEYS.map((key) => (
<label key={key} className="ccai-dropdown-item decidron-settings-check">
<input
type="checkbox"
checked={!!settings.panels[key]}
onChange={() => togglePanel(key)}
/>
<span className="ccai-dropdown-item-text">
<span className="ccai-dropdown-item-name">{PANEL_LABELS[key]}</span>
</span>
</label>
))}
</div>
</div>
)}
</div>
);
}