@granite-js/react-native 0.0.1

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 (189) hide show
  1. package/CHANGELOG.md +66 -0
  2. package/LICENSE +202 -0
  3. package/README.md +24 -0
  4. package/bin/cli.js +3 -0
  5. package/cli.d.ts +1 -0
  6. package/cli.js +4 -0
  7. package/config.d.ts +2 -0
  8. package/config.js +5 -0
  9. package/dist/app/App/index.android.d.ts +2 -0
  10. package/dist/app/App/index.ios.d.ts +6 -0
  11. package/dist/app/Granite.d.ts +60 -0
  12. package/dist/app/index.d.ts +2 -0
  13. package/dist/app/registerPage.d.ts +20 -0
  14. package/dist/async-bridges.d.ts +2 -0
  15. package/dist/constant-bridges.d.ts +1 -0
  16. package/dist/dev-entrypoint/index.d.ts +2 -0
  17. package/dist/event/abstract.d.ts +42 -0
  18. package/dist/event/index.d.ts +2 -0
  19. package/dist/event/useGraniteEvent.d.ts +14 -0
  20. package/dist/impression-area/ImpressionArea.d.ts +231 -0
  21. package/dist/impression-area/index.d.ts +1 -0
  22. package/dist/index.d.ts +17 -0
  23. package/dist/initial-props/InitialProps.d.ts +127 -0
  24. package/dist/initial-props/index.d.ts +1 -0
  25. package/dist/intersection-observer/IOContext.d.ts +10 -0
  26. package/dist/intersection-observer/IOFlatList.d.ts +55 -0
  27. package/dist/intersection-observer/IOManager.d.ts +24 -0
  28. package/dist/intersection-observer/IOScrollView.d.ts +59 -0
  29. package/dist/intersection-observer/InView.d.ts +107 -0
  30. package/dist/intersection-observer/IntersectionObserver.d.ts +67 -0
  31. package/dist/intersection-observer/index.d.ts +8 -0
  32. package/dist/intersection-observer/withIO.d.ts +20 -0
  33. package/dist/jest/index.d.ts +1 -0
  34. package/dist/jest/index.js +32 -0
  35. package/dist/keyboard/KeyboardAboveView.d.ts +40 -0
  36. package/dist/keyboard/index.d.ts +1 -0
  37. package/dist/keyboard/useKeyboardAnimatedHeight.d.ts +20 -0
  38. package/dist/native-event-emitter/eventEmitters/index.d.ts +2 -0
  39. package/dist/native-event-emitter/eventEmitters/types.d.ts +4 -0
  40. package/dist/native-event-emitter/eventEmitters/visibilityChanged.d.ts +10 -0
  41. package/dist/native-event-emitter/index.d.ts +1 -0
  42. package/dist/native-event-emitter/nativeEventEmitter.d.ts +15 -0
  43. package/dist/native-modules/core/GraniteCoreModule.d.ts +8 -0
  44. package/dist/native-modules/index.d.ts +3 -0
  45. package/dist/native-modules/natives/GraniteModule.d.ts +7 -0
  46. package/dist/native-modules/natives/closeView.d.ts +21 -0
  47. package/dist/native-modules/natives/getSchemeUri.d.ts +23 -0
  48. package/dist/native-modules/natives/index.d.ts +3 -0
  49. package/dist/native-modules/natives/openURL.d.ts +36 -0
  50. package/dist/react/index.d.ts +1 -0
  51. package/dist/react/useWaitForReturnNavigator.d.ts +39 -0
  52. package/dist/rn-polyfills/index.d.ts +1 -0
  53. package/dist/rn-polyfills/symbol-asynciterator/index.d.ts +9 -0
  54. package/dist/rn-polyfills/url/index.d.ts +1 -0
  55. package/dist/router/Router.d.ts +59 -0
  56. package/dist/router/components/BackButton.d.ts +7 -0
  57. package/dist/router/components/CanGoBackGuard.d.ts +6 -0
  58. package/dist/router/components/RouterBackButton.d.ts +9 -0
  59. package/dist/router/components/StackNavigator.d.ts +54 -0
  60. package/dist/router/constants.d.ts +2 -0
  61. package/dist/router/createRoute.d.ts +39 -0
  62. package/dist/router/createRoute.test-d.d.ts +9 -0
  63. package/dist/router/hooks/useInitialRouteName.d.ts +1 -0
  64. package/dist/router/hooks/useIsInitialScreen.d.ts +1 -0
  65. package/dist/router/hooks/useRouterControls.d.ts +11 -0
  66. package/dist/router/index.d.ts +3 -0
  67. package/dist/router/types/RequireContext.d.ts +7 -0
  68. package/dist/router/types/RouteScreen.d.ts +16 -0
  69. package/dist/router/types/Screen.d.ts +23 -0
  70. package/dist/router/types/index.d.ts +3 -0
  71. package/dist/router/types/screen-option.d.ts +4 -0
  72. package/dist/router/utils/createParentRouteScreenMap.d.ts +8 -0
  73. package/dist/router/utils/defaultParserParams.d.ts +9 -0
  74. package/dist/router/utils/index.d.ts +2 -0
  75. package/dist/router/utils/matchers.d.ts +2 -0
  76. package/dist/router/utils/mergeParentLayoutScreen.d.ts +18 -0
  77. package/dist/router/utils/path.d.ts +53 -0
  78. package/dist/router/utils/screen.d.ts +53 -0
  79. package/dist/scroll-view-inertial-background/ScrollViewInertialBackground.d.ts +49 -0
  80. package/dist/scroll-view-inertial-background/index.d.ts +1 -0
  81. package/dist/types/global.d.ts +18 -0
  82. package/dist/use-back-event/index.d.ts +1 -0
  83. package/dist/use-back-event/useBackEvent.d.ts +135 -0
  84. package/dist/utils/noop.d.ts +1 -0
  85. package/dist/utils/usePreservedCallback.d.ts +1 -0
  86. package/dist/visibility/VisibilityProvider.d.ts +27 -0
  87. package/dist/visibility/index.d.ts +6 -0
  88. package/dist/visibility/react-navigation/index.d.ts +2 -0
  89. package/dist/visibility/react-navigation/useIsFocusedSafely.d.ts +20 -0
  90. package/dist/visibility/react-navigation/useNavigationSafely.d.ts +19 -0
  91. package/dist/visibility/useIsAppForeground.d.ts +39 -0
  92. package/dist/visibility/useVisibility.d.ts +35 -0
  93. package/dist/visibility/useVisibilityChange.d.ts +51 -0
  94. package/dist/visibility/useVisibilityChanged.d.ts +41 -0
  95. package/dist/visibility/utils/usePrevious.d.ts +15 -0
  96. package/jest.d.ts +1 -0
  97. package/package.json +92 -0
  98. package/presets.d.ts +1 -0
  99. package/src/app/App/index.android.tsx +6 -0
  100. package/src/app/App/index.d.ts +6 -0
  101. package/src/app/App/index.ios.tsx +13 -0
  102. package/src/app/Granite.tsx +130 -0
  103. package/src/app/index.ts +2 -0
  104. package/src/app/registerPage.ts +29 -0
  105. package/src/async-bridges.ts +2 -0
  106. package/src/constant-bridges.ts +1 -0
  107. package/src/dev-entrypoint/index.tsx +21 -0
  108. package/src/event/abstract.ts +130 -0
  109. package/src/event/index.ts +2 -0
  110. package/src/event/useGraniteEvent.ts +34 -0
  111. package/src/impression-area/ImpressionArea.tsx +341 -0
  112. package/src/impression-area/index.ts +1 -0
  113. package/src/index.ts +19 -0
  114. package/src/initial-props/InitialProps.ts +144 -0
  115. package/src/initial-props/index.ts +1 -0
  116. package/src/intersection-observer/IOContext.ts +16 -0
  117. package/src/intersection-observer/IOFlatList.ts +72 -0
  118. package/src/intersection-observer/IOManager.ts +73 -0
  119. package/src/intersection-observer/IOScrollView.ts +69 -0
  120. package/src/intersection-observer/InView.tsx +205 -0
  121. package/src/intersection-observer/IntersectionObserver.ts +212 -0
  122. package/src/intersection-observer/index.ts +24 -0
  123. package/src/intersection-observer/withIO.tsx +151 -0
  124. package/src/jest/index.ts +1 -0
  125. package/src/keyboard/KeyboardAboveView.tsx +62 -0
  126. package/src/keyboard/index.ts +1 -0
  127. package/src/keyboard/useKeyboardAnimatedHeight.tsx +81 -0
  128. package/src/native-event-emitter/eventEmitters/index.ts +3 -0
  129. package/src/native-event-emitter/eventEmitters/types.ts +4 -0
  130. package/src/native-event-emitter/eventEmitters/visibilityChanged.ts +11 -0
  131. package/src/native-event-emitter/index.ts +1 -0
  132. package/src/native-event-emitter/nativeEventEmitter.ts +18 -0
  133. package/src/native-modules/core/GraniteCoreModule.ts +9 -0
  134. package/src/native-modules/index.ts +3 -0
  135. package/src/native-modules/natives/GraniteModule.ts +8 -0
  136. package/src/native-modules/natives/closeView.ts +25 -0
  137. package/src/native-modules/natives/getSchemeUri.ts +27 -0
  138. package/src/native-modules/natives/index.ts +3 -0
  139. package/src/native-modules/natives/openURL.ts +40 -0
  140. package/src/react/index.ts +1 -0
  141. package/src/react/useWaitForReturnNavigator.ts +75 -0
  142. package/src/rn-polyfills/index.ts +7 -0
  143. package/src/rn-polyfills/symbol-asynciterator/index.ts +15 -0
  144. package/src/rn-polyfills/url/index.ts +1 -0
  145. package/src/router/Router.tsx +164 -0
  146. package/src/router/components/BackButton.tsx +58 -0
  147. package/src/router/components/CanGoBackGuard.tsx +31 -0
  148. package/src/router/components/RouterBackButton.tsx +32 -0
  149. package/src/router/components/StackNavigator.tsx +12 -0
  150. package/src/router/constants.ts +3 -0
  151. package/src/router/createRoute.test-d.ts +52 -0
  152. package/src/router/createRoute.ts +161 -0
  153. package/src/router/hooks/useInitialRouteName.tsx +22 -0
  154. package/src/router/hooks/useIsInitialScreen.ts +7 -0
  155. package/src/router/hooks/useRouterControls.tsx +72 -0
  156. package/src/router/index.ts +3 -0
  157. package/src/router/types/RequireContext.ts +7 -0
  158. package/src/router/types/RouteScreen.ts +17 -0
  159. package/src/router/types/Screen.tsx +24 -0
  160. package/src/router/types/index.ts +3 -0
  161. package/src/router/types/screen-option.ts +23 -0
  162. package/src/router/utils/createParentRouteScreenMap.spec.ts +166 -0
  163. package/src/router/utils/createParentRouteScreenMap.ts +136 -0
  164. package/src/router/utils/defaultParserParams.spec.ts +46 -0
  165. package/src/router/utils/defaultParserParams.ts +19 -0
  166. package/src/router/utils/index.ts +2 -0
  167. package/src/router/utils/matchers.ts +5 -0
  168. package/src/router/utils/mergeParentLayoutScreen.spec.tsx +112 -0
  169. package/src/router/utils/mergeParentLayoutScreen.tsx +43 -0
  170. package/src/router/utils/path.spec.ts +135 -0
  171. package/src/router/utils/path.ts +105 -0
  172. package/src/router/utils/screen.tsx +111 -0
  173. package/src/scroll-view-inertial-background/ScrollViewInertialBackground.tsx +99 -0
  174. package/src/scroll-view-inertial-background/index.ts +1 -0
  175. package/src/types/global.ts +31 -0
  176. package/src/use-back-event/index.ts +1 -0
  177. package/src/use-back-event/useBackEvent.tsx +260 -0
  178. package/src/utils/noop.ts +1 -0
  179. package/src/utils/usePreservedCallback.ts +16 -0
  180. package/src/visibility/VisibilityProvider.tsx +36 -0
  181. package/src/visibility/index.ts +6 -0
  182. package/src/visibility/react-navigation/index.ts +2 -0
  183. package/src/visibility/react-navigation/useIsFocusedSafely.tsx +58 -0
  184. package/src/visibility/react-navigation/useNavigationSafely.tsx +30 -0
  185. package/src/visibility/useIsAppForeground.tsx +73 -0
  186. package/src/visibility/useVisibility.tsx +54 -0
  187. package/src/visibility/useVisibilityChange.ts +69 -0
  188. package/src/visibility/useVisibilityChanged.tsx +69 -0
  189. package/src/visibility/utils/usePrevious.tsx +24 -0
@@ -0,0 +1,11 @@
1
+ import { type ComponentType, type PropsWithChildren } from 'react';
2
+ import { RequireContext } from '../types/RequireContext';
3
+ export interface RouterControlsConfig {
4
+ prefix: string;
5
+ context: RequireContext;
6
+ screenContainer?: ComponentType<PropsWithChildren<any>>;
7
+ }
8
+ export declare function useRouterControls({ prefix, context, screenContainer: ScreenContainer }: RouterControlsConfig): {
9
+ Screens: import("react/jsx-runtime").JSX.Element[];
10
+ linkingOptions: import("@react-navigation/native").LinkingOptions<{}>;
11
+ };
@@ -0,0 +1,3 @@
1
+ export * from './Router';
2
+ export { getRouteScreens, getScreenPathMapConfig, defaultParserParams } from './utils';
3
+ export * from './types';
@@ -0,0 +1,7 @@
1
+ export interface RequireContext {
2
+ keys(): string[];
3
+ (id: string): any;
4
+ <T>(id: string): T;
5
+ resolve(id: string): string;
6
+ id: string;
7
+ }
@@ -0,0 +1,16 @@
1
+ import { Screen } from './Screen';
2
+ /**
3
+ * @name RouteScreen
4
+ */
5
+ export interface RouteScreen {
6
+ /**
7
+ * @name path
8
+ * @description Path information (e.g. "/", "/list", "/list/:id", etc.)
9
+ */
10
+ path: string;
11
+ /**
12
+ * @name component
13
+ * @description Screen component
14
+ */
15
+ component: Screen;
16
+ }
@@ -0,0 +1,23 @@
1
+ import type { NativeStackNavigationOptions } from '@granite-js/native/@react-navigation/native-stack';
2
+ import type { ComponentType } from 'react';
3
+ /**
4
+ * @name Screen
5
+ * @description A Screen that serves as a unit of navigation
6
+ * @example
7
+ *
8
+ * ```ts
9
+ * function Page() {
10
+ * // ...
11
+ * }
12
+ *
13
+ * Page.screenOptions = {
14
+ * // ...
15
+ * }
16
+ * ```
17
+ */
18
+ export type Screen = ComponentType & GraniteScreenOptions;
19
+ interface GraniteScreenOptions {
20
+ /** @description Add this when customization is needed for NativeStack Screen's screenOptions */
21
+ screenOptions?: NativeStackNavigationOptions;
22
+ }
23
+ export {};
@@ -0,0 +1,3 @@
1
+ export * from './RequireContext';
2
+ export * from './RouteScreen';
3
+ export * from './Screen';
@@ -0,0 +1,4 @@
1
+ import { NativeStackNavigationOptions } from '@granite-js/native/@react-navigation/native-stack';
2
+ export declare const DEFAULT_BACKGROUND_COLOR = "#ffffff";
3
+ export declare const DEFAULT_HEADER_TINT_COLOR = "#333d4b";
4
+ export declare const BASE_STACK_NAVIGATOR_STYLE: NativeStackNavigationOptions;
@@ -0,0 +1,8 @@
1
+ import type { RouteScreen } from '../types/RouteScreen';
2
+ /**
3
+ * @name createParentRouteScreenMap
4
+ * @description
5
+ * Finds a specific keyword in a given list of files and
6
+ * maps each page/layout to use its "nearest parent layout"
7
+ */
8
+ export declare function createParentRouteScreenMap(routeScreens: RouteScreen[], keyword: string): Map<string, RouteScreen>;
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Parses URL query string and converts it to an object.
3
+ * @param params - Query string to parse
4
+ * @returns Parsed query object
5
+ * @example
6
+ * // Input: { foo: '123', bar: 'true' }
7
+ * // Output: { foo: 123, bar: true }
8
+ */
9
+ export declare function defaultParserParams(params?: Record<string, string>): Record<string, unknown>;
@@ -0,0 +1,2 @@
1
+ export * from './screen';
2
+ export * from './defaultParserParams';
@@ -0,0 +1,2 @@
1
+ /** `[page]` -> `page` */
2
+ export declare function matchDynamicName(name: string): string | undefined;
@@ -0,0 +1,18 @@
1
+ import { FC, ReactNode } from 'react';
2
+ import { RouteScreen } from '../types/RouteScreen';
3
+ export type LayoutScreen = FC<{
4
+ children: ReactNode;
5
+ }>;
6
+ /**
7
+ * Starting from the layout mapped to a specific path, traverses up to parent layouts,
8
+ * creates an array in the order of "innermost → outermost",
9
+ * then builds up the final wrapper component using reduce.
10
+ *
11
+ * Example) map:
12
+ * './item/detail' => { component: ItemLayout, path: './item/_layout' }
13
+ * './item/_layout' => { component: RootLayout, path: './_layout' }
14
+ *
15
+ * => layoutChain = [ItemLayout, RootLayout]
16
+ * => Final rendering result: <RootLayout><ItemLayout>children</ItemLayout></RootLayout>
17
+ */
18
+ export declare function mergeParentLayoutScreen(screens: Map<string, RouteScreen>, path: string): LayoutScreen;
@@ -0,0 +1,53 @@
1
+ /**
2
+ * @name excludeFileExtension
3
+ * @description Removes file extension.
4
+ */
5
+ export declare function excludeFileExtension(name: string): string;
6
+ /**
7
+ * @name excludeRelativePath
8
+ * @description Removes relative path from path.
9
+ * @example
10
+ * ```ts
11
+ * excludeRelativePath("./index.tsx") // "index.tsx"
12
+ * excludeRelativePath("./list/detail.tsx") // "list/detail.tsx"
13
+ * excludeRelativePath("../../index.tsx") // "index.tsx"
14
+ * ```
15
+ */
16
+ export declare function excludeRelativePath(filePath: string): string;
17
+ /**
18
+ * @name excludeDynamicNamePattern
19
+ * @description Removes `[` `]` from dynamic route pattern.
20
+ * @example
21
+ * ```ts
22
+ * excludeDynamicNamePattern("[id]") // "id"
23
+ * excludeDynamicNamePattern("[id]/[name]") // "id/name"
24
+ * ```
25
+ */
26
+ export declare function excludeDynamicNamePattern(filePath: string): string;
27
+ /**
28
+ * @name getRoutePath
29
+ * @description Converts to route path.
30
+ * @example
31
+ * ```ts
32
+ * getRoutePath('./index.tsx') // "/"
33
+ * getRoutePath('./list/index.tsx') // "/list"
34
+ * getRoutePath('./list/detail.tsx') // "/list/detail"
35
+ * getRoutePath('./list/[id].js') // "/list/:id"
36
+ * ```
37
+ */
38
+ export declare function getRoutePath(filePath: string): string;
39
+ /**
40
+ * @name getFileNameFromPath
41
+ * @description Extracts filename from file path.
42
+ * @example
43
+ * ```ts
44
+ * getFileNameFromPath('/path/to/file.txt') // "file.txt"
45
+ * getFileNameFromPath('file.txt') // "file.txt"
46
+ * getFileNameFromPath('') // ""
47
+ * getFileNameFromPath('/path/to/directory/') // ""
48
+ * getFileNameFromPath('/path/to/file.txt', { withExtension: false }) // "file"
49
+ * ```
50
+ */
51
+ export declare function getFileNameFromPath(filePath: string, options?: {
52
+ withExtension?: boolean;
53
+ }): string;
@@ -0,0 +1,53 @@
1
+ import { RequireContext, RouteScreen } from '../types';
2
+ /**
3
+ * @kind function
4
+ * @name getRouteScreens
5
+ * @description
6
+ * Gets screens from the pages folder.
7
+ *
8
+ * @param {RequireContext} context - Object containing information about screens in Router
9
+ * @returns {RouteScreen[]} screens - Returns a list of screens that can be navigated to.
10
+ *
11
+ * @example
12
+ * ```tsx
13
+ * import { getRouteScreens } from '@granite-js/react-native';
14
+ *
15
+ * const context = require.context('../pages');
16
+ * const screens = getRouteScreens(context);
17
+ * ```
18
+ */
19
+ export declare function getRouteScreens(context: RequireContext): RouteScreen[];
20
+ /**
21
+ * @kind function
22
+ * @name getScreenPathMapConfig
23
+ * @description Maps paths of screens.
24
+ *
25
+ * @param {RouteScreen[]} routeScreens - List of screens that can be navigated to
26
+ *
27
+ * @example
28
+ * ```tsx
29
+ * import { registerPage, getRouteScreens, getScreenPathMapConfig, Router } from '@granite-js/react-native';
30
+ * import { context } from '../require.context';
31
+ *
32
+ * function App() {
33
+ * return <Router context={context} prefix={'scheme://minibench'} />;
34
+ * }
35
+ *
36
+ * export default registerPage(
37
+ * App,
38
+ * 'minibench',
39
+ * getScreenPathMapConfig(getRouteScreens(context))
40
+ * );
41
+ * ```
42
+ */
43
+ export declare function getScreenPathMapConfig(routeScreens: RouteScreen[]): ScreenPath;
44
+ /**
45
+ * @name ScreenPath
46
+ * @description
47
+ * Type representing screen paths.
48
+ *
49
+ * @typedef {Record<string, { path?: string }>} ScreenPath
50
+ */
51
+ export type ScreenPath = Record<string, {
52
+ path?: string;
53
+ }>;
@@ -0,0 +1,49 @@
1
+ interface ScrollViewInertialBackgroundProps {
2
+ topColor?: string;
3
+ bottomColor?: string;
4
+ spacer?: number;
5
+ }
6
+ /**
7
+ * @public
8
+ * @category UI
9
+ * @name ScrollViewInertialBackground
10
+ * @description
11
+ * Adds background colors to the top and bottom spaces of iOS `ScrollView` content to provide a natural visual effect when scrolling.
12
+ * In iOS, when scrolling reaches the end, a slight bouncing effect occurs, known as the [Bounce effect](https://medium.com/@wcandillon/ios-bounce-list-effect-with-react-native-5102e3a83999). Setting background colors in the spaces above and below the content can provide a more consistent user experience.
13
+ *
14
+ * @param {object} [props] - `props` object passed to the component.
15
+ * @param {string} [props.topColor] - Background color to apply to the top area of the scroll. Default is `adaptive.background` which is automatically applied based on the system theme.
16
+ * @param {string} [props.bottomColor] - Background color to apply to the bottom area of the scroll. Default is `adaptive.background` which is automatically applied based on the system theme.
17
+ * @param {number} [props.spacer] - Specifies the size of the space between the top and bottom areas where the background color is applied. Default uses the screen height obtained from [`useWindowDimensions`](https://reactnative.dev/docs/next/usewindowdimensions).
18
+ *
19
+ * @example
20
+ *
21
+ * ### Adding background colors to the top and bottom of a scroll view
22
+ *
23
+ * Adds red background color to the top and blue to the bottom of the scroll view. The background color is applied to areas outside the scroll.
24
+ *
25
+ * ```tsx
26
+ * import { ScrollView, View, Text } from 'react-native';
27
+ * import { ScrollViewInertialBackground } from '@granite-js/react-native';
28
+ *
29
+ * const dummies = Array.from({ length: 20 }, (_, i) => i);
30
+ *
31
+ * export function InertialBackgroundExample() {
32
+ * return (
33
+ * <ScrollView>
34
+ * <ScrollViewInertialBackground topColor="red" bottomColor="blue" />
35
+ * {dummies.map((i) => (
36
+ * <View
37
+ * key={`dummy-${i}`}
38
+ * style={{ width: '100%', height: 100, borderBottomColor: 'black', borderBottomWidth: 1 }}
39
+ * >
40
+ * <Text>Try scrolling.</Text>
41
+ * </View>
42
+ * ))}
43
+ * </ScrollView>
44
+ * );
45
+ * }
46
+ * ```
47
+ */
48
+ export declare function ScrollViewInertialBackground({ topColor, bottomColor, spacer: _spacer, }: ScrollViewInertialBackgroundProps): import("react/jsx-runtime").JSX.Element;
49
+ export {};
@@ -0,0 +1 @@
1
+ export * from './ScrollViewInertialBackground';
@@ -0,0 +1,18 @@
1
+ export interface GraniteGlobal {
2
+ shared: {
3
+ buildNumber: string;
4
+ };
5
+ app: {
6
+ name: string;
7
+ scheme: string;
8
+ buildNumber: string;
9
+ };
10
+ }
11
+ declare global {
12
+ var window: {
13
+ __granite: GraniteGlobal;
14
+ };
15
+ var global: {
16
+ __granite: GraniteGlobal;
17
+ };
18
+ }
@@ -0,0 +1 @@
1
+ export * from './useBackEvent';
@@ -0,0 +1,135 @@
1
+ import { ReactNode } from 'react';
2
+ export interface BackEventControls {
3
+ addEventListener: (...handlers: Array<() => void>) => void;
4
+ removeEventListener: (...handlers: Array<() => void>) => void;
5
+ }
6
+ interface PrivateBackEventControls extends BackEventControls {
7
+ handlersRef: Set<() => void>;
8
+ hasBackEvent: boolean;
9
+ onBack: () => void;
10
+ }
11
+ /**
12
+ * @component
13
+ * @name BackEventProvider
14
+ * @description
15
+ * A component that provides a `Context` for handling back events within the app. Using this component, child components can subscribe to and manage back events. Placing `BackEventProvider` at the top of the tree allows all back events to be handled centrally.
16
+ *
17
+ * @param {ReactNode} children Child components that will control back events.
18
+ * @param {BackEventControls} backEvent Control object for handling back events. You can register back events using the `addEventListener` method and remove registered back events using the `removeEventListener` method.
19
+ * @returns {JSX.Element} A component that can handle back events.
20
+ *
21
+ * By adding `BackEventProvider` as shown below, child components can handle back events.
22
+ *
23
+ * @example
24
+ * ```jsx
25
+ * const backEventControls = {
26
+ * addEventListener: (handler) => { ... },
27
+ * removeEventListener: (handler) => { ... },
28
+ * };
29
+ *
30
+ * <BackEventProvider backEvent={backEventControls}>
31
+ * <App />
32
+ * </BackEventProvider>
33
+ * ```
34
+ */
35
+ export declare function BackEventProvider({ children, backEvent, }: {
36
+ children: ReactNode;
37
+ backEvent: PrivateBackEventControls;
38
+ }): import("react/jsx-runtime").JSX.Element;
39
+ /**
40
+ * @name useBackEventState
41
+ * @description
42
+ * A hook that returns the current back event state and control methods managed by `BackEventProvider`. Using this hook, you can add or remove back event handlers and check the current state.
43
+ *
44
+ * @returns {{ handlers: Array<() => void>, backEvent: BackEventControls, routerProps: { canGoBack: boolean, onBack: () => void } }} Returns an array of back event handlers, the event control method `backEvent`, and `routerProps` that can be used when handling back functionality in the router.
45
+ *
46
+ * Using this Hook, you can add or remove back event handlers and integrate with the router.
47
+ *
48
+ * @example
49
+ * ```javascript
50
+ * const { backEvent, routerProps } = useBackEventState();
51
+ * // Handle back events in the router through routerProps
52
+ * backEvent.addEventListener(() => {
53
+ * console.log('Back event triggered');
54
+ * });
55
+ *
56
+ * return (
57
+ * <BackEventProvider backEvent={backEvent}>
58
+ * <GraniteRouter {...routerProps} context={context} prefix={'scheme://testbench'} />
59
+ * </BackEventProvider>
60
+ * );
61
+ *
62
+ * ```
63
+ */
64
+ export declare function useBackEventState(): PrivateBackEventControls;
65
+ /**
66
+ * @public
67
+ * @category Screen Control
68
+ * @name useBackEvent
69
+ * @description
70
+ * A Hook that returns a controller object for registering and removing back events. Using this Hook, you can handle back events only when a specific component is active.
71
+ * Use `addEventListener` to register back events and `removeEventListener` to remove them.
72
+ * Registered back events are only active when the user is viewing the screen. The condition for viewing the screen is determined using [useVisibility](/en/reference/react-native/Screen%20Control/useVisibility).
73
+ *
74
+ * Using this Hook, you can define logic to handle back events in specific components.
75
+ *
76
+ * @returns {BackEventControls} An object that can control back events. This object includes the `addEventListener` method for registering events and the `removeEventListener` method for removing them.
77
+ *
78
+ * @throws {Error} Throws an error if this hook is not used within a `BackEventProvider`.
79
+ *
80
+ * @example
81
+ *
82
+ * ### Example of Registering and Removing Back Events
83
+ *
84
+ * - **When the "Add BackEvent" button is pressed, a back event is registered.** After that, pressing the back button shows an alert with "back" and prevents actual navigation.
85
+ * - **When the "Remove BackEvent" button is pressed, the registered event is removed.** After that, pressing the back button navigates back normally as per default behavior.
86
+ *
87
+ * ```tsx
88
+ * import { useEffect, useState } from 'react';
89
+ * import { Alert, Button, View } from 'react-native';
90
+ * import { useBackEvent } from '@granite-js/react-native';
91
+ *
92
+ * export function UseBackEventExample() {
93
+ * const backEvent = useBackEvent();
94
+ *
95
+ * const [handler, setHandler] = useState<{ callback: () => void } | undefined>(undefined);
96
+ *
97
+ * useEffect(() => {
98
+ * const callback = handler?.callback;
99
+ *
100
+ * if (callback != null) {
101
+ * backEvent.addEventListener(callback);
102
+ *
103
+ * return () => {
104
+ * backEvent.removeEventListener(callback);
105
+ * };
106
+ * }
107
+ *
108
+ * return;
109
+ * }, [backEvent, handler]);
110
+ *
111
+ * return (
112
+ * <View>
113
+ * <Button
114
+ * title="Add BackEvent"
115
+ * onPress={() => {
116
+ * setHandler({ callback: () => Alert.alert('back') });
117
+ * }}
118
+ * />
119
+ * <Button
120
+ * title="Remove BackEvent"
121
+ * onPress={() => {
122
+ * setHandler(undefined);
123
+ * }}
124
+ * />
125
+ * </View>
126
+ * );
127
+ * }
128
+ * ```
129
+ */
130
+ export declare function useBackEvent(): BackEventControls;
131
+ export declare function useBackEventContext(): {
132
+ onGoBack: () => void;
133
+ hasBackEvent: boolean;
134
+ };
135
+ export {};
@@ -0,0 +1 @@
1
+ export declare const noop: () => void;
@@ -0,0 +1 @@
1
+ export declare function usePreservedCallback<Callback extends (...args: any[]) => any>(callback: Callback): Callback;
@@ -0,0 +1,27 @@
1
+ import { ReactElement, ReactNode } from 'react';
2
+ interface Props {
3
+ isVisible: boolean;
4
+ children: ReactNode;
5
+ }
6
+ /**
7
+ * @name VisibilityProvider
8
+ * @description
9
+ * A Provider that manages whether a ReactNative view is currently in the foreground state.
10
+ * @param {boolean} isVisible - Whether the app is in the foreground state.
11
+ * @param {ReactNode | undefined} children - Child components that observe `AppState`.
12
+ * @returns {ReactElement} - A React Provider component wrapped with `VisibilityChangedProvider`.
13
+ * @example
14
+ * ```typescript
15
+ *
16
+ * function App() {
17
+ * return (
18
+ * <VisibilityProvider isVisible={true}>
19
+ * <MyApp />
20
+ * </VisibilityProvider>
21
+ * );
22
+ * }
23
+ *
24
+ * ```
25
+ */
26
+ export declare function VisibilityProvider({ isVisible, children }: Props): ReactElement;
27
+ export {};
@@ -0,0 +1,6 @@
1
+ export * from './react-navigation';
2
+ export * from './useIsAppForeground';
3
+ export * from './useVisibility';
4
+ export * from './useVisibilityChanged';
5
+ export * from './useVisibilityChange';
6
+ export * from './VisibilityProvider';
@@ -0,0 +1,2 @@
1
+ export * from './useIsFocusedSafely';
2
+ export * from './useNavigationSafely';
@@ -0,0 +1,20 @@
1
+ /**
2
+ * @name useIsFocusedSafely
3
+ * @category Hooks
4
+ * @kind function
5
+ * @link https://github.com/react-navigation/react-navigation/blob/%40react-navigation/native%406.1.18/packages/core/src/useIsFocused.tsx
6
+ * @description
7
+ * Returns whether the current screen is in focus.
8
+ *
9
+ * A Hook that safely uses `useIsFocused` provided by `@react-navigation/native`.
10
+ * This Hook is based on `useIsFocused` from `@react-navigation/native`, but modified to not throw errors when `navigation` or `root` objects are `null` or `undefined`.
11
+ * It ensures that users don't see errors even when the code is used in environments where `@react-navigation/native` is not used.
12
+ *
13
+ * @returns {boolean} - Returns the focus state of the current screen.
14
+ * @example
15
+ * ```typescript
16
+ * const isFocused = useIsFocusedSafely();
17
+ * console.log(isFocused); // true or false
18
+ * ```
19
+ */
20
+ export declare function useIsFocusedSafely(): boolean;
@@ -0,0 +1,19 @@
1
+ import { NavigationProp } from '@granite-js/native/@react-navigation/native';
2
+ /**
3
+ * @name useNavigationSafely
4
+ * @category Hooks
5
+ * @kind function
6
+ * @link https://github.com/react-navigation/react-navigation/blob/d1cd940d9a3fb46bec0eb6bf4f8023789fc93b28/packages/core/src/useNavigation.tsx#L13
7
+ * @description
8
+ * A Hook that safely uses [`useNavigation`](https://reactnavigation.org/docs/use-navigation/) from `@react-navigation/native` for managing navigation between screens.
9
+ * This Hook is based on `useNavigation` provided by `@react-navigation/native`, but operates more safely by not throwing errors when `navigation` or `root` objects are `null` or `undefined`.
10
+ * It also ensures the code runs safely in environments where `@react-navigation/native` is not used, preventing users from experiencing errors.
11
+ *
12
+ * @returns {NavigationProp<ReactNavigation.RootParamList> | undefined} - The screen is in a visible state.
13
+ * @example
14
+ * ```typescript
15
+ * const navigation = useNavigationSafely();
16
+ * const isNavigationFocused = () => navigation?.isFocused() ?? true;
17
+ * ```
18
+ */
19
+ export declare function useNavigationSafely(): NavigationProp<ReactNavigation.RootParamList> | undefined;
@@ -0,0 +1,39 @@
1
+ import { ReactElement, ReactNode } from 'react';
2
+ interface Props {
3
+ children: ReactNode;
4
+ }
5
+ /**
6
+ * @name AppStateProvider
7
+ * @description
8
+ * A Provider that manages the `AppState` of React Native screens. This Provider manages the app's state (active, background, etc.) and passes it to child components that subscribe to it.
9
+ * @link https://reactnative.dev/docs/appstate
10
+ * @param {Props} children - Child components to be wrapped by `AppStateProvider`. These components can detect and respond to changes in `AppState`.
11
+ * @returns {ReactElement} - A React Provider component wrapped with `AppStateProvider`.
12
+ * @example
13
+ * ```tsx
14
+ * export function App() {
15
+ * return (
16
+ * <AppStateProvider>
17
+ * <MyApp />
18
+ * </AppStateProvider>
19
+ * );
20
+ * }
21
+ * ```
22
+ */
23
+ export declare function AppStateProvider({ children }: Props): ReactElement;
24
+ /**
25
+ * @category Hooks
26
+ * @name useIsAppForeground
27
+ * @description
28
+ * Returns whether the React Native app is in the foreground state.
29
+ *
30
+ * @see https://reactnative.dev/docs/0.72/appstate#app-states
31
+ * @returns {boolean} - Returns whether the app is in the foreground state.
32
+ * @throws {Error} Throws an error when the managed AppState is `null`.
33
+ * @example
34
+ * ```typescript
35
+ * const isForeground = useIsAppForeground();
36
+ * ```
37
+ */
38
+ export declare const useIsAppForeground: () => boolean;
39
+ export {};
@@ -0,0 +1,35 @@
1
+ /**
2
+ * @public
3
+ * @category Screen Control
4
+ * @name useVisibility
5
+ * @description
6
+ * Returns whether the screen is visible to the user.
7
+ * Returns `true` if the app's screen is currently visible to the user, and `false` if it's not. However, the screen visibility state does not change when opening and closing the system share modal ([share](/reference/react-native/Share/share)).
8
+ *
9
+ * Usage examples:
10
+ * - Returns `false` when switching to another app or pressing the home button.
11
+ * - Returns `true` when returning to the granite app or when the screen becomes visible.
12
+ * - Returns `false` when navigating to another service within the granite app.
13
+ *
14
+ * @returns {boolean} - Whether the current screen is visible to the user.
15
+ * @example
16
+ *
17
+ * ### Example of checking screen visibility
18
+ *
19
+ * ```tsx
20
+ * import { useEffect } from 'react';
21
+ * import { Text } from 'react-native';
22
+ * import { useVisibility } from '@granite-js/react-native';
23
+ *
24
+ * export function UseVisibilityExample() {
25
+ * const visibility = useVisibility();
26
+ *
27
+ * useEffect(() => {
28
+ * console.log({ visibility });
29
+ * }, [visibility]);
30
+ *
31
+ * return <Text>Logs are created when leaving and returning to the home screen.</Text>;
32
+ * }
33
+ * ```
34
+ */
35
+ export declare function useVisibility(): boolean;
@@ -0,0 +1,51 @@
1
+ /**
2
+ * String representing whether the screen is visible.
3
+ * @typedef {string} VisibilityState
4
+ * @property {'visible'} visible - The screen is visible.
5
+ * @property {'hidden'} hidden - The screen is not visible.
6
+ */
7
+ export type VisibilityState = 'visible' | 'hidden';
8
+ /**
9
+ * @callback VisibilityCallback
10
+ * @param {VisibilityState} state - String representing the visibility state of the screen.
11
+ */
12
+ export type VisibilityCallback = (state: VisibilityState) => void;
13
+ /**
14
+ * @public
15
+ * @category Screen Control
16
+ * @name useVisibilityChange
17
+ * @kind function
18
+ * @description
19
+ * Calls a callback function with the visibility state when the screen's visibility changes.
20
+ * The callback function receives the return value from [useVisibility](/en/reference/react-native/Screen%20Control/useVisibility). If the return value is `true`, it passes 'visible', and if `false`, it passes 'hidden'.
21
+ *
22
+ * @param {VisibilityCallback} callback - Calls a callback function that receives visibility changes when the screen's visibility changes.
23
+ * @example
24
+ *
25
+ * ### Example of logging when screen visibility changes
26
+ *
27
+ * ```tsx
28
+ * import { useState } from 'react';
29
+ * import { Text, View } from 'react-native';
30
+ * import { useVisibilityChange, VisibilityState } from '@granite-js/react-native';
31
+ *
32
+ * export function UseVisibilityChangeExample() {
33
+ * const [visibilityHistory, setVisibilityHistory] = useState<VisibilityState[]>([]);
34
+ *
35
+ * useVisibilityChange((visibility) => {
36
+ * setVisibilityHistory((prev) => [...prev, visibility]);
37
+ * });
38
+ *
39
+ * return (
40
+ * <View>
41
+ * <Text>Logs are created when leaving and returning to the home screen.</Text>
42
+ *
43
+ * {visibilityHistory.map((visibility, index) => (
44
+ * <Text key={index}>{JSON.stringify(visibility)}</Text>
45
+ * ))}
46
+ * </View>
47
+ * );
48
+ * }
49
+ * ```
50
+ */
51
+ export declare function useVisibilityChange(callback: VisibilityCallback): void;