react-native-dodge-keyboard 1.0.7 → 1.0.8
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/README.md +42 -6
- package/index.d.ts +1 -1
- package/index.js +7 -9
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -5,10 +5,11 @@
|
|
|
5
5
|
react-native-dodge-keyboard is a tiny, zero-dependency library designed to flawlessly move your UI out of the way of the keyboard.
|
|
6
6
|
It is built to solve a long-standing React Native pain point: TextInputs inside ScrollViews, FlatLists, and custom scrollable layouts not being properly lifted when focused.
|
|
7
7
|
|
|
8
|
-
Unlike KeyboardAvoidingView and older third-party libraries, react-native-dodge-keyboard:
|
|
8
|
+
Unlike `KeyboardAvoidingView` and older third-party libraries, react-native-dodge-keyboard:
|
|
9
9
|
|
|
10
|
-
- Works with any scrollable container
|
|
10
|
+
- Works with any scrollable container (ScrollView, FlatList, SectionList, ...more)
|
|
11
11
|
- Supports dynamic layout sizes
|
|
12
|
+
- Handles elements that are not inside a scrollable view.
|
|
12
13
|
- Handles scrollviews placed anywhere (nested, offset, inside modals, bottom sheets, etc.)
|
|
13
14
|
- Works on both iOS and Android
|
|
14
15
|
- Requires zero configuration
|
|
@@ -27,6 +28,13 @@ or using yarn
|
|
|
27
28
|
yarn add react-native-dodge-keyboard
|
|
28
29
|
```
|
|
29
30
|
|
|
31
|
+
## Demo
|
|
32
|
+
|
|
33
|
+
<p>
|
|
34
|
+
<img src="https://github.com/deflexable/react-native-dodge-keyboard/blob/main/screenshots/main.gif" width="260">
|
|
35
|
+
<img src="https://github.com/deflexable/react-native-dodge-keyboard/blob/main/screenshots/android_main.gif" width="260">
|
|
36
|
+
</p>
|
|
37
|
+
|
|
30
38
|
## Usage
|
|
31
39
|
|
|
32
40
|
Wrap your screen (or only the part you want to dodge) with the DodgeKeyboard component.
|
|
@@ -34,18 +42,46 @@ Wrap your screen (or only the part you want to dodge) with the DodgeKeyboard com
|
|
|
34
42
|
### Basic Example
|
|
35
43
|
|
|
36
44
|
```js
|
|
37
|
-
import DodgeKeyboard from 'react-native-dodge-keyboard';
|
|
45
|
+
import { DodgeKeyboard } from 'react-native-dodge-keyboard';
|
|
38
46
|
import { ScrollView, TextInput } from 'react-native';
|
|
39
47
|
|
|
40
|
-
export default function
|
|
48
|
+
export default function TestScreen() {
|
|
41
49
|
|
|
42
50
|
return (
|
|
43
51
|
<DodgeKeyboard>
|
|
44
|
-
<ScrollView
|
|
52
|
+
<ScrollView style={{ flex: 1 }}>
|
|
45
53
|
<TextInput placeholder="Name" style={styles.input} />
|
|
46
54
|
<TextInput multiline placeholder="Message" style={styles.multiline} />
|
|
47
55
|
</ScrollView>
|
|
48
56
|
</DodgeKeyboard>
|
|
49
57
|
);
|
|
50
58
|
}
|
|
51
|
-
```
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
## Known Issues
|
|
62
|
+
|
|
63
|
+
### Android Soft Input
|
|
64
|
+
Some Android devices handle keyboard dodging natively, which can lead to unexpected behavior when used with this library. To disable the native behavior and avoid issues, set `android:windowSoftInputMode="adjustNothing"` in your AndroidManifest.xml.
|
|
65
|
+
|
|
66
|
+
## Advance Use Cases
|
|
67
|
+
|
|
68
|
+
### Dodging custom views
|
|
69
|
+
Out of the box, `TextInput` is the only component that supports keyboard dodging. To enable this behavior for other components, pass `dodge_keyboard_input={true}` as a prop.
|
|
70
|
+
|
|
71
|
+
You can also listen to `checkIfElementIsFocused` prop and return whether the element passed as an argument is currently focused and needs to dodge the keyboard.
|
|
72
|
+
|
|
73
|
+
Kindly check [examples/CustomFocusDodge.jsx](https://github.com/deflexable/react-native-dodge-keyboard/blob/main/examples/CustomFocusDodge.jsx) for example on this approach.
|
|
74
|
+
|
|
75
|
+
A demo of the example is attach below:
|
|
76
|
+
|
|
77
|
+
<img src="https://github.com/deflexable/react-native-dodge-keyboard/blob/main/screenshots/custom.gif" width="260">
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
### Dodging static element
|
|
81
|
+
To dodge `TextInput` or component with prop `dodge_keyboard_input={true}` that are not inside a scrollable view, you need to listen to `onHandleDodging` to manually lift up the component yourself.
|
|
82
|
+
|
|
83
|
+
Kindly check [examples/ManualLifting.jsx](https://github.com/deflexable/react-native-dodge-keyboard/blob/main/examples/ManualLifting.jsx) for example on this approach.
|
|
84
|
+
|
|
85
|
+
A demo of the example is attach below:
|
|
86
|
+
|
|
87
|
+
<img src="https://github.com/deflexable/react-native-dodge-keyboard/blob/main/screenshots/static.gif" width="260">
|
package/index.d.ts
CHANGED
package/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
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
|
-
const DodgeKeyboard = forwardRef(({ children, offset = 10, disabled, onHandleDodging, disableTagCheck, checkIfElementIsFocused }, ref) => {
|
|
4
|
+
export 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';
|
|
@@ -140,14 +140,14 @@ const DodgeKeyboard = forwardRef(({ children, offset = 10, disabled, onHandleDod
|
|
|
140
140
|
});
|
|
141
141
|
}),
|
|
142
142
|
new Promise(resolve => {
|
|
143
|
-
|
|
143
|
+
UIManager.measure(findNodeHandle(inputObj), (x, y, width, height, pageX, pageY) => { // y is dynamic
|
|
144
144
|
resolve({ py: pageY, layout: { x, y, width, height, pageX, pageY } });
|
|
145
145
|
});
|
|
146
146
|
}),
|
|
147
147
|
new Promise((resolve, reject) => {
|
|
148
|
-
|
|
148
|
+
UIManager.measureLayout(findNodeHandle(inputObj), findNodeHandle(scrollRef), reject, (l, t, width, height) => { // t is fixed
|
|
149
149
|
resolve({ t, h: height, relativeLayout: { left: l, top: t, width, height } });
|
|
150
|
-
}
|
|
150
|
+
});
|
|
151
151
|
})
|
|
152
152
|
]).then(([{ h: sh, py: sy, scrollLayout }, { py: y, layout }, { t, h, relativeLayout }]) => {
|
|
153
153
|
|
|
@@ -198,7 +198,7 @@ const DodgeKeyboard = forwardRef(({ children, offset = 10, disabled, onHandleDod
|
|
|
198
198
|
}
|
|
199
199
|
}
|
|
200
200
|
}
|
|
201
|
-
} else {
|
|
201
|
+
} else if (!visible) {
|
|
202
202
|
setCurrentPaddedScroller();
|
|
203
203
|
clearPreviousDodge();
|
|
204
204
|
}
|
|
@@ -333,7 +333,7 @@ const DodgeKeyboard = forwardRef(({ children, offset = 10, disabled, onHandleDod
|
|
|
333
333
|
...inputNode.props,
|
|
334
334
|
__dodging_keyboard: true,
|
|
335
335
|
onFocus: (...args) => {
|
|
336
|
-
doDodgeKeyboard.current();
|
|
336
|
+
doDodgeKeyboard.current(lastKeyboardEvent.current);
|
|
337
337
|
return inputNode.props?.onFocus?.(...args);
|
|
338
338
|
},
|
|
339
339
|
onLayout: (...args) => {
|
|
@@ -392,7 +392,7 @@ const DodgeKeyboard = forwardRef(({ children, offset = 10, disabled, onHandleDod
|
|
|
392
392
|
},
|
|
393
393
|
...isStandalone ? {
|
|
394
394
|
onFocus: (...args) => {
|
|
395
|
-
doDodgeKeyboard.current();
|
|
395
|
+
doDodgeKeyboard.current(lastKeyboardEvent.current);
|
|
396
396
|
return node.props?.onFocus?.(...args);
|
|
397
397
|
}
|
|
398
398
|
} : {},
|
|
@@ -437,8 +437,6 @@ const DodgeKeyboard = forwardRef(({ children, offset = 10, disabled, onHandleDod
|
|
|
437
437
|
);
|
|
438
438
|
});
|
|
439
439
|
|
|
440
|
-
export default DodgeKeyboard;
|
|
441
|
-
|
|
442
440
|
const niceFunction = (func, message) => {
|
|
443
441
|
return (...args) => {
|
|
444
442
|
try {
|
package/package.json
CHANGED