react-native-advanced-text 0.1.8 → 0.1.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -9,9 +9,11 @@ import android.text.TextPaint
9
9
  import android.text.method.LinkMovementMethod
10
10
  import android.text.style.ClickableSpan
11
11
  import android.text.style.BackgroundColorSpan
12
+ import android.text.style.ForegroundColorSpan
12
13
  import android.util.AttributeSet
13
14
  import android.util.Log
14
- import android.view.ContextMenu
15
+ import android.view.ActionMode
16
+ import android.view.Menu
15
17
  import android.view.MenuItem
16
18
  import android.view.View
17
19
  import android.widget.TextView
@@ -20,7 +22,7 @@ import com.facebook.react.bridge.ReactContext
20
22
  import com.facebook.react.uimanager.events.RCTEventEmitter
21
23
  import android.text.Selection
22
24
 
23
- class AdvancedTextView : TextView, View.OnCreateContextMenuListener {
25
+ class AdvancedTextView : TextView {
24
26
 
25
27
  private val TAG = "AdvancedTextView"
26
28
 
@@ -28,7 +30,7 @@ class AdvancedTextView : TextView, View.OnCreateContextMenuListener {
28
30
  private var menuOptions: List<String> = emptyList()
29
31
  private var indicatorWordIndex: Int = -1
30
32
  private var lastSelectedText: String = ""
31
- private var isSelectionEnabled: Boolean = true
33
+ private var customActionMode: ActionMode? = null
32
34
 
33
35
  constructor(context: Context?) : super(context) { init() }
34
36
  constructor(context: Context?, attrs: AttributeSet?) : super(context, attrs) { init() }
@@ -37,24 +39,65 @@ class AdvancedTextView : TextView, View.OnCreateContextMenuListener {
37
39
  private fun init() {
38
40
  Log.d(TAG, "AdvancedTextView initialized")
39
41
 
40
- // Set default text appearance
41
- setTextColor(Color.BLACK)
42
+ // Set default text appearance - DON'T set black color here
42
43
  textSize = 16f
43
44
  setPadding(16, 16, 16, 16)
44
45
 
45
46
  movementMethod = LinkMovementMethod.getInstance()
46
47
  setTextIsSelectable(true)
47
- setOnCreateContextMenuListener(this)
48
48
 
49
- // Ensure minimum height for visibility during debugging
50
- minHeight = 100
49
+ // Use custom action mode for selection menu
50
+ customSelectionActionModeCallback = object : ActionMode.Callback {
51
+ override fun onCreateActionMode(mode: ActionMode?, menu: Menu?): Boolean {
52
+ Log.d(TAG, "onCreateActionMode triggered")
53
+ customActionMode = mode
54
+ return true
55
+ }
56
+
57
+ override fun onPrepareActionMode(mode: ActionMode?, menu: Menu?): Boolean {
58
+ Log.d(TAG, "onPrepareActionMode triggered")
59
+ menu?.clear()
60
+
61
+ val selectionStart = selectionStart
62
+ val selectionEnd = selectionEnd
63
+
64
+ if (selectionStart >= 0 && selectionEnd >= 0 && selectionStart != selectionEnd) {
65
+ lastSelectedText = text.subSequence(selectionStart, selectionEnd).toString()
66
+ Log.d(TAG, "User selected text: '$lastSelectedText'")
67
+ Log.d(TAG, "Menu options available: $menuOptions")
68
+
69
+ menuOptions.forEachIndexed { index, option ->
70
+ menu?.add(0, index, index, option)
71
+ }
72
+
73
+ sendSelectionEvent(lastSelectedText, "selection")
74
+ return true
75
+ }
76
+ return false
77
+ }
78
+
79
+ override fun onActionItemClicked(mode: ActionMode?, item: MenuItem?): Boolean {
80
+ item?.let {
81
+ val menuItemText = it.title.toString()
82
+ Log.d(TAG, "Menu item clicked: $menuItemText")
83
+ sendSelectionEvent(lastSelectedText, menuItemText)
84
+ mode?.finish()
85
+ return true
86
+ }
87
+ return false
88
+ }
89
+
90
+ override fun onDestroyActionMode(mode: ActionMode?) {
91
+ Log.d(TAG, "onDestroyActionMode")
92
+ customActionMode = null
93
+ }
94
+ }
51
95
  }
52
96
 
53
97
  fun setAdvancedText(text: String) {
54
98
  Log.d(TAG, "setAdvancedText: $text (length=${text.length})")
55
99
  this.text = text
56
100
  updateTextWithHighlights()
57
- // Force layout update
58
101
  requestLayout()
59
102
  invalidate()
60
103
  }
@@ -118,16 +161,16 @@ class AdvancedTextView : TextView, View.OnCreateContextMenuListener {
118
161
 
119
162
  if (wordIndex == indicatorWordIndex) {
120
163
  Log.d(TAG, "Applying indicator span to word '$word' at index $wordIndex")
121
-
164
+ // Apply red color to the indicator word
122
165
  spannableString.setSpan(
123
- IndicatorSpan(),
166
+ ForegroundColorSpan(Color.RED),
124
167
  wordStart,
125
168
  wordEnd,
126
169
  Spanned.SPAN_EXCLUSIVE_EXCLUSIVE
127
170
  )
128
171
  }
129
172
 
130
- // clickable span
173
+ // Make words clickable
131
174
  spannableString.setSpan(
132
175
  WordClickableSpan(wordIndex, word),
133
176
  wordStart,
@@ -144,39 +187,6 @@ class AdvancedTextView : TextView, View.OnCreateContextMenuListener {
144
187
  Log.d(TAG, "Text updated with spans")
145
188
  }
146
189
 
147
- override fun onCreateContextMenu(menu: ContextMenu?, v: View?, menuInfo: ContextMenu.ContextMenuInfo?) {
148
- val selectionStart = selectionStart
149
- val selectionEnd = selectionEnd
150
-
151
- Log.d(TAG, "onCreateContextMenu triggered. selectionStart=$selectionStart selectionEnd=$selectionEnd")
152
-
153
- if (selectionStart >= 0 && selectionEnd >= 0 && selectionStart != selectionEnd) {
154
- lastSelectedText = text.subSequence(selectionStart, selectionEnd).toString()
155
-
156
- Log.d(TAG, "User selected text: '$lastSelectedText'")
157
- Log.d(TAG, "Menu options available: $menuOptions")
158
-
159
- menu?.clear()
160
-
161
- menuOptions.forEachIndexed { index, option ->
162
- menu?.add(0, index, index, option)?.setOnMenuItemClickListener {
163
- Log.d(TAG, "Menu item clicked: $option")
164
- onMenuItemClick(it, lastSelectedText)
165
- true
166
- }
167
- }
168
-
169
- sendSelectionEvent(lastSelectedText, "selection")
170
- }
171
- }
172
-
173
- private fun onMenuItemClick(item: MenuItem, selectedText: String): Boolean {
174
- val menuItemText = menuOptions[item.itemId]
175
- Log.d(TAG, "onMenuItemClick: menuOption='$menuItemText', selectedText='$selectedText'")
176
- sendSelectionEvent(selectedText, menuItemText)
177
- return true
178
- }
179
-
180
190
  private fun sendSelectionEvent(selectedText: String, eventType: String) {
181
191
  Log.d(TAG, "sendSelectionEvent -> eventType='$eventType' selectedText='$selectedText'")
182
192
 
@@ -201,24 +211,17 @@ class AdvancedTextView : TextView, View.OnCreateContextMenuListener {
201
211
 
202
212
  override fun onClick(widget: View) {
203
213
  Log.d(TAG, "Word clicked: '$word' (index=$wordIndex)")
214
+ // Clear any selection first to prevent interference
215
+ val spannable = widget as? TextView
216
+ spannable?.let {
217
+ Selection.removeSelection(it.text as? android.text.Spannable)
218
+ }
204
219
  sendWordPressEvent(word, wordIndex)
205
220
  }
206
221
 
207
222
  override fun updateDrawState(ds: TextPaint) {
208
223
  super.updateDrawState(ds)
209
- ds.color = currentTextColor
210
- ds.isUnderlineText = false
211
- }
212
- }
213
-
214
- private inner class IndicatorSpan : ClickableSpan() {
215
- override fun onClick(widget: View) {
216
- Log.d(TAG, "IndicatorSpan clicked (shouldn't trigger action)")
217
- }
218
-
219
- override fun updateDrawState(ds: TextPaint) {
220
- ds.color = Color.RED
221
- ds.isFakeBoldText = true
224
+ // Don't change the color - let ForegroundColorSpan handle it
222
225
  ds.isUnderlineText = false
223
226
  }
224
227
  }
@@ -1,7 +1,7 @@
1
1
  // File: AdvancedTextViewManager.kt
2
- // This should be the ONLY content in this file
3
2
  package com.advancedtext
4
3
 
4
+ import android.graphics.Color
5
5
  import android.view.ViewGroup
6
6
  import com.facebook.react.bridge.ReadableArray
7
7
  import com.facebook.react.module.annotations.ReactModule
@@ -31,10 +31,10 @@ class AdvancedTextViewManager : SimpleViewManager<AdvancedTextView>(),
31
31
 
32
32
  public override fun createViewInstance(context: ThemedReactContext): AdvancedTextView {
33
33
  val view = AdvancedTextView(context)
34
- // Set default layout params to ensure the view is visible
34
+ // Set layout params for proper sizing
35
35
  view.layoutParams = ViewGroup.LayoutParams(
36
36
  ViewGroup.LayoutParams.MATCH_PARENT,
37
- ViewGroup.LayoutParams.WRAP_CONTENT
37
+ ViewGroup.LayoutParams.WRAP_CONTENT // Changed to WRAP_CONTENT for auto height
38
38
  )
39
39
  return view
40
40
  }
@@ -81,7 +81,15 @@ class AdvancedTextViewManager : SimpleViewManager<AdvancedTextView>(),
81
81
  view?.setIndicatorWordIndex(index)
82
82
  }
83
83
 
84
- // Add this method to register custom events
84
+ // Handle color prop from React Native style
85
+ @ReactProp(name = "color", customType = "Color")
86
+ fun setColor(view: AdvancedTextView?, color: Int?) {
87
+ color?.let {
88
+ view?.setTextColor(it)
89
+ }
90
+ }
91
+
92
+ // Register custom events
85
93
  override fun getExportedCustomDirectEventTypeConstants(): Map<String, Any> {
86
94
  return mapOf(
87
95
  "onWordPress" to mapOf("registrationName" to "onWordPress"),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-native-advanced-text",
3
- "version": "0.1.8",
3
+ "version": "0.1.9",
4
4
  "description": " Advanced text component for React Native with custom select options.",
5
5
  "main": "./lib/module/index.js",
6
6
  "types": "./lib/typescript/src/index.d.ts",