Add Dockview layout manager and update dependencies; remove GoldenLayout
This commit is contained in:
@@ -0,0 +1,139 @@
|
||||
import { useEffect, useRef, useState } from 'react';
|
||||
import {
|
||||
DockviewReact,
|
||||
DockviewReadyEvent,
|
||||
DockviewApi,
|
||||
themeAbyss,
|
||||
themeLight,
|
||||
} from 'dockview';
|
||||
import { useMantineColorScheme, useComputedColorScheme } from '@mantine/core';
|
||||
import { useDockviewStore } from '../stores/useDockviewStore';
|
||||
import { Welcome } from './Welcome/Welcome';
|
||||
import { ColorSchemeToggle } from './ColorSchemeToggle/ColorSchemeToggle';
|
||||
import 'dockview/dist/styles/dockview.css';
|
||||
|
||||
export function DockviewLayoutManager() {
|
||||
const hostRef = useRef<HTMLDivElement | null>(null);
|
||||
const apiRef = useRef<DockviewApi | null>(null);
|
||||
const { layoutConfig, setLayoutConfig } = useDockviewStore();
|
||||
|
||||
// 🎨 Detecta automáticamente el tema de Mantine (light / dark / system)
|
||||
const { colorScheme } = useMantineColorScheme();
|
||||
const computedScheme = useComputedColorScheme('light', {
|
||||
getInitialValueInEffect: true,
|
||||
});
|
||||
|
||||
// ⚡ Inicializa Dockview al estar listo
|
||||
const onReady = (event: DockviewReadyEvent) => {
|
||||
const api = event.api;
|
||||
apiRef.current = api;
|
||||
|
||||
if (layoutConfig) {
|
||||
try {
|
||||
api.fromJSON(layoutConfig);
|
||||
} catch {
|
||||
console.warn('Error loading saved Dockview layout, using default');
|
||||
createDefaultLayout(api);
|
||||
}
|
||||
} else {
|
||||
createDefaultLayout(api);
|
||||
}
|
||||
|
||||
// 🧠 Guarda el layout cuando cambia
|
||||
api.onDidLayoutChange(() => {
|
||||
const saved = api.toJSON();
|
||||
setLayoutConfig(saved);
|
||||
});
|
||||
};
|
||||
|
||||
// 🌗 Sincroniza Dockview con el tema de Mantine automáticamente
|
||||
useEffect(() => {
|
||||
const el = hostRef.current;
|
||||
if (!el) return;
|
||||
|
||||
// Remueve las clases anteriores
|
||||
el.classList.remove('dockview-theme-dark', 'dockview-theme-light');
|
||||
|
||||
// Aplica el tema adecuado
|
||||
const isDark = computedScheme === 'dark';
|
||||
el.classList.add(isDark ? 'dockview-theme-dark' : 'dockview-theme-light');
|
||||
el.style.backgroundColor = isDark ? '#1A1B1E' : '#f5f6f7';
|
||||
}, [computedScheme]);
|
||||
|
||||
// 🧱 Layout inicial por defecto
|
||||
const createDefaultLayout = (api: DockviewApi) => {
|
||||
const welcome = api.addPanel({
|
||||
id: 'welcome',
|
||||
component: 'welcome',
|
||||
title: 'Welcome',
|
||||
});
|
||||
|
||||
api.addPanel({
|
||||
id: 'toggle',
|
||||
component: 'toggle',
|
||||
title: 'Theme',
|
||||
position: {
|
||||
referencePanel: welcome,
|
||||
direction: 'right',
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
// ⚙️ Tema de Dockview sincronizado con Mantine
|
||||
const dockviewTheme = computedScheme === 'dark' ? themeAbyss : themeLight;
|
||||
|
||||
return (
|
||||
<div
|
||||
ref={hostRef}
|
||||
style={{
|
||||
flex: 1,
|
||||
width: '100%',
|
||||
height: '100%',
|
||||
display: 'flex',
|
||||
overflow: 'hidden',
|
||||
transition: 'background-color 0.3s ease-in-out',
|
||||
}}
|
||||
>
|
||||
<DockviewReact
|
||||
theme={dockviewTheme} // 🔥 Tema dinámico oficial de Dockview
|
||||
components={{
|
||||
welcome: (props) => (
|
||||
<ResponsivePanel component="welcome" {...props} />
|
||||
),
|
||||
toggle: (props) => (
|
||||
<ResponsivePanel component="toggle" {...props} />
|
||||
),
|
||||
}}
|
||||
onReady={onReady}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
// ✅ Panel adaptable al tamaño
|
||||
function ResponsivePanel({
|
||||
component,
|
||||
api,
|
||||
}: {
|
||||
component: 'welcome' | 'toggle';
|
||||
api: any;
|
||||
}) {
|
||||
const [size, setSize] = useState({ width: api.width, height: api.height });
|
||||
|
||||
useEffect(() => {
|
||||
const unsubscribe = api.onDidDimensionsChange(() => {
|
||||
setSize({ width: api.width, height: api.height });
|
||||
});
|
||||
return () => unsubscribe.dispose();
|
||||
}, [api]);
|
||||
|
||||
if (component === 'welcome') {
|
||||
return <Welcome width={size.width} height={size.height} />;
|
||||
}
|
||||
|
||||
if (component === 'toggle') {
|
||||
return <ColorSchemeToggle width={size.width} height={size.height} />;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
Reference in New Issue
Block a user