react-native-highlight-text-view 0.1.21 → 0.1.23

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.
@@ -84,31 +84,79 @@ class RoundedBackgroundSpan(
84
84
  val leftPad = if (isLineStart) paddingLeft else 0f
85
85
  val rightPad = if (isLineEnd) paddingRight else 0f
86
86
 
87
- // Aggressive overlap to ensure completely seamless connection (no gaps)
88
- // Extended both horizontally AND vertically for complete coverage
89
- val overlapExtension = 4f
90
- val leftExtend = if (!isLineStart) overlapExtension else 0f
87
+ // SELECTIVE ROUNDING STRATEGY:
88
+ // 1. Line Start: Round Left corners.
89
+ // 2. Line End: Round Right corners.
90
+ // 3. Middle: Square (no rounding).
91
+ // 4. Overlap: Minimal (1px) to seal seams.
92
+
93
+ val overlapExtension = 1f
94
+
95
+ // No extension needed for start/end boundaries
96
+ val leftExtend = 0f
97
+
98
+ // Extend right slightly for middle characters to seal the gap
91
99
  val rightExtend = if (!isLineEnd) {
92
- // If this is line start, extend by padding amount to bridge the gap
93
100
  if (isLineStart) leftPad + overlapExtension else overlapExtension
94
101
  } else {
95
102
  0f
96
103
  }
97
104
 
98
- // Vertical overlap to eliminate gaps at top/bottom edges
99
- val topExtend = overlapExtension
100
- val bottomExtend = overlapExtension
105
+ // Vertical overlap to eliminate gaps (reduced to prevent descender clipping)
106
+ val topExtend = 0f
107
+ val bottomExtend = 0f
101
108
 
102
- // Calculate background rect with padding only at line boundaries
109
+ // Calculate background rect
110
+ // NOTE: Since this is a ReplacementSpan, 'x' is the start of the span (including padding).
111
+ // So we draw from 'x', not 'x - leftPad'.
103
112
  val rect = RectF(
104
- x - leftPad + backgroundInsetLeft - leftExtend,
113
+ x + backgroundInsetLeft - leftExtend,
105
114
  insetTop - paddingTop - topExtend,
106
- x + width + rightPad - backgroundInsetRight + rightExtend,
115
+ x + leftPad + width + rightPad - backgroundInsetRight + rightExtend,
107
116
  insetTop + insetHeight + paddingBottom + bottomExtend
108
117
  )
109
118
 
110
- // Draw rounded rect (full corners for all characters - they overlap seamlessly)
111
- canvas.drawRoundRect(rect, cornerRadius, cornerRadius, bgPaint)
119
+ // Draw based on position
120
+ when {
121
+ isLineStart && isLineEnd -> {
122
+ // Single character - round all corners
123
+ canvas.drawRoundRect(rect, cornerRadius, cornerRadius, bgPaint)
124
+ }
125
+ isLineStart -> {
126
+ // Line START - round LEFT corners only
127
+ val path = android.graphics.Path()
128
+ path.addRoundRect(
129
+ rect,
130
+ floatArrayOf(
131
+ cornerRadius, cornerRadius, // top-left
132
+ 0f, 0f, // top-right
133
+ 0f, 0f, // bottom-right
134
+ cornerRadius, cornerRadius // bottom-left
135
+ ),
136
+ android.graphics.Path.Direction.CW
137
+ )
138
+ canvas.drawPath(path, bgPaint)
139
+ }
140
+ isLineEnd -> {
141
+ // Line END - round RIGHT corners only
142
+ val path = android.graphics.Path()
143
+ path.addRoundRect(
144
+ rect,
145
+ floatArrayOf(
146
+ 0f, 0f, // top-left
147
+ cornerRadius, cornerRadius, // top-right
148
+ cornerRadius, cornerRadius, // bottom-right
149
+ 0f, 0f // bottom-left
150
+ ),
151
+ android.graphics.Path.Direction.CW
152
+ )
153
+ canvas.drawPath(path, bgPaint)
154
+ }
155
+ else -> {
156
+ // Middle - NO rounded corners (Square)
157
+ canvas.drawRect(rect, bgPaint)
158
+ }
159
+ }
112
160
 
113
161
  // Draw text offset by left padding only if at line start
114
162
  val textPaint = Paint(paint).apply {
@@ -205,29 +253,44 @@ class HighlightTextView : AppCompatEditText {
205
253
  charPaddingTop = top
206
254
  charPaddingRight = right
207
255
  charPaddingBottom = bottom
256
+ updateViewPadding()
208
257
  applyCharacterBackgrounds()
209
258
  }
210
259
 
211
260
  fun setCharPaddingLeft(padding: Float) {
212
261
  charPaddingLeft = padding
262
+ updateViewPadding()
213
263
  applyCharacterBackgrounds()
214
264
  }
215
265
 
216
266
  fun setCharPaddingRight(padding: Float) {
217
267
  charPaddingRight = padding
268
+ updateViewPadding()
218
269
  applyCharacterBackgrounds()
219
270
  }
220
271
 
221
272
  fun setCharPaddingTop(padding: Float) {
222
273
  charPaddingTop = padding
274
+ updateViewPadding()
223
275
  applyCharacterBackgrounds()
224
276
  }
225
277
 
226
278
  fun setCharPaddingBottom(padding: Float) {
227
279
  charPaddingBottom = padding
280
+ updateViewPadding()
228
281
  applyCharacterBackgrounds()
229
282
  }
230
283
 
284
+ private fun updateViewPadding() {
285
+ // Sync View padding with char padding to prevent clipping of background
286
+ setPadding(
287
+ charPaddingLeft.toInt(),
288
+ charPaddingTop.toInt(),
289
+ charPaddingRight.toInt(),
290
+ charPaddingBottom.toInt()
291
+ )
292
+ }
293
+
231
294
  fun setCornerRadius(radius: Float) {
232
295
  cornerRadius = radius
233
296
  applyCharacterBackgrounds()
@@ -484,10 +547,14 @@ class HighlightTextView : AppCompatEditText {
484
547
  val textStr = editable.toString()
485
548
  if (textStr.isEmpty()) return
486
549
 
487
- // Apply line height if specified
550
+ // Apply line height if specified, or add spacing for padding
488
551
  if (customLineHeight > 0) {
489
552
  val lineSpacingMultiplier = customLineHeight / textSize
490
553
  setLineSpacing(0f, lineSpacingMultiplier)
554
+ } else {
555
+ // Add line spacing to accommodate vertical padding and prevent overlap
556
+ val extraSpacing = charPaddingTop + charPaddingBottom
557
+ setLineSpacing(extraSpacing, 1.0f)
491
558
  }
492
559
 
493
560
  isUpdatingText = true
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-native-highlight-text-view",
3
- "version": "0.1.21",
3
+ "version": "0.1.23",
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",