Skip to content

feat(ui): add TagsInput component with click-to-edit behavior#8066

Merged
DrJKL merged 19 commits intomainfrom
drjkl/some-people-call-it-a-yard-sale
Jan 15, 2026
Merged

feat(ui): add TagsInput component with click-to-edit behavior#8066
DrJKL merged 19 commits intomainfrom
drjkl/some-people-call-it-a-yard-sale

Conversation

@DrJKL
Copy link
Contributor

@DrJKL DrJKL commented Jan 15, 2026

Summary

Add TagsInput component based on shadcn-vue/Reka UI primitives with a click-to-edit UX pattern.

Features

  • Click-to-edit behavior: Starts in read-only state; clicking enables editing and focuses input; clicking outside exits edit mode
  • Disabled state: When disabled=true, component is completely inert
  • Empty state placeholder: Shows input placeholder when tag list is empty
  • Animated transitions: Delete button animates when toggling edit mode

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Jan 15, 2026

📝 Walkthrough
✨ Finishing touches
  • 📝 Generate docstrings


📜 Recent review details

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 5d21cfe and fd1ce93.

📒 Files selected for processing (2)
  • packages/design-system/src/css/style.css
  • src/components/ui/tags-input/TagsInput.test.ts
🧰 Additional context used
📓 Path-based instructions (11)
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/ui/tags-input/TagsInput.test.ts
src/**/*.ts

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

src/**/*.ts: Use es-toolkit for utility functions
Use TypeScript for type safety

src/**/*.ts: Derive component types using vue-component-type-helpers (ComponentProps, ComponentSlots) instead of separate type files
Use es-toolkit for utility functions
Minimize the surface area (exported values) of each module and composable
Favor pure functions, especially testable ones

Files:

  • src/components/ui/tags-input/TagsInput.test.ts
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}: Use separate import type statements instead of inline type in mixed imports
Apply Prettier formatting with 2-space indentation, single quotes, no trailing semicolons, 80-character width
Sort and group imports by plugin, run pnpm format before committing
Never use any type - use proper TypeScript types
Never use as any type assertions - fix the underlying type issue
Write code that is expressive and self-documenting - avoid unnecessary comments
Do not add or retain redundant comments - clean as you go
Avoid mutable state - prefer immutability and assignment at point of declaration
Watch out for Code Smells and refactor to avoid them

Files:

  • src/components/ui/tags-input/TagsInput.test.ts
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/ui/tags-input/TagsInput.test.ts
src/**/*.{vue,ts,tsx}

📄 CodeRabbit inference engine (src/CLAUDE.md)

Follow Vue 3 composition API style guide

Files:

  • src/components/ui/tags-input/TagsInput.test.ts
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/ui/tags-input/TagsInput.test.ts
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/ui/tags-input/TagsInput.test.ts
+(tests-ui|src)/**/*.test.ts

📄 CodeRabbit inference engine (AGENTS.md)

+(tests-ui|src)/**/*.test.ts: Unit and component tests belong in tests-ui/ or src/**/*.test.ts using Vitest
Write tests for all changes, especially bug fixes to catch future regressions
Do not write tests dependent on non-behavioral features like utility classes or styles
Do not write tests that just test the mocks - ensure tests fail when code behaves unexpectedly
Leverage Vitest's utilities for mocking where possible
Keep module mocks contained - do not use global mutable state within test files; use vi.hoisted() if necessary
Use Vue Test Utils for Component testing and follow best practices for making components easy to test
Aim for behavioral coverage of critical and new features in unit tests

Files:

  • src/components/ui/tags-input/TagsInput.test.ts
src/**/*.{ts,vue}

📄 CodeRabbit inference engine (AGENTS.md)

src/**/*.{ts,vue}: Use ref for reactive state, computed() for derived values, and watch/watchEffect for side effects in Composition API
Avoid using ref with watch if a computed would suffice - minimize refs and derived state
Use provide/inject for dependency injection only when simpler alternatives (Store or shared composable) won't work
Leverage VueUse functions for performance-enhancing composables
Use VueUse function for useI18n in composition API for string literals

Files:

  • src/components/ui/tags-input/TagsInput.test.ts
src/**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

src/**/*.{ts,tsx}: Keep functions short and functional
Minimize nesting (if statements, for loops, etc.)
Use function declarations instead of function expressions when possible

Files:

  • src/components/ui/tags-input/TagsInput.test.ts
+(tests-ui|src|browser_tests)/**/*.+(test.ts|spec.ts)

📄 CodeRabbit inference engine (AGENTS.md)

+(tests-ui|src|browser_tests)/**/*.+(test.ts|spec.ts): Do not write change detector tests - avoid tests that only assert default values
Be parsimonious in testing - do not write redundant tests
Don't Mock What You Don't Own

Files:

  • src/components/ui/tags-input/TagsInput.test.ts
🧠 Learnings (32)
📚 Learning: 2026-01-10T00:24:17.695Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-10T00:24:17.695Z
Learning: Applies to +(tests-ui|src)/**/*.test.ts : Write tests for all changes, especially bug fixes to catch future regressions

Applied to files:

  • src/components/ui/tags-input/TagsInput.test.ts
📚 Learning: 2026-01-10T00:24:17.695Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-10T00:24:17.695Z
Learning: Applies to +(tests-ui|src)/**/*.test.ts : Aim for behavioral coverage of critical and new features in unit tests

Applied to files:

  • src/components/ui/tags-input/TagsInput.test.ts
📚 Learning: 2026-01-10T00:24:17.695Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-10T00:24:17.695Z
Learning: Applies to +(tests-ui|src)/**/*.test.ts : Use Vue Test Utils for Component testing and follow best practices for making components easy to test

Applied to files:

  • src/components/ui/tags-input/TagsInput.test.ts
📚 Learning: 2026-01-10T00:24:17.695Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-10T00:24:17.695Z
Learning: Applies to +(tests-ui|src)/**/*.test.ts : Unit and component tests belong in `tests-ui/` or `src/**/*.test.ts` using Vitest

Applied to files:

  • src/components/ui/tags-input/TagsInput.test.ts
📚 Learning: 2026-01-10T00:24:17.695Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-10T00:24:17.695Z
Learning: Applies to +(tests-ui|src)/**/*.test.ts : Do not write tests dependent on non-behavioral features like utility classes or styles

Applied to files:

  • src/components/ui/tags-input/TagsInput.test.ts
📚 Learning: 2026-01-10T00:24:17.695Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-10T00:24:17.695Z
Learning: Applies to browser_tests/**/*.spec.ts : Use tags like `mobile`, `2x` in Playwright tests for configuration-aware test selection

Applied to files:

  • src/components/ui/tags-input/TagsInput.test.ts
📚 Learning: 2026-01-10T00:24:17.695Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-10T00:24:17.695Z
Learning: Applies to +(tests-ui|src|browser_tests)/**/*.+(test.ts|spec.ts) : Do not write change detector tests - avoid tests that only assert default values

Applied to files:

  • src/components/ui/tags-input/TagsInput.test.ts
📚 Learning: 2026-01-10T00:24:17.695Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-10T00:24:17.695Z
Learning: Applies to +(tests-ui|src|browser_tests)/**/*.+(test.ts|spec.ts) : Be parsimonious in testing - do not write redundant tests

Applied to files:

  • src/components/ui/tags-input/TagsInput.test.ts
📚 Learning: 2026-01-10T00:24:17.695Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-10T00:24:17.695Z
Learning: Applies to +(tests-ui|src)/**/*.test.ts : Leverage Vitest's utilities for mocking where possible

Applied to files:

  • src/components/ui/tags-input/TagsInput.test.ts
📚 Learning: 2026-01-08T02:40:15.482Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7894
File: src/renderer/extensions/vueNodes/widgets/components/WidgetToggleSwitch.test.ts:11-14
Timestamp: 2026-01-08T02:40:15.482Z
Learning: In TypeScript test files (e.g., any test under src), avoid duplicating interface/type definitions. Import real type definitions from the component modules under test and reference them directly, so there is a single source of truth and to prevent type drift. This improves maintainability and consistency across tests.

Applied to files:

  • src/components/ui/tags-input/TagsInput.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:

  • src/components/ui/tags-input/TagsInput.test.ts
📚 Learning: 2026-01-10T00:24:17.695Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-10T00:24:17.695Z
Learning: Applies to +(tests-ui|src)/**/*.test.ts : Do not write tests that just test the mocks - ensure tests fail when code behaves unexpectedly

Applied to files:

  • src/components/ui/tags-input/TagsInput.test.ts
📚 Learning: 2025-11-24T19:47:56.371Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/lib/litegraph/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:56.371Z
Learning: Applies to src/lib/litegraph/**/*.{test,spec}.{js,ts,jsx,tsx} : When adding features, always write vitest unit tests using cursor rules in @.cursor

Applied to files:

  • src/components/ui/tags-input/TagsInput.test.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} : Prefer specific selectors in browser tests

Applied to files:

  • src/components/ui/tags-input/TagsInput.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 `test` instead of `it` for defining test cases in vitest

Applied to files:

  • src/components/ui/tags-input/TagsInput.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:

  • src/components/ui/tags-input/TagsInput.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} : Prefer the use of `test.extend` over loose variables; import `test as baseTest` from `vitest`

Applied to files:

  • src/components/ui/tags-input/TagsInput.test.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:

  • src/components/ui/tags-input/TagsInput.test.ts
📚 Learning: 2026-01-10T00:24:17.695Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-10T00:24:17.695Z
Learning: Applies to +(tests-ui|src)/**/*.test.ts : Keep module mocks contained - do not use global mutable state within test files; use `vi.hoisted()` if necessary

Applied to files:

  • src/components/ui/tags-input/TagsInput.test.ts
📚 Learning: 2025-12-05T08:52:50.787Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7137
File: src/components/rightSidePanel/parameters/SectionWidgets.vue:41-49
Timestamp: 2025-12-05T08:52:50.787Z
Learning: In Vue 3.4+ SFCs with a build step, kebab-case prop shorthand (e.g., `:is-empty`) automatically resolves to the corresponding camelCase variable in scope (e.g., `isEmpty`). This is valid syntax combining same-name shorthand with automatic kebab-case-to-camelCase conversion and should not be flagged as an error.

Applied to files:

  • src/components/ui/tags-input/TagsInput.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,ts,js} : Use vue-i18n for ALL UI strings

Applied to files:

  • src/components/ui/tags-input/TagsInput.test.ts
📚 Learning: 2026-01-10T00:24:17.695Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-10T00:24:17.695Z
Learning: Applies to src/**/*.{ts,vue} : Use VueUse function for useI18n in composition API for string literals

Applied to files:

  • src/components/ui/tags-input/TagsInput.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:

  • src/components/ui/tags-input/TagsInput.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:

  • src/components/ui/tags-input/TagsInput.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:

  • src/components/ui/tags-input/TagsInput.test.ts
📚 Learning: 2025-12-30T22:22:33.836Z
Learnt from: kaili-yang
Repo: Comfy-Org/ComfyUI_frontend PR: 7805
File: src/composables/useCoreCommands.ts:439-439
Timestamp: 2025-12-30T22:22:33.836Z
Learning: When accessing reactive properties from Pinia stores in TypeScript files, avoid using .value on direct property access (e.g., useStore().isOverlayExpanded). Pinia auto-wraps refs when accessed directly, returning the primitive value. The .value accessor is only needed when destructuring store properties or when using storeToRefs().

Applied to files:

  • src/components/ui/tags-input/TagsInput.test.ts
📚 Learning: 2025-12-30T01:31:04.927Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7797
File: tests-ui/tests/lib/litegraph/src/widgets/ComboWidget.test.ts:648-648
Timestamp: 2025-12-30T01:31:04.927Z
Learning: In Vitest v4, when mocking functions that may be called as constructors (using new), the mock implementation must use function() or class syntax rather than an arrow function. Arrow mocks can cause '<anonymous> is not a constructor' errors. This is a breaking change from Vitest v3 where mocks could use an arrow function. Apply this guideline to test files that mock constructor-like calls (e.g., in tests under tests-ui, such as ComboWidget.test.ts) and ensure mock implementations are defined with function() { ... } or class { ... } to preserve constructor behavior.

Applied to files:

  • src/components/ui/tags-input/TagsInput.test.ts
📚 Learning: 2026-01-09T02:07:54.558Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7898
File: src/composables/usePaste.test.ts:248-248
Timestamp: 2026-01-09T02:07:54.558Z
Learning: In test files (e.g., any .test.ts or .test.tsx under src/...), when you create mock objects that partially implement an interface (such as LGraphNode), prefer casting with as Partial<InterfaceType> as InterfaceType rather than as any or as unknown as InterfaceType. This makes the incomplete implementation explicit while preserving type safety, improving readability and maintainability of tests.

Applied to files:

  • src/components/ui/tags-input/TagsInput.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:

  • src/components/ui/tags-input/TagsInput.test.ts
📚 Learning: 2026-01-12T17:39:27.738Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7906
File: src/components/sidebar/tabs/AssetsSidebarTab.vue:545-552
Timestamp: 2026-01-12T17:39:27.738Z
Learning: In Vue/TypeScript files (src/**/*.{ts,tsx,vue}), prefer if/else statements over ternary operators when performing side effects or actions (e.g., mutating state, calling methods with side effects). Ternaries should be reserved for computing and returning values.

Applied to files:

  • src/components/ui/tags-input/TagsInput.test.ts
📚 Learning: 2026-01-10T00:24:17.695Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-10T00:24:17.695Z
Learning: Applies to src/**/*.vue : Use Tailwind utility classes instead of `dark:` variant - use semantic values from `style.css` theme (e.g., `bg-node-component-surface`)

Applied to files:

  • packages/design-system/src/css/style.css
📚 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,css} : Use the correct tokens from style.css in the design system package

Applied to files:

  • packages/design-system/src/css/style.css
🧬 Code graph analysis (1)
src/components/ui/tags-input/TagsInput.test.ts (1)
src/extensions/core/widgetInputs.ts (1)
  • input (355-368)
⏰ 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: test
  • GitHub Check: lint-and-format
  • GitHub Check: setup
  • GitHub Check: collect
🔇 Additional comments (5)
packages/design-system/src/css/style.css (1)

285-285: LGTM!

The design token update from --color-smoke-400 to --color-smoke-200 provides a lighter tag background in light theme. This aligns with the new TagsInput component being added in this PR. Based on learnings, this follows the correct pattern of using semantic tokens from style.css in the design system.

src/components/ui/tags-input/TagsInput.test.ts (4)

12-34: LGTM!

Clean i18n setup for tests with minimal messages, and the basic slot rendering test is appropriately simple.


36-74: LGTM!

Well-structured helper function and consolidated structural test that verifies both component structure and text content. This appropriately addresses the previous review feedback.


76-100: LGTM!

Solid behavioral test that verifies the v-model update cycle when adding a new tag via user interaction.


102-142: LGTM!

Good coverage of the disabled state and click-outside behaviors. The click-outside test properly attaches to the DOM and cleans up with unmount().

✏️ Tip: You can disable this entire section by setting review_details to false in your review settings.


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 Jan 15, 2026

🎨 Storybook Build Status

Build completed successfully!

⏰ Completed at: 01/15/2026, 04:48:18 AM UTC

🔗 Links


🎉 Your Storybook is ready for review!

@github-actions
Copy link

github-actions bot commented Jan 15, 2026

🎭 Playwright Tests: ⚠️ Passed with flaky tests

Results: 505 passed, 0 failed, 1 flaky, 8 skipped (Total: 514)

❌ Failed Tests

📊 Browser Reports
  • chromium: View Report (✅ 495 / ❌ 0 / ⚠️ 0 / ⏭️ 8)
  • chromium-2x: View Report (✅ 2 / ❌ 0 / ⚠️ 0 / ⏭️ 0)
  • chromium-0.5x: View Report (✅ 1 / ❌ 0 / ⚠️ 0 / ⏭️ 0)
  • mobile-chrome: View Report (✅ 7 / ❌ 0 / ⚠️ 1 / ⏭️ 0)

@github-actions
Copy link

github-actions bot commented Jan 15, 2026

Bundle Size Report

Summary

  • Raw size: 19.7 MB baseline 19.7 MB — 🔴 +27 B
  • Gzip: 4.01 MB baseline 4.01 MB — 🔴 +22 B
  • Brotli: 3.06 MB baseline 3.06 MB — 🟢 -10 B
  • Bundles: 99 current • 99 baseline • 38 added / 38 removed

Category Glance
App Entry Points 🔴 +27 B (3.34 MB) · Vendor & Third-Party ⚪ 0 B (9.34 MB) · Other ⚪ 0 B (5.25 MB) · Graph Workspace ⚪ 0 B (1.15 MB) · Panels & Settings ⚪ 0 B (372 kB) · UI Components ⚪ 0 B (209 kB) · + 3 more

Per-category breakdown
App Entry Points — 3.34 MB (baseline 3.34 MB) • 🔴 +27 B

Main entry bundles and manifests

File Before After Δ Raw Δ Gzip Δ Brotli
assets/index-CghIIweD.js (new) 3.14 MB 🔴 +3.14 MB 🔴 +657 kB 🔴 +499 kB
assets/index-BEcNU0Ot.js (removed) 3.14 MB 🟢 -3.14 MB 🟢 -657 kB 🟢 -499 kB
assets/index-B9r6AOdC.js (new) 200 kB 🔴 +200 kB 🔴 +44 kB 🔴 +36.4 kB
assets/index-DuGghTnm.js (removed) 200 kB 🟢 -200 kB 🟢 -44 kB 🟢 -36.4 kB
assets/index-CZUlS2YH.js (new) 345 B 🔴 +345 B 🔴 +245 B 🔴 +209 B
assets/index-DrtsZ6q4.js (removed) 345 B 🟢 -345 B 🟢 -246 B 🟢 -202 B

Status: 3 added / 3 removed

Graph Workspace — 1.15 MB (baseline 1.15 MB) • ⚪ 0 B

Graph editor runtime, canvas, workflow orchestration

File Before After Δ Raw Δ Gzip Δ Brotli
assets/GraphView-DA7iRHWP.js (new) 1.15 MB 🔴 +1.15 MB 🔴 +220 kB 🔴 +165 kB
assets/GraphView-SP99TtgG.js (removed) 1.15 MB 🟢 -1.15 MB 🟢 -220 kB 🟢 -165 kB

Status: 1 added / 1 removed

Views & Navigation — 6.66 kB (baseline 6.66 kB) • ⚪ 0 B

Top-level views, pages, and routed surfaces

File Before After Δ Raw Δ Gzip Δ Brotli
assets/UserSelectView-DMpz6yrH.js (removed) 6.66 kB 🟢 -6.66 kB 🟢 -2.16 kB 🟢 -1.91 kB
assets/UserSelectView-kI6Y2e9T.js (new) 6.66 kB 🔴 +6.66 kB 🔴 +2.16 kB 🔴 +1.91 kB

Status: 1 added / 1 removed

Panels & Settings — 372 kB (baseline 372 kB) • ⚪ 0 B

Configuration panels, inspectors, and settings screens

File Before After Δ Raw Δ Gzip Δ Brotli
assets/LegacyCreditsPanel-CPDZUNwl.js (new) 25.2 kB 🔴 +25.2 kB 🔴 +5.76 kB 🔴 +5.03 kB
assets/LegacyCreditsPanel-DvkWKWMK.js (removed) 25.2 kB 🟢 -25.2 kB 🟢 -5.76 kB 🟢 -5.02 kB
assets/KeybindingPanel-ApEuOX6_.js (removed) 14.9 kB 🟢 -14.9 kB 🟢 -3.59 kB 🟢 -3.14 kB
assets/KeybindingPanel-DXTmgV2W.js (new) 14.9 kB 🔴 +14.9 kB 🔴 +3.59 kB 🔴 +3.14 kB
assets/ExtensionPanel-DLoZh526.js (new) 11.1 kB 🔴 +11.1 kB 🔴 +2.63 kB 🔴 +2.31 kB
assets/ExtensionPanel-MQnu84Wn.js (removed) 11.1 kB 🟢 -11.1 kB 🟢 -2.63 kB 🟢 -2.31 kB
assets/AboutPanel-CdpRZ6jo.js (new) 9.2 kB 🔴 +9.2 kB 🔴 +2.47 kB 🔴 +2.23 kB
assets/AboutPanel-CNCcWicC.js (removed) 9.2 kB 🟢 -9.2 kB 🟢 -2.47 kB 🟢 -2.23 kB
assets/ServerConfigPanel-DhY3WYo4.js (new) 7.55 kB 🔴 +7.55 kB 🔴 +2.06 kB 🔴 +1.83 kB
assets/ServerConfigPanel-dIbItxwR.js (removed) 7.55 kB 🟢 -7.55 kB 🟢 -2.06 kB 🟢 -1.83 kB
assets/UserPanel-BHVbFuwx.js (removed) 6.92 kB 🟢 -6.92 kB 🟢 -1.81 kB 🟢 -1.58 kB
assets/UserPanel-Ct2_Wgk3.js (new) 6.92 kB 🔴 +6.92 kB 🔴 +1.8 kB 🔴 +1.58 kB
assets/settings-BGQfQzTx.js 25.6 kB 25.6 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/settings-BVE4KHTw.js 22.7 kB 22.7 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/settings-BVtpJmlU.js 30.9 kB 30.9 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/settings-C2aO00Dz.js 28.6 kB 28.6 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/settings-Cm3ieBXR.js 27.8 kB 27.8 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/settings-CzQKMdK3.js 26.2 kB 26.2 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/settings-CzYUIUnL.js 27.1 kB 27.1 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/settings-DwKpL7jw.js 26.3 kB 26.3 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/settings-DX8feV4n.js 25.3 kB 25.3 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/settings-mWzYycGc.js 22 kB 22 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/settings-U4AdZ8Rl.js 34.9 kB 34.9 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B

Status: 6 added / 6 removed

UI Components — 209 kB (baseline 209 kB) • ⚪ 0 B

Reusable component library chunks

File Before After Δ Raw Δ Gzip Δ Brotli
assets/LazyImage.vue_vue_type_script_setup_true_lang-CwMqtpea.js (removed) 69.6 kB 🟢 -69.6 kB 🟢 -14.2 kB 🟢 -12.3 kB
assets/LazyImage.vue_vue_type_script_setup_true_lang-JKBOgosZ.js (new) 69.6 kB 🔴 +69.6 kB 🔴 +14.2 kB 🔴 +12.3 kB
assets/Load3D.vue_vue_type_script_setup_true_lang-BtlgLWpR.js (removed) 56.4 kB 🟢 -56.4 kB 🟢 -8.78 kB 🟢 -7.55 kB
assets/Load3D.vue_vue_type_script_setup_true_lang-DXNkf9HF.js (new) 56.4 kB 🔴 +56.4 kB 🔴 +8.78 kB 🔴 +7.55 kB
assets/WidgetSelect.vue_vue_type_script_setup_true_lang-6nuypd2K.js (removed) 48.1 kB 🟢 -48.1 kB 🟢 -10.4 kB 🟢 -9 kB
assets/WidgetSelect.vue_vue_type_script_setup_true_lang-BWesrske.js (new) 48.1 kB 🔴 +48.1 kB 🔴 +10.4 kB 🔴 +9 kB
assets/WidgetInputNumber.vue_vue_type_script_setup_true_lang-BKF_RA5A.js (new) 16.4 kB 🔴 +16.4 kB 🔴 +4.11 kB 🔴 +3.65 kB
assets/WidgetInputNumber.vue_vue_type_script_setup_true_lang-DGzk8-6A.js (removed) 16.4 kB 🟢 -16.4 kB 🟢 -4.11 kB 🟢 -3.64 kB
assets/ComfyQueueButton-C8Jea8DJ.js (removed) 8.87 kB 🟢 -8.87 kB 🟢 -2.6 kB 🟢 -2.31 kB
assets/ComfyQueueButton-pEfPBWyk.js (new) 8.87 kB 🔴 +8.87 kB 🔴 +2.6 kB 🔴 +2.31 kB
assets/WidgetWithControl.vue_vue_type_script_setup_true_lang-DaNi360P.js (removed) 3.75 kB 🟢 -3.75 kB 🟢 -1.47 kB 🟢 -1.33 kB
assets/WidgetWithControl.vue_vue_type_script_setup_true_lang-DhiuRmi2.js (new) 3.75 kB 🔴 +3.75 kB 🔴 +1.47 kB 🔴 +1.34 kB
assets/WidgetButton-Bi4C__wu.js (new) 2.25 kB 🔴 +2.25 kB 🔴 +1.01 kB 🔴 +909 B
assets/WidgetButton-U03IDX91.js (removed) 2.25 kB 🟢 -2.25 kB 🟢 -1.01 kB 🟢 -915 B
assets/WidgetLayoutField.vue_vue_type_script_setup_true_lang-CWqLyYhx.js (new) 2.14 kB 🔴 +2.14 kB 🔴 +891 B 🔴 +772 B
assets/WidgetLayoutField.vue_vue_type_script_setup_true_lang-DgF28yMI.js (removed) 2.14 kB 🟢 -2.14 kB 🟢 -891 B 🟢 -773 B
assets/UserAvatar.vue_vue_type_script_setup_true_lang-IJTLOeU1.js 1.34 kB 1.34 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B

Status: 8 added / 8 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-BZtgVvVj.js (removed) 7.51 kB 🟢 -7.51 kB 🟢 -1.83 kB 🟢 -1.57 kB
assets/keybindingService-Chw97LEf.js (new) 7.51 kB 🔴 +7.51 kB 🔴 +1.83 kB 🔴 +1.58 kB
assets/audioService-BAbpLisu.js (new) 2.2 kB 🔴 +2.2 kB 🔴 +958 B 🔴 +821 B
assets/audioService-BQnxfEX4.js (removed) 2.2 kB 🟢 -2.2 kB 🟢 -961 B 🟢 -833 B
assets/serverConfigStore-DyIvWaGz.js 2.83 kB 2.83 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B

Status: 2 added / 2 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-27cHnfGR.js (removed) 1.41 kB 🟢 -1.41 kB 🟢 -650 B 🟢 -542 B
assets/audioUtils-CpqFOsNW.js (new) 1.41 kB 🔴 +1.41 kB 🔴 +651 B 🔴 +552 B

Status: 1 added / 1 removed

Vendor & Third-Party — 9.34 MB (baseline 9.34 MB) • ⚪ 0 B

External libraries and shared vendor chunks

File Before After Δ Raw Δ Gzip Δ Brotli
assets/vendor-chart-DZdD68iT.js 452 kB 452 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/vendor-other-C9GFBFnP.js 3.93 MB 3.93 MB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/vendor-primevue-NX-4NPlN.js 1.95 MB 1.95 MB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/vendor-reka-ui-7Sidv1he.js 111 kB 111 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/vendor-three-Bz1zdJb0.js 2.08 MB 2.08 MB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/vendor-tiptap-DFkXpum7.js 232 kB 232 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/vendor-vue-DMH2Ziq4.js 165 kB 165 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/vendor-xterm-BF8peZ5_.js 420 kB 420 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
Other — 5.25 MB (baseline 5.25 MB) • ⚪ 0 B

Bundles that do not match a named category

File Before After Δ Raw Δ Gzip Δ Brotli
assets/SubscriptionRequiredDialogContent-B1zzAvtx.js (removed) 29.3 kB 🟢 -29.3 kB 🟢 -6.5 kB 🟢 -5.66 kB
assets/SubscriptionRequiredDialogContent-BWoedvKf.js (new) 29.3 kB 🔴 +29.3 kB 🔴 +6.51 kB 🔴 +5.66 kB
assets/WidgetRecordAudio-D4Q4DjvW.js (new) 20.5 kB 🔴 +20.5 kB 🔴 +5.25 kB 🔴 +4.66 kB
assets/WidgetRecordAudio-RaQywv7a.js (removed) 20.5 kB 🟢 -20.5 kB 🟢 -5.25 kB 🟢 -4.65 kB
assets/AudioPreviewPlayer-CQDqMAsg.js (removed) 13.4 kB 🟢 -13.4 kB 🟢 -3.36 kB 🟢 -3 kB
assets/AudioPreviewPlayer-DdD5bKtX.js (new) 13.4 kB 🔴 +13.4 kB 🔴 +3.36 kB 🔴 +3.02 kB
assets/ValueControlPopover-BbglqTl4.js (new) 5.53 kB 🔴 +5.53 kB 🔴 +1.72 kB 🔴 +1.53 kB
assets/ValueControlPopover-DLLZywZF.js (removed) 5.53 kB 🟢 -5.53 kB 🟢 -1.72 kB 🟢 -1.53 kB
assets/WidgetGalleria-BpiFv0DO.js (removed) 4.14 kB 🟢 -4.14 kB 🟢 -1.46 kB 🟢 -1.32 kB
assets/WidgetGalleria-hKJqam_A.js (new) 4.14 kB 🔴 +4.14 kB 🔴 +1.46 kB 🔴 +1.32 kB
assets/WidgetColorPicker-8czklh2F.js (new) 3.44 kB 🔴 +3.44 kB 🔴 +1.4 kB 🔴 +1.25 kB
assets/WidgetColorPicker-L2KPuoKc.js (removed) 3.44 kB 🟢 -3.44 kB 🟢 -1.4 kB 🟢 -1.25 kB
assets/WidgetTextarea-B6Fs5sQw.js (removed) 3.12 kB 🟢 -3.12 kB 🟢 -1.23 kB 🟢 -1.11 kB
assets/WidgetTextarea-yBCJRakt.js (new) 3.12 kB 🔴 +3.12 kB 🔴 +1.23 kB 🔴 +1.09 kB
assets/WidgetMarkdown-BfruS-cc.js (new) 3.12 kB 🔴 +3.12 kB 🔴 +1.29 kB 🔴 +1.14 kB
assets/WidgetMarkdown-BY0IRa92.js (removed) 3.12 kB 🟢 -3.12 kB 🟢 -1.3 kB 🟢 -1.14 kB
assets/WidgetAudioUI-B8GWndMb.js (new) 2.93 kB 🔴 +2.93 kB 🔴 +1.18 kB 🔴 +1.07 kB
assets/WidgetAudioUI-CYHjWbCj.js (removed) 2.93 kB 🟢 -2.93 kB 🟢 -1.18 kB 🟢 -1.07 kB
assets/WidgetToggleSwitch-CJuPEApF.js (new) 2.7 kB 🔴 +2.7 kB 🔴 +1.14 kB 🔴 +1.03 kB
assets/WidgetToggleSwitch-CnfZGEqF.js (removed) 2.7 kB 🟢 -2.7 kB 🟢 -1.14 kB 🟢 -1.03 kB
assets/WidgetInputText-DRkV9e28.js (new) 2.03 kB 🔴 +2.03 kB 🔴 +937 B 🔴 +867 B
assets/WidgetInputText-DXSPKFmI.js (removed) 2.03 kB 🟢 -2.03 kB 🟢 -935 B 🟢 -861 B
assets/Media3DTop-DpXQuoav.js (new) 1.53 kB 🔴 +1.53 kB 🔴 +782 B 🔴 +671 B
assets/Media3DTop-DXJJsMlz.js (removed) 1.53 kB 🟢 -1.53 kB 🟢 -782 B 🟢 -672 B
assets/WidgetSelect-CircntNd.js (removed) 772 B 🟢 -772 B 🟢 -377 B 🟢 -352 B
assets/WidgetSelect-ox_Yc68o.js (new) 772 B 🔴 +772 B 🔴 +376 B 🔴 +356 B
assets/WidgetInputNumber-1m453JqL.js (new) 712 B 🔴 +712 B 🔴 +362 B 🔴 +336 B
assets/WidgetInputNumber-AV_KFNCu.js (removed) 712 B 🟢 -712 B 🟢 -361 B 🟢 -326 B
assets/Load3D-DDjZlUeh.js (new) 463 B 🔴 +463 B 🔴 +282 B 🔴 +238 B
assets/Load3D-rj29YKyb.js (removed) 463 B 🟢 -463 B 🟢 -284 B 🟢 -238 B
assets/WidgetLegacy-BEulZSau.js (new) 403 B 🔴 +403 B 🔴 +252 B 🔴 +212 B
assets/WidgetLegacy-CbW8vPQA.js (removed) 403 B 🟢 -403 B 🟢 -254 B 🟢 -213 B
assets/commands-B32ZbeYu.js 16.5 kB 16.5 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/commands-B7wQT83I.js 17 kB 17 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/commands-BK3JVjMG.js 15.7 kB 15.7 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/commands-C6twMpaZ.js 15.5 kB 15.5 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/commands-CDUWpEwM.js 18.3 kB 18.3 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/commands-CfZ6FPZ-.js 15.7 kB 15.7 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/commands-COIPP_pv.js 17 kB 17 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/commands-CoPn_77e.js 14.7 kB 14.7 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/commands-CuRNS4XD.js 14.9 kB 14.9 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/commands-DBHjCSPA.js 16.2 kB 16.2 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/commands-DZJaRLKH.js 15.7 kB 15.7 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-8eC7XcBf.js 95 kB 95 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-BpcYE6Bq.js 109 kB 109 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-BRhbiQsB.js 129 kB 129 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-BrWdnTiG.js 113 kB 113 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-C-cUNbuc.js 123 kB 123 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-CGe0e9vH.js 106 kB 106 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-Cv9Dlj-b.js 107 kB 107 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-CzsdJqwO.js 94.3 kB 94.3 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-Dbu4m_fl.js 133 kB 133 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-DwAX_AEJ.js 149 kB 149 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/main-kiVYDd2_.js 110 kB 110 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/MediaAudioTop-DUiRGHAk.js 1.46 kB 1.46 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/MediaImageTop-bDoNEAep.js 1.75 kB 1.75 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/MediaVideoTop-BrNs2ijx.js 2.65 kB 2.65 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-B-XzzBeS.js 317 kB 317 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-BGwoeek4.js 329 kB 329 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-C6xl5-mL.js 358 kB 358 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-CRZGOJB7.js 310 kB 310 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-D8-Yzlzh.js 289 kB 289 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-Du8VrAwA.js 320 kB 320 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-jjlLVrIs.js 317 kB 317 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-JQwk1kgy.js 292 kB 292 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-JuuXdMpv.js 391 kB 391 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-l2Y20bod.js 314 kB 314 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/nodeDefs-VLMdhOwo.js 357 kB 357 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/OBJLoader2WorkerModule-DTMpvldF.js 109 kB 109 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/WidgetChart-CTa5K4p_.js 2.48 kB 2.48 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/WidgetImageCompare-BAyqYPiH.js 3.21 kB 3.21 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B
assets/widgetPropFilter-BIbGSUAt.js 1.28 kB 1.28 kB ⚪ 0 B ⚪ 0 B ⚪ 0 B

Status: 16 added / 16 removed

@DrJKL DrJKL marked this pull request as ready for review January 15, 2026 02:43
@DrJKL DrJKL requested a review from a team as a code owner January 15, 2026 02:43
@dosubot dosubot bot added the size:L This PR changes 100-499 lines, ignoring generated files. label Jan 15, 2026
@DrJKL DrJKL added the Design Used to request Product feedback on design decisions label Jan 15, 2026
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

🤖 Fix all issues with AI agents
In `@src/components/ui/tags-input/TagsInput.stories.ts`:
- Around line 68-91: Add an args object to the Empty story so Storybook controls
have initial values; for example, add args: { disabled: false } on the exported
Empty Story and ensure the template continues to reference args.disabled (no
code changes needed elsewhere), enabling the Controls panel to toggle disabled
for the TagsInput story.

In `@src/components/ui/tags-input/TagsInput.test.ts`:
- Around line 49-75: Consolidate the four repetitive structural tests into one
focused test: replace the separate tests ('renders tags as child items',
'renders delete buttons for each tag', 'renders tag text for each tag', 'renders
input for adding new tags') with a single test (e.g., 'renders tags structure
and content') that mounts mountFullTagsInput(['tag1','tag2']), asserts the
number of TagsInputItem, TagsInputItemDelete, and TagsInputItemText all equal
the input length, and also verifies the actual text content of each
TagsInputItemText matches the input array; keep the existing test for
TagsInputInput (or include it in the consolidated test) so presence of the input
is still asserted.
- Around line 29-101: Add unit tests covering click-to-edit behaviors missing
from TagsInput: write three tests using mount/mountFullTagsInput or mounting
TagsInput directly that assert (1) when the component is rendered with prop
disabled=true it does not enter edit mode or focus the input after a click
(reference TagsInput and TagsInputInput), (2) clicking outside the component
exits edit mode—simulate entering edit mode then dispatch a click on
document/body and assert the input is removed or blurred (reference
TagsInputInput and the component's model/update flow), and (3) when modelValue
is an empty array the empty-state placeholder text is rendered (assert
findComponent(TagsInputInput) or placeholder presence); ensure tests use the
existing mounting patterns (mountFullTagsInput or mount<typeof TagsInput>) and
await nextTick where necessary to let DOM updates settle.

In `@src/components/ui/tags-input/TagsInput.vue`:
- Around line 71-74: The decorative pen icon in TagsInput.vue (<i
v-if="!disabled && !isEditing" ... />) lacks an accessibility marker; update
that <i> element to include aria-hidden="true" so assistive tech ignores it
(keep the existing v-if logic tied to disabled and isEditing and do not change
click handlers or visibility).

In `@src/components/ui/tags-input/TagsInputItemDelete.vue`:
- Around line 28-31: In TagsInputItemDelete, the icon-only delete control needs
an accessible label: add aria-label="$t('g.removeTag')" (using vue-i18n) to the
button element that renders the <slot> / icon in the TagsInputItemDelete
component so screen readers get "Remove tag"; also add the translation key
"g.removeTag": "Remove tag" to your English locale (e.g., main.json).
📜 Review details

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 29f727a and 7cfc37f.

📒 Files selected for processing (8)
  • src/components/ui/tags-input/TagsInput.stories.ts
  • src/components/ui/tags-input/TagsInput.test.ts
  • src/components/ui/tags-input/TagsInput.vue
  • src/components/ui/tags-input/TagsInputInput.vue
  • src/components/ui/tags-input/TagsInputItem.vue
  • src/components/ui/tags-input/TagsInputItemDelete.vue
  • src/components/ui/tags-input/TagsInputItemText.vue
  • src/components/ui/tags-input/tagsInputContext.ts
🧰 Additional context used
📓 Path-based instructions (14)
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: Use Vue 3 Single File Components (SFCs) with Composition API only
Use <script setup lang="ts"> for component logic in Vue SFCs
Avoid <style> blocks in Vue components - use Tailwind 4 styling instead
Use vue-i18n for all string literals in Vue components - place translation entries in src/locales/en/main.json
Use Tailwind utility classes instead of dark: variant - use semantic values from style.css theme (e.g., bg-node-component-surface)
Use cn() utility from @/utils/tailwindUtil for merging Tailwind class names instead of :class="[]" or hardcoding
Never use !important or ! Tailwind prefix - fix interfering classes instead
Use Tailwind fraction utilities instead of arbitrary percentage values (e.g., w-4/5 instead of w-[80%])
Use TypeScript Vue 3.5 style default prop declaration with reactive props destructuring - avoid withDefaults or runtime props
Prefer defineModel over separately defining a prop and emit for v-model bindings
Define slots via template usage, not via defineSlots
Use same-name shorthand for slot prop bindings (e.g., :isExpanded instead of :is-expanded="isExpanded")
Do not import Vue macros unnecessarily
Avoid new usage of PrimeVue components
Use Tailwind's plurals system via i18n instead of hardcoding ...

Files:

  • src/components/ui/tags-input/TagsInput.vue
  • src/components/ui/tags-input/TagsInputItemText.vue
  • src/components/ui/tags-input/TagsInputItem.vue
  • src/components/ui/tags-input/TagsInputItemDelete.vue
  • src/components/ui/tags-input/TagsInputInput.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/ui/tags-input/TagsInput.vue
  • src/components/ui/tags-input/TagsInputItemText.vue
  • src/components/ui/tags-input/TagsInput.test.ts
  • src/components/ui/tags-input/TagsInput.stories.ts
  • src/components/ui/tags-input/TagsInputItem.vue
  • src/components/ui/tags-input/TagsInputItemDelete.vue
  • src/components/ui/tags-input/TagsInputInput.vue
  • src/components/ui/tags-input/tagsInputContext.ts
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}: Use separate import type statements instead of inline type in mixed imports
Apply Prettier formatting with 2-space indentation, single quotes, no trailing semicolons, 80-character width
Sort and group imports by plugin, run pnpm format before committing
Never use any type - use proper TypeScript types
Never use as any type assertions - fix the underlying type issue
Write code that is expressive and self-documenting - avoid unnecessary comments
Do not add or retain redundant comments - clean as you go
Avoid mutable state - prefer immutability and assignment at point of declaration
Watch out for Code Smells and refactor to avoid them

Files:

  • src/components/ui/tags-input/TagsInput.vue
  • src/components/ui/tags-input/TagsInputItemText.vue
  • src/components/ui/tags-input/TagsInput.test.ts
  • src/components/ui/tags-input/TagsInput.stories.ts
  • src/components/ui/tags-input/TagsInputItem.vue
  • src/components/ui/tags-input/TagsInputItemDelete.vue
  • src/components/ui/tags-input/TagsInputInput.vue
  • src/components/ui/tags-input/tagsInputContext.ts
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/ui/tags-input/TagsInput.vue
  • src/components/ui/tags-input/TagsInputItemText.vue
  • src/components/ui/tags-input/TagsInput.test.ts
  • src/components/ui/tags-input/TagsInput.stories.ts
  • src/components/ui/tags-input/TagsInputItem.vue
  • src/components/ui/tags-input/TagsInputItemDelete.vue
  • src/components/ui/tags-input/TagsInputInput.vue
  • src/components/ui/tags-input/tagsInputContext.ts
src/**/*.{vue,ts,tsx}

📄 CodeRabbit inference engine (src/CLAUDE.md)

Follow Vue 3 composition API style guide

Files:

  • src/components/ui/tags-input/TagsInput.vue
  • src/components/ui/tags-input/TagsInputItemText.vue
  • src/components/ui/tags-input/TagsInput.test.ts
  • src/components/ui/tags-input/TagsInput.stories.ts
  • src/components/ui/tags-input/TagsInputItem.vue
  • src/components/ui/tags-input/TagsInputItemDelete.vue
  • src/components/ui/tags-input/TagsInputInput.vue
  • src/components/ui/tags-input/tagsInputContext.ts
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/ui/tags-input/TagsInput.vue
  • src/components/ui/tags-input/TagsInputItemText.vue
  • src/components/ui/tags-input/TagsInput.test.ts
  • src/components/ui/tags-input/TagsInput.stories.ts
  • src/components/ui/tags-input/TagsInputItem.vue
  • src/components/ui/tags-input/TagsInputItemDelete.vue
  • src/components/ui/tags-input/TagsInputInput.vue
  • src/components/ui/tags-input/tagsInputContext.ts
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

Name Vue components in PascalCase (e.g., MenuHamburger.vue)

Files:

  • src/components/ui/tags-input/TagsInput.vue
  • src/components/ui/tags-input/TagsInputItemText.vue
  • src/components/ui/tags-input/TagsInputItem.vue
  • src/components/ui/tags-input/TagsInputItemDelete.vue
  • src/components/ui/tags-input/TagsInputInput.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/ui/tags-input/TagsInput.vue
  • src/components/ui/tags-input/TagsInputItemText.vue
  • src/components/ui/tags-input/TagsInputItem.vue
  • src/components/ui/tags-input/TagsInputItemDelete.vue
  • src/components/ui/tags-input/TagsInputInput.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/ui/tags-input/TagsInput.vue
  • src/components/ui/tags-input/TagsInputItemText.vue
  • src/components/ui/tags-input/TagsInput.test.ts
  • src/components/ui/tags-input/TagsInput.stories.ts
  • src/components/ui/tags-input/TagsInputItem.vue
  • src/components/ui/tags-input/TagsInputItemDelete.vue
  • src/components/ui/tags-input/TagsInputInput.vue
  • src/components/ui/tags-input/tagsInputContext.ts
src/**/*.{ts,vue}

📄 CodeRabbit inference engine (AGENTS.md)

src/**/*.{ts,vue}: Use ref for reactive state, computed() for derived values, and watch/watchEffect for side effects in Composition API
Avoid using ref with watch if a computed would suffice - minimize refs and derived state
Use provide/inject for dependency injection only when simpler alternatives (Store or shared composable) won't work
Leverage VueUse functions for performance-enhancing composables
Use VueUse function for useI18n in composition API for string literals

Files:

  • src/components/ui/tags-input/TagsInput.vue
  • src/components/ui/tags-input/TagsInputItemText.vue
  • src/components/ui/tags-input/TagsInput.test.ts
  • src/components/ui/tags-input/TagsInput.stories.ts
  • src/components/ui/tags-input/TagsInputItem.vue
  • src/components/ui/tags-input/TagsInputItemDelete.vue
  • src/components/ui/tags-input/TagsInputInput.vue
  • src/components/ui/tags-input/tagsInputContext.ts
src/**/*.ts

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

src/**/*.ts: Use es-toolkit for utility functions
Use TypeScript for type safety

src/**/*.ts: Derive component types using vue-component-type-helpers (ComponentProps, ComponentSlots) instead of separate type files
Use es-toolkit for utility functions
Minimize the surface area (exported values) of each module and composable
Favor pure functions, especially testable ones

Files:

  • src/components/ui/tags-input/TagsInput.test.ts
  • src/components/ui/tags-input/TagsInput.stories.ts
  • src/components/ui/tags-input/tagsInputContext.ts
+(tests-ui|src)/**/*.test.ts

📄 CodeRabbit inference engine (AGENTS.md)

+(tests-ui|src)/**/*.test.ts: Unit and component tests belong in tests-ui/ or src/**/*.test.ts using Vitest
Write tests for all changes, especially bug fixes to catch future regressions
Do not write tests dependent on non-behavioral features like utility classes or styles
Do not write tests that just test the mocks - ensure tests fail when code behaves unexpectedly
Leverage Vitest's utilities for mocking where possible
Keep module mocks contained - do not use global mutable state within test files; use vi.hoisted() if necessary
Use Vue Test Utils for Component testing and follow best practices for making components easy to test
Aim for behavioral coverage of critical and new features in unit tests

Files:

  • src/components/ui/tags-input/TagsInput.test.ts
src/**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

src/**/*.{ts,tsx}: Keep functions short and functional
Minimize nesting (if statements, for loops, etc.)
Use function declarations instead of function expressions when possible

Files:

  • src/components/ui/tags-input/TagsInput.test.ts
  • src/components/ui/tags-input/TagsInput.stories.ts
  • src/components/ui/tags-input/tagsInputContext.ts
+(tests-ui|src|browser_tests)/**/*.+(test.ts|spec.ts)

📄 CodeRabbit inference engine (AGENTS.md)

+(tests-ui|src|browser_tests)/**/*.+(test.ts|spec.ts): Do not write change detector tests - avoid tests that only assert default values
Be parsimonious in testing - do not write redundant tests
Don't Mock What You Don't Own

Files:

  • src/components/ui/tags-input/TagsInput.test.ts
🧠 Learnings (56)
📓 Common learnings
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 Chips component with AutoComplete with multiple enabled
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
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-10T00:24:17.695Z
Learning: Applies to src/**/*.vue : Use TypeScript Vue 3.5 style default prop declaration with reactive props destructuring - avoid `withDefaults` or runtime props
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 : Destructure props using Vue 3.5 style in Vue components
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/**/{components,composables}/**/*.{ts,tsx,vue} : Use vue-i18n for ALL user-facing strings by adding them to `src/locales/en/main.json`
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 : Follow Vue 3 style guide and naming conventions
📚 Learning: 2026-01-10T00:24:17.695Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-10T00:24:17.695Z
Learning: Applies to src/**/*.vue : Use Vue 3 Single File Components (SFCs) with Composition API only

Applied to files:

  • src/components/ui/tags-input/TagsInput.vue
  • src/components/ui/tags-input/TagsInputItem.vue
  • src/components/ui/tags-input/TagsInputItemDelete.vue
  • src/components/ui/tags-input/TagsInputInput.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/ui/tags-input/TagsInput.vue
  • src/components/ui/tags-input/TagsInputItemText.vue
  • src/components/ui/tags-input/TagsInputItem.vue
  • src/components/ui/tags-input/TagsInputItemDelete.vue
  • src/components/ui/tags-input/TagsInputInput.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/components/ui/tags-input/TagsInput.vue
  • src/components/ui/tags-input/TagsInputItemText.vue
  • src/components/ui/tags-input/TagsInputItem.vue
  • src/components/ui/tags-input/TagsInputItemDelete.vue
  • src/components/ui/tags-input/TagsInputInput.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/components/ui/tags-input/TagsInput.vue
  • src/components/ui/tags-input/TagsInputItemText.vue
  • src/components/ui/tags-input/TagsInputItem.vue
  • src/components/ui/tags-input/TagsInputItemDelete.vue
  • src/components/ui/tags-input/TagsInputInput.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 : Follow Vue 3 style guide and naming conventions

Applied to files:

  • src/components/ui/tags-input/TagsInput.vue
  • src/components/ui/tags-input/TagsInputInput.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/ui/tags-input/TagsInput.vue
  • src/components/ui/tags-input/TagsInputInput.vue
📚 Learning: 2026-01-10T00:24:17.695Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-10T00:24:17.695Z
Learning: Applies to src/**/*.vue : Use TypeScript Vue 3.5 style default prop declaration with reactive props destructuring - avoid `withDefaults` or runtime props

Applied to files:

  • src/components/ui/tags-input/TagsInput.vue
  • src/components/ui/tags-input/TagsInputItemText.vue
  • src/components/ui/tags-input/TagsInputItemDelete.vue
  • src/components/ui/tags-input/TagsInputInput.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/ui/tags-input/TagsInput.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/components/ui/tags-input/TagsInput.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/ui/tags-input/TagsInput.vue
  • src/components/ui/tags-input/TagsInputItemText.vue
  • src/components/ui/tags-input/TagsInputItem.vue
  • src/components/ui/tags-input/TagsInputItemDelete.vue
  • src/components/ui/tags-input/TagsInputInput.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/ui/tags-input/TagsInput.vue
  • src/components/ui/tags-input/TagsInputItemText.vue
  • src/components/ui/tags-input/TagsInputItem.vue
  • src/components/ui/tags-input/TagsInputItemDelete.vue
  • src/components/ui/tags-input/TagsInputInput.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/ui/tags-input/TagsInput.vue
  • src/components/ui/tags-input/TagsInputItemText.vue
  • src/components/ui/tags-input/TagsInputItem.vue
  • src/components/ui/tags-input/TagsInputItemDelete.vue
  • src/components/ui/tags-input/TagsInputInput.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/ui/tags-input/TagsInput.vue
  • src/components/ui/tags-input/TagsInputItemText.vue
  • src/components/ui/tags-input/TagsInputItem.vue
  • src/components/ui/tags-input/TagsInputItemDelete.vue
  • src/components/ui/tags-input/TagsInputInput.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/components/ui/tags-input/TagsInput.vue
  • src/components/ui/tags-input/TagsInputItemText.vue
  • src/components/ui/tags-input/TagsInputItem.vue
  • src/components/ui/tags-input/TagsInputItemDelete.vue
  • src/components/ui/tags-input/TagsInputInput.vue
📚 Learning: 2026-01-08T02:26:18.357Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7893
File: src/components/button/IconGroup.vue:5-6
Timestamp: 2026-01-08T02:26:18.357Z
Learning: In components that use the cn utility from '@/utils/tailwindUtil' with tailwind-merge, rely on the behavior that conflicting Tailwind classes are resolved by keeping the last one. For example, cn('base-classes bg-default', propClass) will have any conflicting background class from propClass override bg-default. This additive pattern is intentional and aligns with the shadcn-ui convention; ensure you document or review expectations accordingly in Vue components.

Applied to files:

  • src/components/ui/tags-input/TagsInput.vue
  • src/components/ui/tags-input/TagsInputItemText.vue
  • src/components/ui/tags-input/TagsInputItem.vue
  • src/components/ui/tags-input/TagsInputItemDelete.vue
  • src/components/ui/tags-input/TagsInputInput.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/ui/tags-input/TagsInput.vue
  • src/components/ui/tags-input/TagsInputItemText.vue
  • src/components/ui/tags-input/TagsInput.test.ts
  • src/components/ui/tags-input/TagsInput.stories.ts
  • src/components/ui/tags-input/TagsInputItem.vue
  • src/components/ui/tags-input/TagsInputItemDelete.vue
  • src/components/ui/tags-input/TagsInputInput.vue
  • src/components/ui/tags-input/tagsInputContext.ts
📚 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/ui/tags-input/TagsInput.vue
  • src/components/ui/tags-input/TagsInputItemText.vue
  • src/components/ui/tags-input/TagsInputItem.vue
  • src/components/ui/tags-input/TagsInputItemDelete.vue
  • src/components/ui/tags-input/TagsInputInput.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/ui/tags-input/TagsInput.vue
  • src/components/ui/tags-input/TagsInputItemText.vue
  • src/components/ui/tags-input/TagsInputItem.vue
  • src/components/ui/tags-input/TagsInputItemDelete.vue
  • src/components/ui/tags-input/TagsInputInput.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/ui/tags-input/TagsInput.vue
  • src/components/ui/tags-input/TagsInputItemText.vue
  • src/components/ui/tags-input/TagsInputItem.vue
  • src/components/ui/tags-input/TagsInputItemDelete.vue
  • src/components/ui/tags-input/TagsInputInput.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/ui/tags-input/TagsInput.vue
  • src/components/ui/tags-input/TagsInputItemText.vue
  • src/components/ui/tags-input/TagsInputItem.vue
  • src/components/ui/tags-input/TagsInputItemDelete.vue
  • src/components/ui/tags-input/TagsInputInput.vue
📚 Learning: 2026-01-12T17:39:27.738Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7906
File: src/components/sidebar/tabs/AssetsSidebarTab.vue:545-552
Timestamp: 2026-01-12T17:39:27.738Z
Learning: In Vue/TypeScript files (src/**/*.{ts,tsx,vue}), prefer if/else statements over ternary operators when performing side effects or actions (e.g., mutating state, calling methods with side effects). Ternaries should be reserved for computing and returning values.

Applied to files:

  • src/components/ui/tags-input/TagsInput.vue
  • src/components/ui/tags-input/TagsInputItemText.vue
  • src/components/ui/tags-input/TagsInput.test.ts
  • src/components/ui/tags-input/TagsInput.stories.ts
  • src/components/ui/tags-input/TagsInputItem.vue
  • src/components/ui/tags-input/TagsInputItemDelete.vue
  • src/components/ui/tags-input/TagsInputInput.vue
  • src/components/ui/tags-input/tagsInputContext.ts
📚 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 proper props and emits definitions

Applied to files:

  • src/components/ui/tags-input/TagsInputItemText.vue
  • src/components/ui/tags-input/TagsInputItem.vue
  • src/components/ui/tags-input/TagsInputItemDelete.vue
📚 Learning: 2026-01-10T00:24:17.695Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-10T00:24:17.695Z
Learning: Applies to src/**/*.ts : Derive component types using `vue-component-type-helpers` (`ComponentProps`, `ComponentSlots`) instead of separate type files

Applied to files:

  • src/components/ui/tags-input/TagsInputItemText.vue
  • src/components/ui/tags-input/TagsInputItem.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/components/ui/tags-input/TagsInputItemText.vue
📚 Learning: 2026-01-10T00:24:17.695Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-10T00:24:17.695Z
Learning: Applies to src/**/*.vue : Use `cn()` utility from `@/utils/tailwindUtil` for merging Tailwind class names instead of `:class="[]"` or hardcoding

Applied to files:

  • src/components/ui/tags-input/TagsInputItemText.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/**/{components,composables}/**/*.{ts,tsx,vue} : Use vue-i18n for ALL user-facing strings by adding them to `src/locales/en/main.json`

Applied to files:

  • src/components/ui/tags-input/TagsInputItemText.vue
  • src/components/ui/tags-input/TagsInputItem.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/ui/tags-input/TagsInputItemText.vue
📚 Learning: 2026-01-10T00:24:17.695Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-10T00:24:17.695Z
Learning: Applies to src/**/*.vue : Use `<script setup lang="ts">` for component logic in Vue SFCs

Applied to files:

  • src/components/ui/tags-input/TagsInputItemText.vue
  • src/components/ui/tags-input/TagsInputInput.vue
📚 Learning: 2026-01-10T00:24:17.695Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-10T00:24:17.695Z
Learning: Applies to +(tests-ui|src)/**/*.test.ts : Use Vue Test Utils for Component testing and follow best practices for making components easy to test

Applied to files:

  • src/components/ui/tags-input/TagsInput.test.ts
📚 Learning: 2026-01-10T00:24:17.695Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-10T00:24:17.695Z
Learning: Applies to +(tests-ui|src)/**/*.test.ts : Write tests for all changes, especially bug fixes to catch future regressions

Applied to files:

  • src/components/ui/tags-input/TagsInput.test.ts
📚 Learning: 2026-01-10T00:24:17.695Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-10T00:24:17.695Z
Learning: Applies to +(tests-ui|src)/**/*.test.ts : Aim for behavioral coverage of critical and new features in unit tests

Applied to files:

  • src/components/ui/tags-input/TagsInput.test.ts
📚 Learning: 2026-01-10T00:24:17.695Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-10T00:24:17.695Z
Learning: Applies to +(tests-ui|src)/**/*.test.ts : Unit and component tests belong in `tests-ui/` or `src/**/*.test.ts` using Vitest

Applied to files:

  • src/components/ui/tags-input/TagsInput.test.ts
📚 Learning: 2026-01-10T00:24:17.695Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-10T00:24:17.695Z
Learning: Applies to +(tests-ui|src)/**/*.test.ts : Do not write tests dependent on non-behavioral features like utility classes or styles

Applied to files:

  • src/components/ui/tags-input/TagsInput.test.ts
📚 Learning: 2026-01-10T00:24:17.695Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-10T00:24:17.695Z
Learning: Applies to +(tests-ui|src)/**/*.test.ts : Leverage Vitest's utilities for mocking where possible

Applied to files:

  • src/components/ui/tags-input/TagsInput.test.ts
📚 Learning: 2026-01-10T00:24:17.695Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-10T00:24:17.695Z
Learning: Applies to browser_tests/**/*.spec.ts : Use tags like `mobile`, `2x` in Playwright tests for configuration-aware test selection

Applied to files:

  • src/components/ui/tags-input/TagsInput.test.ts
📚 Learning: 2026-01-10T00:24:17.695Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-10T00:24:17.695Z
Learning: Applies to +(tests-ui|src|browser_tests)/**/*.+(test.ts|spec.ts) : Be parsimonious in testing - do not write redundant tests

Applied to files:

  • src/components/ui/tags-input/TagsInput.test.ts
📚 Learning: 2026-01-10T00:24:17.695Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-10T00:24:17.695Z
Learning: Applies to +(tests-ui|src|browser_tests)/**/*.+(test.ts|spec.ts) : Do not write change detector tests - avoid tests that only assert default values

Applied to files:

  • src/components/ui/tags-input/TagsInput.test.ts
📚 Learning: 2026-01-10T00:24:17.695Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-10T00:24:17.695Z
Learning: Applies to +(tests-ui|src)/**/*.test.ts : Keep module mocks contained - do not use global mutable state within test files; use `vi.hoisted()` if necessary

Applied to files:

  • src/components/ui/tags-input/TagsInput.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:

  • src/components/ui/tags-input/TagsInput.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 `test` instead of `it` for defining test cases in vitest

Applied to files:

  • src/components/ui/tags-input/TagsInput.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} : Prefer the use of `test.extend` over loose variables; import `test as baseTest` from `vitest`

Applied to files:

  • src/components/ui/tags-input/TagsInput.test.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} : Prefer specific selectors in browser tests

Applied to files:

  • src/components/ui/tags-input/TagsInput.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:

  • src/components/ui/tags-input/TagsInput.test.ts
  • src/components/ui/tags-input/TagsInput.stories.ts
  • src/components/ui/tags-input/tagsInputContext.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:

  • src/components/ui/tags-input/TagsInput.test.ts
  • src/components/ui/tags-input/TagsInput.stories.ts
  • src/components/ui/tags-input/tagsInputContext.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:

  • src/components/ui/tags-input/TagsInput.test.ts
  • src/components/ui/tags-input/TagsInput.stories.ts
  • src/components/ui/tags-input/tagsInputContext.ts
📚 Learning: 2025-12-30T22:22:33.836Z
Learnt from: kaili-yang
Repo: Comfy-Org/ComfyUI_frontend PR: 7805
File: src/composables/useCoreCommands.ts:439-439
Timestamp: 2025-12-30T22:22:33.836Z
Learning: When accessing reactive properties from Pinia stores in TypeScript files, avoid using .value on direct property access (e.g., useStore().isOverlayExpanded). Pinia auto-wraps refs when accessed directly, returning the primitive value. The .value accessor is only needed when destructuring store properties or when using storeToRefs().

Applied to files:

  • src/components/ui/tags-input/TagsInput.test.ts
  • src/components/ui/tags-input/TagsInput.stories.ts
  • src/components/ui/tags-input/tagsInputContext.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:

  • src/components/ui/tags-input/TagsInput.test.ts
📚 Learning: 2025-12-30T01:31:04.927Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7797
File: tests-ui/tests/lib/litegraph/src/widgets/ComboWidget.test.ts:648-648
Timestamp: 2025-12-30T01:31:04.927Z
Learning: In Vitest v4, when mocking functions that may be called as constructors (using new), the mock implementation must use function() or class syntax rather than an arrow function. Arrow mocks can cause '<anonymous> is not a constructor' errors. This is a breaking change from Vitest v3 where mocks could use an arrow function. Apply this guideline to test files that mock constructor-like calls (e.g., in tests under tests-ui, such as ComboWidget.test.ts) and ensure mock implementations are defined with function() { ... } or class { ... } to preserve constructor behavior.

Applied to files:

  • src/components/ui/tags-input/TagsInput.test.ts
📚 Learning: 2026-01-08T02:40:15.482Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7894
File: src/renderer/extensions/vueNodes/widgets/components/WidgetToggleSwitch.test.ts:11-14
Timestamp: 2026-01-08T02:40:15.482Z
Learning: In TypeScript test files (e.g., any test under src), avoid duplicating interface/type definitions. Import real type definitions from the component modules under test and reference them directly, so there is a single source of truth and to prevent type drift. This improves maintainability and consistency across tests.

Applied to files:

  • src/components/ui/tags-input/TagsInput.test.ts
📚 Learning: 2026-01-09T02:07:54.558Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7898
File: src/composables/usePaste.test.ts:248-248
Timestamp: 2026-01-09T02:07:54.558Z
Learning: In test files (e.g., any .test.ts or .test.tsx under src/...), when you create mock objects that partially implement an interface (such as LGraphNode), prefer casting with as Partial<InterfaceType> as InterfaceType rather than as any or as unknown as InterfaceType. This makes the incomplete implementation explicit while preserving type safety, improving readability and maintainability of tests.

Applied to files:

  • src/components/ui/tags-input/TagsInput.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:

  • src/components/ui/tags-input/TagsInputItemDelete.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/ui/tags-input/TagsInputItemDelete.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,css} : Use Tailwind CSS only for styling (no custom CSS)

Applied to files:

  • src/components/ui/tags-input/TagsInputItemDelete.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 provide/inject for dependency injection in Vue components

Applied to files:

  • src/components/ui/tags-input/TagsInputInput.vue
  • src/components/ui/tags-input/tagsInputContext.ts
📚 Learning: 2026-01-10T00:24:17.695Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-10T00:24:17.695Z
Learning: Applies to src/**/*.{ts,vue} : Use `provide`/`inject` for dependency injection only when simpler alternatives (Store or shared composable) won't work

Applied to files:

  • src/components/ui/tags-input/tagsInputContext.ts
🧬 Code graph analysis (1)
src/components/ui/tags-input/TagsInput.stories.ts (1)
src/components/input/SingleSelect.stories.ts (1)
  • Story (40-40)
⏰ 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). (3)
  • GitHub Check: setup
  • GitHub Check: lint-and-format
  • GitHub Check: test
🔇 Additional comments (15)
src/components/ui/tags-input/TagsInputItem.vue (1)

1-27: LGTM!

Clean wrapper component following Vue 3.5 conventions. Proper use of cn() for class merging, correct type/value import separation, and appropriate design token usage.

src/components/ui/tags-input/TagsInputItemText.vue (1)

1-20: LGTM!

Simple, well-structured wrapper component. Follows established patterns with proper props forwarding and class composition.

src/components/ui/tags-input/tagsInputContext.ts (1)

1-10: LGTM!

Well-designed context module using Vue's InjectionKey for type-safe dependency injection. The FocusCallback type allowing undefined correctly supports the cleanup pattern used in TagsInputInput.vue.

src/components/ui/tags-input/TagsInputInput.vue (2)

26-32: LGTM on lifecycle handling.

Clean focus registration pattern with proper cleanup in onUnmounted. The optional chaining correctly handles cases where the context isn't provided.


11-21: This pattern is correct for Vue 3.5+.

Vue 3.5's compiler transformation maintains reactivity for destructured props, including primitives with default values. The pattern const { isEmpty = false, ... } = defineProps<...>() is the recommended modern approach and correctly updates in the computed when the parent changes the prop value. No changes needed.

Likely an incorrect or invalid review comment.

src/components/ui/tags-input/TagsInputItemDelete.vue (1)

16-27: LGTM on animation implementation.

The transition classes using transition-[opacity,width] with data-[disabled] states create smooth animations when toggling edit mode. The overflow-hidden prevents visual artifacts during the width transition.

src/components/ui/tags-input/TagsInput.test.ts (2)

77-101: Good behavioral coverage for tag addition flow.

This test covers the core click-to-edit and tag addition behavior effectively. It verifies user interaction (click → type → Enter) updates the model value.


2-2: Use test instead of it for defining test cases.

Per coding guidelines, prefer test over it for defining test cases in Vitest.

Suggested fix
-import { describe, expect, it } from 'vitest'
+import { describe, expect, test } from 'vitest'

Then replace all it( occurrences with test(.

⛔ Skipped due to learnings
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 `test` instead of `it` for defining test cases in vitest
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
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-10T00:24:17.695Z
Learning: Applies to +(tests-ui|src)/**/*.test.ts : Use Vue Test Utils for Component testing and follow best practices for making components easy to test
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} : Prefer the use of `test.extend` over loose variables; import `test as baseTest` from `vitest`
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-10T00:24:17.695Z
Learning: Applies to +(tests-ui|src)/**/*.test.ts : Leverage Vitest's utilities for mocking where possible
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-10T00:24:17.695Z
Learning: Applies to +(tests-ui|src)/**/*.test.ts : Unit and component tests belong in `tests-ui/` or `src/**/*.test.ts` using Vitest
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-10T00:24:17.695Z
Learning: Applies to +(tests-ui|src|browser_tests)/**/*.+(test.ts|spec.ts) : Be parsimonious in testing - do not write redundant tests
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-10T00:24:17.695Z
Learning: Applies to +(tests-ui|src)/**/*.test.ts : Write tests for all changes, especially bug fixes to catch future regressions
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
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-10T00:24:17.695Z
Learning: Applies to +(tests-ui|src)/**/*.test.ts : Do not write tests dependent on non-behavioral features like utility classes or styles
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-10T00:24:17.695Z
Learning: Applies to +(tests-ui|src)/**/*.test.ts : Keep module mocks contained - do not use global mutable state within test files; use `vi.hoisted()` if necessary
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/lib/litegraph/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:56.371Z
Learning: Applies to src/lib/litegraph/**/*.{test,spec}.{js,ts,jsx,tsx} : When adding features, always write vitest unit tests using cursor rules in @.cursor
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-10T00:24:17.695Z
Learning: Applies to browser_tests/**/*.spec.ts : Follow Playwright best practices for E2E testing
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/lib/litegraph/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:56.371Z
Learning: Applies to src/lib/litegraph/**/*.{test,spec}.{ts,tsx} : Use provided test helpers `createTestSubgraph` and `createTestSubgraphNode` from `./fixtures/subgraphHelpers` for consistent subgraph test setup
src/components/ui/tags-input/TagsInput.vue (4)

1-22: Well-structured component setup following Vue 3.5 conventions.

Good use of:

  • Vue 3.5 style props destructuring with defaults (line 17-21)
  • Separate import type statements (lines 3-7, 10, 15)
  • VueUse composables for click-outside handling
  • Generic typing for flexible value types

24-31: Appropriate use of provide/inject for component coordination.

The focus callback registration and shared editing state via provide/inject is a clean pattern for this component family coordination. The scoped nature makes this preferable to a shared store or composable.


33-38: Clean computed state for click-to-edit behavior.

The internalDisabled computed correctly implements the read-only-until-clicked UX: the underlying TagsInputRoot is disabled until the user explicitly enters edit mode.


42-48: Correct async enable editing implementation.

Good defensive coding with:

  • Guard conditions preventing disabled state editing
  • nextTick ensuring DOM updates before focus
  • Optional chaining handling unregistered focus callback
src/components/ui/tags-input/TagsInput.stories.ts (3)

1-34: Well-structured Storybook meta configuration.

The GenericMeta interface is a clean workaround for typing generic Vue components in Storybook. Good coverage of argTypes with descriptions.


36-66: Comprehensive Default story with good interactivity.

The Default story demonstrates:

  • Two-way binding with v-model
  • Disabled state toggle via args
  • Live tag display for debugging

Good pattern for interactive component documentation.


93-179: Good coverage of edge cases and configurations.

The ManyTags, Disabled, and CustomWidth stories effectively demonstrate:

  • Overflow/wrap behavior with many tags
  • Disabled state appearance
  • Layout flexibility with custom widths

✏️ Tip: You can disable this entire section by setting review_details to false in your review settings.

@dosubot dosubot bot added size:XL This PR changes 500-999 lines, ignoring generated files. and removed size:L This PR changes 100-499 lines, ignoring generated files. labels Jan 15, 2026
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

🤖 Fix all issues with AI agents
In `@src/components/ui/tags-input/TagsInput.test.ts`:
- Around line 145-161: The test "shows placeholder when modelValue is empty"
passes the slot-scoped isEmpty into TagsInputInput but never asserts its effect;
either assert that isEmpty is true and that this causes the expected behavior
(e.g., the input is auto-shown or a CSS class/prop on TagsInputInput is set) by
reading the slot scope or inspecting TagsInputInput props/classes, or remove the
unused isEmpty prop from the slot to simplify the test; update the test for
TagsInput and TagsInputInput accordingly so the intent is explicit (reference:
isEmpty, TagsInputInput, TagsInput, and the test case name).
- Around line 1-3: The test file uses "it(...)" to define test cases but your
coding guidelines require "test(...)" instead; update every test case
declaration in TagsInput.test.ts by replacing each "it(" call with "test(" while
keeping the same callback functions, descriptions, and any async/await usage
(i.e., preserve the existing describe blocks, callbacks, and imports such as
mount, describe, expect, h, nextTick) so only the test declaration identifier
changes.
♻️ Duplicate comments (1)
src/components/ui/tags-input/TagsInput.test.ts (1)

49-75: Consider consolidating redundant structural tests.

These tests verify the same underlying behavior: that N tags result in N rendered subcomponents. They are borderline change-detector tests that only assert counts match input length.

Consider consolidating into a single test that verifies the complete structure, or focus on behavioral aspects like verifying actual tag text content is rendered correctly.

📜 Review details

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 7cfc37f and c289af0.

📒 Files selected for processing (1)
  • src/components/ui/tags-input/TagsInput.test.ts
🧰 Additional context used
📓 Path-based instructions (11)
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/ui/tags-input/TagsInput.test.ts
src/**/*.ts

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

src/**/*.ts: Use es-toolkit for utility functions
Use TypeScript for type safety

src/**/*.ts: Derive component types using vue-component-type-helpers (ComponentProps, ComponentSlots) instead of separate type files
Use es-toolkit for utility functions
Minimize the surface area (exported values) of each module and composable
Favor pure functions, especially testable ones

Files:

  • src/components/ui/tags-input/TagsInput.test.ts
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}: Use separate import type statements instead of inline type in mixed imports
Apply Prettier formatting with 2-space indentation, single quotes, no trailing semicolons, 80-character width
Sort and group imports by plugin, run pnpm format before committing
Never use any type - use proper TypeScript types
Never use as any type assertions - fix the underlying type issue
Write code that is expressive and self-documenting - avoid unnecessary comments
Do not add or retain redundant comments - clean as you go
Avoid mutable state - prefer immutability and assignment at point of declaration
Watch out for Code Smells and refactor to avoid them

Files:

  • src/components/ui/tags-input/TagsInput.test.ts
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/ui/tags-input/TagsInput.test.ts
src/**/*.{vue,ts,tsx}

📄 CodeRabbit inference engine (src/CLAUDE.md)

Follow Vue 3 composition API style guide

Files:

  • src/components/ui/tags-input/TagsInput.test.ts
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/ui/tags-input/TagsInput.test.ts
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/ui/tags-input/TagsInput.test.ts
+(tests-ui|src)/**/*.test.ts

📄 CodeRabbit inference engine (AGENTS.md)

+(tests-ui|src)/**/*.test.ts: Unit and component tests belong in tests-ui/ or src/**/*.test.ts using Vitest
Write tests for all changes, especially bug fixes to catch future regressions
Do not write tests dependent on non-behavioral features like utility classes or styles
Do not write tests that just test the mocks - ensure tests fail when code behaves unexpectedly
Leverage Vitest's utilities for mocking where possible
Keep module mocks contained - do not use global mutable state within test files; use vi.hoisted() if necessary
Use Vue Test Utils for Component testing and follow best practices for making components easy to test
Aim for behavioral coverage of critical and new features in unit tests

Files:

  • src/components/ui/tags-input/TagsInput.test.ts
src/**/*.{ts,vue}

📄 CodeRabbit inference engine (AGENTS.md)

src/**/*.{ts,vue}: Use ref for reactive state, computed() for derived values, and watch/watchEffect for side effects in Composition API
Avoid using ref with watch if a computed would suffice - minimize refs and derived state
Use provide/inject for dependency injection only when simpler alternatives (Store or shared composable) won't work
Leverage VueUse functions for performance-enhancing composables
Use VueUse function for useI18n in composition API for string literals

Files:

  • src/components/ui/tags-input/TagsInput.test.ts
src/**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

src/**/*.{ts,tsx}: Keep functions short and functional
Minimize nesting (if statements, for loops, etc.)
Use function declarations instead of function expressions when possible

Files:

  • src/components/ui/tags-input/TagsInput.test.ts
+(tests-ui|src|browser_tests)/**/*.+(test.ts|spec.ts)

📄 CodeRabbit inference engine (AGENTS.md)

+(tests-ui|src|browser_tests)/**/*.+(test.ts|spec.ts): Do not write change detector tests - avoid tests that only assert default values
Be parsimonious in testing - do not write redundant tests
Don't Mock What You Don't Own

Files:

  • src/components/ui/tags-input/TagsInput.test.ts
🧠 Learnings (28)
📓 Common learnings
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 : Use provide/inject for dependency injection in Vue components
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-10T00:24:17.695Z
Learning: Applies to +(tests-ui|src)/**/*.test.ts : Use Vue Test Utils for Component testing and follow best practices for making components easy to test
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: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T19:47:02.860Z
Learning: Applies to src/**/*.vue : Utilize provide/inject for dependency injection
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
📚 Learning: 2026-01-10T00:24:17.695Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-10T00:24:17.695Z
Learning: Applies to +(tests-ui|src)/**/*.test.ts : Use Vue Test Utils for Component testing and follow best practices for making components easy to test

Applied to files:

  • src/components/ui/tags-input/TagsInput.test.ts
📚 Learning: 2026-01-10T00:24:17.695Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-10T00:24:17.695Z
Learning: Applies to +(tests-ui|src)/**/*.test.ts : Write tests for all changes, especially bug fixes to catch future regressions

Applied to files:

  • src/components/ui/tags-input/TagsInput.test.ts
📚 Learning: 2026-01-10T00:24:17.695Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-10T00:24:17.695Z
Learning: Applies to +(tests-ui|src)/**/*.test.ts : Aim for behavioral coverage of critical and new features in unit tests

Applied to files:

  • src/components/ui/tags-input/TagsInput.test.ts
📚 Learning: 2026-01-10T00:24:17.695Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-10T00:24:17.695Z
Learning: Applies to +(tests-ui|src)/**/*.test.ts : Unit and component tests belong in `tests-ui/` or `src/**/*.test.ts` using Vitest

Applied to files:

  • src/components/ui/tags-input/TagsInput.test.ts
📚 Learning: 2026-01-10T00:24:17.695Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-10T00:24:17.695Z
Learning: Applies to +(tests-ui|src)/**/*.test.ts : Do not write tests dependent on non-behavioral features like utility classes or styles

Applied to files:

  • src/components/ui/tags-input/TagsInput.test.ts
📚 Learning: 2026-01-10T00:24:17.695Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-10T00:24:17.695Z
Learning: Applies to +(tests-ui|src)/**/*.test.ts : Leverage Vitest's utilities for mocking where possible

Applied to files:

  • src/components/ui/tags-input/TagsInput.test.ts
📚 Learning: 2026-01-10T00:24:17.695Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-10T00:24:17.695Z
Learning: Applies to browser_tests/**/*.spec.ts : Use tags like `mobile`, `2x` in Playwright tests for configuration-aware test selection

Applied to files:

  • src/components/ui/tags-input/TagsInput.test.ts
📚 Learning: 2026-01-10T00:24:17.695Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-10T00:24:17.695Z
Learning: Applies to +(tests-ui|src|browser_tests)/**/*.+(test.ts|spec.ts) : Be parsimonious in testing - do not write redundant tests

Applied to files:

  • src/components/ui/tags-input/TagsInput.test.ts
📚 Learning: 2026-01-10T00:24:17.695Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-10T00:24:17.695Z
Learning: Applies to +(tests-ui|src|browser_tests)/**/*.+(test.ts|spec.ts) : Do not write change detector tests - avoid tests that only assert default values

Applied to files:

  • src/components/ui/tags-input/TagsInput.test.ts
📚 Learning: 2026-01-10T00:24:17.695Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-10T00:24:17.695Z
Learning: Applies to +(tests-ui|src)/**/*.test.ts : Keep module mocks contained - do not use global mutable state within test files; use `vi.hoisted()` if necessary

Applied to files:

  • src/components/ui/tags-input/TagsInput.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:

  • src/components/ui/tags-input/TagsInput.test.ts
📚 Learning: 2026-01-10T00:24:17.695Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-10T00:24:17.695Z
Learning: Applies to +(tests-ui|src)/**/*.test.ts : Do not write tests that just test the mocks - ensure tests fail when code behaves unexpectedly

Applied to files:

  • src/components/ui/tags-input/TagsInput.test.ts
📚 Learning: 2025-11-24T19:47:56.371Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/lib/litegraph/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:56.371Z
Learning: Applies to src/lib/litegraph/**/*.{test,spec}.{js,ts,jsx,tsx} : When adding features, always write vitest unit tests using cursor rules in @.cursor

Applied to files:

  • src/components/ui/tags-input/TagsInput.test.ts
📚 Learning: 2026-01-08T02:40:15.482Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7894
File: src/renderer/extensions/vueNodes/widgets/components/WidgetToggleSwitch.test.ts:11-14
Timestamp: 2026-01-08T02:40:15.482Z
Learning: In TypeScript test files (e.g., any test under src), avoid duplicating interface/type definitions. Import real type definitions from the component modules under test and reference them directly, so there is a single source of truth and to prevent type drift. This improves maintainability and consistency across tests.

Applied to files:

  • src/components/ui/tags-input/TagsInput.test.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} : Prefer specific selectors in browser tests

Applied to files:

  • src/components/ui/tags-input/TagsInput.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} : Mocks should be cleanly written and easy to understand, with reusable mocks where possible

Applied to files:

  • src/components/ui/tags-input/TagsInput.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:

  • src/components/ui/tags-input/TagsInput.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 `test` instead of `it` for defining test cases in vitest

Applied to files:

  • src/components/ui/tags-input/TagsInput.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} : Prefer the use of `test.extend` over loose variables; import `test as baseTest` from `vitest`

Applied to files:

  • src/components/ui/tags-input/TagsInput.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:

  • src/components/ui/tags-input/TagsInput.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:

  • src/components/ui/tags-input/TagsInput.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:

  • src/components/ui/tags-input/TagsInput.test.ts
📚 Learning: 2025-12-30T22:22:33.836Z
Learnt from: kaili-yang
Repo: Comfy-Org/ComfyUI_frontend PR: 7805
File: src/composables/useCoreCommands.ts:439-439
Timestamp: 2025-12-30T22:22:33.836Z
Learning: When accessing reactive properties from Pinia stores in TypeScript files, avoid using .value on direct property access (e.g., useStore().isOverlayExpanded). Pinia auto-wraps refs when accessed directly, returning the primitive value. The .value accessor is only needed when destructuring store properties or when using storeToRefs().

Applied to files:

  • src/components/ui/tags-input/TagsInput.test.ts
📚 Learning: 2025-12-30T01:31:04.927Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7797
File: tests-ui/tests/lib/litegraph/src/widgets/ComboWidget.test.ts:648-648
Timestamp: 2025-12-30T01:31:04.927Z
Learning: In Vitest v4, when mocking functions that may be called as constructors (using new), the mock implementation must use function() or class syntax rather than an arrow function. Arrow mocks can cause '<anonymous> is not a constructor' errors. This is a breaking change from Vitest v3 where mocks could use an arrow function. Apply this guideline to test files that mock constructor-like calls (e.g., in tests under tests-ui, such as ComboWidget.test.ts) and ensure mock implementations are defined with function() { ... } or class { ... } to preserve constructor behavior.

Applied to files:

  • src/components/ui/tags-input/TagsInput.test.ts
📚 Learning: 2026-01-09T02:07:54.558Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7898
File: src/composables/usePaste.test.ts:248-248
Timestamp: 2026-01-09T02:07:54.558Z
Learning: In test files (e.g., any .test.ts or .test.tsx under src/...), when you create mock objects that partially implement an interface (such as LGraphNode), prefer casting with as Partial<InterfaceType> as InterfaceType rather than as any or as unknown as InterfaceType. This makes the incomplete implementation explicit while preserving type safety, improving readability and maintainability of tests.

Applied to files:

  • src/components/ui/tags-input/TagsInput.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:

  • src/components/ui/tags-input/TagsInput.test.ts
📚 Learning: 2026-01-12T17:39:27.738Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7906
File: src/components/sidebar/tabs/AssetsSidebarTab.vue:545-552
Timestamp: 2026-01-12T17:39:27.738Z
Learning: In Vue/TypeScript files (src/**/*.{ts,tsx,vue}), prefer if/else statements over ternary operators when performing side effects or actions (e.g., mutating state, calling methods with side effects). Ternaries should be reserved for computing and returning values.

Applied to files:

  • src/components/ui/tags-input/TagsInput.test.ts
🧬 Code graph analysis (1)
src/components/ui/tags-input/TagsInput.test.ts (1)
src/extensions/core/widgetInputs.ts (1)
  • input (355-368)
⏰ 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: test
  • GitHub Check: setup
  • GitHub Check: lint-and-format
  • GitHub Check: collect
🔇 Additional comments (3)
src/components/ui/tags-input/TagsInput.test.ts (3)

77-101: LGTM! Good behavioral test for model updates.

This test properly verifies the interaction flow: clicking to enter edit mode, typing a value, pressing Enter, and confirming the model is updated. The use of an external variable to capture emitted payloads is appropriate.


103-120: LGTM! Disabled state test covers critical behavior.

This test correctly verifies that when disabled=true, the input is not shown initially and clicking does not enter edit mode. Good coverage of a key UX requirement.


122-143: LGTM! Click-outside behavior is properly tested with cleanup.

The test correctly attaches to document.body for proper event propagation, verifies edit mode can be entered and exited via outside click, and properly unmounts to prevent memory leaks.

✏️ Tip: You can disable this entire section by setting review_details to false in your review settings.

Comment on lines +1 to +3
import { mount } from '@vue/test-utils'
import { describe, expect, it } from 'vitest'
import { h, nextTick } from 'vue'
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

Use test instead of it per coding guidelines.

The coding guidelines specify using test instead of it for defining test cases in Vitest. This applies throughout the file.

♻️ Suggested change
-import { describe, expect, it } from 'vitest'
+import { describe, expect, test } from 'vitest'

Then replace all it(...) calls with test(...) throughout the file.

🤖 Prompt for AI Agents
In `@src/components/ui/tags-input/TagsInput.test.ts` around lines 1 - 3, The test
file uses "it(...)" to define test cases but your coding guidelines require
"test(...)" instead; update every test case declaration in TagsInput.test.ts by
replacing each "it(" call with "test(" while keeping the same callback
functions, descriptions, and any async/await usage (i.e., preserve the existing
describe blocks, callbacks, and imports such as mount, describe, expect, h,
nextTick) so only the test declaration identifier changes.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

What testing guideline says that?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@coderabbitai What guideline says that? It's wrong.

Comment on lines +145 to +161
it('shows placeholder when modelValue is empty', async () => {
const wrapper = mount<typeof TagsInput<string>>(TagsInput, {
props: {
modelValue: []
},
slots: {
default: ({ isEmpty }: { isEmpty: boolean }) =>
h(TagsInputInput, { placeholder: 'Add tag...', isEmpty })
}
})

await nextTick()

const input = wrapper.find('input')
expect(input.exists()).toBe(true)
expect(input.attributes('placeholder')).toBe('Add tag...')
})
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

Clarify the intent of isEmpty prop in placeholder test.

The test passes isEmpty from the slot scope to TagsInputInput, but this appears unused in the assertion. If isEmpty drives specific behavior (e.g., automatically showing the input), consider adding an assertion that validates this relationship, or remove it if unnecessary.

♻️ Suggested simplification if isEmpty is not needed
     slots: {
-      default: ({ isEmpty }: { isEmpty: boolean }) =>
-        h(TagsInputInput, { placeholder: 'Add tag...', isEmpty })
+      default: () => h(TagsInputInput, { placeholder: 'Add tag...' })
     }
📝 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
it('shows placeholder when modelValue is empty', async () => {
const wrapper = mount<typeof TagsInput<string>>(TagsInput, {
props: {
modelValue: []
},
slots: {
default: ({ isEmpty }: { isEmpty: boolean }) =>
h(TagsInputInput, { placeholder: 'Add tag...', isEmpty })
}
})
await nextTick()
const input = wrapper.find('input')
expect(input.exists()).toBe(true)
expect(input.attributes('placeholder')).toBe('Add tag...')
})
it('shows placeholder when modelValue is empty', async () => {
const wrapper = mount<typeof TagsInput<string>>(TagsInput, {
props: {
modelValue: []
},
slots: {
default: () => h(TagsInputInput, { placeholder: 'Add tag...' })
}
})
await nextTick()
const input = wrapper.find('input')
expect(input.exists()).toBe(true)
expect(input.attributes('placeholder')).toBe('Add tag...')
})
🤖 Prompt for AI Agents
In `@src/components/ui/tags-input/TagsInput.test.ts` around lines 145 - 161, The
test "shows placeholder when modelValue is empty" passes the slot-scoped isEmpty
into TagsInputInput but never asserts its effect; either assert that isEmpty is
true and that this causes the expected behavior (e.g., the input is auto-shown
or a CSS class/prop on TagsInputInput is set) by reading the slot scope or
inspecting TagsInputInput props/classes, or remove the unused isEmpty prop from
the slot to simplify the test; update the test for TagsInput and TagsInputInput
accordingly so the intent is explicit (reference: isEmpty, TagsInputInput,
TagsInput, and the test case name).

@DrJKL DrJKL requested a review from a team as a code owner January 15, 2026 02:59
viva-jinyi
viva-jinyi previously approved these changes Jan 15, 2026
Copy link
Member

@viva-jinyi viva-jinyi left a comment

Choose a reason for hiding this comment

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

Awesome

@comfydesigner
Copy link
Collaborator

When not editing tags, gap-1 makes the right side of a tag (when the X isn't visible) appear slightly larger than on the left side. Other than that, looks solid to me

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

🤖 Fix all issues with AI agents
In `@src/components/ui/tags-input/TagsInput.stories.ts`:
- Around line 96-128: The ManyTags story is missing an args property which
prevents Storybook controls from showing consistently; update the export const
ManyTags: Story object to include an args: { disabled: false } (or match default
story controls) so the story provides the same controls as
Default/Empty/Disabled, ensuring the render setup still uses args and v-model
behavior remains unchanged.
- Around line 159-182: The CustomWidth story lacks an args property for
Storybook controls which `render` already expects (it reads args.disabled); add
an args object to the CustomWidth export (e.g., export const CustomWidth: Story
= { args: { disabled: false }, render: (...) }) so controls work consistently
with other stories like ManyTags and ensure the prop name matches usage
(`disabled`) used inside the render function.
♻️ Duplicate comments (2)
src/components/ui/tags-input/TagsInput.test.ts (2)

1-3: Use test instead of it per coding guidelines.

The import uses it but the coding guidelines require test for defining test cases in Vitest. This applies to all test cases in the file (lines 22, 49, 68, 94, 113, 136).

♻️ Suggested change
-import { describe, expect, it } from 'vitest'
+import { describe, expect, test } from 'vitest'

Then replace all it(...) calls with test(...) throughout the file.


136-152: Clarify the purpose of the isEmpty slot prop.

The test passes isEmpty from the slot scope to TagsInputInput, but the assertion only checks the placeholder attribute. If isEmpty is meant to trigger automatic input visibility (which appears to be the case), consider adding an explicit assertion or comment clarifying this relationship.

♻️ Option 1: Add clarifying assertion
   it('shows placeholder when modelValue is empty', async () => {
     const wrapper = mount<typeof TagsInput<string>>(TagsInput, {
       props: {
         modelValue: []
       },
       slots: {
         default: ({ isEmpty }: { isEmpty: boolean }) =>
           h(TagsInputInput, { placeholder: 'Add tag...', isEmpty })
       }
     })

     await nextTick()

     const input = wrapper.find('input')
     expect(input.exists()).toBe(true)
     expect(input.attributes('placeholder')).toBe('Add tag...')
+    // isEmpty=true causes TagsInputInput to auto-show without requiring click
   })
♻️ Option 2: Remove unused prop if isEmpty doesn't affect this test
       slots: {
-        default: ({ isEmpty }: { isEmpty: boolean }) =>
-          h(TagsInputInput, { placeholder: 'Add tag...', isEmpty })
+        default: () => h(TagsInputInput, { placeholder: 'Add tag...' })
       }
📜 Review details

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between c289af0 and 5d21cfe.

📒 Files selected for processing (6)
  • src/components/ui/tags-input/TagsInput.stories.ts
  • src/components/ui/tags-input/TagsInput.test.ts
  • src/components/ui/tags-input/TagsInput.vue
  • src/components/ui/tags-input/TagsInputItem.vue
  • src/components/ui/tags-input/TagsInputItemDelete.vue
  • src/locales/en/main.json
🧰 Additional context used
📓 Path-based instructions (14)
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: Use Vue 3 Single File Components (SFCs) with Composition API only
Use <script setup lang="ts"> for component logic in Vue SFCs
Avoid <style> blocks in Vue components - use Tailwind 4 styling instead
Use vue-i18n for all string literals in Vue components - place translation entries in src/locales/en/main.json
Use Tailwind utility classes instead of dark: variant - use semantic values from style.css theme (e.g., bg-node-component-surface)
Use cn() utility from @/utils/tailwindUtil for merging Tailwind class names instead of :class="[]" or hardcoding
Never use !important or ! Tailwind prefix - fix interfering classes instead
Use Tailwind fraction utilities instead of arbitrary percentage values (e.g., w-4/5 instead of w-[80%])
Use TypeScript Vue 3.5 style default prop declaration with reactive props destructuring - avoid withDefaults or runtime props
Prefer defineModel over separately defining a prop and emit for v-model bindings
Define slots via template usage, not via defineSlots
Use same-name shorthand for slot prop bindings (e.g., :isExpanded instead of :is-expanded="isExpanded")
Do not import Vue macros unnecessarily
Avoid new usage of PrimeVue components
Use Tailwind's plurals system via i18n instead of hardcoding ...

Files:

  • src/components/ui/tags-input/TagsInputItem.vue
  • src/components/ui/tags-input/TagsInput.vue
  • src/components/ui/tags-input/TagsInputItemDelete.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/ui/tags-input/TagsInputItem.vue
  • src/components/ui/tags-input/TagsInput.vue
  • src/components/ui/tags-input/TagsInput.test.ts
  • src/components/ui/tags-input/TagsInputItemDelete.vue
  • src/components/ui/tags-input/TagsInput.stories.ts
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}: Use separate import type statements instead of inline type in mixed imports
Apply Prettier formatting with 2-space indentation, single quotes, no trailing semicolons, 80-character width
Sort and group imports by plugin, run pnpm format before committing
Never use any type - use proper TypeScript types
Never use as any type assertions - fix the underlying type issue
Write code that is expressive and self-documenting - avoid unnecessary comments
Do not add or retain redundant comments - clean as you go
Avoid mutable state - prefer immutability and assignment at point of declaration
Watch out for Code Smells and refactor to avoid them

Files:

  • src/components/ui/tags-input/TagsInputItem.vue
  • src/components/ui/tags-input/TagsInput.vue
  • src/components/ui/tags-input/TagsInput.test.ts
  • src/components/ui/tags-input/TagsInputItemDelete.vue
  • src/components/ui/tags-input/TagsInput.stories.ts
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/ui/tags-input/TagsInputItem.vue
  • src/components/ui/tags-input/TagsInput.vue
  • src/components/ui/tags-input/TagsInput.test.ts
  • src/components/ui/tags-input/TagsInputItemDelete.vue
  • src/components/ui/tags-input/TagsInput.stories.ts
src/**/*.{vue,ts,tsx}

📄 CodeRabbit inference engine (src/CLAUDE.md)

Follow Vue 3 composition API style guide

Files:

  • src/components/ui/tags-input/TagsInputItem.vue
  • src/components/ui/tags-input/TagsInput.vue
  • src/components/ui/tags-input/TagsInput.test.ts
  • src/components/ui/tags-input/TagsInputItemDelete.vue
  • src/components/ui/tags-input/TagsInput.stories.ts
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/ui/tags-input/TagsInputItem.vue
  • src/components/ui/tags-input/TagsInput.vue
  • src/components/ui/tags-input/TagsInput.test.ts
  • src/components/ui/tags-input/TagsInputItemDelete.vue
  • src/components/ui/tags-input/TagsInput.stories.ts
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

Name Vue components in PascalCase (e.g., MenuHamburger.vue)

Files:

  • src/components/ui/tags-input/TagsInputItem.vue
  • src/components/ui/tags-input/TagsInput.vue
  • src/components/ui/tags-input/TagsInputItemDelete.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/ui/tags-input/TagsInputItem.vue
  • src/components/ui/tags-input/TagsInput.vue
  • src/components/ui/tags-input/TagsInputItemDelete.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/ui/tags-input/TagsInputItem.vue
  • src/components/ui/tags-input/TagsInput.vue
  • src/components/ui/tags-input/TagsInput.test.ts
  • src/components/ui/tags-input/TagsInputItemDelete.vue
  • src/components/ui/tags-input/TagsInput.stories.ts
src/**/*.{ts,vue}

📄 CodeRabbit inference engine (AGENTS.md)

src/**/*.{ts,vue}: Use ref for reactive state, computed() for derived values, and watch/watchEffect for side effects in Composition API
Avoid using ref with watch if a computed would suffice - minimize refs and derived state
Use provide/inject for dependency injection only when simpler alternatives (Store or shared composable) won't work
Leverage VueUse functions for performance-enhancing composables
Use VueUse function for useI18n in composition API for string literals

Files:

  • src/components/ui/tags-input/TagsInputItem.vue
  • src/components/ui/tags-input/TagsInput.vue
  • src/components/ui/tags-input/TagsInput.test.ts
  • src/components/ui/tags-input/TagsInputItemDelete.vue
  • src/components/ui/tags-input/TagsInput.stories.ts
src/**/*.ts

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

src/**/*.ts: Use es-toolkit for utility functions
Use TypeScript for type safety

src/**/*.ts: Derive component types using vue-component-type-helpers (ComponentProps, ComponentSlots) instead of separate type files
Use es-toolkit for utility functions
Minimize the surface area (exported values) of each module and composable
Favor pure functions, especially testable ones

Files:

  • src/components/ui/tags-input/TagsInput.test.ts
  • src/components/ui/tags-input/TagsInput.stories.ts
+(tests-ui|src)/**/*.test.ts

📄 CodeRabbit inference engine (AGENTS.md)

+(tests-ui|src)/**/*.test.ts: Unit and component tests belong in tests-ui/ or src/**/*.test.ts using Vitest
Write tests for all changes, especially bug fixes to catch future regressions
Do not write tests dependent on non-behavioral features like utility classes or styles
Do not write tests that just test the mocks - ensure tests fail when code behaves unexpectedly
Leverage Vitest's utilities for mocking where possible
Keep module mocks contained - do not use global mutable state within test files; use vi.hoisted() if necessary
Use Vue Test Utils for Component testing and follow best practices for making components easy to test
Aim for behavioral coverage of critical and new features in unit tests

Files:

  • src/components/ui/tags-input/TagsInput.test.ts
src/**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

src/**/*.{ts,tsx}: Keep functions short and functional
Minimize nesting (if statements, for loops, etc.)
Use function declarations instead of function expressions when possible

Files:

  • src/components/ui/tags-input/TagsInput.test.ts
  • src/components/ui/tags-input/TagsInput.stories.ts
+(tests-ui|src|browser_tests)/**/*.+(test.ts|spec.ts)

📄 CodeRabbit inference engine (AGENTS.md)

+(tests-ui|src|browser_tests)/**/*.+(test.ts|spec.ts): Do not write change detector tests - avoid tests that only assert default values
Be parsimonious in testing - do not write redundant tests
Don't Mock What You Don't Own

Files:

  • src/components/ui/tags-input/TagsInput.test.ts
🧠 Learnings (56)
📓 Common learnings
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 : Use provide/inject for dependency injection in Vue components
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 provide/inject for dependency injection
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: AGENTS.md:0-0
Timestamp: 2026-01-10T00:24:17.695Z
Learning: Applies to +(tests-ui|src)/**/*.test.ts : Use Vue Test Utils for Component testing and follow best practices for making components easy to test
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
📚 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/ui/tags-input/TagsInputItem.vue
  • src/components/ui/tags-input/TagsInput.vue
  • src/components/ui/tags-input/TagsInputItemDelete.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/components/ui/tags-input/TagsInputItem.vue
  • src/components/ui/tags-input/TagsInput.vue
  • src/components/ui/tags-input/TagsInputItemDelete.vue
📚 Learning: 2026-01-10T00:24:17.695Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-10T00:24:17.695Z
Learning: Applies to src/**/*.vue : Use Vue 3 Single File Components (SFCs) with Composition API only

Applied to files:

  • src/components/ui/tags-input/TagsInputItem.vue
  • src/components/ui/tags-input/TagsInput.vue
  • src/components/ui/tags-input/TagsInputItemDelete.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/components/ui/tags-input/TagsInputItem.vue
  • src/components/ui/tags-input/TagsInput.vue
  • src/components/ui/tags-input/TagsInputItemDelete.vue
📚 Learning: 2026-01-10T00:24:17.695Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-10T00:24:17.695Z
Learning: Applies to src/**/*.ts : Derive component types using `vue-component-type-helpers` (`ComponentProps`, `ComponentSlots`) instead of separate type files

Applied to files:

  • src/components/ui/tags-input/TagsInputItem.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/**/{components,composables}/**/*.{ts,tsx,vue} : Use vue-i18n for ALL user-facing strings by adding them to `src/locales/en/main.json`

Applied to files:

  • src/components/ui/tags-input/TagsInputItem.vue
  • src/components/ui/tags-input/TagsInputItemDelete.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 proper props and emits definitions

Applied to files:

  • src/components/ui/tags-input/TagsInputItem.vue
  • src/components/ui/tags-input/TagsInputItemDelete.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/ui/tags-input/TagsInputItem.vue
  • src/components/ui/tags-input/TagsInput.vue
  • src/components/ui/tags-input/TagsInputItemDelete.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/ui/tags-input/TagsInputItem.vue
  • src/components/ui/tags-input/TagsInput.vue
  • src/components/ui/tags-input/TagsInputItemDelete.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/ui/tags-input/TagsInputItem.vue
  • src/components/ui/tags-input/TagsInput.vue
  • src/components/ui/tags-input/TagsInputItemDelete.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/ui/tags-input/TagsInputItem.vue
  • src/components/ui/tags-input/TagsInput.vue
  • src/components/ui/tags-input/TagsInputItemDelete.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/components/ui/tags-input/TagsInputItem.vue
  • src/components/ui/tags-input/TagsInput.vue
  • src/components/ui/tags-input/TagsInputItemDelete.vue
📚 Learning: 2026-01-08T02:26:18.357Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7893
File: src/components/button/IconGroup.vue:5-6
Timestamp: 2026-01-08T02:26:18.357Z
Learning: In components that use the cn utility from '@/utils/tailwindUtil' with tailwind-merge, rely on the behavior that conflicting Tailwind classes are resolved by keeping the last one. For example, cn('base-classes bg-default', propClass) will have any conflicting background class from propClass override bg-default. This additive pattern is intentional and aligns with the shadcn-ui convention; ensure you document or review expectations accordingly in Vue components.

Applied to files:

  • src/components/ui/tags-input/TagsInputItem.vue
  • src/components/ui/tags-input/TagsInput.vue
  • src/components/ui/tags-input/TagsInputItemDelete.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/ui/tags-input/TagsInputItem.vue
  • src/components/ui/tags-input/TagsInput.vue
  • src/components/ui/tags-input/TagsInput.test.ts
  • src/components/ui/tags-input/TagsInputItemDelete.vue
  • src/components/ui/tags-input/TagsInput.stories.ts
📚 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/ui/tags-input/TagsInputItem.vue
  • src/components/ui/tags-input/TagsInput.vue
  • src/components/ui/tags-input/TagsInputItemDelete.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/ui/tags-input/TagsInputItem.vue
  • src/components/ui/tags-input/TagsInput.vue
  • src/components/ui/tags-input/TagsInputItemDelete.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/ui/tags-input/TagsInputItem.vue
  • src/components/ui/tags-input/TagsInput.vue
  • src/components/ui/tags-input/TagsInputItemDelete.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/ui/tags-input/TagsInputItem.vue
  • src/components/ui/tags-input/TagsInput.vue
  • src/components/ui/tags-input/TagsInputItemDelete.vue
📚 Learning: 2026-01-12T17:39:27.738Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7906
File: src/components/sidebar/tabs/AssetsSidebarTab.vue:545-552
Timestamp: 2026-01-12T17:39:27.738Z
Learning: In Vue/TypeScript files (src/**/*.{ts,tsx,vue}), prefer if/else statements over ternary operators when performing side effects or actions (e.g., mutating state, calling methods with side effects). Ternaries should be reserved for computing and returning values.

Applied to files:

  • src/components/ui/tags-input/TagsInputItem.vue
  • src/components/ui/tags-input/TagsInput.vue
  • src/components/ui/tags-input/TagsInput.test.ts
  • src/components/ui/tags-input/TagsInputItemDelete.vue
  • src/components/ui/tags-input/TagsInput.stories.ts
📚 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/ui/tags-input/TagsInput.vue
📚 Learning: 2026-01-10T00:24:17.695Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-10T00:24:17.695Z
Learning: Applies to src/**/*.vue : Use TypeScript Vue 3.5 style default prop declaration with reactive props destructuring - avoid `withDefaults` or runtime props

Applied to files:

  • src/components/ui/tags-input/TagsInput.vue
  • src/components/ui/tags-input/TagsInputItemDelete.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/ui/tags-input/TagsInput.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 : Follow Vue 3 style guide and naming conventions

Applied to files:

  • src/components/ui/tags-input/TagsInput.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/components/ui/tags-input/TagsInput.vue
📚 Learning: 2026-01-10T00:24:17.695Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-10T00:24:17.695Z
Learning: Applies to +(tests-ui|src)/**/*.test.ts : Use Vue Test Utils for Component testing and follow best practices for making components easy to test

Applied to files:

  • src/components/ui/tags-input/TagsInput.test.ts
📚 Learning: 2026-01-10T00:24:17.695Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-10T00:24:17.695Z
Learning: Applies to +(tests-ui|src)/**/*.test.ts : Write tests for all changes, especially bug fixes to catch future regressions

Applied to files:

  • src/components/ui/tags-input/TagsInput.test.ts
📚 Learning: 2026-01-10T00:24:17.695Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-10T00:24:17.695Z
Learning: Applies to +(tests-ui|src)/**/*.test.ts : Aim for behavioral coverage of critical and new features in unit tests

Applied to files:

  • src/components/ui/tags-input/TagsInput.test.ts
📚 Learning: 2026-01-10T00:24:17.695Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-10T00:24:17.695Z
Learning: Applies to +(tests-ui|src)/**/*.test.ts : Unit and component tests belong in `tests-ui/` or `src/**/*.test.ts` using Vitest

Applied to files:

  • src/components/ui/tags-input/TagsInput.test.ts
📚 Learning: 2026-01-10T00:24:17.695Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-10T00:24:17.695Z
Learning: Applies to +(tests-ui|src)/**/*.test.ts : Do not write tests dependent on non-behavioral features like utility classes or styles

Applied to files:

  • src/components/ui/tags-input/TagsInput.test.ts
📚 Learning: 2026-01-10T00:24:17.695Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-10T00:24:17.695Z
Learning: Applies to +(tests-ui|src)/**/*.test.ts : Leverage Vitest's utilities for mocking where possible

Applied to files:

  • src/components/ui/tags-input/TagsInput.test.ts
📚 Learning: 2026-01-10T00:24:17.695Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-10T00:24:17.695Z
Learning: Applies to browser_tests/**/*.spec.ts : Use tags like `mobile`, `2x` in Playwright tests for configuration-aware test selection

Applied to files:

  • src/components/ui/tags-input/TagsInput.test.ts
📚 Learning: 2026-01-10T00:24:17.695Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-10T00:24:17.695Z
Learning: Applies to +(tests-ui|src|browser_tests)/**/*.+(test.ts|spec.ts) : Be parsimonious in testing - do not write redundant tests

Applied to files:

  • src/components/ui/tags-input/TagsInput.test.ts
📚 Learning: 2026-01-10T00:24:17.695Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-10T00:24:17.695Z
Learning: Applies to +(tests-ui|src|browser_tests)/**/*.+(test.ts|spec.ts) : Do not write change detector tests - avoid tests that only assert default values

Applied to files:

  • src/components/ui/tags-input/TagsInput.test.ts
📚 Learning: 2026-01-10T00:24:17.695Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-10T00:24:17.695Z
Learning: Applies to +(tests-ui|src)/**/*.test.ts : Keep module mocks contained - do not use global mutable state within test files; use `vi.hoisted()` if necessary

Applied to files:

  • src/components/ui/tags-input/TagsInput.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:

  • src/components/ui/tags-input/TagsInput.test.ts
📚 Learning: 2026-01-10T00:24:17.695Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-10T00:24:17.695Z
Learning: Applies to +(tests-ui|src)/**/*.test.ts : Do not write tests that just test the mocks - ensure tests fail when code behaves unexpectedly

Applied to files:

  • src/components/ui/tags-input/TagsInput.test.ts
📚 Learning: 2025-11-24T19:47:56.371Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/lib/litegraph/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:56.371Z
Learning: Applies to src/lib/litegraph/**/*.{test,spec}.{js,ts,jsx,tsx} : When adding features, always write vitest unit tests using cursor rules in @.cursor

Applied to files:

  • src/components/ui/tags-input/TagsInput.test.ts
📚 Learning: 2026-01-08T02:40:15.482Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7894
File: src/renderer/extensions/vueNodes/widgets/components/WidgetToggleSwitch.test.ts:11-14
Timestamp: 2026-01-08T02:40:15.482Z
Learning: In TypeScript test files (e.g., any test under src), avoid duplicating interface/type definitions. Import real type definitions from the component modules under test and reference them directly, so there is a single source of truth and to prevent type drift. This improves maintainability and consistency across tests.

Applied to files:

  • src/components/ui/tags-input/TagsInput.test.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} : Prefer specific selectors in browser tests

Applied to files:

  • src/components/ui/tags-input/TagsInput.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 `test` instead of `it` for defining test cases in vitest

Applied to files:

  • src/components/ui/tags-input/TagsInput.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:

  • src/components/ui/tags-input/TagsInput.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} : Prefer the use of `test.extend` over loose variables; import `test as baseTest` from `vitest`

Applied to files:

  • src/components/ui/tags-input/TagsInput.test.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:

  • src/components/ui/tags-input/TagsInput.test.ts
📚 Learning: 2025-12-05T08:52:50.787Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7137
File: src/components/rightSidePanel/parameters/SectionWidgets.vue:41-49
Timestamp: 2025-12-05T08:52:50.787Z
Learning: In Vue 3.4+ SFCs with a build step, kebab-case prop shorthand (e.g., `:is-empty`) automatically resolves to the corresponding camelCase variable in scope (e.g., `isEmpty`). This is valid syntax combining same-name shorthand with automatic kebab-case-to-camelCase conversion and should not be flagged as an error.

Applied to files:

  • src/components/ui/tags-input/TagsInput.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:

  • src/components/ui/tags-input/TagsInput.test.ts
  • src/components/ui/tags-input/TagsInput.stories.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:

  • src/components/ui/tags-input/TagsInput.test.ts
  • src/components/ui/tags-input/TagsInput.stories.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:

  • src/components/ui/tags-input/TagsInput.test.ts
  • src/components/ui/tags-input/TagsInput.stories.ts
📚 Learning: 2025-12-30T22:22:33.836Z
Learnt from: kaili-yang
Repo: Comfy-Org/ComfyUI_frontend PR: 7805
File: src/composables/useCoreCommands.ts:439-439
Timestamp: 2025-12-30T22:22:33.836Z
Learning: When accessing reactive properties from Pinia stores in TypeScript files, avoid using .value on direct property access (e.g., useStore().isOverlayExpanded). Pinia auto-wraps refs when accessed directly, returning the primitive value. The .value accessor is only needed when destructuring store properties or when using storeToRefs().

Applied to files:

  • src/components/ui/tags-input/TagsInput.test.ts
  • src/components/ui/tags-input/TagsInput.stories.ts
📚 Learning: 2025-12-30T01:31:04.927Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7797
File: tests-ui/tests/lib/litegraph/src/widgets/ComboWidget.test.ts:648-648
Timestamp: 2025-12-30T01:31:04.927Z
Learning: In Vitest v4, when mocking functions that may be called as constructors (using new), the mock implementation must use function() or class syntax rather than an arrow function. Arrow mocks can cause '<anonymous> is not a constructor' errors. This is a breaking change from Vitest v3 where mocks could use an arrow function. Apply this guideline to test files that mock constructor-like calls (e.g., in tests under tests-ui, such as ComboWidget.test.ts) and ensure mock implementations are defined with function() { ... } or class { ... } to preserve constructor behavior.

Applied to files:

  • src/components/ui/tags-input/TagsInput.test.ts
📚 Learning: 2026-01-09T02:07:54.558Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7898
File: src/composables/usePaste.test.ts:248-248
Timestamp: 2026-01-09T02:07:54.558Z
Learning: In test files (e.g., any .test.ts or .test.tsx under src/...), when you create mock objects that partially implement an interface (such as LGraphNode), prefer casting with as Partial<InterfaceType> as InterfaceType rather than as any or as unknown as InterfaceType. This makes the incomplete implementation explicit while preserving type safety, improving readability and maintainability of tests.

Applied to files:

  • src/components/ui/tags-input/TagsInput.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:

  • src/components/ui/tags-input/TagsInputItemDelete.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/ui/tags-input/TagsInputItemDelete.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,css} : Use Tailwind CSS only for styling (no custom CSS)

Applied to files:

  • src/components/ui/tags-input/TagsInputItemDelete.vue
📚 Learning: 2025-12-05T06:11:09.383Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7177
File: src/platform/assets/components/UploadModelFooter.vue:72-78
Timestamp: 2025-12-05T06:11:09.383Z
Learning: For the ComfyUI_frontend repository, avoid suggesting comments that would be redundant when the code is already self-explanatory through descriptive naming (e.g., filenames, prop names, aria-labels). The project prefers clean code without unnecessary documentation comments.

Applied to files:

  • src/components/ui/tags-input/TagsInputItemDelete.vue
📚 Learning: 2025-12-16T17:30:29.719Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7559
File: .storybook/preview.ts:61-61
Timestamp: 2025-12-16T17:30:29.719Z
Learning: In .storybook/preview.ts for the Comfy-Org/ComfyUI_frontend repository, using `document.body.classList.add('[&_*]:!font-inter')` is the correct approach for applying the Inter font to all Storybook story elements. The simpler `font-inter` class alone does not work in this context. This runtime arbitrary variant pattern is valid and should not be flagged as an issue.

Applied to files:

  • src/components/ui/tags-input/TagsInput.stories.ts
🧬 Code graph analysis (1)
src/components/ui/tags-input/TagsInput.stories.ts (1)
src/components/input/SingleSelect.stories.ts (1)
  • Story (40-40)
⏰ 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). (7)
  • GitHub Check: deploy-and-comment
  • GitHub Check: setup
  • GitHub Check: lint-and-format
  • GitHub Check: test
  • GitHub Check: collect
  • GitHub Check: collect
  • GitHub Check: lint-and-format
🔇 Additional comments (9)
src/components/ui/tags-input/TagsInputItem.vue (1)

1-27: LGTM!

The component correctly wraps reka-ui's TagsInputItem with proper prop forwarding and Tailwind class composition. Good use of Vue 3.5 style prop destructuring and separate type imports.

src/locales/en/main.json (1)

19-19: LGTM!

The translation key g.removeTag is correctly added and matches the usage in TagsInputItemDelete.vue (t('g.removeTag')).

src/components/ui/tags-input/TagsInputItemDelete.vue (1)

1-36: LGTM!

The component correctly implements an accessible delete button with:

  • Proper aria-label via vue-i18n for screen reader support
  • Smooth transition animations using data-[disabled] selectors for the click-to-edit UX
  • Correct use of the shared Button component with appropriate variant/size
src/components/ui/tags-input/TagsInput.vue (1)

1-77: LGTM!

The component implements the click-to-edit pattern cleanly with:

  • Proper use of provide/inject for cross-component focus/editing coordination (per coding guidelines)
  • VueUse's onClickOutside for exiting edit mode
  • Correct handling of async focus with nextTick
  • Decorative icon marked with aria-hidden="true"
  • Clean slot API exposing isEmpty for conditional placeholder rendering
src/components/ui/tags-input/TagsInput.test.ts (5)

11-27: LGTM!

The helper function and slot content test are clean and verify actual rendering behavior.


29-47: LGTM!

The mountFullTagsInput helper cleanly composes the full component tree using render functions, making tests readable and maintainable.


49-66: LGTM!

Good consolidation - the test verifies both structural elements and actual text content rendering, making it a meaningful behavioral test rather than just count assertions.


68-92: LGTM!

The test properly validates the complete user flow: clicking to enter edit mode, typing a tag, and pressing Enter to add it. Using a mutable variable to capture onUpdate:modelValue is an acceptable pattern for testing v-model behavior.


94-134: LGTM!

Good coverage of critical UX behaviors:

  • Disabled state correctly prevents edit mode entry
  • Click-outside properly exits edit mode
  • The attachTo: document.body and explicit wrapper.unmount() follow best practices for DOM-attached tests to prevent memory leaks.

✏️ Tip: You can disable this entire section by setting review_details to false in your review settings.

Comment on lines +96 to +128
export const ManyTags: Story = {
render: (args) => ({
components: {
TagsInput,
TagsInputInput,
TagsInputItem,
TagsInputItemDelete,
TagsInputItemText
},
setup() {
const tags = ref([
'JavaScript',
'TypeScript',
'Vue',
'React',
'Svelte',
'Node.js',
'Python',
'Rust'
])
return { tags, args }
},
template: `
<TagsInput v-model="tags" :disabled="args.disabled" class="w-96" v-slot="{ isEmpty }">
<TagsInputItem v-for="tag in tags" :key="tag" :value="tag">
<TagsInputItemText />
<TagsInputItemDelete />
</TagsInputItem>
<TagsInputInput :is-empty="isEmpty" placeholder="Add technology..." />
</TagsInput>
`
})
}
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 adding args for Storybook controls consistency.

The ManyTags story doesn't have an args property, unlike Default, Empty, and Disabled. Adding args would enable the Storybook controls panel to work consistently across all stories.

Suggested fix
 export const ManyTags: Story = {
+  args: {
+    disabled: false
+  },
   render: (args) => ({
📝 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
export const ManyTags: Story = {
render: (args) => ({
components: {
TagsInput,
TagsInputInput,
TagsInputItem,
TagsInputItemDelete,
TagsInputItemText
},
setup() {
const tags = ref([
'JavaScript',
'TypeScript',
'Vue',
'React',
'Svelte',
'Node.js',
'Python',
'Rust'
])
return { tags, args }
},
template: `
<TagsInput v-model="tags" :disabled="args.disabled" class="w-96" v-slot="{ isEmpty }">
<TagsInputItem v-for="tag in tags" :key="tag" :value="tag">
<TagsInputItemText />
<TagsInputItemDelete />
</TagsInputItem>
<TagsInputInput :is-empty="isEmpty" placeholder="Add technology..." />
</TagsInput>
`
})
}
export const ManyTags: Story = {
args: {
disabled: false
},
render: (args) => ({
components: {
TagsInput,
TagsInputInput,
TagsInputItem,
TagsInputItemDelete,
TagsInputItemText
},
setup() {
const tags = ref([
'JavaScript',
'TypeScript',
'Vue',
'React',
'Svelte',
'Node.js',
'Python',
'Rust'
])
return { tags, args }
},
template: `
<TagsInput v-model="tags" :disabled="args.disabled" class="w-96" v-slot="{ isEmpty }">
<TagsInputItem v-for="tag in tags" :key="tag" :value="tag">
<TagsInputItemText />
<TagsInputItemDelete />
</TagsInputItem>
<TagsInputInput :is-empty="isEmpty" placeholder="Add technology..." />
</TagsInput>
`
})
}
🤖 Prompt for AI Agents
In `@src/components/ui/tags-input/TagsInput.stories.ts` around lines 96 - 128, The
ManyTags story is missing an args property which prevents Storybook controls
from showing consistently; update the export const ManyTags: Story object to
include an args: { disabled: false } (or match default story controls) so the
story provides the same controls as Default/Empty/Disabled, ensuring the render
setup still uses args and v-model behavior remains unchanged.

Comment on lines +159 to +182
export const CustomWidth: Story = {
render: (args) => ({
components: {
TagsInput,
TagsInputInput,
TagsInputItem,
TagsInputItemDelete,
TagsInputItemText
},
setup() {
const tags = ref(['Full', 'Width'])
return { tags, args }
},
template: `
<TagsInput v-model="tags" :disabled="args.disabled" class="w-full" v-slot="{ isEmpty }">
<TagsInputItem v-for="tag in tags" :key="tag" :value="tag">
<TagsInputItemText />
<TagsInputItemDelete />
</TagsInputItem>
<TagsInputInput :is-empty="isEmpty" placeholder="Add tag..." />
</TagsInput>
`
})
}
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 adding args for Storybook controls consistency.

Similar to ManyTags, the CustomWidth story would benefit from an args property for consistent Storybook controls behavior.

Suggested fix
 export const CustomWidth: Story = {
+  args: {
+    disabled: false
+  },
   render: (args) => ({
🤖 Prompt for AI Agents
In `@src/components/ui/tags-input/TagsInput.stories.ts` around lines 159 - 182,
The CustomWidth story lacks an args property for Storybook controls which
`render` already expects (it reads args.disabled); add an args object to the
CustomWidth export (e.g., export const CustomWidth: Story = { args: { disabled:
false }, render: (...) }) so controls work consistently with other stories like
ManyTags and ensure the prop name matches usage (`disabled`) used inside the
render function.

Copy link
Collaborator

@comfydesigner comfydesigner left a comment

Choose a reason for hiding this comment

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

Colors and spacing are good now

@coderabbitai coderabbitai bot requested a review from comfydesigner January 15, 2026 04:47
@DrJKL DrJKL requested a review from viva-jinyi January 15, 2026 05:02
@DrJKL DrJKL merged commit 23694f3 into main Jan 15, 2026
28 checks passed
@DrJKL DrJKL deleted the drjkl/some-people-call-it-a-yard-sale branch January 15, 2026 05:17
@DrJKL DrJKL added needs-backport Fix/change that needs to be cherry-picked to the current feature freeze branch cloud/1.37 Backport PRs for cloud 1.37 labels Jan 22, 2026
github-actions bot pushed a commit that referenced this pull request Jan 22, 2026
## Summary

Add TagsInput component based on shadcn-vue/Reka UI primitives with a
click-to-edit UX pattern.

## Features

- **Click-to-edit behavior**: Starts in read-only state; clicking
enables editing and focuses input; clicking outside exits edit mode
- **Disabled state**: When `disabled=true`, component is completely
inert
- **Empty state placeholder**: Shows input placeholder when tag list is
empty
- **Animated transitions**: Delete button animates when toggling edit
mode

---------

Co-authored-by: Amp <amp@ampcode.com>
@comfy-pr-bot
Copy link
Member

@DrJKL Successfully backported to #8236

@github-actions github-actions bot removed the needs-backport Fix/change that needs to be cherry-picked to the current feature freeze branch label Jan 22, 2026
DrJKL added a commit that referenced this pull request Jan 22, 2026
…-edit behavior (#8236)

Backport of #8066 to `cloud/1.37`

Automatically created by backport workflow.

Co-authored-by: Alexander Brown <drjkl@comfy.org>
Co-authored-by: Amp <amp@ampcode.com>
DrJKL added a commit that referenced this pull request Jan 22, 2026
…xt and TagsInput escape key (#8238)

Backport of #8204 to `cloud/1.37`.

Cherry-picked merge commit `7b701ad07b1c34d121448e21d6f8b5c13ef07d73`.

## Original PR Summary
This PR improves keyboard event handling consistency and fixes an issue
where pressing Escape in nested input components would unintentionally
close parent modals/dialogs.

### Changes
- **EditableText keyup → keydown Migration**: Changed `@keyup.enter` to
`@keydown.enter` and `@keyup.escape` to `@keydown.escape` for more
consistent and responsive feedback
- Updated corresponding unit tests to use `keydown` triggers

> **Note**: The TagsInput escape key handling changes from the original
PR are not included in this backport because the TagsInput component
(#8066) was added after the cloud/1.37 branch was created.

┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-8238-backport-cloud-1-37-fix-Consistent-keydown-handling-for-EditableText-and-TagsInput-esc-2f06d73d365081288e5ed0c656d78412)
by [Unito](https://www.unito.io)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

cloud/1.37 Backport PRs for cloud 1.37 Design Used to request Product feedback on design decisions size:XL This PR changes 500-999 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants