feat(web): refonte visuelle « Emerald » (thème clair/sombre, polices, tokens)
Adopte le langage visuel du design system Emerald dans l'IDE web : neutres zinc + accent emerald, polices auto-hébergées Inter + JetBrains Mono, radii/pills mono, points de statut, motif terminal, halo/grain. Refonte purement visuelle et additive (layout, routing, stores, protocole inchangés). - style.css : défauts sombres dans @theme + override clair sous html[data-theme=light] ; accent scindé (bright #34d399 / solid #059669 / hover) ; tokens border-soft/info/warn/danger/coffee ; idiomes globaux (focus/selection accent, scrollbars fines, jl-pulse/jl-blink, classes .chip/.status/.eyebrow/.label-mono/.caret/.halo/.grain, .btn*/.badge pill). - lib/theme.ts : singleton themeMode/resolvedTheme (dark/light/system, persistedRef arb.theme) + application dataset.theme/metas ; script anti-FOUC inline dans index.html ; toggle ActivityBar + Réglages. - Thèmes Monaco + xterm dark/light réactifs (palette ANSI + coloration syntaxique) ; fonts.ready + remeasureFonts pour l'alignement des glyphes. - status-tokens : tons sémantiques tokenisés ; balayage des ~340 couleurs Tailwind brutes vers les tokens sur tout components/* et views/* (exceptions assumées commentées). - GroupSummary.color exploité : icône de groupe teintée + ColorSwatchPicker (lib/group-colors.ts) dans les modals de groupe. - Polices via @fontsource-variable/{inter,jetbrains-mono} (offline).
This commit is contained in:
@@ -23,7 +23,7 @@
|
||||
<!-- bannière de conflit (le fichier a changé sur le disque depuis le chargement) -->
|
||||
<div
|
||||
v-if="conflict && activeTab.view === 'editor'"
|
||||
class="flex flex-wrap items-center gap-2 border-b border-amber-700/40 bg-amber-950/30 px-3 py-1.5 text-xs text-amber-200"
|
||||
class="flex flex-wrap items-center gap-2 border-b border-warn/40 bg-warn/10 px-3 py-1.5 text-xs text-warn"
|
||||
>
|
||||
<TriangleAlert :size="14" /> {{ t('editor.conflict') }}
|
||||
<div class="ml-auto flex items-center gap-2">
|
||||
@@ -31,7 +31,7 @@
|
||||
<BaseButton size="sm" variant="danger" :loading="saving" @click="overwrite">{{ t('editor.overwrite') }}</BaseButton>
|
||||
</div>
|
||||
</div>
|
||||
<p v-if="loadError && activeTab.view === 'editor'" class="px-3 py-1 text-xs text-rose-400">{{ loadError }}</p>
|
||||
<p v-if="loadError && activeTab.view === 'editor'" class="px-3 py-1 text-xs text-danger">{{ loadError }}</p>
|
||||
|
||||
<div class="relative min-h-0 flex-1">
|
||||
<div v-show="activeTab.view === 'editor'" ref="host" class="h-full min-h-0" />
|
||||
@@ -64,6 +64,7 @@ import { useIdeStore, type EditorTab } from '../../stores/ide';
|
||||
import { gitApi } from '../../lib/git-api';
|
||||
import { ApiError } from '../../lib/api';
|
||||
import { loadMonaco } from '../../composables/useMonaco';
|
||||
import { resolvedTheme } from '../../lib/theme';
|
||||
import EditorTabs from './EditorTabs.vue';
|
||||
import DiffViewer from '../workspace/DiffViewer.vue';
|
||||
import SegmentedControl from '../ui/SegmentedControl.vue';
|
||||
@@ -109,14 +110,19 @@ onMounted(async () => {
|
||||
if (disposed || !host.value) return;
|
||||
editor.value = monaco.editor.create(host.value, {
|
||||
value: '',
|
||||
theme: 'arboretum-dark',
|
||||
theme: resolvedTheme.value === 'light' ? 'arboretum-light' : 'arboretum-dark',
|
||||
automaticLayout: true,
|
||||
minimap: { enabled: false },
|
||||
wordWrap: 'on',
|
||||
fontSize: 13,
|
||||
fontFamily: "'JetBrains Mono Variable', ui-monospace, 'Fira Code', Menlo, Consolas, monospace",
|
||||
scrollBeyondLastLine: false,
|
||||
tabSize: 2,
|
||||
});
|
||||
// Re-mesure après chargement de la fonte web (sinon curseur/colonnes décalés).
|
||||
void document.fonts?.ready.then(() => {
|
||||
if (!disposed) monaco?.editor.remeasureFonts();
|
||||
});
|
||||
editor.value.onDidChangeModelContent(() => {
|
||||
if (!shownTabId) return;
|
||||
const entry = entries.get(shownTabId);
|
||||
@@ -227,6 +233,11 @@ watch(
|
||||
},
|
||||
);
|
||||
|
||||
// bascule de thème -> réapplique le thème Monaco (setTheme est global et idempotent).
|
||||
watch(resolvedTheme, (r) => {
|
||||
monaco?.editor.setTheme(r === 'light' ? 'arboretum-light' : 'arboretum-dark');
|
||||
});
|
||||
|
||||
// onglets fermés -> dispose leurs modèles et view states (évite les fuites mémoire).
|
||||
watch(
|
||||
() => ide.editorTabs.map((tb) => tb.id),
|
||||
|
||||
Reference in New Issue
Block a user