@nativescript/input-accessory 1.0.0 → 1.0.2

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/CHANGELOG.md ADDED
@@ -0,0 +1,9 @@
1
+ # 1.0.0 (2026-02-26)
2
+
3
+ ### 🚀 Features
4
+
5
+ - input accessory ([#659](https://github.com/NativeScript/plugins/pull/659))
6
+
7
+ ### ❤️ Thank You
8
+
9
+ - Nathan Walker
package/index.ios.js CHANGED
@@ -44,6 +44,14 @@ export class InputAccessoryManager extends InputAccessoryManagerBase {
44
44
  bottom: 10,
45
45
  right: 10,
46
46
  });
47
+ nativeTextView.autocorrectionType = 2 /* UITextAutocorrectionType.Yes */;
48
+ nativeTextView.spellCheckingType = 1 /* UITextSpellCheckingType.No */;
49
+ nativeTextView.smartQuotesType = 1 /* UITextSmartQuotesType.No */;
50
+ nativeTextView.smartDashesType = 1 /* UITextSmartDashesType.No */;
51
+ nativeTextView.smartInsertDeleteType = 1 /* UITextSmartInsertDeleteType.No */;
52
+ nativeTextView.inputAssistantItem.leadingBarButtonGroups = Utils.ios.collections.jsArrayToNSArray([]);
53
+ nativeTextView.inputAssistantItem.trailingBarButtonGroups = Utils.ios.collections.jsArrayToNSArray([]);
54
+ this.keyboardTrackingView.setTextInputView(nativeTextView);
47
55
  }
48
56
  // Run initial layout of children within the accessory dimensions
49
57
  setTimeout(() => this.relayoutAccessory(), 50);
@@ -71,9 +79,10 @@ export class InputAccessoryManager extends InputAccessoryManagerBase {
71
79
  */
72
80
  dismissKeyboard() {
73
81
  if (this.keyboardTrackingView) {
74
- this.keyboardTrackingView.setDismissingKeyboard();
75
- this.keyboardTrackingView.becomeFirstResponder();
82
+ this.keyboardTrackingView.dismissKeyboard();
83
+ return;
76
84
  }
85
+ Utils.dismissKeyboard();
77
86
  }
78
87
  cleanup() {
79
88
  if (this.keyboardTrackingView) {
package/index.ios.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.ios.js","sourceRoot":"","sources":["../../../packages/input-accessory/index.ios.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.ios.js","sourceRoot":"","sources":["../../../packages/input-accessory/index.ios.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nativescript/input-accessory",
3
- "version": "1.0.0",
3
+ "version": "1.0.2",
4
4
  "description": "iOS/Android keyboard input accessory for NativeScript chat UIs — docked input bar, interactive dismiss, auto-scroll",
5
5
  "main": "index",
6
6
  "types": "index.d.ts",
@@ -25,15 +25,25 @@ public class KeyboardTrackingView: UIView {
25
25
  // Maximum height for the input area (prevents infinite growth)
26
26
  private let maxAccessoryHeight: CGFloat = 200
27
27
 
28
- // Safe area bottom inset for home indicator
28
+ // Home-indicator padding used when the accessory is visible without the keyboard.
29
29
  private var safeAreaBottomInset: CGFloat = 0
30
30
 
31
+ // Active bottom padding inside the accessory. This is removed while the
32
+ // software keyboard is visible so the bar sits flush above the keyboard.
33
+ private var currentAccessoryBottomInset: CGFloat = 0
34
+
31
35
  // Track previous keyboard position to detect show/hide direction
32
36
  private var previousKeyboardY: CGFloat = 0
33
37
 
34
38
  // Flag to suppress animation during programmatic keyboard dismiss (tap close).
35
39
  private var isDismissingKeyboard: Bool = false
36
40
 
41
+ // Text input hosted inside the accessory. When it resigns first responder,
42
+ // the tracking view must take first responder back or iOS removes the
43
+ // inputAccessoryView from the screen.
44
+ private weak var textInputView: UIView?
45
+ private var isCleaningUp: Bool = false
46
+
37
47
  // Callback for triggering ScrollView content relayout from TypeScript
38
48
  private var scrollViewRelayoutCallback: (() -> Void)?
39
49
 
@@ -62,6 +72,7 @@ public class KeyboardTrackingView: UIView {
62
72
  * @param height The height of the input container
63
73
  */
64
74
  public func setup(inputContainer: UIView, scrollView: UIScrollView, height: CGFloat) {
75
+ self.isCleaningUp = false
65
76
  self.accessoryHeight = height
66
77
  self.trackedScrollView = scrollView
67
78
  self.contentView = inputContainer
@@ -81,13 +92,15 @@ public class KeyboardTrackingView: UIView {
81
92
  }
82
93
  }
83
94
 
95
+ self.currentAccessoryBottomInset = self.safeAreaBottomInset
96
+
84
97
  // Total height includes content height + safe area for home indicator
85
- let totalHeight = height + self.safeAreaBottomInset
98
+ let totalHeight = height + self.currentAccessoryBottomInset
86
99
 
87
100
  // Create the accessory view container
88
101
  let screenWidth = UIScreen.main.bounds.width
89
102
  let accessoryContainer = InputAccessoryContainerView(frame: CGRect(x: 0, y: 0, width: screenWidth, height: totalHeight))
90
- accessoryContainer.safeAreaBottomInset = self.safeAreaBottomInset
103
+ accessoryContainer.safeAreaBottomInset = self.currentAccessoryBottomInset
91
104
  accessoryContainer.contentHeight = height
92
105
 
93
106
  // Store original superview and subview index before removal
@@ -172,6 +185,78 @@ public class KeyboardTrackingView: UIView {
172
185
  self.scrollViewRelayoutCallback = callback
173
186
  }
174
187
 
188
+ /**
189
+ * Register the editable view hosted inside the accessory. This lets the
190
+ * plugin recover when callers use UIApplication/endEditing based dismissal
191
+ * instead of InputAccessoryManager.dismissKeyboard().
192
+ */
193
+ public func setTextInputView(_ textInputView: UIView) {
194
+ self.textInputView = textInputView
195
+ suppressTextInputAssistant(for: textInputView)
196
+
197
+ if textInputView is UITextView {
198
+ NotificationCenter.default.addObserver(
199
+ self,
200
+ selector: #selector(textInputDidBeginEditing(_:)),
201
+ name: UITextView.textDidBeginEditingNotification,
202
+ object: textInputView
203
+ )
204
+ NotificationCenter.default.addObserver(
205
+ self,
206
+ selector: #selector(textInputDidEndEditing(_:)),
207
+ name: UITextView.textDidEndEditingNotification,
208
+ object: textInputView
209
+ )
210
+ }
211
+
212
+ if textInputView is UITextField {
213
+ NotificationCenter.default.addObserver(
214
+ self,
215
+ selector: #selector(textInputDidBeginEditing(_:)),
216
+ name: UITextField.textDidBeginEditingNotification,
217
+ object: textInputView
218
+ )
219
+ NotificationCenter.default.addObserver(
220
+ self,
221
+ selector: #selector(textInputDidEndEditing(_:)),
222
+ name: UITextField.textDidEndEditingNotification,
223
+ object: textInputView
224
+ )
225
+ }
226
+ }
227
+
228
+ private func suppressTextInputAssistant(for textInputView: UIView) {
229
+ textInputView.inputAssistantItem.leadingBarButtonGroups = []
230
+ textInputView.inputAssistantItem.trailingBarButtonGroups = []
231
+
232
+ if let textView = textInputView as? UITextView {
233
+ textView.autocorrectionType = .no
234
+ textView.spellCheckingType = .no
235
+ textView.smartQuotesType = .no
236
+ textView.smartDashesType = .no
237
+ textView.smartInsertDeleteType = .no
238
+ textView.textContentType = nil
239
+ if #available(iOS 17.0, *) {
240
+ textView.inlinePredictionType = .no
241
+ }
242
+ textView.reloadInputViews()
243
+ return
244
+ }
245
+
246
+ if let textField = textInputView as? UITextField {
247
+ textField.autocorrectionType = .no
248
+ textField.spellCheckingType = .no
249
+ textField.smartQuotesType = .no
250
+ textField.smartDashesType = .no
251
+ textField.smartInsertDeleteType = .no
252
+ textField.textContentType = nil
253
+ if #available(iOS 17.0, *) {
254
+ textField.inlinePredictionType = .no
255
+ }
256
+ textField.reloadInputViews()
257
+ }
258
+ }
259
+
175
260
  /**
176
261
  * Trigger NativeScript content remeasurement for ScrollView after frame resize
177
262
  */
@@ -240,15 +325,19 @@ public class KeyboardTrackingView: UIView {
240
325
  let window = accessoryView.window,
241
326
  let scrollView = trackedScrollView else { return }
242
327
 
243
- let frameInWindow = accessoryView.convert(accessoryView.bounds, to: window)
244
- let accessoryTop = frameInWindow.origin.y
245
-
246
328
  let screenHeight = UIScreen.main.bounds.height
329
+ var frameInWindow = accessoryView.convert(accessoryView.bounds, to: window)
330
+ var accessoryTop = frameInWindow.origin.y
331
+ updateAccessoryBottomInsetForAccessoryPosition(accessoryTop, screenHeight: screenHeight)
332
+ frameInWindow = accessoryView.convert(accessoryView.bounds, to: window)
333
+ accessoryTop = frameInWindow.origin.y
334
+
247
335
  let scrollViewTopInWindow = scrollView.superview?.convert(
248
336
  scrollView.frame.origin, to: nil).y ?? scrollView.frame.origin.y
249
337
 
250
338
  let targetFrameHeight = max(100, screenHeight - scrollViewTopInWindow)
251
- let keyboardOverlap = max(0, screenHeight - accessoryTop)
339
+ let accessoryTotalHeight = self.accessoryHeight + self.currentAccessoryBottomInset
340
+ let keyboardOverlap = max(accessoryTotalHeight, screenHeight - accessoryTop)
252
341
 
253
342
  let frameChanged = abs(targetFrameHeight - scrollView.frame.size.height) > 1
254
343
  let insetChanged = abs(keyboardOverlap - scrollView.contentInset.bottom) > 1
@@ -287,7 +376,8 @@ public class KeyboardTrackingView: UIView {
287
376
  let targetFrameHeight = max(100, screenHeight - scrollViewTopInWindow)
288
377
 
289
378
  // contentInset tracks the moving keyboard+accessory area
290
- let keyboardOverlap = max(0, screenHeight - accessoryTop)
379
+ let accessoryTotalHeight = self.accessoryHeight + self.currentAccessoryBottomInset
380
+ let keyboardOverlap = max(accessoryTotalHeight, screenHeight - accessoryTop)
291
381
 
292
382
  let frameChanged = abs(targetFrameHeight - scrollView.frame.size.height) > 0.5
293
383
  let insetChanged = abs(keyboardOverlap - scrollView.contentInset.bottom) > 0.5
@@ -334,11 +424,13 @@ public class KeyboardTrackingView: UIView {
334
424
 
335
425
  self.accessoryHeight = clampedHeight
336
426
 
337
- // Total height includes safe area
338
- let totalHeight = clampedHeight + self.safeAreaBottomInset
427
+ // Total height includes the currently active bottom inset. This is
428
+ // zero while the keyboard is open and safe-area padding when closed.
429
+ let totalHeight = clampedHeight + self.currentAccessoryBottomInset
339
430
 
340
431
  // Update the container's heights
341
432
  accessoryView.contentHeight = clampedHeight
433
+ accessoryView.safeAreaBottomInset = self.currentAccessoryBottomInset
342
434
 
343
435
  // Update via the internal height constraint - the reliable way to resize inputAccessoryViews
344
436
  accessoryView.updateHeightConstraint(totalHeight)
@@ -375,6 +467,32 @@ public class KeyboardTrackingView: UIView {
375
467
  }
376
468
  return nil
377
469
  }
470
+
471
+ private func updateAccessoryBottomInset(_ bottomInset: CGFloat) {
472
+ guard abs(self.currentAccessoryBottomInset - bottomInset) > 0.5 else {
473
+ return
474
+ }
475
+
476
+ self.currentAccessoryBottomInset = bottomInset
477
+
478
+ guard let accessoryView = _keyboardAccessoryView else {
479
+ return
480
+ }
481
+
482
+ accessoryView.safeAreaBottomInset = bottomInset
483
+ accessoryView.updateHeightConstraint(self.accessoryHeight + bottomInset)
484
+
485
+ if let contentView = self.contentView {
486
+ contentView.frame = CGRect(x: 0, y: 0, width: accessoryView.bounds.width, height: self.accessoryHeight)
487
+ }
488
+ }
489
+
490
+ private func updateAccessoryBottomInsetForAccessoryPosition(_ accessoryTop: CGFloat, screenHeight: CGFloat) {
491
+ let accessoryOnlyThreshold = self.accessoryHeight + self.safeAreaBottomInset + 10
492
+ let keyboardOverlap = max(0, screenHeight - accessoryTop)
493
+ let isKeyboardShowing = keyboardOverlap > accessoryOnlyThreshold
494
+ updateAccessoryBottomInset(isKeyboardShowing ? 0 : self.safeAreaBottomInset)
495
+ }
378
496
 
379
497
  /**
380
498
  * Show the keyboard (make text field first responder)
@@ -401,6 +519,78 @@ public class KeyboardTrackingView: UIView {
401
519
  }
402
520
  }
403
521
 
522
+ /**
523
+ * Dismiss the software keyboard while keeping the inputAccessoryView alive.
524
+ * This transfers first responder from the hosted TextView/TextField back to
525
+ * KeyboardTrackingView, producing an accessory-only state instead of fully
526
+ * removing the input bar.
527
+ */
528
+ public func dismissKeyboard() {
529
+ stopInteractiveTracking()
530
+ setDismissingKeyboard()
531
+
532
+ if !self.isFirstResponder {
533
+ self.becomeFirstResponder()
534
+ } else {
535
+ self.reloadInputViews()
536
+ }
537
+
538
+ // The frame notification usually handles this, but finalize on the next
539
+ // turn as a guard against UIKit sending notification(s) before the
540
+ // responder transfer settles.
541
+ DispatchQueue.main.async { [weak self] in
542
+ self?.finalizeScrollViewHeight()
543
+ }
544
+ }
545
+
546
+ @objc private func textInputDidBeginEditing(_ notification: Notification) {
547
+ if let textInputView = notification.object as? UIView {
548
+ suppressTextInputAssistant(for: textInputView)
549
+ }
550
+ }
551
+
552
+ @objc private func textInputDidEndEditing(_ notification: Notification) {
553
+ guard !isCleaningUp,
554
+ let accessoryView = _keyboardAccessoryView,
555
+ accessoryView.window != nil else { return }
556
+
557
+ restoreAccessoryFirstResponderIfNeeded()
558
+ }
559
+
560
+ private func restoreAccessoryFirstResponderIfNeeded() {
561
+ guard !isCleaningUp,
562
+ let accessoryView = _keyboardAccessoryView,
563
+ let window = accessoryView.window else { return }
564
+
565
+ if let activeResponder = findFirstResponder(in: window),
566
+ activeResponder !== self,
567
+ !isView(activeResponder, descendantOf: accessoryView) {
568
+ return
569
+ }
570
+
571
+ guard !self.isFirstResponder else { return }
572
+
573
+ setDismissingKeyboard()
574
+ DispatchQueue.main.async { [weak self] in
575
+ guard let self = self, !self.isCleaningUp else { return }
576
+ if !self.isFirstResponder {
577
+ self.becomeFirstResponder()
578
+ }
579
+ self.finalizeScrollViewHeight()
580
+ }
581
+ }
582
+
583
+ private func isView(_ view: UIView, descendantOf ancestor: UIView) -> Bool {
584
+ var currentView: UIView? = view
585
+ while let candidate = currentView {
586
+ if candidate === ancestor {
587
+ return true
588
+ }
589
+ currentView = candidate.superview
590
+ }
591
+ return false
592
+ }
593
+
404
594
  // MARK: - Keyboard Handling
405
595
 
406
596
  @objc private func keyboardWillChangeFrame(_ notification: Notification) {
@@ -437,14 +627,6 @@ public class KeyboardTrackingView: UIView {
437
627
  // the translucent accessory AND the keyboard (for blur-through visibility).
438
628
  let targetFrameHeight = max(100, screenHeight - scrollViewTopInWindow)
439
629
 
440
- // contentInset covers the full keyboard+accessory area from the screen bottom.
441
- // Clamp to at least the accessory height — the accessory is always visible
442
- // (KeyboardTrackingView is always first responder), so the overlap never drops
443
- // below it. This prevents a transient inset=0 state during first-responder
444
- // transfers (e.g., UITextView → KeyboardTrackingView) that would cause a scroll jump.
445
- let accessoryTotalHeight = self.accessoryHeight + self.safeAreaBottomInset
446
- let keyboardOverlap = max(accessoryTotalHeight, screenHeight - endFrame.origin.y)
447
-
448
630
  // Detect keyboard showing/hiding for scroll behavior.
449
631
  // iOS includes the inputAccessoryView in the reported keyboard frame,
450
632
  // so when only the accessory is visible (keyboard hidden), endFrame.origin.y
@@ -454,6 +636,16 @@ public class KeyboardTrackingView: UIView {
454
636
  let isKeyboardShowing = endFrame.origin.y < screenHeight - accessoryOnlyThreshold
455
637
  let wasKeyboardHidden = previousKeyboardY >= screenHeight - accessoryOnlyThreshold
456
638
  let keyboardJustAppeared = isKeyboardShowing && wasKeyboardHidden
639
+ let desiredBottomInset: CGFloat = isKeyboardShowing ? 0 : self.safeAreaBottomInset
640
+ updateAccessoryBottomInset(desiredBottomInset)
641
+
642
+ // contentInset covers the full keyboard+accessory area from the screen bottom.
643
+ // Clamp to at least the accessory height — the accessory is always visible
644
+ // (KeyboardTrackingView is always first responder), so the overlap never drops
645
+ // below it. This prevents a transient inset=0 state during first-responder
646
+ // transfers (e.g., UITextView → KeyboardTrackingView) that would cause a scroll jump.
647
+ let accessoryTotalHeight = self.accessoryHeight + self.currentAccessoryBottomInset
648
+ let keyboardOverlap = max(accessoryTotalHeight, screenHeight - endFrame.origin.y)
457
649
 
458
650
  // Store current position for next comparison
459
651
  previousKeyboardY = endFrame.origin.y
@@ -488,12 +680,18 @@ public class KeyboardTrackingView: UIView {
488
680
  scrollView.contentInset.bottom = keyboardOverlap
489
681
  scrollView.verticalScrollIndicatorInsets.bottom = keyboardOverlap
490
682
 
491
- // Clamp scroll position to valid range without animation
683
+ // Preserve visual position for short content. Clamping to zero while
684
+ // the keyboard is handing off causes a visible up/down jump, and the
685
+ // chat view will issue its own scroll after adding the sent message.
492
686
  let contentHeight = scrollView.contentSize.height
493
687
  let visibleHeight = targetFrameHeight - keyboardOverlap
494
688
  let maxOffset = max(0, contentHeight - visibleHeight)
495
- let clampedOffset = max(0, min(currentOffset, maxOffset))
496
- scrollView.contentOffset = CGPoint(x: 0, y: clampedOffset)
689
+ if contentHeight > visibleHeight {
690
+ let clampedOffset = max(0, min(currentOffset, maxOffset))
691
+ if abs(clampedOffset - currentOffset) > 0.5 {
692
+ scrollView.contentOffset = CGPoint(x: 0, y: clampedOffset)
693
+ }
694
+ }
497
695
 
498
696
  self.relayoutScrollViewContent()
499
697
  return
@@ -537,11 +735,13 @@ public class KeyboardTrackingView: UIView {
537
735
  // MARK: - Cleanup
538
736
 
539
737
  public func cleanup() {
738
+ isCleaningUp = true
540
739
  stopInteractiveTracking()
541
740
  trackedScrollView?.panGestureRecognizer.removeTarget(self, action: #selector(handleScrollViewPan(_:)))
542
741
  NotificationCenter.default.removeObserver(self)
543
742
  self._keyboardAccessoryView = nil
544
743
  self.contentView = nil
744
+ self.textInputView = nil
545
745
  self.trackedScrollView = nil
546
746
  self.scrollViewRelayoutCallback = nil
547
747
  self.resignFirstResponder()