@openeditor/react-native-prose-editor 0.0.8 → 0.0.9
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.
|
@@ -214,6 +214,7 @@ final class NativeBlockEditorSurface: UIScrollView {
|
|
|
214
214
|
}
|
|
215
215
|
|
|
216
216
|
private let stack = UIStackView()
|
|
217
|
+
private let placeholderLabel = UILabel()
|
|
217
218
|
private var currentEditorId: UInt64 = 0
|
|
218
219
|
private var isApplyingRemoteUpdate = false
|
|
219
220
|
private var currentTheme: EditorTheme?
|
|
@@ -232,6 +233,13 @@ final class NativeBlockEditorSurface: UIScrollView {
|
|
|
232
233
|
private var selectedTextPos: UInt32?
|
|
233
234
|
private let caretView = UIView()
|
|
234
235
|
|
|
236
|
+
var placeholder: String = "" {
|
|
237
|
+
didSet {
|
|
238
|
+
placeholderLabel.text = placeholder
|
|
239
|
+
refreshPlaceholder()
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
|
|
235
243
|
var baseFont: UIFont = .systemFont(ofSize: 16)
|
|
236
244
|
var baseTextColor: UIColor = .label
|
|
237
245
|
var baseBackgroundColor: UIColor = .systemBackground {
|
|
@@ -270,6 +278,11 @@ final class NativeBlockEditorSurface: UIScrollView {
|
|
|
270
278
|
stack.spacing = 8
|
|
271
279
|
stack.alignment = .fill
|
|
272
280
|
addSubview(stack)
|
|
281
|
+
placeholderLabel.numberOfLines = 0
|
|
282
|
+
placeholderLabel.isUserInteractionEnabled = false
|
|
283
|
+
placeholderLabel.isHidden = true
|
|
284
|
+
placeholderLabel.layer.zPosition = 1
|
|
285
|
+
addSubview(placeholderLabel)
|
|
273
286
|
caretView.backgroundColor = .systemBlue
|
|
274
287
|
caretView.isUserInteractionEnabled = false
|
|
275
288
|
caretView.layer.cornerRadius = 1
|
|
@@ -297,6 +310,16 @@ final class NativeBlockEditorSurface: UIScrollView {
|
|
|
297
310
|
).height
|
|
298
311
|
stack.frame.size.height = contentHeight
|
|
299
312
|
stack.layoutIfNeeded()
|
|
313
|
+
placeholderLabel.font = font(for: ["nodeType": "paragraph"])
|
|
314
|
+
placeholderLabel.textColor = currentTheme?.placeholderColor ?? .placeholderText
|
|
315
|
+
placeholderLabel.frame = CGRect(
|
|
316
|
+
x: leftInset,
|
|
317
|
+
y: topInset,
|
|
318
|
+
width: contentWidth,
|
|
319
|
+
height: placeholderLabel.sizeThatFits(
|
|
320
|
+
CGSize(width: contentWidth, height: .greatestFiniteMagnitude)
|
|
321
|
+
).height
|
|
322
|
+
)
|
|
300
323
|
contentSize = CGSize(width: bounds.width, height: stack.frame.maxY + bottomInset)
|
|
301
324
|
refreshCaret()
|
|
302
325
|
onContentHeightMayChange?(contentSize.height)
|
|
@@ -304,13 +327,16 @@ final class NativeBlockEditorSurface: UIScrollView {
|
|
|
304
327
|
|
|
305
328
|
func applyTheme(_ theme: EditorTheme?) {
|
|
306
329
|
currentTheme = theme
|
|
330
|
+
backgroundColor = theme?.backgroundColor ?? baseBackgroundColor
|
|
307
331
|
contentInset = .zero
|
|
308
332
|
verticalScrollIndicatorInsets = .zero
|
|
309
|
-
if let currentRoot {
|
|
310
|
-
rebuildAll(from:
|
|
333
|
+
if let root = currentRoot {
|
|
334
|
+
rebuildAll(from: root)
|
|
335
|
+
currentRoot = root
|
|
311
336
|
refreshTableCellRegistry()
|
|
312
337
|
refreshImageSelection()
|
|
313
338
|
}
|
|
339
|
+
refreshPlaceholder()
|
|
314
340
|
setNeedsLayout()
|
|
315
341
|
}
|
|
316
342
|
|
|
@@ -351,6 +377,7 @@ final class NativeBlockEditorSurface: UIScrollView {
|
|
|
351
377
|
refreshImageSelection()
|
|
352
378
|
refreshCaret()
|
|
353
379
|
currentRoot = root
|
|
380
|
+
refreshPlaceholder()
|
|
354
381
|
isApplyingRemoteUpdate = false
|
|
355
382
|
setNeedsLayout()
|
|
356
383
|
layoutIfNeeded()
|
|
@@ -375,6 +402,22 @@ final class NativeBlockEditorSurface: UIScrollView {
|
|
|
375
402
|
}
|
|
376
403
|
}
|
|
377
404
|
|
|
405
|
+
private func refreshPlaceholder() {
|
|
406
|
+
placeholderLabel.isHidden = placeholder.isEmpty || !isRenderedDocumentEmpty()
|
|
407
|
+
setNeedsLayout()
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
private func isRenderedDocumentEmpty() -> Bool {
|
|
411
|
+
guard let root = currentRoot else { return false }
|
|
412
|
+
let children = root["children"] as? [[String: Any]] ?? []
|
|
413
|
+
guard children.count <= 1 else { return false }
|
|
414
|
+
guard let child = children.first else {
|
|
415
|
+
return textLeafViews.count == 1 && textLeafViews[0].attributedText.length == 0
|
|
416
|
+
}
|
|
417
|
+
guard (child["nodeType"] as? String ?? "paragraph") == "paragraph" else { return false }
|
|
418
|
+
return textLeafViews.count == 1 && textLeafViews[0].attributedText.length == 0
|
|
419
|
+
}
|
|
420
|
+
|
|
378
421
|
/// Applies canonical recursive patches at the smallest native view boundary.
|
|
379
422
|
/// Metadata-only changes mutate bindings in place; node replacements stop at
|
|
380
423
|
/// the nearest rendered owner (normally the edited text block); and root
|
|
@@ -546,6 +589,7 @@ final class NativeBlockEditorSurface: UIScrollView {
|
|
|
546
589
|
view.removeFromSuperview()
|
|
547
590
|
}
|
|
548
591
|
currentRoot = nil
|
|
592
|
+
refreshPlaceholder()
|
|
549
593
|
nodeViews.removeAll()
|
|
550
594
|
tableCells.removeAll()
|
|
551
595
|
imageViews.removeAll()
|
|
@@ -734,6 +778,14 @@ final class NativeBlockEditorSurface: UIScrollView {
|
|
|
734
778
|
stack.arrangedSubviews.count
|
|
735
779
|
}
|
|
736
780
|
|
|
781
|
+
func isPlaceholderVisibleForTesting() -> Bool {
|
|
782
|
+
!placeholderLabel.isHidden
|
|
783
|
+
}
|
|
784
|
+
|
|
785
|
+
func placeholderColorForTesting() -> UIColor? {
|
|
786
|
+
placeholderLabel.textColor
|
|
787
|
+
}
|
|
788
|
+
|
|
737
789
|
func firstTextAttributesForTesting() -> [NSAttributedString.Key: Any]? {
|
|
738
790
|
func find(in view: UIView) -> TextLeafView? {
|
|
739
791
|
if let leaf = view as? TextLeafView, leaf.attributedText.length > 0 {
|
|
@@ -962,7 +1014,7 @@ final class NativeBlockEditorSurface: UIScrollView {
|
|
|
962
1014
|
attributes[.strikethroughStyle] = NSUnderlineStyle.single.rawValue
|
|
963
1015
|
}
|
|
964
1016
|
if markTypes.contains("link") {
|
|
965
|
-
attributes[.foregroundColor] = tintColor
|
|
1017
|
+
attributes[.foregroundColor] = currentTheme?.links?.color ?? tintColor
|
|
966
1018
|
}
|
|
967
1019
|
if markTypes.contains("code") {
|
|
968
1020
|
attributes[.font] = UIFont.monospacedSystemFont(ofSize: baseFont.pointSize, weight: .regular)
|
|
@@ -538,7 +538,7 @@ public class NativeEditorModule: Module {
|
|
|
538
538
|
view.setEditable(editable)
|
|
539
539
|
}
|
|
540
540
|
Prop("placeholder") { (view: NativeEditorExpoView, placeholder: String) in
|
|
541
|
-
view.richTextView.
|
|
541
|
+
view.richTextView.placeholder = placeholder
|
|
542
542
|
}
|
|
543
543
|
Prop("autoFocus") { (view: NativeEditorExpoView, autoFocus: Bool) in
|
|
544
544
|
view.setAutoFocus(autoFocus)
|
|
@@ -5064,6 +5064,13 @@ final class RichTextEditorView: UIView {
|
|
|
5064
5064
|
/// The editor text view that handles input interception.
|
|
5065
5065
|
let textView: EditorTextView
|
|
5066
5066
|
private let blockSurface = NativeBlockEditorSurface()
|
|
5067
|
+
|
|
5068
|
+
var placeholder: String = "" {
|
|
5069
|
+
didSet {
|
|
5070
|
+
textView.placeholder = placeholder
|
|
5071
|
+
blockSurface.placeholder = placeholder
|
|
5072
|
+
}
|
|
5073
|
+
}
|
|
5067
5074
|
private let remoteSelectionOverlayView = RemoteSelectionOverlayView()
|
|
5068
5075
|
private let taskListMarkerTapOverlayView = TaskListMarkerTapOverlayView()
|
|
5069
5076
|
private let imageTapOverlayView = ImageTapOverlayView()
|
|
@@ -5400,6 +5407,18 @@ final class RichTextEditorView: UIView {
|
|
|
5400
5407
|
blockSurface.topLevelViewCountForTesting
|
|
5401
5408
|
}
|
|
5402
5409
|
|
|
5410
|
+
func isBlockSurfacePlaceholderVisibleForTesting() -> Bool {
|
|
5411
|
+
blockSurface.isPlaceholderVisibleForTesting()
|
|
5412
|
+
}
|
|
5413
|
+
|
|
5414
|
+
func blockSurfaceBackgroundColorForTesting() -> UIColor? {
|
|
5415
|
+
blockSurface.backgroundColor
|
|
5416
|
+
}
|
|
5417
|
+
|
|
5418
|
+
func blockSurfacePlaceholderColorForTesting() -> UIColor? {
|
|
5419
|
+
blockSurface.placeholderColorForTesting()
|
|
5420
|
+
}
|
|
5421
|
+
|
|
5403
5422
|
func blockSurfaceFirstTextAttributesForTesting() -> [NSAttributedString.Key: Any]? {
|
|
5404
5423
|
blockSurface.firstTextAttributesForTesting()
|
|
5405
5424
|
}
|
package/package.json
CHANGED