Skip to content

Conversation

@DrJKL
Copy link
Contributor

@DrJKL DrJKL commented Dec 19, 2025

Summary

Automated initial change, cleaned up manually.

Please check the screenshot changes.

Includes a11y updates to icon buttons.

Doesn't hit the buttons in Desktop.

┆Issue is synchronized with this Notion page by Unito

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Dec 19, 2025

Important

Review skipped

Review was skipped due to path filters

⛔ Files ignored due to path filters (10)
  • browser_tests/tests/vueNodes/groups/groups.spec.ts-snapshots/vue-groups-create-group-chromium-linux.png is excluded by !**/*.png
  • browser_tests/tests/vueNodes/groups/groups.spec.ts-snapshots/vue-groups-fit-to-contents-chromium-linux.png is excluded by !**/*.png
  • browser_tests/tests/vueNodes/interactions/links/linkInteraction.spec.ts-snapshots/vue-node-dragging-link-chromium-linux.png is excluded by !**/*.png
  • browser_tests/tests/vueNodes/interactions/links/linkInteraction.spec.ts-snapshots/vue-node-input-drag-ctrl-alt-chromium-linux.png is excluded by !**/*.png
  • browser_tests/tests/vueNodes/interactions/links/linkInteraction.spec.ts-snapshots/vue-node-input-drag-reuses-origin-chromium-linux.png is excluded by !**/*.png
  • browser_tests/tests/vueNodes/interactions/links/linkInteraction.spec.ts-snapshots/vue-node-reroute-input-drag-chromium-linux.png is excluded by !**/*.png
  • browser_tests/tests/vueNodes/interactions/links/linkInteraction.spec.ts-snapshots/vue-node-reroute-output-shift-drag-chromium-linux.png is excluded by !**/*.png
  • browser_tests/tests/vueNodes/interactions/links/linkInteraction.spec.ts-snapshots/vue-node-shift-output-multi-link-chromium-linux.png is excluded by !**/*.png
  • browser_tests/tests/vueNodes/interactions/links/linkInteraction.spec.ts-snapshots/vue-node-snap-to-node-chromium-linux.png is excluded by !**/*.png
  • browser_tests/tests/vueNodes/interactions/links/linkInteraction.spec.ts-snapshots/vue-node-snap-to-slot-chromium-linux.png is excluded by !**/*.png

CodeRabbit blocks several paths by default. You can override this behavior by explicitly including those paths in the path filters. For example, including **/dist/** will override the default block on the dist directory, by removing the pattern from both the lists.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

📝 Walkthrough

Walkthrough

Replaced PrimeVue Button usages with a local slot/variant-based Button across many components; added loading/disabled props and a destructive-textonly variant; updated component imports/usages, button sizes, ARIA labels; and adjusted tests/fixtures to use role/text and scoped dialog locators.

Changes

Cohort / File(s) Summary
Test locators & fixtures
browser_tests/fixtures/ComfyPage.ts, browser_tests/fixtures/components/ComfyNodeSearchBox.ts, browser_tests/tests/dialog.spec.ts, browser_tests/tests/nodeHelp.spec.ts, browser_tests/tests/sidebar/nodeLibrary.spec.ts
Switched element queries from label-based to text/role-based selectors and added scoped dialog root locators; updated a few DOM selectors used by tests.
Core Button & variants
src/components/ui/button/Button.vue, src/components/ui/button/button.variants.ts
Added loading and disabled props with spinner/slot render behavior in Button.vue; added destructive-textonly variant and exposed it in story variants.
Global Button migration
src/components/..., src/platform/... (many files; examples: src/components/topbar/**, src/components/sidebar/**, src/components/dialog/**, src/components/load3d/**, src/components/graph/**)
Replaced import Button from 'primevue/button' with import Button from '@/components/ui/button/Button.vue' across many files; migrated from prop-based API (label/icon/severity/text/old sizes) to slot-based content plus variant/size; adjusted size tokens (e.g., smallsm) and added aria-labels.
Dialog & signin flows
src/components/dialog/content/*.vue, src/components/dialog/content/signin/*.vue
Converted dialog action buttons (Save/Submit/Back/Confirm/Cancel/etc.) to slot-based labels and variant props; updated tests to locate buttons by text/role or type attribute.
Graph, selection toolbox & controls
src/components/graph/**, src/components/load3d/**
Migrated many icon/action buttons to new Button API: inline <i> icons, variant-driven styling, size adjustments, added aria-labels; some handler declarations normalized to function declarations.
Sidebar / Tabs / Topbar / Panels
src/components/sidebar/**, src/components/sidebar/tabs/**, src/components/topbar/**, src/components/bottomPanel/**, src/components/rightSidePanel/**
Updated toolbar/action buttons to use local Button, moved icons/labels into slots, added accessibility attributes and responsive label logic (e.g., ActionBarButtons).
Cloud onboarding & subscription UI
src/platform/cloud/onboarding/**, src/platform/cloud/subscription/components/**
Replaced imports/usages with local Button.vue, changed severity→variant, moved labels into slots; updated SubscribeButton prop sizes (sm/lg) and aligned tests/stubs to new Button API.
Tests & stubs
tests-ui/tests/platform/cloud/subscription/components/SubscriptionPanel.test.ts, tests-ui/tests/platform/cloud/subscription/components/PricingTable.test.ts
Simplified test Button stubs to slot-based template and reduced props; some tests now register the real Button component; a couple of describe blocks were skipped pending migration.
Localization
src/locales/en/main.json
Added two translation keys: g.settings.scrollLeft and g.settings.scrollRight.

Possibly related PRs


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions
Copy link

github-actions bot commented Dec 19, 2025

🎨 Storybook Build Status

Build completed successfully!

⏰ Completed at: 12/29/2025, 06:32:04 PM UTC

🔗 Links


🎉 Your Storybook is ready for review!

@github-actions
Copy link

github-actions bot commented Dec 19, 2025

🎭 Playwright Test Results

🕵🏻 No test results found

⏰ Completed at: 12/29/2025, 06:31:54 PM UTC

📊 Test Reports by Browser

  • chromium: Deployment failed
  • chromium-2x: Deployment failed
  • chromium-0.5x: Deployment failed
  • mobile-chrome: Deployment failed

🎉 Click on the links above to view detailed test results for each browser configuration.

@github-actions
Copy link

github-actions bot commented Dec 19, 2025

Bundle Size Report

Summary

  • Raw size: 17.3 MB baseline 17.3 MB — 🔴 +24.5 kB
  • Gzip: 3.54 MB baseline 3.53 MB — 🔴 +2.44 kB
  • Brotli: 2.7 MB baseline 2.7 MB — 🔴 +1.19 kB
  • Bundles: 98 current • 98 baseline • 55 added / 55 removed

Category Glance
App Entry Points 🔴 +14.3 kB (3.2 MB) · Panels & Settings 🔴 +3.86 kB (300 kB) · Graph Workspace 🔴 +3.1 kB (998 kB) · UI Components 🔴 +2.65 kB (199 kB) · Other 🔴 +518 B (3.47 MB) · Views & Navigation 🔴 +85 B (6.63 kB) · + 3 more

Per-category breakdown
App Entry Points — 3.2 MB (baseline 3.19 MB) • 🔴 +14.3 kB

Main entry bundles and manifests

File Before After Δ Raw Δ Gzip Δ Brotli
assets/index-DtHaAcxg.js (new) 3.01 MB 🔴 +3.01 MB 🔴 +633 kB 🔴 +481 kB
assets/index-CvorPY1L.js (removed) 3 MB 🟢 -3 MB 🟢 -632 kB 🟢 -481 kB
assets/index-BgDRQuno.js (removed) 193 kB 🟢 -193 kB 🟢 -42 kB 🟢 -35 kB
assets/index-DiZZq3yw.js (new) 193 kB 🔴 +193 kB 🔴 +42 kB 🔴 +35 kB
assets/index-B0FiExit.js (new) 345 B 🔴 +345 B 🔴 +243 B 🔴 +228 B
assets/index-STxi41Aq.js (removed) 345 B 🟢 -345 B 🟢 -246 B 🟢 -239 B

Status: 3 added / 3 removed

Graph Workspace — 998 kB (baseline 995 kB) • 🔴 +3.1 kB

Graph editor runtime, canvas, workflow orchestration

File Before After Δ Raw Δ Gzip Δ Brotli
assets/GraphView-DVfViW-J.js (new) 998 kB 🔴 +998 kB 🔴 +194 kB 🔴 +148 kB
assets/GraphView-CgS56sex.js (removed) 995 kB 🟢 -995 kB 🟢 -194 kB 🟢 -148 kB

Status: 1 added / 1 removed

Views & Navigation — 6.63 kB (baseline 6.54 kB) • 🔴 +85 B

Top-level views, pages, and routed surfaces

File Before After Δ Raw Δ Gzip Δ Brotli
assets/UserSelectView-CZALpgbN.js (new) 6.63 kB 🔴 +6.63 kB 🔴 +2.15 kB 🔴 +1.9 kB
assets/UserSelectView-CMduJEpS.js (removed) 6.54 kB 🟢 -6.54 kB 🟢 -2.14 kB 🟢 -1.89 kB

Status: 1 added / 1 removed

Panels & Settings — 300 kB (baseline 296 kB) • 🔴 +3.86 kB

Configuration panels, inspectors, and settings screens

File Before After Δ Raw Δ Gzip Δ Brotli
assets/LegacyCreditsPanel-W_h3Pdip.js (new) 22.7 kB 🔴 +22.7 kB 🔴 +5.25 kB 🔴 +4.6 kB
assets/LegacyCreditsPanel-DTv-fsff.js (removed) 21.4 kB 🟢 -21.4 kB 🟢 -5.15 kB 🟢 -4.51 kB
assets/KeybindingPanel-BGRFbQtT.js (new) 14.8 kB 🔴 +14.8 kB 🔴 +3.57 kB 🔴 +3.12 kB
assets/KeybindingPanel-BAr8cUsD.js (removed) 13.6 kB 🟢 -13.6 kB 🟢 -3.42 kB 🟢 -3.01 kB
assets/ExtensionPanel-BXQIfDgl.js (new) 11.1 kB 🔴 +11.1 kB 🔴 +2.62 kB 🔴 +2.3 kB
assets/ExtensionPanel-NsCiuW6U.js (removed) 10.8 kB 🟢 -10.8 kB 🟢 -2.57 kB 🟢 -2.24 kB
assets/AboutPanel-ByCOzSVb.js (removed) 9.16 kB 🟢 -9.16 kB 🟢 -2.46 kB 🟢 -2.2 kB
assets/AboutPanel-DQKY3YWU.js (new) 9.16 kB 🔴 +9.16 kB 🔴 +2.46 kB 🔴 +2.2 kB
assets/ServerConfigPanel-CtcwnNRX.js (new) 7.51 kB 🔴 +7.51 kB 🔴 +2.04 kB 🔴 +1.81 kB
assets/ServerConfigPanel-CmfR2xQr.js (removed) 7.07 kB 🟢 -7.07 kB 🟢 -1.98 kB 🟢 -1.76 kB
assets/UserPanel-BZZ_7M7p.js (new) 6.88 kB 🔴 +6.88 kB 🔴 +1.79 kB 🔴 +1.57 kB
assets/UserPanel-D5du6HhC.js (removed) 6.23 kB 🟢 -6.23 kB 🟢 -1.72 kB 🟢 -1.5 kB
assets/settings-AN2JfZVQ.js 21.7 kB 21.7 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/settings-BhbWhsRg.js 101 B 101 B ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/settings-BIdKi-OT.js 26.2 kB 26.2 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/settings-Bu3OR-lX.js 24.6 kB 24.6 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/settings-ByL6gy5c.js 25.4 kB 25.4 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/settings-CjlRFMdL.js 32.8 kB 32.8 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/settings-DkGwvylK.js 26.9 kB 26.9 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/settings-Dyd027Dx.js 24.7 kB 24.7 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/settings-wwBxqLH5.js 21.3 kB 21.3 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/settings-xx2Yb6R2.js 23.8 kB 23.8 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B

Status: 6 added / 6 removed

UI Components — 199 kB (baseline 196 kB) • 🔴 +2.65 kB

Reusable component library chunks

File Before After Δ Raw Δ Gzip Δ Brotli
assets/LazyImage.vue_vue_type_script_setup_true_lang-BuF3mn96.js (removed) 59.9 kB 🟢 -59.9 kB 🟢 -12.4 kB 🟢 -10.8 kB
assets/LazyImage.vue_vue_type_script_setup_true_lang-TLLdIu5K.js (new) 59.9 kB 🔴 +59.9 kB 🔴 +12.4 kB 🔴 +10.8 kB
assets/Load3D.vue_vue_type_script_setup_true_lang-BUtrB1SP.js (new) 56.4 kB 🔴 +56.4 kB 🔴 +8.9 kB 🔴 +7.6 kB
assets/Load3D.vue_vue_type_script_setup_true_lang-B6bx6BEl.js (removed) 54.3 kB 🟢 -54.3 kB 🟢 -8.62 kB 🟢 -7.43 kB
assets/WidgetSelect.vue_vue_type_script_setup_true_lang-DDx4-uo9.js (new) 48.8 kB 🔴 +48.8 kB 🔴 +10.5 kB 🔴 +9.14 kB
assets/WidgetSelect.vue_vue_type_script_setup_true_lang-DtvUkdso.js (removed) 48.8 kB 🟢 -48.8 kB 🟢 -10.5 kB 🟢 -9.13 kB
assets/WidgetInputNumber.vue_vue_type_script_setup_true_lang-BMUvRoLX.js (new) 14.3 kB 🔴 +14.3 kB 🔴 +3.73 kB 🔴 +3.29 kB
assets/WidgetInputNumber.vue_vue_type_script_setup_true_lang-BNIOLQAk.js (removed) 14.3 kB 🟢 -14.3 kB 🟢 -3.74 kB 🟢 -3.29 kB
assets/ComfyQueueButton-Czo71VRM.js (new) 8.83 kB 🔴 +8.83 kB 🔴 +2.58 kB 🔴 +2.3 kB
assets/ComfyQueueButton-C0nNlKMW.js (removed) 8.45 kB 🟢 -8.45 kB 🟢 -2.46 kB 🟢 -2.2 kB
assets/WidgetWithControl.vue_vue_type_script_setup_true_lang-aXoZX6p8.js (new) 3.72 kB 🔴 +3.72 kB 🔴 +1.46 kB 🔴 +1.32 kB
assets/WidgetWithControl.vue_vue_type_script_setup_true_lang-DG1dAsz4.js (removed) 3.68 kB 🟢 -3.68 kB 🟢 -1.45 kB 🟢 -1.31 kB
assets/WidgetButton-DKcxnN_a.js (new) 2.21 kB 🔴 +2.21 kB 🔴 +996 B 🔴 +888 B
assets/WidgetLayoutField.vue_vue_type_script_setup_true_lang-CR6pnzPn.js (removed) 2.14 kB 🟢 -2.14 kB 🟢 -889 B 🟢 -769 B
assets/WidgetLayoutField.vue_vue_type_script_setup_true_lang-DPncE6dA.js (new) 2.14 kB 🔴 +2.14 kB 🔴 +889 B 🔴 +768 B
assets/WidgetButton-CD0L1KzN.js (removed) 2.04 kB 🟢 -2.04 kB 🟢 -927 B 🟢 -817 B
assets/UserAvatar.vue_vue_type_script_setup_true_lang-3ve79e_P.js (new) 1.34 kB 🔴 +1.34 kB 🔴 +686 B 🔴 +597 B
assets/UserAvatar.vue_vue_type_script_setup_true_lang-B6P2AFxg.js (removed) 1.34 kB 🟢 -1.34 kB 🟢 -687 B 🟢 -598 B
assets/MediaTitle.vue_vue_type_script_setup_true_lang-Ci1ghGxp.js (removed) 897 B 🟢 -897 B 🟢 -503 B 🟢 -435 B
assets/MediaTitle.vue_vue_type_script_setup_true_lang-y1DoUB1h.js (new) 897 B 🔴 +897 B 🔴 +502 B 🔴 +466 B

Status: 10 added / 10 removed

Data & Services — 12.5 kB (baseline 12.5 kB) • ⚪ 0 B

Stores, services, APIs, and repositories

File Before After Δ Raw Δ Gzip Δ Brotli
assets/keybindingService-aPYrNVSU.js (removed) 7.51 kB 🟢 -7.51 kB 🟢 -1.83 kB 🟢 -1.58 kB
assets/keybindingService-BC1m3POe.js (new) 7.51 kB 🔴 +7.51 kB 🔴 +1.83 kB 🔴 +1.57 kB
assets/serverConfigStore-ClbvVDb_.js (new) 2.83 kB 🔴 +2.83 kB 🔴 +908 B 🔴 +788 B
assets/serverConfigStore-CNSmwya1.js (removed) 2.83 kB 🟢 -2.83 kB 🟢 -902 B 🟢 -792 B
assets/audioService-C19J6tiN.js (new) 2.2 kB 🔴 +2.2 kB 🔴 +962 B 🔴 +825 B
assets/audioService-C4ee3b-O.js (removed) 2.2 kB 🟢 -2.2 kB 🟢 -961 B 🟢 -823 B

Status: 3 added / 3 removed

Utilities & Hooks — 1.41 kB (baseline 1.41 kB) • ⚪ 0 B

Helpers, composables, and utility bundles

File Before After Δ Raw Δ Gzip Δ Brotli
assets/audioUtils-CU0QJ2to.js (new) 1.41 kB 🔴 +1.41 kB 🔴 +649 B 🔴 +546 B
assets/audioUtils-CUt_Q9Dg.js (removed) 1.41 kB 🟢 -1.41 kB 🟢 -651 B 🟢 -551 B

Status: 1 added / 1 removed

Vendor & Third-Party — 9.1 MB (baseline 9.1 MB) • 🔴 +6 B

External libraries and shared vendor chunks

File Before After Δ Raw Δ Gzip Δ Brotli
assets/vendor-other-DdEHkzYa.js (new) 3.86 MB 🔴 +3.86 MB 🔴 +839 kB 🔴 +672 kB
assets/vendor-other-BKKxyZwz.js (removed) 3.86 MB 🟢 -3.86 MB 🟢 -839 kB 🟢 -672 kB
assets/vendor-primevue-Btu8cl1B.js (removed) 1.95 MB 🟢 -1.95 MB 🟢 -334 kB 🟢 -201 kB
assets/vendor-primevue-DmDWdkDd.js (new) 1.95 MB 🔴 +1.95 MB 🔴 +334 kB 🔴 +201 kB
assets/vendor-chart-ByLwKL2Y.js (new) 452 kB 🔴 +452 kB 🔴 +99 kB 🔴 +81 kB
assets/vendor-chart-DOvov576.js (removed) 452 kB 🟢 -452 kB 🟢 -99 kB 🟢 -81 kB
assets/vendor-tiptap-B76LFN34.js (new) 232 kB 🔴 +232 kB 🔴 +45.7 kB 🔴 +37.7 kB
assets/vendor-tiptap-CUNFo3Ub.js (removed) 232 kB 🟢 -232 kB 🟢 -45.7 kB 🟢 -37.7 kB
assets/vendor-vue-BIRc7P93.js (new) 160 kB 🔴 +160 kB 🔴 +37.2 kB 🔴 +31.4 kB
assets/vendor-vue-BlzIh1pE.js (removed) 160 kB 🟢 -160 kB 🟢 -37.2 kB 🟢 -31.4 kB
assets/vendor-three-DYL0ZbEr.js 2.02 MB 2.02 MB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/vendor-xterm-BF8peZ5_.js 420 kB 420 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B

Status: 5 added / 5 removed

Other — 3.47 MB (baseline 3.46 MB) • 🔴 +518 B

Bundles that do not match a named category

File Before After Δ Raw Δ Gzip Δ Brotli
assets/SubscriptionRequiredDialogContent-Du2uA2ql.js (new) 28.5 kB 🔴 +28.5 kB 🔴 +6.3 kB 🔴 +5.46 kB
assets/SubscriptionRequiredDialogContent-Dl1KV5c6.js (removed) 28 kB 🟢 -28 kB 🟢 -6.27 kB 🟢 -5.44 kB
assets/WidgetRecordAudio-BQvuXieY.js (new) 20.4 kB 🔴 +20.4 kB 🔴 +5.24 kB 🔴 +4.63 kB
assets/WidgetRecordAudio-mK8pG_J8.js (removed) 20.4 kB 🟢 -20.4 kB 🟢 -5.23 kB 🟢 -4.63 kB
assets/AudioPreviewPlayer-CDgrNahI.js (new) 13.3 kB 🔴 +13.3 kB 🔴 +3.35 kB 🔴 +3 kB
assets/AudioPreviewPlayer-ju-8XcLM.js (removed) 13.3 kB 🟢 -13.3 kB 🟢 -3.35 kB 🟢 -2.99 kB
assets/ValueControlPopover-BKzcH72q.js (new) 5.49 kB 🔴 +5.49 kB 🔴 +1.71 kB 🔴 +1.52 kB
assets/ValueControlPopover-DIg_X8FB.js (removed) 5.49 kB 🟢 -5.49 kB 🟢 -1.7 kB 🟢 -1.52 kB
assets/WidgetGalleria-BdliFCh4.js (new) 4.1 kB 🔴 +4.1 kB 🔴 +1.45 kB 🔴 +1.3 kB
assets/WidgetGalleria-BOG6ZBkS.js (removed) 4.1 kB 🟢 -4.1 kB 🟢 -1.44 kB 🟢 -1.3 kB
assets/WidgetColorPicker-D927Vo08.js (removed) 3.41 kB 🟢 -3.41 kB 🟢 -1.38 kB 🟢 -1.23 kB
assets/WidgetColorPicker-DxwYZCoC.js (new) 3.41 kB 🔴 +3.41 kB 🔴 +1.38 kB 🔴 +1.23 kB
assets/WidgetImageCompare-Bvg3Od2A.js (new) 3.18 kB 🔴 +3.18 kB 🔴 +1.1 kB 🔴 +967 B
assets/WidgetImageCompare-C_Tqin9v.js (removed) 3.18 kB 🟢 -3.18 kB 🟢 -1.1 kB 🟢 -961 B
assets/WidgetTextarea-B2P0Z4zB.js (new) 3.08 kB 🔴 +3.08 kB 🔴 +1.22 kB 🔴 +1.07 kB
assets/WidgetTextarea-CKkjY5d_.js (removed) 3.08 kB 🟢 -3.08 kB 🟢 -1.21 kB 🟢 -1.07 kB
assets/WidgetMarkdown-BfaNBJeD.js (removed) 3.08 kB 🟢 -3.08 kB 🟢 -1.28 kB 🟢 -1.12 kB
assets/WidgetMarkdown-BsYJVTyk.js (new) 3.08 kB 🔴 +3.08 kB 🔴 +1.28 kB 🔴 +1.13 kB
assets/WidgetAudioUI-CPWwzdVW.js (new) 2.89 kB 🔴 +2.89 kB 🔴 +1.17 kB 🔴 +1.06 kB
assets/WidgetAudioUI-CxBRFlKm.js (removed) 2.89 kB 🟢 -2.89 kB 🟢 -1.17 kB 🟢 -1.06 kB
assets/MediaVideoTop-BqwS3WNi.js (removed) 2.65 kB 🟢 -2.65 kB 🟢 -1.02 kB 🟢 -868 B
assets/MediaVideoTop-DrDqLo2M.js (new) 2.65 kB 🔴 +2.65 kB 🔴 +1.02 kB 🔴 +868 B
assets/WidgetChart-B3VlzWCa.js (removed) 2.48 kB 🟢 -2.48 kB 🟢 -930 B 🟢 -820 B
assets/WidgetChart-DE0SfMVO.js (new) 2.48 kB 🔴 +2.48 kB 🔴 +932 B 🔴 +819 B
assets/WidgetInputText-Cm3wYpf8.js (removed) 1.99 kB 🟢 -1.99 kB 🟢 -916 B 🟢 -847 B
assets/WidgetInputText-dme7GcAT.js (new) 1.99 kB 🔴 +1.99 kB 🔴 +920 B 🔴 +860 B
assets/WidgetToggleSwitch-B1Sdfqyv.js (removed) 1.76 kB 🟢 -1.76 kB 🟢 -830 B 🟢 -736 B
assets/WidgetToggleSwitch-OMJVz83t.js (new) 1.76 kB 🔴 +1.76 kB 🔴 +835 B 🔴 +732 B
assets/MediaImageTop-BmT4ess7.js (new) 1.75 kB 🔴 +1.75 kB 🔴 +841 B 🔴 +718 B
assets/MediaImageTop-DTAowaFC.js (removed) 1.75 kB 🟢 -1.75 kB 🟢 -843 B 🟢 -722 B
assets/MediaImageBottom-BC-2HI_g.js (removed) 1.55 kB 🟢 -1.55 kB 🟢 -732 B 🟢 -636 B
assets/MediaImageBottom-BuJXJob8.js (new) 1.55 kB 🔴 +1.55 kB 🔴 +733 B 🔴 +638 B
assets/MediaAudioBottom-B84l_W4X.js (new) 1.51 kB 🔴 +1.51 kB 🔴 +733 B 🔴 +644 B
assets/MediaAudioBottom-CAtPBbIK.js (removed) 1.51 kB 🟢 -1.51 kB 🟢 -730 B 🟢 -642 B
assets/Media3DBottom-BO6Ft3e6.js (new) 1.5 kB 🔴 +1.5 kB 🔴 +732 B 🔴 +645 B
assets/Media3DBottom-C3Nasj2E.js (removed) 1.5 kB 🟢 -1.5 kB 🟢 -727 B 🟢 -645 B
assets/MediaVideoBottom-B5lR1q8U.js (new) 1.5 kB 🔴 +1.5 kB 🔴 +732 B 🔴 +644 B
assets/MediaVideoBottom-BQl2HlLG.js (removed) 1.5 kB 🟢 -1.5 kB 🟢 -729 B 🟢 -642 B
assets/Media3DTop-9huZkNiM.js (removed) 1.49 kB 🟢 -1.49 kB 🟢 -763 B 🟢 -653 B
assets/Media3DTop-C8EcbISM.js (new) 1.49 kB 🔴 +1.49 kB 🔴 +769 B 🔴 +652 B
assets/MediaAudioTop-Bu3Uau7e.js (removed) 1.46 kB 🟢 -1.46 kB 🟢 -741 B 🟢 -616 B
assets/MediaAudioTop-CgldzfMV.js (new) 1.46 kB 🔴 +1.46 kB 🔴 +738 B 🔴 +615 B
assets/WidgetSelect-B9yKnJ4x.js (new) 733 B 🔴 +733 B 🔴 +361 B 🔴 +304 B
assets/WidgetSelect-BGmsUwfK.js (removed) 733 B 🟢 -733 B 🟢 -360 B 🟢 -315 B
assets/WidgetInputNumber-CcPMm4tJ.js (new) 673 B 🔴 +673 B 🔴 +348 B 🔴 +292 B
assets/WidgetInputNumber-UKT-Xjb0.js (removed) 673 B 🟢 -673 B 🟢 -350 B 🟢 -296 B
assets/Load3D-CGgFC63-.js (new) 424 B 🔴 +424 B 🔴 +268 B 🔴 +223 B
assets/Load3D-DjiAqHCe.js (removed) 424 B 🟢 -424 B 🟢 -267 B 🟢 -263 B
assets/WidgetLegacy-BfL1p4_s.js (removed) 364 B 🟢 -364 B 🟢 -236 B 🟢 -195 B
assets/WidgetLegacy-BR6-Y4P4.js (new) 364 B 🔴 +364 B 🔴 +237 B 🔴 +194 B
assets/commands-bTEY9Mp6.js 13.8 kB 13.8 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/commands-BWp4HdfU.js 101 B 101 B ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/commands-CcfGaui5.js 14.4 kB 14.4 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/commands-CisfgZf5.js 13.7 kB 13.7 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/commands-CkU12Foh.js 13 kB 13 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/commands-CoH2DJa6.js 14.2 kB 14.2 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/commands-COSt-Bjx.js 14.9 kB 14.9 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/commands-DalfIW5f.js 15.9 kB 15.9 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/commands-DfTl0eCm.js 13.5 kB 13.5 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/commands-DwSJL865.js 13.7 kB 13.7 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-Bdc58rJq.js 97.1 kB 97.1 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-BRKE6VDs.js 91 kB 91 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-C9ZJBRdI.js 81.5 kB 81.5 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-CAL83XT3.js 84.6 kB 84.6 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-CHLLfvpG.js 82.4 kB 82.4 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-Cw9RZWRY.js 89 B 89 B ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-DDqR5EuX.js 71.3 kB 71.3 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-DLHyaEcz.js 92.1 kB 92.1 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-O7KfJeMO.js 79.9 kB 79.9 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-OzGsrlqJ.js 112 kB 112 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-aW9En70v.js 260 kB 260 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-BIckSVgU.js 273 kB 273 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-BiYpVi7D.js 263 kB 263 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-Bw_Jitw_.js 101 B 101 B ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-CCEXtYfM.js 243 kB 243 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-CvmVDWYd.js 323 kB 323 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-D_wreoPJ.js 267 kB 267 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-DIAYlJwM.js 246 kB 246 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-Dz-0ZIBN.js 297 kB 297 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-VZsNmhG7.js 264 kB 264 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/widgetPropFilter-BIbGSUAt.js 1.28 kB 1.28 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B

Status: 25 added / 25 removed

@github-actions
Copy link

🔧 Auto-fixes Applied

This PR has been automatically updated to fix linting and formatting issues.

⚠️ Important: Your local branch is now behind. Run git pull before making additional changes to avoid conflicts.

Changes made:

  • ESLint auto-fixes
  • Prettier formatting

@DrJKL DrJKL force-pushed the drjkl/button-the-fourth branch 3 times, most recently from 08661dc to db56a81 Compare December 20, 2025 05:16
@github-actions
Copy link

🔧 Auto-fixes Applied

This PR has been automatically updated to fix linting and formatting issues.

⚠️ Important: Your local branch is now behind. Run git pull before making additional changes to avoid conflicts.

Changes made:

  • ESLint auto-fixes
  • Prettier formatting

@DrJKL DrJKL force-pushed the drjkl/button-the-fourth branch 2 times, most recently from f8b8994 to 496636c Compare December 20, 2025 09:34
@DrJKL DrJKL added the New Browser Test Expectations New browser test screenshot should be set by github action label Dec 20, 2025
@github-actions
Copy link

Updating Playwright Expectations

@github-actions
Copy link

🔧 Auto-fixes Applied

This PR has been automatically updated to fix linting and formatting issues.

⚠️ Important: Your local branch is now behind. Run git pull before making additional changes to avoid conflicts.

Changes made:

  • ESLint auto-fixes
  • Prettier formatting

@github-actions github-actions bot removed the New Browser Test Expectations New browser test screenshot should be set by github action label Dec 20, 2025
@DrJKL DrJKL requested review from a team and shinshin86 as code owners December 21, 2025 00:48
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (8)
src/components/graph/selectionToolbox/ConvertToSubgraphButton.vue (1)

2-14: Add missing size="icon" prop for consistency.

The first button is missing the size="icon" prop that the second button has (line 22). Since both buttons are icon-only with no text content, they should have consistent size props for uniform styling.

🔎 Proposed fix
 <Button
   v-if="isUnpackVisible"
   v-tooltip.top="{
     value: $t('commands.Comfy_Graph_UnpackSubgraph.label'),
     showDelay: 1000
   }"
   variant="muted-textonly"
+  size="icon"
   :aria-label="$t('commands.Comfy_Graph_UnpackSubgraph.label')"
   data-testid="convert-to-subgraph-button"
   @click="() => commandStore.execute('Comfy.Graph.UnpackSubgraph')"
 >
   <i class="icon-[lucide--expand] size-4" />
 </Button>
src/components/graph/selectionToolbox/ExtensionCommandButton.vue (1)

2-17: Excellent migration! Icon-only button properly implements accessibility.

The Button migration correctly:

  • Uses the new variant-based API (muted-textonly)
  • Provides aria-label for the icon-only button using i18n
  • Moves icon rendering to slot content
  • Maintains tooltip functionality

The aria-label usage is appropriate here since this is an icon-only button without visible text.

Optional: Simplify class binding

The array wrapper around the class expression is redundant since there's only one element:

-    <i
-      :class="[
-        typeof command.icon === 'function' ? command.icon() : command.icon
-      ]"
-    />
+    <i
+      :class="typeof command.icon === 'function' ? command.icon() : command.icon"
+    />
src/components/load3d/controls/RecordingControls.vue (2)

24-30: Replace array class syntax with cn() utility.

The :class="[]" array syntax violates the coding guideline. Use the cn() utility for merging class names instead.

🔎 Proposed fix
-        <i
-          :class="[
-            'pi',
-            isRecording ? 'pi-circle-fill' : 'pi-video',
-            'text-lg text-white'
-          ]"
-        />
+        <i
+          :class="
+            cn('pi text-lg text-white', isRecording ? 'pi-circle-fill' : 'pi-video')
+          "
+        />

Based on coding guidelines.


111-125: Consider using Tailwind animation utilities or theme configuration.

The <style scoped> block with custom @keyframes violates the "Use Tailwind CSS only for styling (no custom CSS)" guideline. Consider either:

  1. Use Tailwind's built-in animate-pulse (though it pulses 0-1 opacity, not 0.5-1)
  2. Define the animation in your Tailwind theme configuration for reusability
  3. Use arbitrary animation values in Tailwind v4 if supported
💡 Option 1: Use built-in animate-pulse
           cn(
             'rounded-full',
-            isRecording && 'text-red-500 recording-button-blink'
+            isRecording && 'text-red-500 animate-pulse'
           )

Remove the <style scoped> block entirely.

Note: animate-pulse pulses opacity from 1 to 0 instead of 1 to 0.5, which creates a more pronounced effect.

Based on coding guidelines.

src/components/graph/selectionToolbox/NodeOptionsButton.vue (1)

20-22: Consider simplifying the event handler.

The handleClick wrapper adds no additional logic. You can directly bind toggleNodeOptions in the template:

🔎 Proposed simplification

In the template (line 10):

-    @click="handleClick"
+    @click="toggleNodeOptions"

In the script section:

 import Button from '@/components/ui/button/Button.vue'
 import { toggleNodeOptions } from '@/composables/graph/useMoreOptionsMenu'
-
-const handleClick = (event: Event) => {
-  toggleNodeOptions(event)
-}
src/components/load3d/controls/AnimationControls.vue (1)

6-16: Replace PrimeVue Select with custom Select component.

The Button migration is correctly implemented. However, this file still imports Select from PrimeVue (lines 18, 26), which should be replaced with the custom Select component from @/components/ui/select/Select.vue to align with the codebase migration away from PrimeVue components.

Regarding icons: PrimeIcons (pi-pause, pi-play) are the documented standard for ComfyUI. No migration to Lucide icons is occurring in the codebase.

src/components/load3d/controls/ExportControls.vue (2)

54-70: Prefer arrow functions in Composition API.

The conversion from arrow functions to traditional function declarations is unnecessary in <script setup>. Arrow functions are preferred in modern TypeScript and Composition API contexts where there's no this binding concern.

🔎 Suggested refactor to arrow functions
-function toggleExportFormats() {
+const toggleExportFormats = () => {
   showExportFormats.value = !showExportFormats.value
 }
 
-function exportModel(format: string) {
+const exportModel = (format: string) => {
   emit('exportModel', format)
 
   showExportFormats.value = false
 }
 
-function closeExportFormatsList(e: MouseEvent) {
+const closeExportFormatsList = (e: MouseEvent) => {
   const target = e.target as HTMLElement
 
   if (!target.closest('.show-export-formats')) {
     showExportFormats.value = false
   }
 }

72-78: Replace manual event listeners with VueUse onClickOutside.

The manual click-outside implementation can be replaced with VueUse's onClickOutside composable for cleaner, more declarative code.

🔎 Suggested refactor using VueUse

Remove the onMounted/onUnmounted blocks and replace with:

-import { onMounted, onUnmounted, ref } from 'vue'
+import { ref } from 'vue'
+import { onClickOutside } from '@vueuse/core'
 
 import Button from '@/components/ui/button/Button.vue'
+const exportFormatsRef = ref<HTMLElement>()
+
+onClickOutside(exportFormatsRef, () => {
+  showExportFormats.value = false
+})

Then add ref="exportFormatsRef" to the .show-export-formats div on line 3.

As per coding guidelines: Use existing VueUse composables instead of manually managing event listeners.

♻️ Duplicate comments (7)
src/components/sidebar/tabs/nodeLibrary/NodeTreeLeaf.vue (1)

38-53: Make bookmark button aria-label dynamic to reflect current state.

The bookmark button has a static aria-label that doesn't convey whether the action will add or remove the bookmark. Screen reader users need to know the button's current purpose. The aria-label should be conditional based on isBookmarked state.

Additionally, the i18n key icon.bookmark uses an unusual namespace—prefer g.addBookmark and g.removeBookmark for consistency with other keys like g.delete and g.edit.

🔎 Proposed fix with conditional aria-label
 <Button
   class="bookmark-button"
   variant="muted-textonly"
   size="icon-sm"
-  :aria-label="$t('icon.bookmark')"
+  :aria-label="isBookmarked ? $t('g.removeBookmark') : $t('g.addBookmark')"
   @click.stop="toggleBookmark"
 >
   <i
     :class="
       cn(
         isBookmarked ? 'pi pi-bookmark-fill' : 'pi pi-bookmark',
         'size-3.5'
       )
     "
   />
 </Button>

Note: Ensure g.addBookmark and g.removeBookmark keys exist in src/locales/en/main.json.

Based on coding guidelines: Icon-only buttons must have aria-labels that clearly describe their action, and the previous review feedback specifically requested conditional labels for the bookmark button.

src/components/sidebar/tabs/NodeLibrarySidebarTab.vue (1)

8-53: LGTM! Toolbar buttons properly migrated with accessibility.

All icon-only toolbar buttons now have appropriate aria-labels, use the local Button component with variant/size props, and render icons as inner content. The past review comments about missing aria-labels have been addressed.

src/components/sidebar/tabs/ModelLibrarySidebarTab.vue (1)

4-21: LGTM! Toolbar buttons properly migrated with accessibility.

Both icon-only buttons now have appropriate aria-labels. The past review comments about missing aria-labels have been addressed.

src/components/topbar/WorkflowTabs.vue (2)

7-17: LGTM! Left scroll button properly migrated with accessibility.

The icon-only scroll button now has an appropriate aria-label. The past review comment about the missing aria-label has been addressed.


44-54: LGTM! Right scroll button properly migrated with accessibility.

The icon-only scroll button now has an appropriate aria-label. The past review comment about the missing aria-label has been addressed.

src/components/topbar/WorkflowTab.vue (1)

19-27: LGTM! Close button properly migrated with accessibility.

The icon-only close button now has an appropriate aria-label. The past review comment about the missing aria-label has been addressed.

src/components/sidebar/tabs/workflows/WorkflowTreeLeaf.vue (1)

4-16: aria-label should reflect the bookmark state and action.

The icon-only bookmark button uses a static aria-label that doesn't convey the current state or the action that will be performed. Screen readers need to know whether clicking will add or remove a bookmark.

🔎 Proposed fix
     <Button
       variant="muted-textonly"
       size="icon-sm"
-      :aria-label="$t('icon.bookmark')"
+      :aria-label="
+        isBookmarked
+          ? $t('workflows.removeBookmark')
+          : $t('workflows.addBookmark')
+      "
       @click.stop="handleBookmarkClick"
     >

Note: You'll need to add workflows.addBookmark and workflows.removeBookmark keys to src/locales/en/main.json.

Based on learnings: Icon-only buttons require aria-label that describes the action.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

♻️ Duplicate comments (2)
src/platform/cloud/subscription/components/SubscriptionPanel.vue (2)

98-106: Add aria-label for accessibility on this icon-only refresh button.

This icon-only button lacks an accessible name. Screen readers cannot announce its purpose without one.

🔎 Proposed fix
                   <Button
                     variant="muted-textonly"
                     size="icon-sm"
                     class="absolute top-0.5 right-0"
                     :loading="isLoadingBalance"
+                    :aria-label="$t('g.refresh')"
                     @click="handleRefresh"
                   >
                     <i class="pi pi-sync text-text-secondary text-xs" />
                   </Button>

Based on learnings: aria-label should only be used for elements without visible labels, such as icon-only buttons.


164-173: Add aria-label for accessibility on this icon-only info button.

This icon-only question mark button lacks an accessible name. The tooltip provides visual context but isn't accessible to screen readers.

🔎 Proposed fix
                         <Button
                           v-tooltip="$t('subscription.prepaidCreditsInfo')"
                           variant="muted-textonly"
                           size="icon-sm"
                           class="h-4 w-4 shrink-0 rounded-full"
+                          :aria-label="$t('subscription.prepaidCreditsInfo')"
                         >
                           <i
                             class="pi pi-question-circle text-text-secondary text-xs"
                           />
                         </Button>

Based on learnings: aria-label should only be used for elements without visible labels, such as icon-only buttons.

📜 Review details

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 04f1b06 and 7bc460c.

📒 Files selected for processing (5)
  • browser_tests/tests/sidebar/nodeLibrary.spec.ts (4 hunks)
  • src/components/graph/selectionToolbox/ColorPickerButton.vue (2 hunks)
  • src/components/topbar/CurrentUserPopover.vue (2 hunks)
  • src/platform/cloud/subscription/components/SubscribeButton.vue (2 hunks)
  • src/platform/cloud/subscription/components/SubscriptionPanel.vue (5 hunks)
🧰 Additional context used
📓 Path-based instructions (13)
browser_tests/**/*.{e2e,spec}.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (browser_tests/CLAUDE.md)

browser_tests/**/*.{e2e,spec}.{ts,tsx,js,jsx}: Test user workflows in browser tests
Use Playwright fixtures for browser tests
Follow naming conventions for browser tests
Check assets/ directory for test data when writing tests
Prefer specific selectors in browser tests
Test across multiple viewports

Files:

  • browser_tests/tests/sidebar/nodeLibrary.spec.ts
browser_tests/**/*.spec.ts

📄 CodeRabbit inference engine (AGENTS.md)

browser_tests/**/*.spec.ts: E2E test files must use pattern browser_tests/**/*.spec.ts with Playwright
Do not use waitForTimeout in Playwright - use Locator actions and retrying assertions
Use Playwright tags like @mobile, @2x for relevant E2E tests - they are respected by config

Files:

  • browser_tests/tests/sidebar/nodeLibrary.spec.ts
src/**/*.vue

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

src/**/*.vue: Use the Vue 3 Composition API instead of the Options API when writing Vue components (exception: when overriding or extending PrimeVue components for compatibility)
Use setup() function for component logic
Utilize ref and reactive for reactive state
Implement computed properties with computed()
Use watch and watchEffect for side effects
Implement lifecycle hooks with onMounted, onUpdated, etc.
Utilize provide/inject for dependency injection
Use vue 3.5 style of default prop declaration
Use Tailwind CSS for styling
Implement proper props and emits definitions
Utilize Vue 3's Teleport component when needed
Use Suspense for async components
Follow Vue 3 style guide and naming conventions

src/**/*.vue: Vue 3 SFCs must use Composition API only - no Options API
Use <script setup lang="ts"> for component logic
Use Tailwind 4 utility classes for styling - avoid <style> blocks
Use cn() utility from @/utils/tailwindUtil to merge Tailwind class names - never use :class="[]" syntax
Never use the dark: Tailwind variant - use semantic values from style.css theme instead (e.g., bg-node-component-surface)
Use Vue 3.5+ TypeScript style default prop declaration with reactive destructuring - prefer useModel to prop/emit pairs, do not use withDefaults
Do not import Vue macros unnecessarily
Use vue-i18n in composition API for string literals - place translation entries in src/locales/en/main.json
Implement proper props and emits definitions in Vue components
Utilize Vue 3's Teleport component when needed
Use Suspense for async components
Avoid new usage of PrimeVue components

Files:

  • src/components/topbar/CurrentUserPopover.vue
  • src/platform/cloud/subscription/components/SubscriptionPanel.vue
  • src/components/graph/selectionToolbox/ColorPickerButton.vue
  • src/platform/cloud/subscription/components/SubscribeButton.vue
src/**/*.{vue,ts}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

src/**/*.{vue,ts}: Leverage VueUse functions for performance-enhancing styles
Implement proper error handling
Use vue-i18n in composition API for any string literals. Place new translation entries in src/locales/en/main.json

src/**/*.{vue,ts}: Avoid using ref and watch together - use computed instead if possible
Do not add ref if a prop would suffice; do not add computed if the ref/prop directly would work; use watch only when computed won't accomplish the goal
Leverage VueUse functions for performance-enhancing styles

Files:

  • src/components/topbar/CurrentUserPopover.vue
  • src/platform/cloud/subscription/components/SubscriptionPanel.vue
  • src/components/graph/selectionToolbox/ColorPickerButton.vue
  • src/platform/cloud/subscription/components/SubscribeButton.vue
src/**/*.{ts,tsx,vue}

📄 CodeRabbit inference engine (src/CLAUDE.md)

src/**/*.{ts,tsx,vue}: Sanitize HTML with DOMPurify to prevent XSS attacks
Avoid using @ts-expect-error; use proper TypeScript types instead
Use es-toolkit for utility functions instead of other utility libraries
Implement proper TypeScript types throughout the codebase

src/**/*.{ts,tsx,vue}: ESLint rules: Vue + TS rules, no floating promises, unused imports disallowed, i18n raw text restrictions in templates
Use es-toolkit for utility functions
Avoid mutable state - prefer immutability and assignment at point of declaration
Never use any type - use proper TypeScript types
Never use as any type assertions - fix the underlying type issue

Files:

  • src/components/topbar/CurrentUserPopover.vue
  • src/platform/cloud/subscription/components/SubscriptionPanel.vue
  • src/components/graph/selectionToolbox/ColorPickerButton.vue
  • src/platform/cloud/subscription/components/SubscribeButton.vue
src/**/{composables,components}/**/*.{ts,tsx,vue}

📄 CodeRabbit inference engine (src/CLAUDE.md)

Clean up subscriptions in state management to prevent memory leaks

Files:

  • src/components/topbar/CurrentUserPopover.vue
  • src/platform/cloud/subscription/components/SubscriptionPanel.vue
  • src/components/graph/selectionToolbox/ColorPickerButton.vue
  • src/platform/cloud/subscription/components/SubscribeButton.vue
src/**/*.{vue,ts,tsx}

📄 CodeRabbit inference engine (src/CLAUDE.md)

Follow Vue 3 composition API style guide

Files:

  • src/components/topbar/CurrentUserPopover.vue
  • src/platform/cloud/subscription/components/SubscriptionPanel.vue
  • src/components/graph/selectionToolbox/ColorPickerButton.vue
  • src/platform/cloud/subscription/components/SubscribeButton.vue
src/**/{components,composables}/**/*.{ts,tsx,vue}

📄 CodeRabbit inference engine (src/CLAUDE.md)

Use vue-i18n for ALL user-facing strings by adding them to src/locales/en/main.json

Files:

  • src/components/topbar/CurrentUserPopover.vue
  • src/platform/cloud/subscription/components/SubscriptionPanel.vue
  • src/components/graph/selectionToolbox/ColorPickerButton.vue
  • src/platform/cloud/subscription/components/SubscribeButton.vue
src/components/**/*.vue

📄 CodeRabbit inference engine (src/components/CLAUDE.md)

src/components/**/*.vue: Use setup() function in Vue 3 Composition API
Destructure props using Vue 3.5 style in Vue components
Use ref/reactive for state management in Vue 3 Composition API
Implement computed() for derived state in Vue 3 Composition API
Use provide/inject for dependency injection in Vue components
Prefer emit/@event-name for state changes over other communication patterns
Use defineExpose only for imperative operations (such as form.validate(), modal.open())
Replace PrimeVue Dropdown component with Select
Replace PrimeVue OverlayPanel component with Popover
Replace PrimeVue Calendar component with DatePicker
Replace PrimeVue InputSwitch component with ToggleSwitch
Replace PrimeVue Sidebar component with Drawer
Replace PrimeVue Chips component with AutoComplete with multiple enabled
Replace PrimeVue TabMenu component with Tabs without panels
Replace PrimeVue Steps component with Stepper without panels
Replace PrimeVue InlineMessage component with Message
Extract complex conditionals to computed properties
Implement cleanup for async operations in Vue components
Use lifecycle hooks: onMounted, onUpdated in Vue 3 Composition API
Use Teleport/Suspense when needed for component rendering
Define proper props and emits definitions in Vue components

Vue components must be named in PascalCase (e.g., MenuHamburger.vue)

Files:

  • src/components/topbar/CurrentUserPopover.vue
  • src/components/graph/selectionToolbox/ColorPickerButton.vue
src/components/**/*.{vue,css}

📄 CodeRabbit inference engine (src/components/CLAUDE.md)

src/components/**/*.{vue,css}: Use Tailwind CSS only for styling (no custom CSS)
Use the correct tokens from style.css in the design system package

Files:

  • src/components/topbar/CurrentUserPopover.vue
  • src/components/graph/selectionToolbox/ColorPickerButton.vue
src/components/**/*.{vue,ts,js}

📄 CodeRabbit inference engine (src/components/CLAUDE.md)

src/components/**/*.{vue,ts,js}: Use existing VueUse composables (such as useElementHover) instead of manually managing event listeners
Use useIntersectionObserver for visibility detection instead of custom scroll handlers
Use vue-i18n for ALL UI strings

Files:

  • src/components/topbar/CurrentUserPopover.vue
  • src/components/graph/selectionToolbox/ColorPickerButton.vue
src/**/*.{js,ts,tsx,vue}

📄 CodeRabbit inference engine (AGENTS.md)

Use TypeScript exclusively - no new JavaScript files

Files:

  • src/components/topbar/CurrentUserPopover.vue
  • src/platform/cloud/subscription/components/SubscriptionPanel.vue
  • src/components/graph/selectionToolbox/ColorPickerButton.vue
  • src/platform/cloud/subscription/components/SubscribeButton.vue
src/**/*.{ts,tsx,vue,js}

📄 CodeRabbit inference engine (AGENTS.md)

src/**/*.{ts,tsx,vue,js}: Indent with 2 spaces, use single quotes, no trailing semicolons, line width 80 - see .prettierrc
Sort and group imports by plugin, run pnpm format before committing

Files:

  • src/components/topbar/CurrentUserPopover.vue
  • src/platform/cloud/subscription/components/SubscriptionPanel.vue
  • src/components/graph/selectionToolbox/ColorPickerButton.vue
  • src/platform/cloud/subscription/components/SubscribeButton.vue
🧠 Learnings (41)
📓 Common learnings
Learnt from: christian-byrne
Repo: Comfy-Org/ComfyUI_frontend PR: 6300
File: src/platform/updates/components/WhatsNewPopup.vue:5-13
Timestamp: 2025-12-09T03:50:03.127Z
Learning: In the Comfy-Org/ComfyUI_frontend repository, when avoiding PrimeVue components, prefer using the repo's common button components from src/components/button/ (IconButton.vue, TextButton.vue, IconTextButton.vue) rather than plain HTML buttons. These components wrap PrimeVue with custom design system styling.
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7603
File: src/components/queue/QueueOverlayHeader.vue:49-59
Timestamp: 2025-12-18T21:15:54.349Z
Learning: For Vue components in Comfy-Org/ComfyUI_frontend: Do not suggest adding aria-label to buttons that already have visible text content (e.g., <span> elements with labels). The visible text automatically provides the accessible name. aria-label should only be used for elements without visible labels, such as icon-only buttons.
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Replace PrimeVue InputSwitch component with ToggleSwitch
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Replace PrimeVue InlineMessage component with Message
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Replace PrimeVue OverlayPanel component with Popover
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Replace PrimeVue Steps component with Stepper without panels
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Replace PrimeVue Dropdown component with Select
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Replace PrimeVue TabMenu component with Tabs without panels
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-17T01:01:03.609Z
Learning: Applies to src/**/*.vue : Avoid new usage of PrimeVue components
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Replace PrimeVue Sidebar component with Drawer
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Replace PrimeVue Calendar component with DatePicker
📚 Learning: 2025-11-24T19:47:22.909Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: browser_tests/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:22.909Z
Learning: Applies to browser_tests/**/*.{e2e,spec}.{ts,tsx,js,jsx} : Prefer specific selectors in browser tests

Applied to files:

  • browser_tests/tests/sidebar/nodeLibrary.spec.ts
📚 Learning: 2025-12-17T01:01:03.609Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-17T01:01:03.609Z
Learning: Applies to tests-ui/**/*.test.ts : Write tests for all changes, especially bug fixes to catch future regressions

Applied to files:

  • browser_tests/tests/sidebar/nodeLibrary.spec.ts
📚 Learning: 2025-12-17T01:01:03.609Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-17T01:01:03.609Z
Learning: Applies to tests-ui/**/*.test.ts : Aim for behavioral coverage of critical and new features

Applied to files:

  • browser_tests/tests/sidebar/nodeLibrary.spec.ts
📚 Learning: 2025-11-24T19:48:03.270Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: tests-ui/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:48:03.270Z
Learning: Applies to tests-ui/**/*.test.{js,ts,jsx,tsx} : Write tests for new features

Applied to files:

  • browser_tests/tests/sidebar/nodeLibrary.spec.ts
📚 Learning: 2025-12-10T03:09:19.636Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7303
File: src/components/topbar/CurrentUserPopover.test.ts:199-205
Timestamp: 2025-12-10T03:09:19.636Z
Learning: For test files in the Comfy-Org/ComfyUI_frontend repository: When writing tests, prefer selecting elements by accessible properties (text content, aria-label, role, accessible name) over data-testid attributes. This ensures tests verify actual user-facing behavior and accessibility compliance.

Applied to files:

  • browser_tests/tests/sidebar/nodeLibrary.spec.ts
📚 Learning: 2025-12-17T01:01:03.609Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-17T01:01:03.609Z
Learning: Applies to tests-ui/**/*.test.ts : Be parsimonious in testing - do not write redundant tests

Applied to files:

  • browser_tests/tests/sidebar/nodeLibrary.spec.ts
📚 Learning: 2025-11-24T19:47:22.909Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: browser_tests/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:22.909Z
Learning: Applies to browser_tests/**/*.{e2e,spec}.{ts,tsx,js,jsx} : Follow naming conventions for browser tests

Applied to files:

  • browser_tests/tests/sidebar/nodeLibrary.spec.ts
📚 Learning: 2025-11-24T19:48:03.270Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: tests-ui/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:48:03.270Z
Learning: Applies to tests-ui/**/*.test.{js,ts,jsx,tsx} : Follow existing test patterns in the codebase

Applied to files:

  • browser_tests/tests/sidebar/nodeLibrary.spec.ts
📚 Learning: 2025-11-24T19:47:22.909Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: browser_tests/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:22.909Z
Learning: Applies to browser_tests/**/*.{e2e,spec}.{ts,tsx,js,jsx} : Test user workflows in browser tests

Applied to files:

  • browser_tests/tests/sidebar/nodeLibrary.spec.ts
📚 Learning: 2025-12-17T01:01:03.609Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-17T01:01:03.609Z
Learning: Applies to browser_tests/**/*.spec.ts : Do not use waitForTimeout in Playwright - use Locator actions and retrying assertions

Applied to files:

  • browser_tests/tests/sidebar/nodeLibrary.spec.ts
📚 Learning: 2025-12-13T05:54:35.779Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7415
File: browser_tests/tests/mobileBaseline.spec.ts:17-22
Timestamp: 2025-12-13T05:54:35.779Z
Learning: In browser_tests tests for the Comfy-Org/ComfyUI_frontend repository, the `comfyPage.loadWorkflow()` method already handles all necessary synchronization and waiting. No additional `await comfyPage.nextFrame()` call is needed before taking screenshots after loading a workflow.

Applied to files:

  • browser_tests/tests/sidebar/nodeLibrary.spec.ts
📚 Learning: 2025-12-09T03:39:54.501Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7169
File: src/platform/remote/comfyui/jobs/jobTypes.ts:1-107
Timestamp: 2025-12-09T03:39:54.501Z
Learning: In the ComfyUI_frontend project, Zod is on v3.x. Do not suggest Zod v4 standalone validators (z.uuid, z.ulid, z.cuid2, z.nanoid) until an upgrade to Zod 4 is performed. When reviewing TypeScript files (e.g., src/platform/remote/comfyui/jobs/jobTypes.ts) validate against Zod 3 capabilities and avoid introducing v4-specific features; flag any proposal to upgrade or incorporate v4-only validators and propose staying with compatible 3.x patterns.

Applied to files:

  • browser_tests/tests/sidebar/nodeLibrary.spec.ts
📚 Learning: 2025-12-13T11:03:11.264Z
Learnt from: christian-byrne
Repo: Comfy-Org/ComfyUI_frontend PR: 7416
File: src/stores/imagePreviewStore.ts:5-7
Timestamp: 2025-12-13T11:03:11.264Z
Learning: In the ComfyUI_frontend repository, lint rules require keeping 'import type' statements separate from non-type imports, even if importing from the same module. Do not suggest consolidating them into a single import statement. Ensure type imports remain on their own line (import type { ... } from 'module') and regular imports stay on separate lines.

Applied to files:

  • browser_tests/tests/sidebar/nodeLibrary.spec.ts
📚 Learning: 2025-12-17T00:40:09.635Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7537
File: src/components/ui/button/Button.stories.ts:45-55
Timestamp: 2025-12-17T00:40:09.635Z
Learning: Prefer pure function declarations over function expressions (e.g., use function foo() { ... } instead of const foo = () => { ... }) for pure functions in the repository. Function declarations are more functional-leaning, offer better hoisting clarity, and can improve readability and tooling consistency. Apply this guideline across TypeScript files in Comfy-Org/ComfyUI_frontend, including story and UI component code, except where a function expression is semantically required (e.g., callbacks, higher-order functions with closures).

Applied to files:

  • browser_tests/tests/sidebar/nodeLibrary.spec.ts
📚 Learning: 2025-12-11T12:25:15.470Z
Learnt from: christian-byrne
Repo: Comfy-Org/ComfyUI_frontend PR: 7358
File: src/components/dialog/content/signin/SignUpForm.vue:45-54
Timestamp: 2025-12-11T12:25:15.470Z
Learning: This repository uses CI automation to format code (pnpm format). Do not include manual formatting suggestions in code reviews for Comfy-Org/ComfyUI_frontend. If formatting issues are detected, rely on the CI formatter or re-run pnpm format. Focus reviews on correctness, readability, performance, accessibility, and maintainability rather than style formatting.

Applied to files:

  • browser_tests/tests/sidebar/nodeLibrary.spec.ts
  • src/components/topbar/CurrentUserPopover.vue
  • src/platform/cloud/subscription/components/SubscriptionPanel.vue
  • src/components/graph/selectionToolbox/ColorPickerButton.vue
  • src/platform/cloud/subscription/components/SubscribeButton.vue
📚 Learning: 2025-12-13T05:34:15.488Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7415
File: browser_tests/tests/mobileBaseline.spec.ts:7-15
Timestamp: 2025-12-13T05:34:15.488Z
Learning: In Playwright tests for the ComfyUI frontend, the toPass() assertion uses incremental backoff during retries. When a test may involve async operations, increasing the timeout (e.g., to 5000 ms) can be sufficient instead of aggressively extending timeouts. Apply this understanding to tests under browser_tests/tests/; if not resolved, review the toPass() backoff behavior and ensure timeouts align with expected async completion without masking issues.

Applied to files:

  • browser_tests/tests/sidebar/nodeLibrary.spec.ts
📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Replace PrimeVue OverlayPanel component with Popover

Applied to files:

  • src/components/topbar/CurrentUserPopover.vue
  • src/platform/cloud/subscription/components/SubscriptionPanel.vue
  • src/components/graph/selectionToolbox/ColorPickerButton.vue
  • src/platform/cloud/subscription/components/SubscribeButton.vue
📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Replace PrimeVue InputSwitch component with ToggleSwitch

Applied to files:

  • src/components/topbar/CurrentUserPopover.vue
  • src/platform/cloud/subscription/components/SubscriptionPanel.vue
  • src/components/graph/selectionToolbox/ColorPickerButton.vue
  • src/platform/cloud/subscription/components/SubscribeButton.vue
📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Replace PrimeVue InlineMessage component with Message

Applied to files:

  • src/components/topbar/CurrentUserPopover.vue
  • src/platform/cloud/subscription/components/SubscriptionPanel.vue
  • src/components/graph/selectionToolbox/ColorPickerButton.vue
  • src/platform/cloud/subscription/components/SubscribeButton.vue
📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Replace PrimeVue Sidebar component with Drawer

Applied to files:

  • src/components/topbar/CurrentUserPopover.vue
  • src/components/graph/selectionToolbox/ColorPickerButton.vue
  • src/platform/cloud/subscription/components/SubscribeButton.vue
📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Replace PrimeVue Dropdown component with Select

Applied to files:

  • src/components/topbar/CurrentUserPopover.vue
  • src/components/graph/selectionToolbox/ColorPickerButton.vue
  • src/platform/cloud/subscription/components/SubscribeButton.vue
📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Replace PrimeVue TabMenu component with Tabs without panels

Applied to files:

  • src/components/topbar/CurrentUserPopover.vue
  • src/platform/cloud/subscription/components/SubscriptionPanel.vue
📚 Learning: 2025-12-09T03:49:52.828Z
Learnt from: christian-byrne
Repo: Comfy-Org/ComfyUI_frontend PR: 6300
File: src/platform/updates/components/WhatsNewPopup.vue:5-13
Timestamp: 2025-12-09T03:49:52.828Z
Learning: In Vue files across the ComfyUI_frontend repo, when a button is needed, prefer the repo's common button components from src/components/button/ (IconButton.vue, TextButton.vue, IconTextButton.vue) over plain HTML <button> elements. These components wrap PrimeVue with the project’s design system styling. Use only the common button components for consistency and theming, and import them from src/components/button/ as needed.

Applied to files:

  • src/components/topbar/CurrentUserPopover.vue
  • src/platform/cloud/subscription/components/SubscriptionPanel.vue
  • src/components/graph/selectionToolbox/ColorPickerButton.vue
  • src/platform/cloud/subscription/components/SubscribeButton.vue
📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Replace PrimeVue Calendar component with DatePicker

Applied to files:

  • src/components/topbar/CurrentUserPopover.vue
  • src/platform/cloud/subscription/components/SubscriptionPanel.vue
  • src/components/graph/selectionToolbox/ColorPickerButton.vue
📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Replace PrimeVue Steps component with Stepper without panels

Applied to files:

  • src/components/topbar/CurrentUserPopover.vue
  • src/platform/cloud/subscription/components/SubscriptionPanel.vue
  • src/components/graph/selectionToolbox/ColorPickerButton.vue
📚 Learning: 2025-12-17T01:01:03.609Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-17T01:01:03.609Z
Learning: Applies to src/**/*.vue : Avoid new usage of PrimeVue components

Applied to files:

  • src/components/topbar/CurrentUserPopover.vue
  • src/components/graph/selectionToolbox/ColorPickerButton.vue
📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Use setup() function in Vue 3 Composition API

Applied to files:

  • src/components/topbar/CurrentUserPopover.vue
  • src/components/graph/selectionToolbox/ColorPickerButton.vue
📚 Learning: 2025-12-09T21:40:12.361Z
Learnt from: benceruleanlu
Repo: Comfy-Org/ComfyUI_frontend PR: 7297
File: src/components/actionbar/ComfyActionbar.vue:33-43
Timestamp: 2025-12-09T21:40:12.361Z
Learning: In Vue single-file components, allow inline Tailwind CSS class strings for static classes and avoid extracting them into computed properties solely for readability. Prefer keeping static class names inline for simplicity and performance. For dynamic or conditional classes, use Vue bindings (e.g., :class) to compose classes.

Applies to all Vue files in the repository (e.g., src/**/*.vue) where Tailwind utilities are used for static styling.

Applied to files:

  • src/components/topbar/CurrentUserPopover.vue
  • src/platform/cloud/subscription/components/SubscriptionPanel.vue
  • src/components/graph/selectionToolbox/ColorPickerButton.vue
  • src/platform/cloud/subscription/components/SubscribeButton.vue
📚 Learning: 2025-12-16T22:26:49.463Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7537
File: src/components/ui/button/Button.vue:17-17
Timestamp: 2025-12-16T22:26:49.463Z
Learning: In Vue 3.5+ with <script setup>, when using defineProps<Props>() with partial destructuring (e.g., const { as = 'button', class: customClass = '' } = defineProps<Props>() ), props that are not destructured (e.g., variant, size) stay accessible by name in the template scope. This pattern is valid: you can destructure only a subset of props for convenience while referencing the remaining props directly in template expressions. Apply this guideline to Vue components across the codebase (all .vue files).

Applied to files:

  • src/components/topbar/CurrentUserPopover.vue
  • src/platform/cloud/subscription/components/SubscriptionPanel.vue
  • src/components/graph/selectionToolbox/ColorPickerButton.vue
  • src/platform/cloud/subscription/components/SubscribeButton.vue
📚 Learning: 2025-12-18T02:07:38.870Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7598
File: src/components/sidebar/tabs/AssetsSidebarTab.vue:131-131
Timestamp: 2025-12-18T02:07:38.870Z
Learning: Tailwind CSS v4 safe utilities (e.g., items-center-safe, justify-*-safe, place-*-safe) are allowed in Vue components under src/ and in story files. Do not flag these specific safe variants as invalid when reviewing code in src/**/*.vue or related stories.

Applied to files:

  • src/components/topbar/CurrentUserPopover.vue
  • src/platform/cloud/subscription/components/SubscriptionPanel.vue
  • src/components/graph/selectionToolbox/ColorPickerButton.vue
  • src/platform/cloud/subscription/components/SubscribeButton.vue
📚 Learning: 2025-12-18T21:15:46.862Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7603
File: src/components/queue/QueueOverlayHeader.vue:49-59
Timestamp: 2025-12-18T21:15:46.862Z
Learning: In the ComfyUI_frontend repository, for Vue components, do not add aria-label to buttons that have visible text content (e.g., buttons containing <span> text). The visible text provides the accessible name. Use aria-label only for elements without visible labels (e.g., icon-only buttons). If a button has no visible label, provide a clear aria-label or associate with an aria-labelledby describing its action.

Applied to files:

  • src/components/topbar/CurrentUserPopover.vue
  • src/platform/cloud/subscription/components/SubscriptionPanel.vue
  • src/components/graph/selectionToolbox/ColorPickerButton.vue
  • src/platform/cloud/subscription/components/SubscribeButton.vue
📚 Learning: 2025-12-21T01:06:02.786Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7649
File: src/components/graph/selectionToolbox/ColorPickerButton.vue:15-18
Timestamp: 2025-12-21T01:06:02.786Z
Learning: In Comfy-Org/ComfyUI_frontend, in Vue component files, when a filled icon is required (e.g., 'pi pi-circle-fill'), you may mix PrimeIcons with Lucide icons since Lucide lacks filled variants. This mixed usage is acceptable when one icon library does not provide an equivalent filled icon. Apply consistently across Vue components in the src directory where icons are used, and document the rationale when a mixed approach is chosen.

Applied to files:

  • src/components/topbar/CurrentUserPopover.vue
  • src/platform/cloud/subscription/components/SubscriptionPanel.vue
  • src/components/graph/selectionToolbox/ColorPickerButton.vue
  • src/platform/cloud/subscription/components/SubscribeButton.vue
📚 Learning: 2025-12-18T16:03:02.066Z
Learnt from: henrikvilhelmberglund
Repo: Comfy-Org/ComfyUI_frontend PR: 7617
File: src/components/actionbar/ComfyActionbar.vue:301-308
Timestamp: 2025-12-18T16:03:02.066Z
Learning: In the ComfyUI frontend queue system, useQueuePendingTaskCountStore().count indicates the number of tasks in the queue, where count = 1 means a single active/running task and count > 1 means there are pending tasks in addition to the active task. Therefore, in src/components/actionbar/ComfyActionbar.vue, enable the 'Clear Pending Tasks' button only when count > 1 to avoid clearing the currently running task. The active task should be canceled using the 'Cancel current run' button instead. This rule should be enforced via a conditional check on the queue count, with appropriate disabled/aria-disabled states for accessibility, and tests should verify behavior for count = 1 and count > 1.

Applied to files:

  • src/components/topbar/CurrentUserPopover.vue
  • src/components/graph/selectionToolbox/ColorPickerButton.vue
📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Replace PrimeVue Chips component with AutoComplete with multiple enabled

Applied to files:

  • src/components/graph/selectionToolbox/ColorPickerButton.vue
📚 Learning: 2025-12-17T01:01:03.609Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-17T01:01:03.609Z
Learning: Applies to src/**/*.vue : Use `<script setup lang="ts">` for component logic

Applied to files:

  • src/components/graph/selectionToolbox/ColorPickerButton.vue
📚 Learning: 2025-11-24T19:47:02.860Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T19:47:02.860Z
Learning: Applies to src/**/*.{vue,ts} : Leverage VueUse functions for performance-enhancing styles

Applied to files:

  • src/components/graph/selectionToolbox/ColorPickerButton.vue
📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Define proper props and emits definitions in Vue components

Applied to files:

  • src/platform/cloud/subscription/components/SubscribeButton.vue
📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Prefer emit/event-name for state changes over other communication patterns

Applied to files:

  • src/platform/cloud/subscription/components/SubscribeButton.vue
📚 Learning: 2025-12-17T01:01:03.609Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-17T01:01:03.609Z
Learning: Applies to src/**/*.vue : Use Vue 3.5+ TypeScript style default prop declaration with reactive destructuring - prefer `useModel` to prop/emit pairs, do not use `withDefaults`

Applied to files:

  • src/platform/cloud/subscription/components/SubscribeButton.vue
📚 Learning: 2025-12-17T01:01:03.609Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-17T01:01:03.609Z
Learning: Applies to src/**/*.{vue,ts} : Do not add `ref` if a prop would suffice; do not add `computed` if the ref/prop directly would work; use `watch` only when `computed` won't accomplish the goal

Applied to files:

  • src/platform/cloud/subscription/components/SubscribeButton.vue
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
  • GitHub Check: setup
  • GitHub Check: test
  • GitHub Check: lint-and-format
  • GitHub Check: collect
🔇 Additional comments (11)
src/platform/cloud/subscription/components/SubscribeButton.vue (1)

1-41: LGTM!

The migration to the local Button.vue component is well-implemented:

  • Uses Vue 3.5 style prop declaration with reactive destructuring and inline defaults
  • Correctly uses cn() utility for class merging
  • Slot-based content with i18n fallback follows the new Button API pattern
  • Avoids PrimeVue Button as per project guidelines
src/platform/cloud/subscription/components/SubscriptionPanel.vue (3)

55-74: LGTM!

Both buttons are correctly migrated with appropriate variants and slot-based content. The visible text provides the accessible name.


187-194: LGTM!

These buttons are correctly migrated to the new Button API:

  • Slot-based content with proper i18n usage
  • Buttons with visible text don't need additional aria-label attributes
  • Consistent use of variant="muted-textonly" for footer actions

Also applies to: 248-282


295-295: LGTM!

Import correctly updated to the local Button.vue component, aligning with the project's approach of avoiding direct PrimeVue component usage.

browser_tests/tests/sidebar/nodeLibrary.spec.ts (1)

103-103: Excellent selector improvement!

The change from getByLabel('New Folder') to getByRole('button', { name: 'New Folder' }) is more specific and semantic. This pattern correctly queries for a button by its accessible name, making the test more robust and aligned with accessibility best practices.

Based on learnings, prefer selecting by accessible properties (role, accessible name) over generic selectors.

src/components/topbar/CurrentUserPopover.vue (3)

146-146: LGTM! Correct migration to local Button component.

The import path change from PrimeVue Button to the local Button component aligns with the PR objectives and coding guidelines to avoid new PrimeVue component usage.


48-56: LGTM! Correct migration to slot-based Button API.

The Button usage correctly migrates to the new slot-based API:

  • severityvariant="secondary"
  • Size normalized to "sm"
  • Label text moved from prop to slot content with proper i18n

The visible text content provides the accessible name, so no aria-label is needed.


63-63: No issues found. The SubscribeButton component accepts size="sm" as a valid prop value.

src/components/graph/selectionToolbox/ColorPickerButton.vue (3)

9-10: LGTM! Button migration and accessibility improvement.

The migration from PrimeVue Button to the local Button.vue component is correctly implemented. The variant="muted-textonly" prop is appropriate for this icon-based button, and the aria-label binding is essential since the button contains only visual icons without visible text.


14-15: LGTM! Icon rendering correctly implemented.

The icon implementation appropriately uses PrimeIcons for the filled circle (pi-circle-fill) with dynamic color styling and Lucide for the chevron indicator. This mixed approach is justified since Lucide doesn't provide filled icon variants easily.

Based on learnings, this pattern is acceptable when one icon library lacks equivalent functionality.


50-50: LGTM! Import correctly updated.

The Button import has been properly updated to reference the local component at @/components/ui/button/Button.vue, completing the migration away from PrimeVue's Button component as intended by this PR.

Copy link
Contributor

@huchenlei huchenlei left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a link to issue or noiton why we need this change?

- Always use `import { cn } from '@/utils/tailwindUtil'`
- e.g. `<div :class="cn('text-node-component-header-icon', hasError && 'text-danger')" />`
- Use `cn()` inline in the template when feasible instead of creating a `computed` to hold the value
- NEVER use `!important` or the `!` important prefix for tailwind classes
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This change does not seem to correlated with the button change described in the summary. Consider split to a separate PR.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Makes sense 🙂
#7691

@DrJKL
Copy link
Contributor Author

DrJKL commented Dec 21, 2025

Is there a link to issue or noiton why we need this change?

Yep, sent it to you.

@christian-byrne christian-byrne added the claude-review Add to trigger a PR code review from Claude Code label Dec 22, 2025
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The "add new tab" plus icon seems to be in the incorrect location here

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

note: seems the color picker button was broken previously

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

note: the missing models dialog has a new design ready for dev - so the style here is not too important.


// Click the back button - use a more specific selector
const backButton = comfyPage.page.locator('button:has(.pi-arrow-left)')
await expect(backButton).toBeVisible()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

note: this can be removed because click already does a visibility check with retries.

})

describe('action buttons', () => {
// TODO: Re-enable when migrating to VTL so we can find by user visible content.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@coderabbitai make an issue to track this todo.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Create GitHub issue to track the TODO for re-enabling skipped tests

gh issue create \
  --title "Re-enable SubscriptionPanel action button tests when migrating to VTL" \
  --body "## Context

Tests in \`tests-ui/tests/platform/cloud/subscription/components/SubscriptionPanel.test.ts\` have been skipped pending migration to Vue Testing Library (VTL).

## Details

The \`action buttons\` and \`loading states\` test suites are currently using \`describe.skip\` because the current test setup cannot find buttons by user-visible content after the PrimeVue to custom Button component migration.

**Location:** \`tests-ui/tests/platform/cloud/subscription/components/SubscriptionPanel.test.ts:276\`

**TODO Comment:**
\`\`\`
// TODO: Re-enable when migrating to VTL so we can find by user visible content.
\`\`\`

## Tasks

- [ ] Migrate test setup to Vue Testing Library
- [ ] Update button selectors to find by user-visible content (text/labels)
- [ ] Re-enable the \`action buttons\` test suite
- [ ] Re-enable the \`loading states\` test suite
- [ ] Verify all tests pass with the new approach

## References

- PR: https://github.com/Comfy-Org/ComfyUI_frontend/pull/7649
- Comment: https://github.com/Comfy-Org/ComfyUI_frontend/pull/7649#discussion_r2640213960
- Requested by: @christian-byrne" \
  --assignee christian-byrne \
  --repo Comfy-Org/ComfyUI_frontend

Length of output: 57


@christian-byrne, I've created issue #7707 to track re-enabling the skipped SubscriptionPanel action button tests when migrating to Vue Testing Library.

Issue: #7707

The issue includes:

  • Context about why the tests were skipped (button selectors need user-visible content after PrimeVue migration)
  • Specific tasks for the migration
  • References to this PR and comment as backlinks

🧠 Learnings used
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: tests-ui/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:48:03.270Z
Learning: Applies to tests-ui/**/*.test.{js,ts,jsx,tsx} : Write tests for new features

Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: tests-ui/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:48:03.270Z
Learning: Check tests-ui/README.md for test guidelines

Learnt from: christian-byrne
Repo: Comfy-Org/ComfyUI_frontend PR: 6300
File: src/platform/updates/components/WhatsNewPopup.vue:5-13
Timestamp: 2025-12-09T03:50:03.127Z
Learning: In the Comfy-Org/ComfyUI_frontend repository, when avoiding PrimeVue components, prefer using the repo's common button components from src/components/button/ (IconButton.vue, TextButton.vue, IconTextButton.vue) rather than plain HTML buttons. These components wrap PrimeVue with custom design system styling.

Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7603
File: src/components/queue/QueueOverlayHeader.vue:49-59
Timestamp: 2025-12-18T21:15:54.349Z
Learning: For Vue components in Comfy-Org/ComfyUI_frontend: Do not suggest adding aria-label to buttons that already have visible text content (e.g., <span> elements with labels). The visible text automatically provides the accessible name. aria-label should only be used for elements without visible labels, such as icon-only buttons.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/components/sidebar/tabs/nodeLibrary/NodeHelpPage.vue (1)

23-32: Remove the duplicate PrimeVue Button import.

The old PrimeVue Button import on line 25 conflicts with the new local Button import on line 29, causing a duplicate identifier error that blocks compilation, linting, and Storybook builds.

🔎 Proposed fix
 <script setup lang="ts">
 import { whenever } from '@vueuse/core'
-import Button from 'primevue/button'
 import { computed } from 'vue'
 
 import NodeHelpContent from '@/components/node/NodeHelpContent.vue'
 import Button from '@/components/ui/button/Button.vue'
 import { useSelectionState } from '@/composables/graph/useSelectionState'
 import type { ComfyNodeDefImpl } from '@/stores/nodeDefStore'
 import { useNodeHelpStore } from '@/stores/workspace/nodeHelpStore'
♻️ Duplicate comments (2)
src/platform/cloud/subscription/components/SubscriptionPanel.vue (2)

98-106: Add aria-label for accessibility on this icon-only refresh button.

This icon-only button needs an accessible name for screen readers. Based on learnings, aria-label should be used for elements without visible labels.

🔎 Proposed fix
                   <Button
                     variant="muted-textonly"
                     size="icon-sm"
                     class="absolute top-0.5 right-0"
                     :loading="isLoadingBalance"
+                    :aria-label="$t('g.refresh')"
                     @click="handleRefresh"
                   >

164-173: Add aria-label for accessibility on this icon-only info button.

This icon-only question mark button needs an accessible name. The tooltip provides visual context but isn't accessible to screen readers.

🔎 Proposed fix
                         <Button
                           v-tooltip="$t('subscription.prepaidCreditsInfo')"
                           variant="muted-textonly"
                           size="icon-sm"
                           class="h-4 w-4 shrink-0 rounded-full"
+                          :aria-label="$t('subscription.prepaidCreditsInfo')"
                         >
📜 Review details

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between acda9de and ced57f1.

📒 Files selected for processing (9)
  • src/components/load3d/Load3DControls.vue
  • src/components/load3d/Load3dViewerContent.vue
  • src/components/load3d/controls/ModelControls.vue
  • src/components/sidebar/tabs/nodeLibrary/NodeHelpPage.vue
  • src/components/topbar/CurrentUserPopover.vue
  • src/locales/en/main.json
  • src/platform/cloud/subscription/components/PricingTable.vue
  • src/platform/cloud/subscription/components/SubscriptionPanel.vue
  • tests-ui/tests/platform/cloud/subscription/components/SubscriptionPanel.test.ts
🧰 Additional context used
📓 Path-based instructions (15)
src/**/*.vue

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

src/**/*.vue: Use the Vue 3 Composition API instead of the Options API when writing Vue components (exception: when overriding or extending PrimeVue components for compatibility)
Use setup() function for component logic
Utilize ref and reactive for reactive state
Implement computed properties with computed()
Use watch and watchEffect for side effects
Implement lifecycle hooks with onMounted, onUpdated, etc.
Utilize provide/inject for dependency injection
Use vue 3.5 style of default prop declaration
Use Tailwind CSS for styling
Implement proper props and emits definitions
Utilize Vue 3's Teleport component when needed
Use Suspense for async components
Follow Vue 3 style guide and naming conventions

Files:

  • src/components/load3d/Load3DControls.vue
  • src/components/load3d/controls/ModelControls.vue
  • src/platform/cloud/subscription/components/PricingTable.vue
  • src/components/sidebar/tabs/nodeLibrary/NodeHelpPage.vue
  • src/components/load3d/Load3dViewerContent.vue
  • src/components/topbar/CurrentUserPopover.vue
  • src/platform/cloud/subscription/components/SubscriptionPanel.vue
src/**/*.{vue,ts}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

src/**/*.{vue,ts}: Leverage VueUse functions for performance-enhancing styles
Implement proper error handling
Use vue-i18n in composition API for any string literals. Place new translation entries in src/locales/en/main.json

Files:

  • src/components/load3d/Load3DControls.vue
  • src/components/load3d/controls/ModelControls.vue
  • src/platform/cloud/subscription/components/PricingTable.vue
  • src/components/sidebar/tabs/nodeLibrary/NodeHelpPage.vue
  • src/components/load3d/Load3dViewerContent.vue
  • src/components/topbar/CurrentUserPopover.vue
  • src/platform/cloud/subscription/components/SubscriptionPanel.vue
src/**/*.{ts,tsx,vue}

📄 CodeRabbit inference engine (src/CLAUDE.md)

src/**/*.{ts,tsx,vue}: Sanitize HTML with DOMPurify to prevent XSS attacks
Avoid using @ts-expect-error; use proper TypeScript types instead
Use es-toolkit for utility functions instead of other utility libraries
Implement proper TypeScript types throughout the codebase

Files:

  • src/components/load3d/Load3DControls.vue
  • src/components/load3d/controls/ModelControls.vue
  • src/platform/cloud/subscription/components/PricingTable.vue
  • src/components/sidebar/tabs/nodeLibrary/NodeHelpPage.vue
  • src/components/load3d/Load3dViewerContent.vue
  • src/components/topbar/CurrentUserPopover.vue
  • src/platform/cloud/subscription/components/SubscriptionPanel.vue
src/**/{composables,components}/**/*.{ts,tsx,vue}

📄 CodeRabbit inference engine (src/CLAUDE.md)

Clean up subscriptions in state management to prevent memory leaks

Files:

  • src/components/load3d/Load3DControls.vue
  • src/components/load3d/controls/ModelControls.vue
  • src/platform/cloud/subscription/components/PricingTable.vue
  • src/components/sidebar/tabs/nodeLibrary/NodeHelpPage.vue
  • src/components/load3d/Load3dViewerContent.vue
  • src/components/topbar/CurrentUserPopover.vue
  • src/platform/cloud/subscription/components/SubscriptionPanel.vue
src/**/*.{vue,ts,tsx}

📄 CodeRabbit inference engine (src/CLAUDE.md)

Follow Vue 3 composition API style guide

Files:

  • src/components/load3d/Load3DControls.vue
  • src/components/load3d/controls/ModelControls.vue
  • src/platform/cloud/subscription/components/PricingTable.vue
  • src/components/sidebar/tabs/nodeLibrary/NodeHelpPage.vue
  • src/components/load3d/Load3dViewerContent.vue
  • src/components/topbar/CurrentUserPopover.vue
  • src/platform/cloud/subscription/components/SubscriptionPanel.vue
src/**/{components,composables}/**/*.{ts,tsx,vue}

📄 CodeRabbit inference engine (src/CLAUDE.md)

Use vue-i18n for ALL user-facing strings by adding them to src/locales/en/main.json

Files:

  • src/components/load3d/Load3DControls.vue
  • src/components/load3d/controls/ModelControls.vue
  • src/platform/cloud/subscription/components/PricingTable.vue
  • src/components/sidebar/tabs/nodeLibrary/NodeHelpPage.vue
  • src/components/load3d/Load3dViewerContent.vue
  • src/components/topbar/CurrentUserPopover.vue
  • src/platform/cloud/subscription/components/SubscriptionPanel.vue
src/components/**/*.vue

📄 CodeRabbit inference engine (src/components/CLAUDE.md)

src/components/**/*.vue: Use setup() function in Vue 3 Composition API
Destructure props using Vue 3.5 style in Vue components
Use ref/reactive for state management in Vue 3 Composition API
Implement computed() for derived state in Vue 3 Composition API
Use provide/inject for dependency injection in Vue components
Prefer emit/@event-name for state changes over other communication patterns
Use defineExpose only for imperative operations (such as form.validate(), modal.open())
Replace PrimeVue Dropdown component with Select
Replace PrimeVue OverlayPanel component with Popover
Replace PrimeVue Calendar component with DatePicker
Replace PrimeVue InputSwitch component with ToggleSwitch
Replace PrimeVue Sidebar component with Drawer
Replace PrimeVue Chips component with AutoComplete with multiple enabled
Replace PrimeVue TabMenu component with Tabs without panels
Replace PrimeVue Steps component with Stepper without panels
Replace PrimeVue InlineMessage component with Message
Extract complex conditionals to computed properties
Implement cleanup for async operations in Vue components
Use lifecycle hooks: onMounted, onUpdated in Vue 3 Composition API
Use Teleport/Suspense when needed for component rendering
Define proper props and emits definitions in Vue components

Files:

  • src/components/load3d/Load3DControls.vue
  • src/components/load3d/controls/ModelControls.vue
  • src/components/sidebar/tabs/nodeLibrary/NodeHelpPage.vue
  • src/components/load3d/Load3dViewerContent.vue
  • src/components/topbar/CurrentUserPopover.vue
src/components/**/*.{vue,css}

📄 CodeRabbit inference engine (src/components/CLAUDE.md)

src/components/**/*.{vue,css}: Use Tailwind CSS only for styling (no custom CSS)
Use the correct tokens from style.css in the design system package

Files:

  • src/components/load3d/Load3DControls.vue
  • src/components/load3d/controls/ModelControls.vue
  • src/components/sidebar/tabs/nodeLibrary/NodeHelpPage.vue
  • src/components/load3d/Load3dViewerContent.vue
  • src/components/topbar/CurrentUserPopover.vue
src/components/**/*.{vue,ts,js}

📄 CodeRabbit inference engine (src/components/CLAUDE.md)

src/components/**/*.{vue,ts,js}: Use existing VueUse composables (such as useElementHover) instead of manually managing event listeners
Use useIntersectionObserver for visibility detection instead of custom scroll handlers
Use vue-i18n for ALL UI strings

Files:

  • src/components/load3d/Load3DControls.vue
  • src/components/load3d/controls/ModelControls.vue
  • src/components/sidebar/tabs/nodeLibrary/NodeHelpPage.vue
  • src/components/load3d/Load3dViewerContent.vue
  • src/components/topbar/CurrentUserPopover.vue
**/*.vue

📄 CodeRabbit inference engine (AGENTS.md)

**/*.vue: Use Vue 3.5+ with TypeScript in .vue files, exclusively using Composition API with <script setup lang="ts"> syntax
Use Tailwind 4 for styling in Vue components; avoid <style> blocks
Name Vue components using PascalCase (e.g., MenuHamburger.vue)
Use Vue 3.5 TypeScript-style default prop declaration with reactive props destructuring; do not use withDefaults or runtime props declaration
Prefer computed() over ref with watch when deriving values
Prefer useModel over separately defining prop and emit for two-way binding
Use vue-i18n in composition API for string literals; place new translation entries in src/locales/en/main.json
Use cn() utility function from @/utils/tailwindUtil for merging Tailwind class names; do not use :class="[]" syntax
Do not use the dark: Tailwind variant; use semantic values from the style.css theme instead (e.g., bg-node-component-surface)
Do not use !important or the ! important prefix for Tailwind classes; find and correct interfering !important classes instead
Avoid new usage of PrimeVue components; use VueUse, shadcn/vue, or Reka UI instead
Leverage VueUse functions for performance-enhancing styles in Vue components
Implement proper props and emits definitions in Vue components
Utilize Vue 3's Teleport component when needed
Use Suspense for async components
Follow Vue 3 style guide and naming conventions

Files:

  • src/components/load3d/Load3DControls.vue
  • src/components/load3d/controls/ModelControls.vue
  • src/platform/cloud/subscription/components/PricingTable.vue
  • src/components/sidebar/tabs/nodeLibrary/NodeHelpPage.vue
  • src/components/load3d/Load3dViewerContent.vue
  • src/components/topbar/CurrentUserPopover.vue
  • src/platform/cloud/subscription/components/SubscriptionPanel.vue
**/*.{ts,tsx,vue}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{ts,tsx,vue}: Use TypeScript exclusively; do not write new JavaScript code
Use sorted and grouped imports organized by plugin/source
Enforce ESLint rules including Vue + TypeScript rules, disallow floating promises, disallow unused imports, and restrict i18n raw text in templates
Do not use any type or as any type assertions; fix the underlying type issue instead
Write code that is expressive and self-documenting; avoid redundant comments and clean as you go
Keep functions short and functional; minimize nesting and follow the arrow anti-pattern
Avoid mutable state; prefer immutability and assignment at point of declaration
Use function declarations instead of function expressions when possible
Use es-toolkit for utility functions
Implement proper error handling in code

Files:

  • src/components/load3d/Load3DControls.vue
  • src/components/load3d/controls/ModelControls.vue
  • src/platform/cloud/subscription/components/PricingTable.vue
  • tests-ui/tests/platform/cloud/subscription/components/SubscriptionPanel.test.ts
  • src/components/sidebar/tabs/nodeLibrary/NodeHelpPage.vue
  • src/components/load3d/Load3dViewerContent.vue
  • src/components/topbar/CurrentUserPopover.vue
  • src/platform/cloud/subscription/components/SubscriptionPanel.vue
**/*.{ts,tsx,vue,js,jsx,json,css}

📄 CodeRabbit inference engine (AGENTS.md)

Apply Prettier formatting with 2-space indentation, single quotes, no trailing semicolons, and 80-character line width

Files:

  • src/components/load3d/Load3DControls.vue
  • src/locales/en/main.json
  • src/components/load3d/controls/ModelControls.vue
  • src/platform/cloud/subscription/components/PricingTable.vue
  • tests-ui/tests/platform/cloud/subscription/components/SubscriptionPanel.test.ts
  • src/components/sidebar/tabs/nodeLibrary/NodeHelpPage.vue
  • src/components/load3d/Load3dViewerContent.vue
  • src/components/topbar/CurrentUserPopover.vue
  • src/platform/cloud/subscription/components/SubscriptionPanel.vue
tests-ui/**/*.test.{js,ts,jsx,tsx}

📄 CodeRabbit inference engine (tests-ui/CLAUDE.md)

tests-ui/**/*.test.{js,ts,jsx,tsx}: Write tests for new features
Follow existing test patterns in the codebase
Use existing test utilities rather than writing custom utilities
Mock external dependencies in tests
Always prefer vitest mock functions over writing verbose manual mocks

Files:

  • tests-ui/tests/platform/cloud/subscription/components/SubscriptionPanel.test.ts
**/*.test.ts

📄 CodeRabbit inference engine (AGENTS.md)

**/*.test.ts: Use unit/component tests in tests-ui/ or src/**/*.test.ts with Vitest framework
For mocking in tests, leverage Vitest utilities; keep module mocks contained and avoid global mutable state within test files
Do not write change detector tests or tests dependent on non-behavioral features like utility classes or styles
Aim for behavioral coverage of critical and new features in unit tests

Files:

  • tests-ui/tests/platform/cloud/subscription/components/SubscriptionPanel.test.ts
**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Minimize the surface area (exported values) of each module and composable

Files:

  • tests-ui/tests/platform/cloud/subscription/components/SubscriptionPanel.test.ts
🧠 Learnings (45)
📓 Common learnings
Learnt from: christian-byrne
Repo: Comfy-Org/ComfyUI_frontend PR: 6300
File: src/platform/updates/components/WhatsNewPopup.vue:5-13
Timestamp: 2025-12-09T03:50:03.127Z
Learning: In the Comfy-Org/ComfyUI_frontend repository, when avoiding PrimeVue components, prefer using the repo's common button components from src/components/button/ (IconButton.vue, TextButton.vue, IconTextButton.vue) rather than plain HTML buttons. These components wrap PrimeVue with custom design system styling.
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7603
File: src/components/queue/QueueOverlayHeader.vue:49-59
Timestamp: 2025-12-18T21:15:54.349Z
Learning: For Vue components in Comfy-Org/ComfyUI_frontend: Do not suggest adding aria-label to buttons that already have visible text content (e.g., <span> elements with labels). The visible text automatically provides the accessible name. aria-label should only be used for elements without visible labels, such as icon-only buttons.
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Replace PrimeVue InputSwitch component with ToggleSwitch
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Replace PrimeVue Steps component with Stepper without panels
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Replace PrimeVue Dropdown component with Select
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Replace PrimeVue InlineMessage component with Message
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Replace PrimeVue Calendar component with DatePicker
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Replace PrimeVue OverlayPanel component with Popover
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Replace PrimeVue TabMenu component with Tabs without panels
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Replace PrimeVue Sidebar component with Drawer
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-21T06:04:12.548Z
Learning: Applies to **/*.vue : Avoid new usage of PrimeVue components; use VueUse, shadcn/vue, or Reka UI instead
📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Replace PrimeVue InputSwitch component with ToggleSwitch

Applied to files:

  • src/components/load3d/Load3DControls.vue
  • src/components/load3d/controls/ModelControls.vue
  • src/platform/cloud/subscription/components/PricingTable.vue
  • src/components/sidebar/tabs/nodeLibrary/NodeHelpPage.vue
  • src/components/load3d/Load3dViewerContent.vue
  • src/components/topbar/CurrentUserPopover.vue
  • src/platform/cloud/subscription/components/SubscriptionPanel.vue
📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Replace PrimeVue TabMenu component with Tabs without panels

Applied to files:

  • src/components/load3d/Load3DControls.vue
  • src/components/load3d/controls/ModelControls.vue
  • src/platform/cloud/subscription/components/PricingTable.vue
  • src/components/sidebar/tabs/nodeLibrary/NodeHelpPage.vue
  • src/components/load3d/Load3dViewerContent.vue
  • src/components/topbar/CurrentUserPopover.vue
  • src/platform/cloud/subscription/components/SubscriptionPanel.vue
📚 Learning: 2025-12-09T03:49:52.828Z
Learnt from: christian-byrne
Repo: Comfy-Org/ComfyUI_frontend PR: 6300
File: src/platform/updates/components/WhatsNewPopup.vue:5-13
Timestamp: 2025-12-09T03:49:52.828Z
Learning: In Vue files across the ComfyUI_frontend repo, when a button is needed, prefer the repo's common button components from src/components/button/ (IconButton.vue, TextButton.vue, IconTextButton.vue) over plain HTML <button> elements. These components wrap PrimeVue with the project’s design system styling. Use only the common button components for consistency and theming, and import them from src/components/button/ as needed.

Applied to files:

  • src/components/load3d/Load3DControls.vue
  • src/components/load3d/controls/ModelControls.vue
  • src/platform/cloud/subscription/components/PricingTable.vue
  • src/components/sidebar/tabs/nodeLibrary/NodeHelpPage.vue
  • src/components/load3d/Load3dViewerContent.vue
  • src/components/topbar/CurrentUserPopover.vue
  • src/platform/cloud/subscription/components/SubscriptionPanel.vue
📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Replace PrimeVue OverlayPanel component with Popover

Applied to files:

  • src/components/load3d/Load3DControls.vue
  • src/components/load3d/controls/ModelControls.vue
  • src/platform/cloud/subscription/components/PricingTable.vue
  • src/components/sidebar/tabs/nodeLibrary/NodeHelpPage.vue
  • src/components/load3d/Load3dViewerContent.vue
  • src/components/topbar/CurrentUserPopover.vue
  • src/platform/cloud/subscription/components/SubscriptionPanel.vue
📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Replace PrimeVue Sidebar component with Drawer

Applied to files:

  • src/components/load3d/Load3DControls.vue
  • src/components/load3d/controls/ModelControls.vue
  • src/platform/cloud/subscription/components/PricingTable.vue
  • src/components/sidebar/tabs/nodeLibrary/NodeHelpPage.vue
  • src/components/load3d/Load3dViewerContent.vue
  • src/components/topbar/CurrentUserPopover.vue
  • src/platform/cloud/subscription/components/SubscriptionPanel.vue
📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Replace PrimeVue Steps component with Stepper without panels

Applied to files:

  • src/components/load3d/Load3DControls.vue
  • src/components/load3d/controls/ModelControls.vue
  • src/platform/cloud/subscription/components/PricingTable.vue
  • src/components/sidebar/tabs/nodeLibrary/NodeHelpPage.vue
  • src/components/load3d/Load3dViewerContent.vue
  • src/components/topbar/CurrentUserPopover.vue
  • src/platform/cloud/subscription/components/SubscriptionPanel.vue
📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Replace PrimeVue InlineMessage component with Message

Applied to files:

  • src/components/load3d/Load3DControls.vue
  • src/components/load3d/controls/ModelControls.vue
  • src/platform/cloud/subscription/components/PricingTable.vue
  • src/components/sidebar/tabs/nodeLibrary/NodeHelpPage.vue
  • src/components/load3d/Load3dViewerContent.vue
  • src/components/topbar/CurrentUserPopover.vue
  • src/platform/cloud/subscription/components/SubscriptionPanel.vue
📚 Learning: 2025-12-21T06:04:12.548Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-21T06:04:12.548Z
Learning: Applies to **/*.vue : Avoid new usage of PrimeVue components; use VueUse, shadcn/vue, or Reka UI instead

Applied to files:

  • src/components/load3d/Load3DControls.vue
  • src/components/load3d/controls/ModelControls.vue
  • src/platform/cloud/subscription/components/PricingTable.vue
  • src/components/sidebar/tabs/nodeLibrary/NodeHelpPage.vue
  • src/components/load3d/Load3dViewerContent.vue
  • src/components/topbar/CurrentUserPopover.vue
  • src/platform/cloud/subscription/components/SubscriptionPanel.vue
📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Replace PrimeVue Dropdown component with Select

Applied to files:

  • src/components/load3d/Load3DControls.vue
  • src/components/load3d/controls/ModelControls.vue
  • src/platform/cloud/subscription/components/PricingTable.vue
  • src/components/sidebar/tabs/nodeLibrary/NodeHelpPage.vue
  • src/components/topbar/CurrentUserPopover.vue
📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Replace PrimeVue Chips component with AutoComplete with multiple enabled

Applied to files:

  • src/components/load3d/Load3DControls.vue
📚 Learning: 2025-12-18T21:15:46.862Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7603
File: src/components/queue/QueueOverlayHeader.vue:49-59
Timestamp: 2025-12-18T21:15:46.862Z
Learning: In the ComfyUI_frontend repository, for Vue components, do not add aria-label to buttons that have visible text content (e.g., buttons containing <span> text). The visible text provides the accessible name. Use aria-label only for elements without visible labels (e.g., icon-only buttons). If a button has no visible label, provide a clear aria-label or associate with an aria-labelledby describing its action.

Applied to files:

  • src/components/load3d/Load3DControls.vue
  • src/components/load3d/controls/ModelControls.vue
  • src/platform/cloud/subscription/components/PricingTable.vue
  • src/components/sidebar/tabs/nodeLibrary/NodeHelpPage.vue
  • src/components/load3d/Load3dViewerContent.vue
  • src/components/topbar/CurrentUserPopover.vue
  • src/platform/cloud/subscription/components/SubscriptionPanel.vue
📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Use setup() function in Vue 3 Composition API

Applied to files:

  • src/components/load3d/Load3DControls.vue
  • src/components/load3d/controls/ModelControls.vue
  • src/platform/cloud/subscription/components/PricingTable.vue
  • src/components/topbar/CurrentUserPopover.vue
📚 Learning: 2025-12-21T06:04:12.548Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-21T06:04:12.548Z
Learning: Applies to **/*.vue : Use Vue 3.5+ with TypeScript in `.vue` files, exclusively using Composition API with `<script setup lang="ts">` syntax

Applied to files:

  • src/components/load3d/Load3DControls.vue
  • src/components/load3d/controls/ModelControls.vue
  • src/platform/cloud/subscription/components/PricingTable.vue
📚 Learning: 2025-11-24T19:47:02.860Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T19:47:02.860Z
Learning: Applies to src/**/*.vue : Utilize Vue 3's Teleport component when needed

Applied to files:

  • src/components/load3d/Load3DControls.vue
  • src/components/load3d/controls/ModelControls.vue
📚 Learning: 2025-12-21T06:04:12.548Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-21T06:04:12.548Z
Learning: Applies to **/*.vue : Utilize Vue 3's Teleport component when needed

Applied to files:

  • src/components/load3d/Load3DControls.vue
  • src/components/load3d/controls/ModelControls.vue
📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Use ref/reactive for state management in Vue 3 Composition API

Applied to files:

  • src/components/load3d/Load3DControls.vue
📚 Learning: 2025-12-16T22:26:49.463Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7537
File: src/components/ui/button/Button.vue:17-17
Timestamp: 2025-12-16T22:26:49.463Z
Learning: In Vue 3.5+ with <script setup>, when using defineProps<Props>() with partial destructuring (e.g., const { as = 'button', class: customClass = '' } = defineProps<Props>() ), props that are not destructured (e.g., variant, size) stay accessible by name in the template scope. This pattern is valid: you can destructure only a subset of props for convenience while referencing the remaining props directly in template expressions. Apply this guideline to Vue components across the codebase (all .vue files).

Applied to files:

  • src/components/load3d/Load3DControls.vue
  • src/components/load3d/controls/ModelControls.vue
  • src/platform/cloud/subscription/components/PricingTable.vue
  • src/components/sidebar/tabs/nodeLibrary/NodeHelpPage.vue
  • src/components/load3d/Load3dViewerContent.vue
  • src/components/topbar/CurrentUserPopover.vue
  • src/platform/cloud/subscription/components/SubscriptionPanel.vue
📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Use lifecycle hooks: onMounted, onUpdated in Vue 3 Composition API

Applied to files:

  • src/components/load3d/Load3DControls.vue
  • src/components/load3d/controls/ModelControls.vue
📚 Learning: 2025-12-18T20:39:30.137Z
Learnt from: jtydhr88
Repo: Comfy-Org/ComfyUI_frontend PR: 7621
File: src/components/load3d/Load3DScene.vue:4-4
Timestamp: 2025-12-18T20:39:30.137Z
Learning: In src/components/load3d/Load3DScene.vue, the scoped `<style>` block with `!important` declarations for the canvas element is necessary because Three.js dynamically creates the canvas with inline styles, preventing direct application of Tailwind classes. This is a valid exception to the Tailwind-only styling guideline.

Applied to files:

  • src/components/load3d/Load3DControls.vue
📚 Learning: 2025-12-09T21:40:12.361Z
Learnt from: benceruleanlu
Repo: Comfy-Org/ComfyUI_frontend PR: 7297
File: src/components/actionbar/ComfyActionbar.vue:33-43
Timestamp: 2025-12-09T21:40:12.361Z
Learning: In Vue single-file components, allow inline Tailwind CSS class strings for static classes and avoid extracting them into computed properties solely for readability. Prefer keeping static class names inline for simplicity and performance. For dynamic or conditional classes, use Vue bindings (e.g., :class) to compose classes.

Applies to all Vue files in the repository (e.g., src/**/*.vue) where Tailwind utilities are used for static styling.

Applied to files:

  • src/components/load3d/Load3DControls.vue
  • src/components/load3d/controls/ModelControls.vue
  • src/platform/cloud/subscription/components/PricingTable.vue
  • src/components/sidebar/tabs/nodeLibrary/NodeHelpPage.vue
  • src/components/load3d/Load3dViewerContent.vue
  • src/components/topbar/CurrentUserPopover.vue
  • src/platform/cloud/subscription/components/SubscriptionPanel.vue
📚 Learning: 2025-12-11T12:25:15.470Z
Learnt from: christian-byrne
Repo: Comfy-Org/ComfyUI_frontend PR: 7358
File: src/components/dialog/content/signin/SignUpForm.vue:45-54
Timestamp: 2025-12-11T12:25:15.470Z
Learning: This repository uses CI automation to format code (pnpm format). Do not include manual formatting suggestions in code reviews for Comfy-Org/ComfyUI_frontend. If formatting issues are detected, rely on the CI formatter or re-run pnpm format. Focus reviews on correctness, readability, performance, accessibility, and maintainability rather than style formatting.

Applied to files:

  • src/components/load3d/Load3DControls.vue
  • src/components/load3d/controls/ModelControls.vue
  • src/platform/cloud/subscription/components/PricingTable.vue
  • tests-ui/tests/platform/cloud/subscription/components/SubscriptionPanel.test.ts
  • src/components/sidebar/tabs/nodeLibrary/NodeHelpPage.vue
  • src/components/load3d/Load3dViewerContent.vue
  • src/components/topbar/CurrentUserPopover.vue
  • src/platform/cloud/subscription/components/SubscriptionPanel.vue
📚 Learning: 2025-12-18T02:07:38.870Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7598
File: src/components/sidebar/tabs/AssetsSidebarTab.vue:131-131
Timestamp: 2025-12-18T02:07:38.870Z
Learning: Tailwind CSS v4 safe utilities (e.g., items-center-safe, justify-*-safe, place-*-safe) are allowed in Vue components under src/ and in story files. Do not flag these specific safe variants as invalid when reviewing code in src/**/*.vue or related stories.

Applied to files:

  • src/components/load3d/Load3DControls.vue
  • src/components/load3d/controls/ModelControls.vue
  • src/platform/cloud/subscription/components/PricingTable.vue
  • src/components/sidebar/tabs/nodeLibrary/NodeHelpPage.vue
  • src/components/load3d/Load3dViewerContent.vue
  • src/components/topbar/CurrentUserPopover.vue
  • src/platform/cloud/subscription/components/SubscriptionPanel.vue
📚 Learning: 2025-12-21T01:06:02.786Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7649
File: src/components/graph/selectionToolbox/ColorPickerButton.vue:15-18
Timestamp: 2025-12-21T01:06:02.786Z
Learning: In Comfy-Org/ComfyUI_frontend, in Vue component files, when a filled icon is required (e.g., 'pi pi-circle-fill'), you may mix PrimeIcons with Lucide icons since Lucide lacks filled variants. This mixed usage is acceptable when one icon library does not provide an equivalent filled icon. Apply consistently across Vue components in the src directory where icons are used, and document the rationale when a mixed approach is chosen.

Applied to files:

  • src/components/load3d/Load3DControls.vue
  • src/components/load3d/controls/ModelControls.vue
  • src/platform/cloud/subscription/components/PricingTable.vue
  • src/components/sidebar/tabs/nodeLibrary/NodeHelpPage.vue
  • src/components/load3d/Load3dViewerContent.vue
  • src/components/topbar/CurrentUserPopover.vue
  • src/platform/cloud/subscription/components/SubscriptionPanel.vue
📚 Learning: 2025-12-18T16:03:02.066Z
Learnt from: henrikvilhelmberglund
Repo: Comfy-Org/ComfyUI_frontend PR: 7617
File: src/components/actionbar/ComfyActionbar.vue:301-308
Timestamp: 2025-12-18T16:03:02.066Z
Learning: In the ComfyUI frontend queue system, useQueuePendingTaskCountStore().count indicates the number of tasks in the queue, where count = 1 means a single active/running task and count > 1 means there are pending tasks in addition to the active task. Therefore, in src/components/actionbar/ComfyActionbar.vue, enable the 'Clear Pending Tasks' button only when count > 1 to avoid clearing the currently running task. The active task should be canceled using the 'Cancel current run' button instead. This rule should be enforced via a conditional check on the queue count, with appropriate disabled/aria-disabled states for accessibility, and tests should verify behavior for count = 1 and count > 1.

Applied to files:

  • src/components/load3d/Load3DControls.vue
  • src/components/load3d/controls/ModelControls.vue
  • src/components/sidebar/tabs/nodeLibrary/NodeHelpPage.vue
  • src/components/load3d/Load3dViewerContent.vue
  • src/components/topbar/CurrentUserPopover.vue
📚 Learning: 2025-12-09T04:35:43.971Z
Learnt from: christian-byrne
Repo: Comfy-Org/ComfyUI_frontend PR: 6300
File: src/locales/en/main.json:774-780
Timestamp: 2025-12-09T04:35:43.971Z
Learning: In the Comfy-Org/ComfyUI_frontend repository, locale files other than `src/locales/en/main.json` are generated automatically on every release. Developers only need to add English (en) key/values in `src/locales/en/main.json` when making PRs; manual updates to other locale files (fr, ja, ko, ru, zh, zh-TW, es, ar, tr, etc.) are not required and should not be suggested in reviews.

Applied to files:

  • src/locales/en/main.json
📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Replace PrimeVue Calendar component with DatePicker

Applied to files:

  • src/components/load3d/controls/ModelControls.vue
  • src/platform/cloud/subscription/components/PricingTable.vue
  • src/components/sidebar/tabs/nodeLibrary/NodeHelpPage.vue
  • src/components/load3d/Load3dViewerContent.vue
  • src/components/topbar/CurrentUserPopover.vue
  • src/platform/cloud/subscription/components/SubscriptionPanel.vue
📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.{vue,ts,js} : Use vue-i18n for ALL UI strings

Applied to files:

  • src/platform/cloud/subscription/components/PricingTable.vue
📚 Learning: 2025-11-24T19:47:02.860Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T19:47:02.860Z
Learning: Applies to src/**/*.vue : Use the Vue 3 Composition API instead of the Options API when writing Vue components (exception: when overriding or extending PrimeVue components for compatibility)

Applied to files:

  • src/platform/cloud/subscription/components/PricingTable.vue
  • src/components/load3d/Load3dViewerContent.vue
📚 Learning: 2025-11-24T19:48:03.270Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: tests-ui/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:48:03.270Z
Learning: Applies to tests-ui/**/*.test.{js,ts,jsx,tsx} : Write tests for new features

Applied to files:

  • tests-ui/tests/platform/cloud/subscription/components/SubscriptionPanel.test.ts
📚 Learning: 2025-11-24T19:48:03.270Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: tests-ui/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:48:03.270Z
Learning: Applies to tests-ui/**/*.test.{js,ts,jsx,tsx} : Follow existing test patterns in the codebase

Applied to files:

  • tests-ui/tests/platform/cloud/subscription/components/SubscriptionPanel.test.ts
📚 Learning: 2025-11-24T19:48:03.270Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: tests-ui/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:48:03.270Z
Learning: Check tests-ui/README.md for test guidelines

Applied to files:

  • tests-ui/tests/platform/cloud/subscription/components/SubscriptionPanel.test.ts
📚 Learning: 2025-12-21T06:04:12.548Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-21T06:04:12.548Z
Learning: Applies to **/*.test.ts : Do not write change detector tests or tests dependent on non-behavioral features like utility classes or styles

Applied to files:

  • tests-ui/tests/platform/cloud/subscription/components/SubscriptionPanel.test.ts
📚 Learning: 2025-11-24T19:47:34.324Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:34.324Z
Learning: Applies to src/**/{composables,components}/**/*.{ts,tsx,vue} : Clean up subscriptions in state management to prevent memory leaks

Applied to files:

  • tests-ui/tests/platform/cloud/subscription/components/SubscriptionPanel.test.ts
📚 Learning: 2025-12-10T03:09:13.807Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7303
File: src/components/topbar/CurrentUserPopover.test.ts:199-205
Timestamp: 2025-12-10T03:09:13.807Z
Learning: In test files, prefer selecting or asserting on accessible properties (text content, aria-label, role, accessible name) over data-testid attributes. This ensures tests validate actual user-facing behavior and accessibility, reducing reliance on implementation details like test IDs.

Applied to files:

  • tests-ui/tests/platform/cloud/subscription/components/SubscriptionPanel.test.ts
📚 Learning: 2025-12-18T21:15:54.349Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7603
File: src/components/queue/QueueOverlayHeader.vue:49-59
Timestamp: 2025-12-18T21:15:54.349Z
Learning: For Vue components in Comfy-Org/ComfyUI_frontend: Do not suggest adding aria-label to buttons that already have visible text content (e.g., <span> elements with labels). The visible text automatically provides the accessible name. aria-label should only be used for elements without visible labels, such as icon-only buttons.

Applied to files:

  • tests-ui/tests/platform/cloud/subscription/components/SubscriptionPanel.test.ts
📚 Learning: 2025-12-21T06:04:12.548Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-21T06:04:12.548Z
Learning: Applies to browser_tests/**/*.spec.ts : Do not use `waitForTimeout` in Playwright tests; use Locator actions and retrying assertions instead

Applied to files:

  • tests-ui/tests/platform/cloud/subscription/components/SubscriptionPanel.test.ts
📚 Learning: 2025-12-09T03:39:54.501Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7169
File: src/platform/remote/comfyui/jobs/jobTypes.ts:1-107
Timestamp: 2025-12-09T03:39:54.501Z
Learning: In the ComfyUI_frontend project, Zod is on v3.x. Do not suggest Zod v4 standalone validators (z.uuid, z.ulid, z.cuid2, z.nanoid) until an upgrade to Zod 4 is performed. When reviewing TypeScript files (e.g., src/platform/remote/comfyui/jobs/jobTypes.ts) validate against Zod 3 capabilities and avoid introducing v4-specific features; flag any proposal to upgrade or incorporate v4-only validators and propose staying with compatible 3.x patterns.

Applied to files:

  • tests-ui/tests/platform/cloud/subscription/components/SubscriptionPanel.test.ts
📚 Learning: 2025-12-13T11:03:11.264Z
Learnt from: christian-byrne
Repo: Comfy-Org/ComfyUI_frontend PR: 7416
File: src/stores/imagePreviewStore.ts:5-7
Timestamp: 2025-12-13T11:03:11.264Z
Learning: In the ComfyUI_frontend repository, lint rules require keeping 'import type' statements separate from non-type imports, even if importing from the same module. Do not suggest consolidating them into a single import statement. Ensure type imports remain on their own line (import type { ... } from 'module') and regular imports stay on separate lines.

Applied to files:

  • tests-ui/tests/platform/cloud/subscription/components/SubscriptionPanel.test.ts
📚 Learning: 2025-12-17T00:40:09.635Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7537
File: src/components/ui/button/Button.stories.ts:45-55
Timestamp: 2025-12-17T00:40:09.635Z
Learning: Prefer pure function declarations over function expressions (e.g., use function foo() { ... } instead of const foo = () => { ... }) for pure functions in the repository. Function declarations are more functional-leaning, offer better hoisting clarity, and can improve readability and tooling consistency. Apply this guideline across TypeScript files in Comfy-Org/ComfyUI_frontend, including story and UI component code, except where a function expression is semantically required (e.g., callbacks, higher-order functions with closures).

Applied to files:

  • tests-ui/tests/platform/cloud/subscription/components/SubscriptionPanel.test.ts
📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Implement computed() for derived state in Vue 3 Composition API

Applied to files:

  • src/components/sidebar/tabs/nodeLibrary/NodeHelpPage.vue
📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Extract complex conditionals to computed properties

Applied to files:

  • src/components/sidebar/tabs/nodeLibrary/NodeHelpPage.vue
📚 Learning: 2025-11-24T19:47:02.860Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T19:47:02.860Z
Learning: Applies to src/**/*.vue : Implement computed properties with computed()

Applied to files:

  • src/components/sidebar/tabs/nodeLibrary/NodeHelpPage.vue
📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.{vue,ts,js} : Use existing VueUse composables (such as useElementHover) instead of manually managing event listeners

Applied to files:

  • src/components/sidebar/tabs/nodeLibrary/NodeHelpPage.vue
📚 Learning: 2025-11-24T19:47:02.860Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T19:47:02.860Z
Learning: Applies to src/**/*.{vue,ts} : Leverage VueUse functions for performance-enhancing styles

Applied to files:

  • src/components/sidebar/tabs/nodeLibrary/NodeHelpPage.vue
🪛 GitHub Actions: CI: Lint Format
src/components/sidebar/tabs/nodeLibrary/NodeHelpPage.vue

[error] 25-29: Identifier 'Button' has already been declared. It can not be redeclared here. Command 'pnpm lint:fix' (oxi lint + eslint) failed with exit code 1.

🪛 GitHub Actions: CI: Size Data
src/components/sidebar/tabs/nodeLibrary/NodeHelpPage.vue

[error] 8-8: Type '"muted-textonly"' is not assignable to type '"link" | "text" | "outlined" | undefined'.

🪛 GitHub Actions: CI: Tests Storybook
src/components/sidebar/tabs/nodeLibrary/NodeHelpPage.vue

[error] 7-7: Storybook build failed. Vue compiler error: Identifier 'Button' has already been declared in NodeHelpPage.vue (7:7). Command: pnpm build-storybook.

🪛 GitHub Check: collect
src/components/sidebar/tabs/nodeLibrary/NodeHelpPage.vue

[failure] 9-9:
Type '"icon"' is not assignable to type '"small" | "large" | undefined'.


[failure] 8-8:
Type '"muted-textonly"' is not assignable to type '"link" | "text" | "outlined" | undefined'.


[failure] 29-29:
Duplicate identifier 'Button'.

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: test
  • GitHub Check: setup
🔇 Additional comments (21)
src/locales/en/main.json (1)

122-123: LGTM! Translation keys follow established conventions.

The new scrollLeft and scrollRight keys are well-placed within the settings section and follow the camelCase naming convention used throughout the file. The translations are clear and consistent with similar action-oriented keys in the codebase.

src/components/sidebar/tabs/nodeLibrary/NodeHelpPage.vue (1)

6-14: Button migration looks correct.

The Button template usage properly follows the new local component API with variant, size, slot-based icon content, and accessibility via aria-label. The type errors flagged by static analysis should resolve once the duplicate import is removed.

src/components/load3d/Load3DControls.vue (3)

10-18: LGTM! Accessibility concern previously addressed.

The icon-only button correctly includes aria-label for screen reader accessibility, and the migration to the local Button component with variant/size props is implemented correctly.


25-41: LGTM! Menu category buttons correctly implemented.

The buttons correctly use the new Button API with variant and slot-based content. The cn utility appropriately handles conditional active state styling, and the visible text labels provide accessible names without needing aria-label.


93-93: LGTM! Import statements correctly added.

The imports for the local Button component and cn utility are properly added to support the migration.

Also applies to: 100-100

src/components/load3d/Load3dViewerContent.vue (2)

75-78: LGTM! Cancel button correctly implemented.

The button uses the new Button API with variant="secondary" and slot-based content. The visible text label correctly provides the accessible name without needing aria-label.


93-93: LGTM! Import updated to local Button component.

The import statement correctly references the local Button component, aligning with the migration away from PrimeVue.

src/components/load3d/controls/ModelControls.vue (6)

4-16: LGTM! Up direction button correctly implements accessibility.

The icon-only button appropriately includes both aria-label and v-tooltip for accessibility and user experience. The migration to the local Button component is correctly implemented.


22-32: LGTM! Up direction selection buttons correctly implemented.

The buttons use the new Button API with conditional styling via cn. The visible text labels (direction names) provide accessible names without needing aria-label.


38-50: LGTM! Material mode button correctly implements accessibility.

The icon-only button appropriately includes both aria-label and v-tooltip, providing good accessibility and user experience. The Button API migration is correctly implemented.


56-69: LGTM! Material mode selection buttons correctly implemented.

The buttons use the new Button API with proper conditional styling. The visible text labels from the i18n system provide accessible names.


79-79: LGTM! Import statements correctly added.

The imports for the local Button component and cn utility are properly added to support the component migration.

Also applies to: 85-85


124-158: LGTM! Function declarations follow coding guidelines.

The functions have been correctly converted to function declarations, which aligns with the coding guideline to prefer function declarations over function expressions. The logic and type annotations are preserved.

tests-ui/tests/platform/cloud/subscription/components/SubscriptionPanel.test.ts (1)

281-282: Tests appropriately skipped pending VTL migration.

The skipped tests already have a tracking issue (#7707) created. The TODO comment clearly explains the reason for skipping.

Also applies to: 306-306

src/platform/cloud/subscription/components/SubscriptionPanel.vue (4)

55-83: Button migration looks correct.

The subscription management and upgrade buttons correctly use the new slot-based API with appropriate variant props. The SubscribeButton size prop is updated from "small" to "sm" to align with the new API.


248-282: Footer action buttons correctly migrated.

These buttons with visible text content (icons + labels) properly use slot-based content rendering. No aria-label needed since the visible text provides the accessible name. Based on learnings, aria-label should only be used for icon-only buttons.


295-295: Correct migration to local Button component.

The import path correctly references the local Button.vue component instead of PrimeVue, aligning with the codebase guidelines to avoid new PrimeVue component usage.


413-417: This style override is necessary and should be retained. The :deep() selector targets the bg-comfy-menu-secondary class applied by PrimeVue's TabPanel component, overriding its default background. Since PrimeVue components from third-party libraries cannot be styled via props in this manner, using a scoped style block with :deep() is the appropriate solution here, similar to other PrimeVue component overrides in the codebase.

src/components/topbar/CurrentUserPopover.vue (3)

146-146: LGTM! Import migration aligned with PR objectives.

The import path correctly migrates from PrimeVue Button to the local Button component.


63-63: No issues found. The SubscribeButton component accepts "sm" as a valid size value (defined as size?: 'sm' | 'lg' in its props).


48-56: Button component migration is correct, but test should use accessible properties instead of data-testid.

The Button component migration follows the correct pattern with proper slot-based content and variant prop. However, the test for this button violates the test pattern guidance: it should select the button by its visible text content or aria-label instead of using data-testid="add-credits-button". Update the test to use wrapper.find('button:has-text("Add Credits")') or similar accessible property selection to verify actual user-facing behavior.

⛔ Skipped due to learnings
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7303
File: src/components/topbar/CurrentUserPopover.test.ts:199-205
Timestamp: 2025-12-10T03:09:19.636Z
Learning: For test files in the Comfy-Org/ComfyUI_frontend repository: When writing tests, prefer selecting elements by accessible properties (text content, aria-label, role, accessible name) over data-testid attributes. This ensures tests verify actual user-facing behavior and accessibility compliance.
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7603
File: src/components/queue/QueueOverlayHeader.vue:49-59
Timestamp: 2025-12-18T21:15:54.349Z
Learning: For Vue components in Comfy-Org/ComfyUI_frontend: Do not suggest adding aria-label to buttons that already have visible text content (e.g., <span> elements with labels). The visible text automatically provides the accessible name. aria-label should only be used for elements without visible labels, such as icon-only buttons.
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: tests-ui/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:48:03.270Z
Learning: Check tests-ui/README.md for test guidelines

Comment on lines 189 to 194
Button: {
template:
'<button @click="$emit(\'click\')" :disabled="loading" :data-testid="label" :data-icon="icon">{{ label }}</button>',
props: [
'loading',
'label',
'icon',
'text',
'severity',
'size',
'iconPos',
'pt'
],
'<button @click="$emit(\'click\')" :disabled="loading" :data-testid="label" :data-icon="icon"><slot/></button>',
props: ['variant', 'size'],
emits: ['click']
},
Copy link
Contributor

@coderabbitai coderabbitai bot Dec 22, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick | 🔵 Trivial

Button stub references undefined props.

The stub template binds :disabled="loading", :data-testid="label", and :data-icon="icon", but the props array only declares ['variant', 'size']. These bindings are now always undefined.

Since the tests relying on these selectors are skipped, consider cleaning up the stub to remove the dead bindings:

🔎 Proposed cleanup
         Button: {
-          template:
-            '<button @click="$emit(\'click\')" :disabled="loading" :data-testid="label" :data-icon="icon"><slot/></button>',
-          props: ['variant', 'size'],
+          template: '<button @click="$emit(\'click\')"><slot/></button>',
+          props: ['variant', 'size', 'loading'],
           emits: ['click']
         },
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
Button: {
template:
'<button @click="$emit(\'click\')" :disabled="loading" :data-testid="label" :data-icon="icon">{{ label }}</button>',
props: [
'loading',
'label',
'icon',
'text',
'severity',
'size',
'iconPos',
'pt'
],
'<button @click="$emit(\'click\')" :disabled="loading" :data-testid="label" :data-icon="icon"><slot/></button>',
props: ['variant', 'size'],
emits: ['click']
},
Button: {
template: '<button @click="$emit(\'click\')"><slot/></button>',
props: ['variant', 'size', 'loading'],
emits: ['click']
},
🤖 Prompt for AI Agents
In
tests-ui/tests/platform/cloud/subscription/components/SubscriptionPanel.test.ts
around lines 189-194, the Button stub template binds :disabled="loading",
:data-testid="label" and :data-icon="icon" but only declares props
['variant','size'], so those bindings are undefined; fix by either removing the
dead bindings from the template (strip :disabled, :data-testid and :data-icon)
or add the missing props to the props array (e.g., include
'loading','label','icon') so the bindings resolve, and update any tests that
depend on those attributes accordingly.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should not be stubbing primitives or customized primitives like Button.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@DrJKL, you're absolutely right. The Button stub should be removed entirely and the real Button component should be used instead, consistent with the approach taken in PricingTable.test.ts.

Here's the recommended change:

import Button from '@/components/ui/button/Button.vue'

function createWrapper(overrides = {}) {
  return mount(SubscriptionPanel, {
    global: {
      plugins: [createTestingPinia({ createSpy: vi.fn }), i18n],
      components: {
        Button
      },
      stubs: {
        CloudBadge: true,
        SubscribeButton: true,
        SubscriptionBenefits: true,
        Skeleton: {
          template: '<div class="skeleton"></div>'
        }
      }
    },
    ...overrides
  })
}

This removes the Button stub and registers the real component. When the skipped test suites are re-enabled, they should use accessible selectors (text content, roles, aria-labels) rather than data-testid/data-icon attributes, following the existing test guidelines.


✏️ Learnings added
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7649
File: tests-ui/tests/platform/cloud/subscription/components/SubscriptionPanel.test.ts:189-194
Timestamp: 2025-12-22T21:36:38.905Z
Learning: In the Comfy-Org/ComfyUI_frontend repository test files: Do not stub primitive UI components or customized primitive components (e.g., Button). Instead, import and register the real components in test setup. This ensures tests accurately reflect production behavior and component API usage.

Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure review instructions. You can manage existing learnings in the app.


🧠 Learnings used
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: tests-ui/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:48:03.270Z
Learning: Applies to tests-ui/**/*.test.{js,ts,jsx,tsx} : Mock external dependencies in tests

Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Replace PrimeVue OverlayPanel component with Popover

Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7303
File: src/components/topbar/CurrentUserPopover.test.ts:199-205
Timestamp: 2025-12-10T03:09:19.636Z
Learning: For test files in the Comfy-Org/ComfyUI_frontend repository: When writing tests, prefer selecting elements by accessible properties (text content, aria-label, role, accessible name) over data-testid attributes. This ensures tests verify actual user-facing behavior and accessibility compliance.

Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7603
File: src/components/queue/QueueOverlayHeader.vue:49-59
Timestamp: 2025-12-18T21:15:54.349Z
Learning: For Vue components in Comfy-Org/ComfyUI_frontend: Do not suggest adding aria-label to buttons that already have visible text content (e.g., <span> elements with labels). The visible text automatically provides the accessible name. aria-label should only be used for elements without visible labels, such as icon-only buttons.

Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7537
File: src/components/ui/button/Button.vue:17-17
Timestamp: 2025-12-16T22:26:55.918Z
Learning: In Vue 3.5+ with `<script setup>`, when using `defineProps<Props>()` with partial destructuring (e.g., `const { as = 'button', class: customClass = '' } = defineProps<Props>()`), props that are NOT destructured (like `variant` and `size` in this example) remain accessible by name in the template scope. It's valid to destructure only some props for convenience while accessing others directly in expressions.

Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: tests-ui/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:48:03.270Z
Learning: Applies to tests-ui/**/*.test.{js,ts,jsx,tsx} : Write tests for new features

Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: tests-ui/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:48:03.270Z
Learning: Check tests-ui/README.md for test guidelines

Learnt from: christian-byrne
Repo: Comfy-Org/ComfyUI_frontend PR: 6300
File: src/platform/updates/components/WhatsNewPopup.vue:5-13
Timestamp: 2025-12-09T03:50:03.127Z
Learning: In the Comfy-Org/ComfyUI_frontend repository, when avoiding PrimeVue components, prefer using the repo's common button components from src/components/button/ (IconButton.vue, TextButton.vue, IconTextButton.vue) rather than plain HTML buttons. These components wrap PrimeVue with custom design system styling.

@DrJKL DrJKL added the New Browser Test Expectations New browser test screenshot should be set by github action label Dec 29, 2025
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 5

📜 Review details

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 8245fa6 and d57e47a.

📒 Files selected for processing (3)
  • src/locales/en/main.json
  • src/workbench/extensions/manager/components/manager/NodeConflictDialogContent.vue
  • tests-ui/tests/components/dialog/content/manager/NodeConflictDialogContent.test.ts
🧰 Additional context used
📓 Path-based instructions (12)
**/*.{ts,tsx,vue,js,jsx,json,css}

📄 CodeRabbit inference engine (AGENTS.md)

Apply Prettier formatting with 2-space indentation, single quotes, no trailing semicolons, and 80-character line width

Files:

  • src/locales/en/main.json
  • tests-ui/tests/components/dialog/content/manager/NodeConflictDialogContent.test.ts
  • src/workbench/extensions/manager/components/manager/NodeConflictDialogContent.vue
tests-ui/**/*.test.{js,ts,jsx,tsx}

📄 CodeRabbit inference engine (tests-ui/CLAUDE.md)

tests-ui/**/*.test.{js,ts,jsx,tsx}: Write tests for new features
Follow existing test patterns in the codebase
Use existing test utilities rather than writing custom utilities
Mock external dependencies in tests
Always prefer vitest mock functions over writing verbose manual mocks

Files:

  • tests-ui/tests/components/dialog/content/manager/NodeConflictDialogContent.test.ts
**/*.{ts,tsx,vue}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{ts,tsx,vue}: Use TypeScript exclusively; do not write new JavaScript code
Use sorted and grouped imports organized by plugin/source
Enforce ESLint rules including Vue + TypeScript rules, disallow floating promises, disallow unused imports, and restrict i18n raw text in templates
Do not use any type or as any type assertions; fix the underlying type issue instead
Write code that is expressive and self-documenting; avoid redundant comments and clean as you go
Keep functions short and functional; minimize nesting and follow the arrow anti-pattern
Avoid mutable state; prefer immutability and assignment at point of declaration
Use function declarations instead of function expressions when possible
Use es-toolkit for utility functions
Implement proper error handling in code

Files:

  • tests-ui/tests/components/dialog/content/manager/NodeConflictDialogContent.test.ts
  • src/workbench/extensions/manager/components/manager/NodeConflictDialogContent.vue
**/*.test.ts

📄 CodeRabbit inference engine (AGENTS.md)

**/*.test.ts: Use unit/component tests in tests-ui/ or src/**/*.test.ts with Vitest framework
For mocking in tests, leverage Vitest utilities; keep module mocks contained and avoid global mutable state within test files
Do not write change detector tests or tests dependent on non-behavioral features like utility classes or styles
Aim for behavioral coverage of critical and new features in unit tests

Files:

  • tests-ui/tests/components/dialog/content/manager/NodeConflictDialogContent.test.ts
**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Minimize the surface area (exported values) of each module and composable

Files:

  • tests-ui/tests/components/dialog/content/manager/NodeConflictDialogContent.test.ts
src/**/*.vue

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

src/**/*.vue: Use the Vue 3 Composition API instead of the Options API when writing Vue components (exception: when overriding or extending PrimeVue components for compatibility)
Use setup() function for component logic
Utilize ref and reactive for reactive state
Implement computed properties with computed()
Use watch and watchEffect for side effects
Implement lifecycle hooks with onMounted, onUpdated, etc.
Utilize provide/inject for dependency injection
Use vue 3.5 style of default prop declaration
Use Tailwind CSS for styling
Implement proper props and emits definitions
Utilize Vue 3's Teleport component when needed
Use Suspense for async components
Follow Vue 3 style guide and naming conventions

Files:

  • src/workbench/extensions/manager/components/manager/NodeConflictDialogContent.vue
src/**/*.{vue,ts}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

src/**/*.{vue,ts}: Leverage VueUse functions for performance-enhancing styles
Implement proper error handling
Use vue-i18n in composition API for any string literals. Place new translation entries in src/locales/en/main.json

Files:

  • src/workbench/extensions/manager/components/manager/NodeConflictDialogContent.vue
src/**/*.{ts,tsx,vue}

📄 CodeRabbit inference engine (src/CLAUDE.md)

src/**/*.{ts,tsx,vue}: Sanitize HTML with DOMPurify to prevent XSS attacks
Avoid using @ts-expect-error; use proper TypeScript types instead
Use es-toolkit for utility functions instead of other utility libraries
Implement proper TypeScript types throughout the codebase

Files:

  • src/workbench/extensions/manager/components/manager/NodeConflictDialogContent.vue
src/**/{composables,components}/**/*.{ts,tsx,vue}

📄 CodeRabbit inference engine (src/CLAUDE.md)

Clean up subscriptions in state management to prevent memory leaks

Files:

  • src/workbench/extensions/manager/components/manager/NodeConflictDialogContent.vue
src/**/*.{vue,ts,tsx}

📄 CodeRabbit inference engine (src/CLAUDE.md)

Follow Vue 3 composition API style guide

Files:

  • src/workbench/extensions/manager/components/manager/NodeConflictDialogContent.vue
src/**/{components,composables}/**/*.{ts,tsx,vue}

📄 CodeRabbit inference engine (src/CLAUDE.md)

Use vue-i18n for ALL user-facing strings by adding them to src/locales/en/main.json

Files:

  • src/workbench/extensions/manager/components/manager/NodeConflictDialogContent.vue
**/*.vue

📄 CodeRabbit inference engine (AGENTS.md)

**/*.vue: Use Vue 3.5+ with TypeScript in .vue files, exclusively using Composition API with <script setup lang="ts"> syntax
Use Tailwind 4 for styling in Vue components; avoid <style> blocks
Name Vue components using PascalCase (e.g., MenuHamburger.vue)
Use Vue 3.5 TypeScript-style default prop declaration with reactive props destructuring; do not use withDefaults or runtime props declaration
Prefer computed() over ref with watch when deriving values
Prefer useModel over separately defining prop and emit for two-way binding
Use vue-i18n in composition API for string literals; place new translation entries in src/locales/en/main.json
Use cn() utility function from @/utils/tailwindUtil for merging Tailwind class names; do not use :class="[]" syntax
Do not use the dark: Tailwind variant; use semantic values from the style.css theme instead (e.g., bg-node-component-surface)
Do not use !important or the ! important prefix for Tailwind classes; find and correct interfering !important classes instead
Avoid new usage of PrimeVue components; use VueUse, shadcn/vue, or Reka UI instead
Leverage VueUse functions for performance-enhancing styles in Vue components
Implement proper props and emits definitions in Vue components
Utilize Vue 3's Teleport component when needed
Use Suspense for async components
Follow Vue 3 style guide and naming conventions

Files:

  • src/workbench/extensions/manager/components/manager/NodeConflictDialogContent.vue
🧠 Learnings (40)
📓 Common learnings
Learnt from: christian-byrne
Repo: Comfy-Org/ComfyUI_frontend PR: 6300
File: src/platform/updates/components/WhatsNewPopup.vue:5-13
Timestamp: 2025-12-09T03:50:03.127Z
Learning: In the Comfy-Org/ComfyUI_frontend repository, when avoiding PrimeVue components, prefer using the repo's common button components from src/components/button/ (IconButton.vue, TextButton.vue, IconTextButton.vue) rather than plain HTML buttons. These components wrap PrimeVue with custom design system styling.
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Replace PrimeVue InputSwitch component with ToggleSwitch
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Replace PrimeVue Steps component with Stepper without panels
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Replace PrimeVue InlineMessage component with Message
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Replace PrimeVue OverlayPanel component with Popover
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Replace PrimeVue Dropdown component with Select
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Replace PrimeVue TabMenu component with Tabs without panels
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-21T06:04:12.562Z
Learning: Applies to **/*.vue : Avoid new usage of PrimeVue components; use VueUse, shadcn/vue, or Reka UI instead
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7649
File: src/platform/cloud/subscription/components/PricingTable.vue:185-201
Timestamp: 2025-12-22T21:36:16.031Z
Learning: In the Comfy-Org/ComfyUI_frontend repository, avoid creating single-use variants for the Button component (and other UI components). Variants should be reusable across multiple use cases. It's acceptable to use a mix of variant props and manual Tailwind classes temporarily when a specific styling need exists in only one place, with consolidation deferred to a later phase when patterns emerge.
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Replace PrimeVue Calendar component with DatePicker
📚 Learning: 2025-12-09T04:35:43.971Z
Learnt from: christian-byrne
Repo: Comfy-Org/ComfyUI_frontend PR: 6300
File: src/locales/en/main.json:774-780
Timestamp: 2025-12-09T04:35:43.971Z
Learning: In the Comfy-Org/ComfyUI_frontend repository, locale files other than `src/locales/en/main.json` are generated automatically on every release. Developers only need to add English (en) key/values in `src/locales/en/main.json` when making PRs; manual updates to other locale files (fr, ja, ko, ru, zh, zh-TW, es, ar, tr, etc.) are not required and should not be suggested in reviews.

Applied to files:

  • src/locales/en/main.json
📚 Learning: 2025-12-09T03:50:03.127Z
Learnt from: christian-byrne
Repo: Comfy-Org/ComfyUI_frontend PR: 6300
File: src/platform/updates/components/WhatsNewPopup.vue:5-13
Timestamp: 2025-12-09T03:50:03.127Z
Learning: In the Comfy-Org/ComfyUI_frontend repository, when avoiding PrimeVue components, prefer using the repo's common button components from src/components/button/ (IconButton.vue, TextButton.vue, IconTextButton.vue) rather than plain HTML buttons. These components wrap PrimeVue with custom design system styling.

Applied to files:

  • tests-ui/tests/components/dialog/content/manager/NodeConflictDialogContent.test.ts
📚 Learning: 2025-12-22T21:36:38.905Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7649
File: tests-ui/tests/platform/cloud/subscription/components/SubscriptionPanel.test.ts:189-194
Timestamp: 2025-12-22T21:36:38.905Z
Learning: In tests-ui feature tests, do not stub primitive UI components or customized primitives (e.g., Button). Instead, import and register the real components in the test setup so tests reflect production behavior and component API usage. This improves test reliability and fidelity. If a test must avoid rendering the full component, justify the approach and consider higher-level mocks or integration tests rather than replacing the primitive itself.

Applied to files:

  • tests-ui/tests/components/dialog/content/manager/NodeConflictDialogContent.test.ts
📚 Learning: 2025-12-21T06:04:12.562Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-21T06:04:12.562Z
Learning: Applies to **/*.test.ts : Do not write change detector tests or tests dependent on non-behavioral features like utility classes or styles

Applied to files:

  • tests-ui/tests/components/dialog/content/manager/NodeConflictDialogContent.test.ts
📚 Learning: 2025-11-24T19:48:03.270Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: tests-ui/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:48:03.270Z
Learning: Applies to tests-ui/**/*.test.{js,ts,jsx,tsx} : Write tests for new features

Applied to files:

  • tests-ui/tests/components/dialog/content/manager/NodeConflictDialogContent.test.ts
📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Replace PrimeVue InlineMessage component with Message

Applied to files:

  • tests-ui/tests/components/dialog/content/manager/NodeConflictDialogContent.test.ts
  • src/workbench/extensions/manager/components/manager/NodeConflictDialogContent.vue
📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Replace PrimeVue OverlayPanel component with Popover

Applied to files:

  • tests-ui/tests/components/dialog/content/manager/NodeConflictDialogContent.test.ts
  • src/workbench/extensions/manager/components/manager/NodeConflictDialogContent.vue
📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Replace PrimeVue InputSwitch component with ToggleSwitch

Applied to files:

  • tests-ui/tests/components/dialog/content/manager/NodeConflictDialogContent.test.ts
  • src/workbench/extensions/manager/components/manager/NodeConflictDialogContent.vue
📚 Learning: 2025-11-24T19:48:03.270Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: tests-ui/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:48:03.270Z
Learning: Check tests-ui/README.md for test guidelines

Applied to files:

  • tests-ui/tests/components/dialog/content/manager/NodeConflictDialogContent.test.ts
📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Replace PrimeVue TabMenu component with Tabs without panels

Applied to files:

  • tests-ui/tests/components/dialog/content/manager/NodeConflictDialogContent.test.ts
  • src/workbench/extensions/manager/components/manager/NodeConflictDialogContent.vue
📚 Learning: 2025-11-24T19:48:03.270Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: tests-ui/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:48:03.270Z
Learning: Applies to tests-ui/**/*.test.{js,ts,jsx,tsx} : Follow existing test patterns in the codebase

Applied to files:

  • tests-ui/tests/components/dialog/content/manager/NodeConflictDialogContent.test.ts
📚 Learning: 2025-11-24T19:48:03.270Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: tests-ui/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:48:03.270Z
Learning: Applies to tests-ui/**/*.test.{js,ts,jsx,tsx} : Use existing test utilities rather than writing custom utilities

Applied to files:

  • tests-ui/tests/components/dialog/content/manager/NodeConflictDialogContent.test.ts
📚 Learning: 2025-11-24T19:48:03.270Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: tests-ui/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:48:03.270Z
Learning: Applies to tests-ui/**/*.test.{js,ts,jsx,tsx} : Always prefer vitest mock functions over writing verbose manual mocks

Applied to files:

  • tests-ui/tests/components/dialog/content/manager/NodeConflictDialogContent.test.ts
📚 Learning: 2025-12-21T06:04:12.562Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-21T06:04:12.562Z
Learning: Applies to **/*.test.ts : Use unit/component tests in `tests-ui/` or `src/**/*.test.ts` with Vitest framework

Applied to files:

  • tests-ui/tests/components/dialog/content/manager/NodeConflictDialogContent.test.ts
📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Replace PrimeVue Steps component with Stepper without panels

Applied to files:

  • tests-ui/tests/components/dialog/content/manager/NodeConflictDialogContent.test.ts
  • src/workbench/extensions/manager/components/manager/NodeConflictDialogContent.vue
📚 Learning: 2025-12-21T06:04:12.562Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-21T06:04:12.562Z
Learning: Applies to **/*.test.ts : For mocking in tests, leverage Vitest utilities; keep module mocks contained and avoid global mutable state within test files

Applied to files:

  • tests-ui/tests/components/dialog/content/manager/NodeConflictDialogContent.test.ts
📚 Learning: 2025-11-24T19:48:03.270Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: tests-ui/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:48:03.270Z
Learning: Applies to tests-ui/**/*.test.{js,ts,jsx,tsx} : Mock external dependencies in tests

Applied to files:

  • tests-ui/tests/components/dialog/content/manager/NodeConflictDialogContent.test.ts
📚 Learning: 2025-11-24T19:48:09.318Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: .cursor/rules/unit-test.mdc:0-0
Timestamp: 2025-11-24T19:48:09.318Z
Learning: Applies to test/**/*.{test,spec}.{js,ts,jsx,tsx} : Use `vitest` for unit testing in this project

Applied to files:

  • tests-ui/tests/components/dialog/content/manager/NodeConflictDialogContent.test.ts
📚 Learning: 2025-12-09T03:39:54.501Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7169
File: src/platform/remote/comfyui/jobs/jobTypes.ts:1-107
Timestamp: 2025-12-09T03:39:54.501Z
Learning: In the ComfyUI_frontend project, Zod is on v3.x. Do not suggest Zod v4 standalone validators (z.uuid, z.ulid, z.cuid2, z.nanoid) until an upgrade to Zod 4 is performed. When reviewing TypeScript files (e.g., src/platform/remote/comfyui/jobs/jobTypes.ts) validate against Zod 3 capabilities and avoid introducing v4-specific features; flag any proposal to upgrade or incorporate v4-only validators and propose staying with compatible 3.x patterns.

Applied to files:

  • tests-ui/tests/components/dialog/content/manager/NodeConflictDialogContent.test.ts
📚 Learning: 2025-12-13T11:03:11.264Z
Learnt from: christian-byrne
Repo: Comfy-Org/ComfyUI_frontend PR: 7416
File: src/stores/imagePreviewStore.ts:5-7
Timestamp: 2025-12-13T11:03:11.264Z
Learning: In the ComfyUI_frontend repository, lint rules require keeping 'import type' statements separate from non-type imports, even if importing from the same module. Do not suggest consolidating them into a single import statement. Ensure type imports remain on their own line (import type { ... } from 'module') and regular imports stay on separate lines.

Applied to files:

  • tests-ui/tests/components/dialog/content/manager/NodeConflictDialogContent.test.ts
📚 Learning: 2025-12-17T00:40:09.635Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7537
File: src/components/ui/button/Button.stories.ts:45-55
Timestamp: 2025-12-17T00:40:09.635Z
Learning: Prefer pure function declarations over function expressions (e.g., use function foo() { ... } instead of const foo = () => { ... }) for pure functions in the repository. Function declarations are more functional-leaning, offer better hoisting clarity, and can improve readability and tooling consistency. Apply this guideline across TypeScript files in Comfy-Org/ComfyUI_frontend, including story and UI component code, except where a function expression is semantically required (e.g., callbacks, higher-order functions with closures).

Applied to files:

  • tests-ui/tests/components/dialog/content/manager/NodeConflictDialogContent.test.ts
📚 Learning: 2025-12-10T03:09:13.807Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7303
File: src/components/topbar/CurrentUserPopover.test.ts:199-205
Timestamp: 2025-12-10T03:09:13.807Z
Learning: In test files, prefer selecting or asserting on accessible properties (text content, aria-label, role, accessible name) over data-testid attributes. This ensures tests validate actual user-facing behavior and accessibility, reducing reliance on implementation details like test IDs.

Applied to files:

  • tests-ui/tests/components/dialog/content/manager/NodeConflictDialogContent.test.ts
📚 Learning: 2025-12-11T12:25:15.470Z
Learnt from: christian-byrne
Repo: Comfy-Org/ComfyUI_frontend PR: 7358
File: src/components/dialog/content/signin/SignUpForm.vue:45-54
Timestamp: 2025-12-11T12:25:15.470Z
Learning: This repository uses CI automation to format code (pnpm format). Do not include manual formatting suggestions in code reviews for Comfy-Org/ComfyUI_frontend. If formatting issues are detected, rely on the CI formatter or re-run pnpm format. Focus reviews on correctness, readability, performance, accessibility, and maintainability rather than style formatting.

Applied to files:

  • tests-ui/tests/components/dialog/content/manager/NodeConflictDialogContent.test.ts
  • src/workbench/extensions/manager/components/manager/NodeConflictDialogContent.vue
📚 Learning: 2025-12-09T03:49:52.828Z
Learnt from: christian-byrne
Repo: Comfy-Org/ComfyUI_frontend PR: 6300
File: src/platform/updates/components/WhatsNewPopup.vue:5-13
Timestamp: 2025-12-09T03:49:52.828Z
Learning: In Vue files across the ComfyUI_frontend repo, when a button is needed, prefer the repo's common button components from src/components/button/ (IconButton.vue, TextButton.vue, IconTextButton.vue) over plain HTML <button> elements. These components wrap PrimeVue with the project’s design system styling. Use only the common button components for consistency and theming, and import them from src/components/button/ as needed.

Applied to files:

  • src/workbench/extensions/manager/components/manager/NodeConflictDialogContent.vue
📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Replace PrimeVue Sidebar component with Drawer

Applied to files:

  • src/workbench/extensions/manager/components/manager/NodeConflictDialogContent.vue
📚 Learning: 2025-12-21T06:04:12.562Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-21T06:04:12.562Z
Learning: Applies to **/*.vue : Avoid new usage of PrimeVue components; use VueUse, shadcn/vue, or Reka UI instead

Applied to files:

  • src/workbench/extensions/manager/components/manager/NodeConflictDialogContent.vue
📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Replace PrimeVue Calendar component with DatePicker

Applied to files:

  • src/workbench/extensions/manager/components/manager/NodeConflictDialogContent.vue
📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Replace PrimeVue Chips component with AutoComplete with multiple enabled

Applied to files:

  • src/workbench/extensions/manager/components/manager/NodeConflictDialogContent.vue
📚 Learning: 2025-12-21T06:04:12.562Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-21T06:04:12.562Z
Learning: Applies to **/*.vue : Use Vue 3.5+ with TypeScript in `.vue` files, exclusively using Composition API with `<script setup lang="ts">` syntax

Applied to files:

  • src/workbench/extensions/manager/components/manager/NodeConflictDialogContent.vue
📚 Learning: 2025-11-24T19:47:02.860Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T19:47:02.860Z
Learning: Applies to src/**/*.{vue,ts} : Leverage VueUse functions for performance-enhancing styles

Applied to files:

  • src/workbench/extensions/manager/components/manager/NodeConflictDialogContent.vue
📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.{vue,ts,js} : Use vue-i18n for ALL UI strings

Applied to files:

  • src/workbench/extensions/manager/components/manager/NodeConflictDialogContent.vue
📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Use setup() function in Vue 3 Composition API

Applied to files:

  • src/workbench/extensions/manager/components/manager/NodeConflictDialogContent.vue
📚 Learning: 2025-11-24T19:47:34.324Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:34.324Z
Learning: Applies to src/**/*.{vue,ts,tsx} : Follow Vue 3 composition API style guide

Applied to files:

  • src/workbench/extensions/manager/components/manager/NodeConflictDialogContent.vue
📚 Learning: 2025-12-09T21:40:12.361Z
Learnt from: benceruleanlu
Repo: Comfy-Org/ComfyUI_frontend PR: 7297
File: src/components/actionbar/ComfyActionbar.vue:33-43
Timestamp: 2025-12-09T21:40:12.361Z
Learning: In Vue single-file components, allow inline Tailwind CSS class strings for static classes and avoid extracting them into computed properties solely for readability. Prefer keeping static class names inline for simplicity and performance. For dynamic or conditional classes, use Vue bindings (e.g., :class) to compose classes.

Applies to all Vue files in the repository (e.g., src/**/*.vue) where Tailwind utilities are used for static styling.

Applied to files:

  • src/workbench/extensions/manager/components/manager/NodeConflictDialogContent.vue
📚 Learning: 2025-12-16T22:26:49.463Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7537
File: src/components/ui/button/Button.vue:17-17
Timestamp: 2025-12-16T22:26:49.463Z
Learning: In Vue 3.5+ with <script setup>, when using defineProps<Props>() with partial destructuring (e.g., const { as = 'button', class: customClass = '' } = defineProps<Props>() ), props that are not destructured (e.g., variant, size) stay accessible by name in the template scope. This pattern is valid: you can destructure only a subset of props for convenience while referencing the remaining props directly in template expressions. Apply this guideline to Vue components across the codebase (all .vue files).

Applied to files:

  • src/workbench/extensions/manager/components/manager/NodeConflictDialogContent.vue
📚 Learning: 2025-12-22T21:36:08.369Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7649
File: src/platform/cloud/subscription/components/PricingTable.vue:185-201
Timestamp: 2025-12-22T21:36:08.369Z
Learning: In Vue components, avoid creating single-use variants for common UI components (e.g., Button and other shared components). Aim for reusable variants that cover multiple use cases. It’s acceptable to temporarily mix variant props with inline Tailwind classes when a styling need is unique to one place, but plan and consolidate into shared, reusable variants as patterns emerge across the codebase.

Applied to files:

  • src/workbench/extensions/manager/components/manager/NodeConflictDialogContent.vue
📚 Learning: 2025-12-18T02:07:38.870Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7598
File: src/components/sidebar/tabs/AssetsSidebarTab.vue:131-131
Timestamp: 2025-12-18T02:07:38.870Z
Learning: Tailwind CSS v4 safe utilities (e.g., items-center-safe, justify-*-safe, place-*-safe) are allowed in Vue components under src/ and in story files. Do not flag these specific safe variants as invalid when reviewing code in src/**/*.vue or related stories.

Applied to files:

  • src/workbench/extensions/manager/components/manager/NodeConflictDialogContent.vue
📚 Learning: 2025-12-18T21:15:46.862Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7603
File: src/components/queue/QueueOverlayHeader.vue:49-59
Timestamp: 2025-12-18T21:15:46.862Z
Learning: In the ComfyUI_frontend repository, for Vue components, do not add aria-label to buttons that have visible text content (e.g., buttons containing <span> text). The visible text provides the accessible name. Use aria-label only for elements without visible labels (e.g., icon-only buttons). If a button has no visible label, provide a clear aria-label or associate with an aria-labelledby describing its action.

Applied to files:

  • src/workbench/extensions/manager/components/manager/NodeConflictDialogContent.vue
📚 Learning: 2025-12-21T01:06:02.786Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7649
File: src/components/graph/selectionToolbox/ColorPickerButton.vue:15-18
Timestamp: 2025-12-21T01:06:02.786Z
Learning: In Comfy-Org/ComfyUI_frontend, in Vue component files, when a filled icon is required (e.g., 'pi pi-circle-fill'), you may mix PrimeIcons with Lucide icons since Lucide lacks filled variants. This mixed usage is acceptable when one icon library does not provide an equivalent filled icon. Apply consistently across Vue components in the src directory where icons are used, and document the rationale when a mixed approach is chosen.

Applied to files:

  • src/workbench/extensions/manager/components/manager/NodeConflictDialogContent.vue
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
  • GitHub Check: setup
  • GitHub Check: lint-and-format
  • GitHub Check: collect
  • GitHub Check: test
🔇 Additional comments (3)
src/locales/en/main.json (1)

122-123: Translation keys correctly added.

The new scrollLeft and scrollRight keys follow the existing naming conventions, are properly placed in the settings block, and maintain consistent formatting. Per learnings, other locale files are auto-generated, so updating only the English file is correct.

tests-ui/tests/components/dialog/content/manager/NodeConflictDialogContent.test.ts (1)

3-3: LGTM! Button import correctly migrated to local component.

The import change from PrimeVue Button to the local @/components/ui/button/Button.vue aligns with the PR objectives and follows the pattern of avoiding new PrimeVue usage. Based on learnings, the test correctly imports the real Button component rather than stubbing it.

src/workbench/extensions/manager/components/manager/NodeConflictDialogContent.vue (1)

169-169: LGTM! Button import correctly migrated to local component.

The import change from PrimeVue to the local Button component aligns with the PR objectives and repository guidelines to avoid new PrimeVue usage.

Comment on lines +33 to +41
<Button variant="textonly" class="bg-transparent text-muted">
<i
:class="
importFailedExpanded
? 'pi pi-chevron-down text-xs'
: 'pi pi-chevron-right text-xs'
"
/>
</Button>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Add aria-label to icon-only button for accessibility.

This button contains only an icon without visible text and lacks an aria-label attribute. Screen readers cannot convey the button's purpose to users.

🔎 Recommended fix: Add descriptive aria-label
-            <Button variant="textonly" class="bg-transparent text-muted">
+            <Button 
+              variant="textonly" 
+              class="bg-transparent text-muted"
+              :aria-label="
+                importFailedExpanded 
+                  ? $t('manager.conflicts.collapseImportFailed') 
+                  : $t('manager.conflicts.expandImportFailed')
+              "
+            >
               <i
                 :class="
                   importFailedExpanded

Note: Add corresponding translation keys to src/locales/en/main.json for the aria-label text.

As per coding guidelines, icon-only buttons must have aria-label attributes for screen reader accessibility.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
<Button variant="textonly" class="bg-transparent text-muted">
<i
:class="
importFailedExpanded
? 'pi pi-chevron-down text-xs'
: 'pi pi-chevron-right text-xs'
"
/>
</Button>
<Button
variant="textonly"
class="bg-transparent text-muted"
:aria-label="
importFailedExpanded
? $t('manager.conflicts.collapseImportFailed')
: $t('manager.conflicts.expandImportFailed')
"
>
<i
:class="
importFailedExpanded
? 'pi pi-chevron-down text-xs'
: 'pi pi-chevron-right text-xs'
"
/>
</Button>
🤖 Prompt for AI Agents
In
src/workbench/extensions/manager/components/manager/NodeConflictDialogContent.vue
around lines 33 to 41, the icon-only Button lacks an aria-label; add a
descriptive aria-label using the i18n translation function (e.g.
$t('nodeConflict.toggleDetails') or similar key) on the Button element so screen
readers can convey its purpose, and add the corresponding translation entry to
src/locales/en/main.json with an appropriate English string like "Toggle failed
imports details".

Comment on lines +81 to +89
<Button variant="textonly" class="bg-transparent text-muted">
<i
:class="
conflictsExpanded
? 'pi pi-chevron-down text-xs'
: 'pi pi-chevron-right text-xs'
"
/>
</Button>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Add aria-label to icon-only button for accessibility.

This button has the same accessibility issue as the import failed panel button: it contains only an icon without visible text and lacks an aria-label attribute.

🔎 Recommended fix: Add descriptive aria-label
-            <Button variant="textonly" class="bg-transparent text-muted">
+            <Button 
+              variant="textonly" 
+              class="bg-transparent text-muted"
+              :aria-label="
+                conflictsExpanded 
+                  ? $t('manager.conflicts.collapseConflicts') 
+                  : $t('manager.conflicts.expandConflicts')
+              "
+            >
               <i
                 :class="
                   conflictsExpanded

Note: Add corresponding translation keys to src/locales/en/main.json.

As per coding guidelines, icon-only buttons must have aria-label attributes for screen reader accessibility.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
<Button variant="textonly" class="bg-transparent text-muted">
<i
:class="
conflictsExpanded
? 'pi pi-chevron-down text-xs'
: 'pi pi-chevron-right text-xs'
"
/>
</Button>
<Button
variant="textonly"
class="bg-transparent text-muted"
:aria-label="
conflictsExpanded
? $t('manager.conflicts.collapseConflicts')
: $t('manager.conflicts.expandConflicts')
"
>
<i
:class="
conflictsExpanded
? 'pi pi-chevron-down text-xs'
: 'pi pi-chevron-right text-xs'
"
/>
</Button>
🤖 Prompt for AI Agents
In
src/workbench/extensions/manager/components/manager/NodeConflictDialogContent.vue
around lines 81 to 89, the icon-only Button lacks an aria-label; add a
descriptive aria-label attribute that uses a new translation key (e.g.
"nodes.conflicts.toggleDetails") and wire it to the i18n lookup (this is an
aria-label prop on the Button), then add the corresponding English entry to
src/locales/en/main.json with an appropriate string like "Toggle conflict
details". Ensure the aria-label is descriptive and localized.

Comment on lines +129 to +137
<Button variant="textonly" class="bg-transparent text-muted">
<i
:class="
extensionsExpanded
? 'pi pi-chevron-down text-xs'
: 'pi pi-chevron-right text-xs'
"
/>
</Button>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Add aria-label to icon-only button for accessibility.

This button has the same accessibility issue: it contains only an icon without visible text and lacks an aria-label attribute.

🔎 Recommended fix: Add descriptive aria-label
-            <Button variant="textonly" class="bg-transparent text-muted">
+            <Button 
+              variant="textonly" 
+              class="bg-transparent text-muted"
+              :aria-label="
+                extensionsExpanded 
+                  ? $t('manager.conflicts.collapseExtensions') 
+                  : $t('manager.conflicts.expandExtensions')
+              "
+            >
               <i
                 :class="
                   extensionsExpanded

Note: Add corresponding translation keys to src/locales/en/main.json.

As per coding guidelines, icon-only buttons must have aria-label attributes for screen reader accessibility.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
<Button variant="textonly" class="bg-transparent text-muted">
<i
:class="
extensionsExpanded
? 'pi pi-chevron-down text-xs'
: 'pi pi-chevron-right text-xs'
"
/>
</Button>
<Button
variant="textonly"
class="bg-transparent text-muted"
:aria-label="
extensionsExpanded
? $t('manager.conflicts.collapseExtensions')
: $t('manager.conflicts.expandExtensions')
"
>
<i
:class="
extensionsExpanded
? 'pi pi-chevron-down text-xs'
: 'pi pi-chevron-right text-xs'
"
/>
</Button>
🤖 Prompt for AI Agents
In
src/workbench/extensions/manager/components/manager/NodeConflictDialogContent.vue
around lines 129 to 137, the Button is icon-only and missing an aria-label; add
a descriptive aria-label attribute bound to a translation key (e.g.
$t('extensions.manager.collapseToggle')) on the Button element and add the
corresponding key/value to src/locales/en/main.json; ensure the aria-label
describes the button action (toggle expand/collapse) and update any tests or
snapshots if needed.

Comment on lines 232 to 234
const chevronButton = wrapper.findComponent(Button)
expect(chevronButton.props('icon')).toContain('pi-chevron-down')
expect(chevronButton.find('i').classes()).toContain('pi-chevron-down')
})
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick | 🔵 Trivial

Consider making the button selector more specific.

The test correctly validates the new slot-based icon rendering by checking the inner i element's classes. However, findComponent(Button) returns the first Button in the tree. Since the component has three buttons, this could be fragile if the DOM structure changes.

🔎 Optional: Make selector more specific
-      const chevronButton = wrapper.findComponent(Button)
-      expect(chevronButton.find('i').classes()).toContain('pi-chevron-down')
+      const expandedPanel = wrapper.find('[data-testid="conflict-dialog-panel-expanded"]')
+      const chevronButton = expandedPanel.element.previousElementSibling?.querySelector('button')
+      expect(chevronButton?.querySelector('i')?.classList).toContain('pi-chevron-down')

Alternatively, add data-testid to the specific button being tested.

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
In
tests-ui/tests/components/dialog/content/manager/NodeConflictDialogContent.test.ts
around lines 232 to 234, the test uses findComponent(Button) which returns the
first Button and is brittle because the component contains three buttons; update
the selector to target the specific chevron button (either by using
findAllComponents(Button) and selecting the correct index or, preferably, add a
data-testid attribute to the chevron button in the component and use
wrapper.find('[data-testid="chevron-button"]')) so the test asserts the icon on
the intended button reliably.

Comment on lines +421 to 427
expect(
button
.find('i')
.classes()
.some((c) => /pi-chevron-(right|down)/.test(c))
).toBe(true)
})
Copy link
Contributor

@coderabbitai coderabbitai bot Dec 29, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick | 🔵 Trivial

Consider validating aria-labels for icon-only buttons.

The test correctly validates that buttons contain chevron icons using the new slot-based pattern. However, these are icon-only buttons without visible text, so they should have aria-labels for accessibility.

🔎 Suggested enhancement for accessibility testing
 buttons.forEach((button) => {
   expect(
     button
       .find('i')
       .classes()
       .some((c) => /pi-chevron-(right|down)/.test(c))
   ).toBe(true)
+  // Verify icon-only buttons have aria-label
+  expect(button.attributes('aria-label')).toBeTruthy()
 })

This ensures the component provides proper accessibility attributes for screen readers.

🤖 Prompt for AI Agents
In
tests-ui/tests/components/dialog/content/manager/NodeConflictDialogContent.test.ts
around lines 421 to 427, the test asserts the presence of chevron icon classes
but doesn't validate accessibility for icon-only buttons; update the test to
also assert that the icon-only button(s) include a meaningful aria-label (or
aria-labelledby) attribute (e.g., check button.attributes('aria-label') or
button.attributes('aria-labelledby') is present and non-empty or matches
expected label), ensuring the test fails if the aria attribute is missing or
empty.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is that an assertion about some unit of behavior that belongs in a unit test or is it a style-guide requirement that should be handled by a linter or other static analysis tool?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@DrJKL You're absolutely right—that's a good distinction.

Asserting the presence of aria-label is more of a style-guide or accessibility compliance requirement rather than a unit of behavior. The test is already verifying the behavioral aspect: that the chevron icon renders correctly with the new slot-based pattern.

Accessibility compliance checks like "icon-only buttons must have aria-labels" are better handled by:

  • Linters like eslint-plugin-vuejs-accessibility or eslint-plugin-jsx-a11y
  • Automated accessibility testing tools like jest-axe, @axe-core/playwright, or axe-core
  • Dedicated accessibility test suites that run separately from unit tests

Unit tests should focus on the component's behavior (e.g., "does the button toggle the panel?", "does it show the correct icon?"), while linters and accessibility tools ensure compliance with accessibility standards.

My suggestion was overly prescriptive for a unit test—your instinct is correct here. The current test properly validates the behavioral change from prop-based icons to slot-based icons.


🧠 Learnings used
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: tests-ui/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:48:03.270Z
Learning: Check tests-ui/README.md for test guidelines

Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: tests-ui/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:48:03.270Z
Learning: Applies to tests-ui/**/*.test.{js,ts,jsx,tsx} : Follow existing test patterns in the codebase

Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: tests-ui/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:48:03.270Z
Learning: Applies to tests-ui/**/*.test.{js,ts,jsx,tsx} : Write tests for new features

Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7603
File: src/components/queue/QueueOverlayHeader.vue:49-59
Timestamp: 2025-12-18T21:15:54.349Z
Learning: For Vue components in Comfy-Org/ComfyUI_frontend: Do not suggest adding aria-label to buttons that already have visible text content (e.g., <span> elements with labels). The visible text automatically provides the accessible name. aria-label should only be used for elements without visible labels, such as icon-only buttons.

Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7303
File: src/components/topbar/CurrentUserPopover.test.ts:199-205
Timestamp: 2025-12-10T03:09:19.636Z
Learning: For test files in the Comfy-Org/ComfyUI_frontend repository: When writing tests, prefer selecting elements by accessible properties (text content, aria-label, role, accessible name) over data-testid attributes. This ensures tests verify actual user-facing behavior and accessibility compliance.

Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-21T06:04:12.562Z
Learning: Applies to **/*.test.ts : Aim for behavioral coverage of critical and new features in unit tests

Learnt from: christian-byrne
Repo: Comfy-Org/ComfyUI_frontend PR: 6300
File: src/platform/updates/components/WhatsNewPopup.vue:5-13
Timestamp: 2025-12-09T03:50:03.127Z
Learning: In the Comfy-Org/ComfyUI_frontend repository, when avoiding PrimeVue components, prefer using the repo's common button components from src/components/button/ (IconButton.vue, TextButton.vue, IconTextButton.vue) rather than plain HTML buttons. These components wrap PrimeVue with custom design system styling.

Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Replace PrimeVue InputSwitch component with ToggleSwitch

Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Replace PrimeVue Steps component with Stepper without panels

Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Replace PrimeVue InlineMessage component with Message

Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Replace PrimeVue OverlayPanel component with Popover

Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Replace PrimeVue Sidebar component with Drawer

Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Replace PrimeVue TabMenu component with Tabs without panels

Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-21T06:04:12.562Z
Learning: Applies to **/*.vue : Avoid new usage of PrimeVue components; use VueUse, shadcn/vue, or Reka UI instead

Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Replace PrimeVue Dropdown component with Select

Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Replace PrimeVue Chips component with AutoComplete with multiple enabled

@github-actions github-actions bot removed the New Browser Test Expectations New browser test screenshot should be set by github action label Dec 29, 2025
Copy link
Collaborator

@AustinMroz AustinMroz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

type="submit"
variant="primary"
:loading="loading"
:disabled="loading"
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
:disabled="loading"

Button automatically sets disabled if loading?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's how it was before, yeah

@DrJKL DrJKL merged commit 7b68b19 into main Dec 29, 2025
3 checks passed
@DrJKL DrJKL deleted the drjkl/button-the-fourth branch December 29, 2025 23:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

claude-review Add to trigger a PR code review from Claude Code size:M This PR changes 30-99 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants