Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add KeyboardAvoidingView #5038

Closed
wants to merge 31 commits into from
Closed
Show file tree
Hide file tree
Changes from 5 commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
e2f65ef
First commit
Sep 4, 2023
c0a10e6
Improve height behavior
Sep 5, 2023
b4c43d4
Fix example
Sep 5, 2023
4719d64
Fix warning
Sep 5, 2023
0e08d27
Merge branch 'main' into keyboard-avoiding-view
Latropos Sep 20, 2023
769d0f5
Merge branch 'main' into keyboard-avoiding-view
Oct 31, 2023
833bcbb
Merge branch 'main' into keyboard-avoiding-view
Oct 31, 2023
70b16c1
Add scopes
Oct 31, 2023
7d5a39f
Merge branch 'main' into keyboard-avoiding-view
Nov 2, 2023
76e7417
Apply suggestions from code review
Latropos Nov 2, 2023
339a10c
Minor post-review changes
szydlovsky Nov 2, 2023
8cc3f6f
Fix the logic behind calculating padding/position/height changes
szydlovsky Nov 3, 2023
d3fbff8
Upgrade the example
szydlovsky Nov 3, 2023
cc29fe0
Change the way useHeaderHeight is imported
szydlovsky Nov 6, 2023
bd17f6f
Fix Next
bartlomiejbloniarz Nov 6, 2023
d753e20
Initial code review changes
szydlovsky Nov 8, 2023
814ab46
Revert component name change
szydlovsky Nov 8, 2023
2086722
Further calculations' fixes
szydlovsky Nov 10, 2023
d82eb75
Merge remote-tracking branch 'origin/HEAD' into keyboard-avoiding-view
szydlovsky Nov 10, 2023
f6b6fb3
'runOnUI' code review fix
szydlovsky Nov 14, 2023
4b84d42
Linter fix
szydlovsky Nov 14, 2023
29f5254
Add docs for KeyboardAvoidingView
szydlovsky Nov 14, 2023
bb472c0
Merge branch 'main' into keyboard-avoiding-view
szydlovsky Nov 14, 2023
3c8aa10
Prettier
Nov 16, 2023
679c8af
Fix code highlighting in doca
Nov 16, 2023
f92f391
Merge branch 'main' into keyboard-avoiding-view
Nov 22, 2023
8ec6277
Add type tests for AnimatedRef and fix Animated Components regression…
tjzel Nov 20, 2023
975de37
Merge to main
Dec 18, 2023
79fac63
Update dependecies
Dec 18, 2023
9e046b3
Merge branch 'main' into keyboard-avoiding-view
Feb 8, 2024
2bf8ef8
Fix typescript-eslint/no-shadow
Feb 8, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions Example/ios/Podfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -382,7 +382,7 @@ PODS:
- React-Core
- react-native-pager-view (5.4.25):
- React-Core
- react-native-safe-area-context (4.7.2):
- react-native-safe-area-context (4.7.4):
- React-Core
- react-native-slider (4.4.3):
- React-Core
Expand Down Expand Up @@ -775,7 +775,7 @@ SPEC CHECKSUMS:
React-logger: cebf22b6cf43434e471dc561e5911b40ac01d289
react-native-box2d: a5126c70227755b79a1b5b8d867e3932041631b3
react-native-pager-view: da490aa1f902c9a5aeecf0909cc975ad0e92e53e
react-native-safe-area-context: 7aa8e6d9d0f3100a820efb1a98af68aa747f9284
react-native-safe-area-context: 2cd91d532de12acdb0a9cbc8d43ac72a8e4c897c
react-native-slider: 1cdd6ba29675df21f30544253bf7351d3c2d68c4
React-NativeModulesApple: 02e35e9a51e10c6422f04f5e4076a7c02243fff2
React-perflogger: e3596db7e753f51766bceadc061936ef1472edc3
Expand All @@ -798,7 +798,7 @@ SPEC CHECKSUMS:
RNCMaskedView: f7c74478c83c4fdfc5cf4df51f80c0dd5cf125c6
RNCPicker: 529d564911e93598cc399b56cc0769ce3675f8c8
RNGestureHandler: bb86e378287f7713baf3ca205423eb8109790022
RNReanimated: 7032c33fc6caf259b4872375342b72183c688fc3
szydlovsky marked this conversation as resolved.
Show resolved Hide resolved
RNReanimated: 31c2181e76a33a8f04ae0420b00540c3e27861b7
RNScreens: 85d3880b52d34db7b8eeebe2f1a0e807c05e69fa
RNSVG: d00c8f91c3cbf6d476451313a18f04d220d4f396
SocketRocket: f32cd54efbe0f095c4d7594881e52619cfe80b17
Expand All @@ -807,4 +807,4 @@ SPEC CHECKSUMS:

PODFILE CHECKSUM: f37cea0ea1b6dc523fb88a9c2bdb9993f4b567ce

COCOAPODS: 1.14.0
COCOAPODS: 1.14.2
2 changes: 1 addition & 1 deletion Example/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
"react-native-gesture-handler": "^2.13.2",
"react-native-pager-view": "^5.4.25",
"react-native-reanimated": "link:../",
"react-native-safe-area-context": "^4.7.2",
"react-native-safe-area-context": "4.7.4",
szydlovsky marked this conversation as resolved.
Show resolved Hide resolved
"react-native-screens": "^3.25.0",
"react-native-svg": "^13.14.0"
},
Expand Down
8 changes: 4 additions & 4 deletions Example/yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -5983,10 +5983,10 @@ react-native-pager-view@^5.4.25:
version "0.0.0"
uid ""

react-native-safe-area-context@^4.7.2:
version "4.7.2"
resolved "https://registry.yarnpkg.com/react-native-safe-area-context/-/react-native-safe-area-context-4.7.2.tgz#1673aa99b6a9235e7faaf5a248e69795d6e54e07"
integrity sha512-5fy/hRNJ7bI/U2SliOeKf0D80J4lXPc1NsRiNS7Xaz8YTnqlzWib1ViItkwKPfufe54YKzVBMmM32RpdzvO2gg==
react-native-safe-area-context@4.7.4:
version "4.7.4"
resolved "https://registry.yarnpkg.com/react-native-safe-area-context/-/react-native-safe-area-context-4.7.4.tgz#3dd8438971e70043d76f2428ede75b8a9639265e"
integrity sha512-3LR3DCq9pdzlbq6vsHGWBFehXAKDh2Ljug6jWhLWs1QFuJHM6AS2+mH2JfKlB2LqiSFZOBcZfHQFz0sGaA3uqg==

react-native-screens@^3.25.0:
version "3.25.0"
Expand Down
13 changes: 7 additions & 6 deletions NextExample/next.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ const withBundleAnalyzer = require('@next/bundle-analyzer')({
enabled: process.env.ANALYZE_BUNDLE === '1',
});

const path = require('path');

// this can be used to obtain a more readable bundle for debugging
const disableMinification = process.env.DISABLE_MINIFICATION === '1';

Expand All @@ -21,12 +23,11 @@ module.exports = withPlugins([withBundleAnalyzer, withExpo], {
if (disableMinification) {
config.optimization.minimizer = [];
}
config.resolve.alias.react = require('path').resolve(
__dirname,
'.',
'node_modules',
'react'
);
config.resolve.alias = {
...(config.resolve.alias || {}),
react: path.resolve(__dirname, '.', 'node_modules', 'react'),
'react-dom': path.resolve(__dirname, '.', 'node_modules', 'react-dom'),
};
return config;
},
});
1 change: 0 additions & 1 deletion app/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@
"react-native-gesture-handler": "^2.13.2",
"react-native-pager-view": "^5.4.25",
"react-native-reanimated": "link:../",
Latropos marked this conversation as resolved.
Show resolved Hide resolved
"react-native-safe-area-context": "^4.7.2",
"react-native-screens": "^3.25.0",
"react-native-svg": "^13.14.0",
"react-native-web": "~0.18.12"
Expand Down
14 changes: 12 additions & 2 deletions app/src/examples/KeyboardAvoidingView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ function ListItem({
}

export default function KeyboardAvoidingViewExample(): React.ReactElement {
const [useReanimated, setUseReanimated] = useState(true);
const [useReanimated, setUseReanimated] = useState(false);

const [behavior, setBehavior] = useState<
'position' | 'height' | 'padding' | undefined
Expand Down Expand Up @@ -113,7 +113,7 @@ export default function KeyboardAvoidingViewExample(): React.ReactElement {
<KeyboardAvoidingView
behavior={behavior}
style={styles.flexOne}
keyboardVerticalOffset={48 + 10}
keyboardVerticalOffset={80}
szydlovsky marked this conversation as resolved.
Show resolved Hide resolved
contentContainerStyle={styles.flexOne}>
<Animated.FlatList
inverted
Expand All @@ -132,6 +132,10 @@ export default function KeyboardAvoidingViewExample(): React.ReactElement {
/>
</View>
</KeyboardAvoidingView>

<View style={styles.additionalView}>
<Text>A view below KeyboardAvoidingView</Text>
</View>
</View>
);
}
Expand All @@ -150,6 +154,12 @@ const styles = StyleSheet.create({
paddingHorizontal: 20,
backgroundColor: OVERLAY_COLOR,
},
additionalView: {
height: 100,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: OVERLAY_COLOR,
},
itemContainer: {
flexDirection: 'row',
marginHorizontal: 8,
Expand Down
5 changes: 0 additions & 5 deletions app/yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -1559,11 +1559,6 @@ react-native-pager-view@^5.4.25:
version "0.0.0"
uid ""

react-native-safe-area-context@^4.7.2:
version "4.7.2"
resolved "https://registry.yarnpkg.com/react-native-safe-area-context/-/react-native-safe-area-context-4.7.2.tgz#1673aa99b6a9235e7faaf5a248e69795d6e54e07"
integrity sha512-5fy/hRNJ7bI/U2SliOeKf0D80J4lXPc1NsRiNS7Xaz8YTnqlzWib1ViItkwKPfufe54YKzVBMmM32RpdzvO2gg==

react-native-screens@^3.25.0:
version "3.25.0"
resolved "https://registry.yarnpkg.com/react-native-screens/-/react-native-screens-3.25.0.tgz#cf45e271ce733c9cf782fef8c9b3eb9e53faf01d"
Expand Down
4 changes: 4 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,8 @@
"@babel/preset-env": "^7.20.0",
"@babel/types": "^7.20.0",
"@react-native/eslint-config": "^0.72.2",
"@react-navigation/elements": "^1.3.21",
"@react-navigation/native": "^6.1.9",
"@testing-library/jest-native": "^4.0.4",
"@testing-library/react-hooks": "^8.0.0",
"@testing-library/react-native": "^7.1.0",
Expand Down Expand Up @@ -157,6 +159,8 @@
"react-native": "0.72.6",
"react-native-builder-bob": "^0.18.3",
"react-native-gesture-handler": "^2.13.2",
"react-native-safe-area-context": "^4.7.4",
"react-native-screens": "^3.27.0",
"react-native-web": "~0.18.12",
"react-test-renderer": "17.0.2",
"shelljs": "^0.8.5",
Expand Down
49 changes: 30 additions & 19 deletions src/reanimated2/component/KeyboardAvoidingView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,18 @@ import { AnimatedView as ReanimatedView } from './View';
import {
useAnimatedKeyboard,
useAnimatedStyle,
useWorkletCallback,
runOnUI,
useSharedValue,
} from '../';

let useHeaderHeight: () => number;
try {
// eslint-disable-next-line @typescript-eslint/no-var-requires
useHeaderHeight = require('@react-navigation/elements').useHeaderHeight;
} catch (e) {
useHeaderHeight = () => 0;
szydlovsky marked this conversation as resolved.
Show resolved Hide resolved
}

type Props = ViewProps & KeyboardAvoidingViewProps;
szydlovsky marked this conversation as resolved.
Show resolved Hide resolved

/**
Expand All @@ -36,22 +43,18 @@ const KeyboardAvoidingView = forwardRef<View, React.PropsWithChildren<Props>>(
ref
) => {
const initialFrame = useSharedValue<LayoutRectangle | null>(null);
szydlovsky marked this conversation as resolved.
Show resolved Hide resolved

const currentFrame = useSharedValue<LayoutRectangle | null>(null);

const keyboard = useAnimatedKeyboard();
const { height: screenHeight } = useWindowDimensions();
szydlovsky marked this conversation as resolved.
Show resolved Hide resolved
const headerHeight = useHeaderHeight();

const onLayoutWorklet = useCallback(
(layout: LayoutRectangle) => {
'worklet';
if (initialFrame.value == null) {
initialFrame.value = layout;
}

currentFrame.value = layout;
},
[currentFrame, initialFrame]
[initialFrame]
);

const handleOnLayout = useCallback<NonNullable<ViewProps['onLayout']>>(
Expand All @@ -62,34 +65,42 @@ const KeyboardAvoidingView = forwardRef<View, React.PropsWithChildren<Props>>(
onLayout(event);
}
},
[onLayout]
[onLayout, onLayoutWorklet]
);

const getBackwardCompatibleBottomHeight = useCallback(
(keyboardHeight: number) => {
'worklet';
if (currentFrame.value == null || initialFrame.value == null) {
if (initialFrame.value == null) {
return 0;
}

const keyboardY =
screenHeight - keyboardHeight - keyboardVerticalOffset;
/*
We calculate how much of the view to move by taking sum of keyboard's and view's heights
(keyboardHeight + initialFrame.value.height) and substracting how much space they both should actually
occupy (screenHeight - headerHeight - keyboardVerticalOffset). If the result is less than 0 - it means
that keyboard doesn't cover the view and we don't need to tinker with it.
*/
const amountToMove = Math.max(
szydlovsky marked this conversation as resolved.
Show resolved Hide resolved
keyboardHeight +
initialFrame.value.height -
(screenHeight - headerHeight - keyboardVerticalOffset),
0
);

if (behavior === 'height') {
return Math.max(initialFrame.value.height - keyboardHeight, 0);
// in case of changing height, it is just the view height without the amount to move
return Math.max(initialFrame.value.height - amountToMove);
}

return Math.max(
currentFrame.value.y + currentFrame.value.height - keyboardY,
0
);
return Math.max(amountToMove);
szydlovsky marked this conversation as resolved.
Show resolved Hide resolved
},
[
behavior,
currentFrame,
initialFrame,
keyboardVerticalOffset,
behavior,
screenHeight,
headerHeight,
keyboardVerticalOffset,
]
);

Expand Down
Loading