@swmansion/react-native-bottom-sheet 0.7.0-next.1 → 0.7.0-next.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/android/src/main/java/com/swmansion/reactnativebottomsheet/BottomSheetView.kt +4 -1
- package/ios/BottomSheetContentView.mm +6 -0
- package/ios/RNSBottomSheetHostingView.swift +13 -0
- package/lib/module/BottomSheet.js +101 -28
- package/lib/module/BottomSheet.js.map +1 -1
- package/lib/module/ModalBottomSheet.js +3 -7
- package/lib/module/ModalBottomSheet.js.map +1 -1
- package/lib/module/bottomSheetUtils.js +0 -2
- package/lib/module/bottomSheetUtils.js.map +1 -1
- package/lib/module/index.js +0 -3
- package/lib/module/index.js.map +1 -1
- package/lib/typescript/src/BottomSheet.d.ts +4 -3
- package/lib/typescript/src/BottomSheet.d.ts.map +1 -1
- package/lib/typescript/src/ModalBottomSheet.d.ts +3 -6
- package/lib/typescript/src/ModalBottomSheet.d.ts.map +1 -1
- package/lib/typescript/src/bottomSheetUtils.d.ts.map +1 -1
- package/lib/typescript/src/index.d.ts +0 -5
- package/lib/typescript/src/index.d.ts.map +1 -1
- package/package.json +2 -8
- package/src/BottomSheet.tsx +144 -28
- package/src/ModalBottomSheet.tsx +5 -13
- package/src/bottomSheetUtils.ts +0 -1
- package/src/index.tsx +0 -5
- package/lib/module/BottomSheetBase.js +0 -207
- package/lib/module/BottomSheetBase.js.map +0 -1
- package/lib/module/BottomSheetContext.js +0 -13
- package/lib/module/BottomSheetContext.js.map +0 -1
- package/lib/module/BottomSheetFlatList.js +0 -6
- package/lib/module/BottomSheetFlatList.js.map +0 -1
- package/lib/module/BottomSheetScrollView.js +0 -6
- package/lib/module/BottomSheetScrollView.js.map +0 -1
- package/lib/module/bottomSheetScrollable.js +0 -35
- package/lib/module/bottomSheetScrollable.js.map +0 -1
- package/lib/module/useBottomSheetPanGesture.js +0 -202
- package/lib/module/useBottomSheetPanGesture.js.map +0 -1
- package/lib/module/useBottomSheetScrollable.js +0 -61
- package/lib/module/useBottomSheetScrollable.js.map +0 -1
- package/lib/typescript/src/BottomSheetBase.d.ts +0 -20
- package/lib/typescript/src/BottomSheetBase.d.ts.map +0 -1
- package/lib/typescript/src/BottomSheetContext.d.ts +0 -19
- package/lib/typescript/src/BottomSheetContext.d.ts.map +0 -1
- package/lib/typescript/src/BottomSheetFlatList.d.ts +0 -10
- package/lib/typescript/src/BottomSheetFlatList.d.ts.map +0 -1
- package/lib/typescript/src/BottomSheetScrollView.d.ts +0 -10
- package/lib/typescript/src/BottomSheetScrollView.d.ts.map +0 -1
- package/lib/typescript/src/bottomSheetScrollable.d.ts +0 -9
- package/lib/typescript/src/bottomSheetScrollable.d.ts.map +0 -1
- package/lib/typescript/src/useBottomSheetPanGesture.d.ts +0 -18
- package/lib/typescript/src/useBottomSheetPanGesture.d.ts.map +0 -1
- package/lib/typescript/src/useBottomSheetScrollable.d.ts +0 -13
- package/lib/typescript/src/useBottomSheetScrollable.d.ts.map +0 -1
- package/src/BottomSheetBase.tsx +0 -276
- package/src/BottomSheetContext.tsx +0 -33
- package/src/BottomSheetFlatList.tsx +0 -21
- package/src/BottomSheetScrollView.tsx +0 -22
- package/src/bottomSheetScrollable.tsx +0 -42
- package/src/useBottomSheetPanGesture.ts +0 -253
- package/src/useBottomSheetScrollable.ts +0 -68
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
import type { ReactNode } from 'react';
|
|
2
|
-
import type { SharedValue, WithSpringConfig } from 'react-native-reanimated';
|
|
3
|
-
import type { Detent } from './bottomSheetUtils';
|
|
4
|
-
export type { Detent, DetentValue } from './bottomSheetUtils';
|
|
5
|
-
export { programmatic } from './bottomSheetUtils';
|
|
6
|
-
export interface BottomSheetCommonProps {
|
|
7
|
-
children: ReactNode;
|
|
8
|
-
detents?: Detent[];
|
|
9
|
-
index: number;
|
|
10
|
-
onIndexChange?: (index: number) => void;
|
|
11
|
-
position?: SharedValue<number>;
|
|
12
|
-
openAnimationConfig?: WithSpringConfig;
|
|
13
|
-
closeAnimationConfig?: WithSpringConfig;
|
|
14
|
-
}
|
|
15
|
-
export interface BottomSheetBaseProps extends BottomSheetCommonProps {
|
|
16
|
-
modal?: boolean;
|
|
17
|
-
renderScrim?: (progress: SharedValue<number>) => ReactNode;
|
|
18
|
-
}
|
|
19
|
-
export declare const BottomSheetBase: ({ children, detents, index, onIndexChange, position: externalPosition, openAnimationConfig, closeAnimationConfig, modal, renderScrim, }: BottomSheetBaseProps) => import("react/jsx-runtime").JSX.Element;
|
|
20
|
-
//# sourceMappingURL=BottomSheetBase.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"BottomSheetBase.d.ts","sourceRoot":"","sources":["../../../src/BottomSheetBase.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAGvC,OAAO,KAAK,EAAE,WAAW,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAqB7E,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAEjD,YAAY,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAC9D,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAElD,MAAM,WAAW,sBAAsB;IACrC,QAAQ,EAAE,SAAS,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACxC,QAAQ,CAAC,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IAC/B,mBAAmB,CAAC,EAAE,gBAAgB,CAAC;IACvC,oBAAoB,CAAC,EAAE,gBAAgB,CAAC;CACzC;AAED,MAAM,WAAW,oBAAqB,SAAQ,sBAAsB;IAClE,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,WAAW,CAAC,EAAE,CAAC,QAAQ,EAAE,WAAW,CAAC,MAAM,CAAC,KAAK,SAAS,CAAC;CAC5D;AA2BD,eAAO,MAAM,eAAe,GAAI,yIAU7B,oBAAoB,4CAmMtB,CAAC"}
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
import type { PanGesture } from 'react-native-gesture-handler';
|
|
2
|
-
import type { AnimatedRef, SharedValue } from 'react-native-reanimated';
|
|
3
|
-
export interface ScrollableEntry {
|
|
4
|
-
ref: AnimatedRef<any>;
|
|
5
|
-
scrollOffset: SharedValue<number>;
|
|
6
|
-
isGestureActive: SharedValue<boolean>;
|
|
7
|
-
}
|
|
8
|
-
export interface BottomSheetContextType {
|
|
9
|
-
translateY: SharedValue<number>;
|
|
10
|
-
position: SharedValue<number>;
|
|
11
|
-
index: SharedValue<number>;
|
|
12
|
-
sheetHeight: SharedValue<number>;
|
|
13
|
-
isScrollableLocked: SharedValue<boolean>;
|
|
14
|
-
registerScrollable: (entry: ScrollableEntry) => () => void;
|
|
15
|
-
panGesture: PanGesture;
|
|
16
|
-
}
|
|
17
|
-
export declare const BottomSheetContextProvider: import("react").Provider<BottomSheetContextType | null>;
|
|
18
|
-
export declare const useBottomSheetContext: () => BottomSheetContextType;
|
|
19
|
-
//# sourceMappingURL=BottomSheetContext.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"BottomSheetContext.d.ts","sourceRoot":"","sources":["../../../src/BottomSheetContext.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,8BAA8B,CAAC;AAC/D,OAAO,KAAK,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAExE,MAAM,WAAW,eAAe;IAC9B,GAAG,EAAE,WAAW,CAAC,GAAG,CAAC,CAAC;IACtB,YAAY,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IAClC,eAAe,EAAE,WAAW,CAAC,OAAO,CAAC,CAAC;CACvC;AAED,MAAM,WAAW,sBAAsB;IACrC,UAAU,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IAChC,QAAQ,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IAC9B,KAAK,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IAC3B,WAAW,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IACjC,kBAAkB,EAAE,WAAW,CAAC,OAAO,CAAC,CAAC;IACzC,kBAAkB,EAAE,CAAC,KAAK,EAAE,eAAe,KAAK,MAAM,IAAI,CAAC;IAC3D,UAAU,EAAE,UAAU,CAAC;CACxB;AAID,eAAO,MAAM,0BAA0B,yDAA8B,CAAC;AAEtE,eAAO,MAAM,qBAAqB,8BAQjC,CAAC"}
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
import { FlatList, type NativeScrollEvent } from 'react-native';
|
|
2
|
-
import type { FlatListPropsWithLayout, SharedValue } from 'react-native-reanimated';
|
|
3
|
-
import type { Ref, ReactElement } from 'react';
|
|
4
|
-
export type BottomSheetFlatListProps<T> = Omit<FlatListPropsWithLayout<T>, 'onScroll' | 'scrollEnabled' | 'ref'> & {
|
|
5
|
-
scrollEnabled?: boolean | SharedValue<boolean | undefined>;
|
|
6
|
-
onScroll?: (event: NativeScrollEvent) => void;
|
|
7
|
-
ref?: Ref<FlatList<T>>;
|
|
8
|
-
};
|
|
9
|
-
export declare const BottomSheetFlatList: <T>(props: BottomSheetFlatListProps<T>) => ReactElement;
|
|
10
|
-
//# sourceMappingURL=BottomSheetFlatList.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"BottomSheetFlatList.d.ts","sourceRoot":"","sources":["../../../src/BottomSheetFlatList.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,KAAK,iBAAiB,EAAE,MAAM,cAAc,CAAC;AAChE,OAAO,KAAK,EACV,uBAAuB,EACvB,WAAW,EACZ,MAAM,yBAAyB,CAAC;AACjC,OAAO,KAAK,EAAE,GAAG,EAAE,YAAY,EAAE,MAAM,OAAO,CAAC;AAI/C,MAAM,MAAM,wBAAwB,CAAC,CAAC,IAAI,IAAI,CAC5C,uBAAuB,CAAC,CAAC,CAAC,EAC1B,UAAU,GAAG,eAAe,GAAG,KAAK,CACrC,GAAG;IACF,aAAa,CAAC,EAAE,OAAO,GAAG,WAAW,CAAC,OAAO,GAAG,SAAS,CAAC,CAAC;IAC3D,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,iBAAiB,KAAK,IAAI,CAAC;IAC9C,GAAG,CAAC,EAAE,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC;CACxB,CAAC;AAEF,eAAO,MAAM,mBAAmB,EAAsC,CAAC,CAAC,EACtE,KAAK,EAAE,wBAAwB,CAAC,CAAC,CAAC,KAC/B,YAAY,CAAC"}
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
import type { Ref, ReactElement } from 'react';
|
|
2
|
-
import { ScrollView, type NativeScrollEvent, type ScrollViewProps } from 'react-native';
|
|
3
|
-
import type { SharedValue } from 'react-native-reanimated';
|
|
4
|
-
export type BottomSheetScrollViewProps = Omit<ScrollViewProps, 'onScroll' | 'scrollEnabled' | 'ref'> & {
|
|
5
|
-
scrollEnabled?: boolean | SharedValue<boolean | undefined>;
|
|
6
|
-
onScroll?: (event: NativeScrollEvent) => void;
|
|
7
|
-
ref?: Ref<ScrollView>;
|
|
8
|
-
};
|
|
9
|
-
export declare const BottomSheetScrollView: (props: BottomSheetScrollViewProps) => ReactElement;
|
|
10
|
-
//# sourceMappingURL=BottomSheetScrollView.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"BottomSheetScrollView.d.ts","sourceRoot":"","sources":["../../../src/BottomSheetScrollView.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,GAAG,EAAE,YAAY,EAAE,MAAM,OAAO,CAAC;AAC/C,OAAO,EACL,UAAU,EACV,KAAK,iBAAiB,EACtB,KAAK,eAAe,EACrB,MAAM,cAAc,CAAC;AACtB,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAI3D,MAAM,MAAM,0BAA0B,GAAG,IAAI,CAC3C,eAAe,EACf,UAAU,GAAG,eAAe,GAAG,KAAK,CACrC,GAAG;IACF,aAAa,CAAC,EAAE,OAAO,GAAG,WAAW,CAAC,OAAO,GAAG,SAAS,CAAC,CAAC;IAC3D,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,iBAAiB,KAAK,IAAI,CAAC;IAC9C,GAAG,CAAC,EAAE,GAAG,CAAC,UAAU,CAAC,CAAC;CACvB,CAAC;AAEF,eAAO,MAAM,qBAAqB,EAAwC,CACxE,KAAK,EAAE,0BAA0B,KAC9B,YAAY,CAAC"}
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
import { type ComponentType, type Ref } from 'react';
|
|
2
|
-
import type { NativeScrollEvent } from 'react-native';
|
|
3
|
-
import { type SharedValue } from 'react-native-reanimated';
|
|
4
|
-
export declare function bottomSheetScrollable<P extends Record<string, any>, R = unknown>(ScrollableComponent: ComponentType<P>): ({ scrollEnabled, onScroll, ref, ...rest }: Omit<P, "onScroll" | "scrollEnabled" | "ref"> & {
|
|
5
|
-
scrollEnabled?: boolean | SharedValue<boolean | undefined>;
|
|
6
|
-
onScroll?: (event: NativeScrollEvent) => void;
|
|
7
|
-
ref?: Ref<R>;
|
|
8
|
-
}) => import("react/jsx-runtime").JSX.Element;
|
|
9
|
-
//# sourceMappingURL=bottomSheetScrollable.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"bottomSheetScrollable.d.ts","sourceRoot":"","sources":["../../../src/bottomSheetScrollable.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,aAAa,EAAE,KAAK,GAAG,EAAuB,MAAM,OAAO,CAAC;AAC1E,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AAEtD,OAAiB,EAAE,KAAK,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAIrE,wBAAgB,qBAAqB,CACnC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAC7B,CAAC,GAAG,OAAO,EACX,mBAAmB,EAAE,aAAa,CAAC,CAAC,CAAC,IAI7B,2CAKL,IAAI,CAAC,CAAC,EAAE,UAAU,GAAG,eAAe,GAAG,KAAK,CAAC,GAAG;IACjD,aAAa,CAAC,EAAE,OAAO,GAAG,WAAW,CAAC,OAAO,GAAG,SAAS,CAAC,CAAC;IAC3D,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,iBAAiB,KAAK,IAAI,CAAC;IAC9C,GAAG,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC;CACd,6CAkBF"}
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
import type { PanGesture } from 'react-native-gesture-handler';
|
|
2
|
-
import { type SharedValue } from 'react-native-reanimated';
|
|
3
|
-
import type { ScrollableEntry } from './BottomSheetContext';
|
|
4
|
-
interface BottomSheetPanGestureParams {
|
|
5
|
-
animationTarget: SharedValue<number>;
|
|
6
|
-
translateY: SharedValue<number>;
|
|
7
|
-
sheetHeight: SharedValue<number>;
|
|
8
|
-
detentsValue: SharedValue<number[]>;
|
|
9
|
-
isDraggableValue: SharedValue<boolean[]>;
|
|
10
|
-
currentIndex: SharedValue<number>;
|
|
11
|
-
scrollableEntries: ScrollableEntry[];
|
|
12
|
-
isScrollableLocked: SharedValue<boolean>;
|
|
13
|
-
handleIndexChange: (nextIndex: number) => void;
|
|
14
|
-
animateToIndex: (targetIndex: number, velocity?: number) => void;
|
|
15
|
-
}
|
|
16
|
-
export declare const useBottomSheetPanGesture: ({ animationTarget, translateY, sheetHeight, detentsValue, isDraggableValue, currentIndex, scrollableEntries, isScrollableLocked, handleIndexChange, animateToIndex, }: BottomSheetPanGestureParams) => PanGesture;
|
|
17
|
-
export {};
|
|
18
|
-
//# sourceMappingURL=useBottomSheetPanGesture.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"useBottomSheetPanGesture.d.ts","sourceRoot":"","sources":["../../../src/useBottomSheetPanGesture.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,8BAA8B,CAAC;AAG/D,OAAO,EAGL,KAAK,WAAW,EAEjB,MAAM,yBAAyB,CAAC;AAEjC,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAG5D,UAAU,2BAA2B;IACnC,eAAe,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IACrC,UAAU,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IAChC,WAAW,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IACjC,YAAY,EAAE,WAAW,CAAC,MAAM,EAAE,CAAC,CAAC;IACpC,gBAAgB,EAAE,WAAW,CAAC,OAAO,EAAE,CAAC,CAAC;IACzC,YAAY,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IAClC,iBAAiB,EAAE,eAAe,EAAE,CAAC;IACrC,kBAAkB,EAAE,WAAW,CAAC,OAAO,CAAC,CAAC;IACzC,iBAAiB,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;IAC/C,cAAc,EAAE,CAAC,WAAW,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;CAClE;AAED,eAAO,MAAM,wBAAwB,GAAI,uKAWtC,2BAA2B,KAAG,UAuNhC,CAAC"}
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import type { NativeScrollEvent } from 'react-native';
|
|
2
|
-
import { type SharedValue } from 'react-native-reanimated';
|
|
3
|
-
type ScrollHandler = (event: NativeScrollEvent) => void;
|
|
4
|
-
export declare const useBottomSheetScrollable: (baseScrollEnabled?: boolean | SharedValue<boolean | undefined>, onScroll?: ScrollHandler) => {
|
|
5
|
-
scrollHandler: import("react-native-reanimated").ScrollHandlerProcessed<Record<string, unknown>>;
|
|
6
|
-
scrollableRef: import("react-native-reanimated").AnimatedRef<import("react").Component<{}, {}, any>>;
|
|
7
|
-
nativeGesture: import("react-native-gesture-handler/lib/typescript/handlers/gestures/nativeGesture").NativeGesture;
|
|
8
|
-
animatedProps: Partial<{
|
|
9
|
-
scrollEnabled: boolean;
|
|
10
|
-
}>;
|
|
11
|
-
};
|
|
12
|
-
export {};
|
|
13
|
-
//# sourceMappingURL=useBottomSheetScrollable.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"useBottomSheetScrollable.d.ts","sourceRoot":"","sources":["../../../src/useBottomSheetScrollable.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AAEtD,OAAO,EACL,KAAK,WAAW,EAKjB,MAAM,yBAAyB,CAAC;AAIjC,KAAK,aAAa,GAAG,CAAC,KAAK,EAAE,iBAAiB,KAAK,IAAI,CAAC;AAExD,eAAO,MAAM,wBAAwB,GACnC,oBAAmB,OAAO,GAAG,WAAW,CAAC,OAAO,GAAG,SAAS,CAAQ,EACpE,WAAW,aAAa;;;;;;;CAiDzB,CAAC"}
|
package/src/BottomSheetBase.tsx
DELETED
|
@@ -1,276 +0,0 @@
|
|
|
1
|
-
import { useCallback, useEffect, useState } from 'react';
|
|
2
|
-
import type { ReactNode } from 'react';
|
|
3
|
-
import type { LayoutChangeEvent } from 'react-native';
|
|
4
|
-
import { Pressable, StyleSheet, View, useWindowDimensions } from 'react-native';
|
|
5
|
-
import type { SharedValue, WithSpringConfig } from 'react-native-reanimated';
|
|
6
|
-
import Animated, {
|
|
7
|
-
useAnimatedReaction,
|
|
8
|
-
useAnimatedStyle,
|
|
9
|
-
useDerivedValue,
|
|
10
|
-
useSharedValue,
|
|
11
|
-
withSpring,
|
|
12
|
-
} from 'react-native-reanimated';
|
|
13
|
-
import { scheduleOnUI } from 'react-native-worklets';
|
|
14
|
-
import { GestureDetector } from 'react-native-gesture-handler';
|
|
15
|
-
import { useSafeAreaInsets } from 'react-native-safe-area-context';
|
|
16
|
-
import { Portal } from './BottomSheetProvider';
|
|
17
|
-
import {
|
|
18
|
-
BottomSheetContextProvider,
|
|
19
|
-
type ScrollableEntry,
|
|
20
|
-
} from './BottomSheetContext';
|
|
21
|
-
import {
|
|
22
|
-
clampIndex,
|
|
23
|
-
isDetentProgrammatic,
|
|
24
|
-
resolveDetent,
|
|
25
|
-
} from './bottomSheetUtils';
|
|
26
|
-
import type { Detent } from './bottomSheetUtils';
|
|
27
|
-
import { useBottomSheetPanGesture } from './useBottomSheetPanGesture';
|
|
28
|
-
export type { Detent, DetentValue } from './bottomSheetUtils';
|
|
29
|
-
export { programmatic } from './bottomSheetUtils';
|
|
30
|
-
|
|
31
|
-
export interface BottomSheetCommonProps {
|
|
32
|
-
children: ReactNode;
|
|
33
|
-
detents?: Detent[];
|
|
34
|
-
index: number;
|
|
35
|
-
onIndexChange?: (index: number) => void;
|
|
36
|
-
position?: SharedValue<number>;
|
|
37
|
-
openAnimationConfig?: WithSpringConfig;
|
|
38
|
-
closeAnimationConfig?: WithSpringConfig;
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
export interface BottomSheetBaseProps extends BottomSheetCommonProps {
|
|
42
|
-
modal?: boolean;
|
|
43
|
-
renderScrim?: (progress: SharedValue<number>) => ReactNode;
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
const DEFAULT_OPEN_ANIMATION_CONFIG: WithSpringConfig = {
|
|
47
|
-
dampingRatio: 1,
|
|
48
|
-
duration: 300,
|
|
49
|
-
overshootClamping: true,
|
|
50
|
-
};
|
|
51
|
-
|
|
52
|
-
const DEFAULT_CLOSE_ANIMATION_CONFIG: WithSpringConfig = {
|
|
53
|
-
dampingRatio: 1,
|
|
54
|
-
duration: 250,
|
|
55
|
-
overshootClamping: true,
|
|
56
|
-
};
|
|
57
|
-
|
|
58
|
-
const DefaultScrim = ({ progress }: { progress: SharedValue<number> }) => {
|
|
59
|
-
const style = useAnimatedStyle(() => ({ opacity: progress.value }));
|
|
60
|
-
return (
|
|
61
|
-
<Animated.View
|
|
62
|
-
style={[
|
|
63
|
-
StyleSheet.absoluteFill,
|
|
64
|
-
{ flex: 1, backgroundColor: 'rgba(0, 0, 0, 0.5)' },
|
|
65
|
-
style,
|
|
66
|
-
]}
|
|
67
|
-
/>
|
|
68
|
-
);
|
|
69
|
-
};
|
|
70
|
-
|
|
71
|
-
export const BottomSheetBase = ({
|
|
72
|
-
children,
|
|
73
|
-
detents = [0, 'max'],
|
|
74
|
-
index,
|
|
75
|
-
onIndexChange,
|
|
76
|
-
position: externalPosition,
|
|
77
|
-
openAnimationConfig = DEFAULT_OPEN_ANIMATION_CONFIG,
|
|
78
|
-
closeAnimationConfig = DEFAULT_CLOSE_ANIMATION_CONFIG,
|
|
79
|
-
modal = false,
|
|
80
|
-
renderScrim,
|
|
81
|
-
}: BottomSheetBaseProps) => {
|
|
82
|
-
const { height: screenHeight } = useWindowDimensions();
|
|
83
|
-
const insets = useSafeAreaInsets();
|
|
84
|
-
const maxHeight = screenHeight - insets.top;
|
|
85
|
-
const resolvedIndex = clampIndex(index, detents.length);
|
|
86
|
-
const [contentHeight, setContentHeight] = useState(0);
|
|
87
|
-
|
|
88
|
-
if (detents.length === 0) {
|
|
89
|
-
throw new Error('detents must include at least one value.');
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
const normalizedDetents = detents.map((detent) => {
|
|
93
|
-
const resolved = resolveDetent(detent, contentHeight, maxHeight);
|
|
94
|
-
return Math.max(0, Math.min(resolved, maxHeight));
|
|
95
|
-
});
|
|
96
|
-
const isDraggable = detents.map((detent) => !isDetentProgrammatic(detent));
|
|
97
|
-
const initialMaxSnap = Math.max(0, ...normalizedDetents);
|
|
98
|
-
|
|
99
|
-
const translateY = useSharedValue(initialMaxSnap);
|
|
100
|
-
const animationTarget = useSharedValue(NaN);
|
|
101
|
-
const sheetHeight = useSharedValue(initialMaxSnap);
|
|
102
|
-
const [scrollableEntries, setScrollableEntries] = useState<ScrollableEntry[]>(
|
|
103
|
-
[]
|
|
104
|
-
);
|
|
105
|
-
const isScrollableLocked = useSharedValue(false);
|
|
106
|
-
|
|
107
|
-
const registerScrollable = useCallback((entry: ScrollableEntry) => {
|
|
108
|
-
setScrollableEntries((prev) => [...prev, entry]);
|
|
109
|
-
return () => {
|
|
110
|
-
setScrollableEntries((prev) => prev.filter((e) => e !== entry));
|
|
111
|
-
};
|
|
112
|
-
}, []);
|
|
113
|
-
|
|
114
|
-
const detentsValue = useSharedValue(normalizedDetents);
|
|
115
|
-
const isDraggableValue = useSharedValue(isDraggable);
|
|
116
|
-
const firstNonzeroDetent = useSharedValue(
|
|
117
|
-
normalizedDetents.find((detent) => detent > 0) ?? 0
|
|
118
|
-
);
|
|
119
|
-
const currentIndex = useSharedValue(resolvedIndex);
|
|
120
|
-
const internalPosition = useDerivedValue(() =>
|
|
121
|
-
Math.max(0, sheetHeight.value - translateY.value)
|
|
122
|
-
);
|
|
123
|
-
|
|
124
|
-
useAnimatedReaction(
|
|
125
|
-
() => internalPosition.value,
|
|
126
|
-
(value) => {
|
|
127
|
-
if (externalPosition !== undefined) externalPosition.set(value);
|
|
128
|
-
}
|
|
129
|
-
);
|
|
130
|
-
|
|
131
|
-
const scrimProgress = useDerivedValue(() => {
|
|
132
|
-
const target = firstNonzeroDetent.value;
|
|
133
|
-
if (target <= 0) return 0;
|
|
134
|
-
const progress = internalPosition.value / target;
|
|
135
|
-
return Math.min(1, Math.max(0, progress));
|
|
136
|
-
});
|
|
137
|
-
|
|
138
|
-
const handleIndexChange = (nextIndex: number) => {
|
|
139
|
-
onIndexChange?.(nextIndex);
|
|
140
|
-
};
|
|
141
|
-
|
|
142
|
-
useEffect(() => {
|
|
143
|
-
const maxSnap = Math.max(0, ...normalizedDetents);
|
|
144
|
-
detentsValue.set(normalizedDetents);
|
|
145
|
-
isDraggableValue.set(isDraggable);
|
|
146
|
-
sheetHeight.set(maxSnap);
|
|
147
|
-
firstNonzeroDetent.set(normalizedDetents.find((detent) => detent > 0) ?? 0);
|
|
148
|
-
}, [
|
|
149
|
-
normalizedDetents,
|
|
150
|
-
isDraggable,
|
|
151
|
-
sheetHeight,
|
|
152
|
-
detentsValue,
|
|
153
|
-
isDraggableValue,
|
|
154
|
-
firstNonzeroDetent,
|
|
155
|
-
]);
|
|
156
|
-
|
|
157
|
-
const animateToIndex = useCallback(
|
|
158
|
-
(targetIndex: number, velocity?: number) => {
|
|
159
|
-
'worklet';
|
|
160
|
-
const maxSnap = sheetHeight.value;
|
|
161
|
-
const targetTranslate = maxSnap - (detentsValue.value[targetIndex] ?? 0);
|
|
162
|
-
if (animationTarget.value === targetTranslate && velocity === undefined) {
|
|
163
|
-
currentIndex.set(targetIndex);
|
|
164
|
-
return;
|
|
165
|
-
}
|
|
166
|
-
animationTarget.set(targetTranslate);
|
|
167
|
-
const isOpening = targetTranslate < translateY.value;
|
|
168
|
-
const baseConfig = isOpening ? openAnimationConfig : closeAnimationConfig;
|
|
169
|
-
const springConfig =
|
|
170
|
-
velocity === undefined ? baseConfig : { ...baseConfig, velocity };
|
|
171
|
-
translateY.set(withSpring(targetTranslate, springConfig));
|
|
172
|
-
currentIndex.set(targetIndex);
|
|
173
|
-
},
|
|
174
|
-
[
|
|
175
|
-
animationTarget,
|
|
176
|
-
closeAnimationConfig,
|
|
177
|
-
currentIndex,
|
|
178
|
-
detentsValue,
|
|
179
|
-
openAnimationConfig,
|
|
180
|
-
sheetHeight,
|
|
181
|
-
translateY,
|
|
182
|
-
]
|
|
183
|
-
);
|
|
184
|
-
|
|
185
|
-
useEffect(() => {
|
|
186
|
-
scheduleOnUI(animateToIndex, resolvedIndex);
|
|
187
|
-
}, [animateToIndex, resolvedIndex, normalizedDetents]);
|
|
188
|
-
|
|
189
|
-
const panGesture = useBottomSheetPanGesture({
|
|
190
|
-
animationTarget,
|
|
191
|
-
translateY,
|
|
192
|
-
sheetHeight,
|
|
193
|
-
detentsValue,
|
|
194
|
-
isDraggableValue,
|
|
195
|
-
currentIndex,
|
|
196
|
-
scrollableEntries,
|
|
197
|
-
isScrollableLocked,
|
|
198
|
-
handleIndexChange,
|
|
199
|
-
animateToIndex,
|
|
200
|
-
});
|
|
201
|
-
|
|
202
|
-
const handleSentinelLayout = (event: LayoutChangeEvent) => {
|
|
203
|
-
setContentHeight(event.nativeEvent.layout.y);
|
|
204
|
-
};
|
|
205
|
-
const closedIndex = normalizedDetents.indexOf(0);
|
|
206
|
-
const handleScrimPress = () => {
|
|
207
|
-
if (closedIndex === -1 || resolvedIndex === closedIndex) return;
|
|
208
|
-
handleIndexChange(closedIndex);
|
|
209
|
-
scheduleOnUI(animateToIndex, closedIndex);
|
|
210
|
-
};
|
|
211
|
-
|
|
212
|
-
const wrapperStyle = useAnimatedStyle(() => ({
|
|
213
|
-
transform: [{ translateY: translateY.value }],
|
|
214
|
-
height: sheetHeight.value,
|
|
215
|
-
opacity: translateY.value >= sheetHeight.value ? 0 : 1,
|
|
216
|
-
}));
|
|
217
|
-
const isCollapsed = normalizedDetents[resolvedIndex] === 0;
|
|
218
|
-
const pointerEvents = modal ? (isCollapsed ? 'none' : 'auto') : 'box-none';
|
|
219
|
-
let scrimElement: ReactNode | null = null;
|
|
220
|
-
if (renderScrim !== undefined) {
|
|
221
|
-
scrimElement = renderScrim(scrimProgress);
|
|
222
|
-
} else if (modal) {
|
|
223
|
-
scrimElement = <DefaultScrim progress={scrimProgress} />;
|
|
224
|
-
}
|
|
225
|
-
|
|
226
|
-
const sheetContent = (
|
|
227
|
-
<BottomSheetContextProvider
|
|
228
|
-
value={{
|
|
229
|
-
translateY,
|
|
230
|
-
position: internalPosition,
|
|
231
|
-
index: currentIndex,
|
|
232
|
-
sheetHeight,
|
|
233
|
-
isScrollableLocked,
|
|
234
|
-
registerScrollable,
|
|
235
|
-
panGesture,
|
|
236
|
-
}}
|
|
237
|
-
>
|
|
238
|
-
<Animated.View
|
|
239
|
-
style={[
|
|
240
|
-
{
|
|
241
|
-
position: 'absolute',
|
|
242
|
-
bottom: 0,
|
|
243
|
-
left: 0,
|
|
244
|
-
right: 0,
|
|
245
|
-
},
|
|
246
|
-
wrapperStyle,
|
|
247
|
-
]}
|
|
248
|
-
pointerEvents="box-none"
|
|
249
|
-
>
|
|
250
|
-
<GestureDetector gesture={panGesture}>
|
|
251
|
-
<View style={{ flex: 1 }} pointerEvents="box-none">
|
|
252
|
-
{children}
|
|
253
|
-
<View onLayout={handleSentinelLayout} pointerEvents="none" />
|
|
254
|
-
</View>
|
|
255
|
-
</GestureDetector>
|
|
256
|
-
</Animated.View>
|
|
257
|
-
</BottomSheetContextProvider>
|
|
258
|
-
);
|
|
259
|
-
|
|
260
|
-
const sheetContainer = (
|
|
261
|
-
<Animated.View
|
|
262
|
-
style={StyleSheet.absoluteFill}
|
|
263
|
-
pointerEvents={pointerEvents}
|
|
264
|
-
>
|
|
265
|
-
{modal && scrimElement !== null ? (
|
|
266
|
-
<Pressable style={StyleSheet.absoluteFill} onPress={handleScrimPress}>
|
|
267
|
-
{scrimElement}
|
|
268
|
-
</Pressable>
|
|
269
|
-
) : null}
|
|
270
|
-
{sheetContent}
|
|
271
|
-
</Animated.View>
|
|
272
|
-
);
|
|
273
|
-
if (modal) return <Portal>{sheetContainer}</Portal>;
|
|
274
|
-
|
|
275
|
-
return sheetContainer;
|
|
276
|
-
};
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
import { createContext, useContext } from 'react';
|
|
2
|
-
import type { PanGesture } from 'react-native-gesture-handler';
|
|
3
|
-
import type { AnimatedRef, SharedValue } from 'react-native-reanimated';
|
|
4
|
-
|
|
5
|
-
export interface ScrollableEntry {
|
|
6
|
-
ref: AnimatedRef<any>;
|
|
7
|
-
scrollOffset: SharedValue<number>;
|
|
8
|
-
isGestureActive: SharedValue<boolean>;
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
export interface BottomSheetContextType {
|
|
12
|
-
translateY: SharedValue<number>;
|
|
13
|
-
position: SharedValue<number>;
|
|
14
|
-
index: SharedValue<number>;
|
|
15
|
-
sheetHeight: SharedValue<number>;
|
|
16
|
-
isScrollableLocked: SharedValue<boolean>;
|
|
17
|
-
registerScrollable: (entry: ScrollableEntry) => () => void;
|
|
18
|
-
panGesture: PanGesture;
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
const BottomSheetContext = createContext<BottomSheetContextType | null>(null);
|
|
22
|
-
|
|
23
|
-
export const BottomSheetContextProvider = BottomSheetContext.Provider;
|
|
24
|
-
|
|
25
|
-
export const useBottomSheetContext = () => {
|
|
26
|
-
const context = useContext(BottomSheetContext);
|
|
27
|
-
if (context === null) {
|
|
28
|
-
throw new Error(
|
|
29
|
-
'`useBottomSheetContext` must be used within `BottomSheet`.'
|
|
30
|
-
);
|
|
31
|
-
}
|
|
32
|
-
return context;
|
|
33
|
-
};
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
import { FlatList, type NativeScrollEvent } from 'react-native';
|
|
2
|
-
import type {
|
|
3
|
-
FlatListPropsWithLayout,
|
|
4
|
-
SharedValue,
|
|
5
|
-
} from 'react-native-reanimated';
|
|
6
|
-
import type { Ref, ReactElement } from 'react';
|
|
7
|
-
|
|
8
|
-
import { bottomSheetScrollable } from './bottomSheetScrollable';
|
|
9
|
-
|
|
10
|
-
export type BottomSheetFlatListProps<T> = Omit<
|
|
11
|
-
FlatListPropsWithLayout<T>,
|
|
12
|
-
'onScroll' | 'scrollEnabled' | 'ref'
|
|
13
|
-
> & {
|
|
14
|
-
scrollEnabled?: boolean | SharedValue<boolean | undefined>;
|
|
15
|
-
onScroll?: (event: NativeScrollEvent) => void;
|
|
16
|
-
ref?: Ref<FlatList<T>>;
|
|
17
|
-
};
|
|
18
|
-
|
|
19
|
-
export const BottomSheetFlatList = bottomSheetScrollable(FlatList) as <T>(
|
|
20
|
-
props: BottomSheetFlatListProps<T>
|
|
21
|
-
) => ReactElement;
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
import type { Ref, ReactElement } from 'react';
|
|
2
|
-
import {
|
|
3
|
-
ScrollView,
|
|
4
|
-
type NativeScrollEvent,
|
|
5
|
-
type ScrollViewProps,
|
|
6
|
-
} from 'react-native';
|
|
7
|
-
import type { SharedValue } from 'react-native-reanimated';
|
|
8
|
-
|
|
9
|
-
import { bottomSheetScrollable } from './bottomSheetScrollable';
|
|
10
|
-
|
|
11
|
-
export type BottomSheetScrollViewProps = Omit<
|
|
12
|
-
ScrollViewProps,
|
|
13
|
-
'onScroll' | 'scrollEnabled' | 'ref'
|
|
14
|
-
> & {
|
|
15
|
-
scrollEnabled?: boolean | SharedValue<boolean | undefined>;
|
|
16
|
-
onScroll?: (event: NativeScrollEvent) => void;
|
|
17
|
-
ref?: Ref<ScrollView>;
|
|
18
|
-
};
|
|
19
|
-
|
|
20
|
-
export const BottomSheetScrollView = bottomSheetScrollable(ScrollView) as (
|
|
21
|
-
props: BottomSheetScrollViewProps
|
|
22
|
-
) => ReactElement;
|
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
import { type ComponentType, type Ref, useImperativeHandle } from 'react';
|
|
2
|
-
import type { NativeScrollEvent } from 'react-native';
|
|
3
|
-
import { GestureDetector } from 'react-native-gesture-handler';
|
|
4
|
-
import Animated, { type SharedValue } from 'react-native-reanimated';
|
|
5
|
-
|
|
6
|
-
import { useBottomSheetScrollable } from './useBottomSheetScrollable';
|
|
7
|
-
|
|
8
|
-
export function bottomSheetScrollable<
|
|
9
|
-
P extends Record<string, any>,
|
|
10
|
-
R = unknown
|
|
11
|
-
>(ScrollableComponent: ComponentType<P>) {
|
|
12
|
-
const AnimatedComponent =
|
|
13
|
-
Animated.createAnimatedComponent(ScrollableComponent);
|
|
14
|
-
|
|
15
|
-
return ({
|
|
16
|
-
scrollEnabled,
|
|
17
|
-
onScroll,
|
|
18
|
-
ref,
|
|
19
|
-
...rest
|
|
20
|
-
}: Omit<P, 'onScroll' | 'scrollEnabled' | 'ref'> & {
|
|
21
|
-
scrollEnabled?: boolean | SharedValue<boolean | undefined>;
|
|
22
|
-
onScroll?: (event: NativeScrollEvent) => void;
|
|
23
|
-
ref?: Ref<R>;
|
|
24
|
-
}) => {
|
|
25
|
-
const { scrollHandler, scrollableRef, nativeGesture, animatedProps } =
|
|
26
|
-
useBottomSheetScrollable(scrollEnabled, onScroll);
|
|
27
|
-
|
|
28
|
-
useImperativeHandle(ref, () => scrollableRef.current as R, [scrollableRef]);
|
|
29
|
-
|
|
30
|
-
return (
|
|
31
|
-
<GestureDetector gesture={nativeGesture}>
|
|
32
|
-
<AnimatedComponent
|
|
33
|
-
{...(rest as any)}
|
|
34
|
-
animatedProps={animatedProps}
|
|
35
|
-
ref={scrollableRef}
|
|
36
|
-
onScroll={scrollHandler}
|
|
37
|
-
scrollEventThrottle={16}
|
|
38
|
-
/>
|
|
39
|
-
</GestureDetector>
|
|
40
|
-
);
|
|
41
|
-
};
|
|
42
|
-
}
|