@apollohg/react-native-rich-text-editor 2.0.0 → 2.0.1
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 +1 -1
- package/THIRD_PARTY_NOTICES.md +1 -1
- package/android/build.gradle +3 -0
- 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 +84 -37
- 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/Info.plist +5 -5
- 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/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/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
|
@@ -29,7 +29,13 @@ function useEditorToolbarInteractions(context) {
|
|
|
29
29
|
}
|
|
30
30
|
(0, EditorToolbarRegistry_1.registerEditorToolbarFrame)(registrationId, { x, y, width, height }, measuredFrameOwnerId);
|
|
31
31
|
});
|
|
32
|
-
}, [frameOwnerId,
|
|
32
|
+
}, [frameOwnerId,
|
|
33
|
+
frameOwnerIdRef,
|
|
34
|
+
framePublisherMountedRef,
|
|
35
|
+
publishesFocusFrames,
|
|
36
|
+
publishesFocusFramesRef,
|
|
37
|
+
registrationIdRef,
|
|
38
|
+
rootRef]);
|
|
33
39
|
const publishMenuFrame = (0, react_1.useCallback)(() => {
|
|
34
40
|
const registrationId = menuRegistrationIdRef.current;
|
|
35
41
|
const menuCard = menuCardRef.current;
|
|
@@ -53,17 +59,25 @@ function useEditorToolbarInteractions(context) {
|
|
|
53
59
|
}
|
|
54
60
|
(0, EditorToolbarRegistry_1.registerEditorToolbarFrame)(registrationId, { x, y, width, height }, measuredFrameOwnerId);
|
|
55
61
|
});
|
|
56
|
-
}, [frameOwnerId,
|
|
62
|
+
}, [frameOwnerId,
|
|
63
|
+
frameOwnerIdRef,
|
|
64
|
+
framePublisherMountedRef,
|
|
65
|
+
menuCardRef,
|
|
66
|
+
menuRegistrationIdRef,
|
|
67
|
+
menuState,
|
|
68
|
+
menuStateRef,
|
|
69
|
+
publishesFocusFrames,
|
|
70
|
+
publishesFocusFramesRef]);
|
|
57
71
|
const publishToolbarFrames = (0, react_1.useCallback)(() => {
|
|
58
72
|
publishToolbarFrame();
|
|
59
73
|
publishMenuFrame();
|
|
60
74
|
}, [publishMenuFrame, publishToolbarFrame]);
|
|
61
75
|
const cancelScheduledFramePublishes = (0, react_1.useCallback)(() => {
|
|
62
|
-
framePublishAnimationFramesRef.current.forEach(
|
|
76
|
+
framePublishAnimationFramesRef.current.forEach(frame => cancelAnimationFrame(frame));
|
|
63
77
|
framePublishAnimationFramesRef.current = [];
|
|
64
|
-
framePublishTimeoutsRef.current.forEach(
|
|
78
|
+
framePublishTimeoutsRef.current.forEach(timeout => clearTimeout(timeout));
|
|
65
79
|
framePublishTimeoutsRef.current = [];
|
|
66
|
-
}, []);
|
|
80
|
+
}, [framePublishAnimationFramesRef, framePublishTimeoutsRef]);
|
|
67
81
|
const scheduleToolbarFramePublish = (0, react_1.useCallback)(() => {
|
|
68
82
|
if (!publishesFocusFrames) {
|
|
69
83
|
return;
|
|
@@ -71,10 +85,14 @@ function useEditorToolbarInteractions(context) {
|
|
|
71
85
|
cancelScheduledFramePublishes();
|
|
72
86
|
publishToolbarFrames();
|
|
73
87
|
framePublishAnimationFramesRef.current.push(requestAnimationFrame(publishToolbarFrames));
|
|
74
|
-
EditorToolbarVisuals_1.KEYBOARD_FRAME_REMEASURE_DELAYS_MS.forEach(
|
|
88
|
+
EditorToolbarVisuals_1.KEYBOARD_FRAME_REMEASURE_DELAYS_MS.forEach(delay => {
|
|
75
89
|
framePublishTimeoutsRef.current.push(setTimeout(publishToolbarFrames, delay));
|
|
76
90
|
});
|
|
77
|
-
}, [
|
|
91
|
+
}, [publishesFocusFrames,
|
|
92
|
+
cancelScheduledFramePublishes,
|
|
93
|
+
publishToolbarFrames,
|
|
94
|
+
framePublishAnimationFramesRef,
|
|
95
|
+
framePublishTimeoutsRef]);
|
|
78
96
|
const handleToolbarLayout = (0, react_1.useCallback)(() => {
|
|
79
97
|
requestAnimationFrame(publishToolbarFrame);
|
|
80
98
|
}, [publishToolbarFrame]);
|
|
@@ -91,8 +109,7 @@ function useEditorToolbarInteractions(context) {
|
|
|
91
109
|
}
|
|
92
110
|
const frame = requestAnimationFrame(publishToolbarFrame);
|
|
93
111
|
return () => cancelAnimationFrame(frame);
|
|
94
|
-
}, [
|
|
95
|
-
expandedGroupKey,
|
|
112
|
+
}, [expandedGroupKey,
|
|
96
113
|
menuState?.groupKey,
|
|
97
114
|
publishesFocusFrames,
|
|
98
115
|
publishToolbarFrame,
|
|
@@ -101,7 +118,7 @@ function useEditorToolbarInteractions(context) {
|
|
|
101
118
|
endItems.length,
|
|
102
119
|
windowHeight,
|
|
103
120
|
windowWidth,
|
|
104
|
-
|
|
121
|
+
registrationIdRef]);
|
|
105
122
|
(0, react_1.useEffect)(() => {
|
|
106
123
|
if (!publishesFocusFrames || menuState == null) {
|
|
107
124
|
const registrationId = menuRegistrationIdRef.current;
|
|
@@ -112,7 +129,12 @@ function useEditorToolbarInteractions(context) {
|
|
|
112
129
|
}
|
|
113
130
|
const frame = requestAnimationFrame(publishMenuFrame);
|
|
114
131
|
return () => cancelAnimationFrame(frame);
|
|
115
|
-
}, [menuState,
|
|
132
|
+
}, [menuState,
|
|
133
|
+
publishesFocusFrames,
|
|
134
|
+
publishMenuFrame,
|
|
135
|
+
windowHeight,
|
|
136
|
+
windowWidth,
|
|
137
|
+
menuRegistrationIdRef]);
|
|
116
138
|
(0, react_1.useEffect)(() => {
|
|
117
139
|
const registrationId = registrationIdRef.current;
|
|
118
140
|
const menuRegistrationId = menuRegistrationIdRef.current;
|
|
@@ -129,7 +151,7 @@ function useEditorToolbarInteractions(context) {
|
|
|
129
151
|
(0, EditorToolbarRegistry_1.unregisterEditorToolbarFrame)(menuRegistrationId);
|
|
130
152
|
}
|
|
131
153
|
};
|
|
132
|
-
}, [cancelScheduledFramePublishes]);
|
|
154
|
+
}, [cancelScheduledFramePublishes, menuRegistrationIdRef, registrationIdRef, toolbarInteractionActiveRef]);
|
|
133
155
|
(0, react_1.useEffect)(() => {
|
|
134
156
|
if (!publishesFocusFrames) {
|
|
135
157
|
cancelScheduledFramePublishes();
|
|
@@ -141,7 +163,7 @@ function useEditorToolbarInteractions(context) {
|
|
|
141
163
|
react_native_1.Keyboard.addListener('keyboardDidChangeFrame', scheduleToolbarFramePublish),
|
|
142
164
|
];
|
|
143
165
|
return () => {
|
|
144
|
-
subscriptions.forEach(
|
|
166
|
+
subscriptions.forEach(subscription => subscription.remove());
|
|
145
167
|
cancelScheduledFramePublishes();
|
|
146
168
|
};
|
|
147
169
|
}, [cancelScheduledFramePublishes, publishesFocusFrames, scheduleToolbarFramePublish]);
|
|
@@ -149,44 +171,44 @@ function useEditorToolbarInteractions(context) {
|
|
|
149
171
|
if (expandedGroupKey != null && !groupsByKey.has(expandedGroupKey)) {
|
|
150
172
|
setExpandedGroupKey(null);
|
|
151
173
|
}
|
|
152
|
-
}, [expandedGroupKey, groupsByKey]);
|
|
174
|
+
}, [expandedGroupKey, groupsByKey, setExpandedGroupKey]);
|
|
153
175
|
(0, react_1.useEffect)(() => {
|
|
154
176
|
if (menuState != null && !groupsByKey.has(menuState.groupKey)) {
|
|
155
177
|
setMenuState(null);
|
|
156
178
|
}
|
|
157
|
-
}, [groupsByKey, menuState]);
|
|
179
|
+
}, [groupsByKey, menuState, setMenuState]);
|
|
158
180
|
(0, react_1.useEffect)(() => {
|
|
159
181
|
if (shouldRenderMentionSuggestions) {
|
|
160
182
|
setExpandedGroupKey(null);
|
|
161
183
|
setMenuState(null);
|
|
162
184
|
}
|
|
163
|
-
}, [shouldRenderMentionSuggestions]);
|
|
185
|
+
}, [setExpandedGroupKey, setMenuState, shouldRenderMentionSuggestions]);
|
|
164
186
|
const handleButtonPress = (0, react_1.useCallback)((button) => {
|
|
165
187
|
button.action();
|
|
166
188
|
if (button.groupKey) {
|
|
167
|
-
setExpandedGroupKey(
|
|
189
|
+
setExpandedGroupKey(current => (current === button.groupKey ? null : current));
|
|
168
190
|
}
|
|
169
191
|
setMenuState(null);
|
|
170
|
-
}, []);
|
|
192
|
+
}, [setExpandedGroupKey, setMenuState]);
|
|
171
193
|
const handleToolbarPressIn = (0, react_1.useCallback)(() => {
|
|
172
194
|
if (preserveEditorFocus && !toolbarInteractionActiveRef.current) {
|
|
173
195
|
toolbarInteractionActiveRef.current = true;
|
|
174
196
|
(0, EditorToolbarRegistry_1.beginEditorToolbarInteraction)();
|
|
175
197
|
}
|
|
176
|
-
}, [preserveEditorFocus]);
|
|
198
|
+
}, [preserveEditorFocus, toolbarInteractionActiveRef]);
|
|
177
199
|
const handleToolbarPressOut = (0, react_1.useCallback)(() => {
|
|
178
200
|
if (preserveEditorFocus && toolbarInteractionActiveRef.current) {
|
|
179
201
|
toolbarInteractionActiveRef.current = false;
|
|
180
202
|
(0, EditorToolbarRegistry_1.endEditorToolbarInteraction)();
|
|
181
203
|
}
|
|
182
|
-
}, [preserveEditorFocus]);
|
|
204
|
+
}, [preserveEditorFocus, toolbarInteractionActiveRef]);
|
|
183
205
|
const handleGroupPress = (0, react_1.useCallback)((group) => {
|
|
184
206
|
if (group.isDisabled) {
|
|
185
207
|
return;
|
|
186
208
|
}
|
|
187
209
|
if (group.presentation === 'expand') {
|
|
188
210
|
setMenuState(null);
|
|
189
|
-
setExpandedGroupKey(
|
|
211
|
+
setExpandedGroupKey(current => (current === group.key ? null : group.key));
|
|
190
212
|
return;
|
|
191
213
|
}
|
|
192
214
|
const anchor = groupButtonRefs.current.get(group.key);
|
|
@@ -195,7 +217,7 @@ function useEditorToolbarInteractions(context) {
|
|
|
195
217
|
}
|
|
196
218
|
anchor.measureInWindow((x, y, width, height) => {
|
|
197
219
|
setExpandedGroupKey(null);
|
|
198
|
-
setMenuState(
|
|
220
|
+
setMenuState(current => current?.groupKey === group.key
|
|
199
221
|
? null
|
|
200
222
|
: {
|
|
201
223
|
groupKey: group.key,
|
|
@@ -205,7 +227,7 @@ function useEditorToolbarInteractions(context) {
|
|
|
205
227
|
height,
|
|
206
228
|
});
|
|
207
229
|
});
|
|
208
|
-
}, []);
|
|
230
|
+
}, [groupButtonRefs, setExpandedGroupKey, setMenuState]);
|
|
209
231
|
return {
|
|
210
232
|
handleToolbarPressIn,
|
|
211
233
|
handleToolbarPressOut,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { useEditorToolbarState } from './useEditorToolbarState';
|
|
1
|
+
import { type useEditorToolbarState } from './useEditorToolbarState';
|
|
2
2
|
import { type ToolbarRenderedItem, type ToolbarGroupButton } from './EditorToolbarTypes';
|
|
3
3
|
export declare function useEditorToolbarItems(context: Pick<ReturnType<typeof useEditorToolbarState>, 'onToggleMark' | 'onToggleBold' | 'onToggleItalic' | 'onToggleUnderline' | 'onToggleStrike' | 'onToggleListType' | 'onToggleBulletList' | 'onToggleOrderedList' | 'onRequestLink' | 'onRequestImage' | 'onToggleHeading' | 'onToggleBlockquote' | 'onInsertNodeType' | 'onInsertLineBreak' | 'onInsertHorizontalRule' | 'onRunCommand' | 'onIndentList' | 'onOutdentList' | 'onUndo' | 'onRedo' | 'onToolbarAction' | 'isMarkActive' | 'allowedMarks' | 'insertableNodes' | 'nodes' | 'commands' | 'canIndentList' | 'canOutdentList' | 'historyState' | 'toolbarItems' | 'expandedGroupKey' | 'menuState'>): {
|
|
4
4
|
startItems: ToolbarRenderedItem[];
|
|
@@ -66,6 +66,7 @@ function useEditorToolbarItems(context) {
|
|
|
66
66
|
case 'redo':
|
|
67
67
|
return onRedo;
|
|
68
68
|
}
|
|
69
|
+
// Falls through for unsupported commands.
|
|
69
70
|
case 'action':
|
|
70
71
|
return onToolbarAction ? () => onToolbarAction(item.key) : null;
|
|
71
72
|
}
|
|
@@ -110,7 +111,7 @@ function useEditorToolbarItems(context) {
|
|
|
110
111
|
? `${prefix}command:${item.command}:${index}`
|
|
111
112
|
: item.type === 'node'
|
|
112
113
|
? `${prefix}node:${item.nodeType}:${index}`
|
|
113
|
-
: `${prefix}action:${item.key}:${index}`, []);
|
|
114
|
+
: `${prefix}action:${String(item.key)}:${index}`, []);
|
|
114
115
|
const resolveButton = (0, react_1.useCallback)((item, index, prefix = '', groupKey, placement = 'scroll') => {
|
|
115
116
|
const resolvedPlacement = (0, EditorToolbarItems_1.resolveToolbarItemPlacement)(item.placement ?? placement);
|
|
116
117
|
const action = getActionForItem(item);
|
|
@@ -247,8 +248,8 @@ function useEditorToolbarItems(context) {
|
|
|
247
248
|
presentation,
|
|
248
249
|
placement,
|
|
249
250
|
children,
|
|
250
|
-
isActive: children.some(
|
|
251
|
-
isDisabled: children.every(
|
|
251
|
+
isActive: children.some(child => child.isActive) || isExpanded || isMenuOpen,
|
|
252
|
+
isDisabled: children.every(child => child.isDisabled),
|
|
252
253
|
isExpanded,
|
|
253
254
|
isOpen: isExpanded || isMenuOpen,
|
|
254
255
|
};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { useEditorToolbarState } from './useEditorToolbarState';
|
|
2
|
-
import { useEditorToolbarItems } from './useEditorToolbarItems';
|
|
3
|
-
import { useEditorToolbarInteractions } from './useEditorToolbarInteractions';
|
|
1
|
+
import { type useEditorToolbarState } from './useEditorToolbarState';
|
|
2
|
+
import { type useEditorToolbarItems } from './useEditorToolbarItems';
|
|
3
|
+
import { type useEditorToolbarInteractions } from './useEditorToolbarInteractions';
|
|
4
4
|
export declare function useEditorToolbarPresentation(context: Pick<ReturnType<typeof useEditorToolbarState>, 'menuState' | 'theme' | 'windowHeight' | 'windowWidth' | 'groupButtonRefs' | 'rootRef' | 'shouldRenderMentionSuggestions' | 'mentionState' | 'setMenuState' | 'menuCardRef'> & Pick<ReturnType<typeof useEditorToolbarItems>, 'groupsByKey' | 'startItems' | 'scrollItems' | 'endItems'> & Pick<ReturnType<typeof useEditorToolbarInteractions>, 'handleToolbarPressIn' | 'handleToolbarPressOut' | 'handleGroupPress' | 'handleButtonPress' | 'handleToolbarLayout' | 'resolvedShowTopBorder' | 'handleMenuLayout'>): import("react/jsx-runtime").JSX.Element;
|
|
@@ -59,7 +59,7 @@ function useEditorToolbarPresentation(context) {
|
|
|
59
59
|
const anchorGroupKey = options?.anchorGroupKey;
|
|
60
60
|
return ((0, jsx_runtime_1.jsxs)(react_native_1.View, { ref: anchorGroupKey == null
|
|
61
61
|
? undefined
|
|
62
|
-
:
|
|
62
|
+
: node => {
|
|
63
63
|
if (node) {
|
|
64
64
|
groupButtonRefs.current.set(anchorGroupKey, node);
|
|
65
65
|
}
|
|
@@ -84,7 +84,7 @@ function useEditorToolbarPresentation(context) {
|
|
|
84
84
|
{ height: resolvedSeparatorHeight },
|
|
85
85
|
theme?.separatorColor != null ? { backgroundColor: theme.separatorColor } : null,
|
|
86
86
|
] }, key));
|
|
87
|
-
const renderToolbarItems = (items) => items.map(
|
|
87
|
+
const renderToolbarItems = (items) => items.map(item => {
|
|
88
88
|
if (item.type === 'separator') {
|
|
89
89
|
return renderSeparator(item.key);
|
|
90
90
|
}
|
|
@@ -144,7 +144,7 @@ function useEditorToolbarPresentation(context) {
|
|
|
144
144
|
elevation: 8,
|
|
145
145
|
}
|
|
146
146
|
: null,
|
|
147
|
-
], contentContainerStyle: EditorToolbarVisuals_1.styles.mentionSuggestionsContent, keyboardShouldPersistTaps: 'always', children: mentionState.suggestions.map(
|
|
147
|
+
], contentContainerStyle: EditorToolbarVisuals_1.styles.mentionSuggestionsContent, keyboardShouldPersistTaps: 'always', children: mentionState.suggestions.map(suggestion => {
|
|
148
148
|
const label = (0, EditorToolbarVisuals_1.resolveMentionSuggestionDisplayLabel)(suggestion, mentionState.trigger);
|
|
149
149
|
const optionTheme = (mentionState.suggestionThemes?.[suggestion.key] ??
|
|
150
150
|
mentionState.theme)?.suggestions?.option;
|
|
@@ -184,7 +184,7 @@ function useEditorToolbarPresentation(context) {
|
|
|
184
184
|
backgroundColor: theme?.backgroundColor ?? EditorToolbarVisuals_1.TOOLBAR_BG,
|
|
185
185
|
borderColor: theme?.borderColor ?? EditorToolbarVisuals_1.MENU_BORDER,
|
|
186
186
|
},
|
|
187
|
-
], children: menuGroup.children.map(
|
|
187
|
+
], children: menuGroup.children.map(button => {
|
|
188
188
|
const visuals = resolveButtonVisuals(button);
|
|
189
189
|
return ((0, jsx_runtime_1.jsxs)(react_native_1.Pressable, { onPressIn: handleToolbarPressIn, onPressOut: handleToolbarPressOut, onPress: () => handleButtonPress(button), disabled: button.isDisabled, style: ({ pressed }) => [
|
|
190
190
|
EditorToolbarVisuals_1.styles.menuItem,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { View } from 'react-native';
|
|
1
|
+
import { type View } from 'react-native';
|
|
2
2
|
import { type EditorToolbarProps, type ToolbarMenuState } from './EditorToolbarTypes';
|
|
3
3
|
export declare function useEditorToolbarState({ activeState, historyState, onToggleBold, onToggleItalic, onToggleUnderline, onToggleStrike, onToggleBulletList, onToggleHeading, onToggleBlockquote, onToggleOrderedList, onIndentList, onOutdentList, onInsertHorizontalRule, onInsertLineBreak, onUndo, onRedo, onToggleMark, onToggleListType, onInsertNodeType, onRunCommand, onToolbarAction, onRequestLink, onRequestImage, toolbarItems, theme, showTopBorder, preserveEditorFocus, }: EditorToolbarProps): {
|
|
4
4
|
onToggleMark: ((mark: string) => void) | undefined;
|
|
@@ -6,7 +6,7 @@ const react_native_1 = require("react-native");
|
|
|
6
6
|
const EditorToolbarItems_1 = require("./EditorToolbarItems");
|
|
7
7
|
const EditorToolbarRegistry_1 = require("./EditorToolbarRegistry");
|
|
8
8
|
function useEditorToolbarState({ activeState, historyState, onToggleBold, onToggleItalic, onToggleUnderline, onToggleStrike, onToggleBulletList, onToggleHeading, onToggleBlockquote, onToggleOrderedList, onIndentList, onOutdentList, onInsertHorizontalRule, onInsertLineBreak, onUndo, onRedo, onToggleMark, onToggleListType, onInsertNodeType, onRunCommand, onToolbarAction, onRequestLink, onRequestImage, toolbarItems = EditorToolbarItems_1.DEFAULT_EDITOR_TOOLBAR_ITEMS, theme, showTopBorder, preserveEditorFocus = true, }) {
|
|
9
|
-
const marks = activeState.marks ?? {};
|
|
9
|
+
const marks = (0, react_1.useMemo)(() => activeState.marks ?? {}, [activeState.marks]);
|
|
10
10
|
const nodes = activeState.nodes ?? {};
|
|
11
11
|
const commands = activeState.commands ?? {};
|
|
12
12
|
const allowedMarks = activeState.allowedMarks ?? [];
|
|
@@ -34,17 +34,17 @@ function useFocusPreservingFrames(refs, enabled) {
|
|
|
34
34
|
const framesByRef = (0, react_1.useRef)(new Map());
|
|
35
35
|
const [frames, setFrames] = (0, react_1.useState)(EMPTY_FRAMES);
|
|
36
36
|
const publish = (0, react_1.useCallback)(() => {
|
|
37
|
-
const nextFrames = currentRefs.flatMap(
|
|
37
|
+
const nextFrames = currentRefs.flatMap(ref => {
|
|
38
38
|
const measurement = framesByRef.current.get(ref);
|
|
39
39
|
return measurement == null ? [] : [measurement.frame];
|
|
40
40
|
});
|
|
41
|
-
setFrames(
|
|
41
|
+
setFrames(current => (sameFrames(current, nextFrames) ? current : nextFrames));
|
|
42
42
|
}, [currentRefs]);
|
|
43
43
|
const refresh = (0, react_1.useCallback)(() => {
|
|
44
44
|
const callbackGeneration = ++generation.current;
|
|
45
45
|
if (!enabled) {
|
|
46
46
|
framesByRef.current.clear();
|
|
47
|
-
setFrames(
|
|
47
|
+
setFrames(current => (current.length === 0 ? current : EMPTY_FRAMES));
|
|
48
48
|
return;
|
|
49
49
|
}
|
|
50
50
|
const admittedRefs = new Set(currentRefs);
|
|
@@ -57,7 +57,7 @@ function useFocusPreservingFrames(refs, enabled) {
|
|
|
57
57
|
}
|
|
58
58
|
}
|
|
59
59
|
publish();
|
|
60
|
-
currentRefs.forEach(
|
|
60
|
+
currentRefs.forEach(ref => {
|
|
61
61
|
const target = ref.current;
|
|
62
62
|
if (target == null || typeof target.measureInWindow !== 'function') {
|
|
63
63
|
framesByRef.current.delete(ref);
|
|
@@ -67,8 +67,9 @@ function useFocusPreservingFrames(refs, enabled) {
|
|
|
67
67
|
try {
|
|
68
68
|
target.measureInWindow((x, y, width, height) => {
|
|
69
69
|
// An older measurement must not restore a removed or replaced target.
|
|
70
|
-
if (generation.current !== callbackGeneration || ref.current !== target)
|
|
70
|
+
if (generation.current !== callbackGeneration || ref.current !== target) {
|
|
71
71
|
return;
|
|
72
|
+
}
|
|
72
73
|
const frame = validFrame(x, y, width, height);
|
|
73
74
|
if (frame == null) {
|
|
74
75
|
framesByRef.current.delete(ref);
|
|
@@ -80,8 +81,9 @@ function useFocusPreservingFrames(refs, enabled) {
|
|
|
80
81
|
});
|
|
81
82
|
}
|
|
82
83
|
catch {
|
|
83
|
-
if (generation.current !== callbackGeneration)
|
|
84
|
+
if (generation.current !== callbackGeneration) {
|
|
84
85
|
return;
|
|
86
|
+
}
|
|
85
87
|
framesByRef.current.delete(ref);
|
|
86
88
|
publish();
|
|
87
89
|
}
|
|
@@ -91,14 +93,15 @@ function useFocusPreservingFrames(refs, enabled) {
|
|
|
91
93
|
refresh();
|
|
92
94
|
});
|
|
93
95
|
(0, react_1.useEffect)(() => {
|
|
94
|
-
if (!enabled)
|
|
96
|
+
if (!enabled) {
|
|
95
97
|
return;
|
|
98
|
+
}
|
|
96
99
|
const subscriptions = [
|
|
97
100
|
react_native_1.Keyboard.addListener('keyboardDidShow', refresh),
|
|
98
101
|
react_native_1.Keyboard.addListener('keyboardDidHide', refresh),
|
|
99
102
|
react_native_1.Keyboard.addListener('keyboardDidChangeFrame', refresh),
|
|
100
103
|
];
|
|
101
|
-
return () => subscriptions.forEach(
|
|
104
|
+
return () => subscriptions.forEach(subscription => subscription.remove());
|
|
102
105
|
}, [enabled, refresh]);
|
|
103
106
|
(0, react_1.useEffect)(() => () => {
|
|
104
107
|
generation.current += 1;
|
|
@@ -57,7 +57,7 @@ export interface UseNativeEditorDocumentReturn {
|
|
|
57
57
|
/**
|
|
58
58
|
* Headless binding to a document handle: the same controlled content,
|
|
59
59
|
* getters, and history the editor exposes, with no view attached. Use it to
|
|
60
|
-
* read or drive a document that is not currently mounted
|
|
60
|
+
* read or drive a document that is not currently mounted : a preview, a
|
|
61
61
|
* background save, a test.
|
|
62
62
|
*
|
|
63
63
|
* `RichTextEditor` uses this internally, so mounting an editor on the
|
package/dist/useNativeEditor.js
CHANGED
|
@@ -11,7 +11,7 @@ function isRevisionMismatchError(error) {
|
|
|
11
11
|
/**
|
|
12
12
|
* Headless binding to a document handle: the same controlled content,
|
|
13
13
|
* getters, and history the editor exposes, with no view attached. Use it to
|
|
14
|
-
* read or drive a document that is not currently mounted
|
|
14
|
+
* read or drive a document that is not currently mounted : a preview, a
|
|
15
15
|
* background save, a test.
|
|
16
16
|
*
|
|
17
17
|
* `RichTextEditor` uses this internally, so mounting an editor on the
|
|
@@ -85,8 +85,9 @@ function useNativeEditorDocument(options) {
|
|
|
85
85
|
snapshotJson = snapshot.json;
|
|
86
86
|
contentKey = JSON.stringify(snapshot.json);
|
|
87
87
|
}
|
|
88
|
-
if (currentEditorIdRef.current !== refreshedEditorId)
|
|
88
|
+
if (currentEditorIdRef.current !== refreshedEditorId) {
|
|
89
89
|
return;
|
|
90
|
+
}
|
|
90
91
|
const historyState = {
|
|
91
92
|
canUndo: state.canUndo,
|
|
92
93
|
canRedo: state.canRedo,
|
|
@@ -122,8 +123,9 @@ function useNativeEditorDocument(options) {
|
|
|
122
123
|
onContentChangeRef.current != null) {
|
|
123
124
|
const echoes = pendingControlledEchoesRef.current.keys;
|
|
124
125
|
echoes.push(`html:${snapshotHtml}`);
|
|
125
|
-
if (echoes.length > 32)
|
|
126
|
+
if (echoes.length > 32) {
|
|
126
127
|
echoes.shift();
|
|
128
|
+
}
|
|
127
129
|
}
|
|
128
130
|
onContentChangeRef.current?.(snapshotHtml);
|
|
129
131
|
}
|
|
@@ -132,8 +134,9 @@ function useNativeEditorDocument(options) {
|
|
|
132
134
|
onContentChangeJSONRef.current != null) {
|
|
133
135
|
const echoes = pendingControlledEchoesRef.current.keys;
|
|
134
136
|
echoes.push(`json:${contentKey}`);
|
|
135
|
-
if (echoes.length > 32)
|
|
137
|
+
if (echoes.length > 32) {
|
|
136
138
|
echoes.shift();
|
|
139
|
+
}
|
|
137
140
|
}
|
|
138
141
|
onContentChangeJSONRef.current?.(snapshotJson);
|
|
139
142
|
}
|
|
@@ -153,14 +156,17 @@ function useNativeEditorDocument(options) {
|
|
|
153
156
|
// local-API replacement carrying the rendered engine revision as its
|
|
154
157
|
// base. Content callbacks stay suppressed (controlled sync parity).
|
|
155
158
|
(0, react_1.useEffect)(() => {
|
|
156
|
-
if (engineView.editorId !== editorId || !engineView.ready || handle.isDestroyed)
|
|
159
|
+
if (engineView.editorId !== editorId || !engineView.ready || handle.isDestroyed) {
|
|
157
160
|
return;
|
|
158
|
-
|
|
161
|
+
}
|
|
162
|
+
if (engineView.documentRevision == null) {
|
|
159
163
|
return;
|
|
164
|
+
}
|
|
160
165
|
const wantsHtml = value != null;
|
|
161
166
|
const wantsJson = value == null && serializedControlledJson != null;
|
|
162
|
-
if (!wantsHtml && !wantsJson)
|
|
167
|
+
if (!wantsHtml && !wantsJson) {
|
|
163
168
|
return;
|
|
169
|
+
}
|
|
164
170
|
const controlledContentKey = wantsHtml
|
|
165
171
|
? `html:${value}`
|
|
166
172
|
: `json:${serializedControlledJson}`;
|
|
@@ -169,10 +175,12 @@ function useNativeEditorDocument(options) {
|
|
|
169
175
|
lastControlledContentKeyRef.current = controlledContentKey;
|
|
170
176
|
ignoredControlledEchoRef.current = null;
|
|
171
177
|
}
|
|
172
|
-
if (ignoredControlledEchoRef.current === controlledContentKey)
|
|
178
|
+
if (ignoredControlledEchoRef.current === controlledContentKey) {
|
|
173
179
|
return;
|
|
174
|
-
|
|
180
|
+
}
|
|
181
|
+
if (!controlledContentChanged && pendingControlledEchoesRef.current.keys.length > 0) {
|
|
175
182
|
return;
|
|
183
|
+
}
|
|
176
184
|
const snapshot = handle.bridge.getContentSnapshot();
|
|
177
185
|
if (currentEditorIdRef.current !== editorId || emittedRef.current.editorId !== editorId) {
|
|
178
186
|
return;
|
|
@@ -211,8 +219,9 @@ function useNativeEditorDocument(options) {
|
|
|
211
219
|
history: valueJSONUpdateMode === 'reset' ? 'resetAndClear' : 'undoableBoundary',
|
|
212
220
|
baseDocumentRevision: engineView.documentRevision,
|
|
213
221
|
});
|
|
214
|
-
if (currentEditorIdRef.current !== editorId)
|
|
222
|
+
if (currentEditorIdRef.current !== editorId) {
|
|
215
223
|
return;
|
|
224
|
+
}
|
|
216
225
|
onLocalCommitRef.current?.();
|
|
217
226
|
refresh(false);
|
|
218
227
|
}
|
|
@@ -248,8 +257,9 @@ function useNativeEditorDocument(options) {
|
|
|
248
257
|
return;
|
|
249
258
|
}
|
|
250
259
|
operation();
|
|
251
|
-
if (currentEditorIdRef.current !== handle.editorId)
|
|
260
|
+
if (currentEditorIdRef.current !== handle.editorId) {
|
|
252
261
|
return;
|
|
262
|
+
}
|
|
253
263
|
onLocalCommitRef.current?.();
|
|
254
264
|
refresh(true);
|
|
255
265
|
}, [handle, refresh]);
|
|
@@ -2,8 +2,8 @@ import { type AtomAttrsUpdate } from './atoms';
|
|
|
2
2
|
import { type AtomInstance } from './atomInstances';
|
|
3
3
|
import { type NativeEditorDocumentHandle } from './NativeEditorBridge';
|
|
4
4
|
import { type EditorToolbarHeadingLevel } from './EditorToolbar';
|
|
5
|
-
import { useRichTextEditorState } from './useRichTextEditorState';
|
|
6
|
-
import { useRichTextEditorUpdates } from './useRichTextEditorUpdates';
|
|
5
|
+
import { type useRichTextEditorState } from './useRichTextEditorState';
|
|
6
|
+
import { type useRichTextEditorUpdates } from './useRichTextEditorUpdates';
|
|
7
7
|
export declare function useRichTextEditorCommands(context: Pick<ReturnType<typeof useRichTextEditorState>, 'editable' | 'documentHandle' | 'latestRevisionRef' | 'atomStateRef' | 'bridge' | 'document' | 'nativeViewRef' | 'activeStateRef' | 'documentDescriptor' | 'onRequestLinkRef' | 'selectionRef' | 'onRequestImageRef' | 'ref' | 'externalCompositionManager'> & Pick<ReturnType<typeof useRichTextEditorUpdates>, 'refreshAtomsFromUpdate' | 'afterLocalEngineMutation' | 'pushEngineUpdateToView'>): {
|
|
8
8
|
openLinkRequest: () => void;
|
|
9
9
|
openImageRequest: () => void;
|