feat: editor improvements and collapsible sidebars

Add collapse/expand toggle for the AppShell navigation sidebar and the
editor properties panel (both persisted to localStorage). Bundles other
in-progress editor work including position anchors, outlet sizing, PBR
textures, window slope/frame depth, curtain metadata, and various 2D/3D
rendering tweaks.
This commit is contained in:
2026-04-08 12:27:57 +03:00
parent aa8a874348
commit d8a914bf2a
116 changed files with 7324 additions and 1114 deletions
@@ -53,7 +53,7 @@ export function EditorToolbar({ onSave, isSaving, onExport, onImport }: EditorTo
const { state, setTool, setZoom, dispatch } = useEditor();
const { undo, redo, canUndo, canRedo } = useUndoRedo();
const { activeTool, zoom, gridVisible, snapEnabled, layerVisibility } = state;
const { activeTool, zoom, gridVisible, snapEnabled, layerVisibility, globalFurnitureOpacity } = state;
const zoomPercent = Math.round((zoom / 100) * 100);
@@ -193,6 +193,37 @@ export function EditorToolbar({ onSave, isSaving, onExport, onImport }: EditorTo
>
{t('toolbar.meas')}
</button>
<label
title={t('toolbar.furnitureOpacity') ?? 'Furniture opacity'}
style={{
display: 'flex',
alignItems: 'center',
gap: 6,
paddingLeft: 6,
fontSize: 12,
color: 'var(--color-text-secondary)',
}}
>
<span aria-hidden style={{ fontSize: 14 }}></span>
<input
type="range"
min={0}
max={1}
step={0.05}
value={globalFurnitureOpacity}
onChange={(e) => {
const next = parseFloat(e.target.value);
if (Number.isFinite(next)) {
dispatch({ type: 'SET_GLOBAL_FURNITURE_OPACITY', opacity: next });
}
}}
style={{ width: 70 }}
aria-label={t('toolbar.furnitureOpacity') ?? 'Furniture opacity'}
/>
<span style={{ minWidth: 30, textAlign: 'right', fontVariantNumeric: 'tabular-nums' }}>
{Math.round(globalFurnitureOpacity * 100)}%
</span>
</label>
</div>
{/* Alignment tools — visible when 2+ items selected */}