diff --git a/frontend/src/index.css b/frontend/src/index.css
index b032ef8..0b2ddd5 100644
--- a/frontend/src/index.css
+++ b/frontend/src/index.css
@@ -300,9 +300,43 @@ body {
bottom: 0 !important;
width: 100vw !important;
height: 100vh !important;
- z-index: 99999 !important;
+ min-width: 100vw !important;
+ min-height: 100vh !important;
+ max-width: 100vw !important;
+ max-height: 100vh !important;
+ z-index: 2147483647 !important; /* Maximum z-index value */
margin: 0 !important;
padding: 0 !important;
border-radius: 0 !important;
+ border: none !important;
background: var(--color-surface-900) !important;
+ transform: none !important;
+ box-sizing: border-box !important;
+ overflow: hidden !important;
+}
+
+/* Portal-based fullscreen editor - renders directly to body */
+.fullscreen-editor-portal {
+ position: fixed;
+ top: 0;
+ left: 0;
+ right: 0;
+ bottom: 0;
+ width: 100vw;
+ height: 100vh;
+ z-index: 2147483647;
+ background: var(--color-surface-900);
+}
+
+/* Ensure fullscreen content fills the space */
+.fullscreen-overlay > *,
+.fullscreen-editor-portal > * {
+ max-width: 100% !important;
+ width: 100% !important;
+ height: 100% !important;
+}
+
+.fullscreen-overlay .cm-editor,
+.fullscreen-editor-portal .cm-editor {
+ height: 100% !important;
}
diff --git a/frontend/src/pages/OpenClaw.tsx b/frontend/src/pages/OpenClaw.tsx
index 2536ce1..79dd782 100644
--- a/frontend/src/pages/OpenClaw.tsx
+++ b/frontend/src/pages/OpenClaw.tsx
@@ -1,4 +1,5 @@
import { useEffect, useState, useCallback, useRef } from 'react';
+import { createPortal } from 'react-dom';
import CodeMirror from '@uiw/react-codemirror';
import { json } from '@codemirror/lang-json';
import { markdown } from '@codemirror/lang-markdown';
@@ -10,6 +11,38 @@ import type {
} from '../api/client';
import { api } from '../api/client';
+// ═════════════════════════════════════════════════════════════════════════════════
+// Fullscreen Editor Component using Portal for true fullscreen
+// ═════════════════════════════════════════════════════════════════════════════════
+
+interface FullscreenEditorProps {
+ isOpen: boolean;
+ onClose: () => void;
+ children: React.ReactNode;
+}
+
+function FullscreenEditor({ isOpen, onClose, children }: FullscreenEditorProps) {
+ useEffect(() => {
+ if (isOpen) {
+ document.body.style.overflow = 'hidden';
+ } else {
+ document.body.style.overflow = '';
+ }
+ return () => {
+ document.body.style.overflow = '';
+ };
+ }, [isOpen]);
+
+ if (!isOpen) return null;
+
+ return createPortal(
+
+ {children}
+
,
+ document.body
+ );
+}
+
// ═════════════════════════════════════════════════════════════════════════════════
// Tab definitions
// ═════════════════════════════════════════════════════════════════════════════════
@@ -625,16 +658,14 @@ function AgentsTab() {
})}
- {/* Identity File Editor */}
- {activeFile?.agent === agent.name && (
-
-
+ {/* Identity File Editor - Inline (not fullscreen) */}
+ {activeFile?.agent === agent.name && !isFullscreen && (
+
+
workspace/{agent.name}/{activeFile.file}
-
)}
+
+ {/* Identity File Editor - Fullscreen via Portal */}
+ {activeFile?.agent === agent.name && isFullscreen && createPortal(
+
+
+
+
workspace/{agent.name}/{activeFile.file}
+
+ setIsFullscreen(false)} className="px-3 py-1.5 rounded text-xs text-gray-400 hover:bg-surface-700 hover:text-white transition-colors">
+ 🗗 Réduire
+
+ { setActiveFile(null); setIsFullscreen(false); }} className="px-3 py-1.5 rounded text-xs text-gray-400 hover:bg-surface-700 hover:text-white transition-colors">
+ Fermer
+
+
+ {saving ? '...' : 'Sauvegarder'}
+
+
+
+ {fileLoading ? (
+
Chargement…
+ ) : (
+
+ setFileContent(val)}
+ basicSetup={{ lineNumbers: true, foldGutter: false, highlightActiveLine: true, tabSize: 2 }}
+ />
+
+ )}
+
+
,
+ document.body
+ )}
)}
@@ -1153,62 +1221,65 @@ function ConfigFileEditor({ onClose, onSave }: { onClose: () => void, onSave: ()
}
};
- return (
-
-
-
-
- ✏️
+ return createPortal(
+
+
+
+
+
+ ✏️
+
+
+
+ Édition directe
+
+
openclaw.json
+
-
-
- Édition directe
-
-
openclaw.json
+
+
+
+ Annuler
+
+
+ {saving ? 'Sauvegarde...' : '💾 Sauvegarder .json'}
+
-
-
-
- Annuler
-
-
- {saving ? 'Sauvegarde...' : '💾 Sauvegarder .json'}
-
-
-
-
- {loading ? (
-
- ⚙️
- Lecture de la configuration brute...
-
- ) : (
-
setContent(val)}
- basicSetup={{
- lineNumbers: true,
- foldGutter: true,
- highlightActiveLine: true,
- tabSize: 2,
- }}
- />
- )}
+
+ {loading ? (
+
+ ⚙️
+ Lecture de la configuration brute...
+
+ ) : (
+
setContent(val)}
+ basicSetup={{
+ lineNumbers: true,
+ foldGutter: true,
+ highlightActiveLine: true,
+ tabSize: 2,
+ }}
+ />
+ )}
+
-
+
,
+ document.body
);
}
@@ -1278,6 +1349,89 @@ function FilesystemTab() {
return [];
};
+ // Fullscreen editor via portal
+ if (isFullscreen && selectedFile) {
+ return createPortal(
+
+
+
+
+
+ 📄 {selectedFile.path.split('/').pop()}
+
+
+ {selectedFile.path}
+ •
+ {formatSize(selectedFile.size)}
+ •
+ {selectedFile.language}
+
+
+
+ setIsFullscreen(false)}
+ className="px-3 py-1.5 rounded-lg bg-surface-700 text-gray-300 text-sm hover:bg-surface-600 transition-colors flex items-center justify-center font-bold"
+ title="Réduire"
+ >
+ 🗗
+
+ {!selectedFile.binary && (
+ <>
+ {editMode ? (
+ <>
+ setEditMode(false)} disabled={saving} className="px-3.5 py-1.5 rounded-lg bg-surface-700 text-gray-300 text-sm hover:bg-surface-600 transition-colors">
+ Annuler
+
+
+ {saving ? 'Sauvegarde…' : '💾 Sauvegarder'}
+
+ >
+ ) : (
+ { setEditMode(true); setEditContent(selectedFile.pretty || selectedFile.content || ''); }} className="px-4 py-1.5 rounded-lg bg-gradient-to-r from-purple-600 to-indigo-600 text-white text-sm font-medium hover:from-purple-500 hover:to-indigo-500 transition-all shadow-[0_0_12px_rgba(147,51,234,0.3)] hover:scale-105 flex items-center gap-2">
+ ✏️ Modifier
+
+ )}
+ >
+ )}
+
+
+
+
+ {selectedFile.binary ? (
+
+
+
📦
+
Fichier binaire. Aperçu non disponible.
+
+
+ ) : editMode ? (
+
setEditContent(val)}
+ basicSetup={{
+ lineNumbers: true,
+ foldGutter: true,
+ highlightActiveLine: true,
+ tabSize: 2,
+ }}
+ />
+ ) : (
+
+
+ {selectedFile.pretty || selectedFile.content}
+
+
+ )}
+
+
+
,
+ document.body
+ );
+ }
+
return (
{/* Sidebar Tree */}
@@ -1303,11 +1457,9 @@ function FilesystemTab() {
- {/* Editor Panel */}
-
+ {/* Editor Panel - hidden when in fullscreen */}
+ {!isFullscreen && (
+
{fileLoading ? (
@@ -1323,7 +1475,7 @@ function FilesystemTab() {
) : (
{/* Editor Header */}
-
+
📄 {selectedFile.path.split('/').pop()}
@@ -1338,11 +1490,11 @@ function FilesystemTab() {
setIsFullscreen(!isFullscreen)}
+ onClick={() => setIsFullscreen(true)}
className="px-3 py-1.5 rounded-lg bg-surface-700 text-gray-300 text-sm hover:bg-surface-600 transition-colors flex items-center justify-center font-bold"
- title={isFullscreen ? "Réduire" : "Plein écran"}
+ title="Plein écran"
>
- {isFullscreen ? "🗗" : "⛶"}
+ ⛶
{!selectedFile.binary && (
<>
@@ -1399,6 +1551,7 @@ function FilesystemTab() {
)}
+ )}
);
}