react-native-highlight-text-view 0.1.4 → 0.1.5
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/ios/HighlightTextView.mm +76 -27
- package/package.json +1 -1
package/ios/HighlightTextView.mm
CHANGED
|
@@ -74,6 +74,8 @@ using namespace facebook::react;
|
|
|
74
74
|
CGFloat _paddingBottom;
|
|
75
75
|
CGFloat _cornerRadius;
|
|
76
76
|
BOOL _isUpdatingText;
|
|
77
|
+
NSString * _currentVerticalAlignment;
|
|
78
|
+
NSTextAlignment _currentHorizontalAlignment;
|
|
77
79
|
}
|
|
78
80
|
|
|
79
81
|
+ (ComponentDescriptorProvider)componentDescriptorProvider
|
|
@@ -94,6 +96,8 @@ using namespace facebook::react;
|
|
|
94
96
|
_paddingTop = 4.0;
|
|
95
97
|
_paddingBottom = 4.0;
|
|
96
98
|
_cornerRadius = 4.0;
|
|
99
|
+
_currentVerticalAlignment = nil;
|
|
100
|
+
_currentHorizontalAlignment = NSTextAlignmentCenter;
|
|
97
101
|
|
|
98
102
|
// Create text storage, layout manager, and text container
|
|
99
103
|
NSTextStorage *textStorage = [[NSTextStorage alloc] init];
|
|
@@ -128,6 +132,52 @@ using namespace facebook::react;
|
|
|
128
132
|
return self;
|
|
129
133
|
}
|
|
130
134
|
|
|
135
|
+
- (void)layoutSubviews
|
|
136
|
+
{
|
|
137
|
+
[super layoutSubviews];
|
|
138
|
+
|
|
139
|
+
// Recalculate vertical alignment after layout
|
|
140
|
+
if (_currentVerticalAlignment) {
|
|
141
|
+
[self updateVerticalAlignment:_currentVerticalAlignment];
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
- (void)updateVerticalAlignment:(NSString *)verticalAlign
|
|
146
|
+
{
|
|
147
|
+
if ([verticalAlign isEqualToString:@"top"]) {
|
|
148
|
+
_textView.textContainerInset = UIEdgeInsetsMake(10, 10, 0, 10);
|
|
149
|
+
} else if ([verticalAlign isEqualToString:@"bottom"]) {
|
|
150
|
+
// Force layout to get accurate content height
|
|
151
|
+
[_textView.layoutManager ensureLayoutForTextContainer:_textView.textContainer];
|
|
152
|
+
|
|
153
|
+
CGFloat contentHeight = [_textView.layoutManager usedRectForTextContainer:_textView.textContainer].size.height;
|
|
154
|
+
CGFloat viewHeight = _textView.bounds.size.height;
|
|
155
|
+
|
|
156
|
+
// Only apply bottom alignment if we have valid dimensions
|
|
157
|
+
if (viewHeight > 0 && contentHeight > 0) {
|
|
158
|
+
if (contentHeight + 20 <= viewHeight) {
|
|
159
|
+
// Content fits in view - align to bottom with inset
|
|
160
|
+
CGFloat topInset = MAX(10, viewHeight - contentHeight - 10);
|
|
161
|
+
_textView.textContainerInset = UIEdgeInsetsMake(topInset, 10, 10, 10);
|
|
162
|
+
} else {
|
|
163
|
+
// Content exceeds view - use minimal inset and scroll to bottom
|
|
164
|
+
_textView.textContainerInset = UIEdgeInsetsMake(10, 10, 10, 10);
|
|
165
|
+
|
|
166
|
+
// Scroll to bottom to show the latest text
|
|
167
|
+
dispatch_async(dispatch_get_main_queue(), ^{
|
|
168
|
+
CGFloat bottomOffset = self->_textView.contentSize.height - self->_textView.bounds.size.height + self->_textView.contentInset.bottom;
|
|
169
|
+
if (bottomOffset > 0) {
|
|
170
|
+
[self->_textView setContentOffset:CGPointMake(0, bottomOffset) animated:NO];
|
|
171
|
+
}
|
|
172
|
+
});
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
} else {
|
|
176
|
+
// Default or center
|
|
177
|
+
_textView.textContainerInset = UIEdgeInsetsMake(10, 10, 10, 10);
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
|
|
131
181
|
- (void)updateProps:(Props::Shared const &)props oldProps:(Props::Shared const &)oldProps
|
|
132
182
|
{
|
|
133
183
|
const auto &oldViewProps = *std::static_pointer_cast<HighlightTextViewProps const>(_props);
|
|
@@ -169,29 +219,26 @@ using namespace facebook::react;
|
|
|
169
219
|
// Apply horizontal alignment
|
|
170
220
|
if (horizontalPart) {
|
|
171
221
|
if ([horizontalPart isEqualToString:@"center"]) {
|
|
172
|
-
|
|
222
|
+
_currentHorizontalAlignment = NSTextAlignmentCenter;
|
|
173
223
|
} else if ([horizontalPart isEqualToString:@"right"] || [horizontalPart isEqualToString:@"flex-end"]) {
|
|
174
|
-
|
|
224
|
+
_currentHorizontalAlignment = NSTextAlignmentRight;
|
|
175
225
|
} else if ([horizontalPart isEqualToString:@"left"] || [horizontalPart isEqualToString:@"flex-start"]) {
|
|
176
|
-
|
|
226
|
+
_currentHorizontalAlignment = NSTextAlignmentLeft;
|
|
177
227
|
} else if ([horizontalPart isEqualToString:@"justify"]) {
|
|
178
|
-
|
|
228
|
+
_currentHorizontalAlignment = NSTextAlignmentJustified;
|
|
179
229
|
} else {
|
|
180
|
-
|
|
230
|
+
_currentHorizontalAlignment = NSTextAlignmentLeft;
|
|
181
231
|
}
|
|
232
|
+
_textView.textAlignment = _currentHorizontalAlignment;
|
|
182
233
|
}
|
|
183
234
|
|
|
184
|
-
//
|
|
185
|
-
if (
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
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) {
|
|
235
|
+
// Store and apply vertical alignment
|
|
236
|
+
if (verticalPart) {
|
|
237
|
+
_currentVerticalAlignment = verticalPart;
|
|
238
|
+
[self updateVerticalAlignment:verticalPart];
|
|
239
|
+
} else if (!verticalPart && horizontalPart) {
|
|
194
240
|
// Default vertical centering for horizontal-only alignments
|
|
241
|
+
_currentVerticalAlignment = nil;
|
|
195
242
|
_textView.textContainerInset = UIEdgeInsetsMake(10, 10, 10, 10);
|
|
196
243
|
}
|
|
197
244
|
|
|
@@ -269,6 +316,12 @@ using namespace facebook::react;
|
|
|
269
316
|
_isUpdatingText = YES;
|
|
270
317
|
_textView.text = text;
|
|
271
318
|
[self applyCharacterBackgrounds];
|
|
319
|
+
|
|
320
|
+
// Recalculate vertical alignment when text changes
|
|
321
|
+
if (_currentVerticalAlignment) {
|
|
322
|
+
[self updateVerticalAlignment:_currentVerticalAlignment];
|
|
323
|
+
}
|
|
324
|
+
|
|
272
325
|
_isUpdatingText = NO;
|
|
273
326
|
}
|
|
274
327
|
}
|
|
@@ -279,18 +332,8 @@ using namespace facebook::react;
|
|
|
279
332
|
|
|
280
333
|
if (oldViewProps.verticalAlign != newViewProps.verticalAlign) {
|
|
281
334
|
NSString *verticalAlign = [[NSString alloc] initWithUTF8String: newViewProps.verticalAlign.c_str()];
|
|
282
|
-
|
|
283
|
-
|
|
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
|
-
|
|
335
|
+
_currentVerticalAlignment = verticalAlign;
|
|
336
|
+
[self updateVerticalAlignment:verticalAlign];
|
|
294
337
|
[self applyCharacterBackgrounds];
|
|
295
338
|
}
|
|
296
339
|
|
|
@@ -305,6 +348,12 @@ Class<RCTComponentViewProtocol> HighlightTextViewCls(void)
|
|
|
305
348
|
- (void)textViewDidChange:(UITextView *)textView
|
|
306
349
|
{
|
|
307
350
|
[self applyCharacterBackgrounds];
|
|
351
|
+
|
|
352
|
+
// Recalculate vertical alignment when text changes
|
|
353
|
+
if (_currentVerticalAlignment) {
|
|
354
|
+
[self updateVerticalAlignment:_currentVerticalAlignment];
|
|
355
|
+
}
|
|
356
|
+
|
|
308
357
|
if (!_isUpdatingText) {
|
|
309
358
|
if (_eventEmitter != nullptr) {
|
|
310
359
|
std::dynamic_pointer_cast<const HighlightTextViewEventEmitter>(_eventEmitter)
|
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.5",
|
|
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",
|