-
Notifications
You must be signed in to change notification settings - Fork 325
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
Close sheet when top of FlatList is reached #20
Comments
@pontusab I think it possible to add to the container and it does behave like Apple maps. Here is my implementation
@osdnk Please let me know if I'm using this lib in a wrong way. |
Thanks! of course, it's possible to add it as a container, but I want the sheet to expand if the scroll position within Flatlist is 0 and when the user scrolls down it should stay. but when the user scrolls to top again the sheet should go down. |
@osdnk any comments or suggestion for us to add a FlatList in the content? |
Considering two examples I have added a few days ago I think I cover most cases of FlatList usage. The only point is virtualization, but you see it's necessary for bottom-sheet? |
Thanks, I would like to have a list of images from camera roll that the user can scroll, then I need a FlatList to be performant, The list should expand like this bottom sheet when the user starts to scroll up, but when reaching the top of the Flatlist again it should go down, I guess its not possible whit this lib because I need to handle FlatList scroll position? |
@osdnk I was able to get the flat list working very close to apple maps. But the biggest issue I'm facing is the innerContent height when my flat list has no data or few rows. I can share the example I have if you think it will be useful to see the issue |
+1 for virtualization support for the the bottom sheet (maybe based on a generic react-native-gesture-handler based scrollview with virtualization support). |
I don't have a clear idea of how to do it neither enough time, but I'll happily see some solution. Maybe you could build some own idea of virtualization basing on the position of content? |
@osdnk it is possible to handle this? Really needs this feature for my app |
@blohamen you can use |
@gorhom Please, send an example, very interesting. I tried to do something similar, but I didn’t succeed. Your example will be very helpfull. |
My example with bottom sheet
|
Hello there! I'm close to reach a proper implementation of this animation. But I'm stuck on last part I think. Can you share your example with "apple maps alike" bottom sheet please? Thanks man! |
I really needed this feature as well. I am basically recreating flatlist while retaining the bottomsheet behavior. |
Maybe @gorhom or @Priyatham51 can shed a light on how to use the Flatlist? |
@jeffreybello , @avegrv sorry i have been busy lately , however i setup this example to how to handle flatlist scrolling, hope it helps https://gist.github.com/Gorhom/32db5ee4d0423c8f227fd3c48e3dd991 |
@gorhom thank you very much for your input. I appreciate it. |
@jeffreybello , yeah that part is tricky 😅, you would need to simulate the flatlist scrolling with bottomsheet pan gesture, i will give it a try this weekend |
Yes, ill try my best too but I just got started in RN. But please let us know if you have made progress. |
This is not perfect, but as good as it gets with simple implementation. First see the video: Here I post code that are relevant:
|
hey all, I'm trying to understand how to put a FlatList and make it fill up the screen. Do i need to explicitly set its Maybe this requires an issue of its own(or some documentation, if i'm missing smth). @pontusab could you perhaps rename this issue to smth like Close sheet when top of FlatList is reached? |
Great approaches and workarounds here, highly appreciated! 😄 We are also integrating RN Reanimated-Bottomsheet with a Flatlist into our app. Am I correct to assume that we have not found a solution to virtualization yet? Thanks! 👍🏼 |
Very interested in the feature too, on big phones it’s not easy to close the bottom sheet by reaching the header, when it’s fully opened. I think this is also what user intuitively expects |
hey, did any one found a workaround for this? |
Unfortunately, we were not able to find a viable solution for flatlist and have disabled scroll to dismiss for the flatlist area as of now. |
I was able to achieve this functionality with an adaptation of an older example in the |
@southerneer It'd be super useful! |
@southerneer any update on your implementation? I'm running into the same issue where the sheet doesn't close when I reach the top of my flat list (works fine when I have I use a View instead of a FlatList). Here's my code: /* BottomSheet */
import React, { ReactNode, useRef, useEffect, useState } from "react";
import { Dimensions, View, StyleSheet } from "react-native";
import { useDimensions } from "react-native-hooks";
import BottomSheetRN from "reanimated-bottom-sheet";
import size, { unit } from "../themes/size";
import Elevation from "../themes/elevation";
interface BottomSheetProps {
children?: ReactNode;
onClose?: () => void;
onOpen?: () => void;
renderHeader?: () => ReactNode;
isVisible?: boolean;
}
const BottomSheet = (props: BottomSheetProps) => {
const { children, renderHeader, onClose, onOpen } = props;
const [isVisible, setIsVisible] = useState(props.isVisible);
const ref = useRef<BottomSheetRN>();
const {
screen: { height },
} = useDimensions();
const [headerHeight, setHeaderHeight] = useState(0);
useEffect(() => setIsVisible(props.isVisible), [props.isVisible]);
useEffect(() => {
if (ref.current) {
if (isVisible) {
ref.current.snapTo(1);
} else {
ref.current.snapTo(0);
}
}
}, [ref.current, isVisible]);
return (
<View style={[styles.container, isVisible && styles.containerVisible]}>
<BottomSheetRN
ref={ref}
initialSnap={0}
snapPoints={[0, "80%"]}
onCloseEnd={() => {
setIsVisible(false);
onClose && onClose();
}}
onOpenEnd={() => {
setIsVisible(true);
onOpen && onOpen();
}}
enabledContentTapInteraction
enabledGestureInteraction
enabledContentGestureInteraction
enabledInnerScrolling
renderHeader={() => (
<View
style={styles.header}
onLayout={event => setHeaderHeight(event.nativeEvent.layout.height)}
>
<View style={styles.panelHeader}>
<View style={styles.panelHandle} />
</View>
{renderHeader()}
</View>
)}
renderContent={() => (
<View style={[styles.panel, { height: ((height - headerHeight) * 80) / 100 }]}>
{children}
</View>
)}
/>
</View>
);
};
export default BottomSheet;
const styles = StyleSheet.create({
container: {
flex: 1,
position: "absolute",
top: 0,
bottom: 0,
left: 0,
right: 0,
},
containerVisible: {
zIndex: 100,
...Elevation.tertiary,
},
panel: {
backgroundColor: "white",
},
header: {
backgroundColor: "white",
paddingTop: size.vertical.small,
borderTopLeftRadius: unit * 2,
borderTopRightRadius: unit * 2,
},
panelHeader: {
alignItems: "center",
},
panelHandle: {
width: 40,
height: unit / 2,
borderRadius: 4,
backgroundColor: "#00000040",
marginBottom: 20,
},
panelTitle: {
fontSize: 27,
height: 35,
},
panelSubtitle: {
fontSize: 14,
color: "gray",
height: 30,
marginBottom: 10,
},
panelButton: {
padding: 20,
borderRadius: 10,
backgroundColor: "#318bfb",
alignItems: "center",
marginVertical: 10,
},
panelButtonTitle: {
fontSize: 17,
fontWeight: "bold",
color: "white",
},
photo: {
width: "100%",
height: 225,
marginTop: 30,
},
map: {
height: "100%",
width: "100%",
},
});
/* AutocompleteSheet */
import React, { useState, useEffect } from "react";
import { View, StyleSheet, TextInput, ActivityIndicator } from "react-native";
import { FlatList } from "react-native-gesture-handler";
import useDebounce from "../hooks/useDebounce";
import { ListItem } from "../types";
import AutocompleteRow from "./AutocompleteRow";
import BottomSheet from "./BottomSheet";
import size from "../themes/size";
import Elevation from "../themes/elevation";
import color from "../themes/color";
interface AutocompletePanelProps {
isVisible?: boolean;
onChange: (term: string) => Promise<void>;
onVisibilityChange: (isVisible: boolean) => void;
onSelect?: (item: any, index?: number) => void;
keyExtractor?: (item: any, index?: number) => string;
results: Array<ListItem>;
}
const AutocompletePanel = ({
isVisible,
onChange,
onSelect,
onVisibilityChange,
keyExtractor,
results,
}: AutocompletePanelProps) => {
const [searchTerm, onChangeSearchTerm] = useState("");
const debouncedSearchTerm = useDebounce(searchTerm, 400);
const [isLoading, setIsLoading] = useState(false);
useEffect(() => {
(async () => {
setIsLoading(true);
await onChange(debouncedSearchTerm);
setIsLoading(false);
})();
}, [debouncedSearchTerm]);
return (
<BottomSheet
isVisible={isVisible}
onClose={() => onVisibilityChange(false)}
onOpen={() => onVisibilityChange(true)}
renderHeader={() => (
<View style={[styles.container, styles.row]}>
<TextInput
style={styles.input}
placeholder={"Type text here"}
onChangeText={text => onChangeSearchTerm(text)}
value={searchTerm}
/>
{isLoading && <ActivityIndicator size='small' color='#4631EB' style={styles.loading} />}
</View>
)}
>
<FlatList
data={results}
scrollEnabled
keyExtractor={keyExtractor}
keyboardShouldPersistTaps='always'
style={styles.listView}
renderItem={({ item, index }) => (
<AutocompleteRow
id={item.id}
index={index}
onSelect={onSelect}
properties={item.properties}
/>
)}
/>
</BottomSheet>
);
};
export default AutocompletePanel;
const styles = StyleSheet.create({
container: {
paddingHorizontal: size.horizontal.large,
},
listView: {
backgroundColor: "red",
paddingHorizontal: 24,
},
loading: {
position: "absolute",
top: 8,
right: 32,
},
row: {
flexDirection: "row",
},
input: {
width: "100%",
paddingHorizontal: size.horizontal.regular,
paddingVertical: size.vertical.medium,
fontSize: 18,
borderRadius: 8,
borderWidth: 0.5,
borderColor: "#ddd",
...Elevation.tertiary,
backgroundColor: color.white,
},
}); |
Hi guys, @gorhom solution is still way buggy and doesn't work properly , where first and last item gets cut off. Any solution regarding this is very very much appreciated. |
I have to switch to another component because of this. |
Hey! Great lib!
Is it possible to add a FlatList to content and use that scroll position when the bottom sheet should expand or not?
Like the apple map, when the list is in the top and you move upwards, the sheat goes up. but when you scroll down the sheet stays until the user scroll to the top of the list within.
Is it possible to hook up using this or should I go custom with reanimates and gesture handler?
The text was updated successfully, but these errors were encountered: