[iOS/macOS] [TextInput] Implement ghost text #1897
Merged
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Please select one of the following
Summary
Ghost text is hint text that is inserted inline as a hint to the user (for example predictive text). Unlike autocomplete for combo boxes, which is "visible" to the model, ghost text is "invisible" or transparent to the model (i.e. not observable in any callback or imperative method). Ghost text isn't selectable by the user.
Ideally we do ghost text only in the display layer, meaning it isn't in the model. Unfortunately it doesn't look like we can render ghost text and still have Apple flow text for us (ghost text that is in the middle of regular text will want to reflow the regular text to make room for ghost text). Overriding all text box rendering seems like substantial rework (we need to deal with all drawing, including but not limited to the text box background, text, insertion pointer\selection, ... as well as other ancillary things around positioning related input UI such as IME's), so here we DO introduce it in the model, but try to keep awareness on the native side, and away from Application logic.
Since ghost text is presumed dependent on immediate user context (e.g. text and selection), we reset ghost text automatically when either of these change. We could not do that, but that requires us to deal with any possible edits around\on the ghost text, as well as actually ensure we "hide" ghost text from any callbacks made to the app (something we are getting away with right now since we remove ghost text on pretty much any user interaction).
Plumbing for new imperative method to set ghost text.
Introduce a property on the
RCTUITextView
andRCTUITextField
to store state on whether we're currently in the midst of setting\clearing ghost text. We use this to suppress various callbacks to the Application that may be triggered as a result of us changing the ghost text\selection to compensate for addition\removal of ghost text.Actual ghost text management logic. I placed as much as I reasonably could here since that allows us to share most of the functionality between single and multi line text inputs.
Test page for ghost text. Shows predictive text example.
Changelog
General Changed - Initial commit
Test Plan
Testing (macOS\iOS x multi\single line):
setGhostText:
on native. Ensure we clear ghost text (due to text chagnes)Test page example video: https://github.com/microsoft/react-native-macos/assets/72474613/38f466c3-695b-4526-bbb2-a5afb8e333d8