react-native-dodge-keyboard 1.0.5 → 1.0.7

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 (3) hide show
  1. package/index.d.ts +1 -1
  2. package/index.js +48 -25
  3. package/package.json +1 -1
package/index.d.ts CHANGED
@@ -11,7 +11,7 @@ export interface LiftUpDodge {
11
11
  /**
12
12
  * A reference to the view that should be lifted.
13
13
  *
14
- * null is returned if the view has been recently removed from the node hierarchy
14
+ * null may be returned if the view has been recently removed from the node hierarchy
15
15
  */
16
16
  viewRef: ScrollView | View | null;
17
17
  }
package/index.js CHANGED
@@ -1,7 +1,7 @@
1
- import { Children, cloneElement, createElement, forwardRef, isValidElement, memo, useEffect, useMemo, useRef, useState } from "react";
1
+ import { Children, cloneElement, createElement, forwardRef, isValidElement, memo, useEffect, useMemo, useRef, useState, useImperativeHandle } from "react";
2
2
  import { Animated, Dimensions, findNodeHandle, Keyboard, Platform, StyleSheet, UIManager, useAnimatedValue } from "react-native";
3
3
 
4
- export default function ({ children, offset = 10, disabled, onHandleDodging, disableTagCheck, checkIfElementIsFocused }) {
4
+ const DodgeKeyboard = forwardRef(({ children, offset = 10, disabled, onHandleDodging, disableTagCheck, checkIfElementIsFocused }, ref) => {
5
5
  if (checkIfElementIsFocused !== undefined) {
6
6
  if (typeof checkIfElementIsFocused !== 'function')
7
7
  throw 'checkIfElementIsFocused should be a function';
@@ -25,21 +25,21 @@ export default function ({ children, offset = 10, disabled, onHandleDodging, dis
25
25
  */
26
26
  const viewRefsMap = useRef({});
27
27
  const doDodgeKeyboard = useRef();
28
- const previousLift = useRef();
28
+ const previousLift = useRef({ scrollId: undefined, lift: undefined });
29
29
  const wasVisible = useRef();
30
30
  const pendingIdleTask = useRef();
31
31
  const resizerTimer = useRef();
32
32
  const lastKeyboardEvent = useRef();
33
33
 
34
34
  const clearPreviousDodge = (scrollId) => {
35
- if (previousLift.current && previousLift.current !== scrollId) {
36
- const viewRef = viewRefsMap.current[previousLift.current]?.scrollRef;
35
+ if (previousLift.current.scrollId && previousLift.current.scrollId !== scrollId) {
36
+ const viewRef = viewRefsMap.current[previousLift.current.scrollId]?.scrollRef;
37
37
  onHandleDodging?.({
38
38
  liftUp: 0,
39
39
  viewRef: viewRef || null,
40
40
  keyboardEvent: lastKeyboardEvent.current
41
41
  });
42
- previousLift.current = undefined;
42
+ previousLift.current = { scrollId: undefined, lift: undefined };
43
43
  }
44
44
  }
45
45
 
@@ -107,16 +107,17 @@ export default function ({ children, offset = 10, disabled, onHandleDodging, dis
107
107
  if (scrollRef) {
108
108
  if (__is_standalone) {
109
109
  if (checkFocused(scrollRef, allInputList)) {
110
- UIManager.measure(findNodeHandle(scrollRef), (_x, _y, w, h, x, y) => {
111
- const { dodge_keyboard_offset } = _standalone_props || {};
110
+ UIManager.measure(findNodeHandle(scrollRef), (x, y, width, height, pageX, pageY) => {
111
+ const { dodge_keyboard_offset, dodge_keyboard_clipping } = _standalone_props || {};
112
112
  const thisOffset = isNumber(dodge_keyboard_offset) ? dodge_keyboard_offset : offset;
113
113
 
114
- const liftUp = Math.max(0, (y - keyboardInfo.screenY) + Math.min(h + thisOffset, keyboardInfo.screenY));
114
+ const liftUp = (pageY - keyboardInfo.screenY) + Math.min(height + thisOffset, keyboardInfo.screenY);
115
115
  clearPreviousDodge(scrollId);
116
- if (liftUp) {
117
- previousLift.current = scrollId;
116
+ if (liftUp > 0 || (dodge_keyboard_clipping && liftUp && previousLift.current.lift !== liftUp)) {
117
+ previousLift.current = { scrollId, lift: liftUp };
118
118
  onHandleDodging?.({
119
119
  liftUp,
120
+ layout: { x, y, width, height, pageX, pageY },
120
121
  viewRef: scrollRef,
121
122
  keyboardEvent: lastKeyboardEvent.current
122
123
  });
@@ -130,23 +131,27 @@ export default function ({ children, offset = 10, disabled, onHandleDodging, dis
130
131
  if (checkFocused(inputObj, allInputList)) {
131
132
  Promise.all([
132
133
  new Promise(resolve => {
133
- UIManager.measure(findNodeHandle(scrollRef), (x, y, w, h, px, py) => {
134
- resolve({ h, py });
134
+ UIManager.measure(findNodeHandle(scrollRef), (x, y, width, height, pageX, pageY) => {
135
+ resolve({
136
+ h: height,
137
+ py: pageY,
138
+ scrollLayout: { x, y, width, height, pageX, pageY }
139
+ });
135
140
  });
136
141
  }),
137
142
  new Promise(resolve => {
138
- inputObj.measure((x, y, w, h, px, py) => { // y is dynamic
139
- resolve({ py });
143
+ inputObj.measure((x, y, width, height, pageX, pageY) => { // y is dynamic
144
+ resolve({ py: pageY, layout: { x, y, width, height, pageX, pageY } });
140
145
  });
141
146
  }),
142
147
  new Promise((resolve, reject) => {
143
- inputObj.measureLayout(scrollRef, (l, t, w, h) => { // t is fixed
144
- resolve({ t, h })
148
+ inputObj.measureLayout(scrollRef, (l, t, width, height) => { // t is fixed
149
+ resolve({ t, h: height, relativeLayout: { left: l, top: t, width, height } });
145
150
  }, reject);
146
151
  })
147
- ]).then(([{ h: sh, py: sy }, { py: y }, { t, h }]) => {
152
+ ]).then(([{ h: sh, py: sy, scrollLayout }, { py: y, layout }, { t, h, relativeLayout }]) => {
148
153
 
149
- const { dodge_keyboard_offset } = props || {};
154
+ const { dodge_keyboard_offset, dodge_keyboard_clipping } = props || {};
150
155
  const thisOffset = isNumber(dodge_keyboard_offset) ? dodge_keyboard_offset : offset;
151
156
 
152
157
  const scrollInputY = y - sy;
@@ -159,10 +164,13 @@ export default function ({ children, offset = 10, disabled, onHandleDodging, dis
159
164
  // for lifting up the scroll-view
160
165
  const liftUp = Math.max(0, requiredScrollY - t);
161
166
  clearPreviousDodge(scrollId);
162
- if (liftUp) {
163
- previousLift.current = scrollId;
167
+ if (liftUp > 0 || (dodge_keyboard_clipping && liftUp && previousLift.current.lift !== liftUp)) {
168
+ previousLift.current = { scrollId, lift: liftUp };
164
169
  onHandleDodging?.({
165
170
  liftUp,
171
+ layout,
172
+ scrollLayout,
173
+ relativeLayout,
166
174
  viewRef: scrollRef,
167
175
  keyboardEvent: lastKeyboardEvent.current
168
176
  });
@@ -216,7 +224,14 @@ export default function ({ children, offset = 10, disabled, onHandleDodging, dis
216
224
  useEffect(() => {
217
225
  if (currentPaddedScroller) {
218
226
  const ref = viewRefsMap.current[paddedId]?.scrollRef;
219
- tryPerformScroll(ref, paddedScroll, false);
227
+ if (Platform.OS === 'android') {
228
+ tryPerformScroll(ref, paddedScroll, false);
229
+ } else {
230
+ // this seem to be removing `the flash bang` on IOS
231
+ setTimeout(() => {
232
+ tryPerformScroll(ref, paddedScroll, false);
233
+ }, 1);
234
+ }
220
235
  }
221
236
  }, [currentPaddedScroller]);
222
237
 
@@ -224,6 +239,10 @@ export default function ({ children, offset = 10, disabled, onHandleDodging, dis
224
239
  doDodgeKeyboard.current();
225
240
  }, [offset, !disabled]);
226
241
 
242
+ useImperativeHandle(ref, () => ({
243
+ trigger: () => doDodgeKeyboard.current()
244
+ }), []);
245
+
227
246
  useEffect(() => {
228
247
  if (disabled) return;
229
248
  const frameListener = Keyboard.addListener('keyboardDidChangeFrame', e => doDodgeKeyboard.current(e));
@@ -272,7 +291,8 @@ export default function ({ children, offset = 10, disabled, onHandleDodging, dis
272
291
  viewRefsMap.current[scrollId].__is_standalone = true;
273
292
  viewRefsMap.current[scrollId]._standalone_props = {
274
293
  dodge_keyboard_offset: node.props?.dodge_keyboard_offset,
275
- dodge_keyboard_lift: node.props?.dodge_keyboard_lift
294
+ dodge_keyboard_lift: node.props?.dodge_keyboard_lift,
295
+ dodge_keyboard_clipping: node.props?.dodge_keyboard_clipping
276
296
  };
277
297
  }
278
298
  }
@@ -302,7 +322,8 @@ export default function ({ children, offset = 10, disabled, onHandleDodging, dis
302
322
  viewRefsMap.current[scrollId].inputRef[inputId] = {};
303
323
  viewRefsMap.current[scrollId].inputRef[inputId].props = {
304
324
  dodge_keyboard_offset: inputNode.props?.dodge_keyboard_offset,
305
- dodge_keyboard_lift: inputNode.props?.dodge_keyboard_lift
325
+ dodge_keyboard_lift: inputNode.props?.dodge_keyboard_lift,
326
+ dodge_keyboard_clipping: inputNode.props?.dodge_keyboard_clipping
306
327
  };
307
328
  }
308
329
 
@@ -414,7 +435,9 @@ export default function ({ children, offset = 10, disabled, onHandleDodging, dis
414
435
  {children}
415
436
  </ReactHijacker>
416
437
  );
417
- };
438
+ });
439
+
440
+ export default DodgeKeyboard;
418
441
 
419
442
  const niceFunction = (func, message) => {
420
443
  return (...args) => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-native-dodge-keyboard",
3
- "version": "1.0.5",
3
+ "version": "1.0.7",
4
4
  "description": "react-native-dodge-keyboard is a tiny library designed to flawlessly move your UI out of the way of the keyboard",
5
5
  "keywords": [
6
6
  "react-native",