mirror of
https://github.com/Comfy-Org/ComfyUI_frontend.git
synced 2026-05-22 21:38:52 +00:00
## Summary Migrate the default combo widget select from the PrimeVue `SelectPlus` wrapper to a Reka `Combobox` implementation while preserving the existing Comfy combo widget contract and the node-canvas dropdown behavior. ## Changes - **What**: Rewrites `WidgetSelectDefault.vue` on top of Reka `ComboboxRoot`, `ComboboxTrigger`, `ComboboxInput`, `ComboboxContent`, and `ComboboxItem`. - **What**: Preserves the default combo widget surface: `v-model`, `widget` prop, `aria-label` from the widget name/label, `data-capture-wheel`, disabled state, placeholder/filter placeholder, default slot controls, invalid current value display, array values, dynamic/factory values, and `getOptionLabel` fallback behavior. - **What**: Keeps dynamic `values` compatibility by refreshing function-backed options when the dropdown opens, without re-evaluating the factory on every search keystroke. - **What**: Deletes the now-unused PrimeVue `SelectPlus.vue` wrapper and removes the PrimeVue test plugin/stub path from the default widget select tests. - **What**: Updates App Mode dropdown clipping coverage and combo-widget browser coverage to target the new Reka overlay/viewport structure. - **Breaking**: No breaking change is intended for the documented Comfy combo widget contract. This migration does not preserve incidental PrimeVue `Select` prop pass-through from `widget.options`; that was a side effect of wrapping PrimeVue rather than a stable widget API. - **Dependencies**: No new dependencies. ## Review Focus ### Compatibility choices The goal of this PR is a migration PR, not a broad behavior redesign. The new implementation keeps the Comfy-specific combo contract rather than attempting to emulate PrimeVue internals. In particular: - `values` still accepts arrays and functions, and function values are re-read on open to support dynamic/custom node option sources. - `getOptionLabel(value) || value` is intentionally preserved to match the sibling dropdown path and avoid turning an empty-string label into a blank rendered option. - Invalid/current values that are not present in the option list are still rendered in the trigger instead of disappearing. - `WidgetWithControl` continues to render its default slot in the control area, with trigger text truncation preserved. - App Mode `OverlayAppendToKey='body'` continues to map to a body portal to avoid panel clipping. ### Visual alignment and screenshot updates The previous PrimeVue implementation passed `size="small"`, which injected internal `.p-select-sm .p-select-label` styling. That internal PrimeVue style used its own small-select font size and padding, overriding the surrounding widget sizing intent and making the select trigger subtly taller with slightly larger text than nearby inline node widget controls. The Reka implementation intentionally keeps the normal widget styling path instead of recreating that PrimeVue-specific internal override. This means the trigger follows the same inline widget sizing direction as neighboring controls rather than preserving the incidental PrimeVue height/text-size delta. Because this is an expected visual difference from the migration, the affected E2E screenshots should be recaptured instead of treating the old PrimeVue select height as the target. ### Scrollbar and focus behavior Reka provides the combobox/listbox semantics we want, including search, arrow navigation, highlighted items, and Enter selection. The tricky part is the canvas dropdown scrollbar behavior. The native Reka viewport path hides/owns scrollbar behavior in a way that made it hard to preserve the previous widget dropdown affordances, especially visible scrollbars and mouse wheel capture over the node canvas. To keep the previous behavior, this PR renders a dedicated scrollable viewport inside `ComboboxContent` with the project scrollbar utilities (`scrollbar-thin`, stable gutter, transparent track). That preserves visible scroll affordance and allows wheel events over the dropdown to scroll the list instead of zooming the canvas. There was one Reka interaction to account for: pressing the native scrollbar can be treated as a focus-outside event from the search input, which previously closed the dropdown on mouse down or caused subsequent wheel events to leak back to the canvas. The new `useRestoreFocusOnViewportPointer` composable handles only that short pointer gesture: - viewport pointerdown marks a short-lived scrollbar/viewport interaction, - the next focus-outside event is prevented only if the search input can be restored, - the guard is cleared by `pointerup`, `pointercancel`, and a timeout so normal outside clicks still close the dropdown. ### Tests and regression coverage Unit coverage was updated around the new Reka implementation: - option sources from arrays and functions, - dynamic values refreshed on open but not on each search keystroke, - selection updates and blank/undefined Reka emissions being ignored, - search filtering and Reka keyboard selection behavior, - disabled state, invalid current values, `getOptionLabel`, empty results status, and WidgetWithControl slot preservation, - composable coverage for pointerup, pointercancel, repeated pointerdown listener cleanup, and no-input/no-op behavior. Browser regression coverage now checks the canvas-specific interaction surface: - opening and selecting default combo widget options, - wheel over the dropdown scrolls the list instead of zooming the canvas, - pressing the scrollbar does not close the dropdown, - wheel capture still works after pressing the scrollbar, - opening another node widget closes the previous dropdown, - switching between node widgets preserves dropdown scroll capture, - serialize/reload retains selected combo values. ## Screenshots (if applicable) New <img width="527" height="753" alt="스크린샷 2026-05-18 오전 1 36 27" src="https://github.com/user-attachments/assets/2293d510-6965-4b84-9b12-b8528f8a734f" /> Old <img width="496" height="473" alt="스크린샷 2026-05-18 오전 1 35 57" src="https://github.com/user-attachments/assets/47c0e28a-27df-44a6-81a8-14fcc1f3bd8f" /> Reka Supports Auto highlight top item on search (Search -> Enter -> Select 👍) https://github.com/user-attachments/assets/9d633dfc-c23a-4e7a-8d39-b044c219f1f3 The default combo widget trigger has a small intentional visual delta from the old PrimeVue path because the Reka implementation does not recreate PrimeVue's internal `size="small"` label override. https://github.com/user-attachments/assets/a9053a14-e39e-4d5e-a846-dcf9aeb0caed ## Validation - `pnpm format` - `pnpm lint` (passes; existing warning-only lint output remains in unrelated tests) - `pnpm typecheck` - `pnpm typecheck:browser` - `pnpm test:unit` - `PLAYWRIGHT_LOCAL=1 PLAYWRIGHT_TEST_URL=http://127.0.0.1:5174 pnpm exec playwright test browser_tests/tests/vueNodes/widgets/combo/comboWidget.spec.ts --project=chromium` ┆Issue is synchronized with this [Notion page](https://www.notion.so/PR-12288-refactor-migrate-default-combo-widget-select-to-Reka-3616d73d365081fd8742c038a7dc7851) by [Unito](https://www.unito.io) --------- Co-authored-by: GitHub Action <action@github.com> Co-authored-by: github-actions <github-actions@github.com>