@apollohg/react-native-prose-editor 0.1.0

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.
Files changed (47) hide show
  1. package/LICENSE +160 -0
  2. package/README.md +143 -0
  3. package/android/build.gradle +39 -0
  4. package/android/src/main/assets/editor-icons/MaterialIcons.json +2236 -0
  5. package/android/src/main/assets/editor-icons/MaterialIcons.ttf +0 -0
  6. package/android/src/main/java/com/apollohg/editor/EditorAddons.kt +131 -0
  7. package/android/src/main/java/com/apollohg/editor/EditorEditText.kt +1057 -0
  8. package/android/src/main/java/com/apollohg/editor/EditorHeightBehavior.kt +14 -0
  9. package/android/src/main/java/com/apollohg/editor/EditorInputConnection.kt +191 -0
  10. package/android/src/main/java/com/apollohg/editor/EditorTheme.kt +325 -0
  11. package/android/src/main/java/com/apollohg/editor/NativeEditorExpoView.kt +647 -0
  12. package/android/src/main/java/com/apollohg/editor/NativeEditorModule.kt +257 -0
  13. package/android/src/main/java/com/apollohg/editor/NativeToolbar.kt +714 -0
  14. package/android/src/main/java/com/apollohg/editor/PositionBridge.kt +76 -0
  15. package/android/src/main/java/com/apollohg/editor/RenderBridge.kt +1044 -0
  16. package/android/src/main/java/com/apollohg/editor/RichTextEditorView.kt +211 -0
  17. package/expo-module.config.json +9 -0
  18. package/ios/EditorAddons.swift +228 -0
  19. package/ios/EditorCore.xcframework/Info.plist +44 -0
  20. package/ios/EditorCore.xcframework/ios-arm64/libeditor_core.a +0 -0
  21. package/ios/EditorCore.xcframework/ios-arm64_x86_64-simulator/libeditor_core.a +0 -0
  22. package/ios/EditorLayoutManager.swift +254 -0
  23. package/ios/EditorTheme.swift +372 -0
  24. package/ios/Generated_editor_core.swift +1143 -0
  25. package/ios/NativeEditorExpoView.swift +1417 -0
  26. package/ios/NativeEditorModule.swift +263 -0
  27. package/ios/PositionBridge.swift +278 -0
  28. package/ios/ReactNativeProseEditor.podspec +49 -0
  29. package/ios/RenderBridge.swift +825 -0
  30. package/ios/RichTextEditorView.swift +1559 -0
  31. package/ios/editor_coreFFI/editor_coreFFI.h +1014 -0
  32. package/ios/editor_coreFFI/module.modulemap +7 -0
  33. package/ios/editor_coreFFI.h +904 -0
  34. package/ios/editor_coreFFI.modulemap +7 -0
  35. package/package.json +66 -0
  36. package/rust/android/arm64-v8a/libeditor_core.so +0 -0
  37. package/rust/android/armeabi-v7a/libeditor_core.so +0 -0
  38. package/rust/android/x86_64/libeditor_core.so +0 -0
  39. package/rust/bindings/kotlin/uniffi/editor_core/editor_core.kt +2014 -0
  40. package/src/EditorTheme.ts +130 -0
  41. package/src/EditorToolbar.tsx +620 -0
  42. package/src/NativeEditorBridge.ts +607 -0
  43. package/src/NativeRichTextEditor.tsx +951 -0
  44. package/src/addons.ts +158 -0
  45. package/src/index.ts +63 -0
  46. package/src/schemas.ts +153 -0
  47. package/src/useNativeEditor.ts +173 -0
@@ -0,0 +1,131 @@
1
+ package com.apollohg.editor
2
+
3
+ import org.json.JSONObject
4
+
5
+ data class NativeMentionSuggestion(
6
+ val key: String,
7
+ val title: String,
8
+ val subtitle: String?,
9
+ val label: String,
10
+ val attrs: JSONObject
11
+ ) {
12
+ companion object {
13
+ fun fromJson(json: JSONObject?): NativeMentionSuggestion? {
14
+ json ?: return null
15
+ val key = json.optString("key", "")
16
+ val title = json.optString("title", "")
17
+ val label = json.optString("label", "")
18
+ if (key.isBlank() || title.isBlank() || label.isBlank()) return null
19
+ return NativeMentionSuggestion(
20
+ key = key,
21
+ title = title,
22
+ subtitle = json.takeUnless { it.isNull("subtitle") }?.optString("subtitle"),
23
+ label = label,
24
+ attrs = json.optJSONObject("attrs") ?: JSONObject()
25
+ )
26
+ }
27
+ }
28
+ }
29
+
30
+ data class NativeMentionsAddonConfig(
31
+ val trigger: String,
32
+ val suggestions: List<NativeMentionSuggestion>,
33
+ val theme: EditorMentionTheme?
34
+ ) {
35
+ companion object {
36
+ fun fromJson(json: JSONObject?): NativeMentionsAddonConfig? {
37
+ json ?: return null
38
+ val trigger = json.optString("trigger", "@").ifBlank { "@" }
39
+ val rawSuggestions = json.optJSONArray("suggestions")
40
+ val suggestions = mutableListOf<NativeMentionSuggestion>()
41
+ if (rawSuggestions != null) {
42
+ for (index in 0 until rawSuggestions.length()) {
43
+ val suggestion = NativeMentionSuggestion.fromJson(
44
+ rawSuggestions.optJSONObject(index)
45
+ )
46
+ if (suggestion != null) {
47
+ suggestions.add(suggestion)
48
+ }
49
+ }
50
+ }
51
+ return NativeMentionsAddonConfig(
52
+ trigger = trigger,
53
+ suggestions = suggestions,
54
+ theme = EditorMentionTheme.fromJson(json.optJSONObject("theme"))
55
+ )
56
+ }
57
+ }
58
+ }
59
+
60
+ data class NativeEditorAddons(
61
+ val mentions: NativeMentionsAddonConfig?
62
+ ) {
63
+ companion object {
64
+ fun fromJson(json: String?): NativeEditorAddons {
65
+ if (json.isNullOrBlank()) return NativeEditorAddons(null)
66
+ val root = try {
67
+ JSONObject(json)
68
+ } catch (_: Exception) {
69
+ return NativeEditorAddons(null)
70
+ }
71
+ return NativeEditorAddons(
72
+ mentions = NativeMentionsAddonConfig.fromJson(root.optJSONObject("mentions"))
73
+ )
74
+ }
75
+ }
76
+ }
77
+
78
+ data class MentionQueryState(
79
+ val query: String,
80
+ val trigger: String,
81
+ val anchor: Int,
82
+ val head: Int
83
+ )
84
+
85
+ internal fun isMentionIdentifierCodePoint(codePoint: Int): Boolean {
86
+ return Character.isLetterOrDigit(codePoint) || codePoint == '_'.code || codePoint == '-'.code
87
+ }
88
+
89
+ internal fun resolveMentionQueryState(
90
+ text: String,
91
+ cursorScalar: Int,
92
+ trigger: String,
93
+ isCaretInsideMention: Boolean
94
+ ): MentionQueryState? {
95
+ if (isCaretInsideMention) return null
96
+
97
+ val scalars = text.codePoints().toArray()
98
+ if (cursorScalar > scalars.size) return null
99
+ val triggerCodePoint = trigger.codePointAt(0)
100
+
101
+ var start = cursorScalar
102
+ while (start > 0) {
103
+ val previous = scalars[start - 1]
104
+ if (Character.isWhitespace(previous) ||
105
+ previous == '\n'.code ||
106
+ previous == 0xFFFC ||
107
+ (!isMentionIdentifierCodePoint(previous) && previous != triggerCodePoint)
108
+ ) {
109
+ break
110
+ }
111
+ start -= 1
112
+ }
113
+
114
+ if (start >= scalars.size || scalars[start] != triggerCodePoint) return null
115
+ if (start > 0) {
116
+ val previous = scalars[start - 1]
117
+ if (isMentionIdentifierCodePoint(previous)) {
118
+ return null
119
+ }
120
+ }
121
+
122
+ val query = String(scalars, start + 1, cursorScalar - (start + 1))
123
+ if (query.any { it.isWhitespace() }) return null
124
+
125
+ return MentionQueryState(
126
+ query = query,
127
+ trigger = trigger,
128
+ anchor = start,
129
+ head = cursorScalar
130
+ )
131
+ }