react-native-advanced-text 0.1.42 → 0.1.44
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.
- package/android/src/main/java/com/advancedtext/AdvancedTextView.kt +40 -6
- package/android/src/main/java/com/advancedtext/AdvancedTextViewManager.kt +8 -0
- package/ios/AdvancedTextView.mm +35 -3
- package/lib/module/AdvancedTextViewNativeComponent.ts +1 -0
- package/lib/typescript/src/AdvancedTextViewNativeComponent.d.ts +1 -0
- package/lib/typescript/src/AdvancedTextViewNativeComponent.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/AdvancedTextViewNativeComponent.ts +1 -0
|
@@ -44,6 +44,7 @@ class AdvancedTextView : TextView {
|
|
|
44
44
|
|
|
45
45
|
private var indicatorWordIndex: Int = -1
|
|
46
46
|
private var indicatorColor: String = ""
|
|
47
|
+
private var indicatorMode: String = "Highlight"
|
|
47
48
|
|
|
48
49
|
private var wordPositions: List<WordPosition> = emptyList()
|
|
49
50
|
|
|
@@ -162,12 +163,27 @@ class AdvancedTextView : TextView {
|
|
|
162
163
|
fun setIndicatorWordIndex(index: Int) {
|
|
163
164
|
if (indicatorWordIndex == index) return
|
|
164
165
|
indicatorWordIndex = index
|
|
165
|
-
|
|
166
|
+
if (indicatorMode == "fill") {
|
|
167
|
+
updateTextWithHighlights()
|
|
168
|
+
} else {
|
|
169
|
+
invalidate()
|
|
170
|
+
}
|
|
166
171
|
}
|
|
167
172
|
|
|
168
173
|
fun setIndicatorColor(color: String) {
|
|
169
174
|
if (indicatorColor == color) return
|
|
170
175
|
indicatorColor = color
|
|
176
|
+
if (indicatorMode == "fill") {
|
|
177
|
+
updateTextWithHighlights()
|
|
178
|
+
} else {
|
|
179
|
+
invalidate()
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
fun setIndicatorMode(mode: String) {
|
|
184
|
+
if (indicatorMode == mode) return
|
|
185
|
+
indicatorMode = mode
|
|
186
|
+
updateTextWithHighlights()
|
|
171
187
|
invalidate()
|
|
172
188
|
}
|
|
173
189
|
|
|
@@ -214,11 +230,19 @@ class AdvancedTextView : TextView {
|
|
|
214
230
|
val spannableString = SpannableString(currentText)
|
|
215
231
|
|
|
216
232
|
wordPositions.forEach { wordPos ->
|
|
233
|
+
val wordColor = if (indicatorMode == "fill" &&
|
|
234
|
+
indicatorWordIndex >= 0 &&
|
|
235
|
+
wordPos.index <= indicatorWordIndex &&
|
|
236
|
+
indicatorColor.isNotEmpty()) {
|
|
237
|
+
parseColor(indicatorColor)
|
|
238
|
+
} else {
|
|
239
|
+
parseColor(textColor)
|
|
240
|
+
}
|
|
217
241
|
spannableString.setSpan(
|
|
218
242
|
WordClickableSpan(
|
|
219
243
|
wordIndex = wordPos.index,
|
|
220
244
|
word = wordPos.word,
|
|
221
|
-
wordColor =
|
|
245
|
+
wordColor = wordColor
|
|
222
246
|
),
|
|
223
247
|
wordPos.start,
|
|
224
248
|
wordPos.end,
|
|
@@ -280,7 +304,12 @@ class AdvancedTextView : TextView {
|
|
|
280
304
|
if (lineStartOffset >= lineEndOffset) continue
|
|
281
305
|
|
|
282
306
|
val left = currentLayout.getPrimaryHorizontal(lineStartOffset)
|
|
283
|
-
val
|
|
307
|
+
val isLastWordOnLine = lineEndOffset >= currentLayout.getLineEnd(line)
|
|
308
|
+
val right = if (isLastWordOnLine) {
|
|
309
|
+
currentLayout.getLineRight(line)
|
|
310
|
+
} else {
|
|
311
|
+
currentLayout.getPrimaryHorizontal(lineEndOffset)
|
|
312
|
+
}
|
|
284
313
|
val top = currentLayout.getLineTop(line).toFloat()
|
|
285
314
|
val bottom = currentLayout.getLineBottom(line).toFloat()
|
|
286
315
|
val rect = RectF(
|
|
@@ -294,8 +323,8 @@ class AdvancedTextView : TextView {
|
|
|
294
323
|
}
|
|
295
324
|
}
|
|
296
325
|
|
|
297
|
-
// Draw indicator
|
|
298
|
-
if (indicatorWordIndex >= 0 && indicatorColor.isNotEmpty()) {
|
|
326
|
+
// Draw indicator background only in Highlight mode
|
|
327
|
+
if (indicatorMode != "fill" && indicatorWordIndex >= 0 && indicatorColor.isNotEmpty()) {
|
|
299
328
|
val wordPos = wordPositions.find { it.index == indicatorWordIndex }
|
|
300
329
|
if (wordPos != null) {
|
|
301
330
|
val start = wordPos.start
|
|
@@ -314,7 +343,12 @@ class AdvancedTextView : TextView {
|
|
|
314
343
|
if (lineStartOffset >= lineEndOffset) continue
|
|
315
344
|
|
|
316
345
|
val left = currentLayout.getPrimaryHorizontal(lineStartOffset)
|
|
317
|
-
val
|
|
346
|
+
val isLastWordOnLine = lineEndOffset >= currentLayout.getLineEnd(line)
|
|
347
|
+
val right = if (isLastWordOnLine) {
|
|
348
|
+
currentLayout.getLineRight(line)
|
|
349
|
+
} else {
|
|
350
|
+
currentLayout.getPrimaryHorizontal(lineEndOffset)
|
|
351
|
+
}
|
|
318
352
|
val top = currentLayout.getLineTop(line).toFloat()
|
|
319
353
|
val bottom = currentLayout.getLineBottom(line).toFloat()
|
|
320
354
|
val rect = RectF(
|
|
@@ -136,6 +136,14 @@ class AdvancedTextViewManager : SimpleViewManager<AdvancedTextView>() {
|
|
|
136
136
|
}
|
|
137
137
|
}
|
|
138
138
|
|
|
139
|
+
@ReactProp(name = "indicatorMode")
|
|
140
|
+
fun setIndicatorMode(view: AdvancedTextView?, indicatorMode: String?) {
|
|
141
|
+
android.util.Log.d(NAME, "setIndicatorMode called with: $indicatorMode")
|
|
142
|
+
if (indicatorMode != null) {
|
|
143
|
+
view?.setIndicatorMode(indicatorMode)
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
|
|
139
147
|
@ReactProp(name = "lineHeight")
|
|
140
148
|
fun setLineHeight(view: AdvancedTextView?, lineHeight: Float) {
|
|
141
149
|
android.util.Log.d(NAME, "setLineHeight called with: $lineHeight")
|
package/ios/AdvancedTextView.mm
CHANGED
|
@@ -25,6 +25,7 @@ using namespace facebook::react;
|
|
|
25
25
|
@property (nonatomic, assign) CGFloat lineHeight;
|
|
26
26
|
@property (nonatomic, assign) NSInteger indicatorWordIndex;
|
|
27
27
|
@property (nonatomic, strong) UIColor *indicatorColor;
|
|
28
|
+
@property (nonatomic, strong) NSString *indicatorMode;
|
|
28
29
|
|
|
29
30
|
- (void)handleCustomMenuAction:(UIMenuItem *)sender;
|
|
30
31
|
- (void)drawHighlightedBackgroundsInTextView:(UITextView *)textView;
|
|
@@ -100,6 +101,7 @@ using namespace facebook::react;
|
|
|
100
101
|
_lineHeight = 0.0;
|
|
101
102
|
_indicatorWordIndex = -1;
|
|
102
103
|
_indicatorColor = nil;
|
|
104
|
+
_indicatorMode = @"Highlight";
|
|
103
105
|
|
|
104
106
|
[self setupTextView];
|
|
105
107
|
[self setupGestureRecognizers];
|
|
@@ -234,10 +236,20 @@ using namespace facebook::react;
|
|
|
234
236
|
styleChanged = YES;
|
|
235
237
|
}
|
|
236
238
|
|
|
239
|
+
BOOL indicatorChanged = NO;
|
|
240
|
+
|
|
241
|
+
if (oldViewProps.indicatorMode != newViewProps.indicatorMode) {
|
|
242
|
+
NSLog(@"[AdvancedTextView] Updating indicatorMode to: %s", newViewProps.indicatorMode.c_str());
|
|
243
|
+
_indicatorMode = newViewProps.indicatorMode.empty()
|
|
244
|
+
? @"Highlight"
|
|
245
|
+
: [NSString stringWithUTF8String:newViewProps.indicatorMode.c_str()];
|
|
246
|
+
indicatorChanged = YES;
|
|
247
|
+
}
|
|
248
|
+
|
|
237
249
|
if (oldViewProps.indicatorWordIndex != newViewProps.indicatorWordIndex) {
|
|
238
250
|
NSLog(@"[AdvancedTextView] Updating indicatorWordIndex to: %d", newViewProps.indicatorWordIndex);
|
|
239
251
|
_indicatorWordIndex = static_cast<NSInteger>(newViewProps.indicatorWordIndex);
|
|
240
|
-
|
|
252
|
+
indicatorChanged = YES;
|
|
241
253
|
}
|
|
242
254
|
|
|
243
255
|
if (oldViewProps.indicatorColor != newViewProps.indicatorColor) {
|
|
@@ -248,7 +260,15 @@ using namespace facebook::react;
|
|
|
248
260
|
} else {
|
|
249
261
|
_indicatorColor = nil;
|
|
250
262
|
}
|
|
251
|
-
|
|
263
|
+
indicatorChanged = YES;
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
if (indicatorChanged) {
|
|
267
|
+
if ([_indicatorMode isEqualToString:@"fill"]) {
|
|
268
|
+
[self updateTextAppearance]; // rebuilds attributed text with fill colors; calls setNeedsDisplay
|
|
269
|
+
} else {
|
|
270
|
+
[_textView setNeedsDisplay];
|
|
271
|
+
}
|
|
252
272
|
}
|
|
253
273
|
|
|
254
274
|
if (textChanged) {
|
|
@@ -452,6 +472,18 @@ using namespace facebook::react;
|
|
|
452
472
|
value:color
|
|
453
473
|
range:NSMakeRange(0, attributedString.length)];
|
|
454
474
|
|
|
475
|
+
if ([_indicatorMode isEqualToString:@"fill"] && _indicatorWordIndex >= 0 && _indicatorColor) {
|
|
476
|
+
for (NSDictionary *wordInfo in _wordRanges) {
|
|
477
|
+
NSInteger idx = [wordInfo[@"index"] integerValue];
|
|
478
|
+
if (idx <= _indicatorWordIndex) {
|
|
479
|
+
NSRange wordRange = [wordInfo[@"range"] rangeValue];
|
|
480
|
+
[attributedString addAttribute:NSForegroundColorAttributeName
|
|
481
|
+
value:_indicatorColor
|
|
482
|
+
range:wordRange];
|
|
483
|
+
}
|
|
484
|
+
}
|
|
485
|
+
}
|
|
486
|
+
|
|
455
487
|
_textView.attributedText = attributedString;
|
|
456
488
|
[_textView setNeedsDisplay];
|
|
457
489
|
|
|
@@ -513,7 +545,7 @@ using namespace facebook::react;
|
|
|
513
545
|
}];
|
|
514
546
|
}
|
|
515
547
|
|
|
516
|
-
if (_indicatorWordIndex >= 0 && _indicatorColor) {
|
|
548
|
+
if (![_indicatorMode isEqualToString:@"fill"] && _indicatorWordIndex >= 0 && _indicatorColor) {
|
|
517
549
|
for (NSDictionary *wordInfo in _wordRanges) {
|
|
518
550
|
NSNumber *index = wordInfo[@"index"];
|
|
519
551
|
if ([index integerValue] != _indicatorWordIndex) {
|
|
@@ -25,6 +25,7 @@ export interface NativeProps extends ViewProps {
|
|
|
25
25
|
lineHeight?: Float;
|
|
26
26
|
indicatorWordIndex?: Int32;
|
|
27
27
|
indicatorColor?: string;
|
|
28
|
+
indicatorMode?: string;
|
|
28
29
|
}
|
|
29
30
|
declare const _default: import("react-native/types_generated/Libraries/Utilities/codegenNativeComponent").NativeComponentType<NativeProps>;
|
|
30
31
|
export default _default;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AdvancedTextViewNativeComponent.d.ts","sourceRoot":"","sources":["../../../src/AdvancedTextViewNativeComponent.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAG9C,OAAO,KAAK,EAAE,kBAAkB,EAAE,KAAK,EAAG,KAAK,EAAG,MAAM,2CAA2C,CAAC;AAEpG,UAAU,eAAe;IACvB,KAAK,EAAE,KAAK,CAAC;IACb,cAAc,EAAE,MAAM,CAAC;IACvB,YAAY,CAAC,EAAE,KAAK,CAAC;CACtB;AAED,MAAM,WAAW,WAAY,SAAQ,SAAS;IAC5C,IAAI,EAAE,MAAM,CAAC;IACb,gBAAgB,CAAC,EAAE,aAAa,CAAC,eAAe,CAAC,CAAC;IAClD,WAAW,CAAC,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;IACpC,WAAW,CAAC,EAAE,kBAAkB,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,KAAK,CAAA;KAAE,CAAC,CAAC;IACjE,WAAW,CAAC,EAAE,kBAAkB,CAAC;QAAE,YAAY,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC1E,QAAQ,CAAC,EAAE,KAAK,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,KAAK,CAAC;IACnB,kBAAkB,CAAC,EAAE,KAAK,CAAC;IAC3B,cAAc,CAAC,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"AdvancedTextViewNativeComponent.d.ts","sourceRoot":"","sources":["../../../src/AdvancedTextViewNativeComponent.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAG9C,OAAO,KAAK,EAAE,kBAAkB,EAAE,KAAK,EAAG,KAAK,EAAG,MAAM,2CAA2C,CAAC;AAEpG,UAAU,eAAe;IACvB,KAAK,EAAE,KAAK,CAAC;IACb,cAAc,EAAE,MAAM,CAAC;IACvB,YAAY,CAAC,EAAE,KAAK,CAAC;CACtB;AAED,MAAM,WAAW,WAAY,SAAQ,SAAS;IAC5C,IAAI,EAAE,MAAM,CAAC;IACb,gBAAgB,CAAC,EAAE,aAAa,CAAC,eAAe,CAAC,CAAC;IAClD,WAAW,CAAC,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;IACpC,WAAW,CAAC,EAAE,kBAAkB,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,KAAK,CAAA;KAAE,CAAC,CAAC;IACjE,WAAW,CAAC,EAAE,kBAAkB,CAAC;QAAE,YAAY,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC1E,QAAQ,CAAC,EAAE,KAAK,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,KAAK,CAAC;IACnB,kBAAkB,CAAC,EAAE,KAAK,CAAC;IAC3B,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;;AAED,wBAAuE"}
|
package/package.json
CHANGED