react-native-highlight-text-view 0.1.2 → 0.1.3
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/README.md +47 -5
- package/ios/HighlightTextView.mm +63 -5
- package/lib/module/HighlightTextViewNativeComponent.ts +34 -0
- package/lib/typescript/src/HighlightTextViewNativeComponent.d.ts +19 -0
- package/lib/typescript/src/HighlightTextViewNativeComponent.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/HighlightTextViewNativeComponent.ts +34 -0
package/README.md
CHANGED
|
@@ -12,13 +12,55 @@ npm install react-native-highlight-text
|
|
|
12
12
|
|
|
13
13
|
## Usage
|
|
14
14
|
|
|
15
|
-
|
|
16
15
|
```js
|
|
17
|
-
import {
|
|
18
|
-
|
|
19
|
-
|
|
16
|
+
import { useState } from 'react';
|
|
17
|
+
import { HighlightTextView } from 'react-native-highlight-text-view';
|
|
18
|
+
|
|
19
|
+
export default function App() {
|
|
20
|
+
const [text, setText] = useState('Hello World');
|
|
21
|
+
|
|
22
|
+
return (
|
|
23
|
+
<HighlightTextView
|
|
24
|
+
color="#00A4A3"
|
|
25
|
+
textColor="#000000"
|
|
26
|
+
textAlign="flex-start"
|
|
27
|
+
fontSize="32"
|
|
28
|
+
paddingLeft="8"
|
|
29
|
+
paddingRight="8"
|
|
30
|
+
paddingTop="4"
|
|
31
|
+
paddingBottom="4"
|
|
32
|
+
text={text}
|
|
33
|
+
isEditable={true}
|
|
34
|
+
onChange={(e) => {
|
|
35
|
+
setText(e.nativeEvent.text);
|
|
36
|
+
}}
|
|
37
|
+
style={{ width: '100%', height: 200 }}
|
|
38
|
+
/>
|
|
39
|
+
);
|
|
40
|
+
}
|
|
41
|
+
```
|
|
20
42
|
|
|
21
|
-
|
|
43
|
+
## Props
|
|
44
|
+
|
|
45
|
+
| Prop | Type | Default | Description |
|
|
46
|
+
|------|------|---------|-------------|
|
|
47
|
+
| `color` | `string` | `#FFFF00` | Background highlight color (hex format) |
|
|
48
|
+
| `textColor` | `string` | - | Text color (hex format) |
|
|
49
|
+
| `textAlign` | `string` | `left` | Text alignment. Supports: `'left'`, `'center'`, `'right'`, `'justify'`, `'flex-start'`, `'flex-end'`, `'top'`, `'bottom'`, `'top-left'`, `'top-center'`, `'top-right'`, `'bottom-left'`, `'bottom-center'`, `'bottom-right'` |
|
|
50
|
+
| `verticalAlign` | `'top' \| 'center' \| 'middle' \| 'bottom'` | - | Vertical alignment (iOS only). Alternative to using combined `textAlign` values |
|
|
51
|
+
| `fontFamily` | `string` | - | Font family name |
|
|
52
|
+
| `fontSize` | `string` | `32` | Font size in points |
|
|
53
|
+
| `padding` | `string` | `4` | Padding around each character highlight |
|
|
54
|
+
| `paddingLeft` | `string` | - | Left padding for character highlight |
|
|
55
|
+
| `paddingRight` | `string` | - | Right padding for character highlight |
|
|
56
|
+
| `paddingTop` | `string` | - | Top padding for character highlight |
|
|
57
|
+
| `paddingBottom` | `string` | - | Bottom padding for character highlight |
|
|
58
|
+
| `text` | `string` | - | Controlled text value |
|
|
59
|
+
| `isEditable` | `boolean` | `true` | Whether the text is editable |
|
|
60
|
+
| `onChange` | `(event: { nativeEvent: { text: string } }) => void` | - | Callback fired when text changes |
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
**Note:** Vertical alignment is currently supported on iOS only. On Android, text will use default vertical positioning.
|
|
22
64
|
```
|
|
23
65
|
|
|
24
66
|
|
package/ios/HighlightTextView.mm
CHANGED
|
@@ -147,13 +147,54 @@ using namespace facebook::react;
|
|
|
147
147
|
|
|
148
148
|
if (oldViewProps.textAlign != newViewProps.textAlign) {
|
|
149
149
|
NSString *alignment = [[NSString alloc] initWithUTF8String: newViewProps.textAlign.c_str()];
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
150
|
+
|
|
151
|
+
// Parse combined alignment (e.g., "top-left", "bottom-center")
|
|
152
|
+
NSArray *parts = [alignment componentsSeparatedByString:@"-"];
|
|
153
|
+
NSString *verticalPart = nil;
|
|
154
|
+
NSString *horizontalPart = nil;
|
|
155
|
+
|
|
156
|
+
if (parts.count == 2) {
|
|
157
|
+
// Combined format: "top-left", "bottom-center", etc.
|
|
158
|
+
verticalPart = parts[0];
|
|
159
|
+
horizontalPart = parts[1];
|
|
154
160
|
} else {
|
|
155
|
-
|
|
161
|
+
// Single value - determine if it's horizontal or vertical
|
|
162
|
+
if ([alignment isEqualToString:@"top"] || [alignment isEqualToString:@"bottom"]) {
|
|
163
|
+
verticalPart = alignment;
|
|
164
|
+
} else {
|
|
165
|
+
horizontalPart = alignment;
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
// Apply horizontal alignment
|
|
170
|
+
if (horizontalPart) {
|
|
171
|
+
if ([horizontalPart isEqualToString:@"center"]) {
|
|
172
|
+
_textView.textAlignment = NSTextAlignmentCenter;
|
|
173
|
+
} else if ([horizontalPart isEqualToString:@"right"] || [horizontalPart isEqualToString:@"flex-end"]) {
|
|
174
|
+
_textView.textAlignment = NSTextAlignmentRight;
|
|
175
|
+
} else if ([horizontalPart isEqualToString:@"left"] || [horizontalPart isEqualToString:@"flex-start"]) {
|
|
176
|
+
_textView.textAlignment = NSTextAlignmentLeft;
|
|
177
|
+
} else if ([horizontalPart isEqualToString:@"justify"]) {
|
|
178
|
+
_textView.textAlignment = NSTextAlignmentJustified;
|
|
179
|
+
} else {
|
|
180
|
+
_textView.textAlignment = NSTextAlignmentLeft;
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
// Apply vertical alignment via textContainerInset
|
|
185
|
+
if ([verticalPart isEqualToString:@"top"]) {
|
|
186
|
+
_textView.textContainerInset = UIEdgeInsetsMake(10, 10, 0, 10);
|
|
187
|
+
} else if ([verticalPart isEqualToString:@"bottom"]) {
|
|
188
|
+
// Calculate bottom alignment by adjusting top inset
|
|
189
|
+
CGFloat contentHeight = [_textView.layoutManager usedRectForTextContainer:_textView.textContainer].size.height;
|
|
190
|
+
CGFloat viewHeight = _textView.bounds.size.height;
|
|
191
|
+
CGFloat topInset = MAX(10, viewHeight - contentHeight - 10);
|
|
192
|
+
_textView.textContainerInset = UIEdgeInsetsMake(topInset, 10, 10, 10);
|
|
193
|
+
} else if (!verticalPart) {
|
|
194
|
+
// Default vertical centering for horizontal-only alignments
|
|
195
|
+
_textView.textContainerInset = UIEdgeInsetsMake(10, 10, 10, 10);
|
|
156
196
|
}
|
|
197
|
+
|
|
157
198
|
[self applyCharacterBackgrounds]; // Reapply to update alignment
|
|
158
199
|
}
|
|
159
200
|
|
|
@@ -235,6 +276,23 @@ using namespace facebook::react;
|
|
|
235
276
|
if (oldViewProps.isEditable != newViewProps.isEditable) {
|
|
236
277
|
_textView.editable = newViewProps.isEditable;
|
|
237
278
|
}
|
|
279
|
+
|
|
280
|
+
if (oldViewProps.verticalAlign != newViewProps.verticalAlign) {
|
|
281
|
+
NSString *verticalAlign = [[NSString alloc] initWithUTF8String: newViewProps.verticalAlign.c_str()];
|
|
282
|
+
|
|
283
|
+
if ([verticalAlign isEqualToString:@"top"]) {
|
|
284
|
+
_textView.textContainerInset = UIEdgeInsetsMake(10, 10, 0, 10);
|
|
285
|
+
} else if ([verticalAlign isEqualToString:@"bottom"]) {
|
|
286
|
+
CGFloat contentHeight = [_textView.layoutManager usedRectForTextContainer:_textView.textContainer].size.height;
|
|
287
|
+
CGFloat viewHeight = _textView.bounds.size.height;
|
|
288
|
+
CGFloat topInset = MAX(10, viewHeight - contentHeight - 10);
|
|
289
|
+
_textView.textContainerInset = UIEdgeInsetsMake(topInset, 10, 10, 10);
|
|
290
|
+
} else if ([verticalAlign isEqualToString:@"center"] || [verticalAlign isEqualToString:@"middle"]) {
|
|
291
|
+
_textView.textContainerInset = UIEdgeInsetsMake(10, 10, 10, 10);
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
[self applyCharacterBackgrounds];
|
|
295
|
+
}
|
|
238
296
|
|
|
239
297
|
[super updateProps:props oldProps:oldProps];
|
|
240
298
|
}
|
|
@@ -6,10 +6,44 @@ export interface OnChangeEventData {
|
|
|
6
6
|
readonly text: string;
|
|
7
7
|
}
|
|
8
8
|
|
|
9
|
+
/**
|
|
10
|
+
* Text alignment options
|
|
11
|
+
*
|
|
12
|
+
* Horizontal alignment:
|
|
13
|
+
* - 'left' or 'flex-start': Align text to the left
|
|
14
|
+
* - 'center': Center align text
|
|
15
|
+
* - 'right' or 'flex-end': Align text to the right
|
|
16
|
+
* - 'justify': Justify text (distribute evenly)
|
|
17
|
+
*
|
|
18
|
+
* Vertical alignment (iOS only):
|
|
19
|
+
* - 'top': Align to top
|
|
20
|
+
* - 'bottom': Align to bottom
|
|
21
|
+
*
|
|
22
|
+
* Combined alignment (iOS only):
|
|
23
|
+
* - 'top-left', 'top-center', 'top-right'
|
|
24
|
+
* - 'bottom-left', 'bottom-center', 'bottom-right'
|
|
25
|
+
*/
|
|
26
|
+
export type TextAlignment =
|
|
27
|
+
| 'left'
|
|
28
|
+
| 'center'
|
|
29
|
+
| 'right'
|
|
30
|
+
| 'justify'
|
|
31
|
+
| 'flex-start'
|
|
32
|
+
| 'flex-end'
|
|
33
|
+
| 'top'
|
|
34
|
+
| 'bottom'
|
|
35
|
+
| 'top-left'
|
|
36
|
+
| 'top-center'
|
|
37
|
+
| 'top-right'
|
|
38
|
+
| 'bottom-left'
|
|
39
|
+
| 'bottom-center'
|
|
40
|
+
| 'bottom-right';
|
|
41
|
+
|
|
9
42
|
export interface HighlightTextViewProps extends ViewProps {
|
|
10
43
|
color?: string;
|
|
11
44
|
textColor?: string;
|
|
12
45
|
textAlign?: string;
|
|
46
|
+
verticalAlign?: string;
|
|
13
47
|
fontFamily?: string;
|
|
14
48
|
fontSize?: string;
|
|
15
49
|
padding?: string;
|
|
@@ -3,10 +3,29 @@ import type { BubblingEventHandler } from 'react-native/Libraries/Types/CodegenT
|
|
|
3
3
|
export interface OnChangeEventData {
|
|
4
4
|
readonly text: string;
|
|
5
5
|
}
|
|
6
|
+
/**
|
|
7
|
+
* Text alignment options
|
|
8
|
+
*
|
|
9
|
+
* Horizontal alignment:
|
|
10
|
+
* - 'left' or 'flex-start': Align text to the left
|
|
11
|
+
* - 'center': Center align text
|
|
12
|
+
* - 'right' or 'flex-end': Align text to the right
|
|
13
|
+
* - 'justify': Justify text (distribute evenly)
|
|
14
|
+
*
|
|
15
|
+
* Vertical alignment (iOS only):
|
|
16
|
+
* - 'top': Align to top
|
|
17
|
+
* - 'bottom': Align to bottom
|
|
18
|
+
*
|
|
19
|
+
* Combined alignment (iOS only):
|
|
20
|
+
* - 'top-left', 'top-center', 'top-right'
|
|
21
|
+
* - 'bottom-left', 'bottom-center', 'bottom-right'
|
|
22
|
+
*/
|
|
23
|
+
export type TextAlignment = 'left' | 'center' | 'right' | 'justify' | 'flex-start' | 'flex-end' | 'top' | 'bottom' | 'top-left' | 'top-center' | 'top-right' | 'bottom-left' | 'bottom-center' | 'bottom-right';
|
|
6
24
|
export interface HighlightTextViewProps extends ViewProps {
|
|
7
25
|
color?: string;
|
|
8
26
|
textColor?: string;
|
|
9
27
|
textAlign?: string;
|
|
28
|
+
verticalAlign?: string;
|
|
10
29
|
fontFamily?: string;
|
|
11
30
|
fontSize?: string;
|
|
12
31
|
padding?: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"HighlightTextViewNativeComponent.d.ts","sourceRoot":"","sources":["../../../src/HighlightTextViewNativeComponent.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AAEtF,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,sBAAuB,SAAQ,SAAS;IACvD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,QAAQ,CAAC,EAAE,oBAAoB,CAAC,iBAAiB,CAAC,CAAC;CACpD;;AAED,wBAEE"}
|
|
1
|
+
{"version":3,"file":"HighlightTextViewNativeComponent.d.ts","sourceRoot":"","sources":["../../../src/HighlightTextViewNativeComponent.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AAEtF,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACvB;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,MAAM,aAAa,GACrB,MAAM,GACN,QAAQ,GACR,OAAO,GACP,SAAS,GACT,YAAY,GACZ,UAAU,GACV,KAAK,GACL,QAAQ,GACR,UAAU,GACV,YAAY,GACZ,WAAW,GACX,aAAa,GACb,eAAe,GACf,cAAc,CAAC;AAEnB,MAAM,WAAW,sBAAuB,SAAQ,SAAS;IACvD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,QAAQ,CAAC,EAAE,oBAAoB,CAAC,iBAAiB,CAAC,CAAC;CACpD;;AAED,wBAEE"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "react-native-highlight-text-view",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.3",
|
|
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",
|
|
@@ -6,10 +6,44 @@ export interface OnChangeEventData {
|
|
|
6
6
|
readonly text: string;
|
|
7
7
|
}
|
|
8
8
|
|
|
9
|
+
/**
|
|
10
|
+
* Text alignment options
|
|
11
|
+
*
|
|
12
|
+
* Horizontal alignment:
|
|
13
|
+
* - 'left' or 'flex-start': Align text to the left
|
|
14
|
+
* - 'center': Center align text
|
|
15
|
+
* - 'right' or 'flex-end': Align text to the right
|
|
16
|
+
* - 'justify': Justify text (distribute evenly)
|
|
17
|
+
*
|
|
18
|
+
* Vertical alignment (iOS only):
|
|
19
|
+
* - 'top': Align to top
|
|
20
|
+
* - 'bottom': Align to bottom
|
|
21
|
+
*
|
|
22
|
+
* Combined alignment (iOS only):
|
|
23
|
+
* - 'top-left', 'top-center', 'top-right'
|
|
24
|
+
* - 'bottom-left', 'bottom-center', 'bottom-right'
|
|
25
|
+
*/
|
|
26
|
+
export type TextAlignment =
|
|
27
|
+
| 'left'
|
|
28
|
+
| 'center'
|
|
29
|
+
| 'right'
|
|
30
|
+
| 'justify'
|
|
31
|
+
| 'flex-start'
|
|
32
|
+
| 'flex-end'
|
|
33
|
+
| 'top'
|
|
34
|
+
| 'bottom'
|
|
35
|
+
| 'top-left'
|
|
36
|
+
| 'top-center'
|
|
37
|
+
| 'top-right'
|
|
38
|
+
| 'bottom-left'
|
|
39
|
+
| 'bottom-center'
|
|
40
|
+
| 'bottom-right';
|
|
41
|
+
|
|
9
42
|
export interface HighlightTextViewProps extends ViewProps {
|
|
10
43
|
color?: string;
|
|
11
44
|
textColor?: string;
|
|
12
45
|
textAlign?: string;
|
|
46
|
+
verticalAlign?: string;
|
|
13
47
|
fontFamily?: string;
|
|
14
48
|
fontSize?: string;
|
|
15
49
|
padding?: string;
|