Skip to content

fix(PinInput, InputDate): resolve double input and segment issues in IME mode#6390

Open
k90325248 wants to merge 3 commits intonuxt:v4from
k90325248:fix-ime-double-input
Open

fix(PinInput, InputDate): resolve double input and segment issues in IME mode#6390
k90325248 wants to merge 3 commits intonuxt:v4from
k90325248:fix-ime-double-input

Conversation

@k90325248
Copy link
Copy Markdown

@k90325248 k90325248 commented Apr 23, 2026

🔗 Linked issue

Resolves (None) - Fixed based on local testing for IME compatibility.

❓ Type of change

  • 📖 Documentation (updates to the documentation or readme)
  • 🐞 Bug fix (a non-breaking change that fixes an issue)
  • 👌 Enhancement (improving an existing functionality)
  • ✨ New feature (a non-breaking change that adds functionality)
  • 🧹 Chore (updates to the build process or auxiliary tools and libraries)
  • ⚠️ Breaking change (fix or feature that would cause existing functionality to change)

📚 Description

This PR fixes several major issues encountered by users of CJK Input Method Editors (IME):

  1. PinInput Double Input & Firefox Compatibility:

    • Problem: When using an IME, reka-ui shifts focus to the next field too early, resulting in duplicate digits.
    • Fix: We now capture and block input events during composition and manually dispatch a clean input event upon compositionend.
    • Enhancement: Added a user-agent check to skip the synthetic input dispatch on Firefox. Firefox natively fires a post-compositionend input event, so skipping our synthetic event prevents duplicate inputs specific to Firefox.
  2. InputDate Segment Recognition & Sanitization:

    • Problem: In IME mode, numeric inputs were often treated as raw text, corrupting segments (e.g., mm1).
    • Fix: We intercept IME keydown (229) and simulate standard numeric keydown/input events when composition ends.
    • Enhancement: Added regex validation (/^\d$/.test()) during compositionend to ensure only pure numeric digits are dispatched. This prevents invalid KeyboardEvent codes (like DigitA) if a user accidentally types letters or symbols during IME composition.
  3. InputDate Validation/Clamping Bypass:

    • Problem: When typing an invalid value such as "33" in the "dd" (day) segment using an IME, the input would bypass the validation/clamping logic and immediately jump to the "yyyy" segment.
    • Fix: Ensured that values entered via IME are properly validated and clamped (e.g., automatically restricted to "3") before shifting focus to the next segment.

📝 Checklist

  • I have linked an issue or discussion.
  • I have updated the documentation accordingly.
  • My code follows the code style of this project.
  • I have performed a self-review of my own code.

@github-actions github-actions Bot added the v4 #4488 label Apr 23, 2026
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Apr 23, 2026

📝 Walkthrough

Walkthrough

Adds IME composition handling to two Vue input components. InputDate.vue tracks isComposing, stops keydown propagation during IME (including keycode 229) and stops input propagation during composition or when InputEvent.isComposing is true; on compositionend it extracts digits from the composed text and dispatches synthetic bubbling keydown and input events per digit to document.activeElement. PinInput.vue tracks isComposing, stops input propagation via stopImmediatePropagation() during composition (handled in capture), and on compositionend clears the flag and dispatches a bubbling synthetic input event except on Firefox. Handlers are attached to each rendered input segment.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely summarizes the main changes: fixing double input and segment issues in IME mode for PinInput and InputDate components.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description check ✅ Passed The PR description clearly outlines IME-related bug fixes for PinInput and InputDate components with detailed problem statements and solutions.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

Copy link
Copy Markdown
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

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/runtime/components/InputDate.vue`:
- Around line 133-148: The onCompositionEnd logic that iterates over `data` and
dispatches synthetic KeyboardEvent/InputEvent should filter to numeric digits
only to avoid creating invalid codes like "DigitA"; update the loop in the
`onCompositionEnd` handler (the block using `for (const char of data)` and
dispatching `KeyboardEvent('keydown'...)` and `InputEvent('input'...)`) to skip
any character that does not match a single digit (e.g. test with /^\d$/ or an
isDigit check) so only 0-9 characters are dispatched to the DateField segment
logic.

In `@src/runtime/components/PinInput.vue`:
- Around line 98-105: onCompositionEnd currently always re-dispatches a
synthetic input which duplicates Firefox's native post-compositionend input;
update onCompositionEnd to only dispatch the synthetic Event when the browser
does not emit a native post-compositionend input (or when we can't detect one).
Concretely, modify the onCompositionEnd handler (and related isComposing.value
logic) to either (a) skip the synthetic target.dispatchEvent(new Event('input',
{ bubbles: true })) when running in Firefox (detect via navigator.userAgent or
feature-detection for post-composition input behavior), or (b) introduce a
short-lived dedupe flag/listener so that if a native input with
isComposing=false arrives immediately after compositionend we ignore the
synthetic dispatch; ensure changes reference onCompositionEnd, isComposing, and
the target.dispatchEvent call so the duplicate final-value handling is
prevented.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 0f4e3cc8-6dd8-4d97-a3d8-d205aa10e05e

📥 Commits

Reviewing files that changed from the base of the PR and between 3cf7d75 and 8c2ed14.

📒 Files selected for processing (2)
  • src/runtime/components/InputDate.vue
  • src/runtime/components/PinInput.vue

Comment thread src/runtime/components/InputDate.vue Outdated
Comment thread src/runtime/components/PinInput.vue
@pkg-pr-new
Copy link
Copy Markdown

pkg-pr-new Bot commented Apr 23, 2026

npm i https://pkg.pr.new/@nuxt/ui@6390

commit: 6d2440d

@benjamincanac
Copy link
Copy Markdown
Member

benjamincanac commented Apr 23, 2026

Should we not fix these in Reka UI directly instead? 🤔 Also, we have a useIMEGuard composable already (used in ChatPrompt).

@k90325248
Copy link
Copy Markdown
Author

k90325248 commented Apr 23, 2026

Should we not fix these in Reka UI directly instead? 🤔 Also, we have a useIMEGuard composable already (used in ChatPrompt).

Good point! I did look into useIMEGuard, but it primarily handles keydown events (like preventing Enter submissions). The issues we are facing here are more complex:

  1. PinInput requires capturing the input event to prevent premature focus shifts during composition.
  2. InputDate needs to simulate standard keydown/input events from the composition data because it relies on specific key values that IME (keyCode 229) doesn't provide.

I completely agree that fixing this directly in Reka UI is the ideal long-term solution. I'd be happy to open an issue/PR upstream in the Reka UI repo to address the root cause.

However, since IME bugs severely impact the usability for CJK users right now, would you be open to merging these guards in Nuxt UI as a reliable interim patch? I've made sure it's robust, including specific user-agent checks to handle Firefox's native post-composition input events.

PinInput

1776937149091

InputDate

1776937769527

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

v4 #4488

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants