@niibase/bottom-sheet-manager 1.2.0 → 1.4.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.
Files changed (64) hide show
  1. package/README.md +414 -69
  2. package/lib/commonjs/events.js +100 -15
  3. package/lib/commonjs/events.js.map +1 -1
  4. package/lib/commonjs/index.js +14 -0
  5. package/lib/commonjs/index.js.map +1 -1
  6. package/lib/commonjs/manager.js +153 -35
  7. package/lib/commonjs/manager.js.map +1 -1
  8. package/lib/commonjs/provider.js +92 -54
  9. package/lib/commonjs/provider.js.map +1 -1
  10. package/lib/commonjs/router/index.js +80 -21
  11. package/lib/commonjs/router/index.js.map +1 -1
  12. package/lib/commonjs/router/router.js +137 -12
  13. package/lib/commonjs/router/router.js.map +1 -1
  14. package/lib/commonjs/router/view.js +93 -126
  15. package/lib/commonjs/router/view.js.map +1 -1
  16. package/lib/commonjs/sheet.js +122 -98
  17. package/lib/commonjs/sheet.js.map +1 -1
  18. package/lib/module/events.js +100 -15
  19. package/lib/module/events.js.map +1 -1
  20. package/lib/module/index.js +2 -2
  21. package/lib/module/index.js.map +1 -1
  22. package/lib/module/manager.js +154 -35
  23. package/lib/module/manager.js.map +1 -1
  24. package/lib/module/provider.js +87 -50
  25. package/lib/module/provider.js.map +1 -1
  26. package/lib/module/router/index.js +66 -19
  27. package/lib/module/router/index.js.map +1 -1
  28. package/lib/module/router/router.js +135 -11
  29. package/lib/module/router/router.js.map +1 -1
  30. package/lib/module/router/view.js +92 -126
  31. package/lib/module/router/view.js.map +1 -1
  32. package/lib/module/sheet.js +124 -100
  33. package/lib/module/sheet.js.map +1 -1
  34. package/lib/typescript/events.d.ts +46 -12
  35. package/lib/typescript/events.d.ts.map +1 -1
  36. package/lib/typescript/index.d.ts +2 -2
  37. package/lib/typescript/index.d.ts.map +1 -1
  38. package/lib/typescript/manager.d.ts +73 -7
  39. package/lib/typescript/manager.d.ts.map +1 -1
  40. package/lib/typescript/provider.d.ts +22 -16
  41. package/lib/typescript/provider.d.ts.map +1 -1
  42. package/lib/typescript/router/index.d.ts +47 -17
  43. package/lib/typescript/router/index.d.ts.map +1 -1
  44. package/lib/typescript/router/router.d.ts +44 -5
  45. package/lib/typescript/router/router.d.ts.map +1 -1
  46. package/lib/typescript/router/types.d.ts +142 -32
  47. package/lib/typescript/router/types.d.ts.map +1 -1
  48. package/lib/typescript/router/view.d.ts +3 -3
  49. package/lib/typescript/router/view.d.ts.map +1 -1
  50. package/lib/typescript/sheet.d.ts +1 -1
  51. package/lib/typescript/sheet.d.ts.map +1 -1
  52. package/lib/typescript/types.d.ts +52 -21
  53. package/lib/typescript/types.d.ts.map +1 -1
  54. package/package.json +14 -15
  55. package/src/events.ts +118 -27
  56. package/src/index.ts +2 -1
  57. package/src/manager.ts +209 -42
  58. package/src/provider.tsx +144 -71
  59. package/src/router/index.tsx +77 -33
  60. package/src/router/router.ts +188 -15
  61. package/src/router/types.ts +172 -57
  62. package/src/router/view.tsx +111 -213
  63. package/src/sheet.tsx +192 -124
  64. package/src/types.ts +51 -24
@@ -1,5 +1,6 @@
1
1
  import type { BottomSheetProps as RNBottomSheetProps } from "@gorhom/bottom-sheet";
2
2
  import type { WithSpringConfig, WithTimingConfig } from "react-native-reanimated";
3
+ import { StatusBarStyle } from "react-native";
3
4
  import React from "react";
4
5
  export interface Sheets {
5
6
  }
@@ -17,6 +18,39 @@ export interface SheetDefinition<Payload = never, ReturnValue = never> {
17
18
  payload: Payload;
18
19
  returnValue: ReturnValue;
19
20
  }
21
+ /**
22
+ * Defines how sheets behave when a new sheet is opened.
23
+ *
24
+ * - `switch`: Closes current sheet and shows new one. Previous sheet is
25
+ * restored when new one closes.
26
+ *
27
+ * - `replace`: Closes current sheet and opens new one. Previous sheet is
28
+ * removed from stack (not restored on close).
29
+ *
30
+ * - `push`: Stacks new sheet on top. Previous sheet remains visible underneath.
31
+ */
32
+ export type StackBehavior = "switch" | "replace" | "push";
33
+ export type SheetProviderProps = React.PropsWithChildren<{
34
+ context?: string;
35
+ /** @default default */
36
+ statusBar?: StatusBarStyle;
37
+ scaleConfig?: {
38
+ /** Scale factor when sheet is open (default: 0.92) */
39
+ scale?: number;
40
+ /** Vertical translation when sheet is open (default: 5) */
41
+ translateY?: number;
42
+ /** Border radius when sheet is open (default: 24) */
43
+ borderRadius?: number;
44
+ /** Animation config - timing or spring (default: timing with 300ms duration) */
45
+ animation?: {
46
+ type: "timing";
47
+ config?: WithTimingConfig;
48
+ } | {
49
+ type: "spring";
50
+ config?: WithSpringConfig;
51
+ };
52
+ };
53
+ }>;
20
54
  export interface BottomSheetInstance<Id extends SheetIds = SheetIds> {
21
55
  /**
22
56
  * Close the bottom sheet.
@@ -64,11 +98,11 @@ export interface BottomSheetInstance<Id extends SheetIds = SheetIds> {
64
98
  */
65
99
  readonly snapToPosition: (position: string | number, animationConfigs?: AnimationConfigs) => void;
66
100
  }
67
- export type BottomSheetProps = Omit<RNBottomSheetProps, "children" | "onClose" | "animatedIndex" | "topInset"> & {
101
+ export type BottomSheetProps<Id extends SheetIds = SheetIds> = Omit<RNBottomSheetProps, "children" | "onClose"> & {
68
102
  /**
69
103
  * ID of the `BottomSheet`.
70
104
  */
71
- id?: SheetID<SheetIds>;
105
+ id?: SheetID<Id>;
72
106
  /**
73
107
  * Content of the `BottomSheet`.
74
108
  */
@@ -79,48 +113,45 @@ export type BottomSheetProps = Omit<RNBottomSheetProps, "children" | "onClose" |
79
113
  */
80
114
  hardwareBackPressToClose?: boolean;
81
115
  /**
82
- * Callback when the sheet close.
116
+ * Callback when the sheet closes. Return a value to override the close data
117
+ * forwarded to `SheetManager.show()` callers.
83
118
  *
84
- * @type () => any;
85
- * @returns The data returned by the sheet to be returned when closed.
119
+ * @returns Optionally return a new value to pass back to the caller.
86
120
  */
87
- onClose?: (data?: any) => any;
121
+ onClose?: (data?: SheetReturnValue<Id>) => SheetReturnValue<Id> | void;
88
122
  /**
89
123
  * Event called before sheets is visible.
90
124
  * @param data Payload of the sheet if any.
91
125
  * @type () => void;
92
126
  */
93
- onBeforeShow?: (data?: any) => void;
127
+ onBeforeShow?: (data?: SheetPayload<Id>) => void;
94
128
  /**
95
129
  * Can click through the sheet to the underlying view.
96
130
  * @default false
97
131
  */
98
- clickThrough?: boolean;
132
+ passThrough?: boolean;
99
133
  /**
100
134
  * Opacity of the sheet's overlay.
101
135
  * @default 0.45
102
136
  */
103
137
  opacity?: number;
104
138
  /**
105
- * Defines the stack behavior when modal mounts. (experimental)
139
+ * Defines the stack behavior when sheets are opened.
140
+ *
141
+ * - `switch`: (default) Dismisses the current sheet before showing the new one.
142
+ * - `replace`: Swaps the current sheet's content with smooth crossfade animation.
143
+ * - `push`: Pushes new sheet on top, creating a navigable stack.
144
+ *
106
145
  * @default "switch"
107
146
  */
108
- stackBehavior?: "push" | "replace" | "switch";
109
- /**
110
- * Whether the bottom sheet edge to edge.
111
- * @default false
112
- */
113
- fullScreen?: boolean;
147
+ stackBehavior?: StackBehavior;
114
148
  /**
115
- * Whether the bottom sheet is an iOS modal sheet type of animation.
149
+ * Whether the bottom sheet is an iOS 18 modal sheet type of animation.
150
+ * When enabled at snap point 90%, the content behind the sheet scales down and gets a
151
+ * border radius, similar to iOS 18 system sheets.
116
152
  * @default false
117
153
  */
118
154
  iosModalSheetTypeOfAnimation?: boolean;
119
- className?: string;
120
- handleIndicatorClassName?: string;
121
- backgroundClassName?: string;
122
- containerClassName?: string;
123
- handleClassName?: string;
124
155
  };
125
156
  export {};
126
157
  //# sourceMappingURL=types.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@niibase/bottom-sheet-manager",
3
- "version": "1.2.0",
3
+ "version": "1.4.0",
4
4
  "description": "A bottom sheet manager for react-native based on @gorhom/bottom-sheet",
5
5
  "main": "lib/commonjs/index",
6
6
  "module": "lib/module/index",
@@ -14,9 +14,10 @@
14
14
  "build": "bob build && yarn copy-dts && yarn delete-dts.js",
15
15
  "copy-dts": "copyfiles -u 1 \"src/**/*.d.ts\" lib/typescript",
16
16
  "delete-dts.js": "find ./lib/commonjs -name '*.d.js*' -delete && find ./lib/module -name '*.d.js*' -delete",
17
- "release": "rm -rf lib && yarn build && release-it",
17
+ "postinstall": "node scripts/postinstall.mjs",
18
+ "bootstrap": "yarn install && yarn example",
18
19
  "example": "yarn --cwd example",
19
- "bootstrap": "yarn install && yarn example"
20
+ "patch": "patch-package"
20
21
  },
21
22
  "repository": {
22
23
  "type": "git",
@@ -49,13 +50,13 @@
49
50
  "LICENSE"
50
51
  ],
51
52
  "peerDependencies": {
52
- "@react-navigation/native": ">=6.0.0 || >=7.0.0-",
53
+ "@react-navigation/native": ">=7.1.8",
53
54
  "@types/react": "*",
54
55
  "@types/react-native": "*",
55
56
  "react": "*",
56
57
  "react-native": "*",
57
- "react-native-gesture-handler": ">=2.16.1",
58
- "react-native-reanimated": ">=3.16.0 || >=4.0.0-",
58
+ "react-native-gesture-handler": ">=2.28.0",
59
+ "react-native-reanimated": ">=3.16.0 || >=4.0.0",
59
60
  "react-native-safe-area-context": "*"
60
61
  },
61
62
  "peerDependenciesMeta": {
@@ -67,27 +68,25 @@
67
68
  }
68
69
  },
69
70
  "dependencies": {
70
- "@gorhom/bottom-sheet": "^5.2.6",
71
+ "@gorhom/bottom-sheet": "^5.2.8",
71
72
  "nanoid": "^5.1.6"
72
73
  },
73
74
  "devDependencies": {
74
- "@commitlint/cli": "^19.8.1",
75
- "@commitlint/config-conventional": "^19.8.1",
76
- "@ianvs/prettier-plugin-sort-imports": "file:patched/prettier-plugin-sort-imports",
77
- "@react-navigation/native": "^7.1.9",
78
- "@release-it/conventional-changelog": "^10.0.1",
75
+ "@ianvs/prettier-plugin-sort-imports": "4.7.0",
76
+ "@react-navigation/native": "^7.1.8",
79
77
  "@types/react": "~18.3.12",
80
78
  "@types/react-native": "~0.73.0",
81
79
  "copyfiles": "^2.4.1",
82
80
  "metro-react-native-babel-preset": "^0.77.0",
81
+ "patch-package": "^8.0.1",
83
82
  "prettier": "3.6.2",
84
83
  "react": "18.3.1",
85
84
  "react-native": "0.76.0",
86
85
  "react-native-builder-bob": "^0.23.2",
87
- "react-native-gesture-handler": "~2.20.2",
86
+ "react-native-gesture-handler": "~2.28.0",
88
87
  "react-native-reanimated": "~3.19.1",
89
88
  "react-native-safe-area-context": "~5.6.0",
90
- "release-it": "^19.0.4",
89
+ "react-native-screens": "~4.16.0",
91
90
  "typescript": "^5.8.3"
92
91
  },
93
92
  "react-native-builder-bob": {
@@ -99,4 +98,4 @@
99
98
  "typescript"
100
99
  ]
101
100
  }
102
- }
101
+ }
package/src/events.ts CHANGED
@@ -1,40 +1,131 @@
1
- import {
2
- DeviceEventEmitter,
3
- NativeAppEventEmitter,
4
- NativeEventEmitter,
5
- Platform,
6
- } from "react-native";
7
-
8
- /* eslint-disable curly */
9
- export type EventHandler = (...args: any[]) => void;
10
- export type EventHandlerSubscription = {
11
- unsubscribe: () => void;
1
+ /**
2
+ * High-performance event manager using Maps for O(1) lookups.
3
+ * Replaces React Native's EventEmitter which has significant overhead.
4
+ */
5
+
6
+ export type EventHandler<T extends unknown[] = unknown[]> = (...args: T) => void;
7
+
8
+ export interface EventSubscription {
9
+ readonly unsubscribe: () => void;
10
+ }
11
+
12
+ type HandlerEntry = {
13
+ handler: EventHandler;
14
+ id: number;
12
15
  };
13
16
 
14
- export default class EventManager {
15
- _registry?: NativeEventEmitter;
16
- constructor() {
17
- this._registry = Platform.select({
18
- ios: NativeAppEventEmitter,
19
- android: DeviceEventEmitter,
20
- });
17
+ class EventManager {
18
+ private _handlers = new Map<string, HandlerEntry[]>();
19
+ private _nextId = 0;
20
+
21
+ /**
22
+ * Subscribe to an event with a handler function.
23
+ * Returns a subscription object with an unsubscribe method.
24
+ */
25
+ subscribe<T extends unknown[] = unknown[]>(
26
+ name: string,
27
+ handler: EventHandler<T>,
28
+ ): EventSubscription {
29
+ if (!name || typeof handler !== "function") {
30
+ throw new Error("Event name and handler function are required.");
31
+ }
32
+
33
+ const id = this._nextId++;
34
+ const entry: HandlerEntry = { handler: handler as EventHandler, id };
35
+
36
+ const handlers = this._handlers.get(name);
37
+ if (handlers) {
38
+ handlers.push(entry);
39
+ } else {
40
+ this._handlers.set(name, [entry]);
41
+ }
42
+
43
+ return {
44
+ unsubscribe: () => {
45
+ const currentHandlers = this._handlers.get(name);
46
+ if (currentHandlers) {
47
+ const index = currentHandlers.findIndex((h) => h.id === id);
48
+ if (index !== -1) {
49
+ currentHandlers.splice(index, 1);
50
+ if (currentHandlers.length === 0) {
51
+ this._handlers.delete(name);
52
+ }
53
+ }
54
+ }
55
+ },
56
+ };
21
57
  }
22
58
 
23
- subscribe(name: string, handler: EventHandler) {
24
- if (!name || !handler) throw new Error("name and handler are required.");
25
- const event = this._registry?.addListener(name, handler);
26
- return { unsubscribe: () => event?.remove() };
59
+ /**
60
+ * Publish an event with optional arguments.
61
+ * All subscribed handlers will be called synchronously.
62
+ */
63
+ publish<T extends unknown[] = unknown[]>(name: string, ...args: T): void {
64
+ const handlers = this._handlers.get(name);
65
+ if (!handlers || handlers.length === 0) return;
66
+
67
+ // Create a copy to avoid issues if handlers modify the list during iteration
68
+ const handlersSnapshot = handlers.slice();
69
+ for (let i = 0; i < handlersSnapshot.length; i++) {
70
+ handlersSnapshot[i].handler(...args);
71
+ }
72
+ }
73
+
74
+ /**
75
+ * Publish an event asynchronously using microtasks for better performance.
76
+ * Useful when you don't need immediate execution.
77
+ */
78
+ publishAsync<T extends unknown[] = unknown[]>(name: string, ...args: T): void {
79
+ queueMicrotask(() => this.publish(name, ...args));
27
80
  }
28
81
 
29
- publish(name: string, ...args: any[]) {
30
- this._registry?.emit(name, ...args);
82
+ /**
83
+ * Check if an event has any subscribers.
84
+ */
85
+ hasSubscribers(name: string): boolean {
86
+ const handlers = this._handlers.get(name);
87
+ return !!handlers && handlers.length > 0;
31
88
  }
32
89
 
33
- remove(...names: string[]) {
34
- for (const eventType of names) {
35
- this._registry?.removeAllListeners(eventType);
90
+ /**
91
+ * Get the number of subscribers for an event.
92
+ */
93
+ subscriberCount(name: string): number {
94
+ return this._handlers.get(name)?.length ?? 0;
95
+ }
96
+
97
+ /**
98
+ * Remove all listeners for the specified event names.
99
+ */
100
+ remove(...names: string[]): void {
101
+ for (const name of names) {
102
+ this._handlers.delete(name);
36
103
  }
37
104
  }
105
+
106
+ /**
107
+ * Remove all event listeners.
108
+ */
109
+ clear(): void {
110
+ this._handlers.clear();
111
+ }
112
+
113
+ /**
114
+ * Subscribe to an event that will only fire once.
115
+ */
116
+ once<T extends unknown[] = unknown[]>(
117
+ name: string,
118
+ handler: EventHandler<T>,
119
+ ): EventSubscription {
120
+ const subscription = this.subscribe<T>(name, (...args) => {
121
+ subscription.unsubscribe();
122
+ handler(...args);
123
+ });
124
+ return subscription;
125
+ }
38
126
  }
39
127
 
128
+ // Singleton instance for global event management
40
129
  export const eventManager = new EventManager();
130
+
131
+ export default EventManager;
package/src/index.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  export { default as BottomSheet } from "./sheet";
2
- export { SheetManager } from "./manager";
2
+ export { SheetManager, PrivateManager } from "./manager";
3
3
  export * from "./router";
4
4
  export * from "./types";
5
5
  export {
@@ -7,5 +7,6 @@ export {
7
7
  useSheetPayload,
8
8
  useSheetRef,
9
9
  useOnSheet,
10
+ useStackBehaviorContext as useSheetStackBehavior,
10
11
  registerSheet,
11
12
  } from "./provider";