feat: update component styles and add serial monitor functionality
This commit is contained in:
parent
a5c6987aca
commit
c1fc653de2
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"generatedAt": "2026-03-06T02:57:38.515Z",
|
"generatedAt": "2026-03-06T13:12:51.254Z",
|
||||||
"components": [
|
"components": [
|
||||||
{
|
{
|
||||||
"id": "arduino-mega",
|
"id": "arduino-mega",
|
||||||
|
|
|
||||||
|
|
@ -136,7 +136,7 @@ export const EditorToolbar = ({ consoleOpen, setConsoleOpen, compileLogs: _compi
|
||||||
className="tb-btn tb-btn-stop"
|
className="tb-btn tb-btn-stop"
|
||||||
title="Stop"
|
title="Stop"
|
||||||
>
|
>
|
||||||
<svg width="20" height="20" viewBox="0 0 24 24" fill="currentColor" stroke="none">
|
<svg width="22" height="22" viewBox="0 0 24 24" fill="currentColor" stroke="none">
|
||||||
<rect x="3" y="3" width="18" height="18" rx="2" />
|
<rect x="3" y="3" width="18" height="18" rx="2" />
|
||||||
</svg>
|
</svg>
|
||||||
</button>
|
</button>
|
||||||
|
|
@ -195,7 +195,7 @@ export const EditorToolbar = ({ consoleOpen, setConsoleOpen, compileLogs: _compi
|
||||||
className={`tb-btn tb-btn-output${consoleOpen ? ' tb-btn-output-active' : ''}`}
|
className={`tb-btn tb-btn-output${consoleOpen ? ' tb-btn-output-active' : ''}`}
|
||||||
title="Toggle Output Console"
|
title="Toggle Output Console"
|
||||||
>
|
>
|
||||||
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
|
<svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
|
||||||
<polyline points="4 17 10 11 4 5" />
|
<polyline points="4 17 10 11 4 5" />
|
||||||
<line x1="12" y1="19" x2="20" y2="19" />
|
<line x1="12" y1="19" x2="20" y2="19" />
|
||||||
</svg>
|
</svg>
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,8 @@
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
padding: 7px 10px 6px;
|
padding: 0 10px;
|
||||||
|
height: 46px;
|
||||||
color: #9d9d9d;
|
color: #9d9d9d;
|
||||||
font-size: 11px;
|
font-size: 11px;
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
|
|
@ -23,20 +24,24 @@
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.file-explorer-header-actions {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
.file-explorer-new-btn {
|
.file-explorer-new-btn {
|
||||||
background: none;
|
background: none;
|
||||||
border: none;
|
border: none;
|
||||||
color: #9d9d9d;
|
color: #9d9d9d;
|
||||||
font-size: 18px;
|
|
||||||
line-height: 1;
|
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
padding: 0 3px;
|
padding: 2px;
|
||||||
border-radius: 3px;
|
border-radius: 3px;
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
width: 22px;
|
width: 26px;
|
||||||
height: 22px;
|
height: 26px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.file-explorer-new-btn:hover {
|
.file-explorer-new-btn:hover {
|
||||||
|
|
@ -44,6 +49,25 @@
|
||||||
color: #fff;
|
color: #fff;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.file-explorer-save-btn {
|
||||||
|
background: none;
|
||||||
|
border: none;
|
||||||
|
color: #9d9d9d;
|
||||||
|
cursor: pointer;
|
||||||
|
padding: 2px;
|
||||||
|
border-radius: 3px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
width: 26px;
|
||||||
|
height: 26px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.file-explorer-save-btn:hover {
|
||||||
|
background: rgba(255, 255, 255, 0.08);
|
||||||
|
color: #4fc3f7;
|
||||||
|
}
|
||||||
|
|
||||||
.file-explorer-list {
|
.file-explorer-list {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
|
|
@ -92,8 +116,10 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.file-explorer-dot {
|
.file-explorer-dot {
|
||||||
color: #e8a87c;
|
width: 7px;
|
||||||
font-size: 9px;
|
height: 7px;
|
||||||
|
border-radius: 50%;
|
||||||
|
background: #e8a87c;
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,13 +2,44 @@ import React, { useState, useRef, useEffect, useCallback } from 'react';
|
||||||
import { useEditorStore } from '../../store/useEditorStore';
|
import { useEditorStore } from '../../store/useEditorStore';
|
||||||
import './FileExplorer.css';
|
import './FileExplorer.css';
|
||||||
|
|
||||||
function getFileIcon(name: string): string {
|
// SVG icons — same style as EditorToolbar (stroke-based, 16x16)
|
||||||
|
const IcoFile = () => (
|
||||||
|
<svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
|
||||||
|
<path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z" />
|
||||||
|
<polyline points="14 2 14 8 20 8" />
|
||||||
|
</svg>
|
||||||
|
);
|
||||||
|
|
||||||
|
const IcoHeader = () => (
|
||||||
|
<svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
|
||||||
|
<path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z" />
|
||||||
|
<polyline points="14 2 14 8 20 8" />
|
||||||
|
<line x1="9" y1="13" x2="15" y2="13" />
|
||||||
|
<line x1="9" y1="17" x2="13" y2="17" />
|
||||||
|
</svg>
|
||||||
|
);
|
||||||
|
|
||||||
|
const IcoNewFile = () => (
|
||||||
|
<svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
|
||||||
|
<path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z" />
|
||||||
|
<polyline points="14 2 14 8 20 8" />
|
||||||
|
<line x1="12" y1="18" x2="12" y2="12" />
|
||||||
|
<line x1="9" y1="15" x2="15" y2="15" />
|
||||||
|
</svg>
|
||||||
|
);
|
||||||
|
|
||||||
|
const IcoSave = () => (
|
||||||
|
<svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
|
||||||
|
<path d="M19 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h11l5 5v11a2 2 0 0 1-2 2z" />
|
||||||
|
<polyline points="17 21 17 13 7 13 7 21" />
|
||||||
|
<polyline points="7 3 7 8 15 8" />
|
||||||
|
</svg>
|
||||||
|
);
|
||||||
|
|
||||||
|
function FileIcon({ name }: { name: string }) {
|
||||||
const ext = name.split('.').pop()?.toLowerCase() ?? '';
|
const ext = name.split('.').pop()?.toLowerCase() ?? '';
|
||||||
if (ext === 'ino') return '⚡';
|
if (['h', 'hpp'].includes(ext)) return <IcoHeader />;
|
||||||
if (['cpp', 'c', 'cc'].includes(ext)) return '📄';
|
return <IcoFile />;
|
||||||
if (['h', 'hpp'].includes(ext)) return '📋';
|
|
||||||
if (ext === 'json') return '{}';
|
|
||||||
return '📝';
|
|
||||||
}
|
}
|
||||||
|
|
||||||
interface ContextMenu {
|
interface ContextMenu {
|
||||||
|
|
@ -17,7 +48,11 @@ interface ContextMenu {
|
||||||
y: number;
|
y: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const FileExplorer: React.FC = () => {
|
interface FileExplorerProps {
|
||||||
|
onSaveClick: () => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const FileExplorer: React.FC<FileExplorerProps> = ({ onSaveClick }) => {
|
||||||
const { files, activeFileId, openFile, createFile, deleteFile, renameFile } =
|
const { files, activeFileId, openFile, createFile, deleteFile, renameFile } =
|
||||||
useEditorStore();
|
useEditorStore();
|
||||||
const [contextMenu, setContextMenu] = useState<ContextMenu | null>(null);
|
const [contextMenu, setContextMenu] = useState<ContextMenu | null>(null);
|
||||||
|
|
@ -94,13 +129,22 @@ export const FileExplorer: React.FC = () => {
|
||||||
<div className="file-explorer">
|
<div className="file-explorer">
|
||||||
<div className="file-explorer-header">
|
<div className="file-explorer-header">
|
||||||
<span className="file-explorer-title">WORKSPACE</span>
|
<span className="file-explorer-title">WORKSPACE</span>
|
||||||
|
<div className="file-explorer-header-actions">
|
||||||
<button
|
<button
|
||||||
className="file-explorer-new-btn"
|
className="file-explorer-new-btn"
|
||||||
title="New File"
|
title="New File"
|
||||||
onClick={startCreateFile}
|
onClick={startCreateFile}
|
||||||
>
|
>
|
||||||
+
|
<IcoNewFile />
|
||||||
</button>
|
</button>
|
||||||
|
<button
|
||||||
|
className="file-explorer-save-btn"
|
||||||
|
title="Save project (Ctrl+S)"
|
||||||
|
onClick={onSaveClick}
|
||||||
|
>
|
||||||
|
<IcoSave />
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="file-explorer-list">
|
<div className="file-explorer-list">
|
||||||
|
|
@ -113,7 +157,9 @@ export const FileExplorer: React.FC = () => {
|
||||||
onDoubleClick={() => startRename(file.id)}
|
onDoubleClick={() => startRename(file.id)}
|
||||||
title={`${file.name}${file.modified ? ' (unsaved)' : ''}`}
|
title={`${file.name}${file.modified ? ' (unsaved)' : ''}`}
|
||||||
>
|
>
|
||||||
<span className="file-explorer-icon">{getFileIcon(file.name)}</span>
|
<span className="file-explorer-icon">
|
||||||
|
<FileIcon name={file.name} />
|
||||||
|
</span>
|
||||||
|
|
||||||
{renamingId === file.id ? (
|
{renamingId === file.id ? (
|
||||||
<input
|
<input
|
||||||
|
|
@ -133,16 +179,16 @@ export const FileExplorer: React.FC = () => {
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{file.modified && (
|
{file.modified && (
|
||||||
<span className="file-explorer-dot" title="Unsaved changes">
|
<span className="file-explorer-dot" title="Unsaved changes" />
|
||||||
●
|
|
||||||
</span>
|
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
))}
|
))}
|
||||||
|
|
||||||
{creatingFile && (
|
{creatingFile && (
|
||||||
<div className="file-explorer-item file-explorer-item-new">
|
<div className="file-explorer-item file-explorer-item-new">
|
||||||
<span className="file-explorer-icon">⚡</span>
|
<span className="file-explorer-icon">
|
||||||
|
<IcoFile />
|
||||||
|
</span>
|
||||||
<input
|
<input
|
||||||
ref={newFileInputRef}
|
ref={newFileInputRef}
|
||||||
className="file-explorer-rename-input"
|
className="file-explorer-rename-input"
|
||||||
|
|
|
||||||
|
|
@ -43,8 +43,10 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.file-tab-modified {
|
.file-tab-modified {
|
||||||
color: #e8a87c;
|
width: 7px;
|
||||||
font-size: 9px;
|
height: 7px;
|
||||||
|
border-radius: 50%;
|
||||||
|
background: #e8a87c;
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -39,7 +39,7 @@ export const FileTabs: React.FC = () => {
|
||||||
onClick={() => setActiveFile(file.id)}
|
onClick={() => setActiveFile(file.id)}
|
||||||
title={file.name}
|
title={file.name}
|
||||||
>
|
>
|
||||||
{file.modified && <span className="file-tab-modified">●</span>}
|
{file.modified && <span className="file-tab-modified" title="Unsaved changes" />}
|
||||||
<span className="file-tab-name">{file.name}</span>
|
<span className="file-tab-name">{file.name}</span>
|
||||||
<button
|
<button
|
||||||
className="file-tab-close"
|
className="file-tab-close"
|
||||||
|
|
|
||||||
|
|
@ -1,15 +1,10 @@
|
||||||
import { useState, useRef, useEffect } from 'react';
|
import { useState, useRef, useEffect } from 'react';
|
||||||
import { Link, useNavigate } from 'react-router-dom';
|
import { Link, useNavigate } from 'react-router-dom';
|
||||||
import { useAuthStore } from '../../store/useAuthStore';
|
import { useAuthStore } from '../../store/useAuthStore';
|
||||||
import { useSimulatorStore } from '../../store/useSimulatorStore';
|
|
||||||
|
|
||||||
interface AppHeaderProps {
|
interface AppHeaderProps {}
|
||||||
onSaveClick: () => void;
|
|
||||||
}
|
|
||||||
|
|
||||||
export const AppHeader: React.FC<AppHeaderProps> = ({ onSaveClick }) => {
|
export const AppHeader: React.FC<AppHeaderProps> = () => {
|
||||||
const serialMonitorOpen = useSimulatorStore((s) => s.serialMonitorOpen);
|
|
||||||
const toggleSerialMonitor = useSimulatorStore((s) => s.toggleSerialMonitor);
|
|
||||||
const user = useAuthStore((s) => s.user);
|
const user = useAuthStore((s) => s.user);
|
||||||
const logout = useAuthStore((s) => s.logout);
|
const logout = useAuthStore((s) => s.logout);
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
|
|
@ -55,56 +50,6 @@ export const AppHeader: React.FC<AppHeaderProps> = ({ onSaveClick }) => {
|
||||||
Examples
|
Examples
|
||||||
</Link>
|
</Link>
|
||||||
|
|
||||||
<button
|
|
||||||
onClick={toggleSerialMonitor}
|
|
||||||
className="serial-monitor-toggle"
|
|
||||||
title="Toggle Serial Monitor"
|
|
||||||
style={{
|
|
||||||
background: serialMonitorOpen ? '#0e639c' : 'transparent',
|
|
||||||
border: '1px solid #555',
|
|
||||||
color: '#ccc',
|
|
||||||
padding: '4px 10px',
|
|
||||||
borderRadius: 4,
|
|
||||||
cursor: 'pointer',
|
|
||||||
display: 'flex',
|
|
||||||
alignItems: 'center',
|
|
||||||
gap: 5,
|
|
||||||
fontSize: 13,
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
|
|
||||||
<rect x="2" y="3" width="20" height="14" rx="2" />
|
|
||||||
<path d="M8 21h8M12 17v4" />
|
|
||||||
</svg>
|
|
||||||
Serial
|
|
||||||
</button>
|
|
||||||
|
|
||||||
{/* Save button */}
|
|
||||||
<button
|
|
||||||
onClick={onSaveClick}
|
|
||||||
title="Save project (Ctrl+S)"
|
|
||||||
style={{
|
|
||||||
background: '#0e639c',
|
|
||||||
border: 'none',
|
|
||||||
color: '#fff',
|
|
||||||
padding: '4px 12px',
|
|
||||||
borderRadius: 4,
|
|
||||||
cursor: 'pointer',
|
|
||||||
display: 'flex',
|
|
||||||
alignItems: 'center',
|
|
||||||
gap: 6,
|
|
||||||
fontSize: 13,
|
|
||||||
fontWeight: 500,
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
|
|
||||||
<path d="M19 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h11l5 5v11a2 2 0 0 1-2 2z" />
|
|
||||||
<polyline points="17 21 17 13 7 13 7 21" />
|
|
||||||
<polyline points="7 3 7 8 15 8" />
|
|
||||||
</svg>
|
|
||||||
Save
|
|
||||||
</button>
|
|
||||||
|
|
||||||
{/* Auth UI */}
|
{/* Auth UI */}
|
||||||
{user ? (
|
{user ? (
|
||||||
<div style={{ position: 'relative' }} ref={dropdownRef}>
|
<div style={{ position: 'relative' }} ref={dropdownRef}>
|
||||||
|
|
|
||||||
|
|
@ -85,6 +85,35 @@
|
||||||
cursor: not-allowed;
|
cursor: not-allowed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ── Serial Monitor button ───────────────────────── */
|
||||||
|
.canvas-serial-btn {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 5px;
|
||||||
|
padding: 0 10px;
|
||||||
|
height: 32px;
|
||||||
|
background: transparent;
|
||||||
|
border: 1px solid #3a4a5a;
|
||||||
|
border-radius: 5px;
|
||||||
|
color: #9d9d9d;
|
||||||
|
font-size: 12px;
|
||||||
|
font-weight: 500;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: border-color 0.15s, background 0.15s, color 0.15s;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.canvas-serial-btn:hover {
|
||||||
|
border-color: #007acc;
|
||||||
|
color: #ccc;
|
||||||
|
}
|
||||||
|
|
||||||
|
.canvas-serial-btn-active {
|
||||||
|
background: #0e3a5a;
|
||||||
|
border-color: #007acc;
|
||||||
|
color: #4fc3f7;
|
||||||
|
}
|
||||||
|
|
||||||
/* ── Component count ─────────────────────────────── */
|
/* ── Component count ─────────────────────────────── */
|
||||||
.component-count {
|
.component-count {
|
||||||
display: flex;
|
display: flex;
|
||||||
|
|
|
||||||
|
|
@ -27,6 +27,8 @@ export const SimulatorCanvas = () => {
|
||||||
addComponent,
|
addComponent,
|
||||||
removeComponent,
|
removeComponent,
|
||||||
updateComponent,
|
updateComponent,
|
||||||
|
serialMonitorOpen,
|
||||||
|
toggleSerialMonitor,
|
||||||
} = useSimulatorStore();
|
} = useSimulatorStore();
|
||||||
|
|
||||||
// Wire management from store
|
// Wire management from store
|
||||||
|
|
@ -400,6 +402,19 @@ export const SimulatorCanvas = () => {
|
||||||
<option key={type} value={type}>{label}</option>
|
<option key={type} value={type}>{label}</option>
|
||||||
))}
|
))}
|
||||||
</select>
|
</select>
|
||||||
|
|
||||||
|
{/* Serial Monitor toggle */}
|
||||||
|
<button
|
||||||
|
onClick={toggleSerialMonitor}
|
||||||
|
className={`canvas-serial-btn${serialMonitorOpen ? ' canvas-serial-btn-active' : ''}`}
|
||||||
|
title="Toggle Serial Monitor"
|
||||||
|
>
|
||||||
|
<svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
|
||||||
|
<rect x="2" y="3" width="20" height="14" rx="2" />
|
||||||
|
<path d="M8 21h8M12 17v4" />
|
||||||
|
</svg>
|
||||||
|
Serial
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="canvas-header-right">
|
<div className="canvas-header-right">
|
||||||
|
|
@ -419,7 +434,7 @@ export const SimulatorCanvas = () => {
|
||||||
title="Add Component"
|
title="Add Component"
|
||||||
disabled={running}
|
disabled={running}
|
||||||
>
|
>
|
||||||
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5" strokeLinecap="round" strokeLinejoin="round">
|
<svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5" strokeLinecap="round" strokeLinejoin="round">
|
||||||
<line x1="12" y1="5" x2="12" y2="19" />
|
<line x1="12" y1="5" x2="12" y2="19" />
|
||||||
<line x1="5" y1="12" x2="19" y2="12" />
|
<line x1="5" y1="12" x2="19" y2="12" />
|
||||||
</svg>
|
</svg>
|
||||||
|
|
|
||||||
|
|
@ -112,7 +112,7 @@ export const EditorPage: React.FC = () => {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="app">
|
<div className="app">
|
||||||
<AppHeader onSaveClick={handleSaveClick} />
|
<AppHeader />
|
||||||
|
|
||||||
<div className="app-container" ref={containerRef}>
|
<div className="app-container" ref={containerRef}>
|
||||||
{/* ── Editor side ── */}
|
{/* ── Editor side ── */}
|
||||||
|
|
@ -121,7 +121,7 @@ export const EditorPage: React.FC = () => {
|
||||||
style={{ width: `${editorWidthPct}%`, display: 'flex', flexDirection: 'row' }}
|
style={{ width: `${editorWidthPct}%`, display: 'flex', flexDirection: 'row' }}
|
||||||
>
|
>
|
||||||
{/* File explorer sidebar */}
|
{/* File explorer sidebar */}
|
||||||
{explorerOpen && <FileExplorer />}
|
{explorerOpen && <FileExplorer onSaveClick={handleSaveClick} />}
|
||||||
|
|
||||||
{/* Editor main area */}
|
{/* Editor main area */}
|
||||||
<div style={{ flex: 1, display: 'flex', flexDirection: 'column', overflow: 'hidden', minWidth: 0 }}>
|
<div style={{ flex: 1, display: 'flex', flexDirection: 'column', overflow: 'hidden', minWidth: 0 }}>
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue