{boards.map((board) => {
const groupId = board.activeFileGroupId;
const groupFiles = fileGroups[groupId] ?? [];
const isActiveBoard = board.id === activeBoardId;
const isOpen = !collapsed[board.id];
const color = BOARD_COLOR[board.boardKind];
// Status dot color
const statusColor = board.running
? '#22c55e'
: board.compiledProgram
? '#f59e0b'
: '#6b7280';
return (
{/* Board section header */}
{
switchToBoard(board.id, groupId);
if (!isOpen) toggleCollapse(board.id);
}}
title={`${boardDisplayName(board)} — ${t('editor.fileExplorer.clickToEdit')}`}
>
{BOARD_ICON[board.boardKind]}
{renamingSection?.id === board.id && renamingSection.kind === 'board' ? (
setSectionRenameValue(e.target.value)}
onBlur={commitSectionRename}
onKeyDown={(e) => {
if (e.key === 'Enter') commitSectionRename();
if (e.key === 'Escape') cancelSectionRename();
}}
onClick={(e) => e.stopPropagation()}
/>
) : (
{
e.stopPropagation();
startBoardRename(board);
}}
title="Double-click to rename"
>
{boardDisplayName(board)}
)}
{/* Rename + new-file buttons — visible on hover */}
{/* Files under this board */}
{isOpen && (
)}
);
})}
{/* Programmable custom-chip program sections — one per chip, each its
own collapsible group (the chip's ROM source / C), separate from the
board sketch above. */}
{programmableChips.map((chip) => {
const groupId = chipFileGroupId(chip.id);
const groupFiles = fileGroups[groupId] ?? [];
if (groupFiles.length === 0) return null;
const isActiveGroup = activeGroupId === groupId;
const isOpen = !collapsed[chip.id];
const chipName =
String((chip.properties as Record