fix(autocomplete): resolve Firefox focus reset issue#5842
Conversation
|
@nikhil-304 is attempting to deploy a commit to the HeroUI Inc Team on Vercel. A member of the Team first needs to authorize it. |
🦋 Changeset detectedLatest commit: 3a18c0c The changes in this PR will be included in the next version bump. This PR includes changesets to release 2 packages
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
WalkthroughIntroduces focus and selection tracking to the Autocomplete hook: tracks Tab vs mouse interactions, conditions caret placement vs selecting text on focus, adds onSelectionChange prop, records Tab key for later focus behavior, and enables listbox virtualization when collection size > 50. Adds tests and a changeset. Changes
Sequence Diagram(s)sequenceDiagram
participant User
participant Input as AutocompleteInput
participant Hook as useAutocomplete
participant List as ListBox
rect rgba(200,230,255,0.25)
User->>Input: Press Tab to focus
Input->>Hook: onKeyDown (records Tab -> lastKeyRef)
Input->>Hook: onFocus
Hook->>Hook: detect lastKeyRef == 'Tab'
Hook->>Input: selectAll() (shouldSkipSelect / select-on-focus path)
end
rect rgba(230,255,210,0.25)
User->>Input: Click to focus (mouse)
Input->>Hook: onMouseDown (set isMouseFocus)
Input->>Hook: onFocus
Hook->>Hook: detect mouse focus -> place caret at end (no selection)
end
alt large collection (size > 50) or isVirtualized true
Hook->>List: enable virtualization (maxListboxHeight, itemHeight)
else small collection
Hook->>List: normal rendering (no virtualization)
end
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes
Possibly related PRs
Suggested reviewers
Pre-merge checks and finishing touches❌ Failed checks (1 warning, 1 inconclusive)
✅ Passed checks (3 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
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. Comment |
@heroui/accordion
@heroui/alert
@heroui/autocomplete
@heroui/avatar
@heroui/badge
@heroui/breadcrumbs
@heroui/button
@heroui/calendar
@heroui/card
@heroui/checkbox
@heroui/chip
@heroui/code
@heroui/date-input
@heroui/date-picker
@heroui/divider
@heroui/drawer
@heroui/dropdown
@heroui/form
@heroui/image
@heroui/input
@heroui/input-otp
@heroui/kbd
@heroui/link
@heroui/listbox
@heroui/menu
@heroui/modal
@heroui/navbar
@heroui/number-input
@heroui/pagination
@heroui/popover
@heroui/progress
@heroui/radio
@heroui/ripple
@heroui/scroll-shadow
@heroui/select
@heroui/skeleton
@heroui/slider
@heroui/snippet
@heroui/spacer
@heroui/spinner
@heroui/switch
@heroui/table
@heroui/tabs
@heroui/toast
@heroui/tooltip
@heroui/user
@heroui/react
@heroui/system
@heroui/system-rsc
@heroui/theme
@heroui/use-aria-accordion
@heroui/use-aria-accordion-item
@heroui/use-aria-button
@heroui/use-aria-link
@heroui/use-aria-modal-overlay
@heroui/use-aria-multiselect
@heroui/use-aria-overlay
@heroui/use-callback-ref
@heroui/use-clipboard
@heroui/use-data-scroll-overflow
@heroui/use-disclosure
@heroui/use-draggable
@heroui/use-form-reset
@heroui/use-image
@heroui/use-infinite-scroll
@heroui/use-intersection-observer
@heroui/use-is-mobile
@heroui/use-is-mounted
@heroui/use-measure
@heroui/use-pagination
@heroui/use-real-shape
@heroui/use-ref-state
@heroui/use-resize
@heroui/use-safe-layout-effect
@heroui/use-scroll-position
@heroui/use-ssr
@heroui/use-theme
@heroui/use-update-effect
@heroui/use-viewport-size
@heroui/aria-utils
@heroui/dom-animation
@heroui/framer-utils
@heroui/react-rsc-utils
@heroui/react-utils
@heroui/shared-icons
@heroui/shared-utils
@heroui/stories-utils
@heroui/test-utils
commit: |
|
Hey @jrgarciadev 👋 |
wingkwong
left a comment
There was a problem hiding this comment.
- please add changeset
- please include a test case
- your change will alter the existing behaviour. If there is a value in autocomplete, when you tab it to focus, the expected behavior is the whole text got selected and users can type without producing the incorrect input after 1-2 characters (referring to the linked issue). You can also see this behaviour in other components like input.
…Input behavior and prevent partial overwrite
There was a problem hiding this comment.
Actionable comments posted: 0
🧹 Nitpick comments (3)
packages/components/autocomplete/src/use-autocomplete.ts (2)
149-152: Variable naming could be clearer.The variable
shouldSkipSelectis confusing because when it'sfalse, text selection actually occurs, and when it'strue, selection is skipped. Consider renaming to something more intuitive likeshouldPlaceCursorAtEndor inverting the logic withshouldSelectTextto improve code readability.
513-537: Consider simplifying the onFocus logic.The onFocus handler has multiple conditional branches that could be refactored for better readability. Consider extracting this logic into a separate helper function with clear documentation explaining each case:
- When to place cursor at end (mouse selection)
- When to select all text (Tab selection with matching value)
- Default fallback behavior
Apply this refactor if you want to improve readability:
+const handleTextSelection = ( + target: HTMLInputElement, + shouldSkipSelect: boolean, + selectedItem: any, +) => { + if (!target.value) return; + + const length = target.value.length; + + // Place cursor at end if mouse selection + if (shouldSkipSelect) { + target.setSelectionRange(length, length); + return; + } + + // Select text if Tab selection with matching value + if (selectedItem && target.value === selectedItem.textValue) { + target.select(); + return; + } + + // Default: place cursor at end + target.setSelectionRange(length, length); +}; onFocus: chain( inputProps.onFocus, otherProps.onFocus, (e: React.FocusEvent<HTMLInputElement>) => { - if (shouldSkipSelect) { - if (e.target.value) { - const length = e.target.value.length; - e.target.setSelectionRange(length, length); - } - } else if ( - e.target.value && - state.selectedItem && - e.target.value === state.selectedItem.textValue - ) { - e.target.select(); - } else if (e.target.value) { - const length = e.target.value.length; - e.target.setSelectionRange(length, length); - } + handleTextSelection(e.target, shouldSkipSelect, state.selectedItem); setShouldSkipSelect(false); }, ),packages/components/autocomplete/__tests__/autocomplete.test.tsx (1)
1092-1142: Consider adding edge case tests.While the current tests cover the primary scenarios, consider adding tests for edge cases:
- Clicking into the field after a previous selection (does it preserve cursor position?)
- Tab selection followed by blur and re-focus (is selection preserved/reset correctly?)
- Rapid switching between mouse and keyboard selection methods
These additional tests would provide more confidence in the robustness of the fix, especially for the Firefox-specific focus behavior.
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (3)
.changeset/fix-text-selection.md(1 hunks)packages/components/autocomplete/__tests__/autocomplete.test.tsx(1 hunks)packages/components/autocomplete/src/use-autocomplete.ts(5 hunks)
🧰 Additional context used
🧠 Learnings (4)
📚 Learning: 2025-10-27T21:48:35.308Z
Learnt from: adbjo
Repo: heroui-inc/heroui PR: 5846
File: packages/components/tabs/src/tabs.tsx:76-101
Timestamp: 2025-10-27T21:48:35.308Z
Learning: In packages/components/tabs/src/tabs.tsx, the updateCursorPosition useCallback dependency array intentionally includes `cursorRef.current` to handle the case where the cursor span element is unmounted and remounted (e.g., when `disableAnimation` or `disableCursorAnimation` toggles). This ensures the callback is recreated when the ref points to a new element, triggering a dependency chain that re-establishes the ResizeObserver and initializes the new cursor element with the data-initialized attribute.
</learning]
Applied to files:
packages/components/autocomplete/src/use-autocomplete.ts
📚 Learning: 2025-10-25T17:11:59.338Z
Learnt from: adbjo
Repo: heroui-inc/heroui PR: 5846
File: packages/components/tabs/src/tabs.tsx:155-155
Timestamp: 2025-10-25T17:11:59.338Z
Learning: In packages/components/tabs/src/tabs.tsx, the renderTabs useMemo dependency array intentionally includes both `domRef` and `cursorRef` to maintain consistency in how ref objects are handled in dependency arrays, even though ref objects have stable identity across renders.
Applied to files:
packages/components/autocomplete/src/use-autocomplete.ts
📚 Learning: 2025-10-27T21:52:33.324Z
Learnt from: adbjo
Repo: heroui-inc/heroui PR: 5846
File: packages/components/tabs/src/tabs.tsx:115-125
Timestamp: 2025-10-27T21:52:33.324Z
Learning: In packages/components/tabs/src/tabs.tsx, the useEffect dependency array at line 125 intentionally uses `domRef.current` rather than `domRef` because domRef.current can change between renders (when React sets it during the commit phase), whereas domRef itself has stable identity and won't change.
Applied to files:
packages/components/autocomplete/src/use-autocomplete.ts
📚 Learning: 2025-10-25T17:08:46.283Z
Learnt from: adbjo
Repo: heroui-inc/heroui PR: 5846
File: packages/components/tabs/src/tabs.tsx:156-157
Timestamp: 2025-10-25T17:08:46.283Z
Learning: In packages/components/tabs/src/tabs.tsx, the renderTabs useMemo dependency array intentionally includes `variant` and `isVertical` to prevent potential side-effects, even though they might appear redundant based on static analysis.
Applied to files:
packages/components/autocomplete/src/use-autocomplete.ts
⏰ 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: Continuous Release
- GitHub Check: TypeScript
- GitHub Check: Build
- GitHub Check: ESLint
🔇 Additional comments (6)
packages/components/autocomplete/src/use-autocomplete.ts (3)
218-227: Text selection logic works correctly.The logic correctly handles the two selection paths:
- Mouse selection: sets
shouldSkipSelect = true→ cursor placed at end on next focus- Tab selection: sets
shouldSkipSelect = false→ text selected on next focusThis addresses the Firefox focus reset issue by ensuring proper text selection behavior based on interaction method.
431-434: Tab key tracking implementation is correct.Tracking the Tab key press in
onKeyDownallows the component to differentiate between keyboard and mouse-based selections. ThelastKeyRefis appropriately reset inonSelectionChangeafter being consumed.
540-559: The virtualization logic predates the Firefox focus fix—it was not introduced by those changes.The virtualization feature (
isVirtualizedprop with auto-enable threshold at 50 items) already existed before the Firefox focus fix commit (c60b080). The Firefox fix specifically added only theonFocushandler to manage text selection behavior during focus events. These are separate, unrelated features. The virtualization logic is a performance optimization for large lists and has no connection to the Firefox focus reset issue, which involves keyboard/selection behavior management.Likely an incorrect or invalid review comment.
packages/components/autocomplete/__tests__/autocomplete.test.tsx (2)
1092-1117: Mouse selection test validates cursor positioning correctly.The test confirms that selecting an item via mouse click places the cursor at the end of the value without selecting text. This is the expected behavior for mouse-based interactions.
1119-1142: Tab selection test validates text selection correctly.The test confirms that committing a selection via Tab key fully selects the text (selectionStart = 0, selectionEnd = length). This addresses the Firefox focus reset issue by ensuring the text is in a selected state, allowing immediate typing to replace the value.
.changeset/fix-text-selection.md (1)
1-5: Changeset documentation is clear and appropriate.The changeset correctly documents the fix as a patch release and clearly describes the two behavioral changes: text selection on Tab key and cursor positioning on mouse click. This aligns well with the changes implemented in the code.
|
Hi @wingkwong @jrgarciadev, firefox-autocomplete-focus-fix-demo.mp4 |
… focus improvements - Fix Firefox focus reset issues with intelligent caret positioning - Add mouse/keyboard interaction differentiation for better UX - Ensure consistent text selection across all browsers - Tab navigation now selects full text for replacement workflows
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (1)
packages/components/autocomplete/src/use-autocomplete.ts (1)
301-307: Consider filtering mouse button types.The
onMouseDownhandler currently triggers for all mouse buttons. While the focus event typically only fires for left-clicks, you might want to explicitly check for left-button clicks to be more precise:- onMouseDown: () => setIsMouseFocus(true), + onMouseDown: (e: React.MouseEvent) => { + if (e.button === 0) { + setIsMouseFocus(true); + } + },
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
packages/components/autocomplete/src/use-autocomplete.ts(7 hunks)
🧰 Additional context used
🧠 Learnings (4)
📚 Learning: 2025-10-27T21:48:35.308Z
Learnt from: adbjo
Repo: heroui-inc/heroui PR: 5846
File: packages/components/tabs/src/tabs.tsx:76-101
Timestamp: 2025-10-27T21:48:35.308Z
Learning: In packages/components/tabs/src/tabs.tsx, the updateCursorPosition useCallback dependency array intentionally includes `cursorRef.current` to handle the case where the cursor span element is unmounted and remounted (e.g., when `disableAnimation` or `disableCursorAnimation` toggles). This ensures the callback is recreated when the ref points to a new element, triggering a dependency chain that re-establishes the ResizeObserver and initializes the new cursor element with the data-initialized attribute.
</learning]
Applied to files:
packages/components/autocomplete/src/use-autocomplete.ts
📚 Learning: 2025-10-25T17:11:59.338Z
Learnt from: adbjo
Repo: heroui-inc/heroui PR: 5846
File: packages/components/tabs/src/tabs.tsx:155-155
Timestamp: 2025-10-25T17:11:59.338Z
Learning: In packages/components/tabs/src/tabs.tsx, the renderTabs useMemo dependency array intentionally includes both `domRef` and `cursorRef` to maintain consistency in how ref objects are handled in dependency arrays, even though ref objects have stable identity across renders.
Applied to files:
packages/components/autocomplete/src/use-autocomplete.ts
📚 Learning: 2025-10-27T21:52:33.324Z
Learnt from: adbjo
Repo: heroui-inc/heroui PR: 5846
File: packages/components/tabs/src/tabs.tsx:115-125
Timestamp: 2025-10-27T21:52:33.324Z
Learning: In packages/components/tabs/src/tabs.tsx, the useEffect dependency array at line 125 intentionally uses `domRef.current` rather than `domRef` because domRef.current can change between renders (when React sets it during the commit phase), whereas domRef itself has stable identity and won't change.
Applied to files:
packages/components/autocomplete/src/use-autocomplete.ts
📚 Learning: 2025-10-25T17:08:46.283Z
Learnt from: adbjo
Repo: heroui-inc/heroui PR: 5846
File: packages/components/tabs/src/tabs.tsx:156-157
Timestamp: 2025-10-25T17:08:46.283Z
Learning: In packages/components/tabs/src/tabs.tsx, the renderTabs useMemo dependency array intentionally includes `variant` and `isVertical` to prevent potential side-effects, even though they might appear redundant based on static analysis.
Applied to files:
packages/components/autocomplete/src/use-autocomplete.ts
🧬 Code graph analysis (1)
packages/components/autocomplete/src/use-autocomplete.ts (1)
packages/hooks/use-safe-layout-effect/src/index.ts (1)
useSafeLayoutEffect(3-3)
⏰ 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: Continuous Release
- GitHub Check: ESLint
- GitHub Check: TypeScript
- GitHub Check: Build
🔇 Additional comments (4)
packages/components/autocomplete/src/use-autocomplete.ts (4)
149-156: Well-structured state management for interaction tracking.The combination of
useStatefor values that affect rendering (shouldSkipSelect,isMouseFocus) anduseReffor tracking values without re-renders (lastKeyRef) is appropriate. The inline documentation clearly explains each variable's purpose.
475-484: Tab key tracking implementation looks good.The selective tracking of only the Tab key (not other keys) correctly implements the requirement to distinguish Tab navigation from other keyboard interactions. The inline comments clearly explain the purpose and lifecycle of
lastKeyRef.
563-617: Comprehensive focus handler with clear interaction-based logic.The enhanced
onFocusimplementation effectively distinguishes between mouse and keyboard interactions, applies the appropriate selection behavior, and properly resets state flags. The extensive inline documentation makes the complex conditional logic understandable and maintainable.The condition at line 602 (
e.target.value === state.selectedItem.textValue) is a good safeguard to only select text when it matches the selected item, avoiding unexpected selection of user-typed content.
221-238: No action required—behavior is intentional and test-verified.The conditional Tab vs. mouse selection behavior you questioned is a deliberate design feature, not an inconsistency. The codebase includes explicit tests validating both cases:
- Tab key selection (line 1119): Text is selected (
selectionStart=0,selectionEnd=length)- Mouse selection (line 1092): Caret is placed at end (
selectionStart=end,selectionEnd=end)This allows Tab navigation to select all text for easy replacement, while mouse selections position the caret for continued editing. The implementation aligns with its documented intent.
| /** | ||
| * Post-selection caret positioning for dropdown interactions: | ||
| * | ||
| * PROBLEM: When selecting items from dropdown via mouse, the input remains focused | ||
| * but React Aria doesn't trigger onFocus again, so our focus handler doesn't run. | ||
| * | ||
| * SOLUTION: Watch for selection changes and position caret at end for mouse interactions. | ||
| * - Uses useSafeLayoutEffect to run after DOM updates but before paint | ||
| * - Only applies when selection changed and lastKeyRef is null (mouse interaction) | ||
| * - Ensures input is still focused before setting selection | ||
| * - Provides consistent behavior regardless of how dropdown items are selected | ||
| */ | ||
| const prevSelectedKeyRef = useRef(state.selectedKey); | ||
|
|
||
| useSafeLayoutEffect(() => { | ||
| if (state.selectedKey !== prevSelectedKeyRef.current && lastKeyRef.current === null) { | ||
| // Mouse selection from dropdown: ensure caret is at end | ||
| if (inputRef.current && document.activeElement === inputRef.current) { | ||
| const length = inputRef.current.value.length; | ||
|
|
||
| inputRef.current.setSelectionRange(length, length); | ||
| } | ||
| } | ||
| prevSelectedKeyRef.current = state.selectedKey; | ||
| }, [state.selectedKey]); |
There was a problem hiding this comment.
Misleading comment: effect applies to all selections, not just mouse.
The comment on line 442 states "Mouse selection from dropdown: ensure caret is at end" and line 434 claims "Only applies when selection changed and lastKeyRef is null (mouse interaction)". However, lastKeyRef.current is reset to null in onSelectionChange (line 237) before this effect runs, so the condition lastKeyRef.current === null will be true for all selections (mouse, keyboard, Tab-initiated), not just mouse selections.
If the intent is to position the caret at the end for all dropdown selections (and rely on shouldSkipSelect to control the next focus behavior), please update the comments to reflect this. Otherwise, if you truly want to distinguish mouse from Tab-initiated selections here, you should check shouldSkipSelect instead:
- useSafeLayoutEffect(() => {
- if (state.selectedKey !== prevSelectedKeyRef.current && lastKeyRef.current === null) {
- // Mouse selection from dropdown: ensure caret is at end
+ useSafeLayoutEffect(() => {
+ if (state.selectedKey !== prevSelectedKeyRef.current && shouldSkipSelect) {
+ // Non-Tab selection from dropdown: ensure caret is at end
if (inputRef.current && document.activeElement === inputRef.current) {Alternatively, update the comments to clarify that this runs for all selections:
/**
- * Post-selection caret positioning for dropdown interactions:
+ * Post-selection caret positioning for all dropdown interactions:
*
- * PROBLEM: When selecting items from dropdown via mouse, the input remains focused
+ * PROBLEM: When selecting items from dropdown, the input remains focused
* but React Aria doesn't trigger onFocus again, so our focus handler doesn't run.
*
- * SOLUTION: Watch for selection changes and position caret at end for mouse interactions.
+ * SOLUTION: Watch for selection changes and position caret at end.📝 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.
| /** | |
| * Post-selection caret positioning for dropdown interactions: | |
| * | |
| * PROBLEM: When selecting items from dropdown via mouse, the input remains focused | |
| * but React Aria doesn't trigger onFocus again, so our focus handler doesn't run. | |
| * | |
| * SOLUTION: Watch for selection changes and position caret at end for mouse interactions. | |
| * - Uses useSafeLayoutEffect to run after DOM updates but before paint | |
| * - Only applies when selection changed and lastKeyRef is null (mouse interaction) | |
| * - Ensures input is still focused before setting selection | |
| * - Provides consistent behavior regardless of how dropdown items are selected | |
| */ | |
| const prevSelectedKeyRef = useRef(state.selectedKey); | |
| useSafeLayoutEffect(() => { | |
| if (state.selectedKey !== prevSelectedKeyRef.current && lastKeyRef.current === null) { | |
| // Mouse selection from dropdown: ensure caret is at end | |
| if (inputRef.current && document.activeElement === inputRef.current) { | |
| const length = inputRef.current.value.length; | |
| inputRef.current.setSelectionRange(length, length); | |
| } | |
| } | |
| prevSelectedKeyRef.current = state.selectedKey; | |
| }, [state.selectedKey]); | |
| /** | |
| * Post-selection caret positioning for all dropdown interactions: | |
| * | |
| * PROBLEM: When selecting items from dropdown, the input remains focused | |
| * but React Aria doesn't trigger onFocus again, so our focus handler doesn't run. | |
| * | |
| * SOLUTION: Watch for selection changes and position caret at end. | |
| * - Uses useSafeLayoutEffect to run after DOM updates but before paint | |
| * - Applies when selection changed and lastKeyRef is null | |
| * - Ensures input is still focused before setting selection | |
| * - Provides consistent behavior regardless of how dropdown items are selected | |
| */ | |
| const prevSelectedKeyRef = useRef(state.selectedKey); | |
| useSafeLayoutEffect(() => { | |
| if (state.selectedKey !== prevSelectedKeyRef.current && lastKeyRef.current === null) { | |
| // Selection from dropdown: ensure caret is at end | |
| if (inputRef.current && document.activeElement === inputRef.current) { | |
| const length = inputRef.current.value.length; | |
| inputRef.current.setSelectionRange(length, length); | |
| } | |
| } | |
| prevSelectedKeyRef.current = state.selectedKey; | |
| }, [state.selectedKey]); |
|
Hi @wingkwong @jrgarciadev , I also took some time to study how Firefox and Chromium-based browsers handle input selection differently, and adjusted the caret logic to behave consistently across all browsers. I know things are busy with the HeroUI v3 beta launch (which looks amazing 🎉), but whenever you both get a moment, I’d really appreciate it if you could take another look 🙏 |
|
Hi @wingkwong, I know things are super busy with the v3 beta release, but whenever you get a moment I’d really appreciate another review 🙏 |
wingkwong
left a comment
There was a problem hiding this comment.
This PR seems adding more complexity to the component while the issue should be resolved from the upstream as it is also reproducible in https://react-spectrum.adobe.com/react-aria/Autocomplete.html#value
|
Got it, thanks for the clarification. |
Closes #5840
📝 Description
This PR fixes the Firefox Autocomplete input reset issue where typing after navigating into the input field using the Tab key caused the text to reset or get overwritten.
The problem occurred only in Firefox and only when focusing via keyboard - clicking into the field worked fine.
The fix ensures that the Autocomplete input now correctly handles focus events in Firefox, maintaining the input state regardless of how the field is focused.
⛳️ Current behavior (updates)
📹 Before videos:
https://github.com/user-attachments/assets/1137923c-6b03-46ac-a93d-07c8a7295a94
https://github.com/user-attachments/assets/76cf2edf-8add-4e22-b8c3-b0d1f2a2100e
🚀 New behavior
📹 After video:
https://github.com/user-attachments/assets/54b31896-c4d1-4273-826a-2fa47b54bb0e
💣 Is this a breaking change (Yes/No):
No
📝 Additional Information
Summary by CodeRabbit
Bug Fixes
New Features
Tests