Open wise-danya opened 1 week ago
Hey @wise-danya 👋 Thank you for providing a repo and high quality issue description!
Before digging into internals may I ask you what is the purpose of disabling the module and keeping edge-to-edge mode?
Basically the feature with disabling module was added to fallback to default Android adjustResize
behavior. But if you keep edge-to-edge
and just remove keyboard callbacks from native side, then you still will have edge-to-edge mode (i. e. automatic window resize will be disabled). So I'm kind of curious what is it the purpose you are following when trying to keep edge-to-edge and remove keyboard callbacks?
Hey @kirillzyusko 👋 Thanks for the quick response and for digging into the issue! Let me provide some additional context to clarify.
The reason I want to keep edge-to-edge
mode enabled while using react-native-keyboard-controller
is due to the usage of another library, react-native-bars
. This library solves several issues with system bars and requires EdgeToEdge
theme configuration in the styles.xml
file:
<resources>
<style name="AppTheme" parent="Theme.EdgeToEdge">
<!-- … -->
</style>
</resources>
Since the app’s theme relies on EdgeToEdge
, the NavigationBar
is expected to stay hidden or translucent. When react-native-keyboard-controller
disables edge-to-edge
mode, it conflicts with this setup and causes the NavigationBar
to reappear, disrupting the layout.
As for disabling the module, the main reason is to allow a gradual adaptation of react-native-keyboard-controller
in the project. Not all screens are ready to use the keyboard controller functionality, and enabling the module across the app requires careful adjustments for various keyboard usage scenarios.
I’m following the approach you suggested for gradual adoption:
"If you want to gradually adopt the functionality of this package in your app, you can use
useKeyboardController
hook. You can disable the module by default<KeyboardProvider enabled={false}>
and enable it usinguseKeyboardController
on screens where you want to use it."
This allows me to selectively enable the module on screens where it has been fully integrated, while the rest of the app uses the default Android adjustResize
behavior. However, the conflict between react-native-bars
and react-native-keyboard-controller
prevents me from providing a consistent visual experience across all screens.
Any workaround or ideas on how to avoid this conflict between the two libraries would be really helpful!
Thanks @wise-danya
I think now I understand better what you are trying to achieve.
Let me dig a little bit in internals and ask you about how you are going to handle them in your app 👀
edge-to-edge
+ adjustResize
As you pointed out earlier when you add react-native-bars
it enters edge-to-edge
mode. But when you refer to adjustResize
behavior - it's kind of not truth adjustResize
😓
By default in Android when you activate edge-to-edge
and adjustResize
then you window will stop resizing 😱 react-native-bars
handles that by implementing an additional logic and simulating old adjustResize
behavior:
So when you call RNBars.init(this);
the Android OS doesn't resize the window, but react-native-bar
will do that for you.
react-native-keyboard-controller
integrationBy default, when you wrap app with KeyboardProvider
it shouldn't change the behavior (since you already in edge-to-edge mode). But! react-native-keyboard-controller
and react-native-bars
both setup onApplyWindowInsetsListener
to rootView
/decorView
which may conflict with each other (i. e. when you disable/enable react-native-keyboard-controller
).
react-native-bars
keyboard handlingHonestly I didn't have a chance to clone your project and run reproduction. But I think there will be a conflict anyway, let's consider following cases:
react-native-keyboard-controller
overwrites the callback which is set by react-native-bars
- in this case when you disable react-native-keyboard-controller
keyboard handling will stop to work in the app at all;react-native-keyboard-controller
doesn't overwrite the callback which is set by react-native-bars
- in this case you will not be able to integrate react-native-keyboard-controller
selectively, because react-native-bars
will apply default keyboard handling on all screens (and you don't have an ability to turn it on/off on demand, right?). So if you add keyboard handling from (let's say you'll start to use KeyboardAvoidingView
from RNKC), then there are high chances that both modules will handle keyboard appearance at the same time and you will get double resize 🙈 So taking all these restrictions I don't think it's really possible to use setEnabled
method if you use react-native-bars
😔
The potential solution would be to disable react-native-bars
keyboard handling (by RNBars.init(this, false)
). It will not resize the window anymore. And then you can wrap your entire app with KeyboardAvoidingView
- theoretically it will give you the same behavior as you had behavior (just with one small difference - keyboard transitions will be animated now). And then you can write your own solution for disabling global KeyboardAvoidingView
and usage of specific keyboard handling on specific screens.
Let me know what do you think and whether we are on the same page or not 😅 I'll clone your project to play around it later today 👀
Hi, I think the issue was introduced from react-native-screens
version 3.32.0. There is a fix that has been merged but not released yet that you can cherry pick to make it work as before, or patch it yourself with patch-package
. I was getting a strange inset above and below that this PR fixes:
https://github.com/software-mansion/react-native-screens/pull/2301
@RayKay91 the provided example doesn't use react-native-screens
directly or native-stack
navigator in any form, so I highly doubt that it can be fixed by changes from react-native-screens
(just because react-native-screens
is not used in reproduction example).
Description
On Android, when toggling the
enabled
prop of the<KeyboardProvider />
usinguseKeyboardController
, the systemNavigationBar
behaves inconsistently due to the handling ofedge-to-edge
mode:When
enabled
is set totrue
, theNavigationBar
disappears. Whenenabled
is set tofalse
, theNavigationBar
reappears and causes layout issues by lifting the content. This issue is primarily caused by togglingedge-to-edge
mode in theenable()
anddisable()
methods.Steps to reproduce the behavior
react-native-keyboard-controller
andreact-native-bars
into a project.useKeyboardController
hook to toggle the enabled prop of<KeyboardProvider />
.enabled
totrue
, observe that the systemNavigationBar
disappears.enabled
tofalse
, observe that theNavigationBar
reappears and lifts the content.Expected behavior
The
NavigationBar
should remain hidden or translucent and should not affect the layout or content positioning, regardless of the enabled state of theKeyboardProvider
.Repo for reproducing
You can find a minimal reproducible example for this issue in the following repository: https://github.com/wise-danya/rn-keyboard-controller-issue-example
Video Demo
https://github.com/user-attachments/assets/b24e775e-021a-4131-ba13-bd29a497cf73
Additional context
On some screens, when the library is disabled, the
NavigationBar
is visible and causes the content to be lifted, leading to layout issues. This makes it hard to gradually adopt the library across multiple screens in an app.Environment: