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.
@@ -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
- _textView.textAlignment = NSTextAlignmentCenter;
222
+ _currentHorizontalAlignment = NSTextAlignmentCenter;
173
223
  } else if ([horizontalPart isEqualToString:@"right"] || [horizontalPart isEqualToString:@"flex-end"]) {
174
- _textView.textAlignment = NSTextAlignmentRight;
224
+ _currentHorizontalAlignment = NSTextAlignmentRight;
175
225
  } else if ([horizontalPart isEqualToString:@"left"] || [horizontalPart isEqualToString:@"flex-start"]) {
176
- _textView.textAlignment = NSTextAlignmentLeft;
226
+ _currentHorizontalAlignment = NSTextAlignmentLeft;
177
227
  } else if ([horizontalPart isEqualToString:@"justify"]) {
178
- _textView.textAlignment = NSTextAlignmentJustified;
228
+ _currentHorizontalAlignment = NSTextAlignmentJustified;
179
229
  } else {
180
- _textView.textAlignment = NSTextAlignmentLeft;
230
+ _currentHorizontalAlignment = NSTextAlignmentLeft;
181
231
  }
232
+ _textView.textAlignment = _currentHorizontalAlignment;
182
233
  }
183
234
 
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) {
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
- 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
-
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.4",
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",