import React, { useState } from 'react'; import { useTranslation } from 'react-i18next'; import { useEditorStore, CHIP_GROUP_PREFIX } from '../../store/useEditorStore'; import { useSimulatorStore } from '../../store/useSimulatorStore'; import { boardDisplayName } from '../../types/board'; import './FileTabs.css'; export const FileTabs: React.FC = () => { const { t } = useTranslation(); const { files, openFileIds, activeFileId, activeGroupId, setActiveFile, closeFile } = useEditorStore(); const [confirmCloseId, setConfirmCloseId] = useState(null); const openFiles = openFileIds .map((id) => files.find((f) => f.id === id)) .filter(Boolean) as typeof files; // Which target owns the files currently shown — a board or a custom chip — // so the user can tell whose code they're editing at a glance. Resolved as a // SELECTOR returning just the label string, so FileTabs only re-renders when // that label changes — not on every pin toggle that mutates the components // array during simulation. const ownerLabel = useSimulatorStore((s): string | null => { if (activeGroupId?.startsWith(CHIP_GROUP_PREFIX)) { const chipId = activeGroupId.slice(CHIP_GROUP_PREFIX.length); const chip = s.components.find((c) => c.id === chipId); return ( String((chip?.properties as Record)?.chipName ?? '').trim() || 'Custom Chip' ); } const board = s.boards.find((b) => b.activeFileGroupId === activeGroupId); return board ? boardDisplayName(board) : null; }); const handleCloseClick = (e: React.MouseEvent, fileId: string, modified: boolean) => { e.stopPropagation(); if (modified) { setConfirmCloseId(fileId); } else { closeFile(fileId); } }; const confirmClose = () => { if (confirmCloseId) closeFile(confirmCloseId); setConfirmCloseId(null); }; return ( <>
{ownerLabel && ( {ownerLabel} )} {openFiles.map((file) => (
setActiveFile(file.id)} title={file.name} > {file.modified && ( )} {file.name}
))}
{confirmCloseId && (
setConfirmCloseId(null)}>
e.stopPropagation()}>

{t('editor.fileTabs.confirmClose')}

)} ); };