import { useEffect, useRef } from 'react';
import { parseFenMeta } from '../engine/pgnFormat.js';
import { buildMoveListItems, buildVariation } from '../engine/moveLine.js';
import { scrollIntoViewWithin } from '../engine/scroll.js';
import Button from './ui/Button.jsx';
import Panel from './ui/Panel.jsx';
function MoveButton({ node, isCurrent, chip, onGoTo }) {
const cls = `move-line__move${chip ? ' move-line__move--chip' : ''}${isCurrent ? ' is-current' : ''}`;
return ;
}
function renderItems(items, nodes, rootChildren, currentId, onGoTo, keyPrefix) {
return items.flatMap((item, idx) => {
const key = `${keyPrefix}-${idx}`;
if (item.kind === 'row') {
const whiteEmpty = !item.white || item.white.placeholder;
return [
{item.num}.
onGoTo(item.white.node.id) : undefined}
>
{item.white?.placeholder ? '...' : null}
{item.white && !item.white.placeholder && }
onGoTo(item.black.node.id) : undefined}
>
{item.black && }
,
];
}
if (item.kind === 'para') {
return [
{item.chips.map((chip, ci) => chip.kind === 'num'
? {chip.text}
: )}
,
];
}
// 'variation' marker - expand lazily so nested forks don't need to
// be walked until they're actually reached.
const varItems = buildVariation(nodes, rootChildren, item.nodeIds, item.whiteToMove, item.moveNum, currentId, item.depth);
return renderItems(varItems, nodes, rootChildren, currentId, onGoTo, `${key}-v`);
});
}
export default function PgnPanel({ explorer }) {
const { moveHistory, startFen, historyInitialized, actions } = explorer;
const { nodes, rootChildren, currentId } = moveHistory;
const scrollRef = useRef(null);
useEffect(() => {
const container = scrollRef.current;
const current = container?.querySelector('.is-current');
scrollIntoViewWithin(current, container);
}, [currentId, nodes]);
let content = null;
if (!historyInitialized) {
content = null; // no render until Board reports its first move-tree change
} else if (!rootChildren || rootChildren.length === 0) {
content = No moves yet;
} else {
const { turn, fullmove } = parseFenMeta(startFen);
const items = buildMoveListItems(nodes, rootChildren, currentId, turn, fullmove);
content = renderItems(items, nodes, rootChildren, currentId, actions.goToNode, 'm');
}
return (
>
}
>
);
}