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

Wrapping my App with <KeyboardProvider> adds space on top and bottom of the screen. #587

Closed
e-biba-ofti opened this issue Sep 18, 2024 · 37 comments · Fixed by #744
Closed
Assignees
Labels
🤖 android Android specific 🐛 bug Something isn't working

Comments

@e-biba-ofti
Copy link

Describe the bug
When wrapping my app with KeyboardProvider it adds space looks like it tries to do the same <SafeAreaView> does but I am already using <SafeAreaView> partially in my app as in some screens is not needed. If I just disable it <KeyboardProvider enabled={false}> then the app shows in full view.

Expected behavior
The app should show in full screen

Screenshots
image

Smartphone (please complete the following information):

  • Desktop OS: [e.g. Windows 10, MacOS 10.15.5]
  • Device: Android
  • OS: Android
  • RN version: 0.73.2
  • RN architecture: [e.g. old/new or paper/fabric]
  • JS engine: [e.g. JSC, Hermes, v8]
  • Library version: 1.13.3
@kirillzyusko
Copy link
Owner

@e-biba-ofti have you tried to specify statusBarTranslucent and navigationBarTranslucent props on KeyboardProvider level?

@kirillzyusko kirillzyusko added question You wanted to clarify something about the usage of the library or have a question about something 🤖 android Android specific labels Sep 18, 2024
@edisoni1995
Copy link

@kirillzyusko navigationBarTransparent seems to work fine but the statusBarTranslucent doesn't work. After checking it a bit more when I remove my status bar it works as expected or when I set my status bar as translucent it's working. But I don't want my status bar to be translucent as the content will be drawn under it.

@kirillzyusko
Copy link
Owner

@edisoni1995 when you wrap app in KeyboardProvider it will move to edge-to-edge mode and app will be drawn under status bar. Since edge-to-edge is not a default mode for RN app the KeyboardProvider will try to match default RN behavior and add paddings.

On your screenshot these white paddings most likely are caused by this fact (i. e. it's paddings from KeyboardProvider and for me it looks like you already handle safe-area paddings somewhere in your code). To remove these padding you will need to add navigationBarTranslucent and statusBarTranslucent props.

statusBarTranslucent doesn't work in your case because you are using StatusBar component and translucent is false by default, so you overwrite an initial config of KeyboardProvider and you are adding white padding again.

I think in your case it'll be safe to add translucent property to StatusBar - in this case it shouldn't draw anything under StatusBar because react-native-keyboard-controller uses its own implementation (this implementation is compatible with edge-to-edge mode, unlike RN component) of StatusBar and it becomes to be used automatically when you use KeyboardProvider.

Can you share here two screenshots side by side:

  • one how your current app screen looks right now without react-native-keyboard-controller integration;
  • the second one is with KeyboardProvider (with translucent props) and with <StatusBar translucent /> in place?

In my understanding these screenshots should be identical.

@e-biba-ofti
Copy link
Author

Here you have it, I made a red border just to be able to tell that some part of the content is going under the status bar.
The image on the right is the one with <StatusBar translucent /> and with translucent props for KeyboardProvider.

image image

@kirillzyusko
Copy link
Owner

@e-biba-ofti would you be able to provide a minimal reproduction example?

Something is definetely going wrong here, but without a code I can not say what exactly 😔

Would you be able also to try to comment out this line:

And re-run app again?

@e-biba-ofti
Copy link
Author

@kirillzyusko that would be very difficult to create for now but I will try to find a minimal reproducable example. I did the change in the android file and re-build android but nothing changed.

@kirillzyusko
Copy link
Owner

@e-biba-ofti got you! Then minimal reproduction example is highly appreciate - it can significantly reduce the time needed for fixing this problem! ❤️

@RayKay91
Copy link

The issue will be resolved soon - it's been merged to react-native-screens but is yet unreleased. I posted this in another issue:

#592 (comment)

@kirillzyusko
Copy link
Owner

kirillzyusko commented Sep 24, 2024

@RayKay91 oh, yeah, you are right, good catch! @e-biba-ofti did you use native-stack with navigationBar* options by any chance? If yes, then what is the version of react-native-screens did you use?

@e-biba-ofti
Copy link
Author

Yes I am using navigationBarOptions and [email protected]

@kirillzyusko
Copy link
Owner

Well @e-biba-ofti [email protected] is highly unlikely to break something 🤔

I really can't help here 😔 If you can provide a reproduction example that would be a dope and would significantly reduce time for fixing 🙏

@kirillzyusko kirillzyusko added 🐛 bug Something isn't working and removed question You wanted to clarify something about the usage of the library or have a question about something labels Oct 9, 2024
@rranjan14
Copy link

rranjan14 commented Oct 22, 2024

Screenshot_20241021_125911
I am also facing this issue on android. I am getting a white space at the top of the screen. The space is roughly equal to the height of the statusbar. This is happening with react-native-screens >=3.31.0

@kirillzyusko
Copy link
Owner

@rranjan14 what is the exact version of react-native-screens in package-lock.json or yarn.lock? Can you share a snippet of data from your .lock file?

@rranjan14
Copy link

Screenshot 2024-10-22 at 14 20 36

here you go @kirillzyusko

@kirillzyusko
Copy link
Owner

@rranjan14 okay, you'll need to add a patch like https://github.com/kirillzyusko/react-native-keyboard-controller/blob/main/example/patches/react-native-screens%2B3.34.0.patch or apply changes from this PR: software-mansion/react-native-screens#2301

Both patches are identical. Hopefully new version of react-native-screens will be released and that issue will go away 😅

Alternatively you can downgrade your version to 3.31.0 (without >= modifiers).

@rranjan14
Copy link

@kirillzyusko I have been following this issue for some time now. I have tried this but to no avail sadly 😕

@kirillzyusko
Copy link
Owner

@rranjan14 okay, then, please, create a small reproduction example and I will have a look on it 👀 By the way - did you specify statusBarTranslucent property for KeyboardProvider?

@rranjan14
Copy link

rranjan14 commented Oct 22, 2024

@kirillzyusko I did. And also, I am using SystemBars from react-native-edge-to-edge and not StatusBar from react-native or expo-status-bar. Also, I have created this issue here with react navigation as I am facing this issue only with if I have tab navigator it works well otherwise

@kirillzyusko
Copy link
Owner

I did. And also, I am using SystemBars from react-native-edge-to-edge and not StatusBar from react-native or expo-status-bar

Well, interesting 🤔 Can you provide a minimal reproduction example?

react-native-edge-to-edge is not using deprecated API so it should work fine. If you can provide a minimal reproduction example, then it can definitely speed up the process of fixing the problem 👀

@rranjan14
Copy link

@kirillzyusko unfortunately I do not see this happening in a new project. I suspect this is a configuration issue at my end. I have tried too many things to solve but the outcome is always same. Also, what i observed is, when the value of top inset returned is not 0 from react-native-safe-area-context after first render, the white space is gone. What's happening is, after first render, the values returned from useSafeAreaInsets hook is 0 for all the sides.

@kirillzyusko
Copy link
Owner

@rranjan14 but you can try to simplify your project. In the end you'll end up with a project, where you have 5-6 files and where the issue is reproducible. And then you can share that project (or create a new project and copy all changes from your simplified project to a new project) 👀

@rranjan14
Copy link

@kirillzyusko its a big task. I'd surely try this. Will share the simplified project when I can. Thanks a lot! 🫡

@rotoxl
Copy link

rotoxl commented Nov 8, 2024

In case it helps, I had the same problem and adding statusBarTranslucent and navigationBarTranslucent to the provider fixed it

<KeyboardProvider statusBarTranslucent navigationBarTranslucent>
   {children}
</KeyboardProvider>

@Tobbe
Copy link

Tobbe commented Dec 20, 2024

I also have issues with extra space at the top sometimes. It only happens sometimes.
image

(This is what I want it to look like, and what it usually does look like.)
image

Sometimes I also have the same thing happening but at the bottom of the screen when the keyboard is visible. Like this (notice the yellow bar above the keyboard that hides part of the button)

image

So far uninstalling and then reinstalling the app has been the only way to fix it for me once it starts doing that. Here it works as expected. (No extra yellow bar between the top of the keyboard and what's visible on the screen)
image

Using react-native-screens 4.1.0
image

It happens both with dev build and preview build.
It happens both with and without statusBarTranslucent + navigationBarTranslucent

I understand it's almost impossible to fix without a reproduction app. I'll see what I can do about creating one. But since it only happens sometimes it very difficult 😅

@Tobbe
Copy link

Tobbe commented Dec 20, 2024

Working on a reproduction I see weird things happening both at the top and the bottom of the screen at the same time
image

Here's a link to the code used for the screenshot above
https://github.com/Tobbe/rnkc-keyboard-padding

If I add enabled={false} to <KeyboardController> and reload the app (by pressing r) I see this, which doesn't have the extra padding neither at the top nor the bottom
image


I simplified the code for the reproduction even more. Now it's just two files.

image

// _layout.tsx

import { Stack } from "expo-router";
import { KeyboardProvider } from "react-native-keyboard-controller";

export default function RootLayout() {
  return (
    <KeyboardProvider>
      <Stack />
    </KeyboardProvider>
  );
}
// index.tsx

import React from "react";
import { Text, ScrollView, StyleSheet } from "react-native";

export default function App() {
  return (
    <ScrollView contentContainerStyle={styles.scrollViewContainer}>
      <Text>Foobar</Text>
    </ScrollView>
  );
}

const styles = StyleSheet.create({
  scrollViewContainer: {
    backgroundColor: "lightpink",
    flexGrow: 1,
  },
});

@rranjan14
Copy link

Working on a reproduction I see weird things happening both at the top and the bottom of the screen at the same time image

Here's a link to the code used for the screenshot above https://github.com/Tobbe/rnkc-keyboard-padding

If I add enabled={false} to <KeyboardController> and reload the app (by pressing r) I see this, which doesn't have the extra padding neither at the top nor the bottom image

I simplified the code for the reproduction even more. Now it's just two files.

image

// _layout.tsx

import { Stack } from "expo-router";
import { KeyboardProvider } from "react-native-keyboard-controller";

export default function RootLayout() {
  return (
    <KeyboardProvider>
      <Stack />
    </KeyboardProvider>
  );
}
// index.tsx

import React from "react";
import { Text, ScrollView, StyleSheet } from "react-native";

export default function App() {
  return (
    <ScrollView contentContainerStyle={styles.scrollViewContainer}>
      <Text>Foobar</Text>
    </ScrollView>
  );
}

const styles = StyleSheet.create({
  scrollViewContainer: {
    backgroundColor: "lightpink",
    flexGrow: 1,
  },
});

Can you try adding the react-native-edge-to-edge package and check with enabled prop set as true? It might solve it for you.

@Tobbe
Copy link

Tobbe commented Dec 20, 2024

@rranjan14 Thanks! That seems to have improved things 🙂 Now I just need to start slowly adding things back one by one and see how far I can take it until my app breaks again 😆

image

@kirillzyusko
Copy link
Owner

react-native-screens@4 also might be not always compatible with keyboard-controller: software-mansion/react-native-screens#2554 😔

@Tobbe
Copy link

Tobbe commented Dec 20, 2024

@kirillzyusko Thank you! That might explain why rnkc sometimes just stops working altogether for me. Is there any kind of workaround right now? Or do I need to downgrade to earlier version of react-native-screens?

@kirillzyusko
Copy link
Owner

Or do I need to downgrade to earlier version of react-native-screens?

Well, this is the most proper way to resolve that now 👍

Another workaround that I discovered is mounting KeyboardProvider with some delay (however it's far from being perfect approach). I'm going to look into why the integration with RNS is broken and how it can be fixed 👀

@kirillzyusko
Copy link
Owner

@Tobbe would you mind to check if #744 fixes a problem for you or not? 👀

It may fix a problem 👀

@kirillzyusko
Copy link
Owner

@e-biba-ofti I also believe that #744 should fix the reported problem (after re-reading our conversation). Could you please check that? 🙏

@kirillzyusko kirillzyusko linked a pull request Dec 23, 2024 that will close this issue
2 tasks
kirillzyusko added a commit that referenced this issue Dec 24, 2024
## 📜 Description

Execute monkey-patch applying earlier than `StatusBar` modifications.

## 💡 Motivation and Context

It happens when `KeyboardProvider` had direct child as `StatusBar` - and
such thing can happen in `expo-router`, for example:
https://github.com/expo/expo/blob/5f40a80019bb6b892eda94dd244fdc0df8880ccb/packages/expo-router/src/ExpoRoot.tsx#L57

To prevent this problem I'm executing monkey patch applying in "layout
effect" instead of plain "effect". This gives me a precious time and an
ability to apply patch earlier and thus re-direct a call to my module.

And if we dig a little bit deeper. When `KeyboardProvider` gets mounted
the `useLayoutEffect` will be fired after component mount. On contrast
`StatusBar` will try to change its properties in `componentDidMount`.
And technically `componentDidMount` will be executed first (before
`useLayoutEffect`). But `StatusBar` schedules update via `setImmediate`
and `setImmediate` will execute its callback after `useLayoutEffect`, so
this fix should work 🙂

Closes
#708
#587

## 📢 Changelog

### Android

- apply monkey patch in layout effect to be sure monkey patch can be
applied earlier than first call to `StatusBar` module (if
`KeyboardProvider` and `StatusBar` were mounted simultaneously).

## 🤔 How Has This Been Tested?

Tested manually in
https://github.com/NyoriK/keyboard-controller-test-project

## 📸 Screenshots (if appropriate):


https://github.com/user-attachments/assets/6e259ffe-de59-46a6-b9a6-26de05698b06

## 📝 Checklist

- [x] CI successfully passed
- [x] I added new mocks and corresponding unit-tests if library API was
changed
@kirillzyusko
Copy link
Owner

The issue was automatically closed because I merged the PR. I'm going to publish a fix to npm under 1.15.2 tag.

If you still encounter this problem, then please open a new issue with all necessary information (such as reproduction example etc.)

I strongly believe, that the merged PR should resolve this problem! ❤️

@RayKay91
Copy link

Can confirm it fixed the issue for me! I was using react-native-edge-to-edge as a workaround but just removed that and bumped the keyboard-controller to 1.15.2 and there's no extra padding above or below. Thank you! :D

@kirillzyusko
Copy link
Owner

Yooohooo @RayKay91 🎉 Glad it resolved the problem! 😊

@Tobbe
Copy link

Tobbe commented Dec 24, 2024

@kirillzyusko Thanks for working on this issue!
I'm away spending some time with family over the holidays. I'll try the new version when I'm back at work again.

@kirillzyusko
Copy link
Owner

I'm away spending some time with family over the holidays. I'll try the new version when I'm back at work again.

Sure ❤️

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
🤖 android Android specific 🐛 bug Something isn't working
Projects
None yet
Development

Successfully merging a pull request may close this issue.

7 participants