fix: refine floating workspace controls
Keep ScaleInfo pinned to the map corner and move the centered timeline above collisions, preventing the previous conditional offset from lifting the scale. Remove collapsed Agent rail width reservation and add timeline state transitions.
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
import { ArrowLeft, FileChartColumnIncreasing } from "lucide-react";
|
||||
import { AnimatePresence, motion, useReducedMotion } from "motion/react";
|
||||
import type { ReactNode } from "react";
|
||||
import { cn } from "@/shared/ui/cn";
|
||||
import { OPERATIONAL_TIMELINE_LAYOUT } from "../operational-timeline/operational-timeline-model";
|
||||
@@ -15,7 +16,7 @@ type WorkbenchMainFrameProps = {
|
||||
mapOverlay?: ReactNode;
|
||||
timelineContent: ReactNode;
|
||||
timelineMode: "compact" | "expanded" | "summary";
|
||||
reserveMapScaleSpace: boolean;
|
||||
timelineBottom: number;
|
||||
activeArtifact: AnalysisArtifact | null;
|
||||
pendingArtifact: AnalysisArtifact | null;
|
||||
surfaceMode: WorkbenchSurfaceMode;
|
||||
@@ -32,7 +33,7 @@ export function WorkbenchMainFrame({
|
||||
mapOverlay,
|
||||
timelineContent,
|
||||
timelineMode,
|
||||
reserveMapScaleSpace,
|
||||
timelineBottom,
|
||||
activeArtifact,
|
||||
pendingArtifact,
|
||||
surfaceMode,
|
||||
@@ -43,8 +44,12 @@ export function WorkbenchMainFrame({
|
||||
onCollapseArtifact,
|
||||
onDestroyArtifact
|
||||
}: WorkbenchMainFrameProps) {
|
||||
const prefersReducedMotion = useReducedMotion();
|
||||
const showMap = surfaceMode !== "focus";
|
||||
const showArtifact = activeArtifact && surfaceMode !== "map_only";
|
||||
const timelineTransition = prefersReducedMotion
|
||||
? { duration: 0 }
|
||||
: { duration: 0.28, ease: [0.22, 1, 0.36, 1] as const };
|
||||
|
||||
return (
|
||||
<div
|
||||
@@ -113,18 +118,30 @@ export function WorkbenchMainFrame({
|
||||
) : null}
|
||||
</div>
|
||||
|
||||
<div
|
||||
className="pointer-events-auto absolute bottom-3 left-3 z-40 mx-auto min-h-0"
|
||||
style={{
|
||||
<motion.div
|
||||
className="pointer-events-auto absolute left-3 z-40 mx-auto min-h-0"
|
||||
initial={false}
|
||||
animate={{
|
||||
bottom: timelineBottom,
|
||||
maxWidth: OPERATIONAL_TIMELINE_LAYOUT[timelineMode].maxWidth,
|
||||
right: reserveMapScaleSpace
|
||||
? OPERATIONAL_TIMELINE_LAYOUT.mapScaleSafeWidth +
|
||||
OPERATIONAL_TIMELINE_LAYOUT.floatingGap
|
||||
: 12
|
||||
right: 12
|
||||
}}
|
||||
transition={timelineTransition}
|
||||
>
|
||||
{timelineContent}
|
||||
</div>
|
||||
<AnimatePresence initial={false}>
|
||||
{timelineContent ? (
|
||||
<motion.div
|
||||
key="operational-timeline"
|
||||
initial={prefersReducedMotion ? false : { opacity: 0, y: 14, scale: 0.985 }}
|
||||
animate={{ opacity: 1, y: 0, scale: 1 }}
|
||||
exit={prefersReducedMotion ? { opacity: 0 } : { opacity: 0, y: 12, scale: 0.985 }}
|
||||
transition={timelineTransition}
|
||||
>
|
||||
{timelineContent}
|
||||
</motion.div>
|
||||
) : null}
|
||||
</AnimatePresence>
|
||||
</motion.div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user