@apollohg/react-native-prose-editor 0.5.2 → 0.5.4
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/android/src/main/java/com/apollohg/editor/EditorEditText.kt +33 -1
- package/android/src/main/java/com/apollohg/editor/EditorTheme.kt +6 -0
- package/android/src/main/java/com/apollohg/editor/NativeEditorModule.kt +20 -1
- package/android/src/main/java/com/apollohg/editor/NativeProseViewerExpoView.kt +148 -12
- package/android/src/main/java/com/apollohg/editor/RenderBridge.kt +35 -3
- package/dist/EditorTheme.d.ts +3 -0
- package/dist/EditorToolbar.js +11 -6
- package/dist/NativeProseViewer.d.ts +19 -3
- package/dist/NativeProseViewer.js +193 -13
- package/dist/NativeRichTextEditor.js +189 -30
- package/dist/index.d.ts +1 -1
- 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/ios/EditorTheme.swift +6 -0
- package/ios/NativeEditorModule.swift +18 -1
- package/ios/NativeProseViewerExpoView.swift +152 -17
- package/ios/RenderBridge.swift +13 -2
- 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_64/libeditor_core.so +0 -0
|
@@ -8,32 +8,32 @@
|
|
|
8
8
|
<key>BinaryPath</key>
|
|
9
9
|
<string>libeditor_core.a</string>
|
|
10
10
|
<key>LibraryIdentifier</key>
|
|
11
|
-
<string>ios-
|
|
11
|
+
<string>ios-arm64_x86_64-simulator</string>
|
|
12
12
|
<key>LibraryPath</key>
|
|
13
13
|
<string>libeditor_core.a</string>
|
|
14
14
|
<key>SupportedArchitectures</key>
|
|
15
15
|
<array>
|
|
16
16
|
<string>arm64</string>
|
|
17
|
+
<string>x86_64</string>
|
|
17
18
|
</array>
|
|
18
19
|
<key>SupportedPlatform</key>
|
|
19
20
|
<string>ios</string>
|
|
21
|
+
<key>SupportedPlatformVariant</key>
|
|
22
|
+
<string>simulator</string>
|
|
20
23
|
</dict>
|
|
21
24
|
<dict>
|
|
22
25
|
<key>BinaryPath</key>
|
|
23
26
|
<string>libeditor_core.a</string>
|
|
24
27
|
<key>LibraryIdentifier</key>
|
|
25
|
-
<string>ios-
|
|
28
|
+
<string>ios-arm64</string>
|
|
26
29
|
<key>LibraryPath</key>
|
|
27
30
|
<string>libeditor_core.a</string>
|
|
28
31
|
<key>SupportedArchitectures</key>
|
|
29
32
|
<array>
|
|
30
33
|
<string>arm64</string>
|
|
31
|
-
<string>x86_64</string>
|
|
32
34
|
</array>
|
|
33
35
|
<key>SupportedPlatform</key>
|
|
34
36
|
<string>ios</string>
|
|
35
|
-
<key>SupportedPlatformVariant</key>
|
|
36
|
-
<string>simulator</string>
|
|
37
37
|
</dict>
|
|
38
38
|
</array>
|
|
39
39
|
<key>CFBundlePackageType</key>
|
|
Binary file
|
|
Binary file
|
package/ios/EditorTheme.swift
CHANGED
|
@@ -80,12 +80,14 @@ struct EditorTextStyle {
|
|
|
80
80
|
|
|
81
81
|
struct EditorListTheme {
|
|
82
82
|
var indent: CGFloat?
|
|
83
|
+
var baseIndentMultiplier: CGFloat?
|
|
83
84
|
var itemSpacing: CGFloat?
|
|
84
85
|
var markerColor: UIColor?
|
|
85
86
|
var markerScale: CGFloat?
|
|
86
87
|
|
|
87
88
|
init(dictionary: [String: Any]) {
|
|
88
89
|
indent = EditorTheme.cgFloat(dictionary["indent"])
|
|
90
|
+
baseIndentMultiplier = EditorTheme.cgFloat(dictionary["baseIndentMultiplier"])
|
|
89
91
|
itemSpacing = EditorTheme.cgFloat(dictionary["itemSpacing"])
|
|
90
92
|
markerColor = EditorTheme.color(from: dictionary["markerColor"])
|
|
91
93
|
markerScale = EditorTheme.cgFloat(dictionary["markerScale"])
|
|
@@ -194,6 +196,8 @@ struct EditorToolbarTheme {
|
|
|
194
196
|
var borderColor: UIColor?
|
|
195
197
|
var borderWidth: CGFloat?
|
|
196
198
|
var borderRadius: CGFloat?
|
|
199
|
+
var marginTop: CGFloat?
|
|
200
|
+
var showTopBorder: Bool?
|
|
197
201
|
var keyboardOffset: CGFloat?
|
|
198
202
|
var horizontalInset: CGFloat?
|
|
199
203
|
var separatorColor: UIColor?
|
|
@@ -209,6 +213,8 @@ struct EditorToolbarTheme {
|
|
|
209
213
|
borderColor = EditorTheme.color(from: dictionary["borderColor"])
|
|
210
214
|
borderWidth = EditorTheme.cgFloat(dictionary["borderWidth"])
|
|
211
215
|
borderRadius = EditorTheme.cgFloat(dictionary["borderRadius"])
|
|
216
|
+
marginTop = EditorTheme.cgFloat(dictionary["marginTop"])
|
|
217
|
+
showTopBorder = dictionary["showTopBorder"] as? Bool
|
|
212
218
|
keyboardOffset = EditorTheme.cgFloat(dictionary["keyboardOffset"])
|
|
213
219
|
horizontalInset = EditorTheme.cgFloat(dictionary["horizontalInset"])
|
|
214
220
|
separatorColor = EditorTheme.color(from: dictionary["separatorColor"])
|
|
@@ -268,6 +268,13 @@ public class NativeEditorModule: Module {
|
|
|
268
268
|
}
|
|
269
269
|
return editorSetJson(id: editorId, json: json)
|
|
270
270
|
}
|
|
271
|
+
Function("renderDocumentHtml") { (configJson: String, html: String) -> String in
|
|
272
|
+
let editorId = editorCreate(configJson: configJson)
|
|
273
|
+
defer {
|
|
274
|
+
editorDestroy(id: editorId)
|
|
275
|
+
}
|
|
276
|
+
return editorSetHtml(id: editorId, html: html)
|
|
277
|
+
}
|
|
271
278
|
Function("editorReplaceHtml") { (id: Int, html: String) -> String in
|
|
272
279
|
editorReplaceHtml(id: UInt64(id), html: html)
|
|
273
280
|
}
|
|
@@ -375,7 +382,7 @@ public class NativeEditorModule: Module {
|
|
|
375
382
|
|
|
376
383
|
View(NativeProseViewerExpoView.self) {
|
|
377
384
|
ViewName("NativeProseViewer")
|
|
378
|
-
Events("onContentHeightChange", "onPressMention")
|
|
385
|
+
Events("onContentHeightChange", "onPressLink", "onPressMention")
|
|
379
386
|
|
|
380
387
|
Prop("renderJson") { (view: NativeProseViewerExpoView, renderJson: String?) in
|
|
381
388
|
view.setRenderJson(renderJson)
|
|
@@ -383,6 +390,16 @@ public class NativeEditorModule: Module {
|
|
|
383
390
|
Prop("themeJson") { (view: NativeProseViewerExpoView, themeJson: String?) in
|
|
384
391
|
view.setThemeJson(themeJson)
|
|
385
392
|
}
|
|
393
|
+
Prop("collapsesWhenEmpty") {
|
|
394
|
+
(view: NativeProseViewerExpoView, collapsesWhenEmpty: Bool?) in
|
|
395
|
+
view.setCollapsesWhenEmpty(collapsesWhenEmpty)
|
|
396
|
+
}
|
|
397
|
+
Prop("enableLinkTaps") { (view: NativeProseViewerExpoView, enableLinkTaps: Bool?) in
|
|
398
|
+
view.setEnableLinkTaps(enableLinkTaps)
|
|
399
|
+
}
|
|
400
|
+
Prop("interceptLinkTaps") { (view: NativeProseViewerExpoView, interceptLinkTaps: Bool?) in
|
|
401
|
+
view.setInterceptLinkTaps(interceptLinkTaps)
|
|
402
|
+
}
|
|
386
403
|
}
|
|
387
404
|
}
|
|
388
405
|
}
|
|
@@ -3,6 +3,7 @@ import UIKit
|
|
|
3
3
|
|
|
4
4
|
final class NativeProseViewerExpoView: ExpoView {
|
|
5
5
|
let onContentHeightChange = EventDispatcher()
|
|
6
|
+
let onPressLink = EventDispatcher()
|
|
6
7
|
let onPressMention = EventDispatcher()
|
|
7
8
|
|
|
8
9
|
private let textView = EditorTextView(frame: .zero, textContainer: nil)
|
|
@@ -11,11 +12,15 @@ final class NativeProseViewerExpoView: ExpoView {
|
|
|
11
12
|
private var lastEmittedContentHeight: CGFloat = 0
|
|
12
13
|
private var lastMeasuredWidth: CGFloat = 0
|
|
13
14
|
private var allowContentHeightShrink = true
|
|
15
|
+
private var collapsesWhenEmpty = true
|
|
16
|
+
private var isCollapsedEmptyContent = false
|
|
17
|
+
private var enableLinkTaps = true
|
|
18
|
+
private var interceptLinkTaps = false
|
|
14
19
|
|
|
15
|
-
private lazy var
|
|
20
|
+
private lazy var interactiveTapRecognizer: UITapGestureRecognizer = {
|
|
16
21
|
let recognizer = UITapGestureRecognizer(
|
|
17
22
|
target: self,
|
|
18
|
-
action: #selector(
|
|
23
|
+
action: #selector(handleInteractiveTap(_:))
|
|
19
24
|
)
|
|
20
25
|
recognizer.cancelsTouchesInView = false
|
|
21
26
|
return recognizer
|
|
@@ -36,10 +41,28 @@ final class NativeProseViewerExpoView: ExpoView {
|
|
|
36
41
|
textView.onHeightMayChange = { [weak self] measuredHeight in
|
|
37
42
|
self?.emitContentHeightIfNeeded(measuredHeight: measuredHeight, force: true)
|
|
38
43
|
}
|
|
39
|
-
textView.addGestureRecognizer(
|
|
44
|
+
textView.addGestureRecognizer(interactiveTapRecognizer)
|
|
40
45
|
addSubview(textView)
|
|
41
46
|
}
|
|
42
47
|
|
|
48
|
+
func setEnableLinkTaps(_ enabled: Bool?) {
|
|
49
|
+
enableLinkTaps = enabled ?? true
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
func setInterceptLinkTaps(_ intercept: Bool?) {
|
|
53
|
+
interceptLinkTaps = intercept ?? false
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
func setCollapsesWhenEmpty(_ collapses: Bool?) {
|
|
57
|
+
let nextValue = collapses ?? true
|
|
58
|
+
guard collapsesWhenEmpty != nextValue else { return }
|
|
59
|
+
collapsesWhenEmpty = nextValue
|
|
60
|
+
allowContentHeightShrink = true
|
|
61
|
+
updateCollapsedEmptyState()
|
|
62
|
+
setNeedsLayout()
|
|
63
|
+
emitContentHeightIfNeeded(force: true)
|
|
64
|
+
}
|
|
65
|
+
|
|
43
66
|
func setRenderJson(_ renderJson: String?) {
|
|
44
67
|
guard lastRenderJSON != renderJson else { return }
|
|
45
68
|
lastRenderJSON = renderJson
|
|
@@ -60,6 +83,9 @@ final class NativeProseViewerExpoView: ExpoView {
|
|
|
60
83
|
}
|
|
61
84
|
|
|
62
85
|
override var intrinsicContentSize: CGSize {
|
|
86
|
+
if isCollapsedEmptyContent {
|
|
87
|
+
return CGSize(width: UIView.noIntrinsicMetric, height: 0)
|
|
88
|
+
}
|
|
63
89
|
guard lastEmittedContentHeight > 0 else {
|
|
64
90
|
return CGSize(width: UIView.noIntrinsicMetric, height: UIView.noIntrinsicMetric)
|
|
65
91
|
}
|
|
@@ -68,8 +94,13 @@ final class NativeProseViewerExpoView: ExpoView {
|
|
|
68
94
|
|
|
69
95
|
override func layoutSubviews() {
|
|
70
96
|
super.layoutSubviews()
|
|
71
|
-
|
|
72
|
-
|
|
97
|
+
if isCollapsedEmptyContent {
|
|
98
|
+
textView.frame = CGRect(x: 0, y: 0, width: bounds.width, height: 0)
|
|
99
|
+
textView.updateAutoGrowHostHeight(0)
|
|
100
|
+
} else {
|
|
101
|
+
textView.frame = bounds
|
|
102
|
+
textView.updateAutoGrowHostHeight(bounds.height)
|
|
103
|
+
}
|
|
73
104
|
|
|
74
105
|
let currentWidth = ceil(bounds.width)
|
|
75
106
|
guard abs(currentWidth - lastMeasuredWidth) > 0.5 else { return }
|
|
@@ -78,21 +109,36 @@ final class NativeProseViewerExpoView: ExpoView {
|
|
|
78
109
|
}
|
|
79
110
|
|
|
80
111
|
private func applyRenderJSON() {
|
|
112
|
+
updateCollapsedEmptyState()
|
|
81
113
|
textView.applyRenderJSON(lastRenderJSON ?? "[]")
|
|
114
|
+
textView.isHidden = isCollapsedEmptyContent
|
|
115
|
+
invalidateIntrinsicContentSize()
|
|
116
|
+
setNeedsLayout()
|
|
82
117
|
emitContentHeightIfNeeded(force: true)
|
|
83
118
|
}
|
|
84
119
|
|
|
120
|
+
private func updateCollapsedEmptyState() {
|
|
121
|
+
isCollapsedEmptyContent = collapsesWhenEmpty
|
|
122
|
+
&& Self.renderJsonContainsOnlyEmptyParagraphs(lastRenderJSON ?? "[]")
|
|
123
|
+
textView.isHidden = isCollapsedEmptyContent
|
|
124
|
+
}
|
|
125
|
+
|
|
85
126
|
private func emitContentHeightIfNeeded(
|
|
86
127
|
measuredHeight: CGFloat? = nil,
|
|
87
128
|
force: Bool = false
|
|
88
129
|
) {
|
|
89
|
-
let
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
130
|
+
let contentHeight: CGFloat
|
|
131
|
+
if isCollapsedEmptyContent {
|
|
132
|
+
contentHeight = 0
|
|
133
|
+
} else {
|
|
134
|
+
let resolvedWidth = bounds.width > 0
|
|
135
|
+
? bounds.width
|
|
136
|
+
: (superview?.bounds.width ?? UIScreen.main.bounds.width)
|
|
137
|
+
let fittedHeight = measuredHeight
|
|
138
|
+
?? textView.measuredAutoGrowHeightForTesting(width: resolvedWidth)
|
|
139
|
+
contentHeight = ceil(fittedHeight)
|
|
140
|
+
guard contentHeight > 0 else { return }
|
|
141
|
+
}
|
|
96
142
|
guard allowContentHeightShrink || contentHeight >= lastEmittedContentHeight else { return }
|
|
97
143
|
allowContentHeightShrink = false
|
|
98
144
|
guard force || abs(contentHeight - lastEmittedContentHeight) > 0.5 else { return }
|
|
@@ -101,20 +147,32 @@ final class NativeProseViewerExpoView: ExpoView {
|
|
|
101
147
|
onContentHeightChange(["contentHeight": contentHeight])
|
|
102
148
|
}
|
|
103
149
|
|
|
104
|
-
@objc private func
|
|
105
|
-
guard recognizer.state == .ended
|
|
106
|
-
|
|
107
|
-
|
|
150
|
+
@objc private func handleInteractiveTap(_ recognizer: UITapGestureRecognizer) {
|
|
151
|
+
guard recognizer.state == .ended else {
|
|
152
|
+
return
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
let location = recognizer.location(in: textView)
|
|
156
|
+
if enableLinkTaps, let link = linkHit(at: location) {
|
|
157
|
+
if interceptLinkTaps {
|
|
158
|
+
onPressLink([
|
|
159
|
+
"href": link.href,
|
|
160
|
+
"text": link.text,
|
|
161
|
+
])
|
|
162
|
+
} else {
|
|
163
|
+
openLink(link.href)
|
|
164
|
+
}
|
|
108
165
|
return
|
|
109
166
|
}
|
|
110
167
|
|
|
168
|
+
guard let mention = mentionHit(at: location) else { return }
|
|
111
169
|
onPressMention([
|
|
112
170
|
"docPos": mention.docPos,
|
|
113
171
|
"label": mention.label,
|
|
114
172
|
])
|
|
115
173
|
}
|
|
116
174
|
|
|
117
|
-
private func
|
|
175
|
+
private func characterIndex(at location: CGPoint) -> Int? {
|
|
118
176
|
let textStorage = textView.textStorage
|
|
119
177
|
guard textStorage.length > 0 else { return nil }
|
|
120
178
|
|
|
@@ -133,6 +191,26 @@ final class NativeProseViewerExpoView: ExpoView {
|
|
|
133
191
|
guard glyphIndex < layoutManager.numberOfGlyphs else { return nil }
|
|
134
192
|
let characterIndex = layoutManager.characterIndexForGlyph(at: glyphIndex)
|
|
135
193
|
guard characterIndex < textStorage.length else { return nil }
|
|
194
|
+
return characterIndex
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
private func linkHit(at location: CGPoint) -> (href: String, text: String)? {
|
|
198
|
+
let textStorage = textView.textStorage
|
|
199
|
+
guard let characterIndex = characterIndex(at: location) else { return nil }
|
|
200
|
+
|
|
201
|
+
var effectiveRange = NSRange(location: 0, length: 0)
|
|
202
|
+
let attrs = textStorage.attributes(at: characterIndex, effectiveRange: &effectiveRange)
|
|
203
|
+
guard let href = attrs[RenderBridgeAttributes.linkHref] as? String, !href.isEmpty else {
|
|
204
|
+
return nil
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
let text = (textStorage.string as NSString).substring(with: effectiveRange)
|
|
208
|
+
return (href: href, text: text)
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
private func mentionHit(at location: CGPoint) -> (docPos: Int, label: String)? {
|
|
212
|
+
let textStorage = textView.textStorage
|
|
213
|
+
guard let characterIndex = characterIndex(at: location) else { return nil }
|
|
136
214
|
|
|
137
215
|
var effectiveRange = NSRange(location: 0, length: 0)
|
|
138
216
|
let attrs = textStorage.attributes(at: characterIndex, effectiveRange: &effectiveRange)
|
|
@@ -146,4 +224,61 @@ final class NativeProseViewerExpoView: ExpoView {
|
|
|
146
224
|
let label = (textStorage.string as NSString).substring(with: effectiveRange)
|
|
147
225
|
return (docPos: docPos, label: label)
|
|
148
226
|
}
|
|
227
|
+
|
|
228
|
+
private func openLink(_ href: String) {
|
|
229
|
+
guard let url = URL(string: href) else { return }
|
|
230
|
+
UIApplication.shared.open(url, options: [:], completionHandler: nil)
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
static func renderJsonContainsOnlyEmptyParagraphs(_ renderJson: String) -> Bool {
|
|
234
|
+
guard let data = renderJson.data(using: .utf8),
|
|
235
|
+
let elements = try? JSONSerialization.jsonObject(with: data) as? [[String: Any]]
|
|
236
|
+
else {
|
|
237
|
+
return false
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
if elements.isEmpty {
|
|
241
|
+
return true
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
var hasParagraph = false
|
|
245
|
+
var paragraphIsOpen = false
|
|
246
|
+
|
|
247
|
+
for element in elements {
|
|
248
|
+
guard let type = element["type"] as? String else {
|
|
249
|
+
return false
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
switch type {
|
|
253
|
+
case "blockStart":
|
|
254
|
+
guard !paragraphIsOpen,
|
|
255
|
+
element["nodeType"] as? String == "paragraph",
|
|
256
|
+
(element["depth"] as? NSNumber)?.intValue == 0
|
|
257
|
+
else {
|
|
258
|
+
return false
|
|
259
|
+
}
|
|
260
|
+
paragraphIsOpen = true
|
|
261
|
+
hasParagraph = true
|
|
262
|
+
|
|
263
|
+
case "textRun":
|
|
264
|
+
guard paragraphIsOpen,
|
|
265
|
+
let text = element["text"] as? String,
|
|
266
|
+
text.allSatisfy({ $0 == "\u{200B}" })
|
|
267
|
+
else {
|
|
268
|
+
return false
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
case "blockEnd":
|
|
272
|
+
guard paragraphIsOpen else {
|
|
273
|
+
return false
|
|
274
|
+
}
|
|
275
|
+
paragraphIsOpen = false
|
|
276
|
+
|
|
277
|
+
default:
|
|
278
|
+
return false
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
return hasParagraph && !paragraphIsOpen
|
|
283
|
+
}
|
|
149
284
|
}
|
package/ios/RenderBridge.swift
CHANGED
|
@@ -107,6 +107,9 @@ enum RenderBridgeAttributes {
|
|
|
107
107
|
/// Marks synthetic zero-width placeholders used only for UIKit layout.
|
|
108
108
|
static let syntheticPlaceholder = NSAttributedString.Key("com.apollohg.editor.syntheticPlaceholder")
|
|
109
109
|
|
|
110
|
+
/// Stores the link href for visually styled link text without enabling UITextView's default link interaction.
|
|
111
|
+
static let linkHref = NSAttributedString.Key("com.apollohg.editor.linkHref")
|
|
112
|
+
|
|
110
113
|
/// Stores the owning top-level document child index for partial native patching.
|
|
111
114
|
static let topLevelChildIndex = NSAttributedString.Key("com.apollohg.editor.topLevelChildIndex")
|
|
112
115
|
}
|
|
@@ -564,11 +567,11 @@ final class RenderBridge {
|
|
|
564
567
|
var traits: UIFontDescriptor.SymbolicTraits = []
|
|
565
568
|
var useMonospace = false
|
|
566
569
|
for mark in marks {
|
|
570
|
+
let markObject = mark as? [String: Any]
|
|
567
571
|
let markType: String
|
|
568
572
|
if let markName = mark as? String {
|
|
569
573
|
markType = markName
|
|
570
|
-
} else if let
|
|
571
|
-
let resolvedType = markObject["type"] as? String {
|
|
574
|
+
} else if let resolvedType = markObject?["type"] as? String {
|
|
572
575
|
markType = resolvedType
|
|
573
576
|
} else {
|
|
574
577
|
continue
|
|
@@ -588,6 +591,9 @@ final class RenderBridge {
|
|
|
588
591
|
case "link":
|
|
589
592
|
attrs[.underlineStyle] = NSUnderlineStyle.single.rawValue
|
|
590
593
|
attrs[.foregroundColor] = UIColor.systemBlue
|
|
594
|
+
if let href = markObject?["href"] as? String, !href.isEmpty {
|
|
595
|
+
attrs[RenderBridgeAttributes.linkHref] = href
|
|
596
|
+
}
|
|
591
597
|
default:
|
|
592
598
|
break
|
|
593
599
|
}
|
|
@@ -841,8 +847,13 @@ final class RenderBridge {
|
|
|
841
847
|
(theme?.blockquote?.markerGap ?? LayoutConstants.blockquoteMarkerGap)
|
|
842
848
|
+ (theme?.blockquote?.borderWidth ?? LayoutConstants.blockquoteBorderWidth)
|
|
843
849
|
)
|
|
850
|
+
let listBaseIndentMultiplier = max(theme?.list?.baseIndentMultiplier ?? 1, 0)
|
|
851
|
+
let listBaseIndentAdjustment = context.listContext != nil
|
|
852
|
+
? ((listBaseIndentMultiplier - 1) * indentPerDepth)
|
|
853
|
+
: 0
|
|
844
854
|
let baseIndent = (CGFloat(context.depth) * indentPerDepth)
|
|
845
855
|
- (quoteDepth * indentPerDepth)
|
|
856
|
+
+ listBaseIndentAdjustment
|
|
846
857
|
+ (quoteDepth * quoteIndent)
|
|
847
858
|
|
|
848
859
|
if context.listContext != nil {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@apollohg/react-native-prose-editor",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.4",
|
|
4
4
|
"description": "Native rich text editor with Rust core for React Native",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"homepage": "https://github.com/apollohg/react-native-prose-editor",
|
|
Binary file
|
|
Binary file
|
|
Binary file
|