Skip to content

Rebuild the node cards on the app's own controls - #388

Merged
dovvnloading merged 1 commit into
mainfrom
ux/node-card-controls
Sep 1, 2026
Merged

dovvnloading merged 1 commit into
mainfrom
ux/node-card-controls

Conversation

@dovvnloading

Copy link
Copy Markdown
Owner

Problem

The Qt-to-React refactor modernized the app chrome and left the canvas node views behind. A QA pass over the seven plugin cards - read statically, then measured in the running app at 1440x900 with a fixture holding one node of every kind - found them still rendering controls the rest of the app had already replaced, and two cards unable to size or bound their own content.

  • Gitlink's Context scope was the last native <select> in the app. CustomSelect backs every dropdown in Settings, Builder, Chat Library and the View popover, and no node view at all.
  • Raw OS checkboxes in Web Research's retain-to-knowledge opt-in and Gitlink's per-file rows, while the View panel already ships a drawn checkbox introduced when the team replaced "the last engine-drawn controls" there. Most visible in the file list, where the control repeats once per row.
  • Artifact's and Conversation's instruction inputs were rows={1} textareas with no height in CSS at all - they stayed one line regardless of how much was typed.
  • Artifact bounded its card body and left the document preview unbounded, so a long draft pushed the turn history and the instruction row out of the visible card.
  • Gitlink's Setup tab scrolled its file list inside an already-scrolling body - measured bodyClipped: true with a nested inner scroller, the same defect the code-sandbox card had before its rebuild: a max-height flex column shrinks its children below their content size unless told not to.
  • Artifact's submit stayed on "Generate" while merely disabled during a request, where the sandbox card states "Running…".
  • Gitlink labelled two of its four Setup fields and left the other two placeholder-only, and offered four equal-weight buttons with no primary.
  • Web Research rendered a query box above blank space with nothing describing what a run produces.
  • The HTML card shipped a permanently disabled "Popout" button explaining itself in a tooltip.

Change

Frontend and CSS only - no backend, no wire change, no contract regeneration.

  • Gitlink's Context scope uses CustomSelect. It portals to the body and positions from getBoundingClientRect, so React Flow's viewport transform does not affect it.
  • The View panel's drawn checkbox is extracted to a shared .gl-checkbox class and adopted by both node-view checkboxes; the View panel itself renders identically.
  • Both instruction inputs auto-size natively (field-sizing: content with real bounds), the posture .composer-input and .code-sandbox-node-input already take.
  • Artifact's document preview and turn history each scroll themselves, children no longer shrink below their content size, and the instruction row can never be scrolled out of reach.
  • Gitlink's Setup tab keeps its children at content size and gets a larger budget, so the nested scrollbars collapse to a single scroll region.
  • Artifact's submit reads "Generating…" / "Refining…" while in flight.
  • All four Gitlink Setup fields are labelled, and Load Repo Tree is the tab's one primary.
  • Web Research renders an empty state before its first run, in .library-empty-state's idiom at card scale.
  • The Popout button is removed; the reason popout is unbuilt moves into the module doc, and a test asserts the control's absence so a dead placeholder cannot return.

Test plan

  • npm run check (schema drift, typecheck, lint, vitest, build, bundle size) against a clean checkout of this branch: all green.
  • New/updated tests: Gitlink renders no native <select> and exposes the Context scope trigger; its file-row checkboxes carry .gl-checkbox; the scope-mode test drives the real dropdown through the same trigger-then-option idiom SettingsDialog.test.tsx uses; Web Research shows the empty state initially, hides it beside a failure banner, and carries the drawn checkbox; Artifact asserts both the busy label and the disabled state, for the Generate and Refine cases; the HTML card asserts Popout's absence and that no window is opened.
  • Measured live against the built bundle at 1440x900 with all nine node kinds on the canvas: zero native selects and zero unstyled checkboxes across every card; Artifact's body no longer clips, with its document preview as the single intended scroll region; Gitlink's nested scrolling is gone, leaving one scroll region on a dense card.

The Qt-to-React move modernized the app chrome and left the canvas node
views behind. The cards were still rendering controls the rest of the app
had already replaced, and two of them could not size or bound their own
content.

Controls:

- Gitlink's Context scope was the last native <select> in the app.
  CustomSelect is what Settings, Builder, Chat Library and the View
  popover all render; it portals to the body and positions off
  getBoundingClientRect, so React Flow's viewport transform does not
  affect it.
- The drawn checkbox that replaced "the last engine-drawn controls" in the
  View panel becomes a shared .gl-checkbox class. Web Research's
  retain-to-knowledge opt-in and Gitlink's per-file rows were still raw OS
  checkboxes - most visible in the file list, where the control repeats
  once per row. The View panel adopts the extracted class unchanged.

Sizing:

- Artifact's and Conversation's instruction inputs were rows=1 textareas
  with no height in CSS at all, so they stayed one line no matter how much
  was typed. They auto-size natively now, the same posture .composer-input
  and .code-sandbox-node-input already take.
- Artifact's card bounded its BODY and left the document preview
  unbounded, so a long draft pushed the turn history and the instruction
  row out of the visible card. The preview and the history each scroll
  themselves now, children no longer shrink below their content, and the
  instruction row can never be scrolled out of reach.
- Gitlink's Setup tab had the same squeeze, and scrolled its file list
  INSIDE an already-scrolling body - two nested scrollbars on one card.
  Children keep their size now and the budget is raised, leaving a single
  scroll region.

Copy and affordances:

- Artifact's submit states that it is busy ("Generating…" / "Refining…")
  instead of staying on "Generate" while merely disabled, matching the
  sandbox card's "Running…".
- Gitlink's Setup tab labels all four of its fields; two were
  placeholder-only, so they announced themselves only until you typed.
  Load Repo Tree becomes the tab's one primary among what were four
  equal-weight buttons.
- Web Research renders an empty state before its first run instead of a
  query box above blank space.
- The HTML card's Popout button is gone. It shipped permanently disabled
  with its reason in a tooltip; a control that can never be used is noise,
  and the reason lives in the module doc now.

Co-Authored-By: Claude <noreply@anthropic.com>
@dovvnloading
dovvnloading merged commit 54b37b4 into main Sep 1, 2026
4 checks passed
@dovvnloading
dovvnloading deleted the ux/node-card-controls branch September 1, 2026 16:16
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant