6cdd8814a3
## Summary - Run-view inspector panel was glitching out on Firefox: visual flicker on close, locking up at min size, and intermittent `panelHasSpace` invariant errors. Root cause is the underlying `react-window-splitter` library's collapse animation, which uses `@react-spring/rafz` and interacts poorly with Firefox. - Disabled the library's collapse animation on Firefox only, app-wide (every consumer of `RESIZABLE_PANEL_ANIMATION`). Chromium and Safari behaviour is unchanged. ## Changes - **Firefox animation skip** in `RESIZABLE_PANEL_ANIMATION` — UA-detected at module load, resolves to `undefined` for Firefox so the library's animation actor completes in one frame instead of running its rAF loop. - **Inspector min raised 50px → 250px** so dragging can't shrink the panel into a near-useless width. - **`autosaveId` bumped `v2` → `v3`** to invalidate stale persisted snapshots (the library has a `// TODO` branch that ignores prop changes for already-registered panels, so existing users would otherwise still see the old 50px min). - **`react-window-splitter` pinned** to exact `0.4.1` to protect the patch from drifting if line offsets change in a patch release. - **Two hunks added to the existing `@window-splitter/state` patch:** - Removed the library's auto-collapse-on-drag block entirely. Every collapsible panel in the app is parent-controlled, and that block was triggering state-machine deadlocks when handlers were no-ops. Drag-to-collapse is now disabled across the app; collapse is only triggered explicitly (close button, ESC, URL change, etc.). - In `getDeltaForEvent`, fall back to the panel's `default` before its `min` when expanding — so the first ever click on a span opens the inspector at 500px, not 250px. ## Local testing confirmed - [x] Firefox: open a run, click various spans → panel opens instantly at 500px, drags freely between 250px and max, closes instantly to 0. No console errors. - [x] Chrome/Chromium: same flow, but with smooth open/close animation as before. - [x] Safari: same as Chrome. - [x] Reload mid-session → panel restores cleanly to the dragged size. - [x] Other resizable panels in the app (logs, deployments, schedules, batches, bulk-actions, runs index) still animate on Chromium/Safari. ## Notes - Linear: TRI-8584 - Branch contains intermediate commits exploring an unsuccessful snapshot-validator approach; they're reverted by the final commit. Cumulative diff is 6 files. Squash on merge if you'd prefer a clean history. --------- Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
115 lines
6.7 KiB
Diff
115 lines
6.7 KiB
Diff
diff --git a/dist/commonjs/index.js b/dist/commonjs/index.js
|
|
index e3bdcf702702392e9a06c981545f659ee7c5970e..d88ae6b2dc5b4cf1970cb693f58a926bd12a8f45 100644
|
|
--- a/dist/commonjs/index.js
|
|
+++ b/dist/commonjs/index.js
|
|
@@ -757,30 +757,14 @@ function updateLayout(context, dragEvent) {
|
|
panelAfter.onCollapseChange.current(false);
|
|
}
|
|
}
|
|
- const panelBeforeIsAboutToCollapse = panelBefore.currentValue.value.eq(getUnitPixelValue(context, panelBefore.min));
|
|
- // If the panel was expanded and now is at it's min size, collapse it
|
|
- if (!dragEvent.disregardCollapseBuffer &&
|
|
- panelBefore.collapsible &&
|
|
- panelBeforeIsAboutToCollapse) {
|
|
- if (panelBefore.onCollapseChange?.current &&
|
|
- panelBefore.collapseIsControlled &&
|
|
- !dragEvent.controlled &&
|
|
- !dragEvent.isVirtual) {
|
|
- panelBefore.onCollapseChange.current(true);
|
|
- return { dragOvershoot: newDragOvershoot };
|
|
- }
|
|
- // Make it collapsed
|
|
- panelBefore.collapsed = true;
|
|
- panelBeforeNewValue = getUnitPixelValue(context, panelBefore.collapsedSize);
|
|
- // Add the extra space created to the before panel
|
|
- panelAfterNewValue = panelAfter.currentValue.value.add(panelBeforePreviousValue.minus(panelBeforeNewValue));
|
|
- if (panelBefore.onCollapseChange?.current &&
|
|
- !panelBefore.collapseIsControlled &&
|
|
- !dragEvent.controlled &&
|
|
- !dragEvent.isVirtual) {
|
|
- panelBefore.onCollapseChange.current(true);
|
|
- }
|
|
- }
|
|
+ // Drag-to-collapse is disabled in this fork: every consumer of the
|
|
+ // library uses controlled `collapsed` props and triggers collapse
|
|
+ // explicitly (close button, ESC, URL change, etc.). The original auto-
|
|
+ // collapse-on-drag logic that lived here would notify the parent when a
|
|
+ // collapsible panel reached its min during a drag — keeping it for our
|
|
+ // (controlled-only) case caused state-machine deadlocks when handlers
|
|
+ // were no-ops, so the block is removed entirely. Panels just clamp at
|
|
+ // `min` during drag now.
|
|
panelBefore.currentValue = { type: "pixel", value: panelBeforeNewValue };
|
|
panelAfter.currentValue = { type: "pixel", value: panelAfterNewValue };
|
|
const leftoverSpace = new big_js_1.default(getGroupSize(context)).minus(newItems.reduce((acc, b) => acc.add(isPanelData(b) ? b.currentValue.value : b.size.value), new big_js_1.default(0)));
|
|
@@ -940,7 +924,12 @@ function setCookie(name, jsonData) {
|
|
function getDeltaForEvent(context, event) {
|
|
const panel = getPanelWithId(context, event.panelId);
|
|
if (event.type === "expandPanel") {
|
|
- return new big_js_1.default(panel.sizeBeforeCollapse ?? getUnitPixelValue(context, panel.min)).minus(panel.currentValue.value);
|
|
+ // Fall back to `default` before `min` so the first-ever expand of a
|
|
+ // panel that started life collapsed lands at its configured default
|
|
+ // size rather than getting stuck at `min`.
|
|
+ const defaultPx = panel.default ? getUnitPixelValue(context, panel.default) : undefined;
|
|
+ const target = panel.sizeBeforeCollapse ?? defaultPx ?? getUnitPixelValue(context, panel.min);
|
|
+ return new big_js_1.default(target).minus(panel.currentValue.value);
|
|
}
|
|
const collapsedSize = getUnitPixelValue(context, panel.collapsedSize);
|
|
return panel.currentValue.value.minus(collapsedSize);
|
|
diff --git a/dist/esm/index.js b/dist/esm/index.js
|
|
index f8fddd70c0f1aaed29f2fb0ca0d8093d8ce66335..d1dae8beb1447afca47b91e796b8279135f50c36 100644
|
|
--- a/dist/esm/index.js
|
|
+++ b/dist/esm/index.js
|
|
@@ -728,30 +728,14 @@ function updateLayout(context, dragEvent) {
|
|
panelAfter.onCollapseChange.current(false);
|
|
}
|
|
}
|
|
- const panelBeforeIsAboutToCollapse = panelBefore.currentValue.value.eq(getUnitPixelValue(context, panelBefore.min));
|
|
- // If the panel was expanded and now is at it's min size, collapse it
|
|
- if (!dragEvent.disregardCollapseBuffer &&
|
|
- panelBefore.collapsible &&
|
|
- panelBeforeIsAboutToCollapse) {
|
|
- if (panelBefore.onCollapseChange?.current &&
|
|
- panelBefore.collapseIsControlled &&
|
|
- !dragEvent.controlled &&
|
|
- !dragEvent.isVirtual) {
|
|
- panelBefore.onCollapseChange.current(true);
|
|
- return { dragOvershoot: newDragOvershoot };
|
|
- }
|
|
- // Make it collapsed
|
|
- panelBefore.collapsed = true;
|
|
- panelBeforeNewValue = getUnitPixelValue(context, panelBefore.collapsedSize);
|
|
- // Add the extra space created to the before panel
|
|
- panelAfterNewValue = panelAfter.currentValue.value.add(panelBeforePreviousValue.minus(panelBeforeNewValue));
|
|
- if (panelBefore.onCollapseChange?.current &&
|
|
- !panelBefore.collapseIsControlled &&
|
|
- !dragEvent.controlled &&
|
|
- !dragEvent.isVirtual) {
|
|
- panelBefore.onCollapseChange.current(true);
|
|
- }
|
|
- }
|
|
+ // Drag-to-collapse is disabled in this fork: every consumer of the
|
|
+ // library uses controlled `collapsed` props and triggers collapse
|
|
+ // explicitly (close button, ESC, URL change, etc.). The original auto-
|
|
+ // collapse-on-drag logic that lived here would notify the parent when a
|
|
+ // collapsible panel reached its min during a drag — keeping it for our
|
|
+ // (controlled-only) case caused state-machine deadlocks when handlers
|
|
+ // were no-ops, so the block is removed entirely. Panels just clamp at
|
|
+ // `min` during drag now.
|
|
panelBefore.currentValue = { type: "pixel", value: panelBeforeNewValue };
|
|
panelAfter.currentValue = { type: "pixel", value: panelAfterNewValue };
|
|
const leftoverSpace = new Big(getGroupSize(context)).minus(newItems.reduce((acc, b) => acc.add(isPanelData(b) ? b.currentValue.value : b.size.value), new Big(0)));
|
|
@@ -911,7 +895,12 @@ function setCookie(name, jsonData) {
|
|
function getDeltaForEvent(context, event) {
|
|
const panel = getPanelWithId(context, event.panelId);
|
|
if (event.type === "expandPanel") {
|
|
- return new Big(panel.sizeBeforeCollapse ?? getUnitPixelValue(context, panel.min)).minus(panel.currentValue.value);
|
|
+ // Fall back to `default` before `min` so the first-ever expand of a
|
|
+ // panel that started life collapsed lands at its configured default
|
|
+ // size rather than getting stuck at `min`.
|
|
+ const defaultPx = panel.default ? getUnitPixelValue(context, panel.default) : undefined;
|
|
+ const target = panel.sizeBeforeCollapse ?? defaultPx ?? getUnitPixelValue(context, panel.min);
|
|
+ return new Big(target).minus(panel.currentValue.value);
|
|
}
|
|
const collapsedSize = getUnitPixelValue(context, panel.collapsedSize);
|
|
return panel.currentValue.value.minus(collapsedSize);
|