T19: Integrate PropertiesPanel into SidePanel with prop forwarding

This commit is contained in:
2026-06-22 23:05:55 +00:00
parent b8c2ef5aea
commit a4351f63c6
+26 -15
View File
@@ -2,13 +2,23 @@ import React, { useState, useEffect, useRef } from 'react';
import './SidePanel.css'; import './SidePanel.css';
import LayerPanel from './LayerPanel'; import LayerPanel from './LayerPanel';
import BlockLibrary from './BlockLibrary'; import BlockLibrary from './BlockLibrary';
import PropertiesPanel from './PropertiesPanel/PropertiesPanel';
const SidePanel: React.FC = () => { interface SidePanelProps {
canvasRef?: React.RefObject<unknown>;
yjsDoc?: React.RefObject<unknown>;
}
const SidePanel: React.FC<SidePanelProps> = ({ canvasRef, yjsDoc }) => {
const [activeTab, setActiveTab] = useState('blocks'); const [activeTab, setActiveTab] = useState('blocks');
const [layers, setLayers] = useState([]); const [layers, setLayers] = useState([]);
const [activeLayer, setActiveLayer] = useState(''); const [activeLayer, setActiveLayer] = useState('');
const canvasRef = useRef(null); const localCanvasRef = useRef(null);
const yjsDocRef = useRef(null); const localYjsDocRef = useRef(null);
// Use props if provided, otherwise fall back to local refs
const effectiveCanvasRef = (canvasRef ?? localCanvasRef) as React.RefObject<unknown>;
const effectiveYjsDocRef = (yjsDoc ?? localYjsDocRef) as React.RefObject<unknown>;
const tabs = [ const tabs = [
{ id: 'blocks', label: 'Blocks', icon: '🧱' }, { id: 'blocks', label: 'Blocks', icon: '🧱' },
@@ -19,16 +29,17 @@ const SidePanel: React.FC = () => {
// Observe changes in yjsDoc.layers // Observe changes in yjsDoc.layers
useEffect(() => { useEffect(() => {
if (yjsDocRef.current) { const yjsDocInstance = effectiveYjsDocRef?.current as { layers?: { forEach: (cb: (layer: Record<string, unknown>, id: string) => void) => void; observe: (cb: () => void) => void; unobserve: (cb: () => void) => void } } | null;
const yjsDoc = yjsDocRef.current; if (yjsDocInstance?.layers) {
const yjsDoc = yjsDocInstance;
// Function to update layers from yjsDoc // Function to update layers from yjsDoc
const updateLayers = () => { const updateLayers = () => {
const layersArray = []; const layersArray: Array<Record<string, unknown> & { id: string }> = [];
yjsDoc.layers.forEach((layer, id) => { yjsDoc.layers.forEach((layer, id) => {
layersArray.push({ ...layer, id }); layersArray.push({ ...layer, id });
}); });
setLayers(layersArray); setLayers(layersArray as never);
// Set active layer if none is set or if current active layer doesn't exist // Set active layer if none is set or if current active layer doesn't exist
if (!activeLayer || !layersArray.some(layer => layer.id === activeLayer)) { if (!activeLayer || !layersArray.some(layer => layer.id === activeLayer)) {
@@ -49,24 +60,24 @@ const SidePanel: React.FC = () => {
yjsDoc.layers.unobserve(updateLayers); yjsDoc.layers.unobserve(updateLayers);
}; };
} }
}, [activeLayer, yjsDocRef]); }, [activeLayer, effectiveYjsDocRef]);
const renderContent = () => { const renderContent = () => {
switch (activeTab) { switch (activeTab) {
case 'blocks': case 'blocks':
return <BlockLibrary canvasRef={canvasRef} yjsDoc={yjsDocRef.current} />; return <BlockLibrary canvasRef={effectiveCanvasRef as never} yjsDoc={(effectiveYjsDocRef as React.MutableRefObject<unknown>).current} />;
case 'layers': case 'layers':
return ( return (
<LayerPanel <LayerPanel
layers={layers} layers={layers as never}
setLayers={setLayers} setLayers={setLayers as never}
activeLayer={activeLayer} activeLayer={activeLayer}
setActiveLayer={setActiveLayer} setActiveLayer={setActiveLayer}
yjsDoc={yjsDocRef.current} yjsDoc={(effectiveYjsDocRef as React.MutableRefObject<unknown>).current}
/> />
); );
case 'properties': case 'properties':
return <div className="panel-content">Properties content goes here</div>; return <PropertiesPanel canvasRef={effectiveCanvasRef} yjsDocRef={effectiveYjsDocRef} />;
case 'copilot': case 'copilot':
return <div className="panel-content">KI Copilot content goes here</div>; return <div className="panel-content">KI Copilot content goes here</div>;
default: default: