Code editor and widget
This commit is contained in:
@@ -0,0 +1,63 @@
|
||||
import { useMemo } from 'react';
|
||||
import { X } from 'lucide-react';
|
||||
import { getIcon } from 'material-file-icons';
|
||||
import type { OpenFile } from './useEditorState';
|
||||
|
||||
type EditorTabsProps = {
|
||||
files: OpenFile[];
|
||||
activePath: string | null;
|
||||
onSelect: (path: string) => void;
|
||||
onClose: (path: string) => void;
|
||||
theme?: string;
|
||||
};
|
||||
|
||||
const FileIcon = ({ name }: { name: string }) => {
|
||||
const svg = useMemo(() => getIcon(name).svg, [name]);
|
||||
return <span className="inline-flex h-4 w-4 shrink-0" dangerouslySetInnerHTML={{ __html: svg }} />;
|
||||
};
|
||||
|
||||
export const EditorTabs = ({ files, activePath, onSelect, onClose, theme }: EditorTabsProps) => {
|
||||
if (files.length === 0) return null;
|
||||
|
||||
const isDark = theme !== 'vs';
|
||||
const borderColor = isDark ? '#333' : '#e0e0e0';
|
||||
const activeBg = isDark ? '#1e1e1e' : '#ffffff';
|
||||
const inactiveBg = isDark ? '#181818' : '#f3f3f3';
|
||||
const activeColor = isDark ? '#ccc' : '#333';
|
||||
const inactiveColor = isDark ? '#888' : '#666';
|
||||
|
||||
return (
|
||||
<div className="flex items-center overflow-x-auto shrink-0 code-editor-scrollable" style={{ borderBottom: `1px solid ${borderColor}` }}>
|
||||
{files.map((file) => {
|
||||
const isActive = file.path === activePath;
|
||||
return (
|
||||
<button
|
||||
key={file.path}
|
||||
onClick={() => onSelect(file.path)}
|
||||
className="flex items-center gap-1.5 px-3 py-1.5 text-sm cursor-pointer whitespace-nowrap transition-colors"
|
||||
style={{
|
||||
background: isActive ? activeBg : inactiveBg,
|
||||
color: isActive ? activeColor : inactiveColor,
|
||||
borderRight: `1px solid ${borderColor}`,
|
||||
}}
|
||||
>
|
||||
<FileIcon name={file.name} />
|
||||
<span>{file.name}</span>
|
||||
{file.isDirty && <span className="w-2 h-2 rounded-full bg-blue-400 shrink-0" />}
|
||||
<span
|
||||
role="button"
|
||||
className="ml-1 p-0.5 rounded transition-colors"
|
||||
style={{ color: inactiveColor }}
|
||||
onClick={(ev) => {
|
||||
ev.stopPropagation();
|
||||
onClose(file.path);
|
||||
}}
|
||||
>
|
||||
<X className="h-3 w-3" />
|
||||
</span>
|
||||
</button>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
Reference in New Issue
Block a user