From f5dd99ed083ba9035f378438e7a9dc9c5ce1c674 Mon Sep 17 00:00:00 2001 From: Hiroshi Ogawa Date: Tue, 6 Oct 2026 22:07:55 +0900 Subject: [PATCH] feat(ui): add fit and zoom controls to trace viewer (#11490) Co-authored-by: Hiroshi Ogawa <4232207+hi-ogawa@users.noreply.github.com> Co-authored-by: Claude Opus 5.5 --- .../ui/client/components/trace/TraceView.vue | 32 +++++++-- .../client/components/trace/TraceViewPane.vue | 2 + .../components/trace/TraceZoomControl.vue | 55 +++++++++++++++ packages/ui/client/composables/trace-view.ts | 42 ++++++++++- packages/ui/client/styles/main.css | 16 +++++ test/ui/fixtures/trace/basic.test.ts | 41 +++++++++++ test/ui/test/trace.spec.ts | 69 ++++++++++++++++++- 7 files changed, 247 insertions(+), 10 deletions(-) create mode 100644 packages/ui/client/components/trace/TraceZoomControl.vue diff --git a/packages/ui/client/components/trace/TraceView.vue b/packages/ui/client/components/trace/TraceView.vue index cb51880bb..c9b9ce7ae 100644 --- a/packages/ui/client/components/trace/TraceView.vue +++ b/packages/ui/client/components/trace/TraceView.vue @@ -14,6 +14,7 @@ import { getTraceEntryClass, selectActiveTraceStep, showTraceSelectorHighlight, + useTraceZoom, } from '~/composables/trace-view' const props = defineProps<{ @@ -31,6 +32,17 @@ const iframeSandbox = computed(() => { return props.trace.recordCanvas ? 'allow-same-origin allow-scripts' : 'allow-same-origin' }) +const { level: zoomLevel, setFitContainer } = useTraceZoom() +const viewport = computed(() => selectedStep.value?.snapshot.viewport) +const scaledViewportStyle = computed(() => + viewport.value + ? { + width: `${Math.floor(viewport.value.width * zoomLevel.value)}px`, + height: `${Math.floor(viewport.value.height * zoomLevel.value)}px`, + } + : undefined, +) + function onSelectStep(index: number) { selectActiveTraceStep(index) const step = entries.value[index] @@ -254,14 +266,20 @@ function onSplitpanesResized({ panes }: SplitpanesResizedPayload) { -
-