fix(studio): polish media panel UX and preserve selection on undo

- Move Timing + Media sections above Layout in the Design panel
- Remove LayerTree from Design panel (redundant with Layers tab)
- Replace Rate and Media Start with sliders matching Volume's UX
- Replace Position DetailField with SelectField to match Fit height
- Remove Poster field (not useful for HyperFrames compositions)
- Show absolute filesystem path for Source (resolves symlinks)
- Add Copy button for source path with checkmark feedback
- Preserve element selection on undo/redo instead of clearing it
This commit is contained in:
Miguel Ángel
2026-05-18 17:26:38 -04:00
parent 96f9462e42
commit 1098f3af84
5 changed files with 104 additions and 164 deletions
@@ -12,8 +12,7 @@ import {
/** Motion data without targeting metadata. */
type StudioMotionData = Omit<StudioGsapMotion, "kind" | "target" | "updatedAt">;
import { useCallback } from "react";
import { resolveDomEditSelection, type DomEditLayerItem } from "./editor/domEditing";
import { useStudioContext } from "../contexts/StudioContext";
import { usePanelLayoutContext } from "../contexts/PanelLayoutContext";
import { useFileManagerContext } from "../contexts/FileManagerContext";
@@ -67,23 +66,10 @@ export function StudioRightPanel({
handleAskAgent,
handleDomMotionCommit,
handleDomMotionClear,
applyDomSelection,
} = useDomEditContext();
const { assets, fontAssets, handleImportFiles, handleImportFonts } = useFileManagerContext();
const isMasterView = !activeCompPath || activeCompPath === "index.html";
const handleSelectLayer = useCallback(
(layer: DomEditLayerItem) => {
const selection = resolveDomEditSelection(layer.element, {
activeCompositionPath: activeCompPath,
isMasterView,
preferClipAncestor: false,
});
if (selection) applyDomSelection(selection);
},
[activeCompPath, isMasterView, applyDomSelection],
);
const { assets, fontAssets, projectDir, handleImportFiles, handleImportFonts } =
useFileManagerContext();
const renderJobs = renderQueue.jobs as RenderJob[];
@@ -164,6 +150,7 @@ export function StudioRightPanel({
) : designPanelActive ? (
<PropertyPanel
projectId={projectId}
projectDir={projectDir}
assets={assets}
element={domEditGroupSelections.length > 1 ? null : domEditSelection}
multiSelectCount={domEditGroupSelections.length}
@@ -183,8 +170,6 @@ export function StudioRightPanel({
onImportAssets={handleImportFiles}
fontAssets={fontAssets}
onImportFonts={handleImportFonts}
activeCompositionPath={activeCompPath}
onSelectLayer={handleSelectLayer}
/>
) : motionPanelActive ? (
<MotionPanel