blockly3d/src/components/MenuView.tsx

62 lines
2.0 KiB
TypeScript

import { observer } from 'mobx-react-lite';
import { useEffect, useRef } from 'react';
import { state } from '../state';
import './MenuView.scss';
import type { MenuNode } from '../state/menuState';
import { useNavigate } from 'react-router-dom';
export const MenuNodeView = observer(function ({ node }: { node: MenuNode }) {
const forceOpen = state.menu.nodeContainsSelected(node);
const navigate = useNavigate();
const ref = useRef<HTMLDetailsElement>(null);
useEffect(() => {
if (forceOpen && ref.current)
ref.current.open = true;
}, [forceOpen]);
const classNames = [];
if (node.selected?.())
classNames.push('selected');
if (node.className !== undefined)
classNames.push(node.className);
return (
<details ref={ref}>
<summary
className={classNames.join(' ')}
onClick={() => node.onClick?.()}
>
<div className="title">{node.title}</div>
{node.actions && <div className="actions">
{node.actions.map((action) =>
<div
key={action.id}
title={action.tooltip}
onClick={(e) => {
e.stopPropagation();
e.preventDefault();
action.onClick?.();
if (action.link)
navigate(action.link);
}}
>
{action.content}
</div>
)}
</div>}
</summary>
{node.children?.map((child) => <MenuNodeView key={child.id} node={child} />)}
</details>
);
});
export const MenuView = observer(function () {
return (
<nav className="menu">
{state.menu.nodes.map((node) => <MenuNodeView key={node.id} node={node} />)}
</nav>
);
});