Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions .changeset/animated-resizable-panel.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
"@trigger.dev/core": patch
"@trigger.dev/sdk": patch
Comment on lines +2 to +3

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Changeset bumps appear to target unrelated packages.

This PR’s code changes are in apps/webapp, but the changeset bumps @trigger.dev/core and @trigger.dev/sdk. That will trigger unnecessary package releases/changelog entries. Please retarget the changeset to the actually affected publishable package(s), or remove the changeset if this is webapp-only.

---

Feat(webapp): animated resizable panel

Adds animated open/close transitions to Resizable panels using react-window-splitter built-in animation hooks. Includes new exports: RESIZABLE_PANEL_ANIMATION, collapsibleHandleClassName(), and useFrozenValue(). Converts inspector/detail side panels from conditionally-mounted to always-mounted collapsible panels across multiple routes (batches, runs, schedules, deployments, logs, waitpoints, bulk-actions).
Comment on lines +1 to +8

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🚩 Changeset targets @trigger.dev/core and @trigger.dev/sdk but PR only modifies webapp files

The changeset at .changeset/animated-resizable-panel.md declares @trigger.dev/core: patch and @trigger.dev/sdk: patch, but none of the PR's changes touch files in packages/core or packages/trigger-sdk. The exports mentioned in the changeset description (RESIZABLE_PANEL_ANIMATION, collapsibleHandleClassName(), useFrozenValue()) only exist in the webapp's Resizable.tsx component, not in either published package. This will cause unnecessary version bumps and changelog entries for packages that weren't actually changed.

Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

14 changes: 5 additions & 9 deletions apps/webapp/app/components/primitives/Resizable.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
"use client";

import React, { useRef } from "react";
import { PanelGroup, Panel, PanelResizer } from "@window-splitter/react";
import { PanelGroup, Panel, PanelResizer } from "react-window-splitter";

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔴 Import from non-existent package react-window-splitter (should be @window-splitter/react)

The import was changed from @window-splitter/react to react-window-splitter, but react-window-splitter is not listed in apps/webapp/package.json (which only has "@window-splitter/react": "1.1.3") and does not appear in pnpm-lock.yaml. The react-window-splitter npm package is actually the deprecated predecessor of @window-splitter/react — the project was already using the correct renamed package. This import will fail module resolution at build time. Additionally, another file (apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam._index/route.tsx:6) still imports from @window-splitter/react, creating an inconsistency.

Suggested change
import { PanelGroup, Panel, PanelResizer } from "react-window-splitter";
import { PanelGroup, Panel, PanelResizer } from "@window-splitter/react";
Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

import { cn } from "~/utils/cn";

const ResizablePanelGroup = ({ className, ...props }: React.ComponentProps<typeof PanelGroup>) => (
Expand Down Expand Up @@ -69,14 +69,10 @@ const ResizableHandle = ({
</PanelResizer>
);

// react-window-splitter drives the collapse animation through @react-spring/rafz,
// which has timing/interaction issues with Firefox that produce visual glitches
// (alternating frames, panels stuck at min, panelHasSpace invariant violations).
// Disable the animation on Firefox; it works correctly in Chromium and Safari.
const RESIZABLE_PANEL_ANIMATION =
typeof navigator !== "undefined" && /firefox/i.test(navigator.userAgent)
? undefined
: ({ easing: "ease-in-out", duration: 300 } as const);
const RESIZABLE_PANEL_ANIMATION = {
easing: "ease-in-out" as const,
duration: 200,
};
Comment on lines +72 to +75

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🚩 Firefox animation workaround removed without explanation

The previous code at apps/webapp/app/components/primitives/Resizable.tsx:72-79 (old) explicitly disabled collapse animation on Firefox due to documented visual glitches with @react-spring/rafz (alternating frames, panels stuck at min, panelHasSpace invariant violations). The new code unconditionally applies the animation. There's also a patch file (patches/@window-splitter__state@1.1.3.patch) that modifies collapse behavior in the state library. It's unclear whether the patch fully resolves the Firefox issues or if this removal will reintroduce the glitches on Firefox. The animation duration was also reduced from 300ms to 200ms.

Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.


const COLLAPSIBLE_HANDLE_CLASSNAME = "transition-opacity duration-200";

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -413,7 +413,7 @@ function LogsList({
const frozenLogId = useFrozenValue(selectedLogId);
const frozenLog = useFrozenValue(selectedLog);
const displayLogId = selectedLogId ?? frozenLogId;
const displayLog = selectedLog ?? frozenLog ?? undefined;
const displayLog = selectedLog ?? frozenLog;

const updateUrlWithLog = useCallback((logId: string | undefined) => {
const url = new URL(window.location.href);
Expand Down