@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,73 @@
1
+ import { createContext, ReactElement, ReactNode, useContext, useEffect, useState } from 'react';
2
+ import { AppState, AppStateStatus } from 'react-native';
3
+
4
+ interface Props {
5
+ children: ReactNode;
6
+ }
7
+
8
+ const AppStateContext = createContext<AppStateStatus | undefined>(undefined);
9
+
10
+ /**
11
+ * @name AppStateProvider
12
+ * @description
13
+ * 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.
14
+ * @link https://reactnative.dev/docs/appstate
15
+ * @param {Props} children - Child components to be wrapped by `AppStateProvider`. These components can detect and respond to changes in `AppState`.
16
+ * @returns {ReactElement} - A React Provider component wrapped with `AppStateProvider`.
17
+ * @example
18
+ * ```tsx
19
+ * export function App() {
20
+ * return (
21
+ * <AppStateProvider>
22
+ * <MyApp />
23
+ * </AppStateProvider>
24
+ * );
25
+ * }
26
+ * ```
27
+ */
28
+ export function AppStateProvider({ children }: Props): ReactElement {
29
+ const [appState, setAppState] = useState<AppStateStatus>(AppState.currentState);
30
+
31
+ const handleAppStateChange = (status: AppStateStatus) => {
32
+ setAppState(status);
33
+ };
34
+
35
+ useEffect(() => {
36
+ const subscription = AppState.addEventListener('change', handleAppStateChange);
37
+
38
+ return () => {
39
+ subscription.remove();
40
+ };
41
+ }, []);
42
+
43
+ return <AppStateContext.Provider value={appState}>{children}</AppStateContext.Provider>;
44
+ }
45
+
46
+ /**
47
+ * @category Hooks
48
+ * @name useIsAppForeground
49
+ * @description
50
+ * Returns whether the React Native app is in the foreground state.
51
+ *
52
+ * @see https://reactnative.dev/docs/0.72/appstate#app-states
53
+ * @returns {boolean} - Returns whether the app is in the foreground state.
54
+ * @throws {Error} Throws an error when the managed AppState is `null`.
55
+ * @example
56
+ * ```typescript
57
+ * const isForeground = useIsAppForeground();
58
+ * ```
59
+ */
60
+ export const useIsAppForeground = (): boolean => {
61
+ const appState = useContext(AppStateContext);
62
+
63
+ if (appState == null) {
64
+ throw new Error('useIsAppForeground must be used within a AppStateProvider');
65
+ }
66
+
67
+ /**
68
+ * In iOS, the 'inactive' state is also considered as foreground.
69
+ * 'inactive' is a state that only exists in iOS, for example, when the control center or notification panel is open.
70
+ * @see https://reactnative.dev/docs/0.72/appstate#app-states
71
+ */
72
+ return appState === 'active' || appState === 'inactive';
73
+ };
@@ -0,0 +1,54 @@
1
+ import { Platform } from 'react-native';
2
+ import { useIsFocusedSafely } from './react-navigation/useIsFocusedSafely';
3
+ import { useIsAppForeground } from './useIsAppForeground';
4
+ import { useVisibilityChanged } from './useVisibilityChanged';
5
+
6
+ /**
7
+ * @public
8
+ * @category Screen Control
9
+ * @name useVisibility
10
+ * @description
11
+ * Returns whether the screen is visible to the user.
12
+ * 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)).
13
+ *
14
+ * Usage examples:
15
+ * - Returns `false` when switching to another app or pressing the home button.
16
+ * - Returns `true` when returning to the granite app or when the screen becomes visible.
17
+ * - Returns `false` when navigating to another service within the granite app.
18
+ *
19
+ * @returns {boolean} - Whether the current screen is visible to the user.
20
+ * @example
21
+ *
22
+ * ### Example of checking screen visibility
23
+ *
24
+ * ```tsx
25
+ * import { useEffect } from 'react';
26
+ * import { Text } from 'react-native';
27
+ * import { useVisibility } from '@granite-js/react-native';
28
+ *
29
+ * export function UseVisibilityExample() {
30
+ * const visibility = useVisibility();
31
+ *
32
+ * useEffect(() => {
33
+ * console.log({ visibility });
34
+ * }, [visibility]);
35
+ *
36
+ * return <Text>Logs are created when leaving and returning to the home screen.</Text>;
37
+ * }
38
+ * ```
39
+ */
40
+ export function useVisibility(): boolean {
41
+ const visible = useVisibilityChanged();
42
+ const isForeground = useIsAppForeground();
43
+ const isReactNavigationFocused = useIsFocusedSafely();
44
+
45
+ /**
46
+ * We don't use AppState in Android. (AppState uses `onHostPause` and `onHostResume`.)
47
+ * From Android version 5.172.0, `visibilityChanged` uses `onHostStop` and `onHostStart`.
48
+ * - For example, in Android, the `visible` state is maintained even when the share modal appears (share app bridge call).
49
+ */
50
+ const androidCondition = visible && isReactNavigationFocused;
51
+ const iOSCondition = visible && isForeground && isReactNavigationFocused;
52
+
53
+ return Platform.OS === 'android' ? androidCondition : iOSCondition;
54
+ }
@@ -0,0 +1,69 @@
1
+ import { useEffect } from 'react';
2
+ import { useVisibility } from './useVisibility';
3
+ import { usePrevious } from './utils/usePrevious';
4
+
5
+ /**
6
+ * String representing whether the screen is visible.
7
+ * @typedef {string} VisibilityState
8
+ * @property {'visible'} visible - The screen is visible.
9
+ * @property {'hidden'} hidden - The screen is not visible.
10
+ */
11
+ export type VisibilityState = 'visible' | 'hidden';
12
+
13
+ /**
14
+ * @callback VisibilityCallback
15
+ * @param {VisibilityState} state - String representing the visibility state of the screen.
16
+ */
17
+ export type VisibilityCallback = (state: VisibilityState) => void;
18
+
19
+ /**
20
+ * @public
21
+ * @category Screen Control
22
+ * @name useVisibilityChange
23
+ * @kind function
24
+ * @description
25
+ * Calls a callback function with the visibility state when the screen's visibility changes.
26
+ * 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'.
27
+ *
28
+ * @param {VisibilityCallback} callback - Calls a callback function that receives visibility changes when the screen's visibility changes.
29
+ * @example
30
+ *
31
+ * ### Example of logging when screen visibility changes
32
+ *
33
+ * ```tsx
34
+ * import { useState } from 'react';
35
+ * import { Text, View } from 'react-native';
36
+ * import { useVisibilityChange, VisibilityState } from '@granite-js/react-native';
37
+ *
38
+ * export function UseVisibilityChangeExample() {
39
+ * const [visibilityHistory, setVisibilityHistory] = useState<VisibilityState[]>([]);
40
+ *
41
+ * useVisibilityChange((visibility) => {
42
+ * setVisibilityHistory((prev) => [...prev, visibility]);
43
+ * });
44
+ *
45
+ * return (
46
+ * <View>
47
+ * <Text>Logs are created when leaving and returning to the home screen.</Text>
48
+ *
49
+ * {visibilityHistory.map((visibility, index) => (
50
+ * <Text key={index}>{JSON.stringify(visibility)}</Text>
51
+ * ))}
52
+ * </View>
53
+ * );
54
+ * }
55
+ * ```
56
+ */
57
+ export function useVisibilityChange(callback: VisibilityCallback) {
58
+ const isVisible = useVisibility();
59
+
60
+ const prevValue = usePrevious<boolean>(isVisible) ?? false;
61
+
62
+ useEffect(() => {
63
+ if (prevValue === isVisible) {
64
+ return;
65
+ }
66
+
67
+ callback(isVisible ? 'visible' : 'hidden');
68
+ }, [callback, isVisible, prevValue]);
69
+ }
@@ -0,0 +1,69 @@
1
+ import { createContext, PropsWithChildren, ReactElement, useContext, useEffect, useState } from 'react';
2
+ import { nativeEventEmitter } from '../native-event-emitter';
3
+
4
+ const VisibilityChangedContext = createContext<boolean | undefined>(undefined);
5
+
6
+ /**
7
+ * @name VisibilityChangedProvider
8
+ * @kind function
9
+ * @description
10
+ * A Provider that manages whether a React Native screen is visible.
11
+ * It subscribes to the app's `visibilityChanged` event to detect and manage screen visibility.
12
+ *
13
+ * @param {ReactNode | undefined} children - Child components that check screen visibility.
14
+ * @param {boolean} isVisible - A boolean value indicating whether the screen is visible.
15
+ * @returns {ReactElement} - A React Provider component wrapped with `VisibilityChangedContext.Provider`.
16
+ * @example
17
+ * ```typescript
18
+ * export function VisibilityProvider({ isVisible, children }: Props) {
19
+ * return (
20
+ * <VisibilityChangedProvider isVisible={isVisible}>
21
+ * {children}
22
+ * </VisibilityChangedProvider>
23
+ * );
24
+ * }
25
+ * ```
26
+ */
27
+ export function VisibilityChangedProvider({
28
+ children,
29
+ isVisible,
30
+ }: PropsWithChildren<{ isVisible: boolean }>): ReactElement {
31
+ const [visible, setVisible] = useState(isVisible);
32
+
33
+ useEffect(() => {
34
+ const subscription = nativeEventEmitter.addListener('visibilityChanged', (nextVisible) => {
35
+ setVisible(nextVisible);
36
+ });
37
+
38
+ return () => {
39
+ subscription.remove();
40
+ };
41
+ }, []);
42
+
43
+ return <VisibilityChangedContext.Provider value={visible}>{children}</VisibilityChangedContext.Provider>;
44
+ }
45
+
46
+ /**
47
+ * @name useVisibilityChanged
48
+ * @category Hooks
49
+ * @kind function
50
+ * @description
51
+ * A Hook that returns whether a React Native screen is visible.
52
+ * @returns {boolean} - Returns whether the screen is visible.
53
+ * @throws {Error} Throws an error when not used within a `VisibilityChangedProvider`.
54
+ * @example
55
+ * ```typescript
56
+ * const isVisible = useVisibilityChanged();
57
+ * console.log(isVisible);
58
+ * // true or false
59
+ * ```
60
+ */
61
+ export function useVisibilityChanged(): boolean {
62
+ const isVisible = useContext(VisibilityChangedContext);
63
+
64
+ if (isVisible == null) {
65
+ throw new Error('useVisibilityChanged must be used within a VisibilityChangedProvider');
66
+ }
67
+
68
+ return isVisible;
69
+ }
@@ -0,0 +1,24 @@
1
+ import { useEffect, useRef } from 'react';
2
+
3
+ /**
4
+ * @name usePrevious
5
+ * @category Hooks
6
+ * @kind function
7
+ * @description
8
+ * A Hook that returns the previous value.
9
+ * @param {T} value - The value to return the previous value of.
10
+ * @returns {T} - Returns the previous value.
11
+ * @example
12
+ * ```typescript
13
+ * const isVisible = useVisibility();
14
+ * const prevValue = usePrevious<boolean>(isVisible) ?? false;
15
+ * ```
16
+ */
17
+ export function usePrevious<T>(value: T): T {
18
+ const ref: any = useRef<T>();
19
+ useEffect(() => {
20
+ ref.current = value;
21
+ }, [value]);
22
+
23
+ return ref.current;
24
+ }