react-native-advanced-text 0.1.27 → 0.1.28

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.
@@ -1,637 +1,318 @@
1
- #import "AdvancedTextView.h"
2
-
3
- #import <react/renderer/components/AdvancedTextViewSpec/ComponentDescriptors.h>
4
- #import <react/renderer/components/AdvancedTextViewSpec/EventEmitters.h>
5
- #import <react/renderer/components/AdvancedTextViewSpec/Props.h>
6
- #import <react/renderer/components/AdvancedTextViewSpec/RCTComponentViewHelpers.h>
7
-
8
- #import "RCTFabricComponentsPlugins.h"
9
-
10
- using namespace facebook::react;
11
-
12
-
13
- @class AdvancedTextView;
14
-
15
- @interface AdvancedTextView () <RCTAdvancedTextViewViewProtocol, UIGestureRecognizerDelegate, UITextViewDelegate>
16
-
17
- @property (nonatomic, strong) NSMutableArray<NSDictionary *> *wordRanges;
18
- @property (nonatomic, strong) NSMutableDictionary<NSNumber *, UIColor *> *highlightColors;
19
- @property (nonatomic, strong) NSArray<NSString *> *menuOptions;
20
- @property (nonatomic, assign) NSInteger indicatorWordIndex;
21
- @property (nonatomic, assign) CGFloat fontSize;
22
- @property (nonatomic, strong) NSString *fontWeight;
23
- @property (nonatomic, strong) UIColor *textColor;
24
- @property (nonatomic, strong) NSString *textAlign;
25
- @property (nonatomic, strong) NSString *fontFamily;
26
-
27
- - (void)handleCustomMenuAction:(UIMenuItem *)sender;
28
-
29
- @end
30
-
31
-
32
- @interface CustomTextView : UITextView
33
- @property (nonatomic, weak) AdvancedTextView *parentView;
34
- @end
35
-
36
- @implementation CustomTextView
37
-
38
- - (BOOL)canPerformAction:(SEL)action withSender:(id)sender
39
- {
40
- NSLog(@"[CustomTextView] canPerformAction: %@", NSStringFromSelector(action));
41
-
42
- if (action == @selector(handleCustomMenuAction:)) {
43
- NSLog(@"[CustomTextView] Allowing custom action");
44
- return YES;
45
- }
46
-
47
- NSLog(@"[CustomTextView] Blocking system action: %@", NSStringFromSelector(action));
48
- return NO;
49
- }
50
-
51
- - (void)handleCustomMenuAction:(UIMenuItem *)sender
52
- {
53
- if (self.parentView) {
54
- [self.parentView handleCustomMenuAction:sender];
55
- }
56
- }
57
-
58
- @end
59
-
60
-
61
-
62
- @interface AdvancedTextView () <RCTAdvancedTextViewViewProtocol, UIGestureRecognizerDelegate, UITextViewDelegate>
63
-
64
- @property (nonatomic, strong) CustomTextView *textView;
65
-
66
- @end
67
-
68
- @implementation AdvancedTextView
69
-
70
- + (ComponentDescriptorProvider)componentDescriptorProvider
71
- {
72
- NSLog(@"[AdvancedTextView] componentDescriptorProvider called");
73
- return concreteComponentDescriptorProvider<AdvancedTextViewComponentDescriptor>();
74
- }
75
-
76
- - (instancetype)initWithFrame:(CGRect)frame
77
- {
78
- NSLog(@"[AdvancedTextView] initWithFrame called");
79
- if (self = [super initWithFrame:frame]) {
80
- @try {
81
- static const auto defaultProps = std::make_shared<const AdvancedTextViewProps>();
82
- _props = defaultProps;
83
-
84
- _wordRanges = [NSMutableArray array];
85
- _highlightColors = [NSMutableDictionary dictionary];
86
- _indicatorWordIndex = -1;
87
- _fontSize = 16.0;
88
- _fontWeight = @"normal";
89
- _textColor = [UIColor labelColor];
90
- _textAlign = @"left";
91
- _fontFamily = @"System";
92
-
93
- [self setupTextView];
94
- [self setupGestureRecognizers];
95
-
96
- NSLog(@"[AdvancedTextView] Initialization successful");
97
- } @catch (NSException *exception) {
98
- NSLog(@"[AdvancedTextView] Exception in init: %@", exception);
99
- @throw;
100
- }
101
- }
102
-
103
- return self;
104
- }
105
-
106
- - (void)setupTextView
107
- {
108
- NSLog(@"[AdvancedTextView] setupTextView called");
109
- @try {
110
- _textView = [[CustomTextView alloc] initWithFrame:self.bounds];
111
- _textView.parentView = self;
112
- _textView.editable = NO;
113
- _textView.selectable = YES;
114
- _textView.scrollEnabled = YES;
115
- _textView.backgroundColor = [UIColor clearColor];
116
- _textView.textContainerInset = UIEdgeInsetsMake(8, 8, 8, 8);
117
- _textView.font = [UIFont systemFontOfSize:16];
118
- _textView.textColor = [UIColor labelColor];
119
- _textView.delegate = self;
120
-
121
- self.contentView = _textView;
122
- NSLog(@"[AdvancedTextView] TextView setup successful");
123
- } @catch (NSException *exception) {
124
- NSLog(@"[AdvancedTextView] Exception in setupTextView: %@", exception);
125
- @throw;
126
- }
127
- }
128
-
129
- - (void)setupGestureRecognizers
130
- {
131
- NSLog(@"[AdvancedTextView] setupGestureRecognizers called");
132
- @try {
133
- UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc]
134
- initWithTarget:self
135
- action:@selector(handleTap:)];
136
- tapGesture.delegate = self;
137
- [_textView addGestureRecognizer:tapGesture];
138
-
139
- NSLog(@"[AdvancedTextView] Gesture recognizers setup successful");
140
- } @catch (NSException *exception) {
141
- NSLog(@"[AdvancedTextView] Exception in setupGestureRecognizers: %@", exception);
142
- @throw;
143
- }
144
- }
145
-
146
- - (void)updateProps:(Props::Shared const &)props oldProps:(Props::Shared const &)oldProps
147
- {
148
- NSLog(@"[AdvancedTextView] updateProps called");
149
- @try {
150
- const auto &oldViewProps = *std::static_pointer_cast<AdvancedTextViewProps const>(_props);
151
- const auto &newViewProps = *std::static_pointer_cast<AdvancedTextViewProps const>(props);
152
-
153
- BOOL textChanged = NO;
154
- BOOL highlightsChanged = NO;
155
- BOOL menuChanged = NO;
156
- BOOL indicatorChanged = NO;
157
- BOOL styleChanged = NO;
158
-
159
- if (oldViewProps.fontSize != newViewProps.fontSize && newViewProps.fontSize) {
160
- NSLog(@"[AdvancedTextView] Updating fontSize to: %f", newViewProps.fontSize);
161
- _fontSize = static_cast<CGFloat>(newViewProps.fontSize);
162
- styleChanged = YES;
163
- }
1
+ package com.advancedtext
2
+
3
+ import android.content.Context
4
+ import android.graphics.Color
5
+ import android.text.SpannableString
6
+ import android.text.Spanned
7
+ import android.text.TextPaint
8
+ import android.text.method.LinkMovementMethod
9
+ import android.text.style.ClickableSpan
10
+ import android.text.style.BackgroundColorSpan
11
+ import android.text.style.ForegroundColorSpan
12
+ import android.util.AttributeSet
13
+ import android.util.Log
14
+ import android.view.ActionMode
15
+ import android.view.Menu
16
+ import android.view.MenuItem
17
+ import android.view.View
18
+ import android.widget.TextView
19
+ import com.facebook.react.bridge.Arguments
20
+ import com.facebook.react.bridge.ReactContext
21
+ import com.facebook.react.uimanager.events.RCTEventEmitter
22
+ import android.text.Selection
23
+ import android.graphics.Typeface
24
+
25
+ class AdvancedTextView : TextView {
26
+
27
+ private val TAG = "AdvancedTextView"
28
+
29
+ private var highlightedWords: List<HighlightedWord> = emptyList()
30
+ private var menuOptions: List<String> = emptyList()
31
+ private var indicatorWordIndex: Int = -1
32
+ private var lastSelectedText: String = ""
33
+ private var customActionMode: ActionMode? = null
34
+ private var currentText: String = ""
35
+ private var textColor: String = "#000000"
36
+ private var fontSize: Float = 16f
37
+ private var fontWeight: String = "normal"
38
+ private var textAlign: String = "left"
39
+ private var fontFamily: String = "sans-serif"
40
+
41
+ private var wordPositions: List<WordPosition> = emptyList()
42
+
43
+ constructor(context: Context?) : super(context) { init() }
44
+ constructor(context: Context?, attrs: AttributeSet?) : super(context, attrs) { init() }
45
+ constructor(context: Context?, attrs: AttributeSet?, defStyleAttr: Int) : super(context, attrs, defStyleAttr) { init() }
46
+
47
+ private fun init() {
48
+ Log.d(TAG, "AdvancedTextView initialized")
49
+
50
+ textSize = 16f
51
+ setPadding(16, 16, 16, 16)
52
+ movementMethod = LinkMovementMethod.getInstance()
53
+ setTextIsSelectable(true)
54
+
55
+
56
+ customSelectionActionModeCallback = object : ActionMode.Callback {
57
+ override fun onCreateActionMode(mode: ActionMode?, menu: Menu?): Boolean {
58
+ customActionMode = mode
59
+ return true
60
+ }
164
61
 
165
- if (oldViewProps.textAlign != newViewProps.textAlign && !newViewProps.textAlign.empty()) {
166
- NSLog(@"[AdvancedTextView] Updating textAlign to: %s", newViewProps.textAlign.c_str());
167
- _textAlign = [NSString stringWithUTF8String:newViewProps.textAlign.c_str()];
168
- styleChanged = YES;
169
- }
62
+ override fun onPrepareActionMode(mode: ActionMode?, menu: Menu?): Boolean {
63
+ menu?.clear()
170
64
 
171
- if (oldViewProps.fontWeight != newViewProps.fontWeight && !newViewProps.fontWeight.empty()) {
172
- NSLog(@"[AdvancedTextView] Updating fontWeight to: %s", newViewProps.fontWeight.c_str());
173
- _fontWeight = [NSString stringWithUTF8String:newViewProps.fontWeight.c_str()];
174
- styleChanged = YES;
175
- }
65
+ val selectionStart = selectionStart
66
+ val selectionEnd = selectionEnd
176
67
 
177
- if (oldViewProps.fontFamily != newViewProps.fontFamily && !newViewProps.fontFamily.empty()) {
178
- NSLog(@"[AdvancedTextView] Updating fontFamily to: %s", newViewProps.fontFamily.c_str());
179
- _fontFamily = [NSString stringWithUTF8String:newViewProps.fontFamily.c_str()];
180
- styleChanged = YES;
181
- }
68
+ if (selectionStart >= 0 && selectionEnd >= 0 && selectionStart != selectionEnd) {
69
+ lastSelectedText = text.subSequence(selectionStart, selectionEnd).toString()
182
70
 
183
- if (oldViewProps.color != newViewProps.color && !newViewProps.color.empty()) {
184
- NSLog(@"[AdvancedTextView] Updating color to: %s", newViewProps.color.c_str());
185
- NSString *colorStr = [NSString stringWithUTF8String:newViewProps.color.c_str()];
186
- _textColor = [self hexStringToColor:colorStr];
187
- styleChanged = YES;
188
- }
71
+ menuOptions.forEachIndexed { index, option ->
72
+ menu?.add(0, index, index, option)
73
+ }
189
74
 
190
- if (oldViewProps.text != newViewProps.text) {
191
- textChanged = YES;
192
- NSLog(@"[AdvancedTextView] Text changed");
193
- }
194
-
195
- if (oldViewProps.highlightedWords.size() != newViewProps.highlightedWords.size()) {
196
- highlightsChanged = YES;
197
- } else {
198
- for (size_t i = 0; i < oldViewProps.highlightedWords.size(); i++) {
199
- const auto &oldHW = oldViewProps.highlightedWords[i];
200
- const auto &newHW = newViewProps.highlightedWords[i];
201
- if (oldHW.index != newHW.index || oldHW.highlightColor != newHW.highlightColor) {
202
- highlightsChanged = YES;
203
- break;
75
+ sendSelectionEvent(lastSelectedText, "selection")
76
+ return true
204
77
  }
78
+ return false
205
79
  }
206
- }
207
80
 
208
- if (oldViewProps.menuOptions.size() != newViewProps.menuOptions.size()) {
209
- menuChanged = YES;
210
- } else {
211
- for (size_t i = 0; i < oldViewProps.menuOptions.size(); i++) {
212
- if (oldViewProps.menuOptions[i] != newViewProps.menuOptions[i]) {
213
- menuChanged = YES;
214
- break;
81
+ override fun onActionItemClicked(mode: ActionMode?, item: MenuItem?): Boolean {
82
+ item?.let {
83
+ val menuItemText = it.title.toString()
84
+ sendSelectionEvent(lastSelectedText, menuItemText)
85
+ mode?.finish()
86
+ return true
215
87
  }
88
+ return false
216
89
  }
217
- }
218
-
219
- if (oldViewProps.indicatorWordIndex != newViewProps.indicatorWordIndex) {
220
- indicatorChanged = YES;
221
- }
222
90
 
223
- if (textChanged) {
224
- NSString *text = [NSString stringWithUTF8String:newViewProps.text.c_str()];
225
- [self updateTextContent:text];
91
+ override fun onDestroyActionMode(mode: ActionMode?) {
92
+ customActionMode = null
93
+ }
226
94
  }
95
+ }
227
96
 
228
- if (highlightsChanged) {
229
- [self updateHighlightedWords:newViewProps.highlightedWords];
230
- }
231
97
 
232
- if (menuChanged) {
233
- [self updateMenuOptions:newViewProps.menuOptions];
234
- }
235
98
 
236
- if (indicatorChanged) {
237
- _indicatorWordIndex = newViewProps.indicatorWordIndex;
238
- [self updateTextAppearance];
99
+ fun setAdvancedText(text: String) {
100
+ if (currentText == text) {
101
+ Log.d(TAG, "Text unchanged, skipping update")
102
+ return
239
103
  }
240
104
 
241
- if (styleChanged) {
242
- NSLog(@"[AdvancedTextView] Style properties changed, updating appearance");
243
- [self updateTextAppearance];
244
- }
245
-
246
- [super updateProps:props oldProps:oldProps];
247
- NSLog(@"[AdvancedTextView] updateProps completed successfully");
248
- } @catch (NSException *exception) {
249
- NSLog(@"[AdvancedTextView] Exception in updateProps: %@", exception.reason);
250
- @throw;
105
+ Log.d(TAG, "setAdvancedText: length=${text.length}")
106
+ currentText = text
107
+ calculateWordPositions(text)
108
+ updateTextWithHighlights()
251
109
  }
252
- }
253
-
254
- - (void)updateTextContent:(NSString *)text
255
- {
256
- NSLog(@"[AdvancedTextView] updateTextContent called with text length: %lu",
257
- (unsigned long)text.length);
258
- @try {
259
- if (!text) {
260
- NSLog(@"[AdvancedTextView] Text is nil, skipping update");
261
- return;
262
- }
263
-
264
- _textView.text = text;
265
-
266
- [_wordRanges removeAllObjects];
267
-
268
- NSRange searchRange = NSMakeRange(0, text.length);
269
- NSCharacterSet *whitespaceSet = [NSCharacterSet whitespaceAndNewlineCharacterSet];
270
-
271
- NSInteger wordIndex = 0;
272
- while (searchRange.location < text.length) {
273
- while (searchRange.location < text.length &&
274
- [whitespaceSet characterIsMember:[text characterAtIndex:searchRange.location]]) {
275
- searchRange.location++;
276
- searchRange.length = text.length - searchRange.location;
277
- }
278
110
 
279
- if (searchRange.location >= text.length) break;
111
+ fun setAdvancedTextColor(colorInt: Int) {
112
+ textColor = String.format("#%06X", 0xFFFFFF and colorInt)
113
+ updateTextWithHighlights()
114
+ }
280
115
 
281
- NSUInteger wordStart = searchRange.location;
282
- while (searchRange.location < text.length &&
283
- ![whitespaceSet characterIsMember:[text characterAtIndex:searchRange.location]]) {
284
- searchRange.location++;
285
- }
286
116
 
287
- NSRange wordRange = NSMakeRange(wordStart, searchRange.location - wordStart);
288
- NSString *word = [text substringWithRange:wordRange];
117
+ fun setAdvancedTextSize(size: Float) {
118
+ if (fontSize == size) return
119
+ fontSize = size
120
+ updateTextWithHighlights()
121
+ }
289
122
 
290
- [_wordRanges addObject:@{
291
- @"word": word,
292
- @"range": [NSValue valueWithRange:wordRange],
293
- @"index": @(wordIndex)
294
- }];
123
+ fun setAdvancedFontWeight(weight: String) {
124
+ if (fontWeight == weight) return
125
+ fontWeight = weight
126
+ updateTextWithHighlights()
127
+ }
295
128
 
296
- wordIndex++;
297
- searchRange.length = text.length - searchRange.location;
129
+ fun setAdvancedTextAlign(align: String) {
130
+ if (textAlign == align) return
131
+ textAlign = align
132
+ when (align) {
133
+ "left" -> textAlignment = View.TEXT_ALIGNMENT_TEXT_START
134
+ "center" -> textAlignment = View.TEXT_ALIGNMENT_CENTER
135
+ "right" -> textAlignment = View.TEXT_ALIGNMENT_TEXT_END
136
+ else -> textAlignment = View.TEXT_ALIGNMENT_TEXT_START
298
137
  }
299
-
300
- NSLog(@"[AdvancedTextView] Parsed %ld words", (long)_wordRanges.count);
301
- [self updateTextAppearance];
302
- } @catch (NSException *exception) {
303
- NSLog(@"[AdvancedTextView] Exception in updateTextContent: %@", exception);
304
- @throw;
305
138
  }
306
- }
307
139
 
308
- - (void)updateHighlightedWords:(const std::vector<AdvancedTextViewHighlightedWordsStruct> &)highlightedWords
309
- {
310
- NSLog(@"[AdvancedTextView] updateHighlightedWords called with %zu highlights",
311
- highlightedWords.size());
312
- @try {
313
- [_highlightColors removeAllObjects];
314
-
315
- for (const auto &hw : highlightedWords) {
316
- NSInteger index = hw.index;
317
- NSString *colorString = [NSString stringWithUTF8String:hw.highlightColor.c_str()];
318
- UIColor *color = [self hexStringToColor:colorString];
140
+ fun setAdvancedFontFamily(family: String) {
141
+ if (fontFamily == family) return
142
+ fontFamily = family
143
+ typeface = Typeface.create(family, Typeface.NORMAL)
144
+ }
319
145
 
320
- if (color) {
321
- _highlightColors[@(index)] = color;
322
- }
323
- }
146
+ fun setMenuOptions(menuOptions: List<String>) {
147
+ if (this.menuOptions == menuOptions) return
148
+ this.menuOptions = menuOptions
149
+ }
324
150
 
325
- [self updateTextAppearance];
326
- } @catch (NSException *exception) {
327
- NSLog(@"[AdvancedTextView] Exception in updateHighlightedWords: %@", exception);
328
- @throw;
151
+ fun setHighlightedWords(highlightedWords: List<HighlightedWord>) {
152
+ if (this.highlightedWords == highlightedWords) return
153
+ this.highlightedWords = highlightedWords
154
+ updateTextWithHighlights()
329
155
  }
330
- }
331
156
 
332
- - (void)updateMenuOptions:(const std::vector<std::string> &)options
333
- {
334
- NSLog(@"[AdvancedTextView] updateMenuOptions called with %zu options", options.size());
335
- @try {
336
- NSMutableArray *menuArray = [NSMutableArray array];
337
- for (const auto &option : options) {
338
- NSString *optionStr = [NSString stringWithUTF8String:option.c_str()];
339
- [menuArray addObject:optionStr];
340
- NSLog(@"[AdvancedTextView] Added menu option: %@", optionStr);
341
- }
342
- _menuOptions = [menuArray copy];
343
- } @catch (NSException *exception) {
344
- NSLog(@"[AdvancedTextView] Exception in updateMenuOptions: %@", exception);
345
- @throw;
157
+ fun setIndicatorWordIndex(index: Int) {
158
+ if (this.indicatorWordIndex == index) return
159
+ this.indicatorWordIndex = index
160
+ updateTextWithHighlights()
346
161
  }
347
- }
348
162
 
349
- - (void)updateTextAppearance
350
- {
351
- @try {
352
- if (!_textView.text || _textView.text.length == 0) {
353
- return;
163
+ private fun calculateWordPositions(text: String) {
164
+ if (text.isEmpty()) {
165
+ wordPositions = emptyList()
166
+ return
354
167
  }
355
168
 
356
- NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc]
357
- initWithString:_textView.text];
358
-
359
-
360
- UIFont *font = nil;
169
+ val positions = mutableListOf<WordPosition>()
170
+ val regex = "\\S+".toRegex()
361
171
 
362
- if (_fontFamily && _fontFamily.length > 0) {
363
- font = [UIFont fontWithName:_fontFamily size:_fontSize > 0 ? _fontSize : 16.0];
172
+ regex.findAll(text).forEachIndexed { index, match ->
173
+ positions.add(WordPosition(
174
+ index = index,
175
+ start = match.range.first,
176
+ end = match.range.last + 1,
177
+ word = match.value
178
+ ))
364
179
  }
365
180
 
366
- if (!font) {
367
- if (_fontWeight && [_fontWeight.lowercaseString isEqualToString:@"bold"]) {
368
- font = [UIFont boldSystemFontOfSize:_fontSize > 0 ? _fontSize : 16.0];
369
- } else if (_fontWeight && [_fontWeight.lowercaseString isEqualToString:@"italic"]) {
370
- font = [UIFont italicSystemFontOfSize:_fontSize > 0 ? _fontSize : 16.0];
371
- } else {
372
- font = [UIFont systemFontOfSize:_fontSize > 0 ? _fontSize : 16.0];
373
- }
374
- }
375
-
376
- [attributedString addAttribute:NSFontAttributeName
377
- value:font
378
- range:NSMakeRange(0, attributedString.length)];
379
-
380
-
381
- UIColor *color = _textColor ?: [UIColor labelColor];
382
- [attributedString addAttribute:NSForegroundColorAttributeName
383
- value:color
384
- range:NSMakeRange(0, attributedString.length)];
181
+ wordPositions = positions
182
+ Log.d(TAG, "Calculated ${wordPositions.size} word positions")
183
+ }
385
184
 
185
+ private fun updateTextWithHighlights() {
186
+ if (currentText.isEmpty()) {
187
+ Log.d(TAG, "No text available, skipping")
188
+ return
189
+ }
386
190
 
387
- for (NSDictionary *wordInfo in _wordRanges) {
388
- NSNumber *index = wordInfo[@"index"];
389
- NSValue *rangeValue = wordInfo[@"range"];
390
- NSRange range = [rangeValue rangeValue];
191
+ val spannableString = SpannableString(currentText)
391
192
 
392
- if (range.location + range.length > attributedString.length) {
393
- continue;
193
+ wordPositions.forEach { wordPos ->
194
+ highlightedWords.find { it.index == wordPos.index }?.let { highlightedWord ->
195
+ val color = parseColor(highlightedWord.highlightColor)
196
+ spannableString.setSpan(
197
+ BackgroundColorSpan(color),
198
+ wordPos.start,
199
+ wordPos.end,
200
+ Spanned.SPAN_EXCLUSIVE_EXCLUSIVE
201
+ )
394
202
  }
395
203
 
396
- UIColor *highlightColor = _highlightColors[index];
397
- if (highlightColor) {
398
- [attributedString addAttribute:NSBackgroundColorAttributeName
399
- value:highlightColor
400
- range:range];
204
+ if (wordPos.index == indicatorWordIndex) {
205
+ spannableString.setSpan(
206
+ ForegroundColorSpan(Color.parseColor(textColor)),
207
+ wordPos.start,
208
+ wordPos.end,
209
+ Spanned.SPAN_EXCLUSIVE_EXCLUSIVE
210
+ )
401
211
  }
402
212
 
403
- if (_indicatorWordIndex >= 0 && [index integerValue] == _indicatorWordIndex) {
404
- UIColor *indicatorColor = [[UIColor systemBlueColor] colorWithAlphaComponent:0.3];
405
- [attributedString addAttribute:NSBackgroundColorAttributeName
406
- value:indicatorColor
407
- range:range];
408
- }
213
+ spannableString.setSpan(
214
+ WordClickableSpan(wordPos.index, wordPos.word),
215
+ wordPos.start,
216
+ wordPos.end,
217
+ Spanned.SPAN_EXCLUSIVE_EXCLUSIVE
218
+ )
409
219
  }
410
220
 
411
- _textView.attributedText = attributedString;
412
-
413
- if (_textAlign) {
414
- if ([_textAlign.lowercaseString isEqualToString:@"center"]) {
415
- _textView.textAlignment = NSTextAlignmentCenter;
416
- } else if ([_textAlign.lowercaseString isEqualToString:@"right"]) {
417
- _textView.textAlignment = NSTextAlignmentRight;
418
- } else {
419
- _textView.textAlignment = NSTextAlignmentLeft;
420
- }
421
- } else {
422
- _textView.textAlignment = NSTextAlignmentLeft;
221
+ textAlignment = when (textAlign) {
222
+ "left" -> View.TEXT_ALIGNMENT_TEXT_START
223
+ "center" -> View.TEXT_ALIGNMENT_CENTER
224
+ "right" -> View.TEXT_ALIGNMENT_TEXT_END
225
+ else -> View.TEXT_ALIGNMENT_TEXT_START
423
226
  }
424
227
 
425
- } @catch (NSException *exception) {
426
- NSLog(@"[AdvancedTextView] Exception in updateTextAppearance: %@", exception.reason);
427
- }
428
- }
429
-
430
-
431
- - (void)handleTap:(UITapGestureRecognizer *)gesture
432
- {
433
- @try {
434
- if (gesture.state != UIGestureRecognizerStateEnded) return;
435
-
436
- CGPoint location = [gesture locationInView:_textView];
437
- NSInteger wordIndex = [self wordIndexAtPoint:location];
438
-
439
- _textView.selectedTextRange = nil;
228
+ setTextSize(fontSize)
440
229
 
441
- if (wordIndex >= 0 && wordIndex < _wordRanges.count) {
442
- NSDictionary *wordInfo = _wordRanges[wordIndex];
443
- NSString *word = wordInfo[@"word"];
444
-
445
- [self emitWordPressEvent:word index:wordIndex];
230
+ typeface = when (fontWeight) {
231
+ "bold" -> Typeface.create(fontFamily, Typeface.BOLD)
232
+ "italic" -> Typeface.create(fontFamily, Typeface.ITALIC)
233
+ else -> Typeface.create(fontFamily, Typeface.NORMAL)
446
234
  }
447
- } @catch (NSException *exception) {
448
- NSLog(@"[AdvancedTextView] Exception in handleTap: %@", exception);
449
- }
450
- }
451
-
452
- #pragma mark - UITextViewDelegate
453
-
454
- - (void)textViewDidChangeSelection:(UITextView *)textView
455
- {
456
- NSString *selectedText = [textView.text substringWithRange:textView.selectedRange];
457
235
 
458
- if (selectedText.length > 0) {
459
- NSLog(@"[AdvancedTextView] Selected text: %@", selectedText);
460
-
461
- if (_menuOptions && _menuOptions.count > 0) {
462
- [self setupCustomMenuItems];
236
+ post {
237
+ setText(spannableString, BufferType.SPANNABLE)
238
+ Log.d(TAG, "Text updated with ${wordPositions.size} spans")
463
239
  }
464
240
  }
465
- }
466
-
467
- - (void)setupCustomMenuItems
468
- {
469
- NSLog(@"[AdvancedTextView] Setting up %lu custom menu items", (unsigned long)_menuOptions.count);
470
241
 
471
- UIMenuController *menuController = [UIMenuController sharedMenuController];
472
- NSMutableArray *customItems = [NSMutableArray array];
473
-
474
- for (NSString *option in _menuOptions) {
475
- UIMenuItem *item = [[UIMenuItem alloc] initWithTitle:option
476
- action:@selector(handleCustomMenuAction:)];
477
- [customItems addObject:item];
478
- NSLog(@"[AdvancedTextView] Created menu item: %@", option);
242
+ private fun parseColor(colorString: String): Int {
243
+ return try {
244
+ Color.parseColor(colorString)
245
+ } catch (e: IllegalArgumentException) {
246
+ Log.e(TAG, "Invalid color: $colorString, using yellow")
247
+ Color.YELLOW
248
+ }
479
249
  }
480
250
 
481
- menuController.menuItems = customItems;
482
- }
483
-
484
-
485
- - (void)handleCustomMenuAction:(UIMenuItem *)sender
486
- {
487
- NSLog(@"[AdvancedTextView] Custom menu action: %@", sender.title);
488
-
489
- NSString *selectedText = [_textView.text substringWithRange:_textView.selectedRange];
490
-
491
- [self emitSelectionEvent:selectedText menuOption:sender.title];
492
-
493
- dispatch_async(dispatch_get_main_queue(), ^{
494
- self->_textView.selectedTextRange = nil;
495
- NSLog(@"[AdvancedTextView] Selection cleared");
496
- });
497
- }
251
+ private fun sendSelectionEvent(selectedText: String, eventType: String) {
252
+ try {
253
+ val reactContext = context as? ReactContext ?: return
254
+ val event = Arguments.createMap().apply {
255
+ putString("selectedText", selectedText)
256
+ putString("event", eventType)
257
+ }
498
258
 
499
- - (NSInteger)wordIndexAtPoint:(CGPoint)point
500
- {
501
- @try {
502
- if (!_textView.layoutManager || !_textView.textContainer) {
503
- return -1;
259
+ reactContext.getJSModule(RCTEventEmitter::class.java)
260
+ .receiveEvent(id, "onSelection", event)
261
+ } catch (e: Exception) {
262
+ Log.e(TAG, "Error sending selection event", e)
504
263
  }
264
+ }
505
265
 
506
- point.x -= _textView.textContainerInset.left;
507
- point.y -= _textView.textContainerInset.top;
508
-
509
- NSLayoutManager *layoutManager = _textView.layoutManager;
510
- NSTextContainer *textContainer = _textView.textContainer;
511
-
512
- NSUInteger characterIndex = [layoutManager characterIndexForPoint:point
513
- inTextContainer:textContainer
514
- fractionOfDistanceBetweenInsertionPoints:nil];
266
+ private inner class WordClickableSpan(
267
+ private val wordIndex: Int,
268
+ private val word: String
269
+ ) : ClickableSpan() {
515
270
 
516
- for (NSDictionary *wordInfo in _wordRanges) {
517
- NSValue *rangeValue = wordInfo[@"range"];
518
- NSRange range = [rangeValue rangeValue];
271
+ override fun onClick(widget: View) {
272
+ Log.d(TAG, "WordClickableSpan onClick triggered: '$word' (index=$wordIndex)")
519
273
 
520
- if (NSLocationInRange(characterIndex, range)) {
521
- return [wordInfo[@"index"] integerValue];
274
+ widget.post {
275
+ sendWordPressEvent(word, wordIndex)
522
276
  }
523
277
  }
524
278
 
525
- return -1;
526
- } @catch (NSException *exception) {
527
- return -1;
528
- }
529
- }
530
-
531
- - (void)setFontSize:(CGFloat)fontSize {
532
- _fontSize = fontSize;
533
- [self updateTextAppearance];
534
- }
535
-
536
- - (void)setFontWeight:(NSString *)fontWeight {
537
- _fontWeight = fontWeight;
538
- [self updateTextAppearance];
539
- }
540
-
541
- - (void)setTextColor:(UIColor *)textColor {
542
- _textColor = textColor;
543
- [self updateTextAppearance];
544
- }
545
-
546
- - (void)setTextAlign:(NSString *)textAlign {
547
- _textAlign = textAlign;
548
- [self updateTextAppearance];
549
- }
550
-
551
- - (void)setFontFamily:(NSString *)fontFamily {
552
- _fontFamily = fontFamily;
553
- [self updateTextAppearance];
554
- }
555
-
556
- - (void)emitWordPressEvent:(NSString *)word index:(NSInteger)index
557
- {
558
- NSLog(@"[AdvancedTextView] emitWordPressEvent: %@ at index: %ld", word, (long)index);
559
- @try {
560
- if (_eventEmitter) {
561
- auto emitter = std::static_pointer_cast<const AdvancedTextViewEventEmitter>(_eventEmitter);
562
-
563
- AdvancedTextViewEventEmitter::OnWordPress event;
564
- event.word = [word UTF8String];
565
- event.index = static_cast<int>(index);
566
-
567
- emitter->onWordPress(event);
279
+ override fun updateDrawState(ds: TextPaint) {
280
+ super.updateDrawState(ds)
281
+ ds.isUnderlineText = false
282
+ ds.color = Color.parseColor(textColor)
568
283
  }
569
- } @catch (NSException *exception) {
570
- NSLog(@"[AdvancedTextView] Exception in emitWordPressEvent: %@", exception);
571
284
  }
572
- }
573
-
574
- - (void)emitSelectionEvent:(NSString *)selectedText menuOption:(NSString *)option
575
- {
576
- NSLog(@"[AdvancedTextView] emitSelectionEvent: %@ with option: %@", selectedText, option);
577
- @try {
578
- if (_eventEmitter) {
579
- auto emitter = std::static_pointer_cast<const AdvancedTextViewEventEmitter>(_eventEmitter);
580
285
 
581
- AdvancedTextViewEventEmitter::OnSelection event;
582
- event.selectedText = [selectedText UTF8String];
583
- event.event = [option UTF8String];
286
+ private fun sendWordPressEvent(word: String, index: Int) {
287
+ try {
288
+ val reactContext = context as? ReactContext ?: return
289
+ val event = Arguments.createMap().apply {
290
+ putString("word", word)
291
+ putInt("index", index)
292
+ }
584
293
 
585
- emitter->onSelection(event);
294
+ reactContext.getJSModule(RCTEventEmitter::class.java)
295
+ .receiveEvent(id, "onWordPress", event)
296
+ } catch (e: Exception) {
297
+ Log.e(TAG, "Error sending word press event", e)
586
298
  }
587
- } @catch (NSException *exception) {
588
- NSLog(@"[AdvancedTextView] Exception in emitSelectionEvent: %@", exception);
589
- }
590
- }
591
-
592
- - (void)layoutSubviews
593
- {
594
- @try {
595
- [super layoutSubviews];
596
- _textView.frame = self.bounds;
597
- } @catch (NSException *exception) {
598
- NSLog(@"[AdvancedTextView] Exception in layoutSubviews: %@", exception);
599
299
  }
600
- }
601
300
 
602
- - (UIColor *)hexStringToColor:(NSString *)stringToConvert
603
- {
604
- @try {
605
- if (!stringToConvert || [stringToConvert length] == 0) {
606
- return nil;
301
+ fun clearSelection() {
302
+ (text as? android.text.Spannable)?.let {
303
+ Selection.removeSelection(it)
607
304
  }
608
-
609
- NSString *noHashString = [stringToConvert stringByReplacingOccurrencesOfString:@"#" withString:@""];
610
- NSScanner *stringScanner = [NSScanner scannerWithString:noHashString];
611
-
612
- unsigned hex;
613
- if (![stringScanner scanHexInt:&hex]) {
614
- return nil;
615
- }
616
-
617
- int r = (hex >> 16) & 0xFF;
618
- int g = (hex >> 8) & 0xFF;
619
- int b = (hex) & 0xFF;
620
-
621
- return [UIColor colorWithRed:r / 255.0f green:g / 255.0f blue:b / 255.0f alpha:1.0f];
622
- } @catch (NSException *exception) {
623
- return nil;
624
305
  }
625
- }
626
-
627
- Class<RCTComponentViewProtocol> AdvancedTextViewCls(void)
628
- {
629
- return AdvancedTextView.class;
630
- }
631
306
 
632
- - (void)dealloc
633
- {
634
- NSLog(@"[AdvancedTextView] dealloc called");
307
+ data class WordPosition(
308
+ val index: Int,
309
+ val start: Int,
310
+ val end: Int,
311
+ val word: String
312
+ )
635
313
  }
636
314
 
637
- @end
315
+ data class HighlightedWord(
316
+ val index: Int,
317
+ val highlightColor: String
318
+ )
@@ -10,7 +10,6 @@
10
10
  using namespace facebook::react;
11
11
 
12
12
 
13
- // Forward declaration
14
13
  @class AdvancedTextView;
15
14
 
16
15
  @interface AdvancedTextView () <RCTAdvancedTextViewViewProtocol, UIGestureRecognizerDelegate, UITextViewDelegate>
@@ -19,14 +18,17 @@ using namespace facebook::react;
19
18
  @property (nonatomic, strong) NSMutableDictionary<NSNumber *, UIColor *> *highlightColors;
20
19
  @property (nonatomic, strong) NSArray<NSString *> *menuOptions;
21
20
  @property (nonatomic, assign) NSInteger indicatorWordIndex;
21
+ @property (nonatomic, assign) CGFloat fontSize;
22
+ @property (nonatomic, strong) NSString *fontWeight;
23
+ @property (nonatomic, strong) UIColor *textColor;
24
+ @property (nonatomic, strong) NSString *textAlign;
25
+ @property (nonatomic, strong) NSString *fontFamily;
22
26
 
23
- // ✅ ADD THIS LINE
24
27
  - (void)handleCustomMenuAction:(UIMenuItem *)sender;
25
28
 
26
29
  @end
27
30
 
28
31
 
29
- // Custom UITextView subclass to override menu behavior
30
32
  @interface CustomTextView : UITextView
31
33
  @property (nonatomic, weak) AdvancedTextView *parentView;
32
34
  @end
@@ -37,22 +39,18 @@ using namespace facebook::react;
37
39
  {
38
40
  NSLog(@"[CustomTextView] canPerformAction: %@", NSStringFromSelector(action));
39
41
 
40
- // Only allow our custom menu actions
41
42
  if (action == @selector(handleCustomMenuAction:)) {
42
43
  NSLog(@"[CustomTextView] ✅ Allowing custom action");
43
44
  return YES;
44
45
  }
45
46
 
46
- // Block ALL system actions
47
47
  NSLog(@"[CustomTextView] ❌ Blocking system action: %@", NSStringFromSelector(action));
48
48
  return NO;
49
49
  }
50
50
 
51
51
  - (void)handleCustomMenuAction:(UIMenuItem *)sender
52
52
  {
53
- // Forward to parent view
54
53
  if (self.parentView) {
55
-
56
54
  [self.parentView handleCustomMenuAction:sender];
57
55
  }
58
56
  }
@@ -86,6 +84,11 @@ using namespace facebook::react;
86
84
  _wordRanges = [NSMutableArray array];
87
85
  _highlightColors = [NSMutableDictionary dictionary];
88
86
  _indicatorWordIndex = -1;
87
+ _fontSize = 16.0;
88
+ _fontWeight = @"normal";
89
+ _textColor = [UIColor labelColor];
90
+ _textAlign = @"left";
91
+ _fontFamily = @"System";
89
92
 
90
93
  [self setupTextView];
91
94
  [self setupGestureRecognizers];
@@ -127,7 +130,6 @@ using namespace facebook::react;
127
130
  {
128
131
  NSLog(@"[AdvancedTextView] setupGestureRecognizers called");
129
132
  @try {
130
- // Single tap for word selection
131
133
  UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc]
132
134
  initWithTarget:self
133
135
  action:@selector(handleTap:)];
@@ -152,14 +154,44 @@ using namespace facebook::react;
152
154
  BOOL highlightsChanged = NO;
153
155
  BOOL menuChanged = NO;
154
156
  BOOL indicatorChanged = NO;
157
+ BOOL styleChanged = NO;
158
+
159
+ if (oldViewProps.fontSize != newViewProps.fontSize && newViewProps.fontSize) {
160
+ NSLog(@"[AdvancedTextView] Updating fontSize to: %f", newViewProps.fontSize);
161
+ _fontSize = static_cast<CGFloat>(newViewProps.fontSize);
162
+ styleChanged = YES;
163
+ }
164
+
165
+ if (oldViewProps.textAlign != newViewProps.textAlign && !newViewProps.textAlign.empty()) {
166
+ NSLog(@"[AdvancedTextView] Updating textAlign to: %s", newViewProps.textAlign.c_str());
167
+ _textAlign = [NSString stringWithUTF8String:newViewProps.textAlign.c_str()];
168
+ styleChanged = YES;
169
+ }
170
+
171
+ if (oldViewProps.fontWeight != newViewProps.fontWeight && !newViewProps.fontWeight.empty()) {
172
+ NSLog(@"[AdvancedTextView] Updating fontWeight to: %s", newViewProps.fontWeight.c_str());
173
+ _fontWeight = [NSString stringWithUTF8String:newViewProps.fontWeight.c_str()];
174
+ styleChanged = YES;
175
+ }
176
+
177
+ if (oldViewProps.fontFamily != newViewProps.fontFamily && !newViewProps.fontFamily.empty()) {
178
+ NSLog(@"[AdvancedTextView] Updating fontFamily to: %s", newViewProps.fontFamily.c_str());
179
+ _fontFamily = [NSString stringWithUTF8String:newViewProps.fontFamily.c_str()];
180
+ styleChanged = YES;
181
+ }
182
+
183
+ if (oldViewProps.color != newViewProps.color && !newViewProps.color.empty()) {
184
+ NSLog(@"[AdvancedTextView] Updating color to: %s", newViewProps.color.c_str());
185
+ NSString *colorStr = [NSString stringWithUTF8String:newViewProps.color.c_str()];
186
+ _textColor = [self hexStringToColor:colorStr];
187
+ styleChanged = YES;
188
+ }
155
189
 
156
- // Check text change
157
190
  if (oldViewProps.text != newViewProps.text) {
158
191
  textChanged = YES;
159
192
  NSLog(@"[AdvancedTextView] Text changed");
160
193
  }
161
194
 
162
- // Check highlighted words change
163
195
  if (oldViewProps.highlightedWords.size() != newViewProps.highlightedWords.size()) {
164
196
  highlightsChanged = YES;
165
197
  } else {
@@ -173,7 +205,6 @@ using namespace facebook::react;
173
205
  }
174
206
  }
175
207
 
176
- // Check menu options change
177
208
  if (oldViewProps.menuOptions.size() != newViewProps.menuOptions.size()) {
178
209
  menuChanged = YES;
179
210
  } else {
@@ -185,12 +216,10 @@ using namespace facebook::react;
185
216
  }
186
217
  }
187
218
 
188
- // Check indicator change
189
219
  if (oldViewProps.indicatorWordIndex != newViewProps.indicatorWordIndex) {
190
220
  indicatorChanged = YES;
191
221
  }
192
222
 
193
- // Apply updates
194
223
  if (textChanged) {
195
224
  NSString *text = [NSString stringWithUTF8String:newViewProps.text.c_str()];
196
225
  [self updateTextContent:text];
@@ -209,6 +238,11 @@ using namespace facebook::react;
209
238
  [self updateTextAppearance];
210
239
  }
211
240
 
241
+ if (styleChanged) {
242
+ NSLog(@"[AdvancedTextView] Style properties changed, updating appearance");
243
+ [self updateTextAppearance];
244
+ }
245
+
212
246
  [super updateProps:props oldProps:oldProps];
213
247
  NSLog(@"[AdvancedTextView] updateProps completed successfully");
214
248
  } @catch (NSException *exception) {
@@ -229,7 +263,6 @@ using namespace facebook::react;
229
263
 
230
264
  _textView.text = text;
231
265
 
232
- // Parse text into words and their ranges
233
266
  [_wordRanges removeAllObjects];
234
267
 
235
268
  NSRange searchRange = NSMakeRange(0, text.length);
@@ -237,7 +270,6 @@ using namespace facebook::react;
237
270
 
238
271
  NSInteger wordIndex = 0;
239
272
  while (searchRange.location < text.length) {
240
- // Skip whitespace
241
273
  while (searchRange.location < text.length &&
242
274
  [whitespaceSet characterIsMember:[text characterAtIndex:searchRange.location]]) {
243
275
  searchRange.location++;
@@ -246,7 +278,6 @@ using namespace facebook::react;
246
278
 
247
279
  if (searchRange.location >= text.length) break;
248
280
 
249
- // Find word end
250
281
  NSUInteger wordStart = searchRange.location;
251
282
  while (searchRange.location < text.length &&
252
283
  ![whitespaceSet characterIsMember:[text characterAtIndex:searchRange.location]]) {
@@ -318,21 +349,41 @@ using namespace facebook::react;
318
349
  - (void)updateTextAppearance
319
350
  {
320
351
  @try {
321
- if (_wordRanges.count == 0 || !_textView.text || _textView.text.length == 0) {
352
+ if (!_textView.text || _textView.text.length == 0) {
322
353
  return;
323
354
  }
324
355
 
325
356
  NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc]
326
357
  initWithString:_textView.text];
327
358
 
359
+
360
+ UIFont *font = nil;
361
+
362
+ if (_fontFamily && _fontFamily.length > 0) {
363
+ font = [UIFont fontWithName:_fontFamily size:_fontSize > 0 ? _fontSize : 16.0];
364
+ }
365
+
366
+ if (!font) {
367
+ if (_fontWeight && [_fontWeight.lowercaseString isEqualToString:@"bold"]) {
368
+ font = [UIFont boldSystemFontOfSize:_fontSize > 0 ? _fontSize : 16.0];
369
+ } else if (_fontWeight && [_fontWeight.lowercaseString isEqualToString:@"italic"]) {
370
+ font = [UIFont italicSystemFontOfSize:_fontSize > 0 ? _fontSize : 16.0];
371
+ } else {
372
+ font = [UIFont systemFontOfSize:_fontSize > 0 ? _fontSize : 16.0];
373
+ }
374
+ }
375
+
328
376
  [attributedString addAttribute:NSFontAttributeName
329
- value:[UIFont systemFontOfSize:16]
377
+ value:font
330
378
  range:NSMakeRange(0, attributedString.length)];
331
379
 
380
+
381
+ UIColor *color = _textColor ?: [UIColor labelColor];
332
382
  [attributedString addAttribute:NSForegroundColorAttributeName
333
- value:[UIColor labelColor]
383
+ value:color
334
384
  range:NSMakeRange(0, attributedString.length)];
335
385
 
386
+
336
387
  for (NSDictionary *wordInfo in _wordRanges) {
337
388
  NSNumber *index = wordInfo[@"index"];
338
389
  NSValue *rangeValue = wordInfo[@"range"];
@@ -358,11 +409,25 @@ using namespace facebook::react;
358
409
  }
359
410
 
360
411
  _textView.attributedText = attributedString;
412
+
413
+ if (_textAlign) {
414
+ if ([_textAlign.lowercaseString isEqualToString:@"center"]) {
415
+ _textView.textAlignment = NSTextAlignmentCenter;
416
+ } else if ([_textAlign.lowercaseString isEqualToString:@"right"]) {
417
+ _textView.textAlignment = NSTextAlignmentRight;
418
+ } else {
419
+ _textView.textAlignment = NSTextAlignmentLeft;
420
+ }
421
+ } else {
422
+ _textView.textAlignment = NSTextAlignmentLeft;
423
+ }
424
+
361
425
  } @catch (NSException *exception) {
362
426
  NSLog(@"[AdvancedTextView] Exception in updateTextAppearance: %@", exception.reason);
363
427
  }
364
428
  }
365
429
 
430
+
366
431
  - (void)handleTap:(UITapGestureRecognizer *)gesture
367
432
  {
368
433
  @try {
@@ -371,7 +436,6 @@ using namespace facebook::react;
371
436
  CGPoint location = [gesture locationInView:_textView];
372
437
  NSInteger wordIndex = [self wordIndexAtPoint:location];
373
438
 
374
- // Dismiss any existing selection
375
439
  _textView.selectedTextRange = nil;
376
440
 
377
441
  if (wordIndex >= 0 && wordIndex < _wordRanges.count) {
@@ -464,6 +528,31 @@ using namespace facebook::react;
464
528
  }
465
529
  }
466
530
 
531
+ - (void)setFontSize:(CGFloat)fontSize {
532
+ _fontSize = fontSize;
533
+ [self updateTextAppearance];
534
+ }
535
+
536
+ - (void)setFontWeight:(NSString *)fontWeight {
537
+ _fontWeight = fontWeight;
538
+ [self updateTextAppearance];
539
+ }
540
+
541
+ - (void)setTextColor:(UIColor *)textColor {
542
+ _textColor = textColor;
543
+ [self updateTextAppearance];
544
+ }
545
+
546
+ - (void)setTextAlign:(NSString *)textAlign {
547
+ _textAlign = textAlign;
548
+ [self updateTextAppearance];
549
+ }
550
+
551
+ - (void)setFontFamily:(NSString *)fontFamily {
552
+ _fontFamily = fontFamily;
553
+ [self updateTextAppearance];
554
+ }
555
+
467
556
  - (void)emitWordPressEvent:(NSString *)word index:(NSInteger)index
468
557
  {
469
558
  NSLog(@"[AdvancedTextView] emitWordPressEvent: %@ at index: %ld", word, (long)index);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-native-advanced-text",
3
- "version": "0.1.27",
3
+ "version": "0.1.28",
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",