Skip to content

feat(ui): add form controls for webview parameter forms - #1101

Open
EhabY wants to merge 6 commits into
mainfrom
feat/ui-form-controls
Open

feat(ui): add form controls for webview parameter forms#1101
EhabY wants to merge 6 commits into
mainfrom
feat/ui-form-controls

Conversation

@EhabY

@EhabY EhabY commented Aug 28, 2026

Copy link
Copy Markdown
Collaborator

Adds the form-control vocabulary packages/ui needs for the #972 dynamic-parameter webview form: Input (text / number / password with reveal toggle), Textarea, Checkbox, Select (Radix), and Field/Label.

Design principle

Render like VS Code, not like the dashboard. VS Code's settings editor covers every configuration shape with text fields, number fields, checkboxes, and dropdowns, so the library ships exactly that vocabulary and the future form layer maps the richer dashboard form_types onto it:

form_type Rendered with
input (+ mask) Input (text / number / password + reveal)
textarea Textarea
dropdown, radio Select
checkbox, switch Checkbox
slider Input type="number" with min/max
multi-select Stacked Checkboxes in a Field (composition)
tag-select Input, comma-separated (form-layer split)

No Switch, Slider, RadioGroup, or MultiSelect widgets: VS Code has none, and every shipped control has a direct @vscode-elements parity reference, so the "Known gaps" list doesn't grow.

Implementation notes

  • Controlled-only APIs following the SearchInput precedent (value + onChange(next)); Select keeps Radix naming and flat compound exports like DropdownMenu.
  • New tokens: --ui-checkbox-*, --ui-dropdown-*, and --ui-list-focus-* (quick-input list colors, matching native selectBoxStyles); all with fallback chains incl. high contrast.
  • The select list renders without animation, like the native dropdown, which also keeps Pixel snapshots stable.
  • @radix-ui/react-select added via the workspace catalog (catalogMode: strict).
  • One parity row and one test file per component; one commit per component.

Verification

  • pnpm typecheck, pnpm lint, pnpm format:check
  • pnpm test:webview (40 files, 339 tests)
  • pnpm build, Storybook build
  • Pixel snapshots in all four themes (CI)
  • Side-by-side eyeball against native VS Code
Implementation plan

Why

Issue #972's dynamic-parameter flow returns server-evaluated parameters with form_types the QuickPick prompter cannot render reactively; a webview form built from packages/ui is required. The package has the full quality pipeline (tokens, four-theme Pixel snapshots, parity stories, webview tests, isolation lint) but had no form controls — only SearchInput and menu items.

Scope — five components

Component Approach New dep
Input Native <input>; SearchInput precedent; type passthrough incl. number (min/max) and password with reveal toggle
Textarea Native <textarea>, same tokens, vertical resize
Checkbox Native input painted with --vscode-checkbox-* geometry, codicon check; children as label
Select Radix react-select; flat compound exports matching the DropdownMenu* convention; portal on .ui-overlay; option rows support a description slot @radix-ui/react-select
Field + Label One directory, two exports: Label (htmlFor + children), thin Field (label + control + description/error slot)

Deferred to the #972 form layer: form_type mapping, diagnostics, immutable/ephemeral badges, JSON list(string) encoding, debounce, WebSocket session, IPC, panel provider.

Extraction-readiness (future standalone repo)

No @repo/* imports (lint-enforced), react peer dep, colocated stories/parity, --ui-*-only component CSS, public root exports as the boundary, per-component test files so tests move wholesale at extraction time.

Decisions

  1. Select engine — Radix react-select (established practice; native <select> + appearance: base-select considered and rejected for Storybook portability).
  2. VS Code-like rendering — no Switch/Slider/RadioGroup/MultiSelect/TagInput components; form_types map per the table above.
  3. Test placement — repo-root test/webview/ui/ per AGENTS.md; per-file layout keeps a future move into the package mechanical.

Note

This PR was generated by Coder Agents on behalf of @EhabY.

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