fix: various mentions bugs and inconsistencies between platforms#637
fix: various mentions bugs and inconsistencies between platforms#637hejsztynx wants to merge 25 commits into
Conversation
There was a problem hiding this comment.
Pull request overview
This PR addresses multiple cross-platform inconsistencies and edge-case bugs in “mentions” handling (trigger lifecycle events, selection-driven re-analysis, insertion behavior) across iOS, Android, and Web, and updates the example apps + E2E coverage to reflect the intended event semantics.
Changes:
- Web: refactors mention event handling into a React hook, fixes trigger range/query evaluation, and avoids inserting duplicate trailing spaces when setting a mention.
- iOS/Android: improves mention lifecycle event emission when switching directly between mentions, avoids duplicate events, and aligns “recent input” tracking to support selection-driven mention detection.
- E2E: adds Playwright coverage for switching between different mention triggers and validating end/start ordering.
Reviewed changes
Copilot reviewed 18 out of 18 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| src/web/pmPlugins/MentionPlugin/useMentionEvents.ts | New React hook to subscribe to mention trigger + detected-mention events. |
| src/web/pmPlugins/MentionPlugin/subscribeMentionEvents.ts | Removes the prior imperative subscribe/unsubscribe helper. |
| src/web/pmPlugins/MentionPlugin/setMention.ts | Avoids inserting an extra trailing space when setting a mention. |
| src/web/pmPlugins/MentionPlugin/makeMentionPluginState.ts | Updates how the mention query range is computed (to word end) and adjusts indicator detection behavior. |
| src/web/pmPlugins/MentionPlugin/index.ts | Exports the new hook instead of the removed subscribe helper. |
| src/web/EnrichedTextInput.tsx | Switches mention event wiring from subscribeMentionEvents to useMentionEvents. |
| ios/styles/MentionStyle.mm | Fixes mention event emission ordering / deduping and avoids inserting duplicate spaces on mention insert. |
| ios/EnrichedTextInputView.mm | Ensures _recentInputString stays in sync even if no onChangeText emitter exists. |
| apps/example/src/hooks/useEditorState.ts | Updates example mention popup behavior to use start/end events rather than change events. |
| apps/example-web/src/testScreens/TestMentions.tsx | Extends the web test screen UI to expose last end-event indicator for assertions. |
| apps/example-web/src/App.tsx | Updates example popup-open behavior to align with start/end mention events. |
| android/src/main/java/com/swmansion/enriched/textinput/watchers/EnrichedTextWatcher.kt | Tracks recentInputString to support selection-only mention analysis. |
| android/src/main/java/com/swmansion/enriched/textinput/utils/EnrichedSelection.kt | Re-analyzes mentions on selection changes when text hasn’t changed. |
| android/src/main/java/com/swmansion/enriched/textinput/styles/ParametrizedStyles.kt | Adds selection-change mention detection path and renames internal detection helper. |
| android/src/main/java/com/swmansion/enriched/textinput/events/OnMentionEvent.kt | Disables event coalescing so end/start/change bursts aren’t collapsed. |
| android/src/main/java/com/swmansion/enriched/textinput/events/MentionHandler.kt | Ensures correct end→start→change sequence when switching mentions; improves dedupe logic. |
| android/src/main/java/com/swmansion/enriched/textinput/EnrichedTextInputView.kt | Adds recentInputString storage on the view. |
| .playwright/tests/mentions.spec.ts | Adds E2E test for switching between different mentions and verifying lifecycle events. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
kacperzolkiewski
left a comment
There was a problem hiding this comment.
- Something is wrong on Android right now:
Screen.Recording.2026-06-25.at.11.34.16.mov
- Should it emit event when we are with the cursor before indicator:
Screen.Recording.2026-06-25.at.11.38.08.mov
- (If answer on second question is yes): On web the cursor does not go to the end of mention when we insert one like in native:
Screen.Recording.2026-06-25.at.11.40.25.mov
ad 1 - I am aware of that, I fixed it, but I've decided to fix Android's ad 2 - I believe we should emit the event before the indicator, that's how it was initially implemented and the behavior is shared across all platforms. ad 3 - Good catch, fixed it. |
szydlovsky
left a comment
There was a problem hiding this comment.
iOS looks good to me, just a one tiny comment
# Summary When setting a mention, now it makes sure that: - to replace the whole word with the created mention, - to always move the cursor to the mention's trailing space ## Test Plan Try setting a mention with the cursor in various places and experiment when there already are trailing spaces. ## Screenshots / Videos Before: https://github.com/user-attachments/assets/37fb805c-aaa1-4947-a8dd-4d1427ab1629 After: https://github.com/user-attachments/assets/dfa3de9b-a8d4-410c-bbf1-0d028b0bab87 ## Compatibility | OS | Implemented | | ------- | :---------: | | iOS | ❌ | | Android | ✅ | | Web | ❌ | ## Checklist - [x] E2E tests are passing - [ ] Required E2E tests have been added (if applicable)
It turned out, that PR didn't produce much changes as I initially expected - I merged it and the fix is present on this PR. |
Summary
There were various bugs and inconsistencies with mentions functionalities across every platform.
Mainly it wasn't handled properly when you switched directly between different mentions, which caused improper event emission and the lists stayed visible - documented in the videos section
iOS:
onChangeevents when just moving a cursor across a mention_recentInputStringwas not updated if noonChangeTextprop was givenAndroid:
setMentiona duplicated space was inserted if there already was onesetMentionwasn't replacing the surrounding textsetMentionthe selection wasn't moved to the trailing spaceWeb:
setMentiona duplicated space was inserted if there already was oneExample apps:
onChangemention event would handle popup list opening - something whatonStartis forTest Plan
Follow the text written in the attached videos, play around with selection changes, all events should emit correctly and the lists should function as expected.
Screenshots / Videos
(all platforms) events not emitting when switching between mentions
Screen.Recording.2026-05-29.at.22.47.12.mov
(web) incorrect query evaluation and inserting, doubled space
Screen.Recording.2026-06-14.at.18.15.19.mov
(android)
setMentionnot replacing surrounding text:Screen.Recording.2026-07-02.at.16.08.45.mov
Compatibility
Checklist