55 lines
1.7 KiB
TypeScript
55 lines
1.7 KiB
TypeScript
|
|
import React, { useState, useCallback } from 'react';
|
||
|
|
import { useEditor } from '@craftjs/core';
|
||
|
|
import { TopBar } from '../panels/topbar/TopBar';
|
||
|
|
import { LeftPanel } from '../panels/left/LeftPanel';
|
||
|
|
import { RightPanel } from '../panels/right/RightPanel';
|
||
|
|
import { Canvas } from './Canvas';
|
||
|
|
import { ContextMenu } from '../panels/context-menu/ContextMenu';
|
||
|
|
import { useContextMenu } from '../hooks/useContextMenu';
|
||
|
|
import { useKeyboardShortcuts } from '../hooks/useKeyboardShortcuts';
|
||
|
|
import { DeviceMode } from '../types';
|
||
|
|
|
||
|
|
export const EditorShell: React.FC = () => {
|
||
|
|
const [device, setDevice] = useState<DeviceMode>('desktop');
|
||
|
|
const { menuState, show: showMenu, hide: hideMenu } = useContextMenu();
|
||
|
|
const { query } = useEditor();
|
||
|
|
|
||
|
|
// Register keyboard shortcuts
|
||
|
|
useKeyboardShortcuts();
|
||
|
|
|
||
|
|
const handleContextMenu = useCallback((e: React.MouseEvent) => {
|
||
|
|
e.preventDefault();
|
||
|
|
// Find the selected node id
|
||
|
|
let nodeId: string | null = null;
|
||
|
|
try {
|
||
|
|
const selected = query.getEvent('selected').all();
|
||
|
|
if (selected.length > 0) {
|
||
|
|
nodeId = selected[0];
|
||
|
|
}
|
||
|
|
} catch {
|
||
|
|
// No selection
|
||
|
|
}
|
||
|
|
showMenu(e.clientX, e.clientY, nodeId);
|
||
|
|
}, [query, showMenu]);
|
||
|
|
|
||
|
|
return (
|
||
|
|
<div className="editor-app">
|
||
|
|
<TopBar device={device} onDeviceChange={setDevice} />
|
||
|
|
<div className="editor-container">
|
||
|
|
<LeftPanel />
|
||
|
|
<div onContextMenu={handleContextMenu} style={{ flex: 1, display: 'flex', minWidth: 0 }}>
|
||
|
|
<Canvas device={device} />
|
||
|
|
</div>
|
||
|
|
<RightPanel />
|
||
|
|
</div>
|
||
|
|
<ContextMenu
|
||
|
|
visible={menuState.visible}
|
||
|
|
x={menuState.x}
|
||
|
|
y={menuState.y}
|
||
|
|
nodeId={menuState.nodeId}
|
||
|
|
onClose={hideMenu}
|
||
|
|
/>
|
||
|
|
</div>
|
||
|
|
);
|
||
|
|
};
|