2026-03-06 20:14:50 +07:00
|
|
|
|
import React, { useState } from 'react';
|
|
|
|
|
|
import { useEditorStore } from '../../store/useEditorStore';
|
|
|
|
|
|
import './FileTabs.css';
|
|
|
|
|
|
|
|
|
|
|
|
export const FileTabs: React.FC = () => {
|
|
|
|
|
|
const { files, openFileIds, activeFileId, setActiveFile, closeFile } =
|
|
|
|
|
|
useEditorStore();
|
|
|
|
|
|
const [confirmCloseId, setConfirmCloseId] = useState<string | null>(null);
|
|
|
|
|
|
|
|
|
|
|
|
const openFiles = openFileIds
|
|
|
|
|
|
.map((id) => files.find((f) => f.id === id))
|
|
|
|
|
|
.filter(Boolean) as typeof files;
|
|
|
|
|
|
|
|
|
|
|
|
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 (
|
|
|
|
|
|
<>
|
|
|
|
|
|
<div className="file-tabs">
|
|
|
|
|
|
{openFiles.map((file) => (
|
|
|
|
|
|
<div
|
|
|
|
|
|
key={file.id}
|
|
|
|
|
|
className={`file-tab${file.id === activeFileId ? ' file-tab-active' : ''}`}
|
|
|
|
|
|
onClick={() => setActiveFile(file.id)}
|
|
|
|
|
|
title={file.name}
|
|
|
|
|
|
>
|
2026-03-06 20:24:03 +07:00
|
|
|
|
{file.modified && <span className="file-tab-modified" title="Unsaved changes" />}
|
2026-03-06 20:14:50 +07:00
|
|
|
|
<span className="file-tab-name">{file.name}</span>
|
|
|
|
|
|
<button
|
|
|
|
|
|
className="file-tab-close"
|
|
|
|
|
|
onClick={(e) => handleCloseClick(e, file.id, file.modified)}
|
|
|
|
|
|
title="Close"
|
|
|
|
|
|
>
|
|
|
|
|
|
×
|
|
|
|
|
|
</button>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
))}
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
{confirmCloseId && (
|
|
|
|
|
|
<div className="ftabs-overlay" onClick={() => setConfirmCloseId(null)}>
|
|
|
|
|
|
<div
|
|
|
|
|
|
className="ftabs-confirm-box"
|
|
|
|
|
|
onClick={(e) => e.stopPropagation()}
|
|
|
|
|
|
>
|
|
|
|
|
|
<p>Close file with unsaved changes?</p>
|
|
|
|
|
|
<div className="ftabs-confirm-actions">
|
|
|
|
|
|
<button className="ftabs-btn-close" onClick={confirmClose}>
|
|
|
|
|
|
Close anyway
|
|
|
|
|
|
</button>
|
|
|
|
|
|
<button onClick={() => setConfirmCloseId(null)}>Cancel</button>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
)}
|
|
|
|
|
|
</>
|
|
|
|
|
|
);
|
|
|
|
|
|
};
|