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

KeyboardAwareScrollView no longer works with @gorhom/bottom-sheet #819

Open
Junveloper opened this issue Feb 19, 2025 · 6 comments
Open
Assignees
Labels
🐛 bug Something isn't working KeyboardAwareScrollView 📜 Anything related to KeyboardAwareScrollView component

Comments

@Junveloper
Copy link

Describe the bug
Using @gorhom/bottom-sheet version 5.1.1 and following 3rd party component integration guide from here does not seem to yield the outcome it was designed for.

When clicking on the Input and the keyboard appears, I expect BottomSheetModal to be pushed up so the input doesn't sit behind the keyboard.

Code snippet
// TestForm Component

import BottomSheetKeyboardAwareScrollView from '@components/ui/bottom-sheet/bottom-sheet-keyboard-aware-scroll-view';
import { BottomSheetBackdrop, BottomSheetModal } from '@gorhom/bottom-sheet';
import React, { useCallback, useMemo, useRef, useState } from 'react';
import { Button, StyleSheet, Text, TextInput, View } from 'react-native';

export default function TestForm() {
  const [textValue, setTextValue] = useState('');

  const bottomSheetModalRef = useRef<BottomSheetModal>(null);

  const handlePresentModalPress = useCallback(() => {
    bottomSheetModalRef.current?.present();
  }, []);

  const snapPoints = useMemo(() => ['30%'], []);
  return (
    <>
      <Button title="Test Form" onPress={handlePresentModalPress} />

      <BottomSheetModal
        ref={bottomSheetModalRef}
        index={0}
        snapPoints={snapPoints}
        enableDynamicSizing={false}
        enableBlurKeyboardOnGesture={true}
        keyboardBehavior="interactive"
        backdropComponent={(props) => (
          <BottomSheetBackdrop
            {...props}
            opacity={0.5}
            enableTouchThrough={false}
            appearsOnIndex={0}
            disappearsOnIndex={-1}
            style={[
              { backgroundColor: 'rgba(0, 0, 0, 1)' },
              StyleSheet.absoluteFillObject,
            ]}
          />
        )}
      >
        <BottomSheetKeyboardAwareScrollView>
          <View className="flex w-full px-4">
            <View>
              <Text className="mb-2 font-bold">Details</Text>
              <TextInput
                value={textValue}
                onChangeText={setTextValue}
                style={styles.input}
              />
            </View>
          </View>
        </BottomSheetKeyboardAwareScrollView>
      </BottomSheetModal>
    </>
  );
}
const styles = StyleSheet.create({
  input: {
    marginTop: 8,
    marginBottom: 10,
    borderRadius: 10,
    fontSize: 16,
    lineHeight: 20,
    padding: 8,
    backgroundColor: 'rgba(151, 151, 151, 0.25)',
  },
});

// BottomSheetKeyboardAwareScrollView

import {
  type BottomSheetScrollViewMethods,
  createBottomSheetScrollableComponent,
  SCROLLABLE_TYPE,
} from '@gorhom/bottom-sheet';
import type { BottomSheetScrollViewProps } from '@gorhom/bottom-sheet/src/components/bottomSheetScrollable/types';
import { memo } from 'react';
import {
  KeyboardAwareScrollView,
  type KeyboardAwareScrollViewProps,
} from 'react-native-keyboard-controller';
import Reanimated from 'react-native-reanimated';

const AnimatedScrollView =
  Reanimated.createAnimatedComponent<KeyboardAwareScrollViewProps>(
    KeyboardAwareScrollView,
  );
const BottomSheetScrollViewComponent = createBottomSheetScrollableComponent<
  BottomSheetScrollViewMethods,
  BottomSheetScrollViewProps
>(SCROLLABLE_TYPE.SCROLLVIEW, AnimatedScrollView);
const BottomSheetKeyboardAwareScrollView = memo(BottomSheetScrollViewComponent);

BottomSheetKeyboardAwareScrollView.displayName =
  'BottomSheetKeyboardAwareScrollView';

export default BottomSheetKeyboardAwareScrollView as (
  props: BottomSheetScrollViewProps & KeyboardAwareScrollViewProps,
) => ReturnType<typeof BottomSheetKeyboardAwareScrollView>;

To Reproduce
The code above will result in this behaviour

Screen.Recording.2025-02-20.at.12.44.43.am.mov

Expected behavior
BottomSheet to be pushed up as the keyboard appears.

Smartphone (please complete the following information):

  • iPhone 14 Pro Simulator and physical device

Additional context
Add any other context about the problem here.

@kirillzyusko kirillzyusko added KeyboardAwareScrollView 📜 Anything related to KeyboardAwareScrollView component 🐛 bug Something isn't working labels Feb 19, 2025
@Junveloper
Copy link
Author

Hi @kirillzyusko, I was wondering whether you were able to replicate the bug on your end or whether I am using something incorrectly. Thank you for this awesome library by the way! :)

@kirillzyusko
Copy link
Owner

Hey @Junveloper

I haven't tested it. I've tried to bump bottom-sheet to v5 i example app, and all bottom-sheets stopped working in example app, so I didn't spend a lot of time on making it working.

Also integrating KeyboardAwareScrollView with @gorhom/bottom-sheet was a community effort. @VladyslavMartynov10 I know you were working a lot with bottom sheets - maybe you struggled with bottom-sheet v5 issue as well?

@VladyslavMartynov10
Copy link

Hey @Junveloper

I’ll try to reproduce the behavior with version 5. Previously, with version 4, it was working without any issues as far as I remember, but I may have used some extra hacks to achieve consistent behavior. I’ll let you know.

@Junveloper
Copy link
Author

@kirillzyusko @VladyslavMartynov10 Thank you very much for your responses guys. I love what you guys have done with this library. Please let me know if I can help in any way!

@VladyslavMartynov10
Copy link

VladyslavMartynov10 commented Feb 26, 2025

@Junveloper As a quick fix but still additional logic required:

import { BottomSheetBackdrop, BottomSheetModal } from '@gorhom/bottom-sheet';
import React, { useMemo, useState } from 'react';
import { Button, StyleSheet, Text, TextInput, View } from 'react-native';
import BottomSheetKeyboardAwareScrollView from './BottomSheetKeyboardAwareScrollView';
import { useBottomSheetModal } from './useBottomSheetModal';

export const Auth = () => {
  const [textValue, setTextValue] = useState('');

  const { panelRef, snapToIndex, present } = useBottomSheetModal();

  const snapPoints = useMemo(() => ['30%', '60%', '100%'], []);

  return (
    <View style={{ paddingTop: 20 }}>
      <Button title="Test Form" onPress={present} />

      <BottomSheetModal
        ref={panelRef}
        index={0}
        snapPoints={snapPoints}
        enableDynamicSizing={false}
        enableBlurKeyboardOnGesture={true}
        keyboardBehavior="interactive"
        backdropComponent={props => (
          <BottomSheetBackdrop
            {...props}
            opacity={0.5}
            enableTouchThrough={false}
            appearsOnIndex={0}
            disappearsOnIndex={-1}
            style={[
              { backgroundColor: 'rgba(0, 0, 0, 1)' },
              StyleSheet.absoluteFillObject,
            ]}
          />
        )}>
        <BottomSheetKeyboardAwareScrollView>
          <View className="flex w-full px-4">
            <View>
              <Text className="mb-2 font-bold">Details</Text>
              <TextInput
                value={textValue}
                onChangeText={setTextValue}
                style={styles.input}
                onFocus={() => snapToIndex(1)}
              />
            </View>
          </View>
        </BottomSheetKeyboardAwareScrollView>
      </BottomSheetModal>
    </View>
  );
};
const styles = StyleSheet.create({
  input: {
    marginTop: 8,
    marginBottom: 10,
    borderRadius: 10,
    fontSize: 16,
    lineHeight: 20,
    padding: 8,
    backgroundColor: 'rgba(151, 151, 151, 0.25)',
  },
});
import { BottomSheetModal } from '@gorhom/bottom-sheet';
import { useCallback, useRef } from 'react';

export const useBottomSheetModal = () => {
  const panelRef = useRef<BottomSheetModal>(null);

  const present = (data?: any) => {
    panelRef.current?.present(data);
  };

  const close = useCallback(() => {
    panelRef.current?.close();
  }, []);

  const collapse = useCallback(() => {
    panelRef.current?.collapse();
  }, []);

  const dismiss = useCallback(() => {
    panelRef.current?.dismiss();
  }, []);

  const forceClose = useCallback(() => {
    panelRef.current?.forceClose();
  }, []);

  const snapToIndex = useCallback((index: number) => {
    panelRef.current?.snapToIndex(index);
  }, []);

  const snapToPosition = useCallback((position: string | number) => {
    panelRef.current?.snapToPosition(position);
  }, []);

  return {
    panelRef,
    present,
    close,
    collapse,
    dismiss,
    forceClose,
    snapToIndex,
    snapToPosition,
  };
};
Simulator.Screen.Recording.-.iPhone.SE.3rd.generation.-.2025-02-26.at.17.47.17.mp4

I somehow achieved it without focus logic, need to find out.

@Junveloper
Copy link
Author

@VladyslavMartynov10 Hey mate, thank you so much for providing the code. I will give it a go and will report back. Really appreciate it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
🐛 bug Something isn't working KeyboardAwareScrollView 📜 Anything related to KeyboardAwareScrollView component
Projects
None yet
Development

No branches or pull requests

3 participants