@lodev09/react-native-true-sheet 3.4.0-beta.0 → 3.4.0-beta.2

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/README.md CHANGED
@@ -91,10 +91,23 @@ export const App = () => {
91
91
 
92
92
  ## Testing
93
93
 
94
- TrueSheet includes built-in Jest mocks for easy testing. Simply mock the package in your tests:
94
+ TrueSheet exports mocks for easy testing:
95
95
 
96
96
  ```tsx
97
- jest.mock('@lodev09/react-native-true-sheet');
97
+ // Main component
98
+ jest.mock('@lodev09/react-native-true-sheet', () =>
99
+ require('@lodev09/react-native-true-sheet/mock')
100
+ );
101
+
102
+ // Navigation (if using)
103
+ jest.mock('@lodev09/react-native-true-sheet/navigation', () =>
104
+ require('@lodev09/react-native-true-sheet/navigation/mock')
105
+ );
106
+
107
+ // Reanimated (if using)
108
+ jest.mock('@lodev09/react-native-true-sheet/reanimated', () =>
109
+ require('@lodev09/react-native-true-sheet/reanimated/mock')
110
+ );
98
111
  ```
99
112
 
100
113
  All methods (`present`, `dismiss`, `resize`) are mocked as Jest functions, allowing you to test your components without native dependencies.
@@ -368,8 +368,8 @@ class TrueSheetView(private val reactContext: ThemedReactContext) :
368
368
  isSheetUpdatePending = true
369
369
  viewController.post {
370
370
  isSheetUpdatePending = false
371
- viewController.setupSheetDetents()
372
- viewController.positionFooter()
371
+ viewController.setupSheetDetentsForSizeChange()
372
+ TrueSheetDialogObserver.onSheetSizeChanged(this)
373
373
  }
374
374
  }
375
375
 
@@ -384,11 +384,39 @@ class TrueSheetView(private val reactContext: ThemedReactContext) :
384
384
  }
385
385
 
386
386
  override fun containerViewFooterDidChangeSize(width: Int, height: Int) {
387
- if (viewController.isPresented) {
388
- viewController.positionFooter()
387
+ viewController.positionFooter()
388
+ }
389
+
390
+ // ==================== Stack Translation ====================
391
+
392
+ /**
393
+ * Updates this sheet's translation based on its direct child's position.
394
+ * Propagates additional translation to parent so it stays behind this sheet.
395
+ */
396
+ fun updateTranslationForChild(childSheetTop: Int) {
397
+ if (!viewController.isDialogVisible || viewController.isExpanded) return
398
+
399
+ val mySheetTop = viewController.getExpectedSheetTop(viewController.currentDetentIndex)
400
+ val newTranslation = maxOf(0, childSheetTop - mySheetTop)
401
+ val additionalTranslation = newTranslation - viewController.currentTranslationY
402
+
403
+ viewController.translateDialog(newTranslation)
404
+
405
+ if (additionalTranslation > 0) {
406
+ TrueSheetDialogObserver.getParentSheet(this)?.addTranslation(additionalTranslation)
389
407
  }
390
408
  }
391
409
 
410
+ /**
411
+ * Adds translation to this sheet and propagates to parent.
412
+ */
413
+ private fun addTranslation(amount: Int) {
414
+ if (!viewController.isDialogVisible || viewController.isExpanded) return
415
+
416
+ viewController.translateDialog(viewController.currentTranslationY + amount)
417
+ TrueSheetDialogObserver.getParentSheet(this)?.addTranslation(amount)
418
+ }
419
+
392
420
  companion object {
393
421
  const val TAG_NAME = "TrueSheet"
394
422
  }
@@ -76,6 +76,7 @@ class TrueSheetViewController(private val reactContext: ThemedReactContext) :
76
76
  // Animation durations from res/anim/true_sheet_slide_in.xml and true_sheet_slide_out.xml
77
77
  private const val PRESENT_ANIMATION_DURATION = 250L
78
78
  private const val DISMISS_ANIMATION_DURATION = 150L
79
+ private const val TRANSLATE_ANIMATION_DURATION = 100L
79
80
  }
80
81
 
81
82
  // ====================================================================
@@ -408,6 +409,8 @@ class TrueSheetViewController(private val reactContext: ThemedReactContext) :
408
409
  isDialogVisible = false
409
410
  dialog?.window?.setWindowAnimations(com.lodev09.truesheet.R.style.TrueSheetFadeOutAnimation)
410
411
  dialog?.window?.decorView?.visibility = INVISIBLE
412
+ dimView?.visibility = INVISIBLE
413
+ parentDimView?.visibility = INVISIBLE
411
414
  wasHiddenByModal = true
412
415
  }
413
416
  },
@@ -416,6 +419,8 @@ class TrueSheetViewController(private val reactContext: ThemedReactContext) :
416
419
  if (isPresented && wasHiddenByModal) {
417
420
  isDialogVisible = true
418
421
  dialog?.window?.decorView?.visibility = VISIBLE
422
+ dimView?.visibility = VISIBLE
423
+ parentDimView?.visibility = VISIBLE
419
424
  // Restore animation after visibility change to avoid slide animation
420
425
  sheetContainer?.post {
421
426
  dialog?.window?.setWindowAnimations(windowAnimation)
@@ -470,6 +475,9 @@ class TrueSheetViewController(private val reactContext: ThemedReactContext) :
470
475
  val currentSheetTop: Int
471
476
  get() = bottomSheetView?.top ?: screenHeight
472
477
 
478
+ val currentTranslationY: Int
479
+ get() = bottomSheetView?.translationY?.toInt() ?: 0
480
+
473
481
  fun getExpectedSheetTop(detentIndex: Int): Int {
474
482
  if (detentIndex < 0 || detentIndex >= detents.size) return screenHeight
475
483
  return realScreenHeight - getDetentHeight(detents[detentIndex])
@@ -478,11 +486,10 @@ class TrueSheetViewController(private val reactContext: ThemedReactContext) :
478
486
  /** Translates the sheet when stacking. Pass 0 to reset. */
479
487
  fun translateDialog(translationY: Int) {
480
488
  val bottomSheet = bottomSheetView ?: return
481
- val duration = if (translationY > 0) PRESENT_ANIMATION_DURATION else DISMISS_ANIMATION_DURATION
482
489
 
483
490
  bottomSheet.animate()
484
491
  .translationY(translationY.toFloat())
485
- .setDuration(duration)
492
+ .setDuration(TRANSLATE_ANIMATION_DURATION)
486
493
  .setUpdateListener {
487
494
  val effectiveTop = bottomSheet.top + bottomSheet.translationY.toInt()
488
495
  emitChangePositionDelegate(effectiveTop)
@@ -589,6 +596,11 @@ class TrueSheetViewController(private val reactContext: ThemedReactContext) :
589
596
  }
590
597
  }
591
598
 
599
+ fun setupSheetDetentsForSizeChange() {
600
+ setupSheetDetents()
601
+ positionFooter()
602
+ }
603
+
592
604
  fun setupGrabber() {
593
605
  val bottomSheet = bottomSheetView ?: return
594
606
 
@@ -20,18 +20,8 @@ object TrueSheetDialogObserver {
20
20
  val parentSheet = presentedSheetStack.lastOrNull()
21
21
  ?.takeIf { it.viewController.isPresented && it.viewController.isDialogVisible }
22
22
 
23
- // Translate parent sheets down to match the new sheet's position
24
- val newSheetTop = sheetView.viewController.getExpectedSheetTop(detentIndex)
25
- for (sheet in presentedSheetStack) {
26
- if (!sheet.viewController.isDialogVisible) continue
27
- if (sheet.viewController.isExpanded) continue
28
-
29
- val sheetTop = sheet.viewController.currentSheetTop
30
- if (sheetTop < newSheetTop) {
31
- val translationY = newSheetTop - sheetTop
32
- sheet.viewController.translateDialog(translationY)
33
- }
34
- }
23
+ val childSheetTop = sheetView.viewController.getExpectedSheetTop(detentIndex)
24
+ parentSheet?.updateTranslationForChild(childSheetTop)
35
25
 
36
26
  if (!presentedSheetStack.contains(sheetView)) {
37
27
  presentedSheetStack.add(sheetView)
@@ -43,7 +33,7 @@ object TrueSheetDialogObserver {
43
33
 
44
34
  /**
45
35
  * Called when a sheet has been dismissed.
46
- * Shows the parent sheet if this sheet was stacked on it.
36
+ * Resets parent sheet translation if this sheet was stacked on it.
47
37
  */
48
38
  @JvmStatic
49
39
  fun onSheetDidDismiss(sheetView: TrueSheetView, hadParent: Boolean) {
@@ -55,6 +45,29 @@ object TrueSheetDialogObserver {
55
45
  }
56
46
  }
57
47
 
48
+ /**
49
+ * Called when a presented sheet's size changes (e.g., after setupSheetDetents).
50
+ * Updates parent sheet translations to match the new sheet position.
51
+ */
52
+ @JvmStatic
53
+ fun onSheetSizeChanged(sheetView: TrueSheetView) {
54
+ synchronized(presentedSheetStack) {
55
+ val index = presentedSheetStack.indexOf(sheetView)
56
+ if (index <= 0) return
57
+
58
+ val parentSheet = presentedSheetStack[index - 1]
59
+
60
+ // Post to ensure layout is complete before reading position
61
+ sheetView.viewController.post {
62
+ val childMinSheetTop = sheetView.viewController.getExpectedSheetTop(0)
63
+ val childCurrentSheetTop = sheetView.viewController.getExpectedSheetTop(sheetView.viewController.currentDetentIndex)
64
+ // Cap to minimum detent position
65
+ val childSheetTop = maxOf(childMinSheetTop, childCurrentSheetTop)
66
+ parentSheet.updateTranslationForChild(childSheetTop)
67
+ }
68
+ }
69
+ }
70
+
58
71
  /**
59
72
  * Returns all sheets presented on top of the given sheet (children/descendants).
60
73
  * Returns them in reverse order (top-most first) for proper dismissal.
@@ -81,4 +94,16 @@ object TrueSheetDialogObserver {
81
94
  presentedSheetStack.clear()
82
95
  }
83
96
  }
97
+
98
+ /**
99
+ * Gets the parent sheet of the given sheet, if any.
100
+ */
101
+ @JvmStatic
102
+ fun getParentSheet(sheetView: TrueSheetView): TrueSheetView? {
103
+ synchronized(presentedSheetStack) {
104
+ val index = presentedSheetStack.indexOf(sheetView)
105
+ if (index <= 0) return null
106
+ return presentedSheetStack[index - 1]
107
+ }
108
+ }
84
109
  }
@@ -403,10 +403,7 @@ using namespace facebook::react;
403
403
 
404
404
  dispatch_async(dispatch_get_main_queue(), ^{
405
405
  self->_isSheetUpdatePending = NO;
406
-
407
- [self->_controller.sheetPresentationController animateChanges:^{
408
- [self->_controller setupSheetDetentsForSizeChange];
409
- }];
406
+ [self->_controller setupSheetDetentsForSizeChange];
410
407
  });
411
408
  }
412
409
 
@@ -594,8 +594,10 @@
594
594
  #pragma mark - Sheet Configuration
595
595
 
596
596
  - (void)setupSheetDetentsForSizeChange {
597
- _pendingContentSizeChange = YES;
598
- [self setupSheetDetents];
597
+ [self.sheetPresentationController animateChanges:^{
598
+ _pendingContentSizeChange = YES;
599
+ [self setupSheetDetents];
600
+ }];
599
601
  }
600
602
 
601
603
  - (void)setupSheetDetentsForDetentsChange {
@@ -0,0 +1,78 @@
1
+ "use strict";
2
+
3
+ import React, { createElement, isValidElement } from 'react';
4
+ import { View } from 'react-native';
5
+ /**
6
+ * Mock TrueSheet component for testing.
7
+ * Import from '@lodev09/react-native-true-sheet/mock' in your test setup.
8
+ */
9
+ export class TrueSheet extends React.Component {
10
+ static instances = {};
11
+ static dismiss = jest.fn((_name, _animated) => Promise.resolve());
12
+ static present = jest.fn((_name, _index, _animated) => Promise.resolve());
13
+ static resize = jest.fn((_name, _index) => Promise.resolve());
14
+ dismiss = jest.fn(_animated => Promise.resolve());
15
+ present = jest.fn((_index, _animated) => Promise.resolve());
16
+ resize = jest.fn(_index => Promise.resolve());
17
+ componentDidMount() {
18
+ const {
19
+ name
20
+ } = this.props;
21
+ if (name) {
22
+ TrueSheet.instances[name] = this;
23
+ }
24
+ }
25
+ componentWillUnmount() {
26
+ const {
27
+ name
28
+ } = this.props;
29
+ if (name) {
30
+ delete TrueSheet.instances[name];
31
+ }
32
+ }
33
+ renderHeader() {
34
+ const {
35
+ header
36
+ } = this.props;
37
+ if (!header) return null;
38
+ return /*#__PURE__*/isValidElement(header) ? header : /*#__PURE__*/createElement(header);
39
+ }
40
+ renderFooter() {
41
+ const {
42
+ footer
43
+ } = this.props;
44
+ if (!footer) return null;
45
+ return /*#__PURE__*/isValidElement(footer) ? footer : /*#__PURE__*/createElement(footer);
46
+ }
47
+ render() {
48
+ const {
49
+ children,
50
+ style
51
+ } = this.props;
52
+ return /*#__PURE__*/React.createElement(View, {
53
+ style
54
+ }, this.renderHeader(), children, this.renderFooter());
55
+ }
56
+ }
57
+
58
+ /**
59
+ * Mock TrueSheetProvider for testing.
60
+ */
61
+ export function TrueSheetProvider({
62
+ children
63
+ }) {
64
+ return children;
65
+ }
66
+
67
+ /**
68
+ * Mock useTrueSheet hook for testing.
69
+ */
70
+ export function useTrueSheet() {
71
+ return {
72
+ present: TrueSheet.present,
73
+ dismiss: TrueSheet.dismiss,
74
+ resize: TrueSheet.resize
75
+ };
76
+ }
77
+ export * from "../TrueSheet.types.js";
78
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["React","createElement","isValidElement","View","TrueSheet","Component","instances","dismiss","jest","fn","_name","_animated","Promise","resolve","present","_index","resize","componentDidMount","name","props","componentWillUnmount","renderHeader","header","renderFooter","footer","render","children","style","TrueSheetProvider","useTrueSheet"],"sourceRoot":"../../../src","sources":["mocks/index.ts"],"mappings":";;AAAA,OAAOA,KAAK,IAAIC,aAAa,EAAEC,cAAc,QAAwB,OAAO;AAC5E,SAASC,IAAI,QAAQ,cAAc;AAQnC;AACA;AACA;AACA;AACA,OAAO,MAAMC,SAAS,SACZJ,KAAK,CAACK,SAAS,CAEzB;EACE,OAAOC,SAAS,GAA8B,CAAC,CAAC;EAEhD,OAAOC,OAAO,GAAGC,IAAI,CAACC,EAAE,CAAC,CAACC,KAAa,EAAEC,SAAmB,KAAKC,OAAO,CAACC,OAAO,CAAC,CAAC,CAAC;EACnF,OAAOC,OAAO,GAAGN,IAAI,CAACC,EAAE,CAAC,CAACC,KAAa,EAAEK,MAAe,EAAEJ,SAAmB,KAC3EC,OAAO,CAACC,OAAO,CAAC,CAClB,CAAC;EACD,OAAOG,MAAM,GAAGR,IAAI,CAACC,EAAE,CAAC,CAACC,KAAa,EAAEK,MAAc,KAAKH,OAAO,CAACC,OAAO,CAAC,CAAC,CAAC;EAE7EN,OAAO,GAAGC,IAAI,CAACC,EAAE,CAAEE,SAAmB,IAAKC,OAAO,CAACC,OAAO,CAAC,CAAC,CAAC;EAC7DC,OAAO,GAAGN,IAAI,CAACC,EAAE,CAAC,CAACM,MAAe,EAAEJ,SAAmB,KAAKC,OAAO,CAACC,OAAO,CAAC,CAAC,CAAC;EAC9EG,MAAM,GAAGR,IAAI,CAACC,EAAE,CAAEM,MAAc,IAAKH,OAAO,CAACC,OAAO,CAAC,CAAC,CAAC;EAEvDI,iBAAiBA,CAAA,EAAG;IAClB,MAAM;MAAEC;IAAK,CAAC,GAAG,IAAI,CAACC,KAAK;IAC3B,IAAID,IAAI,EAAE;MACRd,SAAS,CAACE,SAAS,CAACY,IAAI,CAAC,GAAG,IAAI;IAClC;EACF;EAEAE,oBAAoBA,CAAA,EAAG;IACrB,MAAM;MAAEF;IAAK,CAAC,GAAG,IAAI,CAACC,KAAK;IAC3B,IAAID,IAAI,EAAE;MACR,OAAOd,SAAS,CAACE,SAAS,CAACY,IAAI,CAAC;IAClC;EACF;EAEQG,YAAYA,CAAA,EAAc;IAChC,MAAM;MAAEC;IAAO,CAAC,GAAG,IAAI,CAACH,KAAK;IAC7B,IAAI,CAACG,MAAM,EAAE,OAAO,IAAI;IACxB,OAAO,aAAApB,cAAc,CAACoB,MAAM,CAAC,GAAGA,MAAM,gBAAGrB,aAAa,CAACqB,MAAM,CAAC;EAChE;EAEQC,YAAYA,CAAA,EAAc;IAChC,MAAM;MAAEC;IAAO,CAAC,GAAG,IAAI,CAACL,KAAK;IAC7B,IAAI,CAACK,MAAM,EAAE,OAAO,IAAI;IACxB,OAAO,aAAAtB,cAAc,CAACsB,MAAM,CAAC,GAAGA,MAAM,gBAAGvB,aAAa,CAACuB,MAAM,CAAC;EAChE;EAEAC,MAAMA,CAAA,EAAG;IACP,MAAM;MAAEC,QAAQ;MAAEC;IAAM,CAAC,GAAG,IAAI,CAACR,KAAK;IACtC,oBAAOnB,KAAK,CAACC,aAAa,CAACE,IAAI,EAAE;MAAEwB;IAAM,CAAC,EAAE,IAAI,CAACN,YAAY,CAAC,CAAC,EAAEK,QAAQ,EAAE,IAAI,CAACH,YAAY,CAAC,CAAC,CAAC;EACjG;AACF;;AAEA;AACA;AACA;AACA,OAAO,SAASK,iBAAiBA,CAAC;EAAEF;AAAwC,CAAC,EAAE;EAC7E,OAAOA,QAAQ;AACjB;;AAEA;AACA;AACA;AACA,OAAO,SAASG,YAAYA,CAAA,EAA4B;EACtD,OAAO;IACLf,OAAO,EAAEV,SAAS,CAACU,OAAO;IAC1BP,OAAO,EAAEH,SAAS,CAACG,OAAO;IAC1BS,MAAM,EAAEZ,SAAS,CAACY;EACpB,CAAC;AACH;AAEA,cAAc,uBAAoB","ignoreList":[]}
@@ -0,0 +1,85 @@
1
+ "use strict";
2
+
3
+ /**
4
+ * Mock createTrueSheetNavigator for testing.
5
+ * Import from '@lodev09/react-native-true-sheet/navigation/mock' in your test setup.
6
+ */
7
+ export const createTrueSheetNavigator = jest.fn(() => ({
8
+ Navigator: jest.fn(({
9
+ children
10
+ }) => children),
11
+ Screen: jest.fn(() => null),
12
+ Group: jest.fn(() => null)
13
+ }));
14
+
15
+ /**
16
+ * Mock TrueSheetActions for testing.
17
+ */
18
+ export const TrueSheetActions = {
19
+ push: jest.fn((name, params) => ({
20
+ type: 'PUSH',
21
+ payload: {
22
+ name,
23
+ params
24
+ }
25
+ })),
26
+ pop: jest.fn(count => ({
27
+ type: 'POP',
28
+ payload: {
29
+ count
30
+ }
31
+ })),
32
+ popTo: jest.fn((name, params) => ({
33
+ type: 'POP_TO',
34
+ payload: {
35
+ name,
36
+ params
37
+ }
38
+ })),
39
+ popToTop: jest.fn(() => ({
40
+ type: 'POP_TO_TOP'
41
+ })),
42
+ replace: jest.fn((name, params) => ({
43
+ type: 'REPLACE',
44
+ payload: {
45
+ name,
46
+ params
47
+ }
48
+ })),
49
+ resize: jest.fn(index => ({
50
+ type: 'RESIZE',
51
+ index
52
+ })),
53
+ dismiss: jest.fn(() => ({
54
+ type: 'DISMISS'
55
+ })),
56
+ remove: jest.fn(() => ({
57
+ type: 'REMOVE'
58
+ }))
59
+ };
60
+
61
+ /**
62
+ * Mock useTrueSheetNavigation hook for testing.
63
+ */
64
+ export const useTrueSheetNavigation = jest.fn(() => ({
65
+ navigate: jest.fn(),
66
+ goBack: jest.fn(),
67
+ reset: jest.fn(),
68
+ setParams: jest.fn(),
69
+ dispatch: jest.fn(),
70
+ isFocused: jest.fn(() => true),
71
+ canGoBack: jest.fn(() => true),
72
+ getId: jest.fn(),
73
+ getParent: jest.fn(),
74
+ getState: jest.fn(),
75
+ addListener: jest.fn(() => jest.fn()),
76
+ removeListener: jest.fn(),
77
+ setOptions: jest.fn(),
78
+ push: jest.fn(),
79
+ pop: jest.fn(),
80
+ popTo: jest.fn(),
81
+ popToTop: jest.fn(),
82
+ replace: jest.fn(),
83
+ resize: jest.fn()
84
+ }));
85
+ //# sourceMappingURL=navigation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["createTrueSheetNavigator","jest","fn","Navigator","children","Screen","Group","TrueSheetActions","push","name","params","type","payload","pop","count","popTo","popToTop","replace","resize","index","dismiss","remove","useTrueSheetNavigation","navigate","goBack","reset","setParams","dispatch","isFocused","canGoBack","getId","getParent","getState","addListener","removeListener","setOptions"],"sourceRoot":"../../../src","sources":["mocks/navigation.ts"],"mappings":"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","ignoreList":[]}
@@ -0,0 +1,89 @@
1
+ "use strict";
2
+
3
+ import React, { createElement, isValidElement } from 'react';
4
+ import { View } from 'react-native';
5
+ const createMockSharedValue = initialValue => ({
6
+ value: initialValue,
7
+ get: () => initialValue,
8
+ set: () => {},
9
+ addListener: () => () => {},
10
+ removeListener: () => {},
11
+ modify: () => {}
12
+ });
13
+
14
+ /**
15
+ * Mock ReanimatedTrueSheet component for testing.
16
+ * Import from '@lodev09/react-native-true-sheet/reanimated/mock' in your test setup.
17
+ */
18
+ export class ReanimatedTrueSheet extends React.Component {
19
+ static instances = {};
20
+ static dismiss = jest.fn((_name, _animated) => Promise.resolve());
21
+ static present = jest.fn((_name, _index, _animated) => Promise.resolve());
22
+ static resize = jest.fn((_name, _index) => Promise.resolve());
23
+ dismiss = jest.fn(_animated => Promise.resolve());
24
+ present = jest.fn((_index, _animated) => Promise.resolve());
25
+ resize = jest.fn(_index => Promise.resolve());
26
+ componentDidMount() {
27
+ const {
28
+ name
29
+ } = this.props;
30
+ if (name) {
31
+ ReanimatedTrueSheet.instances[name] = this;
32
+ }
33
+ }
34
+ componentWillUnmount() {
35
+ const {
36
+ name
37
+ } = this.props;
38
+ if (name) {
39
+ delete ReanimatedTrueSheet.instances[name];
40
+ }
41
+ }
42
+ renderHeader() {
43
+ const {
44
+ header
45
+ } = this.props;
46
+ if (!header) return null;
47
+ return /*#__PURE__*/isValidElement(header) ? header : /*#__PURE__*/createElement(header);
48
+ }
49
+ renderFooter() {
50
+ const {
51
+ footer
52
+ } = this.props;
53
+ if (!footer) return null;
54
+ return /*#__PURE__*/isValidElement(footer) ? footer : /*#__PURE__*/createElement(footer);
55
+ }
56
+ render() {
57
+ const {
58
+ children,
59
+ style
60
+ } = this.props;
61
+ return /*#__PURE__*/React.createElement(View, {
62
+ style
63
+ }, this.renderHeader(), children, this.renderFooter());
64
+ }
65
+ }
66
+
67
+ /**
68
+ * Mock ReanimatedTrueSheetProvider for testing.
69
+ */
70
+ export function ReanimatedTrueSheetProvider({
71
+ children
72
+ }) {
73
+ return children;
74
+ }
75
+
76
+ /**
77
+ * Mock useReanimatedTrueSheet hook for testing.
78
+ */
79
+ export const useReanimatedTrueSheet = jest.fn(() => ({
80
+ animatedPosition: createMockSharedValue(0),
81
+ animatedIndex: createMockSharedValue(-1),
82
+ animatedDetent: createMockSharedValue(0)
83
+ }));
84
+
85
+ /**
86
+ * Mock useReanimatedPositionChangeHandler hook for testing.
87
+ */
88
+ export const useReanimatedPositionChangeHandler = jest.fn((_handler, _dependencies) => jest.fn());
89
+ //# sourceMappingURL=reanimated.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["React","createElement","isValidElement","View","createMockSharedValue","initialValue","value","get","set","addListener","removeListener","modify","ReanimatedTrueSheet","Component","instances","dismiss","jest","fn","_name","_animated","Promise","resolve","present","_index","resize","componentDidMount","name","props","componentWillUnmount","renderHeader","header","renderFooter","footer","render","children","style","ReanimatedTrueSheetProvider","useReanimatedTrueSheet","animatedPosition","animatedIndex","animatedDetent","useReanimatedPositionChangeHandler","_handler","_dependencies"],"sourceRoot":"../../../src","sources":["mocks/reanimated.ts"],"mappings":"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","ignoreList":[]}
@@ -0,0 +1,36 @@
1
+ import React from 'react';
2
+ import { View } from 'react-native';
3
+ import type { TrueSheetProps, TrueSheetRef, TrueSheetContextMethods } from '../TrueSheet.types';
4
+ interface TrueSheetState {
5
+ shouldRenderNativeView: boolean;
6
+ }
7
+ /**
8
+ * Mock TrueSheet component for testing.
9
+ * Import from '@lodev09/react-native-true-sheet/mock' in your test setup.
10
+ */
11
+ export declare class TrueSheet extends React.Component<TrueSheetProps, TrueSheetState> implements TrueSheetRef {
12
+ static instances: Record<string, TrueSheet>;
13
+ static dismiss: jest.Mock<Promise<void>, [_name: string, _animated?: boolean | undefined], any>;
14
+ static present: jest.Mock<Promise<void>, [_name: string, _index?: number | undefined, _animated?: boolean | undefined], any>;
15
+ static resize: jest.Mock<Promise<void>, [_name: string, _index: number], any>;
16
+ dismiss: jest.Mock<Promise<void>, [_animated?: boolean | undefined], any>;
17
+ present: jest.Mock<Promise<void>, [_index?: number | undefined, _animated?: boolean | undefined], any>;
18
+ resize: jest.Mock<Promise<void>, [_index: number], any>;
19
+ componentDidMount(): void;
20
+ componentWillUnmount(): void;
21
+ private renderHeader;
22
+ private renderFooter;
23
+ render(): React.CElement<import("react-native").ViewProps, View>;
24
+ }
25
+ /**
26
+ * Mock TrueSheetProvider for testing.
27
+ */
28
+ export declare function TrueSheetProvider({ children }: {
29
+ children: React.ReactNode;
30
+ }): React.ReactNode;
31
+ /**
32
+ * Mock useTrueSheet hook for testing.
33
+ */
34
+ export declare function useTrueSheet(): TrueSheetContextMethods;
35
+ export * from '../TrueSheet.types';
36
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/mocks/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAwD,MAAM,OAAO,CAAC;AAC7E,OAAO,EAAE,IAAI,EAAE,MAAM,cAAc,CAAC;AAEpC,OAAO,KAAK,EAAE,cAAc,EAAE,YAAY,EAAE,uBAAuB,EAAE,MAAM,oBAAoB,CAAC;AAEhG,UAAU,cAAc;IACtB,sBAAsB,EAAE,OAAO,CAAC;CACjC;AAED;;;GAGG;AACH,qBAAa,SACX,SAAQ,KAAK,CAAC,SAAS,CAAC,cAAc,EAAE,cAAc,CACtD,YAAW,YAAY;IAEvB,MAAM,CAAC,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,CAAM;IAEjD,MAAM,CAAC,OAAO,kFAAsE;IACpF,MAAM,CAAC,OAAO,+GAEZ;IACF,MAAM,CAAC,MAAM,iEAAiE;IAE9E,OAAO,mEAAuD;IAC9D,OAAO,gGAAwE;IAC/E,MAAM,kDAAkD;IAExD,iBAAiB;IAOjB,oBAAoB;IAOpB,OAAO,CAAC,YAAY;IAMpB,OAAO,CAAC,YAAY;IAMpB,MAAM;CAIP;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,EAAE,QAAQ,EAAE,EAAE;IAAE,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAA;CAAE,mBAE5E;AAED;;GAEG;AACH,wBAAgB,YAAY,IAAI,uBAAuB,CAMtD;AAED,cAAc,oBAAoB,CAAC"}
@@ -0,0 +1,66 @@
1
+ import type { ParamListBase } from '@react-navigation/native';
2
+ import type { TrueSheetNavigationProp } from '../navigation/types';
3
+ /**
4
+ * Mock createTrueSheetNavigator for testing.
5
+ * Import from '@lodev09/react-native-true-sheet/navigation/mock' in your test setup.
6
+ */
7
+ export declare const createTrueSheetNavigator: jest.Mock<{
8
+ Navigator: jest.Mock<import("react").ReactNode, [{
9
+ children: React.ReactNode;
10
+ }], any>;
11
+ Screen: jest.Mock<null, [], any>;
12
+ Group: jest.Mock<null, [], any>;
13
+ }, [], any>;
14
+ /**
15
+ * Mock TrueSheetActions for testing.
16
+ */
17
+ export declare const TrueSheetActions: {
18
+ push: jest.Mock<{
19
+ type: string;
20
+ payload: {
21
+ name: string;
22
+ params: object | undefined;
23
+ };
24
+ }, [name: string, params?: object | undefined], any>;
25
+ pop: jest.Mock<{
26
+ type: string;
27
+ payload: {
28
+ count: number | undefined;
29
+ };
30
+ }, [count?: number | undefined], any>;
31
+ popTo: jest.Mock<{
32
+ type: string;
33
+ payload: {
34
+ name: string;
35
+ params: object | undefined;
36
+ };
37
+ }, [name: string, params?: object | undefined], any>;
38
+ popToTop: jest.Mock<{
39
+ type: string;
40
+ }, [], any>;
41
+ replace: jest.Mock<{
42
+ type: string;
43
+ payload: {
44
+ name: string;
45
+ params: object | undefined;
46
+ };
47
+ }, [name: string, params?: object | undefined], any>;
48
+ resize: jest.Mock<{
49
+ type: string;
50
+ index: number;
51
+ }, [index: number], any>;
52
+ dismiss: jest.Mock<{
53
+ type: string;
54
+ }, [], any>;
55
+ remove: jest.Mock<{
56
+ type: string;
57
+ }, [], any>;
58
+ };
59
+ /**
60
+ * Mock useTrueSheetNavigation hook for testing.
61
+ */
62
+ export declare const useTrueSheetNavigation: jest.Mock<TrueSheetNavigationProp<ParamListBase>, [], any>;
63
+ export type { TrueSheetActionType } from '../navigation/TrueSheetRouter';
64
+ export type { DetentInfoEventPayload, PositionChangeEventPayload } from '../TrueSheet.types';
65
+ export type { TrueSheetNavigationEventMap, TrueSheetNavigationHelpers, TrueSheetNavigationOptions, TrueSheetNavigationProp, TrueSheetNavigationState, TrueSheetScreenProps, } from '../navigation/types';
66
+ //# sourceMappingURL=navigation.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"navigation.d.ts","sourceRoot":"","sources":["../../../../src/mocks/navigation.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AAE9D,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,qBAAqB,CAAC;AAEnE;;;GAGG;AACH,eAAO,MAAM,wBAAwB;;kBACW,KAAK,CAAC,SAAS;;;;WAG5D,CAAC;AAEJ;;GAEG;AACH,eAAO,MAAM,gBAAgB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAe5B,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,sBAAsB,4DAuBlC,CAAC;AAEF,YAAY,EAAE,mBAAmB,EAAE,MAAM,+BAA+B,CAAC;AACzE,YAAY,EAAE,sBAAsB,EAAE,0BAA0B,EAAE,MAAM,oBAAoB,CAAC;AAC7F,YAAY,EACV,2BAA2B,EAC3B,0BAA0B,EAC1B,0BAA0B,EAC1B,uBAAuB,EACvB,wBAAwB,EACxB,oBAAoB,GACrB,MAAM,qBAAqB,CAAC"}
@@ -0,0 +1,46 @@
1
+ import React from 'react';
2
+ import { View } from 'react-native';
3
+ import type { SharedValue } from 'react-native-reanimated';
4
+ import type { TrueSheetProps, TrueSheetRef, PositionChangeEventPayload } from '../TrueSheet.types';
5
+ interface TrueSheetState {
6
+ shouldRenderNativeView: boolean;
7
+ }
8
+ interface MockReanimatedTrueSheetContextValue {
9
+ animatedPosition: SharedValue<number>;
10
+ animatedIndex: SharedValue<number>;
11
+ animatedDetent: SharedValue<number>;
12
+ }
13
+ /**
14
+ * Mock ReanimatedTrueSheet component for testing.
15
+ * Import from '@lodev09/react-native-true-sheet/reanimated/mock' in your test setup.
16
+ */
17
+ export declare class ReanimatedTrueSheet extends React.Component<TrueSheetProps, TrueSheetState> implements TrueSheetRef {
18
+ static instances: Record<string, ReanimatedTrueSheet>;
19
+ static dismiss: jest.Mock<Promise<void>, [_name: string, _animated?: boolean | undefined], any>;
20
+ static present: jest.Mock<Promise<void>, [_name: string, _index?: number | undefined, _animated?: boolean | undefined], any>;
21
+ static resize: jest.Mock<Promise<void>, [_name: string, _index: number], any>;
22
+ dismiss: jest.Mock<Promise<void>, [_animated?: boolean | undefined], any>;
23
+ present: jest.Mock<Promise<void>, [_index?: number | undefined, _animated?: boolean | undefined], any>;
24
+ resize: jest.Mock<Promise<void>, [_index: number], any>;
25
+ componentDidMount(): void;
26
+ componentWillUnmount(): void;
27
+ private renderHeader;
28
+ private renderFooter;
29
+ render(): React.CElement<import("react-native").ViewProps, View>;
30
+ }
31
+ /**
32
+ * Mock ReanimatedTrueSheetProvider for testing.
33
+ */
34
+ export declare function ReanimatedTrueSheetProvider({ children }: {
35
+ children: React.ReactNode;
36
+ }): React.ReactNode;
37
+ /**
38
+ * Mock useReanimatedTrueSheet hook for testing.
39
+ */
40
+ export declare const useReanimatedTrueSheet: jest.Mock<MockReanimatedTrueSheetContextValue, [], any>;
41
+ /**
42
+ * Mock useReanimatedPositionChangeHandler hook for testing.
43
+ */
44
+ export declare const useReanimatedPositionChangeHandler: jest.Mock<jest.Mock<any, any, any>, [_handler: (payload: PositionChangeEventPayload) => void, _dependencies?: unknown[] | undefined], any>;
45
+ export {};
46
+ //# sourceMappingURL=reanimated.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reanimated.d.ts","sourceRoot":"","sources":["../../../../src/mocks/reanimated.ts"],"names":[],"mappings":"AAAA,OAAO,KAAwD,MAAM,OAAO,CAAC;AAC7E,OAAO,EAAE,IAAI,EAAE,MAAM,cAAc,CAAC;AACpC,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAE3D,OAAO,KAAK,EAAE,cAAc,EAAE,YAAY,EAAE,0BAA0B,EAAE,MAAM,oBAAoB,CAAC;AAEnG,UAAU,cAAc;IACtB,sBAAsB,EAAE,OAAO,CAAC;CACjC;AAED,UAAU,mCAAmC;IAC3C,gBAAgB,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IACtC,aAAa,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IACnC,cAAc,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;CACrC;AAYD;;;GAGG;AACH,qBAAa,mBACX,SAAQ,KAAK,CAAC,SAAS,CAAC,cAAc,EAAE,cAAc,CACtD,YAAW,YAAY;IAEvB,MAAM,CAAC,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,mBAAmB,CAAC,CAAM;IAE3D,MAAM,CAAC,OAAO,kFAAsE;IACpF,MAAM,CAAC,OAAO,+GAEZ;IACF,MAAM,CAAC,MAAM,iEAAiE;IAE9E,OAAO,mEAAuD;IAC9D,OAAO,gGAAwE;IAC/E,MAAM,kDAAkD;IAExD,iBAAiB;IAOjB,oBAAoB;IAOpB,OAAO,CAAC,YAAY;IAMpB,OAAO,CAAC,YAAY;IAMpB,MAAM;CAIP;AAED;;GAEG;AACH,wBAAgB,2BAA2B,CAAC,EAAE,QAAQ,EAAE,EAAE;IAAE,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAA;CAAE,mBAEtF;AAED;;GAEG;AACH,eAAO,MAAM,sBAAsB,yDAMlC,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,kCAAkC,2DACxB,0BAA0B,KAAK,IAAI,8CACzD,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lodev09/react-native-true-sheet",
3
- "version": "3.4.0-beta.0",
3
+ "version": "3.4.0-beta.2",
4
4
  "description": "The true native bottom sheet experience for your React Native Apps.",
5
5
  "source": "./src/index.ts",
6
6
  "main": "./lib/module/index.js",
@@ -11,6 +11,9 @@
11
11
  "types": "./lib/typescript/src/index.d.ts",
12
12
  "default": "./lib/module/index.js"
13
13
  },
14
+ "./mock": "./lib/module/mocks/index.js",
15
+ "./navigation/mock": "./lib/module/mocks/navigation.js",
16
+ "./reanimated/mock": "./lib/module/mocks/reanimated.js",
14
17
  "./reanimated": {
15
18
  "source": "./src/reanimated/index.ts",
16
19
  "types": "./lib/typescript/src/reanimated/index.d.ts",
@@ -164,7 +167,6 @@
164
167
  ],
165
168
  "testPathIgnorePatterns": [
166
169
  "/node_modules/",
167
- "<rootDir>/src/__mocks__/",
168
170
  "<rootDir>/example/"
169
171
  ]
170
172
  },
@@ -214,7 +216,6 @@
214
216
  "react-native-builder-bob": {
215
217
  "source": "src",
216
218
  "output": "lib",
217
- "exclude": "**/{__tests__,__fixtures__}/**",
218
219
  "targets": [
219
220
  [
220
221
  "module",
@@ -0,0 +1,80 @@
1
+ import React, { createElement, isValidElement, type ReactNode } from 'react';
2
+ import { View } from 'react-native';
3
+
4
+ import type { TrueSheetProps, TrueSheetRef, TrueSheetContextMethods } from '../TrueSheet.types';
5
+
6
+ interface TrueSheetState {
7
+ shouldRenderNativeView: boolean;
8
+ }
9
+
10
+ /**
11
+ * Mock TrueSheet component for testing.
12
+ * Import from '@lodev09/react-native-true-sheet/mock' in your test setup.
13
+ */
14
+ export class TrueSheet
15
+ extends React.Component<TrueSheetProps, TrueSheetState>
16
+ implements TrueSheetRef
17
+ {
18
+ static instances: Record<string, TrueSheet> = {};
19
+
20
+ static dismiss = jest.fn((_name: string, _animated?: boolean) => Promise.resolve());
21
+ static present = jest.fn((_name: string, _index?: number, _animated?: boolean) =>
22
+ Promise.resolve()
23
+ );
24
+ static resize = jest.fn((_name: string, _index: number) => Promise.resolve());
25
+
26
+ dismiss = jest.fn((_animated?: boolean) => Promise.resolve());
27
+ present = jest.fn((_index?: number, _animated?: boolean) => Promise.resolve());
28
+ resize = jest.fn((_index: number) => Promise.resolve());
29
+
30
+ componentDidMount() {
31
+ const { name } = this.props;
32
+ if (name) {
33
+ TrueSheet.instances[name] = this;
34
+ }
35
+ }
36
+
37
+ componentWillUnmount() {
38
+ const { name } = this.props;
39
+ if (name) {
40
+ delete TrueSheet.instances[name];
41
+ }
42
+ }
43
+
44
+ private renderHeader(): ReactNode {
45
+ const { header } = this.props;
46
+ if (!header) return null;
47
+ return isValidElement(header) ? header : createElement(header);
48
+ }
49
+
50
+ private renderFooter(): ReactNode {
51
+ const { footer } = this.props;
52
+ if (!footer) return null;
53
+ return isValidElement(footer) ? footer : createElement(footer);
54
+ }
55
+
56
+ render() {
57
+ const { children, style } = this.props;
58
+ return React.createElement(View, { style }, this.renderHeader(), children, this.renderFooter());
59
+ }
60
+ }
61
+
62
+ /**
63
+ * Mock TrueSheetProvider for testing.
64
+ */
65
+ export function TrueSheetProvider({ children }: { children: React.ReactNode }) {
66
+ return children;
67
+ }
68
+
69
+ /**
70
+ * Mock useTrueSheet hook for testing.
71
+ */
72
+ export function useTrueSheet(): TrueSheetContextMethods {
73
+ return {
74
+ present: TrueSheet.present,
75
+ dismiss: TrueSheet.dismiss,
76
+ resize: TrueSheet.resize,
77
+ };
78
+ }
79
+
80
+ export * from '../TrueSheet.types';
@@ -0,0 +1,72 @@
1
+ import type { ParamListBase } from '@react-navigation/native';
2
+
3
+ import type { TrueSheetNavigationProp } from '../navigation/types';
4
+
5
+ /**
6
+ * Mock createTrueSheetNavigator for testing.
7
+ * Import from '@lodev09/react-native-true-sheet/navigation/mock' in your test setup.
8
+ */
9
+ export const createTrueSheetNavigator = jest.fn(() => ({
10
+ Navigator: jest.fn(({ children }: { children: React.ReactNode }) => children),
11
+ Screen: jest.fn(() => null),
12
+ Group: jest.fn(() => null),
13
+ }));
14
+
15
+ /**
16
+ * Mock TrueSheetActions for testing.
17
+ */
18
+ export const TrueSheetActions = {
19
+ push: jest.fn((name: string, params?: object) => ({ type: 'PUSH', payload: { name, params } })),
20
+ pop: jest.fn((count?: number) => ({ type: 'POP', payload: { count } })),
21
+ popTo: jest.fn((name: string, params?: object) => ({
22
+ type: 'POP_TO',
23
+ payload: { name, params },
24
+ })),
25
+ popToTop: jest.fn(() => ({ type: 'POP_TO_TOP' })),
26
+ replace: jest.fn((name: string, params?: object) => ({
27
+ type: 'REPLACE',
28
+ payload: { name, params },
29
+ })),
30
+ resize: jest.fn((index: number) => ({ type: 'RESIZE', index })),
31
+ dismiss: jest.fn(() => ({ type: 'DISMISS' })),
32
+ remove: jest.fn(() => ({ type: 'REMOVE' })),
33
+ };
34
+
35
+ /**
36
+ * Mock useTrueSheetNavigation hook for testing.
37
+ */
38
+ export const useTrueSheetNavigation = jest.fn(
39
+ <T extends ParamListBase = ParamListBase>() =>
40
+ ({
41
+ navigate: jest.fn(),
42
+ goBack: jest.fn(),
43
+ reset: jest.fn(),
44
+ setParams: jest.fn(),
45
+ dispatch: jest.fn(),
46
+ isFocused: jest.fn(() => true),
47
+ canGoBack: jest.fn(() => true),
48
+ getId: jest.fn(),
49
+ getParent: jest.fn(),
50
+ getState: jest.fn(),
51
+ addListener: jest.fn(() => jest.fn()),
52
+ removeListener: jest.fn(),
53
+ setOptions: jest.fn(),
54
+ push: jest.fn(),
55
+ pop: jest.fn(),
56
+ popTo: jest.fn(),
57
+ popToTop: jest.fn(),
58
+ replace: jest.fn(),
59
+ resize: jest.fn(),
60
+ }) as unknown as TrueSheetNavigationProp<T>
61
+ );
62
+
63
+ export type { TrueSheetActionType } from '../navigation/TrueSheetRouter';
64
+ export type { DetentInfoEventPayload, PositionChangeEventPayload } from '../TrueSheet.types';
65
+ export type {
66
+ TrueSheetNavigationEventMap,
67
+ TrueSheetNavigationHelpers,
68
+ TrueSheetNavigationOptions,
69
+ TrueSheetNavigationProp,
70
+ TrueSheetNavigationState,
71
+ TrueSheetScreenProps,
72
+ } from '../navigation/types';
@@ -0,0 +1,102 @@
1
+ import React, { createElement, isValidElement, type ReactNode } from 'react';
2
+ import { View } from 'react-native';
3
+ import type { SharedValue } from 'react-native-reanimated';
4
+
5
+ import type { TrueSheetProps, TrueSheetRef, PositionChangeEventPayload } from '../TrueSheet.types';
6
+
7
+ interface TrueSheetState {
8
+ shouldRenderNativeView: boolean;
9
+ }
10
+
11
+ interface MockReanimatedTrueSheetContextValue {
12
+ animatedPosition: SharedValue<number>;
13
+ animatedIndex: SharedValue<number>;
14
+ animatedDetent: SharedValue<number>;
15
+ }
16
+
17
+ const createMockSharedValue = <T>(initialValue: T): SharedValue<T> =>
18
+ ({
19
+ value: initialValue,
20
+ get: () => initialValue,
21
+ set: () => {},
22
+ addListener: () => () => {},
23
+ removeListener: () => {},
24
+ modify: () => {},
25
+ }) as unknown as SharedValue<T>;
26
+
27
+ /**
28
+ * Mock ReanimatedTrueSheet component for testing.
29
+ * Import from '@lodev09/react-native-true-sheet/reanimated/mock' in your test setup.
30
+ */
31
+ export class ReanimatedTrueSheet
32
+ extends React.Component<TrueSheetProps, TrueSheetState>
33
+ implements TrueSheetRef
34
+ {
35
+ static instances: Record<string, ReanimatedTrueSheet> = {};
36
+
37
+ static dismiss = jest.fn((_name: string, _animated?: boolean) => Promise.resolve());
38
+ static present = jest.fn((_name: string, _index?: number, _animated?: boolean) =>
39
+ Promise.resolve()
40
+ );
41
+ static resize = jest.fn((_name: string, _index: number) => Promise.resolve());
42
+
43
+ dismiss = jest.fn((_animated?: boolean) => Promise.resolve());
44
+ present = jest.fn((_index?: number, _animated?: boolean) => Promise.resolve());
45
+ resize = jest.fn((_index: number) => Promise.resolve());
46
+
47
+ componentDidMount() {
48
+ const { name } = this.props;
49
+ if (name) {
50
+ ReanimatedTrueSheet.instances[name] = this;
51
+ }
52
+ }
53
+
54
+ componentWillUnmount() {
55
+ const { name } = this.props;
56
+ if (name) {
57
+ delete ReanimatedTrueSheet.instances[name];
58
+ }
59
+ }
60
+
61
+ private renderHeader(): ReactNode {
62
+ const { header } = this.props;
63
+ if (!header) return null;
64
+ return isValidElement(header) ? header : createElement(header);
65
+ }
66
+
67
+ private renderFooter(): ReactNode {
68
+ const { footer } = this.props;
69
+ if (!footer) return null;
70
+ return isValidElement(footer) ? footer : createElement(footer);
71
+ }
72
+
73
+ render() {
74
+ const { children, style } = this.props;
75
+ return React.createElement(View, { style }, this.renderHeader(), children, this.renderFooter());
76
+ }
77
+ }
78
+
79
+ /**
80
+ * Mock ReanimatedTrueSheetProvider for testing.
81
+ */
82
+ export function ReanimatedTrueSheetProvider({ children }: { children: React.ReactNode }) {
83
+ return children;
84
+ }
85
+
86
+ /**
87
+ * Mock useReanimatedTrueSheet hook for testing.
88
+ */
89
+ export const useReanimatedTrueSheet = jest.fn(
90
+ (): MockReanimatedTrueSheetContextValue => ({
91
+ animatedPosition: createMockSharedValue(0),
92
+ animatedIndex: createMockSharedValue(-1),
93
+ animatedDetent: createMockSharedValue(0),
94
+ })
95
+ );
96
+
97
+ /**
98
+ * Mock useReanimatedPositionChangeHandler hook for testing.
99
+ */
100
+ export const useReanimatedPositionChangeHandler = jest.fn(
101
+ (_handler: (payload: PositionChangeEventPayload) => void, _dependencies?: unknown[]) => jest.fn()
102
+ );
@@ -1,81 +0,0 @@
1
- "use strict";
2
-
3
- import React from 'react';
4
- import { View } from 'react-native';
5
-
6
- // Mock TrueSheet class component
7
- import { jsxs as _jsxs, jsx as _jsx, Fragment as _Fragment } from "react/jsx-runtime";
8
- export class TrueSheet extends React.Component {
9
- static instances = {};
10
-
11
- // Static methods
12
- static dismiss = jest.fn((name, animated = true) => Promise.resolve());
13
- static present = jest.fn((name, index = 0, animated = true) => Promise.resolve());
14
- static resize = jest.fn((name, index) => Promise.resolve());
15
-
16
- // Instance methods
17
- dismiss = jest.fn((animated = true) => Promise.resolve());
18
- present = jest.fn((index = 0, animated = true) => Promise.resolve());
19
- resize = jest.fn(index => Promise.resolve());
20
- componentDidMount() {
21
- const {
22
- name
23
- } = this.props;
24
- if (name) {
25
- TrueSheet.instances[name] = this;
26
- }
27
- }
28
- componentWillUnmount() {
29
- const {
30
- name
31
- } = this.props;
32
- if (name) {
33
- delete TrueSheet.instances[name];
34
- }
35
- }
36
- render() {
37
- const {
38
- children,
39
- header,
40
- footer,
41
- style,
42
- ...rest
43
- } = this.props;
44
- return /*#__PURE__*/_jsxs(View, {
45
- style: style,
46
- ...rest,
47
- children: [header, children, footer]
48
- });
49
- }
50
- }
51
-
52
- // Mock ReanimatedTrueSheet
53
- export class ReanimatedTrueSheet extends TrueSheet {
54
- render() {
55
- return /*#__PURE__*/_jsx(TrueSheet, {
56
- ...this.props
57
- });
58
- }
59
- }
60
-
61
- // Mock ReanimatedTrueSheetProvider
62
- export const ReanimatedTrueSheetProvider = ({
63
- children
64
- }) => /*#__PURE__*/_jsx(_Fragment, {
65
- children: children
66
- });
67
-
68
- // Mock hooks
69
- export const useReanimatedTrueSheet = jest.fn(() => ({
70
- animatedPosition: {
71
- value: 0
72
- },
73
- animatedIndex: {
74
- value: -1
75
- }
76
- }));
77
- export const useReanimatedPositionChangeHandler = jest.fn(callback => jest.fn());
78
-
79
- // Re-export types (these will be no-ops in JS but useful for TS consumers)
80
- export * from "../TrueSheet.types.js";
81
- //# sourceMappingURL=index.js.map
@@ -1 +0,0 @@
1
- {"version":3,"names":["React","View","jsxs","_jsxs","jsx","_jsx","Fragment","_Fragment","TrueSheet","Component","instances","dismiss","jest","fn","name","animated","Promise","resolve","present","index","resize","componentDidMount","props","componentWillUnmount","render","children","header","footer","style","rest","ReanimatedTrueSheet","ReanimatedTrueSheetProvider","useReanimatedTrueSheet","animatedPosition","value","animatedIndex","useReanimatedPositionChangeHandler","callback"],"sourceRoot":"../../../src","sources":["__mocks__/index.js"],"mappings":";;AAAA,OAAOA,KAAK,MAAM,OAAO;AACzB,SAASC,IAAI,QAAQ,cAAc;;AAEnC;AAAA,SAAAC,IAAA,IAAAC,KAAA,EAAAC,GAAA,IAAAC,IAAA,EAAAC,QAAA,IAAAC,SAAA;AACA,OAAO,MAAMC,SAAS,SAASR,KAAK,CAACS,SAAS,CAAC;EAC7C,OAAOC,SAAS,GAAG,CAAC,CAAC;;EAErB;EACA,OAAOC,OAAO,GAAGC,IAAI,CAACC,EAAE,CAAC,CAACC,IAAI,EAAEC,QAAQ,GAAG,IAAI,KAAKC,OAAO,CAACC,OAAO,CAAC,CAAC,CAAC;EACtE,OAAOC,OAAO,GAAGN,IAAI,CAACC,EAAE,CAAC,CAACC,IAAI,EAAEK,KAAK,GAAG,CAAC,EAAEJ,QAAQ,GAAG,IAAI,KAAKC,OAAO,CAACC,OAAO,CAAC,CAAC,CAAC;EACjF,OAAOG,MAAM,GAAGR,IAAI,CAACC,EAAE,CAAC,CAACC,IAAI,EAAEK,KAAK,KAAKH,OAAO,CAACC,OAAO,CAAC,CAAC,CAAC;;EAE3D;EACAN,OAAO,GAAGC,IAAI,CAACC,EAAE,CAAC,CAACE,QAAQ,GAAG,IAAI,KAAKC,OAAO,CAACC,OAAO,CAAC,CAAC,CAAC;EACzDC,OAAO,GAAGN,IAAI,CAACC,EAAE,CAAC,CAACM,KAAK,GAAG,CAAC,EAAEJ,QAAQ,GAAG,IAAI,KAAKC,OAAO,CAACC,OAAO,CAAC,CAAC,CAAC;EACpEG,MAAM,GAAGR,IAAI,CAACC,EAAE,CAAEM,KAAK,IAAKH,OAAO,CAACC,OAAO,CAAC,CAAC,CAAC;EAE9CI,iBAAiBA,CAAA,EAAG;IAClB,MAAM;MAAEP;IAAK,CAAC,GAAG,IAAI,CAACQ,KAAK;IAC3B,IAAIR,IAAI,EAAE;MACRN,SAAS,CAACE,SAAS,CAACI,IAAI,CAAC,GAAG,IAAI;IAClC;EACF;EAEAS,oBAAoBA,CAAA,EAAG;IACrB,MAAM;MAAET;IAAK,CAAC,GAAG,IAAI,CAACQ,KAAK;IAC3B,IAAIR,IAAI,EAAE;MACR,OAAON,SAAS,CAACE,SAAS,CAACI,IAAI,CAAC;IAClC;EACF;EAEAU,MAAMA,CAAA,EAAG;IACP,MAAM;MAAEC,QAAQ;MAAEC,MAAM;MAAEC,MAAM;MAAEC,KAAK;MAAE,GAAGC;IAAK,CAAC,GAAG,IAAI,CAACP,KAAK;IAC/D,oBACEnB,KAAA,CAACF,IAAI;MAAC2B,KAAK,EAAEA,KAAM;MAAA,GAAKC,IAAI;MAAAJ,QAAA,GACzBC,MAAM,EACND,QAAQ,EACRE,MAAM;IAAA,CACH,CAAC;EAEX;AACF;;AAEA;AACA,OAAO,MAAMG,mBAAmB,SAAStB,SAAS,CAAC;EACjDgB,MAAMA,CAAA,EAAG;IACP,oBAAOnB,IAAA,CAACG,SAAS;MAAA,GAAK,IAAI,CAACc;IAAK,CAAG,CAAC;EACtC;AACF;;AAEA;AACA,OAAO,MAAMS,2BAA2B,GAAGA,CAAC;EAAEN;AAAS,CAAC,kBAAKpB,IAAA,CAAAE,SAAA;EAAAkB,QAAA,EAAGA;AAAQ,CAAG,CAAC;;AAE5E;AACA,OAAO,MAAMO,sBAAsB,GAAGpB,IAAI,CAACC,EAAE,CAAC,OAAO;EACnDoB,gBAAgB,EAAE;IAAEC,KAAK,EAAE;EAAE,CAAC;EAC9BC,aAAa,EAAE;IAAED,KAAK,EAAE,CAAC;EAAE;AAC7B,CAAC,CAAC,CAAC;AAEH,OAAO,MAAME,kCAAkC,GAAGxB,IAAI,CAACC,EAAE,CAAEwB,QAAQ,IAAKzB,IAAI,CAACC,EAAE,CAAC,CAAC,CAAC;;AAElF;AACA,cAAc,uBAAoB","ignoreList":[]}
@@ -1,63 +0,0 @@
1
- import React from 'react';
2
- import { View } from 'react-native';
3
-
4
- // Mock TrueSheet class component
5
- export class TrueSheet extends React.Component {
6
- static instances = {};
7
-
8
- // Static methods
9
- static dismiss = jest.fn((name, animated = true) => Promise.resolve());
10
- static present = jest.fn((name, index = 0, animated = true) => Promise.resolve());
11
- static resize = jest.fn((name, index) => Promise.resolve());
12
-
13
- // Instance methods
14
- dismiss = jest.fn((animated = true) => Promise.resolve());
15
- present = jest.fn((index = 0, animated = true) => Promise.resolve());
16
- resize = jest.fn((index) => Promise.resolve());
17
-
18
- componentDidMount() {
19
- const { name } = this.props;
20
- if (name) {
21
- TrueSheet.instances[name] = this;
22
- }
23
- }
24
-
25
- componentWillUnmount() {
26
- const { name } = this.props;
27
- if (name) {
28
- delete TrueSheet.instances[name];
29
- }
30
- }
31
-
32
- render() {
33
- const { children, header, footer, style, ...rest } = this.props;
34
- return (
35
- <View style={style} {...rest}>
36
- {header}
37
- {children}
38
- {footer}
39
- </View>
40
- );
41
- }
42
- }
43
-
44
- // Mock ReanimatedTrueSheet
45
- export class ReanimatedTrueSheet extends TrueSheet {
46
- render() {
47
- return <TrueSheet {...this.props} />;
48
- }
49
- }
50
-
51
- // Mock ReanimatedTrueSheetProvider
52
- export const ReanimatedTrueSheetProvider = ({ children }) => <>{children}</>;
53
-
54
- // Mock hooks
55
- export const useReanimatedTrueSheet = jest.fn(() => ({
56
- animatedPosition: { value: 0 },
57
- animatedIndex: { value: -1 },
58
- }));
59
-
60
- export const useReanimatedPositionChangeHandler = jest.fn((callback) => jest.fn());
61
-
62
- // Re-export types (these will be no-ops in JS but useful for TS consumers)
63
- export * from '../TrueSheet.types';