react-native-enriched 0.2.1 → 0.3.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 (156) hide show
  1. package/README.md +15 -12
  2. package/android/build.gradle +77 -72
  3. package/android/generated/java/com/facebook/react/viewmanagers/EnrichedTextInputViewManagerDelegate.java +18 -0
  4. package/android/generated/java/com/facebook/react/viewmanagers/EnrichedTextInputViewManagerInterface.java +6 -0
  5. package/android/generated/jni/react/renderer/components/RNEnrichedTextInputViewSpec/EventEmitters.cpp +146 -0
  6. package/android/generated/jni/react/renderer/components/RNEnrichedTextInputViewSpec/EventEmitters.h +140 -0
  7. package/android/generated/jni/react/renderer/components/RNEnrichedTextInputViewSpec/Props.cpp +10 -0
  8. package/android/generated/jni/react/renderer/components/RNEnrichedTextInputViewSpec/Props.h +194 -0
  9. package/android/lint.gradle +70 -0
  10. package/android/src/main/java/com/swmansion/enriched/EnrichedTextInputConnectionWrapper.kt +140 -0
  11. package/android/src/main/java/com/swmansion/enriched/EnrichedTextInputView.kt +245 -116
  12. package/android/src/main/java/com/swmansion/enriched/EnrichedTextInputViewLayoutManager.kt +3 -1
  13. package/android/src/main/java/com/swmansion/enriched/EnrichedTextInputViewManager.kt +162 -53
  14. package/android/src/main/java/com/swmansion/enriched/EnrichedTextInputViewPackage.kt +1 -3
  15. package/android/src/main/java/com/swmansion/enriched/MeasurementStore.kt +70 -21
  16. package/android/src/main/java/com/swmansion/enriched/events/MentionHandler.kt +20 -10
  17. package/android/src/main/java/com/swmansion/enriched/events/OnChangeHtmlEvent.kt +8 -9
  18. package/android/src/main/java/com/swmansion/enriched/events/OnChangeSelectionEvent.kt +10 -9
  19. package/android/src/main/java/com/swmansion/enriched/events/OnChangeStateDeprecatedEvent.kt +21 -0
  20. package/android/src/main/java/com/swmansion/enriched/events/OnChangeStateEvent.kt +9 -12
  21. package/android/src/main/java/com/swmansion/enriched/events/OnChangeTextEvent.kt +10 -10
  22. package/android/src/main/java/com/swmansion/enriched/events/OnInputBlurEvent.kt +7 -9
  23. package/android/src/main/java/com/swmansion/enriched/events/OnInputFocusEvent.kt +7 -9
  24. package/android/src/main/java/com/swmansion/enriched/events/OnInputKeyPressEvent.kt +27 -0
  25. package/android/src/main/java/com/swmansion/enriched/events/OnLinkDetectedEvent.kt +13 -11
  26. package/android/src/main/java/com/swmansion/enriched/events/OnMentionDetectedEvent.kt +10 -9
  27. package/android/src/main/java/com/swmansion/enriched/events/OnMentionEvent.kt +9 -8
  28. package/android/src/main/java/com/swmansion/enriched/events/OnRequestHtmlResultEvent.kt +1 -2
  29. package/android/src/main/java/com/swmansion/enriched/spans/EnrichedBlockQuoteSpan.kt +21 -8
  30. package/android/src/main/java/com/swmansion/enriched/spans/EnrichedBoldSpan.kt +5 -4
  31. package/android/src/main/java/com/swmansion/enriched/spans/EnrichedCodeBlockSpan.kt +7 -5
  32. package/android/src/main/java/com/swmansion/enriched/spans/EnrichedH1Span.kt +5 -4
  33. package/android/src/main/java/com/swmansion/enriched/spans/EnrichedH2Span.kt +5 -4
  34. package/android/src/main/java/com/swmansion/enriched/spans/EnrichedH3Span.kt +5 -4
  35. package/android/src/main/java/com/swmansion/enriched/spans/EnrichedH4Span.kt +24 -0
  36. package/android/src/main/java/com/swmansion/enriched/spans/EnrichedH5Span.kt +24 -0
  37. package/android/src/main/java/com/swmansion/enriched/spans/EnrichedH6Span.kt +24 -0
  38. package/android/src/main/java/com/swmansion/enriched/spans/EnrichedImageSpan.kt +29 -17
  39. package/android/src/main/java/com/swmansion/enriched/spans/EnrichedInlineCodeSpan.kt +5 -4
  40. package/android/src/main/java/com/swmansion/enriched/spans/EnrichedItalicSpan.kt +5 -4
  41. package/android/src/main/java/com/swmansion/enriched/spans/EnrichedLinkSpan.kt +7 -7
  42. package/android/src/main/java/com/swmansion/enriched/spans/EnrichedMentionSpan.kt +11 -14
  43. package/android/src/main/java/com/swmansion/enriched/spans/EnrichedOrderedListSpan.kt +15 -14
  44. package/android/src/main/java/com/swmansion/enriched/spans/EnrichedSpans.kt +167 -71
  45. package/android/src/main/java/com/swmansion/enriched/spans/EnrichedStrikeThroughSpan.kt +5 -4
  46. package/android/src/main/java/com/swmansion/enriched/spans/EnrichedUnderlineSpan.kt +5 -4
  47. package/android/src/main/java/com/swmansion/enriched/spans/EnrichedUnorderedListSpan.kt +8 -8
  48. package/android/src/main/java/com/swmansion/enriched/spans/interfaces/EnrichedBlockSpan.kt +3 -2
  49. package/android/src/main/java/com/swmansion/enriched/spans/interfaces/EnrichedHeadingSpan.kt +1 -2
  50. package/android/src/main/java/com/swmansion/enriched/spans/interfaces/EnrichedInlineSpan.kt +1 -2
  51. package/android/src/main/java/com/swmansion/enriched/spans/interfaces/EnrichedParagraphSpan.kt +3 -2
  52. package/android/src/main/java/com/swmansion/enriched/spans/interfaces/EnrichedSpan.kt +1 -0
  53. package/android/src/main/java/com/swmansion/enriched/spans/interfaces/EnrichedZeroWidthSpaceSpan.kt +1 -2
  54. package/android/src/main/java/com/swmansion/enriched/spans/utils/ForceRedrawSpan.kt +2 -1
  55. package/android/src/main/java/com/swmansion/enriched/styles/HtmlStyle.kt +78 -21
  56. package/android/src/main/java/com/swmansion/enriched/styles/InlineStyles.kt +25 -8
  57. package/android/src/main/java/com/swmansion/enriched/styles/ListStyles.kt +60 -20
  58. package/android/src/main/java/com/swmansion/enriched/styles/ParagraphStyles.kt +86 -26
  59. package/android/src/main/java/com/swmansion/enriched/styles/ParametrizedStyles.kt +128 -52
  60. package/android/src/main/java/com/swmansion/enriched/utils/AsyncDrawable.kt +10 -7
  61. package/android/src/main/java/com/swmansion/enriched/utils/EnrichedConstants.kt +11 -0
  62. package/android/src/main/java/com/swmansion/enriched/utils/EnrichedEditableFactory.kt +17 -0
  63. package/android/src/main/java/com/swmansion/enriched/utils/EnrichedParser.java +128 -87
  64. package/android/src/main/java/com/swmansion/enriched/utils/EnrichedSelection.kt +71 -42
  65. package/android/src/main/java/com/swmansion/enriched/utils/EnrichedSpanState.kt +183 -48
  66. package/android/src/main/java/com/swmansion/enriched/utils/EnrichedSpannable.kt +82 -0
  67. package/android/src/main/java/com/swmansion/enriched/utils/EnrichedSpannableStringBuilder.kt +15 -0
  68. package/android/src/main/java/com/swmansion/enriched/utils/Utils.kt +0 -70
  69. package/android/src/main/java/com/swmansion/enriched/watchers/EnrichedSpanWatcher.kt +46 -14
  70. package/android/src/main/java/com/swmansion/enriched/watchers/EnrichedTextWatcher.kt +34 -11
  71. package/android/src/main/new_arch/CMakeLists.txt +6 -0
  72. package/android/src/main/new_arch/react/renderer/components/RNEnrichedTextInputViewSpec/conversions.h +21 -1
  73. package/ios/EnrichedTextInputView.h +1 -1
  74. package/ios/EnrichedTextInputView.mm +381 -49
  75. package/ios/config/InputConfig.h +18 -0
  76. package/ios/config/InputConfig.mm +118 -8
  77. package/ios/generated/RNEnrichedTextInputViewSpec/EventEmitters.cpp +146 -0
  78. package/ios/generated/RNEnrichedTextInputViewSpec/EventEmitters.h +140 -0
  79. package/ios/generated/RNEnrichedTextInputViewSpec/Props.cpp +10 -0
  80. package/ios/generated/RNEnrichedTextInputViewSpec/Props.h +194 -0
  81. package/ios/generated/RNEnrichedTextInputViewSpec/RCTComponentViewHelpers.h +74 -0
  82. package/ios/inputParser/InputParser.mm +83 -10
  83. package/ios/{attachments → interfaces}/ImageAttachment.mm +3 -1
  84. package/ios/interfaces/LinkRegexConfig.h +19 -0
  85. package/ios/interfaces/LinkRegexConfig.mm +37 -0
  86. package/ios/{utils → interfaces}/MentionStyleProps.mm +2 -2
  87. package/ios/{utils → interfaces}/StyleHeaders.h +10 -0
  88. package/ios/{utils → interfaces}/StyleTypeEnum.h +3 -0
  89. package/ios/styles/BlockQuoteStyle.mm +5 -5
  90. package/ios/styles/BoldStyle.mm +21 -6
  91. package/ios/styles/CodeBlockStyle.mm +5 -5
  92. package/ios/styles/H4Style.mm +17 -0
  93. package/ios/styles/H5Style.mm +17 -0
  94. package/ios/styles/H6Style.mm +17 -0
  95. package/ios/styles/HeadingStyleBase.mm +27 -10
  96. package/ios/styles/ImageStyle.mm +5 -5
  97. package/ios/styles/InlineCodeStyle.mm +30 -19
  98. package/ios/styles/ItalicStyle.mm +5 -5
  99. package/ios/styles/LinkStyle.mm +98 -40
  100. package/ios/styles/MentionStyle.mm +4 -4
  101. package/ios/styles/OrderedListStyle.mm +5 -5
  102. package/ios/styles/StrikethroughStyle.mm +5 -5
  103. package/ios/styles/UnderlineStyle.mm +5 -5
  104. package/ios/styles/UnorderedListStyle.mm +5 -5
  105. package/ios/utils/ParagraphAttributesUtils.h +4 -0
  106. package/ios/utils/ParagraphAttributesUtils.mm +67 -0
  107. package/ios/utils/ParagraphsUtils.mm +4 -4
  108. package/lib/module/EnrichedTextInput.js +22 -1
  109. package/lib/module/EnrichedTextInput.js.map +1 -1
  110. package/lib/module/EnrichedTextInputNativeComponent.ts +138 -12
  111. package/lib/module/{normalizeHtmlStyle.js → utils/normalizeHtmlStyle.js} +12 -0
  112. package/lib/module/utils/normalizeHtmlStyle.js.map +1 -0
  113. package/lib/module/utils/regexParser.js +46 -0
  114. package/lib/module/utils/regexParser.js.map +1 -0
  115. package/lib/typescript/src/EnrichedTextInput.d.ts +23 -14
  116. package/lib/typescript/src/EnrichedTextInput.d.ts.map +1 -1
  117. package/lib/typescript/src/EnrichedTextInputNativeComponent.d.ts +123 -12
  118. package/lib/typescript/src/EnrichedTextInputNativeComponent.d.ts.map +1 -1
  119. package/lib/typescript/src/index.d.ts +1 -1
  120. package/lib/typescript/src/index.d.ts.map +1 -1
  121. package/lib/typescript/src/utils/normalizeHtmlStyle.d.ts +4 -0
  122. package/lib/typescript/src/utils/normalizeHtmlStyle.d.ts.map +1 -0
  123. package/lib/typescript/src/utils/regexParser.d.ts +3 -0
  124. package/lib/typescript/src/utils/regexParser.d.ts.map +1 -0
  125. package/package.json +10 -6
  126. package/src/EnrichedTextInput.tsx +51 -13
  127. package/src/EnrichedTextInputNativeComponent.ts +138 -12
  128. package/src/index.tsx +2 -0
  129. package/src/{normalizeHtmlStyle.ts → utils/normalizeHtmlStyle.ts} +14 -2
  130. package/src/utils/regexParser.ts +56 -0
  131. package/lib/module/normalizeHtmlStyle.js.map +0 -1
  132. package/lib/typescript/src/normalizeHtmlStyle.d.ts +0 -4
  133. package/lib/typescript/src/normalizeHtmlStyle.d.ts.map +0 -1
  134. /package/ios/{utils → extensions}/ColorExtension.h +0 -0
  135. /package/ios/{utils → extensions}/ColorExtension.mm +0 -0
  136. /package/ios/{utils → extensions}/FontExtension.h +0 -0
  137. /package/ios/{utils → extensions}/FontExtension.mm +0 -0
  138. /package/ios/{utils → extensions}/LayoutManagerExtension.h +0 -0
  139. /package/ios/{utils → extensions}/LayoutManagerExtension.mm +0 -0
  140. /package/ios/{utils → extensions}/StringExtension.h +0 -0
  141. /package/ios/{utils → extensions}/StringExtension.mm +0 -0
  142. /package/ios/{utils → interfaces}/BaseStyleProtocol.h +0 -0
  143. /package/ios/{attachments → interfaces}/ImageAttachment.h +0 -0
  144. /package/ios/{utils → interfaces}/ImageData.h +0 -0
  145. /package/ios/{utils → interfaces}/ImageData.mm +0 -0
  146. /package/ios/{utils → interfaces}/LinkData.h +0 -0
  147. /package/ios/{utils → interfaces}/LinkData.mm +0 -0
  148. /package/ios/{attachments → interfaces}/MediaAttachment.h +0 -0
  149. /package/ios/{attachments → interfaces}/MediaAttachment.mm +0 -0
  150. /package/ios/{utils → interfaces}/MentionParams.h +0 -0
  151. /package/ios/{utils → interfaces}/MentionParams.mm +0 -0
  152. /package/ios/{utils → interfaces}/MentionStyleProps.h +0 -0
  153. /package/ios/{utils → interfaces}/StylePair.h +0 -0
  154. /package/ios/{utils → interfaces}/StylePair.mm +0 -0
  155. /package/ios/{utils → interfaces}/TextDecorationLineEnum.h +0 -0
  156. /package/ios/{utils → interfaces}/TextDecorationLineEnum.mm +0 -0
@@ -15,12 +15,14 @@ import com.facebook.react.uimanager.annotations.ReactProp
15
15
  import com.facebook.react.viewmanagers.EnrichedTextInputViewManagerDelegate
16
16
  import com.facebook.react.viewmanagers.EnrichedTextInputViewManagerInterface
17
17
  import com.facebook.yoga.YogaMeasureMode
18
- import com.swmansion.enriched.events.OnInputBlurEvent
19
18
  import com.swmansion.enriched.events.OnChangeHtmlEvent
20
19
  import com.swmansion.enriched.events.OnChangeSelectionEvent
20
+ import com.swmansion.enriched.events.OnChangeStateDeprecatedEvent
21
21
  import com.swmansion.enriched.events.OnChangeStateEvent
22
22
  import com.swmansion.enriched.events.OnChangeTextEvent
23
+ import com.swmansion.enriched.events.OnInputBlurEvent
23
24
  import com.swmansion.enriched.events.OnInputFocusEvent
25
+ import com.swmansion.enriched.events.OnInputKeyPressEvent
24
26
  import com.swmansion.enriched.events.OnLinkDetectedEvent
25
27
  import com.swmansion.enriched.events.OnMentionDetectedEvent
26
28
  import com.swmansion.enriched.events.OnMentionEvent
@@ -30,22 +32,17 @@ import com.swmansion.enriched.styles.HtmlStyle
30
32
  import com.swmansion.enriched.utils.jsonStringToStringMap
31
33
 
32
34
  @ReactModule(name = EnrichedTextInputViewManager.NAME)
33
- class EnrichedTextInputViewManager : SimpleViewManager<EnrichedTextInputView>(),
35
+ class EnrichedTextInputViewManager :
36
+ SimpleViewManager<EnrichedTextInputView>(),
34
37
  EnrichedTextInputViewManagerInterface<EnrichedTextInputView> {
35
38
  private val mDelegate: ViewManagerDelegate<EnrichedTextInputView> =
36
39
  EnrichedTextInputViewManagerDelegate(this)
37
40
 
38
- override fun getDelegate(): ViewManagerDelegate<EnrichedTextInputView>? {
39
- return mDelegate
40
- }
41
+ override fun getDelegate(): ViewManagerDelegate<EnrichedTextInputView>? = mDelegate
41
42
 
42
- override fun getName(): String {
43
- return NAME
44
- }
43
+ override fun getName(): String = NAME
45
44
 
46
- public override fun createViewInstance(context: ThemedReactContext): EnrichedTextInputView {
47
- return EnrichedTextInputView(context)
48
- }
45
+ public override fun createViewInstance(context: ThemedReactContext): EnrichedTextInputView = EnrichedTextInputView(context)
49
46
 
50
47
  override fun onDropViewInstance(view: EnrichedTextInputView) {
51
48
  super.onDropViewInstance(view)
@@ -55,65 +52,91 @@ class EnrichedTextInputViewManager : SimpleViewManager<EnrichedTextInputView>(),
55
52
  override fun updateState(
56
53
  view: EnrichedTextInputView,
57
54
  props: ReactStylesDiffMap?,
58
- stateWrapper: StateWrapper?
55
+ stateWrapper: StateWrapper?,
59
56
  ): Any? {
60
57
  view.stateWrapper = stateWrapper
61
58
  return super.updateState(view, props, stateWrapper)
62
59
  }
63
60
 
64
- override fun getExportedCustomDirectEventTypeConstants(): MutableMap<String, Any> {
65
- val map = mutableMapOf<String, Any>()
66
- map.put(OnInputFocusEvent.EVENT_NAME, mapOf("registrationName" to OnInputFocusEvent.EVENT_NAME))
67
- map.put(OnInputBlurEvent.EVENT_NAME, mapOf("registrationName" to OnInputBlurEvent.EVENT_NAME))
68
- map.put(OnChangeTextEvent.EVENT_NAME, mapOf("registrationName" to OnChangeTextEvent.EVENT_NAME))
69
- map.put(OnChangeHtmlEvent.EVENT_NAME, mapOf("registrationName" to OnChangeHtmlEvent.EVENT_NAME))
70
- map.put(OnChangeStateEvent.EVENT_NAME, mapOf("registrationName" to OnChangeStateEvent.EVENT_NAME))
71
- map.put(OnLinkDetectedEvent.EVENT_NAME, mapOf("registrationName" to OnLinkDetectedEvent.EVENT_NAME))
72
- map.put(OnMentionDetectedEvent.EVENT_NAME, mapOf("registrationName" to OnMentionDetectedEvent.EVENT_NAME))
73
- map.put(OnMentionEvent.EVENT_NAME, mapOf("registrationName" to OnMentionEvent.EVENT_NAME))
74
- map.put(OnChangeSelectionEvent.EVENT_NAME, mapOf("registrationName" to OnChangeSelectionEvent.EVENT_NAME))
75
- map.put(OnRequestHtmlResultEvent.EVENT_NAME, mapOf("registrationName" to OnRequestHtmlResultEvent.EVENT_NAME))
61
+ override fun getExportedCustomDirectEventTypeConstants(): MutableMap<String, Any> {
62
+ val map = mutableMapOf<String, Any>()
63
+ map.put(OnInputFocusEvent.EVENT_NAME, mapOf("registrationName" to OnInputFocusEvent.EVENT_NAME))
64
+ map.put(OnInputBlurEvent.EVENT_NAME, mapOf("registrationName" to OnInputBlurEvent.EVENT_NAME))
65
+ map.put(OnChangeTextEvent.EVENT_NAME, mapOf("registrationName" to OnChangeTextEvent.EVENT_NAME))
66
+ map.put(OnChangeHtmlEvent.EVENT_NAME, mapOf("registrationName" to OnChangeHtmlEvent.EVENT_NAME))
67
+ map.put(OnChangeStateEvent.EVENT_NAME, mapOf("registrationName" to OnChangeStateEvent.EVENT_NAME))
68
+ map.put(OnChangeStateDeprecatedEvent.EVENT_NAME, mapOf("registrationName" to OnChangeStateDeprecatedEvent.EVENT_NAME))
69
+ map.put(OnLinkDetectedEvent.EVENT_NAME, mapOf("registrationName" to OnLinkDetectedEvent.EVENT_NAME))
70
+ map.put(OnMentionDetectedEvent.EVENT_NAME, mapOf("registrationName" to OnMentionDetectedEvent.EVENT_NAME))
71
+ map.put(OnMentionEvent.EVENT_NAME, mapOf("registrationName" to OnMentionEvent.EVENT_NAME))
72
+ map.put(OnChangeSelectionEvent.EVENT_NAME, mapOf("registrationName" to OnChangeSelectionEvent.EVENT_NAME))
73
+ map.put(OnRequestHtmlResultEvent.EVENT_NAME, mapOf("registrationName" to OnRequestHtmlResultEvent.EVENT_NAME))
74
+ map.put(OnInputKeyPressEvent.EVENT_NAME, mapOf("registrationName" to OnInputKeyPressEvent.EVENT_NAME))
76
75
 
77
- return map
78
- }
76
+ return map
77
+ }
79
78
 
80
79
  @ReactProp(name = "defaultValue")
81
- override fun setDefaultValue(view: EnrichedTextInputView?, value: String?) {
80
+ override fun setDefaultValue(
81
+ view: EnrichedTextInputView?,
82
+ value: String?,
83
+ ) {
82
84
  view?.setDefaultValue(value)
83
85
  }
84
86
 
85
87
  @ReactProp(name = "placeholder")
86
- override fun setPlaceholder(view: EnrichedTextInputView?, value: String?) {
88
+ override fun setPlaceholder(
89
+ view: EnrichedTextInputView?,
90
+ value: String?,
91
+ ) {
87
92
  view?.setPlaceholder(value)
88
93
  }
89
94
 
90
95
  @ReactProp(name = "placeholderTextColor", customType = "Color")
91
- override fun setPlaceholderTextColor(view: EnrichedTextInputView?, color: Int?) {
96
+ override fun setPlaceholderTextColor(
97
+ view: EnrichedTextInputView?,
98
+ color: Int?,
99
+ ) {
92
100
  view?.setPlaceholderTextColor(color)
93
101
  }
94
102
 
95
103
  @ReactProp(name = "cursorColor", customType = "Color")
96
- override fun setCursorColor(view: EnrichedTextInputView?, color: Int?) {
104
+ override fun setCursorColor(
105
+ view: EnrichedTextInputView?,
106
+ color: Int?,
107
+ ) {
97
108
  view?.setCursorColor(color)
98
109
  }
99
110
 
100
111
  @ReactProp(name = "selectionColor", customType = "Color")
101
- override fun setSelectionColor(view: EnrichedTextInputView?, color: Int?) {
112
+ override fun setSelectionColor(
113
+ view: EnrichedTextInputView?,
114
+ color: Int?,
115
+ ) {
102
116
  view?.setSelectionColor(color)
103
117
  }
104
118
 
105
119
  @ReactProp(name = "autoFocus", defaultBoolean = false)
106
- override fun setAutoFocus(view: EnrichedTextInputView?, autoFocus: Boolean) {
120
+ override fun setAutoFocus(
121
+ view: EnrichedTextInputView?,
122
+ autoFocus: Boolean,
123
+ ) {
107
124
  view?.setAutoFocus(autoFocus)
108
125
  }
109
126
 
110
127
  @ReactProp(name = "editable", defaultBoolean = true)
111
- override fun setEditable(view: EnrichedTextInputView?, editable: Boolean) {
128
+ override fun setEditable(
129
+ view: EnrichedTextInputView?,
130
+ editable: Boolean,
131
+ ) {
112
132
  view?.isEnabled = editable
113
133
  }
114
134
 
115
135
  @ReactProp(name = "mentionIndicators")
116
- override fun setMentionIndicators(view: EnrichedTextInputView?, indicators: ReadableArray?) {
136
+ override fun setMentionIndicators(
137
+ view: EnrichedTextInputView?,
138
+ indicators: ReadableArray?,
139
+ ) {
117
140
  if (indicators == null) return
118
141
 
119
142
  val indicatorsList = mutableListOf<String>()
@@ -127,37 +150,58 @@ class EnrichedTextInputViewManager : SimpleViewManager<EnrichedTextInputView>(),
127
150
  }
128
151
 
129
152
  @ReactProp(name = "htmlStyle")
130
- override fun setHtmlStyle(view: EnrichedTextInputView?, style: ReadableMap?) {
153
+ override fun setHtmlStyle(
154
+ view: EnrichedTextInputView?,
155
+ style: ReadableMap?,
156
+ ) {
131
157
  view?.htmlStyle = HtmlStyle(view, style)
132
158
  }
133
159
 
134
160
  @ReactProp(name = ViewProps.COLOR, customType = "Color")
135
- override fun setColor(view: EnrichedTextInputView?, color: Int?) {
161
+ override fun setColor(
162
+ view: EnrichedTextInputView?,
163
+ color: Int?,
164
+ ) {
136
165
  view?.setColor(color)
137
166
  }
138
167
 
139
168
  @ReactProp(name = "fontSize", defaultFloat = ViewDefaults.FONT_SIZE_SP)
140
- override fun setFontSize(view: EnrichedTextInputView?, size: Float) {
169
+ override fun setFontSize(
170
+ view: EnrichedTextInputView?,
171
+ size: Float,
172
+ ) {
141
173
  view?.setFontSize(size)
142
174
  }
143
175
 
144
176
  @ReactProp(name = "fontFamily")
145
- override fun setFontFamily(view: EnrichedTextInputView?, family: String?) {
177
+ override fun setFontFamily(
178
+ view: EnrichedTextInputView?,
179
+ family: String?,
180
+ ) {
146
181
  view?.setFontFamily(family)
147
182
  }
148
183
 
149
184
  @ReactProp(name = "fontWeight")
150
- override fun setFontWeight(view: EnrichedTextInputView?, weight: String?) {
185
+ override fun setFontWeight(
186
+ view: EnrichedTextInputView?,
187
+ weight: String?,
188
+ ) {
151
189
  view?.setFontWeight(weight)
152
190
  }
153
191
 
154
192
  @ReactProp(name = "fontStyle")
155
- override fun setFontStyle(view: EnrichedTextInputView?, style: String?) {
193
+ override fun setFontStyle(
194
+ view: EnrichedTextInputView?,
195
+ style: String?,
196
+ ) {
156
197
  view?.setFontStyle(style)
157
198
  }
158
199
 
159
200
  @ReactProp(name = "scrollEnabled")
160
- override fun setScrollEnabled(view: EnrichedTextInputView, scrollEnabled: Boolean) {
201
+ override fun setScrollEnabled(
202
+ view: EnrichedTextInputView,
203
+ scrollEnabled: Boolean,
204
+ ) {
161
205
  view.scrollEnabled = scrollEnabled
162
206
  }
163
207
 
@@ -171,24 +215,44 @@ class EnrichedTextInputViewManager : SimpleViewManager<EnrichedTextInputView>(),
171
215
  left: Int,
172
216
  top: Int,
173
217
  right: Int,
174
- bottom: Int
218
+ bottom: Int,
175
219
  ) {
176
220
  super.setPadding(view, left, top, right, bottom)
177
221
 
178
222
  view?.setPadding(left, top, right, bottom)
179
223
  }
180
224
 
181
- override fun setIsOnChangeHtmlSet(view: EnrichedTextInputView?, value: Boolean) {
225
+ override fun setIsOnChangeHtmlSet(
226
+ view: EnrichedTextInputView?,
227
+ value: Boolean,
228
+ ) {
182
229
  view?.shouldEmitHtml = value
183
230
  }
184
231
 
185
- override fun setAutoCapitalize(view: EnrichedTextInputView?, flag: String?) {
232
+ override fun setIsOnChangeTextSet(
233
+ view: EnrichedTextInputView?,
234
+ value: Boolean,
235
+ ) {
236
+ view?.shouldEmitOnChangeText = value
237
+ }
238
+
239
+ override fun setAutoCapitalize(
240
+ view: EnrichedTextInputView?,
241
+ flag: String?,
242
+ ) {
186
243
  view?.setAutoCapitalize(flag)
187
244
  }
188
245
 
246
+ override fun setLinkRegex(
247
+ view: EnrichedTextInputView?,
248
+ config: ReadableMap?,
249
+ ) {
250
+ view?.setLinkRegex(config)
251
+ }
252
+
189
253
  override fun setAndroidExperimentalSynchronousEvents(
190
254
  view: EnrichedTextInputView?,
191
- value: Boolean
255
+ value: Boolean,
192
256
  ) {
193
257
  view?.experimentalSynchronousEvents = value
194
258
  }
@@ -201,10 +265,21 @@ class EnrichedTextInputViewManager : SimpleViewManager<EnrichedTextInputView>(),
201
265
  view?.clearFocus()
202
266
  }
203
267
 
204
- override fun setValue(view: EnrichedTextInputView?, text: String) {
268
+ override fun setValue(
269
+ view: EnrichedTextInputView?,
270
+ text: String,
271
+ ) {
205
272
  view?.setValue(text)
206
273
  }
207
274
 
275
+ override fun setSelection(
276
+ view: EnrichedTextInputView?,
277
+ start: Int,
278
+ end: Int,
279
+ ) {
280
+ view?.setCustomSelection(start, end)
281
+ }
282
+
208
283
  override fun toggleBold(view: EnrichedTextInputView?) {
209
284
  view?.verifyAndToggleStyle(EnrichedSpans.BOLD)
210
285
  }
@@ -237,6 +312,18 @@ class EnrichedTextInputViewManager : SimpleViewManager<EnrichedTextInputView>(),
237
312
  view?.verifyAndToggleStyle(EnrichedSpans.H3)
238
313
  }
239
314
 
315
+ override fun toggleH4(view: EnrichedTextInputView?) {
316
+ view?.verifyAndToggleStyle(EnrichedSpans.H4)
317
+ }
318
+
319
+ override fun toggleH5(view: EnrichedTextInputView?) {
320
+ view?.verifyAndToggleStyle(EnrichedSpans.H5)
321
+ }
322
+
323
+ override fun toggleH6(view: EnrichedTextInputView?) {
324
+ view?.verifyAndToggleStyle(EnrichedSpans.H6)
325
+ }
326
+
240
327
  override fun toggleCodeBlock(view: EnrichedTextInputView?) {
241
328
  view?.verifyAndToggleStyle(EnrichedSpans.CODE_BLOCK)
242
329
  }
@@ -253,24 +340,46 @@ class EnrichedTextInputViewManager : SimpleViewManager<EnrichedTextInputView>(),
253
340
  view?.verifyAndToggleStyle(EnrichedSpans.UNORDERED_LIST)
254
341
  }
255
342
 
256
- override fun addLink(view: EnrichedTextInputView?, start: Int, end: Int, text: String, url: String) {
343
+ override fun addLink(
344
+ view: EnrichedTextInputView?,
345
+ start: Int,
346
+ end: Int,
347
+ text: String,
348
+ url: String,
349
+ ) {
257
350
  view?.addLink(start, end, text, url)
258
351
  }
259
352
 
260
- override fun addImage(view: EnrichedTextInputView?, src: String, width: Float, height: Float) {
353
+ override fun addImage(
354
+ view: EnrichedTextInputView?,
355
+ src: String,
356
+ width: Float,
357
+ height: Float,
358
+ ) {
261
359
  view?.addImage(src, width, height)
262
360
  }
263
361
 
264
- override fun startMention(view: EnrichedTextInputView?, indicator: String) {
362
+ override fun startMention(
363
+ view: EnrichedTextInputView?,
364
+ indicator: String,
365
+ ) {
265
366
  view?.startMention(indicator)
266
367
  }
267
368
 
268
- override fun addMention(view: EnrichedTextInputView?, indicator: String, text: String, payload: String) {
369
+ override fun addMention(
370
+ view: EnrichedTextInputView?,
371
+ indicator: String,
372
+ text: String,
373
+ payload: String,
374
+ ) {
269
375
  val attributes = jsonStringToStringMap(payload)
270
376
  view?.addMention(text, indicator, attributes)
271
377
  }
272
378
 
273
- override fun requestHTML(view: EnrichedTextInputView?, requestId: Int) {
379
+ override fun requestHTML(
380
+ view: EnrichedTextInputView?,
381
+ requestId: Int,
382
+ ) {
274
383
  view?.requestHTML(requestId)
275
384
  }
276
385
 
@@ -283,10 +392,10 @@ class EnrichedTextInputViewManager : SimpleViewManager<EnrichedTextInputView>(),
283
392
  widthMode: YogaMeasureMode?,
284
393
  height: Float,
285
394
  heightMode: YogaMeasureMode?,
286
- attachmentsPositions: FloatArray?
395
+ attachmentsPositions: FloatArray?,
287
396
  ): Long {
288
397
  val id = localData?.getInt("viewTag")
289
- return MeasurementStore.getMeasureById(context, id, width, props)
398
+ return MeasurementStore.getMeasureById(context, id, width, height, heightMode, props)
290
399
  }
291
400
 
292
401
  companion object {
@@ -15,7 +15,5 @@ class EnrichedTextInputViewPackage : ReactPackage {
15
15
  return viewManagers
16
16
  }
17
17
 
18
- override fun createNativeModules(reactContext: ReactApplicationContext): List<NativeModule> {
19
- return emptyList()
20
- }
18
+ override fun createNativeModules(reactContext: ReactApplicationContext): List<NativeModule> = emptyList()
21
19
  }
@@ -13,6 +13,7 @@ import com.facebook.react.uimanager.PixelUtil
13
13
  import com.facebook.react.views.text.ReactTypefaceUtils.applyStyles
14
14
  import com.facebook.react.views.text.ReactTypefaceUtils.parseFontStyle
15
15
  import com.facebook.react.views.text.ReactTypefaceUtils.parseFontWeight
16
+ import com.facebook.yoga.YogaMeasureMode
16
17
  import com.facebook.yoga.YogaMeasureOutput
17
18
  import com.swmansion.enriched.styles.HtmlStyle
18
19
  import com.swmansion.enriched.utils.EnrichedParser
@@ -27,17 +28,19 @@ object MeasurementStore {
27
28
 
28
29
  data class MeasurementParams(
29
30
  val initialized: Boolean,
30
-
31
31
  val cachedWidth: Float,
32
32
  val cachedSize: Long,
33
-
34
33
  val spannable: CharSequence?,
35
34
  val paintParams: PaintParams,
36
35
  )
37
36
 
38
37
  private val data = ConcurrentHashMap<Int, MeasurementParams>()
39
38
 
40
- fun store(id: Int, spannable: Spannable?, paint: TextPaint): Boolean {
39
+ fun store(
40
+ id: Int,
41
+ spannable: Spannable?,
42
+ paint: TextPaint,
43
+ ): Boolean {
41
44
  val cachedWidth = data[id]?.cachedWidth ?: 0f
42
45
  val cachedSize = data[id]?.cachedSize ?: 0L
43
46
  val initialized = data[id]?.initialized ?: true
@@ -53,22 +56,32 @@ object MeasurementStore {
53
56
  data.remove(id)
54
57
  }
55
58
 
56
- private fun measure(maxWidth: Float, spannable: CharSequence?, paintParams: PaintParams): Long {
57
- val paint = TextPaint().apply {
58
- typeface = paintParams.typeface
59
- textSize = paintParams.fontSize
60
- }
59
+ private fun measure(
60
+ maxWidth: Float,
61
+ spannable: CharSequence?,
62
+ paintParams: PaintParams,
63
+ ): Long {
64
+ val paint =
65
+ TextPaint().apply {
66
+ typeface = paintParams.typeface
67
+ textSize = paintParams.fontSize
68
+ }
61
69
 
62
70
  return measure(maxWidth, spannable, paint)
63
71
  }
64
72
 
65
- private fun measure(maxWidth: Float, spannable: CharSequence?, paint: TextPaint): Long {
73
+ private fun measure(
74
+ maxWidth: Float,
75
+ spannable: CharSequence?,
76
+ paint: TextPaint,
77
+ ): Long {
66
78
  val text = spannable ?: ""
67
79
  val textLength = text.length
68
- val builder = StaticLayout.Builder
69
- .obtain(text, 0, textLength, paint, maxWidth.toInt())
70
- .setIncludePad(true)
71
- .setLineSpacing(0f, 1f)
80
+ val builder =
81
+ StaticLayout.Builder
82
+ .obtain(text, 0, textLength, paint, maxWidth.toInt())
83
+ .setIncludePad(true)
84
+ .setLineSpacing(0f, 1f)
72
85
 
73
86
  if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
74
87
  builder.setBreakStrategy(LineBreaker.BREAK_STRATEGY_HIGH_QUALITY)
@@ -85,7 +98,10 @@ object MeasurementStore {
85
98
  }
86
99
 
87
100
  // Returns either: Spannable parsed from HTML defaultValue, or plain text defaultValue, or "I" if no defaultValue
88
- private fun getInitialText(defaultView: EnrichedTextInputView, props: ReadableMap?): CharSequence {
101
+ private fun getInitialText(
102
+ defaultView: EnrichedTextInputView,
103
+ props: ReadableMap?,
104
+ ): CharSequence {
89
105
  val defaultValue = props?.getString("defaultValue")
90
106
 
91
107
  // If there is no default value, assume text is one line, "I" is a good approximation of height
@@ -104,7 +120,10 @@ object MeasurementStore {
104
120
  }
105
121
  }
106
122
 
107
- private fun getInitialFontSize(defaultView: EnrichedTextInputView, props: ReadableMap?): Float {
123
+ private fun getInitialFontSize(
124
+ defaultView: EnrichedTextInputView,
125
+ props: ReadableMap?,
126
+ ): Float {
108
127
  val propsFontSize = props?.getDouble("fontSize")?.toFloat()
109
128
  if (propsFontSize == null) return defaultView.textSize
110
129
 
@@ -113,7 +132,12 @@ object MeasurementStore {
113
132
 
114
133
  // Called when view measurements are not available in the store
115
134
  // Most likely first measurement, we can use defaultValue, as no native state is set yet
116
- private fun initialMeasure(context: Context, id: Int?, width: Float, props: ReadableMap?): Long {
135
+ private fun initialMeasure(
136
+ context: Context,
137
+ id: Int?,
138
+ width: Float,
139
+ props: ReadableMap?,
140
+ ): Long {
117
141
  val defaultView = EnrichedTextInputView(context)
118
142
 
119
143
  val text = getInitialText(defaultView, props)
@@ -134,7 +158,12 @@ object MeasurementStore {
134
158
  return size
135
159
  }
136
160
 
137
- fun getMeasureById(context: Context, id: Int?, width: Float, props: ReadableMap?): Long {
161
+ private fun getMeasureById(
162
+ context: Context,
163
+ id: Int?,
164
+ width: Float,
165
+ props: ReadableMap?,
166
+ ): Long {
138
167
  val id = id ?: return initialMeasure(context, id, width, props)
139
168
  val value = data[id] ?: return initialMeasure(context, id, width, props)
140
169
 
@@ -146,13 +175,33 @@ object MeasurementStore {
146
175
  return value.cachedSize
147
176
  }
148
177
 
149
- val paint = TextPaint().apply {
150
- typeface = value.paintParams.typeface
151
- textSize = value.paintParams.fontSize
152
- }
178
+ val paint =
179
+ TextPaint().apply {
180
+ typeface = value.paintParams.typeface
181
+ textSize = value.paintParams.fontSize
182
+ }
153
183
 
154
184
  val size = measure(width, value.spannable, paint)
155
185
  data[id] = MeasurementParams(true, width, size, value.spannable, value.paintParams)
156
186
  return size
157
187
  }
188
+
189
+ fun getMeasureById(
190
+ context: Context,
191
+ id: Int?,
192
+ width: Float,
193
+ height: Float,
194
+ heightMode: YogaMeasureMode?,
195
+ props: ReadableMap?,
196
+ ): Long {
197
+ val size = getMeasureById(context, id, width, props)
198
+ if (heightMode !== YogaMeasureMode.AT_MOST) {
199
+ return size
200
+ }
201
+
202
+ val calculatedHeight = YogaMeasureOutput.getHeight(size)
203
+ val atMostHeight = PixelUtil.toDIPFromPixel(height)
204
+ val finalHeight = calculatedHeight.coerceAtMost(atMostHeight)
205
+ return YogaMeasureOutput.make(YogaMeasureOutput.getWidth(size), finalHeight)
206
+ }
158
207
  }
@@ -4,7 +4,9 @@ import com.facebook.react.bridge.ReactContext
4
4
  import com.facebook.react.uimanager.UIManagerHelper
5
5
  import com.swmansion.enriched.EnrichedTextInputView
6
6
 
7
- class MentionHandler(private val view: EnrichedTextInputView) {
7
+ class MentionHandler(
8
+ private val view: EnrichedTextInputView,
9
+ ) {
8
10
  private var previousText: String? = null
9
11
  private var previousIndicator: String? = null
10
12
 
@@ -21,12 +23,18 @@ class MentionHandler(private val view: EnrichedTextInputView) {
21
23
  previousIndicator = null
22
24
  }
23
25
 
24
- fun onMention(indicator: String, text: String?) {
26
+ fun onMention(
27
+ indicator: String,
28
+ text: String?,
29
+ ) {
25
30
  emitEvent(indicator, text)
26
31
  previousIndicator = indicator
27
32
  }
28
33
 
29
- private fun emitEvent(indicator: String, text: String?) {
34
+ private fun emitEvent(
35
+ indicator: String,
36
+ text: String?,
37
+ ) {
30
38
  // Do not emit events too often
31
39
  if (previousText == text) return
32
40
 
@@ -34,12 +42,14 @@ class MentionHandler(private val view: EnrichedTextInputView) {
34
42
  val context = view.context as ReactContext
35
43
  val surfaceId = UIManagerHelper.getSurfaceId(context)
36
44
  val dispatcher = UIManagerHelper.getEventDispatcherForReactTag(context, view.id)
37
- dispatcher?.dispatchEvent(OnMentionEvent(
38
- surfaceId,
39
- view.id,
40
- indicator,
41
- text,
42
- view.experimentalSynchronousEvents,
43
- ))
45
+ dispatcher?.dispatchEvent(
46
+ OnMentionEvent(
47
+ surfaceId,
48
+ view.id,
49
+ indicator,
50
+ text,
51
+ view.experimentalSynchronousEvents,
52
+ ),
53
+ )
44
54
  }
45
55
  }
@@ -4,12 +4,13 @@ import com.facebook.react.bridge.Arguments
4
4
  import com.facebook.react.bridge.WritableMap
5
5
  import com.facebook.react.uimanager.events.Event
6
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
- }
7
+ class OnChangeHtmlEvent(
8
+ surfaceId: Int,
9
+ viewId: Int,
10
+ private val html: String,
11
+ private val experimentalSynchronousEvents: Boolean,
12
+ ) : Event<OnChangeHtmlEvent>(surfaceId, viewId) {
13
+ override fun getEventName(): String = EVENT_NAME
13
14
 
14
15
  override fun getEventData(): WritableMap {
15
16
  val eventData: WritableMap = Arguments.createMap()
@@ -18,9 +19,7 @@ class OnChangeHtmlEvent(surfaceId: Int, viewId: Int, private val html: String, p
18
19
  return eventData
19
20
  }
20
21
 
21
- override fun experimental_isSynchronous(): Boolean {
22
- return experimentalSynchronousEvents
23
- }
22
+ override fun experimental_isSynchronous(): Boolean = experimentalSynchronousEvents
24
23
 
25
24
  companion object {
26
25
  const val EVENT_NAME: String = "onChangeHtml"
@@ -4,12 +4,15 @@ import com.facebook.react.bridge.Arguments
4
4
  import com.facebook.react.bridge.WritableMap
5
5
  import com.facebook.react.uimanager.events.Event
6
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
- }
7
+ class OnChangeSelectionEvent(
8
+ surfaceId: Int,
9
+ viewId: Int,
10
+ private val text: String,
11
+ private val start: Int,
12
+ private val end: Int,
13
+ private val experimentalSynchronousEvents: Boolean,
14
+ ) : Event<OnChangeSelectionEvent>(surfaceId, viewId) {
15
+ override fun getEventName(): String = EVENT_NAME
13
16
 
14
17
  override fun getEventData(): WritableMap {
15
18
  val eventData: WritableMap = Arguments.createMap()
@@ -19,9 +22,7 @@ class OnChangeSelectionEvent(surfaceId: Int, viewId: Int, private val text: Stri
19
22
  return eventData
20
23
  }
21
24
 
22
- override fun experimental_isSynchronous(): Boolean {
23
- return experimentalSynchronousEvents
24
- }
25
+ override fun experimental_isSynchronous(): Boolean = experimentalSynchronousEvents
25
26
 
26
27
  companion object {
27
28
  const val EVENT_NAME: String = "onChangeSelection"