@umituz/react-native-bottom-sheet 1.1.2 → 1.1.4

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@umituz/react-native-bottom-sheet",
3
- "version": "1.1.2",
3
+ "version": "1.1.4",
4
4
  "description": "Modern, performant bottom sheets for React Native with preset configurations, keyboard handling, and smooth animations",
5
5
  "main": "./src/index.ts",
6
6
  "types": "./src/index.ts",
@@ -161,23 +161,22 @@ export const BottomSheet = forwardRef<BottomSheetRef, BottomSheetProps>(
161
161
  // @gorhom/bottom-sheet uses useAnimatedDetents which accesses layoutState.get
162
162
  // during initialization, so we need to wait for Reanimated to be fully ready
163
163
  useEffect(() => {
164
- // Use a combination of setTimeout and requestAnimationFrame
165
- // to ensure Reanimated is fully initialized before rendering
166
- let frameId: number;
164
+ // Use a longer delay to ensure Reanimated is fully initialized
165
+ // This is critical because @gorhom/bottom-sheet's internal hooks
166
+ // access layoutState.get immediately when the component renders
167
167
  const timer = setTimeout(() => {
168
168
  // Use multiple animation frames to ensure Reanimated worklets are ready
169
- frameId = requestAnimationFrame(() => {
169
+ requestAnimationFrame(() => {
170
170
  requestAnimationFrame(() => {
171
- setIsMounted(true);
171
+ requestAnimationFrame(() => {
172
+ setIsMounted(true);
173
+ });
172
174
  });
173
175
  });
174
- }, 150); // Increased delay to ensure Reanimated is fully initialized
176
+ }, 300); // Increased delay to 300ms to ensure Reanimated is fully initialized
175
177
 
176
178
  return () => {
177
179
  clearTimeout(timer);
178
- if (frameId) {
179
- cancelAnimationFrame(frameId);
180
- }
181
180
  };
182
181
  }, []);
183
182
 
@@ -185,31 +184,37 @@ export const BottomSheet = forwardRef<BottomSheetRef, BottomSheetProps>(
185
184
  React.useImperativeHandle(ref, () => ({
186
185
  snapToIndex: (index: number) => {
187
186
  if (isMounted) {
188
- sheetRef.current?.snapToIndex(index);
187
+ sheetRef.current?.snapToIndex(index);
189
188
  }
190
189
  },
191
190
  snapToPosition: (position: string | number) => {
192
191
  if (isMounted) {
193
- sheetRef.current?.snapToPosition(position);
192
+ sheetRef.current?.snapToPosition(position);
194
193
  }
195
194
  },
196
195
  expand: () => {
197
196
  if (isMounted) {
198
- sheetRef.current?.expand();
197
+ sheetRef.current?.expand();
199
198
  }
200
199
  },
201
200
  collapse: () => {
202
201
  if (isMounted) {
203
- sheetRef.current?.collapse();
202
+ sheetRef.current?.collapse();
204
203
  }
205
204
  },
206
205
  close: () => {
207
206
  if (isMounted) {
208
- sheetRef.current?.close();
207
+ sheetRef.current?.close();
209
208
  }
210
209
  },
211
210
  }));
212
211
 
212
+ // Don't compute config or callbacks until mounted to prevent early hook execution
213
+ // This ensures @gorhom/bottom-sheet's internal hooks don't run before Reanimated is ready
214
+ if (!isMounted) {
215
+ return null;
216
+ }
217
+
213
218
  // Get configuration from preset or custom
214
219
  const config: BottomSheetConfig = useMemo(() => {
215
220
  if (customSnapPoints) {
@@ -265,11 +270,6 @@ export const BottomSheet = forwardRef<BottomSheetRef, BottomSheetProps>(
265
270
  [onChange, onClose]
266
271
  );
267
272
 
268
- // Don't render until Reanimated is ready to prevent layoutState errors
269
- if (!isMounted) {
270
- return null;
271
- }
272
-
273
273
  return (
274
274
  <GorhomBottomSheet
275
275
  ref={sheetRef}
@@ -163,23 +163,22 @@ export const BottomSheetModal = forwardRef<BottomSheetModalRef, BottomSheetModal
163
163
  // @gorhom/bottom-sheet uses useAnimatedDetents which accesses layoutState.get
164
164
  // during initialization, so we need to wait for Reanimated to be fully ready
165
165
  useEffect(() => {
166
- // Use a combination of setTimeout and requestAnimationFrame
167
- // to ensure Reanimated is fully initialized before rendering
168
- let frameId: number;
166
+ // Use a longer delay to ensure Reanimated is fully initialized
167
+ // This is critical because @gorhom/bottom-sheet's internal hooks
168
+ // access layoutState.get immediately when the component renders
169
169
  const timer = setTimeout(() => {
170
170
  // Use multiple animation frames to ensure Reanimated worklets are ready
171
- frameId = requestAnimationFrame(() => {
171
+ requestAnimationFrame(() => {
172
172
  requestAnimationFrame(() => {
173
- setIsMounted(true);
173
+ requestAnimationFrame(() => {
174
+ setIsMounted(true);
175
+ });
174
176
  });
175
177
  });
176
- }, 150); // Increased delay to ensure Reanimated is fully initialized
178
+ }, 300); // Increased delay to 300ms to ensure Reanimated is fully initialized
177
179
 
178
180
  return () => {
179
181
  clearTimeout(timer);
180
- if (frameId) {
181
- cancelAnimationFrame(frameId);
182
- }
183
182
  };
184
183
  }, []);
185
184
 
@@ -188,35 +187,46 @@ export const BottomSheetModal = forwardRef<BottomSheetModalRef, BottomSheetModal
188
187
  present: () => {
189
188
  if (isMounted) {
190
189
  modalRef.current?.present();
190
+ // Snap to initial index after presenting
191
+ const initialIdx = initialIndex ?? config.initialIndex ?? 0;
192
+ setTimeout(() => {
193
+ modalRef.current?.snapToIndex(initialIdx);
194
+ }, 100);
191
195
  }
192
196
  },
193
197
  dismiss: () => {
194
198
  if (isMounted) {
195
- modalRef.current?.dismiss();
199
+ modalRef.current?.dismiss();
196
200
  }
197
201
  },
198
202
  snapToIndex: (index: number) => {
199
203
  if (isMounted) {
200
- modalRef.current?.snapToIndex(index);
204
+ modalRef.current?.snapToIndex(index);
201
205
  }
202
206
  },
203
207
  snapToPosition: (position: string | number) => {
204
208
  if (isMounted) {
205
- modalRef.current?.snapToPosition(position);
209
+ modalRef.current?.snapToPosition(position);
206
210
  }
207
211
  },
208
212
  expand: () => {
209
213
  if (isMounted) {
210
- modalRef.current?.expand();
214
+ modalRef.current?.expand();
211
215
  }
212
216
  },
213
217
  collapse: () => {
214
218
  if (isMounted) {
215
- modalRef.current?.collapse();
219
+ modalRef.current?.collapse();
216
220
  }
217
221
  },
218
222
  }));
219
223
 
224
+ // Don't compute config or callbacks until mounted to prevent early hook execution
225
+ // This ensures @gorhom/bottom-sheet's internal hooks don't run before Reanimated is ready
226
+ if (!isMounted) {
227
+ return null;
228
+ }
229
+
220
230
  // Get configuration from preset or custom
221
231
  const config: BottomSheetConfig = useMemo(() => {
222
232
  if (customSnapPoints) {
@@ -272,15 +282,10 @@ export const BottomSheetModal = forwardRef<BottomSheetModalRef, BottomSheetModal
272
282
  [onChange, onDismiss]
273
283
  );
274
284
 
275
- // Don't render until Reanimated is ready to prevent layoutState errors
276
- if (!isMounted) {
277
- return null;
278
- }
279
-
280
285
  return (
281
286
  <GorhomBottomSheetModal
282
287
  ref={modalRef}
283
- index={config.initialIndex ?? 0}
288
+ index={-1}
284
289
  snapPoints={config.snapPoints}
285
290
  enableDynamicSizing={config.enableDynamicSizing}
286
291
  backdropComponent={renderBackdrop}