[eric] canvas: app cards resize on every tab, not just preview (ENG-290)

This commit is contained in:
ciregenz
2026-08-13 19:53:08 -07:00
parent 6b3c93278f
commit 0554ffab56
3 changed files with 40 additions and 2 deletions
@@ -30,6 +30,7 @@ import TerminalPanel, { TerminalLine } from '@/app/pages/Views/TerminalPanel';
import AppCodePanel from '@/app/pages/Views/AppCodePanel';
import HistoryPanel from '@/app/pages/Views/HistoryPanel';
import ShareButton from '@/app/components/share/ShareButton';
import { CONTENT_OVERLAY_Z, RESIZE_HANDLE_Z } from './cardLayers';
import ShareModal from '@/app/components/share/ShareModal';
import { getDefault } from '@/shared/inputSchemaDefaults';
import { useOverlayScrollPassthrough } from '../hooks/interaction/useOverlayScrollPassthrough';
@@ -885,7 +886,7 @@ const DashboardViewCard: React.FC<Props> = ({
/>
{/* Code/Terminal overlay the always-mounted preview instead of replacing it: unmounting the webview kills the app's live state and forces a reload on switch-back. */}
{output.workspace_id && activeView !== 'preview' && (
<Box sx={{ position: 'absolute', inset: 0, zIndex: 13, bgcolor: c.bg.surface }}>
<Box sx={{ position: 'absolute', inset: 0, zIndex: CONTENT_OVERLAY_Z, bgcolor: c.bg.surface }}>
{activeView === 'terminal' ? (
<TerminalPanel lines={terminalLines} />
) : activeView === 'history' ? (
@@ -916,7 +917,7 @@ const DashboardViewCard: React.FC<Props> = ({
position: 'absolute',
cursor: CURSOR_MAP[dir],
opacity: 0,
zIndex: 10,
zIndex: RESIZE_HANDLE_Z,
...sx,
}}
/>
@@ -0,0 +1,21 @@
// Run: npm test (frontend/scripts/run-tests.mjs)
//
// ENG-290. App cards could only be resized on the preview tab: the code/terminal/history panel fills
// the card and sat ABOVE the resize handles, so the grab strips were buried the moment you switched
// tabs. The bug was purely an ordering mistake between two numbers written 700 lines apart, which is
// the kind of thing nobody re-derives while reading a component.
import { test } from 'node:test';
import assert from 'node:assert/strict';
import { CONTENT_OVERLAY_Z, RESIZE_HANDLE_Z } from './cardLayers.ts';
test('resize handles sit above any content that fills the card', () => {
assert.ok(
RESIZE_HANDLE_Z > CONTENT_OVERLAY_Z,
`handles at ${RESIZE_HANDLE_Z} are under the content overlay at ${CONTENT_OVERLAY_Z}, so the `
+ 'card cannot be resized wherever that content shows',
);
});
test('the two layers are distinct, so neither can silently absorb the other', () => {
assert.notEqual(RESIZE_HANDLE_Z, CONTENT_OVERLAY_Z);
});
@@ -0,0 +1,16 @@
// Where things stack inside a canvas card (ENG-290).
//
// App cards could only be resized on the preview tab. The Code/Terminal/History panel renders only
// when `activeView !== 'preview'`, covers the card with `inset: 0`, and sat at z-index 13 while the
// resize handles sat at 10, so switching tabs buried the handles under the panel. AgentCard already
// used 20 for the same handles, so this was one component drifting rather than a design question.
//
// Named and ordered here so the next panel someone adds has an obvious ceiling to stay under, and
// so the ordering is a thing a test can check rather than a number to eyeball.
/** Full-card content that replaces the preview (code, terminal, history). */
export const CONTENT_OVERLAY_Z = 13;
/** The invisible grab strips at the card's edges. Must sit ABOVE any content that fills the card,
* or the edges stop being grabbable wherever that content is showing. */
export const RESIZE_HANDLE_Z = 20;