@apollohg/react-native-rich-text-editor 2.0.1 → 2.0.3
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 +29 -123
- package/android/src/main/java/com/apollohg/editor/EditorEditText.kt +20 -6
- package/android/src/main/java/com/apollohg/editor/EditorEditTextClipboard.kt +181 -36
- package/android/src/main/java/com/apollohg/editor/EditorEditTextImages.kt +25 -0
- package/android/src/main/java/com/apollohg/editor/EditorEditTextSelection.kt +7 -0
- package/android/src/main/java/com/apollohg/editor/EditorTextSurfaceInteraction.kt +31 -11
- package/android/src/main/java/com/apollohg/editor/EditorV2Adapter.kt +36 -0
- package/android/src/main/java/com/apollohg/editor/EditorV2Backend.kt +1 -0
- package/android/src/main/java/com/apollohg/editor/EditorV2Driver.kt +10 -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/NativeEditorExpoView.kt +2 -0
- package/android/src/main/java/com/apollohg/editor/NativeEditorExpoViewProperties.kt +4 -0
- package/android/src/main/java/com/apollohg/editor/NativeEditorModule.kt +3 -0
- 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/UniffiEditorV2Backend.kt +4 -0
- package/android/src/main/java/com/apollohg/editor/viewer/AndroidProseLayoutEngine.kt +1 -1
- package/dist/EditorStyleSheetNormalization.js +1 -1
- package/dist/EditorStyleSheetTypes.d.ts +1 -1
- package/dist/NativeRichTextEditor.d.ts +1 -1
- package/dist/RichTextEditorNativeTypes.d.ts +2 -1
- package/dist/RichTextEditorTypes.d.ts +4 -0
- package/dist/index.d.ts +1 -1
- package/dist/useRichTextEditorPresentation.d.ts +1 -1
- package/dist/useRichTextEditorPresentation.js +2 -2
- package/dist/useRichTextEditorState.d.ts +5 -3
- package/dist/useRichTextEditorState.js +4 -3
- 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+KeyboardInput.swift +299 -0
- package/ios/EditorTextView.swift +64 -44
- package/ios/EditorV2Adapter+Commands.swift +22 -0
- package/ios/EditorV2Adapter+RenderValidation.swift +2 -2
- package/ios/EditorV2Shadow.swift +12 -0
- package/ios/Generated_editor_core.swift +10 -0
- package/ios/NativeEditorExpoView+Properties.swift +4 -0
- package/ios/NativeEditorModule.swift +3 -0
- 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/ios/editor_coreFFI/editor_coreFFI.h +11 -0
- package/package.json +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/rust/bindings/kotlin/uniffi/editor_core/editor_core.kt +18 -0
- package/src/EditorStyleSheetNormalization.ts +1 -1
- package/src/EditorStyleSheetTypes.ts +1 -1
- package/src/NativeRichTextEditor.tsx +1 -0
- package/src/RichTextEditorNativeTypes.tsx +2 -0
- package/src/RichTextEditorTypes.tsx +5 -0
- package/src/index.ts +1 -0
- package/src/useRichTextEditorPresentation.tsx +3 -0
- package/src/useRichTextEditorState.tsx +5 -2
|
@@ -796,6 +796,42 @@ internal class EditorV2Adapter private constructor(
|
|
|
796
796
|
)
|
|
797
797
|
}
|
|
798
798
|
|
|
799
|
+
override fun clipboardJson(): String? {
|
|
800
|
+
if (destroyed) return null
|
|
801
|
+
return when (val result = backend.getClipboard(editorId)) {
|
|
802
|
+
is EditorV2CallResult.Ok -> result.value
|
|
803
|
+
|
|
804
|
+
is EditorV2CallResult.Err -> {
|
|
805
|
+
emit(result.error)
|
|
806
|
+
null
|
|
807
|
+
}
|
|
808
|
+
}
|
|
809
|
+
}
|
|
810
|
+
|
|
811
|
+
override fun pasteAtSelection(
|
|
812
|
+
fragment: String?,
|
|
813
|
+
html: String?,
|
|
814
|
+
text: String?,
|
|
815
|
+
plainText: Boolean,
|
|
816
|
+
anchor: Int,
|
|
817
|
+
head: Int,
|
|
818
|
+
preserveEngineSelection: Boolean
|
|
819
|
+
): String? {
|
|
820
|
+
val command = JSONObject().put("type", "paste")
|
|
821
|
+
fragment?.let { command.put("fragment", it) }
|
|
822
|
+
html?.let { command.put("html", it) }
|
|
823
|
+
text?.let { command.put("text", it) }
|
|
824
|
+
if (plainText) command.put("plainText", true)
|
|
825
|
+
return performMutation(
|
|
826
|
+
preSelection = if (preserveEngineSelection) null else intArrayOf(anchor, head),
|
|
827
|
+
adoptEngineSelection = true
|
|
828
|
+
) {
|
|
829
|
+
callWithEnvelope(JSONObject().put("command", command)) { requestJson ->
|
|
830
|
+
backend.applyCommand(editorId, requestJson)
|
|
831
|
+
}
|
|
832
|
+
}
|
|
833
|
+
}
|
|
834
|
+
|
|
799
835
|
override fun toggleMark(markName: String, anchor: Int, head: Int): String? = commandAtSelection(
|
|
800
836
|
JSONObject().put("type", "toggleMark").put("markType", markName),
|
|
801
837
|
anchor,
|
|
@@ -37,6 +37,7 @@ internal interface EditorV2Backend {
|
|
|
37
37
|
fun getDocumentJson(editorId: String): EditorV2CallResult<String>
|
|
38
38
|
fun getDocumentHtml(editorId: String): EditorV2CallResult<String>
|
|
39
39
|
fun getContentSnapshot(editorId: String): EditorV2CallResult<String>
|
|
40
|
+
fun getClipboard(editorId: String): EditorV2CallResult<String>
|
|
40
41
|
fun applyInput(editorId: String, requestJson: String): EditorV2CallResult<String>
|
|
41
42
|
fun applyCommand(editorId: String, requestJson: String): EditorV2CallResult<String>
|
|
42
43
|
fun applyLocalApi(editorId: String, requestJson: String): EditorV2CallResult<String>
|
|
@@ -50,6 +50,16 @@ internal interface EditorV2Driver {
|
|
|
50
50
|
fun insertNode(nodeType: String, anchor: Int, head: Int): String?
|
|
51
51
|
fun insertContentHtmlAtSelection(html: String, anchor: Int, head: Int): String?
|
|
52
52
|
fun insertContentJsonAtSelection(json: String, anchor: Int, head: Int): String?
|
|
53
|
+
fun clipboardJson(): String?
|
|
54
|
+
fun pasteAtSelection(
|
|
55
|
+
fragment: String?,
|
|
56
|
+
html: String?,
|
|
57
|
+
text: String?,
|
|
58
|
+
plainText: Boolean,
|
|
59
|
+
anchor: Int,
|
|
60
|
+
head: Int,
|
|
61
|
+
preserveEngineSelection: Boolean = false
|
|
62
|
+
): String?
|
|
53
63
|
fun toggleMark(markName: String, anchor: Int, head: Int): String?
|
|
54
64
|
fun setMark(markName: String, attrsJson: String, anchor: Int, head: Int): String?
|
|
55
65
|
fun unsetMark(markName: String, anchor: Int, head: Int): String?
|
|
@@ -141,6 +141,7 @@ private fun validMentionNodeStyle(value: Any?): Boolean {
|
|
|
141
141
|
listOf("Top", "Right", "Bottom", "Left").map { "border${it}Color" }
|
|
142
142
|
val nonnegative =
|
|
143
143
|
listOf("Top", "Right", "Bottom", "Left").map { "border${it}Width" } +
|
|
144
|
+
listOf("Top", "Right", "Bottom", "Left").map { "padding$it" } +
|
|
144
145
|
listOf("TopLeft", "TopRight", "BottomLeft", "BottomRight").map { "border${it}Radius" }
|
|
145
146
|
val enums = mapOf(
|
|
146
147
|
"fontWeight" to
|
|
@@ -30,8 +30,15 @@ internal class ImageResizeOverlayView @JvmOverloads constructor(
|
|
|
30
30
|
val corner: Corner,
|
|
31
31
|
val originalRect: RectF,
|
|
32
32
|
val docPos: Int,
|
|
33
|
+
val span: BlockImageSpan,
|
|
34
|
+
val downX: Float,
|
|
35
|
+
val downY: Float,
|
|
36
|
+
val originalSize: Pair<Int, Int>,
|
|
37
|
+
val fixedWidthPx: Float,
|
|
38
|
+
val fixedHeightPx: Float,
|
|
33
39
|
val maximumWidthPx: Float,
|
|
34
|
-
var previewRect: RectF
|
|
40
|
+
var previewRect: RectF,
|
|
41
|
+
var previewContentSize: Pair<Float, Float>
|
|
35
42
|
)
|
|
36
43
|
|
|
37
44
|
private var editorView: RichTextEditorView? = null
|
|
@@ -73,7 +80,10 @@ internal class ImageResizeOverlayView @JvmOverloads constructor(
|
|
|
73
80
|
cancelActiveResize()
|
|
74
81
|
return
|
|
75
82
|
}
|
|
76
|
-
|
|
83
|
+
val selectedSpan = editorView?.selectedImageSpanForResize()
|
|
84
|
+
if (currentGeometry?.docPos != nextGeometry.docPos ||
|
|
85
|
+
dragState?.span?.let { it !== selectedSpan } == true
|
|
86
|
+
) cancelActiveResize()
|
|
77
87
|
currentGeometry = nextGeometry
|
|
78
88
|
visibility = VISIBLE
|
|
79
89
|
bringToFront()
|
|
@@ -82,6 +92,7 @@ internal class ImageResizeOverlayView @JvmOverloads constructor(
|
|
|
82
92
|
}
|
|
83
93
|
|
|
84
94
|
fun cancelActiveResize() {
|
|
95
|
+
dragState?.let { state -> editorView?.restoreImageResizePreview(state.span) }
|
|
85
96
|
dragState = null
|
|
86
97
|
currentGeometry = null
|
|
87
98
|
parent?.requestDisallowInterceptTouchEvent(false)
|
|
@@ -114,12 +125,20 @@ internal class ImageResizeOverlayView @JvmOverloads constructor(
|
|
|
114
125
|
when (event.actionMasked) {
|
|
115
126
|
MotionEvent.ACTION_DOWN -> {
|
|
116
127
|
val corner = cornerAt(event.x, event.y, geometry.rect) ?: return false
|
|
128
|
+
val span = editorView?.selectedImageSpanForResize() ?: return false
|
|
117
129
|
dragState = DragState(
|
|
118
130
|
corner = corner,
|
|
119
131
|
originalRect = RectF(geometry.rect),
|
|
120
132
|
docPos = geometry.docPos,
|
|
133
|
+
span = span,
|
|
134
|
+
downX = event.x,
|
|
135
|
+
downY = event.y,
|
|
136
|
+
originalSize = span.currentSizePx(),
|
|
137
|
+
fixedWidthPx = geometry.rect.width() - span.currentSizePx().first,
|
|
138
|
+
fixedHeightPx = geometry.rect.height() - span.currentSizePx().second,
|
|
121
139
|
maximumWidthPx = editorView?.maximumImageWidthPx() ?: geometry.rect.width(),
|
|
122
|
-
previewRect = RectF(geometry.rect)
|
|
140
|
+
previewRect = RectF(geometry.rect),
|
|
141
|
+
previewContentSize = span.currentSizePx().let { it.first.toFloat() to it.second.toFloat() }
|
|
123
142
|
)
|
|
124
143
|
parent?.requestDisallowInterceptTouchEvent(true)
|
|
125
144
|
return true
|
|
@@ -127,29 +146,24 @@ internal class ImageResizeOverlayView @JvmOverloads constructor(
|
|
|
127
146
|
|
|
128
147
|
MotionEvent.ACTION_MOVE -> {
|
|
129
148
|
val state = dragState ?: return false
|
|
130
|
-
|
|
131
|
-
originalRect = state.originalRect,
|
|
132
|
-
corner = state.corner,
|
|
133
|
-
deltaX = event.x - handleCenter(state.corner, state.originalRect).x,
|
|
134
|
-
deltaY = event.y - handleCenter(state.corner, state.originalRect).y,
|
|
135
|
-
maximumWidthPx = state.maximumWidthPx
|
|
136
|
-
)
|
|
137
|
-
state.previewRect = RectF(nextRect)
|
|
138
|
-
currentGeometry = EditorEditText.SelectedImageGeometry(state.docPos, nextRect)
|
|
139
|
-
updateSystemGestureExclusionRects()
|
|
140
|
-
invalidate()
|
|
149
|
+
updatePreview(state, event.x, event.y)
|
|
141
150
|
return true
|
|
142
151
|
}
|
|
143
152
|
|
|
144
153
|
MotionEvent.ACTION_UP, MotionEvent.ACTION_CANCEL -> {
|
|
145
154
|
val state = dragState ?: return false
|
|
146
155
|
if (event.actionMasked == MotionEvent.ACTION_UP) {
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
156
|
+
updatePreview(state, event.x, event.y)
|
|
157
|
+
val previewSize = state.span.currentSizePx()
|
|
158
|
+
if (previewSize != state.originalSize) {
|
|
159
|
+
editorView?.resizeImage(
|
|
160
|
+
state.docPos,
|
|
161
|
+
state.previewContentSize.first,
|
|
162
|
+
state.previewContentSize.second
|
|
163
|
+
)
|
|
164
|
+
}
|
|
165
|
+
editorView?.restoreImageResizePreview(state.span)
|
|
166
|
+
} else editorView?.restoreImageResizePreview(state.span)
|
|
153
167
|
dragState = null
|
|
154
168
|
parent?.requestDisallowInterceptTouchEvent(false)
|
|
155
169
|
post { refresh() }
|
|
@@ -160,6 +174,51 @@ internal class ImageResizeOverlayView @JvmOverloads constructor(
|
|
|
160
174
|
return false
|
|
161
175
|
}
|
|
162
176
|
|
|
177
|
+
private fun updatePreview(state: DragState, x: Float, y: Float) {
|
|
178
|
+
val deltaX = x - state.downX
|
|
179
|
+
val deltaY = y - state.downY
|
|
180
|
+
if (deltaX == 0f && deltaY == 0f) {
|
|
181
|
+
val originalContentSize = state.originalSize.let {
|
|
182
|
+
it.first.toFloat() to it.second.toFloat()
|
|
183
|
+
}
|
|
184
|
+
if (state.previewContentSize == originalContentSize) return
|
|
185
|
+
val boundEditor = editorView ?: return
|
|
186
|
+
if (!boundEditor.previewImageResize(
|
|
187
|
+
state.span,
|
|
188
|
+
originalContentSize.first,
|
|
189
|
+
originalContentSize.second
|
|
190
|
+
)
|
|
191
|
+
) return
|
|
192
|
+
state.previewRect = RectF(state.originalRect)
|
|
193
|
+
state.previewContentSize = originalContentSize
|
|
194
|
+
currentGeometry = boundEditor.selectedImageGeometry()
|
|
195
|
+
?.takeIf { it.docPos == state.docPos }
|
|
196
|
+
?: EditorEditText.SelectedImageGeometry(state.docPos, state.originalRect)
|
|
197
|
+
updateSystemGestureExclusionRects()
|
|
198
|
+
invalidate()
|
|
199
|
+
return
|
|
200
|
+
}
|
|
201
|
+
val (nextRect, contentSize) = resizedRect(
|
|
202
|
+
originalRect = state.originalRect,
|
|
203
|
+
originalContentSize = state.originalSize,
|
|
204
|
+
fixedWidthPx = state.fixedWidthPx,
|
|
205
|
+
fixedHeightPx = state.fixedHeightPx,
|
|
206
|
+
corner = state.corner,
|
|
207
|
+
deltaX = deltaX,
|
|
208
|
+
deltaY = deltaY,
|
|
209
|
+
maximumWidthPx = state.maximumWidthPx
|
|
210
|
+
)
|
|
211
|
+
val boundEditor = editorView ?: return
|
|
212
|
+
if (!boundEditor.previewImageResize(state.span, contentSize.first, contentSize.second)) return
|
|
213
|
+
state.previewRect = RectF(nextRect)
|
|
214
|
+
state.previewContentSize = contentSize
|
|
215
|
+
currentGeometry = boundEditor.selectedImageGeometry()
|
|
216
|
+
?.takeIf { it.docPos == state.docPos }
|
|
217
|
+
?: EditorEditText.SelectedImageGeometry(state.docPos, nextRect)
|
|
218
|
+
updateSystemGestureExclusionRects()
|
|
219
|
+
invalidate()
|
|
220
|
+
}
|
|
221
|
+
|
|
163
222
|
override fun onDetachedFromWindow() {
|
|
164
223
|
cancelActiveResize()
|
|
165
224
|
super.onDetachedFromWindow()
|
|
@@ -217,12 +276,17 @@ internal class ImageResizeOverlayView @JvmOverloads constructor(
|
|
|
217
276
|
|
|
218
277
|
private fun resizedRect(
|
|
219
278
|
originalRect: RectF,
|
|
279
|
+
originalContentSize: Pair<Int, Int>,
|
|
280
|
+
fixedWidthPx: Float,
|
|
281
|
+
fixedHeightPx: Float,
|
|
220
282
|
corner: Corner,
|
|
221
283
|
deltaX: Float,
|
|
222
284
|
deltaY: Float,
|
|
223
285
|
maximumWidthPx: Float?
|
|
224
|
-
): RectF {
|
|
225
|
-
val
|
|
286
|
+
): Pair<RectF, Pair<Float, Float>> {
|
|
287
|
+
val originalWidth = max(originalContentSize.first.toFloat(), 1f)
|
|
288
|
+
val originalHeight = max(originalContentSize.second.toFloat(), 1f)
|
|
289
|
+
val aspectRatio = max(originalWidth / originalHeight, 0.1f)
|
|
226
290
|
val signedDx = if (corner == Corner.TOP_RIGHT ||
|
|
227
291
|
corner == Corner.BOTTOM_RIGHT
|
|
228
292
|
) {
|
|
@@ -237,30 +301,34 @@ internal class ImageResizeOverlayView @JvmOverloads constructor(
|
|
|
237
301
|
} else {
|
|
238
302
|
-deltaY
|
|
239
303
|
}
|
|
240
|
-
val
|
|
241
|
-
|
|
304
|
+
val projectedScale = 1f +
|
|
305
|
+
((signedDx * originalWidth) + (signedDy * originalHeight)) /
|
|
306
|
+
((originalWidth * originalWidth) + (originalHeight * originalHeight))
|
|
242
307
|
val scale = max(
|
|
243
|
-
|
|
244
|
-
minimumImageSizePx /
|
|
308
|
+
projectedScale,
|
|
309
|
+
max(minimumImageSizePx / originalWidth, minimumImageSizePx / originalHeight)
|
|
245
310
|
)
|
|
246
|
-
val unclampedWidth = max(minimumImageSizePx,
|
|
311
|
+
val unclampedWidth = max(minimumImageSizePx, originalWidth * scale)
|
|
247
312
|
val unclampedHeight = max(minimumImageSizePx / aspectRatio, unclampedWidth / aspectRatio)
|
|
248
313
|
val (width, height) = editorView?.let { boundEditor ->
|
|
249
314
|
maximumWidthPx?.let { maxWidth ->
|
|
250
315
|
boundEditor.clampImageSize(
|
|
251
316
|
widthPx = unclampedWidth,
|
|
252
317
|
heightPx = unclampedHeight,
|
|
253
|
-
maximumWidthPx = maxWidth
|
|
318
|
+
maximumWidthPx = (maxWidth - fixedWidthPx).coerceAtLeast(minimumImageSizePx)
|
|
254
319
|
)
|
|
255
320
|
} ?: boundEditor.clampImageSize(unclampedWidth, unclampedHeight)
|
|
256
321
|
} ?: (unclampedWidth to unclampedHeight)
|
|
257
322
|
val anchor = anchorPoint(corner, originalRect)
|
|
258
323
|
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
Corner.
|
|
263
|
-
Corner.
|
|
324
|
+
val visualWidth = width + fixedWidthPx
|
|
325
|
+
val visualHeight = height + fixedHeightPx
|
|
326
|
+
val rect = when (corner) {
|
|
327
|
+
Corner.TOP_LEFT -> RectF(anchor.x - visualWidth, anchor.y - visualHeight, anchor.x, anchor.y)
|
|
328
|
+
Corner.TOP_RIGHT -> RectF(anchor.x, anchor.y - visualHeight, anchor.x + visualWidth, anchor.y)
|
|
329
|
+
Corner.BOTTOM_LEFT -> RectF(anchor.x - visualWidth, anchor.y, anchor.x, anchor.y + visualHeight)
|
|
330
|
+
Corner.BOTTOM_RIGHT -> RectF(anchor.x, anchor.y, anchor.x + visualWidth, anchor.y + visualHeight)
|
|
264
331
|
}
|
|
332
|
+
return rect to (width to height)
|
|
265
333
|
}
|
|
266
334
|
}
|
|
@@ -388,6 +388,8 @@ class NativeEditorExpoView(context: Context, appContext: AppContext) :
|
|
|
388
388
|
|
|
389
389
|
fun setEditable(editable: Boolean) = setEditableImpl(editable)
|
|
390
390
|
|
|
391
|
+
fun setPasteMode(rawPasteMode: String?) = setPasteModeImpl(rawPasteMode)
|
|
392
|
+
|
|
391
393
|
fun beginExternalTextComposition(sessionId: String): String =
|
|
392
394
|
beginExternalTextCompositionImpl(sessionId)
|
|
393
395
|
|
|
@@ -140,6 +140,10 @@ internal fun NativeEditorExpoView.setEditableImpl(editable: Boolean) {
|
|
|
140
140
|
updateKeyboardToolbarVisibility()
|
|
141
141
|
}
|
|
142
142
|
|
|
143
|
+
internal fun NativeEditorExpoView.setPasteModeImpl(rawPasteMode: String?) {
|
|
144
|
+
richTextView.editorEditText.pasteMode = EditorPasteMode.fromRaw(rawPasteMode)
|
|
145
|
+
}
|
|
146
|
+
|
|
143
147
|
internal fun NativeEditorExpoView.setAccessibilityLabelImpl(label: String?) {
|
|
144
148
|
richTextView.editorEditText.contentDescription = label
|
|
145
149
|
}
|
|
@@ -520,6 +520,9 @@ class NativeEditorModule : Module() {
|
|
|
520
520
|
Prop("editable") { view: NativeEditorExpoView, editable: Boolean ->
|
|
521
521
|
view.setEditable(editable)
|
|
522
522
|
}
|
|
523
|
+
Prop("pasteMode") { view: NativeEditorExpoView, pasteMode: String? ->
|
|
524
|
+
view.setPasteMode(pasteMode)
|
|
525
|
+
}
|
|
523
526
|
Prop("accessibilityLabel") { view: NativeEditorExpoView, label: String? ->
|
|
524
527
|
view.setAccessibilityLabel(label)
|
|
525
528
|
}
|
|
@@ -74,6 +74,7 @@ internal class BlockImageSpan(
|
|
|
74
74
|
|
|
75
75
|
@Volatile
|
|
76
76
|
private var lastDrawRect: RectF? = null
|
|
77
|
+
private var temporarySizePx: Pair<Int, Int>? = null
|
|
77
78
|
|
|
78
79
|
init {
|
|
79
80
|
if (preparedSource != null) {
|
|
@@ -228,9 +229,6 @@ internal class BlockImageSpan(
|
|
|
228
229
|
paint.color = Color.argb(24, 0, 0, 0)
|
|
229
230
|
paint.style = Paint.Style.FILL
|
|
230
231
|
canvas.drawRoundRect(rect, 16f * density, 16f * density, paint)
|
|
231
|
-
paint.color = Color.argb(120, 0, 0, 0)
|
|
232
|
-
val iconRadius = minOf(rect.width(), rect.height()) * 0.12f
|
|
233
|
-
canvas.drawCircle(rect.centerX(), rect.centerY(), iconRadius, paint)
|
|
234
232
|
paint.color = previousColor
|
|
235
233
|
paint.style = previousStyle
|
|
236
234
|
}
|
|
@@ -247,6 +245,7 @@ internal class BlockImageSpan(
|
|
|
247
245
|
}
|
|
248
246
|
|
|
249
247
|
internal fun currentSizePx(): Pair<Int, Int> {
|
|
248
|
+
temporarySizePx?.let { return it }
|
|
250
249
|
val maxWidth = resolvedMaxWidth()
|
|
251
250
|
val loadedBitmap = bitmapLease.get()?.bitmap
|
|
252
251
|
val fallbackAspectRatio = if (loadedBitmap != null && loadedBitmap.width > 0 &&
|
|
@@ -299,6 +298,19 @@ internal class BlockImageSpan(
|
|
|
299
298
|
|
|
300
299
|
internal fun currentDrawRect(): RectF? = lastDrawRect?.let(::RectF)
|
|
301
300
|
|
|
301
|
+
internal fun setTemporarySizePx(widthPx: Float, heightPx: Float): Boolean {
|
|
302
|
+
val next = checkedPositiveInt(widthPx) to checkedPositiveInt(heightPx)
|
|
303
|
+
if (temporarySizePx == next) return false
|
|
304
|
+
temporarySizePx = next
|
|
305
|
+
return true
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
internal fun clearTemporarySize(): Boolean {
|
|
309
|
+
if (temporarySizePx == null) return false
|
|
310
|
+
temporarySizePx = null
|
|
311
|
+
return true
|
|
312
|
+
}
|
|
313
|
+
|
|
302
314
|
private fun resolvedMaxWidth(): Float {
|
|
303
315
|
val host = hostRef.get()
|
|
304
316
|
val hostWidth = host?.let {
|
|
@@ -943,6 +943,20 @@ class RichTextEditorView @JvmOverloads constructor(
|
|
|
943
943
|
editorEditText.resizeImageAtDocPos(docPos, clampedWidth, clampedHeight)
|
|
944
944
|
}
|
|
945
945
|
|
|
946
|
+
internal fun selectedImageSpanForResize(): BlockImageSpan? =
|
|
947
|
+
editorEditText.selectedImageSpanForResize()
|
|
948
|
+
|
|
949
|
+
internal fun previewImageResize(span: BlockImageSpan, widthPx: Float, heightPx: Float): Boolean {
|
|
950
|
+
if (!span.setTemporarySizePx(widthPx, heightPx)) return false
|
|
951
|
+
editorEditText.relayoutImageResizePreview(span)
|
|
952
|
+
return true
|
|
953
|
+
}
|
|
954
|
+
|
|
955
|
+
internal fun restoreImageResizePreview(span: BlockImageSpan) {
|
|
956
|
+
if (!span.clearTemporarySize()) return
|
|
957
|
+
editorEditText.relayoutImageResizePreview(span)
|
|
958
|
+
}
|
|
959
|
+
|
|
946
960
|
private fun refreshOverlays() {
|
|
947
961
|
layoutAtomHostViews()
|
|
948
962
|
remoteSelectionOverlayView.refreshGeometry()
|
|
@@ -20,6 +20,7 @@ import uniffi.editor_core.editorV2CollaborationSocketOpen
|
|
|
20
20
|
import uniffi.editor_core.editorV2Create
|
|
21
21
|
import uniffi.editor_core.editorV2Destroy
|
|
22
22
|
import uniffi.editor_core.editorV2DocToScalar
|
|
23
|
+
import uniffi.editor_core.editorV2GetClipboard
|
|
23
24
|
import uniffi.editor_core.editorV2GetContentSnapshot
|
|
24
25
|
import uniffi.editor_core.editorV2GetDocumentHtml
|
|
25
26
|
import uniffi.editor_core.editorV2GetDocumentJson
|
|
@@ -77,6 +78,9 @@ internal object UniffiEditorV2Backend : EditorV2Backend {
|
|
|
77
78
|
override fun getContentSnapshot(editorId: String): EditorV2CallResult<String> =
|
|
78
79
|
normalize(editorV2GetContentSnapshot(editorId))
|
|
79
80
|
|
|
81
|
+
override fun getClipboard(editorId: String): EditorV2CallResult<String> =
|
|
82
|
+
normalize(editorV2GetClipboard(editorId))
|
|
83
|
+
|
|
80
84
|
override fun applyInput(editorId: String, requestJson: String): EditorV2CallResult<String> =
|
|
81
85
|
normalize(editorV2ApplyInput(editorId, requestJson))
|
|
82
86
|
|
|
@@ -1182,7 +1182,7 @@ internal class StaticLayoutAndroidProseLayoutEngine : AndroidProseLayoutEngine {
|
|
|
1182
1182
|
)
|
|
1183
1183
|
val width =
|
|
1184
1184
|
max(
|
|
1185
|
-
base.sizePx.toInt(),
|
|
1185
|
+
if (inline.nodeType == "mention") 0 else base.sizePx.toInt(),
|
|
1186
1186
|
ceil(
|
|
1187
1187
|
labelPaint.measureText(label) + atomInset.left + atomInset.right
|
|
1188
1188
|
).toInt()
|
|
@@ -91,7 +91,7 @@ export interface EditorHorizontalRuleStyle extends EditorBorderStyle, EditorMarg
|
|
|
91
91
|
backgroundColor?: string;
|
|
92
92
|
height?: number;
|
|
93
93
|
}
|
|
94
|
-
export interface EditorMentionStyle extends EditorInlineStyle, EditorBorderStyle {
|
|
94
|
+
export interface EditorMentionStyle extends EditorInlineStyle, EditorBorderStyle, EditorPaddingStyle {
|
|
95
95
|
}
|
|
96
96
|
export interface EditorStyleMap {
|
|
97
97
|
content: EditorSurfaceStyle;
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
export { type RichTextEditorHeightBehavior, type RichTextEditorToolbarPlacement, type RichTextEditorValueJSONUpdateMode, type RichTextEditorAutoCapitalize, type RichTextEditorKeyboardType, type RichTextEditorAndroidInputOptions, type RemoteSelectionDecoration, type LinkRequestContext, type ImageRequestContext, type RichTextEditorProps, type RichTextEditorRef, type RichTextEditorCaretRect, type NativeRichTextEditorHeightBehavior, type NativeRichTextEditorToolbarPlacement, type NativeRichTextEditorValueJSONUpdateMode, type NativeRichTextEditorAutoCapitalize, type NativeRichTextEditorKeyboardType, type NativeRichTextEditorAndroidInputOptions, type NativeRichTextEditorProps, type NativeRichTextEditorRef, type NativeRichTextEditorCaretRect, } from './RichTextEditorTypes';
|
|
1
|
+
export { type RichTextEditorHeightBehavior, type RichTextEditorToolbarPlacement, type RichTextEditorValueJSONUpdateMode, type RichTextEditorPasteMode, type RichTextEditorAutoCapitalize, type RichTextEditorKeyboardType, type RichTextEditorAndroidInputOptions, type RemoteSelectionDecoration, type LinkRequestContext, type ImageRequestContext, type RichTextEditorProps, type RichTextEditorRef, type RichTextEditorCaretRect, type NativeRichTextEditorHeightBehavior, type NativeRichTextEditorToolbarPlacement, type NativeRichTextEditorValueJSONUpdateMode, type NativeRichTextEditorAutoCapitalize, type NativeRichTextEditorKeyboardType, type NativeRichTextEditorAndroidInputOptions, type NativeRichTextEditorProps, type NativeRichTextEditorRef, type NativeRichTextEditorCaretRect, } from './RichTextEditorTypes';
|
|
2
2
|
export { RichTextEditor, NativeRichTextEditor } from './RichTextEditor';
|
|
3
3
|
export type { NativeRichTextEditorFocusPreservingElement, NativeRichTextEditorFocusPreservingRef, NativeRichTextEditorFocusPreservingRefs, RichTextEditorFocusPreservingElement, RichTextEditorFocusPreservingRef, RichTextEditorFocusPreservingRefs, } from './useFocusPreservingFrames';
|
|
@@ -2,7 +2,7 @@ import { type ExternalTextCompositionManager, type NativeExternalTextComposition
|
|
|
2
2
|
import { type ReactNode } from 'react';
|
|
3
3
|
import { type NativeSyntheticEvent, type StyleProp, type ViewStyle } from 'react-native';
|
|
4
4
|
import { type DocumentJSON, type NativeEditorDocumentHandle } from './NativeEditorBridge';
|
|
5
|
-
import { type RichTextEditorAutoCapitalize, type RichTextEditorKeyboardType, type RichTextEditorToolbarPlacement, type RichTextEditorHeightBehavior } from './RichTextEditorTypes';
|
|
5
|
+
import { type RichTextEditorPasteMode, type RichTextEditorAutoCapitalize, type RichTextEditorKeyboardType, type RichTextEditorToolbarPlacement, type RichTextEditorHeightBehavior } from './RichTextEditorTypes';
|
|
6
6
|
export interface NativeExternalTextCompositionEvent {
|
|
7
7
|
editorId: string;
|
|
8
8
|
resultJson: string;
|
|
@@ -21,6 +21,7 @@ export interface NativeEditorViewProps {
|
|
|
21
21
|
editorId: string;
|
|
22
22
|
placeholder?: string;
|
|
23
23
|
editable: boolean;
|
|
24
|
+
pasteMode: RichTextEditorPasteMode;
|
|
24
25
|
autoFocus: boolean;
|
|
25
26
|
autoCapitalize?: RichTextEditorAutoCapitalize;
|
|
26
27
|
autoCorrect?: boolean;
|
|
@@ -24,6 +24,8 @@ export type RichTextEditorToolbarPlacement = 'keyboard' | 'inline';
|
|
|
24
24
|
* records one undoable step, `'reset'` clears history entirely.
|
|
25
25
|
*/
|
|
26
26
|
export type RichTextEditorValueJSONUpdateMode = 'replace' | 'reset';
|
|
27
|
+
/** Controls native clipboard paste. Plain text keeps destination typing marks. */
|
|
28
|
+
export type RichTextEditorPasteMode = 'rich' | 'plainText' | 'disabled';
|
|
27
29
|
/** Native keyboard auto-capitalization behavior. */
|
|
28
30
|
export type RichTextEditorAutoCapitalize = 'none' | 'sentences' | 'words' | 'characters';
|
|
29
31
|
/** Native keyboard layout. Values not supported by a platform fall back to its default. */
|
|
@@ -104,6 +106,8 @@ export interface RichTextEditorProps {
|
|
|
104
106
|
placeholder?: string;
|
|
105
107
|
/** Whether the editor is editable. Defaults to true. When false, every mutation ref method rejects with MUTATION_REJECTED; selection and controlled content still flow. */
|
|
106
108
|
editable?: boolean;
|
|
109
|
+
/** Clipboard paste policy. Defaults to rich; updates apply immediately. */
|
|
110
|
+
pasteMode?: RichTextEditorPasteMode;
|
|
107
111
|
/** Whether to auto-focus on mount. */
|
|
108
112
|
autoFocus?: boolean;
|
|
109
113
|
/** Controls native keyboard auto-capitalization. Defaults to sentences. */
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { RichTextEditor, type RichTextEditorProps, type RichTextEditorRef, type RichTextEditorCaretRect, type RichTextEditorHeightBehavior, type RichTextEditorToolbarPlacement, type RichTextEditorValueJSONUpdateMode, type RichTextEditorAutoCapitalize, type RichTextEditorKeyboardType, type RichTextEditorAndroidInputOptions, type RichTextEditorFocusPreservingElement, type RichTextEditorFocusPreservingRef, type RichTextEditorFocusPreservingRefs, type RemoteSelectionDecoration, type LinkRequestContext, type ImageRequestContext, NativeRichTextEditor, type NativeRichTextEditorProps, type NativeRichTextEditorRef, type NativeRichTextEditorCaretRect, type NativeRichTextEditorHeightBehavior, type NativeRichTextEditorToolbarPlacement, type NativeRichTextEditorValueJSONUpdateMode, type NativeRichTextEditorAutoCapitalize, type NativeRichTextEditorKeyboardType, type NativeRichTextEditorAndroidInputOptions, type NativeRichTextEditorFocusPreservingElement, type NativeRichTextEditorFocusPreservingRef, type NativeRichTextEditorFocusPreservingRefs, } from './NativeRichTextEditor';
|
|
1
|
+
export { RichTextEditor, type RichTextEditorProps, type RichTextEditorRef, type RichTextEditorCaretRect, type RichTextEditorHeightBehavior, type RichTextEditorToolbarPlacement, type RichTextEditorValueJSONUpdateMode, type RichTextEditorPasteMode, type RichTextEditorAutoCapitalize, type RichTextEditorKeyboardType, type RichTextEditorAndroidInputOptions, type RichTextEditorFocusPreservingElement, type RichTextEditorFocusPreservingRef, type RichTextEditorFocusPreservingRefs, type RemoteSelectionDecoration, type LinkRequestContext, type ImageRequestContext, NativeRichTextEditor, type NativeRichTextEditorProps, type NativeRichTextEditorRef, type NativeRichTextEditorCaretRect, type NativeRichTextEditorHeightBehavior, type NativeRichTextEditorToolbarPlacement, type NativeRichTextEditorValueJSONUpdateMode, type NativeRichTextEditorAutoCapitalize, type NativeRichTextEditorKeyboardType, type NativeRichTextEditorAndroidInputOptions, type NativeRichTextEditorFocusPreservingElement, type NativeRichTextEditorFocusPreservingRef, type NativeRichTextEditorFocusPreservingRefs, } from './NativeRichTextEditor';
|
|
2
2
|
export type { ExternalTextCompositionEndCause, ExternalTextCompositionEndEvent, ExternalTextCompositionOptions, ExternalTextCompositionSession, } from './ExternalTextComposition';
|
|
3
3
|
export { RichTextViewer, type RichTextViewerProps, type RichTextViewerAddons, type RichTextViewerBaseProps, type RichTextViewerMentionsConfig, type RichTextViewerLinkPressEvent, type RichTextViewerMentionPressEvent, type RichTextViewerErrorEvent, type RichTextViewerAtomAttrsUpdateEvent, NativeProseViewer, type NativeProseViewerProps, type NativeProseViewerAddons, type NativeProseViewerBaseProps, type NativeProseViewerMentionsConfig, type NativeProseViewerLinkPressEvent, type NativeProseViewerMentionPressEvent, type NativeProseViewerErrorEvent, type NativeProseViewerAtomAttrsUpdateEvent, } from './NativeProseViewer';
|
|
4
4
|
export { EditorToolbar, DEFAULT_EDITOR_TOOLBAR_ITEMS, type EditorToolbarProps, type EditorToolbarItem, type EditorToolbarLeafItem, type EditorToolbarGroupChildItem, type EditorToolbarGroupItem, type EditorToolbarGroupPresentation, type EditorToolbarIcon, type EditorToolbarButtonStyle, type EditorToolbarDefaultIconId, type EditorToolbarSFSymbolIcon, type EditorToolbarMaterialIcon, type EditorToolbarCommand, type EditorToolbarHeadingLevel, type EditorToolbarListType, type EditorToolbarItemPlacement, } from './EditorToolbar';
|
|
@@ -2,4 +2,4 @@ import { type useRichTextEditorState } from './useRichTextEditorState';
|
|
|
2
2
|
import { type useRichTextEditorMentions } from './useRichTextEditorMentions';
|
|
3
3
|
import { type useRichTextEditorCommands } from './useRichTextEditorCommands';
|
|
4
4
|
import { type useRichTextEditorEvents } from './useRichTextEditorEvents';
|
|
5
|
-
export declare function useRichTextEditorPresentation(context: Pick<ReturnType<typeof useRichTextEditorState>, 'theme' | 'addons' | 'imageLoadingPolicy' | 'androidInputOptions' | 'remoteSelections' | 'atoms' | 'atomState' | 'atomComponents' | 'warnedUnknownAtomTypesRef' | 'atomContentWidth' | 'atomPositions' | 'atomViewport' | 'virtualizeAtoms' | 'nativeAtomViewport' | 'selectedKeys' | 'editable' | 'atomsInteractive' | 'documentHandle' | 'activeState' | 'onRequestLink' | 'onRequestImage' | 'toolbarItemsSerializationCacheRef' | 'toolbarItems' | 'document' | 'toolbarPlacement' | 'showToolbar' | 'containerStyle' | 'style' | 'heightBehavior' | 'autoGrowHeight' | 'pushedUpdate' | 'editorId' | 'registeredToolbarFrames' | 'suppliedFocusPreservingFrames' | 'isFocused' | 'nativeViewRef' | 'refreshFocusPreservingFrames' | 'accessibilityLabel' | 'accessibilityHint' | 'placeholder' | 'autoFocus' | 'autoCapitalize' | 'autoCorrect' | 'keyboardType' | 'allowImageResizing' | 'toolbarFrameOwnerId' | 'onToolbarAction'> & Pick<ReturnType<typeof useRichTextEditorMentions>, 'mentionSuggestionTheme' | 'handleAddonEvent'> & Pick<ReturnType<typeof useRichTextEditorCommands>, 'runAtomAction' | 'updateAtomAttrs' | 'atomOwnerRef' | 'commandToggleMark' | 'commandToggleList' | 'commandToggleHeading' | 'commandToggleBlockquote' | 'commandInsertNode' | 'commandIndentListItem' | 'commandOutdentListItem' | 'openLinkRequest' | 'openImageRequest'> & Pick<ReturnType<typeof useRichTextEditorEvents>, 'handleEditorUpdate' | 'handleEditorError' | 'handleExternalTextCompositionEnd' | 'handleSelectionChange' | 'handleFocusChange' | 'handleContentHeightChange' | 'handleAtomLayout' | 'handleToolbarAction'>): import("react/jsx-runtime").JSX.Element | null;
|
|
5
|
+
export declare function useRichTextEditorPresentation(context: Pick<ReturnType<typeof useRichTextEditorState>, 'theme' | 'addons' | 'imageLoadingPolicy' | 'androidInputOptions' | 'remoteSelections' | 'atoms' | 'atomState' | 'atomComponents' | 'warnedUnknownAtomTypesRef' | 'atomContentWidth' | 'atomPositions' | 'atomViewport' | 'virtualizeAtoms' | 'nativeAtomViewport' | 'selectedKeys' | 'editable' | 'atomsInteractive' | 'documentHandle' | 'activeState' | 'onRequestLink' | 'onRequestImage' | 'toolbarItemsSerializationCacheRef' | 'toolbarItems' | 'document' | 'toolbarPlacement' | 'showToolbar' | 'containerStyle' | 'style' | 'heightBehavior' | 'autoGrowHeight' | 'pushedUpdate' | 'editorId' | 'registeredToolbarFrames' | 'suppliedFocusPreservingFrames' | 'isFocused' | 'nativeViewRef' | 'refreshFocusPreservingFrames' | 'accessibilityLabel' | 'accessibilityHint' | 'placeholder' | 'autoFocus' | 'pasteMode' | 'autoCapitalize' | 'autoCorrect' | 'keyboardType' | 'allowImageResizing' | 'toolbarFrameOwnerId' | 'onToolbarAction'> & Pick<ReturnType<typeof useRichTextEditorMentions>, 'mentionSuggestionTheme' | 'handleAddonEvent'> & Pick<ReturnType<typeof useRichTextEditorCommands>, 'runAtomAction' | 'updateAtomAttrs' | 'atomOwnerRef' | 'commandToggleMark' | 'commandToggleList' | 'commandToggleHeading' | 'commandToggleBlockquote' | 'commandInsertNode' | 'commandIndentListItem' | 'commandOutdentListItem' | 'openLinkRequest' | 'openImageRequest'> & Pick<ReturnType<typeof useRichTextEditorEvents>, 'handleEditorUpdate' | 'handleEditorError' | 'handleExternalTextCompositionEnd' | 'handleSelectionChange' | 'handleFocusChange' | 'handleContentHeightChange' | 'handleAtomLayout' | 'handleToolbarAction'>): import("react/jsx-runtime").JSX.Element | null;
|
|
@@ -17,7 +17,7 @@ const EditorToolbar_1 = require("./EditorToolbar");
|
|
|
17
17
|
const RichTextEditorSerialization_1 = require("./RichTextEditorSerialization");
|
|
18
18
|
const RichTextEditorNativeView_1 = require("./RichTextEditorNativeView");
|
|
19
19
|
function useRichTextEditorPresentation(context) {
|
|
20
|
-
const { theme, mentionSuggestionTheme, addons, imageLoadingPolicy, androidInputOptions, remoteSelections, atoms, atomState, atomComponents, warnedUnknownAtomTypesRef, runAtomAction, updateAtomAttrs, atomOwnerRef, atomContentWidth, atomPositions, atomViewport, virtualizeAtoms, nativeAtomViewport, selectedKeys, editable, atomsInteractive, documentHandle, activeState, onRequestLink, onRequestImage, toolbarItemsSerializationCacheRef, toolbarItems, document, toolbarPlacement, showToolbar, containerStyle, style, heightBehavior, autoGrowHeight, pushedUpdate, editorId, registeredToolbarFrames, suppliedFocusPreservingFrames, isFocused, nativeViewRef, refreshFocusPreservingFrames, accessibilityLabel, accessibilityHint, placeholder, autoFocus, autoCapitalize, autoCorrect, keyboardType, allowImageResizing, handleEditorUpdate, handleEditorError, handleExternalTextCompositionEnd, handleSelectionChange, handleFocusChange, handleContentHeightChange, handleAtomLayout, handleToolbarAction, handleAddonEvent, toolbarFrameOwnerId, commandToggleMark, commandToggleList, commandToggleHeading, commandToggleBlockquote, commandInsertNode, commandIndentListItem, commandOutdentListItem, openLinkRequest, openImageRequest, onToolbarAction, } = context;
|
|
20
|
+
const { theme, mentionSuggestionTheme, addons, imageLoadingPolicy, androidInputOptions, remoteSelections, atoms, atomState, atomComponents, warnedUnknownAtomTypesRef, runAtomAction, updateAtomAttrs, atomOwnerRef, atomContentWidth, atomPositions, atomViewport, virtualizeAtoms, nativeAtomViewport, selectedKeys, editable, atomsInteractive, documentHandle, activeState, onRequestLink, onRequestImage, toolbarItemsSerializationCacheRef, toolbarItems, document, toolbarPlacement, showToolbar, containerStyle, style, heightBehavior, autoGrowHeight, pushedUpdate, editorId, registeredToolbarFrames, suppliedFocusPreservingFrames, isFocused, nativeViewRef, refreshFocusPreservingFrames, accessibilityLabel, accessibilityHint, placeholder, autoFocus, pasteMode, autoCapitalize, autoCorrect, keyboardType, allowImageResizing, handleEditorUpdate, handleEditorError, handleExternalTextCompositionEnd, handleSelectionChange, handleFocusChange, handleContentHeightChange, handleAtomLayout, handleToolbarAction, handleAddonEvent, toolbarFrameOwnerId, commandToggleMark, commandToggleList, commandToggleHeading, commandToggleBlockquote, commandInsertNode, commandIndentListItem, commandOutdentListItem, openLinkRequest, openImageRequest, onToolbarAction, } = context;
|
|
21
21
|
const themeJson = (0, react_1.useMemo)(() => (0, EditorTheme_1.serializeEditorTheme)(theme, mentionSuggestionTheme), [mentionSuggestionTheme, theme]);
|
|
22
22
|
const addonsJson = (0, RichTextEditorSerialization_1.useSerializedValue)(addons, value => (0, addons_1.serializeNormalizedEditorAddons)(value));
|
|
23
23
|
const imageLoadingPolicyJson = (0, RichTextEditorSerialization_1.useSerializedValue)(imageLoadingPolicy, value => (0, ImageLoadingPolicy_1.serializeEditorImageLoadingPolicy)(value));
|
|
@@ -161,7 +161,7 @@ function useRichTextEditorPresentation(context) {
|
|
|
161
161
|
const currentPushedUpdate = pushedUpdate?.editorId === editorId ? pushedUpdate : null;
|
|
162
162
|
const focusPreservingFrames = [...registeredToolbarFrames, ...suppliedFocusPreservingFrames];
|
|
163
163
|
const toolbarFrameJson = (0, RichTextEditorSerialization_1.serializeToolbarFrames)(editable && isFocused ? focusPreservingFrames : undefined);
|
|
164
|
-
return ((0, jsx_runtime_1.jsxs)(react_native_1.View, { style: [RichTextEditorNativeView_1.styles.container, containerStyle], children: [(0, jsx_runtime_1.jsx)(RichTextEditorNativeView_1.NativeEditorView, { ref: nativeViewRef, style: nativeViewStyle, onLayout: refreshFocusPreservingFrames, accessibilityLabel: accessibilityLabel, accessibilityHint: accessibilityHint, editorId: editorId, placeholder: placeholder, editable: editable, autoFocus: autoFocus, autoCapitalize: autoCapitalize, autoCorrect: autoCorrect, keyboardType: keyboardType, ...(react_native_1.Platform.OS === 'android' ? { androidInputOptionsJson } : {}), showToolbar: showToolbar, toolbarPlacement: toolbarPlacement, heightBehavior: heightBehavior, allowImageResizing: allowImageResizing, imageLoadingPolicyJson: imageLoadingPolicyJson, themeJson: themeJson, addonsJson: addonsJson, atomsJson: atomsJson, toolbarItemsJson: toolbarItemsJson, toolbarFrameJson: toolbarFrameJson, remoteSelectionsJson: remoteSelectionsJson, editorUpdateJson: currentPushedUpdate?.json, editorUpdateResetJson: currentPushedUpdate?.resetJson, editorUpdateEditorId: currentPushedUpdate?.editorId, editorUpdateRevision: currentPushedUpdate?.revision ?? 0, onEditorUpdate: handleEditorUpdate, onEditorError: handleEditorError, onExternalTextCompositionEnd: handleExternalTextCompositionEnd, onSelectionChange: handleSelectionChange, onFocusChange: handleFocusChange, onContentHeightChange: handleContentHeightChange, onAtomLayout: handleAtomLayout, onToolbarAction: handleToolbarAction, onAddonEvent: handleAddonEvent, children: atomChildren }), shouldRenderJsToolbar ? ((0, jsx_runtime_1.jsx)(react_native_1.View, { testID: 'native-editor-js-toolbar', style: [RichTextEditorNativeView_1.styles.inlineToolbar, { marginTop: inlineToolbarMarginTop }], children: (0, jsx_runtime_1.jsx)(EditorToolbar_1.EditorToolbarFrameOwnerProvider, { ownerId: toolbarFrameOwnerId, children: (0, jsx_runtime_1.jsx)(EditorToolbar_1.EditorToolbar, { activeState: activeState, historyState: document.historyState, toolbarItems: toolbarItems, theme: theme?.toolbar, showTopBorder: theme?.toolbar?.showTopBorder ?? false, preserveEditorFocus: false, onToggleMark: commandToggleMark, onToggleListType: (listType) => commandToggleList(listType), onToggleHeading: commandToggleHeading, onToggleBlockquote: commandToggleBlockquote, onInsertNodeType: commandInsertNode, onRunCommand: (command) => {
|
|
164
|
+
return ((0, jsx_runtime_1.jsxs)(react_native_1.View, { style: [RichTextEditorNativeView_1.styles.container, containerStyle], children: [(0, jsx_runtime_1.jsx)(RichTextEditorNativeView_1.NativeEditorView, { ref: nativeViewRef, style: nativeViewStyle, onLayout: refreshFocusPreservingFrames, accessibilityLabel: accessibilityLabel, accessibilityHint: accessibilityHint, editorId: editorId, placeholder: placeholder, editable: editable, autoFocus: autoFocus, pasteMode: pasteMode, autoCapitalize: autoCapitalize, autoCorrect: autoCorrect, keyboardType: keyboardType, ...(react_native_1.Platform.OS === 'android' ? { androidInputOptionsJson } : {}), showToolbar: showToolbar, toolbarPlacement: toolbarPlacement, heightBehavior: heightBehavior, allowImageResizing: allowImageResizing, imageLoadingPolicyJson: imageLoadingPolicyJson, themeJson: themeJson, addonsJson: addonsJson, atomsJson: atomsJson, toolbarItemsJson: toolbarItemsJson, toolbarFrameJson: toolbarFrameJson, remoteSelectionsJson: remoteSelectionsJson, editorUpdateJson: currentPushedUpdate?.json, editorUpdateResetJson: currentPushedUpdate?.resetJson, editorUpdateEditorId: currentPushedUpdate?.editorId, editorUpdateRevision: currentPushedUpdate?.revision ?? 0, onEditorUpdate: handleEditorUpdate, onEditorError: handleEditorError, onExternalTextCompositionEnd: handleExternalTextCompositionEnd, onSelectionChange: handleSelectionChange, onFocusChange: handleFocusChange, onContentHeightChange: handleContentHeightChange, onAtomLayout: handleAtomLayout, onToolbarAction: handleToolbarAction, onAddonEvent: handleAddonEvent, children: atomChildren }), shouldRenderJsToolbar ? ((0, jsx_runtime_1.jsx)(react_native_1.View, { testID: 'native-editor-js-toolbar', style: [RichTextEditorNativeView_1.styles.inlineToolbar, { marginTop: inlineToolbarMarginTop }], children: (0, jsx_runtime_1.jsx)(EditorToolbar_1.EditorToolbarFrameOwnerProvider, { ownerId: toolbarFrameOwnerId, children: (0, jsx_runtime_1.jsx)(EditorToolbar_1.EditorToolbar, { activeState: activeState, historyState: document.historyState, toolbarItems: toolbarItems, theme: theme?.toolbar, showTopBorder: theme?.toolbar?.showTopBorder ?? false, preserveEditorFocus: false, onToggleMark: commandToggleMark, onToggleListType: (listType) => commandToggleList(listType), onToggleHeading: commandToggleHeading, onToggleBlockquote: commandToggleBlockquote, onInsertNodeType: commandInsertNode, onRunCommand: (command) => {
|
|
165
165
|
switch (command) {
|
|
166
166
|
case 'indentList':
|
|
167
167
|
commandIndentListItem();
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { StyleProp, ViewStyle } from 'react-native';
|
|
1
2
|
import { type EditorToolbarItem } from './EditorToolbar';
|
|
2
3
|
import type React from 'react';
|
|
3
4
|
import { type ReadonlyActiveState, type Selection } from './NativeEditorBridge';
|
|
@@ -8,7 +9,7 @@ import { type AtomViewport } from './AtomHost';
|
|
|
8
9
|
import { type RichTextEditorProps, type RichTextEditorRef } from './RichTextEditorTypes';
|
|
9
10
|
import { type AtomRenderState } from './RichTextEditorSerialization';
|
|
10
11
|
import { type NativeEditorViewHandle, type NativeEditorErrorBinding, type NativeAtomPosition } from './RichTextEditorNativeTypes';
|
|
11
|
-
export declare function useRichTextEditorState({ documentHandle, documentRevision, value, valueJSON, valueJSONRevision, valueJSONUpdateMode, placeholder, editable, autoFocus, autoCapitalize, autoCorrect, keyboardType, androidInputOptions, heightBehavior, showToolbar, toolbarPlacement, toolbarItems, onToolbarAction, onRequestLink, onRequestImage, imageLoadingPolicy, accessibilityLabel, accessibilityHint, style, containerStyle, theme, addons: addonDescriptors, atoms, atomsInteractive, virtualizeAtoms, atomViewport, remoteSelections, allowImageResizing, onContentChange, onContentChangeJSON, onSelectionChange, onActiveStateChange, onHistoryStateChange, onFocus, onBlur, focusPreservingRefs, onLocalCommit, }: RichTextEditorProps, ref: React.ForwardedRef<RichTextEditorRef>): {
|
|
12
|
+
export declare function useRichTextEditorState({ documentHandle, documentRevision, value, valueJSON, valueJSONRevision, valueJSONUpdateMode, placeholder, editable, pasteMode, autoFocus, autoCapitalize, autoCorrect, keyboardType, androidInputOptions, heightBehavior, showToolbar, toolbarPlacement, toolbarItems, onToolbarAction, onRequestLink, onRequestImage, imageLoadingPolicy, accessibilityLabel, accessibilityHint, style, containerStyle, theme, addons: addonDescriptors, atoms, atomsInteractive, virtualizeAtoms, atomViewport, remoteSelections, allowImageResizing, onContentChange, onContentChangeJSON, onSelectionChange, onActiveStateChange, onHistoryStateChange, onFocus, onBlur, focusPreservingRefs, onLocalCommit, }: RichTextEditorProps, ref: React.ForwardedRef<RichTextEditorRef>): {
|
|
12
13
|
atomStateRef: React.RefObject<AtomRenderState>;
|
|
13
14
|
setSelectedKeys: React.Dispatch<React.SetStateAction<ReadonlySet<string>>>;
|
|
14
15
|
bridge: import("./NativeEditorDocumentBridge").NativeEditorDocumentBridge;
|
|
@@ -156,8 +157,8 @@ export declare function useRichTextEditorState({ documentHandle, documentRevisio
|
|
|
156
157
|
toolbarItems: readonly EditorToolbarItem[];
|
|
157
158
|
toolbarPlacement: import("./RichTextEditorTypes").RichTextEditorToolbarPlacement;
|
|
158
159
|
showToolbar: boolean;
|
|
159
|
-
containerStyle:
|
|
160
|
-
style:
|
|
160
|
+
containerStyle: StyleProp<ViewStyle>;
|
|
161
|
+
style: StyleProp<ViewStyle>;
|
|
161
162
|
autoGrowHeight: number | null;
|
|
162
163
|
pushedUpdate: {
|
|
163
164
|
json: string;
|
|
@@ -172,6 +173,7 @@ export declare function useRichTextEditorState({ documentHandle, documentRevisio
|
|
|
172
173
|
accessibilityHint: string | undefined;
|
|
173
174
|
placeholder: string | undefined;
|
|
174
175
|
autoFocus: boolean;
|
|
176
|
+
pasteMode: import("./RichTextEditorTypes").RichTextEditorPasteMode;
|
|
175
177
|
autoCapitalize: import("./RichTextEditorTypes").RichTextEditorAutoCapitalize | undefined;
|
|
176
178
|
autoCorrect: boolean | undefined;
|
|
177
179
|
keyboardType: import("./RichTextEditorTypes").RichTextEditorKeyboardType | undefined;
|
|
@@ -10,7 +10,7 @@ const useNativeEditor_1 = require("./useNativeEditor");
|
|
|
10
10
|
const addons_1 = require("./addons");
|
|
11
11
|
const useFocusPreservingFrames_1 = require("./useFocusPreservingFrames");
|
|
12
12
|
const RichTextEditorSerialization_1 = require("./RichTextEditorSerialization");
|
|
13
|
-
function useRichTextEditorState({ documentHandle, documentRevision, value, valueJSON, valueJSONRevision, valueJSONUpdateMode = 'replace', placeholder, editable = true, autoFocus = false, autoCapitalize, autoCorrect, keyboardType, androidInputOptions, heightBehavior = 'autoGrow', showToolbar = true, toolbarPlacement = 'keyboard', toolbarItems = EditorToolbar_1.DEFAULT_EDITOR_TOOLBAR_ITEMS, onToolbarAction, onRequestLink, onRequestImage, imageLoadingPolicy, accessibilityLabel, accessibilityHint, style, containerStyle, theme, addons: addonDescriptors, atoms, atomsInteractive = true, virtualizeAtoms = false, atomViewport, remoteSelections, allowImageResizing = true, onContentChange, onContentChangeJSON, onSelectionChange, onActiveStateChange, onHistoryStateChange, onFocus, onBlur, focusPreservingRefs, onLocalCommit, }, ref) {
|
|
13
|
+
function useRichTextEditorState({ documentHandle, documentRevision, value, valueJSON, valueJSONRevision, valueJSONUpdateMode = 'replace', placeholder, editable = true, pasteMode = 'rich', autoFocus = false, autoCapitalize, autoCorrect, keyboardType, androidInputOptions, heightBehavior = 'autoGrow', showToolbar = true, toolbarPlacement = 'keyboard', toolbarItems = EditorToolbar_1.DEFAULT_EDITOR_TOOLBAR_ITEMS, onToolbarAction, onRequestLink, onRequestImage, imageLoadingPolicy, accessibilityLabel, accessibilityHint, style, containerStyle, theme, addons: addonDescriptors, atoms, atomsInteractive = true, virtualizeAtoms = false, atomViewport, remoteSelections, allowImageResizing = true, onContentChange, onContentChangeJSON, onSelectionChange, onActiveStateChange, onHistoryStateChange, onFocus, onBlur, focusPreservingRefs, onLocalCommit, }, ref) {
|
|
14
14
|
const addons = (0, react_1.useMemo)(() => (0, addons_1.normalizeEditorAddons)(addonDescriptors), [addonDescriptors]);
|
|
15
15
|
(0, NativeEditorBridge_1._assertNativeEditorDocumentHandle)(documentHandle);
|
|
16
16
|
const documentDescriptor = (0, NativeEditorBridge_1._getNativeEditorDocumentHandleDescriptor)(documentHandle);
|
|
@@ -390,8 +390,8 @@ function useRichTextEditorState({ documentHandle, documentRevision, value, value
|
|
|
390
390
|
toolbarItems,
|
|
391
391
|
toolbarPlacement,
|
|
392
392
|
showToolbar,
|
|
393
|
-
containerStyle,
|
|
394
|
-
style,
|
|
393
|
+
containerStyle: containerStyle,
|
|
394
|
+
style: style,
|
|
395
395
|
autoGrowHeight,
|
|
396
396
|
pushedUpdate,
|
|
397
397
|
registeredToolbarFrames,
|
|
@@ -401,6 +401,7 @@ function useRichTextEditorState({ documentHandle, documentRevision, value, value
|
|
|
401
401
|
accessibilityHint,
|
|
402
402
|
placeholder,
|
|
403
403
|
autoFocus,
|
|
404
|
+
pasteMode,
|
|
404
405
|
autoCapitalize,
|
|
405
406
|
autoCorrect,
|
|
406
407
|
keyboardType,
|
|
Binary file
|
|
Binary file
|