@apollohg/react-native-rich-text-editor 2.0.0 → 2.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +8 -116
- package/THIRD_PARTY_NOTICES.md +1 -1
- package/android/build.gradle +3 -0
- package/android/src/main/java/com/apollohg/editor/EditorEditTextImages.kt +25 -0
- package/android/src/main/java/com/apollohg/editor/EditorV2RenderValidation.kt +1 -0
- package/android/src/main/java/com/apollohg/editor/ImageResizeOverlayView.kt +101 -33
- package/android/src/main/java/com/apollohg/editor/RenderMediaSpans.kt +15 -3
- package/android/src/main/java/com/apollohg/editor/RichTextEditorView.kt +14 -0
- package/android/src/main/java/com/apollohg/editor/viewer/AndroidProseLayoutEngine.kt +1 -1
- package/app.plugin.js +42 -39
- package/dist/AtomHost.js +18 -11
- package/dist/EditorAddon.js +4 -2
- package/dist/EditorAddonNormalization.js +17 -9
- package/dist/EditorMentionThemeNormalization.js +6 -3
- package/dist/EditorMentionThemeValidation.js +28 -11
- package/dist/EditorStyleSheetNormalization.js +85 -38
- package/dist/EditorStyleSheetTypes.d.ts +1 -1
- package/dist/EditorTheme.d.ts +4 -0
- package/dist/EditorTheme.js +5 -3
- package/dist/EditorToolbarComponent.d.ts +1 -1
- package/dist/EditorToolbarComponent.js +1 -1
- package/dist/EditorToolbarRegistry.js +5 -5
- package/dist/EditorToolbarTypes.d.ts +12 -12
- package/dist/EditorToolbarVisuals.js +1 -1
- package/dist/ExternalTextComposition.js +89 -43
- package/dist/ImageLoadingPolicy.d.ts +1 -1
- package/dist/NativeEditorBoundaryError.d.ts +7 -7
- package/dist/NativeEditorBoundaryError.js +9 -5
- package/dist/NativeEditorCollaborationTransport.d.ts +7 -7
- package/dist/NativeEditorCollaborationTransport.js +28 -15
- package/dist/NativeEditorCreateConfig.js +11 -6
- package/dist/NativeEditorCreateJson.js +51 -25
- package/dist/NativeEditorCreateValidation.js +11 -6
- package/dist/NativeEditorDocumentBridge.d.ts +1 -1
- package/dist/NativeEditorDocumentBridge.js +32 -18
- package/dist/NativeEditorDocumentHandle.d.ts +4 -4
- package/dist/NativeEditorDocumentHandle.js +1 -1
- package/dist/NativeEditorLocalAwareness.js +25 -13
- package/dist/NativeEditorNativeModule.d.ts +8 -1
- package/dist/NativeEditorNativeModule.js +7 -5
- package/dist/NativeEditorRenderNormalization.js +66 -25
- package/dist/NativeEditorResultNormalization.js +53 -29
- package/dist/NativeEditorTypes.d.ts +10 -10
- package/dist/NativeEditorV2Decimal.js +6 -3
- package/dist/NativeProseViewer.js +11 -3
- package/dist/ResourceLimits.d.ts +2 -2
- package/dist/ResourceLimits.js +7 -2
- package/dist/RichTextEditor.js +1 -1
- package/dist/RichTextEditorNativeTypes.d.ts +1 -1
- package/dist/RichTextEditorNativeView.d.ts +1 -3
- package/dist/RichTextEditorSerialization.js +24 -14
- package/dist/RichTextEditorTypes.d.ts +1 -1
- package/dist/YjsCollaboration.d.ts +7 -7
- package/dist/YjsCollaboration.js +42 -26
- package/dist/addons.d.ts +4 -4
- package/dist/addons.js +3 -3
- package/dist/atomInstances.js +6 -3
- package/dist/atomUpdates.js +7 -4
- package/dist/atoms.js +20 -12
- package/dist/attributeValidation.js +55 -24
- package/dist/contentExpression.js +80 -42
- package/dist/listMarkers.d.ts +1 -1
- package/dist/listMarkers.js +1 -1
- package/dist/schemaDefinition.d.ts +1 -1
- package/dist/schemaDefinition.js +23 -14
- package/dist/schemaDocument.js +1 -1
- package/dist/schemaDocumentConstruction.js +25 -14
- package/dist/schemaNormalization.js +51 -29
- package/dist/schemaPresets.d.ts +1 -1
- package/dist/schemaPresets.js +9 -4
- package/dist/schemaResolution.js +46 -25
- package/dist/specs/PreparedProseViewerNativeComponent.d.ts +4 -0
- package/dist/useEditorToolbarInteractions.d.ts +2 -2
- package/dist/useEditorToolbarInteractions.js +45 -23
- package/dist/useEditorToolbarItems.d.ts +1 -1
- package/dist/useEditorToolbarItems.js +4 -3
- package/dist/useEditorToolbarPresentation.d.ts +3 -3
- package/dist/useEditorToolbarPresentation.js +4 -4
- package/dist/useEditorToolbarState.d.ts +1 -1
- package/dist/useEditorToolbarState.js +1 -1
- package/dist/useFocusPreservingFrames.js +11 -8
- package/dist/useNativeEditor.d.ts +1 -1
- package/dist/useNativeEditor.js +21 -11
- package/dist/useRichTextEditorCommands.d.ts +2 -2
- package/dist/useRichTextEditorCommands.js +59 -29
- package/dist/useRichTextEditorEvents.d.ts +3 -3
- package/dist/useRichTextEditorEvents.js +75 -32
- package/dist/useRichTextEditorMentions.d.ts +4 -4
- package/dist/useRichTextEditorMentions.js +48 -29
- package/dist/useRichTextEditorPresentation.d.ts +4 -4
- package/dist/useRichTextEditorPresentation.js +25 -23
- package/dist/useRichTextEditorState.d.ts +3 -3
- package/dist/useRichTextEditorState.js +20 -15
- package/dist/useRichTextEditorUpdates.d.ts +1 -1
- package/dist/useRichTextEditorUpdates.js +99 -41
- package/dist/useViewerAtoms.js +63 -36
- package/ios/EditorCore.xcframework/ios-arm64/libeditor_core.a +0 -0
- package/ios/EditorCore.xcframework/ios-arm64_x86_64-simulator/libeditor_core.a +0 -0
- package/ios/EditorInteractionOverlays.swift +114 -122
- package/ios/EditorLayoutManager.swift +13 -3
- package/ios/EditorStyleSheet.swift +12 -1
- package/ios/EditorTextView+Images.swift +32 -10
- package/ios/EditorTextView.swift +1 -1
- package/ios/EditorV2Adapter+RenderValidation.swift +2 -2
- package/ios/NativeToolbar+ButtonStyle.swift +17 -5
- package/ios/NativeToolbar+Diagnostics.swift +15 -0
- package/ios/RenderBridge+Atoms.swift +0 -1
- package/ios/RenderBridge+Attachments.swift +0 -29
- package/ios/RichTextEditorView.swift +4 -12
- package/ios/Viewer/CoreTextProseLayoutEngine+AttributedText.swift +3 -2
- package/package.json +11 -3
- package/react-native.config.js +1 -1
- package/rust/android/arm64-v8a/libeditor_core.so +0 -0
- package/rust/android/armeabi-v7a/libeditor_core.so +0 -0
- package/rust/android/x86/libeditor_core.so +0 -0
- package/rust/android/x86_64/libeditor_core.so +0 -0
- package/src/AtomHost.tsx +58 -28
- package/src/EditorAddon.ts +18 -8
- package/src/EditorAddonNormalization.ts +40 -11
- package/src/EditorMentionThemeNormalization.ts +15 -4
- package/src/EditorMentionThemeValidation.ts +51 -14
- package/src/EditorStyleSheet.ts +1 -0
- package/src/EditorStyleSheetNormalization.ts +195 -64
- package/src/EditorStyleSheetTypes.ts +1 -1
- package/src/EditorTheme.ts +13 -5
- package/src/EditorToolbarComponent.tsx +2 -1
- package/src/EditorToolbarRegistry.tsx +23 -13
- package/src/EditorToolbarTypes.tsx +12 -12
- package/src/EditorToolbarVisuals.tsx +6 -3
- package/src/EditorUpdateRevision.ts +1 -0
- package/src/ExternalTextComposition.ts +259 -49
- package/src/ImageLoadingPolicy.ts +3 -1
- package/src/NativeEditorBoundaryError.ts +38 -11
- package/src/NativeEditorCollaborationTransport.ts +108 -27
- package/src/NativeEditorCreateConfig.ts +92 -19
- package/src/NativeEditorCreateJson.ts +163 -26
- package/src/NativeEditorCreateValidation.ts +33 -12
- package/src/NativeEditorDocumentBridge.ts +111 -19
- package/src/NativeEditorDocumentHandle.ts +9 -4
- package/src/NativeEditorLocalAwareness.ts +70 -15
- package/src/NativeEditorNativeModule.ts +13 -9
- package/src/NativeEditorRenderNormalization.ts +128 -29
- package/src/NativeEditorResultNormalization.ts +143 -32
- package/src/NativeEditorTypes.ts +12 -11
- package/src/NativeEditorV2Decimal.ts +12 -3
- package/src/NativeProseViewer.tsx +46 -16
- package/src/ResourceLimits.ts +15 -8
- package/src/RichTextEditor.tsx +3 -1
- package/src/RichTextEditorNativeTypes.tsx +1 -1
- package/src/RichTextEditorNativeView.tsx +2 -8
- package/src/RichTextEditorSerialization.tsx +70 -24
- package/src/RichTextEditorTypes.tsx +1 -1
- package/src/YjsCollaboration.ts +143 -47
- package/src/addons.ts +12 -8
- package/src/atomInstances.ts +25 -5
- package/src/atomUpdates.ts +23 -6
- package/src/atoms.ts +85 -18
- package/src/attributeValidation.ts +97 -33
- package/src/contentExpression.ts +218 -63
- package/src/listMarkers.ts +1 -1
- package/src/schemaDefinition.ts +82 -20
- package/src/schemaDocument.ts +15 -1
- package/src/schemaDocumentConstruction.ts +80 -16
- package/src/schemaNormalization.ts +155 -41
- package/src/schemaPresets.ts +37 -31
- package/src/schemaResolution.ts +126 -27
- package/src/specs/PreparedProseViewerNativeComponent.ts +4 -2
- package/src/useEditorToolbarInteractions.tsx +85 -36
- package/src/useEditorToolbarItems.tsx +50 -22
- package/src/useEditorToolbarPresentation.tsx +81 -58
- package/src/useEditorToolbarState.tsx +8 -6
- package/src/useFocusPreservingFrames.ts +43 -15
- package/src/useNativeEditor.ts +111 -51
- package/src/useRichTextEditorCommands.tsx +127 -54
- package/src/useRichTextEditorEvents.tsx +144 -42
- package/src/useRichTextEditorMentions.tsx +118 -37
- package/src/useRichTextEditorPresentation.tsx +128 -114
- package/src/useRichTextEditorState.tsx +76 -40
- package/src/useRichTextEditorUpdates.tsx +207 -56
- package/src/useViewerAtoms.tsx +162 -66
|
@@ -12,10 +12,10 @@ import { type EditorMentionTheme } from './EditorTheme';
|
|
|
12
12
|
import { validEditorMentionTheme, type NativeEditorPositionAffinity } from './NativeEditorBridge';
|
|
13
13
|
import { type NativeSyntheticEvent } from 'react-native';
|
|
14
14
|
import { setEditorToolbarMentionState } from './EditorToolbar';
|
|
15
|
-
import { useRichTextEditorState } from './useRichTextEditorState';
|
|
16
|
-
import { useRichTextEditorCommands } from './useRichTextEditorCommands';
|
|
17
|
-
import { useRichTextEditorUpdates } from './useRichTextEditorUpdates';
|
|
18
|
-
import { useRichTextEditorEvents } from './useRichTextEditorEvents';
|
|
15
|
+
import { type useRichTextEditorState } from './useRichTextEditorState';
|
|
16
|
+
import { type useRichTextEditorCommands } from './useRichTextEditorCommands';
|
|
17
|
+
import { type useRichTextEditorUpdates } from './useRichTextEditorUpdates';
|
|
18
|
+
import { type useRichTextEditorEvents } from './useRichTextEditorEvents';
|
|
19
19
|
import {
|
|
20
20
|
isRecord,
|
|
21
21
|
isPositionInvalidError,
|
|
@@ -69,6 +69,7 @@ export function useRichTextEditorMentions(
|
|
|
69
69
|
const resolveMentionSelectionAttrs = useCallback(
|
|
70
70
|
(selectionEvent: MentionSelectionAttrsEvent): Record<string, unknown> => {
|
|
71
71
|
let resolvedAttrs: Record<string, unknown> | null | undefined;
|
|
72
|
+
|
|
72
73
|
try {
|
|
73
74
|
resolvedAttrs =
|
|
74
75
|
addonsRef.current?.mentions?.resolveSelectionAttrs?.(selectionEvent);
|
|
@@ -80,16 +81,18 @@ export function useRichTextEditorMentions(
|
|
|
80
81
|
);
|
|
81
82
|
}
|
|
82
83
|
}
|
|
84
|
+
|
|
83
85
|
return isRecord(resolvedAttrs)
|
|
84
86
|
? { ...selectionEvent.attrs, ...resolvedAttrs }
|
|
85
87
|
: selectionEvent.attrs;
|
|
86
88
|
},
|
|
87
|
-
[]
|
|
89
|
+
[ addonsRef ]
|
|
88
90
|
);
|
|
89
91
|
|
|
90
92
|
const resolveMentionTheme = useCallback(
|
|
91
93
|
(selectionEvent: MentionSelectionAttrsEvent): EditorMentionTheme | undefined => {
|
|
92
94
|
let resolvedTheme: unknown;
|
|
95
|
+
|
|
93
96
|
try {
|
|
94
97
|
resolvedTheme = addonsRef.current?.mentions?.resolveTheme?.(selectionEvent);
|
|
95
98
|
} catch (error) {
|
|
@@ -97,7 +100,11 @@ export function useRichTextEditorMentions(
|
|
|
97
100
|
console.error('NativeRichTextEditor: mentions.resolveTheme threw', error);
|
|
98
101
|
}
|
|
99
102
|
}
|
|
100
|
-
|
|
103
|
+
|
|
104
|
+
if (resolvedTheme === undefined || resolvedTheme === null) {
|
|
105
|
+
return undefined;
|
|
106
|
+
}
|
|
107
|
+
|
|
101
108
|
// A rejected theme is dropped rather than written into the
|
|
102
109
|
// document: every later renderUpdate revalidates it, so one bad
|
|
103
110
|
// value would make the content permanently unrenderable.
|
|
@@ -108,22 +115,25 @@ export function useRichTextEditorMentions(
|
|
|
108
115
|
resolvedTheme
|
|
109
116
|
);
|
|
110
117
|
}
|
|
118
|
+
|
|
111
119
|
return undefined;
|
|
112
120
|
}
|
|
121
|
+
|
|
113
122
|
return resolvedTheme;
|
|
114
123
|
},
|
|
115
|
-
[]
|
|
124
|
+
[ addonsRef ]
|
|
116
125
|
);
|
|
117
126
|
|
|
118
127
|
const resolveMentionInsertionAttrs = useCallback(
|
|
119
128
|
(selectionEvent: MentionSelectionAttrsEvent): Record<string, unknown> => {
|
|
120
129
|
const attrs = resolveMentionSelectionAttrs(selectionEvent);
|
|
121
130
|
const resolvedTheme = resolveMentionTheme({ ...selectionEvent, attrs });
|
|
131
|
+
|
|
122
132
|
return resolvedTheme != null
|
|
123
133
|
? { ...attrs, mentionTheme: normalizeEditorMentionTheme(resolvedTheme) }
|
|
124
134
|
: attrs;
|
|
125
135
|
},
|
|
126
|
-
[resolveMentionSelectionAttrs, resolveMentionTheme]
|
|
136
|
+
[ resolveMentionSelectionAttrs, resolveMentionTheme ]
|
|
127
137
|
);
|
|
128
138
|
|
|
129
139
|
const insertMentionSuggestion = useCallback(
|
|
@@ -135,12 +145,16 @@ export function useRichTextEditorMentions(
|
|
|
135
145
|
documentVersion?: string;
|
|
136
146
|
}) => {
|
|
137
147
|
const mentions = addonsRef.current?.mentions;
|
|
138
|
-
|
|
148
|
+
|
|
149
|
+
if (!mentions || !editableRef.current) {
|
|
150
|
+
return;
|
|
151
|
+
}
|
|
139
152
|
|
|
140
153
|
const snapshot = bridge.renderUpdate({
|
|
141
154
|
anchor: request.range.anchor,
|
|
142
155
|
head: request.range.head,
|
|
143
156
|
});
|
|
157
|
+
|
|
144
158
|
if (
|
|
145
159
|
snapshot.selection.type !== 'text' ||
|
|
146
160
|
(request.documentVersion != null &&
|
|
@@ -148,12 +162,14 @@ export function useRichTextEditorMentions(
|
|
|
148
162
|
) {
|
|
149
163
|
return;
|
|
150
164
|
}
|
|
165
|
+
|
|
151
166
|
const markAttrs = Object.fromEntries(
|
|
152
|
-
Object.entries(snapshot.activeState.markAttrs).map(([mark, attrs]) => [
|
|
167
|
+
Object.entries(snapshot.activeState.markAttrs).map(([ mark, attrs ]) => [
|
|
153
168
|
mark,
|
|
154
169
|
{ ...attrs },
|
|
155
170
|
])
|
|
156
171
|
);
|
|
172
|
+
|
|
157
173
|
const callbackEvent: MentionSelectionAttrsEvent = {
|
|
158
174
|
trigger: request.trigger,
|
|
159
175
|
suggestion: request.suggestion,
|
|
@@ -162,10 +178,12 @@ export function useRichTextEditorMentions(
|
|
|
162
178
|
range: request.range,
|
|
163
179
|
documentVersion: snapshot.documentVersion,
|
|
164
180
|
};
|
|
181
|
+
|
|
165
182
|
const attrs = resolveMentionInsertionAttrs(callbackEvent);
|
|
166
183
|
// Selection envelopes address scalars, not document positions.
|
|
167
184
|
const anchorScalar = snapshot.selection.anchorScalar;
|
|
168
185
|
const headScalar = snapshot.selection.headScalar;
|
|
186
|
+
|
|
169
187
|
if (
|
|
170
188
|
documentHandle.isDestroyed ||
|
|
171
189
|
currentPushedUpdateEditorIdRef.current !== documentHandle.editorId ||
|
|
@@ -179,8 +197,9 @@ export function useRichTextEditorMentions(
|
|
|
179
197
|
// own cursor resolution: a collapsed caret prefers After with a
|
|
180
198
|
// deterministic Before fallback at text-boundary positions; a
|
|
181
199
|
// range uses Before. The fallback changes only the stickiness
|
|
182
|
-
// of the SAME position
|
|
200
|
+
// of the SAME position : it is not a guessed-position retry.
|
|
183
201
|
const collapsed = anchorScalar === headScalar;
|
|
202
|
+
|
|
184
203
|
const syncSelection = (affinity: NativeEditorPositionAffinity) =>
|
|
185
204
|
bridge.setSelection({
|
|
186
205
|
baseDocumentRevision: snapshot.documentVersion,
|
|
@@ -195,9 +214,13 @@ export function useRichTextEditorMentions(
|
|
|
195
214
|
try {
|
|
196
215
|
syncSelection(collapsed ? 'after' : 'before');
|
|
197
216
|
} catch (error) {
|
|
198
|
-
if (!collapsed || !isPositionInvalidError(error))
|
|
217
|
+
if (!collapsed || !isPositionInvalidError(error)) {
|
|
218
|
+
throw error;
|
|
219
|
+
}
|
|
220
|
+
|
|
199
221
|
syncSelection('before');
|
|
200
222
|
}
|
|
223
|
+
|
|
201
224
|
const outcome = bridge.applyCommand({
|
|
202
225
|
baseDocumentRevision: snapshot.documentVersion,
|
|
203
226
|
command: {
|
|
@@ -207,17 +230,24 @@ export function useRichTextEditorMentions(
|
|
|
207
230
|
}),
|
|
208
231
|
},
|
|
209
232
|
});
|
|
210
|
-
|
|
233
|
+
|
|
234
|
+
if (outcome.type !== 'transaction' || !outcome.changed) {
|
|
235
|
+
return;
|
|
236
|
+
}
|
|
237
|
+
|
|
211
238
|
latestRevisionRef.current = outcome.documentRevision;
|
|
212
239
|
} catch (error) {
|
|
213
240
|
if (isRevisionMismatchError(error)) {
|
|
214
241
|
document.refresh();
|
|
242
|
+
|
|
215
243
|
return;
|
|
216
244
|
}
|
|
245
|
+
|
|
217
246
|
throw error;
|
|
218
247
|
}
|
|
219
248
|
|
|
220
249
|
afterLocalEngineMutation();
|
|
250
|
+
|
|
221
251
|
mentions.onSelect?.({
|
|
222
252
|
trigger: request.trigger,
|
|
223
253
|
suggestion: request.suggestion,
|
|
@@ -225,30 +255,45 @@ export function useRichTextEditorMentions(
|
|
|
225
255
|
documentVersion: snapshot.documentVersion,
|
|
226
256
|
});
|
|
227
257
|
},
|
|
228
|
-
[
|
|
258
|
+
[ addonsRef,
|
|
229
259
|
afterLocalEngineMutation,
|
|
230
260
|
bridge,
|
|
261
|
+
currentPushedUpdateEditorIdRef,
|
|
231
262
|
document,
|
|
232
263
|
documentDescriptor,
|
|
233
|
-
documentHandle,
|
|
234
|
-
|
|
235
|
-
|
|
264
|
+
documentHandle.editorId,
|
|
265
|
+
documentHandle.isDestroyed,
|
|
266
|
+
editableRef,
|
|
267
|
+
latestRevisionRef,
|
|
268
|
+
resolveMentionInsertionAttrs ]
|
|
236
269
|
);
|
|
237
270
|
|
|
238
271
|
const handleAddonEvent = useCallback(
|
|
239
272
|
(event: NativeSyntheticEvent<NativeAddonEvent>) => {
|
|
240
|
-
if (documentHandle.isDestroyed || !isForThisEditor(event.nativeEvent))
|
|
273
|
+
if (documentHandle.isDestroyed || !isForThisEditor(event.nativeEvent)) {
|
|
274
|
+
return;
|
|
275
|
+
}
|
|
276
|
+
|
|
241
277
|
let parsed: EditorAddonEvent;
|
|
278
|
+
|
|
242
279
|
try {
|
|
243
280
|
const value = JSON.parse(event.nativeEvent.eventJson) as unknown;
|
|
244
|
-
|
|
245
|
-
|
|
281
|
+
|
|
282
|
+
if (!isRecord(value) || typeof value.type !== 'string') {
|
|
283
|
+
return;
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
parsed = value as EditorAddonEvent;
|
|
246
287
|
} catch {
|
|
247
288
|
return;
|
|
248
289
|
}
|
|
249
290
|
|
|
250
291
|
const mentions = addonsRef.current?.mentions;
|
|
251
|
-
|
|
292
|
+
|
|
293
|
+
if (!mentions) {
|
|
294
|
+
return;
|
|
295
|
+
}
|
|
296
|
+
|
|
252
297
|
const documentVersion =
|
|
253
298
|
typeof parsed.documentVersion === 'string' ? parsed.documentVersion : undefined;
|
|
254
299
|
|
|
@@ -263,6 +308,7 @@ export function useRichTextEditorMentions(
|
|
|
263
308
|
) {
|
|
264
309
|
return;
|
|
265
310
|
}
|
|
311
|
+
|
|
266
312
|
const queryEvent: MentionQueryChangeEvent = {
|
|
267
313
|
query: parsed.query,
|
|
268
314
|
trigger: parsed.trigger,
|
|
@@ -270,8 +316,10 @@ export function useRichTextEditorMentions(
|
|
|
270
316
|
isActive: parsed.isActive,
|
|
271
317
|
...(documentVersion ? { documentVersion } : {}),
|
|
272
318
|
};
|
|
319
|
+
|
|
273
320
|
mentions.onQueryChange?.(queryEvent);
|
|
274
321
|
setMentionQuery(parsed.isActive ? queryEvent : null);
|
|
322
|
+
|
|
275
323
|
return;
|
|
276
324
|
}
|
|
277
325
|
|
|
@@ -283,16 +331,22 @@ export function useRichTextEditorMentions(
|
|
|
283
331
|
) {
|
|
284
332
|
return;
|
|
285
333
|
}
|
|
334
|
+
|
|
286
335
|
const suggestion = mentions.suggestions?.find(
|
|
287
|
-
|
|
336
|
+
candidate => candidate.key === parsed.suggestionKey
|
|
288
337
|
);
|
|
289
|
-
|
|
338
|
+
|
|
339
|
+
if (!suggestion) {
|
|
340
|
+
return;
|
|
341
|
+
}
|
|
342
|
+
|
|
290
343
|
mentions.onSelect?.({
|
|
291
344
|
trigger: parsed.trigger,
|
|
292
345
|
suggestion,
|
|
293
346
|
attrs: parsed.attrs,
|
|
294
347
|
...(documentVersion ? { documentVersion } : {}),
|
|
295
348
|
});
|
|
349
|
+
|
|
296
350
|
return;
|
|
297
351
|
}
|
|
298
352
|
|
|
@@ -311,10 +365,14 @@ export function useRichTextEditorMentions(
|
|
|
311
365
|
) {
|
|
312
366
|
return;
|
|
313
367
|
}
|
|
368
|
+
|
|
314
369
|
const suggestion = mentions.suggestions?.find(
|
|
315
|
-
|
|
370
|
+
candidate => candidate.key === parsed.suggestionKey
|
|
316
371
|
);
|
|
317
|
-
|
|
372
|
+
|
|
373
|
+
if (!suggestion) {
|
|
374
|
+
return;
|
|
375
|
+
}
|
|
318
376
|
|
|
319
377
|
insertMentionSuggestion({
|
|
320
378
|
trigger: parsed.trigger,
|
|
@@ -324,18 +382,29 @@ export function useRichTextEditorMentions(
|
|
|
324
382
|
documentVersion,
|
|
325
383
|
});
|
|
326
384
|
},
|
|
327
|
-
[
|
|
385
|
+
[ addonsRef,
|
|
386
|
+
documentHandle.isDestroyed,
|
|
387
|
+
insertMentionSuggestion,
|
|
388
|
+
isForThisEditor,
|
|
389
|
+
setMentionQuery ]
|
|
328
390
|
);
|
|
329
391
|
|
|
330
392
|
const handleMentionSuggestionPress = useCallback(
|
|
331
393
|
(suggestion: MentionSuggestion) => {
|
|
332
|
-
if (mentionQuery == null)
|
|
394
|
+
if (mentionQuery == null) {
|
|
395
|
+
return;
|
|
396
|
+
}
|
|
397
|
+
|
|
333
398
|
const normalized = normalizeNativeEditorAddons(
|
|
334
399
|
addonsRef.current
|
|
335
|
-
)?.mentions?.suggestions.find(
|
|
336
|
-
|
|
400
|
+
)?.mentions?.suggestions.find(candidate => candidate.key === suggestion.key);
|
|
401
|
+
|
|
402
|
+
if (normalized == null) {
|
|
403
|
+
return;
|
|
404
|
+
}
|
|
337
405
|
|
|
338
406
|
setMentionQuery(null);
|
|
407
|
+
|
|
339
408
|
insertMentionSuggestion({
|
|
340
409
|
trigger: mentionQuery.trigger,
|
|
341
410
|
suggestion,
|
|
@@ -344,16 +413,17 @@ export function useRichTextEditorMentions(
|
|
|
344
413
|
documentVersion: mentionQuery.documentVersion,
|
|
345
414
|
});
|
|
346
415
|
},
|
|
347
|
-
[insertMentionSuggestion, mentionQuery]
|
|
416
|
+
[ addonsRef, insertMentionSuggestion, mentionQuery, setMentionQuery ]
|
|
348
417
|
);
|
|
349
418
|
|
|
350
419
|
const mentionsEnabled = addons.mentions != null;
|
|
351
420
|
const mentionTrigger = addons.mentions?.trigger?.trim() || '@';
|
|
421
|
+
|
|
352
422
|
useEffect(() => {
|
|
353
423
|
if (!mentionsEnabled || (mentionQuery != null && mentionQuery.trigger !== mentionTrigger)) {
|
|
354
424
|
setMentionQuery(null);
|
|
355
425
|
}
|
|
356
|
-
}, [mentionsEnabled, mentionQuery, mentionTrigger, setMentionQuery]);
|
|
426
|
+
}, [ mentionsEnabled, mentionQuery, mentionTrigger, setMentionQuery ]);
|
|
357
427
|
|
|
358
428
|
const mentionSuggestions = addons?.mentions?.suggestions;
|
|
359
429
|
|
|
@@ -372,14 +442,21 @@ export function useRichTextEditorMentions(
|
|
|
372
442
|
}
|
|
373
443
|
|
|
374
444
|
const normalized = normalizeNativeEditorAddons(addons)?.mentions?.suggestions;
|
|
375
|
-
|
|
445
|
+
|
|
446
|
+
if (normalized == null) {
|
|
447
|
+
return undefined;
|
|
448
|
+
}
|
|
376
449
|
|
|
377
450
|
const themes: Record<string, EditorMentionTheme> = {};
|
|
451
|
+
|
|
378
452
|
for (const suggestion of mentionSuggestions) {
|
|
379
453
|
const normalizedSuggestion = normalized.find(
|
|
380
|
-
|
|
454
|
+
candidate => candidate.key === suggestion.key
|
|
381
455
|
);
|
|
382
|
-
|
|
456
|
+
|
|
457
|
+
if (normalizedSuggestion == null) {
|
|
458
|
+
continue;
|
|
459
|
+
}
|
|
383
460
|
|
|
384
461
|
const selectionEvent: MentionSelectionAttrsEvent = {
|
|
385
462
|
trigger: mentionQuery.trigger,
|
|
@@ -391,25 +468,27 @@ export function useRichTextEditorMentions(
|
|
|
391
468
|
? { documentVersion: mentionQuery.documentVersion }
|
|
392
469
|
: {}),
|
|
393
470
|
};
|
|
471
|
+
|
|
394
472
|
const attrs = resolveMentionSelectionAttrs(selectionEvent);
|
|
473
|
+
|
|
395
474
|
const merged = mergeMentionSuggestionTheme(
|
|
396
475
|
mentionSuggestionTheme,
|
|
397
476
|
resolveMentionTheme({ ...selectionEvent, attrs })
|
|
398
477
|
);
|
|
478
|
+
|
|
399
479
|
if (merged != null) {
|
|
400
480
|
themes[suggestion.key] = merged;
|
|
401
481
|
}
|
|
402
482
|
}
|
|
403
483
|
|
|
404
484
|
return Object.keys(themes).length > 0 ? themes : undefined;
|
|
405
|
-
}, [
|
|
485
|
+
}, [ activeStateRef,
|
|
406
486
|
addons,
|
|
407
487
|
mentionQuery,
|
|
408
488
|
mentionSuggestionTheme,
|
|
409
489
|
mentionSuggestions,
|
|
410
490
|
resolveMentionSelectionAttrs,
|
|
411
|
-
resolveMentionTheme
|
|
412
|
-
]);
|
|
491
|
+
resolveMentionTheme ]);
|
|
413
492
|
|
|
414
493
|
useEffect(() => {
|
|
415
494
|
if (
|
|
@@ -418,6 +497,7 @@ export function useRichTextEditorMentions(
|
|
|
418
497
|
mentionSuggestions == null
|
|
419
498
|
) {
|
|
420
499
|
setEditorToolbarMentionState(toolbarFrameOwnerId, null);
|
|
500
|
+
|
|
421
501
|
return;
|
|
422
502
|
}
|
|
423
503
|
|
|
@@ -437,5 +517,6 @@ export function useRichTextEditorMentions(
|
|
|
437
517
|
shouldPublishMentionSuggestions,
|
|
438
518
|
toolbarFrameOwnerId,
|
|
439
519
|
]);
|
|
520
|
+
|
|
440
521
|
return { mentionSuggestionTheme, handleAddonEvent };
|
|
441
522
|
}
|