-
Notifications
You must be signed in to change notification settings - Fork 2
External Text Composition
External text composition lets a consumer display provisional text directly inside RichTextEditor, revise it in place, and either commit or cancel it.
The package does not provide the external text source. It provides the editor integration needed to present provisional text without treating each revision as a document edit.
The API is available through RichTextEditorRef on iOS and Android:
supportsExternalTextComposition(): boolean;
beginExternalTextComposition(
options?: ExternalTextCompositionOptions
): Promise<ExternalTextCompositionSession>;Check supportsExternalTextComposition() immediately before beginning a session. It returns false when the native view is unavailable, not bound, or does not include this capability.
Keep the returned session and pass provisional revisions to update(). Finish the session with either commit() or cancel().
const editor = editorRef.current;
if (!editor?.supportsExternalTextComposition()) {
return;
}
const composition = await editor.beginExternalTextComposition({
onEnd(event) {
console.log(event.outcome, event.cause);
},
});
await composition.update(provisionalText);
await composition.update(correctedProvisionalText);
await composition.commit(finalText);cancel() is the terminal alternative to commit():
await composition.cancel();Connect the session to the external text source and controls owned by the consumer. Keep promise rejections observable and clear stored session state from onEnd.
ExternalTextCompositionSession exposes:
| Method | Behavior |
|---|---|
update(text) |
Replaces the currently displayed provisional text. It may be called repeatedly as the value changes. |
commit(finalText) |
Commits the final text through the editor's normal typed-input path. |
cancel() |
Removes the provisional text without committing it. |
Only one external composition owns an editor at a time. Beginning a new session settles the current owner. Calls made after a session ends reject with EXTERNAL_COMPOSITION_ENDED.
onEnd runs once when a session finishes:
type ExternalTextCompositionEndCause =
| 'consumer'
| 'interaction'
| 'documentChange'
| 'lifecycle';
type ExternalTextCompositionEndEvent = {
outcome: 'committed' | 'cancelled';
cause: ExternalTextCompositionEndCause;
text: string;
error?: NativeEditorErrorBase;
};| Cause | Meaning |
|---|---|
consumer |
The consumer committed or cancelled the session, or began a replacement session. |
interaction |
Native editing, selection, clipboard, accessibility, or toolbar interaction settled the composition. |
documentChange |
A controlled or imperative document change ended the composition. An authoritative reset discards provisional text instead of committing it into the replacement document. |
lifecycle |
Rebinding, a read-only transition, destruction, or final native detachment cancelled the session. |
Use onEnd as the synchronization point for consumer state. It can arrive before the promise returned by a native command settles; the public session object handles this ordering.
The editor captures its current text selection when composition begins:
- A collapsed caret inserts the committed text.
- A text range is replaced by the committed text.
- A node or all-document selection cannot begin an external composition.
Provisional update() calls affect only the native presentation. They do not mutate the document, create undo entries, publish collaboration updates, or invoke content callbacks. The empty-editor placeholder stays hidden while provisional text is visible.
A changed commit() produces one normal typed transaction and one undo boundary. An unchanged or fully filtered commit succeeds without a local content update. Normal document policy—including readOnly, maxLength, inputFilter, schema validation, and resource limits—still applies.
For ordinary document changes, the captured position is resolved against the current document before commit. An authoritative reset, including clearContent() or controlled JSON with valueJSONUpdateMode="reset", cancels provisional presentation and wins over pending native input. The consumer does not manage document revisions or relative positions.
beginExternalTextComposition() can reject when the editor is unavailable, not editable, unsupported, or does not have a text selection.
commit() can reject when policy or position reconciliation refuses the final value. The editor removes provisional presentation, restores the latest authorized render, and ends the session as cancelled with an error.
Observe both error surfaces:
-
onEndcontains the terminal outcome and optional typed error. - Underlying autonomous native failures continue through
documentHandle.addErrorListener(...).
A reconciliation failure can report EXTERNAL_COMPOSITION_COMMIT_FAILED to the session while its underlying error, such as POSITION_EPOCH_INVALID, is delivered to the document-handle error listener. Start a new session only after handling the terminal event.
See Production Limits and Errors for typed error handling.
React Native Rich Text Editor · Documentation · Migration Guide