improvement(ui): align terminal with the workflow design system, fix row hover states - #6534
Conversation
…row hover states Terminal: - derive log-row block tiles the way the canvas does (role accent for core blocks and subflows, provider colour only for role-less integrations) - compose rows from chipGeometryClass, chipContentLabelClass and disclosureChevronClass instead of re-deriving the pill - align the output tree's greys with the log rows; share ROW_STYLES.nested and BADGE_STYLE instead of duplicating the literals - neutralise value-type badges so red is the only colour in the tree - unify the row/separator gutter; normalise icon sizes to size-[14px] - drop dead flattenEntryTree and the RunningBadge re-exports Hover model (chipVariants, PopoverItem, Combobox, docs sidebar, terminal): - hover paints --surface-hover, one step below the --surface-active a selected row keeps, so a hovered row no longer impersonates the selected one - an active row holds its surface through hover instead of brightening Deploy modal: - move the footer actions onto the Chip family, primary action as Chip variant='primary' to match every other modal footer
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
PR SummaryMedium Risk Overview Terminal and output log rows now compose Workspace chrome: Deploy modal footers switch from Reviewed by Cursor Bugbot for commit a13712c. Configure here. |
Greptile SummaryThe PR aligns terminal and row-state styling with shared EMCN design-system primitives while updating deploy actions and resize-related layout behavior.
Confidence Score: 5/5The PR appears safe to merge. No blocking failure remains.
|
| Filename | Overview |
|---|---|
| packages/emcn/src/components/chip/chip-chrome.ts | Adds canonical hover and active row-state classes for reuse across component and application surfaces. |
| apps/docs/components/docs-layout/sidebar-components.tsx | Replaces duplicated sidebar state colors with shared EMCN classes while keeping active and hover states mutually exclusive. |
| apps/docs/app/global.css | Keeps the required high-specificity Fumadocs override synchronized with the shared hover token and removes active-row brightening. |
| apps/sim/app/(landing)/components/landing-preview/components/landing-preview-sidebar/landing-preview-sidebar.tsx | Fully removes the previously flagged inline token aliases and uses canonical active and hover classes. |
| apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/terminal/components/entry-block-tile/entry-block-tile.tsx | Centralizes terminal block-tile rendering and preserves the permitted runtime provider-color fallback. |
| apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/terminal/terminal.tsx | Reuses shared terminal row and tile styling instead of duplicating visual chrome. |
| apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/deploy/components/deploy-modal/deploy-modal.tsx | Migrates modal footer actions to the design-system Chip controls. |
| apps/sim/hooks/use-drag-resize.ts | Updates shared drag-resize behavior and CSS-variable handling for the revised panel and terminal layout. |
Reviews (10): Last reviewed commit: "fix(toast): derive the workflow inset fr..." | Re-trigger Greptile
…erminal rows Review follow-ups from /simplify and /cleanup: - add chipHoverSurfaceClass / chipActiveSurfaceClass to chip-chrome as the one home for the two-surface row model, and route chipVariants, PopoverItem, Combobox, the docs sidebar, the landing preview and queued messages through them instead of restating the literals - terminal ROW_STYLES now renders chipVariants rather than re-deriving its output, and the four rows share content/label/status classes resolved once - structured-output composes chipGeometryClass with an h-auto override rather than restating four of its literals - getEntryAccentType collapses to one expression, dropping the SYNTHETIC_BLOCK types coupling - collapse the chip compound variants to two array-matched entries - deploy modal: hoist the shared loader adornment, size it with chipContentIconClass so it matches every other chip icon - landing preview drops its --c-active/--c-hover inline aliases for the tokens - trim the rationale to one canonical copy with cross-references, and convert the block comments on declarations to TSDoc
…and icon scale - floating controls sit on --surface-2, the surface the block cards use, rather than --surface-1 (the sidebar/panel surface) - undo/redo/fit glyphs drop 16px -> the platform's 14px default, and the mode dropdown's own 12px icons come up to match; the control had three icon sizes - inactive buttons hover to --surface-hover instead of --surface-5, which was the active mode button's resting fill, so hovering one looked selected - inner radius goes concentric with the 4px padding (rounded-sm inside rounded-lg)
|
@cursor review |
…t as its siblings It was the only control in the cluster with no hover fill and a different rest colour (--text-muted against the others' --text-secondary), so it read fainter and behaved differently under the pointer. It is also a disclosure chevron, so it now uses disclosureChevronClass instead of a hand-rolled duration-100 copy, and a real 20px box instead of the !p-1.5 override plus -m-1 hit-area hack.
|
@cursor review |
getEntryAccentType encodes a cross-surface rule — a block must be accented the same way in the terminal as in the block toolbar — and nothing enforced it. The table covers every branch: core blocks mapped and unmapped, role-bearing and role-less integrations and triggers, the config-less subflows, and the synthesized error/validation/cancelled rows that must keep their status fill. Verified failing: reverting the guard to an unconditional return reds two of the four cases.
|
@cursor review |
The toast stack insets by --panel-width / --terminal-height, but a resize drag writes those to the resized subtree only (.panel-container / .terminal-container) rather than to :root, because a custom-property write on :root recalculates the whole document (~150x slower). The stack is portalled to <body>, so it shares no ancestor with either and kept reading the stale :root value — it held its pre-drag position and jumped once the drag committed, while the canvas controls, which are laid out inside the shrinking canvas, tracked the drag in realtime. useDragResize now accepts several target subtrees and writes each one, so the scoped recalc is preserved and every consumer follows the drag frame by frame. The stack is found through a new data-toast-viewport attribute. Also drops the canvas controls from bottom-4 to bottom-2: the toast clears the terminal by 8px (it anchors from the viewport, and the terminal is inset by CONTENT_WINDOW_GAP), where the controls measure from the canvas floor and so sat at twice the gap.
|
@cursor review |
The toast stack clears the terminal and the panel by 8px — it anchors from the viewport at --terminal-height/--panel-width + 16px, and both are themselves inset by CONTENT_WINDOW_GAP (8px). The controls measure from the canvas floor and wall instead, so their 16px read as twice the gap on both axes.
|
@cursor review |
…clearance 8px sat them too close to the terminal. 12 is on the same 4px grid as the surrounding spacing, where 10 would have been the only off-grid value in the area. Both surfaces clear the terminal and the panel by the same amount, so they read as one row; the toast's literals move into named insets rather than staying bare numbers in a style object.
|
@cursor review |
…nsumers getTarget briefly accepted a list, which made the first entry both the resized element and the drag's liveness reference. A toast auto-dismisses after 5s, so had one ever led that list, its mid-drag unmount would have read as the drag target detaching and skipped the final recompute on release. The co-consumers now come through getExtraTargets, which is written but never consulted for liveness, and can come and go freely.
|
@cursor review |
The option rows painted --surface-active from CSS :hover as well as from isHighlighted. CSS :hover tracks the pointer continuously while highlightedIndex only advances on mouseenter, so once the list scrolled under a stationary pointer the row that looked selected was not the one Enter would commit — Enter reads filteredOptions[highlightedIndex]. isHighlighted is now the single source of truth for the cursor, so paint and commit cannot disagree. The row under a stationary pointer may lag a scroll until the mouse moves, but it lags in agreement with what Enter will do, which is the invariant worth keeping. Disabled options also stop painting on hover, matching the mouseenter guard that already refused to highlight them. The 'All' row keeps its own hover: it clears the highlight rather than taking it, so it has no isHighlighted paint to fall back on.
|
@cursor review |
WORKFLOW_INSET_PX baked in the 8px the workspace shell normally insets the panel and terminal by, so the stack's 20px resolved to a 12px clearance — matching the canvas controls. But the shell drops to p-0 on the desktop title-bar shell with a collapsed sidebar, and there the stack would have sat 20px out while the controls, laid out inside the shell, stayed at 12. The stack now adds --workspace-content-gap (published on :root, zeroed by the same condition that zeroes the padding) to a flat 12, so the two surfaces hold the same clearance in both configurations. Before this PR they matched in the p-0 case at 16px each, so this closes a divergence the PR would otherwise have introduced.
|
@cursor review |
There was a problem hiding this comment.
✅ Bugbot reviewed your changes and found no new issues!
Comment @cursor review or bugbot run to trigger another review on this PR
Reviewed by Cursor Bugbot for commit a13712c. Configure here.
Summary
Terminal → workflow design system
bgColor, so an Agent block was a purple swatch in the terminal and an inverse chip on the canvas.chipGeometryClass/chipContentLabelClass/disclosureChevronClassinstead of re-deriving the pill; the output tree's greys now match the log rows, and it sharesROW_STYLES.nested+BADGE_STYLEinstead of duplicating those literals.size-[14px], dropped deadflattenEntryTreeand theRunningBadgere-exports.Row hover model (
chipVariants,PopoverItem,Combobox, docs sidebar, terminal, landing preview, queued messages)--surface-hover, one step below the--surface-activea selected row keeps. Hover used to land on--surface-activetoo, so a row the pointer merely passed over was painted exactly like the selected one.--surface-6, which read as the selection changing under the cursor.Deploy modal
Chipfamily, primary action asChip variant='primary', matching every other modal footer in the app. The spinner usesleftAdornmentso the component owns the gap.Type of Change
Testing
Typecheck clean on
apps/sim,apps/docs,packages/emcn,packages/workflow-renderer. Tests pass: emcn (62), workflow-renderer (62), terminal utils (22), panel + sidebar (174). Not visually verified — browser tooling was unavailable for this session, so the colour-relationship changes in particular are worth a look before merge.Checklist