@lodev09/react-native-true-sheet 4.0.0-beta.1 → 4.0.0-beta.11

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 (221) hide show
  1. package/README.md +25 -4
  2. package/android/build.gradle +22 -1
  3. package/android/src/main/java/com/lodev09/truesheet/TrueSheetContainerView.kt +24 -7
  4. package/android/src/main/java/com/lodev09/truesheet/TrueSheetContentView.kt +211 -182
  5. package/android/src/main/java/com/lodev09/truesheet/TrueSheetContentViewManager.kt +5 -1
  6. package/android/src/main/java/com/lodev09/truesheet/TrueSheetFooterView.kt +14 -19
  7. package/android/src/main/java/com/lodev09/truesheet/TrueSheetOverlayView.kt +106 -0
  8. package/android/src/main/java/com/lodev09/truesheet/TrueSheetOverlayViewManager.kt +45 -0
  9. package/android/src/main/java/com/lodev09/truesheet/TrueSheetPackage.kt +2 -1
  10. package/android/src/main/java/com/lodev09/truesheet/TrueSheetStateUpdater.kt +18 -0
  11. package/android/src/main/java/com/lodev09/truesheet/TrueSheetView.kt +82 -39
  12. package/android/src/main/java/com/lodev09/truesheet/TrueSheetViewController.kt +275 -88
  13. package/android/src/main/java/com/lodev09/truesheet/TrueSheetViewManager.kt +26 -1
  14. package/android/src/main/java/com/lodev09/truesheet/core/TrueSheetCoordinatorLayout.kt +75 -3
  15. package/android/src/main/java/com/lodev09/truesheet/core/TrueSheetDetentCalculator.kt +56 -34
  16. package/android/src/main/java/com/lodev09/truesheet/core/TrueSheetOverlayRootView.kt +137 -0
  17. package/android/src/main/java/com/lodev09/truesheet/events/TrueSheetLifecycleEvents.kt +15 -0
  18. package/android/src/main/java/com/lodev09/truesheet/utils/KeyboardUtils.kt +1 -1
  19. package/android/src/main/java/com/lodev09/truesheet/utils/TouchEventDeduper.kt +31 -0
  20. package/android/src/main/java/com/lodev09/truesheet/utils/ViewUtils.kt +19 -7
  21. package/android/src/main/jni/TrueSheetSpec.h +1 -0
  22. package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetContentViewComponentDescriptor.h +0 -8
  23. package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetContentViewShadowNode.cpp +52 -29
  24. package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetContentViewShadowNode.h +6 -1
  25. package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetContentViewState.cpp +1 -1
  26. package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetContentViewState.h +6 -4
  27. package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetFooterViewShadowNode.cpp +7 -0
  28. package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetLayoutUtils.h +46 -0
  29. package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetOverlayViewComponentDescriptor.h +21 -0
  30. package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetOverlayViewShadowNode.cpp +17 -0
  31. package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetOverlayViewShadowNode.h +36 -0
  32. package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetViewShadowNode.cpp +4 -35
  33. package/ios/TrueSheetContainerView.h +14 -7
  34. package/ios/TrueSheetContainerView.mm +10 -7
  35. package/ios/TrueSheetContentView.h +31 -15
  36. package/ios/TrueSheetContentView.mm +148 -188
  37. package/ios/TrueSheetFooterView.h +6 -0
  38. package/ios/TrueSheetFooterView.mm +48 -2
  39. package/ios/TrueSheetModule.h +2 -7
  40. package/ios/TrueSheetModule.mm +7 -16
  41. package/ios/TrueSheetOverlayView.h +32 -0
  42. package/ios/TrueSheetOverlayView.mm +161 -0
  43. package/ios/TrueSheetView.mm +171 -29
  44. package/ios/TrueSheetViewController.h +10 -0
  45. package/ios/TrueSheetViewController.mm +256 -74
  46. package/ios/core/TrueSheetGrabberView.mm +13 -3
  47. package/ios/core/TrueSheetOverlayContainerView.h +31 -0
  48. package/ios/core/TrueSheetOverlayContainerView.mm +35 -0
  49. package/ios/events/TrueSheetLifecycleEvents.h +2 -0
  50. package/ios/events/TrueSheetLifecycleEvents.mm +8 -0
  51. package/ios/tvos/TrueSheetStubs.mm +12 -0
  52. package/ios/utils/UIView+ScrollEdgeInteraction.h +1 -0
  53. package/ios/utils/UIView+ScrollEdgeInteraction.mm +24 -2
  54. package/lib/module/TrueSheet.js +149 -34
  55. package/lib/module/TrueSheet.js.map +1 -1
  56. package/lib/module/TrueSheet.web.js +122 -53
  57. package/lib/module/TrueSheet.web.js.map +1 -1
  58. package/lib/module/TrueSheetOverlay.js +30 -0
  59. package/lib/module/TrueSheetOverlay.js.map +1 -0
  60. package/lib/module/TrueSheetOverlay.web.js +35 -0
  61. package/lib/module/TrueSheetOverlay.web.js.map +1 -0
  62. package/lib/module/TrueSheetPeek.web.js +3 -3
  63. package/lib/module/TrueSheetPeek.web.js.map +1 -1
  64. package/lib/module/fabric/TrueSheetContentViewNativeComponent.ts +1 -1
  65. package/lib/module/fabric/TrueSheetOverlayViewNativeComponent.ts +12 -0
  66. package/lib/module/fabric/TrueSheetViewNativeComponent.ts +5 -0
  67. package/lib/module/index.js +1 -0
  68. package/lib/module/index.js.map +1 -1
  69. package/lib/module/mocks/index.js +10 -0
  70. package/lib/module/mocks/index.js.map +1 -1
  71. package/lib/module/mocks/navigation.js +31 -21
  72. package/lib/module/mocks/navigation.js.map +1 -1
  73. package/lib/module/mocks/navigationExpoRouter.js +21 -0
  74. package/lib/module/mocks/navigationExpoRouter.js.map +1 -0
  75. package/lib/module/mocks/reanimated.js +1 -1
  76. package/lib/module/mocks/reanimated.js.map +1 -1
  77. package/lib/module/navigation/{TrueSheetView.js → TrueSheetNavigatorContent.js} +14 -12
  78. package/lib/module/navigation/TrueSheetNavigatorContent.js.map +1 -0
  79. package/lib/module/navigation/actions.js +50 -0
  80. package/lib/module/navigation/actions.js.map +1 -0
  81. package/lib/module/navigation/base-types.js +2 -0
  82. package/lib/module/navigation/base-types.js.map +1 -0
  83. package/lib/module/navigation/{TrueSheetRouter.js → createTrueSheetRouter.js} +11 -24
  84. package/lib/module/navigation/createTrueSheetRouter.js.map +1 -0
  85. package/lib/module/navigation/expo-router/base-types.js +2 -0
  86. package/lib/module/navigation/expo-router/base-types.js.map +1 -0
  87. package/lib/module/navigation/expo-router/index.js +50 -0
  88. package/lib/module/navigation/expo-router/index.js.map +1 -0
  89. package/lib/module/navigation/expo-router/types.js +4 -0
  90. package/lib/module/navigation/expo-router/types.js.map +1 -0
  91. package/lib/module/navigation/index.js +43 -2
  92. package/lib/module/navigation/index.js.map +1 -1
  93. package/lib/module/navigation/navigator.js +10 -0
  94. package/lib/module/navigation/navigator.js.map +1 -0
  95. package/lib/module/navigation/screen/ReanimatedTrueSheetScreen.js +2 -2
  96. package/lib/module/navigation/screen/ReanimatedTrueSheetScreen.js.map +1 -1
  97. package/lib/module/navigation/screen/TrueSheetScreen.js +2 -2
  98. package/lib/module/navigation/screen/TrueSheetScreen.js.map +1 -1
  99. package/lib/module/navigation/screen/useSheetScreenState.js +5 -4
  100. package/lib/module/navigation/screen/useSheetScreenState.js.map +1 -1
  101. package/lib/module/navigation/useTrueSheetNavigation.js +1 -1
  102. package/lib/module/navigation/useTrueSheetNavigation.js.map +1 -1
  103. package/lib/module/web/dom.js +10 -0
  104. package/lib/module/web/dom.js.map +1 -0
  105. package/lib/module/web/vaul/constants.js +4 -0
  106. package/lib/module/web/vaul/constants.js.map +1 -1
  107. package/lib/module/web/vaul/context.js.map +1 -1
  108. package/lib/module/web/vaul/helpers.js +10 -4
  109. package/lib/module/web/vaul/helpers.js.map +1 -1
  110. package/lib/module/web/vaul/index.js +35 -2
  111. package/lib/module/web/vaul/index.js.map +1 -1
  112. package/lib/typescript/src/TrueSheet.d.ts +6 -0
  113. package/lib/typescript/src/TrueSheet.d.ts.map +1 -1
  114. package/lib/typescript/src/TrueSheet.types.d.ts +72 -1
  115. package/lib/typescript/src/TrueSheet.types.d.ts.map +1 -1
  116. package/lib/typescript/src/TrueSheet.web.d.ts.map +1 -1
  117. package/lib/typescript/src/TrueSheetOverlay.d.ts +8 -0
  118. package/lib/typescript/src/TrueSheetOverlay.d.ts.map +1 -0
  119. package/lib/typescript/src/TrueSheetOverlay.web.d.ts +8 -0
  120. package/lib/typescript/src/TrueSheetOverlay.web.d.ts.map +1 -0
  121. package/lib/typescript/src/TrueSheetPeek.web.d.ts.map +1 -1
  122. package/lib/typescript/src/fabric/TrueSheetOverlayViewNativeComponent.d.ts +6 -0
  123. package/lib/typescript/src/fabric/TrueSheetOverlayViewNativeComponent.d.ts.map +1 -0
  124. package/lib/typescript/src/fabric/TrueSheetViewNativeComponent.d.ts +4 -0
  125. package/lib/typescript/src/fabric/TrueSheetViewNativeComponent.d.ts.map +1 -1
  126. package/lib/typescript/src/index.d.ts +1 -0
  127. package/lib/typescript/src/index.d.ts.map +1 -1
  128. package/lib/typescript/src/mocks/index.d.ts +4 -0
  129. package/lib/typescript/src/mocks/index.d.ts.map +1 -1
  130. package/lib/typescript/src/mocks/navigation.d.ts +5 -1
  131. package/lib/typescript/src/mocks/navigation.d.ts.map +1 -1
  132. package/lib/typescript/src/mocks/navigationExpoRouter.d.ts +22 -0
  133. package/lib/typescript/src/mocks/navigationExpoRouter.d.ts.map +1 -0
  134. package/lib/typescript/src/mocks/reanimated.d.ts.map +1 -1
  135. package/lib/typescript/src/navigation/TrueSheetNavigatorContent.d.ts +5 -0
  136. package/lib/typescript/src/navigation/TrueSheetNavigatorContent.d.ts.map +1 -0
  137. package/lib/typescript/src/navigation/actions.d.ts +71 -0
  138. package/lib/typescript/src/navigation/actions.d.ts.map +1 -0
  139. package/lib/typescript/src/navigation/base-types.d.ts +9 -0
  140. package/lib/typescript/src/navigation/base-types.d.ts.map +1 -0
  141. package/lib/typescript/src/navigation/createTrueSheetRouter.d.ts +3 -0
  142. package/lib/typescript/src/navigation/createTrueSheetRouter.d.ts.map +1 -0
  143. package/lib/typescript/src/navigation/expo-router/base-types.d.ts +8 -0
  144. package/lib/typescript/src/navigation/expo-router/base-types.d.ts.map +1 -0
  145. package/lib/typescript/src/navigation/expo-router/index.d.ts +37 -0
  146. package/lib/typescript/src/navigation/expo-router/index.d.ts.map +1 -0
  147. package/lib/typescript/src/navigation/expo-router/types.d.ts +44 -0
  148. package/lib/typescript/src/navigation/expo-router/types.d.ts.map +1 -0
  149. package/lib/typescript/src/navigation/index.d.ts +42 -3
  150. package/lib/typescript/src/navigation/index.d.ts.map +1 -1
  151. package/lib/typescript/src/navigation/navigator.d.ts +7 -0
  152. package/lib/typescript/src/navigation/navigator.d.ts.map +1 -0
  153. package/lib/typescript/src/navigation/screen/ReanimatedTrueSheetScreen.d.ts +1 -1
  154. package/lib/typescript/src/navigation/screen/ReanimatedTrueSheetScreen.d.ts.map +1 -1
  155. package/lib/typescript/src/navigation/screen/TrueSheetScreen.d.ts +1 -1
  156. package/lib/typescript/src/navigation/screen/TrueSheetScreen.d.ts.map +1 -1
  157. package/lib/typescript/src/navigation/screen/types.d.ts +3 -4
  158. package/lib/typescript/src/navigation/screen/types.d.ts.map +1 -1
  159. package/lib/typescript/src/navigation/screen/useSheetScreenState.d.ts +5 -6
  160. package/lib/typescript/src/navigation/screen/useSheetScreenState.d.ts.map +1 -1
  161. package/lib/typescript/src/navigation/types.d.ts +65 -5
  162. package/lib/typescript/src/navigation/types.d.ts.map +1 -1
  163. package/lib/typescript/src/navigation/useTrueSheetNavigation.d.ts +1 -1
  164. package/lib/typescript/src/navigation/useTrueSheetNavigation.d.ts.map +1 -1
  165. package/lib/typescript/src/web/dom.d.ts +7 -0
  166. package/lib/typescript/src/web/dom.d.ts.map +1 -0
  167. package/lib/typescript/src/web/vaul/constants.d.ts +1 -0
  168. package/lib/typescript/src/web/vaul/constants.d.ts.map +1 -1
  169. package/lib/typescript/src/web/vaul/context.d.ts +1 -0
  170. package/lib/typescript/src/web/vaul/context.d.ts.map +1 -1
  171. package/lib/typescript/src/web/vaul/helpers.d.ts.map +1 -1
  172. package/lib/typescript/src/web/vaul/index.d.ts +7 -1
  173. package/lib/typescript/src/web/vaul/index.d.ts.map +1 -1
  174. package/package.json +32 -9
  175. package/react-native.config.js +1 -0
  176. package/src/TrueSheet.tsx +184 -46
  177. package/src/TrueSheet.types.ts +77 -1
  178. package/src/TrueSheet.web.tsx +135 -64
  179. package/src/TrueSheetOverlay.tsx +24 -0
  180. package/src/TrueSheetOverlay.web.tsx +33 -0
  181. package/src/TrueSheetPeek.web.tsx +4 -3
  182. package/src/fabric/TrueSheetContentViewNativeComponent.ts +1 -1
  183. package/src/fabric/TrueSheetOverlayViewNativeComponent.ts +12 -0
  184. package/src/fabric/TrueSheetViewNativeComponent.ts +5 -0
  185. package/src/index.ts +1 -0
  186. package/src/mocks/index.ts +7 -0
  187. package/src/mocks/navigation.ts +32 -25
  188. package/src/mocks/navigationExpoRouter.ts +41 -0
  189. package/src/mocks/reanimated.ts +8 -9
  190. package/src/navigation/{TrueSheetView.tsx → TrueSheetNavigatorContent.tsx} +24 -17
  191. package/src/navigation/actions.ts +78 -0
  192. package/src/navigation/base-types.ts +20 -0
  193. package/src/navigation/createTrueSheetRouter.ts +194 -0
  194. package/src/navigation/expo-router/base-types.ts +18 -0
  195. package/src/navigation/expo-router/index.ts +90 -0
  196. package/src/navigation/expo-router/types.ts +116 -0
  197. package/src/navigation/index.ts +68 -2
  198. package/src/navigation/navigator.ts +18 -0
  199. package/src/navigation/screen/ReanimatedTrueSheetScreen.tsx +2 -2
  200. package/src/navigation/screen/TrueSheetScreen.tsx +2 -2
  201. package/src/navigation/screen/types.ts +4 -6
  202. package/src/navigation/screen/useSheetScreenState.ts +10 -15
  203. package/src/navigation/types.ts +99 -16
  204. package/src/navigation/useTrueSheetNavigation.ts +1 -1
  205. package/src/web/dom.ts +9 -0
  206. package/src/web/vaul/constants.ts +4 -0
  207. package/src/web/vaul/context.ts +1 -0
  208. package/src/web/vaul/helpers.ts +13 -6
  209. package/src/web/vaul/index.tsx +46 -1
  210. package/lib/module/navigation/TrueSheetRouter.js.map +0 -1
  211. package/lib/module/navigation/TrueSheetView.js.map +0 -1
  212. package/lib/module/navigation/createTrueSheetNavigator.js +0 -63
  213. package/lib/module/navigation/createTrueSheetNavigator.js.map +0 -1
  214. package/lib/typescript/src/navigation/TrueSheetRouter.d.ts +0 -57
  215. package/lib/typescript/src/navigation/TrueSheetRouter.d.ts.map +0 -1
  216. package/lib/typescript/src/navigation/TrueSheetView.d.ts +0 -10
  217. package/lib/typescript/src/navigation/TrueSheetView.d.ts.map +0 -1
  218. package/lib/typescript/src/navigation/createTrueSheetNavigator.d.ts +0 -35
  219. package/lib/typescript/src/navigation/createTrueSheetNavigator.d.ts.map +0 -1
  220. package/src/navigation/TrueSheetRouter.ts +0 -234
  221. package/src/navigation/createTrueSheetNavigator.tsx +0 -93
@@ -0,0 +1,116 @@
1
+ /**
2
+ * Expo Router flavour of `../types`: same shapes, but bound to Expo Router's
3
+ * vendored React Navigation types so apps that only install `expo-router` still
4
+ * get real types instead of `any` — see `./base-types`.
5
+ */
6
+ import type { TrueSheetActionType } from '../actions';
7
+ import type {
8
+ TrueSheetActionHelpersOf,
9
+ TrueSheetDispatch,
10
+ TrueSheetNavigationEventMap,
11
+ TrueSheetNavigationOptions,
12
+ TrueSheetStateOf,
13
+ } from '../types';
14
+ import type {
15
+ DefaultNavigatorOptions,
16
+ NavigationAction,
17
+ NavigationHelpers,
18
+ NavigationProp,
19
+ NavigationState,
20
+ ParamListBase,
21
+ RouteProp,
22
+ Router,
23
+ StackActionHelpers,
24
+ StackRouterOptions,
25
+ } from './base-types';
26
+
27
+ export type TrueSheetRouterOptions = StackRouterOptions;
28
+
29
+ export type TrueSheetNavigationState<ParamList extends ParamListBase> = TrueSheetStateOf<
30
+ NavigationState<ParamList>
31
+ >;
32
+
33
+ export type TrueSheetRouterState = TrueSheetNavigationState<ParamListBase>;
34
+
35
+ export type TrueSheetRouter = Router<TrueSheetRouterState, TrueSheetActionType>;
36
+
37
+ export type TrueSheetRouterFactory = (options: TrueSheetRouterOptions) => TrueSheetRouter;
38
+
39
+ /**
40
+ * The base `StackRouter` factory to wrap — see `../types` for the shared contract.
41
+ */
42
+ export type StackRouterFactory = <
43
+ State extends NavigationState<ParamListBase>,
44
+ Action extends NavigationAction,
45
+ >(
46
+ options: TrueSheetRouterOptions
47
+ ) => Router<State, Action>;
48
+
49
+ export type TrueSheetRoute = TrueSheetNavigationState<ParamListBase>['routes'][number];
50
+
51
+ /**
52
+ * Props injected into the navigator content by Expo Router's `createProps`.
53
+ * Raw routes carry the custom fields (`closing`, `resizeIndex`, `resizeKey`)
54
+ * that the standard state strips out.
55
+ */
56
+ export interface TrueSheetNavigatorContentExtraProps {
57
+ routes: TrueSheetRoute[];
58
+ dispatch: TrueSheetDispatch;
59
+ }
60
+
61
+ export type TrueSheetActionHelpers<ParamList extends ParamListBase> = TrueSheetActionHelpersOf<
62
+ StackActionHelpers<ParamList>
63
+ >;
64
+
65
+ export type TrueSheetNavigationProp<
66
+ ParamList extends ParamListBase,
67
+ RouteName extends keyof ParamList = string,
68
+ NavigatorID extends string | undefined = undefined,
69
+ > = NavigationProp<
70
+ ParamList,
71
+ RouteName,
72
+ NavigatorID,
73
+ TrueSheetNavigationState<ParamList>,
74
+ TrueSheetNavigationOptions,
75
+ TrueSheetNavigationEventMap
76
+ > &
77
+ TrueSheetActionHelpers<ParamList>;
78
+
79
+ export type TrueSheetScreenProps<
80
+ ParamList extends ParamListBase,
81
+ RouteName extends keyof ParamList = string,
82
+ NavigatorID extends string | undefined = undefined,
83
+ > = {
84
+ navigation: TrueSheetNavigationProp<ParamList, RouteName, NavigatorID>;
85
+ route: RouteProp<ParamList, RouteName>;
86
+ };
87
+
88
+ export type TrueSheetNavigationHelpers = NavigationHelpers<
89
+ ParamListBase,
90
+ TrueSheetNavigationEventMap
91
+ >;
92
+
93
+ export type TrueSheetNavigatorProps = DefaultNavigatorOptions<
94
+ ParamListBase,
95
+ string | undefined,
96
+ TrueSheetNavigationState<ParamListBase>,
97
+ TrueSheetNavigationOptions,
98
+ TrueSheetNavigationEventMap,
99
+ unknown
100
+ > & {
101
+ /**
102
+ * The name of the route to use as the base screen.
103
+ * This screen will be rendered as a regular screen, while other screens are presented as sheets.
104
+ * Defaults to the first screen defined in the navigator.
105
+ */
106
+ initialRouteName?: string;
107
+ };
108
+
109
+ export type {
110
+ PositionChangeHandler,
111
+ TrueSheetDispatch,
112
+ TrueSheetNavigationEventMap,
113
+ TrueSheetNavigationOptions,
114
+ TrueSheetNavigationSheetProps,
115
+ TrueSheetStandardEventMap,
116
+ } from '../types';
@@ -1,14 +1,80 @@
1
- export { createTrueSheetNavigator } from './createTrueSheetNavigator';
2
- export { TrueSheetActions, type TrueSheetActionType } from './TrueSheetRouter';
1
+ import {
2
+ createStandardNavigationFactories,
3
+ StackRouter,
4
+ type StandardNavigationTypeBagBase,
5
+ } from '@react-navigation/native';
6
+
7
+ import { createTrueSheetRouter } from './createTrueSheetRouter';
8
+ import { trueSheetNavigator } from './navigator';
9
+ import type {
10
+ StackRouterFactory,
11
+ TrueSheetActionHelpers,
12
+ TrueSheetNavigationOptions,
13
+ TrueSheetNavigationEventMap,
14
+ TrueSheetNavigationState,
15
+ TrueSheetNavigatorContentExtraProps,
16
+ TrueSheetRouterOptions,
17
+ } from './types';
18
+
19
+ export interface TrueSheetNavigationTypeBag extends StandardNavigationTypeBagBase {
20
+ State: TrueSheetNavigationState<this['ParamList']>;
21
+ ActionHelpers: TrueSheetActionHelpers<this['ParamList']>;
22
+ ScreenOptions: TrueSheetNavigationOptions;
23
+ EventMap: TrueSheetNavigationEventMap;
24
+ RouterOptions: TrueSheetRouterOptions;
25
+ }
26
+
27
+ const { createNavigator, createScreen } = createStandardNavigationFactories<
28
+ TrueSheetNavigationTypeBag,
29
+ {},
30
+ TrueSheetNavigatorContentExtraProps
31
+ >(
32
+ trueSheetNavigator,
33
+ createTrueSheetRouter(StackRouter as StackRouterFactory),
34
+ ({ state, navigation }) => ({ routes: state.routes, dispatch: navigation.dispatch })
35
+ );
36
+
37
+ /**
38
+ * Creates a TrueSheet navigator.
39
+ *
40
+ * @example
41
+ * ```tsx
42
+ * const Sheet = createTrueSheetNavigator();
43
+ *
44
+ * function App() {
45
+ * return (
46
+ * <Sheet.Navigator>
47
+ * <Sheet.Screen name="Home" component={HomeScreen} />
48
+ * <Sheet.Screen
49
+ * name="Details"
50
+ * component={DetailsSheet}
51
+ * options={{ detents: [0.5, 1] }}
52
+ * />
53
+ * </Sheet.Navigator>
54
+ * );
55
+ * }
56
+ * ```
57
+ */
58
+ export const createTrueSheetNavigator = createNavigator;
59
+
60
+ /**
61
+ * Creates a screen configuration for the static API.
62
+ */
63
+ export const createTrueSheetScreen = createScreen;
64
+
65
+ export { TrueSheetActions, type TrueSheetActionType } from './actions';
66
+ export { createTrueSheetRouter } from './createTrueSheetRouter';
3
67
  export { useTrueSheetNavigation } from './useTrueSheetNavigation';
4
68
 
5
69
  export type { DetentInfoEventPayload, PositionChangeEventPayload } from '../TrueSheet.types';
6
70
 
7
71
  export type {
72
+ StackRouterFactory,
8
73
  TrueSheetNavigationEventMap,
9
74
  TrueSheetNavigationHelpers,
10
75
  TrueSheetNavigationOptions,
11
76
  TrueSheetNavigationProp,
12
77
  TrueSheetNavigationState,
78
+ TrueSheetRouterOptions,
13
79
  TrueSheetScreenProps,
14
80
  } from './types';
@@ -0,0 +1,18 @@
1
+ import { createStandardNavigator } from 'standard-navigation';
2
+
3
+ import { TrueSheetNavigatorContent } from './TrueSheetNavigatorContent';
4
+ import type {
5
+ TrueSheetNavigationOptions,
6
+ TrueSheetNavigatorContentExtraProps,
7
+ TrueSheetStandardEventMap,
8
+ } from './types';
9
+
10
+ /**
11
+ * Framework-agnostic TrueSheet navigator.
12
+ * Wired into React Navigation via `./index` and Expo Router via `./expo-router`.
13
+ */
14
+ export const trueSheetNavigator = createStandardNavigator<
15
+ TrueSheetNavigationOptions,
16
+ TrueSheetStandardEventMap,
17
+ TrueSheetNavigatorContentExtraProps
18
+ >(TrueSheetNavigatorContent);
@@ -12,7 +12,7 @@ const AnimatedTrueSheet = Animated.createAnimatedComponent(TrueSheet);
12
12
  export const ReanimatedTrueSheetScreen = ({
13
13
  detentIndex,
14
14
  resizeKey,
15
- navigation,
15
+ dispatch,
16
16
  emit,
17
17
  routeKey,
18
18
  closing,
@@ -29,7 +29,7 @@ export const ReanimatedTrueSheetScreen = ({
29
29
  detentIndex,
30
30
  resizeKey,
31
31
  closing,
32
- navigation,
32
+ dispatch,
33
33
  routeKey,
34
34
  emit,
35
35
  });
@@ -8,7 +8,7 @@ import { useSheetScreenState } from './useSheetScreenState';
8
8
  export const TrueSheetScreen = ({
9
9
  detentIndex,
10
10
  resizeKey,
11
- navigation,
11
+ dispatch,
12
12
  emit,
13
13
  routeKey,
14
14
  closing,
@@ -25,7 +25,7 @@ export const TrueSheetScreen = ({
25
25
  detentIndex,
26
26
  resizeKey,
27
27
  closing,
28
- navigation,
28
+ dispatch,
29
29
  routeKey,
30
30
  emit,
31
31
  });
@@ -1,18 +1,16 @@
1
- import type { ParamListBase } from '@react-navigation/core';
2
-
3
1
  import type { TrueSheetProps } from '../../TrueSheet.types';
4
2
  import type {
5
3
  PositionChangeHandler,
6
- TrueSheetNavigationHelpers,
7
- TrueSheetNavigationProp,
4
+ TrueSheetDispatch,
5
+ TrueSheetEmitFn,
8
6
  TrueSheetNavigationSheetProps,
9
7
  } from '../types';
10
8
 
11
9
  export interface TrueSheetScreenProps extends TrueSheetNavigationSheetProps {
12
10
  detentIndex: number;
13
11
  resizeKey?: number;
14
- navigation: TrueSheetNavigationProp<ParamListBase>;
15
- emit: TrueSheetNavigationHelpers['emit'];
12
+ dispatch: TrueSheetDispatch;
13
+ emit: TrueSheetEmitFn;
16
14
  routeKey: string;
17
15
  closing?: boolean;
18
16
  detents: TrueSheetProps['detents'];
@@ -14,30 +14,24 @@ import type {
14
14
  PositionChangeEventPayload,
15
15
  WillBlurEvent,
16
16
  WillDismissEvent,
17
+ DismissAttemptEvent,
17
18
  WillFocusEvent,
18
19
  WillPresentEvent,
19
20
  } from '../../TrueSheet.types';
20
- import type {
21
- TrueSheetNavigationEventMap,
22
- TrueSheetNavigationHelpers,
23
- TrueSheetNavigationProp,
24
- } from '../types';
25
- import { TrueSheetActions } from '../TrueSheetRouter';
26
- import type { ParamListBase } from '@react-navigation/core';
27
-
28
- type EmitFn = TrueSheetNavigationHelpers['emit'];
21
+ import type { TrueSheetDispatch, TrueSheetEmitFn, TrueSheetNavigationEventMap } from '../types';
22
+ import { TrueSheetActions } from '../actions';
29
23
 
30
24
  interface UseSheetScreenStateProps {
31
25
  detentIndex: number;
32
26
  resizeKey?: number;
33
27
  closing?: boolean;
34
- navigation: TrueSheetNavigationProp<ParamListBase>;
28
+ dispatch: TrueSheetDispatch;
35
29
  routeKey: string;
36
- emit: EmitFn;
30
+ emit: TrueSheetEmitFn;
37
31
  }
38
32
 
39
33
  export const useSheetScreenState = (props: UseSheetScreenStateProps) => {
40
- const { detentIndex, resizeKey, closing, navigation, routeKey, emit } = props;
34
+ const { detentIndex, resizeKey, closing, dispatch, routeKey, emit } = props;
41
35
 
42
36
  const ref = useRef<TrueSheet>(null);
43
37
  const isDismissedRef = useRef(false);
@@ -68,7 +62,7 @@ export const useSheetScreenState = (props: UseSheetScreenStateProps) => {
68
62
  type,
69
63
  target: routeKey,
70
64
  data,
71
- } as Parameters<EmitFn>[0]);
65
+ } as Parameters<TrueSheetEmitFn>[0]);
72
66
  },
73
67
  [emit, routeKey]
74
68
  );
@@ -76,8 +70,8 @@ export const useSheetScreenState = (props: UseSheetScreenStateProps) => {
76
70
  const onDidDismiss = useCallback(() => {
77
71
  emitEvent('sheetDidDismiss', undefined);
78
72
  isDismissedRef.current = true;
79
- navigation.dispatch({ ...TrueSheetActions.remove(), source: routeKey });
80
- }, [emitEvent, navigation, routeKey]);
73
+ dispatch({ ...TrueSheetActions.remove(), source: routeKey });
74
+ }, [emitEvent, dispatch, routeKey]);
81
75
 
82
76
  const eventHandlers = useMemo(
83
77
  () => ({
@@ -85,6 +79,7 @@ export const useSheetScreenState = (props: UseSheetScreenStateProps) => {
85
79
  onDidPresent: (e: DidPresentEvent) => emitEvent('sheetDidPresent', e.nativeEvent),
86
80
  onWillDismiss: (_e: WillDismissEvent) => emitEvent('sheetWillDismiss', undefined),
87
81
  onDidDismiss,
82
+ onDismissAttempt: (_e: DismissAttemptEvent) => emitEvent('sheetDismissAttempt', undefined),
88
83
  onDetentChange: (e: DetentChangeEvent) => emitEvent('sheetDetentChange', e.nativeEvent),
89
84
  onDragBegin: (e: DragBeginEvent) => emitEvent('sheetDragBegin', e.nativeEvent),
90
85
  onDragChange: (e: DragChangeEvent) => emitEvent('sheetDragChange', e.nativeEvent),
@@ -1,19 +1,24 @@
1
+ import type { NavigatorArgs } from 'standard-navigation';
2
+
3
+ import type {
4
+ DetentInfoEventPayload,
5
+ PositionChangeEventPayload,
6
+ TrueSheetProps,
7
+ } from '../TrueSheet.types';
8
+ import type { TrueSheetActionType } from './actions';
1
9
  import type {
2
10
  DefaultNavigatorOptions,
3
11
  Descriptor,
12
+ NavigationAction,
4
13
  NavigationHelpers,
5
14
  NavigationProp,
6
15
  NavigationState,
7
16
  ParamListBase,
8
17
  RouteProp,
18
+ Router,
9
19
  StackActionHelpers,
10
- } from '@react-navigation/core';
11
-
12
- import type {
13
- DetentInfoEventPayload,
14
- PositionChangeEventPayload,
15
- TrueSheetProps,
16
- } from '../TrueSheet.types';
20
+ StackRouterOptions,
21
+ } from './base-types';
17
22
 
18
23
  export type PositionChangeHandler = (payload: PositionChangeEventPayload) => void;
19
24
 
@@ -34,6 +39,10 @@ export type TrueSheetNavigationEventMap = {
34
39
  * Event fired when the sheet has been dismissed.
35
40
  */
36
41
  sheetDidDismiss: { data: undefined };
42
+ /**
43
+ * Event fired when the user tries to dismiss a non-dismissible sheet.
44
+ */
45
+ sheetDismissAttempt: { data: undefined };
37
46
  /**
38
47
  * Event fired when the sheet's detent changes.
39
48
  */
@@ -72,25 +81,98 @@ export type TrueSheetNavigationEventMap = {
72
81
  sheetDidBlur: { data: undefined };
73
82
  };
74
83
 
75
- export type TrueSheetNavigationState<ParamList extends ParamListBase> = Omit<
76
- NavigationState<ParamList>,
84
+ /**
85
+ * A navigation state tagged as `true-sheet`, with the sheet fields the router
86
+ * adds to each route.
87
+ * Generic over the base state so each entry point can bind its own
88
+ * `NavigationState` — see `./base-types`.
89
+ */
90
+ export type TrueSheetStateOf<State extends { routes: readonly unknown[] }> = Omit<
91
+ State,
77
92
  'routes'
78
93
  > & {
79
94
  type: 'true-sheet';
80
- routes: (NavigationState<ParamList>['routes'][number] & {
95
+ routes: (State['routes'][number] & {
81
96
  resizeIndex?: number;
82
97
  resizeKey?: number;
83
98
  closing?: boolean;
84
99
  })[];
85
100
  };
86
101
 
87
- export type TrueSheetActionHelpers<ParamList extends ParamListBase> =
88
- StackActionHelpers<ParamList> & {
89
- /**
90
- * Resize the sheet to a specific detent index.
91
- */
92
- resize(index?: number): void;
102
+ export type TrueSheetNavigationState<ParamList extends ParamListBase> = TrueSheetStateOf<
103
+ NavigationState<ParamList>
104
+ >;
105
+
106
+ export type TrueSheetRouterState = TrueSheetNavigationState<ParamListBase>;
107
+
108
+ export type TrueSheetRouterOptions = StackRouterOptions;
109
+
110
+ export type TrueSheetRouter = Router<TrueSheetRouterState, TrueSheetActionType>;
111
+
112
+ /**
113
+ * The wrapped router factory — also the shape `createTrueSheetRouter` accepts,
114
+ * pre-instantiated so either entry point's `StackRouterFactory` fits it.
115
+ */
116
+ export type TrueSheetRouterFactory = (options: TrueSheetRouterOptions) => TrueSheetRouter;
117
+
118
+ /**
119
+ * The base `StackRouter` factory to wrap, typed generically over the state and
120
+ * action types the wrapper threads through — `StackRouter` is structural and
121
+ * never touches the sheet-specific fields.
122
+ * Injected by each entry point so the shared router never imports
123
+ * `@react-navigation/*` at runtime (Expo Router apps don't install it).
124
+ */
125
+ export type StackRouterFactory = <
126
+ State extends NavigationState<ParamListBase>,
127
+ Action extends NavigationAction,
128
+ >(
129
+ options: TrueSheetRouterOptions
130
+ ) => Router<State, Action>;
131
+
132
+ /**
133
+ * `TrueSheetNavigationEventMap` in the `standard-navigation` event-map shape.
134
+ */
135
+ export type TrueSheetStandardEventMap = {
136
+ [K in keyof TrueSheetNavigationEventMap]: {
137
+ data: TrueSheetNavigationEventMap[K]['data'];
138
+ canPreventDefault: false;
93
139
  };
140
+ };
141
+
142
+ export type TrueSheetRoute = TrueSheetNavigationState<ParamListBase>['routes'][number];
143
+
144
+ export type TrueSheetDispatch = (action: TrueSheetActionType) => void;
145
+
146
+ export type TrueSheetEmitFn = NavigatorArgs<
147
+ TrueSheetNavigationOptions,
148
+ TrueSheetStandardEventMap
149
+ >['emitter']['emit'];
150
+
151
+ /**
152
+ * Props injected into the navigator content by each adapter
153
+ * (React Navigation's `mapper` / Expo Router's `createProps`).
154
+ * Raw routes carry the custom fields (`closing`, `resizeIndex`, `resizeKey`)
155
+ * that the standard state strips out.
156
+ */
157
+ export interface TrueSheetNavigatorContentExtraProps {
158
+ routes: TrueSheetRoute[];
159
+ dispatch: TrueSheetDispatch;
160
+ }
161
+
162
+ /**
163
+ * Generic over the base helpers so each entry point can bind its own
164
+ * `StackActionHelpers` — see `./base-types`.
165
+ */
166
+ export type TrueSheetActionHelpersOf<Helpers> = Helpers & {
167
+ /**
168
+ * Resize the sheet to a specific detent index.
169
+ */
170
+ resize(index?: number): void;
171
+ };
172
+
173
+ export type TrueSheetActionHelpers<ParamList extends ParamListBase> = TrueSheetActionHelpersOf<
174
+ StackActionHelpers<ParamList>
175
+ >;
94
176
 
95
177
  export type TrueSheetNavigationProp<
96
178
  ParamList extends ParamListBase,
@@ -144,6 +226,7 @@ export type TrueSheetNavigationSheetProps = Pick<
144
226
  | 'footer'
145
227
  | 'footerStyle'
146
228
  | 'footerOptions'
229
+ | 'scrollableRef'
147
230
  | 'scrollableOptions'
148
231
  | 'insetAdjustment'
149
232
  | 'anchor'
@@ -1,4 +1,4 @@
1
- import { useNavigation, type ParamListBase } from '@react-navigation/core';
1
+ import { useNavigation, type ParamListBase } from '@react-navigation/native';
2
2
 
3
3
  import type { TrueSheetNavigationProp } from './types';
4
4
 
package/src/web/dom.ts ADDED
@@ -0,0 +1,9 @@
1
+ /// <reference lib="dom" />
2
+ import type { View } from 'react-native';
3
+
4
+ /**
5
+ * Resolves a React Native web `View` ref value to its underlying DOM element —
6
+ * RN-web refs expose the host DOM node directly.
7
+ */
8
+ export const getDOMElement = (view: View | null): HTMLElement | null =>
9
+ view instanceof HTMLElement ? view : null;
@@ -9,6 +9,10 @@ export const DEFAULT_PEEK_HEIGHT = 150;
9
9
 
10
10
  export const CLOSE_THRESHOLD = 0.25;
11
11
 
12
+ // Minimum downward pull (px) on a non-dismissible drawer at its first snap
13
+ // point before the release counts as a dismiss attempt.
14
+ export const DISMISS_ATTEMPT_THRESHOLD = 24;
15
+
12
16
  export const SCROLL_LOCK_TIMEOUT = 100;
13
17
 
14
18
  export const BORDER_RADIUS = 8;
@@ -23,6 +23,7 @@ interface DrawerContextValue {
23
23
  onNestedOpenChange: (o: boolean) => void;
24
24
  onNestedRelease: (event: React.PointerEvent<HTMLDivElement>, open: boolean) => void;
25
25
  dismissible: boolean;
26
+ onDismissAttempt?: () => void;
26
27
  isOpen: boolean;
27
28
  isDragging: boolean;
28
29
  keyboardIsOpen: React.MutableRefObject<boolean>;
@@ -4,7 +4,12 @@ interface Style {
4
4
  [key: string]: string;
5
5
  }
6
6
 
7
- const cache = new WeakMap();
7
+ // CSSStyleDeclaration has no string index signature, so dynamic camelCase
8
+ // keys are assigned through this writable-record view. Values include
9
+ // undefined: originals captured for unknown keys read back as undefined.
10
+ type IndexableStyle = CSSStyleDeclaration & Record<string, string | undefined>;
11
+
12
+ const cache = new WeakMap<HTMLElement, Record<string, string | undefined>>();
8
13
 
9
14
  export function isInView(el: HTMLElement): boolean {
10
15
  const rect = el.getBoundingClientRect();
@@ -26,7 +31,8 @@ export function set(
26
31
  ignoreCache = false
27
32
  ) {
28
33
  if (!el || !(el instanceof HTMLElement)) return;
29
- let originalStyles: Style = {};
34
+ let originalStyles: Record<string, string | undefined> = {};
35
+ const style = el.style as IndexableStyle;
30
36
 
31
37
  Object.entries(styles).forEach(([key, value]: [string, string]) => {
32
38
  if (key.startsWith('--')) {
@@ -34,8 +40,8 @@ export function set(
34
40
  return;
35
41
  }
36
42
 
37
- originalStyles[key] = (el.style as any)[key];
38
- (el.style as any)[key] = value;
43
+ originalStyles[key] = style[key];
44
+ style[key] = value;
39
45
  });
40
46
 
41
47
  if (ignoreCache) return;
@@ -51,11 +57,12 @@ export function reset(el: Element | HTMLElement | null, prop?: string) {
51
57
  return;
52
58
  }
53
59
 
60
+ const style = el.style as IndexableStyle;
54
61
  if (prop) {
55
- (el.style as any)[prop] = originalStyles[prop];
62
+ style[prop] = originalStyles[prop];
56
63
  } else {
57
64
  Object.entries(originalStyles).forEach(([key, value]) => {
58
- (el.style as any)[key] = value;
65
+ style[key] = value;
59
66
  });
60
67
  }
61
68
  }