@nativescript/input-accessory 1.0.0 → 1.0.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/CHANGELOG.md ADDED
@@ -0,0 +1,19 @@
1
+ ## 1.0.2 (2026-05-20)
2
+
3
+ ### 🩹 Fixes
4
+
5
+ - **input-accessory:** improved positioning and state handling ([#664](https://github.com/NativeScript/plugins/pull/664))
6
+
7
+ ### ❤️ Thank You
8
+
9
+ - Nathan Walker
10
+
11
+ # 1.0.0 (2026-02-26)
12
+
13
+ ### 🚀 Features
14
+
15
+ - input accessory ([#659](https://github.com/NativeScript/plugins/pull/659))
16
+
17
+ ### ❤️ Thank You
18
+
19
+ - 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.3",
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
@@ -128,14 +141,7 @@ public class KeyboardTrackingView: UIView {
128
141
 
129
142
  self._keyboardAccessoryView = accessoryContainer
130
143
 
131
- // On iOS 26+, add scroll edge blending so the bottom of the ScrollView
132
- // fades into the glass accessory (like Apple Notes / iMessage).
133
- if #available(iOS 26.0, *) {
134
- let edgeInteraction = UIScrollEdgeElementContainerInteraction()
135
- edgeInteraction.scrollView = scrollView
136
- edgeInteraction.edge = .bottom
137
- accessoryContainer.addInteraction(edgeInteraction)
138
- }
144
+ addScrollEdgeElementContainerInteractionIfAvailable(to: accessoryContainer, scrollView: scrollView)
139
145
 
140
146
  // Set up scroll view for interactive dismiss
141
147
  scrollView.keyboardDismissMode = .interactive
@@ -163,6 +169,26 @@ public class KeyboardTrackingView: UIView {
163
169
  self?.becomeFirstResponder()
164
170
  }
165
171
  }
172
+
173
+ private func addScrollEdgeElementContainerInteractionIfAvailable(to containerView: UIView, scrollView: UIScrollView) {
174
+ guard #available(iOS 26.0, *) else { return }
175
+
176
+ // UIScrollEdgeElementContainerInteraction is an iOS 26 SDK symbol. Resolve
177
+ // it dynamically so the plugin still compiles with Xcode 16.x / iOS 18.x SDKs.
178
+ let interactionClass = (
179
+ NSClassFromString("UIScrollEdgeElementContainerInteraction")
180
+ ?? NSClassFromString("UIKit.UIScrollEdgeElementContainerInteraction")
181
+ ) as? NSObject.Type
182
+
183
+ guard let interactionClass = interactionClass else { return }
184
+
185
+ let interaction = interactionClass.init()
186
+ interaction.setValue(scrollView, forKey: "scrollView")
187
+ interaction.setValue(NSNumber(value: UIRectEdge.bottom.rawValue), forKey: "edge")
188
+
189
+ guard let edgeInteraction = interaction as? UIInteraction else { return }
190
+ containerView.addInteraction(edgeInteraction)
191
+ }
166
192
 
167
193
  /**
168
194
  * Set the callback for relayouting ScrollView content
@@ -172,6 +198,78 @@ public class KeyboardTrackingView: UIView {
172
198
  self.scrollViewRelayoutCallback = callback
173
199
  }
174
200
 
201
+ /**
202
+ * Register the editable view hosted inside the accessory. This lets the
203
+ * plugin recover when callers use UIApplication/endEditing based dismissal
204
+ * instead of InputAccessoryManager.dismissKeyboard().
205
+ */
206
+ public func setTextInputView(_ textInputView: UIView) {
207
+ self.textInputView = textInputView
208
+ suppressTextInputAssistant(for: textInputView)
209
+
210
+ if textInputView is UITextView {
211
+ NotificationCenter.default.addObserver(
212
+ self,
213
+ selector: #selector(textInputDidBeginEditing(_:)),
214
+ name: UITextView.textDidBeginEditingNotification,
215
+ object: textInputView
216
+ )
217
+ NotificationCenter.default.addObserver(
218
+ self,
219
+ selector: #selector(textInputDidEndEditing(_:)),
220
+ name: UITextView.textDidEndEditingNotification,
221
+ object: textInputView
222
+ )
223
+ }
224
+
225
+ if textInputView is UITextField {
226
+ NotificationCenter.default.addObserver(
227
+ self,
228
+ selector: #selector(textInputDidBeginEditing(_:)),
229
+ name: UITextField.textDidBeginEditingNotification,
230
+ object: textInputView
231
+ )
232
+ NotificationCenter.default.addObserver(
233
+ self,
234
+ selector: #selector(textInputDidEndEditing(_:)),
235
+ name: UITextField.textDidEndEditingNotification,
236
+ object: textInputView
237
+ )
238
+ }
239
+ }
240
+
241
+ private func suppressTextInputAssistant(for textInputView: UIView) {
242
+ textInputView.inputAssistantItem.leadingBarButtonGroups = []
243
+ textInputView.inputAssistantItem.trailingBarButtonGroups = []
244
+
245
+ if let textView = textInputView as? UITextView {
246
+ textView.autocorrectionType = .no
247
+ textView.spellCheckingType = .no
248
+ textView.smartQuotesType = .no
249
+ textView.smartDashesType = .no
250
+ textView.smartInsertDeleteType = .no
251
+ textView.textContentType = nil
252
+ if #available(iOS 17.0, *) {
253
+ textView.inlinePredictionType = .no
254
+ }
255
+ textView.reloadInputViews()
256
+ return
257
+ }
258
+
259
+ if let textField = textInputView as? UITextField {
260
+ textField.autocorrectionType = .no
261
+ textField.spellCheckingType = .no
262
+ textField.smartQuotesType = .no
263
+ textField.smartDashesType = .no
264
+ textField.smartInsertDeleteType = .no
265
+ textField.textContentType = nil
266
+ if #available(iOS 17.0, *) {
267
+ textField.inlinePredictionType = .no
268
+ }
269
+ textField.reloadInputViews()
270
+ }
271
+ }
272
+
175
273
  /**
176
274
  * Trigger NativeScript content remeasurement for ScrollView after frame resize
177
275
  */
@@ -240,15 +338,19 @@ public class KeyboardTrackingView: UIView {
240
338
  let window = accessoryView.window,
241
339
  let scrollView = trackedScrollView else { return }
242
340
 
243
- let frameInWindow = accessoryView.convert(accessoryView.bounds, to: window)
244
- let accessoryTop = frameInWindow.origin.y
245
-
246
341
  let screenHeight = UIScreen.main.bounds.height
342
+ var frameInWindow = accessoryView.convert(accessoryView.bounds, to: window)
343
+ var accessoryTop = frameInWindow.origin.y
344
+ updateAccessoryBottomInsetForAccessoryPosition(accessoryTop, screenHeight: screenHeight)
345
+ frameInWindow = accessoryView.convert(accessoryView.bounds, to: window)
346
+ accessoryTop = frameInWindow.origin.y
347
+
247
348
  let scrollViewTopInWindow = scrollView.superview?.convert(
248
349
  scrollView.frame.origin, to: nil).y ?? scrollView.frame.origin.y
249
350
 
250
351
  let targetFrameHeight = max(100, screenHeight - scrollViewTopInWindow)
251
- let keyboardOverlap = max(0, screenHeight - accessoryTop)
352
+ let accessoryTotalHeight = self.accessoryHeight + self.currentAccessoryBottomInset
353
+ let keyboardOverlap = max(accessoryTotalHeight, screenHeight - accessoryTop)
252
354
 
253
355
  let frameChanged = abs(targetFrameHeight - scrollView.frame.size.height) > 1
254
356
  let insetChanged = abs(keyboardOverlap - scrollView.contentInset.bottom) > 1
@@ -287,7 +389,8 @@ public class KeyboardTrackingView: UIView {
287
389
  let targetFrameHeight = max(100, screenHeight - scrollViewTopInWindow)
288
390
 
289
391
  // contentInset tracks the moving keyboard+accessory area
290
- let keyboardOverlap = max(0, screenHeight - accessoryTop)
392
+ let accessoryTotalHeight = self.accessoryHeight + self.currentAccessoryBottomInset
393
+ let keyboardOverlap = max(accessoryTotalHeight, screenHeight - accessoryTop)
291
394
 
292
395
  let frameChanged = abs(targetFrameHeight - scrollView.frame.size.height) > 0.5
293
396
  let insetChanged = abs(keyboardOverlap - scrollView.contentInset.bottom) > 0.5
@@ -334,11 +437,13 @@ public class KeyboardTrackingView: UIView {
334
437
 
335
438
  self.accessoryHeight = clampedHeight
336
439
 
337
- // Total height includes safe area
338
- let totalHeight = clampedHeight + self.safeAreaBottomInset
440
+ // Total height includes the currently active bottom inset. This is
441
+ // zero while the keyboard is open and safe-area padding when closed.
442
+ let totalHeight = clampedHeight + self.currentAccessoryBottomInset
339
443
 
340
444
  // Update the container's heights
341
445
  accessoryView.contentHeight = clampedHeight
446
+ accessoryView.safeAreaBottomInset = self.currentAccessoryBottomInset
342
447
 
343
448
  // Update via the internal height constraint - the reliable way to resize inputAccessoryViews
344
449
  accessoryView.updateHeightConstraint(totalHeight)
@@ -375,6 +480,32 @@ public class KeyboardTrackingView: UIView {
375
480
  }
376
481
  return nil
377
482
  }
483
+
484
+ private func updateAccessoryBottomInset(_ bottomInset: CGFloat) {
485
+ guard abs(self.currentAccessoryBottomInset - bottomInset) > 0.5 else {
486
+ return
487
+ }
488
+
489
+ self.currentAccessoryBottomInset = bottomInset
490
+
491
+ guard let accessoryView = _keyboardAccessoryView else {
492
+ return
493
+ }
494
+
495
+ accessoryView.safeAreaBottomInset = bottomInset
496
+ accessoryView.updateHeightConstraint(self.accessoryHeight + bottomInset)
497
+
498
+ if let contentView = self.contentView {
499
+ contentView.frame = CGRect(x: 0, y: 0, width: accessoryView.bounds.width, height: self.accessoryHeight)
500
+ }
501
+ }
502
+
503
+ private func updateAccessoryBottomInsetForAccessoryPosition(_ accessoryTop: CGFloat, screenHeight: CGFloat) {
504
+ let accessoryOnlyThreshold = self.accessoryHeight + self.safeAreaBottomInset + 10
505
+ let keyboardOverlap = max(0, screenHeight - accessoryTop)
506
+ let isKeyboardShowing = keyboardOverlap > accessoryOnlyThreshold
507
+ updateAccessoryBottomInset(isKeyboardShowing ? 0 : self.safeAreaBottomInset)
508
+ }
378
509
 
379
510
  /**
380
511
  * Show the keyboard (make text field first responder)
@@ -401,6 +532,78 @@ public class KeyboardTrackingView: UIView {
401
532
  }
402
533
  }
403
534
 
535
+ /**
536
+ * Dismiss the software keyboard while keeping the inputAccessoryView alive.
537
+ * This transfers first responder from the hosted TextView/TextField back to
538
+ * KeyboardTrackingView, producing an accessory-only state instead of fully
539
+ * removing the input bar.
540
+ */
541
+ public func dismissKeyboard() {
542
+ stopInteractiveTracking()
543
+ setDismissingKeyboard()
544
+
545
+ if !self.isFirstResponder {
546
+ self.becomeFirstResponder()
547
+ } else {
548
+ self.reloadInputViews()
549
+ }
550
+
551
+ // The frame notification usually handles this, but finalize on the next
552
+ // turn as a guard against UIKit sending notification(s) before the
553
+ // responder transfer settles.
554
+ DispatchQueue.main.async { [weak self] in
555
+ self?.finalizeScrollViewHeight()
556
+ }
557
+ }
558
+
559
+ @objc private func textInputDidBeginEditing(_ notification: Notification) {
560
+ if let textInputView = notification.object as? UIView {
561
+ suppressTextInputAssistant(for: textInputView)
562
+ }
563
+ }
564
+
565
+ @objc private func textInputDidEndEditing(_ notification: Notification) {
566
+ guard !isCleaningUp,
567
+ let accessoryView = _keyboardAccessoryView,
568
+ accessoryView.window != nil else { return }
569
+
570
+ restoreAccessoryFirstResponderIfNeeded()
571
+ }
572
+
573
+ private func restoreAccessoryFirstResponderIfNeeded() {
574
+ guard !isCleaningUp,
575
+ let accessoryView = _keyboardAccessoryView,
576
+ let window = accessoryView.window else { return }
577
+
578
+ if let activeResponder = findFirstResponder(in: window),
579
+ activeResponder !== self,
580
+ !isView(activeResponder, descendantOf: accessoryView) {
581
+ return
582
+ }
583
+
584
+ guard !self.isFirstResponder else { return }
585
+
586
+ setDismissingKeyboard()
587
+ DispatchQueue.main.async { [weak self] in
588
+ guard let self = self, !self.isCleaningUp else { return }
589
+ if !self.isFirstResponder {
590
+ self.becomeFirstResponder()
591
+ }
592
+ self.finalizeScrollViewHeight()
593
+ }
594
+ }
595
+
596
+ private func isView(_ view: UIView, descendantOf ancestor: UIView) -> Bool {
597
+ var currentView: UIView? = view
598
+ while let candidate = currentView {
599
+ if candidate === ancestor {
600
+ return true
601
+ }
602
+ currentView = candidate.superview
603
+ }
604
+ return false
605
+ }
606
+
404
607
  // MARK: - Keyboard Handling
405
608
 
406
609
  @objc private func keyboardWillChangeFrame(_ notification: Notification) {
@@ -437,14 +640,6 @@ public class KeyboardTrackingView: UIView {
437
640
  // the translucent accessory AND the keyboard (for blur-through visibility).
438
641
  let targetFrameHeight = max(100, screenHeight - scrollViewTopInWindow)
439
642
 
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
643
  // Detect keyboard showing/hiding for scroll behavior.
449
644
  // iOS includes the inputAccessoryView in the reported keyboard frame,
450
645
  // so when only the accessory is visible (keyboard hidden), endFrame.origin.y
@@ -454,6 +649,16 @@ public class KeyboardTrackingView: UIView {
454
649
  let isKeyboardShowing = endFrame.origin.y < screenHeight - accessoryOnlyThreshold
455
650
  let wasKeyboardHidden = previousKeyboardY >= screenHeight - accessoryOnlyThreshold
456
651
  let keyboardJustAppeared = isKeyboardShowing && wasKeyboardHidden
652
+ let desiredBottomInset: CGFloat = isKeyboardShowing ? 0 : self.safeAreaBottomInset
653
+ updateAccessoryBottomInset(desiredBottomInset)
654
+
655
+ // contentInset covers the full keyboard+accessory area from the screen bottom.
656
+ // Clamp to at least the accessory height — the accessory is always visible
657
+ // (KeyboardTrackingView is always first responder), so the overlap never drops
658
+ // below it. This prevents a transient inset=0 state during first-responder
659
+ // transfers (e.g., UITextView → KeyboardTrackingView) that would cause a scroll jump.
660
+ let accessoryTotalHeight = self.accessoryHeight + self.currentAccessoryBottomInset
661
+ let keyboardOverlap = max(accessoryTotalHeight, screenHeight - endFrame.origin.y)
457
662
 
458
663
  // Store current position for next comparison
459
664
  previousKeyboardY = endFrame.origin.y
@@ -488,12 +693,18 @@ public class KeyboardTrackingView: UIView {
488
693
  scrollView.contentInset.bottom = keyboardOverlap
489
694
  scrollView.verticalScrollIndicatorInsets.bottom = keyboardOverlap
490
695
 
491
- // Clamp scroll position to valid range without animation
696
+ // Preserve visual position for short content. Clamping to zero while
697
+ // the keyboard is handing off causes a visible up/down jump, and the
698
+ // chat view will issue its own scroll after adding the sent message.
492
699
  let contentHeight = scrollView.contentSize.height
493
700
  let visibleHeight = targetFrameHeight - keyboardOverlap
494
701
  let maxOffset = max(0, contentHeight - visibleHeight)
495
- let clampedOffset = max(0, min(currentOffset, maxOffset))
496
- scrollView.contentOffset = CGPoint(x: 0, y: clampedOffset)
702
+ if contentHeight > visibleHeight {
703
+ let clampedOffset = max(0, min(currentOffset, maxOffset))
704
+ if abs(clampedOffset - currentOffset) > 0.5 {
705
+ scrollView.contentOffset = CGPoint(x: 0, y: clampedOffset)
706
+ }
707
+ }
497
708
 
498
709
  self.relayoutScrollViewContent()
499
710
  return
@@ -537,11 +748,13 @@ public class KeyboardTrackingView: UIView {
537
748
  // MARK: - Cleanup
538
749
 
539
750
  public func cleanup() {
751
+ isCleaningUp = true
540
752
  stopInteractiveTracking()
541
753
  trackedScrollView?.panGestureRecognizer.removeTarget(self, action: #selector(handleScrollViewPan(_:)))
542
754
  NotificationCenter.default.removeObserver(self)
543
755
  self._keyboardAccessoryView = nil
544
756
  self.contentView = nil
757
+ self.textInputView = nil
545
758
  self.trackedScrollView = nil
546
759
  self.scrollViewRelayoutCallback = nil
547
760
  self.resignFirstResponder()