react-native-keyboard-controller 1.21.0-beta.1 → 1.21.0-beta.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.
Files changed (89) hide show
  1. package/android/src/fabric/java/com/reactnativekeyboardcontroller/ClippingScrollViewDecoratorViewManager.kt +7 -0
  2. package/android/src/main/java/com/reactnativekeyboardcontroller/views/ClippingScrollViewDecoratorView.kt +28 -1
  3. package/android/src/paper/java/com/reactnativekeyboardcontroller/ClippingScrollViewDecoratorViewManager.kt +8 -0
  4. package/jest/index.js +1 -0
  5. package/lib/commonjs/components/KeyboardAwareScrollView/index.js +7 -4
  6. package/lib/commonjs/components/KeyboardAwareScrollView/index.js.map +1 -1
  7. package/lib/commonjs/components/KeyboardChatScrollView/hooks.js +13 -0
  8. package/lib/commonjs/components/KeyboardChatScrollView/hooks.js.map +1 -0
  9. package/lib/commonjs/components/KeyboardChatScrollView/index.js +80 -0
  10. package/lib/commonjs/components/KeyboardChatScrollView/index.js.map +1 -0
  11. package/lib/commonjs/components/KeyboardChatScrollView/types.js +6 -0
  12. package/lib/commonjs/components/KeyboardChatScrollView/types.js.map +1 -0
  13. package/lib/commonjs/components/KeyboardChatScrollView/useChatKeyboard/helpers.js +135 -0
  14. package/lib/commonjs/components/KeyboardChatScrollView/useChatKeyboard/helpers.js.map +1 -0
  15. package/lib/commonjs/components/KeyboardChatScrollView/useChatKeyboard/index.ios.js +121 -0
  16. package/lib/commonjs/components/KeyboardChatScrollView/useChatKeyboard/index.ios.js.map +1 -0
  17. package/lib/commonjs/components/KeyboardChatScrollView/useChatKeyboard/index.js +205 -0
  18. package/lib/commonjs/components/KeyboardChatScrollView/useChatKeyboard/index.js.map +1 -0
  19. package/lib/commonjs/components/KeyboardChatScrollView/useChatKeyboard/types.js +6 -0
  20. package/lib/commonjs/components/KeyboardChatScrollView/useChatKeyboard/types.js.map +1 -0
  21. package/lib/commonjs/components/KeyboardStickyView/index.js +9 -5
  22. package/lib/commonjs/components/KeyboardStickyView/index.js.map +1 -1
  23. package/lib/commonjs/components/ScrollViewWithBottomPadding/index.js +46 -13
  24. package/lib/commonjs/components/ScrollViewWithBottomPadding/index.js.map +1 -1
  25. package/lib/commonjs/components/hooks/useScrollState.js +20 -1
  26. package/lib/commonjs/components/hooks/useScrollState.js.map +1 -1
  27. package/lib/commonjs/components/index.js +7 -0
  28. package/lib/commonjs/components/index.js.map +1 -1
  29. package/lib/commonjs/index.js +7 -0
  30. package/lib/commonjs/index.js.map +1 -1
  31. package/lib/commonjs/specs/ClippingScrollViewDecoratorViewNativeComponent.js.map +1 -1
  32. package/lib/commonjs/types/views.js.map +1 -1
  33. package/lib/module/components/KeyboardAwareScrollView/index.js +7 -4
  34. package/lib/module/components/KeyboardAwareScrollView/index.js.map +1 -1
  35. package/lib/module/components/KeyboardChatScrollView/hooks.js +2 -0
  36. package/lib/module/components/KeyboardChatScrollView/hooks.js.map +1 -0
  37. package/lib/module/components/KeyboardChatScrollView/index.js +73 -0
  38. package/lib/module/components/KeyboardChatScrollView/index.js.map +1 -0
  39. package/lib/module/components/KeyboardChatScrollView/types.js +2 -0
  40. package/lib/module/components/KeyboardChatScrollView/types.js.map +1 -0
  41. package/lib/module/components/KeyboardChatScrollView/useChatKeyboard/helpers.js +125 -0
  42. package/lib/module/components/KeyboardChatScrollView/useChatKeyboard/helpers.js.map +1 -0
  43. package/lib/module/components/KeyboardChatScrollView/useChatKeyboard/index.ios.js +115 -0
  44. package/lib/module/components/KeyboardChatScrollView/useChatKeyboard/index.ios.js.map +1 -0
  45. package/lib/module/components/KeyboardChatScrollView/useChatKeyboard/index.js +199 -0
  46. package/lib/module/components/KeyboardChatScrollView/useChatKeyboard/index.js.map +1 -0
  47. package/lib/module/components/KeyboardChatScrollView/useChatKeyboard/types.js +2 -0
  48. package/lib/module/components/KeyboardChatScrollView/useChatKeyboard/types.js.map +1 -0
  49. package/lib/module/components/KeyboardStickyView/index.js +9 -5
  50. package/lib/module/components/KeyboardStickyView/index.js.map +1 -1
  51. package/lib/module/components/ScrollViewWithBottomPadding/index.js +47 -14
  52. package/lib/module/components/ScrollViewWithBottomPadding/index.js.map +1 -1
  53. package/lib/module/components/hooks/useScrollState.js +21 -2
  54. package/lib/module/components/hooks/useScrollState.js.map +1 -1
  55. package/lib/module/components/index.js +1 -0
  56. package/lib/module/components/index.js.map +1 -1
  57. package/lib/module/index.js +1 -1
  58. package/lib/module/index.js.map +1 -1
  59. package/lib/module/specs/ClippingScrollViewDecoratorViewNativeComponent.js.map +1 -1
  60. package/lib/module/types/views.js.map +1 -1
  61. package/lib/typescript/components/KeyboardChatScrollView/hooks.d.ts +2 -0
  62. package/lib/typescript/components/KeyboardChatScrollView/index.d.ts +12 -0
  63. package/lib/typescript/components/KeyboardChatScrollView/types.d.ts +48 -0
  64. package/lib/typescript/components/KeyboardChatScrollView/useChatKeyboard/helpers.d.ts +77 -0
  65. package/lib/typescript/components/KeyboardChatScrollView/useChatKeyboard/index.d.ts +21 -0
  66. package/lib/typescript/components/KeyboardChatScrollView/useChatKeyboard/index.ios.d.ts +21 -0
  67. package/lib/typescript/components/KeyboardChatScrollView/useChatKeyboard/types.d.ts +22 -0
  68. package/lib/typescript/components/ScrollViewWithBottomPadding/index.d.ts +3 -0
  69. package/lib/typescript/components/hooks/useScrollState.d.ts +3 -0
  70. package/lib/typescript/components/index.d.ts +2 -0
  71. package/lib/typescript/index.d.ts +2 -2
  72. package/lib/typescript/specs/ClippingScrollViewDecoratorViewNativeComponent.d.ts +1 -0
  73. package/lib/typescript/types/views.d.ts +2 -0
  74. package/package.json +12 -4
  75. package/src/components/KeyboardAwareScrollView/index.tsx +10 -3
  76. package/src/components/KeyboardChatScrollView/hooks.ts +2 -0
  77. package/src/components/KeyboardChatScrollView/index.tsx +106 -0
  78. package/src/components/KeyboardChatScrollView/types.ts +49 -0
  79. package/src/components/KeyboardChatScrollView/useChatKeyboard/helpers.ts +163 -0
  80. package/src/components/KeyboardChatScrollView/useChatKeyboard/index.ios.ts +180 -0
  81. package/src/components/KeyboardChatScrollView/useChatKeyboard/index.ts +300 -0
  82. package/src/components/KeyboardChatScrollView/useChatKeyboard/types.ts +30 -0
  83. package/src/components/KeyboardStickyView/index.tsx +8 -8
  84. package/src/components/ScrollViewWithBottomPadding/index.tsx +63 -17
  85. package/src/components/hooks/useScrollState.ts +24 -2
  86. package/src/components/index.ts +2 -0
  87. package/src/index.ts +2 -0
  88. package/src/specs/ClippingScrollViewDecoratorViewNativeComponent.ts +1 -0
  89. package/src/types/views.ts +2 -0
@@ -0,0 +1,121 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.useChatKeyboard = useChatKeyboard;
7
+ var _reactNativeReanimated = require("react-native-reanimated");
8
+ var _hooks = require("../../../hooks");
9
+ var _useScrollState = _interopRequireDefault(require("../../hooks/useScrollState"));
10
+ var _helpers = require("./helpers");
11
+ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
12
+ /**
13
+ * Hook that manages keyboard-driven scrolling for chat-style scroll views.
14
+ * Calculates padding (extra scrollable space) and content shift values,
15
+ * using iOS-specific strategy (contentOffset set once in onStart).
16
+ *
17
+ * @param scrollViewRef - Animated ref to the scroll view.
18
+ * @param options - Configuration for inverted and keyboardLiftBehavior.
19
+ * @returns Shared values for padding and contentOffsetY.
20
+ * @example
21
+ * ```tsx
22
+ * const { padding, contentOffsetY } = useChatKeyboard(ref, {
23
+ * inverted: false,
24
+ * keyboardLiftBehavior: "always",
25
+ * });
26
+ * ```
27
+ */
28
+ function useChatKeyboard(scrollViewRef, options) {
29
+ const {
30
+ inverted,
31
+ keyboardLiftBehavior,
32
+ freeze,
33
+ offset
34
+ } = options;
35
+ const padding = (0, _reactNativeReanimated.useSharedValue)(0);
36
+ const currentHeight = (0, _reactNativeReanimated.useSharedValue)(0);
37
+ const contentOffsetY = (0, _reactNativeReanimated.useSharedValue)(0);
38
+ const targetKeyboardHeight = (0, _reactNativeReanimated.useSharedValue)(0);
39
+ const {
40
+ layout,
41
+ size,
42
+ offset: scroll,
43
+ onLayout,
44
+ onContentSizeChange
45
+ } = (0, _useScrollState.default)(scrollViewRef);
46
+ (0, _hooks.useKeyboardHandler)({
47
+ onStart: e => {
48
+ "worklet";
49
+
50
+ if (freeze) {
51
+ return;
52
+ }
53
+ if (e.height > 0) {
54
+ // eslint-disable-next-line react-compiler/react-compiler
55
+ targetKeyboardHeight.value = e.height;
56
+ }
57
+ const effective = (0, _helpers.getEffectiveHeight)(e.height, targetKeyboardHeight.value, offset);
58
+ const atEnd = (0, _helpers.isScrollAtEnd)(scroll.value, layout.value.height, size.value.height, inverted);
59
+
60
+ // persistent mode: when keyboard shrinks, snap to end or hold position
61
+ if (keyboardLiftBehavior === "persistent" && effective < padding.value) {
62
+ padding.value = effective;
63
+ if (atEnd) {
64
+ if (inverted) {
65
+ contentOffsetY.value = -effective;
66
+ } else {
67
+ contentOffsetY.value = Math.max(size.value.height - layout.value.height + effective, 0);
68
+ }
69
+ } else {
70
+ // Preserve current scroll position so the animated props
71
+ // don't re-apply the stale contentOffset from keyboard open
72
+ contentOffsetY.value = scroll.value;
73
+ }
74
+ return;
75
+ }
76
+
77
+ // never mode: when keyboard shrinks and at end, snap to end
78
+ // to avoid ghost padding
79
+ if (keyboardLiftBehavior === "never" && effective < padding.value && atEnd) {
80
+ padding.value = effective;
81
+ if (inverted) {
82
+ contentOffsetY.value = -effective;
83
+ } else {
84
+ contentOffsetY.value = Math.max(size.value.height - layout.value.height + effective, 0);
85
+ }
86
+ return;
87
+ }
88
+ const relativeScroll = inverted ? scroll.value + padding.value : scroll.value - padding.value;
89
+ padding.value = effective;
90
+ if (!(0, _helpers.shouldShiftContent)(keyboardLiftBehavior, atEnd)) {
91
+ // Preserve current scroll position so animated props
92
+ // don't re-apply a stale contentOffset when padding changes
93
+ contentOffsetY.value = scroll.value;
94
+ return;
95
+ }
96
+ contentOffsetY.value = (0, _helpers.computeIOSContentOffset)(relativeScroll, effective, size.value.height, layout.value.height, inverted);
97
+ },
98
+ onMove: () => {
99
+ "worklet";
100
+
101
+ // iOS doesn't need per-frame updates (contentOffset handles it)
102
+ },
103
+ onEnd: e => {
104
+ "worklet";
105
+
106
+ if (freeze) {
107
+ return;
108
+ }
109
+ const effective = (0, _helpers.getEffectiveHeight)(e.height, targetKeyboardHeight.value, offset);
110
+ padding.value = effective;
111
+ }
112
+ }, [inverted, keyboardLiftBehavior, freeze, offset]);
113
+ return {
114
+ padding,
115
+ currentHeight,
116
+ contentOffsetY,
117
+ onLayout,
118
+ onContentSizeChange
119
+ };
120
+ }
121
+ //# sourceMappingURL=index.ios.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["_reactNativeReanimated","require","_hooks","_useScrollState","_interopRequireDefault","_helpers","e","__esModule","default","useChatKeyboard","scrollViewRef","options","inverted","keyboardLiftBehavior","freeze","offset","padding","useSharedValue","currentHeight","contentOffsetY","targetKeyboardHeight","layout","size","scroll","onLayout","onContentSizeChange","useScrollState","useKeyboardHandler","onStart","height","value","effective","getEffectiveHeight","atEnd","isScrollAtEnd","Math","max","relativeScroll","shouldShiftContent","computeIOSContentOffset","onMove","onEnd"],"sources":["index.ios.ts"],"sourcesContent":["import { useSharedValue } from \"react-native-reanimated\";\n\nimport { useKeyboardHandler } from \"../../../hooks\";\nimport useScrollState from \"../../hooks/useScrollState\";\n\nimport {\n computeIOSContentOffset,\n getEffectiveHeight,\n isScrollAtEnd,\n shouldShiftContent,\n} from \"./helpers\";\n\nimport type { UseChatKeyboardOptions, UseChatKeyboardReturn } from \"./types\";\nimport type { AnimatedRef } from \"react-native-reanimated\";\nimport type Reanimated from \"react-native-reanimated\";\n\n/**\n * Hook that manages keyboard-driven scrolling for chat-style scroll views.\n * Calculates padding (extra scrollable space) and content shift values,\n * using iOS-specific strategy (contentOffset set once in onStart).\n *\n * @param scrollViewRef - Animated ref to the scroll view.\n * @param options - Configuration for inverted and keyboardLiftBehavior.\n * @returns Shared values for padding and contentOffsetY.\n * @example\n * ```tsx\n * const { padding, contentOffsetY } = useChatKeyboard(ref, {\n * inverted: false,\n * keyboardLiftBehavior: \"always\",\n * });\n * ```\n */\nfunction useChatKeyboard(\n scrollViewRef: AnimatedRef<Reanimated.ScrollView>,\n options: UseChatKeyboardOptions,\n): UseChatKeyboardReturn {\n const { inverted, keyboardLiftBehavior, freeze, offset } = options;\n\n const padding = useSharedValue(0);\n const currentHeight = useSharedValue(0);\n const contentOffsetY = useSharedValue(0);\n const targetKeyboardHeight = useSharedValue(0);\n\n const {\n layout,\n size,\n offset: scroll,\n onLayout,\n onContentSizeChange,\n } = useScrollState(scrollViewRef);\n\n useKeyboardHandler(\n {\n onStart: (e) => {\n \"worklet\";\n\n if (freeze) {\n return;\n }\n\n if (e.height > 0) {\n // eslint-disable-next-line react-compiler/react-compiler\n targetKeyboardHeight.value = e.height;\n }\n\n const effective = getEffectiveHeight(\n e.height,\n targetKeyboardHeight.value,\n offset,\n );\n\n const atEnd = isScrollAtEnd(\n scroll.value,\n layout.value.height,\n size.value.height,\n inverted,\n );\n\n // persistent mode: when keyboard shrinks, snap to end or hold position\n if (\n keyboardLiftBehavior === \"persistent\" &&\n effective < padding.value\n ) {\n padding.value = effective;\n\n if (atEnd) {\n if (inverted) {\n contentOffsetY.value = -effective;\n } else {\n contentOffsetY.value = Math.max(\n size.value.height - layout.value.height + effective,\n 0,\n );\n }\n } else {\n // Preserve current scroll position so the animated props\n // don't re-apply the stale contentOffset from keyboard open\n contentOffsetY.value = scroll.value;\n }\n\n return;\n }\n\n // never mode: when keyboard shrinks and at end, snap to end\n // to avoid ghost padding\n if (\n keyboardLiftBehavior === \"never\" &&\n effective < padding.value &&\n atEnd\n ) {\n padding.value = effective;\n\n if (inverted) {\n contentOffsetY.value = -effective;\n } else {\n contentOffsetY.value = Math.max(\n size.value.height - layout.value.height + effective,\n 0,\n );\n }\n\n return;\n }\n\n const relativeScroll = inverted\n ? scroll.value + padding.value\n : scroll.value - padding.value;\n\n padding.value = effective;\n\n if (!shouldShiftContent(keyboardLiftBehavior, atEnd)) {\n // Preserve current scroll position so animated props\n // don't re-apply a stale contentOffset when padding changes\n contentOffsetY.value = scroll.value;\n\n return;\n }\n\n contentOffsetY.value = computeIOSContentOffset(\n relativeScroll,\n effective,\n size.value.height,\n layout.value.height,\n inverted,\n );\n },\n onMove: () => {\n \"worklet\";\n\n // iOS doesn't need per-frame updates (contentOffset handles it)\n },\n onEnd: (e) => {\n \"worklet\";\n\n if (freeze) {\n return;\n }\n\n const effective = getEffectiveHeight(\n e.height,\n targetKeyboardHeight.value,\n offset,\n );\n\n padding.value = effective;\n },\n },\n [inverted, keyboardLiftBehavior, freeze, offset],\n );\n\n return {\n padding,\n currentHeight,\n contentOffsetY,\n onLayout,\n onContentSizeChange,\n };\n}\n\nexport { useChatKeyboard };\n"],"mappings":"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","ignoreList":[]}
@@ -0,0 +1,205 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.useChatKeyboard = useChatKeyboard;
7
+ var _reactNativeReanimated = require("react-native-reanimated");
8
+ var _hooks = require("../../../hooks");
9
+ var _useScrollState = _interopRequireDefault(require("../../hooks/useScrollState"));
10
+ var _helpers = require("./helpers");
11
+ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
12
+ /**
13
+ * Hook that manages keyboard-driven scrolling for chat-style scroll views.
14
+ * Calculates padding (extra scrollable space) and content shift values,
15
+ * using per-frame scrollTo updates (Android and other platforms).
16
+ *
17
+ * @param scrollViewRef - Animated ref to the scroll view.
18
+ * @param options - Configuration for inverted and keyboardLiftBehavior.
19
+ * @returns Shared values for padding and contentOffsetY (always `undefined`).
20
+ * @example
21
+ * ```tsx
22
+ * const { padding, contentOffsetY } = useChatKeyboard(ref, {
23
+ * inverted: false,
24
+ * keyboardLiftBehavior: "always",
25
+ * });
26
+ * ```
27
+ */
28
+ function useChatKeyboard(scrollViewRef, options) {
29
+ const {
30
+ inverted,
31
+ keyboardLiftBehavior,
32
+ freeze,
33
+ offset
34
+ } = options;
35
+ const padding = (0, _reactNativeReanimated.useSharedValue)(0);
36
+ const currentHeight = (0, _reactNativeReanimated.useSharedValue)(0);
37
+ const offsetBeforeScroll = (0, _reactNativeReanimated.useSharedValue)(0);
38
+ const targetKeyboardHeight = (0, _reactNativeReanimated.useSharedValue)(0);
39
+ const closing = (0, _reactNativeReanimated.useSharedValue)(false);
40
+ const {
41
+ layout,
42
+ size,
43
+ offset: scroll,
44
+ onLayout,
45
+ onContentSizeChange
46
+ } = (0, _useScrollState.default)(scrollViewRef);
47
+ const clampScrollIfNeeded = effective => {
48
+ "worklet";
49
+
50
+ const maxScroll = Math.max(size.value.height - layout.value.height + effective, 0);
51
+ if (scroll.value > maxScroll) {
52
+ (0, _reactNativeReanimated.scrollTo)(scrollViewRef, 0, maxScroll, false);
53
+ }
54
+ };
55
+ (0, _hooks.useKeyboardHandler)({
56
+ onStart: e => {
57
+ "worklet";
58
+
59
+ if (freeze) {
60
+ return;
61
+ }
62
+ if (e.height > 0) {
63
+ // eslint-disable-next-line react-compiler/react-compiler
64
+ targetKeyboardHeight.value = e.height;
65
+ closing.value = false;
66
+ } else {
67
+ closing.value = true;
68
+ }
69
+ const effective = (0, _helpers.getEffectiveHeight)(e.height, targetKeyboardHeight.value, offset);
70
+ const atEnd = (0, _helpers.isScrollAtEnd)(scroll.value, layout.value.height, size.value.height, inverted);
71
+ if (inverted && e.duration === -1) {
72
+ // Android inverted: skip post-interactive snap-back events
73
+ // (duration === -1 means the keyboard is re-establishing its
74
+ // position after an interactive gesture, not a real animation)
75
+ return;
76
+ } else if (e.height > 0) {
77
+ // Android: keyboard opening — set padding + capture scroll position
78
+ padding.value = effective;
79
+ offsetBeforeScroll.value = scroll.value;
80
+ if (!inverted && keyboardLiftBehavior === "whenAtEnd" && !atEnd) {
81
+ // Sentinel: don't scroll in onMove (non-inverted only)
82
+ offsetBeforeScroll.value = -1;
83
+ }
84
+ } else {
85
+ // Android: keyboard closing — re-capture scroll position
86
+ if (inverted) {
87
+ offsetBeforeScroll.value = scroll.value;
88
+ } else {
89
+ // Preserve "whenAtEnd" sentinel: if open didn't shift, close shouldn't either
90
+ if (offsetBeforeScroll.value !== -1) {
91
+ // Non-inverted: subtract padding to get the "natural" position
92
+ // so onMove smoothly scrolls back from where the user is now
93
+ offsetBeforeScroll.value = scroll.value - padding.value;
94
+ }
95
+ }
96
+ }
97
+ },
98
+ onMove: e => {
99
+ "worklet";
100
+
101
+ if (freeze) {
102
+ return;
103
+ }
104
+ currentHeight.value = e.height;
105
+ if (inverted) {
106
+ // Skip post-interactive snap-back (duration === -1)
107
+ if (e.duration === -1) {
108
+ return;
109
+ }
110
+ const effective = (0, _helpers.getEffectiveHeight)(e.height, targetKeyboardHeight.value, offset);
111
+
112
+ // Check if we should shift content based on position when keyboard started
113
+ const wasAtEnd = (0, _helpers.isScrollAtEnd)(offsetBeforeScroll.value, layout.value.height, size.value.height, inverted);
114
+
115
+ // "never" at end: scroll along when keyboard closes to avoid jump
116
+ if (keyboardLiftBehavior === "never" && wasAtEnd && effective < padding.value) {
117
+ padding.value = effective;
118
+ (0, _reactNativeReanimated.scrollTo)(scrollViewRef, 0, 0, false);
119
+ return;
120
+ }
121
+ if (!(0, _helpers.shouldShiftContent)(keyboardLiftBehavior, wasAtEnd)) {
122
+ // Closing, not shifting: reduce padding to avoid gap
123
+ if (closing.value && effective < padding.value) {
124
+ padding.value = effective;
125
+ clampScrollIfNeeded(effective);
126
+ }
127
+ return;
128
+ }
129
+
130
+ // Persistent: don't let shift decrease
131
+ if (keyboardLiftBehavior === "persistent") {
132
+ const currentShift = offsetBeforeScroll.value + padding.value - scroll.value;
133
+ if (effective < currentShift) {
134
+ // When at end, allow scrolling back (snap to end + reduce padding)
135
+ if (wasAtEnd) {
136
+ padding.value = effective;
137
+ (0, _reactNativeReanimated.scrollTo)(scrollViewRef, 0, 0, false);
138
+ } else if (closing.value) {
139
+ // Not at end: reduce padding to avoid gap
140
+ padding.value = effective;
141
+ clampScrollIfNeeded(effective);
142
+ }
143
+ return;
144
+ }
145
+ }
146
+ const target = offsetBeforeScroll.value + padding.value - effective;
147
+ (0, _reactNativeReanimated.scrollTo)(scrollViewRef, 0, target, false);
148
+ } else {
149
+ const effective = (0, _helpers.getEffectiveHeight)(e.height, targetKeyboardHeight.value, offset);
150
+
151
+ // "never" closing: scroll along when at end to avoid jump
152
+ if (keyboardLiftBehavior === "never" && closing.value && effective < padding.value) {
153
+ const wasAtEnd = (0, _helpers.isScrollAtEnd)(offsetBeforeScroll.value + padding.value, layout.value.height, size.value.height, false);
154
+ if (wasAtEnd) {
155
+ const target = (0, _helpers.clampedScrollTarget)(offsetBeforeScroll.value, effective, size.value.height, layout.value.height);
156
+ (0, _reactNativeReanimated.scrollTo)(scrollViewRef, 0, target, false);
157
+ } else {
158
+ // Clamp to valid range as padding shrinks
159
+ clampScrollIfNeeded(effective);
160
+ }
161
+ return;
162
+ }
163
+ if (!(0, _helpers.shouldShiftContent)(keyboardLiftBehavior, true)) {
164
+ return;
165
+ }
166
+
167
+ // "whenAtEnd" sentinel check
168
+ if (offsetBeforeScroll.value === -1) {
169
+ if (closing.value) {
170
+ // Keyboard didn't shift on open; ensure valid position on close
171
+ clampScrollIfNeeded(effective);
172
+ }
173
+ return;
174
+ }
175
+
176
+ // "persistent" closing: maintain position, clamped to valid range
177
+ if (keyboardLiftBehavior === "persistent" && closing.value) {
178
+ const keepAt = offsetBeforeScroll.value + padding.value;
179
+ const maxScroll = Math.max(size.value.height - layout.value.height + effective, 0);
180
+ (0, _reactNativeReanimated.scrollTo)(scrollViewRef, 0, Math.min(keepAt, maxScroll), false);
181
+ return;
182
+ }
183
+ const target = (0, _helpers.clampedScrollTarget)(offsetBeforeScroll.value, effective, size.value.height, layout.value.height);
184
+ (0, _reactNativeReanimated.scrollTo)(scrollViewRef, 0, target, false);
185
+ }
186
+ },
187
+ onEnd: e => {
188
+ "worklet";
189
+
190
+ if (freeze) {
191
+ return;
192
+ }
193
+ const effective = (0, _helpers.getEffectiveHeight)(e.height, targetKeyboardHeight.value, offset);
194
+ padding.value = effective;
195
+ }
196
+ }, [inverted, keyboardLiftBehavior, freeze, offset]);
197
+ return {
198
+ padding,
199
+ currentHeight,
200
+ contentOffsetY: undefined,
201
+ onLayout,
202
+ onContentSizeChange
203
+ };
204
+ }
205
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["_reactNativeReanimated","require","_hooks","_useScrollState","_interopRequireDefault","_helpers","e","__esModule","default","useChatKeyboard","scrollViewRef","options","inverted","keyboardLiftBehavior","freeze","offset","padding","useSharedValue","currentHeight","offsetBeforeScroll","targetKeyboardHeight","closing","layout","size","scroll","onLayout","onContentSizeChange","useScrollState","clampScrollIfNeeded","effective","maxScroll","Math","max","value","height","scrollTo","useKeyboardHandler","onStart","getEffectiveHeight","atEnd","isScrollAtEnd","duration","onMove","wasAtEnd","shouldShiftContent","currentShift","target","clampedScrollTarget","keepAt","min","onEnd","contentOffsetY","undefined"],"sources":["index.ts"],"sourcesContent":["import { scrollTo, useSharedValue } from \"react-native-reanimated\";\n\nimport { useKeyboardHandler } from \"../../../hooks\";\nimport useScrollState from \"../../hooks/useScrollState\";\n\nimport {\n clampedScrollTarget,\n getEffectiveHeight,\n isScrollAtEnd,\n shouldShiftContent,\n} from \"./helpers\";\n\nimport type { UseChatKeyboardOptions, UseChatKeyboardReturn } from \"./types\";\nimport type { AnimatedRef } from \"react-native-reanimated\";\nimport type Reanimated from \"react-native-reanimated\";\n\n/**\n * Hook that manages keyboard-driven scrolling for chat-style scroll views.\n * Calculates padding (extra scrollable space) and content shift values,\n * using per-frame scrollTo updates (Android and other platforms).\n *\n * @param scrollViewRef - Animated ref to the scroll view.\n * @param options - Configuration for inverted and keyboardLiftBehavior.\n * @returns Shared values for padding and contentOffsetY (always `undefined`).\n * @example\n * ```tsx\n * const { padding, contentOffsetY } = useChatKeyboard(ref, {\n * inverted: false,\n * keyboardLiftBehavior: \"always\",\n * });\n * ```\n */\nfunction useChatKeyboard(\n scrollViewRef: AnimatedRef<Reanimated.ScrollView>,\n options: UseChatKeyboardOptions,\n): UseChatKeyboardReturn {\n const { inverted, keyboardLiftBehavior, freeze, offset } = options;\n\n const padding = useSharedValue(0);\n const currentHeight = useSharedValue(0);\n const offsetBeforeScroll = useSharedValue(0);\n const targetKeyboardHeight = useSharedValue(0);\n const closing = useSharedValue(false);\n\n const {\n layout,\n size,\n offset: scroll,\n onLayout,\n onContentSizeChange,\n } = useScrollState(scrollViewRef);\n\n const clampScrollIfNeeded = (effective: number) => {\n \"worklet\";\n\n const maxScroll = Math.max(\n size.value.height - layout.value.height + effective,\n 0,\n );\n\n if (scroll.value > maxScroll) {\n scrollTo(scrollViewRef, 0, maxScroll, false);\n }\n };\n\n useKeyboardHandler(\n {\n onStart: (e) => {\n \"worklet\";\n\n if (freeze) {\n return;\n }\n\n if (e.height > 0) {\n // eslint-disable-next-line react-compiler/react-compiler\n targetKeyboardHeight.value = e.height;\n closing.value = false;\n } else {\n closing.value = true;\n }\n\n const effective = getEffectiveHeight(\n e.height,\n targetKeyboardHeight.value,\n offset,\n );\n\n const atEnd = isScrollAtEnd(\n scroll.value,\n layout.value.height,\n size.value.height,\n inverted,\n );\n\n if (inverted && e.duration === -1) {\n // Android inverted: skip post-interactive snap-back events\n // (duration === -1 means the keyboard is re-establishing its\n // position after an interactive gesture, not a real animation)\n return;\n } else if (e.height > 0) {\n // Android: keyboard opening — set padding + capture scroll position\n padding.value = effective;\n offsetBeforeScroll.value = scroll.value;\n\n if (!inverted && keyboardLiftBehavior === \"whenAtEnd\" && !atEnd) {\n // Sentinel: don't scroll in onMove (non-inverted only)\n offsetBeforeScroll.value = -1;\n }\n } else {\n // Android: keyboard closing — re-capture scroll position\n if (inverted) {\n offsetBeforeScroll.value = scroll.value;\n } else {\n // Preserve \"whenAtEnd\" sentinel: if open didn't shift, close shouldn't either\n if (offsetBeforeScroll.value !== -1) {\n // Non-inverted: subtract padding to get the \"natural\" position\n // so onMove smoothly scrolls back from where the user is now\n offsetBeforeScroll.value = scroll.value - padding.value;\n }\n }\n }\n },\n onMove: (e) => {\n \"worklet\";\n\n if (freeze) {\n return;\n }\n\n currentHeight.value = e.height;\n\n if (inverted) {\n // Skip post-interactive snap-back (duration === -1)\n if (e.duration === -1) {\n return;\n }\n\n const effective = getEffectiveHeight(\n e.height,\n targetKeyboardHeight.value,\n offset,\n );\n\n // Check if we should shift content based on position when keyboard started\n const wasAtEnd = isScrollAtEnd(\n offsetBeforeScroll.value,\n layout.value.height,\n size.value.height,\n inverted,\n );\n\n // \"never\" at end: scroll along when keyboard closes to avoid jump\n if (\n keyboardLiftBehavior === \"never\" &&\n wasAtEnd &&\n effective < padding.value\n ) {\n padding.value = effective;\n scrollTo(scrollViewRef, 0, 0, false);\n\n return;\n }\n\n if (!shouldShiftContent(keyboardLiftBehavior, wasAtEnd)) {\n // Closing, not shifting: reduce padding to avoid gap\n if (closing.value && effective < padding.value) {\n padding.value = effective;\n clampScrollIfNeeded(effective);\n }\n\n return;\n }\n\n // Persistent: don't let shift decrease\n if (keyboardLiftBehavior === \"persistent\") {\n const currentShift =\n offsetBeforeScroll.value + padding.value - scroll.value;\n\n if (effective < currentShift) {\n // When at end, allow scrolling back (snap to end + reduce padding)\n if (wasAtEnd) {\n padding.value = effective;\n scrollTo(scrollViewRef, 0, 0, false);\n } else if (closing.value) {\n // Not at end: reduce padding to avoid gap\n padding.value = effective;\n clampScrollIfNeeded(effective);\n }\n\n return;\n }\n }\n\n const target = offsetBeforeScroll.value + padding.value - effective;\n\n scrollTo(scrollViewRef, 0, target, false);\n } else {\n const effective = getEffectiveHeight(\n e.height,\n targetKeyboardHeight.value,\n offset,\n );\n\n // \"never\" closing: scroll along when at end to avoid jump\n if (\n keyboardLiftBehavior === \"never\" &&\n closing.value &&\n effective < padding.value\n ) {\n const wasAtEnd = isScrollAtEnd(\n offsetBeforeScroll.value + padding.value,\n layout.value.height,\n size.value.height,\n false,\n );\n\n if (wasAtEnd) {\n const target = clampedScrollTarget(\n offsetBeforeScroll.value,\n effective,\n size.value.height,\n layout.value.height,\n );\n\n scrollTo(scrollViewRef, 0, target, false);\n } else {\n // Clamp to valid range as padding shrinks\n clampScrollIfNeeded(effective);\n }\n\n return;\n }\n\n if (!shouldShiftContent(keyboardLiftBehavior, true)) {\n return;\n }\n\n // \"whenAtEnd\" sentinel check\n if (offsetBeforeScroll.value === -1) {\n if (closing.value) {\n // Keyboard didn't shift on open; ensure valid position on close\n clampScrollIfNeeded(effective);\n }\n\n return;\n }\n\n // \"persistent\" closing: maintain position, clamped to valid range\n if (keyboardLiftBehavior === \"persistent\" && closing.value) {\n const keepAt = offsetBeforeScroll.value + padding.value;\n const maxScroll = Math.max(\n size.value.height - layout.value.height + effective,\n 0,\n );\n\n scrollTo(scrollViewRef, 0, Math.min(keepAt, maxScroll), false);\n\n return;\n }\n\n const target = clampedScrollTarget(\n offsetBeforeScroll.value,\n effective,\n size.value.height,\n layout.value.height,\n );\n\n scrollTo(scrollViewRef, 0, target, false);\n }\n },\n onEnd: (e) => {\n \"worklet\";\n\n if (freeze) {\n return;\n }\n\n const effective = getEffectiveHeight(\n e.height,\n targetKeyboardHeight.value,\n offset,\n );\n\n padding.value = effective;\n },\n },\n [inverted, keyboardLiftBehavior, freeze, offset],\n );\n\n return {\n padding,\n currentHeight,\n contentOffsetY: undefined,\n onLayout,\n onContentSizeChange,\n };\n}\n\nexport { useChatKeyboard };\n"],"mappings":"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","ignoreList":[]}
@@ -0,0 +1,6 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":[],"sources":["types.ts"],"sourcesContent":["import type { LayoutChangeEvent } from \"react-native\";\nimport type { SharedValue } from \"react-native-reanimated\";\n\ntype KeyboardLiftBehavior = \"always\" | \"whenAtEnd\" | \"persistent\" | \"never\";\n\ntype UseChatKeyboardOptions = {\n inverted: boolean;\n keyboardLiftBehavior: KeyboardLiftBehavior;\n freeze: boolean;\n offset: number;\n};\n\ntype UseChatKeyboardReturn = {\n /** Extra scrollable space (= keyboard height). Used as contentInset on iOS, contentInsetBottom/contentInsetTop on Android. */\n padding: SharedValue<number>;\n /** Raw keyboard height updated every frame in onMove. Used to force Reanimated commits on Fabric. */\n currentHeight: SharedValue<number>;\n /** Absolute Y content offset for iOS (set once in onStart). `undefined` on Android. */\n contentOffsetY: SharedValue<number> | undefined;\n /** Callback to attach to ScrollView's onLayout prop to capture initial viewport dimensions. */\n onLayout: (e: LayoutChangeEvent) => void;\n /** Callback to attach to ScrollView's onContentSizeChange prop to capture initial content dimensions. */\n onContentSizeChange: (w: number, h: number) => void;\n};\n\nexport type {\n KeyboardLiftBehavior,\n UseChatKeyboardOptions,\n UseChatKeyboardReturn,\n};\n"],"mappings":"","ignoreList":[]}
@@ -40,11 +40,15 @@ const KeyboardStickyView = /*#__PURE__*/(0, _react.forwardRef)(({
40
40
  inputRange: [0, 1],
41
41
  outputRange: [closed, opened]
42
42
  });
43
- const styles = (0, _react.useMemo)(() => [{
44
- transform: [{
45
- translateY: enabled ? _reactNative.Animated.add(height, offset) : closed
46
- }]
47
- }, style], [closed, enabled, height, offset, style]);
43
+ const styles = (0, _react.useMemo)(() => {
44
+ const disabled = _reactNative.Animated.add(_reactNative.Animated.multiply(height, 0), closed);
45
+ const active = _reactNative.Animated.add(height, offset);
46
+ return [{
47
+ transform: [{
48
+ translateY: enabled ? active : disabled
49
+ }]
50
+ }, style];
51
+ }, [closed, enabled, height, offset, style]);
48
52
  return /*#__PURE__*/_react.default.createElement(_reactNative.Animated.View, _extends({
49
53
  ref: ref,
50
54
  style: styles
@@ -1 +1 @@
1
- {"version":3,"names":["_react","_interopRequireWildcard","require","_reactNative","_hooks","e","t","WeakMap","r","n","__esModule","o","i","f","__proto__","default","has","get","set","hasOwnProperty","call","Object","defineProperty","getOwnPropertyDescriptor","_extends","assign","bind","arguments","length","apply","KeyboardStickyView","forwardRef","children","offset","closed","opened","style","enabled","props","ref","height","progress","useKeyboardAnimation","interpolate","inputRange","outputRange","styles","useMemo","transform","translateY","Animated","add","createElement","View","_default","exports"],"sources":["index.tsx"],"sourcesContent":["import React, { forwardRef, useMemo } from \"react\";\nimport { Animated } from \"react-native\";\n\nimport { useKeyboardAnimation } from \"../../hooks\";\n\nimport type { View, ViewProps } from \"react-native\";\n\nexport type KeyboardStickyViewProps = {\n /**\n * Specify additional offset to the view for given keyboard state.\n */\n offset?: {\n /**\n * Adds additional `translateY` when keyboard is close. By default `0`.\n */\n closed?: number;\n /**\n * Adds additional `translateY` when keyboard is open. By default `0`.\n */\n opened?: number;\n };\n\n /** Controls whether this `KeyboardStickyView` instance should take effect. Default is `true`. */\n enabled?: boolean;\n} & ViewProps;\n\n/**\n * A View component that sticks to the keyboard and moves with it when it appears or disappears.\n * The view can be configured with custom offsets for both closed and open keyboard states.\n *\n * @returns An animated View component that sticks to the keyboard.\n * @see {@link https://kirillzyusko.github.io/react-native-keyboard-controller/docs/api/components/keyboard-sticky-view|Documentation} page for more details.\n * @example\n * ```tsx\n * <KeyboardStickyView offset={{ closed: 0, opened: 20 }}>\n * <Button title=\"Submit\" />\n * </KeyboardStickyView>\n * ```\n */\nconst KeyboardStickyView = forwardRef<\n View,\n React.PropsWithChildren<KeyboardStickyViewProps>\n>(\n (\n {\n children,\n offset: { closed = 0, opened = 0 } = {},\n style,\n enabled = true,\n ...props\n },\n ref,\n ) => {\n const { height, progress } = useKeyboardAnimation();\n\n const offset = progress.interpolate({\n inputRange: [0, 1],\n outputRange: [closed, opened],\n });\n\n const styles = useMemo(\n () => [\n {\n transform: [\n { translateY: enabled ? Animated.add(height, offset) : closed },\n ],\n },\n style,\n ],\n [closed, enabled, height, offset, style],\n );\n\n return (\n <Animated.View ref={ref} style={styles} {...props}>\n {children}\n </Animated.View>\n );\n },\n);\n\nexport default KeyboardStickyView;\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"names":["_react","_interopRequireWildcard","require","_reactNative","_hooks","e","t","WeakMap","r","n","__esModule","o","i","f","__proto__","default","has","get","set","hasOwnProperty","call","Object","defineProperty","getOwnPropertyDescriptor","_extends","assign","bind","arguments","length","apply","KeyboardStickyView","forwardRef","children","offset","closed","opened","style","enabled","props","ref","height","progress","useKeyboardAnimation","interpolate","inputRange","outputRange","styles","useMemo","disabled","Animated","add","multiply","active","transform","translateY","createElement","View","_default","exports"],"sources":["index.tsx"],"sourcesContent":["import React, { forwardRef, useMemo } from \"react\";\nimport { Animated } from \"react-native\";\n\nimport { useKeyboardAnimation } from \"../../hooks\";\n\nimport type { View, ViewProps } from \"react-native\";\n\nexport type KeyboardStickyViewProps = {\n /**\n * Specify additional offset to the view for given keyboard state.\n */\n offset?: {\n /**\n * Adds additional `translateY` when keyboard is close. By default `0`.\n */\n closed?: number;\n /**\n * Adds additional `translateY` when keyboard is open. By default `0`.\n */\n opened?: number;\n };\n\n /** Controls whether this `KeyboardStickyView` instance should take effect. Default is `true`. */\n enabled?: boolean;\n} & ViewProps;\n\n/**\n * A View component that sticks to the keyboard and moves with it when it appears or disappears.\n * The view can be configured with custom offsets for both closed and open keyboard states.\n *\n * @returns An animated View component that sticks to the keyboard.\n * @see {@link https://kirillzyusko.github.io/react-native-keyboard-controller/docs/api/components/keyboard-sticky-view|Documentation} page for more details.\n * @example\n * ```tsx\n * <KeyboardStickyView offset={{ closed: 0, opened: 20 }}>\n * <Button title=\"Submit\" />\n * </KeyboardStickyView>\n * ```\n */\nconst KeyboardStickyView = forwardRef<\n View,\n React.PropsWithChildren<KeyboardStickyViewProps>\n>(\n (\n {\n children,\n offset: { closed = 0, opened = 0 } = {},\n style,\n enabled = true,\n ...props\n },\n ref,\n ) => {\n const { height, progress } = useKeyboardAnimation();\n\n const offset = progress.interpolate({\n inputRange: [0, 1],\n outputRange: [closed, opened],\n });\n\n const styles = useMemo(() => {\n const disabled = Animated.add(Animated.multiply(height, 0), closed);\n const active = Animated.add(height, offset);\n\n return [\n {\n transform: [{ translateY: enabled ? active : disabled }],\n },\n style,\n ];\n }, [closed, enabled, height, offset, style]);\n\n return (\n <Animated.View ref={ref} style={styles} {...props}>\n {children}\n </Animated.View>\n );\n },\n);\n\nexport default KeyboardStickyView;\n"],"mappings":"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","ignoreList":[]}
@@ -12,32 +12,65 @@ var _styles = _interopRequireDefault(require("./styles"));
12
12
  function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
13
13
  function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); }
14
14
  function _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); }
15
- const ReanimatedClippingScrollView = _reactNative.Platform.OS === "android" ? _reactNativeReanimated.default.createAnimatedComponent(_bindings.ClippingScrollView) : _bindings.ClippingScrollView;
15
+ const OS = _reactNative.Platform.OS;
16
+ const ReanimatedClippingScrollView = OS === "android" ? _reactNativeReanimated.default.createAnimatedComponent(_bindings.ClippingScrollView) : _bindings.ClippingScrollView;
16
17
  const ScrollViewWithBottomPadding = /*#__PURE__*/(0, _react.forwardRef)(({
17
18
  ScrollViewComponent,
18
19
  bottomPadding,
19
20
  contentInset,
21
+ scrollIndicatorInsets,
22
+ inverted,
23
+ contentOffsetY,
20
24
  children,
21
25
  ...rest
22
26
  }, ref) => {
23
- const animatedProps = (0, _reactNativeReanimated.useAnimatedProps)(() => ({
24
- // iOS prop
25
- contentInset: {
26
- bottom: bottomPadding.value + ((contentInset === null || contentInset === void 0 ? void 0 : contentInset.bottom) || 0),
27
- top: contentInset === null || contentInset === void 0 ? void 0 : contentInset.top,
28
- right: contentInset === null || contentInset === void 0 ? void 0 : contentInset.right,
29
- left: contentInset === null || contentInset === void 0 ? void 0 : contentInset.left
30
- },
31
- // Android prop
32
- contentInsetBottom: bottomPadding.value
33
- }), [contentInset === null || contentInset === void 0 ? void 0 : contentInset.bottom, contentInset === null || contentInset === void 0 ? void 0 : contentInset.top, contentInset === null || contentInset === void 0 ? void 0 : contentInset.right, contentInset === null || contentInset === void 0 ? void 0 : contentInset.left]);
27
+ const animatedProps = (0, _reactNativeReanimated.useAnimatedProps)(() => {
28
+ const insetTop = inverted ? bottomPadding.value : 0;
29
+ const insetBottom = !inverted ? bottomPadding.value : 0;
30
+ const bottom = insetBottom + ((contentInset === null || contentInset === void 0 ? void 0 : contentInset.bottom) || 0);
31
+ const top = insetTop + ((contentInset === null || contentInset === void 0 ? void 0 : contentInset.top) || 0);
32
+ const result = {
33
+ // iOS prop
34
+ contentInset: {
35
+ bottom: bottom,
36
+ top: top,
37
+ right: contentInset === null || contentInset === void 0 ? void 0 : contentInset.right,
38
+ left: contentInset === null || contentInset === void 0 ? void 0 : contentInset.left
39
+ },
40
+ scrollIndicatorInsets: {
41
+ bottom: bottom,
42
+ top: top,
43
+ right: scrollIndicatorInsets === null || scrollIndicatorInsets === void 0 ? void 0 : scrollIndicatorInsets.right,
44
+ left: scrollIndicatorInsets === null || scrollIndicatorInsets === void 0 ? void 0 : scrollIndicatorInsets.left
45
+ },
46
+ // Android prop
47
+ contentInsetBottom: insetBottom,
48
+ contentInsetTop: insetTop
49
+ };
50
+ if (contentOffsetY) {
51
+ result.contentOffset = {
52
+ x: 0,
53
+ y: contentOffsetY.value
54
+ };
55
+ }
56
+ return result;
57
+ }, [contentInset === null || contentInset === void 0 ? void 0 : contentInset.bottom, contentInset === null || contentInset === void 0 ? void 0 : contentInset.top, contentInset === null || contentInset === void 0 ? void 0 : contentInset.right, contentInset === null || contentInset === void 0 ? void 0 : contentInset.left, scrollIndicatorInsets === null || scrollIndicatorInsets === void 0 ? void 0 : scrollIndicatorInsets.bottom, scrollIndicatorInsets === null || scrollIndicatorInsets === void 0 ? void 0 : scrollIndicatorInsets.top, scrollIndicatorInsets === null || scrollIndicatorInsets === void 0 ? void 0 : scrollIndicatorInsets.right, scrollIndicatorInsets === null || scrollIndicatorInsets === void 0 ? void 0 : scrollIndicatorInsets.left, inverted, contentOffsetY]);
34
58
  return /*#__PURE__*/_react.default.createElement(ReanimatedClippingScrollView, {
35
59
  animatedProps: animatedProps,
36
60
  style: _styles.default.container
37
61
  }, /*#__PURE__*/_react.default.createElement(ScrollViewComponent, _extends({
38
62
  ref: ref,
39
63
  animatedProps: animatedProps
40
- }, rest), children));
64
+ }, rest), inverted ?
65
+ /*#__PURE__*/
66
+ // The only thing it can break is `StickyHeader`, but it's already broken in FlatList and other lists
67
+ // don't support this functionality, so we can add additional view here
68
+ // The correct fix would be to add a new prop in ScrollView that allows
69
+ // to customize children extraction logic and skip custom view
70
+ _react.default.createElement(_reactNative.View, {
71
+ collapsable: false,
72
+ nativeID: "container"
73
+ }, children) : children));
41
74
  });
42
75
  var _default = exports.default = ScrollViewWithBottomPadding;
43
76
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"names":["_react","_interopRequireWildcard","require","_reactNative","_reactNativeReanimated","_bindings","_styles","_interopRequireDefault","e","__esModule","default","t","WeakMap","r","n","o","i","f","__proto__","has","get","set","hasOwnProperty","call","Object","defineProperty","getOwnPropertyDescriptor","_extends","assign","bind","arguments","length","apply","ReanimatedClippingScrollView","Platform","OS","Reanimated","createAnimatedComponent","ClippingScrollView","ScrollViewWithBottomPadding","forwardRef","ScrollViewComponent","bottomPadding","contentInset","children","rest","ref","animatedProps","useAnimatedProps","bottom","value","top","right","left","contentInsetBottom","createElement","style","styles","container","_default","exports"],"sources":["index.tsx"],"sourcesContent":["import React, { forwardRef } from \"react\";\nimport { Platform } from \"react-native\";\nimport Reanimated, { useAnimatedProps } from \"react-native-reanimated\";\n\nimport { ClippingScrollView } from \"../../bindings\";\n\nimport styles from \"./styles\";\n\nimport type { ScrollViewProps } from \"react-native\";\nimport type { SharedValue } from \"react-native-reanimated\";\n\nconst ReanimatedClippingScrollView =\n Platform.OS === \"android\"\n ? Reanimated.createAnimatedComponent(ClippingScrollView)\n : ClippingScrollView;\n\ntype AnimatedScrollViewProps = React.ComponentProps<\n typeof Reanimated.ScrollView\n>;\n\nexport type AnimatedScrollViewComponent = React.ForwardRefExoticComponent<\n AnimatedScrollViewProps & React.RefAttributes<Reanimated.ScrollView>\n>;\n\ntype ScrollViewWithBottomPaddingProps = {\n ScrollViewComponent: AnimatedScrollViewComponent;\n children?: React.ReactNode;\n bottomPadding: SharedValue<number>;\n} & ScrollViewProps;\n\nconst ScrollViewWithBottomPadding = forwardRef<\n Reanimated.ScrollView,\n ScrollViewWithBottomPaddingProps\n>(\n (\n { ScrollViewComponent, bottomPadding, contentInset, children, ...rest },\n ref,\n ) => {\n const animatedProps = useAnimatedProps(\n () => ({\n // iOS prop\n contentInset: {\n bottom: bottomPadding.value + (contentInset?.bottom || 0),\n top: contentInset?.top,\n right: contentInset?.right,\n left: contentInset?.left,\n },\n // Android prop\n contentInsetBottom: bottomPadding.value,\n }),\n [\n contentInset?.bottom,\n contentInset?.top,\n contentInset?.right,\n contentInset?.left,\n ],\n );\n\n return (\n <ReanimatedClippingScrollView\n animatedProps={animatedProps}\n style={styles.container}\n >\n <ScrollViewComponent ref={ref} animatedProps={animatedProps} {...rest}>\n {children}\n </ScrollViewComponent>\n </ReanimatedClippingScrollView>\n );\n },\n);\n\nexport default ScrollViewWithBottomPadding;\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"names":["_react","_interopRequireWildcard","require","_reactNative","_reactNativeReanimated","_bindings","_styles","_interopRequireDefault","e","__esModule","default","t","WeakMap","r","n","o","i","f","__proto__","has","get","set","hasOwnProperty","call","Object","defineProperty","getOwnPropertyDescriptor","_extends","assign","bind","arguments","length","apply","OS","Platform","ReanimatedClippingScrollView","Reanimated","createAnimatedComponent","ClippingScrollView","ScrollViewWithBottomPadding","forwardRef","ScrollViewComponent","bottomPadding","contentInset","scrollIndicatorInsets","inverted","contentOffsetY","children","rest","ref","animatedProps","useAnimatedProps","insetTop","value","insetBottom","bottom","top","result","right","left","contentInsetBottom","contentInsetTop","contentOffset","x","y","createElement","style","styles","container","View","collapsable","nativeID","_default","exports"],"sources":["index.tsx"],"sourcesContent":["import React, { forwardRef } from \"react\";\nimport { Platform, View } from \"react-native\";\nimport Reanimated, { useAnimatedProps } from \"react-native-reanimated\";\n\nimport { ClippingScrollView } from \"../../bindings\";\n\nimport styles from \"./styles\";\n\nimport type { ScrollViewProps } from \"react-native\";\nimport type { SharedValue } from \"react-native-reanimated\";\n\nconst OS = Platform.OS;\nconst ReanimatedClippingScrollView =\n OS === \"android\"\n ? Reanimated.createAnimatedComponent(ClippingScrollView)\n : ClippingScrollView;\n\ntype AnimatedScrollViewProps = React.ComponentProps<\n typeof Reanimated.ScrollView\n>;\n\nexport type AnimatedScrollViewComponent = React.ForwardRefExoticComponent<\n AnimatedScrollViewProps & React.RefAttributes<Reanimated.ScrollView>\n>;\n\ntype ScrollViewWithBottomPaddingProps = {\n ScrollViewComponent: AnimatedScrollViewComponent;\n children?: React.ReactNode;\n inverted?: boolean;\n bottomPadding: SharedValue<number>;\n /** Absolute Y content offset (iOS only, for KeyboardChatScrollView). */\n contentOffsetY?: SharedValue<number>;\n} & ScrollViewProps;\n\nconst ScrollViewWithBottomPadding = forwardRef<\n Reanimated.ScrollView,\n ScrollViewWithBottomPaddingProps\n>(\n (\n {\n ScrollViewComponent,\n bottomPadding,\n contentInset,\n scrollIndicatorInsets,\n inverted,\n contentOffsetY,\n children,\n ...rest\n },\n ref,\n ) => {\n const animatedProps = useAnimatedProps(() => {\n const insetTop = inverted ? bottomPadding.value : 0;\n const insetBottom = !inverted ? bottomPadding.value : 0;\n const bottom = insetBottom + (contentInset?.bottom || 0);\n const top = insetTop + (contentInset?.top || 0);\n\n const result: Record<string, unknown> = {\n // iOS prop\n contentInset: {\n bottom: bottom,\n top: top,\n right: contentInset?.right,\n left: contentInset?.left,\n },\n scrollIndicatorInsets: {\n bottom: bottom,\n top: top,\n right: scrollIndicatorInsets?.right,\n left: scrollIndicatorInsets?.left,\n },\n // Android prop\n contentInsetBottom: insetBottom,\n contentInsetTop: insetTop,\n };\n\n if (contentOffsetY) {\n result.contentOffset = { x: 0, y: contentOffsetY.value };\n }\n\n return result;\n }, [\n contentInset?.bottom,\n contentInset?.top,\n contentInset?.right,\n contentInset?.left,\n scrollIndicatorInsets?.bottom,\n scrollIndicatorInsets?.top,\n scrollIndicatorInsets?.right,\n scrollIndicatorInsets?.left,\n inverted,\n contentOffsetY,\n ]);\n\n return (\n <ReanimatedClippingScrollView\n animatedProps={animatedProps}\n style={styles.container}\n >\n <ScrollViewComponent ref={ref} animatedProps={animatedProps} {...rest}>\n {inverted ? (\n // The only thing it can break is `StickyHeader`, but it's already broken in FlatList and other lists\n // don't support this functionality, so we can add additional view here\n // The correct fix would be to add a new prop in ScrollView that allows\n // to customize children extraction logic and skip custom view\n <View collapsable={false} nativeID=\"container\">\n {children}\n </View>\n ) : (\n children\n )}\n </ScrollViewComponent>\n </ReanimatedClippingScrollView>\n );\n },\n);\n\nexport default ScrollViewWithBottomPadding;\n"],"mappings":"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","ignoreList":[]}
@@ -33,10 +33,29 @@ const useScrollState = ref => {
33
33
  cleanup();
34
34
  };
35
35
  }, []);
36
+
37
+ // `onContentSizeChange` is synthesized in JS (from the content container's
38
+ // onLayout) and `onLayout` has a different payload shape than scroll events,
39
+ // so neither can be reliably captured via native event registration.
40
+ // Instead we expose callbacks for the consumer to attach as props.
41
+ const onLayout = (0, _react.useCallback)(e => {
42
+ layout.value = {
43
+ width: e.nativeEvent.layout.width,
44
+ height: e.nativeEvent.layout.height
45
+ };
46
+ }, [layout]);
47
+ const onContentSizeChange = (0, _react.useCallback)((w, h) => {
48
+ size.value = {
49
+ width: w,
50
+ height: h
51
+ };
52
+ }, [size]);
36
53
  return {
37
54
  offset,
38
55
  layout,
39
- size
56
+ size,
57
+ onLayout,
58
+ onContentSizeChange
40
59
  };
41
60
  };
42
61
  var _default = exports.default = useScrollState;
@@ -1 +1 @@
1
- {"version":3,"names":["_react","require","_reactNativeReanimated","_internal","NATIVE_SCROLL_EVENT_NAMES","useScrollState","ref","offset","useSharedValue","layout","width","height","size","register","useEventHandlerRegistration","eventHandler","useEvent","event","value","contentOffset","y","layoutMeasurement","contentSize","useEffect","cleanup","_default","exports","default"],"sources":["useScrollState.ts"],"sourcesContent":["import { useEffect } from \"react\";\nimport { useEvent, useSharedValue } from \"react-native-reanimated\";\n\nimport { useEventHandlerRegistration } from \"../../internal\";\n\nimport type { AnimatedRef } from \"react-native-reanimated\";\nimport type Reanimated from \"react-native-reanimated\";\n\nconst NATIVE_SCROLL_EVENT_NAMES = [\n \"onScroll\",\n \"onScrollBeginDrag\",\n \"onScrollEndDrag\",\n \"onMomentumScrollBegin\",\n \"onMomentumScrollEnd\",\n];\n\ntype ScrollEvent = {\n contentOffset: {\n x: number;\n y: number;\n };\n layoutMeasurement: {\n width: number;\n height: number;\n };\n contentSize: {\n width: number;\n height: number;\n };\n};\n\nconst useScrollState = (ref: AnimatedRef<Reanimated.ScrollView>) => {\n const offset = useSharedValue(0);\n const layout = useSharedValue({ width: 0, height: 0 });\n const size = useSharedValue({ width: 0, height: 0 });\n\n const register = useEventHandlerRegistration(ref);\n\n const eventHandler = useEvent((event: ScrollEvent) => {\n \"worklet\";\n\n // eslint-disable-next-line react-compiler/react-compiler\n offset.value = event.contentOffset.y;\n layout.value = event.layoutMeasurement;\n size.value = event.contentSize;\n }, NATIVE_SCROLL_EVENT_NAMES);\n\n useEffect(() => {\n const cleanup = register(eventHandler);\n\n return () => {\n cleanup();\n };\n }, []);\n\n return { offset, layout, size };\n};\n\nexport default useScrollState;\n"],"mappings":";;;;;;AAAA,IAAAA,MAAA,GAAAC,OAAA;AACA,IAAAC,sBAAA,GAAAD,OAAA;AAEA,IAAAE,SAAA,GAAAF,OAAA;AAKA,MAAMG,yBAAyB,GAAG,CAChC,UAAU,EACV,mBAAmB,EACnB,iBAAiB,EACjB,uBAAuB,EACvB,qBAAqB,CACtB;AAiBD,MAAMC,cAAc,GAAIC,GAAuC,IAAK;EAClE,MAAMC,MAAM,GAAG,IAAAC,qCAAc,EAAC,CAAC,CAAC;EAChC,MAAMC,MAAM,GAAG,IAAAD,qCAAc,EAAC;IAAEE,KAAK,EAAE,CAAC;IAAEC,MAAM,EAAE;EAAE,CAAC,CAAC;EACtD,MAAMC,IAAI,GAAG,IAAAJ,qCAAc,EAAC;IAAEE,KAAK,EAAE,CAAC;IAAEC,MAAM,EAAE;EAAE,CAAC,CAAC;EAEpD,MAAME,QAAQ,GAAG,IAAAC,qCAA2B,EAACR,GAAG,CAAC;EAEjD,MAAMS,YAAY,GAAG,IAAAC,+BAAQ,EAAEC,KAAkB,IAAK;IACpD,SAAS;;IAET;IACAV,MAAM,CAACW,KAAK,GAAGD,KAAK,CAACE,aAAa,CAACC,CAAC;IACpCX,MAAM,CAACS,KAAK,GAAGD,KAAK,CAACI,iBAAiB;IACtCT,IAAI,CAACM,KAAK,GAAGD,KAAK,CAACK,WAAW;EAChC,CAAC,EAAElB,yBAAyB,CAAC;EAE7B,IAAAmB,gBAAS,EAAC,MAAM;IACd,MAAMC,OAAO,GAAGX,QAAQ,CAACE,YAAY,CAAC;IAEtC,OAAO,MAAM;MACXS,OAAO,CAAC,CAAC;IACX,CAAC;EACH,CAAC,EAAE,EAAE,CAAC;EAEN,OAAO;IAAEjB,MAAM;IAAEE,MAAM;IAAEG;EAAK,CAAC;AACjC,CAAC;AAAC,IAAAa,QAAA,GAAAC,OAAA,CAAAC,OAAA,GAEatB,cAAc","ignoreList":[]}
1
+ {"version":3,"names":["_react","require","_reactNativeReanimated","_internal","NATIVE_SCROLL_EVENT_NAMES","useScrollState","ref","offset","useSharedValue","layout","width","height","size","register","useEventHandlerRegistration","eventHandler","useEvent","event","value","contentOffset","y","layoutMeasurement","contentSize","useEffect","cleanup","onLayout","useCallback","e","nativeEvent","onContentSizeChange","w","h","_default","exports","default"],"sources":["useScrollState.ts"],"sourcesContent":["import { useCallback, useEffect } from \"react\";\nimport { useEvent, useSharedValue } from \"react-native-reanimated\";\n\nimport { useEventHandlerRegistration } from \"../../internal\";\n\nimport type { LayoutChangeEvent } from \"react-native\";\nimport type { AnimatedRef } from \"react-native-reanimated\";\nimport type Reanimated from \"react-native-reanimated\";\n\nconst NATIVE_SCROLL_EVENT_NAMES = [\n \"onScroll\",\n \"onScrollBeginDrag\",\n \"onScrollEndDrag\",\n \"onMomentumScrollBegin\",\n \"onMomentumScrollEnd\",\n];\n\ntype ScrollEvent = {\n contentOffset: {\n x: number;\n y: number;\n };\n layoutMeasurement: {\n width: number;\n height: number;\n };\n contentSize: {\n width: number;\n height: number;\n };\n};\n\nconst useScrollState = (ref: AnimatedRef<Reanimated.ScrollView>) => {\n const offset = useSharedValue(0);\n const layout = useSharedValue({ width: 0, height: 0 });\n const size = useSharedValue({ width: 0, height: 0 });\n\n const register = useEventHandlerRegistration(ref);\n\n const eventHandler = useEvent((event: ScrollEvent) => {\n \"worklet\";\n\n // eslint-disable-next-line react-compiler/react-compiler\n offset.value = event.contentOffset.y;\n layout.value = event.layoutMeasurement;\n size.value = event.contentSize;\n }, NATIVE_SCROLL_EVENT_NAMES);\n\n useEffect(() => {\n const cleanup = register(eventHandler);\n\n return () => {\n cleanup();\n };\n }, []);\n\n // `onContentSizeChange` is synthesized in JS (from the content container's\n // onLayout) and `onLayout` has a different payload shape than scroll events,\n // so neither can be reliably captured via native event registration.\n // Instead we expose callbacks for the consumer to attach as props.\n const onLayout = useCallback(\n (e: LayoutChangeEvent) => {\n layout.value = {\n width: e.nativeEvent.layout.width,\n height: e.nativeEvent.layout.height,\n };\n },\n [layout],\n );\n\n const onContentSizeChange = useCallback(\n (w: number, h: number) => {\n size.value = { width: w, height: h };\n },\n [size],\n );\n\n return { offset, layout, size, onLayout, onContentSizeChange };\n};\n\nexport default useScrollState;\n"],"mappings":";;;;;;AAAA,IAAAA,MAAA,GAAAC,OAAA;AACA,IAAAC,sBAAA,GAAAD,OAAA;AAEA,IAAAE,SAAA,GAAAF,OAAA;AAMA,MAAMG,yBAAyB,GAAG,CAChC,UAAU,EACV,mBAAmB,EACnB,iBAAiB,EACjB,uBAAuB,EACvB,qBAAqB,CACtB;AAiBD,MAAMC,cAAc,GAAIC,GAAuC,IAAK;EAClE,MAAMC,MAAM,GAAG,IAAAC,qCAAc,EAAC,CAAC,CAAC;EAChC,MAAMC,MAAM,GAAG,IAAAD,qCAAc,EAAC;IAAEE,KAAK,EAAE,CAAC;IAAEC,MAAM,EAAE;EAAE,CAAC,CAAC;EACtD,MAAMC,IAAI,GAAG,IAAAJ,qCAAc,EAAC;IAAEE,KAAK,EAAE,CAAC;IAAEC,MAAM,EAAE;EAAE,CAAC,CAAC;EAEpD,MAAME,QAAQ,GAAG,IAAAC,qCAA2B,EAACR,GAAG,CAAC;EAEjD,MAAMS,YAAY,GAAG,IAAAC,+BAAQ,EAAEC,KAAkB,IAAK;IACpD,SAAS;;IAET;IACAV,MAAM,CAACW,KAAK,GAAGD,KAAK,CAACE,aAAa,CAACC,CAAC;IACpCX,MAAM,CAACS,KAAK,GAAGD,KAAK,CAACI,iBAAiB;IACtCT,IAAI,CAACM,KAAK,GAAGD,KAAK,CAACK,WAAW;EAChC,CAAC,EAAElB,yBAAyB,CAAC;EAE7B,IAAAmB,gBAAS,EAAC,MAAM;IACd,MAAMC,OAAO,GAAGX,QAAQ,CAACE,YAAY,CAAC;IAEtC,OAAO,MAAM;MACXS,OAAO,CAAC,CAAC;IACX,CAAC;EACH,CAAC,EAAE,EAAE,CAAC;;EAEN;EACA;EACA;EACA;EACA,MAAMC,QAAQ,GAAG,IAAAC,kBAAW,EACzBC,CAAoB,IAAK;IACxBlB,MAAM,CAACS,KAAK,GAAG;MACbR,KAAK,EAAEiB,CAAC,CAACC,WAAW,CAACnB,MAAM,CAACC,KAAK;MACjCC,MAAM,EAAEgB,CAAC,CAACC,WAAW,CAACnB,MAAM,CAACE;IAC/B,CAAC;EACH,CAAC,EACD,CAACF,MAAM,CACT,CAAC;EAED,MAAMoB,mBAAmB,GAAG,IAAAH,kBAAW,EACrC,CAACI,CAAS,EAAEC,CAAS,KAAK;IACxBnB,IAAI,CAACM,KAAK,GAAG;MAAER,KAAK,EAAEoB,CAAC;MAAEnB,MAAM,EAAEoB;IAAE,CAAC;EACtC,CAAC,EACD,CAACnB,IAAI,CACP,CAAC;EAED,OAAO;IAAEL,MAAM;IAAEE,MAAM;IAAEG,IAAI;IAAEa,QAAQ;IAAEI;EAAoB,CAAC;AAChE,CAAC;AAAC,IAAAG,QAAA,GAAAC,OAAA,CAAAC,OAAA,GAEa7B,cAAc","ignoreList":[]}