react-native-enriched 0.0.0 → 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 (169) hide show
  1. package/LICENSE +20 -0
  2. package/README.md +869 -0
  3. package/ReactNativeEnriched.podspec +27 -0
  4. package/android/build.gradle +101 -0
  5. package/android/generated/java/com/facebook/react/viewmanagers/EnrichedTextInputViewManagerDelegate.java +146 -0
  6. package/android/generated/java/com/facebook/react/viewmanagers/EnrichedTextInputViewManagerInterface.java +55 -0
  7. package/android/generated/jni/react/renderer/components/RNEnrichedTextInputViewSpec/ComponentDescriptors.cpp +22 -0
  8. package/android/generated/jni/react/renderer/components/RNEnrichedTextInputViewSpec/ComponentDescriptors.h +24 -0
  9. package/android/generated/jni/react/renderer/components/RNEnrichedTextInputViewSpec/EventEmitters.cpp +118 -0
  10. package/android/generated/jni/react/renderer/components/RNEnrichedTextInputViewSpec/EventEmitters.h +95 -0
  11. package/android/generated/jni/react/renderer/components/RNEnrichedTextInputViewSpec/Props.cpp +128 -0
  12. package/android/generated/jni/react/renderer/components/RNEnrichedTextInputViewSpec/Props.h +577 -0
  13. package/android/generated/jni/react/renderer/components/RNEnrichedTextInputViewSpec/ShadowNodes.cpp +17 -0
  14. package/android/generated/jni/react/renderer/components/RNEnrichedTextInputViewSpec/ShadowNodes.h +23 -0
  15. package/android/generated/jni/react/renderer/components/RNEnrichedTextInputViewSpec/States.cpp +16 -0
  16. package/android/generated/jni/react/renderer/components/RNEnrichedTextInputViewSpec/States.h +20 -0
  17. package/android/gradle.properties +5 -0
  18. package/android/src/main/AndroidManifest.xml +3 -0
  19. package/android/src/main/AndroidManifestNew.xml +2 -0
  20. package/android/src/main/java/com/swmansion/enriched/EnrichedTextInputView.kt +535 -0
  21. package/android/src/main/java/com/swmansion/enriched/EnrichedTextInputViewLayoutManager.kt +64 -0
  22. package/android/src/main/java/com/swmansion/enriched/EnrichedTextInputViewManager.kt +292 -0
  23. package/android/src/main/java/com/swmansion/enriched/EnrichedTextInputViewPackage.kt +19 -0
  24. package/android/src/main/java/com/swmansion/enriched/events/MentionHandler.kt +40 -0
  25. package/android/src/main/java/com/swmansion/enriched/events/OnChangeHtmlEvent.kt +28 -0
  26. package/android/src/main/java/com/swmansion/enriched/events/OnChangeSelectionEvent.kt +29 -0
  27. package/android/src/main/java/com/swmansion/enriched/events/OnChangeStateEvent.kt +24 -0
  28. package/android/src/main/java/com/swmansion/enriched/events/OnChangeTextEvent.kt +30 -0
  29. package/android/src/main/java/com/swmansion/enriched/events/OnInputBlurEvent.kt +27 -0
  30. package/android/src/main/java/com/swmansion/enriched/events/OnInputFocusEvent.kt +27 -0
  31. package/android/src/main/java/com/swmansion/enriched/events/OnLinkDetectedEvent.kt +30 -0
  32. package/android/src/main/java/com/swmansion/enriched/events/OnMentionDetectedEvent.kt +29 -0
  33. package/android/src/main/java/com/swmansion/enriched/events/OnMentionEvent.kt +33 -0
  34. package/android/src/main/java/com/swmansion/enriched/spans/EnrichedBlockQuoteSpan.kt +34 -0
  35. package/android/src/main/java/com/swmansion/enriched/spans/EnrichedBoldSpan.kt +10 -0
  36. package/android/src/main/java/com/swmansion/enriched/spans/EnrichedCodeBlockSpan.kt +38 -0
  37. package/android/src/main/java/com/swmansion/enriched/spans/EnrichedH1Span.kt +17 -0
  38. package/android/src/main/java/com/swmansion/enriched/spans/EnrichedH2Span.kt +17 -0
  39. package/android/src/main/java/com/swmansion/enriched/spans/EnrichedH3Span.kt +17 -0
  40. package/android/src/main/java/com/swmansion/enriched/spans/EnrichedImageSpan.kt +41 -0
  41. package/android/src/main/java/com/swmansion/enriched/spans/EnrichedInlineCodeSpan.kt +16 -0
  42. package/android/src/main/java/com/swmansion/enriched/spans/EnrichedItalicSpan.kt +10 -0
  43. package/android/src/main/java/com/swmansion/enriched/spans/EnrichedLinkSpan.kt +24 -0
  44. package/android/src/main/java/com/swmansion/enriched/spans/EnrichedMentionSpan.kt +36 -0
  45. package/android/src/main/java/com/swmansion/enriched/spans/EnrichedOrderedListSpan.kt +71 -0
  46. package/android/src/main/java/com/swmansion/enriched/spans/EnrichedSpans.kt +111 -0
  47. package/android/src/main/java/com/swmansion/enriched/spans/EnrichedStrikeThroughSpan.kt +9 -0
  48. package/android/src/main/java/com/swmansion/enriched/spans/EnrichedUnderlineSpan.kt +9 -0
  49. package/android/src/main/java/com/swmansion/enriched/spans/EnrichedUnorderedListSpan.kt +49 -0
  50. package/android/src/main/java/com/swmansion/enriched/spans/interfaces/EnrichedBlockSpan.kt +4 -0
  51. package/android/src/main/java/com/swmansion/enriched/spans/interfaces/EnrichedHeadingSpan.kt +4 -0
  52. package/android/src/main/java/com/swmansion/enriched/spans/interfaces/EnrichedInlineSpan.kt +4 -0
  53. package/android/src/main/java/com/swmansion/enriched/spans/interfaces/EnrichedParagraphSpan.kt +4 -0
  54. package/android/src/main/java/com/swmansion/enriched/spans/interfaces/EnrichedSpan.kt +4 -0
  55. package/android/src/main/java/com/swmansion/enriched/spans/interfaces/EnrichedZeroWidthSpaceSpan.kt +5 -0
  56. package/android/src/main/java/com/swmansion/enriched/styles/HtmlStyle.kt +227 -0
  57. package/android/src/main/java/com/swmansion/enriched/styles/InlineStyles.kt +146 -0
  58. package/android/src/main/java/com/swmansion/enriched/styles/ListStyles.kt +173 -0
  59. package/android/src/main/java/com/swmansion/enriched/styles/ParagraphStyles.kt +186 -0
  60. package/android/src/main/java/com/swmansion/enriched/styles/ParametrizedStyles.kt +223 -0
  61. package/android/src/main/java/com/swmansion/enriched/utils/EnrichedParser.java +857 -0
  62. package/android/src/main/java/com/swmansion/enriched/utils/EnrichedSelection.kt +285 -0
  63. package/android/src/main/java/com/swmansion/enriched/utils/EnrichedSpanState.kt +204 -0
  64. package/android/src/main/java/com/swmansion/enriched/utils/Utils.kt +91 -0
  65. package/android/src/main/java/com/swmansion/enriched/watchers/EnrichedSpanWatcher.kt +73 -0
  66. package/android/src/main/java/com/swmansion/enriched/watchers/EnrichedTextWatcher.kt +51 -0
  67. package/android/src/main/new_arch/CMakeLists.txt +56 -0
  68. package/android/src/main/new_arch/RNEnrichedTextInputViewSpec.cpp +22 -0
  69. package/android/src/main/new_arch/RNEnrichedTextInputViewSpec.h +26 -0
  70. package/android/src/main/new_arch/react/renderer/components/RNEnrichedTextInputViewSpec/EnrichedTextInputComponentDescriptor.h +35 -0
  71. package/android/src/main/new_arch/react/renderer/components/RNEnrichedTextInputViewSpec/EnrichedTextInputMeasurementManager.cpp +51 -0
  72. package/android/src/main/new_arch/react/renderer/components/RNEnrichedTextInputViewSpec/EnrichedTextInputMeasurementManager.h +26 -0
  73. package/android/src/main/new_arch/react/renderer/components/RNEnrichedTextInputViewSpec/EnrichedTextInputShadowNode.cpp +34 -0
  74. package/android/src/main/new_arch/react/renderer/components/RNEnrichedTextInputViewSpec/EnrichedTextInputShadowNode.h +54 -0
  75. package/android/src/main/new_arch/react/renderer/components/RNEnrichedTextInputViewSpec/EnrichedTextInputState.cpp +9 -0
  76. package/android/src/main/new_arch/react/renderer/components/RNEnrichedTextInputViewSpec/EnrichedTextInputState.h +25 -0
  77. package/ios/EnrichedTextInputView.h +33 -0
  78. package/ios/EnrichedTextInputView.mm +1190 -0
  79. package/ios/EnrichedTextInputViewManager.mm +13 -0
  80. package/ios/config/InputConfig.h +67 -0
  81. package/ios/config/InputConfig.mm +382 -0
  82. package/ios/generated/RNEnrichedTextInputViewSpec/ComponentDescriptors.cpp +22 -0
  83. package/ios/generated/RNEnrichedTextInputViewSpec/ComponentDescriptors.h +24 -0
  84. package/ios/generated/RNEnrichedTextInputViewSpec/EventEmitters.cpp +118 -0
  85. package/ios/generated/RNEnrichedTextInputViewSpec/EventEmitters.h +95 -0
  86. package/ios/generated/RNEnrichedTextInputViewSpec/Props.cpp +128 -0
  87. package/ios/generated/RNEnrichedTextInputViewSpec/Props.h +577 -0
  88. package/ios/generated/RNEnrichedTextInputViewSpec/RCTComponentViewHelpers.h +384 -0
  89. package/ios/generated/RNEnrichedTextInputViewSpec/ShadowNodes.cpp +17 -0
  90. package/ios/generated/RNEnrichedTextInputViewSpec/ShadowNodes.h +23 -0
  91. package/ios/generated/RNEnrichedTextInputViewSpec/States.cpp +16 -0
  92. package/ios/generated/RNEnrichedTextInputViewSpec/States.h +20 -0
  93. package/ios/inputParser/InputParser.h +11 -0
  94. package/ios/inputParser/InputParser.mm +669 -0
  95. package/ios/inputTextView/InputTextView.h +6 -0
  96. package/ios/inputTextView/InputTextView.mm +115 -0
  97. package/ios/internals/EnrichedTextInputViewComponentDescriptor.h +17 -0
  98. package/ios/internals/EnrichedTextInputViewShadowNode.h +40 -0
  99. package/ios/internals/EnrichedTextInputViewShadowNode.mm +83 -0
  100. package/ios/internals/EnrichedTextInputViewState.cpp +10 -0
  101. package/ios/internals/EnrichedTextInputViewState.h +20 -0
  102. package/ios/styles/BlockQuoteStyle.mm +248 -0
  103. package/ios/styles/BoldStyle.mm +122 -0
  104. package/ios/styles/H1Style.mm +10 -0
  105. package/ios/styles/H2Style.mm +10 -0
  106. package/ios/styles/H3Style.mm +10 -0
  107. package/ios/styles/HeadingStyleBase.mm +144 -0
  108. package/ios/styles/InlineCodeStyle.mm +163 -0
  109. package/ios/styles/ItalicStyle.mm +110 -0
  110. package/ios/styles/LinkStyle.mm +463 -0
  111. package/ios/styles/MentionStyle.mm +476 -0
  112. package/ios/styles/OrderedListStyle.mm +225 -0
  113. package/ios/styles/StrikethroughStyle.mm +80 -0
  114. package/ios/styles/UnderlineStyle.mm +112 -0
  115. package/ios/styles/UnorderedListStyle.mm +225 -0
  116. package/ios/utils/BaseStyleProtocol.h +16 -0
  117. package/ios/utils/ColorExtension.h +6 -0
  118. package/ios/utils/ColorExtension.mm +27 -0
  119. package/ios/utils/FontExtension.h +13 -0
  120. package/ios/utils/FontExtension.mm +91 -0
  121. package/ios/utils/LayoutManagerExtension.h +6 -0
  122. package/ios/utils/LayoutManagerExtension.mm +171 -0
  123. package/ios/utils/LinkData.h +9 -0
  124. package/ios/utils/LinkData.mm +4 -0
  125. package/ios/utils/MentionParams.h +9 -0
  126. package/ios/utils/MentionParams.mm +4 -0
  127. package/ios/utils/MentionStyleProps.h +13 -0
  128. package/ios/utils/MentionStyleProps.mm +56 -0
  129. package/ios/utils/OccurenceUtils.h +37 -0
  130. package/ios/utils/OccurenceUtils.mm +124 -0
  131. package/ios/utils/ParagraphsUtils.h +7 -0
  132. package/ios/utils/ParagraphsUtils.mm +54 -0
  133. package/ios/utils/StringExtension.h +15 -0
  134. package/ios/utils/StringExtension.mm +57 -0
  135. package/ios/utils/StyleHeaders.h +74 -0
  136. package/ios/utils/StylePair.h +9 -0
  137. package/ios/utils/StylePair.mm +4 -0
  138. package/ios/utils/StyleTypeEnum.h +22 -0
  139. package/ios/utils/TextDecorationLineEnum.h +6 -0
  140. package/ios/utils/TextDecorationLineEnum.mm +4 -0
  141. package/ios/utils/TextInsertionUtils.h +6 -0
  142. package/ios/utils/TextInsertionUtils.mm +48 -0
  143. package/ios/utils/WordsUtils.h +6 -0
  144. package/ios/utils/WordsUtils.mm +88 -0
  145. package/ios/utils/ZeroWidthSpaceUtils.h +7 -0
  146. package/ios/utils/ZeroWidthSpaceUtils.mm +164 -0
  147. package/lib/module/EnrichedTextInput.js +191 -0
  148. package/lib/module/EnrichedTextInput.js.map +1 -0
  149. package/lib/module/EnrichedTextInputNativeComponent.ts +235 -0
  150. package/lib/module/index.js +4 -0
  151. package/lib/module/index.js.map +1 -0
  152. package/lib/module/normalizeHtmlStyle.js +141 -0
  153. package/lib/module/normalizeHtmlStyle.js.map +1 -0
  154. package/lib/module/package.json +1 -0
  155. package/lib/typescript/package.json +1 -0
  156. package/lib/typescript/src/EnrichedTextInput.d.ts +113 -0
  157. package/lib/typescript/src/EnrichedTextInput.d.ts.map +1 -0
  158. package/lib/typescript/src/EnrichedTextInputNativeComponent.d.ts +160 -0
  159. package/lib/typescript/src/EnrichedTextInputNativeComponent.d.ts.map +1 -0
  160. package/lib/typescript/src/index.d.ts +3 -0
  161. package/lib/typescript/src/index.d.ts.map +1 -0
  162. package/lib/typescript/src/normalizeHtmlStyle.d.ts +4 -0
  163. package/lib/typescript/src/normalizeHtmlStyle.d.ts.map +1 -0
  164. package/package.json +172 -1
  165. package/react-native.config.js +13 -0
  166. package/src/EnrichedTextInput.tsx +358 -0
  167. package/src/EnrichedTextInputNativeComponent.ts +235 -0
  168. package/src/index.tsx +9 -0
  169. package/src/normalizeHtmlStyle.ts +188 -0
@@ -0,0 +1,292 @@
1
+ package com.swmansion.enriched
2
+
3
+ import android.content.Context
4
+ import com.facebook.react.bridge.ReadableArray
5
+ import com.facebook.react.bridge.ReadableMap
6
+ import com.facebook.react.module.annotations.ReactModule
7
+ import com.facebook.react.uimanager.ReactStylesDiffMap
8
+ import com.facebook.react.uimanager.SimpleViewManager
9
+ import com.facebook.react.uimanager.StateWrapper
10
+ import com.facebook.react.uimanager.ThemedReactContext
11
+ import com.facebook.react.uimanager.ViewDefaults
12
+ import com.facebook.react.uimanager.ViewManagerDelegate
13
+ import com.facebook.react.uimanager.ViewProps
14
+ import com.facebook.react.uimanager.annotations.ReactProp
15
+ import com.facebook.react.viewmanagers.EnrichedTextInputViewManagerDelegate
16
+ import com.facebook.react.viewmanagers.EnrichedTextInputViewManagerInterface
17
+ import com.facebook.yoga.YogaMeasureMode
18
+ import com.facebook.yoga.YogaMeasureOutput
19
+ import com.swmansion.enriched.events.OnInputBlurEvent
20
+ import com.swmansion.enriched.events.OnChangeHtmlEvent
21
+ import com.swmansion.enriched.events.OnChangeSelectionEvent
22
+ import com.swmansion.enriched.events.OnChangeStateEvent
23
+ import com.swmansion.enriched.events.OnChangeTextEvent
24
+ import com.swmansion.enriched.events.OnInputFocusEvent
25
+ import com.swmansion.enriched.events.OnLinkDetectedEvent
26
+ import com.swmansion.enriched.events.OnMentionDetectedEvent
27
+ import com.swmansion.enriched.events.OnMentionEvent
28
+ import com.swmansion.enriched.spans.EnrichedSpans
29
+ import com.swmansion.enriched.styles.HtmlStyle
30
+ import com.swmansion.enriched.utils.jsonStringToStringMap
31
+
32
+ @ReactModule(name = EnrichedTextInputViewManager.NAME)
33
+ class EnrichedTextInputViewManager : SimpleViewManager<EnrichedTextInputView>(),
34
+ EnrichedTextInputViewManagerInterface<EnrichedTextInputView> {
35
+ private val mDelegate: ViewManagerDelegate<EnrichedTextInputView>
36
+ private var view: EnrichedTextInputView? = null
37
+
38
+ init {
39
+ mDelegate = EnrichedTextInputViewManagerDelegate(this)
40
+ }
41
+
42
+ override fun getDelegate(): ViewManagerDelegate<EnrichedTextInputView>? {
43
+ return mDelegate
44
+ }
45
+
46
+ override fun getName(): String {
47
+ return NAME
48
+ }
49
+
50
+ public override fun createViewInstance(context: ThemedReactContext): EnrichedTextInputView {
51
+ val view = EnrichedTextInputView(context)
52
+ this.view = view
53
+
54
+ return view
55
+ }
56
+
57
+ override fun updateState(
58
+ view: EnrichedTextInputView,
59
+ props: ReactStylesDiffMap?,
60
+ stateWrapper: StateWrapper?
61
+ ): Any? {
62
+ view.stateWrapper = stateWrapper
63
+ return super.updateState(view, props, stateWrapper)
64
+ }
65
+
66
+ override fun getExportedCustomDirectEventTypeConstants(): MutableMap<String, Any> {
67
+ val map = mutableMapOf<String, Any>()
68
+ map.put(OnInputFocusEvent.EVENT_NAME, mapOf("registrationName" to OnInputFocusEvent.EVENT_NAME))
69
+ map.put(OnInputBlurEvent.EVENT_NAME, mapOf("registrationName" to OnInputBlurEvent.EVENT_NAME))
70
+ map.put(OnChangeTextEvent.EVENT_NAME, mapOf("registrationName" to OnChangeTextEvent.EVENT_NAME))
71
+ map.put(OnChangeHtmlEvent.EVENT_NAME, mapOf("registrationName" to OnChangeHtmlEvent.EVENT_NAME))
72
+ map.put(OnChangeStateEvent.EVENT_NAME, mapOf("registrationName" to OnChangeStateEvent.EVENT_NAME))
73
+ map.put(OnLinkDetectedEvent.EVENT_NAME, mapOf("registrationName" to OnLinkDetectedEvent.EVENT_NAME))
74
+ map.put(OnMentionDetectedEvent.EVENT_NAME, mapOf("registrationName" to OnMentionDetectedEvent.EVENT_NAME))
75
+ map.put(OnMentionEvent.EVENT_NAME, mapOf("registrationName" to OnMentionEvent.EVENT_NAME))
76
+ map.put(OnChangeSelectionEvent.EVENT_NAME, mapOf("registrationName" to OnChangeSelectionEvent.EVENT_NAME))
77
+
78
+ return map
79
+ }
80
+
81
+ @ReactProp(name = "defaultValue")
82
+ override fun setDefaultValue(view: EnrichedTextInputView?, value: String?) {
83
+ view?.setValue(value)
84
+ }
85
+
86
+ @ReactProp(name = "placeholder")
87
+ override fun setPlaceholder(view: EnrichedTextInputView?, value: String?) {
88
+ view?.setPlaceholder(value)
89
+ }
90
+
91
+ @ReactProp(name = "placeholderTextColor", customType = "Color")
92
+ override fun setPlaceholderTextColor(view: EnrichedTextInputView?, color: Int?) {
93
+ view?.setPlaceholderTextColor(color)
94
+ }
95
+
96
+ @ReactProp(name = "cursorColor", customType = "Color")
97
+ override fun setCursorColor(view: EnrichedTextInputView?, color: Int?) {
98
+ view?.setCursorColor(color)
99
+ }
100
+
101
+ @ReactProp(name = "selectionColor", customType = "Color")
102
+ override fun setSelectionColor(view: EnrichedTextInputView?, color: Int?) {
103
+ view?.setSelectionColor(color)
104
+ }
105
+
106
+ @ReactProp(name = "autoFocus", defaultBoolean = false)
107
+ override fun setAutoFocus(view: EnrichedTextInputView?, autoFocus: Boolean) {
108
+ view?.setAutoFocus(autoFocus)
109
+ }
110
+
111
+ @ReactProp(name = "editable", defaultBoolean = true)
112
+ override fun setEditable(view: EnrichedTextInputView?, editable: Boolean) {
113
+ view?.isEnabled = editable
114
+ }
115
+
116
+ @ReactProp(name = "mentionIndicators")
117
+ override fun setMentionIndicators(view: EnrichedTextInputView?, indicators: ReadableArray?) {
118
+ if (indicators == null) return
119
+
120
+ val indicatorsList = mutableListOf<String>()
121
+ for (i in 0 until indicators.size()) {
122
+ val stringValue = indicators.getString(i) ?: continue
123
+ indicatorsList.add(stringValue)
124
+ }
125
+
126
+ val indicatorsArray = indicatorsList.toTypedArray()
127
+ view?.parametrizedStyles?.mentionIndicators = indicatorsArray
128
+ }
129
+
130
+ @ReactProp(name = "htmlStyle")
131
+ override fun setHtmlStyle(view: EnrichedTextInputView?, style: ReadableMap?) {
132
+ view?.htmlStyle = HtmlStyle(view, style)
133
+ }
134
+
135
+ @ReactProp(name = ViewProps.COLOR, customType = "Color")
136
+ override fun setColor(view: EnrichedTextInputView?, color: Int?) {
137
+ view?.setColor(color)
138
+ }
139
+
140
+ @ReactProp(name = "fontSize", defaultFloat = ViewDefaults.FONT_SIZE_SP)
141
+ override fun setFontSize(view: EnrichedTextInputView?, size: Float) {
142
+ view?.setFontSize(size)
143
+ }
144
+
145
+ @ReactProp(name = "fontFamily")
146
+ override fun setFontFamily(view: EnrichedTextInputView?, family: String?) {
147
+ view?.setFontFamily(family)
148
+ }
149
+
150
+ @ReactProp(name = "fontWeight")
151
+ override fun setFontWeight(view: EnrichedTextInputView?, weight: String?) {
152
+ view?.setFontWeight(weight)
153
+ }
154
+
155
+ @ReactProp(name = "fontStyle")
156
+ override fun setFontStyle(view: EnrichedTextInputView?, style: String?) {
157
+ view?.setFontStyle(style)
158
+ }
159
+
160
+ override fun onAfterUpdateTransaction(view: EnrichedTextInputView) {
161
+ super.onAfterUpdateTransaction(view)
162
+ view.updateTypeface()
163
+ }
164
+
165
+ override fun setPadding(
166
+ view: EnrichedTextInputView?,
167
+ left: Int,
168
+ top: Int,
169
+ right: Int,
170
+ bottom: Int
171
+ ) {
172
+ super.setPadding(view, left, top, right, bottom)
173
+
174
+ view?.setPadding(left, top, right, bottom)
175
+ }
176
+
177
+ override fun setIsOnChangeHtmlSet(view: EnrichedTextInputView?, value: Boolean) {
178
+ // this prop isn't used on Android as of now, but the setter must be present
179
+ }
180
+
181
+ override fun setAutoCapitalize(view: EnrichedTextInputView?, flag: String?) {
182
+ view?.setAutoCapitalize(flag)
183
+ }
184
+
185
+ override fun setAndroidExperimentalSynchronousEvents(
186
+ view: EnrichedTextInputView?,
187
+ value: Boolean
188
+ ) {
189
+ view?.experimentalSynchronousEvents = value
190
+ }
191
+
192
+ override fun focus(view: EnrichedTextInputView?) {
193
+ view?.requestFocusProgrammatically()
194
+ }
195
+
196
+ override fun blur(view: EnrichedTextInputView?) {
197
+ view?.clearFocus()
198
+ }
199
+
200
+ override fun setValue(view: EnrichedTextInputView?, text: String) {
201
+ view?.setValue(text)
202
+ }
203
+
204
+ override fun toggleBold(view: EnrichedTextInputView?) {
205
+ view?.verifyAndToggleStyle(EnrichedSpans.BOLD)
206
+ }
207
+
208
+ override fun toggleItalic(view: EnrichedTextInputView?) {
209
+ view?.verifyAndToggleStyle(EnrichedSpans.ITALIC)
210
+ }
211
+
212
+ override fun toggleUnderline(view: EnrichedTextInputView?) {
213
+ view?.verifyAndToggleStyle(EnrichedSpans.UNDERLINE)
214
+ }
215
+
216
+ override fun toggleStrikeThrough(view: EnrichedTextInputView?) {
217
+ view?.verifyAndToggleStyle(EnrichedSpans.STRIKETHROUGH)
218
+ }
219
+
220
+ override fun toggleInlineCode(view: EnrichedTextInputView?) {
221
+ view?.verifyAndToggleStyle(EnrichedSpans.INLINE_CODE)
222
+ }
223
+
224
+ override fun toggleH1(view: EnrichedTextInputView?) {
225
+ view?.verifyAndToggleStyle(EnrichedSpans.H1)
226
+ }
227
+
228
+ override fun toggleH2(view: EnrichedTextInputView?) {
229
+ view?.verifyAndToggleStyle(EnrichedSpans.H2)
230
+ }
231
+
232
+ override fun toggleH3(view: EnrichedTextInputView?) {
233
+ view?.verifyAndToggleStyle(EnrichedSpans.H3)
234
+ }
235
+
236
+ override fun toggleCodeBlock(view: EnrichedTextInputView?) {
237
+ view?.verifyAndToggleStyle(EnrichedSpans.CODE_BLOCK)
238
+ }
239
+
240
+ override fun toggleBlockQuote(view: EnrichedTextInputView?) {
241
+ view?.verifyAndToggleStyle(EnrichedSpans.BLOCK_QUOTE)
242
+ }
243
+
244
+ override fun toggleOrderedList(view: EnrichedTextInputView?) {
245
+ view?.verifyAndToggleStyle(EnrichedSpans.ORDERED_LIST)
246
+ }
247
+
248
+ override fun toggleUnorderedList(view: EnrichedTextInputView?) {
249
+ view?.verifyAndToggleStyle(EnrichedSpans.UNORDERED_LIST)
250
+ }
251
+
252
+ override fun addLink(view: EnrichedTextInputView?, start: Int, end: Int, text: String, url: String) {
253
+ view?.addLink(start, end, text, url)
254
+ }
255
+
256
+ override fun addImage(view: EnrichedTextInputView?, src: String) {
257
+ view?.addImage(src)
258
+ }
259
+
260
+ override fun startMention(view: EnrichedTextInputView?, indicator: String) {
261
+ view?.startMention(indicator)
262
+ }
263
+
264
+ override fun addMention(view: EnrichedTextInputView?, indicator: String, text: String, payload: String) {
265
+ val attributes = jsonStringToStringMap(payload)
266
+ view?.addMention(text, indicator, attributes)
267
+ }
268
+
269
+ override fun measure(
270
+ context: Context,
271
+ localData: ReadableMap?,
272
+ props: ReadableMap?,
273
+ state: ReadableMap?,
274
+ width: Float,
275
+ widthMode: YogaMeasureMode?,
276
+ height: Float,
277
+ heightMode: YogaMeasureMode?,
278
+ attachmentsPositions: FloatArray?
279
+ ): Long {
280
+ val size = this.view?.layoutManager?.getMeasuredSize(width)
281
+
282
+ if (size != null) {
283
+ return YogaMeasureOutput.make(size.first, size.second)
284
+ }
285
+
286
+ return YogaMeasureOutput.make(0, 0)
287
+ }
288
+
289
+ companion object {
290
+ const val NAME = "EnrichedTextInputView"
291
+ }
292
+ }
@@ -0,0 +1,19 @@
1
+ package com.swmansion.enriched
2
+
3
+ import com.facebook.react.ReactPackage
4
+ import com.facebook.react.bridge.NativeModule
5
+ import com.facebook.react.bridge.ReactApplicationContext
6
+ import com.facebook.react.uimanager.ViewManager
7
+ import java.util.ArrayList
8
+
9
+ class EnrichedTextInputViewPackage : ReactPackage {
10
+ override fun createViewManagers(reactContext: ReactApplicationContext): List<ViewManager<*, *>> {
11
+ val viewManagers: MutableList<ViewManager<*, *>> = ArrayList()
12
+ viewManagers.add(EnrichedTextInputViewManager())
13
+ return viewManagers
14
+ }
15
+
16
+ override fun createNativeModules(reactContext: ReactApplicationContext): List<NativeModule> {
17
+ return emptyList()
18
+ }
19
+ }
@@ -0,0 +1,40 @@
1
+ package com.swmansion.enriched.events
2
+
3
+ import com.facebook.react.bridge.ReactContext
4
+ import com.facebook.react.uimanager.UIManagerHelper
5
+ import com.swmansion.enriched.EnrichedTextInputView
6
+
7
+ class MentionHandler(private val view: EnrichedTextInputView) {
8
+ private var previousText: String? = null
9
+ private var previousIndicator: String? = null
10
+
11
+ fun endMention() {
12
+ val indicator = previousIndicator
13
+ if (indicator == null) return
14
+
15
+ emitEvent(indicator, null)
16
+ previousIndicator = null
17
+ }
18
+
19
+ fun onMention(indicator: String, text: String?) {
20
+ emitEvent(indicator, text)
21
+ previousIndicator = indicator
22
+ }
23
+
24
+ private fun emitEvent(indicator: String, text: String?) {
25
+ // Do not emit events too often
26
+ if (previousText == text) return
27
+
28
+ previousText = text
29
+ val context = view.context as ReactContext
30
+ val surfaceId = UIManagerHelper.getSurfaceId(context)
31
+ val dispatcher = UIManagerHelper.getEventDispatcherForReactTag(context, view.id)
32
+ dispatcher?.dispatchEvent(OnMentionEvent(
33
+ surfaceId,
34
+ view.id,
35
+ indicator,
36
+ text,
37
+ view.experimentalSynchronousEvents,
38
+ ))
39
+ }
40
+ }
@@ -0,0 +1,28 @@
1
+ package com.swmansion.enriched.events
2
+
3
+ import com.facebook.react.bridge.Arguments
4
+ import com.facebook.react.bridge.WritableMap
5
+ import com.facebook.react.uimanager.events.Event
6
+
7
+ class OnChangeHtmlEvent(surfaceId: Int, viewId: Int, private val html: String, private val experimentalSynchronousEvents: Boolean) :
8
+ Event<OnChangeHtmlEvent>(surfaceId, viewId) {
9
+
10
+ override fun getEventName(): String {
11
+ return EVENT_NAME
12
+ }
13
+
14
+ override fun getEventData(): WritableMap {
15
+ val eventData: WritableMap = Arguments.createMap()
16
+ eventData.putString("value", html)
17
+
18
+ return eventData
19
+ }
20
+
21
+ override fun experimental_isSynchronous(): Boolean {
22
+ return experimentalSynchronousEvents
23
+ }
24
+
25
+ companion object {
26
+ const val EVENT_NAME: String = "onChangeHtml"
27
+ }
28
+ }
@@ -0,0 +1,29 @@
1
+ package com.swmansion.enriched.events
2
+
3
+ import com.facebook.react.bridge.Arguments
4
+ import com.facebook.react.bridge.WritableMap
5
+ import com.facebook.react.uimanager.events.Event
6
+
7
+ class OnChangeSelectionEvent(surfaceId: Int, viewId: Int, private val text: String, private val start: Int, private val end: Int, private val experimentalSynchronousEvents: Boolean) :
8
+ Event<OnChangeSelectionEvent>(surfaceId, viewId) {
9
+
10
+ override fun getEventName(): String {
11
+ return EVENT_NAME
12
+ }
13
+
14
+ override fun getEventData(): WritableMap {
15
+ val eventData: WritableMap = Arguments.createMap()
16
+ eventData.putString("text", text)
17
+ eventData.putInt("start", start)
18
+ eventData.putInt("end", end)
19
+ return eventData
20
+ }
21
+
22
+ override fun experimental_isSynchronous(): Boolean {
23
+ return experimentalSynchronousEvents
24
+ }
25
+
26
+ companion object {
27
+ const val EVENT_NAME: String = "onChangeSelection"
28
+ }
29
+ }
@@ -0,0 +1,24 @@
1
+ package com.swmansion.enriched.events
2
+
3
+ import com.facebook.react.bridge.WritableMap
4
+ import com.facebook.react.uimanager.events.Event
5
+
6
+ class OnChangeStateEvent(surfaceId: Int, viewId: Int, private val state: WritableMap, private val experimentalSynchronousEvents: Boolean) :
7
+ Event<OnChangeStateEvent>(surfaceId, viewId) {
8
+
9
+ override fun getEventName(): String {
10
+ return EVENT_NAME
11
+ }
12
+
13
+ override fun getEventData(): WritableMap {
14
+ return state
15
+ }
16
+
17
+ override fun experimental_isSynchronous(): Boolean {
18
+ return experimentalSynchronousEvents
19
+ }
20
+
21
+ companion object {
22
+ const val EVENT_NAME: String = "onChangeState"
23
+ }
24
+ }
@@ -0,0 +1,30 @@
1
+ package com.swmansion.enriched.events
2
+
3
+ import android.text.Editable
4
+ import com.facebook.react.bridge.Arguments
5
+ import com.facebook.react.bridge.WritableMap
6
+ import com.facebook.react.uimanager.events.Event
7
+
8
+ class OnChangeTextEvent(surfaceId: Int, viewId: Int, private val editable: Editable, private val experimentalSynchronousEvents: Boolean) :
9
+ Event<OnChangeTextEvent>(surfaceId, viewId) {
10
+
11
+ override fun getEventName(): String {
12
+ return EVENT_NAME
13
+ }
14
+
15
+ override fun getEventData(): WritableMap {
16
+ val eventData: WritableMap = Arguments.createMap()
17
+ val text = editable.toString()
18
+ val normalizedText = text.replace(Regex("\\u200B"), "")
19
+ eventData.putString("value", normalizedText)
20
+ return eventData
21
+ }
22
+
23
+ override fun experimental_isSynchronous(): Boolean {
24
+ return experimentalSynchronousEvents
25
+ }
26
+
27
+ companion object {
28
+ const val EVENT_NAME: String = "onChangeText"
29
+ }
30
+ }
@@ -0,0 +1,27 @@
1
+ package com.swmansion.enriched.events
2
+
3
+ import com.facebook.react.bridge.Arguments
4
+ import com.facebook.react.bridge.WritableMap
5
+ import com.facebook.react.uimanager.events.Event
6
+
7
+ class OnInputBlurEvent(surfaceId: Int, viewId: Int, private val experimentalSynchronousEvents: Boolean) :
8
+ Event<OnInputBlurEvent>(surfaceId, viewId) {
9
+
10
+ override fun getEventName(): String {
11
+ return EVENT_NAME
12
+ }
13
+
14
+ override fun getEventData(): WritableMap {
15
+ val eventData: WritableMap = Arguments.createMap()
16
+
17
+ return eventData
18
+ }
19
+
20
+ override fun experimental_isSynchronous(): Boolean {
21
+ return experimentalSynchronousEvents
22
+ }
23
+
24
+ companion object {
25
+ const val EVENT_NAME: String = "onInputBlur"
26
+ }
27
+ }
@@ -0,0 +1,27 @@
1
+ package com.swmansion.enriched.events
2
+
3
+ import com.facebook.react.bridge.Arguments
4
+ import com.facebook.react.bridge.WritableMap
5
+ import com.facebook.react.uimanager.events.Event
6
+
7
+ class OnInputFocusEvent(surfaceId: Int, viewId: Int, private val experimentalSynchronousEvents: Boolean) :
8
+ Event<OnInputFocusEvent>(surfaceId, viewId) {
9
+
10
+ override fun getEventName(): String {
11
+ return EVENT_NAME
12
+ }
13
+
14
+ override fun getEventData(): WritableMap {
15
+ val eventData: WritableMap = Arguments.createMap()
16
+
17
+ return eventData
18
+ }
19
+
20
+ override fun experimental_isSynchronous(): Boolean {
21
+ return experimentalSynchronousEvents
22
+ }
23
+
24
+ companion object {
25
+ const val EVENT_NAME: String = "onInputFocus"
26
+ }
27
+ }
@@ -0,0 +1,30 @@
1
+ package com.swmansion.enriched.events
2
+
3
+ import com.facebook.react.bridge.Arguments
4
+ import com.facebook.react.bridge.WritableMap
5
+ import com.facebook.react.uimanager.events.Event
6
+
7
+ class OnLinkDetectedEvent(surfaceId: Int, viewId: Int, private val text: String, private val url: String, private val start: Int, private val end: Int, private val experimentalSynchronousEvents: Boolean) :
8
+ Event<OnLinkDetectedEvent>(surfaceId, viewId) {
9
+
10
+ override fun getEventName(): String {
11
+ return EVENT_NAME
12
+ }
13
+
14
+ override fun getEventData(): WritableMap {
15
+ val eventData: WritableMap = Arguments.createMap()
16
+ eventData.putString("text", text)
17
+ eventData.putString("url", url)
18
+ eventData.putInt("start", start);
19
+ eventData.putInt("end", end);
20
+ return eventData
21
+ }
22
+
23
+ override fun experimental_isSynchronous(): Boolean {
24
+ return experimentalSynchronousEvents
25
+ }
26
+
27
+ companion object {
28
+ const val EVENT_NAME: String = "onLinkDetected"
29
+ }
30
+ }
@@ -0,0 +1,29 @@
1
+ package com.swmansion.enriched.events
2
+
3
+ import com.facebook.react.bridge.Arguments
4
+ import com.facebook.react.bridge.WritableMap
5
+ import com.facebook.react.uimanager.events.Event
6
+
7
+ class OnMentionDetectedEvent(surfaceId: Int, viewId: Int, private val text: String, private val indicator: String, private val payload: String, private val experimentalSynchronousEvents: Boolean) :
8
+ Event<OnMentionDetectedEvent>(surfaceId, viewId) {
9
+
10
+ override fun getEventName(): String {
11
+ return EVENT_NAME
12
+ }
13
+
14
+ override fun getEventData(): WritableMap {
15
+ val eventData: WritableMap = Arguments.createMap()
16
+ eventData.putString("text", text)
17
+ eventData.putString("indicator", indicator)
18
+ eventData.putString("payload", payload)
19
+ return eventData
20
+ }
21
+
22
+ override fun experimental_isSynchronous(): Boolean {
23
+ return experimentalSynchronousEvents
24
+ }
25
+
26
+ companion object {
27
+ const val EVENT_NAME: String = "onMentionDetected"
28
+ }
29
+ }
@@ -0,0 +1,33 @@
1
+ package com.swmansion.enriched.events
2
+
3
+ import com.facebook.react.bridge.Arguments
4
+ import com.facebook.react.bridge.WritableMap
5
+ import com.facebook.react.uimanager.events.Event
6
+
7
+ class OnMentionEvent(surfaceId: Int, viewId: Int, private val indicator: String, private val text: String?, private val experimentalSynchronousEvents: Boolean) : Event<OnMentionEvent>(surfaceId, viewId) {
8
+
9
+ override fun getEventName(): String {
10
+ return EVENT_NAME
11
+ }
12
+
13
+ override fun getEventData(): WritableMap? {
14
+ val eventData: WritableMap = Arguments.createMap()
15
+ eventData.putString("indicator", indicator)
16
+
17
+ if (text == null) {
18
+ eventData.putNull("text")
19
+ } else {
20
+ eventData.putString("text", text)
21
+ }
22
+
23
+ return eventData
24
+ }
25
+
26
+ override fun experimental_isSynchronous(): Boolean {
27
+ return experimentalSynchronousEvents
28
+ }
29
+
30
+ companion object {
31
+ const val EVENT_NAME: String = "onMention"
32
+ }
33
+ }
@@ -0,0 +1,34 @@
1
+ package com.swmansion.enriched.spans
2
+
3
+ import android.graphics.Canvas
4
+ import android.graphics.Paint
5
+ import android.text.Layout
6
+ import android.text.TextPaint
7
+ import android.text.style.CharacterStyle
8
+ import android.text.style.LeadingMarginSpan
9
+ import com.swmansion.enriched.spans.interfaces.EnrichedBlockSpan
10
+ import com.swmansion.enriched.styles.HtmlStyle
11
+
12
+ // https://android.googlesource.com/platform/frameworks/base/+/refs/heads/main/core/java/android/text/style/QuoteSpan.java
13
+ class EnrichedBlockQuoteSpan(private val htmlStyle: HtmlStyle) : CharacterStyle(), LeadingMarginSpan, EnrichedBlockSpan {
14
+ override fun getLeadingMargin(p0: Boolean): Int {
15
+ return htmlStyle.blockquoteStripeWidth + htmlStyle.blockquoteGapWidth
16
+ }
17
+
18
+ override fun drawLeadingMargin(c: Canvas, p: Paint, x: Int, dir: Int, top: Int, baseline: Int, bottom: Int, text: CharSequence?, start: Int, end: Int, first: Boolean, layout: Layout?) {
19
+ val style = p.style
20
+ val color = p.color
21
+ p.style = Paint.Style.FILL
22
+ p.color = htmlStyle.blockquoteBorderColor
23
+ c.drawRect(x.toFloat(), top.toFloat(), x + dir * htmlStyle.blockquoteStripeWidth.toFloat(), bottom.toFloat(), p)
24
+ p.style = style
25
+ p.color = color
26
+ }
27
+
28
+ override fun updateDrawState(textPaint: TextPaint?) {
29
+ val color = htmlStyle.blockquoteColor
30
+ if (color != null) {
31
+ textPaint?.color = color
32
+ }
33
+ }
34
+ }
@@ -0,0 +1,10 @@
1
+ package com.swmansion.enriched.spans
2
+
3
+ import android.graphics.Typeface
4
+ import android.text.style.StyleSpan
5
+ import com.swmansion.enriched.spans.interfaces.EnrichedInlineSpan
6
+ import com.swmansion.enriched.styles.HtmlStyle
7
+
8
+ @Suppress("UNUSED_PARAMETER")
9
+ class EnrichedBoldSpan(htmlStyle: HtmlStyle) : StyleSpan(Typeface.BOLD), EnrichedInlineSpan {
10
+ }