react-native-bottom-sheet-stack 0.1.0
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/LICENSE +20 -0
- package/README.md +82 -0
- package/lib/commonjs/BottomSheet.context.js +14 -0
- package/lib/commonjs/BottomSheet.context.js.map +1 -0
- package/lib/commonjs/BottomSheetHost.js +73 -0
- package/lib/commonjs/BottomSheetHost.js.map +1 -0
- package/lib/commonjs/BottomSheetManaged.js +72 -0
- package/lib/commonjs/BottomSheetManaged.js.map +1 -0
- package/lib/commonjs/BottomSheetManager.provider.js +39 -0
- package/lib/commonjs/BottomSheetManager.provider.js.map +1 -0
- package/lib/commonjs/bottomSheet.store.js +101 -0
- package/lib/commonjs/bottomSheet.store.js.map +1 -0
- package/lib/commonjs/bottomSheetCoordinator.js +43 -0
- package/lib/commonjs/bottomSheetCoordinator.js.map +1 -0
- package/lib/commonjs/index.js +41 -0
- package/lib/commonjs/index.js.map +1 -0
- package/lib/commonjs/package.json +1 -0
- package/lib/commonjs/refsMap.js +8 -0
- package/lib/commonjs/refsMap.js.map +1 -0
- package/lib/commonjs/useBottomSheetManager.js +78 -0
- package/lib/commonjs/useBottomSheetManager.js.map +1 -0
- package/lib/commonjs/useBottomSheetState.js +27 -0
- package/lib/commonjs/useBottomSheetState.js.map +1 -0
- package/lib/typescript/example/src/App.d.ts +4 -0
- package/lib/typescript/example/src/App.d.ts.map +1 -0
- package/lib/typescript/src/BottomSheet.context.d.ts +7 -0
- package/lib/typescript/src/BottomSheet.context.d.ts.map +1 -0
- package/lib/typescript/src/BottomSheetHost.d.ts +5 -0
- package/lib/typescript/src/BottomSheetHost.d.ts.map +1 -0
- package/lib/typescript/src/BottomSheetManaged.d.ts +10 -0
- package/lib/typescript/src/BottomSheetManaged.d.ts.map +1 -0
- package/lib/typescript/src/BottomSheetManager.provider.d.ts +14 -0
- package/lib/typescript/src/BottomSheetManager.provider.d.ts.map +1 -0
- package/lib/typescript/src/bottomSheet.store.d.ts +32 -0
- package/lib/typescript/src/bottomSheet.store.d.ts.map +1 -0
- package/lib/typescript/src/bottomSheetCoordinator.d.ts +2 -0
- package/lib/typescript/src/bottomSheetCoordinator.d.ts.map +1 -0
- package/lib/typescript/src/index.d.ts +6 -0
- package/lib/typescript/src/index.d.ts.map +1 -0
- package/lib/typescript/src/refsMap.d.ts +3 -0
- package/lib/typescript/src/refsMap.d.ts.map +1 -0
- package/lib/typescript/src/useBottomSheetManager.d.ts +22 -0
- package/lib/typescript/src/useBottomSheetManager.d.ts.map +1 -0
- package/lib/typescript/src/useBottomSheetState.d.ts +6 -0
- package/lib/typescript/src/useBottomSheetState.d.ts.map +1 -0
- package/package.json +130 -0
- package/src/BottomSheet.context.ts +15 -0
- package/src/BottomSheetHost.tsx +70 -0
- package/src/BottomSheetManaged.tsx +89 -0
- package/src/BottomSheetManager.provider.tsx +39 -0
- package/src/bottomSheet.store.ts +107 -0
- package/src/bottomSheetCoordinator.ts +34 -0
- package/src/index.tsx +5 -0
- package/src/refsMap.ts +6 -0
- package/src/useBottomSheetManager.tsx +87 -0
- package/src/useBottomSheetState.ts +31 -0
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.useBottomSheetState = useBottomSheetState;
|
|
7
|
+
var _BottomSheet = require("./BottomSheet.context");
|
|
8
|
+
var _bottomSheet = require("./bottomSheet.store");
|
|
9
|
+
function useBottomSheetState() {
|
|
10
|
+
const context = (0, _BottomSheet.useMaybeBottomSheetContext)();
|
|
11
|
+
const {
|
|
12
|
+
bottomSheetsStack,
|
|
13
|
+
startClosing
|
|
14
|
+
} = (0, _bottomSheet.useBottomSheetStore)(store => ({
|
|
15
|
+
bottomSheetsStack: store.stack,
|
|
16
|
+
startClosing: store.startClosing
|
|
17
|
+
}));
|
|
18
|
+
const bottomSheetState = bottomSheetsStack.find(bottomSheet => bottomSheet.id === context?.id);
|
|
19
|
+
if (!bottomSheetState) {
|
|
20
|
+
throw new Error('useBottomSheetState must be used within a BottomSheetProvider');
|
|
21
|
+
}
|
|
22
|
+
return {
|
|
23
|
+
bottomSheetState,
|
|
24
|
+
close: () => startClosing(bottomSheetState.id)
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
//# sourceMappingURL=useBottomSheetState.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["_BottomSheet","require","_bottomSheet","useBottomSheetState","context","useMaybeBottomSheetContext","bottomSheetsStack","startClosing","useBottomSheetStore","store","stack","bottomSheetState","find","bottomSheet","id","Error","close"],"sourceRoot":"../../src","sources":["useBottomSheetState.ts"],"mappings":";;;;;;AAAA,IAAAA,YAAA,GAAAC,OAAA;AACA,IAAAC,YAAA,GAAAD,OAAA;AAKO,SAASE,mBAAmBA,CAAA,EAGjC;EACA,MAAMC,OAAO,GAAG,IAAAC,uCAA0B,EAAC,CAAC;EAC5C,MAAM;IAAEC,iBAAiB;IAAEC;EAAa,CAAC,GAAG,IAAAC,gCAAmB,EAAEC,KAAK,KAAM;IAC1EH,iBAAiB,EAAEG,KAAK,CAACC,KAAK;IAC9BH,YAAY,EAAEE,KAAK,CAACF;EACtB,CAAC,CAAC,CAAC;EAEH,MAAMI,gBAAgB,GAAGL,iBAAiB,CAACM,IAAI,CAC5CC,WAAW,IAAKA,WAAW,CAACC,EAAE,KAAKV,OAAO,EAAEU,EAC/C,CAAC;EAED,IAAI,CAACH,gBAAgB,EAAE;IACrB,MAAM,IAAII,KAAK,CACb,+DACF,CAAC;EACH;EAEA,OAAO;IACLJ,gBAAgB;IAChBK,KAAK,EAAEA,CAAA,KAAMT,YAAY,CAACI,gBAAgB,CAACG,EAAE;EAC/C,CAAC;AACH","ignoreList":[]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"App.d.ts","sourceRoot":"","sources":["../../../../example/src/App.tsx"],"names":[],"mappings":"AAQA,OAAO,EAAc,KAAK,iBAAiB,EAAE,MAAM,OAAO,CAAC;AAO3D,MAAM,CAAC,OAAO,UAAU,GAAG,4CAY1B;AAmBD,eAAO,MAAM,OAAO,GAAI,IAAI,iBAAiB,4CAU5C,CAAC"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
interface BottomSheetContextValue {
|
|
2
|
+
id: string;
|
|
3
|
+
}
|
|
4
|
+
export declare const BottomSheetContext: import("react").Context<BottomSheetContextValue | undefined>;
|
|
5
|
+
export declare function useMaybeBottomSheetContext(): BottomSheetContextValue | undefined;
|
|
6
|
+
export {};
|
|
7
|
+
//# sourceMappingURL=BottomSheet.context.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"BottomSheet.context.d.ts","sourceRoot":"","sources":["../../../src/BottomSheet.context.ts"],"names":[],"mappings":"AAEA,UAAU,uBAAuB;IAC/B,EAAE,EAAE,MAAM,CAAC;CACZ;AAED,eAAO,MAAM,kBAAkB,8DAEnB,CAAC;AAEb,wBAAgB,0BAA0B,wCAIzC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"BottomSheetHost.d.ts","sourceRoot":"","sources":["../../../src/BottomSheetHost.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAqD,MAAM,OAAO,CAAC;AAU1E,iBAAS,mBAAmB,4CA2C3B;AASD,eAAO,MAAM,eAAe,uDAAkC,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { type BottomSheetProps } from '@gorhom/bottom-sheet';
|
|
2
|
+
import { type BottomSheetMethods } from '@gorhom/bottom-sheet/lib/typescript/types';
|
|
3
|
+
import React from 'react';
|
|
4
|
+
export interface BottomSheetRef extends BottomSheetMethods {
|
|
5
|
+
}
|
|
6
|
+
interface BottomSheetManagedProps extends BottomSheetProps {
|
|
7
|
+
}
|
|
8
|
+
export declare const BottomSheetManaged: React.ForwardRefExoticComponent<BottomSheetManagedProps & React.RefAttributes<BottomSheetRef>>;
|
|
9
|
+
export {};
|
|
10
|
+
//# sourceMappingURL=BottomSheetManaged.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"BottomSheetManaged.d.ts","sourceRoot":"","sources":["../../../src/BottomSheetManaged.tsx"],"names":[],"mappings":"AAAA,OAA4B,EAG1B,KAAK,gBAAgB,EACtB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAE,KAAK,kBAAkB,EAAE,MAAM,2CAA2C,CAAC;AACpF,OAAO,KAAK,MAAM,OAAO,CAAC;AAQ1B,MAAM,WAAW,cAAe,SAAQ,kBAAkB;CAAG;AAE7D,UAAU,uBAAwB,SAAQ,gBAAgB;CAAG;AAE7D,eAAO,MAAM,kBAAkB,gGAsE9B,CAAC"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import React, { type PropsWithChildren } from 'react';
|
|
2
|
+
interface Props extends PropsWithChildren {
|
|
3
|
+
id: string;
|
|
4
|
+
}
|
|
5
|
+
declare function BottomSheetManagerProviderComp({ id, children }: Props): import("react/jsx-runtime").JSX.Element;
|
|
6
|
+
export declare const BottomSheetManagerProvider: React.MemoExoticComponent<typeof BottomSheetManagerProviderComp>;
|
|
7
|
+
export declare const useBottomSheetManagerContext: () => {
|
|
8
|
+
groupId: string;
|
|
9
|
+
};
|
|
10
|
+
export declare const useMaybeBottomSheetManagerContext: () => {
|
|
11
|
+
groupId: string;
|
|
12
|
+
} | null;
|
|
13
|
+
export {};
|
|
14
|
+
//# sourceMappingURL=BottomSheetManager.provider.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"BottomSheetManager.provider.d.ts","sourceRoot":"","sources":["../../../src/BottomSheetManager.provider.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,KAAK,iBAAiB,EAAE,MAAM,OAAO,CAAC;AAItD,UAAU,KAAM,SAAQ,iBAAiB;IACvC,EAAE,EAAE,MAAM,CAAC;CACZ;AAED,iBAAS,8BAA8B,CAAC,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,KAAK,2CAM9D;AAED,eAAO,MAAM,0BAA0B,kEAEtC,CAAC;AAEF,eAAO,MAAM,4BAA4B;aAlBM,MAAM;CA2BpD,CAAC;AAEF,eAAO,MAAM,iCAAiC;aA7BC,MAAM;QAoCpD,CAAC"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { type ReactNode } from 'react';
|
|
2
|
+
export type BottomSheetStatus = 'opening' | 'open' | 'closing' | 'hidden';
|
|
3
|
+
export type OpenMode = 'push' | 'switch' | 'replace';
|
|
4
|
+
export interface BottomSheetState {
|
|
5
|
+
groupId: string;
|
|
6
|
+
id: string;
|
|
7
|
+
content: ReactNode;
|
|
8
|
+
status: BottomSheetStatus;
|
|
9
|
+
}
|
|
10
|
+
type TriggerState = Omit<BottomSheetState, 'status'>;
|
|
11
|
+
interface BottomSheetStoreState {
|
|
12
|
+
stack: BottomSheetState[];
|
|
13
|
+
}
|
|
14
|
+
interface BottomSheetStoreActions {
|
|
15
|
+
push(sheet: TriggerState): void;
|
|
16
|
+
switch(sheet: TriggerState): void;
|
|
17
|
+
replace(sheet: TriggerState): void;
|
|
18
|
+
startClosing(id: string): void;
|
|
19
|
+
finishClosing(id: string): void;
|
|
20
|
+
clearAll(): void;
|
|
21
|
+
}
|
|
22
|
+
export declare const useBottomSheetStore: import("zustand/traditional").UseBoundStoreWithEqualityFn<Omit<import("zustand/vanilla").StoreApi<BottomSheetStoreState & BottomSheetStoreActions>, "subscribe"> & {
|
|
23
|
+
subscribe: {
|
|
24
|
+
(listener: (selectedState: BottomSheetStoreState & BottomSheetStoreActions, previousSelectedState: BottomSheetStoreState & BottomSheetStoreActions) => void): () => void;
|
|
25
|
+
<U>(selector: (state: BottomSheetStoreState & BottomSheetStoreActions) => U, listener: (selectedState: U, previousSelectedState: U) => void, options?: {
|
|
26
|
+
equalityFn?: ((a: U, b: U) => boolean) | undefined;
|
|
27
|
+
fireImmediately?: boolean;
|
|
28
|
+
} | undefined): () => void;
|
|
29
|
+
};
|
|
30
|
+
}>;
|
|
31
|
+
export {};
|
|
32
|
+
//# sourceMappingURL=bottomSheet.store.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bottomSheet.store.d.ts","sourceRoot":"","sources":["../../../src/bottomSheet.store.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAIvC,MAAM,MAAM,iBAAiB,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,GAAG,QAAQ,CAAC;AAC1E,MAAM,MAAM,QAAQ,GAAG,MAAM,GAAG,QAAQ,GAAG,SAAS,CAAC;AAErD,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,MAAM,CAAC;IAChB,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,SAAS,CAAC;IACnB,MAAM,EAAE,iBAAiB,CAAC;CAC3B;AAED,KAAK,YAAY,GAAG,IAAI,CAAC,gBAAgB,EAAE,QAAQ,CAAC,CAAC;AAErD,UAAU,qBAAqB;IAC7B,KAAK,EAAE,gBAAgB,EAAE,CAAC;CAC3B;AAED,UAAU,uBAAuB;IAC/B,IAAI,CAAC,KAAK,EAAE,YAAY,GAAG,IAAI,CAAC;IAChC,MAAM,CAAC,KAAK,EAAE,YAAY,GAAG,IAAI,CAAC;IAClC,OAAO,CAAC,KAAK,EAAE,YAAY,GAAG,IAAI,CAAC;IACnC,YAAY,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,aAAa,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,QAAQ,IAAI,IAAI,CAAC;CAClB;AAED,eAAO,MAAM,mBAAmB;;;;;;;;EA6E/B,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bottomSheetCoordinator.d.ts","sourceRoot":"","sources":["../../../src/bottomSheetCoordinator.ts"],"names":[],"mappings":"AAGA,wBAAgB,0BAA0B,SA8BzC"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export { BottomSheetHost } from './BottomSheetHost';
|
|
2
|
+
export { BottomSheetManagerProvider } from './BottomSheetManager.provider';
|
|
3
|
+
export { useBottomSheetManager } from './useBottomSheetManager';
|
|
4
|
+
export { useBottomSheetState } from './useBottomSheetState';
|
|
5
|
+
export { BottomSheetManaged } from './BottomSheetManaged';
|
|
6
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/index.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,EAAE,0BAA0B,EAAE,MAAM,+BAA+B,CAAC;AAC3E,OAAO,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAC;AAChE,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAC5D,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"refsMap.d.ts","sourceRoot":"","sources":["../../../src/refsMap.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,2CAA2C,CAAC;AAEpF,eAAO,MAAM,SAAS,EAAE,MAAM,CAC5B,MAAM,EACN,KAAK,CAAC,SAAS,CAAC,kBAAkB,GAAG,IAAI,CAAC,CACtC,CAAC"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { type OpenMode } from './bottomSheet.store';
|
|
3
|
+
export declare const useBottomSheetManager: () => {
|
|
4
|
+
clearAll: () => void;
|
|
5
|
+
closeTop: () => void;
|
|
6
|
+
openBottomSheet: (content: React.ReactElement, options?: {
|
|
7
|
+
id?: string;
|
|
8
|
+
groupId?: string;
|
|
9
|
+
mode?: OpenMode;
|
|
10
|
+
}) => string;
|
|
11
|
+
pushBottomSheet: (sheet: {
|
|
12
|
+
groupId: string;
|
|
13
|
+
id: string;
|
|
14
|
+
content: React.ReactNode;
|
|
15
|
+
}) => void;
|
|
16
|
+
replaceBottomSheet: (sheet: {
|
|
17
|
+
groupId: string;
|
|
18
|
+
id: string;
|
|
19
|
+
content: React.ReactNode;
|
|
20
|
+
}) => void;
|
|
21
|
+
};
|
|
22
|
+
//# sourceMappingURL=useBottomSheetManager.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useBottomSheetManager.d.ts","sourceRoot":"","sources":["../../../src/useBottomSheetManager.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,OAAO,EAAuB,KAAK,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAKzE,eAAO,MAAM,qBAAqB;;;+BAoBrB,KAAK,CAAC,YAAY,YAClB;QACP,EAAE,CAAC,EAAE,MAAM,CAAC;QACZ,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,IAAI,CAAC,EAAE,QAAQ,CAAC;KACjB;;;;;;;;;;;CAsDJ,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useBottomSheetState.d.ts","sourceRoot":"","sources":["../../../src/useBottomSheetState.ts"],"names":[],"mappings":"AACA,OAAO,EAEL,KAAK,gBAAgB,EACtB,MAAM,qBAAqB,CAAC;AAE7B,wBAAgB,mBAAmB,IAAI;IACrC,gBAAgB,EAAE,gBAAgB,CAAC;IACnC,KAAK,EAAE,MAAM,IAAI,CAAC;CACnB,CAqBA"}
|
package/package.json
ADDED
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "react-native-bottom-sheet-stack",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Bottom Sheet Stack Manager",
|
|
5
|
+
"source": "./src/index.tsx",
|
|
6
|
+
"main": "lib/commonjs/index.js",
|
|
7
|
+
"types": "lib/typescript/src/index.d.ts",
|
|
8
|
+
"files": [
|
|
9
|
+
"src",
|
|
10
|
+
"lib/typescript",
|
|
11
|
+
"lib/commonjs"
|
|
12
|
+
],
|
|
13
|
+
"scripts": {
|
|
14
|
+
"example": "yarn workspace react-native-bottom-sheet-stack-example",
|
|
15
|
+
"test": "jest",
|
|
16
|
+
"typecheck": "tsc",
|
|
17
|
+
"lint": "eslint \"**/*.{js,ts,tsx}\"",
|
|
18
|
+
"clean": "del-cli lib",
|
|
19
|
+
"prepare": "bob build",
|
|
20
|
+
"release": "release-it"
|
|
21
|
+
},
|
|
22
|
+
"keywords": [
|
|
23
|
+
"react-native",
|
|
24
|
+
"ios",
|
|
25
|
+
"android"
|
|
26
|
+
],
|
|
27
|
+
"repository": {
|
|
28
|
+
"type": "git",
|
|
29
|
+
"url": "git+https://github.com/arekkubaczkowski/react-native-bottom-sheet-stack.git"
|
|
30
|
+
},
|
|
31
|
+
"author": "Arek Kubaczkowski <arek.kubaczkowski@gmail.com> (https://github.com/arekkubaczkowski)",
|
|
32
|
+
"license": "MIT",
|
|
33
|
+
"bugs": {
|
|
34
|
+
"url": "https://github.com/arekkubaczkowski/react-native-bottom-sheet-stack/issues"
|
|
35
|
+
},
|
|
36
|
+
"homepage": "https://github.com/arekkubaczkowski/react-native-bottom-sheet-stack#readme",
|
|
37
|
+
"publishConfig": {
|
|
38
|
+
"registry": "https://registry.npmjs.org/"
|
|
39
|
+
},
|
|
40
|
+
"devDependencies": {
|
|
41
|
+
"@commitlint/config-conventional": "^19.6.0",
|
|
42
|
+
"@eslint/compat": "^1.2.7",
|
|
43
|
+
"@eslint/eslintrc": "^3.3.0",
|
|
44
|
+
"@eslint/js": "^9.22.0",
|
|
45
|
+
"@evilmartians/lefthook": "^1.5.0",
|
|
46
|
+
"@gorhom/bottom-sheet": "^5.1.2",
|
|
47
|
+
"@react-native/eslint-config": "^0.78.0",
|
|
48
|
+
"@release-it/conventional-changelog": "^9.0.2",
|
|
49
|
+
"@types/jest": "^29.5.5",
|
|
50
|
+
"@types/react": "^19.0.12",
|
|
51
|
+
"commitlint": "^19.6.1",
|
|
52
|
+
"del-cli": "^5.1.0",
|
|
53
|
+
"eslint": "^9.22.0",
|
|
54
|
+
"eslint-config-prettier": "^10.1.1",
|
|
55
|
+
"eslint-plugin-prettier": "^5.2.3",
|
|
56
|
+
"jest": "^29.7.0",
|
|
57
|
+
"prettier": "^3.0.3",
|
|
58
|
+
"react": "18.3.1",
|
|
59
|
+
"react-native": "0.76.9",
|
|
60
|
+
"react-native-builder-bob": "^0.40.6",
|
|
61
|
+
"react-native-gesture-handler": "^2.25.0",
|
|
62
|
+
"react-native-reanimated": "^3.17.4",
|
|
63
|
+
"release-it": "^17.10.0",
|
|
64
|
+
"typescript": "^5.2.2",
|
|
65
|
+
"zustand": "^5.0.3"
|
|
66
|
+
},
|
|
67
|
+
"peerDependencies": {
|
|
68
|
+
"@gorhom/bottom-sheet": ">=5.0.0",
|
|
69
|
+
"react": "*",
|
|
70
|
+
"react-native": "*",
|
|
71
|
+
"react-native-gesture-handler": ">=2.0.0",
|
|
72
|
+
"react-native-reanimated": ">=3.0.0",
|
|
73
|
+
"zustand": ">=5.0.0"
|
|
74
|
+
},
|
|
75
|
+
"workspaces": [
|
|
76
|
+
"example"
|
|
77
|
+
],
|
|
78
|
+
"packageManager": "yarn@3.6.1",
|
|
79
|
+
"jest": {
|
|
80
|
+
"preset": "react-native",
|
|
81
|
+
"modulePathIgnorePatterns": [
|
|
82
|
+
"<rootDir>/example/node_modules",
|
|
83
|
+
"<rootDir>/lib/"
|
|
84
|
+
]
|
|
85
|
+
},
|
|
86
|
+
"commitlint": {
|
|
87
|
+
"extends": [
|
|
88
|
+
"@commitlint/config-conventional"
|
|
89
|
+
]
|
|
90
|
+
},
|
|
91
|
+
"release-it": {
|
|
92
|
+
"git": {
|
|
93
|
+
"commitMessage": "chore: release ${version}",
|
|
94
|
+
"tagName": "v${version}"
|
|
95
|
+
},
|
|
96
|
+
"npm": {
|
|
97
|
+
"publish": true
|
|
98
|
+
},
|
|
99
|
+
"github": {
|
|
100
|
+
"release": true
|
|
101
|
+
},
|
|
102
|
+
"plugins": {
|
|
103
|
+
"@release-it/conventional-changelog": {
|
|
104
|
+
"preset": {
|
|
105
|
+
"name": "angular"
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
},
|
|
110
|
+
"prettier": {
|
|
111
|
+
"quoteProps": "consistent",
|
|
112
|
+
"singleQuote": true,
|
|
113
|
+
"tabWidth": 2,
|
|
114
|
+
"trailingComma": "es5",
|
|
115
|
+
"useTabs": false
|
|
116
|
+
},
|
|
117
|
+
"react-native-builder-bob": {
|
|
118
|
+
"source": "src",
|
|
119
|
+
"output": "lib",
|
|
120
|
+
"targets": [
|
|
121
|
+
"commonjs",
|
|
122
|
+
"typescript"
|
|
123
|
+
]
|
|
124
|
+
},
|
|
125
|
+
"create-react-native-library": {
|
|
126
|
+
"languages": "js",
|
|
127
|
+
"type": "library",
|
|
128
|
+
"version": "0.49.8"
|
|
129
|
+
}
|
|
130
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { createContext, useContext } from 'react';
|
|
2
|
+
|
|
3
|
+
interface BottomSheetContextValue {
|
|
4
|
+
id: string;
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
export const BottomSheetContext = createContext<
|
|
8
|
+
BottomSheetContextValue | undefined
|
|
9
|
+
>(undefined);
|
|
10
|
+
|
|
11
|
+
export function useMaybeBottomSheetContext() {
|
|
12
|
+
const context = useContext(BottomSheetContext);
|
|
13
|
+
|
|
14
|
+
return context;
|
|
15
|
+
}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import React, { useEffect, useMemo, type PropsWithChildren } from 'react';
|
|
2
|
+
import { StyleSheet, useWindowDimensions, View } from 'react-native';
|
|
3
|
+
|
|
4
|
+
import { BottomSheetContext } from './BottomSheet.context';
|
|
5
|
+
import { useBottomSheetStore } from './bottomSheet.store';
|
|
6
|
+
import { initBottomSheetCoordinator } from './bottomSheetCoordinator';
|
|
7
|
+
import { useBottomSheetManagerContext } from './BottomSheetManager.provider';
|
|
8
|
+
|
|
9
|
+
initBottomSheetCoordinator();
|
|
10
|
+
|
|
11
|
+
function BottomSheetHostComp() {
|
|
12
|
+
const { bottomSheetsStack, clearAll } = useBottomSheetStore((store) => ({
|
|
13
|
+
bottomSheetsStack: store.stack,
|
|
14
|
+
clearAll: store.clearAll,
|
|
15
|
+
}));
|
|
16
|
+
|
|
17
|
+
const { width, height } = useWindowDimensions();
|
|
18
|
+
const { groupId } = useBottomSheetManagerContext();
|
|
19
|
+
|
|
20
|
+
const filteredQueue = useMemo(
|
|
21
|
+
() =>
|
|
22
|
+
bottomSheetsStack.filter(
|
|
23
|
+
(bottomSheet) => bottomSheet.groupId === groupId
|
|
24
|
+
),
|
|
25
|
+
[bottomSheetsStack, groupId]
|
|
26
|
+
);
|
|
27
|
+
|
|
28
|
+
useEffect(() => {
|
|
29
|
+
return () => {
|
|
30
|
+
clearAll();
|
|
31
|
+
};
|
|
32
|
+
}, [clearAll]);
|
|
33
|
+
|
|
34
|
+
return (
|
|
35
|
+
<>
|
|
36
|
+
{filteredQueue.map(({ id, content }) => (
|
|
37
|
+
<BottomSheetContext.Provider key={id} value={{ id }}>
|
|
38
|
+
<View
|
|
39
|
+
style={[
|
|
40
|
+
StyleSheet.absoluteFillObject,
|
|
41
|
+
styles.container,
|
|
42
|
+
{
|
|
43
|
+
width,
|
|
44
|
+
height,
|
|
45
|
+
},
|
|
46
|
+
]}
|
|
47
|
+
>
|
|
48
|
+
<MemoizedContent id={id}>{content}</MemoizedContent>
|
|
49
|
+
</View>
|
|
50
|
+
</BottomSheetContext.Provider>
|
|
51
|
+
))}
|
|
52
|
+
</>
|
|
53
|
+
);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
const MemoizedContent = React.memo(
|
|
57
|
+
({ children }: PropsWithChildren<{ id: string }>) => <>{children}</>,
|
|
58
|
+
(prevProps, nextProps) => {
|
|
59
|
+
return prevProps.id === nextProps.id;
|
|
60
|
+
}
|
|
61
|
+
);
|
|
62
|
+
|
|
63
|
+
export const BottomSheetHost = React.memo(BottomSheetHostComp);
|
|
64
|
+
|
|
65
|
+
const styles = StyleSheet.create({
|
|
66
|
+
container: {
|
|
67
|
+
zIndex: 100_000_000,
|
|
68
|
+
pointerEvents: 'box-none',
|
|
69
|
+
},
|
|
70
|
+
});
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import BottomSheetOriginal, {
|
|
2
|
+
BottomSheetBackdrop,
|
|
3
|
+
useBottomSheetSpringConfigs,
|
|
4
|
+
type BottomSheetProps,
|
|
5
|
+
} from '@gorhom/bottom-sheet';
|
|
6
|
+
import { type BottomSheetMethods } from '@gorhom/bottom-sheet/lib/typescript/types';
|
|
7
|
+
import React from 'react';
|
|
8
|
+
|
|
9
|
+
import {
|
|
10
|
+
useBottomSheetStore,
|
|
11
|
+
type BottomSheetStatus,
|
|
12
|
+
} from './bottomSheet.store';
|
|
13
|
+
import { useBottomSheetState } from './useBottomSheetState';
|
|
14
|
+
|
|
15
|
+
export interface BottomSheetRef extends BottomSheetMethods {}
|
|
16
|
+
|
|
17
|
+
interface BottomSheetManagedProps extends BottomSheetProps {}
|
|
18
|
+
|
|
19
|
+
export const BottomSheetManaged = React.forwardRef<
|
|
20
|
+
BottomSheetRef,
|
|
21
|
+
BottomSheetManagedProps
|
|
22
|
+
>(
|
|
23
|
+
(
|
|
24
|
+
{ children, onAnimate, onClose, enablePanDownToClose = true, ...props },
|
|
25
|
+
ref
|
|
26
|
+
) => {
|
|
27
|
+
const { startClosing, finishClosing } = useBottomSheetStore.getState();
|
|
28
|
+
const { bottomSheetState } = useBottomSheetState();
|
|
29
|
+
|
|
30
|
+
const handleOnAnimate: BottomSheetProps['onAnimate'] = (
|
|
31
|
+
from: number,
|
|
32
|
+
to: number
|
|
33
|
+
) => {
|
|
34
|
+
if (to === -1) {
|
|
35
|
+
if (
|
|
36
|
+
bottomSheetState.status === 'open' ||
|
|
37
|
+
bottomSheetState.status === 'opening'
|
|
38
|
+
) {
|
|
39
|
+
startClosing(bottomSheetState.id);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
if (from === -1 && to >= 0) {
|
|
43
|
+
const currentState = useBottomSheetStore.getState();
|
|
44
|
+
useBottomSheetStore.setState({
|
|
45
|
+
stack: currentState.stack.map((s) =>
|
|
46
|
+
s.id === bottomSheetState.id
|
|
47
|
+
? { ...s, status: 'open' as BottomSheetStatus }
|
|
48
|
+
: s
|
|
49
|
+
),
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
onAnimate?.(from, to);
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
const config = useBottomSheetSpringConfigs({
|
|
56
|
+
stiffness: 400,
|
|
57
|
+
damping: 80,
|
|
58
|
+
mass: 0.7,
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
const handleClose = () => {
|
|
62
|
+
onClose?.();
|
|
63
|
+
|
|
64
|
+
if (bottomSheetState.status !== 'hidden') {
|
|
65
|
+
finishClosing(bottomSheetState.id);
|
|
66
|
+
}
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
return (
|
|
70
|
+
<BottomSheetOriginal
|
|
71
|
+
animationConfigs={config}
|
|
72
|
+
ref={ref}
|
|
73
|
+
{...props}
|
|
74
|
+
onClose={handleClose}
|
|
75
|
+
onAnimate={handleOnAnimate}
|
|
76
|
+
enablePanDownToClose={enablePanDownToClose}
|
|
77
|
+
backdropComponent={(props) => (
|
|
78
|
+
<BottomSheetBackdrop
|
|
79
|
+
{...props}
|
|
80
|
+
disappearsOnIndex={-1}
|
|
81
|
+
appearsOnIndex={0}
|
|
82
|
+
/>
|
|
83
|
+
)}
|
|
84
|
+
>
|
|
85
|
+
{children}
|
|
86
|
+
</BottomSheetOriginal>
|
|
87
|
+
);
|
|
88
|
+
}
|
|
89
|
+
);
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import React, { type PropsWithChildren } from 'react';
|
|
2
|
+
|
|
3
|
+
const Context = React.createContext<{ groupId: string } | null>(null);
|
|
4
|
+
|
|
5
|
+
interface Props extends PropsWithChildren {
|
|
6
|
+
id: string;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
function BottomSheetManagerProviderComp({ id, children }: Props) {
|
|
10
|
+
return (
|
|
11
|
+
<Context.Provider key={id} value={{ groupId: id }}>
|
|
12
|
+
{children}
|
|
13
|
+
</Context.Provider>
|
|
14
|
+
);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export const BottomSheetManagerProvider = React.memo(
|
|
18
|
+
BottomSheetManagerProviderComp,
|
|
19
|
+
);
|
|
20
|
+
|
|
21
|
+
export const useBottomSheetManagerContext = () => {
|
|
22
|
+
const context = React.useContext(Context);
|
|
23
|
+
|
|
24
|
+
if (!context) {
|
|
25
|
+
throw new Error(
|
|
26
|
+
'useBottomSheetManagerContext must be used within a BottomSheetManagerProvider',
|
|
27
|
+
);
|
|
28
|
+
}
|
|
29
|
+
return context;
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
export const useMaybeBottomSheetManagerContext = () => {
|
|
33
|
+
const context = React.useContext(Context);
|
|
34
|
+
|
|
35
|
+
if (!context) {
|
|
36
|
+
return null;
|
|
37
|
+
}
|
|
38
|
+
return context;
|
|
39
|
+
};
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import { type ReactNode } from 'react';
|
|
2
|
+
import { subscribeWithSelector } from 'zustand/middleware';
|
|
3
|
+
import { createWithEqualityFn as create } from 'zustand/traditional';
|
|
4
|
+
|
|
5
|
+
export type BottomSheetStatus = 'opening' | 'open' | 'closing' | 'hidden';
|
|
6
|
+
export type OpenMode = 'push' | 'switch' | 'replace';
|
|
7
|
+
|
|
8
|
+
export interface BottomSheetState {
|
|
9
|
+
groupId: string;
|
|
10
|
+
id: string;
|
|
11
|
+
content: ReactNode;
|
|
12
|
+
status: BottomSheetStatus;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
type TriggerState = Omit<BottomSheetState, 'status'>;
|
|
16
|
+
|
|
17
|
+
interface BottomSheetStoreState {
|
|
18
|
+
stack: BottomSheetState[];
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
interface BottomSheetStoreActions {
|
|
22
|
+
push(sheet: TriggerState): void;
|
|
23
|
+
switch(sheet: TriggerState): void;
|
|
24
|
+
replace(sheet: TriggerState): void;
|
|
25
|
+
startClosing(id: string): void;
|
|
26
|
+
finishClosing(id: string): void;
|
|
27
|
+
clearAll(): void;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export const useBottomSheetStore = create(
|
|
31
|
+
subscribeWithSelector<BottomSheetStoreState & BottomSheetStoreActions>(
|
|
32
|
+
(set) => ({
|
|
33
|
+
stack: [],
|
|
34
|
+
|
|
35
|
+
push: (sheet) =>
|
|
36
|
+
set((state) => ({
|
|
37
|
+
stack: [...state.stack, { ...sheet, status: 'opening' }],
|
|
38
|
+
})),
|
|
39
|
+
switch: (sheet) =>
|
|
40
|
+
set((state) => {
|
|
41
|
+
const stack = [...state.stack];
|
|
42
|
+
|
|
43
|
+
if (stack.length) {
|
|
44
|
+
const topIndex = stack.length - 1;
|
|
45
|
+
if (stack[topIndex]) {
|
|
46
|
+
stack[topIndex] = { ...stack[topIndex], status: 'hidden' };
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
stack.push({ ...sheet, status: 'opening' });
|
|
51
|
+
|
|
52
|
+
return { stack };
|
|
53
|
+
}),
|
|
54
|
+
|
|
55
|
+
replace: (sheet) =>
|
|
56
|
+
set((state) => {
|
|
57
|
+
const stack = [...state.stack];
|
|
58
|
+
const prevTop = stack.pop();
|
|
59
|
+
|
|
60
|
+
if (prevTop) {
|
|
61
|
+
stack.push({ ...prevTop, status: 'closing' });
|
|
62
|
+
}
|
|
63
|
+
stack.push({ ...sheet, status: 'opening' });
|
|
64
|
+
|
|
65
|
+
return { stack };
|
|
66
|
+
}),
|
|
67
|
+
startClosing: (id) =>
|
|
68
|
+
set((state) => {
|
|
69
|
+
const stack = [...state.stack];
|
|
70
|
+
const index = stack.findIndex((s) => s.id === id);
|
|
71
|
+
if (index === -1) {
|
|
72
|
+
return { stack };
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
const closing = stack[index];
|
|
76
|
+
if (closing?.status === 'hidden') {
|
|
77
|
+
return { stack };
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
if (closing) {
|
|
81
|
+
stack[index] = { ...closing, status: 'closing' };
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
const below = stack[index - 1];
|
|
85
|
+
if (below && below.status === 'hidden') {
|
|
86
|
+
stack[index - 1] = { ...below, status: 'opening' };
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
return { stack };
|
|
90
|
+
}),
|
|
91
|
+
|
|
92
|
+
finishClosing: (id) =>
|
|
93
|
+
set((state) => {
|
|
94
|
+
const stack = state.stack.filter((s) => s.id !== id);
|
|
95
|
+
|
|
96
|
+
const topIndex = stack.length - 1;
|
|
97
|
+
if (topIndex >= 0 && stack[topIndex]?.status === 'hidden') {
|
|
98
|
+
stack[topIndex] = { ...stack[topIndex], status: 'opening' };
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
return { stack };
|
|
102
|
+
}),
|
|
103
|
+
|
|
104
|
+
clearAll: () => set(() => ({ stack: [] })),
|
|
105
|
+
})
|
|
106
|
+
)
|
|
107
|
+
);
|