react-native-highlight-text-view 0.1.16 → 0.1.17

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.
@@ -206,6 +206,13 @@ class HighlightTextView : AppCompatEditText {
206
206
  }
207
207
  }
208
208
  })
209
+
210
+ // Set cursor at end when view gains focus
211
+ setOnFocusChangeListener { _, hasFocus ->
212
+ if (hasFocus) {
213
+ text?.length?.let { setSelection(it) }
214
+ }
215
+ }
209
216
  }
210
217
 
211
218
  fun setCharacterBackgroundColor(color: Int) {
@@ -309,7 +316,14 @@ class HighlightTextView : AppCompatEditText {
309
316
  }
310
317
 
311
318
  this.typeface = typeface
312
- applyCharacterBackgrounds()
319
+
320
+ // Force complete layout recalculation with new font metrics
321
+ // This ensures background highlights recalculate with new ascender/descender values
322
+ post {
323
+ applyCharacterBackgrounds()
324
+ requestLayout()
325
+ invalidate()
326
+ }
313
327
  }
314
328
 
315
329
  fun setVerticalAlign(align: String?) {
@@ -367,6 +381,8 @@ class HighlightTextView : AppCompatEditText {
367
381
  if (autoFocus && isFocusable && isFocusableInTouchMode) {
368
382
  post {
369
383
  requestFocus()
384
+ // Set cursor at the end of text
385
+ text?.length?.let { setSelection(it) }
370
386
  val imm = context.getSystemService(android.content.Context.INPUT_METHOD_SERVICE) as? android.view.inputmethod.InputMethodManager
371
387
  imm?.showSoftInput(this, android.view.inputmethod.InputMethodManager.SHOW_IMPLICIT)
372
388
  }
@@ -377,6 +393,9 @@ class HighlightTextView : AppCompatEditText {
377
393
  val text = text?.toString() ?: return
378
394
  if (text.isEmpty()) return
379
395
 
396
+ // Save current cursor position
397
+ val currentSelection = selectionStart
398
+
380
399
  val spannable = SpannableString(text)
381
400
 
382
401
  // Apply line height if specified
@@ -430,7 +449,9 @@ class HighlightTextView : AppCompatEditText {
430
449
 
431
450
  isUpdatingText = true
432
451
  setText(spannable)
433
- setSelection(text.length) // Keep cursor at end
452
+ // Restore cursor position, or set to end if position is invalid
453
+ val safePosition = currentSelection.coerceIn(0, text.length)
454
+ setSelection(safePosition)
434
455
  isUpdatingText = false
435
456
 
436
457
  // Detect line wraps after layout is ready
@@ -430,6 +430,9 @@ using namespace facebook::react;
430
430
  if (newViewProps.autoFocus && _textView.isEditable) {
431
431
  dispatch_async(dispatch_get_main_queue(), ^{
432
432
  [self->_textView becomeFirstResponder];
433
+ // Set cursor at the end of text
434
+ NSUInteger textLength = self->_textView.text.length;
435
+ self->_textView.selectedRange = NSMakeRange(textLength, 0);
433
436
  });
434
437
  }
435
438
  }
@@ -468,6 +471,13 @@ Class<RCTComponentViewProtocol> HighlightTextViewCls(void)
468
471
  }
469
472
  }
470
473
 
474
+ - (void)textViewDidBeginEditing:(UITextView *)textView
475
+ {
476
+ // Set cursor at the end when editing begins
477
+ NSUInteger textLength = textView.text.length;
478
+ textView.selectedRange = NSMakeRange(textLength, 0);
479
+ }
480
+
471
481
  - (void)updateFont
472
482
  {
473
483
  CGFloat fontSize = _fontSize > 0 ? _fontSize : 32.0;
@@ -519,7 +529,18 @@ Class<RCTComponentViewProtocol> HighlightTextViewCls(void)
519
529
  }
520
530
 
521
531
  _textView.font = newFont;
532
+
533
+ // Force layout manager to invalidate and recalculate layout
534
+ [_layoutManager invalidateLayoutForCharacterRange:NSMakeRange(0, _textView.textStorage.length) actualCharacterRange:NULL];
535
+ [_layoutManager invalidateDisplayForCharacterRange:NSMakeRange(0, _textView.textStorage.length)];
536
+
537
+ // Reapply character backgrounds with new font metrics
522
538
  [self applyCharacterBackgrounds];
539
+
540
+ // Force the text view to redraw
541
+ [_textView setNeedsDisplay];
542
+ [_textView setNeedsLayout];
543
+ [_textView layoutIfNeeded];
523
544
  }
524
545
 
525
546
  - (void)applyCharacterBackgrounds
@@ -529,6 +550,9 @@ Class<RCTComponentViewProtocol> HighlightTextViewCls(void)
529
550
  return;
530
551
  }
531
552
 
553
+ // Save current cursor position
554
+ NSRange currentSelection = _textView.selectedRange;
555
+
532
556
  NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc] initWithString:text];
533
557
  UIColor *bgColor = [self hexStringToColor:_characterBackgroundColor];
534
558
 
@@ -577,6 +601,12 @@ Class<RCTComponentViewProtocol> HighlightTextViewCls(void)
577
601
  }
578
602
 
579
603
  _textView.attributedText = attributedString;
604
+
605
+ // Restore cursor position if valid
606
+ if (currentSelection.location <= text.length) {
607
+ _textView.selectedRange = currentSelection;
608
+ }
609
+
580
610
  [_textView setNeedsDisplay];
581
611
  }
582
612
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-native-highlight-text-view",
3
- "version": "0.1.16",
3
+ "version": "0.1.17",
4
4
  "description": "A native text input for React Native that supports inline text highlighting",
5
5
  "main": "./lib/module/index.js",
6
6
  "types": "./lib/typescript/src/index.d.ts",